]> andersk Git - moira.git/blame - server/qoldsup.qc
Used /bin/sh format instead of /bin/csh format, by accident.
[moira.git] / server / qoldsup.qc
CommitLineData
e8660f0a 1/*
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.
5 *
6 * $Source$
7 * $Author$
8 * $Header$
9 *
10 * Copyright (C) 1987 by the Massachusetts Institute of Technology
c801de4c 11 * For copying and distribution information, please see the file
12 * <mit-copyright.h>.
e8660f0a 13 *
14 */
15
16#ifndef lint
17static char *rcsid_qsupport_qc = "$Header$";
18#endif lint
19
c801de4c 20#include <mit-copyright.h>
e8660f0a 21#include "query.h"
22#include "sms_server.h"
23#include <ctype.h>
24
25
26extern char *whoami;
27
28
29add_locker() { return(SMS_UNKNOWN_PROC); }
30add_user_group() { return(SMS_UNKNOWN_PROC); }
31
32
33/* Specialized Access Routines */
34
35
36/**
37 ** access_maillist - access_list + disallow adding user-group to maillists
38 **
39 ** Inputs:
40 ** argv[0] - list_id
41 ** cl - client name
42 **
43 **/
44
45access_maillist(q, argv, cl)
46 struct query *q;
47 char *argv[];
48 client *cl;
49##{
50## int list_id;
51## int exists;
52## char list_name[32];
53 int status;
54
55 if ((status = access_list(q, argv, cl)) != SMS_SUCCESS)
56 return(status);
57 if (strcmp(q->name, "add_maillist"))
58 return(status);
59
60 list_id = *(int *)argv[0];
61## range of l is list
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);
68##}
69
70
71\f
72/* Setup Routines */
73
74
75\f
76/* FOLLOWUP ROUTINES */
77
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.
80 *
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
84 * are skipped.
85 *
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
88 * the same.
89 */
90
91followup_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)();
96 int actarg;
97 client *cl;
98##{
99 char **argv, *p, *index();
100 char *ptype;
101## char mach[129], box[129];
102## int id, rowcount;
103
104 /* for each row */
105 while (sq_get_data(sq, &argv)) {
106 ptype = argv[1];
107 sms_trim_args(2, argv);
108
109 if (!strcmp(ptype, "POP")) {
110 id = atoi(argv[2]);
111## repeat retrieve (mach=machine.name) where machine.mach_id=@id
112 strcpy(box, argv[0]);
113 } else if (!strcmp(ptype, "SMTP")) {
114 id = atoi(argv[3]);
115## repeat retrieve (box=strings.string) where strings.string_id=@id
116## inquire_equel(rowcount = "rowcount")
117 if (rowcount != 1)
118 return(SMS_STRING);
119 p = index(box, '@');
120 if (p) {
121 *p++ = 0;
122 strcpy(mach, p);
123 } else
124 strcpy(mach, "");
125 } else /* ptype == "NONE" */ {
126 goto skip;
127 }
128
129 free(argv[2]);
130 argv[2] = mach;
131 free(argv[3]);
132 argv[3] = box;
133 (*action)(q->vcnt, argv, actarg);
134 skip:
135 /* free saved data */
136 free(argv[0]);
137 free(argv[1]);
138 free(argv);
139 }
140
141 sq_destroy(sq);
142 return (SMS_SUCCESS);
143##}
144
145\f
146/* Specialized query routines */
147
148/* set_user_pobox - this does all of the real work.
149 * argv = user_id, type, machine, box
150 */
151int set_user_pobox(q, argv, cl)
152 struct query *q;
153 char **argv;
154 client *cl;
155##{
156## int user, id, rowcount;
157## char *host;
158## char buffer[256];
159
160 host = argv[2];
161 user = *(int *)argv[0];
162
163 if (!strcmp(argv[1], "POP")) {
164## repeat retrieve (id=machine.mach_id) where machine.name=uppercase(@host)
165## inquire_equel(rowcount = "rowcount")
166 if (rowcount == 0)
167 return(SMS_MACHINE);
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")
174 if (rowcount == 0) {
175## range of v is values
176## repeat retrieve (id = v.value) where v.name = "strings_id"
177 id++;
178## repeat replace v (value = @id) where v.name = "strings_id"
179## append to strings (string_id = id, string = buffer)
180 }
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
185 }
186 set_old_pop_usage(q, argv, 1);
187 set_pobox_modtime(q, argv, cl);
188 return(SMS_SUCCESS);
189##}
190
191followup_delete_pobox(q, argv, cl)
192 struct query *q;
193 char *argv[];
194 client *cl;
195{
196 set_old_pop_usage(q, argv, -1);
197 set_pobox_modtime(q, argv, cl);
198 return(SMS_SUCCESS);
199}
200
201/** set_old_pop_usage - incr/decr usage count for pop server in serverhosts
202 ** table
203 **
204 ** Inputs:
205 ** q->name - "add_pobox" or "delete_pobox"
206 ** argv[1] - type
207 ** argv[2] - mach_id
208 **
209 ** Description:
210 ** - incr/decr value field in serverhosts table for pop/mach_id
211 **
212 **/
213
214set_old_pop_usage(q, argv, count)
215 struct query *q;
216 char *argv[];
217##{
218## int mach_id;
219## int n;
220
221 if (bcmp(argv[1], "POP", 3)) return(SMS_SUCCESS);
222
223 mach_id = *(int *)argv[2];
224 n = count;
225
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
229
230 return(SMS_SUCCESS);
231##}
232
233
234/* Finds "acl_type:acl_name" in the argv (index depends on query) and
235 * replaces it with the list or user name.
236 */
237
238followup_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)();
243 int actarg;
244 client *cl;
245##{
246 char **argv, *p, *index(), *malloc();
247## char *name, *acl;
248## int id, i, rowcount;
249 int idx;
250
251 if (!strcmp(q->shortname, "gaml"))
252 idx = 1;
253 else if (!strcmp(q->shortname, "gamd"))
254 idx = 1;
255 else
256 idx = 2;
257
258 while (sq_get_data(sq, &argv)) {
259 name = argv[idx];
260 p = index(name, ':');
261 *p++ = 0;
262 id = atoi(p);
263 if ((acl = malloc(33)) == NULL)
264 return(SMS_NO_MEM);
265 if (!strcmp(name, "LIST")) {
266## repeat retrieve (acl = list.#name) where list.list_id = @id
267## inquire_equel(rowcount = "rowcount")
268 if (rowcount != 1)
269 strcpy(acl, "???");
270 } else if (!strcmp(name, "USER")) {
271## repeat retrieve (acl = users.login) where users.users_id = @id
272## inquire_equel(rowcount = "rowcount")
273 if (rowcount != 1)
274 strcpy(acl, "???");
275 } else
276 strcpy(acl, "???");
277 free(argv[idx]);
278 argv[idx] = acl;
279
280 /* send the data */
281 (*action)(q->vcnt, argv, actarg);
282
283 /* free saved data */
284 for (i = 0; i < q->vcnt; i++)
285 free(argv[i]);
286 free(argv);
287 }
288
289 sq_destroy(sq);
290 return (SMS_SUCCESS);
291##}
292
293
294/**
295 ** get_list_is_group
296 ** get_list_is_maillist
297 **
298 ** Inputs:
299 ** argv[0] - list_id
300 **
301 ** Returns:
302 ** {true | false}
303 **
304 **/
305
306get_list_is_group(q, argv, cl, action, actarg)
307 struct query *q;
308 char *argv[];
309 client *cl;
310 int (*action)();
311 int actarg;
312##{
313## int exists, list_id, rowcount;
314 char *result;
315
316 list_id = *(int *)argv[0];
317
318## range of l is list
319## repeat retrieve (exists = l.group) where l.#list_id = @list_id
320## inquire_equel(rowcount = "rowcount")
321 if (rowcount != 1)
322 return(SMS_NOT_UNIQUE);
323
324 result = (exists) ? "true" : "false";
325 (*action)(1, &result, actarg);
326 return(SMS_SUCCESS);
327##}
328
329get_list_is_maillist(q, argv, cl, action, actarg)
330 struct query *q;
331 char *argv[];
332 client *cl;
333 int (*action)();
334 int actarg;
335##{
336## int exists, list_id, rowcount;
337 char *result;
338
339 list_id = *(int *)argv[0];
340
341## range of l is list
342## repeat retrieve (exists = l.maillist) where l.#list_id = @list_id
343## inquire_equel(rowcount = "rowcount")
344 if (rowcount != 1)
345 return(SMS_NOT_UNIQUE);
346
347 result = (exists) ? "true" : "false";
348 (*action)(1, &result, actarg);
349 return(SMS_SUCCESS);
350##}
351
352
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.
358 */
359
360get_lists_of_administrator(q, argv, cl, action, actarg)
361 struct query *q;
362 char *argv[];
363 client *cl;
364 int (*action)();
365 int actarg;
366##{
367## int user;
368## char name[33];
369 char *args;
370
371## range of l is list
372## range of m is members
373 user = *(int *) argv[0];
374 args = name;
375
376## repeat retrieve (name = l.#name)
377## where l.acl_type = "USER" and l.acl_id = @user {
378 (*action)(1, &args, actarg);
379## }
380
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);
385## }
386 return(SMS_SUCCESS);
387##}
388
389
390/**
391 ** Setup routine for add_group
392 **
393 ** Inputs: none
394 **
395 ** Description: allocate next gid and store in values table
396 **
397 **/
398
399setup_add_group(q, argv, cl)
400 struct query *q;
401 char *argv[];
402 client *cl;
403##{
404## int ngid, exists, rowcount, list_id;
405 int status;
406
407## range of l is list
408## range of v is values
409 list_id = *(int *)argv[0];
410
411## repeat retrieve (exists = l.group) where l.#list_id = @list_id
412 if (exists)
413 return(SMS_EXISTS);
414
415## repeat retrieve (ngid = v.value) where v.name = "gid"
416 exists = 1;
417 while (exists) {
418 ngid++;
419## repeat retrieve (exists = any(l.#gid where l.#gid = @ngid))
420 }
421
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);
426##}
427
428/**
429 ** get_groups_of_user - optimized query for retrieval of all groups to
430 ** which a user belongs
431 **
432 **/
433
434get_groups_of_user(q, argv, cl, action, actarg)
435 struct query *q;
436 char *argv[];
437 client *cl;
438 int (*action)();
439 int actarg;
440##{
441## int users_id;
442## char list_name[33];
443## char gid[11];
444## int rowcount;
445 char *targv[2];
446
447 users_id = *(int *)argv[0];
448 targv[0] = list_name;
449 targv[1] = gid;
450
451## range of m is members
452## range of l is list
453
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
458## {
459 (*action)(2, targv, actarg);
460## }
461## inquire_equel (rowcount = "rowcount")
462
463 return ((rowcount = 0) ? SMS_NO_MATCH : SMS_SUCCESS);
464##}
465
466get_groups_of_all_users(q, argv, cl, action, actarg)
467 struct query *q;
468 char *argv[];
469 client *cl;
470 int (*action)();
471 int actarg;
472##{
473## char login[9];
474## char group[33];
475## char gid[11];
476 char *targv[3];
477## int errorno;
478
479 targv[0] = login;
480 targv[1] = group;
481 targv[2] = gid;
482
483## range of u is users
484## range of l is list
485## range of m is members
486
487## set lockmode session where readlock = nolock
488
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
493## {
494 (*action)(3, targv, actarg);
495## }
496
497## inquire_equel (errorno = "errorno")
498## set lockmode session where readlock = system
499
500 return((errorno) ? SMS_INGRES_ERR : SMS_SUCCESS);
501##}
502
503
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.
507 */
508expand_list_flags(q, argv, cl)
509 struct query *q;
510 char **argv;
511 client *cl;
512##{
513## int id, flags, active, public, hidden, who;
514## char *entity;
515
516 if (!strcmp(q->shortname, "ulis")) {
517 id = *(int *)argv[0];
518 } else {
519## repeat retrieve (id = values.value) where values.name = "list_id"
520 }
521
522## repeat retrieve (flags = l.#active) where l.list_id = @id
523 active = flags & 1;
524 public = (flags & 2) >> 1;
525 hidden = (flags & 4) >> 2;
526 entity = cl->entity;
527 who = cl->users_id;
528## repeat replace l (#active = @active, #public = @public, #hidden = @hidden,
529## modtime = "now", modby = @who, modwith = @entity)
530## where l.list_id = @id
531 return(SMS_SUCCESS);
532##}
533
534
535/**
536 ** add_new_quota
537 ** delete_current_quota - adjust nfsphys values on xxx_quota queries.
538 **
539 ** Inputs:
540 ** argv[0] - mach_id
541 ** argv[1] - device
542 ** argv[2] - users_id
543 ** argv[3] - quota (add_new_quota only)
544 **
545 ** Description:
546 ** delete_current_quota:
547 ** - find nfsquota entry
548 ** - decrement nfsphys.allocated by nfsquota.quota
549 ** add_new_quota
550 ** - increment nfsphys.allocated by quota
551 **
552 **/
553
554add_new_quota(q, argv, cl)
555 struct query *q;
556 register char *argv[];
557 client *cl;
558##{
559## int mach_id;
560## char *device;
561## int quota;
562
563 mach_id = *(int*)argv[0];
564 device = argv[1];
565 quota = *(int *)argv[3];
566
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
570
571 return(SMS_SUCCESS);
572##}
573
574delete_current_quota(q, argv, cl)
575 struct query *q;
576 register char *argv[];
577 client *cl;
578##{
579## int mach_id;
580## int users_id;
581## char *device;
582## int quota;
583
584 mach_id = *(int *)argv[0];
585 device = argv[1];
586 users_id = *(int *)argv[2];
587
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
595
596 return(SMS_SUCCESS);
597##}
598
599
600/**
601 ** delete_locker - special query routine for deleting a user locker
602 **
603 ** Inputs:
604 ** argv[0] - users_id
605 **
606 ** Description:
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
614 **
615 ** Errors:
616 ** - SMS_FILESYS - no filesys exists for user
617 **
618 **/
619
620delete_locker(q, argv)
621 register struct query *q;
622 register char *argv[];
623##{
624## int users_id;
625## int mach_id;
626## int quota;
627## int rowcount;
628## char login[9];
629## char lname[64];
630## char ndev[32];
631 char *rindex();
632 register char *c;
633
634 /* copy arguments */
635 users_id = *(int *)argv[0];
636
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
642
643 /* get login name */
644## repeat retrieve (login = u.#login) where u.#users_id = @users_id
645
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
652
653 /* get prefix directory */
654 c = rindex(lname, '/');
655 *c = 0;
656
657 /* get nfs device */
658## repeat retrieve (ndev = np.device)
659## where np.#mach_id = @mach_id and np.dir = @lname
660
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
667
668 /* decrement nfsphys.allocated */
669## repeat replace np (allocated = np.allocated - @quota)
670## where np.#mach_id = @mach_id and np.#device = @ndev
671
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"
679
680 return(SMS_SUCCESS);
681##}
This page took 0.155538 seconds and 5 git commands to generate.