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