]> andersk Git - moira.git/blame - server/qsupport.qc
Fixed bug in check_nfs.
[moira.git] / server / qsupport.qc
CommitLineData
05cdd922 1/*
2 * $Source$
3 * $Author$
4 * $Header$
5 *
6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
7 *
8 * $Log$
122ec372 9 * Revision 1.12 1987-08-29 00:05:54 mike
10 * Fixed bug in check_nfs.
11 * Added code to upcasify machine names in validate_id.
05cdd922 12 *
122ec372 13Revision 1.11 87/08/28 14:55:45 mike
14Modified delete_locker to require only one argument, the login name.
15Modified get_groups_of_all_users and get_all_poboxes to disable INGRES
16table locking.
17
9fbd2090 18Revision 1.10 87/08/25 15:56:54 mike
19- Fixed bugs in get_groups_of_all_users
20- Added tblstats updates to add_user_group
21- Added routines: add_hostaccess (ashi), delete_hostaccess (dshi),
22 followup_ushp, and followup_usha
23
4b890cc4 24Revision 1.9 87/08/22 17:41:34 wesommer
25More of Mike's changes.
26
a6cb4d4c 27Revision 1.8 87/08/18 15:05:20 wesommer
28Fixed definition of add_locker.
29
92a943d6 30Revision 1.7 87/08/04 01:49:41 wesommer
31Rearranged messages.
32
b4182127 33Revision 1.6 87/08/04 01:10:02 wesommer
34Changes by mike; checked in prior to my hacking.
35
c2408bd5 36Revision 1.5 87/07/30 14:54:13 wesommer
37Added debugging code in an attempt to catch a flakey problem.
38
247969d5 39Revision 1.4 87/07/30 00:30:21 wesommer
40replaced appends = appends+1 with appends = tbs.appends+1
41
3b2ceb9a 42Revision 1.3 87/07/30 00:26:11 wesommer
43Changes by mike prior to "appends" fix.
44
30967516 45Revision 1.2 87/07/29 16:00:39 wesommer
46Fixed add_locker.
47
7195989f 48Revision 1.1 87/07/29 15:13:57 wesommer
49Initial revision
50
05cdd922 51 */
52
53#ifndef lint
54static char *rcsid_qsupport_qc = "$Header$";
55#endif lint
56
57#include "query.h"
58#include "sms_server.h"
59#include <ctype.h>
60
61#define SMS_SUCCESS 0
62
63extern char *whoami;
64
65/* Specialized Access Routines */
66
67/**
68 ** access_user - verify that client name equals specified login name
69 **
70 ** Used by: update_user_shell
71 ** update_finger_by_login
72 **
73 ** - since field validation routines are called first, a users_id is
74 ** now in argv[0] instead of the login name. Therefore, we must
75 ** convert the client name to a users_id.
76 **/
77
78access_user(q, argv, cl)
79 struct query *q;
80 char *argv[];
81 client *cl;
82##{
83 register struct krbname *krb;
84## int client_id;
85## char *client_name;
86## int rowcount;
87
88 client_name = cl->kname.name;
89## repeat retrieve (client_id = users.users_id)
90## where users.login = @client_name
91## inquire_equel (rowcount = "rowcount")
92 if (rowcount != 1) return(SMS_PERM);
93 if (client_id != *(int *)argv[0]) return(SMS_PERM);
94
95 return(SMS_SUCCESS);
96##}
97
30967516 98/**
99 ** access_pop - same as access_user plus verifies that a user has only one
100 ** mailbox of type "POP"
101 **
102 ** Inputs:
103 ** argv[0] - users_id
104 ** argv[1] - type
105 ** argv[2] - mach_id
106 ** argv[3] - box
107 **
108 ** Description:
109 ** - if q->name = "add_pobox" and type = "POP",
110 ** verify that no POP box already exists for user
111 ** - call access_user
112 **
113 **/
114
115access_pop(q, argv, cl)
116 struct query *q;
117 char *argv[];
118 client *cl;
119##{
120## int users_id;
121## int mach_id;
122## char *box;
123## int exists;
124
125 if (!bcmp(q->name, "add_pobox", 10) && !bcmp(argv[1], "POP", 4)) {
126 users_id = *(int *)argv[0];
127 mach_id = *(int *)argv[2];
128 box = argv[3];
129## range of p is pobox
130## repeat retrieve (exists = any(p.#box where p.#users_id = @users_id
131## and p.type = "POP"
132## and p.#mach_id = @mach_id
133## and p.#box = @box))
134 if (exists) return(SMS_EXISTS);
135 }
136
137 return(access_user(q, argv, cl));
138##}
139
05cdd922 140/**
141 ** access_list - check access for adding or deleting list members
142 **
143 ** Inputs: argv[0] - list_id
144 ** cl->krb.name - client name
145 **
146 ** - check that client is a member of the access control list
147 ** - OR, if q->shortname == {amtl | dfml} and
148 ** if list.flags & LF_PUBLIC, allow access if client = member
149 **
150 **/
151
152access_list(q, argv, cl)
153 struct query *q;
154 char *argv[];
155 client *cl;
156##{
157## int list_id;
158## int acl_id;
159## int flags;
160 int member_id;
161 char *client_type;
162 int client_id;
163 int status;
164 int exists;
165
166 list_id = *(int *)argv[0];
167## repeat retrieve (acl_id = list.#acl_id, flags = list.#flags)
168## where list.#list_id = @list_id
169
170 /* parse client structure */
171 status = get_client(cl, &client_type, &client_id);
172 if (status != SMS_SUCCESS) return(status);
173
174 /* if amtl or dmfl and list is public allow client to add or delete self */
175 if (!bcmp("amtl", q->shortname, 4) || !bcmp("dmfl", q->shortname, 4)) {
176 if ((flags & LF_PUBLIC) && !bcmp("USER", argv[1], 4)) {
177 member_id = *(int *)argv[2];
178 if (member_id == client_id) return(SMS_SUCCESS);
179 }
180 }
181
182 /* check for client in access control list */
183 exists = find_member(acl_id, client_type, client_id, 0);
184 if (!exists) return(SMS_PERM);
185
186 return(SMS_SUCCESS);
187##}
92a943d6 188
a6cb4d4c 189/**
190 ** access_maillist - access_list + disallow adding user-group to maillists
191 **
192 ** Inputs:
193 ** argv[0] - list_id
194 **
195 **/
196
197access_maillist(q, argv, cl)
198 struct query *q;
199 char *argv[];
200 client *cl;
201##{
202## int list_id;
203## int exists;
204## char list_name[32];
205 int status;
206
207 status = access_list(q, argv, cl);
208 if (status != SMS_SUCCESS) return(status);
209 if (bcmp(q->name, "add_maillist", 12)) return(status);
210
211 list_id = *(int *)argv[0];
212## range of g is groups
213## repeat retrieve (exists = any(g.#list_id where g.#list_id = @list_id))
214 if (!exists) return(SMS_SUCCESS);
215## repeat retrieve (list_name = list.name) where list.#list_id = @list_id
216## repeat retrieve (exists = any(users.login where users.login = @list_name))
217 return ((exists) ? SMS_USER_GROUP : SMS_SUCCESS);
218##}
219
92a943d6 220/**
221 ** Setup routine for add_group
222 **
223 ** Inputs: none
224 **
225 ** Description: allocate next gid and store in values table
226 **
227 **/
228
229setup_add_group(q, argv, cl, access_check)
230 struct query *q;
231 char *argv[];
232 client *cl;
233 int access_check;
234##{
235## int ngid;
236## int exists;
237 int status;
238
239 status = access_list(q, argv, cl);
240
241 if (status != SMS_SUCCESS || access_check) return(status);
242
243## range of g is groups
244## range of v is values
245## repeat retrieve (ngid = v.value) where v.name = "gid"
246 exists = 1;
247 while (exists) {
248 ngid++;
249## repeat retrieve (exists = any(g.#gid where g.#gid = @ngid))
250 }
251
252## repeat replace v (value = @ngid) where v.name = "gid"
253 return(SMS_SUCCESS);
254##}
05cdd922 255\f
256/**
257 ** Setup routine for add_user
258 **
259 ** Inputs: argv[0] - login
260 ** argv[1] - uid
261 **
262 ** Description:
263 **
264 ** - if argv[1] == "#" then set argv[1] = next(uid)
265 ** - if argv[0] == "#" then set argv[0] = "#<uid>"
266 **
267 **/
268
269setup_add_user(q, argv, cl, access_check)
270 struct query *q;
271 register char *argv[];
272 client *cl;
273 int access_check;
274##{
275## int nuid;
276## int exists;
277
278 if (access_check) return(SMS_SUCCESS);
279
280 if (!bcmp(argv[1], "#", 2)) {
281## range of u is users
282## range of v is values
283## repeat retrieve (nuid = v.value) where v.name = "uid"
284 exists = 1;
285 while (exists) {
286 nuid++;
287## repeat retrieve (exists = any(u.#uid where u.#uid = @nuid))
288 }
289## repeat replace v (value = @nuid) where v.name = "uid"
290 sprintf(argv[1], "%d", nuid);
291 }
292
293 if (!bcmp(argv[0], "#", 2)) {
294 sprintf(argv[0], "#%s", argv[1]);
295 }
296
297 return(SMS_SUCCESS);
298##}
299
300/**
92a943d6 301 ** followup_add_user - add finger entry, set_user_modtime
302 ** followup_delete_user - delete finger entry
05cdd922 303 **
92a943d6 304 ** Inputs:
305 ** argv[0] - login (add_user)
306 ** argv[0] - users_id (delete_user)
05cdd922 307 **
308 **/
309
92a943d6 310followup_add_user(q, argv)
05cdd922 311 struct query *q;
312 char *argv[];
05cdd922 313##{
92a943d6 314## char *login;
315## int users_id;
316## char first[33];
317## char middle[33];
318## char last[33];
319## char fullname[128];
320 register char *cp1;
321 register char *cp2;
05cdd922 322
92a943d6 323 login = argv[0];
05cdd922 324
92a943d6 325 /* get user information */
326## range of u is users
327## repeat retrieve (users_id = u.#users_id, last = u.#last,
328## first = u.#first, middle = u.#middle)
329## where u.#login = @login
330
331 /* build fullname */
332 cp2 = fullname;
333 cp1 = first;
334 while (*cp1) *cp2++ = *cp1++;
335 *cp2++ = ' ';
336 cp1 = middle;
337 if (*cp1 == 0) cp2--;
338 while (*cp1) *cp2++ = *cp1++;
339 *cp2++ = ' ';
340 cp1 = last;
341 while (*cp2++ = *cp1++) ;
342
343 /* create a finger entry */
344## repeat append finger (#users_id = @users_id, #fullname = @fullname)
345
346 /* set modtime (creation time) on user */
347## repeat replace u (modtime = "now") where u.#users_id = @users_id
05cdd922 348
92a943d6 349 return(SMS_SUCCESS);
350##}
351
352followup_delete_user(q, argv)
353 struct query *q;
354 char *argv[];
355##{
356## int users_id;
357
358 users_id = *(int *)argv[0];
359## repeat delete finger where finger.#users_id = @users_id
05cdd922 360 return(SMS_SUCCESS);
361##}
362\f
c2408bd5 363/**
364 ** setup_add_filesys - verify existance of referenced file systems
365 ** setup_update_filesys - same, except argv[1..5] --> argv[2..6]
366 **
367 ** Inputs: Add Update
368 ** argv[0] - label label
369 ** argv[1] - type new label
370 ** argv[2] - mach_id type
371 ** argv[3] - name mach_id
372 ** argv[4] - mount name
373 ** argv[5] - access mount
374 ** argv[6] - access
375 **
376 ** Description:
377 ** - for type = RVD:
378 ** * verify mach_id/name in rvdvirt
379 ** * verify access in {r, x, R, X}
380 ** - for type = NFS:
381 ** * extract directory prefix from name
382 ** * verify mach_id/dir in nfsphys
383 ** * verify access in {r, w, R, W}
384 **
385 ** Errors:
386 ** SMS_RVD - no such rvd
387 ** SMS_NFS - specified directory not exported
388 ** SMS_FILESYS_ACCESS - invalid filesys access
389 **
390 **/
391
392setup_add_filesys(q, argv)
393 struct query *q;
394 char *argv[];
395{
396 char *type;
397 int mach_id;
398 char *name;
399 char *access;
400
401 type = argv[1];
402 mach_id = *(int *)argv[2];
403 name = argv[3];
404 access = argv[5];
405
406 if (!bcmp(type, "RVD", 3))
407 return (check_rvd(mach_id, name, access));
408 else if (!bcmp(type, "NFS", 3))
409 return (check_nfs(mach_id, name, access));
410 else
411 return(SMS_SUCCESS);
412}
413
414setup_update_filesys(q, argv)
415 struct query *q;
416 char *argv[];
417{
418 char *type;
419 int mach_id;
420 char *name;
421 char *access;
422
423 type = argv[2];
424 mach_id = *(int *)argv[3];
425 name = argv[4];
426 access = argv[6];
427
428 if (!bcmp(type, "RVD", 3))
429 return (check_rvd(mach_id, name, access));
430 else if (!bcmp(type, "NFS", 3))
431 return (check_nfs(mach_id, name, access));
432 else
433 return(SMS_SUCCESS);
434}
435
436##check_rvd(mach_id, name, access)
437## int mach_id;
438## char *name;
439 char *access;
440##{
441## int rowcount;
442 char caccess;
443
444## range of rv is rvdvirt
445## retrieve (rowcount = any(rv.#name where rv.#mach_id = mach_id and
446## rv.#name = name))
447 if (rowcount == 0) return(SMS_RVD);
448
449 caccess = (isupper(*access)) ? tolower(*access) : *access;
450 if (caccess != 'r' && caccess != 'x') return(SMS_FILESYS_ACCESS);
451
452 return(SMS_SUCCESS);
453##}
454
455##check_nfs(mach_id, name, access)
456## int mach_id;
457 char *name;
458 char *access;
459##{
460## int rowcount;
461## char dir[32];
462 char caccess;
122ec372 463 register int status;
c2408bd5 464 register char *cp1;
465 register char *cp2;
466
467 caccess = (isupper(*access)) ? tolower(*access) : *access;
468 if (caccess != 'r' && caccess != 'w') return(SMS_FILESYS_ACCESS);
469
122ec372 470 status = SMS_NFS;
c2408bd5 471## range of np is nfsphys
472## retrieve (dir = np.#dir) where np.#mach_id = mach_id
473## {
474 cp1 = name;
475 cp2 = dir;
476 while (*cp2) {
477 if (*cp1++ != *cp2) break;
478 cp2++;
479 }
122ec372 480 if (*cp2 == 0) {
481 status = SMS_SUCCESS;
482## endretrieve
483 }
c2408bd5 484## }
485
122ec372 486 return(status);
c2408bd5 487##}
488\f
05cdd922 489/* Followup Routines */
490
491set_user_modtime(q, argv)
492 struct query *q;
493 char *argv[];
494##{
495## char *login;
496
497 login = argv[0];
498## repeat replace u (modtime = "now") where u.#login = @login
499 return(SMS_SUCCESS);
500##}
501
502set_user_modtime_by_id(q, argv)
503 struct query *q;
504 char *argv[];
505##{
506## int users_id;
507
508 users_id = *(int *)argv[0];
509## repeat replace users (modtime = "now") where users.#users_id = @users_id
510 return(SMS_SUCCESS);
511##}
512
513set_list_modtime(q, argv)
514 struct query *q;
515 char *argv[];
516##{
517## char *list_name;
518
519 list_name = argv[0];
520## repeat replace list (modtime = "now") where list.name = @list_name
521 return(SMS_SUCCESS);
522##}
523
524set_list_modtime_by_id(q, argv)
525 struct query *q;
526 char *argv[];
527##{
528## int list_id;
529
530 list_id = *(int *)argv[0];
531## repeat replace list (modtime = "now") where list.#list_id = @list_id
532 return(SMS_SUCCESS);
533##}
534
535set_finger_modtime(q, argv)
536 struct query *q;
537 char *argv[];
538##{
539## int users_id;
540
541 users_id = *(int *)argv[0];
542## repeat replace f (modtime = "now") where f.#users_id = @users_id
543 return(SMS_SUCCESS);
544##}
a6cb4d4c 545\f
546/**
547 ** followup_amtl - followup for amtl and dmfl; when adding a list
548 ** member to a maillist, add list to maillist table,
549 ** unless list is a user-group.
550 ** Then set_list_modtime_by_id.
551 **
552 ** Inputs:
553 ** argv[0] - list_id
554 ** argv[1] - member_type
555 ** argv[2] - member_id
556 **
557 **/
558
559followup_amtl(q, argv)
560 struct query *q;
561 char *argv[];
562##{
563## int list_id;
564## int member_id;
565## int exists;
566## char list_name[33];
567
568 list_id = *(int *)argv[0];
569
570## repeat replace list (modtime = "now") where list.#list_id = @list_id
571
572 /* if query is not amtl or if member_type is not LIST then return */
573 if (bcmp(q->shortname, "amtl", 4) || bcmp(argv[1], "LIST", 4))
574 return(SMS_SUCCESS);
575
576 member_id = *(int *)argv[2];
577## range of l is list
578## range of ml is maillists
579## range of g is groups
580
581 /* is parent list a mailing list? */
582## repeat retrieve (exists = any(ml.#list_id where ml.#list_id=@list_id))
583
584 /* if not then return */
585 if (!exists) return(SMS_SUCCESS);
586
587 /* is member_list a user-group? */
588 /* is it a group? */
589## repeat retrieve (exists = any(g.#list_id where g.#list_id = @member_id))
590 if (exists) {
591 /* get list_name */
592## repeat retrieve (list_name = l.#name) where l.#list_id = @member_id
593 /* is list_name a username? */
594## repeat retrieve (exists = any(users.login
595## where users.login = @list_name))
596 /* yes, return error */
597 if (exists) return(SMS_USER_GROUP);
598 }
599
600 /* list is not a user-group; add list to maillist table */
601## repeat append maillists (#list_id = @member_id, ltid = l.tid)
602## where l.#list_id = @member_id
603
604 return(SMS_SUCCESS);
605##}
606\f
607/**
608 ** followup_add_pobox
609 ** followup_delete_pobox - followup routines for pobox queries
610 **
611 ** Description:
612 ** add_pobox: set pobox creation time
613 ** increment pop usage in serverhosts
614 **
615 ** delete_pobox: decrement pop usage in serverhosts
616 **
617 **/
618
619followup_add_pobox(q, argv)
620 struct query *q;
621 char *argv[];
622{
623 set_pobox_creation(q, argv);
624 set_pop_usage(q, argv, 1);
625 return(SMS_SUCCESS);
626}
627
628followup_delete_pobox(q, argv)
629 struct query *q;
630 char *argv[];
631{
632 set_pop_usage(q, argv, -1);
633 return(SMS_SUCCESS);
634}
635
636set_pobox_creation(q, argv)
637 struct query *q;
638 char *argv[];
639##{
640## int users_id;
641## int mach_id;
642## char *type;
643## char *box;
644
645 users_id = *(int *)argv[0];
646 type = argv[1];
647 mach_id = *(int *)argv[2];
648 box = argv[3];
649
650## range of p is pobox
651## repeat replace p (created = "now")
652## where p.#users_id = @users_id and p.#type = @type and
653## p.#mach_id = @mach_id and p.#box = @box
654
655 return (SMS_SUCCESS);
656##}
05cdd922 657
30967516 658/**
659 ** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
660 **
661 ** Inputs:
662 ** q->name - "add_pobox" or "delete_pobox"
a6cb4d4c 663 ** argv[1] - type
30967516 664 ** argv[2] - mach_id
665 **
666 ** Description:
667 ** - incr/decr value field in serverhosts table for pop/mach_id
668 **
669 **/
670
a6cb4d4c 671set_pop_usage(q, argv, count)
30967516 672 struct query *q;
673 char *argv[];
674##{
675## int mach_id;
a6cb4d4c 676## int n;
677
678 if (bcmp(argv[1], "POP", 3)) return(SMS_SUCCESS);
30967516 679
680 mach_id = *(int *)argv[2];
a6cb4d4c 681 n = count;
682
30967516 683## range of sh is serverhosts
a6cb4d4c 684## repeat replace sh (value1 = sh.value1 + @n)
685## where sh.service = "pop" and sh.#mach_id = @mach_id
30967516 686
a6cb4d4c 687 return(SMS_SUCCESS);
688##}
689
690/**
691 ** delete_user_poboxes - delete all poboxes for a user
692 **
693 ** Inputs:
694 ** argv[0] - users_id
695 **
696 **/
697
698delete_user_poboxes(q, argv)
699 struct query *q;
700 char *argv[];
701##{
702## int users_id;
703## int n;
704## int mach_id;
705 register int i;
706 int mach_ids[10];
707
708 users_id = *(int *)argv[0];
709
710 /* get machine ids for pop server(s) on which the user currently exists */
711## range of p is pobox
712 i = 0;
713## repeat retrieve (mach_id = p.#mach_id)
714## where p.#users_id = @users_id and p.type = "POP"
715## {
716 mach_ids[i++] = mach_id;
717 if (i == 10) {
718## endretrieve
719 }
720## }
721
722 /* decrement counts on serverhost entries */
723## range of sh is serverhosts
724 while (--i >= 0) {
725 mach_id = mach_ids[i];
30967516 726## repeat replace sh (value1 = sh.value1 - 1)
727## where sh.service = "pop" and sh.#mach_id = @mach_id
728 }
729
a6cb4d4c 730 /* delete user's poboxes */
731## repeat delete p where p.#users_id = @users_id
732
30967516 733 return(SMS_SUCCESS);
734##}
a6cb4d4c 735
92a943d6 736\f
737/**
738 ** add_new_quota
739 ** delete_current_quota - adjust nfsphys values on xxx_quota queries.
740 **
741 ** Inputs:
742 ** argv[0] - mach_id
743 ** argv[1] - device
744 ** argv[2] - users_id
745 ** argv[3] - quota (add_new_quota only)
746 **
747 ** Description:
748 ** delete_current_quota:
749 ** - find nfsquota entry
750 ** - decrement nfsphys.allocated by nfsquota.quota
751 ** add_new_quota
752 ** - increment nfsphys.allocated by quota
753 **
754 **/
755
756add_new_quota(q, argv)
757 struct query *q;
758 register char *argv[];
759##{
760## int mach_id;
761## char *device;
762## int quota;
763
764 mach_id = *(int*)argv[0];
765 device = argv[1];
766 quota = *(int *)argv[3];
767
768## range of np is nfsphys
769## repeat replace np (allocated = np.allocated + @quota)
770## where np.#mach_id = @mach_id and np.#device = @device
771
772 return(SMS_SUCCESS);
773##}
30967516 774
92a943d6 775delete_current_quota(q, argv, cl, access_check)
776 struct query *q;
777 register char *argv[];
778 client *cl;
779 int access_check;
780##{
781## int mach_id;
782## int users_id;
783## char *device;
784## int quota;
785
786 if (access_check) return(SMS_SUCCESS);
787
788 mach_id = *(int *)argv[0];
789 device = argv[1];
790 users_id = *(int *)argv[2];
791
792## range of np is nfsphys
793## range of nq is nfsquota
794## repeat retrieve (quota = nq.#quota)
795## where nq.#mach_id = @mach_id and nq.#device = @device and
796## nq.#users_id = @users_id
797## repeat replace np (allocated = np.allocated - @quota)
798## where np.#mach_id = @mach_id and np.#device = @device
799
800 return(SMS_SUCCESS);
801##}
802\f
4b890cc4 803/**
804 ** add_hostaccess - create entry in hostaccess table upon adding a new
805 ** machine to the serverhosts table where service =
806 ** "hostaccess".
807 **
808 ** Inputs:
809 ** argv[0] - service
810 ** argv[1] - mach_id
811 **
812 **/
813
814add_hostaccess(q, argv)
815 struct query *q;
816 char *argv[];
817##{
818## int mach_id;
819
820 /* only work with service = "hostaccess" */
821 if (bcmp(argv[0], "hostaccess", 10)) return(SMS_SUCCESS);
822
823 mach_id = *(int *)argv[1];
824## repeat append hostaccess (#mach_id = @mach_id, status = 0)
825## repeat replace tblstats (modtime = "now", appends = tblstats.appends + 1)
826## where tblstats.table = "hostaccess"
827 return(SMS_SUCCESS);
828##}
829
830/* followup to delete_server_host_info */
831
832delete_hostaccess(q, argv)
833 struct query *q;
834 char *argv[];
835##{
836## int mach_id;
837
838 /* only work with service = "hostaccess" */
839 if (bcmp(argv[0], "hostaccess", 10)) return(SMS_SUCCESS);
840
841 mach_id = *(int *)argv[1];
842## repeat delete hostaccess where hostaccess.#mach_id = @mach_id
843## repeat replace tblstats (modtime = "now", deletes = tblstats.deletes + 1)
844## where tblstats.table = "hostaccess"
845 return(SMS_SUCCESS);
846##}
847
848followup_ushp(q, argv)
849 struct query *q;
850 char *argv[];
851##{
852## int mach_id;
853## int status;
854
855 mach_id = *(int *)argv[0];
856## range of ha is hostaccess
857## repeat retrieve (status = ha.#status) where ha.#mach_id = @mach_id
858 status |= 1;
859## repeat replace ha (#status = @status) where ha.#mach_id = @mach_id
860 return(SMS_SUCCESS);
861##}
862
863followup_usha(q, argv)
864 struct query *q;
865 char *argv[];
866##{
867## int mach_id;
868## int status;
869
870 mach_id = *(int *)argv[0];
871## range of ha is hostaccess
872## repeat retrieve (status = ha.#status) where ha.#mach_id = @mach_id
873 status |= 2;
874## repeat replace ha (#status = @status) where ha.#mach_id = @mach_id
875 return(SMS_SUCCESS);
876##}
877\f
05cdd922 878/**
879 ** delete_list_members - called after the delete_list query to clean up
880 ** members table.
881 **
882 ** Inputs: argv[0] - list_id
883 **
884 ** Description:
885 ** - foreach string member: decr string refc; ifzero, delete string
886 ** - delete all members entries for this list_id
887 **
888 **/
889
890delete_list_members(q, argv)
891 struct query *q;
892 register char *argv[];
893##{
894## int list_id;
895## int string_id;
896## int refc;
897## int rowcount;
898 struct save_queue *sq;
899 struct save_queue *sq_create();
900
901 list_id = *(int *)argv[0];
902 sq = sq_create();
903
904## range of m is members
905## repeat retrieve (string_id = m.member_id)
906## where m.#list_id = @list_id and m.member_type = "STRING"
907## {
908 sq_save_data(sq, string_id);
909## }
910
911 while (sq_get_data(sq, &string_id)) {
912## range of s is strings
913## repeat retrieve (refc = s.#refc) where s.#string_id = @string_id
914## inquire_equel (rowcount = "rowcount")
915 if (rowcount == 0) continue;
916 if (--refc == 0) {
917## repeat delete s where s.#string_id = @string_id
918 } else {
919## repeat replace s (#refc = @refc) where s.#string_id = @string_id
920 }
921 }
922 sq_destroy(sq);
923
924## repeat delete m where m.#list_id = @list_id
925
926 return(SMS_SUCCESS);
927##}
92a943d6 928\f
05cdd922 929/**
4b890cc4 930 ** followup_grvd - Support routine for get_rvd_servers query
05cdd922 931 **
932 ** Inputs:
933 ** q - grvd query structure
934 ** sq - save_queue struture: contains list of {machine, oper_acl_id,
935 ** admin_acl_id, shutdown_acl_id} records.
936 ** v - validate structure (not used)
937 ** action - action routine
938 ** actarg - action routine argument
939 **
940 ** Description:
941 ** - translate acl_ids to list names
942 **
943 **/
944
4b890cc4 945followup_grvd(q, sq, v, action, actarg)
05cdd922 946 struct query *q;
947 struct save_queue *sq;
948 struct validate *v;
949 int (*action)();
950 int actarg;
951##{
952 char **argv;
953 char *targv[4];
954## char oper[33];
955## char admin[33];
956## char shutdown[33];
957## int list_id;
958
30967516 959 targv[0] = oper;
960 targv[1] = admin;
961 targv[2] = shutdown;
05cdd922 962
963## range of l is list
964
965 while (sq_get_data(sq, &argv)) {
30967516 966 sscanf(argv[0], "%d", &list_id);
05cdd922 967## repeat retrieve (oper = l.name) where l.#list_id = @list_id
30967516 968 sscanf(argv[1], "%d", &list_id);
05cdd922 969## repeat retrieve (admin = l.name) where l.#list_id = @list_id
30967516 970 sscanf(argv[2], "%d", &list_id);
05cdd922 971## repeat retrieve (shutdown = l.name) where l.#list_id = @list_id
972
30967516 973 (*action)(3, targv, actarg);
05cdd922 974 free(argv[0]);
975 free(argv[1]);
976 free(argv[2]);
05cdd922 977 }
978
979 sq_destroy(sq);
980 return(SMS_SUCCESS);
981##}
982
4b890cc4 983followup_gars(q, sq, v, action, actarg)
92a943d6 984 struct query *q;
985 struct save_queue *sq;
986 struct validate *v;
987 int (*action)();
988 int actarg;
989##{
990 char **argv;
991 char *targv[4];
992## char oper[33];
993## char admin[33];
994## char shutdown[33];
995## int list_id;
996
997 targv[1] = oper;
998 targv[2] = admin;
999 targv[3] = shutdown;
1000
1001## range of l is list
1002
1003 while (sq_get_data(sq, &argv)) {
1004 sscanf(argv[1], "%d", &list_id);
1005## repeat retrieve (oper = l.name) where l.#list_id = @list_id
1006 sscanf(argv[2], "%d", &list_id);
1007## repeat retrieve (admin = l.name) where l.#list_id = @list_id
1008 sscanf(argv[3], "%d", &list_id);
1009## repeat retrieve (shutdown = l.name) where l.#list_id = @list_id
1010
1011 targv[0] = argv[0];
1012 (*action)(4, targv, actarg);
1013 free(argv[0]);
1014 free(argv[1]);
1015 free(argv[2]);
1016 free(argv[3]);
1017 }
1018
1019 sq_destroy(sq);
1020 return(SMS_SUCCESS);
1021##}
1022\f
05cdd922 1023/**
1024 ** set_next_object_id - set next object id in values table
1025 **
1026 ** Inputs: object - object name in values table
1027 **
1028 ** - called before an APPEND operation to set the next object id to
1029 ** be used for the new record
1030 **
1031 **/
1032
1033set_next_object_id(object)
1034 char *object;
1035##{
1036## char *name;
05cdd922 1037
1038 name = object;
1039## range of v is values
30967516 1040## repeat replace v (value = v.value + 1) where v.#name = @name
1041 return(SMS_SUCCESS);
1042##}
1043
1044/**
1045 ** get_query_need - check modtime of query's associated table against given
1046 ** time and return true if greater (false if not)
1047 **
1048 ** Inputs:
1049 ** argv[0] - query name
1050 ** argv[1] - time to compare against
1051 **
1052 **/
1053
1054get_query_need(q, argv, action, actarg)
1055 struct query *q;
1056 register char *argv[];
1057 int (*action)();
1058##{
1059 struct query *q1;
1060## char *last_get_time;
1061## char *table;
1062## int need;
1063 char *result;
1064 struct query *get_query_by_name();
1065
1066 q1 = get_query_by_name(argv[0]);
1067
1068 last_get_time = argv[1];
1069 table = q1->rtable;
1070
92a943d6 1071 if (q1->type != RETRIEVE) return(SMS_NO_MATCH);
30967516 1072
1073## range of tbs is tblstats
1074## repeat retrieve (need = any(tbs.modtime where tbs.#table = @table and
1075## tbs.modtime > @last_get_time))
1076
1077 result = (need) ? "true" : "false";
1078 (*action)(1, &result, actarg);
05cdd922 1079 return(SMS_SUCCESS);
1080##}
1081
92a943d6 1082/**
1083 ** get_list_is_group
1084 ** get_list_is_maillist
1085 **
1086 ** Inputs:
1087 ** argv[0] - list_id
1088 **
1089 ** Returns:
1090 ** {true | false}
1091 **
1092 **/
1093
1094get_list_is_group(q, argv, action, actarg)
1095 struct query *q;
1096 char *argv[];
1097 int (*action)();
1098 int actarg;
1099##{
1100## int exists;
1101## int list_id;
1102 char *result;
1103
1104 list_id = *(int *)argv[0];
1105
1106## range of g is groups
1107## repeat retrieve (exists = any(g.#list_id where g.#list_id = @list_id))
1108
1109 result = (exists) ? "true" : "false";
1110 (*action)(1, &result, actarg);
1111 return(SMS_SUCCESS);
1112##}
1113
1114get_list_is_maillist(q, argv, action, actarg)
1115 struct query *q;
1116 char *argv[];
1117 int (*action)();
1118 int actarg;
1119##{
1120## int exists;
1121## int list_id;
1122 char *result;
1123
1124 list_id = *(int *)argv[0];
1125
1126## range of ml is maillists
1127## repeat retrieve (exists = any(ml.#list_id where ml.#list_id = @list_id))
1128
1129 result = (exists) ? "true" : "false";
1130 (*action)(1, &result, actarg);
1131 return(SMS_SUCCESS);
1132##}
1133
05cdd922 1134\f
1135/**
1136 ** add_locker - special query routine for creating a user locker
1137 **
1138 ** Inputs:
1139 ** argv[0] - users_id
1140 ** argv[1] - machine_id
1141 ** argv[2] - device
1142 ** argv[3] - initial quota
1143 **
1144 ** Description:
1145 ** - get prefix directory (dir) for mount point on specified machine/device
1146 ** - create filesys entry (label=<login>, type=NFS, machine=<machine>,
1147 ** mount=<dir>/<login>, access=w, acl=dbadmin)
1148 ** - increment allocated in nfsphys by quota
1149 ** - create nfsquota entry
1150 **
1151 ** Errors:
1152 ** - SMS_NFSPHYS - machine/device does not exist in nfsphys
1153 ** - SMS_FILESYS_EXISTS - file system already exists
1154 **
1155 **/
1156
1157add_locker(q, argv)
1158 register struct query *q;
1159 char *argv[];
1160##{
1161## int users_id;
1162## int mach_id;
1163## char *device;
1164## int quota;
1165## int rowcount;
30967516 1166## char login[9];
05cdd922 1167## char dir[32];
1168## int allocated;
1169## char locker[64];
1170## char mount[64];
1171## int user_acl;
1172
1173 /* copy arguments */
1174 users_id = *(int *)argv[0];
1175 mach_id = *(int *)argv[1];
1176 device = argv[2];
1177 sscanf(argv[3], "%d", &quota);
1178
1179## range of u is users
1180## range of f is filesys
1181## range of np is nfsphys
30967516 1182## range of tbs is tblstats
05cdd922 1183
1184 /* get login name */
1185## repeat retrieve (login = u.#login) where u.#users_id = @users_id
1186
1187 /* get user's acl id */
1188## repeat retrieve (user_acl = list.list_id) where list.name = @login
1189
1190 /* get filesystem directory prefix; give error if machine/device
1191 pair not in nfsphys table */
247969d5 1192 printf("np.mach_id = %d and np.device = %s\n", mach_id, device);
1193
05cdd922 1194## repeat retrieve (dir = np.#dir, allocated = np.#allocated)
92a943d6 1195## where np.#mach_id = @mach_id and np.#device = @device
05cdd922 1196## inquire_equel (rowcount = "rowcount")
1197 if (rowcount == 0) return(SMS_NFSPHYS);
1198
1199 /* make sure a filesys with user's name does not already exist */
1200## repeat retrieve (rowcount = any(f.label where f.label = @login))
1201 if (rowcount != 0) return(SMS_FILESYS_EXISTS);
1202
1203 /* create a new filesys */
1204 sprintf(locker, "%s/%s", dir, login);
1205 sprintf(mount, "/mit/%s", login);
1206## repeat append filesys
7195989f 1207## (#label = @login, type = "NFS", #mach_id = @mach_id,
05cdd922 1208## name = @locker, access = "w", order = 1, #mount = @mount,
1209## acl_id = @user_acl)
30967516 1210## repeat replace tbs (appends = tbs.appends + 1, modtime = "now")
1211## where tbs.table = "filesys"
05cdd922 1212
1213 /* increment usage count in nfsphys table */
1214 allocated += quota;
1215## replace np (#allocated = allocated)
1216## where np.#mach_id = mach_id and np.#device = device
30967516 1217## repeat replace tbs (updates = tbs.updates + 1, modtime = "now")
1218## where tbs.table = "nfsphys"
05cdd922 1219
1220 /* create nfsquota entry */
1221## append nfsquota (#users_id = users_id, #mach_id = mach_id,
7195989f 1222## #device = device, #quota = quota)
3b2ceb9a 1223## repeat replace tbs (appends = tbs.appends + 1, modtime = "now")
30967516 1224## where tbs.table = "nfsquota"
1225
1226 return(SMS_SUCCESS);
1227##}
1228
1229/**
1230 ** delete_locker - special query routine for deleting a user locker
1231 **
1232 ** Inputs:
1233 ** argv[0] - users_id
30967516 1234 **
1235 ** Description:
9fbd2090 1236 ** - get login name from users_id
1237 ** - get filesys entry from login
1238 ** - use filesys.mach_id and filesys.name to determine machine/device
1239 ** pair for nfsphys and nfsquota
30967516 1240 ** - delete filesys entry (label=<login>)
1241 ** - decrement allocated in nfsphys by quota
1242 ** - delete nfsquota entry
1243 **
1244 ** Errors:
1245 ** - SMS_FILESYS - no filesys exists for user
1246 **
1247 **/
1248
1249delete_locker(q, argv)
1250 register struct query *q;
1251 register char *argv[];
1252##{
1253## int users_id;
1254## int mach_id;
30967516 1255## int quota;
1256## int rowcount;
1257## char login[9];
9fbd2090 1258## char lname[64];
1259## char ndev[32];
1260 register char *c;
30967516 1261
1262 /* copy arguments */
1263 users_id = *(int *)argv[0];
30967516 1264
1265## range of u is users
1266## range of f is filesys
1267## range of np is nfsphys
1268## range of nq is nfsquota
1269## range of tbs is tblstats
1270
1271 /* get login name */
1272## repeat retrieve (login = u.#login) where u.#users_id = @users_id
1273
9fbd2090 1274 /* get mach_id and locker name from filesys entry; then delete it */
1275## repeat retrieve (mach_id = f.#mach_id, lname = f.#name)
1276## where f.#label = @login
30967516 1277## inquire_equel (rowcount = "rowcount")
1278 if (rowcount == 0) return(SMS_FILESYS);
9fbd2090 1279## repeat delete f where f.#label = @login
1280
1281 /* get prefix directory */
1282 c = (char *)rindex(lname, '/');
1283 *c = 0;
1284
1285 /* get nfs device */
1286## repeat retrieve (ndev = np.device)
1287## where np.#mach_id = @mach_id and np.dir = @lname
1288
1289 /* get quota from nfsquota entry; then delete entry */
1290## repeat retrieve (quota = nq.#quota)
1291## where nq.#mach_id = @mach_id and nq.#device = @ndev and
1292## nq.#users_id = @users_id
1293## repeat delete nq where nq.#mach_id = @mach_id and nq.#device = @ndev and
1294## nq.#users_id = @users_id
1295
1296 /* decrement nfsphys.allocated */
1297## repeat replace np (allocated = np.allocated - @quota)
1298## where np.#mach_id = @mach_id and np.#device = @ndev
1299
1300 /* adjust table statistics */
30967516 1301## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now")
1302## where tbs.table = "filesys"
30967516 1303## repeat replace tbs (updates = tbs.updates + 1, modtime = "now")
1304## where tbs.table = "nfsphys"
30967516 1305## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now")
1306## where tbs.table = "nfsquota"
05cdd922 1307
1308 return(SMS_SUCCESS);
1309##}
92a943d6 1310\f
1311/**
1312 ** add_user_group - create a group for a user and add user to group
1313 **
1314 ** Inputs:
1315 ** argv[0] - login
1316 **
1317 ** Description:
1318 ** - verify specified user exists
1319 ** - create a list of same name as user
1320 ** - add user as a member of the list
1321 **
1322 **/
1323
1324add_user_group(q, argv)
1325 struct query *q;
1326 char *argv[];
1327##{
1328## char *login;
1329## int exists;
1330## int users_id;
1331## int list_id;
1332## int gid;
1333
1334 login = argv[0];
1335
1336 /* verify user exists */
1337## repeat retrieve (users_id = users.#users_id) where users.#login = @login
1338## inquire_equel (exists = "rowcount")
1339 if (exists != 1) return(SMS_USER);
1340
1341 /* verify list does not exist */
1342## repeat retrieve (exists = any(list.name where list.name = @login))
1343 if (exists) return(SMS_LIST);
1344
1345 /* get new list_id */
1346## repeat retrieve (list_id = values.value) where values.name = "list_id"
1347 list_id++;
1348## repeat replace values (value = @list_id) where values.name = "list_id"
1349
1350 /* create the list */
4b890cc4 1351## range of tbs is tblstats
92a943d6 1352## repeat append list (name = @login, #list_id = @list_id, flags = 1,
1353## desc = "User Group", acl_id = @list_id,
1354## expdate = "today" + "5 years", modtime = "now")
4b890cc4 1355## repeat replace tbs (modtime = "now", appends = tbs.appends + 1)
1356## where tbs.table = "list"
92a943d6 1357
1358 /* add user to list */
1359## repeat append members (#list_id = @list_id, member_type = "USER",
1360## member_id = @users_id)
4b890cc4 1361## repeat replace tbs (modtime = "now", appends = tbs.appends + 1)
1362## where tbs.table = "members"
92a943d6 1363
1364 /* get new gid */
1365## range of g is groups
1366## range of v is values
1367## repeat retrieve (gid = v.value) where v.name = "gid"
1368 exists = 1;
1369 while (exists) {
1370 gid++;
1371## repeat retrieve (exists = any(g.#gid where g.#gid = @gid))
1372 }
1373## repeat replace v (value = @gid) where v.name = "gid"
1374
1375 /* add list to group table */
1376## repeat append groups (#list_id = @list_id, ltid = list.tid, #gid = @gid)
1377## where list.#list_id = @list_id
4b890cc4 1378## repeat replace tbs (modtime = "now", appends = tbs.appends + 1)
1379## where tbs.table = "members"
92a943d6 1380
1381 /* and we're done */
1382 return(SMS_SUCCESS);
1383##}
1384
05cdd922 1385\f
c2408bd5 1386/**
1387 ** get_members_of_list - optimized query for retrieval of list members
1388 **
1389 ** Inputs:
1390 ** argv[0] - list_id
1391 **
1392 ** Description:
1393 ** - retrieve USER members, then LIST members, then STRING members
1394 **
1395 **/
1396
1397get_members_of_list(q, argv, action, actarg)
1398 struct query *q;
1399 char *argv[];
1400 int (*action)();
1401 int actarg;
1402##{
1403## int list_id;
1404## char member_name[129];
1405 char *targv[2];
1406
1407 list_id = *(int *)argv[0];
1408 targv[0] = "USER";
1409 targv[1] = member_name;
1410
1411## range of m is members
1412## repeat retrieve (member_name = users.login)
1413## where m.#list_id = @list_id and m.member_type = "USER"
1414## and m.member_id = users.users_id
92a943d6 1415## sort by #member_name
c2408bd5 1416## {
1417 (*action)(2, targv, actarg);
1418## }
1419
1420 targv[0] = "LIST";
1421## repeat retrieve (member_name = list.name)
1422## where m.#list_id = @list_id and m.member_type = "LIST"
1423## and m.member_id = list.#list_id
92a943d6 1424## sort by #member_name
c2408bd5 1425## {
1426 (*action)(2, targv, actarg);
1427## }
1428
1429 targv[0] = "STRING";
1430## repeat retrieve (member_name = strings.string)
1431## where m.#list_id = @list_id and m.member_type = "STRING"
1432## and m.member_id = strings.string_id
92a943d6 1433## sort by #member_name
c2408bd5 1434## {
1435 (*action)(2, targv, actarg);
1436## }
1437
1438 return(SMS_SUCCESS);
1439##}
1440
1441/**
92a943d6 1442 ** get_groups_of_user - optimized query for retrieval of all groups to
1443 ** which a user belongs
1444 **
1445 **/
1446
1447get_groups_of_user(q, argv, action, actarg)
1448 struct query *q;
1449 char *argv[];
1450 int (*action)();
1451 int actarg;
1452##{
1453## int users_id;
1454## char list_name[33];
1455## char gid[11];
1456## int rowcount;
1457 char *targv[2];
1458
1459 users_id = *(int *)argv[0];
1460 targv[0] = list_name;
1461 targv[1] = gid;
1462
1463## range of m is members
1464
1465## repeat retrieve (list_name = list.name, gid = text(groups.#gid))
1466## where m.member_id = @users_id and m.member_type = "USER" and
1467## m.list_id = groups.list_id and groups.ltid = list.tid
1468## sort by #list_name
1469## {
1470 (*action)(2, targv, actarg);
1471## }
1472## inquire_equel (rowcount = "rowcount")
1473
1474 return ((rowcount = 0) ? SMS_NO_MATCH : SMS_SUCCESS);
1475##}
a6cb4d4c 1476
1477get_groups_of_all_users(q, argv, action, actarg)
1478 struct query *q;
1479 char *argv[];
1480 int (*action)();
1481 int actarg;
1482##{
1483## char login[9];
1484## char group[33];
1485## char gid[11];
4b890cc4 1486 char *targv[3];
a6cb4d4c 1487## int errorno;
1488
4b890cc4 1489 targv[0] = login;
1490 targv[1] = group;
1491 targv[2] = gid;
1492
a6cb4d4c 1493## range of u is users
1494## range of l is list
1495## range of m is members
1496## range of g is groups
1497
9fbd2090 1498## set lockmode session where readlock = nolock
1499
4b890cc4 1500## repeat retrieve (login = u.#login, group = l.name, gid = text(g.#gid))
a6cb4d4c 1501## where m.member_type = "USER" and m.member_id = u.users_id and
1502## u.status != 0 and m.list_id = g.list_id and
1503## g.ltid = l.tid
1504## sort by #login, #group
4b890cc4 1505## {
1506 (*action)(3, targv, actarg);
1507## }
a6cb4d4c 1508
1509## inquire_equel (errorno = "errorno")
9fbd2090 1510## set lockmode session where readlock = system
a6cb4d4c 1511
1512 return((errorno) ? SMS_INGRES_ERR : SMS_SUCCESS);
1513##}
92a943d6 1514\f
1515/**
1516 ** get_all_poboxes - optimized query for retrieval of all poboxes
c2408bd5 1517 **
1518 ** Description:
1519 ** - retrieve LOCAL boxes, then POP boxes, then FOREIGN boxes
1520 **
1521 **/
1522
1523get_all_poboxes(q, argv, action, actarg)
1524 struct query *q;
1525 char *argv[];
1526 int (*action)();
1527 int actarg;
1528##{
1529## char login[9];
1530## char machine[129];
1531## char box[129];
1532 char *targv[4];
1533
1534 targv[0] = login;
1535 targv[2] = machine;
1536 targv[3] = box;
1537
1538 targv[1] = "LOCAL";
9fbd2090 1539
1540## set lockmode session where readlock = nolock
c2408bd5 1541## range of p is pobox
1542## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
1543## where p.type = "LOCAL" and p.users_id = users.users_id
1544## and p.mach_id = #machine.mach_id
1545## {
1546 (*action)(4, targv, actarg);
1547## }
1548
1549 targv[1] = "POP";
1550## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
1551## where p.type = "POP" and p.users_id = users.users_id
1552## and p.mach_id = #machine.mach_id
1553## {
1554 (*action)(4, targv, actarg);
1555## }
1556
1557 targv[1] = "FOREIGN";
1558## repeat retrieve (login=users.#login, machine=strings.string, box=p.#box)
1559## where p.type = "FOREIGN" and p.users_id = users.users_id
1560## and p.mach_id = strings.string_id
1561## {
1562 (*action)(4, targv, actarg);
1563## }
9fbd2090 1564## set lockmode session where readlock = system
c2408bd5 1565
1566 return(SMS_SUCCESS);
1567##}
a6cb4d4c 1568
1569get_new_poboxes(q, argv, action, actarg)
1570 struct query *q;
1571 char *argv[];
1572 int (*action)();
1573 int actarg;
1574##{
1575## char *created;
1576## char login[9];
1577## char machine[129];
1578## char box[129];
1579 char *targv[4];
1580
1581 created = argv[0];
1582
1583 targv[0] = login;
1584 targv[2] = machine;
1585 targv[3] = box;
1586
1587 targv[1] = "LOCAL";
1588## range of p is pobox
1589## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
1590## where p.type = "LOCAL" and p.users_id = users.users_id
1591## and p.mach_id = #machine.mach_id and
1592## p.#created > @created
1593## {
1594 (*action)(4, targv, actarg);
1595## }
1596
1597 targv[1] = "POP";
1598## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
1599## where p.type = "POP" and p.users_id = users.users_id
1600## and p.mach_id = #machine.mach_id and
1601## p.#created > @created
1602## {
1603 (*action)(4, targv, actarg);
1604## }
1605
1606 targv[1] = "FOREIGN";
1607## repeat retrieve (login=users.#login, machine=strings.string, box=p.#box)
1608## where p.type = "FOREIGN" and p.users_id = users.users_id
1609## and p.mach_id = strings.string_id and
1610## p.#created > @created
1611## {
1612 (*action)(4, targv, actarg);
1613## }
1614
1615 return(SMS_SUCCESS);
1616##}
c2408bd5 1617\f
05cdd922 1618/* Validation Routines */
1619
1620validate_row(q, argv, v)
1621 register struct query *q;
1622 char *argv[];
1623 register struct validate *v;
1624##{
1625## char *rvar;
1626## char *table;
1627## char *name;
1628## char qual[128];
1629## int rowcount;
1630
1631 /* build where clause */
1632 build_qual(v->qual, v->argc, argv, qual);
1633
1634 /* setup ingres variables */
1635 rvar = q->rvar;
1636 table = q->rtable;
1637 name = v->field;
1638
b4182127 1639 if (log_flags & LOG_RES)
1640 /* tell the logfile what we're doing */
1641 com_err(whoami, 0, "validating row: %s", qual);
1642
05cdd922 1643 /* look for the record */
1644## range of rvar is table
1645## retrieve (rowcount = count(rvar.name where qual))
05cdd922 1646 if (rowcount == 0) return(SMS_NO_MATCH);
1647 if (rowcount > 1) return(SMS_NOT_UNIQUE);
1648 return(SMS_EXISTS);
1649##}
1650
1651validate_fields(q, argv, vo, n)
1652 struct query *q;
1653 register char *argv[];
1654 register struct valobj *vo;
1655 register int n;
1656{
1657 register int status;
05cdd922 1658
1659 while (--n >= 0) {
1660 switch (vo->type) {
1661 case V_NAME:
92a943d6 1662 if (log_flags & LOG_RES)
b4182127 1663 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 1664 vo->namefield, vo->table, argv[vo->index]);
05cdd922 1665 status = validate_name(argv, vo);
1666 break;
1667
1668 case V_ID:
92a943d6 1669 if (log_flags & LOG_RES)
b4182127 1670 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 1671 vo->idfield, vo->table, argv[vo->index]);
05cdd922 1672 status = validate_id(argv, vo);
1673 break;
1674
92a943d6 1675 case V_DATE:
1676 if (log_flags & LOG_RES)
1677 com_err(whoami, 0, "validating date: %s", argv[vo->index]);
1678 status = validate_date(argv, vo);
1679 break;
1680
05cdd922 1681 case V_TYPE:
92a943d6 1682 if (log_flags & LOG_RES)
b4182127 1683 com_err(whoami, 0, "validating %s type: %s",
05cdd922 1684 vo->table, argv[vo->index]);
05cdd922 1685 status = validate_type(argv, vo);
1686 break;
1687
1688 case V_TYPEDATA:
92a943d6 1689 if (log_flags & LOG_RES)
1690 com_err(whoami, 0, "validating typed data (%s): %s",
1691 argv[vo->index - 1], argv[vo->index]);
05cdd922 1692 status = validate_typedata(q, argv, vo);
1693 break;
1694
1695 case V_FOLLOWUP:
1696 status = SMS_EXISTS;
1697 break;
1698
92a943d6 1699 case V_SORT:
1700 status = SMS_EXISTS;
1701 break;
1702
05cdd922 1703 }
1704
1705 if (status != SMS_EXISTS) return(status);
1706 vo++;
1707 }
1708
1709 return(SMS_SUCCESS);
1710}
1711
1712validate_id(argv, vo)
1713 char *argv[];
1714 register struct valobj *vo;
1715##{
1716## char *name;
1717## char *table;
1718## char *namefield;
1719## char *idfield;
1720## int id;
1721## int rowcount;
122ec372 1722 register char *c;
05cdd922 1723
1724 name = argv[vo->index];
1725 table = vo->table;
122ec372 1726 /* minor kludge to upcasify machine names */
1727 if (!bcmp(table, "machine", 7))
1728 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 1729 namefield = vo->namefield;
1730 idfield = vo->idfield;
1731## retrieve (id = table.idfield) where table.namefield = name
1732## inquire_equel (rowcount = "rowcount")
1733 if (rowcount != 1) return(vo->error);
1734 *(int *)argv[vo->index] = id;
1735 return(SMS_EXISTS);
1736##}
1737
1738validate_name(argv, vo)
1739 char *argv[];
1740 register struct valobj *vo;
1741##{
1742## char *name;
1743## char *table;
1744## char *namefield;
1745## int rowcount;
1746
1747 name = argv[vo->index];
1748 table = vo->table;
1749 namefield = vo->namefield;
1750## retrieve (rowcount = countu(table.namefield
1751## where table.namefield = name))
1752 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
1753##}
1754
92a943d6 1755validate_date(argv, vo)
1756 char *argv[];
1757 struct valobj *vo;
1758##{
1759## char *idate;
1760## double dd;
1761## int errorno;
1762
1763 idate = argv[vo->index];
1764
1765## retrieve (dd = interval("years", date(idate) - date("today")))
1766## inquire_equel (errorno = "errorno")
1767 if (errorno != 0 || dd > 5.0) return(SMS_DATE);
1768 return(SMS_SUCCESS);
1769##}
1770
05cdd922 1771validate_type(argv, vo)
1772 char *argv[];
1773 register struct valobj *vo;
1774##{
1775## char *typename;
1776## char *value;
1777## int rowcount;
1778 register char *c;
1779
1780 typename = vo->table;
1781 value = argv[vo->index];
1782
1783 /* uppercase type fields */
1784 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
1785
1786## range of a is alias
1787## repeat retrieve (rowcount = count(a.trans where a.name = @typename and
1788## a.type = "TYPE" and
1789## a.trans = @value))
1790 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
1791##}
1792
1793/* validate member or type-specific data field */
1794
1795validate_typedata(q, argv, vo)
1796 register struct query *q;
1797 register char *argv[];
1798 register struct valobj *vo;
1799##{
1800## char *name;
1801## char *field_type;
1802## char data_type[17];
1803## int id;
1804## int refc;
1805## int rowcount;
a6cb4d4c 1806 register char *c;
05cdd922 1807
1808 /* get named object */
1809 name = argv[vo->index];
1810
1811 /* get field type string (known to be at index-1) */
1812 field_type = argv[vo->index-1];
1813
1814 /* get corresponding data type associated with field type name */
1815## repeat retrieve (data_type = alias.trans)
1816## where alias.#name = @field_type and alias.type = "TYPEDATA"
1817## inquire_equel (rowcount = "rowcount")
1818 if (rowcount != 1) return(SMS_TYPE);
1819
1820 /* now retrieve the record id corresponding to the named object */
1821
1822 if (!strcmp(data_type, "user")) {
1823 /* USER */
1824## repeat retrieve (id = users.users_id) where users.login = @name
1825## inquire_equel (rowcount = "rowcount")
1826 if (rowcount != 1) return(SMS_USER);
1827
1828 } else if (!strcmp(data_type, "list")) {
1829 /* LIST */
1830## repeat retrieve (id = list.list_id) where list.#name = @name
1831## inquire_equel (rowcount = "rowcount")
1832 if (rowcount != 1) return(SMS_LIST);
1833
1834 } else if (!strcmp(data_type, "machine")) {
1835 /* MACHINE */
a6cb4d4c 1836 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 1837## repeat retrieve (id = machine.mach_id) where machine.#name = @name
1838## inquire_equel (rowcount = "rowcount")
1839 if (rowcount != 1) return(SMS_MACHINE);
1840
1841 } else if (!strcmp(data_type, "string")) {
1842 /* STRING */
1843## range of s is strings
1844## repeat retrieve (id = s.string_id, refc = s.#refc)
1845## where s.string = @name
1846## inquire_equel (rowcount = "rowcount")
1847 if (rowcount == 0) {
1848 if (q->type != APPEND) return(SMS_STRING);
1849## range of v is values
1850## retrieve (id = v.value) where v.#name = "strings_id"
1851 id++;
1852## replace v (value = id) where v.#name = "strings_id"
1853## append to strings (string_id = id, string = name, #refc = 1)
1854 } else if (rowcount == 1) {
1855 if (q->type == APPEND || q->type == DELETE) {
1856 refc += (q->type == APPEND) ? 1 : -1;
1857 if (refc > 0) {
1858## replace s (#refc = refc) where s.string_id = id
1859 } else {
1860## delete s where s.string_id = id
1861 }
1862 }
1863 }
1864 } else {
1865 return(SMS_TYPE);
1866 }
1867
1868 /* now set value in argv */
1869 *(int *)argv[vo->index] = id;
1870
1871 return (SMS_EXISTS);
1872##}
1873
1874\f
1875translate_ids(q, sq, v, action, actarg)
1876 register struct query *q;
1877 register struct save_queue *sq;
1878 register struct validate *v;
1879 register int (*action)();
1880 int actarg;
1881##{
1882## char *name;
1883## char *field_type;
1884## char data_type[17];
1885## int id;
1886## int rowcount;
1887 register int i;
1888 struct valobj *vo;
1889 char **argv;
1890
1891 for (i = 0; i < v->objcnt; i++) {
1892 vo = &v->valobj[i];
1893 if (vo->type == V_FOLLOWUP) break;
1894 }
1895
1896 /* for each row */
1897 while (sq_get_data(sq, &argv)) {
1898
1899 /* get object id */
1900 i = vo->index;
1901 sscanf(argv[i], "%d", &id);
1902 free(argv[i]);
1903 name = (char *)malloc(129);
1904 argv[i] = name;
1905
1906 /* get field type string (known to be at index-1) */
1907 field_type = argv[vo->index-1];
1908
1909 /* get corresponding data type associated with field type name */
1910## repeat retrieve (data_type = alias.trans)
1911## where alias.#name = @field_type and alias.type = "TYPEDATA"
1912## inquire_equel (rowcount = "rowcount")
1913 if (rowcount != 1) {
1914 sprintf(name, "%d", id);
1915 (*action)(q->vcnt, argv, actarg);
1916 continue;
1917 }
1918
1919 /* retrieve object name */
1920
1921 if (!strcmp(data_type, "user")) {
1922 /* USER */
1923## repeat retrieve (name = users.login) where users.users_id = @id
1924## inquire_equel (rowcount = "rowcount")
1925
1926 } else if (!strcmp(data_type, "list")) {
1927 /* LIST */
1928## repeat retrieve (name = list.#name) where list.list_id = @id
1929## inquire_equel (rowcount = "rowcount")
1930
1931 } else if (!strcmp(data_type, "machine")) {
1932 /* MACHINE */
1933## repeat retrieve (name = machine.#name) where machine.mach_id = @id
1934## inquire_equel (rowcount = "rowcount")
1935
1936 } else if (!strcmp(data_type, "string")) {
1937 /* STRING */
1938## repeat retrieve (name = strings.string)
1939## where strings.string_id = @id
1940## inquire_equel (rowcount = "rowcount")
1941
1942 } else {
1943 rowcount = 0;
1944 }
1945
1946 /* if there wasn't a corresponding object name, then use the id */
1947 if (rowcount != 1) sprintf(name, "%d", id);
1948
1949 /* send the data */
1950 (*action)(q->vcnt, argv, actarg);
1951
1952 /* free saved data */
1953 for (i = 0; i < q->vcnt; i++)
1954 free(argv[i]);
1955 free(argv);
1956 }
1957
1958 sq_destroy(sq);
1959 return (SMS_SUCCESS);
1960##}
1961\f
1962/*
1963 * Local Variables:
1964 * mode: c
1965 * c-indent-level: 4
1966 * c-continued-statement-offset: 4
1967 * c-brace-offset: -4
1968 * c-argdecl-indent: 4
1969 * c-label-offset: -4
1970 * End:
1971 */
This page took 0.36396 seconds and 5 git commands to generate.