]> andersk Git - moira.git/blame - server/qsupport.qc
added copyright message
[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
c801de4c 7 * For copying and distribution information, please see the file
8 * <mit-copyright.h>.
05cdd922 9 *
05cdd922 10 */
11
12#ifndef lint
13static char *rcsid_qsupport_qc = "$Header$";
14#endif lint
15
c801de4c 16#include <mit-copyright.h>
05cdd922 17#include "query.h"
18#include "sms_server.h"
19#include <ctype.h>
20
05cdd922 21
822a6eba 22extern char *whoami, *strsave();
23
05cdd922 24
25/* Specialized Access Routines */
26
822a6eba 27/* access_user - verify that client name equals specified login name
28 *
29 * - since field validation routines are called first, a users_id is
30 * now in argv[0] instead of the login name.
31 */
05cdd922 32
33access_user(q, argv, cl)
34 struct query *q;
35 char *argv[];
36 client *cl;
822a6eba 37{
38 if (cl->users_id != *(int *)argv[0])
39 return(SMS_PERM);
40 else
41 return(SMS_SUCCESS);
42}
05cdd922 43
05cdd922 44
30967516 45
822a6eba 46/* access_login - verify that client name equals specified login name
47 *
48 * argv[0...n] contain search info. q->
49 */
50
51access_login(q, argv, cl)
30967516 52 struct query *q;
53 char *argv[];
54 client *cl;
55##{
822a6eba 56## int rowcount, id;
57## char qual[256];
58
59 build_qual(q->qual, q->argc, argv, qual);
60## retrieve (id = u.users_id) where qual
61## inquire_equel(rowcount = "rowcount")
62 if (rowcount != 1 || id != cl->users_id)
63 return(SMS_PERM);
64 else
65 return(SMS_SUCCESS);
30967516 66##}
67
822a6eba 68
69
70/* access_list - check access for most list operations
71 *
72 * Inputs: argv[0] - list_id
73 * q - query name
74 * argv[2] - member ID (only for queries "amtl" and "dmfl")
4179b9ce 75 * argv[7] - group IID (only for query "ulis")
76 * cl - client name
822a6eba 77 *
78 * - check that client is a member of the access control list
79 * - OR, if the query is add_member_to_list or delete_member_from_list
80 * and the list is public, allow access if client = member
81 */
05cdd922 82
83access_list(q, argv, cl)
84 struct query *q;
85 char *argv[];
86 client *cl;
87##{
4179b9ce 88## int list_id, acl_id, flags, rowcount, gid;
822a6eba 89## char acl_type[9];
05cdd922 90 char *client_type;
822a6eba 91 int client_id, status;
05cdd922 92
93 list_id = *(int *)argv[0];
822a6eba 94## repeat retrieve (acl_id = list.#acl_id, acl_type = list.#acl_type,
4179b9ce 95## gid = list.#gid, flags = list.#public)
05cdd922 96## where list.#list_id = @list_id
822a6eba 97## inquire_equel(rowcount = "rowcount")
98 if (rowcount != 1)
99 return(SMS_INTERNAL);
05cdd922 100
101 /* parse client structure */
822a6eba 102 if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
103 return(status);
05cdd922 104
105 /* if amtl or dmfl and list is public allow client to add or delete self */
822a6eba 106 if ((!strcmp("amtl", q->shortname) || !strcmp("dmfl", q->shortname)) &&
107 (flags && !strcmp("USER", argv[1]))) {
108 if (*(int *)argv[2] == client_id) return(SMS_SUCCESS);
4179b9ce 109 /* if update_list, don't allow them to change the GID */
110 } else if (!strcmp("ulis", q->shortname)) {
111 if ((!strcmp(argv[7], UNIQUE_GID) && (gid != -1)) ||
112 (strcmp(argv[7], UNIQUE_GID) && (gid != atoi(argv[7]))))
113 return(SMS_PERM);
05cdd922 114 }
115
116 /* check for client in access control list */
822a6eba 117 status = find_member(acl_type, acl_id, client_type, client_id, 0);
118 if (!status) return(SMS_PERM);
05cdd922 119
120 return(SMS_SUCCESS);
121##}
92a943d6 122
a6cb4d4c 123
822a6eba 124/* access_visible_list - allow access to list only if it is not hidden,
125 * or if the client is on the ACL
126 *
127 * Inputs: argv[0] - list_id
128 * cl - client identifier
129 */
130
131access_visible_list(q, argv, cl)
a6cb4d4c 132 struct query *q;
133 char *argv[];
134 client *cl;
135##{
822a6eba 136## int list_id, acl_id, flags, rowcount;
137## char acl_type[9];
138 char *client_type;
139 int client_id, status;
a6cb4d4c 140
141 list_id = *(int *)argv[0];
822a6eba 142## repeat retrieve (flags = list.hidden, acl_id = list.#acl_id,
143## acl_type = list.#acl_type) where list.#list_id = @list_id
144## inquire_equel(rowcount = "rowcount")
145 if (rowcount != 1)
146 return(SMS_INTERNAL);
147 if (!flags)
148 return(SMS_SUCCESS);
149
150 /* parse client structure */
151 if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
152 return(status);
153
154 /* check for client in access control list */
155 status = find_member(acl_type, acl_id, client_type, client_id, 0);
156 if (!status)
157 return(SMS_PERM);
158
159 return(SMS_SUCCESS);
a6cb4d4c 160##}
161
92a943d6 162
822a6eba 163/* access_vis_list_by_name - allow access to list only if it is not hidden,
164 * or if the client is on the ACL
165 *
166 * Inputs: argv[0] - list name
167 * cl - client identifier
168 */
169
170access_vis_list_by_name(q, argv, cl)
92a943d6 171 struct query *q;
172 char *argv[];
173 client *cl;
92a943d6 174##{
822a6eba 175## int acl_id, flags, rowcount;
176## char acl_type[9], *listname;
177 char *client_type;
178 int client_id, status;
179
180 listname = argv[0];
181## repeat retrieve (flags = list.hidden, acl_id = list.#acl_id,
182## acl_type = list.#acl_type) where list.#name = @listname
183## inquire_equel(rowcount = "rowcount");
184 if (rowcount > 1)
185 return(SMS_WILDCARD);
186 if (rowcount == 0)
187 return(SMS_NO_MATCH);
188 if (!flags)
189 return(SMS_SUCCESS);
92a943d6 190
822a6eba 191 /* parse client structure */
192 if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
193 return(status);
194
195 /* check for client in access control list */
196 status = find_member(acl_type, acl_id, client_type, client_id, 0);
197 if (!status)
198 return(SMS_PERM);
199
200 return(SMS_SUCCESS);
92a943d6 201##}
05cdd922 202
822a6eba 203
204/* access_member - allow user to access member of type "USER" and name matches
205 * username, or to access member of type "LIST" and list is one that user is
206 * on the acl of, or the list is visible.
207 */
208
209access_member(q, argv, cl)
05cdd922 210 struct query *q;
822a6eba 211 char *argv[];
05cdd922 212 client *cl;
822a6eba 213{
214 if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST"))
215 return(access_visible_list(q, &argv[1], cl));
05cdd922 216
822a6eba 217 if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) {
4179b9ce 218 if (cl->users_id == *(int *)argv[1])
822a6eba 219 return(SMS_SUCCESS);
05cdd922 220 }
221
822a6eba 222 return(SMS_PERM);
223}
05cdd922 224
05cdd922 225
822a6eba 226/* access_qgli - special access routine for Qualified_get_lists. Allows
227 * access iff argv[0] == "TRUE" and argv[2] == "FALSE".
228 */
229
230access_qgli(q, argv, cl)
231 struct query *q;
232 char *argv[];
233 client *cl;
234{
235 if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE"))
236 return(SMS_SUCCESS);
237 return(SMS_PERM);
238}
239
240
241/* access_service - allow access if user is on ACL of service. Don't
242 * allow access if a wildcard is used.
243 */
05cdd922 244
822a6eba 245access_service(q, argv, cl)
05cdd922 246 struct query *q;
247 char *argv[];
822a6eba 248 client *cl;
05cdd922 249##{
822a6eba 250## int acl_id, rowcount;
251## char *name, acl_type[9];
252 int client_id, status;
253 char *client_type;
05cdd922 254
822a6eba 255 name = argv[0];
256## repeat retrieve (acl_id = servers.#acl_id, acl_type = servers.#acl_type)
44bd6f44 257## where servers.#name = uppercase(@name)
822a6eba 258## inquire_equel(rowcount = "rowcount")
259 if (rowcount > 1)
260 return(SMS_PERM);
05cdd922 261
822a6eba 262 /* parse client structure */
263 if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
264 return(status);
92a943d6 265
822a6eba 266 /* check for client in access control list */
267 status = find_member(acl_type, acl_id, client_type, client_id, 0);
268 if (!status) return(SMS_PERM);
05cdd922 269
92a943d6 270 return(SMS_SUCCESS);
271##}
272
822a6eba 273
274
275/* access_filesys - verify that client is owner or on owners list of filesystem
276 * named by argv[0]
277 */
278
279access_filesys(q, argv, cl)
92a943d6 280 struct query *q;
281 char *argv[];
822a6eba 282 client *cl;
92a943d6 283##{
822a6eba 284## int rowcount, users_id, list_id;
285## char *name;
286 int status, client_id;
287 char *client_type;
92a943d6 288
822a6eba 289 name = argv[0];
290## repeat retrieve (users_id = filesys.owner, list_id = filesys.owners)
291## where filesys.label = @name
292## inquire_equel(rowcount = "rowcount")
293
294 if (rowcount != 1)
295 return(SMS_PERM);
296 if (users_id == cl->users_id)
297 return(SMS_SUCCESS);
298 if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
299 return(status);
300 status = find_member("LIST", list_id, client_type, client_id, 0);
301 if (status)
302 return(SMS_SUCCESS);
303 return(SMS_PERM);
05cdd922 304##}
822a6eba 305
306
05cdd922 307\f
822a6eba 308/* Setup Routines */
309
310/* Setup routine for add_user
311 *
312 * Inputs: argv[0] - login
313 * argv[1] - uid
314 *
315 * Description:
316 *
317 * - if argv[1] == UNIQUE_UID then set argv[1] = next(uid)
318 * - if argv[0] == UNIQUE_LOGIN then set argv[0] = "#<uid>"
319 */
c2408bd5 320
822a6eba 321setup_ausr(q, argv, cl)
c2408bd5 322 struct query *q;
822a6eba 323 register char *argv[];
324 client *cl;
325##{
326## int nuid, rowcount;
327
328 if (!strcmp(argv[1], UNIQUE_UID) || atoi(argv[1]) == -1) {
329 if (set_next_object_id("uid", "users"))
330 return(SMS_INGRES_ERR);
331## repeat retrieve (nuid = values.value) where values.name = "uid"
332## inquire_equel(rowcount = "rowcount")
333 if (rowcount != 1)
334 return(SMS_INTERNAL);
335 sprintf(argv[1], "%d", nuid);
336 }
c2408bd5 337
822a6eba 338 if (!strcmp(argv[0], UNIQUE_LOGIN) || atoi(argv[1]) == -1) {
339 sprintf(argv[0], "#%s", argv[1]);
340 }
c2408bd5 341
822a6eba 342 return(SMS_SUCCESS);
343##}
c2408bd5 344
c2408bd5 345
822a6eba 346/* setup_dusr - verify that the user is no longer being referenced
347 * and may safely be deleted.
348 */
c2408bd5 349
822a6eba 350int setup_dusr(q, argv)
351 struct query *q;
352 char **argv;
353##{
354## int flag, id;
355
356 id = *(int *)argv[0];
331b982e 357
358 /* For now, only allow users to be deleted if their status is 0 */
359## repeat retrieve (flag = u.status) where u.users_id = @id
360 if (flag != 0)
361 return(SMS_IN_USE);
362
44bd6f44 363## repeat delete nfsquota where nfsquota.users_id = @id
822a6eba 364## repeat retrieve (flag = any(members.member_id where members.member_id=@id
365## and members.member_type = "USER"))
366 if (flag)
367 return(SMS_IN_USE);
368## repeat retrieve (flag = any(filesys.label where filesys.owner=@id))
369 if (flag)
370 return(SMS_IN_USE);
371## repeat retrieve (flag = any(list.name where list.acl_id=@id and
372## list.acl_type = "USER"))
373 if (flag)
374 return(SMS_IN_USE);
375## repeat retrieve (flag = any(servers.name where servers.acl_id=@id and
376## servers.acl_type = "USER"))
377 if (flag)
378 return(SMS_IN_USE);
44bd6f44 379## repeat retrieve (flag=any(hostaccess.acl_id where hostaccess.acl_id=@id and
380## hostaccess.acl_type = "USER"))
381 if (flag)
382 return(SMS_IN_USE);
c2408bd5 383 else
384 return(SMS_SUCCESS);
822a6eba 385##}
c2408bd5 386
822a6eba 387
388/* setup_spop: verify that there is already a valid POP machine_id in the
389 * pop_id field. Also take care of keeping track of the post office usage.
390 */
391int setup_spop(q, argv)
392struct query *q;
393char **argv;
c2408bd5 394##{
e7fa3293 395## int id, mid, flag;
822a6eba 396## char type[9];
397
398 id = *(int *)argv[0];
e7fa3293 399## repeat retrieve (type = u.potype, mid = u.pop_id,
400## flag = any(machine.name where machine.mach_id = u.pop_id
401## and u.pop_id != 0 and u.users_id = @id))
4f16dc86 402## where u.users_id = @id
822a6eba 403 if (!flag)
404 return(SMS_MACHINE);
e7fa3293 405 if (strcmp(strtrim(type), "POP"))
406 set_pop_usage(mid, 1);
822a6eba 407 return(SMS_SUCCESS);
408##}
c2408bd5 409
c2408bd5 410
822a6eba 411/* setup_dpob: Take care of keeping track of the post office usage.
412 */
413int setup_dpob(q, argv)
414struct query *q;
415char **argv;
416##{
417## int id, user;
418## char type[9];
419
420 user = *(int *)argv[0];
421## repeat retrieve (type = u.potype, id = u.pop_id)
422## where u.users_id = @user
c2408bd5 423
e7fa3293 424 if (!strcmp(strtrim(type), "POP"))
822a6eba 425 set_pop_usage(id, -1);
c2408bd5 426 return(SMS_SUCCESS);
427##}
428
c2408bd5 429
822a6eba 430/* setup_dmac - verify that the machine is no longer being referenced
431 * and may safely be deleted.
432 */
c2408bd5 433
822a6eba 434int setup_dmac(q, argv)
05cdd922 435 struct query *q;
822a6eba 436 char **argv;
05cdd922 437##{
822a6eba 438## int flag, id;
439
440 id = *(int *)argv[0];
441## repeat retrieve (flag = any(users.login where users.potype = "POP"
442## and users.pop_id=@id))
443 if (flag)
444 return(SMS_IN_USE);
445## repeat retrieve (flag = any(serverhosts.mach_id
446## where serverhosts.mach_id=@id))
447 if (flag)
448 return(SMS_IN_USE);
449## repeat retrieve (flag = any(nfsphys.mach_id where nfsphys.mach_id=@id))
450 if (flag)
451 return(SMS_IN_USE);
452## repeat retrieve (flag = any(hostaccess.mach_id where hostaccess.mach_id=@id))
453 if (flag)
454 return(SMS_IN_USE);
e7fa3293 455## repeat retrieve (flag = any(printcap.mach_id where printcap.mach_id=@id))
331b982e 456 if (flag)
457 return(SMS_IN_USE);
44bd6f44 458
459## repeat delete mcmap where mcmap.mach_id = @id
460 return(SMS_SUCCESS);
05cdd922 461##}
462
05cdd922 463
822a6eba 464/* setup_dclu - verify that the cluster is no longer being referenced
465 * and may safely be deleted.
466 */
05cdd922 467
822a6eba 468int setup_dclu(q, argv)
05cdd922 469 struct query *q;
822a6eba 470 char **argv;
05cdd922 471##{
822a6eba 472## int flag, id;
473
474 id = *(int *)argv[0];
475## repeat retrieve (flag = any(mcmap.mach_id where mcmap.clu_id=@id))
476 if (flag)
477 return(SMS_IN_USE);
478## repeat retrieve (flag = any(svc.clu_id where svc.clu_id=@id))
479 if (flag)
480 return(SMS_IN_USE);
481 else
482 return(SMS_SUCCESS);
05cdd922 483##}
484
05cdd922 485
822a6eba 486/* setup_alis - if argv[5] is non-zero and argv[6] is UNIQUE_ID, then allocate
487 * a new gid and put it in argv[6]. Otherwise if argv[6] is UNIQUE_ID but
488 * argv[5] is not, then remember that UNIQUE_ID is being stored by putting
489 * a -1 there. Remember that this is also used for ulis, with the indexes
490 * at 6 & 7.
491 */
05cdd922 492
822a6eba 493int setup_alis(q, argv)
494struct query *q;
495char **argv;
05cdd922 496##{
822a6eba 497## int ngid;
498 char *malloc();
499 int idx;
500
501 if (!strcmp(q->shortname, "alis"))
502 idx = 6;
503 else if (!strcmp(q->shortname, "ulis"))
504 idx = 7;
505
506 if (!strcmp(argv[idx], UNIQUE_GID) || atoi(argv[idx]) == -1) {
507 if (atoi(argv[idx - 1])) {
508 if (set_next_object_id("gid", "list"))
509 return(SMS_INGRES_ERR);
510## repeat retrieve (ngid = values.value) where values.name = "gid"
511 sprintf(argv[idx], "%d", ngid);
512 } else {
513 strcpy(argv[idx], "-1");
514 }
515 }
05cdd922 516
05cdd922 517 return(SMS_SUCCESS);
518##}
a6cb4d4c 519
822a6eba 520
521/* setup_dlist - verify that the list is no longer being referenced
522 * and may safely be deleted.
523 */
524
525int setup_dlis(q, argv)
a6cb4d4c 526 struct query *q;
822a6eba 527 char **argv;
a6cb4d4c 528##{
822a6eba 529## int flag, id;
530
531 id = *(int *)argv[0];
532## repeat retrieve (flag = any(members.member_id where members.member_id=@id
533## and members.member_type = "LIST"))
534 if (flag)
535 return(SMS_IN_USE);
536## repeat retrieve (flag = any(members.member_id where members.list_id=@id))
537 if (flag)
538 return(SMS_IN_USE);
539## repeat retrieve (flag = any(filesys.label where filesys.owners=@id))
540 if (flag)
541 return(SMS_IN_USE);
542## repeat retrieve (flag = any(capacls.tag where capacls.list_id=@id))
543 if (flag)
544 return(SMS_IN_USE);
545## repeat retrieve (flag = any(list.name where list.acl_id=@id and
4f16dc86 546## list.acl_type = "LIST" and list.list_id != @id))
822a6eba 547 if (flag)
548 return(SMS_IN_USE);
549## repeat retrieve (flag = any(servers.name where servers.acl_id=@id and
550## servers.acl_type = "LIST"))
551 if (flag)
552 return(SMS_IN_USE);
44bd6f44 553## repeat retrieve (flag=any(hostaccess.acl_id where hostaccess.acl_id=@id and
554## hostaccess.acl_type = "LIST"))
555 if (flag)
556 return(SMS_IN_USE);
822a6eba 557## repeat retrieve (flag = any(zephyr.class
558## where zephyr.xmt_type = "LIST" and zephyr.xmt_id = @id or
559## zephyr.sub_type = "LIST" and zephyr.sub_id = @id or
560## zephyr.iws_type = "LIST" and zephyr.iws_id = @id or
561## zephyr.iui_type = "LIST" and zephyr.iui_id = @id))
562 if (flag)
563 return(SMS_IN_USE);
564 else
565 return(SMS_SUCCESS);
566##}
a6cb4d4c 567
a6cb4d4c 568
822a6eba 569/* setup_dsin - verify that the service is no longer being referenced
570 * and may safely be deleted.
571 */
a6cb4d4c 572
822a6eba 573int setup_dsin(q, argv)
574 struct query *q;
575 char **argv;
576##{
577## int flag;
578## char *name;
579
580 name = argv[0];
44bd6f44 581## repeat retrieve (flag = any(serverhosts.service
582## where serverhosts.service=uppercase(@name)))
822a6eba 583 if (flag)
584 return(SMS_IN_USE);
585## repeat retrieve (flag = servers.inprogress) where servers.#name = @name
586 if (flag)
587 return(SMS_IN_USE);
588 else
a6cb4d4c 589 return(SMS_SUCCESS);
822a6eba 590##}
a6cb4d4c 591
a6cb4d4c 592
822a6eba 593/* setup_dshi - verify that the service-host is no longer being referenced
594 * and may safely be deleted.
595 */
a6cb4d4c 596
822a6eba 597int setup_dshi(q, argv)
598 struct query *q;
599 char **argv;
600##{
601## int flag, id;
602## char *name;
a6cb4d4c 603
822a6eba 604 name = argv[0];
605 id = *(int *)argv[1];
606## repeat retrieve (flag=serverhosts.inprogress)
44bd6f44 607## where serverhosts.service=uppercase(@name) and serverhosts.mach_id=@id
822a6eba 608 if (flag)
609 return(SMS_IN_USE);
610 else
611 return(SMS_SUCCESS);
a6cb4d4c 612##}
822a6eba 613
614
a6cb4d4c 615/**
822a6eba 616 ** setup_add_filesys - verify existance of referenced file systems
617 **
618 ** Inputs: Add
619 ** argv[1] - type
620 ** argv[2] - mach_id
621 ** argv[3] - name
622 ** argv[5] - access
a6cb4d4c 623 **
624 ** Description:
822a6eba 625 ** - for type = RVD:
626 ** * allow anything
627 ** - for type = NFS:
628 ** * extract directory prefix from name
629 ** * verify mach_id/dir in nfsphys
630 ** * verify access in {r, w, R, W}
631 **
632 ** Side effect: sets variable var_phys_id to the ID of the physical
633 ** filesystem (nfsphys_id for NFS, 0 for RVD)
a6cb4d4c 634 **
822a6eba 635 ** Errors:
636 ** SMS_NFS - specified directory not exported
637 ** SMS_FILESYS_ACCESS - invalid filesys access
a6cb4d4c 638 **
639 **/
640
822a6eba 641##static int var_phys_id;
a6cb4d4c 642
822a6eba 643setup_afil(q, argv)
a6cb4d4c 644 struct query *q;
645 char *argv[];
646{
822a6eba 647 char *type;
648 int mach_id;
649 char *name;
650 char *access;
a6cb4d4c 651
a6cb4d4c 652 type = argv[1];
653 mach_id = *(int *)argv[2];
822a6eba 654 name = argv[3];
655 access = argv[5];
656 var_phys_id = 0;
a6cb4d4c 657
822a6eba 658 if (!strcmp(type, "NFS"))
659 return (check_nfs(mach_id, name, access));
660 else
661 return(SMS_SUCCESS);
662}
05cdd922 663
30967516 664
e7fa3293 665/* Verify the arguments, depending on the FStype. Also, if this is an
666 * NFS filesystem, then update any quotas for that filesystem to reflect
667 * the new phys_id.
668 */
669
822a6eba 670setup_ufil(q, argv)
30967516 671 struct query *q;
672 char *argv[];
e7fa3293 673##{
674 int mach_id, status;
675 char *type, *name, *access;
676## int fid;
30967516 677
822a6eba 678 type = argv[2];
679 mach_id = *(int *)argv[3];
680 name = argv[4];
681 access = argv[6];
682 var_phys_id = 0;
a6cb4d4c 683
e7fa3293 684 if (!strcmp(type, "NFS")) {
685 status = check_nfs(mach_id, name, access);
686 fid = *(int *)argv[0];
db767e36 687## replace nfsquota (phys_id = var_phys_id) where nfsquota.filsys_id = fid
e7fa3293 688 return(status);
689 } else
690 return(SMS_SUCCESS);
691##}
30967516 692
a6cb4d4c 693
822a6eba 694/* Find the NFS physical partition that the named directory is on.
695 * This is done by comparing the dir against the mount point of the
696 * partition. To make sure we get the correct match when there is
697 * more than one, we sort the query in reverse order by dir name.
698 */
a6cb4d4c 699
822a6eba 700##check_nfs(mach_id, name, access)
a6cb4d4c 701## int mach_id;
822a6eba 702 char *name;
703 char *access;
704##{
705## char dir[32];
706 char caccess;
707 register int status;
708 register char *cp1;
709 register char *cp2;
a6cb4d4c 710
822a6eba 711 caccess = (isupper(*access)) ? tolower(*access) : *access;
712 if (caccess != 'r' && caccess != 'w') return(SMS_FILESYS_ACCESS);
a6cb4d4c 713
822a6eba 714 status = SMS_NFS;
715## range of np is nfsphys
716## repeat retrieve (var_phys_id = np.#nfsphys_id, dir = trim(np.#dir))
717## where np.#mach_id = @mach_id sort by #dir:d {
718 cp1 = name;
719 cp2 = dir;
720 while (*cp2) {
721 if (*cp1++ != *cp2) break;
722 cp2++;
723 }
724 if (*cp2 == 0) {
725 status = SMS_SUCCESS;
a6cb4d4c 726## endretrieve
727 }
728## }
729
822a6eba 730 return(status);
30967516 731##}
a6cb4d4c 732
92a943d6 733
822a6eba 734/* setup_dfil: free any quota records associated with a filesystem
735 * when it is deleted.
736 */
92a943d6 737
822a6eba 738setup_dfil(q, argv, cl)
739 struct query *q;
740 char **argv;
741 client *cl;
742##{
743## int id;
92a943d6 744
822a6eba 745 id = *(int *)argv[0];
746## range of q is nfsquota
44bd6f44 747## range of fs is filesys
748## range of n is nfsphys
749## repeat replace n (allocated=n.allocated-sum(q.quota where q.filsys_id=@id))
750## where n.nfsphys_id = fs.phys_id and fs.filsys_id = @id
92a943d6 751
822a6eba 752## repeat delete q where q.filsys_id = @id
92a943d6 753 return(SMS_SUCCESS);
754##}
30967516 755
822a6eba 756
757/* setup_dnfp: check to see that the nfs physical partition does not have
758 * any filesystems assigned to it before allowing it to be deleted.
759 */
760
761setup_dnfp(q, argv, cl)
762 struct query *q;
763 char **argv;
92a943d6 764 client *cl;
92a943d6 765##{
822a6eba 766## int id, exists;
92a943d6 767
822a6eba 768 id = *(int *)argv[0];
769## repeat retrieve (exists = any(filesys.label where filesys.phys_id = @id))
770 if (exists)
771 return(SMS_IN_USE);
92a943d6 772 return(SMS_SUCCESS);
773##}
4b890cc4 774
4b890cc4 775
822a6eba 776/* setup_dnfq: Remove allocation from nfsphys before deleting quota.
777 * argv[0] = filsys_id
778 * argv[1] = users_id
779 */
780
781setup_dnfq(q, argv, cl)
782 struct query *q;
783 char **argv;
784 client *cl;
785##{
786## int quota, fs, user;
787
788 fs = *(int *)argv[0];
789 user = *(int *)argv[1];
790
791## range of q is nfsquota
792## repeat retrieve (quota = q.#quota) where q.users_id = @user and
793## q.filsys_id = @fs
794## repeat replace nfsphys (allocated = nfsphys.allocated - @quota)
795## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
796 return(SMS_SUCCESS);
797##}
798
799
800\f
801/* FOLLOWUP ROUTINES */
802
803/* generic set_modtime routine. This takes the table name from the query,
804 * and will update the modtime, modby, and modwho fields in the entry in
805 * the table whose name field matches argv[0].
806 */
807
808set_modtime(q, argv, cl)
4b890cc4 809 struct query *q;
810 char *argv[];
822a6eba 811 client *cl;
4b890cc4 812##{
822a6eba 813## char *name, *entity, *table;
814## int who;
4b890cc4 815
822a6eba 816 entity = cl->entity;
817 who = cl->users_id;
818 table = q->rtable;
819 name = argv[0];
4b890cc4 820
822a6eba 821## replace table (modtime = "now", modby = who, modwith = entity)
822## where table.#name = name
4b890cc4 823 return(SMS_SUCCESS);
824##}
825
822a6eba 826/* generic set_modtime_by_id routine. This takes the table name from
827 * the query, and the id name from the validate record,
828 * and will update the modtime, modby, and modwho fields in the entry in
829 * the table whose id matches argv[0].
830 */
831
832set_modtime_by_id(q, argv, cl)
4b890cc4 833 struct query *q;
822a6eba 834 char **argv;
835 client *cl;
4b890cc4 836##{
822a6eba 837## char *entity, *table, *id_name;
838## int who, id;
839
840 entity = cl->entity;
841 who = cl->users_id;
842 table = q->rtable;
843 id_name = q->validate->object_id;
4b890cc4 844
822a6eba 845 id = *(int *)argv[0];
846## replace table (modtime = "now", modby = who, modwith = entity)
847## where table.id_name = id
4b890cc4 848 return(SMS_SUCCESS);
849##}
850
822a6eba 851
852/* Sets the finger modtime on a user record. The users_id will be in argv[0].
853 */
854
855set_finger_modtime(q, argv, cl)
4b890cc4 856 struct query *q;
857 char *argv[];
822a6eba 858 client *cl;
4b890cc4 859##{
822a6eba 860## int users_id, who;
861## char *entity;
862
863 entity = cl->entity;
864 who = cl->users_id;
865 users_id = *(int *)argv[0];
4b890cc4 866
822a6eba 867## repeat replace u (fmodtime = "now", fmodby = @who, fmodwith = @entity)
868## where u.#users_id = @users_id
4b890cc4 869 return(SMS_SUCCESS);
870##}
05cdd922 871
822a6eba 872
873/* Sets the pobox modtime on a user record. The users_id will be in argv[0].
874 */
875
876set_pobox_modtime(q, argv, cl)
05cdd922 877 struct query *q;
822a6eba 878 char **argv;
879 client *cl;
05cdd922 880##{
822a6eba 881## int users_id, who;
882## char *entity;
05cdd922 883
822a6eba 884 entity = cl->entity;
885 who = cl->users_id;
886 users_id = *(int *)argv[0];
05cdd922 887
822a6eba 888## repeat replace users (pmodtime = "now", pmodby = @who, pmodwith = @entity)
889## where users.#users_id = @users_id
890 return(SMS_SUCCESS);
891##}
05cdd922 892
05cdd922 893
822a6eba 894/* Sets the modtime on a machine record. The machine name is in argv[0].
895 * This routine is different from the generic set_modtime in that the
896 * name is uppercased first.
897 */
898
899set_mach_modtime(q, argv, cl)
900 struct query *q;
901 char **argv;
902 client *cl;
903##{
904## char *host, *entity;
905## int who;
906
907 entity = cl->entity;
908 who = cl->users_id;
05cdd922 909
822a6eba 910 host = argv[0];
911## repeat replace m (modtime = "now", modby = @who, modwith = @entity)
912## where m.name = uppercase(@host)
05cdd922 913 return(SMS_SUCCESS);
914##}
05cdd922 915
822a6eba 916
917/* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
918 * is necessary for add_machine_to_cluster becuase the table that query
919 * operates on is "mcm", not "machine".
920 */
921
922set_mach_modtime_by_id(q, argv, cl)
05cdd922 923 struct query *q;
05cdd922 924 char **argv;
822a6eba 925 client *cl;
926##{
927## char *entity;
928## int who, id;
05cdd922 929
822a6eba 930 entity = cl->entity;
931 who = cl->users_id;
05cdd922 932
822a6eba 933 id = *(int *)argv[0];
934## range of m is machine
935## repeat replace m (modtime = "now", modby = @who, modwith = @entity)
936## where m.mach_id = @id
937 return(SMS_SUCCESS);
938##}
05cdd922 939
05cdd922 940
822a6eba 941/* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
942 * is necessary for add_cluster_data and delete_cluster_data becuase the
943 * table that query operates on is "svc", not "cluster".
944 */
945
946set_cluster_modtime_by_id(q, argv, cl)
947 struct query *q;
948 char **argv;
949 client *cl;
950##{
951## char *entity;
952## int who, id;
953
954 entity = cl->entity;
955 who = cl->users_id;
956
957 id = *(int *)argv[0];
958## range of c is cluster
959## repeat replace c (modtime = "now", modby = @who, modwith = @entity)
960## where c.clu_id = @id
05cdd922 961 return(SMS_SUCCESS);
962##}
963
822a6eba 964
965/* sets the modtime on the serverhost where the service name is in argv[0]
966 * and the mach_id is in argv[1].
967 */
968
969set_serverhost_modtime(q, argv, cl)
92a943d6 970 struct query *q;
822a6eba 971 char **argv;
972 client *cl;
92a943d6 973##{
822a6eba 974## char *entity, *serv;
975## int who, id;
976
977 entity = cl->entity;
978 who = cl->users_id;
979
980 serv = argv[0];
981 id = *(int *)argv[1];
982## repeat replace sh (modtime = "now", modby = @who, modwith = @entity)
44bd6f44 983## where sh.service = uppercase(@serv) and sh.mach_id = @id
822a6eba 984 return(SMS_SUCCESS);
985##}
986
987
988/* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
989 * directory name is in argv[1].
990 */
991
992set_nfsphys_modtime(q, argv, cl)
993 struct query *q;
92a943d6 994 char **argv;
822a6eba 995 client *cl;
996##{
997## char *entity, *dir;
998## int who, id;
92a943d6 999
822a6eba 1000 entity = cl->entity;
1001 who = cl->users_id;
92a943d6 1002
822a6eba 1003 id = *(int *)argv[0];
1004 dir = argv[1];
1005## repeat replace np (modtime = "now", modby = @who, modwith = @entity)
1006## where np.#dir = @dir and np.mach_id = @id
1007 return(SMS_SUCCESS);
1008##}
92a943d6 1009
92a943d6 1010
822a6eba 1011/* sets the modtime on a filesystem, where argv[0] contains the filesys
1012 * label.
1013 */
1014
1015set_filesys_modtime(q, argv, cl)
1016 struct query *q;
1017 char *argv[];
1018 client *cl;
1019##{
1020## char *label, *entity;
1021## int who;
1022
1023 entity = cl->entity;
1024 who = cl->users_id;
1025
1026 label = argv[0];
1027 if (!strcmp(q->shortname, "ufil"))
1028 label = argv[1];
1029
1030## repeat replace fs (modtime = "now", modby = @who, modwith = @entity,
1031## #phys_id = @var_phys_id) where fs.#label = @label
92a943d6 1032 return(SMS_SUCCESS);
1033##}
05cdd922 1034
822a6eba 1035
1036/* sets the modtime on a zephyr class, where argv[0] contains the class
1037 * name.
1038 */
1039
1040set_zephyr_modtime(q, argv, cl)
1041 struct query *q;
1042 char *argv[];
1043 client *cl;
05cdd922 1044##{
822a6eba 1045## char *class, *entity;
1046## int who;
1047
1048 entity = cl->entity;
1049 who = cl->users_id;
1050
1051 class = argv[0];
1052
1053## repeat replace z (modtime = "now", modby = @who, modwith = @entity)
1054## where z.#class = @class
1055 return(SMS_SUCCESS);
1056##}
1057
1058
1059/* fixes the modby field. This will be the second to last thing in the
1060 * argv, the argv length is determined from the query structure. It is
1061 * passed as a pointer to an integer. This will either turn it into a
1062 * username, or # + the users_id.
1063 */
1064followup_fix_modby(q, sq, v, action, actarg, cl)
1065 struct query *q;
1066 register struct save_queue *sq;
1067 struct validate *v;
1068 register int (*action)();
1069 register int actarg;
1070 client *cl;
1071##{
1072 register int i, j;
1073 char **argv, *malloc();
1074## int id, rowcount;
05cdd922 1075## char *name;
05cdd922 1076
822a6eba 1077 i = q->vcnt - 2;
1078 while (sq_get_data(sq, &argv)) {
1079 id = atoi(argv[i]);
1080 free(argv[i]);
1081 argv[i] = malloc(9);
1082 name = argv[i];
1083## repeat retrieve (name = users.login) where users.users_id = @id
1084## inquire_equel(rowcount = "rowcount")
1085 if (rowcount != 1) {
1086 sprintf(argv[i], "#%d", id);
1087 }
1088 (*action)(q->vcnt, argv, actarg);
1089 for (j = 0; j < q->vcnt; j++)
1090 free(argv[j]);
1091 free(argv);
1092 }
1093 sq_destroy(sq);
1094 return(SMS_SUCCESS);
30967516 1095##}
1096
822a6eba 1097
30967516 1098/**
822a6eba 1099 ** followup_ausr - add finger and pobox entries, set_user_modtime
30967516 1100 **
1101 ** Inputs:
822a6eba 1102 ** argv[0] - login (add_user)
1103 ** argv[3] - last name
1104 ** argv[4] - first name
1105 ** argv[5] - middle name
30967516 1106 **
1107 **/
1108
822a6eba 1109followup_ausr(q, argv, cl)
30967516 1110 struct query *q;
822a6eba 1111 char *argv[];
1112 client *cl;
30967516 1113##{
822a6eba 1114## int who;
1115## char *login, *entity;
1116## char fullname[129];
30967516 1117
822a6eba 1118 login = argv[0];
1119 who = cl->users_id;
1120 entity = cl->entity;
30967516 1121
822a6eba 1122 /* build fullname */
1123 if (strlen(argv[4]) && strlen(argv[5]))
1124 sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
1125 else if (strlen(argv[4]))
1126 sprintf(fullname, "%s %s", argv[4], argv[3]);
1127 else
1128 sprintf(fullname, "%s", argv[3]);
30967516 1129
822a6eba 1130 /* create finger entry, pobox & set modtime on user */
1131## repeat replace u (modtime = "now", modby=@who, modwith=@entity,
1132## #fullname=@fullname, mit_affil = u.mit_year,
1133## fmodtime="now", fmodby=@who, fmodwith=@entity,
1134## potype="NONE", pmodtime="now", pmodby=@who, pmodwith=@entity)
1135## where u.#login = @login
30967516 1136
05cdd922 1137 return(SMS_SUCCESS);
1138##}
1139
822a6eba 1140
1141/* followup_gpob: fixes argv[2] based on the IDs currently there and the
1142 * type in argv[1]. Then completes the upcall to the user.
1143 *
1144 * argv[2] is of the form "123:234" where the first integer is the machine
1145 * ID if it is a pop box, and the second is the string ID if it is an SMTP
1146 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
1147 * are skipped.
1148 */
1149
1150followup_gpob(q, sq, v, action, actarg, cl)
1151 register struct query *q;
1152 register struct save_queue *sq;
1153 register struct validate *v;
1154 register int (*action)();
1155 int actarg;
1156 client *cl;
1157##{
1158 char **argv, *index();
1159 char *ptype, *p;
1160## char box[129], *name;
1161## int mid, sid, rowcount;
1162
1163 /* for each row */
1164 while (sq_get_data(sq, &argv)) {
1165 sms_trim_args(2, argv);
1166 ptype = argv[1];
1167 p = index(argv[2], ':');
1168 *p++ = 0;
1169 mid = atoi(argv[2]);
1170 sid = atoi(p);
1171 free(argv[2]);
1172
1173 if (!strcmp(ptype, "POP")) {
1174## repeat retrieve (box=machine.#name) where machine.mach_id=@mid
1175## inquire_equel(rowcount = "rowcount")
1176 if (rowcount != 1)
1177 return(SMS_MACHINE);
1178 } else if (!strcmp(ptype, "SMTP")) {
1179## repeat retrieve (box=strings.string) where strings.string_id=@sid
1180## inquire_equel(rowcount = "rowcount")
1181 if (rowcount != 1)
1182 return(SMS_STRING);
1183 } else /* ptype == "NONE" */ {
1184 goto skip;
1185 }
1186
1187 if (!strcmp(q->shortname, "gpob")) {
1188 sid = atoi(argv[4]);
1189 free(argv[4]);
1190 argv[4] = malloc(9);
1191 name = argv[4];
1192## repeat retrieve (name = users.login) where users.users_id = @sid
1193## inquire_equel(rowcount = "rowcount")
1194 if (rowcount != 1)
1195 sprintf(name, "#%d", sid);
1196 }
1197
1198 argv[2] = box;
1199 (*action)(q->vcnt, argv, actarg);
1200 skip:
1201 /* free saved data */
1202 free(argv[0]);
1203 free(argv[1]);
1204 free(argv);
1205 }
1206
1207 sq_destroy(sq);
1208 return (SMS_SUCCESS);
1209##}
1210
1211
44bd6f44 1212/* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
1213 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
822a6eba 1214 * proper name based on the type, and repace that string in the argv.
1215 * Also fixes the modby field by called followup_fix_modby.
1216 */
1217
1218followup_glin(q, sq, v, action, actarg, cl)
1219 register struct query *q;
1220 register struct save_queue *sq;
1221 register struct validate *v;
1222 register int (*action)();
1223 int actarg;
1224 client *cl;
1225##{
1226 char **argv, *malloc(), *realloc(), *type;
1227## char *name;
1228## int id, rowcount;
1229 int i, idx;
1230
1231 idx = 8;
1232 if (!strcmp(q->shortname, "gsin"))
4f16dc86 1233 idx = 12;
822a6eba 1234
1235 while (sq_get_data(sq, &argv)) {
1236 sms_trim_args(q->vcnt, argv);
1237
1238 id = atoi(argv[i = q->vcnt - 2]);
1239 free(argv[i]);
1240 name = argv[i] = malloc(9);
1241## repeat retrieve (name = users.login) where users.users_id = @id
1242## inquire_equel(rowcount = "rowcount")
1243 if (rowcount != 1)
1244 sprintf(argv[i], "#%d", id);
1245
1246 id = atoi(argv[idx]);
1247 type = argv[idx - 1];
1248 if ((name = malloc(33)) == NULL)
1249 return(SMS_NO_MEM);
1250
1251 if (!strcmp(type, "LIST")) {
1252## repeat retrieve (name = list.#name) where list.list_id = @id
1253## inquire_equel(rowcount = "rowcount")
1254 if (rowcount != 1)
1255 strcpy(name, "???");
1256 } else if (!strcmp(type, "USER")) {
1257## repeat retrieve (name = users.login) where users.users_id = @id
1258## inquire_equel(rowcount = "rowcount")
1259 if (rowcount != 1)
1260 strcpy(name, "???");
1261 } else if (!strcmp(type, "NONE")) {
1262 strcpy(name, "NONE");
1263 } else
1264 strcpy(name, "???");
1265 free(argv[idx]);
1266 argv[idx] = name;
1267
1268 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) {
1269 argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
1270 strcpy(argv[6], UNIQUE_GID);
1271 }
1272
1273 /* send the data */
1274 (*action)(q->vcnt, argv, actarg);
1275
1276 /* free saved data */
1277 for (i = 0; i < q->vcnt; i++)
1278 free(argv[i]);
1279 free(argv);
1280 }
1281
1282 sq_destroy(sq);
1283 return (SMS_SUCCESS);
1284##}
1285
1286
1287/** followup_amtl - followup for amtl and dmfl; when adding a list
1288 ** member to a maillist, make member list a maillist also
1289 ** unless list is a user-group.
1290 ** Then set_list_modtime_by_id.
92a943d6 1291 **
1292 ** Inputs:
1293 ** argv[0] - list_id
822a6eba 1294 ** argv[1] - member_type
1295 ** argv[2] - member_id
92a943d6 1296 **
1297 **/
1298
822a6eba 1299followup_amtl(q, argv, cl)
92a943d6 1300 struct query *q;
1301 char *argv[];
822a6eba 1302 client *cl;
92a943d6 1303##{
92a943d6 1304## int list_id;
822a6eba 1305## int member_id;
1306## int exists, who;
1307## char *entity;
92a943d6 1308
1309 list_id = *(int *)argv[0];
822a6eba 1310 entity = cl->entity;
1311 who = cl->users_id;
1312
1313## range of l is list
1314## repeat replace l (modtime = "now", modby = @who, modwith = @entity)
1315## where l.#list_id = @list_id
92a943d6 1316
822a6eba 1317 /* if query is not amtl or if member_type is not LIST then return */
1318 if (bcmp(q->shortname, "amtl", 4) || bcmp(argv[1], "LIST", 4))
1319 return(SMS_SUCCESS);
92a943d6 1320
822a6eba 1321 member_id = *(int *)argv[2];
1322
1323 /* is parent list a mailing list? */
1324## repeat retrieve (exists = l.maillist) where l.#list_id=@list_id
1325 if (!exists)
1326 return(SMS_SUCCESS);
1327
1328 /* list is not a user-group; add list to maillist table */
1329## repeat replace l (maillist = 1) where l.#list_id = @member_id
92a943d6 1330 return(SMS_SUCCESS);
1331##}
1332
822a6eba 1333
1334/* followup_anfq: Add allocation to nfsphys after creating quota.
1335 * argv[0] = filsys_id
1336 * argv[2] = ascii(quota)
1337 */
1338
1339followup_anfq(q, argv, cl)
1340 struct query *q;
1341 char **argv;
1342 client *cl;
1343##{
1344## int quota, user, fs, who;
1345## char *entity;
1346
1347 fs = *(int *)argv[0];
1348 user = *(int *)argv[1];
1349 quota = atoi(argv[2]);
1350 who = cl->users_id;
1351 entity = cl->entity;
1352
1353## repeat replace nq (modtime = "now", modby = @who, modwith = @entity)
1354## where nq.filsys_id = @fs and nq.users_id = @user
1355## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
1356## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
1357 return(SMS_SUCCESS);
1358##}
1359
1360
1361/* followup_gzcl:
1362 */
1363
1364followup_gzcl(q, sq, v, action, actarg, cl)
1365 register struct query *q;
1366 register struct save_queue *sq;
1367 register struct validate *v;
1368 register int (*action)();
92a943d6 1369 int actarg;
822a6eba 1370 client *cl;
92a943d6 1371##{
822a6eba 1372## char *name;
1373## int rowcount, id;
1374 char **argv;
1375 int i;
92a943d6 1376
822a6eba 1377 while (sq_get_data(sq, &argv)) {
1378 sms_trim_args(q->vcnt, argv);
92a943d6 1379
822a6eba 1380 id = atoi(argv[i = q->vcnt - 2]);
1381 free(argv[i]);
1382 name = argv[i] = malloc(9);
1383## repeat retrieve (name = users.login) where users.users_id = @id
1384## inquire_equel(rowcount = "rowcount")
1385 if (rowcount != 1)
1386 sprintf(argv[i], "#%d", id);
1387
1388 for (i = 1; i < 8; i+=2) {
1389 id = atoi(argv[i+1]);
1390 free(argv[i+1]);
1391 if ((name = argv[i+1] = malloc(33)) == NULL)
1392 return(SMS_NO_MEM);
1393 if (!strcmp(argv[i], "LIST")) {
1394## repeat retrieve (name = list.#name) where list.list_id = @id
1395## inquire_equel(rowcount = "rowcount")
1396 if (rowcount != 1)
1397 strcpy(name, "???");
1398 } else if (!strcmp(argv[i], "USER")) {
1399## repeat retrieve (name = users.login) where users.users_id = @id
1400## inquire_equel(rowcount = "rowcount")
1401 if (rowcount != 1)
1402 strcpy(name, "???");
1403 } else if (!strcmp(argv[i], "NONE")) {
1404 strcpy(name, "NONE");
1405 } else {
1406 strcpy(name, "???");
1407 }
1408 }
92a943d6 1409
822a6eba 1410 /* send the data */
1411 (*action)(q->vcnt, argv, actarg);
1412
1413 /* free saved data */
1414 for (i = 0; i < q->vcnt; i++)
1415 free(argv[i]);
1416 free(argv);
1417 }
1418 sq_destroy(sq);
92a943d6 1419 return(SMS_SUCCESS);
1420##}
1421
05cdd922 1422
822a6eba 1423/* followup_gsha:
1424 */
1425
1426followup_gsha(q, sq, v, action, actarg, cl)
05cdd922 1427 register struct query *q;
822a6eba 1428 register struct save_queue *sq;
1429 register struct validate *v;
1430 register int (*action)();
1431 int actarg;
1432 client *cl;
05cdd922 1433##{
822a6eba 1434## char *name;
1435## int rowcount, id;
1436 char **argv;
1437 int i;
05cdd922 1438
822a6eba 1439 while (sq_get_data(sq, &argv)) {
1440 sms_trim_args(q->vcnt, argv);
05cdd922 1441
822a6eba 1442 id = atoi(argv[4]);
1443 free(argv[4]);
1444 name = argv[4] = malloc(9);
1445## repeat retrieve (name = users.login) where users.users_id = @id
1446## inquire_equel(rowcount = "rowcount")
1447 if (rowcount != 1)
1448 sprintf(argv[4], "#%d", id);
1449
1450 id = atoi(argv[2]);
1451 free(argv[2]);
1452 if ((name = argv[2] = malloc(33)) == NULL)
1453 return(SMS_NO_MEM);
1454 if (!strcmp(argv[1], "LIST")) {
1455## repeat retrieve (name = list.#name) where list.list_id = @id
1456## inquire_equel(rowcount = "rowcount")
1457 if (rowcount != 1)
1458 strcpy(name, "???");
1459 } else if (!strcmp(argv[1], "USER")) {
1460## repeat retrieve (name = users.login) where users.users_id = @id
1461## inquire_equel(rowcount = "rowcount")
1462 if (rowcount != 1)
1463 strcpy(name, "???");
1464 } else if (!strcmp(argv[1], "NONE")) {
1465 strcpy(name, "NONE");
1466 } else {
1467 strcpy(name, "???");
1468 }
05cdd922 1469
822a6eba 1470 /* send the data */
1471 (*action)(q->vcnt, argv, actarg);
1472
1473 /* free saved data */
1474 for (i = 0; i < q->vcnt; i++)
1475 free(argv[i]);
1476 free(argv);
1477 }
1478 sq_destroy(sq);
1479 return(SMS_SUCCESS);
1480##}
05cdd922 1481
05cdd922 1482
822a6eba 1483\f
1484/* Special query routines */
30967516 1485
822a6eba 1486/* set_pobox - this does all of the real work.
1487 * argv = user_id, type, box
1488 * if type is POP, then box should be a machine, and its ID should be put in
1489 * pop_id. If type is SMTP, then box should be a string and its ID should
1490 * be put in box_id. If type is NONE, then box doesn't matter.
1491 */
1492
1493int set_pobox(q, argv, cl)
1494 struct query *q;
1495 char **argv;
1496 client *cl;
1497##{
1498## int user, id, rowcount;
1499## char *box, potype[9];
1500
1501 box = argv[2];
1502 user = *(int *)argv[0];
1503
1504## repeat retrieve (id = users.pop_id, potype = users.#potype)
1505## where users.users_id = @user
e7fa3293 1506 if (!strcmp(strtrim(potype), "POP"))
822a6eba 1507 set_pop_usage(id, -1);
1508
1509 if (!strcmp(argv[1], "POP")) {
1510## repeat retrieve (id=machine.mach_id) where machine.name=uppercase(@box)
1511## inquire_equel(rowcount = "rowcount")
1512 if (rowcount != 1)
1513 return(SMS_MACHINE);
1514## repeat replace users (#potype = "POP", pop_id = @id)
1515## where users.users_id = @user
1516 set_pop_usage(id, 1);
1517 } else if (!strcmp(argv[1], "SMTP")) {
1518## range of s is strings
1519## repeat retrieve (id = s.string_id) where s.string = @box
1520## inquire_equel (rowcount = "rowcount")
1521 if (rowcount == 0) {
1522## range of v is values
1523## repeat retrieve (id = v.value) where v.name = "strings_id"
1524 id++;
1525## repeat replace v (value = @id) where v.name = "strings_id"
1526## append to strings (string_id = id, string = box)
1527 }
1528## repeat replace users (#potype = "SMTP", box_id = @id)
1529## where users.users_id = @user
1530 } else /* argv[1] == "NONE" */ {
1531## repeat replace users (#potype = "NONE") where users.users_id = @user
1532 }
1533
1534 set_pobox_modtime(q, argv, cl);
1535## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
1536## where tblstats.#table = "users"
30967516 1537 return(SMS_SUCCESS);
1538##}
1539
30967516 1540
822a6eba 1541/* get_list_info: passed a wildcard list name, returns lots of stuff about
1542 * each list. This is tricky: first build a queue of all requested
44bd6f44 1543 * data. Rest of processing consists of fixing gid, ace_name, and modby.
822a6eba 1544 */
1545
1546get_list_info(q, aargv, cl, action, actarg)
30967516 1547 register struct query *q;
822a6eba 1548 char **aargv;
1549 client *cl;
1550 register int (*action)();
1551 int actarg;
30967516 1552##{
822a6eba 1553 char *argv[13], *malloc(), *realloc();
1554## char *name, acl_type[9], listname[33], active[5], public[5], hidden[5];
1555## char maillist[5], group[5], gid[6], acl_name[33], desc[256], modtime[27];
1556## char modby[9], modwith[9];
1557## int id, rowcount, acl_id, hid, modby_id;
1558 int returned;
1559 struct save_queue *sq, *sq_create();
30967516 1560
822a6eba 1561 returned = rowcount = 0;
1562 name = aargv[0];
30967516 1563
822a6eba 1564 sq = sq_create();
1565## range of l is list
1566## repeat retrieve (id = l.list_id) where l.#name = @name {
1567 sq_save_data(sq, id);
1568 rowcount++;
1569## }
1570 if (rowcount == 0)
1571 return(SMS_NO_MATCH);
1572
1573 argv[0] = listname; argv[1] = active; argv[2] = public; argv[3] = hidden;
1574 argv[4] = maillist; argv[5] = group; argv[6] = gid; argv[7] = acl_type;
1575 argv[8] = acl_name; argv[9] = desc; argv[10] = modtime; argv[11] = modby;
1576 argv[12] = modwith;
1577
1578 while (sq_get_data(sq, &id)) {
1579 if (id == 0)
1580 continue;
1581 argv[6] = gid;
1582## repeat retrieve (listname = l.#name, active = text(l.#active),
1583## public = text(l.#public), hidden = text(l.#hidden),
1584## hid = l.#hidden, maillist = text(l.#maillist),
1585## group = text(l.#group), gid = text(l.#gid),
1586## acl_type = trim(l.#acl_type), acl_id = l.#acl_id,
1587## desc = l.#desc, modtime = l.#modtime, modby_id = l.#modby,
1588## modwith =l.#modwith)
1589## where l.list_id = @id
1590
1591 if (atoi(gid) == -1)
1592 argv[6] = UNIQUE_GID;
1593
1594 if (!strcmp(acl_type, "LIST")) {
1595## repeat retrieve (acl_name = l.#name) where l.list_id = @acl_id
1596## inquire_equel(rowcount = "rowcount")
1597 if (rowcount != 1)
1598 strcpy(acl_name, "???");
1599 } else if (!strcmp(acl_type, "USER")) {
1600## repeat retrieve (acl_name = users.#login)
1601## where users.users_id = @acl_id
1602## inquire_equel(rowcount = "rowcount")
1603 if (rowcount != 1)
1604 strcpy(acl_name, "???");
1605 } else if (!strcmp(acl_type, "NONE")) {
1606 strcpy(acl_name, "NONE");
1607 } else
1608 strcpy(acl_name, "???");
1609
1610## repeat retrieve (modby = users.login) where users.users_id = @modby_id
1611## inquire_equel(rowcount = "rowcount")
1612 if (rowcount != 1)
1613 sprintf(modby, "#%d", id);
1614
1615 sms_trim_args(q->vcnt, argv);
1616 returned++;
1617 (*action)(q->vcnt, argv, actarg);
1618 }
30967516 1619
822a6eba 1620 sq_destroy(sq);
1621## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
1622## where tblstats.#table = "list"
5e06ce45 1623
822a6eba 1624 return (SMS_SUCCESS);
1625##}
1626
1627
44bd6f44 1628/* get_ace_use - given a type and a name, return a type and a name.
1629 * The ace_type is one of "LIST", "USER", "RLIST", or "RUSER" in argv[0],
822a6eba 1630 * and argv[1] will contain the ID of the entity in question. The R*
1631 * types mean to recursively look at every containing list, not just
1632 * when the object in question is a direct member. On return, the
1633 * usage type will be one of LIST, SERVICE, FILESYS, QUOTA, QUERY, or ZEPHYR.
1634 */
1635
44bd6f44 1636int get_ace_use(q, argv, cl, action, actarg)
822a6eba 1637 struct query *q;
1638 char *argv[];
1639 client *cl;
1640 int (*action)();
1641 int actarg;
1642##{
1643 int found = 0;
1644## char *atype;
1645## int aid, listid, id;
1646 struct save_queue *sq, *sq_create();
1647
1648 atype = argv[0];
1649 aid = *(int *)argv[1];
1650 if (!strcmp(atype, "LIST") || !strcmp(atype, "USER")) {
44bd6f44 1651 return(get_ace_internal(atype, aid, action, actarg));
822a6eba 1652 }
1653
1654 sq = sq_create();
1655 if (!strcmp(atype, "RLIST")) {
1656 sq_save_data(sq, aid);
1657 /* get all the list_id's of containing lists */
1658## range of m is members
1659 while (sq_get_data(sq, &id)) {
1660## repeat retrieve (listid = m.list_id)
1661## where m.member_type = "LIST" and m.member_id = @id {
1662 sq_save_unique_data(sq, listid);
1663## }
1664 }
1665 /* now process each one */
1666 while (sq_get_data(sq, &id)) {
44bd6f44 1667 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 1668 found++;
1669 }
1670 }
1671
1672 if (!strcmp(atype, "RUSER")) {
1673## range of m is members
1674## repeat retrieve (listid = m.list_id)
1675## where m.member_type = "USER" and m.member_id = @aid {
1676 sq_save_data(sq, listid);
1677## }
1678 /* get all the list_id's of containing lists */
1679 while (sq_get_data(sq, &id)) {
1680## repeat retrieve (listid = m.list_id)
1681## where m.member_type = "LIST" and m.member_id = @id {
1682 sq_save_unique_data(sq, listid);
1683## }
1684 }
1685 /* now process each one */
1686 while (sq_get_data(sq, &id)) {
44bd6f44 1687 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 1688 found++;
1689 }
44bd6f44 1690 if (get_ace_internal("USER", aid, action, actarg) == SMS_SUCCESS)
822a6eba 1691 found++;
1692 }
05cdd922 1693
822a6eba 1694 sq_destroy(sq);
1695 if (!found) return(SMS_NO_MATCH);
05cdd922 1696 return(SMS_SUCCESS);
1697##}
92a943d6 1698
822a6eba 1699
44bd6f44 1700/* This looks up a single list or user for ace use. atype must be "USER"
822a6eba 1701 * or "LIST", and aid is the ID of the corresponding object. This is used
44bd6f44 1702 * by get_ace_use above.
822a6eba 1703 */
1704
44bd6f44 1705##get_ace_internal(atype, aid, action, actarg)
822a6eba 1706## char *atype;
1707## int aid;
1708 int (*action)();
1709 int actarg;
1710##{
1711 char *rargv[2];
1712 int found = 0;
1713## char name[33];
1714
1715 rargv[1] = name;
1716 if (!strcmp(atype, "LIST")) {
1717 rargv[0] = "FILESYS";
1718## repeat retrieve (name = filesys.label)
1719## where filesys.owners = @aid {
1720 (*action)(2, rargv, actarg);
1721 found++;
1722## }
1723
1724 rargv[0] = "QUERY";
1725## repeat retrieve (name = capacls.capability)
1726## where capacls.list_id = @aid {
1727 (*action)(2, rargv, actarg);
1728 found++;
1729## }
1730 } else if (!strcmp(atype, "USER")) {
1731 rargv[0] = "FILESYS";
1732## repeat retrieve (name = filesys.label)
1733## where filesys.owner = @aid {
1734 (*action)(2, rargv, actarg);
1735 found++;
1736## }
1737 }
1738
1739 rargv[0] = "LIST";
1740## repeat retrieve (name = list.#name)
1741## where list.acl_type = @atype and list.acl_id = @aid {
1742 (*action)(2, rargv, actarg);
1743 found++;
1744## }
1745
1746 rargv[0] = "SERVICE";
1747## repeat retrieve (name = servers.#name)
1748## where servers.acl_type = @atype and servers.acl_id = @aid {
1749 (*action)(2, rargv, actarg);
1750 found++;
1751## }
1752
1753 rargv[0] = "HOSTACCESS";
1754## repeat retrieve (name = machine.#name)
1755## where machine.mach_id = hostaccess.mach_id and
1756## hostaccess.acl_type = @atype and hostaccess.acl_id = @aid {
1757 (*action)(2, rargv, actarg);
1758 found++;
1759## }
1760 rargv[0] = "ZEPHYR";
1761## repeat retrieve (name = zephyr.class)
1762## where zephyr.xmt_type = @atype and zephyr.xmt_id = @aid or
1763## zephyr.sub_type = @atype and zephyr.sub_id = @aid or
1764## zephyr.iws_type = @atype and zephyr.iws_id = @aid or
1765## zephyr.iui_type = @atype and zephyr.iui_id = @aid {
1766 (*action)(2, rargv, actarg);
1767 found++;
1768## }
1769
1770 if (!found) return(SMS_NO_MATCH);
1771 return(SMS_SUCCESS);
1772##}
1773
1774
1775/* get_lists_of_member - given a type and a name, return the name and flags
1776 * of all of the lists of the given member. The member_type is one of
1777 * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0],
1778 * and argv[1] will contain the ID of the entity in question. The R*
1779 * types mean to recursively look at every containing list, not just
1780 * when the object in question is a direct member.
1781 */
1782
1783int get_lists_of_member(q, argv, cl, action, actarg)
92a943d6 1784 struct query *q;
1785 char *argv[];
822a6eba 1786 client *cl;
1787 int (*action)();
1788 int actarg;
92a943d6 1789##{
822a6eba 1790 int found = 0;
1791## char *atype;
1792## int aid, listid, id;
1793 struct save_queue *sq, *sq_create();
1794
1795 atype = argv[0];
1796 aid = *(int *)argv[1];
1797 if (!strcmp(atype, "LIST") ||
1798 !strcmp(atype, "USER") ||
1799 !strcmp(atype, "STRING")) {
1800 return(glom_internal(atype, aid, action, actarg));
1801 }
92a943d6 1802
822a6eba 1803 sq = sq_create();
1804 if (!strcmp(atype, "RLIST")) {
1805 sq_save_data(sq, aid);
1806 /* get all the list_id's of containing lists */
1807## range of m is members
1808 while (sq_get_data(sq, &id)) {
1809## repeat retrieve (listid = m.list_id)
1810## where m.member_type = "LIST" and m.member_id = @id {
1811 sq_save_unique_data(sq, listid);
1812## }
1813 }
1814 /* now process each one */
1815 while (sq_get_data(sq, &id)) {
1816 if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1817 found++;
1818 }
1819 }
92a943d6 1820
822a6eba 1821 if (!strcmp(atype, "RUSER")) {
1822## range of m is members
1823## repeat retrieve (listid = m.list_id)
1824## where m.member_type = "USER" and m.member_id = @aid {
1825 sq_save_data(sq, listid);
1826## }
1827 /* get all the list_id's of containing lists */
1828 while (sq_get_data(sq, &id)) {
1829## repeat retrieve (listid = m.list_id)
1830## where m.member_type = "LIST" and m.member_id = @id {
1831 sq_save_unique_data(sq, listid);
1832## }
1833 }
1834 /* now process each one */
1835 while (sq_get_data(sq, &id)) {
1836 if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1837 found++;
1838 }
1839 if (glom_internal("USER", aid, action, actarg) == SMS_SUCCESS)
1840 found++;
1841 }
92a943d6 1842
822a6eba 1843 if (!strcmp(atype, "RSTRING")) {
1844## range of m is members
1845## repeat retrieve (listid = m.list_id)
1846## where m.member_type = "STRING" and m.member_id = @aid {
1847 sq_save_data(sq, listid);
1848## }
1849 /* get all the list_id's of containing lists */
1850 while (sq_get_data(sq, &id)) {
1851## repeat retrieve (listid = m.list_id)
1852## where m.member_type = "LIST" and m.member_id = @id {
1853 sq_save_unique_data(sq, listid);
1854## }
1855 }
1856 /* now process each one */
1857 while (sq_get_data(sq, &id)) {
1858 if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1859 found++;
1860 }
1861 if (glom_internal("STRING", aid, action, actarg) == SMS_SUCCESS)
1862 found++;
92a943d6 1863 }
55534a87 1864
822a6eba 1865## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
1866## where tblstats.#table = "members"
1867 sq_destroy(sq);
1868 if (!found) return(SMS_NO_MATCH);
1869 return(SMS_SUCCESS);
1870##}
1871
55534a87 1872
822a6eba 1873/* This looks up a single list, user, or string as a member. atype must be
1874 * "USER", "LIST", or "STRING" and aid is the ID of the corresponding object.
1875 * This is used by get_lists_of_members above.
1876 */
1877
1878##glom_internal(atype, aid, action, actarg)
1879## char *atype;
1880## int aid;
1881 int (*action)();
1882 int actarg;
1883##{
1884 char *rargv[6];
1885 int found = 0;
1886## char name[33], active[5], public[5], hidden[5], maillist[5], group[5];
1887
1888 rargv[0] = name;
1889 rargv[1] = active;
1890 rargv[2] = public;
1891 rargv[3] = hidden;
1892 rargv[4] = maillist;
1893 rargv[5] = group;
1894## repeat retrieve (name = list.#name, active = text(list.#active),
1895## public = text(list.#public), hidden = text(list.#hidden),
1896## maillist = text(list.#maillist), group = text(list.#group))
1897## where list.list_id = m.list_id and
1898## m.member_type = @atype and m.member_id = @aid {
1899 (*action)(6, rargv, actarg);
1900 found++;
1901## }
92a943d6 1902
822a6eba 1903 if (!found) return(SMS_NO_MATCH);
92a943d6 1904 return(SMS_SUCCESS);
1905##}
1906
822a6eba 1907
1908/* qualified_get_lists: passed "TRUE", "FALSE", or "DONTCARE" for each of
1909 * the five flags associated with each list. It will return the name of
1910 * each list that meets the quailifications. It does this by building a
1911 * where clause based on the arguments, then doing a retrieve.
1912 */
1913
1914static char *lflags[5] = { "active", "public", "hidden", "maillist", "group" };
1915
1916int qualified_get_lists(q, argv, cl, action, actarg)
1917 struct query *q;
1918 char *argv[];
1919 client *cl;
1920 int (*action)();
1921 int actarg;
1922{
1923 return(qualified_get(q, argv, action, actarg, "l.list_id != 0",
1924 "l", "name", lflags));
1925}
1926
1927
1928/** get_members_of_list - optimized query for retrieval of list members
c2408bd5 1929 **
1930 ** Inputs:
1931 ** argv[0] - list_id
1932 **
1933 ** Description:
1934 ** - retrieve USER members, then LIST members, then STRING members
c2408bd5 1935 **/
1936
822a6eba 1937get_members_of_list(q, argv, cl, action, actarg)
c2408bd5 1938 struct query *q;
1939 char *argv[];
822a6eba 1940 client *cl;
c2408bd5 1941 int (*action)();
1942 int actarg;
1943##{
1944## int list_id;
1945## char member_name[129];
1946 char *targv[2];
1947
1948 list_id = *(int *)argv[0];
1949 targv[0] = "USER";
1950 targv[1] = member_name;
1951
1952## range of m is members
1953## repeat retrieve (member_name = users.login)
1954## where m.#list_id = @list_id and m.member_type = "USER"
1955## and m.member_id = users.users_id
92a943d6 1956## sort by #member_name
c2408bd5 1957## {
1958 (*action)(2, targv, actarg);
1959## }
1960
1961 targv[0] = "LIST";
1962## repeat retrieve (member_name = list.name)
1963## where m.#list_id = @list_id and m.member_type = "LIST"
1964## and m.member_id = list.#list_id
92a943d6 1965## sort by #member_name
c2408bd5 1966## {
1967 (*action)(2, targv, actarg);
1968## }
1969
1970 targv[0] = "STRING";
1971## repeat retrieve (member_name = strings.string)
1972## where m.#list_id = @list_id and m.member_type = "STRING"
1973## and m.member_id = strings.string_id
92a943d6 1974## sort by #member_name
c2408bd5 1975## {
1976 (*action)(2, targv, actarg);
1977## }
1978
822a6eba 1979## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
1980## where tblstats.#table = "members"
c2408bd5 1981 return(SMS_SUCCESS);
1982##}
1983
92a943d6 1984
822a6eba 1985/* count_members_of_list: this is a simple query, but it cannot be done
1986 * through the dispatch table.
1987 */
1988
1989int count_members_of_list(q, argv, cl, action, actarg)
92a943d6 1990 struct query *q;
1991 char *argv[];
822a6eba 1992 client *cl;
92a943d6 1993 int (*action)();
1994 int actarg;
1995##{
822a6eba 1996## int list, ct = 0;
1997 char *rargv[1], countbuf[5];
1998
1999 list = *(int *)argv[0];
2000 rargv[0] = countbuf;
2001## repeat retrieve (ct = count(members.list_id where members.list_id = @list))
2002 sprintf(countbuf, "%d", ct);
2003 (*action)(1, rargv, actarg);
2004## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2005## where tblstats.#table = "members"
2006 return(SMS_SUCCESS);
2007##}
92a943d6 2008
92a943d6 2009
822a6eba 2010/* qualified_get_server: passed "TRUE", "FALSE", or "DONTCARE" for each of
2011 * the three flags associated with each service. It will return the name of
2012 * each service that meets the quailifications. It does this by building a
2013 * where clause based on the arguments, then doing a retrieve.
2014 */
92a943d6 2015
822a6eba 2016static char *sflags[3] = { "enable", "inprogress", "harderror" };
a6cb4d4c 2017
822a6eba 2018int qualified_get_server(q, argv, cl, action, actarg)
a6cb4d4c 2019 struct query *q;
2020 char *argv[];
822a6eba 2021 client *cl;
a6cb4d4c 2022 int (*action)();
2023 int actarg;
822a6eba 2024{
2025 return(qualified_get(q, argv, action, actarg, "s.name != \"\"",
2026 "s", "name", sflags));
2027}
a6cb4d4c 2028
a6cb4d4c 2029
822a6eba 2030/* generic qualified get routine, used by qualified_get_lists,
2031 * qualified_get_server, and qualified_get_serverhost.
2032 * Args:
2033 * start - a simple where clause, must not be empty
2034 * range - the name of the range variable
2035 * field - the field to return
2036 * flags - an array of strings, names of the flag variables
2037 */
c2408bd5 2038
822a6eba 2039int qualified_get(q, argv, action, actarg, start, range, field, flags)
c2408bd5 2040 struct query *q;
2041 char *argv[];
2042 int (*action)();
2043 int actarg;
822a6eba 2044 char *start;
2045 char *range;
2046 char *field;
2047 char *flags[];
c2408bd5 2048##{
822a6eba 2049## char name[33], qual[256], *rvar, *rtbl, *rfield;
2050 char *rargv[1], buf[32];
2051## int rowcount, i;
2052
2053 strcpy(qual, start);
2054 for (i = 0; i < q->argc; i++) {
2055 if (!strcmp(argv[i], "TRUE")) {
2056 sprintf(buf, " and %s.%s != 0", range, flags[i]);
2057 (void) strcat(qual, buf);
2058 } else if (!strcmp(argv[i], "FALSE")) {
2059 sprintf(buf, " and %s.%s = 0", range, flags[i]);
2060 (void) strcat(qual, buf);
2061 }
2062 }
2063
2064 rargv[0] = name;
2065 rvar = range;
2066 rtbl = q->rtable;
2067 rfield = field;
2068## range of rvar is rtbl
2069## retrieve (name = rvar.rfield) where qual {
2070 (*action)(1, rargv, actarg);
c2408bd5 2071## }
822a6eba 2072## inquire_equel(rowcount = "rowcount")
2073## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2074## where tblstats.#table = @rtbl
2075 if (rowcount == 0)
2076 return(SMS_NO_MATCH);
2077 return(SMS_SUCCESS);
2078##}
c2408bd5 2079
c2408bd5 2080
822a6eba 2081/* qualified_get_serverhost: passed "TRUE", "FALSE", or "DONTCARE" for each of
2082 * the five flags associated with each serverhost. It will return the name of
2083 * each service and host that meets the quailifications. It does this by
2084 * building a where clause based on the arguments, then doing a retrieve.
2085 */
c2408bd5 2086
822a6eba 2087static char *shflags[6] = { "service", "enable", "override", "success",
2088 "inprogress", "hosterror" };
a6cb4d4c 2089
822a6eba 2090int qualified_get_serverhost(q, argv, cl, action, actarg)
a6cb4d4c 2091 struct query *q;
2092 char *argv[];
822a6eba 2093 client *cl;
a6cb4d4c 2094 int (*action)();
2095 int actarg;
2096##{
822a6eba 2097## char sname[33], mname[33], qual[256];
2098 char *rargv[2], buf[32];
2099## int rowcount, i;
2100
44bd6f44 2101 sprintf(qual, "machine.mach_id = sh.mach_id and sh.service = uppercase(\"%s\")",
822a6eba 2102 argv[0]);
2103 for (i = 1; i < q->argc; i++) {
2104 if (!strcmp(argv[i], "TRUE")) {
2105 sprintf(buf, " and sh.%s != 0", shflags[i]);
2106 strcat(qual, buf);
2107 } else if (!strcmp(argv[i], "FALSE")) {
2108 sprintf(buf, " and sh.%s = 0", shflags[i]);
2109 strcat(qual, buf);
2110 }
2111 }
2112
2113 rargv[0] = sname;
2114 rargv[1] = mname;
2115## range of sh is serverhosts
2116## retrieve (sname = sh.service, mname = machine.name) where qual {
2117 (*action)(2, rargv, actarg);
a6cb4d4c 2118## }
822a6eba 2119## inquire_equel(rowcount = "rowcount")
2120## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2121## where tblstats.#table = "serverhosts"
2122 if (rowcount == 0)
2123 return(SMS_NO_MATCH);
2124 return(SMS_SUCCESS);
2125##}
a6cb4d4c 2126
a6cb4d4c 2127
822a6eba 2128/* register_user - change user's login name and allocate a pobox, group,
2129 * filesystem, and quota for them. The user's status must start out as 0,
2130 * and is left as 2. Arguments are: user's UID, new login name, and user's
2131 * type for filesystem allocation (SMS_FS_STUDENT, SMS_FS_FACULTY,
2132 * SMS_FS_STAFF, SMS_FS_MISC).
2133 */
2134
2135register_user(q, argv, cl)
2136 struct query *q;
2137 char **argv;
2138 client *cl;
2139##{
2140## char *login, dir[65], *entity, *directory, machname[33];
2141## int who, rowcount, mid, uid, users_id, flag, utype, nid, list_id, quota;
2142## int size, alloc, pid, m_id;
2143 int maxsize;
2144
2145 entity = cl->entity;
2146 who = cl->users_id;
2147
2148 uid = atoi(argv[0]);
2149 login = argv[1];
2150 utype = atoi(argv[2]);
2151
2152## range of u is users
2153## range of l is list
2154## range of sh is serverhosts
2155## range of n is nfsphys
2156## range of m is machine
2157
2158 /* find user */
2159## repeat retrieve (users_id = u.#users_id)
2160## where u.#uid = @uid and u.status = 0
2161## inquire_equel(rowcount = "rowcount");
2162 if (rowcount == 0)
2163 return(SMS_NO_MATCH);
2164 if (rowcount > 1)
2165 return(SMS_NOT_UNIQUE);
2166
2167 /* check new login name */
2168## repeat retrieve (flag = any(u.#login where u.#login = @login))
2169 if (flag)
2170 return(SMS_IN_USE);
4f16dc86 2171## repeat retrieve (flag = any(l.#name where l.#name = @login))
822a6eba 2172 if (flag)
2173 return(SMS_IN_USE);
2174## repeat retrieve (flag = any(filesys.#name where filesys.#name = @login))
2175 if (flag)
2176 return(SMS_IN_USE);
2177 com_err(whoami, 0, "new login name OK");
2178
2179 /* choose place for pobox, put in mid */
2180## repeat retrieve (mid = sh.mach_id, machname = m.name)
44bd6f44 2181## where sh.service = "POP" and m.mach_id = sh.mach_id and
2182## sh.value2 - sh.value1 = max(sh.value2-sh.value1 where sh.service="POP")
8ac9ee7a 2183## inquire_equel(rowcount = "rowcount");
822a6eba 2184 if (rowcount == 0)
44bd6f44 2185 return(SMS_NO_POBOX);
822a6eba 2186
2187 /* change login name, set pobox */
2188## repeat replace u (#login = @login, status = 2, modtime = "now",
2189## modby = @who, modwith = @entity, potype="POP",
2190## pop_id = @mid, pmodtime="now", pmodby=@who,
2191## pmodwith=@entity)
2192## where u.#users_id = @users_id
8ac9ee7a 2193## inquire_equel(rowcount = "rowcount");
822a6eba 2194 if (rowcount != 1)
2195 return(SMS_INTERNAL);
2196 set_pop_usage(mid, 1);
2197 com_err(whoami, 0, "set login name to %s and pobox to %s", login,
2198 trim(machname));
2199
2200 /* create group list */
2201 if (set_next_object_id("gid", "list"))
44bd6f44 2202 return(SMS_NO_ID);
822a6eba 2203 if (set_next_object_id("list_id", "list"))
44bd6f44 2204 return(SMS_NO_ID);
822a6eba 2205## repeat retrieve (list_id = values.value) where values.name = "list_id"
8ac9ee7a 2206## inquire_equel(rowcount = "rowcount");
822a6eba 2207 if (rowcount != 1)
2208 return(SMS_INTERNAL);
2209## repeat append list (name = @login, #list_id = @list_id, active = 1,
2210## public = 0, hidden = 0, maillist = 0, group = 1,
2211## #gid = values.value, desc = "User Group",
2212## acl_type = "USER", acl_id = @users_id, modtime = "now",
2213## modby = @who, modwith = @entity)
2214## where values.name = "gid"
8ac9ee7a 2215## inquire_equel(rowcount = "rowcount");
44bd6f44 2216 if (rowcount != 1)
2217 return(SMS_INTERNAL);
2218## repeat append members (#list_id = @list_id, member_type = "USER",
2219## member_id = @users_id)
8ac9ee7a 2220## inquire_equel(rowcount = "rowcount");
822a6eba 2221 if (rowcount != 1)
2222 return(SMS_INTERNAL);
2223 com_err(whoami, 0, "group list created");
2224
2225 /* decide where to put filesystem */
2226 maxsize = 0;
2227 directory = NULL;
2228## repeat retrieve (mid = n.mach_id, dir = trim(n.#dir), nid = n.nfsphys_id,
2229## flag = n.status, size = n.#size, alloc = n.allocated) {
2230 if ((flag & utype) && (size != 0) && (size - alloc > maxsize)) {
2231 maxsize = size - alloc;
2232 if (directory)
2233 free(directory);
2234 directory = strsave(dir);
2235 pid = nid;
2236 m_id = mid;
2237 }
a6cb4d4c 2238## }
822a6eba 2239 if (maxsize == 0)
44bd6f44 2240 return(SMS_NO_FILESYS);
822a6eba 2241
2242 /* create filesystem */
2243 if (set_next_object_id("filsys_id", "filesys"))
44bd6f44 2244 return(SMS_NO_ID);
822a6eba 2245## repeat append filesys (filsys_id = values.value, phys_id = @pid,
2246## label = @login, type = "NFS", mach_id = @m_id,
4f16dc86 2247## name = @directory + "/" + @login,
2248## mount = "/mit/" + @login,
822a6eba 2249## access = "w", comments = "User Locker",
2250## owner = @users_id, owners = @list_id, createflg = 1,
2251## lockertype = "HOMEDIR", modtime = "now",
2252## modby = @who, modwith = @entity)
2253## where values.name = "filsys_id"
8ac9ee7a 2254## inquire_equel(rowcount = "rowcount");
822a6eba 2255 if (rowcount != 1)
2256 return(SMS_INTERNAL);
2257 com_err(whoami, 0, "filesys created on mach %d in %s/%s", m_id,
4f16dc86 2258 directory, login);
822a6eba 2259
2260 /* set quota */
2261## repeat retrieve (quota = values.value) where values.name = "def_quota"
8ac9ee7a 2262## inquire_equel(rowcount = "rowcount");
822a6eba 2263 if (rowcount != 1)
44bd6f44 2264 return(SMS_NO_QUOTA);
822a6eba 2265## repeat append nfsquota (#users_id = @users_id, filsys_id = values.value,
e7fa3293 2266## #quota = @quota, phys_id = @pid, modtime = "now",
2267## modby = @who, modwith = @entity)
822a6eba 2268## where values.name = "filsys_id"
8ac9ee7a 2269## inquire_equel(rowcount = "rowcount");
822a6eba 2270 if (rowcount != 1)
2271 return(SMS_INTERNAL);
2272## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
2273## where nfsphys.nfsphys_id = filesys.#phys_id and
2274## filesys.filsys_id = values.value and values.name = "filsys_id"
8ac9ee7a 2275## inquire_equel(rowcount = "rowcount");
822a6eba 2276 if (rowcount != 1)
2277 return(SMS_INTERNAL);
2278 com_err(whoami, 0, "quota of %d assigned", quota);
2279
4f16dc86 2280## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
2281## where tblstats.table = "users"
2282## repeat replace tblstats (appends = tblstats.appends + 1, modtime = "now")
2283## where tblstats.table = "list" or tblstats.table = "filesys" or
2284## tblstats.table = "nfsquota"
822a6eba 2285 return(SMS_SUCCESS);
2286##}
2287
2288
2289
2290/** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
2291 **
2292 ** Inputs:
2293 ** id of machine
2294 ** delta (will be +/- 1)
2295 **
2296 ** Description:
2297 ** - incr/decr value field in serverhosts table for pop/mach_id
2298 **
2299 **/
2300
2301static int set_pop_usage(id, count)
2302int id;
2303int count;
2304##{
2305## int mach_id = id;
2306## int n = count;
2307
2308## range of sh is serverhosts
2309## repeat replace sh (value1 = sh.value1 + @n)
44bd6f44 2310## where sh.service = "POP" and sh.#mach_id = @mach_id
a6cb4d4c 2311
2312 return(SMS_SUCCESS);
2313##}
822a6eba 2314
2315
c2408bd5 2316\f
05cdd922 2317/* Validation Routines */
2318
2319validate_row(q, argv, v)
2320 register struct query *q;
2321 char *argv[];
2322 register struct validate *v;
2323##{
2324## char *rvar;
2325## char *table;
2326## char *name;
2327## char qual[128];
2328## int rowcount;
2329
2330 /* build where clause */
2331 build_qual(v->qual, v->argc, argv, qual);
2332
2333 /* setup ingres variables */
2334 rvar = q->rvar;
2335 table = q->rtable;
2336 name = v->field;
2337
6388c51a 2338 if (log_flags & LOG_VALID)
b4182127 2339 /* tell the logfile what we're doing */
2340 com_err(whoami, 0, "validating row: %s", qual);
2341
05cdd922 2342 /* look for the record */
2343## range of rvar is table
2344## retrieve (rowcount = count(rvar.name where qual))
05cdd922 2345 if (rowcount == 0) return(SMS_NO_MATCH);
2346 if (rowcount > 1) return(SMS_NOT_UNIQUE);
2347 return(SMS_EXISTS);
2348##}
2349
2350validate_fields(q, argv, vo, n)
2351 struct query *q;
2352 register char *argv[];
2353 register struct valobj *vo;
2354 register int n;
2355{
2356 register int status;
05cdd922 2357
2358 while (--n >= 0) {
2359 switch (vo->type) {
2360 case V_NAME:
6388c51a 2361 if (log_flags & LOG_VALID)
b4182127 2362 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2363 vo->namefield, vo->table, argv[vo->index]);
05cdd922 2364 status = validate_name(argv, vo);
2365 break;
2366
2367 case V_ID:
6388c51a 2368 if (log_flags & LOG_VALID)
b4182127 2369 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2370 vo->idfield, vo->table, argv[vo->index]);
05cdd922 2371 status = validate_id(argv, vo);
2372 break;
2373
92a943d6 2374 case V_DATE:
6388c51a 2375 if (log_flags & LOG_VALID)
92a943d6 2376 com_err(whoami, 0, "validating date: %s", argv[vo->index]);
2377 status = validate_date(argv, vo);
2378 break;
2379
05cdd922 2380 case V_TYPE:
6388c51a 2381 if (log_flags & LOG_VALID)
b4182127 2382 com_err(whoami, 0, "validating %s type: %s",
05cdd922 2383 vo->table, argv[vo->index]);
05cdd922 2384 status = validate_type(argv, vo);
2385 break;
2386
2387 case V_TYPEDATA:
6388c51a 2388 if (log_flags & LOG_VALID)
92a943d6 2389 com_err(whoami, 0, "validating typed data (%s): %s",
2390 argv[vo->index - 1], argv[vo->index]);
05cdd922 2391 status = validate_typedata(q, argv, vo);
2392 break;
2393
822a6eba 2394 case V_RENAME:
6388c51a 2395 if (log_flags & LOG_VALID)
822a6eba 2396 com_err(whoami, 0, "validating rename %s in %s",
2397 argv[vo->index], vo->table);
2398 status = validate_rename(argv, vo);
2399 break;
2400
2401 case V_CHAR:
6388c51a 2402 if (log_flags & LOG_VALID)
822a6eba 2403 com_err(whoami, 0, "validating chars: %s", argv[vo->index]);
2404 status = validate_chars(argv[vo->index]);
05cdd922 2405 break;
2406
92a943d6 2407 case V_SORT:
2408 status = SMS_EXISTS;
2409 break;
2410
05cdd922 2411 }
2412
2413 if (status != SMS_EXISTS) return(status);
2414 vo++;
2415 }
2416
2417 return(SMS_SUCCESS);
2418}
2419
822a6eba 2420
2421/* validate_chars: verify that there are no illegal characters in
2422 * the string. Legal characters are printing chars other than
331b982e 2423 * ", *, ?, \, [ and ].
822a6eba 2424 */
2425static int illegalchars[] = {
2426 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2427 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2428 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
2429 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */
2430 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ - O */
331b982e 2431 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */
822a6eba 2432 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2433 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
2434 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2435 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2436 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2437 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2438 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2439 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2440 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2441 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2442};
2443
2444validate_chars(s)
2445register char *s;
2446{
2447 while (*s)
2448 if (illegalchars[*s++])
2449 return(SMS_BAD_CHAR);
2450 return(SMS_EXISTS);
2451}
2452
2453
05cdd922 2454validate_id(argv, vo)
2455 char *argv[];
2456 register struct valobj *vo;
2457##{
2458## char *name;
2459## char *table;
2460## char *namefield;
2461## char *idfield;
2462## int id;
2463## int rowcount;
122ec372 2464 register char *c;
05cdd922 2465
2466 name = argv[vo->index];
2467 table = vo->table;
122ec372 2468 /* minor kludge to upcasify machine names */
822a6eba 2469 if (!strcmp(table, "machine"))
122ec372 2470 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 2471 namefield = vo->namefield;
2472 idfield = vo->idfield;
822a6eba 2473 if (!strcmp(namefield, "uid")) {
9119288e 2474## retrieve (id = table.idfield) where table.namefield = int4(name)
2475## inquire_equel (rowcount = "rowcount")
2476 } else {
2477## retrieve (id = table.idfield) where table.namefield = name
2478## inquire_equel (rowcount = "rowcount")
2479 }
05cdd922 2480 if (rowcount != 1) return(vo->error);
2481 *(int *)argv[vo->index] = id;
2482 return(SMS_EXISTS);
2483##}
2484
2485validate_name(argv, vo)
2486 char *argv[];
2487 register struct valobj *vo;
2488##{
2489## char *name;
2490## char *table;
2491## char *namefield;
2492## int rowcount;
44bd6f44 2493 register char *c;
05cdd922 2494
2495 name = argv[vo->index];
2496 table = vo->table;
2497 namefield = vo->namefield;
44bd6f44 2498 if (!strcmp(table, "servers") && !strcmp(namefield, "name")) {
2499 for (c = name; *c; c++)
2500 if (islower(*c))
2501 *c = toupper(*c);
2502 }
05cdd922 2503## retrieve (rowcount = countu(table.namefield
2504## where table.namefield = name))
2505 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
2506##}
2507
92a943d6 2508validate_date(argv, vo)
2509 char *argv[];
2510 struct valobj *vo;
2511##{
2512## char *idate;
2513## double dd;
2514## int errorno;
2515
2516 idate = argv[vo->index];
2517
2518## retrieve (dd = interval("years", date(idate) - date("today")))
2519## inquire_equel (errorno = "errorno")
2520 if (errorno != 0 || dd > 5.0) return(SMS_DATE);
44bd6f44 2521 return(SMS_EXISTS);
92a943d6 2522##}
2523
822a6eba 2524
2525validate_rename(argv, vo)
2526char *argv[];
2527struct valobj *vo;
2528##{
2529## char *name, *table, *namefield, *idfield;
2530## int id;
2531 register char *c;
2532
2533 c = name = argv[vo->index];
2534 while (*c)
2535 if (illegalchars[*c++])
2536 return(SMS_BAD_CHAR);
2537 table = vo->table;
2538 /* minor kludge to upcasify machine names */
2539 if (!strcmp(table, "machine"))
2540 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
2541 namefield = vo->namefield;
2542 idfield = vo->idfield;
2543 id = -1;
2544 if (idfield == 0) {
2545 if (!strcmp(argv[vo->index], argv[vo->index - 1]))
2546 return(SMS_EXISTS);
2547## retrieve (id = any(table.namefield where table.namefield = name))
2548 if (id)
2549 return(vo->error);
2550 else
2551 return(SMS_EXISTS);
2552 }
2553## retrieve (id = table.idfield) where table.namefield = name
2554 if (id == -1 || id == *(int *)argv[vo->index - 1])
2555 return(SMS_EXISTS);
2556 else
2557 return(vo->error);
2558##}
2559
2560
05cdd922 2561validate_type(argv, vo)
2562 char *argv[];
2563 register struct valobj *vo;
2564##{
2565## char *typename;
2566## char *value;
822a6eba 2567## int exists;
05cdd922 2568 register char *c;
2569
2570 typename = vo->table;
822a6eba 2571 c = value = argv[vo->index];
2572 while (*c)
2573 if (illegalchars[*c++])
2574 return(SMS_BAD_CHAR);
05cdd922 2575
2576 /* uppercase type fields */
2577 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
2578
2579## range of a is alias
822a6eba 2580## repeat retrieve (exists = any(a.trans where a.name = @typename and
05cdd922 2581## a.type = "TYPE" and
2582## a.trans = @value))
822a6eba 2583 return (exists ? SMS_EXISTS : vo->error);
05cdd922 2584##}
2585
2586/* validate member or type-specific data field */
2587
2588validate_typedata(q, argv, vo)
2589 register struct query *q;
2590 register char *argv[];
2591 register struct valobj *vo;
2592##{
2593## char *name;
2594## char *field_type;
822a6eba 2595## char data_type[129];
05cdd922 2596## int id;
05cdd922 2597## int rowcount;
822a6eba 2598 char *index();
a6cb4d4c 2599 register char *c;
05cdd922 2600
2601 /* get named object */
2602 name = argv[vo->index];
2603
2604 /* get field type string (known to be at index-1) */
2605 field_type = argv[vo->index-1];
2606
2607 /* get corresponding data type associated with field type name */
2608## repeat retrieve (data_type = alias.trans)
2609## where alias.#name = @field_type and alias.type = "TYPEDATA"
2610## inquire_equel (rowcount = "rowcount")
2611 if (rowcount != 1) return(SMS_TYPE);
2612
2613 /* now retrieve the record id corresponding to the named object */
822a6eba 2614 if (index(data_type, ' '))
2615 *index(data_type, ' ') = 0;
05cdd922 2616 if (!strcmp(data_type, "user")) {
2617 /* USER */
2618## repeat retrieve (id = users.users_id) where users.login = @name
2619## inquire_equel (rowcount = "rowcount")
2620 if (rowcount != 1) return(SMS_USER);
2621
2622 } else if (!strcmp(data_type, "list")) {
2623 /* LIST */
2624## repeat retrieve (id = list.list_id) where list.#name = @name
2625## inquire_equel (rowcount = "rowcount")
822a6eba 2626 if (rowcount != 1) {
2627 /* if idfield is non-zero, then if argv[0] matches the string
2628 * that we're trying to resolve, we should get the value of
2629 * values.[idfield] for the id.
2630 */
2631 if (vo->idfield && !strcmp(argv[0], argv[vo->index])) {
4f16dc86 2632 set_next_object_id(q->validate->object_id, q->rtable);
822a6eba 2633 name = vo->idfield;
4f16dc86 2634## repeat retrieve (id = values.value) where values.#name = @name
822a6eba 2635## inquire_equel(rowcount = "rowcount")
2636 if (rowcount != 1) return(SMS_LIST);
2637 } else
2638 return(SMS_LIST);
2639 }
05cdd922 2640 } else if (!strcmp(data_type, "machine")) {
2641 /* MACHINE */
a6cb4d4c 2642 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 2643## repeat retrieve (id = machine.mach_id) where machine.#name = @name
2644## inquire_equel (rowcount = "rowcount")
2645 if (rowcount != 1) return(SMS_MACHINE);
2646
2647 } else if (!strcmp(data_type, "string")) {
2648 /* STRING */
2649## range of s is strings
822a6eba 2650## repeat retrieve (id = s.string_id) where s.string = @name
05cdd922 2651## inquire_equel (rowcount = "rowcount")
2652 if (rowcount == 0) {
2653 if (q->type != APPEND) return(SMS_STRING);
2654## range of v is values
2655## retrieve (id = v.value) where v.#name = "strings_id"
2656 id++;
2657## replace v (value = id) where v.#name = "strings_id"
822a6eba 2658## append to strings (string_id = id, string = name)
05cdd922 2659 }
822a6eba 2660 } else if (!strcmp(data_type, "none")) {
2661 id = 0;
05cdd922 2662 } else {
2663 return(SMS_TYPE);
2664 }
2665
2666 /* now set value in argv */
2667 *(int *)argv[vo->index] = id;
2668
2669 return (SMS_EXISTS);
2670##}
2671
05cdd922 2672
822a6eba 2673/* This looks up a login name and returns the SMS internal ID. It is used
2674 * by authenticate to put the users_id in the client structure.
2675 */
05cdd922 2676
822a6eba 2677int get_users_id(name)
2678char *name;
2679##{
2680## int id, rowcount;
2681## char *login;
05cdd922 2682
822a6eba 2683 login = name;
05cdd922 2684
822a6eba 2685## range of u is users
2686## repeat retrieve (id = u.#users_id) where u.#login = @login
2687## inquire_equel (rowcount = "rowcount")
2688
2689 if (rowcount == 1)
2690 return(id);
2691 else
2692 return(0);
2693##}
05cdd922 2694
05cdd922 2695
822a6eba 2696/* Check the database at startup time. For now this just resets the
2697 * inprogress flags that the DCM uses.
2698 */
05cdd922 2699
822a6eba 2700sanity_check_database()
2701##{
05cdd922 2702##}
This page took 0.492343 seconds and 5 git commands to generate.