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