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