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] and argv[3] based on the pobox type.
565 * Then completes the upcall to the user.
567 * argv[2] is the users_id on input and should be converted to the
568 * pobox name on output. argv[3] is empty on input and should be
569 * converted to an email address on output.
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;
579 EXEC SQL BEGIN DECLARE SECTION;
581 char mach[MACHINE_NAME_SIZE], fs[FILESYS_LABEL_SIZE];
582 char str[STRINGS_STRING_SIZE];
583 EXEC SQL END DECLARE SECTION;
586 while (sq_get_data(sq, &argv))
588 mr_trim_args(4, argv);
590 users_id = atoi(argv[2]);
592 if (!strcmp(ptype, "POP"))
594 EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
595 WHERE u.users_id = :users_id AND u.pop_id = m.mach_id;
599 argv[2] = xstrdup(strtrim(mach));
601 argv[3] = xmalloc(strlen(argv[0]) + strlen(argv[2]) + 2);
602 sprintf(argv[3], "%s@%s", argv[0], argv[2]);
604 else if (!strcmp(ptype, "SMTP"))
606 EXEC SQL SELECT s.string INTO :str FROM strings s, users u
607 WHERE u.users_id = :users_id AND u.box_id = s.string_id;
612 argv[2] = xstrdup(strtrim(str));
613 argv[3] = xstrdup(str);
615 else if (!strcmp(ptype, "IMAP"))
617 EXEC SQL SELECT f.label, m.name INTO :fs, :mach
618 FROM filesys f, machine m, users u
619 WHERE u.users_id = :users_id AND f.filsys_id = u.imap_id
620 AND f.mach_id = m.mach_id;
624 argv[2] = xstrdup(strtrim(fs));
626 argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + 2);
627 sprintf(argv[3], "%s@%s", argv[0], mach);
629 else /* ptype == "NONE" */
632 if (!strcmp(q->shortname, "gpob"))
636 status = id_to_name(sid, USERS_TABLE, &argv[5]);
638 status = id_to_name(-sid, STRINGS_TABLE, &argv[5]);
639 if (status && status != MR_NO_MATCH)
643 (*action)(q->vcnt, argv, actarg);
645 /* free saved data */
646 for (i = 0; i < q->vcnt; i++)
656 /* followup_gsnt: fix the ace_name in argv[7]. argv[6] will contain the
657 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[7] into the
658 * proper name based on the type, and repace that string in the argv.
659 * Also fixes the modby field by called followup_fix_modby.
662 int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
663 int (*action)(int, char *[], void *), void *actarg,
667 int id, i, idx, status;
671 while (sq_get_data(sq, &argv))
673 mr_trim_args(q->vcnt, argv);
675 id = atoi(argv[i = q->vcnt - 2]);
677 status = id_to_name(id, USERS_TABLE, &argv[i]);
679 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
680 if (status && status != MR_NO_MATCH)
683 id = atoi(argv[idx]);
684 type = argv[idx - 1];
686 if (!strcmp(type, "LIST"))
687 status = id_to_name(id, LIST_TABLE, &argv[idx]);
688 else if (!strcmp(type, "USER"))
689 status = id_to_name(id, USERS_TABLE, &argv[idx]);
690 else if (!strcmp(type, "KERBEROS"))
691 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
692 else if (!strcmp(type, "NONE"))
696 argv[idx] = xstrdup("NONE");
702 argv[idx] = xstrdup("???");
704 if (status && status != MR_NO_MATCH)
708 (*action)(q->vcnt, argv, actarg);
710 /* free saved data */
711 for (i = 0; i < q->vcnt; i++)
721 /* followup_ghst: fix the ace_name in argv[12]. argv[11] will contain the
722 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[12] into the
723 * proper name based on the type, and repace that string in the argv.
724 * Also fixes the modby field by called followup_fix_modby.
727 int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
728 int (*action)(int, char *[], void *), void *actarg,
732 int id, i, idx, status;
734 while (sq_get_data(sq, &argv))
736 mr_trim_args(q->vcnt, argv);
738 id = atoi(argv[i = q->vcnt - 2]);
740 status = id_to_name(id, USERS_TABLE, &argv[i]);
742 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
743 if (status && status != MR_NO_MATCH)
747 status = id_to_name(id, STRINGS_TABLE, &argv[13]);
751 status = id_to_name(id, STRINGS_TABLE, &argv[14]);
756 status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
758 status = id_to_name(id, USERS_TABLE, &argv[16]);
759 if (status && status != MR_NO_MATCH)
763 id = atoi(argv[idx]);
764 type = strtrim(argv[idx - 1]);
766 if (!strcmp(type, "LIST"))
767 status = id_to_name(id, LIST_TABLE, &argv[idx]);
768 else if (!strcmp(type, "USER"))
769 status = id_to_name(id, USERS_TABLE, &argv[idx]);
770 else if (!strcmp(type, "KERBEROS"))
771 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
772 else if (!strcmp(type, "NONE"))
776 argv[idx] = xstrdup("NONE");
782 argv[idx] = xstrdup("???");
784 if (status && status != MR_NO_MATCH)
788 (*action)(q->vcnt, argv, actarg);
790 /* free saved data */
791 for (i = 0; i < q->vcnt; i++)
801 /* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
802 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
803 * proper name based on the type, and repace that string in the argv.
804 * Also fixes the modby field by called followup_fix_modby.
807 int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
808 int (*action)(int, char *[], void *), void *actarg,
812 int id, i, idx, status;
815 if (!strcmp(q->shortname, "gsin"))
818 while (sq_get_data(sq, &argv))
820 mr_trim_args(q->vcnt, argv);
822 id = atoi(argv[i = q->vcnt - 2]);
824 status = id_to_name(id, USERS_TABLE, &argv[i]);
826 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
827 if (status && status != MR_NO_MATCH)
830 id = atoi(argv[idx]);
831 type = argv[idx - 1];
833 if (!strcmp(type, "LIST"))
834 status = id_to_name(id, LIST_TABLE, &argv[idx]);
835 else if (!strcmp(type, "USER"))
836 status = id_to_name(id, USERS_TABLE, &argv[idx]);
837 else if (!strcmp(type, "KERBEROS"))
838 status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
839 else if (!strcmp(type, "NONE"))
843 argv[idx] = xstrdup("NONE");
849 argv[idx] = xstrdup("???");
851 if (status && status != MR_NO_MATCH)
854 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
856 argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
857 strcpy(argv[6], UNIQUE_GID);
861 (*action)(q->vcnt, argv, actarg);
863 /* free saved data */
864 for (i = 0; i < q->vcnt; i++)
873 int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
874 int (*action)(int, char *[], void *), void *actarg,
880 while (sq_get_data(sq, &argv))
882 mr_trim_args(q->vcnt, argv);
884 id = atoi(argv[PRINTSERVER_OWNER_NAME]);
885 type = argv[PRINTSERVER_OWNER_TYPE];
887 if (!strcmp(type, "LIST"))
888 status = id_to_name(id, LIST_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
889 else if (!strcmp(type, "USER"))
890 status = id_to_name(id, USERS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
891 else if (!strcmp(type, "KERBEROS"))
892 status = id_to_name(id, STRINGS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
896 free(argv[PRINTSERVER_OWNER_NAME]);
897 argv[PRINTSERVER_OWNER_NAME] = xstrdup("NONE");
899 if (status && status != MR_NO_MATCH)
903 return followup_fix_modby(q, sq, v, action, actarg, cl);
907 /* followup_gqot: Fix the entity name, directory name & modby fields
908 * argv[0] = filsys_id
910 * argv[2] = entity_id
911 * argv[3] = ascii(quota)
914 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
915 int (*action)(int, char *[], void *), void *actarg,
920 EXEC SQL BEGIN DECLARE SECTION;
923 EXEC SQL END DECLARE SECTION;
926 if (!strcmp(q->name, "get_quota") ||
927 !strcmp(q->name, "get_quota_by_filesys"))
931 while (sq_get_data(sq, &argv))
938 status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
942 status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
946 argv[2] = xstrdup("system:anyuser");
950 argv[2] = xmalloc(8);
951 sprintf(argv[2], "%d", id);
954 id = atoi(argv[idx]);
956 argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
962 EXEC SQL SELECT name INTO :name FROM filesys
963 WHERE label = :label;
967 EXEC SQL SELECT dir INTO :name FROM nfsphys
968 WHERE nfsphys_id = :id;
970 if (sqlca.sqlerrd[2] != 1)
971 sprintf(argv[idx], "#%d", id);
973 id = atoi(argv[idx + 3]);
975 status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
977 status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
978 if (status && status != MR_NO_MATCH)
980 (*action)(q->vcnt, argv, actarg);
981 for (j = 0; j < q->vcnt; j++)
990 /* followup_aqot: Add allocation to nfsphys after creating quota.
991 * argv[0] = filsys_id
992 * argv[1] = type if "add_quota" or "update_quota"
994 * argv[3 or 2] = ascii(quota)
997 int followup_aqot(struct query *q, char *argv[], client *cl)
999 EXEC SQL BEGIN DECLARE SECTION;
1000 int quota, id, fs, who, physid, table;
1001 char *entity, *qtype, *tname;
1002 EXEC SQL END DECLARE SECTION;
1008 tname = table_name[table];
1009 fs = *(int *)argv[0];
1010 EXEC SQL SELECT phys_id INTO :physid FROM filesys
1011 WHERE filsys_id = :fs;
1015 if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
1018 id = *(int *)argv[2];
1019 quota = atoi(argv[3]);
1020 sprintf(incr_qual, "q.filsys_id = %d", fs);
1025 id = *(int *)argv[1];
1026 quota = atoi(argv[2]);
1027 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
1028 "q.entity_id = %d", fs, qtype, id);
1031 /* quota case of incremental_{before|after} only looks at slot 1 */
1032 incr_argv[1] = qtype;
1034 /* Follows one of many possible gross hacks to fix these particular
1035 * conflicts between what is possible in the query table and what
1036 * is possible in SQL.
1038 if (q->type == APPEND)
1040 incremental_clear_before();
1041 EXEC SQL INSERT INTO quota
1042 (filsys_id, type, entity_id, quota, phys_id)
1043 VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
1044 incremental_after(table, incr_qual, incr_argv);
1048 incremental_before(table, incr_qual, incr_argv);
1049 EXEC SQL UPDATE quota SET quota = :quota
1050 WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
1051 status = mr_errcode;
1052 incremental_after(table, incr_qual, incr_argv);
1057 flush_name(argv[0], table);
1058 if (q->type == APPEND)
1060 EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
1061 WHERE table_name = :tname;
1065 EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
1066 WHERE table_name = :tname;
1069 /* Proceed with original followup */
1070 who = cl->client_id;
1071 entity = cl->entity;
1073 EXEC SQL UPDATE quota
1074 SET modtime = SYSDATE, modby = :who, modwith = :entity
1075 WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1076 EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
1077 WHERE nfsphys_id = :physid;
1084 /* Necessitated by the requirement of a correlation name by the incremental
1085 * routines, since query table deletes don't provide one.
1087 int followup_dqot(struct query *q, char **argv, client *cl)
1092 EXEC SQL BEGIN DECLARE SECTION;
1093 char incr_qual[80], *tname;
1094 EXEC SQL END DECLARE SECTION;
1097 tname = table_name[table];
1098 fs = *(int *)argv[0];
1099 if (!strcmp(q->shortname, "dqot"))
1102 id = *(int *)argv[2];
1107 id = *(int *)argv[1];
1109 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
1112 /* quota case of incremental_{before|after} only looks at slot 1 */
1113 incr_argv[1] = qtype;
1115 incremental_before(table, incr_qual, incr_argv);
1116 EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
1117 AND q.entity_id = :id;
1118 incremental_clear_after();
1122 flush_name(argv[0], table);
1124 EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
1125 WHERE table_name = :tname;
1132 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
1133 int (*action)(int, char *[], void *), void *actarg,
1139 while (sq_get_data(sq, &argv))
1141 mr_trim_args(q->vcnt, argv);
1143 id = atoi(argv[i = q->vcnt - 2]);
1145 status = id_to_name(id, USERS_TABLE, &argv[i]);
1147 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1148 if (status && status != MR_NO_MATCH)
1151 for (i = 1; i < 8; i += 2)
1153 id = atoi(argv[i + 1]);
1154 if (!strcmp(argv[i], "LIST"))
1155 status = id_to_name(id, LIST_TABLE, &argv[i + 1]);
1156 else if (!strcmp(argv[i], "USER"))
1157 status = id_to_name(id, USERS_TABLE, &argv[i + 1]);
1158 else if (!strcmp(argv[i], "KERBEROS"))
1159 status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]);
1160 else if (!strcmp(argv[i], "NONE"))
1164 argv[i + 1] = xstrdup("NONE");
1170 argv[i + 1] = xstrdup("???");
1172 if (status && status != MR_NO_MATCH)
1177 (*action)(q->vcnt, argv, actarg);
1179 /* free saved data */
1180 for (i = 0; i < q->vcnt; i++)
1192 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
1193 int (*action)(int, char *[], void *), void *actarg,
1199 while (sq_get_data(sq, &argv))
1201 mr_trim_args(q->vcnt, argv);
1205 status = id_to_name(id, USERS_TABLE, &argv[4]);
1207 status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
1208 if (status && status != MR_NO_MATCH)
1212 if (!strcmp(argv[1], "LIST"))
1213 status = id_to_name(id, LIST_TABLE, &argv[2]);
1214 else if (!strcmp(argv[1], "USER"))
1215 status = id_to_name(id, USERS_TABLE, &argv[2]);
1216 else if (!strcmp(argv[1], "KERBEROS"))
1217 status = id_to_name(id, STRINGS_TABLE, &argv[2]);
1218 else if (!strcmp(argv[1], "NONE"))
1222 argv[2] = xstrdup("NONE");
1228 argv[2] = xstrdup("???");
1230 if (status && status != MR_NO_MATCH)
1234 (*action)(q->vcnt, argv, actarg);
1236 /* free saved data */
1237 for (i = 0; i < q->vcnt; i++)
1246 int _sdl_followup(struct query *q, char *argv[], client *cl)
1249 EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
1251 EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
1257 int trigger_dcm(struct query *q, char *argv[], client *cl)
1260 char prog[MAXPATHLEN];
1262 sprintf(prog, "%s/startdcm", BIN_DIR);
1267 execl(prog, "startdcm", 0);