3 * Query followup routines
5 * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
11 #include <mit-copyright.h>
12 #include "mr_server.h"
24 EXEC SQL INCLUDE sqlca;
28 extern char *whoami, *table_name[];
29 extern int dbms_errno, mr_errcode;
31 EXEC SQL BEGIN DECLARE SECTION;
32 extern char stmt_buf[];
33 EXEC SQL END DECLARE SECTION;
35 EXEC SQL WHENEVER SQLERROR DO dbmserr();
38 /* FOLLOWUP ROUTINES */
40 /* generic set_modtime routine. This takes the table id from the query,
41 * and will update the modtime, modby, and modwho fields in the entry in
42 * the table whose name field matches argv[0].
45 int set_modtime(struct query *q, char *argv[], client *cl)
47 char *name, *entity, *table;
52 table = table_name[q->rtable];
55 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
56 "modwith = '%s' WHERE name = '%s'", table, who, entity, name);
57 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
62 /* generic set_modtime_by_id routine. This takes the table id from
63 * the query, and the id name from the validate record,
64 * and will update the modtime, modby, and modwho fields in the entry in
65 * the table whose id matches argv[0].
68 int set_modtime_by_id(struct query *q, char *argv[], client *cl)
70 char *entity, *table, *id_name;
75 table = table_name[q->rtable];
76 id_name = q->validate->object_id;
79 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
80 "modwith = '%s' WHERE %s = %d", table, who, entity, id_name, id);
81 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
86 /* Sets the finger modtime on a user record. The users_id will be in argv[0].
89 int set_finger_modtime(struct query *q, char *argv[], client *cl)
91 EXEC SQL BEGIN DECLARE SECTION;
94 EXEC SQL END DECLARE SECTION;
98 users_id = *(int *)argv[0];
100 EXEC SQL UPDATE users SET fmodtime = SYSDATE, fmodby = :who,
101 fmodwith = :entity WHERE users_id = :users_id;
107 /* Sets the pobox modtime on a user record. The users_id will be in argv[0].
110 int set_pobox_modtime(struct query *q, char *argv[], client *cl)
112 EXEC SQL BEGIN DECLARE SECTION;
115 EXEC SQL END DECLARE SECTION;
119 users_id = *(int *)argv[0];
121 EXEC SQL UPDATE users SET pmodtime = SYSDATE, pmodby = :who,
122 pmodwith = :entity WHERE users_id = :users_id;
128 /* Like set_modtime, but uppercases the name first.
131 int set_uppercase_modtime(struct query *q, char *argv[], client *cl)
133 char *name, *entity, *table;
138 table = table_name[q->rtable];
141 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
142 "modwith = '%s' WHERE name = UPPER('%s')", table, who, entity, name);
143 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
149 /* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
150 * is necessary for add_machine_to_cluster becuase the table that query
151 * operates on is "mcm", not "machine".
154 int set_mach_modtime_by_id(struct query *q, char *argv[], client *cl)
156 EXEC SQL BEGIN DECLARE SECTION;
159 EXEC SQL END DECLARE SECTION;
163 id = *(int *)argv[0];
164 EXEC SQL UPDATE machine SET modtime = SYSDATE, modby = :who,
165 modwith = :entity WHERE mach_id = :id;
171 /* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
172 * is necessary for add_cluster_data and delete_cluster_data becuase the
173 * table that query operates on is "svc", not "cluster".
176 int set_cluster_modtime_by_id(struct query *q, char *argv[], client *cl)
178 EXEC SQL BEGIN DECLARE SECTION;
181 EXEC SQL END DECLARE SECTION;
186 id = *(int *)argv[0];
187 EXEC SQL UPDATE clusters SET modtime = SYSDATE, modby = :who,
188 modwith = :entity WHERE clu_id = :id;
193 /* sets the modtime on the serverhost where the service name is in argv[0]
194 * and the mach_id is in argv[1].
197 int set_serverhost_modtime(struct query *q, char *argv[], client *cl)
199 EXEC SQL BEGIN DECLARE SECTION;
202 EXEC SQL END DECLARE SECTION;
208 id = *(int *)argv[1];
209 EXEC SQL UPDATE serverhosts
210 SET modtime = SYSDATE, modby = :who, modwith = :entity
211 WHERE service = :serv AND mach_id = :id;
216 /* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
217 * directory name is in argv[1].
220 int set_nfsphys_modtime(struct query *q, char *argv[], client *cl)
222 EXEC SQL BEGIN DECLARE SECTION;
225 EXEC SQL END DECLARE SECTION;
230 id = *(int *)argv[0];
232 EXEC SQL UPDATE nfsphys SET modtime = SYSDATE, modby = :who,
233 modwith = :entity WHERE dir = :dir AND mach_id = :id;
238 /* sets the modtime on a filesystem, where argv[0] contains the filesys
242 int set_filesys_modtime(struct query *q, char *argv[], client *cl)
244 EXEC SQL BEGIN DECLARE SECTION;
245 char *label, *entity;
247 extern int _var_phys_id;
248 EXEC SQL END DECLARE SECTION;
254 if (!strcmp(q->shortname, "ufil"))
257 EXEC SQL UPDATE filesys SET modtime = SYSDATE, modby = :who,
258 modwith = :entity, phys_id = :_var_phys_id
259 WHERE label = :label;
264 /* sets the modtime on a zephyr class, where argv[0] contains the class
268 int set_zephyr_modtime(struct query *q, char *argv[], client *cl)
270 EXEC SQL BEGIN DECLARE SECTION;
271 char *class, *entity;
273 EXEC SQL END DECLARE SECTION;
280 EXEC SQL UPDATE zephyr SET modtime = SYSDATE, modby = :who,
281 modwith = :entity WHERE class = :class;
287 /* fixes the modby field. This will be the second to last thing in the
288 * argv, the argv length is determined from the query structure. It is
289 * passed as a pointer to an integer. This will either turn it into a
290 * username, or # + the users_id.
292 int followup_fix_modby(struct query *q, struct save_queue *sq,
293 struct validate *v, int (*action)(int, char *[], void *),
294 void *actarg, client *cl)
301 while (sq_get_data(sq, &argv))
305 status = id_to_name(id, USERS_TABLE, &argv[i]);
307 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
308 if (status && status != MR_NO_MATCH)
310 (*action)(q->vcnt, argv, actarg);
311 for (j = 0; j < q->vcnt; j++)
320 /* After retrieving a user account, fix the modby field and signature.
321 * The modby field is the second to last thing in the
322 * argv, the argv length is determined from the query structure. It is
323 * passed as a pointer to an integer. This will either turn it into a
324 * username, or # + the users_id. Only "gua*" queries have a signature,
325 * these are ones with U_END return values. "gub*" queries also use this
326 * routine but don't have a signature.
328 int followup_guax(struct query *q, struct save_queue *sq, struct validate *v,
329 int (*action)(int, char *[], void *), void *actarg,
335 unsigned char sigbuf[512];
338 EXEC SQL BEGIN DECLARE SECTION;
341 char rsig[USERS_SIGNATURE_SIZE];
342 EXEC SQL VAR rsig IS STRING(USERS_SIGNATURE_SIZE);
343 EXEC SQL END DECLARE SECTION;
348 while (sq_get_data(sq, &argv))
352 status = id_to_name(id, USERS_TABLE, &argv[i]);
354 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
355 if (status && status != MR_NO_MATCH)
358 if (q->vcnt == U_END && strlen(argv[U_SIGNATURE]))
360 login = strtrim(argv[U_NAME]);
361 EXEC SQL SELECT signature, sigdate, sigwho
362 INTO :rsig, :timestamp, :who FROM users
363 WHERE login = :login;
367 status = id_to_name(who, STRINGS_TABLE, &kname);
368 si.timestamp = timestamp;
369 si.SigInfoVersion = 0; /* XXXXX this isn't used */
370 kname_parse(si.pname, si.pinst, si.prealm, kname);
372 si.rawsig = (unsigned char *)xstrdup(rsig);
373 GDSS_Recompose(&si, sigbuf);
375 free(argv[U_SIGNATURE]);
376 argv[U_SIGNATURE] = xstrdup(sigbuf);
379 (*action)(q->vcnt, argv, actarg);
380 for (j = 0; j < q->vcnt; j++)
390 ** followup_ausr - add finger and pobox entries, set_user_modtime
393 ** argv[0] - login (add_user)
394 ** argv[3] - last name
395 ** argv[4] - first name
396 ** argv[5] - middle name
400 int followup_ausr(struct query *q, char *argv[], client *cl)
402 EXEC SQL BEGIN DECLARE SECTION;
404 char *login, *entity, *name;
405 char fullname[USERS_FIRST_SIZE + USERS_MIDDLE_SIZE + USERS_LAST_SIZE];
406 EXEC SQL END DECLARE SECTION;
408 char databuf[USERS_LOGIN_SIZE + USERS_CLEARID_SIZE];
409 EXEC SQL BEGIN DECLARE SECTION;
411 int sigwho, timestamp;
412 EXEC SQL END DECLARE SECTION;
417 if (strlen(argv[4]) && strlen(argv[5]))
418 sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
419 else if (strlen(argv[4]))
420 sprintf(fullname, "%s %s", argv[4], argv[3]);
422 sprintf(fullname, "%s", argv[3]);
425 if (q->vcnt == U_END && *argv[U_SIGNATURE])
427 sprintf(databuf, "%s:%s", argv[U_NAME], argv[U_MITID]);
428 /* skip bytes for timestamp & kname */
429 si.rawsig = (unsigned char *) rawsig;
430 status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE], &si);
431 if (strlen(rawsig) > mr_sig_length)
433 com_err(whoami, 0, "GDSS signature would be truncated.");
438 name = kname_unparse(si.pname, si.pinst, si.prealm);
439 status = name_to_id(name, STRINGS_TABLE, &sigwho);
440 if (status == MR_NO_MATCH)
441 sigwho = add_string(name);
444 timestamp = si.timestamp;
447 return gdss2et(status);
461 /* create finger entry, pobox & set modtime on user */
463 EXEC SQL UPDATE users
464 SET modtime = SYSDATE, modby = :who, modwith = :entity,
465 fullname = NVL(:fullname, CHR(0)), affiliation = type,
466 signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp,
467 sigwho = :sigwho, fmodtime = SYSDATE, fmodby = :who,
468 fmodwith = :entity, potype = 'NONE', pmodtime = SYSDATE,
469 pmodby = :who, pmodwith = :entity
470 WHERE login = :login;
472 EXEC SQL UPDATE users
473 SET modtime = SYSDATE, modby = :who, modwith = :entity,
474 fullname = NVL(:fullname, CHR(0)), affiliation = type,
475 fmodtime = SYSDATE, fmodby = :who, fmodwith = :entity,
476 potype = 'NONE', pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity
477 WHERE login = :login;
485 ** followup_uuac - do signature, set_user_modtime
488 ** argv[0] - login (add_user)
489 ** argv[U_SIGNATURE] - sig
493 int followup_uuac(struct query *q, char *argv[], client *cl)
495 EXEC SQL BEGIN DECLARE SECTION;
498 EXEC SQL END DECLARE SECTION;
500 char databuf[USERS_LOGIN_SIZE + USERS_CLEARID_SIZE];
501 EXEC SQL BEGIN DECLARE SECTION;
504 int sigwho, timestamp;
505 EXEC SQL END DECLARE SECTION;
509 id = *(int *)argv[0];
514 if (q->vcnt == U_MODTIME && *argv[U_SIGNATURE + 1])
517 status = id_to_name(id, USERS_TABLE, &login);
518 sprintf(databuf, "%s:%s", login, argv[U_MITID + 1]);
520 /* skip bytes for timestamp & kname */
521 si.rawsig = (unsigned char *) rawsig;
522 status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE + 1],
524 if (strlen(rawsig) > mr_sig_length)
526 com_err(whoami, 0, "GDSS signature would be truncated.");
531 name = kname_unparse(si.pname, si.pinst, si.prealm);
532 status = name_to_id(name, STRINGS_TABLE, &sigwho);
533 if (status == MR_NO_MATCH)
534 sigwho = add_string(name);
537 timestamp = si.timestamp;
540 return gdss2et(status);
550 /* create finger entry, pobox & set modtime on user */
553 EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity,
554 signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp, sigwho = :sigwho
555 WHERE users_id = :id;
557 EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity
558 WHERE users_id = :id;
564 /* followup_gpob: fixes argv[2] based on the IDs currently there and the
565 * type in argv[1]. Then completes the upcall to the user.
567 * argv[2] is of the form "123:234" where the first integer is the
568 * machine ID if it is a pop box or filesys ID if it is an imap box,
569 * and the second is the string ID if it is an SMTP box. argv[1]
570 * should be "POP", "SMTP", "IMAP", or "NONE". Boxes of type NONE are
574 int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
575 int (*action)(int, char *[], void *), void *actarg,
580 int mid, sid, status, i;
583 while (sq_get_data(sq, &argv))
585 mr_trim_args(2, argv);
587 p = strchr(argv[2], ':');
592 if (!strcmp(ptype, "POP"))
594 status = id_to_name(mid, MACHINE_TABLE, &argv[2]);
595 if (status == MR_NO_MATCH)
598 else if (!strcmp(ptype, "SMTP"))
600 status = id_to_name(sid, STRINGS_TABLE, &argv[2]);
601 if (status == MR_NO_MATCH)
604 else if (!strcmp(ptype, "IMAP"))
606 status = id_to_name(mid, FILESYS_TABLE, &argv[2]);
607 if (status == MR_NO_MATCH)
610 else /* ptype == "NONE" */
615 if (!strcmp(q->shortname, "gpob"))
619 status = id_to_name(sid, USERS_TABLE, &argv[4]);
621 status = id_to_name(-sid, STRINGS_TABLE, &argv[4]);
623 if (status && status != MR_NO_MATCH)
626 (*action)(q->vcnt, argv, actarg);
628 /* free saved data */
629 for (i = 0; i < q->vcnt; i++)
639 /* followup_gsnt: fix the ace_name in argv[7]. argv[6] will contain the
640 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[7] into the
641 * proper name based on the type, and repace that string in the argv.
642 * Also fixes the modby field by called followup_fix_modby.
645 int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
646 int (*action)(int, char *[], void *), void *actarg,
650 int id, i, idx, status;
654 while (sq_get_data(sq, &argv))
656 mr_trim_args(q->vcnt, argv);
658 id = atoi(argv[i = q->vcnt - 2]);
660 status = id_to_name(id, USERS_TABLE, &argv[i]);
662 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
663 if (status && status != MR_NO_MATCH)
666 id = atoi(argv[idx]);
667 type = argv[idx - 1];
669 if (!strcmp(type, "LIST"))
670 status = id_to_name(id, LIST_TABLE, &argv[idx]);
671 else if (!strcmp(type, "USER"))
672 status = id_to_name(id, USERS_TABLE, &argv[idx]);
673 else if (!strcmp(type, "KERBEROS"))
674 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
675 else if (!strcmp(type, "NONE"))
679 argv[idx] = xstrdup("NONE");
685 argv[idx] = xstrdup("???");
687 if (status && status != MR_NO_MATCH)
691 (*action)(q->vcnt, argv, actarg);
693 /* free saved data */
694 for (i = 0; i < q->vcnt; i++)
704 /* followup_ghst: fix the ace_name in argv[12]. argv[11] will contain the
705 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[12] into the
706 * proper name based on the type, and repace that string in the argv.
707 * Also fixes the modby field by called followup_fix_modby.
710 int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
711 int (*action)(int, char *[], void *), void *actarg,
715 int id, i, idx, status;
717 while (sq_get_data(sq, &argv))
719 mr_trim_args(q->vcnt, argv);
721 id = atoi(argv[i = q->vcnt - 2]);
723 status = id_to_name(id, USERS_TABLE, &argv[i]);
725 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
726 if (status && status != MR_NO_MATCH)
730 status = id_to_name(id, STRINGS_TABLE, &argv[13]);
734 status = id_to_name(id, STRINGS_TABLE, &argv[14]);
739 status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
741 status = id_to_name(id, USERS_TABLE, &argv[16]);
742 if (status && status != MR_NO_MATCH)
746 id = atoi(argv[idx]);
747 type = strtrim(argv[idx - 1]);
749 if (!strcmp(type, "LIST"))
750 status = id_to_name(id, LIST_TABLE, &argv[idx]);
751 else if (!strcmp(type, "USER"))
752 status = id_to_name(id, USERS_TABLE, &argv[idx]);
753 else if (!strcmp(type, "KERBEROS"))
754 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
755 else if (!strcmp(type, "NONE"))
759 argv[idx] = xstrdup("NONE");
765 argv[idx] = xstrdup("???");
767 if (status && status != MR_NO_MATCH)
771 (*action)(q->vcnt, argv, actarg);
773 /* free saved data */
774 for (i = 0; i < q->vcnt; i++)
784 /* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
785 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
786 * proper name based on the type, and repace that string in the argv.
787 * Also fixes the modby field by called followup_fix_modby.
790 int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
791 int (*action)(int, char *[], void *), void *actarg,
795 int id, i, idx, status;
798 if (!strcmp(q->shortname, "gsin"))
801 while (sq_get_data(sq, &argv))
803 mr_trim_args(q->vcnt, argv);
805 id = atoi(argv[i = q->vcnt - 2]);
807 status = id_to_name(id, USERS_TABLE, &argv[i]);
809 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
810 if (status && status != MR_NO_MATCH)
813 id = atoi(argv[idx]);
814 type = argv[idx - 1];
816 if (!strcmp(type, "LIST"))
817 status = id_to_name(id, LIST_TABLE, &argv[idx]);
818 else if (!strcmp(type, "USER"))
819 status = id_to_name(id, USERS_TABLE, &argv[idx]);
820 else if (!strcmp(type, "KERBEROS"))
821 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
822 else if (!strcmp(type, "NONE"))
826 argv[idx] = xstrdup("NONE");
832 argv[idx] = xstrdup("???");
834 if (status && status != MR_NO_MATCH)
837 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
839 argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
840 strcpy(argv[6], UNIQUE_GID);
844 (*action)(q->vcnt, argv, actarg);
846 /* free saved data */
847 for (i = 0; i < q->vcnt; i++)
856 int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
857 int (*action)(int, char *[], void *), void *actarg,
863 while (sq_get_data(sq, &argv))
865 mr_trim_args(q->vcnt, argv);
867 id = atoi(argv[PRINTSERVER_OWNER_NAME]);
868 type = argv[PRINTSERVER_OWNER_TYPE];
870 if (!strcmp(type, "LIST"))
871 status = id_to_name(id, LIST_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
872 else if (!strcmp(type, "USER"))
873 status = id_to_name(id, USERS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
874 else if (!strcmp(type, "KERBEROS"))
875 status = id_to_name(id, STRINGS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
879 free(argv[PRINTSERVER_OWNER_NAME]);
880 argv[PRINTSERVER_OWNER_NAME] = xstrdup("NONE");
882 if (status && status != MR_NO_MATCH)
886 return followup_fix_modby(q, sq, v, action, actarg, cl);
890 /* followup_gqot: Fix the entity name, directory name & modby fields
891 * argv[0] = filsys_id
893 * argv[2] = entity_id
894 * argv[3] = ascii(quota)
897 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
898 int (*action)(int, char *[], void *), void *actarg,
903 EXEC SQL BEGIN DECLARE SECTION;
906 EXEC SQL END DECLARE SECTION;
909 if (!strcmp(q->name, "get_quota") ||
910 !strcmp(q->name, "get_quota_by_filesys"))
914 while (sq_get_data(sq, &argv))
921 status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
925 status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
929 argv[2] = xstrdup("system:anyuser");
933 argv[2] = xmalloc(8);
934 sprintf(argv[2], "%d", id);
937 id = atoi(argv[idx]);
939 argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
945 EXEC SQL SELECT name INTO :name FROM filesys
946 WHERE label = :label;
950 EXEC SQL SELECT dir INTO :name FROM nfsphys
951 WHERE nfsphys_id = :id;
953 if (sqlca.sqlerrd[2] != 1)
954 sprintf(argv[idx], "#%d", id);
956 id = atoi(argv[idx + 3]);
958 status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
960 status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
961 if (status && status != MR_NO_MATCH)
963 (*action)(q->vcnt, argv, actarg);
964 for (j = 0; j < q->vcnt; j++)
973 /* followup_aqot: Add allocation to nfsphys after creating quota.
974 * argv[0] = filsys_id
975 * argv[1] = type if "add_quota" or "update_quota"
977 * argv[3 or 2] = ascii(quota)
980 int followup_aqot(struct query *q, char *argv[], client *cl)
982 EXEC SQL BEGIN DECLARE SECTION;
983 int quota, id, fs, who, physid, table;
984 char *entity, *qtype, *tname;
985 EXEC SQL END DECLARE SECTION;
991 tname = table_name[table];
992 fs = *(int *)argv[0];
993 EXEC SQL SELECT phys_id INTO :physid FROM filesys
994 WHERE filsys_id = :fs;
998 if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
1001 id = *(int *)argv[2];
1002 quota = atoi(argv[3]);
1003 sprintf(incr_qual, "q.filsys_id = %d", fs);
1008 id = *(int *)argv[1];
1009 quota = atoi(argv[2]);
1010 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
1011 "q.entity_id = %d", fs, qtype, id);
1014 /* quota case of incremental_{before|after} only looks at slot 1 */
1015 incr_argv[1] = qtype;
1017 /* Follows one of many possible gross hacks to fix these particular
1018 * conflicts between what is possible in the query table and what
1019 * is possible in SQL.
1021 if (q->type == APPEND)
1023 incremental_clear_before();
1024 EXEC SQL INSERT INTO quota
1025 (filsys_id, type, entity_id, quota, phys_id)
1026 VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
1027 incremental_after(table, incr_qual, incr_argv);
1031 incremental_before(table, incr_qual, incr_argv);
1032 EXEC SQL UPDATE quota SET quota = :quota
1033 WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
1034 status = mr_errcode;
1035 incremental_after(table, incr_qual, incr_argv);
1040 flush_name(argv[0], table);
1041 if (q->type == APPEND)
1043 EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
1044 WHERE table_name = :tname;
1048 EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
1049 WHERE table_name = :tname;
1052 /* Proceed with original followup */
1053 who = cl->client_id;
1054 entity = cl->entity;
1056 EXEC SQL UPDATE quota
1057 SET modtime = SYSDATE, modby = :who, modwith = :entity
1058 WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1059 EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
1060 WHERE nfsphys_id = :physid;
1067 /* Necessitated by the requirement of a correlation name by the incremental
1068 * routines, since query table deletes don't provide one.
1070 int followup_dqot(struct query *q, char **argv, client *cl)
1075 EXEC SQL BEGIN DECLARE SECTION;
1076 char incr_qual[80], *tname;
1077 EXEC SQL END DECLARE SECTION;
1080 tname = table_name[table];
1081 fs = *(int *)argv[0];
1082 if (!strcmp(q->shortname, "dqot"))
1085 id = *(int *)argv[2];
1090 id = *(int *)argv[1];
1092 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
1095 /* quota case of incremental_{before|after} only looks at slot 1 */
1096 incr_argv[1] = qtype;
1098 incremental_before(table, incr_qual, incr_argv);
1099 EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
1100 AND q.entity_id = :id;
1101 incremental_clear_after();
1105 flush_name(argv[0], table);
1107 EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
1108 WHERE table_name = :tname;
1115 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
1116 int (*action)(int, char *[], void *), void *actarg,
1122 while (sq_get_data(sq, &argv))
1124 mr_trim_args(q->vcnt, argv);
1126 id = atoi(argv[i = q->vcnt - 2]);
1128 status = id_to_name(id, USERS_TABLE, &argv[i]);
1130 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1131 if (status && status != MR_NO_MATCH)
1134 for (i = 1; i < 8; i += 2)
1136 id = atoi(argv[i + 1]);
1137 if (!strcmp(argv[i], "LIST"))
1138 status = id_to_name(id, LIST_TABLE, &argv[i + 1]);
1139 else if (!strcmp(argv[i], "USER"))
1140 status = id_to_name(id, USERS_TABLE, &argv[i + 1]);
1141 else if (!strcmp(argv[i], "KERBEROS"))
1142 status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]);
1143 else if (!strcmp(argv[i], "NONE"))
1147 argv[i + 1] = xstrdup("NONE");
1153 argv[i + 1] = xstrdup("???");
1155 if (status && status != MR_NO_MATCH)
1160 (*action)(q->vcnt, argv, actarg);
1162 /* free saved data */
1163 for (i = 0; i < q->vcnt; i++)
1175 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
1176 int (*action)(int, char *[], void *), void *actarg,
1182 while (sq_get_data(sq, &argv))
1184 mr_trim_args(q->vcnt, argv);
1188 status = id_to_name(id, USERS_TABLE, &argv[4]);
1190 status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
1191 if (status && status != MR_NO_MATCH)
1195 if (!strcmp(argv[1], "LIST"))
1196 status = id_to_name(id, LIST_TABLE, &argv[2]);
1197 else if (!strcmp(argv[1], "USER"))
1198 status = id_to_name(id, USERS_TABLE, &argv[2]);
1199 else if (!strcmp(argv[1], "KERBEROS"))
1200 status = id_to_name(id, STRINGS_TABLE, &argv[2]);
1201 else if (!strcmp(argv[1], "NONE"))
1205 argv[2] = xstrdup("NONE");
1211 argv[2] = xstrdup("???");
1213 if (status && status != MR_NO_MATCH)
1217 (*action)(q->vcnt, argv, actarg);
1219 /* free saved data */
1220 for (i = 0; i < q->vcnt; i++)
1229 int _sdl_followup(struct query *q, char *argv[], client *cl)
1232 EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
1234 EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
1240 int trigger_dcm(struct query *q, char *argv[], client *cl)
1243 char prog[MAXPATHLEN];
1245 sprintf(prog, "%s/startdcm", BIN_DIR);
1250 execl(prog, "startdcm", 0);