]> andersk Git - moira.git/blame_incremental - server/qfollow.pc
Add a "PIN" screen that's an alternative to the six words screen;
[moira.git] / server / qfollow.pc
... / ...
CommitLineData
1/* $Id$
2 *
3 * Query followup routines
4 *
5 * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 *
9 */
10
11#include <mit-copyright.h>
12#include "mr_server.h"
13#include "query.h"
14#include "qrtn.h"
15
16#include <errno.h>
17#include <ctype.h>
18#include <stdlib.h>
19#include <string.h>
20
21EXEC SQL INCLUDE sqlca;
22
23RCSID("$Header$");
24
25extern char *whoami, *table_name[];
26extern int dbms_errno, mr_errcode;
27
28EXEC SQL BEGIN DECLARE SECTION;
29extern char stmt_buf[];
30EXEC SQL END DECLARE SECTION;
31
32EXEC SQL WHENEVER SQLERROR DO dbmserr();
33
34
35/* FOLLOWUP ROUTINES */
36
37/* generic set_modtime routine. This takes the table id from the query,
38 * and will update the modtime, modby, and modwho fields in the entry in
39 * the table whose name field matches argv[0].
40 */
41
42int set_modtime(struct query *q, char *argv[], client *cl)
43{
44 char *name, *entity, *table;
45 int who;
46
47 entity = cl->entity;
48 who = cl->client_id;
49 table = table_name[q->rtable];
50 name = argv[0];
51
52 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
53 "modwith = '%s' WHERE name = '%s'", table, who, entity, name);
54 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
55
56 return MR_SUCCESS;
57}
58
59/* generic set_modtime_by_id routine. This takes the table id from
60 * the query, and the id name from the validate record,
61 * and will update the modtime, modby, and modwho fields in the entry in
62 * the table whose id matches argv[0].
63 */
64
65int set_modtime_by_id(struct query *q, char *argv[], client *cl)
66{
67 char *entity, *table, *id_name;
68 int who, id;
69
70 entity = cl->entity;
71 who = cl->client_id;
72 table = table_name[q->rtable];
73 id_name = q->validate->object_id;
74
75 id = *(int *)argv[0];
76 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
77 "modwith = '%s' WHERE %s = %d", table, who, entity, id_name, id);
78 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
79 return MR_SUCCESS;
80}
81
82
83/* Sets the finger modtime on a user record. The users_id will be in argv[0].
84 */
85
86int set_finger_modtime(struct query *q, char *argv[], client *cl)
87{
88 EXEC SQL BEGIN DECLARE SECTION;
89 int users_id, who;
90 char *entity;
91 EXEC SQL END DECLARE SECTION;
92
93 entity = cl->entity;
94 who = cl->client_id;
95 users_id = *(int *)argv[0];
96
97 EXEC SQL UPDATE users SET fmodtime = SYSDATE, fmodby = :who,
98 fmodwith = :entity WHERE users_id = :users_id;
99
100 return MR_SUCCESS;
101}
102
103
104/* Sets the pobox modtime on a user record. The users_id will be in argv[0].
105 */
106
107int set_pobox_modtime(struct query *q, char *argv[], client *cl)
108{
109 EXEC SQL BEGIN DECLARE SECTION;
110 int users_id, who;
111 char *entity;
112 EXEC SQL END DECLARE SECTION;
113
114 entity = cl->entity;
115 who = cl->client_id;
116 users_id = *(int *)argv[0];
117
118 EXEC SQL UPDATE users SET pmodtime = SYSDATE, pmodby = :who,
119 pmodwith = :entity WHERE users_id = :users_id;
120
121 return MR_SUCCESS;
122}
123
124
125/* Like set_modtime, but uppercases the name first.
126 */
127
128int set_uppercase_modtime(struct query *q, char *argv[], client *cl)
129{
130 char *name, *entity, *table;
131 int who;
132
133 entity = cl->entity;
134 who = cl->client_id;
135 table = table_name[q->rtable];
136 name = argv[0];
137
138 sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
139 "modwith = '%s' WHERE name = UPPER('%s')", table, who, entity, name);
140 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
141
142 return MR_SUCCESS;
143}
144
145
146/* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
147 * is necessary for add_machine_to_cluster becuase the table that query
148 * operates on is "mcm", not "machine".
149 */
150
151int set_mach_modtime_by_id(struct query *q, char *argv[], client *cl)
152{
153 EXEC SQL BEGIN DECLARE SECTION;
154 char *entity;
155 int who, id;
156 EXEC SQL END DECLARE SECTION;
157
158 entity = cl->entity;
159 who = cl->client_id;
160 id = *(int *)argv[0];
161 EXEC SQL UPDATE machine SET modtime = SYSDATE, modby = :who,
162 modwith = :entity WHERE mach_id = :id;
163
164 return MR_SUCCESS;
165}
166
167
168/* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
169 * is necessary for add_cluster_data and delete_cluster_data becuase the
170 * table that query operates on is "svc", not "cluster".
171 */
172
173int set_cluster_modtime_by_id(struct query *q, char *argv[], client *cl)
174{
175 EXEC SQL BEGIN DECLARE SECTION;
176 char *entity;
177 int who, id;
178 EXEC SQL END DECLARE SECTION;
179
180 entity = cl->entity;
181 who = cl->client_id;
182
183 id = *(int *)argv[0];
184 EXEC SQL UPDATE clusters SET modtime = SYSDATE, modby = :who,
185 modwith = :entity WHERE clu_id = :id;
186 return MR_SUCCESS;
187}
188
189
190/* sets the modtime on the serverhost where the service name is in argv[0]
191 * and the mach_id is in argv[1].
192 */
193
194int set_serverhost_modtime(struct query *q, char *argv[], client *cl)
195{
196 EXEC SQL BEGIN DECLARE SECTION;
197 char *entity, *serv;
198 int who, id;
199 EXEC SQL END DECLARE SECTION;
200
201 entity = cl->entity;
202 who = cl->client_id;
203
204 serv = argv[0];
205 id = *(int *)argv[1];
206 EXEC SQL UPDATE serverhosts
207 SET modtime = SYSDATE, modby = :who, modwith = :entity
208 WHERE service = :serv AND mach_id = :id;
209 return MR_SUCCESS;
210}
211
212
213/* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
214 * directory name is in argv[1].
215 */
216
217int set_nfsphys_modtime(struct query *q, char *argv[], client *cl)
218{
219 EXEC SQL BEGIN DECLARE SECTION;
220 char *entity, *dir;
221 int who, id;
222 EXEC SQL END DECLARE SECTION;
223
224 entity = cl->entity;
225 who = cl->client_id;
226
227 id = *(int *)argv[0];
228 dir = argv[1];
229 EXEC SQL UPDATE nfsphys SET modtime = SYSDATE, modby = :who,
230 modwith = :entity WHERE dir = :dir AND mach_id = :id;
231 return MR_SUCCESS;
232}
233
234
235/* sets the modtime on a filesystem, where argv[0] contains the filesys
236 * label.
237 */
238
239int set_filesys_modtime(struct query *q, char *argv[], client *cl)
240{
241 EXEC SQL BEGIN DECLARE SECTION;
242 char *label, *entity;
243 int who;
244 extern int _var_phys_id;
245 EXEC SQL END DECLARE SECTION;
246
247 entity = cl->entity;
248 who = cl->client_id;
249
250 label = argv[0];
251 if (!strcmp(q->shortname, "ufil"))
252 label = argv[1];
253
254 EXEC SQL UPDATE filesys SET modtime = SYSDATE, modby = :who,
255 modwith = :entity, phys_id = :_var_phys_id
256 WHERE label = :label;
257 return MR_SUCCESS;
258}
259
260
261/* sets the modtime on a zephyr class, where argv[0] contains the class
262 * name.
263 */
264
265int set_zephyr_modtime(struct query *q, char *argv[], client *cl)
266{
267 EXEC SQL BEGIN DECLARE SECTION;
268 char *class, *entity;
269 int who;
270 EXEC SQL END DECLARE SECTION;
271
272 entity = cl->entity;
273 who = cl->client_id;
274
275 class = argv[0];
276
277 EXEC SQL UPDATE zephyr SET modtime = SYSDATE, modby = :who,
278 modwith = :entity WHERE class = :class;
279
280 return MR_SUCCESS;
281}
282
283/* sets the modtime on an entry in services table, where argv[0] contains
284 * the service name.
285 */
286
287int set_service_modtime(struct query *q, char *argv[], client *cl)
288{
289 EXEC SQL BEGIN DECLARE SECTION;
290 char *service, *protocol, *entity;
291 int who;
292 EXEC SQL END DECLARE SECTION;
293
294 entity = cl->entity;
295 who = cl->client_id;
296
297 service = argv[0];
298 protocol = argv[1];
299
300 EXEC SQL UPDATE services SET modtime = SYSDATE, modby = :who,
301 modwith = :entity WHERE name = :service AND protocol = :protocol;
302
303 return MR_SUCCESS;
304}
305
306/* fixes the modby field. This will be the second to last thing in the
307 * argv, the argv length is determined from the query structure. It is
308 * passed as a pointer to an integer. This will either turn it into a
309 * username, or # + the users_id.
310 */
311int followup_fix_modby(struct query *q, struct save_queue *sq,
312 struct validate *v, int (*action)(int, char *[], void *),
313 void *actarg, client *cl)
314{
315 int i, j;
316 char **argv;
317 int id, status;
318
319 i = q->vcnt - 2;
320 while (sq_get_data(sq, &argv))
321 {
322 id = atoi(argv[i]);
323 if (id > 0)
324 status = id_to_name(id, USERS_TABLE, &argv[i]);
325 else
326 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
327 if (status && status != MR_NO_MATCH)
328 return status;
329 (*action)(q->vcnt, argv, actarg);
330 for (j = 0; j < q->vcnt; j++)
331 free(argv[j]);
332 free(argv);
333 }
334 sq_destroy(sq);
335 return MR_SUCCESS;
336}
337
338/**
339 ** followup_ausr - add finger and pobox entries, set_user_modtime
340 **
341 ** Inputs:
342 ** argv[0] - login (add_user)
343 ** argv[U_LAST] - last name
344 ** argv[U_FIRST] - first name
345 ** argv[U_MIDDLE] - middle name
346 **
347 **/
348
349int followup_ausr(struct query *q, char *argv[], client *cl)
350{
351 EXEC SQL BEGIN DECLARE SECTION;
352 int who, status;
353 char *login, *entity, *name;
354 char fullname[USERS_FIRST_SIZE + USERS_MIDDLE_SIZE + USERS_LAST_SIZE];
355 EXEC SQL END DECLARE SECTION;
356
357 /* build fullname */
358 if (strlen(argv[U_FIRST]) && strlen(argv[U_MIDDLE]))
359 sprintf(fullname, "%s %s %s", argv[U_FIRST], argv[U_MIDDLE],
360 argv[U_LAST]);
361 else if (strlen(argv[U_FIRST]))
362 sprintf(fullname, "%s %s", argv[U_FIRST], argv[U_LAST]);
363 else
364 sprintf(fullname, "%s", argv[U_LAST]);
365
366 login = argv[0];
367 who = cl->client_id;
368 entity = cl->entity;
369
370 /* create finger entry, pobox & set modtime on user */
371 EXEC SQL UPDATE users
372 SET modtime = SYSDATE, modby = :who, modwith = :entity,
373 fullname = NVL(:fullname, CHR(0)), affiliation = type,
374 fmodtime = SYSDATE, fmodby = :who, fmodwith = :entity,
375 potype = 'NONE', pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity
376 WHERE login = :login;
377
378 return MR_SUCCESS;
379}
380
381/* followup_gpob: fixes argv[2] and argv[3] based on the pobox type.
382 * Then completes the upcall to the user.
383 *
384 * argv[2] is the users_id on input and should be converted to the
385 * pobox name on output. argv[3] is empty on input and should be
386 * converted to an email address on output.
387 */
388
389int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
390 int (*action)(int, char *[], void *), void *actarg,
391 client *cl)
392{
393 char **argv;
394 char *ptype, *p;
395 int mid, sid, status, i;
396 EXEC SQL BEGIN DECLARE SECTION;
397 int users_id, pid, iid, bid;
398 char mach[MACHINE_NAME_SIZE], fs[FILESYS_LABEL_SIZE];
399 char str[STRINGS_STRING_SIZE];
400 EXEC SQL END DECLARE SECTION;
401
402 /* for each row */
403 while (sq_get_data(sq, &argv))
404 {
405 mr_trim_args(4, argv);
406 ptype = argv[1];
407 users_id = atoi(argv[2]);
408
409 EXEC SQL SELECT pop_id, imap_id, box_id INTO :pid, :iid, :bid
410 FROM users WHERE users_id = :users_id;
411 if (sqlca.sqlcode)
412 return MR_USER;
413
414 if (ptype[0] == 'S')
415 {
416 /* SMTP or SPLIT */
417 EXEC SQL SELECT string INTO :str FROM strings
418 WHERE string_id = :bid;
419 if (sqlca.sqlcode)
420 return MR_STRING;
421
422 /* If SMTP, don't bother fetching IMAP and POP boxes. */
423 if (ptype[1] == 'M')
424 pid = iid = 0;
425 }
426 if (iid)
427 {
428 /* IMAP, or SPLIT with IMAP */
429 EXEC SQL SELECT f.label, m.name INTO :fs, :mach
430 FROM filesys f, machine m
431 WHERE f.filsys_id = :iid AND f.mach_id = m.mach_id;
432 if (sqlca.sqlcode)
433 return MR_FILESYS;
434 }
435 if (pid)
436 {
437 /* POP, or SPLIT with POP */
438 EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
439 WHERE u.users_id = :users_id AND u.pop_id = m.mach_id;
440 if (sqlca.sqlcode)
441 return MR_MACHINE;
442 }
443
444 free(argv[2]);
445 free(argv[3]);
446
447 /* Now assemble the right answer. */
448 if (!strcmp(ptype, "POP"))
449 {
450 argv[2] = xstrdup(strtrim(mach));
451 argv[3] = xmalloc(strlen(argv[0]) + strlen(argv[2]) + 2);
452 sprintf(argv[3], "%s@%s", argv[0], argv[2]);
453 }
454 else if (!strcmp(ptype, "SMTP"))
455 {
456 argv[2] = xstrdup(strtrim(str));
457 argv[3] = xstrdup(str);
458 }
459 else if (!strcmp(ptype, "IMAP"))
460 {
461 argv[2] = xstrdup(strtrim(fs));
462 argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + 2);
463 sprintf(argv[3], "%s@%s", argv[0], mach);
464 }
465 else if (!strcmp(ptype, "SPLIT"))
466 {
467 argv[2] = xstrdup(strtrim(str));
468 argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) +
469 strlen(str) + 4);
470 sprintf(argv[3], "%s@%s, %s", argv[0], mach, str);
471 }
472 else /* ptype == "NONE" */
473 goto skip;
474
475 if (!strcmp(q->shortname, "gpob"))
476 {
477 sid = atoi(argv[5]);
478 if (sid > 0)
479 status = id_to_name(sid, USERS_TABLE, &argv[5]);
480 else
481 status = id_to_name(-sid, STRINGS_TABLE, &argv[5]);
482 if (status && status != MR_NO_MATCH)
483 return status;
484 }
485
486 (*action)(q->vcnt, argv, actarg);
487 skip:
488 /* free saved data */
489 for (i = 0; i < q->vcnt; i++)
490 free(argv[i]);
491 free(argv);
492 }
493
494 sq_destroy(sq);
495 return MR_SUCCESS;
496}
497
498/* Fix an ace_name, based on its type. */
499
500static int fix_ace(char *type, char **name)
501{
502 int id = atoi(*name);
503
504 if (!strcmp(type, "LIST"))
505 return id_to_name(id, LIST_TABLE, name);
506 else if (!strcmp(type, "USER"))
507 return id_to_name(id, USERS_TABLE, name);
508 else if (!strcmp(type, "KERBEROS"))
509 return id_to_name(id, STRINGS_TABLE, name);
510 else
511 {
512 free(*name);
513 if (!strcmp(type, "NONE"))
514 *name = xstrdup("NONE");
515 else
516 *name = xstrdup("???");
517 return MR_SUCCESS;
518 }
519}
520
521
522/* followup_gsnt: fix the ace_name and modby */
523
524int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
525 int (*action)(int, char *[], void *), void *actarg,
526 client *cl)
527{
528 char **argv;
529 int status, idx;
530
531 if (q->version < 8)
532 idx = 0;
533 else
534 idx = 3;
535
536 while (sq_get_data(sq, &argv))
537 {
538 mr_trim_args(q->vcnt, argv);
539
540 status = fix_ace(argv[7 + idx], &argv[8 + idx]);
541 if (status && status != MR_NO_MATCH)
542 return status;
543 }
544
545 return followup_fix_modby(q, sq, v, action, actarg, cl);
546}
547
548
549/* followup_ghst: fix the ace_name, strings and modby */
550
551int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
552 int (*action)(int, char *[], void *), void *actarg,
553 client *cl)
554{
555 char **argv;
556 int id, status, idx;
557
558 if (q->version < 6)
559 idx = 0;
560 else if (q->version >= 6 && q->version < 8)
561 idx = 1;
562 else
563 idx = 2;
564
565 while (sq_get_data(sq, &argv))
566 {
567 mr_trim_args(q->vcnt, argv);
568
569 id = atoi(argv[13 + idx]);
570 status = id_to_name(id, STRINGS_TABLE, &argv[13 + idx]);
571 if (status)
572 return status;
573 id = atoi(argv[14 + idx]);
574 status = id_to_name(id, STRINGS_TABLE, &argv[14 + idx]);
575 if (status)
576 return status;
577 id = atoi(argv[16 + idx]);
578 if (id < 0)
579 status = id_to_name(-id, STRINGS_TABLE, &argv[16 + idx]);
580 else
581 status = id_to_name(id, USERS_TABLE, &argv[16 + idx]);
582 if (status && status != MR_NO_MATCH)
583 return status;
584
585 status = fix_ace(argv[11 + idx], &argv[12 + idx]);
586 if (status && status != MR_NO_MATCH)
587 return status;
588 }
589
590 return followup_fix_modby(q, sq, v, action, actarg, cl);
591}
592
593
594/* followup_glin: fix the ace_name, modace_name, expiration, and modby */
595
596int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
597 int (*action)(int, char *[], void *), void *actarg,
598 client *cl)
599{
600 char **argv;
601 int status;
602
603 while (sq_get_data(sq, &argv))
604 {
605 mr_trim_args(q->vcnt, argv);
606
607 if (q->version == 2)
608 status = fix_ace(argv[7], &argv[8]);
609 else
610 status = fix_ace(argv[8], &argv[9]);
611 if (status && status != MR_NO_MATCH)
612 return status;
613 if (q->version > 3)
614 {
615 status = fix_ace(argv[10], &argv[11]);
616 if (status && status != MR_NO_MATCH)
617 return status;
618 }
619
620 if (atoi(argv[6]) == -1)
621 {
622 argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
623 strcpy(argv[6], UNIQUE_GID);
624 }
625 }
626
627 return followup_fix_modby(q, sq, v, action, actarg, cl);
628}
629
630/* followup_gsin: fix the ace_name and modby. */
631int followup_gsin(struct query *q, struct save_queue *sq, struct validate *v,
632 int (*action)(int, char *[], void *), void *actarg,
633 client *cl)
634{
635 char **argv;
636 int status;
637
638 while (sq_get_data(sq, &argv))
639 {
640 mr_trim_args(q->vcnt, argv);
641
642 status = fix_ace(argv[11], &argv[12]);
643 if (status && status != MR_NO_MATCH)
644 return status;
645 }
646
647 return followup_fix_modby(q, sq, v, action, actarg, cl);
648}
649
650int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
651 int (*action)(int, char *[], void *), void *actarg,
652 client *cl)
653{
654 char **argv;
655 int status;
656
657 while (sq_get_data(sq, &argv))
658 {
659 mr_trim_args(q->vcnt, argv);
660
661 status = fix_ace(argv[PRINTSERVER_OWNER_TYPE],
662 &argv[PRINTSERVER_OWNER_NAME]);
663 if (status && status != MR_NO_MATCH)
664 return status;
665 }
666
667 return followup_fix_modby(q, sq, v, action, actarg, cl);
668}
669
670
671/* followup_gqot: Fix the entity name, directory name & modby fields
672 * argv[0] = filsys_id
673 * argv[1] = type
674 * argv[2] = entity_id
675 * argv[3] = ascii(quota)
676 */
677
678int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
679 int (*action)(int, char *[], void *), void *actarg,
680 client *cl)
681{
682 int j;
683 char **argv;
684 EXEC SQL BEGIN DECLARE SECTION;
685 int id;
686 char *name, *label;
687 EXEC SQL END DECLARE SECTION;
688 int status, idx;
689
690 if (!strcmp(q->name, "get_quota") ||
691 !strcmp(q->name, "get_quota_by_filesys"))
692 idx = 4;
693 else
694 idx = 3;
695
696 while (sq_get_data(sq, &argv))
697 {
698 if (idx == 4)
699 {
700 switch (argv[1][0])
701 {
702 case 'U':
703 status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
704 break;
705 case 'G':
706 case 'L':
707 status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
708 break;
709 case 'A':
710 free(argv[2]);
711 argv[2] = xstrdup("system:anyuser");
712 break;
713 default:
714 id = atoi(argv[2]);
715 argv[2] = xmalloc(8);
716 sprintf(argv[2], "%d", id);
717 }
718 }
719 id = atoi(argv[idx]);
720 free(argv[idx]);
721 argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
722 name = argv[idx];
723 name[0] = '\0';
724 if (id == 0)
725 {
726 label = argv[0];
727 EXEC SQL SELECT name INTO :name FROM filesys
728 WHERE label = :label;
729 }
730 else
731 {
732 EXEC SQL SELECT dir INTO :name FROM nfsphys
733 WHERE nfsphys_id = :id;
734 }
735 if (sqlca.sqlerrd[2] != 1)
736 sprintf(argv[idx], "#%d", id);
737
738 id = atoi(argv[idx + 3]);
739 if (id > 0)
740 status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
741 else
742 status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
743 if (status && status != MR_NO_MATCH)
744 return status;
745 (*action)(q->vcnt, argv, actarg);
746 for (j = 0; j < q->vcnt; j++)
747 free(argv[j]);
748 free(argv);
749 }
750 sq_destroy(sq);
751 return MR_SUCCESS;
752}
753
754
755/* followup_aqot: Add allocation to nfsphys after creating quota.
756 * argv[0] = filsys_id
757 * argv[1] = type if "add_quota" or "update_quota"
758 * argv[2 or 1] = id
759 * argv[3 or 2] = ascii(quota)
760 */
761
762int followup_aqot(struct query *q, char *argv[], client *cl)
763{
764 EXEC SQL BEGIN DECLARE SECTION;
765 int quota, id, fs, who, physid, table;
766 char *entity, *qtype, *tname;
767 EXEC SQL END DECLARE SECTION;
768 char incr_qual[60];
769 char *incr_argv[2];
770 int status;
771
772 table = q->rtable;
773 tname = table_name[table];
774 fs = *(int *)argv[0];
775 EXEC SQL SELECT phys_id INTO :physid FROM filesys
776 WHERE filsys_id = :fs;
777 if (dbms_errno)
778 return mr_errcode;
779
780 if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
781 {
782 qtype = argv[1];
783 id = *(int *)argv[2];
784 quota = atoi(argv[3]);
785 sprintf(incr_qual, "q.filsys_id = %d", fs);
786 }
787 else
788 {
789 qtype = "USER";
790 id = *(int *)argv[1];
791 quota = atoi(argv[2]);
792 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
793 "q.entity_id = %d", fs, qtype, id);
794 }
795
796 /* quota case of incremental_{before|after} only looks at slot 1 */
797 incr_argv[1] = qtype;
798
799 /* Follows one of many possible gross hacks to fix these particular
800 * conflicts between what is possible in the query table and what
801 * is possible in SQL.
802 */
803 if (q->type == APPEND)
804 {
805 incremental_clear_before();
806 EXEC SQL INSERT INTO quota
807 (filsys_id, type, entity_id, quota, phys_id)
808 VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
809 incremental_after(table, incr_qual, incr_argv);
810 }
811 else
812 {
813 incremental_before(table, incr_qual, incr_argv);
814 EXEC SQL UPDATE quota SET quota = :quota
815 WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
816 status = mr_errcode;
817 incremental_after(table, incr_qual, incr_argv);
818 }
819
820 if (dbms_errno)
821 return mr_errcode;
822 if (q->type == APPEND)
823 {
824 EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
825 WHERE table_name = :tname;
826 }
827 else
828 {
829 EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
830 WHERE table_name = :tname;
831 }
832
833 /* Proceed with original followup */
834 who = cl->client_id;
835 entity = cl->entity;
836
837 EXEC SQL UPDATE quota
838 SET modtime = SYSDATE, modby = :who, modwith = :entity
839 WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
840 EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
841 WHERE nfsphys_id = :physid;
842 if (dbms_errno)
843 return mr_errcode;
844 return MR_SUCCESS;
845}
846
847
848/* Necessitated by the requirement of a correlation name by the incremental
849 * routines, since query table deletes don't provide one.
850 */
851int followup_dqot(struct query *q, char **argv, client *cl)
852{
853 char *qtype;
854 int id, fs, table;
855 char *incr_argv[2];
856 EXEC SQL BEGIN DECLARE SECTION;
857 char incr_qual[80], *tname;
858 EXEC SQL END DECLARE SECTION;
859
860 table = q->rtable;
861 tname = table_name[table];
862 fs = *(int *)argv[0];
863 if (!strcmp(q->shortname, "dqot"))
864 {
865 qtype = argv[1];
866 id = *(int *)argv[2];
867 }
868 else
869 {
870 qtype = "USER";
871 id = *(int *)argv[1];
872 }
873 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
874 fs, qtype, id);
875
876 /* quota case of incremental_{before|after} only looks at slot 1 */
877 incr_argv[1] = qtype;
878
879 incremental_before(table, incr_qual, incr_argv);
880 EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
881 AND q.entity_id = :id;
882 incremental_clear_after();
883
884 if (dbms_errno)
885 return mr_errcode;
886
887 EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
888 WHERE table_name = :tname;
889 return MR_SUCCESS;
890}
891
892/* followup_gzcl:
893 */
894
895int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
896 int (*action)(int, char *[], void *), void *actarg,
897 client *cl)
898{
899 int i, n, status;
900 char **argv;
901
902 if (q->version < 5)
903 n = 8;
904 else
905 n = 10;
906
907 while (sq_get_data(sq, &argv))
908 {
909 mr_trim_args(q->vcnt, argv);
910
911 for (i = 1; i < n; i += 2)
912 {
913 status = fix_ace(argv[i], &argv[i + 1]);
914 if (status && status != MR_NO_MATCH)
915 return status;
916 }
917 }
918
919 return followup_fix_modby(q, sq, v, action, actarg, cl);
920}
921
922
923/* followup_gsha:
924 */
925
926int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
927 int (*action)(int, char *[], void *), void *actarg,
928 client *cl)
929{
930 char **argv;
931 int status;
932
933 while (sq_get_data(sq, &argv))
934 {
935 mr_trim_args(q->vcnt, argv);
936
937 status = fix_ace(argv[1], &argv[2]);
938 if (status && status != MR_NO_MATCH)
939 return status;
940 }
941
942 return followup_fix_modby(q, sq, v, action, actarg, cl);
943}
944
945
946int _sdl_followup(struct query *q, char *argv[], client *cl)
947{
948 if (atoi(argv[0]))
949 EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
950 else
951 EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
952
953 return MR_SUCCESS;
954}
955
956
957int trigger_dcm(struct query *q, char *argv[], client *cl)
958{
959 pid_t pid;
960 char prog[MAXPATHLEN];
961
962 sprintf(prog, "%s/startdcm", BIN_DIR);
963 pid = vfork();
964 switch (pid)
965 {
966 case 0:
967 execl(prog, "startdcm", 0);
968 exit(1);
969
970 case -1:
971 return errno;
972
973 default:
974 return MR_SUCCESS;
975 }
976}
977
978/* followup_gcon: fix the ace_name, memace_name, and modby */
979
980int followup_gcon(struct query *q, struct save_queue *sq, struct validate *v,
981 int (*action)(int, char *[], void *), void *actarg,
982 client *cl)
983{
984 char **argv;
985 int status;
986
987 while (sq_get_data(sq, &argv))
988 {
989 mr_trim_args(q->vcnt, argv);
990
991 status = fix_ace(argv[4], &argv[5]);
992 if (status && status != MR_NO_MATCH)
993 return status;
994
995 status = fix_ace(argv[6], &argv[7]);
996 if (status && status != MR_NO_MATCH)
997 return status;
998 }
999
1000 return followup_fix_modby(q, sq, v, action, actarg, cl);
1001}
1002
1003/* followup_get_user: fix the modby and creator.
1004 * This assumes that the modby and creator fields are always
1005 * in the same relative position in the argv.
1006 */
1007
1008int followup_get_user(struct query *q, struct save_queue *sq, struct
1009 validate *v, int (*action)(int, char *[], void *),
1010 void *actarg, client *cl)
1011{
1012 char **argv;
1013 int i, j, k, status, id;
1014
1015 i = q->vcnt - 4;
1016 j = q->vcnt - 1;
1017 while (sq_get_data(sq, &argv))
1018 {
1019 mr_trim_args(q->vcnt, argv);
1020
1021 id = atoi(argv[i]);
1022 if (id > 0)
1023 status = id_to_name(id, USERS_TABLE, &argv[i]);
1024 else
1025 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1026 if (status && status != MR_NO_MATCH)
1027 return status;
1028
1029 id = atoi(argv[j]);
1030 if (id > 0)
1031 status = id_to_name(id, USERS_TABLE, &argv[j]);
1032 else
1033 status = id_to_name(-id, STRINGS_TABLE, &argv[j]);
1034 if (status && status != MR_NO_MATCH)
1035 return status;
1036
1037 (*action)(q->vcnt, argv, actarg);
1038 for (k = 0; k < q->vcnt; k++)
1039 free(argv[k]);
1040 free(argv);
1041 }
1042 sq_destroy(sq);
1043 return MR_SUCCESS;
1044}
1045
1046
1047
1048
This page took 0.053761 seconds and 5 git commands to generate.