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 static void hex_dump(unsigned char *p);
37 EXEC SQL WHENEVER SQLERROR DO dbmserr();
40 /* FOLLOWUP ROUTINES */
42 /* generic set_modtime routine. This takes the table id from the query,
43 * and will update the modtime, modby, and modwho fields in the entry in
44 * the table whose name field matches argv[0].
47 int set_modtime(struct query *q, char *argv[], client *cl)
49 char *name, *entity, *table;
54 table = table_name[q->rtable];
57 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
58 "modwith = '%s' WHERE name = '%s'", table, who, entity, name);
59 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
64 /* generic set_modtime_by_id routine. This takes the table id from
65 * the query, and the id name from the validate record,
66 * and will update the modtime, modby, and modwho fields in the entry in
67 * the table whose id matches argv[0].
70 int set_modtime_by_id(struct query *q, char *argv[], client *cl)
72 char *entity, *table, *id_name;
77 table = table_name[q->rtable];
78 id_name = q->validate->object_id;
81 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
82 "modwith = '%s' WHERE %s = %d", table, who, entity, id_name, id);
83 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
88 /* Sets the finger modtime on a user record. The users_id will be in argv[0].
91 int set_finger_modtime(struct query *q, char *argv[], client *cl)
93 EXEC SQL BEGIN DECLARE SECTION;
96 EXEC SQL END DECLARE SECTION;
100 users_id = *(int *)argv[0];
102 EXEC SQL UPDATE users SET fmodtime = SYSDATE, fmodby = :who,
103 fmodwith = :entity WHERE users_id = :users_id;
109 /* Sets the pobox modtime on a user record. The users_id will be in argv[0].
112 int set_pobox_modtime(struct query *q, char *argv[], client *cl)
114 EXEC SQL BEGIN DECLARE SECTION;
117 EXEC SQL END DECLARE SECTION;
121 users_id = *(int *)argv[0];
123 EXEC SQL UPDATE users SET pmodtime = SYSDATE, pmodby = :who,
124 pmodwith = :entity WHERE users_id = :users_id;
130 /* Like set_modtime, but uppercases the name first.
133 int set_uppercase_modtime(struct query *q, char *argv[], client *cl)
135 char *name, *entity, *table;
140 table = table_name[q->rtable];
143 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
144 "modwith = '%s' WHERE name = UPPER('%s')", table, who, entity, name);
145 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
151 /* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
152 * is necessary for add_machine_to_cluster becuase the table that query
153 * operates on is "mcm", not "machine".
156 int set_mach_modtime_by_id(struct query *q, char *argv[], client *cl)
158 EXEC SQL BEGIN DECLARE SECTION;
161 EXEC SQL END DECLARE SECTION;
165 id = *(int *)argv[0];
166 EXEC SQL UPDATE machine SET modtime = SYSDATE, modby = :who,
167 modwith = :entity WHERE mach_id = :id;
173 /* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
174 * is necessary for add_cluster_data and delete_cluster_data becuase the
175 * table that query operates on is "svc", not "cluster".
178 int set_cluster_modtime_by_id(struct query *q, char *argv[], client *cl)
180 EXEC SQL BEGIN DECLARE SECTION;
183 EXEC SQL END DECLARE SECTION;
188 id = *(int *)argv[0];
189 EXEC SQL UPDATE clusters SET modtime = SYSDATE, modby = :who,
190 modwith = :entity WHERE clu_id = :id;
195 /* sets the modtime on the serverhost where the service name is in argv[0]
196 * and the mach_id is in argv[1].
199 int set_serverhost_modtime(struct query *q, char *argv[], client *cl)
201 EXEC SQL BEGIN DECLARE SECTION;
204 EXEC SQL END DECLARE SECTION;
210 id = *(int *)argv[1];
211 EXEC SQL UPDATE serverhosts
212 SET modtime = SYSDATE, modby = :who, modwith = :entity
213 WHERE service = :serv AND mach_id = :id;
218 /* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
219 * directory name is in argv[1].
222 int set_nfsphys_modtime(struct query *q, char *argv[], client *cl)
224 EXEC SQL BEGIN DECLARE SECTION;
227 EXEC SQL END DECLARE SECTION;
232 id = *(int *)argv[0];
234 EXEC SQL UPDATE nfsphys SET modtime = SYSDATE, modby = :who,
235 modwith = :entity WHERE dir = :dir AND mach_id = :id;
240 /* sets the modtime on a filesystem, where argv[0] contains the filesys
244 int set_filesys_modtime(struct query *q, char *argv[], client *cl)
246 EXEC SQL BEGIN DECLARE SECTION;
247 char *label, *entity;
249 extern int _var_phys_id;
250 EXEC SQL END DECLARE SECTION;
256 if (!strcmp(q->shortname, "ufil"))
259 EXEC SQL UPDATE filesys SET modtime = SYSDATE, modby = :who,
260 modwith = :entity, phys_id = :_var_phys_id
261 WHERE label = :label;
266 /* sets the modtime on a zephyr class, where argv[0] contains the class
270 int set_zephyr_modtime(struct query *q, char *argv[], client *cl)
272 EXEC SQL BEGIN DECLARE SECTION;
273 char *class, *entity;
275 EXEC SQL END DECLARE SECTION;
282 EXEC SQL UPDATE zephyr SET modtime = SYSDATE, modby = :who,
283 modwith = :entity WHERE class = :class;
289 /* fixes the modby field. This will be the second to last thing in the
290 * argv, the argv length is determined from the query structure. It is
291 * passed as a pointer to an integer. This will either turn it into a
292 * username, or # + the users_id.
294 int followup_fix_modby(struct query *q, struct save_queue *sq,
295 struct validate *v, int (*action)(int, char *[], void *),
296 void *actarg, client *cl)
303 while (sq_get_data(sq, &argv))
307 status = id_to_name(id, USERS_TABLE, &argv[i]);
309 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
310 if (status && status != MR_NO_MATCH)
312 (*action)(q->vcnt, argv, actarg);
313 for (j = 0; j < q->vcnt; j++)
322 /* After retrieving a user account, fix the modby field and signature.
323 * The modby field is the second to last thing in the
324 * argv, the argv length is determined from the query structure. It is
325 * passed as a pointer to an integer. This will either turn it into a
326 * username, or # + the users_id. Only "gua*" queries have a signature,
327 * these are ones with U_END return values. "gub*" queries also use this
328 * routine but don't have a signature.
330 int followup_guax(struct query *q, struct save_queue *sq, struct validate *v,
331 int (*action)(int, char *[], void *), void *actarg,
337 unsigned char sigbuf[256];
340 EXEC SQL BEGIN DECLARE SECTION;
344 EXEC SQL VAR rsig IS STRING(256);
345 EXEC SQL END DECLARE SECTION;
350 while (sq_get_data(sq, &argv))
354 status = id_to_name(id, USERS_TABLE, &argv[i]);
356 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
357 if (status && status != MR_NO_MATCH)
360 if (q->vcnt == U_END && strlen(argv[U_SIGNATURE]))
362 login = strtrim(argv[U_NAME]);
363 EXEC SQL SELECT signature, sigdate, sigwho
364 INTO :rsig, :timestamp, :who FROM users
365 WHERE login = :login;
369 status = id_to_name(who, STRINGS_TABLE, &kname);
370 si.timestamp = timestamp;
371 si.SigInfoVersion = 0; /* XXXXX this isn't used */
372 kname_parse(si.pname, si.pinst, si.prealm, kname);
374 si.rawsig = (unsigned char *)strdup(rsig);
375 GDSS_Recompose(&si, sigbuf);
377 free(argv[U_SIGNATURE]);
378 argv[U_SIGNATURE] = strdup(sigbuf);
381 (*action)(q->vcnt, argv, actarg);
382 for (j = 0; j < q->vcnt; j++)
392 ** followup_ausr - add finger and pobox entries, set_user_modtime
395 ** argv[0] - login (add_user)
396 ** argv[3] - last name
397 ** argv[4] - first name
398 ** argv[5] - middle name
402 int followup_ausr(struct query *q, char *argv[], client *cl)
404 EXEC SQL BEGIN DECLARE SECTION;
406 char *login, *entity, *name;
408 EXEC SQL END DECLARE SECTION;
411 EXEC SQL BEGIN DECLARE SECTION;
413 int sigwho, timestamp;
414 EXEC SQL END DECLARE SECTION;
419 if (strlen(argv[4]) && strlen(argv[5]))
420 sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
421 else if (strlen(argv[4]))
422 sprintf(fullname, "%s %s", argv[4], argv[3]);
424 sprintf(fullname, "%s", argv[3]);
427 if (q->vcnt == U_END && *argv[U_SIGNATURE])
429 sprintf(databuf, "%s:%s", argv[U_NAME], argv[U_MITID]);
430 /* skip bytes for timestamp & kname */
431 si.rawsig = (unsigned char *) rawsig;
432 status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE], &si);
433 if (strlen(rawsig) > mr_sig_length)
435 com_err(whoami, 0, "GDSS signature would be truncated.");
440 name = kname_unparse(si.pname, si.pinst, si.prealm);
441 status = name_to_id(name, STRINGS_TABLE, &sigwho);
442 if (status == MR_NO_MATCH)
443 sigwho = add_string(name);
446 timestamp = si.timestamp;
449 return gdss2et(status);
463 /* create finger entry, pobox & set modtime on user */
465 EXEC SQL UPDATE users
466 SET modtime = SYSDATE, modby = :who, modwith = :entity,
467 fullname = NVL(:fullname, CHR(0)), affiliation = type,
468 signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp,
469 sigwho = :sigwho, fmodtime = SYSDATE, fmodby = :who,
470 fmodwith = :entity, potype = 'NONE', pmodtime = SYSDATE,
471 pmodby = :who, pmodwith = :entity
472 WHERE login = :login;
474 EXEC SQL UPDATE users
475 SET modtime = SYSDATE, modby = :who, modwith = :entity,
476 fullname = NVL(:fullname, CHR(0)), affiliation = type,
477 fmodtime = SYSDATE, fmodby = :who, fmodwith = :entity,
478 potype = 'NONE', pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity
479 WHERE login = :login;
487 ** followup_uuac - do signature, set_user_modtime
490 ** argv[0] - login (add_user)
491 ** argv[U_SIGNATURE] - sig
495 int followup_uuac(struct query *q, char *argv[], client *cl)
497 EXEC SQL BEGIN DECLARE SECTION;
500 EXEC SQL END DECLARE SECTION;
503 EXEC SQL BEGIN DECLARE SECTION;
506 int sigwho, timestamp;
507 EXEC SQL END DECLARE SECTION;
511 id = *(int *)argv[0];
516 if (q->vcnt == U_MODTIME && *argv[U_SIGNATURE + 1])
519 status = id_to_name(id, USERS_TABLE, &login);
520 sprintf(databuf, "%s:%s", login, argv[U_MITID + 1]);
522 /* skip bytes for timestamp & kname */
523 si.rawsig = (unsigned char *) rawsig;
524 status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE + 1],
526 if (strlen(rawsig) > mr_sig_length)
528 com_err(whoami, 0, "GDSS signature would be truncated.");
533 name = kname_unparse(si.pname, si.pinst, si.prealm);
534 status = name_to_id(name, STRINGS_TABLE, &sigwho);
535 if (status == MR_NO_MATCH)
536 sigwho = add_string(name);
539 timestamp = si.timestamp;
542 return gdss2et(status);
552 /* create finger entry, pobox & set modtime on user */
555 EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity,
556 signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp, sigwho = :sigwho
557 WHERE users_id = :id;
559 EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity
560 WHERE users_id = :id;
565 /* followup_gpob: fixes argv[2] based on the IDs currently there and the
566 * type in argv[1]. Then completes the upcall to the user.
568 * argv[2] is of the form "123:234" where the first integer is the machine
569 * ID if it is a pop box, and the second is the string ID if it is an SMTP
570 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
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 /* ptype == "NONE" */
609 if (!strcmp(q->shortname, "gpob"))
613 status = id_to_name(sid, USERS_TABLE, &argv[4]);
615 status = id_to_name(-sid, STRINGS_TABLE, &argv[4]);
617 if (status && status != MR_NO_MATCH)
620 (*action)(q->vcnt, argv, actarg);
622 /* free saved data */
623 for (i = 0; i < q->vcnt; i++)
633 /* followup_gsnt: fix the ace_name in argv[7]. argv[6] will contain the
634 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[7] into the
635 * proper name based on the type, and repace that string in the argv.
636 * Also fixes the modby field by called followup_fix_modby.
639 int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
640 int (*action)(int, char *[], void *), void *actarg,
644 int id, i, idx, status;
648 while (sq_get_data(sq, &argv))
650 mr_trim_args(q->vcnt, argv);
652 id = atoi(argv[i = q->vcnt - 2]);
654 status = id_to_name(id, USERS_TABLE, &argv[i]);
656 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
657 if (status && status != MR_NO_MATCH)
660 id = atoi(argv[idx]);
661 type = argv[idx - 1];
663 if (!strcmp(type, "LIST"))
664 status = id_to_name(id, LIST_TABLE, &argv[idx]);
665 else if (!strcmp(type, "USER"))
666 status = id_to_name(id, USERS_TABLE, &argv[idx]);
667 else if (!strcmp(type, "KERBEROS"))
668 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
669 else if (!strcmp(type, "NONE"))
673 argv[idx] = strdup("NONE");
679 argv[idx] = strdup("???");
681 if (status && status != MR_NO_MATCH)
685 (*action)(q->vcnt, argv, actarg);
687 /* free saved data */
688 for (i = 0; i < q->vcnt; i++)
698 /* followup_ghst: fix the ace_name in argv[12]. argv[11] will contain the
699 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[12] into the
700 * proper name based on the type, and repace that string in the argv.
701 * Also fixes the modby field by called followup_fix_modby.
704 int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
705 int (*action)(int, char *[], void *), void *actarg,
709 int id, i, idx, status;
711 while (sq_get_data(sq, &argv))
713 mr_trim_args(q->vcnt, argv);
715 id = atoi(argv[i = q->vcnt - 2]);
717 status = id_to_name(id, USERS_TABLE, &argv[i]);
719 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
720 if (status && status != MR_NO_MATCH)
724 status = id_to_name(id, STRINGS_TABLE, &argv[13]);
728 status = id_to_name(id, STRINGS_TABLE, &argv[14]);
733 status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
735 status = id_to_name(id, USERS_TABLE, &argv[16]);
736 if (status && status != MR_NO_MATCH)
740 id = atoi(argv[idx]);
741 type = strtrim(argv[idx - 1]);
743 if (!strcmp(type, "LIST"))
744 status = id_to_name(id, LIST_TABLE, &argv[idx]);
745 else if (!strcmp(type, "USER"))
746 status = id_to_name(id, USERS_TABLE, &argv[idx]);
747 else if (!strcmp(type, "KERBEROS"))
748 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
749 else if (!strcmp(type, "NONE"))
753 argv[idx] = strdup("NONE");
759 argv[idx] = strdup("???");
761 if (status && status != MR_NO_MATCH)
765 (*action)(q->vcnt, argv, actarg);
767 /* free saved data */
768 for (i = 0; i < q->vcnt; i++)
778 /* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
779 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
780 * proper name based on the type, and repace that string in the argv.
781 * Also fixes the modby field by called followup_fix_modby.
784 int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
785 int (*action)(int, char *[], void *), void *actarg,
789 int id, i, idx, status;
792 if (!strcmp(q->shortname, "gsin"))
795 while (sq_get_data(sq, &argv))
797 mr_trim_args(q->vcnt, argv);
799 id = atoi(argv[i = q->vcnt - 2]);
801 status = id_to_name(id, USERS_TABLE, &argv[i]);
803 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
804 if (status && status != MR_NO_MATCH)
807 id = atoi(argv[idx]);
808 type = argv[idx - 1];
810 if (!strcmp(type, "LIST"))
811 status = id_to_name(id, LIST_TABLE, &argv[idx]);
812 else if (!strcmp(type, "USER"))
813 status = id_to_name(id, USERS_TABLE, &argv[idx]);
814 else if (!strcmp(type, "KERBEROS"))
815 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
816 else if (!strcmp(type, "NONE"))
820 argv[idx] = strdup("NONE");
826 argv[idx] = strdup("???");
828 if (status && status != MR_NO_MATCH)
831 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
833 argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
834 strcpy(argv[6], UNIQUE_GID);
838 (*action)(q->vcnt, argv, actarg);
840 /* free saved data */
841 for (i = 0; i < q->vcnt; i++)
851 /* followup_gqot: Fix the entity name, directory name & modby fields
852 * argv[0] = filsys_id
854 * argv[2] = entity_id
855 * argv[3] = ascii(quota)
858 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
859 int (*action)(int, char *[], void *), void *actarg,
864 EXEC SQL BEGIN DECLARE SECTION;
867 EXEC SQL END DECLARE SECTION;
870 if (!strcmp(q->name, "get_quota") ||
871 !strcmp(q->name, "get_quota_by_filesys"))
875 while (sq_get_data(sq, &argv))
882 status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
886 status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
890 argv[2] = strdup("system:anyuser");
895 sprintf(argv[2], "%d", id);
898 id = atoi(argv[idx]);
900 argv[idx] = malloc(256);
902 memset(name, 0, 256);
906 EXEC SQL SELECT name INTO :name FROM filesys
907 WHERE label = :label;
911 EXEC SQL SELECT dir INTO :name FROM nfsphys
912 WHERE nfsphys_id = :id;
914 if (sqlca.sqlerrd[2] != 1)
915 sprintf(argv[idx], "#%d", id);
917 id = atoi(argv[idx + 3]);
919 status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
921 status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
922 if (status && status != MR_NO_MATCH)
924 (*action)(q->vcnt, argv, actarg);
925 for (j = 0; j < q->vcnt; j++)
934 /* followup_aqot: Add allocation to nfsphys after creating quota.
935 * argv[0] = filsys_id
936 * argv[1] = type if "add_quota" or "update_quota"
938 * argv[3 or 2] = ascii(quota)
941 int followup_aqot(struct query *q, char *argv[], client *cl)
943 EXEC SQL BEGIN DECLARE SECTION;
944 int quota, id, fs, who, physid, table;
945 char *entity, *qtype, *tname;
946 EXEC SQL END DECLARE SECTION;
952 tname = table_name[table];
953 fs = *(int *)argv[0];
954 EXEC SQL SELECT phys_id INTO :physid FROM filesys
955 WHERE filsys_id = :fs;
959 if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
962 id = *(int *)argv[2];
963 quota = atoi(argv[3]);
964 sprintf(incr_qual, "q.filsys_id = %d", fs);
969 id = *(int *)argv[1];
970 quota = atoi(argv[2]);
971 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
972 "q.entity_id = %d", fs, qtype, id);
975 /* quota case of incremental_{before|after} only looks at slot 1 */
976 incr_argv[1] = qtype;
978 /* Follows one of many possible gross hacks to fix these particular
979 * conflicts between what is possible in the query table and what
980 * is possible in SQL.
982 if (q->type == APPEND)
984 incremental_clear_before();
985 EXEC SQL INSERT INTO quota
986 (filsys_id, type, entity_id, quota, phys_id)
987 VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
988 incremental_after(table, incr_qual, incr_argv);
992 incremental_before(table, incr_qual, incr_argv);
993 EXEC SQL UPDATE quota SET quota = :quota
994 WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
996 incremental_after(table, incr_qual, incr_argv);
1001 flush_name(argv[0], table);
1002 if (q->type == APPEND)
1004 EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
1005 WHERE table_name = :tname;
1009 EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
1010 WHERE table_name = :tname;
1013 /* Proceed with original followup */
1014 who = cl->client_id;
1015 entity = cl->entity;
1017 EXEC SQL UPDATE quota
1018 SET modtime = SYSDATE, modby = :who, modwith = :entity
1019 WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1020 EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
1021 WHERE nfsphys_id = :physid;
1028 /* Necessitated by the requirement of a correlation name by the incremental
1029 * routines, since query table deletes don't provide one.
1031 int followup_dqot(struct query *q, char **argv, client *cl)
1036 EXEC SQL BEGIN DECLARE SECTION;
1037 char incr_qual[80], *tname;
1038 EXEC SQL END DECLARE SECTION;
1041 tname = table_name[table];
1042 fs = *(int *)argv[0];
1043 if (!strcmp(q->shortname, "dqot"))
1046 id = *(int *)argv[2];
1051 id = *(int *)argv[1];
1053 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
1056 /* quota case of incremental_{before|after} only looks at slot 1 */
1057 incr_argv[1] = qtype;
1059 incremental_before(table, incr_qual, incr_argv);
1060 EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
1061 AND q.entity_id = :id;
1062 incremental_clear_after();
1066 flush_name(argv[0], table);
1068 EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
1069 WHERE table_name = :tname;
1074 int followup_gpce(struct query *q, struct save_queue *sq, struct validate *v,
1075 int (*action)(int, char *[], void *), void *actarg,
1083 while (sq_get_data(sq, &argv))
1085 id = atoi(argv[PCAP_QSERVER]);
1086 status = id_to_name(id, MACHINE_TABLE, &argv[PCAP_QSERVER]);
1091 status = id_to_name(id, USERS_TABLE, &argv[i]);
1093 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1094 if (status && status != MR_NO_MATCH)
1096 (*action)(q->vcnt, argv, actarg);
1097 for (j = 0; j < q->vcnt; j++)
1109 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
1110 int (*action)(int, char *[], void *), void *actarg,
1116 while (sq_get_data(sq, &argv))
1118 mr_trim_args(q->vcnt, argv);
1120 id = atoi(argv[i = q->vcnt - 2]);
1122 status = id_to_name(id, USERS_TABLE, &argv[i]);
1124 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1125 if (status && status != MR_NO_MATCH)
1128 for (i = 1; i < 8; i += 2)
1130 id = atoi(argv[i + 1]);
1131 if (!strcmp(argv[i], "LIST"))
1132 status = id_to_name(id, LIST_TABLE, &argv[i + 1]);
1133 else if (!strcmp(argv[i], "USER"))
1134 status = id_to_name(id, USERS_TABLE, &argv[i + 1]);
1135 else if (!strcmp(argv[i], "KERBEROS"))
1136 status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]);
1137 else if (!strcmp(argv[i], "NONE"))
1141 argv[i + 1] = strdup("NONE");
1147 argv[i + 1] = strdup("???");
1149 if (status && status != MR_NO_MATCH)
1154 (*action)(q->vcnt, argv, actarg);
1156 /* free saved data */
1157 for (i = 0; i < q->vcnt; i++)
1169 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
1170 int (*action)(int, char *[], void *), void *actarg,
1176 while (sq_get_data(sq, &argv))
1178 mr_trim_args(q->vcnt, argv);
1182 status = id_to_name(id, USERS_TABLE, &argv[4]);
1184 status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
1185 if (status && status != MR_NO_MATCH)
1189 if (!strcmp(argv[1], "LIST"))
1190 status = id_to_name(id, LIST_TABLE, &argv[2]);
1191 else if (!strcmp(argv[1], "USER"))
1192 status = id_to_name(id, USERS_TABLE, &argv[2]);
1193 else if (!strcmp(argv[1], "KERBEROS"))
1194 status = id_to_name(id, STRINGS_TABLE, &argv[2]);
1195 else if (!strcmp(argv[1], "NONE"))
1199 argv[2] = strdup("NONE");
1205 argv[2] = strdup("???");
1207 if (status && status != MR_NO_MATCH)
1211 (*action)(q->vcnt, argv, actarg);
1213 /* free saved data */
1214 for (i = 0; i < q->vcnt; i++)
1223 int _sdl_followup(struct query *q, char *argv[], client *cl)
1226 EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
1228 EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
1234 int trigger_dcm(struct query *q, char *argv[], client *cl)
1239 sprintf(prog, "%s/startdcm", BIN_DIR);
1244 execl(prog, "startdcm", 0);