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