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