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