2 * These are query support routines that are specific to the old version
3 * of the protocol. This file may be removed once support for the old
4 * protocol has been discontinued.
10 * Copyright (C) 1987 by the Massachusetts Institute of Technology
11 * For copying and distribution information, please see the file
17 static char *rcsid_qsupport_qc = "$Header$";
20 #include <mit-copyright.h>
22 #include "sms_server.h"
29 add_locker() { return(SMS_UNKNOWN_PROC); }
30 add_user_group() { return(SMS_UNKNOWN_PROC); }
33 /* Specialized Access Routines */
37 ** access_maillist - access_list + disallow adding user-group to maillists
45 access_maillist(q, argv, cl)
52 ## char list_name[32];
55 if ((status = access_list(q, argv, cl)) != SMS_SUCCESS)
57 if (strcmp(q->name, "add_maillist"))
60 list_id = *(int *)argv[0];
62 ## repeat retrieve (exists = any(l.#list_id
63 ## where l.group != 0 and l.#list_id = @list_id))
64 if (!exists) return(SMS_SUCCESS);
65 ## repeat retrieve (exists = any(users.login where users.login = l.name and
66 ## l.#list_id = @list_id))
67 return ((exists) ? SMS_USER_GROUP : SMS_SUCCESS);
76 /* FOLLOWUP ROUTINES */
78 /* followup_gpob: fixes argv[2] based on the IDs currently there and the
79 * type in argv[1]. Then completes the upcall to the user.
81 * argv[2] is of the form "123:234" where the first integer is the machine
82 * ID if it is a pop box, and the second is the string ID if it is an SMTP
83 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
86 * followup_old_gpob does the same thing for old style queries. The format
87 * is a little different and there is one more argument, but the idea is
91 followup_old_gpob(q, sq, v, action, actarg, cl)
92 register struct query *q;
93 register struct save_queue *sq;
94 register struct validate *v;
95 register int (*action)();
99 char **argv, *p, *index();
101 ## char mach[129], box[129];
105 while (sq_get_data(sq, &argv)) {
107 sms_trim_args(2, argv);
109 if (!strcmp(ptype, "POP")) {
111 ## repeat retrieve (mach=machine.name) where machine.mach_id=@id
112 strcpy(box, argv[0]);
113 } else if (!strcmp(ptype, "SMTP")) {
115 ## repeat retrieve (box=strings.string) where strings.string_id=@id
116 ## inquire_equel(rowcount = "rowcount")
125 } else /* ptype == "NONE" */ {
133 (*action)(q->vcnt, argv, actarg);
135 /* free saved data */
142 return (SMS_SUCCESS);
146 /* Specialized query routines */
148 /* set_user_pobox - this does all of the real work.
149 * argv = user_id, type, machine, box
151 int set_user_pobox(q, argv, cl)
156 ## int user, id, rowcount;
161 user = *(int *)argv[0];
163 if (!strcmp(argv[1], "POP")) {
164 ## repeat retrieve (id=machine.mach_id) where machine.name=uppercase(@host)
165 ## inquire_equel(rowcount = "rowcount")
168 ## replace users (potype="POP", pop_id=id) where users.users_id = user
169 } else if (!strcmp(argv[1], "SMTP")) {
170 sprintf(buffer, "%s@%s", argv[3], host);
171 ## range of s is strings
172 ## repeat retrieve (id = s.string_id) where s.string = @buffer
173 ## inquire_equel (rowcount = "rowcount")
175 ## range of v is values
176 ## repeat retrieve (id = v.value) where v.name = "strings_id"
178 ## repeat replace v (value = @id) where v.name = "strings_id"
179 ## append to strings (string_id = id, string = buffer)
181 ## repeat replace users (potype="SMTP",box_id=@id)
182 ## where users.users_id = @user
183 } else /* argv[1] == "NONE" */ {
184 ## repeat replace users (potype="NONE") where users.users_id = @user
186 set_old_pop_usage(q, argv, 1);
187 set_pobox_modtime(q, argv, cl);
191 followup_delete_pobox(q, argv, cl)
196 set_old_pop_usage(q, argv, -1);
197 set_pobox_modtime(q, argv, cl);
201 /** set_old_pop_usage - incr/decr usage count for pop server in serverhosts
205 ** q->name - "add_pobox" or "delete_pobox"
210 ** - incr/decr value field in serverhosts table for pop/mach_id
214 set_old_pop_usage(q, argv, count)
221 if (bcmp(argv[1], "POP", 3)) return(SMS_SUCCESS);
223 mach_id = *(int *)argv[2];
226 ## range of sh is serverhosts
227 ## repeat replace sh (value1 = sh.value1 + @n)
228 ## where sh.service = "pop" and sh.#mach_id = @mach_id
234 /* Finds "acl_type:acl_name" in the argv (index depends on query) and
235 * replaces it with the list or user name.
238 followup_fix_acl(q, sq, v, action, actarg, cl)
239 register struct query *q;
240 register struct save_queue *sq;
241 register struct validate *v;
242 register int (*action)();
246 char **argv, *p, *index(), *malloc();
248 ## int id, i, rowcount;
251 if (!strcmp(q->shortname, "gaml"))
253 else if (!strcmp(q->shortname, "gamd"))
258 while (sq_get_data(sq, &argv)) {
260 p = index(name, ':');
263 if ((acl = malloc(33)) == NULL)
265 if (!strcmp(name, "LIST")) {
266 ## repeat retrieve (acl = list.#name) where list.list_id = @id
267 ## inquire_equel(rowcount = "rowcount")
270 } else if (!strcmp(name, "USER")) {
271 ## repeat retrieve (acl = users.login) where users.users_id = @id
272 ## inquire_equel(rowcount = "rowcount")
281 (*action)(q->vcnt, argv, actarg);
283 /* free saved data */
284 for (i = 0; i < q->vcnt; i++)
290 return (SMS_SUCCESS);
296 ** get_list_is_maillist
306 get_list_is_group(q, argv, cl, action, actarg)
313 ## int exists, list_id, rowcount;
316 list_id = *(int *)argv[0];
318 ## range of l is list
319 ## repeat retrieve (exists = l.group) where l.#list_id = @list_id
320 ## inquire_equel(rowcount = "rowcount")
322 return(SMS_NOT_UNIQUE);
324 result = (exists) ? "true" : "false";
325 (*action)(1, &result, actarg);
329 get_list_is_maillist(q, argv, cl, action, actarg)
336 ## int exists, list_id, rowcount;
339 list_id = *(int *)argv[0];
341 ## range of l is list
342 ## repeat retrieve (exists = l.maillist) where l.#list_id = @list_id
343 ## inquire_equel(rowcount = "rowcount")
345 return(SMS_NOT_UNIQUE);
347 result = (exists) ? "true" : "false";
348 (*action)(1, &result, actarg);
353 /* implements the get lists of administrator query. It's fairly
354 * straightforward, but too complex for the regular query table.
355 * First retrieve any lists with a USER acl which matches the
356 * specified user. Then retrieve any lists with an acl which is a
357 * list which has the specified user as a member.
360 get_lists_of_administrator(q, argv, cl, action, actarg)
371 ## range of l is list
372 ## range of m is members
373 user = *(int *) argv[0];
376 ## repeat retrieve (name = l.#name)
377 ## where l.acl_type = "USER" and l.acl_id = @user {
378 (*action)(1, &args, actarg);
381 ## repeat retrieve (name = l.#name)
382 ## where l.acl_type = "LIST" and l.acl_id = m.#list_id
383 ## and m.member_type = "USER" and m.member_id = @user {
384 (*action)(1, &args, actarg);
391 ** Setup routine for add_group
395 ** Description: allocate next gid and store in values table
399 setup_add_group(q, argv, cl)
404 ## int ngid, exists, rowcount, list_id;
407 ## range of l is list
408 ## range of v is values
409 list_id = *(int *)argv[0];
411 ## repeat retrieve (exists = l.group) where l.#list_id = @list_id
415 ## repeat retrieve (ngid = v.value) where v.name = "gid"
419 ## repeat retrieve (exists = any(l.#gid where l.#gid = @ngid))
422 ## repeat replace v (value = @ngid) where v.name = "gid"
423 ## inquire_equel (rowcount = "rowcount")
424 if (rowcount != 1) return SMS_INGRES_ERR;
425 else return(SMS_SUCCESS);
429 ** get_groups_of_user - optimized query for retrieval of all groups to
430 ** which a user belongs
434 get_groups_of_user(q, argv, cl, action, actarg)
442 ## char list_name[33];
447 users_id = *(int *)argv[0];
448 targv[0] = list_name;
451 ## range of m is members
452 ## range of l is list
454 ## repeat retrieve (list_name = l.name, gid = text(l.#gid))
455 ## where m.member_id = @users_id and m.member_type = "USER" and
456 ## m.list_id = l.list_id and l.group != 0
457 ## sort by #list_name
459 (*action)(2, targv, actarg);
461 ## inquire_equel (rowcount = "rowcount")
463 return ((rowcount = 0) ? SMS_NO_MATCH : SMS_SUCCESS);
466 get_groups_of_all_users(q, argv, cl, action, actarg)
483 ## range of u is users
484 ## range of l is list
485 ## range of m is members
487 ## set lockmode session where readlock = nolock
489 ## repeat retrieve (login = u.#login, group = l.name, gid = text(l.#gid))
490 ## where m.member_type = "USER" and m.member_id = u.users_id and
491 ## u.status != 0 and m.list_id = l.list_id and l.group != 0
492 ## sort by #login, #group
494 (*action)(3, targv, actarg);
497 ## inquire_equel (errorno = "errorno")
498 ## set lockmode session where readlock = system
500 return((errorno) ? SMS_INGRES_ERR : SMS_SUCCESS);
504 /* expand_list_flags - takes the flag value stuffed into list.active of
505 * the list just created, and expands that value into hidden & public,
506 * then sets the modtime on the list.
508 expand_list_flags(q, argv, cl)
513 ## int id, flags, active, public, hidden, who;
516 if (!strcmp(q->shortname, "ulis")) {
517 id = *(int *)argv[0];
519 ## repeat retrieve (id = values.value) where values.name = "list_id"
522 ## repeat retrieve (flags = l.#active) where l.list_id = @id
524 public = (flags & 2) >> 1;
525 hidden = (flags & 4) >> 2;
528 ## repeat replace l (#active = @active, #public = @public, #hidden = @hidden,
529 ## modtime = "now", modby = @who, modwith = @entity)
530 ## where l.list_id = @id
537 ** delete_current_quota - adjust nfsphys values on xxx_quota queries.
542 ** argv[2] - users_id
543 ** argv[3] - quota (add_new_quota only)
546 ** delete_current_quota:
547 ** - find nfsquota entry
548 ** - decrement nfsphys.allocated by nfsquota.quota
550 ** - increment nfsphys.allocated by quota
554 add_new_quota(q, argv, cl)
556 register char *argv[];
563 mach_id = *(int*)argv[0];
565 quota = *(int *)argv[3];
567 ## range of np is nfsphys
568 ## repeat replace np (allocated = np.allocated + @quota)
569 ## where np.#mach_id = @mach_id and np.#device = @device
574 delete_current_quota(q, argv, cl)
576 register char *argv[];
584 mach_id = *(int *)argv[0];
586 users_id = *(int *)argv[2];
588 ## range of np is nfsphys
589 ## range of nq is nfsquota
590 ## repeat retrieve (quota = nq.#quota)
591 ## where nq.#mach_id = @mach_id and nq.#device = @device and
592 ## nq.#users_id = @users_id
593 ## repeat replace np (allocated = np.allocated - @quota)
594 ## where np.#mach_id = @mach_id and np.#device = @device
601 ** delete_locker - special query routine for deleting a user locker
604 ** argv[0] - users_id
607 ** - get login name from users_id
608 ** - get filesys entry from login
609 ** - use filesys.mach_id and filesys.name to determine machine/device
610 ** pair for nfsphys and nfsquota
611 ** - delete filesys entry (label=<login>)
612 ** - decrement allocated in nfsphys by quota
613 ** - delete nfsquota entry
616 ** - SMS_FILESYS - no filesys exists for user
620 delete_locker(q, argv)
621 register struct query *q;
622 register char *argv[];
635 users_id = *(int *)argv[0];
637 ## range of u is users
638 ## range of f is filesys
639 ## range of np is nfsphys
640 ## range of nq is nfsquota
641 ## range of tbs is tblstats
644 ## repeat retrieve (login = u.#login) where u.#users_id = @users_id
646 /* get mach_id and locker name from filesys entry; then delete it */
647 ## repeat retrieve (mach_id = f.#mach_id, lname = f.#name)
648 ## where f.#label = @login
649 ## inquire_equel (rowcount = "rowcount")
650 if (rowcount == 0) return(SMS_FILESYS);
651 ## repeat delete f where f.#label = @login
653 /* get prefix directory */
654 c = rindex(lname, '/');
658 ## repeat retrieve (ndev = np.device)
659 ## where np.#mach_id = @mach_id and np.dir = @lname
661 /* get quota from nfsquota entry; then delete entry */
662 ## repeat retrieve (quota = nq.#quota)
663 ## where nq.#mach_id = @mach_id and nq.#device = @ndev and
664 ## nq.#users_id = @users_id
665 ## repeat delete nq where nq.#mach_id = @mach_id and nq.#device = @ndev and
666 ## nq.#users_id = @users_id
668 /* decrement nfsphys.allocated */
669 ## repeat replace np (allocated = np.allocated - @quota)
670 ## where np.#mach_id = @mach_id and np.#device = @ndev
672 /* adjust table statistics */
673 ## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now")
674 ## where tbs.table = "filesys"
675 ## repeat replace tbs (updates = tbs.updates + 1, modtime = "now")
676 ## where tbs.table = "nfsphys"
677 ## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now")
678 ## where tbs.table = "nfsquota"