]> andersk Git - moira.git/blame - server/qsupport.qc
add Password_input
[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$
b4182127 9 * Revision 1.7 1987-08-04 01:49:41 wesommer
10 * Rearranged messages.
05cdd922 11 *
b4182127 12Revision 1.6 87/08/04 01:10:02 wesommer
13Changes by mike; checked in prior to my hacking.
14
c2408bd5 15Revision 1.5 87/07/30 14:54:13 wesommer
16Added debugging code in an attempt to catch a flakey problem.
17
247969d5 18Revision 1.4 87/07/30 00:30:21 wesommer
19replaced appends = appends+1 with appends = tbs.appends+1
20
3b2ceb9a 21Revision 1.3 87/07/30 00:26:11 wesommer
22Changes by mike prior to "appends" fix.
23
30967516 24Revision 1.2 87/07/29 16:00:39 wesommer
25Fixed add_locker.
26
7195989f 27Revision 1.1 87/07/29 15:13:57 wesommer
28Initial revision
29
05cdd922 30 */
31
32#ifndef lint
33static char *rcsid_qsupport_qc = "$Header$";
34#endif lint
35
36#include "query.h"
37#include "sms_server.h"
38#include <ctype.h>
39
40#define SMS_SUCCESS 0
41
42extern char *whoami;
43
44/* Specialized Access Routines */
45
46/**
47 ** access_user - verify that client name equals specified login name
48 **
49 ** Used by: update_user_shell
50 ** update_finger_by_login
51 **
52 ** - since field validation routines are called first, a users_id is
53 ** now in argv[0] instead of the login name. Therefore, we must
54 ** convert the client name to a users_id.
55 **/
56
57access_user(q, argv, cl)
58 struct query *q;
59 char *argv[];
60 client *cl;
61##{
62 register struct krbname *krb;
63## int client_id;
64## char *client_name;
65## int rowcount;
66
67 client_name = cl->kname.name;
68## repeat retrieve (client_id = users.users_id)
69## where users.login = @client_name
70## inquire_equel (rowcount = "rowcount")
71 if (rowcount != 1) return(SMS_PERM);
72 if (client_id != *(int *)argv[0]) return(SMS_PERM);
73
74 return(SMS_SUCCESS);
75##}
76
30967516 77/**
78 ** access_pop - same as access_user plus verifies that a user has only one
79 ** mailbox of type "POP"
80 **
81 ** Inputs:
82 ** argv[0] - users_id
83 ** argv[1] - type
84 ** argv[2] - mach_id
85 ** argv[3] - box
86 **
87 ** Description:
88 ** - if q->name = "add_pobox" and type = "POP",
89 ** verify that no POP box already exists for user
90 ** - call access_user
91 **
92 **/
93
94access_pop(q, argv, cl)
95 struct query *q;
96 char *argv[];
97 client *cl;
98##{
99## int users_id;
100## int mach_id;
101## char *box;
102## int exists;
103
104 if (!bcmp(q->name, "add_pobox", 10) && !bcmp(argv[1], "POP", 4)) {
105 users_id = *(int *)argv[0];
106 mach_id = *(int *)argv[2];
107 box = argv[3];
108## range of p is pobox
109## repeat retrieve (exists = any(p.#box where p.#users_id = @users_id
110## and p.type = "POP"
111## and p.#mach_id = @mach_id
112## and p.#box = @box))
113 if (exists) return(SMS_EXISTS);
114 }
115
116 return(access_user(q, argv, cl));
117##}
118
05cdd922 119/**
120 ** access_list - check access for adding or deleting list members
121 **
122 ** Inputs: argv[0] - list_id
123 ** cl->krb.name - client name
124 **
125 ** - check that client is a member of the access control list
126 ** - OR, if q->shortname == {amtl | dfml} and
127 ** if list.flags & LF_PUBLIC, allow access if client = member
128 **
129 **/
130
131access_list(q, argv, cl)
132 struct query *q;
133 char *argv[];
134 client *cl;
135##{
136## int list_id;
137## int acl_id;
138## int flags;
139 int member_id;
140 char *client_type;
141 int client_id;
142 int status;
143 int exists;
144
145 list_id = *(int *)argv[0];
146## repeat retrieve (acl_id = list.#acl_id, flags = list.#flags)
147## where list.#list_id = @list_id
148
149 /* parse client structure */
150 status = get_client(cl, &client_type, &client_id);
151 if (status != SMS_SUCCESS) return(status);
152
153 /* if amtl or dmfl and list is public allow client to add or delete self */
154 if (!bcmp("amtl", q->shortname, 4) || !bcmp("dmfl", q->shortname, 4)) {
155 if ((flags & LF_PUBLIC) && !bcmp("USER", argv[1], 4)) {
156 member_id = *(int *)argv[2];
157 if (member_id == client_id) return(SMS_SUCCESS);
158 }
159 }
160
161 /* check for client in access control list */
162 exists = find_member(acl_id, client_type, client_id, 0);
163 if (!exists) return(SMS_PERM);
164
165 return(SMS_SUCCESS);
166##}
167\f
168/**
169 ** Setup routine for add_user
170 **
171 ** Inputs: argv[0] - login
172 ** argv[1] - uid
173 **
174 ** Description:
175 **
176 ** - if argv[1] == "#" then set argv[1] = next(uid)
177 ** - if argv[0] == "#" then set argv[0] = "#<uid>"
178 **
179 **/
180
181setup_add_user(q, argv, cl, access_check)
182 struct query *q;
183 register char *argv[];
184 client *cl;
185 int access_check;
186##{
187## int nuid;
188## int exists;
189
190 if (access_check) return(SMS_SUCCESS);
191
192 if (!bcmp(argv[1], "#", 2)) {
193## range of u is users
194## range of v is values
195## repeat retrieve (nuid = v.value) where v.name = "uid"
196 exists = 1;
197 while (exists) {
198 nuid++;
199## repeat retrieve (exists = any(u.#uid where u.#uid = @nuid))
200 }
201## repeat replace v (value = @nuid) where v.name = "uid"
202 sprintf(argv[1], "%d", nuid);
203 }
204
205 if (!bcmp(argv[0], "#", 2)) {
206 sprintf(argv[0], "#%s", argv[1]);
207 }
208
209 return(SMS_SUCCESS);
210##}
211
212/**
213 ** Setup routine for add_group
214 **
215 ** Inputs: none
216 **
217 ** Description: allocate next gid and store in values table
218 **
219 **/
220
221setup_add_group(q, argv, cl, access_check)
222 struct query *q;
223 char *argv[];
224 client *cl;
225 int access_check;
226##{
227## int ngid;
228## int exists;
229
230 if (access_check) return(SMS_SUCCESS);
231
232## range of g is groups
233## range of v is values
234## repeat retrieve (ngid = v.value) where v.name = "gid"
235 exists = 1;
236 while (exists) {
237 ngid++;
238## repeat retrieve (exists = any(g.#gid where g.#gid = @ngid))
239 }
240
241## repeat replace v (value = @ngid) where v.name = "gid"
242 return(SMS_SUCCESS);
243##}
244\f
c2408bd5 245/**
246 ** setup_add_filesys - verify existance of referenced file systems
247 ** setup_update_filesys - same, except argv[1..5] --> argv[2..6]
248 **
249 ** Inputs: Add Update
250 ** argv[0] - label label
251 ** argv[1] - type new label
252 ** argv[2] - mach_id type
253 ** argv[3] - name mach_id
254 ** argv[4] - mount name
255 ** argv[5] - access mount
256 ** argv[6] - access
257 **
258 ** Description:
259 ** - for type = RVD:
260 ** * verify mach_id/name in rvdvirt
261 ** * verify access in {r, x, R, X}
262 ** - for type = NFS:
263 ** * extract directory prefix from name
264 ** * verify mach_id/dir in nfsphys
265 ** * verify access in {r, w, R, W}
266 **
267 ** Errors:
268 ** SMS_RVD - no such rvd
269 ** SMS_NFS - specified directory not exported
270 ** SMS_FILESYS_ACCESS - invalid filesys access
271 **
272 **/
273
274setup_add_filesys(q, argv)
275 struct query *q;
276 char *argv[];
277{
278 char *type;
279 int mach_id;
280 char *name;
281 char *access;
282
283 type = argv[1];
284 mach_id = *(int *)argv[2];
285 name = argv[3];
286 access = argv[5];
287
288 if (!bcmp(type, "RVD", 3))
289 return (check_rvd(mach_id, name, access));
290 else if (!bcmp(type, "NFS", 3))
291 return (check_nfs(mach_id, name, access));
292 else
293 return(SMS_SUCCESS);
294}
295
296setup_update_filesys(q, argv)
297 struct query *q;
298 char *argv[];
299{
300 char *type;
301 int mach_id;
302 char *name;
303 char *access;
304
305 type = argv[2];
306 mach_id = *(int *)argv[3];
307 name = argv[4];
308 access = argv[6];
309
310 if (!bcmp(type, "RVD", 3))
311 return (check_rvd(mach_id, name, access));
312 else if (!bcmp(type, "NFS", 3))
313 return (check_nfs(mach_id, name, access));
314 else
315 return(SMS_SUCCESS);
316}
317
318##check_rvd(mach_id, name, access)
319## int mach_id;
320## char *name;
321 char *access;
322##{
323## int rowcount;
324 char caccess;
325
326## range of rv is rvdvirt
327## retrieve (rowcount = any(rv.#name where rv.#mach_id = mach_id and
328## rv.#name = name))
329 if (rowcount == 0) return(SMS_RVD);
330
331 caccess = (isupper(*access)) ? tolower(*access) : *access;
332 if (caccess != 'r' && caccess != 'x') return(SMS_FILESYS_ACCESS);
333
334 return(SMS_SUCCESS);
335##}
336
337##check_nfs(mach_id, name, access)
338## int mach_id;
339 char *name;
340 char *access;
341##{
342## int rowcount;
343## char dir[32];
344 char caccess;
345 register char *cp1;
346 register char *cp2;
347
348 caccess = (isupper(*access)) ? tolower(*access) : *access;
349 if (caccess != 'r' && caccess != 'w') return(SMS_FILESYS_ACCESS);
350
351## range of np is nfsphys
352## retrieve (dir = np.#dir) where np.#mach_id = mach_id
353## {
354 cp1 = name;
355 cp2 = dir;
356 while (*cp2) {
357 if (*cp1++ != *cp2) break;
358 cp2++;
359 }
360 if (*cp2 == 0) return(SMS_SUCCESS);
361## }
362
363 return(SMS_NFS);
364##}
365\f
05cdd922 366/* Followup Routines */
367
368set_user_modtime(q, argv)
369 struct query *q;
370 char *argv[];
371##{
372## char *login;
373
374 login = argv[0];
375## repeat replace u (modtime = "now") where u.#login = @login
376 return(SMS_SUCCESS);
377##}
378
379set_user_modtime_by_id(q, argv)
380 struct query *q;
381 char *argv[];
382##{
383## int users_id;
384
385 users_id = *(int *)argv[0];
386## repeat replace users (modtime = "now") where users.#users_id = @users_id
387 return(SMS_SUCCESS);
388##}
389
390set_list_modtime(q, argv)
391 struct query *q;
392 char *argv[];
393##{
394## char *list_name;
395
396 list_name = argv[0];
397## repeat replace list (modtime = "now") where list.name = @list_name
398 return(SMS_SUCCESS);
399##}
400
401set_list_modtime_by_id(q, argv)
402 struct query *q;
403 char *argv[];
404##{
405## int list_id;
406
407 list_id = *(int *)argv[0];
408## repeat replace list (modtime = "now") where list.#list_id = @list_id
409 return(SMS_SUCCESS);
410##}
411
412set_finger_modtime(q, argv)
413 struct query *q;
414 char *argv[];
415##{
416## int users_id;
417
418 users_id = *(int *)argv[0];
419## repeat replace f (modtime = "now") where f.#users_id = @users_id
420 return(SMS_SUCCESS);
421##}
422
30967516 423/**
424 ** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
425 **
426 ** Inputs:
427 ** q->name - "add_pobox" or "delete_pobox"
428 ** argv[2] - mach_id
429 **
430 ** Description:
431 ** - incr/decr value field in serverhosts table for pop/mach_id
432 **
433 **/
434
435set_pop_usage(q, argv)
436 struct query *q;
437 char *argv[];
438##{
439## int mach_id;
440
441 mach_id = *(int *)argv[2];
442## range of sh is serverhosts
443
444 if (!bcmp(q->name, "add_pobox", 10)) {
445## repeat replace sh (value1 = sh.value1 + 1)
446## where sh.service = "pop" and sh.#mach_id = @mach_id
447 } else if (!bcmp(q->name, "delete_pobox", 13)) {
448## repeat replace sh (value1 = sh.value1 - 1)
449## where sh.service = "pop" and sh.#mach_id = @mach_id
450 }
451
452 return(SMS_SUCCESS);
453##}
454
05cdd922 455/**
456 ** delete_list_members - called after the delete_list query to clean up
457 ** members table.
458 **
459 ** Inputs: argv[0] - list_id
460 **
461 ** Description:
462 ** - foreach string member: decr string refc; ifzero, delete string
463 ** - delete all members entries for this list_id
464 **
465 **/
466
467delete_list_members(q, argv)
468 struct query *q;
469 register char *argv[];
470##{
471## int list_id;
472## int string_id;
473## int refc;
474## int rowcount;
475 struct save_queue *sq;
476 struct save_queue *sq_create();
477
478 list_id = *(int *)argv[0];
479 sq = sq_create();
480
481## range of m is members
482## repeat retrieve (string_id = m.member_id)
483## where m.#list_id = @list_id and m.member_type = "STRING"
484## {
485 sq_save_data(sq, string_id);
486## }
487
488 while (sq_get_data(sq, &string_id)) {
489## range of s is strings
490## repeat retrieve (refc = s.#refc) where s.#string_id = @string_id
491## inquire_equel (rowcount = "rowcount")
492 if (rowcount == 0) continue;
493 if (--refc == 0) {
494## repeat delete s where s.#string_id = @string_id
495 } else {
496## repeat replace s (#refc = @refc) where s.#string_id = @string_id
497 }
498 }
499 sq_destroy(sq);
500
501## repeat delete m where m.#list_id = @list_id
502
503 return(SMS_SUCCESS);
504##}
505
506/**
507 ** grvd_support - Support routine for get_rvd_servers query
508 **
509 ** Inputs:
510 ** q - grvd query structure
511 ** sq - save_queue struture: contains list of {machine, oper_acl_id,
512 ** admin_acl_id, shutdown_acl_id} records.
513 ** v - validate structure (not used)
514 ** action - action routine
515 ** actarg - action routine argument
516 **
517 ** Description:
518 ** - translate acl_ids to list names
519 **
520 **/
521
522grvd_support(q, sq, v, action, actarg)
523 struct query *q;
524 struct save_queue *sq;
525 struct validate *v;
526 int (*action)();
527 int actarg;
528##{
529 char **argv;
530 char *targv[4];
531## char oper[33];
532## char admin[33];
533## char shutdown[33];
534## int list_id;
535
30967516 536 targv[0] = oper;
537 targv[1] = admin;
538 targv[2] = shutdown;
05cdd922 539
540## range of l is list
541
542 while (sq_get_data(sq, &argv)) {
30967516 543 sscanf(argv[0], "%d", &list_id);
05cdd922 544## repeat retrieve (oper = l.name) where l.#list_id = @list_id
30967516 545 sscanf(argv[1], "%d", &list_id);
05cdd922 546## repeat retrieve (admin = l.name) where l.#list_id = @list_id
30967516 547 sscanf(argv[2], "%d", &list_id);
05cdd922 548## repeat retrieve (shutdown = l.name) where l.#list_id = @list_id
549
30967516 550 (*action)(3, targv, actarg);
05cdd922 551 free(argv[0]);
552 free(argv[1]);
553 free(argv[2]);
05cdd922 554 }
555
556 sq_destroy(sq);
557 return(SMS_SUCCESS);
558##}
559
560/**
561 ** set_next_object_id - set next object id in values table
562 **
563 ** Inputs: object - object name in values table
564 **
565 ** - called before an APPEND operation to set the next object id to
566 ** be used for the new record
567 **
568 **/
569
570set_next_object_id(object)
571 char *object;
572##{
573## char *name;
05cdd922 574
575 name = object;
576## range of v is values
30967516 577## repeat replace v (value = v.value + 1) where v.#name = @name
578 return(SMS_SUCCESS);
579##}
580
581/**
582 ** get_query_need - check modtime of query's associated table against given
583 ** time and return true if greater (false if not)
584 **
585 ** Inputs:
586 ** argv[0] - query name
587 ** argv[1] - time to compare against
588 **
589 **/
590
591get_query_need(q, argv, action, actarg)
592 struct query *q;
593 register char *argv[];
594 int (*action)();
595##{
596 struct query *q1;
597## char *last_get_time;
598## char *table;
599## int need;
600 char *result;
601 struct query *get_query_by_name();
602
603 q1 = get_query_by_name(argv[0]);
604
605 last_get_time = argv[1];
606 table = q1->rtable;
607
608 if (q1->type != RETRIEVE || table == (char *)0) return(SMS_NO_MATCH);
609
610## range of tbs is tblstats
611## repeat retrieve (need = any(tbs.modtime where tbs.#table = @table and
612## tbs.modtime > @last_get_time))
613
614 result = (need) ? "true" : "false";
615 (*action)(1, &result, actarg);
05cdd922 616 return(SMS_SUCCESS);
617##}
618
619\f
620/**
621 ** add_locker - special query routine for creating a user locker
622 **
623 ** Inputs:
624 ** argv[0] - users_id
625 ** argv[1] - machine_id
626 ** argv[2] - device
627 ** argv[3] - initial quota
628 **
629 ** Description:
630 ** - get prefix directory (dir) for mount point on specified machine/device
631 ** - create filesys entry (label=<login>, type=NFS, machine=<machine>,
632 ** mount=<dir>/<login>, access=w, acl=dbadmin)
633 ** - increment allocated in nfsphys by quota
634 ** - create nfsquota entry
635 **
636 ** Errors:
637 ** - SMS_NFSPHYS - machine/device does not exist in nfsphys
638 ** - SMS_FILESYS_EXISTS - file system already exists
639 **
640 **/
641
642add_locker(q, argv)
643 register struct query *q;
644 char *argv[];
645##{
646## int users_id;
647## int mach_id;
648## char *device;
649## int quota;
650## int rowcount;
30967516 651## char login[9];
05cdd922 652## char dir[32];
653## int allocated;
654## char locker[64];
655## char mount[64];
656## int user_acl;
657
658 /* copy arguments */
659 users_id = *(int *)argv[0];
660 mach_id = *(int *)argv[1];
661 device = argv[2];
662 sscanf(argv[3], "%d", &quota);
663
664## range of u is users
665## range of f is filesys
666## range of np is nfsphys
30967516 667## range of tbs is tblstats
05cdd922 668
669 /* get login name */
670## repeat retrieve (login = u.#login) where u.#users_id = @users_id
671
672 /* get user's acl id */
673## repeat retrieve (user_acl = list.list_id) where list.name = @login
674
675 /* get filesystem directory prefix; give error if machine/device
676 pair not in nfsphys table */
247969d5 677 printf("np.mach_id = %d and np.device = %s\n", mach_id, device);
678
05cdd922 679## repeat retrieve (dir = np.#dir, allocated = np.#allocated)
680## where np.#mach_id = @mach_id and np.#device = device
681## inquire_equel (rowcount = "rowcount")
682 if (rowcount == 0) return(SMS_NFSPHYS);
683
684 /* make sure a filesys with user's name does not already exist */
685## repeat retrieve (rowcount = any(f.label where f.label = @login))
686 if (rowcount != 0) return(SMS_FILESYS_EXISTS);
687
688 /* create a new filesys */
689 sprintf(locker, "%s/%s", dir, login);
690 sprintf(mount, "/mit/%s", login);
691## repeat append filesys
7195989f 692## (#label = @login, type = "NFS", #mach_id = @mach_id,
05cdd922 693## name = @locker, access = "w", order = 1, #mount = @mount,
694## acl_id = @user_acl)
30967516 695## repeat replace tbs (appends = tbs.appends + 1, modtime = "now")
696## where tbs.table = "filesys"
05cdd922 697
698 /* increment usage count in nfsphys table */
699 allocated += quota;
700## replace np (#allocated = allocated)
701## where np.#mach_id = mach_id and np.#device = device
30967516 702## repeat replace tbs (updates = tbs.updates + 1, modtime = "now")
703## where tbs.table = "nfsphys"
05cdd922 704
705 /* create nfsquota entry */
706## append nfsquota (#users_id = users_id, #mach_id = mach_id,
7195989f 707## #device = device, #quota = quota)
3b2ceb9a 708## repeat replace tbs (appends = tbs.appends + 1, modtime = "now")
30967516 709## where tbs.table = "nfsquota"
710
711 return(SMS_SUCCESS);
712##}
713
714/**
715 ** delete_locker - special query routine for deleting a user locker
716 **
717 ** Inputs:
718 ** argv[0] - users_id
719 ** argv[1] - machine_id
720 ** argv[2] - device
721 ** argv[3] - quota
722 **
723 ** Description:
724 ** - delete filesys entry (label=<login>)
725 ** - decrement allocated in nfsphys by quota
726 ** - delete nfsquota entry
727 **
728 ** Errors:
729 ** - SMS_FILESYS - no filesys exists for user
730 **
731 **/
732
733delete_locker(q, argv)
734 register struct query *q;
735 register char *argv[];
736##{
737## int users_id;
738## int mach_id;
739## char *device;
740## int quota;
741## int rowcount;
742## char login[9];
743
744 /* copy arguments */
745 users_id = *(int *)argv[0];
746 mach_id = *(int *)argv[1];
747 device = argv[2];
748 sscanf(argv[3], "%d", &quota);
749
750## range of u is users
751## range of f is filesys
752## range of np is nfsphys
753## range of nq is nfsquota
754## range of tbs is tblstats
755
756 /* get login name */
757## repeat retrieve (login = u.#login) where u.#users_id = @users_id
758
759 /* delete the filesys entry */
760## repeat delete f where f.label = @login
761## inquire_equel (rowcount = "rowcount")
762 if (rowcount == 0) return(SMS_FILESYS);
763## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now")
764## where tbs.table = "filesys"
765
766 /* decrement usage count in nfsphys table */
767## replace np (#allocated = np.#allocated - quota)
768## where np.#mach_id = mach_id and np.#device = device
769## repeat replace tbs (updates = tbs.updates + 1, modtime = "now")
770## where tbs.table = "nfsphys"
771
772 /* delete nfsquota entry */
773## delete nq where nq.#users_id = users_id and nq.#mach_id = mach_id and
774## nq.#device = device
775## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now")
776## where tbs.table = "nfsquota"
05cdd922 777
778 return(SMS_SUCCESS);
779##}
780\f
c2408bd5 781/**
782 ** get_members_of_list - optimized query for retrieval of list members
783 **
784 ** Inputs:
785 ** argv[0] - list_id
786 **
787 ** Description:
788 ** - retrieve USER members, then LIST members, then STRING members
789 **
790 **/
791
792get_members_of_list(q, argv, action, actarg)
793 struct query *q;
794 char *argv[];
795 int (*action)();
796 int actarg;
797##{
798## int list_id;
799## char member_name[129];
800 char *targv[2];
801
802 list_id = *(int *)argv[0];
803 targv[0] = "USER";
804 targv[1] = member_name;
805
806## range of m is members
807## repeat retrieve (member_name = users.login)
808## where m.#list_id = @list_id and m.member_type = "USER"
809## and m.member_id = users.users_id
810## {
811 (*action)(2, targv, actarg);
812## }
813
814 targv[0] = "LIST";
815## repeat retrieve (member_name = list.name)
816## where m.#list_id = @list_id and m.member_type = "LIST"
817## and m.member_id = list.#list_id
818## {
819 (*action)(2, targv, actarg);
820## }
821
822 targv[0] = "STRING";
823## repeat retrieve (member_name = strings.string)
824## where m.#list_id = @list_id and m.member_type = "STRING"
825## and m.member_id = strings.string_id
826## {
827 (*action)(2, targv, actarg);
828## }
829
830 return(SMS_SUCCESS);
831##}
832
833/**
834 ** get_all_poboxes - optimize query for retrieval of all poboxes
835 **
836 ** Description:
837 ** - retrieve LOCAL boxes, then POP boxes, then FOREIGN boxes
838 **
839 **/
840
841get_all_poboxes(q, argv, action, actarg)
842 struct query *q;
843 char *argv[];
844 int (*action)();
845 int actarg;
846##{
847## char login[9];
848## char machine[129];
849## char box[129];
850 char *targv[4];
851
852 targv[0] = login;
853 targv[2] = machine;
854 targv[3] = box;
855
856 targv[1] = "LOCAL";
857## range of p is pobox
858## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
859## where p.type = "LOCAL" and p.users_id = users.users_id
860## and p.mach_id = #machine.mach_id
861## {
862 (*action)(4, targv, actarg);
863## }
864
865 targv[1] = "POP";
866## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
867## where p.type = "POP" and p.users_id = users.users_id
868## and p.mach_id = #machine.mach_id
869## {
870 (*action)(4, targv, actarg);
871## }
872
873 targv[1] = "FOREIGN";
874## repeat retrieve (login=users.#login, machine=strings.string, box=p.#box)
875## where p.type = "FOREIGN" and p.users_id = users.users_id
876## and p.mach_id = strings.string_id
877## {
878 (*action)(4, targv, actarg);
879## }
880
881 return(SMS_SUCCESS);
882##}
883\f
05cdd922 884/* Validation Routines */
885
886validate_row(q, argv, v)
887 register struct query *q;
888 char *argv[];
889 register struct validate *v;
890##{
891## char *rvar;
892## char *table;
893## char *name;
894## char qual[128];
895## int rowcount;
896
897 /* build where clause */
898 build_qual(v->qual, v->argc, argv, qual);
899
900 /* setup ingres variables */
901 rvar = q->rvar;
902 table = q->rtable;
903 name = v->field;
904
b4182127 905 if (log_flags & LOG_RES)
906 /* tell the logfile what we're doing */
907 com_err(whoami, 0, "validating row: %s", qual);
908
05cdd922 909 /* look for the record */
910## range of rvar is table
911## retrieve (rowcount = count(rvar.name where qual))
05cdd922 912 if (rowcount == 0) return(SMS_NO_MATCH);
913 if (rowcount > 1) return(SMS_NOT_UNIQUE);
914 return(SMS_EXISTS);
915##}
916
917validate_fields(q, argv, vo, n)
918 struct query *q;
919 register char *argv[];
920 register struct valobj *vo;
921 register int n;
922{
923 register int status;
924 char buf[64];
925
926 while (--n >= 0) {
927 switch (vo->type) {
928 case V_NAME:
b4182127 929 if (log_flags&LOG_RES)
930 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 931 vo->namefield, vo->table, argv[vo->index]);
05cdd922 932 status = validate_name(argv, vo);
933 break;
934
935 case V_ID:
b4182127 936 if (log_flags&LOG_RES)
937 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 938 vo->idfield, vo->table, argv[vo->index]);
05cdd922 939 status = validate_id(argv, vo);
940 break;
941
942 case V_TYPE:
b4182127 943 if (log_flags&LOG_RES)
944 com_err(whoami, 0, "validating %s type: %s",
05cdd922 945 vo->table, argv[vo->index]);
05cdd922 946 status = validate_type(argv, vo);
947 break;
948
949 case V_TYPEDATA:
b4182127 950 if (log_flags&LOG_RES)
951 com_err(whoami, 0, "validating type-specific data: %s",
05cdd922 952 argv[vo->index]);
05cdd922 953 status = validate_typedata(q, argv, vo);
954 break;
955
956 case V_FOLLOWUP:
957 status = SMS_EXISTS;
958 break;
959
960 }
961
962 if (status != SMS_EXISTS) return(status);
963 vo++;
964 }
965
966 return(SMS_SUCCESS);
967}
968
969validate_id(argv, vo)
970 char *argv[];
971 register struct valobj *vo;
972##{
973## char *name;
974## char *table;
975## char *namefield;
976## char *idfield;
977## int id;
978## int rowcount;
979
980 name = argv[vo->index];
981 table = vo->table;
982 namefield = vo->namefield;
983 idfield = vo->idfield;
984## retrieve (id = table.idfield) where table.namefield = name
985## inquire_equel (rowcount = "rowcount")
986 if (rowcount != 1) return(vo->error);
987 *(int *)argv[vo->index] = id;
988 return(SMS_EXISTS);
989##}
990
991validate_name(argv, vo)
992 char *argv[];
993 register struct valobj *vo;
994##{
995## char *name;
996## char *table;
997## char *namefield;
998## int rowcount;
999
1000 name = argv[vo->index];
1001 table = vo->table;
1002 namefield = vo->namefield;
1003## retrieve (rowcount = countu(table.namefield
1004## where table.namefield = name))
1005 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
1006##}
1007
1008validate_type(argv, vo)
1009 char *argv[];
1010 register struct valobj *vo;
1011##{
1012## char *typename;
1013## char *value;
1014## int rowcount;
1015 register char *c;
1016
1017 typename = vo->table;
1018 value = argv[vo->index];
1019
1020 /* uppercase type fields */
1021 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
1022
1023## range of a is alias
1024## repeat retrieve (rowcount = count(a.trans where a.name = @typename and
1025## a.type = "TYPE" and
1026## a.trans = @value))
1027 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
1028##}
1029
1030/* validate member or type-specific data field */
1031
1032validate_typedata(q, argv, vo)
1033 register struct query *q;
1034 register char *argv[];
1035 register struct valobj *vo;
1036##{
1037## char *name;
1038## char *field_type;
1039## char data_type[17];
1040## int id;
1041## int refc;
1042## int rowcount;
1043
1044 /* get named object */
1045 name = argv[vo->index];
1046
1047 /* get field type string (known to be at index-1) */
1048 field_type = argv[vo->index-1];
1049
1050 /* get corresponding data type associated with field type name */
1051## repeat retrieve (data_type = alias.trans)
1052## where alias.#name = @field_type and alias.type = "TYPEDATA"
1053## inquire_equel (rowcount = "rowcount")
1054 if (rowcount != 1) return(SMS_TYPE);
1055
1056 /* now retrieve the record id corresponding to the named object */
1057
1058 if (!strcmp(data_type, "user")) {
1059 /* USER */
1060## repeat retrieve (id = users.users_id) where users.login = @name
1061## inquire_equel (rowcount = "rowcount")
1062 if (rowcount != 1) return(SMS_USER);
1063
1064 } else if (!strcmp(data_type, "list")) {
1065 /* LIST */
1066## repeat retrieve (id = list.list_id) where list.#name = @name
1067## inquire_equel (rowcount = "rowcount")
1068 if (rowcount != 1) return(SMS_LIST);
1069
1070 } else if (!strcmp(data_type, "machine")) {
1071 /* MACHINE */
1072## repeat retrieve (id = machine.mach_id) where machine.#name = @name
1073## inquire_equel (rowcount = "rowcount")
1074 if (rowcount != 1) return(SMS_MACHINE);
1075
1076 } else if (!strcmp(data_type, "string")) {
1077 /* STRING */
1078## range of s is strings
1079## repeat retrieve (id = s.string_id, refc = s.#refc)
1080## where s.string = @name
1081## inquire_equel (rowcount = "rowcount")
1082 if (rowcount == 0) {
1083 if (q->type != APPEND) return(SMS_STRING);
1084## range of v is values
1085## retrieve (id = v.value) where v.#name = "strings_id"
1086 id++;
1087## replace v (value = id) where v.#name = "strings_id"
1088## append to strings (string_id = id, string = name, #refc = 1)
1089 } else if (rowcount == 1) {
1090 if (q->type == APPEND || q->type == DELETE) {
1091 refc += (q->type == APPEND) ? 1 : -1;
1092 if (refc > 0) {
1093## replace s (#refc = refc) where s.string_id = id
1094 } else {
1095## delete s where s.string_id = id
1096 }
1097 }
1098 }
1099 } else {
1100 return(SMS_TYPE);
1101 }
1102
1103 /* now set value in argv */
1104 *(int *)argv[vo->index] = id;
1105
1106 return (SMS_EXISTS);
1107##}
1108
1109\f
1110translate_ids(q, sq, v, action, actarg)
1111 register struct query *q;
1112 register struct save_queue *sq;
1113 register struct validate *v;
1114 register int (*action)();
1115 int actarg;
1116##{
1117## char *name;
1118## char *field_type;
1119## char data_type[17];
1120## int id;
1121## int rowcount;
1122 register int i;
1123 struct valobj *vo;
1124 char **argv;
1125
1126 for (i = 0; i < v->objcnt; i++) {
1127 vo = &v->valobj[i];
1128 if (vo->type == V_FOLLOWUP) break;
1129 }
1130
1131 /* for each row */
1132 while (sq_get_data(sq, &argv)) {
1133
1134 /* get object id */
1135 i = vo->index;
1136 sscanf(argv[i], "%d", &id);
1137 free(argv[i]);
1138 name = (char *)malloc(129);
1139 argv[i] = name;
1140
1141 /* get field type string (known to be at index-1) */
1142 field_type = argv[vo->index-1];
1143
1144 /* get corresponding data type associated with field type name */
1145## repeat retrieve (data_type = alias.trans)
1146## where alias.#name = @field_type and alias.type = "TYPEDATA"
1147## inquire_equel (rowcount = "rowcount")
1148 if (rowcount != 1) {
1149 sprintf(name, "%d", id);
1150 (*action)(q->vcnt, argv, actarg);
1151 continue;
1152 }
1153
1154 /* retrieve object name */
1155
1156 if (!strcmp(data_type, "user")) {
1157 /* USER */
1158## repeat retrieve (name = users.login) where users.users_id = @id
1159## inquire_equel (rowcount = "rowcount")
1160
1161 } else if (!strcmp(data_type, "list")) {
1162 /* LIST */
1163## repeat retrieve (name = list.#name) where list.list_id = @id
1164## inquire_equel (rowcount = "rowcount")
1165
1166 } else if (!strcmp(data_type, "machine")) {
1167 /* MACHINE */
1168## repeat retrieve (name = machine.#name) where machine.mach_id = @id
1169## inquire_equel (rowcount = "rowcount")
1170
1171 } else if (!strcmp(data_type, "string")) {
1172 /* STRING */
1173## repeat retrieve (name = strings.string)
1174## where strings.string_id = @id
1175## inquire_equel (rowcount = "rowcount")
1176
1177 } else {
1178 rowcount = 0;
1179 }
1180
1181 /* if there wasn't a corresponding object name, then use the id */
1182 if (rowcount != 1) sprintf(name, "%d", id);
1183
1184 /* send the data */
1185 (*action)(q->vcnt, argv, actarg);
1186
1187 /* free saved data */
1188 for (i = 0; i < q->vcnt; i++)
1189 free(argv[i]);
1190 free(argv);
1191 }
1192
1193 sq_destroy(sq);
1194 return (SMS_SUCCESS);
1195##}
1196\f
1197/*
1198 * Local Variables:
1199 * mode: c
1200 * c-indent-level: 4
1201 * c-continued-statement-offset: 4
1202 * c-brace-offset: -4
1203 * c-argdecl-indent: 4
1204 * c-label-offset: -4
1205 * End:
1206 */
This page took 0.230904 seconds and 5 git commands to generate.