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