* Copyright (C) 1987 by the Massachusetts Institute of Technology
*
* $Log$
- * Revision 1.2 1987-07-29 16:00:39 wesommer
- * Fixed add_locker.
+ * Revision 1.7 1987-08-04 01:49:41 wesommer
+ * Rearranged messages.
*
+Revision 1.6 87/08/04 01:10:02 wesommer
+Changes by mike; checked in prior to my hacking.
+
+Revision 1.5 87/07/30 14:54:13 wesommer
+Added debugging code in an attempt to catch a flakey problem.
+
+Revision 1.4 87/07/30 00:30:21 wesommer
+replaced appends = appends+1 with appends = tbs.appends+1
+
+Revision 1.3 87/07/30 00:26:11 wesommer
+Changes by mike prior to "appends" fix.
+
+Revision 1.2 87/07/29 16:00:39 wesommer
+Fixed add_locker.
+
Revision 1.1 87/07/29 15:13:57 wesommer
Initial revision
return(SMS_SUCCESS);
##}
+/**
+ ** access_pop - same as access_user plus verifies that a user has only one
+ ** mailbox of type "POP"
+ **
+ ** Inputs:
+ ** argv[0] - users_id
+ ** argv[1] - type
+ ** argv[2] - mach_id
+ ** argv[3] - box
+ **
+ ** Description:
+ ** - if q->name = "add_pobox" and type = "POP",
+ ** verify that no POP box already exists for user
+ ** - call access_user
+ **
+ **/
+
+access_pop(q, argv, cl)
+ struct query *q;
+ char *argv[];
+ client *cl;
+##{
+## int users_id;
+## int mach_id;
+## char *box;
+## int exists;
+
+ if (!bcmp(q->name, "add_pobox", 10) && !bcmp(argv[1], "POP", 4)) {
+ users_id = *(int *)argv[0];
+ mach_id = *(int *)argv[2];
+ box = argv[3];
+## range of p is pobox
+## repeat retrieve (exists = any(p.#box where p.#users_id = @users_id
+## and p.type = "POP"
+## and p.#mach_id = @mach_id
+## and p.#box = @box))
+ if (exists) return(SMS_EXISTS);
+ }
+
+ return(access_user(q, argv, cl));
+##}
+
/**
** access_list - check access for adding or deleting list members
**
return(SMS_SUCCESS);
##}
\f
+/**
+ ** setup_add_filesys - verify existance of referenced file systems
+ ** setup_update_filesys - same, except argv[1..5] --> argv[2..6]
+ **
+ ** Inputs: Add Update
+ ** argv[0] - label label
+ ** argv[1] - type new label
+ ** argv[2] - mach_id type
+ ** argv[3] - name mach_id
+ ** argv[4] - mount name
+ ** argv[5] - access mount
+ ** argv[6] - access
+ **
+ ** Description:
+ ** - for type = RVD:
+ ** * verify mach_id/name in rvdvirt
+ ** * verify access in {r, x, R, X}
+ ** - for type = NFS:
+ ** * extract directory prefix from name
+ ** * verify mach_id/dir in nfsphys
+ ** * verify access in {r, w, R, W}
+ **
+ ** Errors:
+ ** SMS_RVD - no such rvd
+ ** SMS_NFS - specified directory not exported
+ ** SMS_FILESYS_ACCESS - invalid filesys access
+ **
+ **/
+
+setup_add_filesys(q, argv)
+ struct query *q;
+ char *argv[];
+{
+ char *type;
+ int mach_id;
+ char *name;
+ char *access;
+
+ type = argv[1];
+ mach_id = *(int *)argv[2];
+ name = argv[3];
+ access = argv[5];
+
+ if (!bcmp(type, "RVD", 3))
+ return (check_rvd(mach_id, name, access));
+ else if (!bcmp(type, "NFS", 3))
+ return (check_nfs(mach_id, name, access));
+ else
+ return(SMS_SUCCESS);
+}
+
+setup_update_filesys(q, argv)
+ struct query *q;
+ char *argv[];
+{
+ char *type;
+ int mach_id;
+ char *name;
+ char *access;
+
+ type = argv[2];
+ mach_id = *(int *)argv[3];
+ name = argv[4];
+ access = argv[6];
+
+ if (!bcmp(type, "RVD", 3))
+ return (check_rvd(mach_id, name, access));
+ else if (!bcmp(type, "NFS", 3))
+ return (check_nfs(mach_id, name, access));
+ else
+ return(SMS_SUCCESS);
+}
+
+##check_rvd(mach_id, name, access)
+## int mach_id;
+## char *name;
+ char *access;
+##{
+## int rowcount;
+ char caccess;
+
+## range of rv is rvdvirt
+## retrieve (rowcount = any(rv.#name where rv.#mach_id = mach_id and
+## rv.#name = name))
+ if (rowcount == 0) return(SMS_RVD);
+
+ caccess = (isupper(*access)) ? tolower(*access) : *access;
+ if (caccess != 'r' && caccess != 'x') return(SMS_FILESYS_ACCESS);
+
+ return(SMS_SUCCESS);
+##}
+
+##check_nfs(mach_id, name, access)
+## int mach_id;
+ char *name;
+ char *access;
+##{
+## int rowcount;
+## char dir[32];
+ char caccess;
+ register char *cp1;
+ register char *cp2;
+
+ caccess = (isupper(*access)) ? tolower(*access) : *access;
+ if (caccess != 'r' && caccess != 'w') return(SMS_FILESYS_ACCESS);
+
+## range of np is nfsphys
+## retrieve (dir = np.#dir) where np.#mach_id = mach_id
+## {
+ cp1 = name;
+ cp2 = dir;
+ while (*cp2) {
+ if (*cp1++ != *cp2) break;
+ cp2++;
+ }
+ if (*cp2 == 0) return(SMS_SUCCESS);
+## }
+
+ return(SMS_NFS);
+##}
+\f
/* Followup Routines */
set_user_modtime(q, argv)
return(SMS_SUCCESS);
##}
+/**
+ ** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
+ **
+ ** Inputs:
+ ** q->name - "add_pobox" or "delete_pobox"
+ ** argv[2] - mach_id
+ **
+ ** Description:
+ ** - incr/decr value field in serverhosts table for pop/mach_id
+ **
+ **/
+
+set_pop_usage(q, argv)
+ struct query *q;
+ char *argv[];
+##{
+## int mach_id;
+
+ mach_id = *(int *)argv[2];
+## range of sh is serverhosts
+
+ if (!bcmp(q->name, "add_pobox", 10)) {
+## repeat replace sh (value1 = sh.value1 + 1)
+## where sh.service = "pop" and sh.#mach_id = @mach_id
+ } else if (!bcmp(q->name, "delete_pobox", 13)) {
+## repeat replace sh (value1 = sh.value1 - 1)
+## where sh.service = "pop" and sh.#mach_id = @mach_id
+ }
+
+ return(SMS_SUCCESS);
+##}
+
/**
** delete_list_members - called after the delete_list query to clean up
** members table.
## char shutdown[33];
## int list_id;
- targv[1] = oper;
- targv[2] = admin;
- targv[3] = shutdown;
+ targv[0] = oper;
+ targv[1] = admin;
+ targv[2] = shutdown;
## range of l is list
while (sq_get_data(sq, &argv)) {
- sscanf(argv[1], "%d", &list_id);
+ sscanf(argv[0], "%d", &list_id);
## repeat retrieve (oper = l.name) where l.#list_id = @list_id
- sscanf(argv[2], "%d", &list_id);
+ sscanf(argv[1], "%d", &list_id);
## repeat retrieve (admin = l.name) where l.#list_id = @list_id
- sscanf(argv[3], "%d", &list_id);
+ sscanf(argv[2], "%d", &list_id);
## repeat retrieve (shutdown = l.name) where l.#list_id = @list_id
- targv[0] = argv[0];
- (*action)(4, targv, actarg);
+ (*action)(3, targv, actarg);
free(argv[0]);
free(argv[1]);
free(argv[2]);
- free(argv[3]);
}
sq_destroy(sq);
char *object;
##{
## char *name;
-## int id;
name = object;
## range of v is values
-## repeat retrieve (id = v.value) where v.#name = @name
- id++;
-## repeat replace v (value = @id) where v.#name = @name
+## repeat replace v (value = v.value + 1) where v.#name = @name
+ return(SMS_SUCCESS);
+##}
+
+/**
+ ** get_query_need - check modtime of query's associated table against given
+ ** time and return true if greater (false if not)
+ **
+ ** Inputs:
+ ** argv[0] - query name
+ ** argv[1] - time to compare against
+ **
+ **/
+
+get_query_need(q, argv, action, actarg)
+ struct query *q;
+ register char *argv[];
+ int (*action)();
+##{
+ struct query *q1;
+## char *last_get_time;
+## char *table;
+## int need;
+ char *result;
+ struct query *get_query_by_name();
+
+ q1 = get_query_by_name(argv[0]);
+
+ last_get_time = argv[1];
+ table = q1->rtable;
+
+ if (q1->type != RETRIEVE || table == (char *)0) return(SMS_NO_MATCH);
+
+## range of tbs is tblstats
+## repeat retrieve (need = any(tbs.modtime where tbs.#table = @table and
+## tbs.modtime > @last_get_time))
+
+ result = (need) ? "true" : "false";
+ (*action)(1, &result, actarg);
return(SMS_SUCCESS);
##}
## char *device;
## int quota;
## int rowcount;
-## char *login;
+## char login[9];
## char dir[32];
## int allocated;
## char locker[64];
## range of u is users
## range of f is filesys
## range of np is nfsphys
+## range of tbs is tblstats
/* get login name */
## repeat retrieve (login = u.#login) where u.#users_id = @users_id
/* get filesystem directory prefix; give error if machine/device
pair not in nfsphys table */
+ printf("np.mach_id = %d and np.device = %s\n", mach_id, device);
+
## repeat retrieve (dir = np.#dir, allocated = np.#allocated)
## where np.#mach_id = @mach_id and np.#device = device
## inquire_equel (rowcount = "rowcount")
## (#label = @login, type = "NFS", #mach_id = @mach_id,
## name = @locker, access = "w", order = 1, #mount = @mount,
## acl_id = @user_acl)
+## repeat replace tbs (appends = tbs.appends + 1, modtime = "now")
+## where tbs.table = "filesys"
/* increment usage count in nfsphys table */
allocated += quota;
## replace np (#allocated = allocated)
## where np.#mach_id = mach_id and np.#device = device
+## repeat replace tbs (updates = tbs.updates + 1, modtime = "now")
+## where tbs.table = "nfsphys"
/* create nfsquota entry */
## append nfsquota (#users_id = users_id, #mach_id = mach_id,
## #device = device, #quota = quota)
+## repeat replace tbs (appends = tbs.appends + 1, modtime = "now")
+## where tbs.table = "nfsquota"
+
+ return(SMS_SUCCESS);
+##}
+
+/**
+ ** delete_locker - special query routine for deleting a user locker
+ **
+ ** Inputs:
+ ** argv[0] - users_id
+ ** argv[1] - machine_id
+ ** argv[2] - device
+ ** argv[3] - quota
+ **
+ ** Description:
+ ** - delete filesys entry (label=<login>)
+ ** - decrement allocated in nfsphys by quota
+ ** - delete nfsquota entry
+ **
+ ** Errors:
+ ** - SMS_FILESYS - no filesys exists for user
+ **
+ **/
+
+delete_locker(q, argv)
+ register struct query *q;
+ register char *argv[];
+##{
+## int users_id;
+## int mach_id;
+## char *device;
+## int quota;
+## int rowcount;
+## char login[9];
+
+ /* copy arguments */
+ users_id = *(int *)argv[0];
+ mach_id = *(int *)argv[1];
+ device = argv[2];
+ sscanf(argv[3], "%d", "a);
+
+## range of u is users
+## range of f is filesys
+## range of np is nfsphys
+## range of nq is nfsquota
+## range of tbs is tblstats
+
+ /* get login name */
+## repeat retrieve (login = u.#login) where u.#users_id = @users_id
+
+ /* delete the filesys entry */
+## repeat delete f where f.label = @login
+## inquire_equel (rowcount = "rowcount")
+ if (rowcount == 0) return(SMS_FILESYS);
+## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now")
+## where tbs.table = "filesys"
+
+ /* decrement usage count in nfsphys table */
+## replace np (#allocated = np.#allocated - quota)
+## where np.#mach_id = mach_id and np.#device = device
+## repeat replace tbs (updates = tbs.updates + 1, modtime = "now")
+## where tbs.table = "nfsphys"
+
+ /* delete nfsquota entry */
+## delete nq where nq.#users_id = users_id and nq.#mach_id = mach_id and
+## nq.#device = device
+## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now")
+## where tbs.table = "nfsquota"
+
+ return(SMS_SUCCESS);
+##}
+\f
+/**
+ ** get_members_of_list - optimized query for retrieval of list members
+ **
+ ** Inputs:
+ ** argv[0] - list_id
+ **
+ ** Description:
+ ** - retrieve USER members, then LIST members, then STRING members
+ **
+ **/
+
+get_members_of_list(q, argv, action, actarg)
+ struct query *q;
+ char *argv[];
+ int (*action)();
+ int actarg;
+##{
+## int list_id;
+## char member_name[129];
+ char *targv[2];
+
+ list_id = *(int *)argv[0];
+ targv[0] = "USER";
+ targv[1] = member_name;
+
+## range of m is members
+## repeat retrieve (member_name = users.login)
+## where m.#list_id = @list_id and m.member_type = "USER"
+## and m.member_id = users.users_id
+## {
+ (*action)(2, targv, actarg);
+## }
+
+ 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
+## {
+ (*action)(2, targv, actarg);
+## }
+
+ 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
+## {
+ (*action)(2, targv, actarg);
+## }
+
+ return(SMS_SUCCESS);
+##}
+
+/**
+ ** get_all_poboxes - optimize query for retrieval of all poboxes
+ **
+ ** Description:
+ ** - retrieve LOCAL boxes, then POP boxes, then FOREIGN boxes
+ **
+ **/
+
+get_all_poboxes(q, argv, action, actarg)
+ struct query *q;
+ char *argv[];
+ int (*action)();
+ int actarg;
+##{
+## char login[9];
+## char machine[129];
+## char box[129];
+ char *targv[4];
+
+ targv[0] = login;
+ targv[2] = machine;
+ targv[3] = box;
+
+ targv[1] = "LOCAL";
+## range of p is pobox
+## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
+## where p.type = "LOCAL" and p.users_id = users.users_id
+## and p.mach_id = #machine.mach_id
+## {
+ (*action)(4, targv, actarg);
+## }
+
+ targv[1] = "POP";
+## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
+## where p.type = "POP" and p.users_id = users.users_id
+## and p.mach_id = #machine.mach_id
+## {
+ (*action)(4, targv, actarg);
+## }
+
+ targv[1] = "FOREIGN";
+## repeat retrieve (login=users.#login, machine=strings.string, box=p.#box)
+## where p.type = "FOREIGN" and p.users_id = users.users_id
+## and p.mach_id = strings.string_id
+## {
+ (*action)(4, targv, actarg);
+## }
return(SMS_SUCCESS);
##}
table = q->rtable;
name = v->field;
- /* tell the logfile what we're doing */
- com_err(whoami, 0, "validating row");
- com_err(whoami, 0, qual);
-
+ if (log_flags & LOG_RES)
+ /* tell the logfile what we're doing */
+ com_err(whoami, 0, "validating row: %s", qual);
+
/* look for the record */
## range of rvar is table
## retrieve (rowcount = count(rvar.name where qual))
- com_err(whoami, 0, "row validated");
if (rowcount == 0) return(SMS_NO_MATCH);
if (rowcount > 1) return(SMS_NOT_UNIQUE);
return(SMS_EXISTS);
while (--n >= 0) {
switch (vo->type) {
case V_NAME:
- sprintf(buf, "validating %s in %s: %s",
+ if (log_flags&LOG_RES)
+ com_err(whoami, 0, "validating %s in %s: %s",
vo->namefield, vo->table, argv[vo->index]);
- com_err(whoami, 0, buf);
status = validate_name(argv, vo);
break;
case V_ID:
- sprintf(buf, "validating %s in %s: %s",
+ if (log_flags&LOG_RES)
+ com_err(whoami, 0, "validating %s in %s: %s",
vo->idfield, vo->table, argv[vo->index]);
- com_err(whoami, 0, buf);
status = validate_id(argv, vo);
break;
case V_TYPE:
- sprintf(buf, "validating %s type: %s",
+ if (log_flags&LOG_RES)
+ com_err(whoami, 0, "validating %s type: %s",
vo->table, argv[vo->index]);
- com_err(whoami, 0, buf);
status = validate_type(argv, vo);
break;
case V_TYPEDATA:
- sprintf(buf, "validating type-specific data: %s",
+ if (log_flags&LOG_RES)
+ com_err(whoami, 0, "validating type-specific data: %s",
argv[vo->index]);
- com_err(whoami, 0, buf);
status = validate_typedata(q, argv, vo);
break;