]> andersk Git - moira.git/blobdiff - server/qfollow.pc
Command line printer manipulation client, and build goo.
[moira.git] / server / qfollow.pc
index 686b26f19c77ea0bacae2e5c6b799aa73442c2ec..480d287fc72e8c9d8fa5e1d11eb126f6b66a8125 100644 (file)
@@ -1,28 +1,26 @@
-/*
- *     $Source$
- *     $Author$
- *     $Header$
+/* $Id$
  *
- *     Copyright (C) 1987 by the Massachusetts Institute of Technology
- *     For copying and distribution information, please see the file
- *     <mit-copyright.h>.
+ * Query followup routines
+ *
+ * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
  *
  */
 
-#ifndef lint
-static char *rcsid_qsupport_dc = "$Header$";
-#endif lint
-
 #include <mit-copyright.h>
 #include "mr_server.h"
 #include "query.h"
+#include "qrtn.h"
+
+#include <errno.h>
 #include <ctype.h>
+#include <stdlib.h>
 #include <string.h>
-#ifdef GDSS
-#include "gdss.h"
-#endif /* GDSS */
+
 EXEC SQL INCLUDE sqlca;
-#include "qrtn.h"
+
+RCSID("$Header$");
 
 extern char *whoami, *table_name[];
 extern int dbms_errno, mr_errcode;
@@ -31,8 +29,6 @@ EXEC SQL BEGIN DECLARE SECTION;
 extern char stmt_buf[];
 EXEC SQL END DECLARE SECTION;
 
-static void hex_dump(unsigned char *p);
-
 EXEC SQL WHENEVER SQLERROR DO dbmserr();
 
 
@@ -43,23 +39,25 @@ EXEC SQL WHENEVER SQLERROR DO dbmserr();
  * the table whose name field matches argv[0].
  */
 
-int set_modtime(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_modtime(struct query *q, char *argv[], client *cl)
 {
-    char *name, *entity, *table;
-    int who;
+  char *name, *entity, *table;
+  int who, row = 0;
+
+  entity = cl->entity;
+  who = cl->client_id;
+  table = table_name[q->rtable];
 
-    entity = cl->entity;
-    who = cl->client_id;
-    table = table_name[q->rtable];
-    name = argv[0];
+  if (q->type == MR_Q_UPDATE)
+    row = 1;
 
-    sprintf(stmt_buf,"UPDATE %s SET modtime = SYSDATE, modby = %d, modwith = '%s' WHERE name = '%s'",table,who,entity,name);
-    EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
+  name = argv[0 + row];
 
-    return(MR_SUCCESS);
+  sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
+         "modwith = '%s' WHERE name = '%s'", table, who, entity, name);
+  EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
+
+  return MR_SUCCESS;
 }
 
 /* generic set_modtime_by_id routine.  This takes the table id from
@@ -68,95 +66,84 @@ int set_modtime(q, argv, cl)
  * the table whose id matches argv[0].
  */
 
-int set_modtime_by_id(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_modtime_by_id(struct query *q, char *argv[], client *cl)
 {
-    char *entity, *table, *id_name;
-    int who, id;
-
-    entity = cl->entity;
-    who = cl->client_id;
-    table = table_name[q->rtable];
-    id_name = q->validate->object_id;
-
-    id = *(int *)argv[0];
-    sprintf(stmt_buf,"UPDATE %s SET modtime = SYSDATE, modby = %d, \
-modwith = '%s' WHERE %s = %d",table,who,entity,id_name,id);
-    EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
-    return(MR_SUCCESS);
+  char *entity, *table, *id_name;
+  int who, id;
+
+  entity = cl->entity;
+  who = cl->client_id;
+  table = table_name[q->rtable];
+  id_name = q->validate->object_id;
+
+  id = *(int *)argv[0];
+  sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
+         "modwith = '%s' WHERE %s = %d", table, who, entity, id_name, id);
+  EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
+  return MR_SUCCESS;
 }
 
 
 /* Sets the finger modtime on a user record.  The users_id will be in argv[0].
  */
 
-int set_finger_modtime(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_finger_modtime(struct query *q, char *argv[], client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    int users_id, who;
-    char *entity;
-    EXEC SQL END DECLARE SECTION;
+  EXEC SQL BEGIN DECLARE SECTION;
+  int users_id, who;
+  char *entity;
+  EXEC SQL END DECLARE SECTION;
 
-    entity = cl->entity;
-    who = cl->client_id;
-    users_id = *(int *)argv[0];
+  entity = cl->entity;
+  who = cl->client_id;
+  users_id = *(int *)argv[0];
 
-    EXEC SQL UPDATE users SET fmodtime=SYSDATE, fmodby = :who,
-      fmodwith = :entity WHERE users_id = :users_id;
+  EXEC SQL UPDATE users SET fmodtime = SYSDATE, fmodby = :who,
+    fmodwith = :entity WHERE users_id = :users_id;
 
-   return(MR_SUCCESS);
+  return MR_SUCCESS;
 }
 
 
 /* Sets the pobox modtime on a user record.  The users_id will be in argv[0].
  */
 
-int set_pobox_modtime(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_pobox_modtime(struct query *q, char *argv[], client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    int users_id, who;
-    char *entity;
-    EXEC SQL END DECLARE SECTION;
+  EXEC SQL BEGIN DECLARE SECTION;
+  int users_id, who;
+  char *entity;
+  EXEC SQL END DECLARE SECTION;
 
-    entity = cl->entity;
-    who = cl->client_id;
-    users_id = *(int *)argv[0];
+  entity = cl->entity;
+  who = cl->client_id;
+  users_id = *(int *)argv[0];
 
-    EXEC SQL UPDATE users SET pmodtime=SYSDATE, pmodby = :who,
-      pmodwith = :entity WHERE users_id = :users_id;
+  EXEC SQL UPDATE users SET pmodtime = SYSDATE, pmodby = :who,
+    pmodwith = :entity WHERE users_id = :users_id;
 
-    return(MR_SUCCESS);
+  return MR_SUCCESS;
 }
 
 
 /* Like set_modtime, but uppercases the name first.
  */
 
-int set_uppercase_modtime(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_uppercase_modtime(struct query *q, char *argv[], client *cl)
 {
-    char *name, *entity, *table;
-    int who;
+  char *name, *entity, *table;
+  int who;
 
-    entity = cl->entity;
-    who = cl->client_id;
-    table = table_name[q->rtable];
-    name = argv[0];
+  entity = cl->entity;
+  who = cl->client_id;
+  table = table_name[q->rtable];
+  name = argv[0];
 
-    sprintf(stmt_buf,"UPDATE %s SET modtime = SYSDATE, modby = %d, modwith = '%s' WHERE name = UPPER('%s')",table,who,entity,name);
-    EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
+  sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
+         "modwith = '%s' WHERE name = UPPER('%s')", table, who, entity, name);
+  EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
 
-    return(MR_SUCCESS);
+  return MR_SUCCESS;
 }
 
 
@@ -165,23 +152,20 @@ int set_uppercase_modtime(q, argv, cl)
  * operates on is "mcm", not "machine".
  */
 
-int set_mach_modtime_by_id(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_mach_modtime_by_id(struct query *q, char *argv[], client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    char *entity;
-    int who, id;
-    EXEC SQL END DECLARE SECTION;
-
-    entity = cl->entity;
-    who = cl->client_id;
-    id = *(int *)argv[0];
-    EXEC SQL UPDATE machine SET modtime=SYSDATE, modby = :who,
-      modwith = :entity WHERE mach_id = :id;
-
-    return(MR_SUCCESS);
+  EXEC SQL BEGIN DECLARE SECTION;
+  char *entity;
+  int who, id;
+  EXEC SQL END DECLARE SECTION;
+
+  entity = cl->entity;
+  who = cl->client_id;
+  id = *(int *)argv[0];
+  EXEC SQL UPDATE machine SET modtime = SYSDATE, modby = :who,
+    modwith = :entity WHERE mach_id = :id;
+
+  return MR_SUCCESS;
 }
 
 
@@ -190,23 +174,20 @@ int set_mach_modtime_by_id(q, argv, cl)
  * table that query operates on is "svc", not "cluster".
  */
 
-int set_cluster_modtime_by_id(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_cluster_modtime_by_id(struct query *q, char *argv[], client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    char *entity;
-    int who, id;
-    EXEC SQL END DECLARE SECTION;
-
-    entity = cl->entity;
-    who = cl->client_id;
-
-    id = *(int *)argv[0];
-    EXEC SQL UPDATE clusters SET modtime=SYSDATE, modby = :who,
-      modwith = :entity WHERE clu_id = :id;
-    return(MR_SUCCESS);
+  EXEC SQL BEGIN DECLARE SECTION;
+  char *entity;
+  int who, id;
+  EXEC SQL END DECLARE SECTION;
+
+  entity = cl->entity;
+  who = cl->client_id;
+
+  id = *(int *)argv[0];
+  EXEC SQL UPDATE clusters SET modtime = SYSDATE, modby = :who,
+    modwith = :entity WHERE clu_id = :id;
+  return MR_SUCCESS;
 }
 
 
@@ -214,25 +195,22 @@ int set_cluster_modtime_by_id(q, argv, cl)
  * and the mach_id is in argv[1].
  */
 
-int set_serverhost_modtime(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_serverhost_modtime(struct query *q, char *argv[], client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    char *entity, *serv;
-    int who, id;
-    EXEC SQL END DECLARE SECTION;
-
-    entity = cl->entity;
-    who = cl->client_id;
-
-    serv = argv[0];
-    id = *(int *)argv[1];
-    EXEC SQL UPDATE serverhosts
-      SET modtime = SYSDATE, modby = :who, modwith = :entity
-      WHERE service = :serv AND mach_id = :id;
-    return(MR_SUCCESS);
+  EXEC SQL BEGIN DECLARE SECTION;
+  char *entity, *serv;
+  int who, id;
+  EXEC SQL END DECLARE SECTION;
+
+  entity = cl->entity;
+  who = cl->client_id;
+
+  serv = argv[0];
+  id = *(int *)argv[1];
+  EXEC SQL UPDATE serverhosts
+    SET modtime = SYSDATE, modby = :who, modwith = :entity
+    WHERE service = :serv AND mach_id = :id;
+  return MR_SUCCESS;
 }
 
 
@@ -240,24 +218,21 @@ int set_serverhost_modtime(q, argv, cl)
  * directory name is in argv[1].
  */
 
-int set_nfsphys_modtime(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_nfsphys_modtime(struct query *q, char *argv[], client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    char *entity, *dir;
-    int who, id;
-    EXEC SQL END DECLARE SECTION;
-
-    entity = cl->entity;
-    who = cl->client_id;
-
-    id = *(int *)argv[0];
-    dir = argv[1];
-    EXEC SQL UPDATE nfsphys SET modtime = SYSDATE, modby = :who,
-      modwith = :entity WHERE dir = :dir AND mach_id = :id;
-    return(MR_SUCCESS);
+  EXEC SQL BEGIN DECLARE SECTION;
+  char *entity, *dir;
+  int who, id;
+  EXEC SQL END DECLARE SECTION;
+
+  entity = cl->entity;
+  who = cl->client_id;
+
+  id = *(int *)argv[0];
+  dir = argv[1];
+  EXEC SQL UPDATE nfsphys SET modtime = SYSDATE, modby = :who,
+    modwith = :entity WHERE dir = :dir AND mach_id = :id;
+  return MR_SUCCESS;
 }
 
 
@@ -265,29 +240,25 @@ int set_nfsphys_modtime(q, argv, cl)
  * label.
  */
 
-int set_filesys_modtime(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_filesys_modtime(struct query *q, char *argv[], client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    char *label, *entity;
-    int who;
-    extern int _var_phys_id;
-
-    EXEC SQL END DECLARE SECTION;
-
-    entity = cl->entity;
-    who = cl->client_id;
-
-    label = argv[0];
-    if (!strcmp(q->shortname, "ufil"))
-      label = argv[1];
-
-    EXEC SQL UPDATE filesys SET modtime = SYSDATE, modby = :who,
-        modwith = :entity, phys_id = :_var_phys_id
-      WHERE label = :label;
-    return(MR_SUCCESS);
+  EXEC SQL BEGIN DECLARE SECTION;
+  char *label, *entity;
+  int who;
+  extern int _var_phys_id;
+  EXEC SQL END DECLARE SECTION;
+
+  entity = cl->entity;
+  who = cl->client_id;
+
+  label = argv[0];
+  if (!strcmp(q->shortname, "ufil"))
+    label = argv[1];
+
+  EXEC SQL UPDATE filesys SET modtime = SYSDATE, modby = :who,
+    modwith = :entity, phys_id = :_var_phys_id
+    WHERE label = :label;
+  return MR_SUCCESS;
 }
 
 
@@ -295,585 +266,427 @@ int set_filesys_modtime(q, argv, cl)
  * name.
  */
 
-int set_zephyr_modtime(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int set_zephyr_modtime(struct query *q, char *argv[], client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    char *class, *entity;
-    int who;
-    EXEC SQL END DECLARE SECTION;
+  EXEC SQL BEGIN DECLARE SECTION;
+  char *class, *entity;
+  int who;
+  EXEC SQL END DECLARE SECTION;
 
-    entity = cl->entity;
-    who = cl->client_id;
+  entity = cl->entity;
+  who = cl->client_id;
 
-    class = argv[0];
+  class = argv[0];
 
-    EXEC SQL UPDATE zephyr SET modtime = SYSDATE, modby = :who,
-      modwith = :entity WHERE class = :class;
+  EXEC SQL UPDATE zephyr SET modtime = SYSDATE, modby = :who,
+    modwith = :entity WHERE class = :class;
 
-    return(MR_SUCCESS);
+  return MR_SUCCESS;
 }
 
-
-/* fixes the modby field.  This will be the second to last thing in the
- * argv, the argv length is determined from the query structure.  It is
- * passed as a pointer to an integer.  This will either turn it into a
- * username, or # + the users_id.
+/* sets the modtime on an entry in services table, where argv[0] contains
+ * the service name.
  */
-int followup_fix_modby(q, sq, v, action, actarg, cl)
-     struct query *q;
-     struct save_queue *sq;
-     struct validate *v;
-     int (*action)(), actarg;
-     client *cl;
+
+int set_service_modtime(struct query *q, char *argv[], client *cl)
 {
-    register int i, j;
-    char **argv;
-    int id, status;
-
-    i = q->vcnt - 2;
-    while (sq_get_data(sq, &argv)) {
-       id = atoi(argv[i]);
-       if (id > 0)
-         status = id_to_name(id, USERS_TABLE, &argv[i]);
-       else
-         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
-       if (status && status != MR_NO_MATCH)
-         return(status);
-       (*action)(q->vcnt, argv, actarg);
-       for (j = 0; j < q->vcnt; j++)
-         free(argv[j]);
-       free(argv);
-    }
-    sq_destroy(sq);
-    return(MR_SUCCESS);
-}
+  EXEC SQL BEGIN DECLARE SECTION;
+  char *service, *protocol, *entity;
+  int who;
+  EXEC SQL END DECLARE SECTION;
+
+  entity = cl->entity;
+  who = cl->client_id; 
+
+  service = argv[0];
+  protocol = argv[1];
 
+  EXEC SQL UPDATE services SET modtime = SYSDATE, modby = :who,
+    modwith = :entity WHERE name = :service AND protocol = :protocol;
 
-/* After retrieving a user account, fix the modby field and signature.
- * The modby field is the second to last thing in the
+  return MR_SUCCESS;
+}
+
+/* fixes the modby field.  This will be the second to last thing in the
  * argv, the argv length is determined from the query structure.  It is
  * passed as a pointer to an integer.  This will either turn it into a
- * username, or # + the users_id.  Only "gua*" queries have a signature,
- * these are ones with U_END return values.  "gub*" queries also use this
- * routine but don't have a signature.
+ * username, or # + the users_id.
  */
-int followup_guax(q, sq, v, action, actarg, cl)
-     struct query *q;
-     struct save_queue *sq;
-     struct validate *v;
-     int (*action)(), actarg;
-     client *cl;
+int followup_fix_modby(struct query *q, struct save_queue *sq,
+                      struct validate *v, int (*action)(int, char *[], void *),
+                      void *actarg, client *cl)
 {
-    register int i, j;
-    char **argv;
-#ifdef GDSS
-    unsigned char sigbuf[256];
-    char *kname;
-    SigInfo  si;
-    EXEC SQL BEGIN DECLARE SECTION; 
-    int timestamp, who, siglen;
-    char *login;
-    char rsig[256];
-    EXEC SQL VAR rsig IS STRING(256);
-    EXEC SQL END DECLARE SECTION; 
-#endif /* GDSS */
-    int id, status;
-
-    i = q->vcnt - 2;
-    while (sq_get_data(sq, &argv)) {
-       id = atoi(argv[i]);
-       if (id > 0)
-         status = id_to_name(id, USERS_TABLE, &argv[i]);
-       else
-         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
-       if (status && status != MR_NO_MATCH)
-         return(status);
-#ifdef GDSS
-       if (q->vcnt == U_END && strlen(argv[U_SIGNATURE])) {
-           login = strtrim(argv[U_NAME]);
-           EXEC SQL SELECT signature, sigdate, sigwho 
-             INTO :rsig, :timestamp, :who FROM users
-             WHERE login = :login;
-           if(dbms_errno) return mr_errcode;
-           kname = malloc(1);
-            status = id_to_name(who, STRINGS_TABLE, &kname);
-            si.timestamp = timestamp;
-           si.SigInfoVersion = 0; /* XXXXX this isn't used */
-           kname_parse(si.pname, si.pinst, si.prealm, kname);
-            free(kname);
-            si.rawsig = (unsigned char *)strsave(rsig);
-           if (log_flags & LOG_GDSS)
-             com_err(whoami, 0, "rawsig length = %d, sig=\"%s\"", strlen(si.rawsig), si.rawsig);
-           GDSS_Recompose(&si, sigbuf);
-           free(si.rawsig);
-           free(argv[U_SIGNATURE]);
-           argv[U_SIGNATURE] = strsave(sigbuf);
-           if (log_flags & LOG_GDSS)
-             com_err(whoami, 0, "generated signature length %d", strlen(sigbuf));
-       }
-#endif /* GDSS */
-       (*action)(q->vcnt, argv, actarg);
-       for (j = 0; j < q->vcnt; j++)
-         free(argv[j]);
-       free(argv);
+  int i, j;
+  char **argv;
+  int id, status;
+
+  i = q->vcnt - 2;
+  while (sq_get_data(sq, &argv))
+    {
+      id = atoi(argv[i]);
+      if (id > 0)
+       status = id_to_name(id, USERS_TABLE, &argv[i]);
+      else
+       status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
+      if (status && status != MR_NO_MATCH)
+       return status;
+      (*action)(q->vcnt, argv, actarg);
+      for (j = 0; j < q->vcnt; j++)
+       free(argv[j]);
+      free(argv);
     }
-    sq_destroy(sq);
-    return(MR_SUCCESS);
+  sq_destroy(sq);
+  return MR_SUCCESS;
 }
 
-
 /**
  ** followup_ausr - add finger and pobox entries, set_user_modtime
  **
  ** Inputs:
  **    argv[0] - login (add_user)
- **    argv[3] - last name
- **    argv[4] - first name
- **    argv[5] - middle name
+ **    argv[U_LAST] - last name
+ **    argv[U_FIRST] - first name
+ **    argv[U_MIDDLE] - middle name
  **
  **/
 
-int followup_ausr(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int followup_ausr(struct query *q, char *argv[], client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    int who, status;
-    char *login, *entity, *name;
-    char fullname[129];
-    EXEC SQL END DECLARE SECTION;
-#ifdef GDSS
-    char databuf[32], *kname_unparse();
-    EXEC SQL BEGIN DECLARE SECTION;
-    char rawsig[128];
-    int sigwho, timestamp;
-    EXEC SQL END DECLARE SECTION;
-    SigInfo si;
-#endif /* GDSS */
-
-    /* build fullname */
-    if (strlen(argv[4]) && strlen(argv[5]))
-       sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
-    else if (strlen(argv[4]))
-       sprintf(fullname, "%s %s", argv[4], argv[3]);
-    else
-       sprintf(fullname, "%s", argv[3]);
-
-#ifdef GDSS
-      if (q->vcnt == U_END && *argv[U_SIGNATURE]) {
-        sprintf(databuf, "%s:%s", argv[U_NAME], argv[U_MITID]);
-        /* skip bytes for timestamp & kname */
-        si.rawsig = (unsigned char *) rawsig;
-        status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE], &si);
-       if (strlen(rawsig) > mr_sig_length) {
-           com_err(whoami, 0, "GDSS signature would be truncated.");  /** untested **/
-           return(MR_INTERNAL);
-       }
-        if (status == 0) {
-            name = kname_unparse(si.pname, si.pinst, si.prealm);
-            status = name_to_id(name, STRINGS_TABLE, &sigwho);
-            if (status == MR_NO_MATCH) {
-             sigwho=add_string(name);
-            } else if (status)
-              return(status);
-            timestamp = si.timestamp;
-        } else {
-           if (log_flags & LOG_GDSS)
-             hex_dump(argv[U_SIGNATURE]);
-           return(gdss2et(status));
-       }
-      } else {
-        rawsig[0] = 0;
-        sigwho = 0;
-        timestamp = 0;
-      }
-#endif /* GDSS */
-
-    login = argv[0];
-    who = cl->client_id;
-    entity = cl->entity;
-
-    /* create finger entry, pobox & set modtime on user */
-#ifdef GDSS
-    EXEC SQL UPDATE users
-      SET modtime=SYSDATE, modby=:who, modwith = :entity,
-          fullname = NVL(:fullname,CHR(0)), affiliation = type,
-          signature = NVL(:rawsig,CHR(0)), sigdate = :timestamp,
-          sigwho = :sigwho, fmodtime=SYSDATE, fmodby = :who, 
-          fmodwith = :entity, potype='NONE', pmodtime=SYSDATE, 
-          pmodby = :who, pmodwith = :entity
-      WHERE login = :login;
-#else /* GDSS */
-    EXEC SQL UPDATE users
-      SET modtime=SYSDATE, modby=:who, modwith = :entity,
-          fullname = NVL(:fullname,CHR(0)), affiliation = type,
-          fmodtime=SYSDATE, fmodby = :who, fmodwith = :entity,
-          potype='NONE', pmodtime=SYSDATE, pmodby = :who, pmodwith = :entity
-      WHERE login = :login;
-#endif /* GDSS */
-
-    return(MR_SUCCESS);
+  EXEC SQL BEGIN DECLARE SECTION;
+  int who, status;
+  char *login, *entity, *name;
+  char fullname[USERS_FIRST_SIZE + USERS_MIDDLE_SIZE + USERS_LAST_SIZE];
+  EXEC SQL END DECLARE SECTION;
+
+  /* build fullname */
+  if (strlen(argv[U_FIRST]) && strlen(argv[U_MIDDLE]))
+    sprintf(fullname, "%s %s %s", argv[U_FIRST], argv[U_MIDDLE], 
+           argv[U_LAST]);
+  else if (strlen(argv[U_FIRST]))
+    sprintf(fullname, "%s %s", argv[U_FIRST], argv[U_LAST]);
+  else
+    sprintf(fullname, "%s", argv[U_LAST]);
+
+  login = argv[0];
+  who = cl->client_id;
+  entity = cl->entity;
+
+  /* create finger entry, pobox & set modtime on user */
+  EXEC SQL UPDATE users
+    SET modtime = SYSDATE, modby = :who, modwith = :entity,
+    fullname = NVL(:fullname, CHR(0)), affiliation = type,
+    fmodtime = SYSDATE, fmodby = :who, fmodwith = :entity,
+    potype = 'NONE', pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity
+    WHERE login = :login;
+
+  return MR_SUCCESS;
 }
 
+/* followup_gpob: fixes argv[2] and argv[3] based on the pobox type.
+ * Then completes the upcall to the user.
+ *
+ * argv[2] is the users_id on input and should be converted to the
+ * pobox name on output. argv[3] is empty on input and should be
+ * converted to an email address on output.
+ */
 
-/**
- ** followup_uuac - do signature, set_user_modtime
- **
- ** Inputs:
- **   argv[0] - login (add_user)
- **   argv[U_SIGNATURE] - sig
- **
- **/
-
-int followup_uuac(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
+                 int (*action)(int, char *[], void *), void *actarg,
+                 client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION; 
-    int who, status, id;
-    char *entity, *name;
-    EXEC SQL END DECLARE SECTION; 
-#ifdef GDSS
-    char databuf[32], *kname_unparse();
-    EXEC SQL BEGIN DECLARE SECTION; 
-    char rawsig[128];
-    char *login;
-    int sigwho, timestamp;
-    EXEC SQL END DECLARE SECTION; 
-    SigInfo si;
-#endif /* GDSS */
-    
-    id = *(int *)argv[0];
-    who = cl->client_id;
-    entity = cl->entity;
-    
-#ifdef GDSS
-    if (q->vcnt == U_MODTIME && *argv[U_SIGNATURE + 1]) {
-        login = malloc(1);
-        status = id_to_name(id, USERS_TABLE, &login);
-        sprintf(databuf, "%s:%s", login, argv[U_MITID+1]);
-        free(login);
-        /* skip bytes for timestamp & kname */
-        si.rawsig = (unsigned char *) rawsig;
-        status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE+1], &si);
-       if (strlen(rawsig) > mr_sig_length) {
-           com_err(whoami, 0, "GDSS signature would be truncated.");  /** untested **/
-           return(MR_INTERNAL);
+  char **argv;
+  char *ptype, *p;
+  int mid, sid, status, i;
+  EXEC SQL BEGIN DECLARE SECTION;
+  int users_id, pid, iid, bid, eid;
+  char mach[MACHINE_NAME_SIZE], fs[FILESYS_LABEL_SIZE];
+  char str[STRINGS_STRING_SIZE];
+  EXEC SQL END DECLARE SECTION;
+
+  /* for each row */
+  while (sq_get_data(sq, &argv))
+    {
+      mr_trim_args(4, argv);
+      ptype = argv[1];
+      users_id = atoi(argv[2]);
+
+      EXEC SQL SELECT pop_id, imap_id, box_id, exchange_id INTO :pid, :iid, :bid, :eid
+       FROM users WHERE users_id = :users_id;
+      if (sqlca.sqlcode)
+       return MR_USER;
+
+      if (ptype[0] == 'S')
+       {
+         /* SMTP or SPLIT */
+         EXEC SQL SELECT string INTO :str FROM strings
+           WHERE string_id = :bid;
+         if (sqlca.sqlcode)
+           return MR_STRING;
+
+         /* If SMTP, don't bother fetching IMAP and POP boxes. */
+         if (ptype[1] == 'M')
+           pid = iid = eid = 0;
        }
-        if (status == 0) {
-            name = kname_unparse(si.pname, si.pinst, si.prealm);
-            status = name_to_id(name, STRINGS_TABLE, &sigwho);
-            if (status == MR_NO_MATCH) {
-             sigwho=add_string(name);
-            } else if (status)
-              return(status);
-            timestamp = si.timestamp;
-        } else {
-           if (log_flags & LOG_GDSS)
-             hex_dump(argv[U_SIGNATURE+1]);
-           return(gdss2et(status));
+      if (iid)
+       {
+         /* IMAP, or SPLIT with IMAP */
+         EXEC SQL SELECT f.label, m.name INTO :fs, :mach
+           FROM filesys f, machine m
+           WHERE f.filsys_id = :iid AND f.mach_id = m.mach_id;
+         if (sqlca.sqlcode)
+           return MR_FILESYS;
+       }
+      if (pid)
+       {
+         /* POP, or SPLIT with POP */
+         EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
+           WHERE u.users_id = :users_id AND u.pop_id = m.mach_id;
+         if (sqlca.sqlcode)
+           return MR_MACHINE;
+       }
+      if (eid)
+       {
+         /* EXCHANGE, or SPLIT with EXCHANGE */
+         EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
+           WHERE u.users_id = :users_id AND u.exchange_id = m.mach_id;
+         if (sqlca.sqlcode)
+           return MR_MACHINE;
        }
-    } else {
-        rawsig[0] = 0;
-        sigwho = 0;
-        timestamp = 0;
-    }
-#endif /* GDSS */
-    /* create finger entry, pobox & set modtime on user */
-
-#ifdef GDSS
-    EXEC SQL UPDATE users SET modtime=SYSDATE, modby = :who, modwith = :entity,
-        signature = NVL(:rawsig,CHR(0)), sigdate = :timestamp, sigwho = :sigwho
-      WHERE users_id = :id;
-#else /* GDSS */
-    EXEC SQL UPDATE users SET modtime=SYSDATE, modby = :who, modwith = :entity
-      WHERE users_id = :id;
-#endif /* GDSS */
-    return(MR_SUCCESS);
-}
-/* followup_gpob: fixes argv[2] based on the IDs currently there and the
- * type in argv[1].  Then completes the upcall to the user.
- *
- * argv[2] is of the form "123:234" where the first integer is the machine
- * ID if it is a pop box, and the second is the string ID if it is an SMTP
- * box.  argv[1] should be "POP", "SMTP", or "NONE".  Boxes of type NONE
- * are skipped.
- */
 
-int followup_gpob(q, sq, v, action, actarg, cl)
-     struct query *q;
-     struct save_queue *sq;
-     struct validate *v;
-     int (*action)();
-     int actarg;
-     client *cl;
-{
-    char **argv;
-    char *ptype, *p;
-    int mid, sid, status, i;
-
-    /* for each row */
-    while (sq_get_data(sq, &argv)) {
-       mr_trim_args(2, argv);
-       ptype = argv[1];
-       p = strchr(argv[2], ':');
-       *p++ = 0;
-       mid = atoi(argv[2]);
-       sid = atoi(p);
-
-       if (!strcmp(ptype, "POP")) {
-           status = id_to_name(mid, MACHINE_TABLE, &argv[2]);
-           if (status == MR_NO_MATCH)
-             return(MR_MACHINE);
-       } else if (!strcmp(ptype, "SMTP")) {
-           status = id_to_name(sid, STRINGS_TABLE, &argv[2]);
-           if (status == MR_NO_MATCH)
-             return(MR_STRING);
-       } else /* ptype == "NONE" */ {
-           goto skip;
+      free(argv[2]);
+      free(argv[3]);
+
+      /* Now assemble the right answer. */
+      if (!strcmp(ptype, "POP") || !strcmp(ptype, "EXCHANGE"))
+       {
+         argv[2] = xstrdup(strtrim(mach));
+         argv[3] = xmalloc(strlen(argv[0]) + strlen(argv[2]) + 2);
+         sprintf(argv[3], "%s@%s", argv[0], argv[2]);
        }
-       if (status) return(status);
-
-       if (!strcmp(q->shortname, "gpob")) {
-           sid = atoi(argv[4]);
-           if (sid > 0)
-             status = id_to_name(sid, USERS_TABLE, &argv[4]);
-           else
-             status = id_to_name(-sid, STRINGS_TABLE, &argv[4]);
+      else if (!strcmp(ptype, "SMTP"))
+       {
+         argv[2] = xstrdup(strtrim(str));
+         argv[3] = xstrdup(str);
+       }
+      else if (!strcmp(ptype, "IMAP"))
+       {
+         argv[2] = xstrdup(strtrim(fs));
+         argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + 2);
+         sprintf(argv[3], "%s@%s", argv[0], mach);
+       }
+      else if (!strcmp(ptype, "SPLIT"))
+       {
+         argv[2] = xstrdup(strtrim(str));
+         argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) +
+                           strlen(str) + 4);
+         sprintf(argv[3], "%s@%s, %s", argv[0], mach, str);
+       }
+      else /* ptype == "NONE" */
+       goto skip;
+
+      if (!strcmp(q->shortname, "gpob"))
+       {
+         sid = atoi(argv[5]);
+         if (sid > 0)
+           status = id_to_name(sid, USERS_TABLE, &argv[5]);
+         else
+           status = id_to_name(-sid, STRINGS_TABLE, &argv[5]);
+         if (status && status != MR_NO_MATCH)
+           return status;
        }
-       if (status && status != MR_NO_MATCH) return(status);
 
-       (*action)(q->vcnt, argv, actarg);
+      (*action)(q->vcnt, argv, actarg);
     skip:
-       /* free saved data */
-       for (i = 0; i < q->vcnt; i++)
-           free(argv[i]);
-       free(argv);
+      /* free saved data */
+      for (i = 0; i < q->vcnt; i++)
+       free(argv[i]);
+      free(argv);
     }
 
-    sq_destroy(sq);
-    return (MR_SUCCESS);
+  sq_destroy(sq);
+  return MR_SUCCESS;
 }
 
+/* Fix an ace_name, based on its type. */
+
+static int fix_ace(char *type, char **name)
+{
+  int id = atoi(*name);
+
+  if (!strcmp(type, "LIST"))
+    return id_to_name(id, LIST_TABLE, name);
+  else if (!strcmp(type, "USER"))
+    return id_to_name(id, USERS_TABLE, name);
+  else if (!strcmp(type, "KERBEROS"))
+    return id_to_name(id, STRINGS_TABLE, name);
+  else
+    {
+      free(*name);
+      if (!strcmp(type, "NONE"))
+       *name = xstrdup("NONE");
+      else
+       *name = xstrdup("???");
+      return MR_SUCCESS;
+    }
+}
 
-/* followup_gsnt: fix the ace_name in argv[7].  argv[6] will contain the
- * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[7] into the
- * proper name based on the type, and repace that string in the argv.
- * Also fixes the modby field by called followup_fix_modby.
- */
 
-int followup_gsnt(q, sq, v, action, actarg, cl)
-     struct query *q;
-     struct save_queue *sq;
-     struct validate *v;
-     int (*action)(), actarg;
-     client *cl;
+/* followup_gsnt: fix the ace_name and modby */
+
+int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
+                 int (*action)(int, char *[], void *), void *actarg,
+                 client *cl)
 {
-    char **argv, *type;
-    int id, i, idx, status;
-
-    idx = 8;
-
-    while (sq_get_data(sq, &argv)) {
-       mr_trim_args(q->vcnt, argv);
-
-       id = atoi(argv[i = q->vcnt - 2]);
-       if (id > 0)
-         status = id_to_name(id, USERS_TABLE, &argv[i]);
-       else
-         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
-       if (status && status != MR_NO_MATCH)
-         return(status);
-
-       id = atoi(argv[idx]);
-       type = argv[idx - 1];
-
-       if (!strcmp(type, "LIST")) {
-           status = id_to_name(id, LIST_TABLE, &argv[idx]);
-       } else if (!strcmp(type, "USER")) {
-           status = id_to_name(id, USERS_TABLE, &argv[idx]);
-       } else if (!strcmp(type, "KERBEROS")) {
-           status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
-       } else if (!strcmp(type, "NONE")) {
-           status = 0;
-           free(argv[idx]);
-           argv[idx] = strsave("NONE");
-       } else {
-           status = 0;
-           free(argv[idx]);
-           argv[idx] = strsave("???");
-       }
-       if (status && status != MR_NO_MATCH)
-         return(status);
+  char **argv;
+  int status, idx;
 
-       /* send the data */
-       (*action)(q->vcnt, argv, actarg);
+  if (q->version < 8)
+    idx = 0;
+  else
+    idx = 3;
 
-       /* free saved data */
-       for (i = 0; i < q->vcnt; i++)
-           free(argv[i]);
-       free(argv);
+  while (sq_get_data(sq, &argv))
+    {
+      mr_trim_args(q->vcnt, argv);
+
+      status = fix_ace(argv[7 + idx], &argv[8 + idx]);
+      if (status && status != MR_NO_MATCH)
+       return status;
     }
 
-    sq_destroy(sq);
-    return (MR_SUCCESS);
+  return followup_fix_modby(q, sq, v, action, actarg, cl);
 }
 
 
-/* followup_ghst: fix the ace_name in argv[12].  argv[11] will contain the
- * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[12] into the
- * proper name based on the type, and repace that string in the argv.
- * Also fixes the modby field by called followup_fix_modby.
- */
+/* followup_ghst: fix the ace_name, strings and modby */
 
-int followup_ghst(q, sq, v, action, actarg, cl)
-     struct query *q;
-     struct save_queue *sq;
-     struct validate *v;
-     int (*action)(), actarg;
-     client *cl;
+int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
+                 int (*action)(int, char *[], void *), void *actarg,
+                 client *cl)
 {
-    char **argv, *type;
-    int id, i, idx, status;
-
-    while (sq_get_data(sq, &argv)) {
-       mr_trim_args(q->vcnt, argv);
-
-       id = atoi(argv[i = q->vcnt - 2]);
-       if (id > 0)
-         status = id_to_name(id, USERS_TABLE, &argv[i]);
-       else
-         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
-       if (status && status != MR_NO_MATCH)
-         return(status);
-
-       id = atoi(argv[13]);
-       status = id_to_name(id, STRINGS_TABLE, &argv[13]);
-       if (status) return(status);
-       id = atoi(argv[14]);
-       status = id_to_name(id, STRINGS_TABLE, &argv[14]);
-       if (status) return(status);
-       id = atoi(argv[16]);
-       if (id < 0)
-         status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
-       else
-         status = id_to_name(id, USERS_TABLE, &argv[16]);
-       if (status && status != MR_NO_MATCH)
-         return(status);
-
-       idx = 12;
-       id = atoi(argv[idx]);
-       type = strtrim(argv[idx - 1]);
-
-       if (!strcmp(type, "LIST")) {
-           status = id_to_name(id, LIST_TABLE, &argv[idx]);
-       } else if (!strcmp(type, "USER")) {
-           status = id_to_name(id, USERS_TABLE, &argv[idx]);
-       } else if (!strcmp(type, "KERBEROS")) {
-           status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
-       } else if (!strcmp(type, "NONE")) {
-           status = 0;
-           free(argv[idx]);
-           argv[idx] = strsave("NONE");
-       } else {
-           status = 0;
-           free(argv[idx]);
-           argv[idx] = strsave("???");
-       }
-       if (status && status != MR_NO_MATCH)
-         return(status);
-
-       /* send the data */
-       (*action)(q->vcnt, argv, actarg);
-
-       /* free saved data */
-       for (i = 0; i < q->vcnt; i++)
-           free(argv[i]);
-       free(argv);
+  char **argv;
+  int id, status, idx;
+
+  if (q->version < 6)
+    idx = 0;
+  else if (q->version >= 6 && q->version < 8)
+    idx = 1;
+  else
+    idx = 2;
+
+  while (sq_get_data(sq, &argv))
+    {
+      mr_trim_args(q->vcnt, argv);
+
+      id = atoi(argv[13 + idx]);
+      status = id_to_name(id, STRINGS_TABLE, &argv[13 + idx]);
+      if (status)
+       return status;
+      id = atoi(argv[14 + idx]);
+      status = id_to_name(id, STRINGS_TABLE, &argv[14 + idx]);
+      if (status)
+       return status;
+      id = atoi(argv[16 + idx]);
+      if (id < 0)
+       status = id_to_name(-id, STRINGS_TABLE, &argv[16 + idx]);
+      else
+       status = id_to_name(id, USERS_TABLE, &argv[16 + idx]);
+      if (status && status != MR_NO_MATCH)
+       return status;
+
+      status = fix_ace(argv[11 + idx], &argv[12 + idx]);
+      if (status && status != MR_NO_MATCH)
+       return status;
     }
 
-    sq_destroy(sq);
-    return (MR_SUCCESS);
+  return followup_fix_modby(q, sq, v, action, actarg, cl);
 }
 
 
-/* followup_glin: fix the ace_name in argv[8].  argv[7] will contain the
- * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[8] into the
- * proper name based on the type, and repace that string in the argv.
- * Also fixes the modby field by called followup_fix_modby.
- */
+/* followup_glin: fix the ace_name, modace_name, expiration, and modby */
 
-int followup_glin(q, sq, v, action, actarg, cl)
-     struct query *q;
-     struct save_queue *sq;
-     struct validate *v;
-     int (*action)(), actarg;
-     client *cl;
+int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
+                 int (*action)(int, char *[], void *), void *actarg,
+                 client *cl)
 {
-    char **argv, *type;
-    int id, i, idx, status;
-
-    idx = 8;
-    if (!strcmp(q->shortname, "gsin"))
-      idx = 12;
-
-    while (sq_get_data(sq, &argv)) {
-       mr_trim_args(q->vcnt, argv);
-
-       id = atoi(argv[i = q->vcnt - 2]);
-       if (id > 0)
-         status = id_to_name(id, USERS_TABLE, &argv[i]);
-       else
-         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
-       if (status && status != MR_NO_MATCH)
-         return(status);
-
-       id = atoi(argv[idx]);
-       type = argv[idx - 1];
-
-       if (!strcmp(type, "LIST")) {
-           status = id_to_name(id, LIST_TABLE, &argv[idx]);
-       } else if (!strcmp(type, "USER")) {
-           status = id_to_name(id, USERS_TABLE, &argv[idx]);
-       } else if (!strcmp(type, "KERBEROS")) {
-           status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
-       } else if (!strcmp(type, "NONE")) {
-           status = 0;
-           free(argv[idx]);
-           argv[idx] = strsave("NONE");
-       } else {
-           status = 0;
-           free(argv[idx]);
-           argv[idx] = strsave("???");
+  char **argv;
+  int status;
+
+  while (sq_get_data(sq, &argv))
+    {
+      mr_trim_args(q->vcnt, argv);
+
+      if (q->version == 2)
+       status = fix_ace(argv[7], &argv[8]);
+      else if (q->version > 2 && q->version < 10)
+       status = fix_ace(argv[8], &argv[9]);
+      else
+       status = fix_ace(argv[10], &argv[11]);
+
+      if (status && status != MR_NO_MATCH)
+       return status;
+
+      if (q->version > 3)
+       {
+         if (q->version < 10)
+           status = fix_ace(argv[10], &argv[11]);
+         else if (q->version >= 10)
+           status = fix_ace(argv[12], &argv[13]); 
+      
+         if (status && status != MR_NO_MATCH)
+           return status;
        }
-       if (status && status != MR_NO_MATCH)
-         return(status);
 
-       if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) {
-           argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
-           strcpy(argv[6], UNIQUE_GID);
+      if (atoi(argv[6]) == -1)
+       {
+         argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
+         strcpy(argv[6], UNIQUE_GID);
        }
+    }
 
-       /* send the data */
-       (*action)(q->vcnt, argv, actarg);
+  return followup_fix_modby(q, sq, v, action, actarg, cl);
+}
+
+/* followup_gsin: fix the ace_name and modby. */
+int followup_gsin(struct query *q, struct save_queue *sq, struct validate *v,
+                 int (*action)(int, char *[], void *), void *actarg,
+                 client *cl)
+{
+  char **argv;
+  int status;
 
-       /* free saved data */
-       for (i = 0; i < q->vcnt; i++)
-           free(argv[i]);
-       free(argv);
+  while (sq_get_data(sq, &argv))
+    {
+      mr_trim_args(q->vcnt, argv);
+
+      status = fix_ace(argv[11], &argv[12]);
+      if (status && status != MR_NO_MATCH)
+       return status;
     }
 
-    sq_destroy(sq);
-    return (MR_SUCCESS);
+  return followup_fix_modby(q, sq, v, action, actarg, cl);
 }
 
+int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
+                 int (*action)(int, char *[], void *), void *actarg,
+                 client *cl)
+{
+  char **argv;
+  int status;
+
+  while (sq_get_data(sq, &argv))
+    {
+      mr_trim_args(q->vcnt, argv);
+
+      status = fix_ace(argv[PRINTSERVER_OWNER_TYPE],
+                      &argv[PRINTSERVER_OWNER_NAME]);
+      if (status && status != MR_NO_MATCH)
+       return status;
+    }
+
+  return followup_fix_modby(q, sq, v, action, actarg, cl);
+}
+  
 
 /* followup_gqot: Fix the entity name, directory name & modby fields
  *   argv[0] = filsys_id
@@ -882,76 +695,80 @@ int followup_glin(q, sq, v, action, actarg, cl)
  *   argv[3] = ascii(quota)
  */
 
-int followup_gqot(q, sq, v, action, actarg, cl)
-     struct query *q;
-     struct save_queue *sq;
-     struct validate *v;
-     int (*action)(), actarg;
-     client *cl;
+int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
+                 int (*action)(int, char *[], void *), void *actarg,
+                 client *cl)
 {
-    register int j;
-    char **argv;
-    EXEC SQL BEGIN DECLARE SECTION;
-    int id;
-    char *name, *label;
-    EXEC SQL END DECLARE SECTION;
-    int status, idx;
-
-    if (!strcmp(q->name, "get_quota") ||
-       !strcmp(q->name, "get_quota_by_filesys"))
-      idx = 4;
-    else
-      idx = 3;
-    while (sq_get_data(sq, &argv)) {
-       if (idx == 4) {
-           switch (argv[1][0]) {
+  int j;
+  char **argv;
+  EXEC SQL BEGIN DECLARE SECTION;
+  int id;
+  char *name, *label;
+  EXEC SQL END DECLARE SECTION;
+  int status, idx;
+
+  if (!strcmp(q->name, "get_quota") ||
+      !strcmp(q->name, "get_quota_by_filesys"))
+    idx = 4;
+  else
+    idx = 3;
+
+  while (sq_get_data(sq, &argv))
+    {
+      if (idx == 4)
+       {
+         switch (argv[1][0])
+           {
            case 'U':
-               status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
-               break;
+             status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
+             break;
            case 'G':
            case 'L':
-               status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
-               break;
+             status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
+             break;
            case 'A':
-               free(argv[2]);
-               argv[2] = strsave("system:anyuser");
-               break;
+             free(argv[2]);
+             argv[2] = xstrdup("system:anyuser");
+             break;
            default:
-               id = atoi(argv[2]);
-               argv[2] = malloc(8);
-               sprintf(argv[2], "%d", id);
+             id = atoi(argv[2]);
+             argv[2] = xmalloc(8);
+             sprintf(argv[2], "%d", id);
            }
        }
-       id = atoi(argv[idx]);
-       free(argv[idx]);
-       argv[idx] = malloc(256);
-       name = argv[idx];
-       if (id == 0) {
-           label = argv[0];
-           EXEC SQL SELECT name INTO :name FROM filesys
-             WHERE label = :label;
-       } else {
-           EXEC SQL SELECT dir INTO :name FROM nfsphys
-             WHERE nfsphys_id = :id;
+      id = atoi(argv[idx]);
+      free(argv[idx]);
+      argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
+      name = argv[idx];
+      name[0] = '\0';
+      if (id == 0)
+       {
+         label = argv[0];
+         EXEC SQL SELECT name INTO :name FROM filesys
+           WHERE label = :label;
        }
-       if (sqlca.sqlerrd[2] != 1) {
-           sprintf(argv[idx], "#%d", id);
+      else
+       {
+         EXEC SQL SELECT dir INTO :name FROM nfsphys
+           WHERE nfsphys_id = :id;
        }
-
-       id = atoi(argv[idx+3]);
-       if (id > 0)
-         status = id_to_name(id, USERS_TABLE, &argv[idx+3]);
-       else
-         status = id_to_name(-id, STRINGS_TABLE, &argv[idx+3]);
-       if (status && status != MR_NO_MATCH)
-         return(status);
-       (*action)(q->vcnt, argv, actarg);
-       for (j = 0; j < q->vcnt; j++)
-         free(argv[j]);
-       free(argv);
+      if (sqlca.sqlerrd[2] != 1)
+       sprintf(argv[idx], "#%d", id);
+
+      id = atoi(argv[idx + 3]);
+      if (id > 0)
+       status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
+      else
+       status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
+      if (status && status != MR_NO_MATCH)
+       return status;
+      (*action)(q->vcnt, argv, actarg);
+      for (j = 0; j < q->vcnt; j++)
+       free(argv[j]);
+      free(argv);
     }
-    sq_destroy(sq);
-    return(MR_SUCCESS);
+  sq_destroy(sq);
+  return MR_SUCCESS;
 }
 
 
@@ -962,337 +779,296 @@ int followup_gqot(q, sq, v, action, actarg, cl)
  *   argv[3 or 2] = ascii(quota)
  */
 
-int followup_aqot(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int followup_aqot(struct query *q, char *argv[], client *cl)
 {
-    EXEC SQL BEGIN DECLARE SECTION;
-    int quota, id, fs, who, physid, table;
-    char *entity, *qtype, *tname;
-    EXEC SQL END DECLARE SECTION;
-    char incr_qual[60];
-    char *incr_argv[2];
-    int status;
-
-    table=q->rtable;
-    tname=table_name[table];
-    fs = *(int *)argv[0];
-    EXEC SQL SELECT phys_id INTO :physid FROM filesys
-      WHERE filsys_id = :fs;
-    if(dbms_errno)
-       return(mr_errcode);
-
-    if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot")) {
-       qtype = argv[1];
-       id = *(int *)argv[2];
-       quota = atoi(argv[3]);
-       sprintf(incr_qual,"q.filsys_id = %d",fs);
-    } else {
-       qtype = "USER";
-       id = *(int *)argv[1];
-       quota = atoi(argv[2]);
-       sprintf(incr_qual,"q.filsys_id=%d AND q.type='%s' AND q.entity_id=%d",
-               fs,qtype,id);
+  EXEC SQL BEGIN DECLARE SECTION;
+  int quota, id, fs, who, physid, table;
+  char *entity, *qtype, *tname;
+  EXEC SQL END DECLARE SECTION;
+  char incr_qual[60];
+  char *incr_argv[2];
+  int status;
+
+  table = q->rtable;
+  tname = table_name[table];
+  fs = *(int *)argv[0];
+  EXEC SQL SELECT phys_id INTO :physid FROM filesys
+    WHERE filsys_id = :fs;
+  if (dbms_errno)
+    return mr_errcode;
+
+  if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
+    {
+      qtype = argv[1];
+      id = *(int *)argv[2];
+      quota = atoi(argv[3]);
+      sprintf(incr_qual, "q.filsys_id = %d", fs);
+    }
+  else
+    {
+      qtype = "USER";
+      id = *(int *)argv[1];
+      quota = atoi(argv[2]);
+      sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
+             "q.entity_id = %d", fs, qtype, id);
     }
 
-    /* quota case of incremental_{before|after} only looks at slot 1 */
-    incr_argv[1]=qtype;
-
-    /* Follows one of many possible gross hacks to fix these particular
-     * conflicts between what is possible in the query table and what 
-     * is possible in SQL.    
-     */
-    if(q->type==APPEND) {
-       incremental_clear_before();
-       EXEC SQL INSERT INTO quota 
-           (filsys_id, type, entity_id, quota, phys_id) 
-         VALUES (:fs, NVL(:qtype,CHR(0)), :id, :quota, :physid);
-       incremental_after(table, incr_qual, incr_argv);    
-    } else {
-       incremental_before(table, incr_qual, incr_argv);
-       EXEC SQL UPDATE quota SET quota = :quota
-         WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
-       status = mr_errcode;
-       incremental_after(table, incr_qual, incr_argv);
+  /* quota case of incremental_{before|after} only looks at slot 1 */
+  incr_argv[1] = qtype;
+
+  /* Follows one of many possible gross hacks to fix these particular
+   * conflicts between what is possible in the query table and what
+   * is possible in SQL.
+   */
+  if (q->type == MR_Q_APPEND)
+    {
+      incremental_clear_before();
+      EXEC SQL INSERT INTO quota
+       (filsys_id, type, entity_id, quota, phys_id)
+       VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
+      incremental_after(table, incr_qual, incr_argv);
+    }
+  else
+    {
+      incremental_before(table, incr_qual, incr_argv);
+      EXEC SQL UPDATE quota SET quota = :quota
+       WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
+      status = mr_errcode;
+      incremental_after(table, incr_qual, incr_argv);
     }
 
-    if (dbms_errno)
-       return(mr_errcode);
-    flush_name(argv[0], table);  
-    if(q->type==APPEND) {
-        EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
-         WHERE table_name = :tname;
-    } else {
-        EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
-         WHERE table_name = :tname;
+  if (dbms_errno)
+    return mr_errcode;
+  if (q->type == MR_Q_APPEND)
+    {
+      EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
+       WHERE table_name = :tname;
     }
-       
-    /* Proceed with original followup */
-    who = cl->client_id;
-    entity = cl->entity;
-
-    EXEC SQL UPDATE quota
-      SET modtime = SYSDATE, modby = :who, modwith = :entity
-      WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
-    EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
-      WHERE nfsphys_id = :physid;
-    if (dbms_errno) return(mr_errcode);
-    return(MR_SUCCESS);
+  else
+    {
+      EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
+       WHERE table_name = :tname;
+    }
+
+  /* Proceed with original followup */
+  who = cl->client_id;
+  entity = cl->entity;
+
+  EXEC SQL UPDATE quota
+    SET modtime = SYSDATE, modby = :who, modwith = :entity
+    WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
+  EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
+    WHERE nfsphys_id = :physid;
+  if (dbms_errno)
+    return mr_errcode;
+  return MR_SUCCESS;
 }
 
 
 /* Necessitated by the requirement of a correlation name by the incremental
- * routines, since query table deletes don't provide one. 
+ * routines, since query table deletes don't provide one.
  */
-int followup_dqot(q, argv, cl)
-     struct query *q;
-     char **argv;
-     client *cl;
+int followup_dqot(struct query *q, char **argv, client *cl)
 {
-    char *qtype;
-    int id, fs, table;
-    char *incr_argv[2];
-    EXEC SQL BEGIN DECLARE SECTION; 
-    char incr_qual[80], *tname;
-    EXEC SQL END DECLARE SECTION; 
-
-    table=q->rtable;
-    tname=table_name[table];
-    fs = *(int *)argv[0];
-    if (!strcmp(q->shortname, "dqot")) {
-       qtype = argv[1];
-       id = *(int *)argv[2];
-    } else {
-       qtype = "USER";
-       id = *(int *)argv[1];
+  char *qtype;
+  int id, fs, table;
+  char *incr_argv[2];
+  EXEC SQL BEGIN DECLARE SECTION;
+  char incr_qual[80], *tname;
+  EXEC SQL END DECLARE SECTION;
+
+  table = q->rtable;
+  tname = table_name[table];
+  fs = *(int *)argv[0];
+  if (!strcmp(q->shortname, "dqot"))
+    {
+      qtype = argv[1];
+      id = *(int *)argv[2];
+    }
+  else
+    {
+      qtype = "USER";
+      id = *(int *)argv[1];
     }
-    sprintf(incr_qual,"q.filsys_id=%d AND q.type='%s' AND q.entity_id=%d",
-           fs,qtype,id);
+  sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
+         fs, qtype, id);
 
-    /* quota case of incremental_{before|after} only looks at slot 1 */
-    incr_argv[1]=qtype;
+  /* quota case of incremental_{before|after} only looks at slot 1 */
+  incr_argv[1] = qtype;
 
-    incremental_before(table, incr_qual, incr_argv);
-    EXEC SQL DELETE FROM quota q WHERE q.filsys_id=:fs AND q.type=:qtype
-      AND q.entity_id=:id;
-    incremental_clear_after();
+  incremental_before(table, incr_qual, incr_argv);
+  EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
+    AND q.entity_id = :id;
+  incremental_clear_after();
 
-    if (dbms_errno) 
-       return(mr_errcode);
-    flush_name(argv[0], table);
+  if (dbms_errno)
+    return mr_errcode;
 
-    EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
-      WHERE table_name = :tname;
-    return(MR_SUCCESS);
+  EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
+    WHERE table_name = :tname;
+  return MR_SUCCESS;
 }
 
+/* followup_gzcl:
+ */
 
-int followup_gpce(q, sq, v, action, actarg, cl)
-     struct query *q;
-     struct save_queue *sq;
-     struct validate *v;
-     int (*action)(), actarg;
-     client *cl;
+int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
+                 int (*action)(int, char *[], void *), void *actarg,
+                 client *cl)
 {
-    register int i, j;
-    char **argv;
-    int id, status;
-
-    i = q->vcnt - 2;
-    while (sq_get_data(sq, &argv)) {
-       id = atoi(argv[PCAP_QSERVER]);
-       status = id_to_name(id, MACHINE_TABLE, &argv[PCAP_QSERVER]);
-       if (status) return (status);
-       id = atoi(argv[i]);
-       if (id > 0)
-         status = id_to_name(id, USERS_TABLE, &argv[i]);
-       else
-         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
-       if (status && status != MR_NO_MATCH)
-         return(status);
-       (*action)(q->vcnt, argv, actarg);
-       for (j = 0; j < q->vcnt; j++)
-         free(argv[j]);
-       free(argv);
+  int i, n, status;
+  char **argv;
+
+  if (q->version < 5)
+    n = 8;
+  else
+    n = 10;
+
+  while (sq_get_data(sq, &argv))
+    {
+      mr_trim_args(q->vcnt, argv);
+
+      for (i = 1; i < n; i += 2)
+       {
+         status = fix_ace(argv[i], &argv[i + 1]);
+         if (status && status != MR_NO_MATCH)
+           return status;
+       }
     }
-    sq_destroy(sq);
-    return(MR_SUCCESS);
+
+  return followup_fix_modby(q, sq, v, action, actarg, cl);
 }
 
 
-/* followup_gzcl:
+/* followup_gsha:
  */
 
-int followup_gzcl(q, sq, v, action, actarg, cl)
-     struct query *q;
-     struct save_queue *sq;
-     struct validate *v;
-     int (*action)(), actarg;
-     client *cl;
+int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
+                 int (*action)(int, char *[], void *), void *actarg,
+                 client *cl)
 {
-    int id, i, status;
-    char **argv;
-
-    while (sq_get_data(sq, &argv)) {
-       mr_trim_args(q->vcnt, argv);
-
-       id = atoi(argv[i = q->vcnt - 2]);
-       if (id > 0)
-         status = id_to_name(id, USERS_TABLE, &argv[i]);
-       else
-         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
-       if (status && status != MR_NO_MATCH)
-         return(status);
-
-       for (i = 1; i < 8; i+=2) {
-           id = atoi(argv[i+1]);
-           if (!strcmp(argv[i], "LIST")) {
-               status = id_to_name(id, LIST_TABLE, &argv[i+1]);
-           } else if (!strcmp(argv[i], "USER")) {
-               status = id_to_name(id, USERS_TABLE, &argv[i+1]);
-           } else if (!strcmp(argv[i], "KERBEROS")) {
-               status = id_to_name(id, STRINGS_TABLE, &argv[i+1]);
-           } else if (!strcmp(argv[i], "NONE")) {
-               status = 0;
-               free(argv[i+1]);
-               argv[i+1] = strsave("NONE");
-           } else {
-               status = 0;
-               free(argv[i+1]);
-               argv[i+1] = strsave("???");
-           }
-           if (status && status != MR_NO_MATCH)
-             return(status);
-       }
+  char **argv;
+  int status;
 
-       /* send the data */
-       (*action)(q->vcnt, argv, actarg);
+  while (sq_get_data(sq, &argv))
+    {
+      mr_trim_args(q->vcnt, argv);
 
-       /* free saved data */
-       for (i = 0; i < q->vcnt; i++)
-           free(argv[i]);
-       free(argv);
+      status = fix_ace(argv[1], &argv[2]);
+      if (status && status != MR_NO_MATCH)
+       return status;
     }
-    sq_destroy(sq);
-    return(MR_SUCCESS);
+
+  return followup_fix_modby(q, sq, v, action, actarg, cl);
 }
 
 
-/* followup_gsha:
- */
+int _sdl_followup(struct query *q, char *argv[], client *cl)
+{
+  if (atoi(argv[0]))
+    EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
+  else
+    EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
+
+  return MR_SUCCESS;
+}
+
 
-int followup_gsha(q, sq, v, action, actarg, cl)
-     struct query *q;
-     struct save_queue *sq;
-     struct validate *v;
-     int (*action)(), actarg;
-     client *cl;
+int trigger_dcm(struct query *q, char *argv[], client *cl)
 {
-    char **argv;
-    int i, id, status;
-
-    while (sq_get_data(sq, &argv)) {
-       mr_trim_args(q->vcnt, argv);
-
-       id = atoi(argv[4]);
-       if (id > 0)
-         status = id_to_name(id, USERS_TABLE, &argv[4]);
-       else
-         status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
-       if (status && status != MR_NO_MATCH)
-         return(status);
-
-       id = atoi(argv[2]);
-       if (!strcmp(argv[1], "LIST")) {
-           status = id_to_name(id, LIST_TABLE, &argv[2]);
-       } else if (!strcmp(argv[1], "USER")) {
-           status = id_to_name(id, USERS_TABLE, &argv[2]);
-       } else if (!strcmp(argv[1], "KERBEROS")) {
-           status = id_to_name(id, STRINGS_TABLE, &argv[2]);
-       } else if (!strcmp(argv[1], "NONE")) {
-           status = 0;
-           free(argv[2]);
-           argv[2] = strsave("NONE");
-       } else {
-           status = 0;
-           free(argv[2]);
-           argv[2] = strsave("???");
-       }
-       if (status && status != MR_NO_MATCH)
-         return(status);
+  pid_t pid;
+  char prog[MAXPATHLEN];
+
+  sprintf(prog, "%s/startdcm", BIN_DIR);
+  pid = vfork();
+  switch (pid)
+    {
+    case 0:
+      execl(prog, "startdcm", 0);
+      exit(1);
 
-       /* send the data */
-       (*action)(q->vcnt, argv, actarg);
+    case -1:
+      return errno;
 
-       /* free saved data */
-       for (i = 0; i < q->vcnt; i++)
-           free(argv[i]);
-       free(argv);
+    default:
+      return MR_SUCCESS;
     }
-    sq_destroy(sq);
-    return(MR_SUCCESS);
 }
 
+/* followup_gcon: fix the ace_name, memace_name, and modby */
 
-int _sdl_followup(q, argv, cl)
-     struct query *q;
-     char *argv[];
-     client *cl;
+int followup_gcon(struct query *q, struct save_queue *sq, struct validate *v,
+                 int (*action)(int, char *[], void *), void *actarg,
+                 client *cl)
 {
-    int i;
-    i = atoi(argv[0]);
-    log_flags = i;
-#ifdef INGRES
-    if (i & LOG_SQL) {
-       EXEC SQL set printqry;
-    } else {
-       EXEC SQL set noprintqry;
-    }
-#endif
-    return(MR_SUCCESS);
+  char **argv;
+  int status, idx = 0;
+
+  if (q->version >= 9)
+    idx = 1;
+
+  while (sq_get_data(sq, &argv))
+  {
+    mr_trim_args(q->vcnt, argv);
+
+    status = fix_ace(argv[4 + idx], &argv[5 + idx]);
+    if (status && status != MR_NO_MATCH)
+           return status;
+      
+         status = fix_ace(argv[6 + idx], &argv[7 + idx]);
+         if (status && status != MR_NO_MATCH)
+           return status;
+       }
+
+  return followup_fix_modby(q, sq, v, action, actarg, cl);
 }
 
+/* followup_get_user:  fix the modby and creator.
+ * This assumes that the modby and creator fields are always 
+ * in the same relative position in the argv.
+ */
 
-static void hex_dump(p)
-     unsigned char *p;
+int followup_get_user(struct query *q, struct save_queue *sq, struct 
+                     validate *v, int (*action)(int, char *[], void *),
+                     void *actarg, client *cl)
 {
-    fprintf(stderr, "Size: %d\n", strlen(p));
-    while (strlen(p) >= 8) {
-       fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
-               p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
-       p += 8;
-    }
-    switch (strlen(p)) {
-    case 7:
-       fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x\n",
-               p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
-       break;
-    case 6:
-       fprintf(stderr, "%02x %02x %02x %02x %02x %02x\n",
-               p[0], p[1], p[2], p[3], p[4], p[5]);
-       break;
-    case 5:
-       fprintf(stderr, "%02x %02x %02x %02x %02x\n",
-               p[0], p[1], p[2], p[3], p[4]);
-       break;
-    case 4:
-       fprintf(stderr, "%02x %02x %02x %02x\n",
-               p[0], p[1], p[2], p[3]);
-       break;
-    case 3:
-       fprintf(stderr, "%02x %02x %02x\n",
-               p[0], p[1], p[2]);
-       break;
-    case 2:
-       fprintf(stderr, "%02x %02x\n",
-               p[0], p[1]);
-       break;
-    case 1:
-       fprintf(stderr, "%02x\n",
-               p[0]);
-       break;
-    default:
-       return;
+  char **argv;
+  int i, j, k, status, id;
+
+  i = q->vcnt - 4;
+  j = q->vcnt - 1;
+  while (sq_get_data(sq, &argv))
+    {
+      mr_trim_args(q->vcnt, argv);
+
+      id = atoi(argv[i]);
+      if (id > 0)
+       status = id_to_name(id, USERS_TABLE, &argv[i]);
+      else
+       status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
+      if (status && status != MR_NO_MATCH)
+       return status;
+
+      id = atoi(argv[j]);
+      if (id > 0)
+       status = id_to_name(id, USERS_TABLE, &argv[j]);
+      else
+       status = id_to_name(-id, STRINGS_TABLE, &argv[j]);
+      if (status && status != MR_NO_MATCH)
+       return status;
+
+      if (q->version > 11)
+       {
+         status = fix_ace(argv[15], &argv[16]);
+         if (status && status != MR_NO_MATCH)
+           return status;
+       }
+
+      (*action)(q->vcnt, argv, actarg);
+      for (k = 0; k < q->vcnt; k++)
+       free(argv[k]);
+      free(argv);
     }
+  sq_destroy(sq);
+  return MR_SUCCESS;
 }
This page took 0.119123 seconds and 4 git commands to generate.