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