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