]> andersk Git - moira.git/blame - server/qsupport.qc
added save_queue and hash_table definitions
[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
3c7c4a07 894/* Like set_modtime, but uppercases the name first.
822a6eba 895 */
896
3c7c4a07 897set_uppercase_modtime(q, argv, cl)
822a6eba 898 struct query *q;
899 char **argv;
900 client *cl;
901##{
3c7c4a07 902## char *name, *entity, *table;
822a6eba 903## int who;
904
905 entity = cl->entity;
906 who = cl->users_id;
3c7c4a07 907 table = q->rtable;
908 name = argv[0];
05cdd922 909
3c7c4a07 910## replace table (modtime = "now", modby = who, modwith = entity)
911## where table.#name = uppercase(name)
05cdd922 912 return(SMS_SUCCESS);
913##}
05cdd922 914
822a6eba 915
916/* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
917 * is necessary for add_machine_to_cluster becuase the table that query
918 * operates on is "mcm", not "machine".
919 */
920
921set_mach_modtime_by_id(q, argv, cl)
05cdd922 922 struct query *q;
05cdd922 923 char **argv;
822a6eba 924 client *cl;
925##{
926## char *entity;
927## int who, id;
05cdd922 928
822a6eba 929 entity = cl->entity;
930 who = cl->users_id;
05cdd922 931
822a6eba 932 id = *(int *)argv[0];
933## range of m is machine
934## repeat replace m (modtime = "now", modby = @who, modwith = @entity)
935## where m.mach_id = @id
936 return(SMS_SUCCESS);
937##}
05cdd922 938
05cdd922 939
822a6eba 940/* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
941 * is necessary for add_cluster_data and delete_cluster_data becuase the
942 * table that query operates on is "svc", not "cluster".
943 */
944
945set_cluster_modtime_by_id(q, argv, cl)
946 struct query *q;
947 char **argv;
948 client *cl;
949##{
950## char *entity;
951## int who, id;
952
953 entity = cl->entity;
954 who = cl->users_id;
955
956 id = *(int *)argv[0];
957## range of c is cluster
958## repeat replace c (modtime = "now", modby = @who, modwith = @entity)
959## where c.clu_id = @id
05cdd922 960 return(SMS_SUCCESS);
961##}
962
822a6eba 963
964/* sets the modtime on the serverhost where the service name is in argv[0]
965 * and the mach_id is in argv[1].
966 */
967
968set_serverhost_modtime(q, argv, cl)
92a943d6 969 struct query *q;
822a6eba 970 char **argv;
971 client *cl;
92a943d6 972##{
822a6eba 973## char *entity, *serv;
974## int who, id;
975
976 entity = cl->entity;
977 who = cl->users_id;
978
979 serv = argv[0];
980 id = *(int *)argv[1];
981## repeat replace sh (modtime = "now", modby = @who, modwith = @entity)
44bd6f44 982## where sh.service = uppercase(@serv) and sh.mach_id = @id
822a6eba 983 return(SMS_SUCCESS);
984##}
985
986
987/* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
988 * directory name is in argv[1].
989 */
990
991set_nfsphys_modtime(q, argv, cl)
992 struct query *q;
92a943d6 993 char **argv;
822a6eba 994 client *cl;
995##{
996## char *entity, *dir;
997## int who, id;
92a943d6 998
822a6eba 999 entity = cl->entity;
1000 who = cl->users_id;
92a943d6 1001
822a6eba 1002 id = *(int *)argv[0];
1003 dir = argv[1];
1004## repeat replace np (modtime = "now", modby = @who, modwith = @entity)
1005## where np.#dir = @dir and np.mach_id = @id
1006 return(SMS_SUCCESS);
1007##}
92a943d6 1008
92a943d6 1009
822a6eba 1010/* sets the modtime on a filesystem, where argv[0] contains the filesys
1011 * label.
1012 */
1013
1014set_filesys_modtime(q, argv, cl)
1015 struct query *q;
1016 char *argv[];
1017 client *cl;
1018##{
1019## char *label, *entity;
1020## int who;
1021
1022 entity = cl->entity;
1023 who = cl->users_id;
1024
1025 label = argv[0];
1026 if (!strcmp(q->shortname, "ufil"))
1027 label = argv[1];
1028
1029## repeat replace fs (modtime = "now", modby = @who, modwith = @entity,
1030## #phys_id = @var_phys_id) where fs.#label = @label
92a943d6 1031 return(SMS_SUCCESS);
1032##}
05cdd922 1033
822a6eba 1034
1035/* sets the modtime on a zephyr class, where argv[0] contains the class
1036 * name.
1037 */
1038
1039set_zephyr_modtime(q, argv, cl)
1040 struct query *q;
1041 char *argv[];
1042 client *cl;
05cdd922 1043##{
822a6eba 1044## char *class, *entity;
1045## int who;
1046
1047 entity = cl->entity;
1048 who = cl->users_id;
1049
1050 class = argv[0];
1051
1052## repeat replace z (modtime = "now", modby = @who, modwith = @entity)
1053## where z.#class = @class
1054 return(SMS_SUCCESS);
1055##}
1056
1057
1058/* fixes the modby field. This will be the second to last thing in the
1059 * argv, the argv length is determined from the query structure. It is
1060 * passed as a pointer to an integer. This will either turn it into a
1061 * username, or # + the users_id.
1062 */
1063followup_fix_modby(q, sq, v, action, actarg, cl)
1064 struct query *q;
1065 register struct save_queue *sq;
1066 struct validate *v;
1067 register int (*action)();
1068 register int actarg;
1069 client *cl;
1070##{
1071 register int i, j;
1072 char **argv, *malloc();
1073## int id, rowcount;
05cdd922 1074## char *name;
05cdd922 1075
822a6eba 1076 i = q->vcnt - 2;
1077 while (sq_get_data(sq, &argv)) {
1078 id = atoi(argv[i]);
1079 free(argv[i]);
1080 argv[i] = malloc(9);
1081 name = argv[i];
1082## repeat retrieve (name = users.login) where users.users_id = @id
1083## inquire_equel(rowcount = "rowcount")
1084 if (rowcount != 1) {
1085 sprintf(argv[i], "#%d", id);
1086 }
1087 (*action)(q->vcnt, argv, actarg);
1088 for (j = 0; j < q->vcnt; j++)
1089 free(argv[j]);
1090 free(argv);
1091 }
1092 sq_destroy(sq);
1093 return(SMS_SUCCESS);
30967516 1094##}
1095
822a6eba 1096
30967516 1097/**
822a6eba 1098 ** followup_ausr - add finger and pobox entries, set_user_modtime
30967516 1099 **
1100 ** Inputs:
822a6eba 1101 ** argv[0] - login (add_user)
1102 ** argv[3] - last name
1103 ** argv[4] - first name
1104 ** argv[5] - middle name
30967516 1105 **
1106 **/
1107
822a6eba 1108followup_ausr(q, argv, cl)
30967516 1109 struct query *q;
822a6eba 1110 char *argv[];
1111 client *cl;
30967516 1112##{
822a6eba 1113## int who;
1114## char *login, *entity;
1115## char fullname[129];
30967516 1116
822a6eba 1117 login = argv[0];
1118 who = cl->users_id;
1119 entity = cl->entity;
30967516 1120
822a6eba 1121 /* build fullname */
1122 if (strlen(argv[4]) && strlen(argv[5]))
1123 sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
1124 else if (strlen(argv[4]))
1125 sprintf(fullname, "%s %s", argv[4], argv[3]);
1126 else
1127 sprintf(fullname, "%s", argv[3]);
30967516 1128
822a6eba 1129 /* create finger entry, pobox & set modtime on user */
1130## repeat replace u (modtime = "now", modby=@who, modwith=@entity,
1131## #fullname=@fullname, mit_affil = u.mit_year,
1132## fmodtime="now", fmodby=@who, fmodwith=@entity,
1133## potype="NONE", pmodtime="now", pmodby=@who, pmodwith=@entity)
1134## where u.#login = @login
30967516 1135
05cdd922 1136 return(SMS_SUCCESS);
1137##}
1138
822a6eba 1139
1140/* followup_gpob: fixes argv[2] based on the IDs currently there and the
1141 * type in argv[1]. Then completes the upcall to the user.
1142 *
1143 * argv[2] is of the form "123:234" where the first integer is the machine
1144 * ID if it is a pop box, and the second is the string ID if it is an SMTP
1145 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
1146 * are skipped.
1147 */
1148
1149followup_gpob(q, sq, v, action, actarg, cl)
1150 register struct query *q;
1151 register struct save_queue *sq;
1152 register struct validate *v;
1153 register int (*action)();
1154 int actarg;
1155 client *cl;
1156##{
1157 char **argv, *index();
1158 char *ptype, *p;
1159## char box[129], *name;
1160## int mid, sid, rowcount;
1161
1162 /* for each row */
1163 while (sq_get_data(sq, &argv)) {
1164 sms_trim_args(2, argv);
1165 ptype = argv[1];
1166 p = index(argv[2], ':');
1167 *p++ = 0;
1168 mid = atoi(argv[2]);
1169 sid = atoi(p);
1170 free(argv[2]);
1171
1172 if (!strcmp(ptype, "POP")) {
1173## repeat retrieve (box=machine.#name) where machine.mach_id=@mid
1174## inquire_equel(rowcount = "rowcount")
1175 if (rowcount != 1)
1176 return(SMS_MACHINE);
1177 } else if (!strcmp(ptype, "SMTP")) {
1178## repeat retrieve (box=strings.string) where strings.string_id=@sid
1179## inquire_equel(rowcount = "rowcount")
1180 if (rowcount != 1)
1181 return(SMS_STRING);
1182 } else /* ptype == "NONE" */ {
1183 goto skip;
1184 }
1185
1186 if (!strcmp(q->shortname, "gpob")) {
1187 sid = atoi(argv[4]);
1188 free(argv[4]);
1189 argv[4] = malloc(9);
1190 name = argv[4];
1191## repeat retrieve (name = users.login) where users.users_id = @sid
1192## inquire_equel(rowcount = "rowcount")
1193 if (rowcount != 1)
1194 sprintf(name, "#%d", sid);
1195 }
1196
1197 argv[2] = box;
1198 (*action)(q->vcnt, argv, actarg);
1199 skip:
1200 /* free saved data */
1201 free(argv[0]);
1202 free(argv[1]);
1203 free(argv);
1204 }
1205
1206 sq_destroy(sq);
1207 return (SMS_SUCCESS);
1208##}
1209
1210
44bd6f44 1211/* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
1212 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
822a6eba 1213 * proper name based on the type, and repace that string in the argv.
1214 * Also fixes the modby field by called followup_fix_modby.
1215 */
1216
1217followup_glin(q, sq, v, action, actarg, cl)
1218 register struct query *q;
1219 register struct save_queue *sq;
1220 register struct validate *v;
1221 register int (*action)();
1222 int actarg;
1223 client *cl;
1224##{
1225 char **argv, *malloc(), *realloc(), *type;
1226## char *name;
1227## int id, rowcount;
1228 int i, idx;
1229
1230 idx = 8;
1231 if (!strcmp(q->shortname, "gsin"))
4f16dc86 1232 idx = 12;
822a6eba 1233
1234 while (sq_get_data(sq, &argv)) {
1235 sms_trim_args(q->vcnt, argv);
1236
1237 id = atoi(argv[i = q->vcnt - 2]);
1238 free(argv[i]);
1239 name = argv[i] = malloc(9);
1240## repeat retrieve (name = users.login) where users.users_id = @id
1241## inquire_equel(rowcount = "rowcount")
1242 if (rowcount != 1)
1243 sprintf(argv[i], "#%d", id);
1244
1245 id = atoi(argv[idx]);
1246 type = argv[idx - 1];
1247 if ((name = malloc(33)) == NULL)
1248 return(SMS_NO_MEM);
1249
1250 if (!strcmp(type, "LIST")) {
1251## repeat retrieve (name = list.#name) where list.list_id = @id
1252## inquire_equel(rowcount = "rowcount")
1253 if (rowcount != 1)
1254 strcpy(name, "???");
1255 } else if (!strcmp(type, "USER")) {
1256## repeat retrieve (name = users.login) where users.users_id = @id
1257## inquire_equel(rowcount = "rowcount")
1258 if (rowcount != 1)
1259 strcpy(name, "???");
1260 } else if (!strcmp(type, "NONE")) {
1261 strcpy(name, "NONE");
1262 } else
1263 strcpy(name, "???");
1264 free(argv[idx]);
1265 argv[idx] = name;
1266
1267 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) {
1268 argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
1269 strcpy(argv[6], UNIQUE_GID);
1270 }
1271
1272 /* send the data */
1273 (*action)(q->vcnt, argv, actarg);
1274
1275 /* free saved data */
1276 for (i = 0; i < q->vcnt; i++)
1277 free(argv[i]);
1278 free(argv);
1279 }
1280
1281 sq_destroy(sq);
1282 return (SMS_SUCCESS);
1283##}
1284
1285
1286/** followup_amtl - followup for amtl and dmfl; when adding a list
1287 ** member to a maillist, make member list a maillist also
1288 ** unless list is a user-group.
1289 ** Then set_list_modtime_by_id.
92a943d6 1290 **
1291 ** Inputs:
1292 ** argv[0] - list_id
822a6eba 1293 ** argv[1] - member_type
1294 ** argv[2] - member_id
92a943d6 1295 **
1296 **/
1297
822a6eba 1298followup_amtl(q, argv, cl)
92a943d6 1299 struct query *q;
1300 char *argv[];
822a6eba 1301 client *cl;
92a943d6 1302##{
92a943d6 1303## int list_id;
822a6eba 1304## int member_id;
1305## int exists, who;
1306## char *entity;
92a943d6 1307
1308 list_id = *(int *)argv[0];
822a6eba 1309 entity = cl->entity;
1310 who = cl->users_id;
1311
1312## range of l is list
1313## repeat replace l (modtime = "now", modby = @who, modwith = @entity)
1314## where l.#list_id = @list_id
92a943d6 1315
822a6eba 1316 /* if query is not amtl or if member_type is not LIST then return */
1317 if (bcmp(q->shortname, "amtl", 4) || bcmp(argv[1], "LIST", 4))
1318 return(SMS_SUCCESS);
92a943d6 1319
822a6eba 1320 member_id = *(int *)argv[2];
1321
1322 /* is parent list a mailing list? */
1323## repeat retrieve (exists = l.maillist) where l.#list_id=@list_id
1324 if (!exists)
1325 return(SMS_SUCCESS);
1326
1327 /* list is not a user-group; add list to maillist table */
1328## repeat replace l (maillist = 1) where l.#list_id = @member_id
92a943d6 1329 return(SMS_SUCCESS);
1330##}
1331
822a6eba 1332
1333/* followup_anfq: Add allocation to nfsphys after creating quota.
1334 * argv[0] = filsys_id
1335 * argv[2] = ascii(quota)
1336 */
1337
1338followup_anfq(q, argv, cl)
1339 struct query *q;
1340 char **argv;
1341 client *cl;
1342##{
1343## int quota, user, fs, who;
1344## char *entity;
1345
1346 fs = *(int *)argv[0];
1347 user = *(int *)argv[1];
1348 quota = atoi(argv[2]);
1349 who = cl->users_id;
1350 entity = cl->entity;
1351
1352## repeat replace nq (modtime = "now", modby = @who, modwith = @entity)
1353## where nq.filsys_id = @fs and nq.users_id = @user
1354## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
1355## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
1356 return(SMS_SUCCESS);
1357##}
1358
1359
1360/* followup_gzcl:
1361 */
1362
1363followup_gzcl(q, sq, v, action, actarg, cl)
1364 register struct query *q;
1365 register struct save_queue *sq;
1366 register struct validate *v;
1367 register int (*action)();
92a943d6 1368 int actarg;
822a6eba 1369 client *cl;
92a943d6 1370##{
822a6eba 1371## char *name;
1372## int rowcount, id;
1373 char **argv;
1374 int i;
92a943d6 1375
822a6eba 1376 while (sq_get_data(sq, &argv)) {
1377 sms_trim_args(q->vcnt, argv);
92a943d6 1378
822a6eba 1379 id = atoi(argv[i = q->vcnt - 2]);
1380 free(argv[i]);
1381 name = argv[i] = malloc(9);
1382## repeat retrieve (name = users.login) where users.users_id = @id
1383## inquire_equel(rowcount = "rowcount")
1384 if (rowcount != 1)
1385 sprintf(argv[i], "#%d", id);
1386
1387 for (i = 1; i < 8; i+=2) {
1388 id = atoi(argv[i+1]);
1389 free(argv[i+1]);
1390 if ((name = argv[i+1] = malloc(33)) == NULL)
1391 return(SMS_NO_MEM);
1392 if (!strcmp(argv[i], "LIST")) {
1393## repeat retrieve (name = list.#name) where list.list_id = @id
1394## inquire_equel(rowcount = "rowcount")
1395 if (rowcount != 1)
1396 strcpy(name, "???");
1397 } else if (!strcmp(argv[i], "USER")) {
1398## repeat retrieve (name = users.login) where users.users_id = @id
1399## inquire_equel(rowcount = "rowcount")
1400 if (rowcount != 1)
1401 strcpy(name, "???");
1402 } else if (!strcmp(argv[i], "NONE")) {
1403 strcpy(name, "NONE");
1404 } else {
1405 strcpy(name, "???");
1406 }
1407 }
92a943d6 1408
822a6eba 1409 /* send the data */
1410 (*action)(q->vcnt, argv, actarg);
1411
1412 /* free saved data */
1413 for (i = 0; i < q->vcnt; i++)
1414 free(argv[i]);
1415 free(argv);
1416 }
1417 sq_destroy(sq);
92a943d6 1418 return(SMS_SUCCESS);
1419##}
1420
05cdd922 1421
822a6eba 1422/* followup_gsha:
1423 */
1424
1425followup_gsha(q, sq, v, action, actarg, cl)
05cdd922 1426 register struct query *q;
822a6eba 1427 register struct save_queue *sq;
1428 register struct validate *v;
1429 register int (*action)();
1430 int actarg;
1431 client *cl;
05cdd922 1432##{
822a6eba 1433## char *name;
1434## int rowcount, id;
1435 char **argv;
1436 int i;
05cdd922 1437
822a6eba 1438 while (sq_get_data(sq, &argv)) {
1439 sms_trim_args(q->vcnt, argv);
05cdd922 1440
822a6eba 1441 id = atoi(argv[4]);
1442 free(argv[4]);
1443 name = argv[4] = malloc(9);
1444## repeat retrieve (name = users.login) where users.users_id = @id
1445## inquire_equel(rowcount = "rowcount")
1446 if (rowcount != 1)
1447 sprintf(argv[4], "#%d", id);
1448
1449 id = atoi(argv[2]);
1450 free(argv[2]);
1451 if ((name = argv[2] = malloc(33)) == NULL)
1452 return(SMS_NO_MEM);
1453 if (!strcmp(argv[1], "LIST")) {
1454## repeat retrieve (name = list.#name) where list.list_id = @id
1455## inquire_equel(rowcount = "rowcount")
1456 if (rowcount != 1)
1457 strcpy(name, "???");
1458 } else if (!strcmp(argv[1], "USER")) {
1459## repeat retrieve (name = users.login) where users.users_id = @id
1460## inquire_equel(rowcount = "rowcount")
1461 if (rowcount != 1)
1462 strcpy(name, "???");
1463 } else if (!strcmp(argv[1], "NONE")) {
1464 strcpy(name, "NONE");
1465 } else {
1466 strcpy(name, "???");
1467 }
05cdd922 1468
822a6eba 1469 /* send the data */
1470 (*action)(q->vcnt, argv, actarg);
1471
1472 /* free saved data */
1473 for (i = 0; i < q->vcnt; i++)
1474 free(argv[i]);
1475 free(argv);
1476 }
1477 sq_destroy(sq);
1478 return(SMS_SUCCESS);
1479##}
05cdd922 1480
05cdd922 1481
822a6eba 1482\f
1483/* Special query routines */
30967516 1484
822a6eba 1485/* set_pobox - this does all of the real work.
1486 * argv = user_id, type, box
1487 * if type is POP, then box should be a machine, and its ID should be put in
1488 * pop_id. If type is SMTP, then box should be a string and its ID should
1489 * be put in box_id. If type is NONE, then box doesn't matter.
1490 */
1491
1492int set_pobox(q, argv, cl)
1493 struct query *q;
1494 char **argv;
1495 client *cl;
1496##{
1497## int user, id, rowcount;
1498## char *box, potype[9];
1499
1500 box = argv[2];
1501 user = *(int *)argv[0];
1502
1503## repeat retrieve (id = users.pop_id, potype = users.#potype)
1504## where users.users_id = @user
e7fa3293 1505 if (!strcmp(strtrim(potype), "POP"))
822a6eba 1506 set_pop_usage(id, -1);
1507
1508 if (!strcmp(argv[1], "POP")) {
1509## repeat retrieve (id=machine.mach_id) where machine.name=uppercase(@box)
1510## inquire_equel(rowcount = "rowcount")
1511 if (rowcount != 1)
1512 return(SMS_MACHINE);
1513## repeat replace users (#potype = "POP", pop_id = @id)
1514## where users.users_id = @user
1515 set_pop_usage(id, 1);
1516 } else if (!strcmp(argv[1], "SMTP")) {
1517## range of s is strings
1518## repeat retrieve (id = s.string_id) where s.string = @box
1519## inquire_equel (rowcount = "rowcount")
1520 if (rowcount == 0) {
1521## range of v is values
1522## repeat retrieve (id = v.value) where v.name = "strings_id"
1523 id++;
1524## repeat replace v (value = @id) where v.name = "strings_id"
1525## append to strings (string_id = id, string = box)
1526 }
1527## repeat replace users (#potype = "SMTP", box_id = @id)
1528## where users.users_id = @user
1529 } else /* argv[1] == "NONE" */ {
1530## repeat replace users (#potype = "NONE") where users.users_id = @user
1531 }
1532
1533 set_pobox_modtime(q, argv, cl);
1534## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
1535## where tblstats.#table = "users"
30967516 1536 return(SMS_SUCCESS);
1537##}
1538
30967516 1539
822a6eba 1540/* get_list_info: passed a wildcard list name, returns lots of stuff about
1541 * each list. This is tricky: first build a queue of all requested
44bd6f44 1542 * data. Rest of processing consists of fixing gid, ace_name, and modby.
822a6eba 1543 */
1544
1545get_list_info(q, aargv, cl, action, actarg)
30967516 1546 register struct query *q;
822a6eba 1547 char **aargv;
1548 client *cl;
1549 register int (*action)();
1550 int actarg;
30967516 1551##{
822a6eba 1552 char *argv[13], *malloc(), *realloc();
1553## char *name, acl_type[9], listname[33], active[5], public[5], hidden[5];
1554## char maillist[5], group[5], gid[6], acl_name[33], desc[256], modtime[27];
1555## char modby[9], modwith[9];
1556## int id, rowcount, acl_id, hid, modby_id;
1557 int returned;
1558 struct save_queue *sq, *sq_create();
30967516 1559
822a6eba 1560 returned = rowcount = 0;
1561 name = aargv[0];
30967516 1562
822a6eba 1563 sq = sq_create();
1564## range of l is list
1565## repeat retrieve (id = l.list_id) where l.#name = @name {
1566 sq_save_data(sq, id);
1567 rowcount++;
1568## }
1569 if (rowcount == 0)
1570 return(SMS_NO_MATCH);
1571
1572 argv[0] = listname; argv[1] = active; argv[2] = public; argv[3] = hidden;
1573 argv[4] = maillist; argv[5] = group; argv[6] = gid; argv[7] = acl_type;
1574 argv[8] = acl_name; argv[9] = desc; argv[10] = modtime; argv[11] = modby;
1575 argv[12] = modwith;
1576
1577 while (sq_get_data(sq, &id)) {
1578 if (id == 0)
1579 continue;
1580 argv[6] = gid;
1581## repeat retrieve (listname = l.#name, active = text(l.#active),
1582## public = text(l.#public), hidden = text(l.#hidden),
1583## hid = l.#hidden, maillist = text(l.#maillist),
1584## group = text(l.#group), gid = text(l.#gid),
1585## acl_type = trim(l.#acl_type), acl_id = l.#acl_id,
1586## desc = l.#desc, modtime = l.#modtime, modby_id = l.#modby,
1587## modwith =l.#modwith)
1588## where l.list_id = @id
1589
1590 if (atoi(gid) == -1)
1591 argv[6] = UNIQUE_GID;
1592
1593 if (!strcmp(acl_type, "LIST")) {
1594## repeat retrieve (acl_name = l.#name) where l.list_id = @acl_id
1595## inquire_equel(rowcount = "rowcount")
1596 if (rowcount != 1)
1597 strcpy(acl_name, "???");
1598 } else if (!strcmp(acl_type, "USER")) {
1599## repeat retrieve (acl_name = users.#login)
1600## where users.users_id = @acl_id
1601## inquire_equel(rowcount = "rowcount")
1602 if (rowcount != 1)
1603 strcpy(acl_name, "???");
1604 } else if (!strcmp(acl_type, "NONE")) {
1605 strcpy(acl_name, "NONE");
1606 } else
1607 strcpy(acl_name, "???");
1608
1609## repeat retrieve (modby = users.login) where users.users_id = @modby_id
1610## inquire_equel(rowcount = "rowcount")
1611 if (rowcount != 1)
1612 sprintf(modby, "#%d", id);
1613
1614 sms_trim_args(q->vcnt, argv);
1615 returned++;
1616 (*action)(q->vcnt, argv, actarg);
1617 }
30967516 1618
822a6eba 1619 sq_destroy(sq);
1620## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
1621## where tblstats.#table = "list"
5e06ce45 1622
822a6eba 1623 return (SMS_SUCCESS);
1624##}
1625
1626
44bd6f44 1627/* get_ace_use - given a type and a name, return a type and a name.
1628 * The ace_type is one of "LIST", "USER", "RLIST", or "RUSER" in argv[0],
822a6eba 1629 * and argv[1] will contain the ID of the entity in question. The R*
1630 * types mean to recursively look at every containing list, not just
1631 * when the object in question is a direct member. On return, the
1632 * usage type will be one of LIST, SERVICE, FILESYS, QUOTA, QUERY, or ZEPHYR.
1633 */
1634
44bd6f44 1635int get_ace_use(q, argv, cl, action, actarg)
822a6eba 1636 struct query *q;
1637 char *argv[];
1638 client *cl;
1639 int (*action)();
1640 int actarg;
1641##{
1642 int found = 0;
1643## char *atype;
1644## int aid, listid, id;
1645 struct save_queue *sq, *sq_create();
1646
1647 atype = argv[0];
1648 aid = *(int *)argv[1];
1649 if (!strcmp(atype, "LIST") || !strcmp(atype, "USER")) {
44bd6f44 1650 return(get_ace_internal(atype, aid, action, actarg));
822a6eba 1651 }
1652
1653 sq = sq_create();
1654 if (!strcmp(atype, "RLIST")) {
1655 sq_save_data(sq, aid);
1656 /* get all the list_id's of containing lists */
1657## range of m is members
1658 while (sq_get_data(sq, &id)) {
1659## repeat retrieve (listid = m.list_id)
1660## where m.member_type = "LIST" and m.member_id = @id {
1661 sq_save_unique_data(sq, listid);
1662## }
1663 }
1664 /* now process each one */
1665 while (sq_get_data(sq, &id)) {
44bd6f44 1666 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 1667 found++;
1668 }
1669 }
1670
1671 if (!strcmp(atype, "RUSER")) {
1672## range of m is members
1673## repeat retrieve (listid = m.list_id)
1674## where m.member_type = "USER" and m.member_id = @aid {
1675 sq_save_data(sq, listid);
1676## }
1677 /* get all the list_id's of containing lists */
1678 while (sq_get_data(sq, &id)) {
1679## repeat retrieve (listid = m.list_id)
1680## where m.member_type = "LIST" and m.member_id = @id {
1681 sq_save_unique_data(sq, listid);
1682## }
1683 }
1684 /* now process each one */
1685 while (sq_get_data(sq, &id)) {
44bd6f44 1686 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 1687 found++;
1688 }
44bd6f44 1689 if (get_ace_internal("USER", aid, action, actarg) == SMS_SUCCESS)
822a6eba 1690 found++;
1691 }
05cdd922 1692
822a6eba 1693 sq_destroy(sq);
1694 if (!found) return(SMS_NO_MATCH);
05cdd922 1695 return(SMS_SUCCESS);
1696##}
92a943d6 1697
822a6eba 1698
44bd6f44 1699/* This looks up a single list or user for ace use. atype must be "USER"
822a6eba 1700 * or "LIST", and aid is the ID of the corresponding object. This is used
44bd6f44 1701 * by get_ace_use above.
822a6eba 1702 */
1703
44bd6f44 1704##get_ace_internal(atype, aid, action, actarg)
822a6eba 1705## char *atype;
1706## int aid;
1707 int (*action)();
1708 int actarg;
1709##{
1710 char *rargv[2];
1711 int found = 0;
1712## char name[33];
1713
1714 rargv[1] = name;
1715 if (!strcmp(atype, "LIST")) {
1716 rargv[0] = "FILESYS";
1717## repeat retrieve (name = filesys.label)
1718## where filesys.owners = @aid {
1719 (*action)(2, rargv, actarg);
1720 found++;
1721## }
1722
1723 rargv[0] = "QUERY";
1724## repeat retrieve (name = capacls.capability)
1725## where capacls.list_id = @aid {
1726 (*action)(2, rargv, actarg);
1727 found++;
1728## }
1729 } else if (!strcmp(atype, "USER")) {
1730 rargv[0] = "FILESYS";
1731## repeat retrieve (name = filesys.label)
1732## where filesys.owner = @aid {
1733 (*action)(2, rargv, actarg);
1734 found++;
1735## }
1736 }
1737
1738 rargv[0] = "LIST";
1739## repeat retrieve (name = list.#name)
1740## where list.acl_type = @atype and list.acl_id = @aid {
1741 (*action)(2, rargv, actarg);
1742 found++;
1743## }
1744
1745 rargv[0] = "SERVICE";
1746## repeat retrieve (name = servers.#name)
1747## where servers.acl_type = @atype and servers.acl_id = @aid {
1748 (*action)(2, rargv, actarg);
1749 found++;
1750## }
1751
1752 rargv[0] = "HOSTACCESS";
1753## repeat retrieve (name = machine.#name)
1754## where machine.mach_id = hostaccess.mach_id and
1755## hostaccess.acl_type = @atype and hostaccess.acl_id = @aid {
1756 (*action)(2, rargv, actarg);
1757 found++;
1758## }
1759 rargv[0] = "ZEPHYR";
1760## repeat retrieve (name = zephyr.class)
1761## where zephyr.xmt_type = @atype and zephyr.xmt_id = @aid or
1762## zephyr.sub_type = @atype and zephyr.sub_id = @aid or
1763## zephyr.iws_type = @atype and zephyr.iws_id = @aid or
1764## zephyr.iui_type = @atype and zephyr.iui_id = @aid {
1765 (*action)(2, rargv, actarg);
1766 found++;
1767## }
1768
1769 if (!found) return(SMS_NO_MATCH);
1770 return(SMS_SUCCESS);
1771##}
1772
1773
1774/* get_lists_of_member - given a type and a name, return the name and flags
1775 * of all of the lists of the given member. The member_type is one of
1776 * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0],
1777 * and argv[1] will contain the ID of the entity in question. The R*
1778 * types mean to recursively look at every containing list, not just
1779 * when the object in question is a direct member.
1780 */
1781
1782int get_lists_of_member(q, argv, cl, action, actarg)
92a943d6 1783 struct query *q;
1784 char *argv[];
822a6eba 1785 client *cl;
1786 int (*action)();
1787 int actarg;
92a943d6 1788##{
822a6eba 1789 int found = 0;
1790## char *atype;
1791## int aid, listid, id;
1792 struct save_queue *sq, *sq_create();
1793
1794 atype = argv[0];
1795 aid = *(int *)argv[1];
1796 if (!strcmp(atype, "LIST") ||
1797 !strcmp(atype, "USER") ||
1798 !strcmp(atype, "STRING")) {
1799 return(glom_internal(atype, aid, action, actarg));
1800 }
92a943d6 1801
822a6eba 1802 sq = sq_create();
1803 if (!strcmp(atype, "RLIST")) {
1804 sq_save_data(sq, aid);
1805 /* get all the list_id's of containing lists */
1806## range of m is members
1807 while (sq_get_data(sq, &id)) {
1808## repeat retrieve (listid = m.list_id)
1809## where m.member_type = "LIST" and m.member_id = @id {
1810 sq_save_unique_data(sq, listid);
1811## }
1812 }
1813 /* now process each one */
1814 while (sq_get_data(sq, &id)) {
1815 if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1816 found++;
1817 }
1818 }
92a943d6 1819
822a6eba 1820 if (!strcmp(atype, "RUSER")) {
1821## range of m is members
1822## repeat retrieve (listid = m.list_id)
1823## where m.member_type = "USER" and m.member_id = @aid {
1824 sq_save_data(sq, listid);
1825## }
1826 /* get all the list_id's of containing lists */
1827 while (sq_get_data(sq, &id)) {
1828## repeat retrieve (listid = m.list_id)
1829## where m.member_type = "LIST" and m.member_id = @id {
1830 sq_save_unique_data(sq, listid);
1831## }
1832 }
1833 /* now process each one */
1834 while (sq_get_data(sq, &id)) {
1835 if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1836 found++;
1837 }
1838 if (glom_internal("USER", aid, action, actarg) == SMS_SUCCESS)
1839 found++;
1840 }
92a943d6 1841
822a6eba 1842 if (!strcmp(atype, "RSTRING")) {
1843## range of m is members
1844## repeat retrieve (listid = m.list_id)
1845## where m.member_type = "STRING" and m.member_id = @aid {
1846 sq_save_data(sq, listid);
1847## }
1848 /* get all the list_id's of containing lists */
1849 while (sq_get_data(sq, &id)) {
1850## repeat retrieve (listid = m.list_id)
1851## where m.member_type = "LIST" and m.member_id = @id {
1852 sq_save_unique_data(sq, listid);
1853## }
1854 }
1855 /* now process each one */
1856 while (sq_get_data(sq, &id)) {
1857 if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1858 found++;
1859 }
1860 if (glom_internal("STRING", aid, action, actarg) == SMS_SUCCESS)
1861 found++;
92a943d6 1862 }
55534a87 1863
822a6eba 1864## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
1865## where tblstats.#table = "members"
1866 sq_destroy(sq);
1867 if (!found) return(SMS_NO_MATCH);
1868 return(SMS_SUCCESS);
1869##}
1870
55534a87 1871
822a6eba 1872/* This looks up a single list, user, or string as a member. atype must be
1873 * "USER", "LIST", or "STRING" and aid is the ID of the corresponding object.
1874 * This is used by get_lists_of_members above.
1875 */
1876
1877##glom_internal(atype, aid, action, actarg)
1878## char *atype;
1879## int aid;
1880 int (*action)();
1881 int actarg;
1882##{
1883 char *rargv[6];
1884 int found = 0;
1885## char name[33], active[5], public[5], hidden[5], maillist[5], group[5];
1886
1887 rargv[0] = name;
1888 rargv[1] = active;
1889 rargv[2] = public;
1890 rargv[3] = hidden;
1891 rargv[4] = maillist;
1892 rargv[5] = group;
1893## repeat retrieve (name = list.#name, active = text(list.#active),
1894## public = text(list.#public), hidden = text(list.#hidden),
1895## maillist = text(list.#maillist), group = text(list.#group))
1896## where list.list_id = m.list_id and
1897## m.member_type = @atype and m.member_id = @aid {
1898 (*action)(6, rargv, actarg);
1899 found++;
1900## }
92a943d6 1901
822a6eba 1902 if (!found) return(SMS_NO_MATCH);
92a943d6 1903 return(SMS_SUCCESS);
1904##}
1905
822a6eba 1906
1907/* qualified_get_lists: passed "TRUE", "FALSE", or "DONTCARE" for each of
1908 * the five flags associated with each list. It will return the name of
1909 * each list that meets the quailifications. It does this by building a
1910 * where clause based on the arguments, then doing a retrieve.
1911 */
1912
1913static char *lflags[5] = { "active", "public", "hidden", "maillist", "group" };
1914
1915int qualified_get_lists(q, argv, cl, action, actarg)
1916 struct query *q;
1917 char *argv[];
1918 client *cl;
1919 int (*action)();
1920 int actarg;
1921{
1922 return(qualified_get(q, argv, action, actarg, "l.list_id != 0",
1923 "l", "name", lflags));
1924}
1925
1926
1927/** get_members_of_list - optimized query for retrieval of list members
c2408bd5 1928 **
1929 ** Inputs:
1930 ** argv[0] - list_id
1931 **
1932 ** Description:
1933 ** - retrieve USER members, then LIST members, then STRING members
c2408bd5 1934 **/
1935
822a6eba 1936get_members_of_list(q, argv, cl, action, actarg)
c2408bd5 1937 struct query *q;
1938 char *argv[];
822a6eba 1939 client *cl;
c2408bd5 1940 int (*action)();
1941 int actarg;
1942##{
1943## int list_id;
1944## char member_name[129];
1945 char *targv[2];
1946
1947 list_id = *(int *)argv[0];
1948 targv[0] = "USER";
1949 targv[1] = member_name;
1950
1951## range of m is members
1952## repeat retrieve (member_name = users.login)
1953## where m.#list_id = @list_id and m.member_type = "USER"
1954## and m.member_id = users.users_id
92a943d6 1955## sort by #member_name
c2408bd5 1956## {
1957 (*action)(2, targv, actarg);
1958## }
1959
1960 targv[0] = "LIST";
1961## repeat retrieve (member_name = list.name)
1962## where m.#list_id = @list_id and m.member_type = "LIST"
1963## and m.member_id = list.#list_id
92a943d6 1964## sort by #member_name
c2408bd5 1965## {
1966 (*action)(2, targv, actarg);
1967## }
1968
1969 targv[0] = "STRING";
1970## repeat retrieve (member_name = strings.string)
1971## where m.#list_id = @list_id and m.member_type = "STRING"
1972## and m.member_id = strings.string_id
92a943d6 1973## sort by #member_name
c2408bd5 1974## {
1975 (*action)(2, targv, actarg);
1976## }
1977
822a6eba 1978## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
1979## where tblstats.#table = "members"
c2408bd5 1980 return(SMS_SUCCESS);
1981##}
1982
92a943d6 1983
822a6eba 1984/* count_members_of_list: this is a simple query, but it cannot be done
1985 * through the dispatch table.
1986 */
1987
1988int count_members_of_list(q, argv, cl, action, actarg)
92a943d6 1989 struct query *q;
1990 char *argv[];
822a6eba 1991 client *cl;
92a943d6 1992 int (*action)();
1993 int actarg;
1994##{
822a6eba 1995## int list, ct = 0;
1996 char *rargv[1], countbuf[5];
1997
1998 list = *(int *)argv[0];
1999 rargv[0] = countbuf;
2000## repeat retrieve (ct = count(members.list_id where members.list_id = @list))
2001 sprintf(countbuf, "%d", ct);
2002 (*action)(1, rargv, actarg);
2003## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2004## where tblstats.#table = "members"
2005 return(SMS_SUCCESS);
2006##}
92a943d6 2007
92a943d6 2008
822a6eba 2009/* qualified_get_server: passed "TRUE", "FALSE", or "DONTCARE" for each of
2010 * the three flags associated with each service. It will return the name of
2011 * each service that meets the quailifications. It does this by building a
2012 * where clause based on the arguments, then doing a retrieve.
2013 */
92a943d6 2014
822a6eba 2015static char *sflags[3] = { "enable", "inprogress", "harderror" };
a6cb4d4c 2016
822a6eba 2017int qualified_get_server(q, argv, cl, action, actarg)
a6cb4d4c 2018 struct query *q;
2019 char *argv[];
822a6eba 2020 client *cl;
a6cb4d4c 2021 int (*action)();
2022 int actarg;
822a6eba 2023{
2024 return(qualified_get(q, argv, action, actarg, "s.name != \"\"",
2025 "s", "name", sflags));
2026}
a6cb4d4c 2027
a6cb4d4c 2028
822a6eba 2029/* generic qualified get routine, used by qualified_get_lists,
2030 * qualified_get_server, and qualified_get_serverhost.
2031 * Args:
2032 * start - a simple where clause, must not be empty
2033 * range - the name of the range variable
2034 * field - the field to return
2035 * flags - an array of strings, names of the flag variables
2036 */
c2408bd5 2037
822a6eba 2038int qualified_get(q, argv, action, actarg, start, range, field, flags)
c2408bd5 2039 struct query *q;
2040 char *argv[];
2041 int (*action)();
2042 int actarg;
822a6eba 2043 char *start;
2044 char *range;
2045 char *field;
2046 char *flags[];
c2408bd5 2047##{
822a6eba 2048## char name[33], qual[256], *rvar, *rtbl, *rfield;
2049 char *rargv[1], buf[32];
2050## int rowcount, i;
2051
2052 strcpy(qual, start);
2053 for (i = 0; i < q->argc; i++) {
2054 if (!strcmp(argv[i], "TRUE")) {
2055 sprintf(buf, " and %s.%s != 0", range, flags[i]);
2056 (void) strcat(qual, buf);
2057 } else if (!strcmp(argv[i], "FALSE")) {
2058 sprintf(buf, " and %s.%s = 0", range, flags[i]);
2059 (void) strcat(qual, buf);
2060 }
2061 }
2062
2063 rargv[0] = name;
2064 rvar = range;
2065 rtbl = q->rtable;
2066 rfield = field;
2067## range of rvar is rtbl
2068## retrieve (name = rvar.rfield) where qual {
2069 (*action)(1, rargv, actarg);
c2408bd5 2070## }
822a6eba 2071## inquire_equel(rowcount = "rowcount")
2072## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2073## where tblstats.#table = @rtbl
2074 if (rowcount == 0)
2075 return(SMS_NO_MATCH);
2076 return(SMS_SUCCESS);
2077##}
c2408bd5 2078
c2408bd5 2079
822a6eba 2080/* qualified_get_serverhost: passed "TRUE", "FALSE", or "DONTCARE" for each of
2081 * the five flags associated with each serverhost. It will return the name of
2082 * each service and host that meets the quailifications. It does this by
2083 * building a where clause based on the arguments, then doing a retrieve.
2084 */
c2408bd5 2085
822a6eba 2086static char *shflags[6] = { "service", "enable", "override", "success",
2087 "inprogress", "hosterror" };
a6cb4d4c 2088
822a6eba 2089int qualified_get_serverhost(q, argv, cl, action, actarg)
a6cb4d4c 2090 struct query *q;
2091 char *argv[];
822a6eba 2092 client *cl;
a6cb4d4c 2093 int (*action)();
2094 int actarg;
2095##{
822a6eba 2096## char sname[33], mname[33], qual[256];
2097 char *rargv[2], buf[32];
2098## int rowcount, i;
2099
44bd6f44 2100 sprintf(qual, "machine.mach_id = sh.mach_id and sh.service = uppercase(\"%s\")",
822a6eba 2101 argv[0]);
2102 for (i = 1; i < q->argc; i++) {
2103 if (!strcmp(argv[i], "TRUE")) {
2104 sprintf(buf, " and sh.%s != 0", shflags[i]);
2105 strcat(qual, buf);
2106 } else if (!strcmp(argv[i], "FALSE")) {
2107 sprintf(buf, " and sh.%s = 0", shflags[i]);
2108 strcat(qual, buf);
2109 }
2110 }
2111
2112 rargv[0] = sname;
2113 rargv[1] = mname;
2114## range of sh is serverhosts
2115## retrieve (sname = sh.service, mname = machine.name) where qual {
2116 (*action)(2, rargv, actarg);
a6cb4d4c 2117## }
822a6eba 2118## inquire_equel(rowcount = "rowcount")
2119## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2120## where tblstats.#table = "serverhosts"
2121 if (rowcount == 0)
2122 return(SMS_NO_MATCH);
2123 return(SMS_SUCCESS);
2124##}
a6cb4d4c 2125
a6cb4d4c 2126
822a6eba 2127/* register_user - change user's login name and allocate a pobox, group,
2128 * filesystem, and quota for them. The user's status must start out as 0,
2129 * and is left as 2. Arguments are: user's UID, new login name, and user's
2130 * type for filesystem allocation (SMS_FS_STUDENT, SMS_FS_FACULTY,
2131 * SMS_FS_STAFF, SMS_FS_MISC).
2132 */
2133
2134register_user(q, argv, cl)
2135 struct query *q;
2136 char **argv;
2137 client *cl;
2138##{
2139## char *login, dir[65], *entity, *directory, machname[33];
2140## int who, rowcount, mid, uid, users_id, flag, utype, nid, list_id, quota;
2141## int size, alloc, pid, m_id;
2142 int maxsize;
2143
2144 entity = cl->entity;
2145 who = cl->users_id;
2146
2147 uid = atoi(argv[0]);
2148 login = argv[1];
2149 utype = atoi(argv[2]);
2150
2151## range of u is users
2152## range of l is list
2153## range of sh is serverhosts
2154## range of n is nfsphys
2155## range of m is machine
2156
2157 /* find user */
2158## repeat retrieve (users_id = u.#users_id)
2159## where u.#uid = @uid and u.status = 0
2160## inquire_equel(rowcount = "rowcount");
2161 if (rowcount == 0)
2162 return(SMS_NO_MATCH);
2163 if (rowcount > 1)
2164 return(SMS_NOT_UNIQUE);
2165
2166 /* check new login name */
2167## repeat retrieve (flag = any(u.#login where u.#login = @login))
2168 if (flag)
2169 return(SMS_IN_USE);
4f16dc86 2170## repeat retrieve (flag = any(l.#name where l.#name = @login))
822a6eba 2171 if (flag)
2172 return(SMS_IN_USE);
2173## repeat retrieve (flag = any(filesys.#name where filesys.#name = @login))
2174 if (flag)
2175 return(SMS_IN_USE);
2176 com_err(whoami, 0, "new login name OK");
2177
2178 /* choose place for pobox, put in mid */
2179## repeat retrieve (mid = sh.mach_id, machname = m.name)
44bd6f44 2180## where sh.service = "POP" and m.mach_id = sh.mach_id and
2181## sh.value2 - sh.value1 = max(sh.value2-sh.value1 where sh.service="POP")
8ac9ee7a 2182## inquire_equel(rowcount = "rowcount");
822a6eba 2183 if (rowcount == 0)
44bd6f44 2184 return(SMS_NO_POBOX);
822a6eba 2185
2186 /* change login name, set pobox */
2187## repeat replace u (#login = @login, status = 2, modtime = "now",
2188## modby = @who, modwith = @entity, potype="POP",
2189## pop_id = @mid, pmodtime="now", pmodby=@who,
2190## pmodwith=@entity)
2191## where u.#users_id = @users_id
8ac9ee7a 2192## inquire_equel(rowcount = "rowcount");
822a6eba 2193 if (rowcount != 1)
2194 return(SMS_INTERNAL);
2195 set_pop_usage(mid, 1);
2196 com_err(whoami, 0, "set login name to %s and pobox to %s", login,
2197 trim(machname));
2198
2199 /* create group list */
2200 if (set_next_object_id("gid", "list"))
44bd6f44 2201 return(SMS_NO_ID);
822a6eba 2202 if (set_next_object_id("list_id", "list"))
44bd6f44 2203 return(SMS_NO_ID);
822a6eba 2204## repeat retrieve (list_id = values.value) where values.name = "list_id"
8ac9ee7a 2205## inquire_equel(rowcount = "rowcount");
822a6eba 2206 if (rowcount != 1)
2207 return(SMS_INTERNAL);
2208## repeat append list (name = @login, #list_id = @list_id, active = 1,
2209## public = 0, hidden = 0, maillist = 0, group = 1,
2210## #gid = values.value, desc = "User Group",
2211## acl_type = "USER", acl_id = @users_id, modtime = "now",
2212## modby = @who, modwith = @entity)
2213## where values.name = "gid"
8ac9ee7a 2214## inquire_equel(rowcount = "rowcount");
44bd6f44 2215 if (rowcount != 1)
2216 return(SMS_INTERNAL);
2217## repeat append members (#list_id = @list_id, member_type = "USER",
2218## member_id = @users_id)
8ac9ee7a 2219## inquire_equel(rowcount = "rowcount");
822a6eba 2220 if (rowcount != 1)
2221 return(SMS_INTERNAL);
2222 com_err(whoami, 0, "group list created");
2223
2224 /* decide where to put filesystem */
2225 maxsize = 0;
2226 directory = NULL;
2227## repeat retrieve (mid = n.mach_id, dir = trim(n.#dir), nid = n.nfsphys_id,
2228## flag = n.status, size = n.#size, alloc = n.allocated) {
2229 if ((flag & utype) && (size != 0) && (size - alloc > maxsize)) {
2230 maxsize = size - alloc;
2231 if (directory)
2232 free(directory);
2233 directory = strsave(dir);
2234 pid = nid;
2235 m_id = mid;
2236 }
a6cb4d4c 2237## }
822a6eba 2238 if (maxsize == 0)
44bd6f44 2239 return(SMS_NO_FILESYS);
822a6eba 2240
2241 /* create filesystem */
2242 if (set_next_object_id("filsys_id", "filesys"))
44bd6f44 2243 return(SMS_NO_ID);
822a6eba 2244## repeat append filesys (filsys_id = values.value, phys_id = @pid,
2245## label = @login, type = "NFS", mach_id = @m_id,
4f16dc86 2246## name = @directory + "/" + @login,
2247## mount = "/mit/" + @login,
822a6eba 2248## access = "w", comments = "User Locker",
2249## owner = @users_id, owners = @list_id, createflg = 1,
2250## lockertype = "HOMEDIR", modtime = "now",
2251## modby = @who, modwith = @entity)
2252## where values.name = "filsys_id"
8ac9ee7a 2253## inquire_equel(rowcount = "rowcount");
822a6eba 2254 if (rowcount != 1)
2255 return(SMS_INTERNAL);
2256 com_err(whoami, 0, "filesys created on mach %d in %s/%s", m_id,
4f16dc86 2257 directory, login);
822a6eba 2258
2259 /* set quota */
2260## repeat retrieve (quota = values.value) where values.name = "def_quota"
8ac9ee7a 2261## inquire_equel(rowcount = "rowcount");
822a6eba 2262 if (rowcount != 1)
44bd6f44 2263 return(SMS_NO_QUOTA);
822a6eba 2264## repeat append nfsquota (#users_id = @users_id, filsys_id = values.value,
e7fa3293 2265## #quota = @quota, phys_id = @pid, modtime = "now",
2266## modby = @who, modwith = @entity)
822a6eba 2267## where values.name = "filsys_id"
8ac9ee7a 2268## inquire_equel(rowcount = "rowcount");
822a6eba 2269 if (rowcount != 1)
2270 return(SMS_INTERNAL);
2271## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
2272## where nfsphys.nfsphys_id = filesys.#phys_id and
2273## filesys.filsys_id = values.value and values.name = "filsys_id"
8ac9ee7a 2274## inquire_equel(rowcount = "rowcount");
822a6eba 2275 if (rowcount != 1)
2276 return(SMS_INTERNAL);
2277 com_err(whoami, 0, "quota of %d assigned", quota);
2278
4f16dc86 2279## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
2280## where tblstats.table = "users"
2281## repeat replace tblstats (appends = tblstats.appends + 1, modtime = "now")
2282## where tblstats.table = "list" or tblstats.table = "filesys" or
2283## tblstats.table = "nfsquota"
822a6eba 2284 return(SMS_SUCCESS);
2285##}
2286
2287
2288
2289/** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
2290 **
2291 ** Inputs:
2292 ** id of machine
2293 ** delta (will be +/- 1)
2294 **
2295 ** Description:
2296 ** - incr/decr value field in serverhosts table for pop/mach_id
2297 **
2298 **/
2299
2300static int set_pop_usage(id, count)
2301int id;
2302int count;
2303##{
2304## int mach_id = id;
2305## int n = count;
2306
2307## range of sh is serverhosts
2308## repeat replace sh (value1 = sh.value1 + @n)
44bd6f44 2309## where sh.service = "POP" and sh.#mach_id = @mach_id
a6cb4d4c 2310
2311 return(SMS_SUCCESS);
2312##}
822a6eba 2313
2314
c2408bd5 2315\f
05cdd922 2316/* Validation Routines */
2317
2318validate_row(q, argv, v)
2319 register struct query *q;
2320 char *argv[];
2321 register struct validate *v;
2322##{
2323## char *rvar;
2324## char *table;
2325## char *name;
2326## char qual[128];
2327## int rowcount;
2328
2329 /* build where clause */
2330 build_qual(v->qual, v->argc, argv, qual);
2331
2332 /* setup ingres variables */
2333 rvar = q->rvar;
2334 table = q->rtable;
2335 name = v->field;
2336
6388c51a 2337 if (log_flags & LOG_VALID)
b4182127 2338 /* tell the logfile what we're doing */
2339 com_err(whoami, 0, "validating row: %s", qual);
2340
05cdd922 2341 /* look for the record */
2342## range of rvar is table
2343## retrieve (rowcount = count(rvar.name where qual))
05cdd922 2344 if (rowcount == 0) return(SMS_NO_MATCH);
2345 if (rowcount > 1) return(SMS_NOT_UNIQUE);
2346 return(SMS_EXISTS);
2347##}
2348
2349validate_fields(q, argv, vo, n)
2350 struct query *q;
2351 register char *argv[];
2352 register struct valobj *vo;
2353 register int n;
2354{
2355 register int status;
05cdd922 2356
2357 while (--n >= 0) {
2358 switch (vo->type) {
2359 case V_NAME:
6388c51a 2360 if (log_flags & LOG_VALID)
b4182127 2361 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2362 vo->namefield, vo->table, argv[vo->index]);
05cdd922 2363 status = validate_name(argv, vo);
2364 break;
2365
2366 case V_ID:
6388c51a 2367 if (log_flags & LOG_VALID)
b4182127 2368 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2369 vo->idfield, vo->table, argv[vo->index]);
05cdd922 2370 status = validate_id(argv, vo);
2371 break;
2372
92a943d6 2373 case V_DATE:
6388c51a 2374 if (log_flags & LOG_VALID)
92a943d6 2375 com_err(whoami, 0, "validating date: %s", argv[vo->index]);
2376 status = validate_date(argv, vo);
2377 break;
2378
05cdd922 2379 case V_TYPE:
6388c51a 2380 if (log_flags & LOG_VALID)
b4182127 2381 com_err(whoami, 0, "validating %s type: %s",
05cdd922 2382 vo->table, argv[vo->index]);
05cdd922 2383 status = validate_type(argv, vo);
2384 break;
2385
2386 case V_TYPEDATA:
6388c51a 2387 if (log_flags & LOG_VALID)
92a943d6 2388 com_err(whoami, 0, "validating typed data (%s): %s",
2389 argv[vo->index - 1], argv[vo->index]);
05cdd922 2390 status = validate_typedata(q, argv, vo);
2391 break;
2392
822a6eba 2393 case V_RENAME:
6388c51a 2394 if (log_flags & LOG_VALID)
822a6eba 2395 com_err(whoami, 0, "validating rename %s in %s",
2396 argv[vo->index], vo->table);
2397 status = validate_rename(argv, vo);
2398 break;
2399
2400 case V_CHAR:
6388c51a 2401 if (log_flags & LOG_VALID)
822a6eba 2402 com_err(whoami, 0, "validating chars: %s", argv[vo->index]);
2403 status = validate_chars(argv[vo->index]);
05cdd922 2404 break;
2405
92a943d6 2406 case V_SORT:
2407 status = SMS_EXISTS;
2408 break;
2409
05cdd922 2410 }
2411
2412 if (status != SMS_EXISTS) return(status);
2413 vo++;
2414 }
2415
2416 return(SMS_SUCCESS);
2417}
2418
822a6eba 2419
2420/* validate_chars: verify that there are no illegal characters in
2421 * the string. Legal characters are printing chars other than
331b982e 2422 * ", *, ?, \, [ and ].
822a6eba 2423 */
2424static int illegalchars[] = {
2425 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2426 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2427 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
2428 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */
2429 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ - O */
331b982e 2430 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */
822a6eba 2431 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2432 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
2433 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
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};
2442
2443validate_chars(s)
2444register char *s;
2445{
2446 while (*s)
2447 if (illegalchars[*s++])
2448 return(SMS_BAD_CHAR);
2449 return(SMS_EXISTS);
2450}
2451
2452
05cdd922 2453validate_id(argv, vo)
2454 char *argv[];
2455 register struct valobj *vo;
2456##{
2457## char *name;
2458## char *table;
2459## char *namefield;
2460## char *idfield;
2461## int id;
2462## int rowcount;
122ec372 2463 register char *c;
05cdd922 2464
2465 name = argv[vo->index];
2466 table = vo->table;
122ec372 2467 /* minor kludge to upcasify machine names */
822a6eba 2468 if (!strcmp(table, "machine"))
122ec372 2469 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 2470 namefield = vo->namefield;
2471 idfield = vo->idfield;
822a6eba 2472 if (!strcmp(namefield, "uid")) {
9119288e 2473## retrieve (id = table.idfield) where table.namefield = int4(name)
2474## inquire_equel (rowcount = "rowcount")
2475 } else {
2476## retrieve (id = table.idfield) where table.namefield = name
2477## inquire_equel (rowcount = "rowcount")
2478 }
05cdd922 2479 if (rowcount != 1) return(vo->error);
2480 *(int *)argv[vo->index] = id;
2481 return(SMS_EXISTS);
2482##}
2483
2484validate_name(argv, vo)
2485 char *argv[];
2486 register struct valobj *vo;
2487##{
2488## char *name;
2489## char *table;
2490## char *namefield;
2491## int rowcount;
44bd6f44 2492 register char *c;
05cdd922 2493
2494 name = argv[vo->index];
2495 table = vo->table;
2496 namefield = vo->namefield;
44bd6f44 2497 if (!strcmp(table, "servers") && !strcmp(namefield, "name")) {
2498 for (c = name; *c; c++)
2499 if (islower(*c))
2500 *c = toupper(*c);
2501 }
05cdd922 2502## retrieve (rowcount = countu(table.namefield
2503## where table.namefield = name))
2504 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
2505##}
2506
92a943d6 2507validate_date(argv, vo)
2508 char *argv[];
2509 struct valobj *vo;
2510##{
2511## char *idate;
2512## double dd;
2513## int errorno;
2514
2515 idate = argv[vo->index];
2516
2517## retrieve (dd = interval("years", date(idate) - date("today")))
2518## inquire_equel (errorno = "errorno")
2519 if (errorno != 0 || dd > 5.0) return(SMS_DATE);
44bd6f44 2520 return(SMS_EXISTS);
92a943d6 2521##}
2522
822a6eba 2523
2524validate_rename(argv, vo)
2525char *argv[];
2526struct valobj *vo;
2527##{
2528## char *name, *table, *namefield, *idfield;
2529## int id;
2530 register char *c;
2531
2532 c = name = argv[vo->index];
2533 while (*c)
2534 if (illegalchars[*c++])
2535 return(SMS_BAD_CHAR);
2536 table = vo->table;
2537 /* minor kludge to upcasify machine names */
2538 if (!strcmp(table, "machine"))
2539 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
2540 namefield = vo->namefield;
2541 idfield = vo->idfield;
2542 id = -1;
2543 if (idfield == 0) {
2544 if (!strcmp(argv[vo->index], argv[vo->index - 1]))
2545 return(SMS_EXISTS);
2546## retrieve (id = any(table.namefield where table.namefield = name))
2547 if (id)
2548 return(vo->error);
2549 else
2550 return(SMS_EXISTS);
2551 }
2552## retrieve (id = table.idfield) where table.namefield = name
2553 if (id == -1 || id == *(int *)argv[vo->index - 1])
2554 return(SMS_EXISTS);
2555 else
2556 return(vo->error);
2557##}
2558
2559
05cdd922 2560validate_type(argv, vo)
2561 char *argv[];
2562 register struct valobj *vo;
2563##{
2564## char *typename;
2565## char *value;
822a6eba 2566## int exists;
05cdd922 2567 register char *c;
2568
2569 typename = vo->table;
822a6eba 2570 c = value = argv[vo->index];
2571 while (*c)
2572 if (illegalchars[*c++])
2573 return(SMS_BAD_CHAR);
05cdd922 2574
2575 /* uppercase type fields */
2576 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
2577
2578## range of a is alias
822a6eba 2579## repeat retrieve (exists = any(a.trans where a.name = @typename and
05cdd922 2580## a.type = "TYPE" and
2581## a.trans = @value))
822a6eba 2582 return (exists ? SMS_EXISTS : vo->error);
05cdd922 2583##}
2584
2585/* validate member or type-specific data field */
2586
2587validate_typedata(q, argv, vo)
2588 register struct query *q;
2589 register char *argv[];
2590 register struct valobj *vo;
2591##{
2592## char *name;
2593## char *field_type;
822a6eba 2594## char data_type[129];
05cdd922 2595## int id;
05cdd922 2596## int rowcount;
822a6eba 2597 char *index();
a6cb4d4c 2598 register char *c;
05cdd922 2599
2600 /* get named object */
2601 name = argv[vo->index];
2602
2603 /* get field type string (known to be at index-1) */
2604 field_type = argv[vo->index-1];
2605
2606 /* get corresponding data type associated with field type name */
2607## repeat retrieve (data_type = alias.trans)
2608## where alias.#name = @field_type and alias.type = "TYPEDATA"
2609## inquire_equel (rowcount = "rowcount")
2610 if (rowcount != 1) return(SMS_TYPE);
2611
2612 /* now retrieve the record id corresponding to the named object */
822a6eba 2613 if (index(data_type, ' '))
2614 *index(data_type, ' ') = 0;
05cdd922 2615 if (!strcmp(data_type, "user")) {
2616 /* USER */
2617## repeat retrieve (id = users.users_id) where users.login = @name
2618## inquire_equel (rowcount = "rowcount")
2619 if (rowcount != 1) return(SMS_USER);
2620
2621 } else if (!strcmp(data_type, "list")) {
2622 /* LIST */
2623## repeat retrieve (id = list.list_id) where list.#name = @name
2624## inquire_equel (rowcount = "rowcount")
822a6eba 2625 if (rowcount != 1) {
2626 /* if idfield is non-zero, then if argv[0] matches the string
2627 * that we're trying to resolve, we should get the value of
2628 * values.[idfield] for the id.
2629 */
2630 if (vo->idfield && !strcmp(argv[0], argv[vo->index])) {
4f16dc86 2631 set_next_object_id(q->validate->object_id, q->rtable);
822a6eba 2632 name = vo->idfield;
4f16dc86 2633## repeat retrieve (id = values.value) where values.#name = @name
822a6eba 2634## inquire_equel(rowcount = "rowcount")
2635 if (rowcount != 1) return(SMS_LIST);
2636 } else
2637 return(SMS_LIST);
2638 }
05cdd922 2639 } else if (!strcmp(data_type, "machine")) {
2640 /* MACHINE */
a6cb4d4c 2641 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 2642## repeat retrieve (id = machine.mach_id) where machine.#name = @name
2643## inquire_equel (rowcount = "rowcount")
2644 if (rowcount != 1) return(SMS_MACHINE);
2645
2646 } else if (!strcmp(data_type, "string")) {
2647 /* STRING */
2648## range of s is strings
822a6eba 2649## repeat retrieve (id = s.string_id) where s.string = @name
05cdd922 2650## inquire_equel (rowcount = "rowcount")
2651 if (rowcount == 0) {
2652 if (q->type != APPEND) return(SMS_STRING);
2653## range of v is values
2654## retrieve (id = v.value) where v.#name = "strings_id"
2655 id++;
2656## replace v (value = id) where v.#name = "strings_id"
822a6eba 2657## append to strings (string_id = id, string = name)
05cdd922 2658 }
822a6eba 2659 } else if (!strcmp(data_type, "none")) {
2660 id = 0;
05cdd922 2661 } else {
2662 return(SMS_TYPE);
2663 }
2664
2665 /* now set value in argv */
2666 *(int *)argv[vo->index] = id;
2667
2668 return (SMS_EXISTS);
2669##}
2670
05cdd922 2671
822a6eba 2672/* This looks up a login name and returns the SMS internal ID. It is used
2673 * by authenticate to put the users_id in the client structure.
2674 */
05cdd922 2675
822a6eba 2676int get_users_id(name)
2677char *name;
2678##{
2679## int id, rowcount;
2680## char *login;
05cdd922 2681
822a6eba 2682 login = name;
05cdd922 2683
822a6eba 2684## range of u is users
2685## repeat retrieve (id = u.#users_id) where u.#login = @login
2686## inquire_equel (rowcount = "rowcount")
2687
2688 if (rowcount == 1)
2689 return(id);
2690 else
2691 return(0);
2692##}
05cdd922 2693
05cdd922 2694
822a6eba 2695/* Check the database at startup time. For now this just resets the
2696 * inprogress flags that the DCM uses.
2697 */
05cdd922 2698
822a6eba 2699sanity_check_database()
2700##{
05cdd922 2701##}
This page took 0.533036 seconds and 5 git commands to generate.