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