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