]> andersk Git - moira.git/blobdiff - server/qsupport.qc
punt unused function followup_amtl; have add_member_to_list and
[moira.git] / server / qsupport.qc
index 0aba3b1fff843a3d1459d3166a270bdb28ff70b6..c300eb2977236f9eaf5b2bbc9caae9bee3d00b96 100644 (file)
@@ -20,6 +20,7 @@ static char *rcsid_qsupport_qc = "$Header$";
 
 
 extern char *whoami, *strsave();
+extern int ingres_errno, sms_errcode;
 
 
 /* Specialized Access Routines */
@@ -57,6 +58,7 @@ access_login(q, argv, cl)
 ##  char qual[256];
 
     build_qual(q->qual, q->argc, argv, qual);
+##  range of u is users
 ##  retrieve (id = u.users_id) where qual
 ##  inquire_equel(rowcount = "rowcount")
     if (rowcount != 1 || id != cl->users_id)
@@ -103,8 +105,9 @@ access_list(q, argv, cl)
        return(status);
 
     /* if amtl or dmfl and list is public allow client to add or delete self */
-    if ((!strcmp("amtl", q->shortname) || !strcmp("dmfl", q->shortname)) &&
-       (flags && !strcmp("USER", argv[1]))) {
+    if (((!strcmp("amtl", q->shortname) && flags) ||
+        (!strcmp("dmfl", q->shortname))) &&
+       (!strcmp("USER", argv[1]))) {
        if (*(int *)argv[2] == client_id) return(SMS_SUCCESS);
     /* if update_list, don't allow them to change the GID */
     } else if (!strcmp("ulis", q->shortname)) {
@@ -147,6 +150,7 @@ access_visible_list(q, argv, cl)
     if (!flags)
        return(SMS_SUCCESS);
 
+
     /* parse client structure */
     if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
        return(status);
@@ -296,11 +300,12 @@ access_filesys(q, argv, cl)
     if (users_id == cl->users_id)
       return(SMS_SUCCESS);
     if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
-       return(status);
+      return(status);
     status = find_member("LIST", list_id, client_type, client_id, 0);
     if (status)
       return(SMS_SUCCESS);
-    return(SMS_PERM);
+    else
+      return(SMS_PERM);
 ##}
 
     
@@ -357,12 +362,13 @@ int setup_dusr(q, argv)
 
     /* For now, only allow users to be deleted if their status is 0 */
 ##  repeat retrieve (flag = u.status) where u.users_id = @id
-    if (flag != 0)
+    if (flag != 0 && flag != 4)
       return(SMS_IN_USE);
 
 ##  repeat delete nfsquota where nfsquota.users_id = @id
-##  repeat retrieve (flag = any(members.member_id where members.member_id=@id
-##                      and members.member_type = "USER"))
+##  repeat delete krbmap where krbmap.users_id = @id
+##  repeat retrieve (flag = any(imembers.member_id where imembers.member_id=@id
+##                      and imembers.member_type = "USER"))
     if (flag)
        return(SMS_IN_USE);
 ##  repeat retrieve (flag = any(filesys.label where filesys.owner=@id))
@@ -380,8 +386,9 @@ int setup_dusr(q, argv)
 ##                     hostaccess.acl_type = "USER"))
     if (flag)
        return(SMS_IN_USE);
-    else
-       return(SMS_SUCCESS);
+    if (ingres_errno)
+       return(sms_errcode);
+    return(SMS_SUCCESS);
 ##}
 
 
@@ -420,6 +427,7 @@ char **argv;
     user = *(int *)argv[0];
 ##  repeat retrieve (type = u.potype, id = u.pop_id)
 ##             where u.users_id = @user
+    if (ingres_errno) return(sms_errcode);
 
     if (!strcmp(strtrim(type), "POP"))
       set_pop_usage(id, -1);
@@ -455,8 +463,12 @@ int setup_dmac(q, argv)
 ##  repeat retrieve (flag = any(printcap.mach_id where printcap.mach_id=@id))
     if (flag)
        return(SMS_IN_USE);
+##  repeat retrieve (flag = any(palladium.mach_id where palladium.mach_id=@id))
+    if (flag)
+       return(SMS_IN_USE);
 
 ##  repeat delete mcmap where mcmap.mach_id = @id
+    if (ingres_errno) return(sms_errcode);
     return(SMS_SUCCESS);
 ##}
 
@@ -478,8 +490,9 @@ int setup_dclu(q, argv)
 ##  repeat retrieve (flag = any(svc.clu_id where svc.clu_id=@id))
     if (flag)
        return(SMS_IN_USE);
-    else
-       return(SMS_SUCCESS);
+    if (ingres_errno)
+       return(sms_errcode);
+    return(SMS_SUCCESS);
 ##}
 
 
@@ -508,6 +521,7 @@ char **argv;
            if (set_next_object_id("gid", "list"))
              return(SMS_INGRES_ERR);
 ##         repeat retrieve (ngid = values.value) where values.name = "gid"
+           if (ingres_errno) return(sms_errcode);
            sprintf(argv[idx], "%d", ngid);
        } else {
            strcpy(argv[idx], "-1");
@@ -529,11 +543,11 @@ int setup_dlis(q, argv)
 ##  int flag, id;
 
     id = *(int *)argv[0];
-##  repeat retrieve (flag = any(members.member_id where members.member_id=@id
-##                      and members.member_type = "LIST"))
+##  repeat retrieve (flag = any(imembers.member_id where imembers.member_id=@id
+##                      and imembers.member_type = "LIST"))
     if (flag)
        return(SMS_IN_USE);
-##  repeat retrieve (flag = any(members.member_id where members.list_id=@id))
+##  repeat retrieve (flag = any(imembers.member_id where imembers.list_id=@id))
     if (flag)
        return(SMS_IN_USE);
 ##  repeat retrieve (flag = any(filesys.label where filesys.owners=@id))
@@ -561,8 +575,9 @@ int setup_dlis(q, argv)
 ##                   zephyr.iui_type = "LIST" and zephyr.iui_id = @id))
     if (flag)
         return(SMS_IN_USE);
-    else
-       return(SMS_SUCCESS);
+    if (ingres_errno)
+       return(sms_errcode);
+    return(SMS_SUCCESS);
 ##}
 
 
@@ -585,8 +600,9 @@ int setup_dsin(q, argv)
 ##  repeat retrieve (flag = servers.inprogress) where servers.#name = @name
     if (flag)
        return(SMS_IN_USE);
-    else
-       return(SMS_SUCCESS);
+    if (ingres_errno)
+       return(sms_errcode);
+    return(SMS_SUCCESS);
 ##}
 
 
@@ -607,8 +623,9 @@ int setup_dshi(q, argv)
 ##     where serverhosts.service=uppercase(@name) and serverhosts.mach_id=@id
     if (flag)
        return(SMS_IN_USE);
-    else
-       return(SMS_SUCCESS);
+    if (ingres_errno)
+       return(sms_errcode);
+    return(SMS_SUCCESS);
 ##}
 
 
@@ -685,6 +702,7 @@ setup_ufil(q, argv)
        status = check_nfs(mach_id, name, access);
        fid = *(int *)argv[0];
 ##     replace nfsquota (phys_id = var_phys_id) where nfsquota.filsys_id = fid
+       if (ingres_errno) return(sms_errcode);
        return(status);
     } else
       return(SMS_SUCCESS);
@@ -702,7 +720,7 @@ setup_ufil(q, argv)
     char *name;
     char *access;
 ##{
-##  char dir[32];
+##  char dir[81];
     char caccess;
     register int status;
     register char *cp1;
@@ -726,13 +744,14 @@ setup_ufil(q, argv)
 ##           endretrieve
         }
 ##  }
-
+    if (ingres_errno)
+       return(sms_errcode);
     return(status);
 ##}
 
 
-/* setup_dfil: free any quota records associated with a filesystem
- * when it is deleted.
+/* setup_dfil: free any quota records and fsgroup info associated with
+ * a filesystem when it is deleted.  Also adjust the allocation numbers.
  */
 
 setup_dfil(q, argv, cl)
@@ -750,6 +769,9 @@ setup_dfil(q, argv, cl)
 ##     where n.nfsphys_id = fs.phys_id and fs.filsys_id = @id
 
 ##  repeat delete q where q.filsys_id = @id
+##  repeat delete fsgroup where fsgroup.filsys_id = @id
+##  repeat delete fsgroup where fsgroup.group_id = @id
+    if (ingres_errno) return(sms_errcode);
     return(SMS_SUCCESS);
 ##}
 
@@ -769,6 +791,8 @@ setup_dnfp(q, argv, cl)
 ##  repeat retrieve (exists = any(filesys.label where filesys.phys_id = @id))
     if (exists)
       return(SMS_IN_USE);
+    if (ingres_errno)
+      return(sms_errcode);
     return(SMS_SUCCESS);
 ##}
 
@@ -793,6 +817,50 @@ setup_dnfq(q, argv, cl)
 ##     q.filsys_id = @fs
 ##  repeat replace nfsphys (allocated = nfsphys.allocated - @quota)
 ##     where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
+    if (ingres_errno) return(sms_errcode);
+    return(SMS_SUCCESS);
+##}
+
+
+/* setup_sshi: don't exclusive lock the machine table during
+ * set_server_host_internal.
+ */
+
+setup_sshi(q, argv, cl)
+    struct query  *q;
+    char **argv;
+    client *cl;
+##{
+##  set lockmode session where readlock = system
+##}
+
+
+/* setup add_kerberos_user_mapping: add the string to the string 
+ * table if necessary.
+ */
+
+setup_akum(q, argv, cl)
+struct query *q;
+char **argv;
+client *cl;
+##{
+##  int id, rowcount;
+##  char *name;
+
+    name = argv[1];
+##  range of s is strings
+##  repeat retrieve (id = s.string_id) where s.string = @name
+##  inquire_equel (rowcount = "rowcount")
+    if (rowcount == 0) {
+       if (q->type != APPEND) return(SMS_STRING);
+##     range of v is values
+##     retrieve (id = v.value) where v.#name = "strings_id"
+       id++;
+##     replace v (value = id) where v.#name = "strings_id"
+##     append to strings (string_id = id, string = name)
+    }
+    if (ingres_errno) return(sms_errcode);
+    *(int *)argv[1] = id;
     return(SMS_SUCCESS);
 ##}
 
@@ -814,7 +882,7 @@ set_modtime(q, argv, cl)
 ##  int who;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
     table = q->rtable;
     name = argv[0];
 
@@ -838,7 +906,7 @@ set_modtime_by_id(q, argv, cl)
 ##  int who, id;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
     table = q->rtable;
     id_name = q->validate->object_id;
 
@@ -861,7 +929,7 @@ set_finger_modtime(q, argv, cl)
 ##  char *entity;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
     users_id = *(int *)argv[0];
 
 ##  repeat replace u (fmodtime = "now", fmodby = @who, fmodwith = @entity)
@@ -882,7 +950,7 @@ set_pobox_modtime(q, argv, cl)
 ##  char *entity;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
     users_id = *(int *)argv[0];
 
 ##  repeat replace users (pmodtime = "now", pmodby = @who, pmodwith = @entity)
@@ -891,25 +959,24 @@ set_pobox_modtime(q, argv, cl)
 ##}
 
 
-/* Sets the modtime on a machine record.  The machine name is in argv[0].
- * This routine is different from the generic set_modtime in that the
- * name is uppercased first.
+/* Like set_modtime, but uppercases the name first.
  */
 
-set_mach_modtime(q, argv, cl)
+set_uppercase_modtime(q, argv, cl)
     struct query *q;
     char **argv;
     client *cl;
 ##{
-##  char *host, *entity;
+##  char *name, *entity, *table;
 ##  int who;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
+    table = q->rtable;
+    name = argv[0];
 
-    host = argv[0];
-##  repeat replace m (modtime = "now", modby = @who, modwith = @entity)
-##      where m.name = uppercase(@host)
+##  replace table (modtime = "now", modby = who, modwith = entity)
+##      where table.#name = uppercase(name)
     return(SMS_SUCCESS);
 ##}
 
@@ -928,7 +995,7 @@ set_mach_modtime_by_id(q, argv, cl)
 ##  int who, id;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
 
     id = *(int *)argv[0];
 ##  range of m is machine
@@ -952,7 +1019,7 @@ set_cluster_modtime_by_id(q, argv, cl)
 ##  int who, id;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
 
     id = *(int *)argv[0];
 ##  range of c is cluster
@@ -975,7 +1042,7 @@ set_serverhost_modtime(q, argv, cl)
 ##  int who, id;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
 
     serv = argv[0];
     id = *(int *)argv[1];
@@ -998,7 +1065,7 @@ set_nfsphys_modtime(q, argv, cl)
 ##  int who, id;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
 
     id = *(int *)argv[0];
     dir = argv[1];
@@ -1021,7 +1088,7 @@ set_filesys_modtime(q, argv, cl)
 ##  int who;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
 
     label = argv[0];
     if (!strcmp(q->shortname, "ufil"))
@@ -1046,7 +1113,7 @@ set_zephyr_modtime(q, argv, cl)
 ##  int who;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
 
     class = argv[0];
 
@@ -1078,9 +1145,15 @@ followup_fix_modby(q, sq, v, action, actarg, cl)
     while (sq_get_data(sq, &argv)) {
        id = atoi(argv[i]);
        free(argv[i]);
-       argv[i] = malloc(9);
+       argv[i] = malloc(256);
        name = argv[i];
-##     repeat retrieve (name = users.login) where users.users_id = @id
+       if (id > 0)
+##       repeat retrieve (name = users.login) where users.users_id = @id
+       else {
+           id = -id;
+##         repeat retrieve (name = strings.string) where strings.string_id = @id
+           id = -id;
+       }
 ##     inquire_equel(rowcount = "rowcount")
        if (rowcount != 1) {
            sprintf(argv[i], "#%d", id);
@@ -1091,6 +1164,7 @@ followup_fix_modby(q, sq, v, action, actarg, cl)
        free(argv);
     }
     sq_destroy(sq);
+    if (ingres_errno) return(sms_errcode);
     return(SMS_SUCCESS);
 ##}
 
@@ -1116,7 +1190,7 @@ followup_ausr(q, argv, cl)
 ##  char fullname[129];
 
     login = argv[0];
-    who = cl->users_id;
+    who = cl->client_id;
     entity = cl->entity;
 
     /* build fullname */
@@ -1187,9 +1261,16 @@ followup_gpob(q, sq, v, action, actarg, cl)
        if (!strcmp(q->shortname, "gpob")) {
            sid = atoi(argv[4]);
            free(argv[4]);
-           argv[4] = malloc(9);
+           argv[4] = malloc(256);
            name = argv[4];
-##         repeat retrieve (name = users.login) where users.users_id = @sid
+           if (sid > 0)
+##           repeat retrieve (name = users.login) where users.users_id = @sid
+           else {
+             sid = -sid;
+##           repeat retrieve (name = strings.string) 
+##               where strings.string_id = @sid
+             sid = -sid;
+           }
 ##         inquire_equel(rowcount = "rowcount")
            if (rowcount != 1)
              sprintf(name, "#%d", sid);
@@ -1201,6 +1282,7 @@ followup_gpob(q, sq, v, action, actarg, cl)
        /* free saved data */
        free(argv[0]);
        free(argv[1]);
+       free(argv[4]);
        free(argv);
     }
 
@@ -1237,8 +1319,14 @@ followup_glin(q, sq, v, action, actarg, cl)
 
        id = atoi(argv[i = q->vcnt - 2]);
        free(argv[i]);
-       name = argv[i] = malloc(9);
-##     repeat retrieve (name = users.login) where users.users_id = @id
+       name = argv[i] = malloc(256);
+       if (id > 0)
+##       repeat retrieve (name = users.login) where users.users_id = @id
+       else {
+         id = -id;
+##       repeat retrieve (name = strings.string) where strings.string_id = @id
+         id = -id;
+       }
 ##     inquire_equel(rowcount = "rowcount")
        if (rowcount != 1)
          sprintf(argv[i], "#%d", id);
@@ -1255,6 +1343,11 @@ followup_glin(q, sq, v, action, actarg, cl)
                strcpy(name, "???");
        } else if (!strcmp(type, "USER")) {
 ##         repeat retrieve (name = users.login) where users.users_id = @id
+##         inquire_equel(rowcount = "rowcount")
+           if (rowcount != 1)
+               strcpy(name, "???");
+       } else if (!strcmp(type, "KERBEROS")) {
+##         repeat retrieve (name = strings.string) where strings.string_id = @id
 ##         inquire_equel(rowcount = "rowcount")
            if (rowcount != 1)
                strcpy(name, "???");
@@ -1284,49 +1377,61 @@ followup_glin(q, sq, v, action, actarg, cl)
 ##}
 
 
-/** followup_amtl - followup for amtl and dmfl; when adding a list 
- **                 member to a maillist, make member list a maillist also
- **                 unless list is a user-group.
- **                 Then set_list_modtime_by_id.
- **
- ** Inputs:
- **   argv[0] - list_id
- **   argv[1] - member_type
- **   argv[2] - member_id
- **
- **/
+/* followup_gnfq: Fix the directory name & modby fields
+ *   argv[0] = filsys_id
+ *   argv[2] = ascii(quota)
+ */
 
-followup_amtl(q, argv, cl)
+followup_gnfq(q, sq, v, action, actarg, cl)
     struct query *q;
-    char *argv[];
+    register struct save_queue *sq;
+    struct validate *v;
+    register int (*action)();
+    register int actarg;
     client *cl;
 ##{
-##  int list_id;
-##  int member_id;
-##  int exists, who;
-##  char *entity;
-
-    list_id = *(int *)argv[0];
-    entity = cl->entity;
-    who = cl->users_id;
-
-##  range of l is list
-##  repeat replace l (modtime = "now", modby = @who, modwith = @entity)
-##      where l.#list_id = @list_id
-
-    /* if query is not amtl or if member_type is not LIST then return */
-    if (bcmp(q->shortname, "amtl", 4) || bcmp(argv[1], "LIST", 4)) 
-       return(SMS_SUCCESS);
-
-    member_id = *(int *)argv[2];
+    register int j;
+    char **argv, *malloc();
+##  int id, rowcount;
+##  char *name, *label;
 
-    /* is parent list a mailing list? */
-##  repeat retrieve (exists = l.maillist) where l.#list_id=@list_id
-    if (!exists)
-       return(SMS_SUCCESS);
+    while (sq_get_data(sq, &argv)) {
+       id = atoi(argv[3]);
+       free(argv[3]);
+       argv[3] = malloc(256);
+       name = argv[3];
+       if (id == 0) {
+           label = argv[0];
+##         repeat retrieve (name = filesys.#name) where filesys.#label = @label
+       } else {
+##         repeat retrieve (name = nfsphys.dir) where nfsphys.nfsphys_id = @id
+       }
+##     inquire_equel(rowcount = "rowcount")
+       if (rowcount != 1) {
+           sprintf(argv[3], "#%d", id);
+       }
 
-    /* list is not a user-group; add list to maillist table */
-##  repeat replace l (maillist = 1) where l.#list_id = @member_id
+       id = atoi(argv[6]);
+       free(argv[6]);
+       argv[6] = malloc(256);
+       name = argv[6];
+       if (id > 0)
+##       repeat retrieve (name = users.login) where users.users_id = @id
+       else {
+           id = -id;
+##         repeat retrieve (name = strings.string) where strings.string_id = @id
+           id = -id;
+       }
+##     inquire_equel(rowcount = "rowcount")
+       if (rowcount != 1) {
+           sprintf(argv[6], "#%d", id);
+       }
+       (*action)(q->vcnt, argv, actarg);
+       for (j = 0; j < q->vcnt; j++)
+         free(argv[j]);
+       free(argv);
+    }
+    sq_destroy(sq);
     return(SMS_SUCCESS);
 ##}
 
@@ -1347,13 +1452,14 @@ followup_anfq(q, argv, cl)
     fs = *(int *)argv[0];
     user = *(int *)argv[1];
     quota = atoi(argv[2]);
-    who = cl->users_id;
+    who = cl->client_id;
     entity = cl->entity;
 
 ##  repeat replace nq (modtime = "now", modby = @who, modwith = @entity)
 ##     where nq.filsys_id = @fs and nq.users_id = @user
 ##  repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
 ##     where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
+    if (ingres_errno) return(sms_errcode);
     return(SMS_SUCCESS);
 ##}
 
@@ -1379,8 +1485,14 @@ followup_gzcl(q, sq, v, action, actarg, cl)
 
        id = atoi(argv[i = q->vcnt - 2]);
        free(argv[i]);
-       name = argv[i] = malloc(9);
-##     repeat retrieve (name = users.login) where users.users_id = @id
+       name = argv[i] = malloc(256);
+       if (id > 0)
+##       repeat retrieve (name = users.login) where users.users_id = @id
+       else {
+         id = -id;
+##       repeat retrieve (name = strings.string) where strings.string_id = @id
+         id = -id;
+       }
 ##     inquire_equel(rowcount = "rowcount")
        if (rowcount != 1)
          sprintf(argv[i], "#%d", id);
@@ -1397,6 +1509,11 @@ followup_gzcl(q, sq, v, action, actarg, cl)
                  strcpy(name, "???");
            } else if (!strcmp(argv[i], "USER")) {
 ##             repeat retrieve (name = users.login) where users.users_id = @id
+##             inquire_equel(rowcount = "rowcount")
+               if (rowcount != 1)
+                 strcpy(name, "???");
+           } else if (!strcmp(argv[i], "KERBEROS")) {
+##             repeat retrieve (name = strings.string) where strings.string_id = @id
 ##             inquire_equel(rowcount = "rowcount")
                if (rowcount != 1)
                  strcpy(name, "???");
@@ -1441,8 +1558,14 @@ followup_gsha(q, sq, v, action, actarg, cl)
 
        id = atoi(argv[4]);
        free(argv[4]);
-       name = argv[4] = malloc(9);
-##     repeat retrieve (name = users.login) where users.users_id = @id
+       name = argv[4] = malloc(256);
+       if (id > 0)
+##       repeat retrieve (name = users.login) where users.users_id = @id
+       else {
+         id = -id;
+##       repeat retrieve (name = strings.string) where strings.string_id = @id
+         id = -id;
+       }
 ##     inquire_equel(rowcount = "rowcount")
        if (rowcount != 1)
          sprintf(argv[4], "#%d", id);
@@ -1458,6 +1581,11 @@ followup_gsha(q, sq, v, action, actarg, cl)
              strcpy(name, "???");
        } else if (!strcmp(argv[1], "USER")) {
 ##         repeat retrieve (name = users.login) where users.users_id = @id
+##         inquire_equel(rowcount = "rowcount")
+           if (rowcount != 1)
+             strcpy(name, "???");
+       } else if (!strcmp(argv[1], "KERBEROS")) {
+##         repeat retrieve (name = strings.string) where strings.string_id = @id
 ##         inquire_equel(rowcount = "rowcount")
            if (rowcount != 1)
              strcpy(name, "???");
@@ -1503,6 +1631,7 @@ int set_pobox(q, argv, cl)
 
 ##  repeat retrieve (id = users.pop_id, potype = users.#potype)
 ##             where users.users_id = @user
+    if (ingres_errno) return(sms_errcode);
     if (!strcmp(strtrim(potype), "POP"))
       set_pop_usage(id, -1);
 
@@ -1515,6 +1644,8 @@ int set_pobox(q, argv, cl)
 ##             where users.users_id = @user
        set_pop_usage(id, 1);
     } else if (!strcmp(argv[1], "SMTP")) {
+       if (index(box, '/') || index(box, '|'))
+         return(SMS_BAD_CHAR);
 ##      range of s is strings
 ##      repeat retrieve (id = s.string_id) where s.string = @box
 ##      inquire_equel (rowcount = "rowcount")
@@ -1534,6 +1665,7 @@ int set_pobox(q, argv, cl)
     set_pobox_modtime(q, argv, cl);
 ##  repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
 ##     where tblstats.#table = "users"
+    if (ingres_errno) return(sms_errcode);
     return(SMS_SUCCESS);
 ##}
 
@@ -1553,7 +1685,7 @@ get_list_info(q, aargv, cl, action, actarg)
     char *argv[13], *malloc(), *realloc();
 ##  char *name, acl_type[9], listname[33], active[5], public[5], hidden[5];
 ##  char maillist[5], group[5], gid[6], acl_name[33], desc[256], modtime[27];
-##  char modby[9], modwith[9];
+##  char modby[256], modwith[9];
 ##  int id, rowcount, acl_id, hid, modby_id;
     int returned;
     struct save_queue *sq, *sq_create();
@@ -1567,6 +1699,7 @@ get_list_info(q, aargv, cl, action, actarg)
        sq_save_data(sq, id);
        rowcount++;
 ##  }
+    if (ingres_errno) return(sms_errcode);
     if (rowcount == 0)
       return(SMS_NO_MATCH);
 
@@ -1587,6 +1720,7 @@ get_list_info(q, aargv, cl, action, actarg)
 ##             desc = l.#desc, modtime = l.#modtime, modby_id = l.#modby,
 ##             modwith =l.#modwith)
 ##         where l.list_id = @id
+       if (ingres_errno) return(sms_errcode);
 
        if (atoi(gid) == -1)
            argv[6] = UNIQUE_GID;
@@ -1599,6 +1733,12 @@ get_list_info(q, aargv, cl, action, actarg)
        } else if (!strcmp(acl_type, "USER")) {
 ##         repeat retrieve (acl_name = users.#login)
 ##             where users.users_id = @acl_id
+##         inquire_equel(rowcount = "rowcount")
+           if (rowcount != 1)
+               strcpy(acl_name, "???");
+       } else if (!strcmp(acl_type, "KERBEROS")) {
+##         repeat retrieve (acl_name = strings.string)
+##             where strings.string_id = @acl_id
 ##         inquire_equel(rowcount = "rowcount")
            if (rowcount != 1)
                strcpy(acl_name, "???");
@@ -1607,10 +1747,18 @@ get_list_info(q, aargv, cl, action, actarg)
        } else
          strcpy(acl_name, "???");
 
-##     repeat retrieve (modby = users.login) where users.users_id = @modby_id
+       if (modby_id > 0)
+##       repeat retrieve (modby = users.login) where users.users_id = @modby_id
+       else {
+           modby_id = -modby_id;
+##          repeat retrieve (modby = strings.string) 
+##             where strings.string_id = @modby_id
+           modby_id = -modby_id;
+       }
 ##     inquire_equel(rowcount = "rowcount")
        if (rowcount != 1)
-         sprintf(modby, "#%d", id);
+         sprintf(modby, "#%d", modby_id);
+       if (ingres_errno) return(sms_errcode);
 
        sms_trim_args(q->vcnt, argv);
        returned++;
@@ -1618,6 +1766,7 @@ get_list_info(q, aargv, cl, action, actarg)
     }
 
     sq_destroy(sq);
+    if (ingres_errno) return(sms_errcode);
 ##  repeat replace tblstats (retrieves = tblstats.retrieves + 1)
 ##     where tblstats.#table = "list"
 
@@ -1625,6 +1774,239 @@ get_list_info(q, aargv, cl, action, actarg)
 ##}
 
 
+/* Add_member_to_list: do list flattening as we go!  MAXLISTDEPTH is
+ * how many different ancestors a member is allowed to have.
+ */
+
+#define MAXLISTDEPTH   100
+
+int add_member_to_list(q, argv, cl)
+    struct query *q;
+    char **argv;
+    client *cl;
+##{
+##  int id, lid, mid, exists, error, who;
+##  char *mtype, dtype[9], buf[256], *entity;
+    int ancestors[MAXLISTDEPTH], acount, a;
+    int descendants[MAXLISTDEPTH], dcount, d;
+    char *dtypes[MAXLISTDEPTH];
+    char *iargv[3];
+
+##  range of m is imembers
+    lid = *(int *)argv[0];
+    mtype = argv[1];
+    mid = *(int *)argv[2];
+##  repeat retrieve (exists = any(m.list_id where m.list_id=@lid and 
+##                        m.member_id = @mid and m.member_type = @mtype
+##                        and m.direct = 1))
+    if (exists)
+      return(SMS_EXISTS);
+    if (!strcasecmp(mtype, "STRING")) {
+##     repeat retrieve (buf = strings.string) where strings.string_id = @mid
+       if (index(buf, '/') || index(buf, '|'))
+         return(SMS_BAD_CHAR);
+    }
+
+    ancestors[0] = lid;
+    acount = 1;
+##  repeat retrieve (id = m.list_id)
+##     where m.member_id = @lid and m.member_type = "LIST" {
+       ancestors[acount++] = id;
+       if (acount >= MAXLISTDEPTH) {
+##         endretrieve
+       }
+##  }
+    if (ingres_errno) return(sms_errcode);
+    if (acount >= MAXLISTDEPTH) {
+       return(SMS_INTERNAL);
+    }
+    descendants[0] = mid;
+    dtypes[0] = mtype;
+    dcount = 1;
+    error = 0;
+    if (!strcmp(mtype, "LIST")) {
+##     repeat retrieve (id = m.member_id, dtype = m.member_type)
+##       where m.list_id = @mid {
+           switch (dtype[0]) {
+           case 'L':
+               dtypes[dcount] = "LIST";
+               break;
+           case 'U':
+               dtypes[dcount] = "USER";
+               break;
+           case 'S':
+               dtypes[dcount] = "STRING";
+               break;
+           case 'K':
+               dtypes[dcount] = "KERBEROS";
+               break;
+           default:
+               error++;
+##             endretrieve
+           }
+           descendants[dcount++] = id;
+           if (dcount >= MAXLISTDEPTH) {
+               error++;
+##             endretrieve
+           }
+##     }
+       if (ingres_errno) return(sms_errcode);
+       if (error)
+         return(SMS_INTERNAL);
+    }
+    for (a = 0; a < acount; a++) {
+       lid = ancestors[a];
+       for (d = 0; d < dcount; d++) {
+           mid = descendants[d];
+           mtype = dtypes[d];
+           if (mid == lid && !strcmp(mtype, "LIST")) {
+               return(SMS_LISTLOOP);
+           }
+##         repeat retrieve (exists = any(m.ref_count where m.list_id = @lid
+##                                      and m.member_id = @mid
+##                                      and m.member_type = @mtype))
+           if (exists) {
+               if (a == 0 && d == 0)
+##               replace m (ref_count = m.ref_count+1, direct = 1)
+##                          where m.list_id = lid and m.member_id = mid and
+##                          m.member_type = mtype
+               else
+##               replace m (ref_count = m.ref_count+1)
+##                          where m.list_id = lid and m.member_id = mid and
+##                          m.member_type = mtype
+           } else {
+               incremental_clear_before();
+               if (a == 0 && d == 0)
+##               append imembers (list_id=lid, member_id = mid, direct = 1,
+##                                member_type=mtype, ref_count = 1)
+               else
+##               append imembers (list_id=lid, member_id = mid,
+##                                member_type=mtype, ref_count = 1)
+               iargv[0] = (char *)lid;
+               iargv[1] = mtype;
+               iargv[2] = (char *)mid;
+               incremental_after("members", 0, iargv);
+           }
+       }
+    }
+    lid = *(int *)argv[0];
+    entity = cl->entity;
+    who = cl->client_id;
+##  repeat replace list (modtime = "now", modby = @who, modwith = @entity)
+##      where list.#list_id = @lid
+    if (ingres_errno) return(sms_errcode);
+    return(SMS_SUCCESS);
+##}
+
+
+/* Delete_member_from_list: do list flattening as we go!
+ */
+
+int delete_member_from_list(q, argv, cl)
+    struct query *q;
+    char **argv;
+    client *cl;
+##{
+##  int id, lid, mid, cnt, exists, error, who;
+##  char *mtype, dtype[9], *entity;
+    int ancestors[MAXLISTDEPTH], acount, a;
+    int descendants[MAXLISTDEPTH], dcount, d;
+    char *dtypes[MAXLISTDEPTH];
+    char *iargv[3];
+
+##  range of m is imembers
+    lid = *(int *)argv[0];
+    mtype = argv[1];
+    mid = *(int *)argv[2];
+##  repeat retrieve (exists = any(m.list_id where m.list_id=@lid and 
+##                        m.member_id = @mid and m.member_type = @mtype
+##                        and m.direct = 1))
+    if (ingres_errno) return(sms_errcode);
+    if (!exists)
+      return(SMS_NO_MATCH);
+    ancestors[0] = lid;
+    acount = 1;
+##  repeat retrieve (id = m.list_id)
+##     where m.member_id = @lid and m.member_type = "LIST" {
+       ancestors[acount++] = id;
+       if (acount >= MAXLISTDEPTH)
+##       endretrieve
+##  }
+         if (ingres_errno) return(sms_errcode);
+    if (acount >= MAXLISTDEPTH)
+      return(SMS_INTERNAL);
+    descendants[0] = mid;
+    dtypes[0] = mtype;
+    dcount = 1;
+    error = 0;
+    if (!strcmp(mtype, "LIST")) {
+##     repeat retrieve (id = m.member_id, dtype = m.member_type)
+##       where m.list_id = @mid {
+           switch (dtype[0]) {
+           case 'L':
+               dtypes[dcount] = "LIST";
+               break;
+           case 'U':
+               dtypes[dcount] = "USER";
+               break;
+           case 'S':
+               dtypes[dcount] = "STRING";
+               break;
+           case 'K':
+               dtypes[dcount] = "KERBEROS";
+               break;
+           default:
+               error++;
+##             endretrieve
+           }
+           descendants[dcount++] = id;
+           if (dcount >= MAXLISTDEPTH)
+##           endretrieve
+##     }
+             if (ingres_errno) return(sms_errcode);
+       if (error)
+         return(SMS_INTERNAL);
+    }
+    for (a = 0; a < acount; a++) {
+       lid = ancestors[a];
+       for (d = 0; d < dcount; d++) {
+           mid = descendants[d];
+           mtype = dtypes[d];
+           if (mid == lid && !strcmp(mtype, "LIST")) {
+               return(SMS_LISTLOOP);
+           }
+##         repeat retrieve (cnt = m.ref_count)
+##             where m.list_id = @lid and m.member_id = @mid
+##               and m.member_type = @mtype
+           if (cnt <= 1) {
+               iargv[0] = (char *)lid;
+               iargv[1] = mtype;
+               iargv[2] = (char *)mid;
+               incremental_before("members", 0, iargv);
+##             delete m where m.list_id = lid and m.member_id = mid and
+##                 m.member_type = mtype
+               incremental_clear_after();
+           } else if (a == 0 && d == 0) {
+##             replace m (ref_count = m.ref_count-1, direct = 0)
+##                 where m.list_id = lid and m.member_id = mid and
+##                 m.member_type = mtype
+           } else {
+##             replace m (ref_count = m.ref_count-1)
+##                 where m.list_id = lid and m.member_id = mid and
+##                 m.member_type = mtype
+           }
+       }
+    }
+    lid = *(int *)argv[0];
+    entity = cl->entity;
+    who = cl->client_id;
+##  repeat replace list (modtime = "now", modby = @who, modwith = @entity)
+##      where list.#list_id = @lid
+    if (ingres_errno) return(sms_errcode);
+    return(SMS_SUCCESS);
+##}
+
+
 /* get_ace_use - given a type and a name, return a type and a name.
  * The ace_type is one of "LIST", "USER", "RLIST", or "RUSER" in argv[0],
  * and argv[1] will contain the ID of the entity in question.  The R*
@@ -1645,9 +2027,11 @@ int get_ace_use(q, argv, cl, action, actarg)
 ##  int aid, listid, id;
     struct save_queue *sq, *sq_create();
 
+##  range of m is imembers
     atype = argv[0];
     aid = *(int *)argv[1];
-    if (!strcmp(atype, "LIST") || !strcmp(atype, "USER")) {
+    if (!strcmp(atype, "LIST") || !strcmp(atype, "USER") ||
+       !strcmp(atype, "KERBEROS")) {
        return(get_ace_internal(atype, aid, action, actarg));
     }
 
@@ -1655,13 +2039,11 @@ int get_ace_use(q, argv, cl, action, actarg)
     if (!strcmp(atype, "RLIST")) {
        sq_save_data(sq, aid);
        /* get all the list_id's of containing lists */
-##     range of m is members
-       while (sq_get_data(sq, &id)) {
-##         repeat retrieve (listid = m.list_id)
+##     range of m is imembers
+##     repeat retrieve (listid = m.list_id)
 ##             where m.member_type = "LIST" and m.member_id = @id {
-             sq_save_unique_data(sq, listid);
-##         }
-         }
+           sq_save_unique_data(sq, listid);
+##     }
        /* now process each one */
        while (sq_get_data(sq, &id)) {
            if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
@@ -1670,18 +2052,10 @@ int get_ace_use(q, argv, cl, action, actarg)
     }
 
     if (!strcmp(atype, "RUSER")) {
-##     range of m is members
 ##     repeat retrieve (listid = m.list_id)
 ##             where m.member_type = "USER" and m.member_id = @aid {
            sq_save_data(sq, listid);
 ##     }
-       /* get all the list_id's of containing lists */
-       while (sq_get_data(sq, &id)) {
-##         repeat retrieve (listid = m.list_id)
-##             where m.member_type = "LIST" and m.member_id = @id {
-             sq_save_unique_data(sq, listid);
-##         }
-         }
        /* now process each one */
        while (sq_get_data(sq, &id)) {
            if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
@@ -1691,7 +2065,22 @@ int get_ace_use(q, argv, cl, action, actarg)
          found++;
     }
 
+    if (!strcmp(atype, "RKERBERO")) {
+##     repeat retrieve (listid = m.list_id)
+##             where m.member_type = "KERBEROS" and m.member_id = @aid {
+           sq_save_data(sq, listid);
+##     }
+       /* now process each one */
+       while (sq_get_data(sq, &id)) {
+           if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
+             found++;
+       }
+       if (get_ace_internal("KERBEROS", aid, action, actarg) == SMS_SUCCESS)
+         found++;
+    }
+
     sq_destroy(sq);    
+    if (ingres_errno) return(sms_errcode);
     if (!found) return(SMS_NO_MATCH);
     return(SMS_SUCCESS);
 ##}
@@ -1787,103 +2176,30 @@ int get_lists_of_member(q, argv, cl, action, actarg)
     int (*action)();
     int actarg;
 ##{
-    int found = 0;
+    int found = 0, direct = 1;
+    char *rargv[6];
 ##  char *atype;
 ##  int aid, listid, id;
-    struct save_queue *sq, *sq_create();
+##  char name[33], active[5], public[5], hidden[5], maillist[5], group[5];
 
     atype = argv[0];
     aid = *(int *)argv[1];
-    if (!strcmp(atype, "LIST") ||
-       !strcmp(atype, "USER") ||
-       !strcmp(atype, "STRING")) {
-      return(glom_internal(atype, aid, action, actarg));
-    }
-
-    sq = sq_create();
     if (!strcmp(atype, "RLIST")) {
-       sq_save_data(sq, aid);
-       /* get all the list_id's of containing lists */
-##     range of m is members
-       while (sq_get_data(sq, &id)) {
-##         repeat retrieve (listid = m.list_id)
-##             where m.member_type = "LIST" and m.member_id = @id {
-             sq_save_unique_data(sq, listid);
-##         }
-         }
-       /* now process each one */
-       while (sq_get_data(sq, &id)) {
-           if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
-             found++;
-       }
+       atype = "LIST";
+       direct = 0;
     }
-
     if (!strcmp(atype, "RUSER")) {
-##     range of m is members
-##     repeat retrieve (listid = m.list_id)
-##             where m.member_type = "USER" and m.member_id = @aid {
-           sq_save_data(sq, listid);
-##     }
-       /* get all the list_id's of containing lists */
-       while (sq_get_data(sq, &id)) {
-##         repeat retrieve (listid = m.list_id)
-##             where m.member_type = "LIST" and m.member_id = @id {
-             sq_save_unique_data(sq, listid);
-##         }
-         }
-       /* now process each one */
-       while (sq_get_data(sq, &id)) {
-           if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
-             found++;
-       }
-       if (glom_internal("USER", aid, action, actarg) == SMS_SUCCESS)
-         found++;
+       atype = "USER";
+       direct = 0;
     }
-
     if (!strcmp(atype, "RSTRING")) {
-##     range of m is members
-##     repeat retrieve (listid = m.list_id)
-##             where m.member_type = "STRING" and m.member_id = @aid {
-           sq_save_data(sq, listid);
-##     }
-       /* get all the list_id's of containing lists */
-       while (sq_get_data(sq, &id)) {
-##         repeat retrieve (listid = m.list_id)
-##             where m.member_type = "LIST" and m.member_id = @id {
-             sq_save_unique_data(sq, listid);
-##         }
-         }
-       /* now process each one */
-       while (sq_get_data(sq, &id)) {
-           if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
-             found++;
-       }
-       if (glom_internal("STRING", aid, action, actarg) == SMS_SUCCESS)
-         found++;
+       atype = "STRING";
+       direct = 0;
+    }
+    if (!strcmp(atype, "RKERBEROS")) {
+       atype = "KERBEROS";
+       direct = 0;
     }
-
-##  repeat replace tblstats (retrieves = tblstats.retrieves + 1)
-##     where tblstats.#table = "members"
-    sq_destroy(sq);    
-    if (!found) return(SMS_NO_MATCH);
-    return(SMS_SUCCESS);
-##}
-
-
-/* This looks up a single list, user, or string as a member.  atype must be
- * "USER", "LIST", or "STRING" and aid is the ID of the corresponding object.
- * This is used by get_lists_of_members above.
- */
-
-##glom_internal(atype, aid, action, actarg)
-##  char *atype;
-##  int aid;
-    int (*action)();
-    int actarg;
-##{
-    char *rargv[6];
-    int found = 0;
-##  char name[33], active[5], public[5], hidden[5], maillist[5], group[5];
 
     rargv[0] = name;
     rargv[1] = active;
@@ -1891,15 +2207,27 @@ int get_lists_of_member(q, argv, cl, action, actarg)
     rargv[3] = hidden;
     rargv[4] = maillist;
     rargv[5] = group;
-##  repeat retrieve (name = list.#name, active = text(list.#active), 
+    if (direct) {
+##    repeat retrieve (name = list.#name, active = text(list.#active), 
+##                  public = text(list.#public), hidden = text(list.#hidden),
+##                  maillist = text(list.#maillist), group = text(list.#group))
+##             where list.list_id = m.list_id and m.direct = 1 and
+##                   m.member_type = @atype and m.member_id = @aid {
+        (*action)(6, rargv, actarg);
+        found++;
+##    }
+    } else {
+##    repeat retrieve (name = list.#name, active = text(list.#active), 
 ##                  public = text(list.#public), hidden = text(list.#hidden),
 ##                  maillist = text(list.#maillist), group = text(list.#group))
 ##             where list.list_id = m.list_id and
 ##                   m.member_type = @atype and m.member_id = @aid {
         (*action)(6, rargv, actarg);
         found++;
-##  }
+##    }
+    }
 
+    if (ingres_errno) return(sms_errcode);
     if (!found) return(SMS_NO_MATCH);
     return(SMS_SUCCESS);
 ##}
@@ -1949,35 +2277,46 @@ get_members_of_list(q, argv, cl, action, actarg)
     targv[0] = "USER";
     targv[1] = member_name;
 
-##  range of m is members
+##  range of m is imembers
 ##  repeat retrieve (member_name = users.login)
 ##             where m.#list_id = @list_id and m.member_type = "USER"
-##                   and m.member_id = users.users_id
+##                   and m.member_id = users.users_id and m.direct = 1
 ##             sort by #member_name
 ##  {
         (*action)(2, targv, actarg);
 ##  }
+    if (ingres_errno) return(sms_errcode);
 
     targv[0] = "LIST";
 ##  repeat retrieve (member_name = list.name)
 ##             where m.#list_id = @list_id and m.member_type = "LIST"
-##                   and m.member_id = list.#list_id
+##                   and m.member_id = list.#list_id and m.direct = 1
 ##             sort by #member_name
 ##  {
         (*action)(2, targv, actarg);
 ##  }
+    if (ingres_errno) return(sms_errcode);
 
     targv[0] = "STRING";
 ##  repeat retrieve (member_name = strings.string)
 ##             where m.#list_id = @list_id and m.member_type = "STRING"
-##                   and m.member_id = strings.string_id
+##                   and m.member_id = strings.string_id and m.direct = 1
 ##             sort by #member_name
 ##  {
         (*action)(2, targv, actarg);
 ##  }
+    if (ingres_errno) return(sms_errcode);
+
+    targv[0] = "KERBEROS";
+##  repeat retrieve (member_name = strings.string)
+##             where m.#list_id = @list_id and m.member_type = "KERBEROS"
+##                   and m.member_id = strings.string_id and m.direct = 1
+##             sort by #member_name
+##  {
+        (*action)(2, targv, actarg);
+##  }
+    if (ingres_errno) return(sms_errcode);
 
-##  repeat replace tblstats (retrieves = tblstats.retrieves + 1)
-##     where tblstats.#table = "members"
     return(SMS_SUCCESS);
 ##}
 
@@ -1998,11 +2337,12 @@ int count_members_of_list(q, argv, cl, action, actarg)
 
     list = *(int *)argv[0];
     rargv[0] = countbuf;
-##  repeat retrieve (ct = count(members.list_id where members.list_id = @list))
+##  repeat retrieve (ct = count(imembers.list_id
+##                             where imembers.list_id = @list and
+##                                   imembers.direct = 1))
+    if (ingres_errno) return(sms_errcode);
     sprintf(countbuf, "%d", ct);
     (*action)(1, rargv, actarg);
-##  repeat replace tblstats (retrieves = tblstats.retrieves + 1)
-##     where tblstats.#table = "members"
     return(SMS_SUCCESS);
 ##}
 
@@ -2069,6 +2409,7 @@ int qualified_get(q, argv, action, actarg, start, range, field, flags)
 ##  retrieve (name = rvar.rfield) where qual {
        (*action)(1, rargv, actarg);
 ##  }
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel(rowcount = "rowcount")
 ##  repeat replace tblstats (retrieves = tblstats.retrieves + 1)
 ##     where tblstats.#table = @rtbl
@@ -2116,6 +2457,7 @@ int qualified_get_serverhost(q, argv, cl, action, actarg)
 ##  retrieve (sname = sh.service, mname = machine.name) where qual {
        (*action)(2, rargv, actarg);
 ##  }
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel(rowcount = "rowcount")
 ##  repeat replace tblstats (retrieves = tblstats.retrieves + 1)
 ##     where tblstats.#table = "serverhosts"
@@ -2140,10 +2482,11 @@ register_user(q, argv, cl)
 ##  char *login, dir[65], *entity, *directory, machname[33];
 ##  int who, rowcount, mid, uid, users_id, flag, utype, nid, list_id, quota;
 ##  int size, alloc, pid, m_id;
+    char buffer[256], *aargv[3];
     int maxsize;
 
     entity = cl->entity;
-    who = cl->users_id;
+    who = cl->client_id;
 
     uid = atoi(argv[0]);
     login = argv[1];
@@ -2157,7 +2500,7 @@ register_user(q, argv, cl)
 
     /* find user */
 ##  repeat retrieve (users_id = u.#users_id)
-##     where u.#uid = @uid and u.status = 0
+##     where u.#uid = @uid and (u.status = 0 or u.status = 5)
 ##  inquire_equel(rowcount = "rowcount");
     if (rowcount == 0)
       return(SMS_NO_MATCH);
@@ -2165,37 +2508,43 @@ register_user(q, argv, cl)
       return(SMS_NOT_UNIQUE);
 
     /* check new login name */
-##  repeat retrieve (flag = any(u.#login where u.#login = @login))
-    if (flag)
-      return(SMS_IN_USE);
+##  repeat retrieve (flag = any(u.#login where u.#login = @login and
+##                             u.#users_id != users_id))
+    if (ingres_errno) return(sms_errcode);
+    if (flag) return(SMS_IN_USE);
 ##  repeat retrieve (flag = any(l.#name where l.#name = @login))
-    if (flag)
-      return(SMS_IN_USE);
-##  repeat retrieve (flag = any(filesys.#name where filesys.#name = @login))
-    if (flag)
-      return(SMS_IN_USE);
+    if (ingres_errno) return(sms_errcode);
+    if (flag) return(SMS_IN_USE);
+##  repeat retrieve (flag = any(filesys.#label where filesys.#label = @login))
+    if (ingres_errno) return(sms_errcode);
+    if (flag) return(SMS_IN_USE);
     com_err(whoami, 0, "new login name OK");
 
     /* choose place for pobox, put in mid */
 ##  repeat retrieve (mid = sh.mach_id, machname = m.name)
 ##    where sh.service = "POP" and m.mach_id = sh.mach_id and
 ##     sh.value2 - sh.value1 = max(sh.value2-sh.value1 where sh.service="POP")
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel(rowcount = "rowcount");
     if (rowcount == 0)
       return(SMS_NO_POBOX);
 
     /* change login name, set pobox */
+    sprintf(buffer, "u.users_id = %d", users_id);
+    incremental_before("users", buffer, 0);
 ##  repeat replace u (#login = @login, status = 2, modtime = "now",
 ##                   modby = @who, modwith = @entity, potype="POP",
 ##                   pop_id = @mid, pmodtime="now", pmodby=@who,
 ##                   pmodwith=@entity)
 ##     where u.#users_id = @users_id
 ##  inquire_equel(rowcount = "rowcount");
+    if (ingres_errno) return(sms_errcode);
     if (rowcount != 1)
       return(SMS_INTERNAL);
     set_pop_usage(mid, 1);
     com_err(whoami, 0, "set login name to %s and pobox to %s", login,
-           trim(machname));
+           strtrim(machname));
+    incremental_after("users", buffer, 0);
 
     /* create group list */
     if (set_next_object_id("gid", "list"))
@@ -2203,23 +2552,34 @@ register_user(q, argv, cl)
     if (set_next_object_id("list_id", "list"))
       return(SMS_NO_ID);
 ##  repeat retrieve (list_id = values.value) where values.name = "list_id"
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel(rowcount = "rowcount");
     if (rowcount != 1)
       return(SMS_INTERNAL);
+    incremental_clear_before();
 ##  repeat append list (name = @login, #list_id = @list_id, active = 1,
 ##                     public = 0, hidden = 0, maillist = 0, group = 1,
 ##                     #gid = values.value, desc = "User Group",
 ##                     acl_type = "USER", acl_id = @users_id, modtime = "now",
 ##                     modby = @who, modwith = @entity)
 ##     where values.name = "gid"
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel(rowcount = "rowcount");
     if (rowcount != 1)
       return(SMS_INTERNAL);
-##  repeat append members (#list_id = @list_id, member_type = "USER",
-##                        member_id = @users_id)
+    sprintf(buffer, "l.list_id = %d", list_id);
+    incremental_after("list", buffer, 0);
+    aargv[0] = (char *) list_id;
+    aargv[1] = "USER";
+    aargv[2] = (char *) users_id;
+    incremental_clear_before();
+##  repeat append imembers (#list_id = @list_id, member_type = "USER",
+##                        member_id = @users_id, ref_count = 1, direct = 1)
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel(rowcount = "rowcount");
     if (rowcount != 1)
       return(SMS_INTERNAL);
+    incremental_after("members", 0, aargv);
     com_err(whoami, 0, "group list created");
 
     /* decide where to put filesystem */
@@ -2236,12 +2596,14 @@ register_user(q, argv, cl)
            m_id = mid;
        }
 ##  }
+    if (ingres_errno) return(sms_errcode);
     if (maxsize == 0)
       return(SMS_NO_FILESYS);
 
     /* create filesystem */
     if (set_next_object_id("filsys_id", "filesys"))
       return(SMS_NO_ID);
+    incremental_clear_before();        
 ##  repeat append filesys (filsys_id = values.value, phys_id = @pid,
 ##                        label = @login, type = "NFS", mach_id = @m_id,
 ##                        name = @directory + "/" + @login,
@@ -2251,37 +2613,51 @@ register_user(q, argv, cl)
 ##                        lockertype = "HOMEDIR", modtime = "now",
 ##                        modby = @who, modwith = @entity)
 ##     where values.name = "filsys_id"
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel(rowcount = "rowcount");
     if (rowcount != 1)
       return(SMS_INTERNAL);
+    incremental_after("filesys", 
+         "fs.filsys_id = values.value and values.name = \"filsys_id\"",
+                     0);
     com_err(whoami, 0, "filesys created on mach %d in %s/%s", m_id,
            directory, login);
 
     /* set quota */
 ##  repeat retrieve (quota = values.value) where values.name = "def_quota"
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel(rowcount = "rowcount");
     if (rowcount != 1)
       return(SMS_NO_QUOTA);
+    incremental_clear_before();
 ##  repeat append nfsquota (#users_id = @users_id, filsys_id = values.value,
 ##                         #quota = @quota, phys_id = @pid, modtime = "now",
 ##                         modby = @who, modwith = @entity)
 ##     where values.name = "filsys_id"
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel(rowcount = "rowcount");
     if (rowcount != 1)
       return(SMS_INTERNAL);
 ##  repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
 ##     where nfsphys.nfsphys_id = filesys.#phys_id and
 ##           filesys.filsys_id = values.value and values.name = "filsys_id"
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel(rowcount = "rowcount");
     if (rowcount != 1)
       return(SMS_INTERNAL);
+    aargv[0] = login;
+    aargv[1] = login;
+    sprintf(buffer, "nq.users_id = %d and nq.filsys_id = values.value and values.name = \"filsys_id\"", users_id);
+    incremental_after("nfsquota", buffer, aargv);
     com_err(whoami, 0, "quota of %d assigned", quota);
+    if (ingres_errno) return(sms_errcode);
 
 ##  repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
 ##     where tblstats.table = "users"
 ##  repeat replace tblstats (appends = tblstats.appends + 1, modtime = "now")
 ##     where tblstats.table = "list" or tblstats.table = "filesys" or
 ##           tblstats.table = "nfsquota"
+    if (ingres_errno) return(sms_errcode);
     return(SMS_SUCCESS);
 ##}
 
@@ -2309,6 +2685,7 @@ int count;
 ##  repeat replace sh (value1 = sh.value1 + @n)
 ##         where sh.service = "POP" and sh.#mach_id = @mach_id
 
+    if (ingres_errno) return(sms_errcode);
     return(SMS_SUCCESS);
 ##}
 
@@ -2342,6 +2719,7 @@ validate_row(q, argv, v)
     /* look for the record */
 ##  range of rvar is table
 ##  retrieve (rowcount = count(rvar.name where qual))
+    if (ingres_errno) return(sms_errcode);
     if (rowcount == 0) return(SMS_NO_MATCH);
     if (rowcount > 1) return(SMS_NOT_UNIQUE);
     return(SMS_EXISTS);
@@ -2408,12 +2786,16 @@ validate_fields(q, argv, vo, n)
            status = SMS_EXISTS;
            break;
 
+       case V_LOCK:
+           status = lock_table(vo);
+           break;
        }
 
        if (status != SMS_EXISTS) return(status);
        vo++;
     }
 
+    if (ingres_errno) return(sms_errcode);
     return(SMS_SUCCESS);
 }
 
@@ -2472,9 +2854,11 @@ validate_id(argv, vo)
     idfield = vo->idfield;
     if (!strcmp(namefield, "uid")) {
 ##    retrieve (id = table.idfield) where table.namefield = int4(name)
+      if (ingres_errno) return(sms_errcode);
 ##    inquire_equel (rowcount = "rowcount")
     } else {
 ##    retrieve (id = table.idfield) where table.namefield = name
+      if (ingres_errno) return(sms_errcode);
 ##    inquire_equel (rowcount = "rowcount")
     }
     if (rowcount != 1) return(vo->error);
@@ -2502,6 +2886,7 @@ validate_name(argv, vo)
     }
 ##  retrieve (rowcount = countu(table.namefield 
 ##            where table.namefield = name))
+    if (ingres_errno) return(sms_errcode);
     return ((rowcount == 1) ? SMS_EXISTS : vo->error);
 ##}
 
@@ -2545,12 +2930,14 @@ struct valobj *vo;
        if (!strcmp(argv[vo->index], argv[vo->index - 1]))
          return(SMS_EXISTS);
 ##     retrieve (id = any(table.namefield where table.namefield = name))
+       if (ingres_errno) return(sms_errcode);
        if (id)
          return(vo->error);
        else
          return(SMS_EXISTS);
     }
 ##  retrieve (id = table.idfield) where table.namefield = name
+    if (ingres_errno) return(sms_errcode);
     if (id == -1 || id == *(int *)argv[vo->index - 1])
       return(SMS_EXISTS);
     else
@@ -2580,6 +2967,7 @@ validate_type(argv, vo)
 ##  repeat retrieve (exists = any(a.trans where a.name = @typename and
 ##                                   a.type = "TYPE" and
 ##                                   a.trans = @value))
+    if (ingres_errno) return(sms_errcode);
     return (exists ? SMS_EXISTS : vo->error);
 ##}
 
@@ -2607,6 +2995,7 @@ validate_typedata(q, argv, vo)
     /* get corresponding data type associated with field type name */
 ##  repeat retrieve (data_type = alias.trans) 
 ##         where alias.#name = @field_type and alias.type = "TYPEDATA"
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel (rowcount = "rowcount")
     if (rowcount != 1) return(SMS_TYPE);
 
@@ -2670,26 +3059,23 @@ validate_typedata(q, argv, vo)
 ##}
 
 
-/* This looks up a login name and returns the SMS internal ID.  It is used
- * by authenticate to put the users_id in the client structure.
- */
+/* Lock the table named by the validation object */
 
-int get_users_id(name)
-char *name;
+lock_table(vo)
+struct valobj *vo;
 ##{
-##  int id, rowcount;
-##  char *login;
-
-    login = name;
+##  char *table, *idfield;
+##  int rowcount;
 
-##  range of u is users
-##  repeat retrieve (id = u.#users_id) where u.#login = @login
+    table = vo->table;
+    idfield = vo->idfield;
+##  replace table (modtime = "now") where table.idfield = 0
+    if (ingres_errno) return(sms_errcode);
 ##  inquire_equel (rowcount = "rowcount")
-    
-    if (rowcount == 1)
-       return(id);
+    if (rowcount != 1)
+      return(vo->error);
     else
-       return(0);
+      return(SMS_EXISTS);
 ##}
 
 
This page took 0.117537 seconds and 4 git commands to generate.