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 machine
568 * ID if it is a pop box, and the second is the string ID if it is an SMTP
569 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
573 int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
574 int (*action)(int, char *[], void *), void *actarg,
579 int mid, sid, status, i;
582 while (sq_get_data(sq, &argv))
584 mr_trim_args(2, argv);
586 p = strchr(argv[2], ':');
591 if (!strcmp(ptype, "POP"))
593 status = id_to_name(mid, MACHINE_TABLE, &argv[2]);
594 if (status == MR_NO_MATCH)
597 else if (!strcmp(ptype, "SMTP"))
599 status = id_to_name(sid, STRINGS_TABLE, &argv[2]);
600 if (status == MR_NO_MATCH)
603 else /* ptype == "NONE" */
608 if (!strcmp(q->shortname, "gpob"))
612 status = id_to_name(sid, USERS_TABLE, &argv[4]);
614 status = id_to_name(-sid, STRINGS_TABLE, &argv[4]);
616 if (status && status != MR_NO_MATCH)
619 (*action)(q->vcnt, argv, actarg);
621 /* free saved data */
622 for (i = 0; i < q->vcnt; i++)
632 /* followup_gsnt: fix the ace_name in argv[7]. argv[6] will contain the
633 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[7] into the
634 * proper name based on the type, and repace that string in the argv.
635 * Also fixes the modby field by called followup_fix_modby.
638 int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
639 int (*action)(int, char *[], void *), void *actarg,
643 int id, i, idx, status;
647 while (sq_get_data(sq, &argv))
649 mr_trim_args(q->vcnt, argv);
651 id = atoi(argv[i = q->vcnt - 2]);
653 status = id_to_name(id, USERS_TABLE, &argv[i]);
655 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
656 if (status && status != MR_NO_MATCH)
659 id = atoi(argv[idx]);
660 type = argv[idx - 1];
662 if (!strcmp(type, "LIST"))
663 status = id_to_name(id, LIST_TABLE, &argv[idx]);
664 else if (!strcmp(type, "USER"))
665 status = id_to_name(id, USERS_TABLE, &argv[idx]);
666 else if (!strcmp(type, "KERBEROS"))
667 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
668 else if (!strcmp(type, "NONE"))
672 argv[idx] = xstrdup("NONE");
678 argv[idx] = xstrdup("???");
680 if (status && status != MR_NO_MATCH)
684 (*action)(q->vcnt, argv, actarg);
686 /* free saved data */
687 for (i = 0; i < q->vcnt; i++)
697 /* followup_ghst: fix the ace_name in argv[12]. argv[11] will contain the
698 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[12] into the
699 * proper name based on the type, and repace that string in the argv.
700 * Also fixes the modby field by called followup_fix_modby.
703 int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
704 int (*action)(int, char *[], void *), void *actarg,
708 int id, i, idx, status;
710 while (sq_get_data(sq, &argv))
712 mr_trim_args(q->vcnt, argv);
714 id = atoi(argv[i = q->vcnt - 2]);
716 status = id_to_name(id, USERS_TABLE, &argv[i]);
718 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
719 if (status && status != MR_NO_MATCH)
723 status = id_to_name(id, STRINGS_TABLE, &argv[13]);
727 status = id_to_name(id, STRINGS_TABLE, &argv[14]);
732 status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
734 status = id_to_name(id, USERS_TABLE, &argv[16]);
735 if (status && status != MR_NO_MATCH)
739 id = atoi(argv[idx]);
740 type = strtrim(argv[idx - 1]);
742 if (!strcmp(type, "LIST"))
743 status = id_to_name(id, LIST_TABLE, &argv[idx]);
744 else if (!strcmp(type, "USER"))
745 status = id_to_name(id, USERS_TABLE, &argv[idx]);
746 else if (!strcmp(type, "KERBEROS"))
747 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
748 else if (!strcmp(type, "NONE"))
752 argv[idx] = xstrdup("NONE");
758 argv[idx] = xstrdup("???");
760 if (status && status != MR_NO_MATCH)
764 (*action)(q->vcnt, argv, actarg);
766 /* free saved data */
767 for (i = 0; i < q->vcnt; i++)
777 /* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
778 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
779 * proper name based on the type, and repace that string in the argv.
780 * Also fixes the modby field by called followup_fix_modby.
783 int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
784 int (*action)(int, char *[], void *), void *actarg,
788 int id, i, idx, status;
791 if (!strcmp(q->shortname, "gsin"))
794 while (sq_get_data(sq, &argv))
796 mr_trim_args(q->vcnt, argv);
798 id = atoi(argv[i = q->vcnt - 2]);
800 status = id_to_name(id, USERS_TABLE, &argv[i]);
802 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
803 if (status && status != MR_NO_MATCH)
806 id = atoi(argv[idx]);
807 type = argv[idx - 1];
809 if (!strcmp(type, "LIST"))
810 status = id_to_name(id, LIST_TABLE, &argv[idx]);
811 else if (!strcmp(type, "USER"))
812 status = id_to_name(id, USERS_TABLE, &argv[idx]);
813 else if (!strcmp(type, "KERBEROS"))
814 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
815 else if (!strcmp(type, "NONE"))
819 argv[idx] = xstrdup("NONE");
825 argv[idx] = xstrdup("???");
827 if (status && status != MR_NO_MATCH)
830 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
832 argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
833 strcpy(argv[6], UNIQUE_GID);
837 (*action)(q->vcnt, argv, actarg);
839 /* free saved data */
840 for (i = 0; i < q->vcnt; i++)
849 int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
850 int (*action)(int, char *[], void *), void *actarg,
856 while (sq_get_data(sq, &argv))
858 mr_trim_args(q->vcnt, argv);
860 id = atoi(argv[PRINTSERVER_OWNER_NAME]);
861 type = argv[PRINTSERVER_OWNER_TYPE];
863 if (!strcmp(type, "LIST"))
864 status = id_to_name(id, LIST_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
865 else if (!strcmp(type, "USER"))
866 status = id_to_name(id, USERS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
867 else if (!strcmp(type, "KERBEROS"))
868 status = id_to_name(id, STRINGS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
872 free(argv[PRINTSERVER_OWNER_NAME]);
873 argv[PRINTSERVER_OWNER_NAME] = xstrdup("NONE");
875 if (status && status != MR_NO_MATCH)
879 return followup_fix_modby(q, sq, v, action, actarg, cl);
883 /* followup_gqot: Fix the entity name, directory name & modby fields
884 * argv[0] = filsys_id
886 * argv[2] = entity_id
887 * argv[3] = ascii(quota)
890 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
891 int (*action)(int, char *[], void *), void *actarg,
896 EXEC SQL BEGIN DECLARE SECTION;
899 EXEC SQL END DECLARE SECTION;
902 if (!strcmp(q->name, "get_quota") ||
903 !strcmp(q->name, "get_quota_by_filesys"))
907 while (sq_get_data(sq, &argv))
914 status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
918 status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
922 argv[2] = xstrdup("system:anyuser");
926 argv[2] = xmalloc(8);
927 sprintf(argv[2], "%d", id);
930 id = atoi(argv[idx]);
932 argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
938 EXEC SQL SELECT name INTO :name FROM filesys
939 WHERE label = :label;
943 EXEC SQL SELECT dir INTO :name FROM nfsphys
944 WHERE nfsphys_id = :id;
946 if (sqlca.sqlerrd[2] != 1)
947 sprintf(argv[idx], "#%d", id);
949 id = atoi(argv[idx + 3]);
951 status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
953 status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
954 if (status && status != MR_NO_MATCH)
956 (*action)(q->vcnt, argv, actarg);
957 for (j = 0; j < q->vcnt; j++)
966 /* followup_aqot: Add allocation to nfsphys after creating quota.
967 * argv[0] = filsys_id
968 * argv[1] = type if "add_quota" or "update_quota"
970 * argv[3 or 2] = ascii(quota)
973 int followup_aqot(struct query *q, char *argv[], client *cl)
975 EXEC SQL BEGIN DECLARE SECTION;
976 int quota, id, fs, who, physid, table;
977 char *entity, *qtype, *tname;
978 EXEC SQL END DECLARE SECTION;
984 tname = table_name[table];
985 fs = *(int *)argv[0];
986 EXEC SQL SELECT phys_id INTO :physid FROM filesys
987 WHERE filsys_id = :fs;
991 if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
994 id = *(int *)argv[2];
995 quota = atoi(argv[3]);
996 sprintf(incr_qual, "q.filsys_id = %d", fs);
1001 id = *(int *)argv[1];
1002 quota = atoi(argv[2]);
1003 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
1004 "q.entity_id = %d", fs, qtype, id);
1007 /* quota case of incremental_{before|after} only looks at slot 1 */
1008 incr_argv[1] = qtype;
1010 /* Follows one of many possible gross hacks to fix these particular
1011 * conflicts between what is possible in the query table and what
1012 * is possible in SQL.
1014 if (q->type == APPEND)
1016 incremental_clear_before();
1017 EXEC SQL INSERT INTO quota
1018 (filsys_id, type, entity_id, quota, phys_id)
1019 VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
1020 incremental_after(table, incr_qual, incr_argv);
1024 incremental_before(table, incr_qual, incr_argv);
1025 EXEC SQL UPDATE quota SET quota = :quota
1026 WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
1027 status = mr_errcode;
1028 incremental_after(table, incr_qual, incr_argv);
1033 flush_name(argv[0], table);
1034 if (q->type == APPEND)
1036 EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
1037 WHERE table_name = :tname;
1041 EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
1042 WHERE table_name = :tname;
1045 /* Proceed with original followup */
1046 who = cl->client_id;
1047 entity = cl->entity;
1049 EXEC SQL UPDATE quota
1050 SET modtime = SYSDATE, modby = :who, modwith = :entity
1051 WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1052 EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
1053 WHERE nfsphys_id = :physid;
1060 /* Necessitated by the requirement of a correlation name by the incremental
1061 * routines, since query table deletes don't provide one.
1063 int followup_dqot(struct query *q, char **argv, client *cl)
1068 EXEC SQL BEGIN DECLARE SECTION;
1069 char incr_qual[80], *tname;
1070 EXEC SQL END DECLARE SECTION;
1073 tname = table_name[table];
1074 fs = *(int *)argv[0];
1075 if (!strcmp(q->shortname, "dqot"))
1078 id = *(int *)argv[2];
1083 id = *(int *)argv[1];
1085 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
1088 /* quota case of incremental_{before|after} only looks at slot 1 */
1089 incr_argv[1] = qtype;
1091 incremental_before(table, incr_qual, incr_argv);
1092 EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
1093 AND q.entity_id = :id;
1094 incremental_clear_after();
1098 flush_name(argv[0], table);
1100 EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
1101 WHERE table_name = :tname;
1108 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
1109 int (*action)(int, char *[], void *), void *actarg,
1115 while (sq_get_data(sq, &argv))
1117 mr_trim_args(q->vcnt, argv);
1119 id = atoi(argv[i = q->vcnt - 2]);
1121 status = id_to_name(id, USERS_TABLE, &argv[i]);
1123 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1124 if (status && status != MR_NO_MATCH)
1127 for (i = 1; i < 8; i += 2)
1129 id = atoi(argv[i + 1]);
1130 if (!strcmp(argv[i], "LIST"))
1131 status = id_to_name(id, LIST_TABLE, &argv[i + 1]);
1132 else if (!strcmp(argv[i], "USER"))
1133 status = id_to_name(id, USERS_TABLE, &argv[i + 1]);
1134 else if (!strcmp(argv[i], "KERBEROS"))
1135 status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]);
1136 else if (!strcmp(argv[i], "NONE"))
1140 argv[i + 1] = xstrdup("NONE");
1146 argv[i + 1] = xstrdup("???");
1148 if (status && status != MR_NO_MATCH)
1153 (*action)(q->vcnt, argv, actarg);
1155 /* free saved data */
1156 for (i = 0; i < q->vcnt; i++)
1168 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
1169 int (*action)(int, char *[], void *), void *actarg,
1175 while (sq_get_data(sq, &argv))
1177 mr_trim_args(q->vcnt, argv);
1181 status = id_to_name(id, USERS_TABLE, &argv[4]);
1183 status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
1184 if (status && status != MR_NO_MATCH)
1188 if (!strcmp(argv[1], "LIST"))
1189 status = id_to_name(id, LIST_TABLE, &argv[2]);
1190 else if (!strcmp(argv[1], "USER"))
1191 status = id_to_name(id, USERS_TABLE, &argv[2]);
1192 else if (!strcmp(argv[1], "KERBEROS"))
1193 status = id_to_name(id, STRINGS_TABLE, &argv[2]);
1194 else if (!strcmp(argv[1], "NONE"))
1198 argv[2] = xstrdup("NONE");
1204 argv[2] = xstrdup("???");
1206 if (status && status != MR_NO_MATCH)
1210 (*action)(q->vcnt, argv, actarg);
1212 /* free saved data */
1213 for (i = 0; i < q->vcnt; i++)
1222 int _sdl_followup(struct query *q, char *argv[], client *cl)
1225 EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
1227 EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
1233 int trigger_dcm(struct query *q, char *argv[], client *cl)
1236 char prog[MAXPATHLEN];
1238 sprintf(prog, "%s/startdcm", BIN_DIR);
1243 execl(prog, "startdcm", 0);