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;
563 /* followup_gpob: fixes argv[2] based on the IDs currently there and the
564 * type in argv[1]. Then completes the upcall to the user.
566 * argv[2] is of the form "123:234" where the first integer is the machine
567 * ID if it is a pop box, and the second is the string ID if it is an SMTP
568 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
572 int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
573 int (*action)(int, char *[], void *), void *actarg,
578 int mid, sid, status, i;
581 while (sq_get_data(sq, &argv))
583 mr_trim_args(2, argv);
585 p = strchr(argv[2], ':');
590 if (!strcmp(ptype, "POP"))
592 status = id_to_name(mid, MACHINE_TABLE, &argv[2]);
593 if (status == MR_NO_MATCH)
596 else if (!strcmp(ptype, "SMTP"))
598 status = id_to_name(sid, STRINGS_TABLE, &argv[2]);
599 if (status == MR_NO_MATCH)
602 else /* ptype == "NONE" */
607 if (!strcmp(q->shortname, "gpob"))
611 status = id_to_name(sid, USERS_TABLE, &argv[4]);
613 status = id_to_name(-sid, STRINGS_TABLE, &argv[4]);
615 if (status && status != MR_NO_MATCH)
618 (*action)(q->vcnt, argv, actarg);
620 /* free saved data */
621 for (i = 0; i < q->vcnt; i++)
631 /* followup_gsnt: fix the ace_name in argv[7]. argv[6] will contain the
632 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[7] into the
633 * proper name based on the type, and repace that string in the argv.
634 * Also fixes the modby field by called followup_fix_modby.
637 int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
638 int (*action)(int, char *[], void *), void *actarg,
642 int id, i, idx, status;
646 while (sq_get_data(sq, &argv))
648 mr_trim_args(q->vcnt, argv);
650 id = atoi(argv[i = q->vcnt - 2]);
652 status = id_to_name(id, USERS_TABLE, &argv[i]);
654 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
655 if (status && status != MR_NO_MATCH)
658 id = atoi(argv[idx]);
659 type = argv[idx - 1];
661 if (!strcmp(type, "LIST"))
662 status = id_to_name(id, LIST_TABLE, &argv[idx]);
663 else if (!strcmp(type, "USER"))
664 status = id_to_name(id, USERS_TABLE, &argv[idx]);
665 else if (!strcmp(type, "KERBEROS"))
666 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
667 else if (!strcmp(type, "NONE"))
671 argv[idx] = xstrdup("NONE");
677 argv[idx] = xstrdup("???");
679 if (status && status != MR_NO_MATCH)
683 (*action)(q->vcnt, argv, actarg);
685 /* free saved data */
686 for (i = 0; i < q->vcnt; i++)
696 /* followup_ghst: fix the ace_name in argv[12]. argv[11] will contain the
697 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[12] into the
698 * proper name based on the type, and repace that string in the argv.
699 * Also fixes the modby field by called followup_fix_modby.
702 int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
703 int (*action)(int, char *[], void *), void *actarg,
707 int id, i, idx, status;
709 while (sq_get_data(sq, &argv))
711 mr_trim_args(q->vcnt, argv);
713 id = atoi(argv[i = q->vcnt - 2]);
715 status = id_to_name(id, USERS_TABLE, &argv[i]);
717 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
718 if (status && status != MR_NO_MATCH)
722 status = id_to_name(id, STRINGS_TABLE, &argv[13]);
726 status = id_to_name(id, STRINGS_TABLE, &argv[14]);
731 status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
733 status = id_to_name(id, USERS_TABLE, &argv[16]);
734 if (status && status != MR_NO_MATCH)
738 id = atoi(argv[idx]);
739 type = strtrim(argv[idx - 1]);
741 if (!strcmp(type, "LIST"))
742 status = id_to_name(id, LIST_TABLE, &argv[idx]);
743 else if (!strcmp(type, "USER"))
744 status = id_to_name(id, USERS_TABLE, &argv[idx]);
745 else if (!strcmp(type, "KERBEROS"))
746 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
747 else if (!strcmp(type, "NONE"))
751 argv[idx] = xstrdup("NONE");
757 argv[idx] = xstrdup("???");
759 if (status && status != MR_NO_MATCH)
763 (*action)(q->vcnt, argv, actarg);
765 /* free saved data */
766 for (i = 0; i < q->vcnt; i++)
776 /* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
777 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
778 * proper name based on the type, and repace that string in the argv.
779 * Also fixes the modby field by called followup_fix_modby.
782 int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
783 int (*action)(int, char *[], void *), void *actarg,
787 int id, i, idx, status;
790 if (!strcmp(q->shortname, "gsin"))
793 while (sq_get_data(sq, &argv))
795 mr_trim_args(q->vcnt, argv);
797 id = atoi(argv[i = q->vcnt - 2]);
799 status = id_to_name(id, USERS_TABLE, &argv[i]);
801 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
802 if (status && status != MR_NO_MATCH)
805 id = atoi(argv[idx]);
806 type = argv[idx - 1];
808 if (!strcmp(type, "LIST"))
809 status = id_to_name(id, LIST_TABLE, &argv[idx]);
810 else if (!strcmp(type, "USER"))
811 status = id_to_name(id, USERS_TABLE, &argv[idx]);
812 else if (!strcmp(type, "KERBEROS"))
813 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
814 else if (!strcmp(type, "NONE"))
818 argv[idx] = xstrdup("NONE");
824 argv[idx] = xstrdup("???");
826 if (status && status != MR_NO_MATCH)
829 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
831 argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
832 strcpy(argv[6], UNIQUE_GID);
836 (*action)(q->vcnt, argv, actarg);
838 /* free saved data */
839 for (i = 0; i < q->vcnt; i++)
849 /* followup_gqot: Fix the entity name, directory name & modby fields
850 * argv[0] = filsys_id
852 * argv[2] = entity_id
853 * argv[3] = ascii(quota)
856 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
857 int (*action)(int, char *[], void *), void *actarg,
862 EXEC SQL BEGIN DECLARE SECTION;
865 EXEC SQL END DECLARE SECTION;
868 if (!strcmp(q->name, "get_quota") ||
869 !strcmp(q->name, "get_quota_by_filesys"))
873 while (sq_get_data(sq, &argv))
880 status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
884 status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
888 argv[2] = xstrdup("system:anyuser");
892 argv[2] = xmalloc(8);
893 sprintf(argv[2], "%d", id);
896 id = atoi(argv[idx]);
898 argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
904 EXEC SQL SELECT name INTO :name FROM filesys
905 WHERE label = :label;
909 EXEC SQL SELECT dir INTO :name FROM nfsphys
910 WHERE nfsphys_id = :id;
912 if (sqlca.sqlerrd[2] != 1)
913 sprintf(argv[idx], "#%d", id);
915 id = atoi(argv[idx + 3]);
917 status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
919 status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
920 if (status && status != MR_NO_MATCH)
922 (*action)(q->vcnt, argv, actarg);
923 for (j = 0; j < q->vcnt; j++)
932 /* followup_aqot: Add allocation to nfsphys after creating quota.
933 * argv[0] = filsys_id
934 * argv[1] = type if "add_quota" or "update_quota"
936 * argv[3 or 2] = ascii(quota)
939 int followup_aqot(struct query *q, char *argv[], client *cl)
941 EXEC SQL BEGIN DECLARE SECTION;
942 int quota, id, fs, who, physid, table;
943 char *entity, *qtype, *tname;
944 EXEC SQL END DECLARE SECTION;
950 tname = table_name[table];
951 fs = *(int *)argv[0];
952 EXEC SQL SELECT phys_id INTO :physid FROM filesys
953 WHERE filsys_id = :fs;
957 if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
960 id = *(int *)argv[2];
961 quota = atoi(argv[3]);
962 sprintf(incr_qual, "q.filsys_id = %d", fs);
967 id = *(int *)argv[1];
968 quota = atoi(argv[2]);
969 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
970 "q.entity_id = %d", fs, qtype, id);
973 /* quota case of incremental_{before|after} only looks at slot 1 */
974 incr_argv[1] = qtype;
976 /* Follows one of many possible gross hacks to fix these particular
977 * conflicts between what is possible in the query table and what
978 * is possible in SQL.
980 if (q->type == APPEND)
982 incremental_clear_before();
983 EXEC SQL INSERT INTO quota
984 (filsys_id, type, entity_id, quota, phys_id)
985 VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
986 incremental_after(table, incr_qual, incr_argv);
990 incremental_before(table, incr_qual, incr_argv);
991 EXEC SQL UPDATE quota SET quota = :quota
992 WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
994 incremental_after(table, incr_qual, incr_argv);
999 flush_name(argv[0], table);
1000 if (q->type == APPEND)
1002 EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
1003 WHERE table_name = :tname;
1007 EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
1008 WHERE table_name = :tname;
1011 /* Proceed with original followup */
1012 who = cl->client_id;
1013 entity = cl->entity;
1015 EXEC SQL UPDATE quota
1016 SET modtime = SYSDATE, modby = :who, modwith = :entity
1017 WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1018 EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
1019 WHERE nfsphys_id = :physid;
1026 /* Necessitated by the requirement of a correlation name by the incremental
1027 * routines, since query table deletes don't provide one.
1029 int followup_dqot(struct query *q, char **argv, client *cl)
1034 EXEC SQL BEGIN DECLARE SECTION;
1035 char incr_qual[80], *tname;
1036 EXEC SQL END DECLARE SECTION;
1039 tname = table_name[table];
1040 fs = *(int *)argv[0];
1041 if (!strcmp(q->shortname, "dqot"))
1044 id = *(int *)argv[2];
1049 id = *(int *)argv[1];
1051 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
1054 /* quota case of incremental_{before|after} only looks at slot 1 */
1055 incr_argv[1] = qtype;
1057 incremental_before(table, incr_qual, incr_argv);
1058 EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
1059 AND q.entity_id = :id;
1060 incremental_clear_after();
1064 flush_name(argv[0], table);
1066 EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
1067 WHERE table_name = :tname;
1072 int followup_gpce(struct query *q, struct save_queue *sq, struct validate *v,
1073 int (*action)(int, char *[], void *), void *actarg,
1081 while (sq_get_data(sq, &argv))
1083 id = atoi(argv[PCAP_QSERVER]);
1084 status = id_to_name(id, MACHINE_TABLE, &argv[PCAP_QSERVER]);
1089 status = id_to_name(id, USERS_TABLE, &argv[i]);
1091 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1092 if (status && status != MR_NO_MATCH)
1094 (*action)(q->vcnt, argv, actarg);
1095 for (j = 0; j < q->vcnt; j++)
1107 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
1108 int (*action)(int, char *[], void *), void *actarg,
1114 while (sq_get_data(sq, &argv))
1116 mr_trim_args(q->vcnt, argv);
1118 id = atoi(argv[i = q->vcnt - 2]);
1120 status = id_to_name(id, USERS_TABLE, &argv[i]);
1122 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1123 if (status && status != MR_NO_MATCH)
1126 for (i = 1; i < 8; i += 2)
1128 id = atoi(argv[i + 1]);
1129 if (!strcmp(argv[i], "LIST"))
1130 status = id_to_name(id, LIST_TABLE, &argv[i + 1]);
1131 else if (!strcmp(argv[i], "USER"))
1132 status = id_to_name(id, USERS_TABLE, &argv[i + 1]);
1133 else if (!strcmp(argv[i], "KERBEROS"))
1134 status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]);
1135 else if (!strcmp(argv[i], "NONE"))
1139 argv[i + 1] = xstrdup("NONE");
1145 argv[i + 1] = xstrdup("???");
1147 if (status && status != MR_NO_MATCH)
1152 (*action)(q->vcnt, argv, actarg);
1154 /* free saved data */
1155 for (i = 0; i < q->vcnt; i++)
1167 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
1168 int (*action)(int, char *[], void *), void *actarg,
1174 while (sq_get_data(sq, &argv))
1176 mr_trim_args(q->vcnt, argv);
1180 status = id_to_name(id, USERS_TABLE, &argv[4]);
1182 status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
1183 if (status && status != MR_NO_MATCH)
1187 if (!strcmp(argv[1], "LIST"))
1188 status = id_to_name(id, LIST_TABLE, &argv[2]);
1189 else if (!strcmp(argv[1], "USER"))
1190 status = id_to_name(id, USERS_TABLE, &argv[2]);
1191 else if (!strcmp(argv[1], "KERBEROS"))
1192 status = id_to_name(id, STRINGS_TABLE, &argv[2]);
1193 else if (!strcmp(argv[1], "NONE"))
1197 argv[2] = xstrdup("NONE");
1203 argv[2] = xstrdup("???");
1205 if (status && status != MR_NO_MATCH)
1209 (*action)(q->vcnt, argv, actarg);
1211 /* free saved data */
1212 for (i = 0; i < q->vcnt; i++)
1221 int _sdl_followup(struct query *q, char *argv[], client *cl)
1224 EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
1226 EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
1232 int trigger_dcm(struct query *q, char *argv[], client *cl)
1235 char prog[MAXPATHLEN];
1237 sprintf(prog, "%s/startdcm", BIN_DIR);
1242 execl(prog, "startdcm", 0);