]> andersk Git - moira.git/blame_incremental - server/qfollow.pc
don't free the pointer to the thing we want to free.
[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
284/* fixes the modby field. This will be the second to last thing in the
285 * argv, the argv length is determined from the query structure. It is
286 * passed as a pointer to an integer. This will either turn it into a
287 * username, or # + the users_id.
288 */
289int followup_fix_modby(struct query *q, struct save_queue *sq,
290 struct validate *v, int (*action)(int, char *[], void *),
291 void *actarg, client *cl)
292{
293 int i, j;
294 char **argv;
295 int id, status;
296
297 i = q->vcnt - 2;
298 while (sq_get_data(sq, &argv))
299 {
300 id = atoi(argv[i]);
301 if (id > 0)
302 status = id_to_name(id, USERS_TABLE, &argv[i]);
303 else
304 status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
305 if (status && status != MR_NO_MATCH)
306 return status;
307 (*action)(q->vcnt, argv, actarg);
308 for (j = 0; j < q->vcnt; j++)
309 free(argv[j]);
310 free(argv);
311 }
312 sq_destroy(sq);
313 return MR_SUCCESS;
314}
315
316/**
317 ** followup_ausr - add finger and pobox entries, set_user_modtime
318 **
319 ** Inputs:
320 ** argv[0] - login (add_user)
321 ** argv[3] - last name
322 ** argv[4] - first name
323 ** argv[5] - middle name
324 **
325 **/
326
327int followup_ausr(struct query *q, char *argv[], client *cl)
328{
329 EXEC SQL BEGIN DECLARE SECTION;
330 int who, status;
331 char *login, *entity, *name;
332 char fullname[USERS_FIRST_SIZE + USERS_MIDDLE_SIZE + USERS_LAST_SIZE];
333 EXEC SQL END DECLARE SECTION;
334
335 /* build fullname */
336 if (strlen(argv[4]) && strlen(argv[5]))
337 sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
338 else if (strlen(argv[4]))
339 sprintf(fullname, "%s %s", argv[4], argv[3]);
340 else
341 sprintf(fullname, "%s", argv[3]);
342
343 login = argv[0];
344 who = cl->client_id;
345 entity = cl->entity;
346
347 /* create finger entry, pobox & set modtime on user */
348 EXEC SQL UPDATE users
349 SET modtime = SYSDATE, modby = :who, modwith = :entity,
350 fullname = NVL(:fullname, CHR(0)), affiliation = type,
351 fmodtime = SYSDATE, fmodby = :who, fmodwith = :entity,
352 potype = 'NONE', pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity
353 WHERE login = :login;
354
355 return MR_SUCCESS;
356}
357
358/* followup_gpob: fixes argv[2] and argv[3] based on the pobox type.
359 * Then completes the upcall to the user.
360 *
361 * argv[2] is the users_id on input and should be converted to the
362 * pobox name on output. argv[3] is empty on input and should be
363 * converted to an email address on output.
364 */
365
366int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
367 int (*action)(int, char *[], void *), void *actarg,
368 client *cl)
369{
370 char **argv;
371 char *ptype, *p;
372 int mid, sid, status, i;
373 EXEC SQL BEGIN DECLARE SECTION;
374 int users_id, pid, iid, bid;
375 char mach[MACHINE_NAME_SIZE], fs[FILESYS_LABEL_SIZE];
376 char str[STRINGS_STRING_SIZE];
377 EXEC SQL END DECLARE SECTION;
378
379 /* for each row */
380 while (sq_get_data(sq, &argv))
381 {
382 mr_trim_args(4, argv);
383 ptype = argv[1];
384 users_id = atoi(argv[2]);
385
386 EXEC SQL SELECT pop_id, imap_id, box_id INTO :pid, :iid, :bid
387 FROM users WHERE users_id = :users_id;
388 if (sqlca.sqlcode)
389 return MR_USER;
390
391 if (ptype[0] == 'S')
392 {
393 /* SMTP or SPLIT */
394 EXEC SQL SELECT string INTO :str FROM strings
395 WHERE string_id = :bid;
396 if (sqlca.sqlcode)
397 return MR_STRING;
398
399 /* If SMTP, don't bother fetching IMAP and POP boxes. */
400 if (ptype[1] == 'M')
401 pid = iid = 0;
402 }
403 if (iid)
404 {
405 /* IMAP, or SPLIT with IMAP */
406 EXEC SQL SELECT f.label, m.name INTO :fs, :mach
407 FROM filesys f, machine m
408 WHERE f.filsys_id = :iid AND f.mach_id = m.mach_id;
409 if (sqlca.sqlcode)
410 return MR_FILESYS;
411 }
412 if (pid)
413 {
414 /* POP, or SPLIT with POP */
415 EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
416 WHERE u.users_id = :users_id AND u.pop_id = m.mach_id;
417 if (sqlca.sqlcode)
418 return MR_MACHINE;
419 }
420
421 free(argv[2]);
422 free(argv[3]);
423
424 /* Now assemble the right answer. */
425 if (!strcmp(ptype, "POP"))
426 {
427 argv[2] = xstrdup(strtrim(mach));
428 argv[3] = xmalloc(strlen(argv[0]) + strlen(argv[2]) + 2);
429 sprintf(argv[3], "%s@%s", argv[0], argv[2]);
430 }
431 else if (!strcmp(ptype, "SMTP"))
432 {
433 argv[2] = xstrdup(strtrim(str));
434 argv[3] = xstrdup(str);
435 }
436 else if (!strcmp(ptype, "IMAP"))
437 {
438 argv[2] = xstrdup(strtrim(fs));
439 argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + 2);
440 sprintf(argv[3], "%s@%s", argv[0], mach);
441 }
442 else if (!strcmp(ptype, "SPLIT"))
443 {
444 argv[2] = xstrdup(strtrim(str));
445 argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) +
446 strlen(str) + 4);
447 sprintf(argv[3], "%s@%s, %s", argv[0], mach, str);
448 }
449 else /* ptype == "NONE" */
450 goto skip;
451
452 if (!strcmp(q->shortname, "gpob"))
453 {
454 sid = atoi(argv[5]);
455 if (sid > 0)
456 status = id_to_name(sid, USERS_TABLE, &argv[5]);
457 else
458 status = id_to_name(-sid, STRINGS_TABLE, &argv[5]);
459 if (status && status != MR_NO_MATCH)
460 return status;
461 }
462
463 (*action)(q->vcnt, argv, actarg);
464 skip:
465 /* free saved data */
466 for (i = 0; i < q->vcnt; i++)
467 free(argv[i]);
468 free(argv);
469 }
470
471 sq_destroy(sq);
472 return MR_SUCCESS;
473}
474
475/* Fix an ace_name, based on its type. */
476
477static int fix_ace(char *type, char **name)
478{
479 int id = atoi(*name);
480
481 if (!strcmp(type, "LIST"))
482 return id_to_name(id, LIST_TABLE, name);
483 else if (!strcmp(type, "USER"))
484 return id_to_name(id, USERS_TABLE, name);
485 else if (!strcmp(type, "KERBEROS"))
486 return id_to_name(id, STRINGS_TABLE, name);
487 else
488 {
489 free(*name);
490 if (!strcmp(type, "NONE"))
491 *name = xstrdup("NONE");
492 else
493 *name = xstrdup("???");
494 return MR_SUCCESS;
495 }
496}
497
498
499/* followup_gsnt: fix the ace_name and modby */
500
501int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
502 int (*action)(int, char *[], void *), void *actarg,
503 client *cl)
504{
505 char **argv;
506 int status;
507
508 while (sq_get_data(sq, &argv))
509 {
510 mr_trim_args(q->vcnt, argv);
511
512 status = fix_ace(argv[7], &argv[8]);
513 if (status && status != MR_NO_MATCH)
514 return status;
515 }
516
517 return followup_fix_modby(q, sq, v, action, actarg, cl);
518}
519
520
521/* followup_ghst: fix the ace_name, strings and modby */
522
523int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
524 int (*action)(int, char *[], void *), void *actarg,
525 client *cl)
526{
527 char **argv;
528 int id, status;
529
530 while (sq_get_data(sq, &argv))
531 {
532 mr_trim_args(q->vcnt, argv);
533
534 id = atoi(argv[13]);
535 status = id_to_name(id, STRINGS_TABLE, &argv[13]);
536 if (status)
537 return status;
538 id = atoi(argv[14]);
539 status = id_to_name(id, STRINGS_TABLE, &argv[14]);
540 if (status)
541 return status;
542 id = atoi(argv[16]);
543 if (id < 0)
544 status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
545 else
546 status = id_to_name(id, USERS_TABLE, &argv[16]);
547 if (status && status != MR_NO_MATCH)
548 return status;
549
550 status = fix_ace(argv[11], &argv[12]);
551 if (status && status != MR_NO_MATCH)
552 return status;
553 }
554
555 return followup_fix_modby(q, sq, v, action, actarg, cl);
556}
557
558
559/* followup_glin: fix the ace_name, modace_name, expiration, and modby */
560
561int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
562 int (*action)(int, char *[], void *), void *actarg,
563 client *cl)
564{
565 char **argv;
566 int id, i, idx, status;
567
568 idx = 7;
569 if (!strcmp(q->shortname, "gsin"))
570 idx = 11;
571
572 while (sq_get_data(sq, &argv))
573 {
574 mr_trim_args(q->vcnt, argv);
575
576 status = fix_ace(argv[idx], &argv[idx + 1]);
577 if (status && status != MR_NO_MATCH)
578 return status;
579
580 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
581 {
582 argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
583 strcpy(argv[6], UNIQUE_GID);
584 }
585 }
586
587 return followup_fix_modby(q, sq, v, action, actarg, cl);
588}
589
590int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
591 int (*action)(int, char *[], void *), void *actarg,
592 client *cl)
593{
594 char **argv;
595 int status;
596
597 while (sq_get_data(sq, &argv))
598 {
599 mr_trim_args(q->vcnt, argv);
600
601 status = fix_ace(argv[PRINTSERVER_OWNER_TYPE],
602 &argv[PRINTSERVER_OWNER_NAME]);
603 if (status && status != MR_NO_MATCH)
604 return status;
605 }
606
607 return followup_fix_modby(q, sq, v, action, actarg, cl);
608}
609
610
611/* followup_gqot: Fix the entity name, directory name & modby fields
612 * argv[0] = filsys_id
613 * argv[1] = type
614 * argv[2] = entity_id
615 * argv[3] = ascii(quota)
616 */
617
618int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
619 int (*action)(int, char *[], void *), void *actarg,
620 client *cl)
621{
622 int j;
623 char **argv;
624 EXEC SQL BEGIN DECLARE SECTION;
625 int id;
626 char *name, *label;
627 EXEC SQL END DECLARE SECTION;
628 int status, idx;
629
630 if (!strcmp(q->name, "get_quota") ||
631 !strcmp(q->name, "get_quota_by_filesys"))
632 idx = 4;
633 else
634 idx = 3;
635
636 while (sq_get_data(sq, &argv))
637 {
638 if (idx == 4)
639 {
640 switch (argv[1][0])
641 {
642 case 'U':
643 status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
644 break;
645 case 'G':
646 case 'L':
647 status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
648 break;
649 case 'A':
650 free(argv[2]);
651 argv[2] = xstrdup("system:anyuser");
652 break;
653 default:
654 id = atoi(argv[2]);
655 argv[2] = xmalloc(8);
656 sprintf(argv[2], "%d", id);
657 }
658 }
659 id = atoi(argv[idx]);
660 free(argv[idx]);
661 argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
662 name = argv[idx];
663 name[0] = '\0';
664 if (id == 0)
665 {
666 label = argv[0];
667 EXEC SQL SELECT name INTO :name FROM filesys
668 WHERE label = :label;
669 }
670 else
671 {
672 EXEC SQL SELECT dir INTO :name FROM nfsphys
673 WHERE nfsphys_id = :id;
674 }
675 if (sqlca.sqlerrd[2] != 1)
676 sprintf(argv[idx], "#%d", id);
677
678 id = atoi(argv[idx + 3]);
679 if (id > 0)
680 status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
681 else
682 status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
683 if (status && status != MR_NO_MATCH)
684 return status;
685 (*action)(q->vcnt, argv, actarg);
686 for (j = 0; j < q->vcnt; j++)
687 free(argv[j]);
688 free(argv);
689 }
690 sq_destroy(sq);
691 return MR_SUCCESS;
692}
693
694
695/* followup_aqot: Add allocation to nfsphys after creating quota.
696 * argv[0] = filsys_id
697 * argv[1] = type if "add_quota" or "update_quota"
698 * argv[2 or 1] = id
699 * argv[3 or 2] = ascii(quota)
700 */
701
702int followup_aqot(struct query *q, char *argv[], client *cl)
703{
704 EXEC SQL BEGIN DECLARE SECTION;
705 int quota, id, fs, who, physid, table;
706 char *entity, *qtype, *tname;
707 EXEC SQL END DECLARE SECTION;
708 char incr_qual[60];
709 char *incr_argv[2];
710 int status;
711
712 table = q->rtable;
713 tname = table_name[table];
714 fs = *(int *)argv[0];
715 EXEC SQL SELECT phys_id INTO :physid FROM filesys
716 WHERE filsys_id = :fs;
717 if (dbms_errno)
718 return mr_errcode;
719
720 if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
721 {
722 qtype = argv[1];
723 id = *(int *)argv[2];
724 quota = atoi(argv[3]);
725 sprintf(incr_qual, "q.filsys_id = %d", fs);
726 }
727 else
728 {
729 qtype = "USER";
730 id = *(int *)argv[1];
731 quota = atoi(argv[2]);
732 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
733 "q.entity_id = %d", fs, qtype, id);
734 }
735
736 /* quota case of incremental_{before|after} only looks at slot 1 */
737 incr_argv[1] = qtype;
738
739 /* Follows one of many possible gross hacks to fix these particular
740 * conflicts between what is possible in the query table and what
741 * is possible in SQL.
742 */
743 if (q->type == APPEND)
744 {
745 incremental_clear_before();
746 EXEC SQL INSERT INTO quota
747 (filsys_id, type, entity_id, quota, phys_id)
748 VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
749 incremental_after(table, incr_qual, incr_argv);
750 }
751 else
752 {
753 incremental_before(table, incr_qual, incr_argv);
754 EXEC SQL UPDATE quota SET quota = :quota
755 WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
756 status = mr_errcode;
757 incremental_after(table, incr_qual, incr_argv);
758 }
759
760 if (dbms_errno)
761 return mr_errcode;
762 flush_name(argv[0], table);
763 if (q->type == APPEND)
764 {
765 EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
766 WHERE table_name = :tname;
767 }
768 else
769 {
770 EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
771 WHERE table_name = :tname;
772 }
773
774 /* Proceed with original followup */
775 who = cl->client_id;
776 entity = cl->entity;
777
778 EXEC SQL UPDATE quota
779 SET modtime = SYSDATE, modby = :who, modwith = :entity
780 WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
781 EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
782 WHERE nfsphys_id = :physid;
783 if (dbms_errno)
784 return mr_errcode;
785 return MR_SUCCESS;
786}
787
788
789/* Necessitated by the requirement of a correlation name by the incremental
790 * routines, since query table deletes don't provide one.
791 */
792int followup_dqot(struct query *q, char **argv, client *cl)
793{
794 char *qtype;
795 int id, fs, table;
796 char *incr_argv[2];
797 EXEC SQL BEGIN DECLARE SECTION;
798 char incr_qual[80], *tname;
799 EXEC SQL END DECLARE SECTION;
800
801 table = q->rtable;
802 tname = table_name[table];
803 fs = *(int *)argv[0];
804 if (!strcmp(q->shortname, "dqot"))
805 {
806 qtype = argv[1];
807 id = *(int *)argv[2];
808 }
809 else
810 {
811 qtype = "USER";
812 id = *(int *)argv[1];
813 }
814 sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
815 fs, qtype, id);
816
817 /* quota case of incremental_{before|after} only looks at slot 1 */
818 incr_argv[1] = qtype;
819
820 incremental_before(table, incr_qual, incr_argv);
821 EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
822 AND q.entity_id = :id;
823 incremental_clear_after();
824
825 if (dbms_errno)
826 return mr_errcode;
827 flush_name(argv[0], table);
828
829 EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
830 WHERE table_name = :tname;
831 return MR_SUCCESS;
832}
833
834/* followup_gzcl:
835 */
836
837int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
838 int (*action)(int, char *[], void *), void *actarg,
839 client *cl)
840{
841 int i, status;
842 char **argv;
843
844 while (sq_get_data(sq, &argv))
845 {
846 mr_trim_args(q->vcnt, argv);
847
848 for (i = 1; i < 8; i += 2)
849 {
850 status = fix_ace(argv[i], &argv[i + 1]);
851 if (status && status != MR_NO_MATCH)
852 return status;
853 }
854 }
855
856 return followup_fix_modby(q, sq, v, action, actarg, cl);
857}
858
859
860/* followup_gsha:
861 */
862
863int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
864 int (*action)(int, char *[], void *), void *actarg,
865 client *cl)
866{
867 char **argv;
868 int status;
869
870 while (sq_get_data(sq, &argv))
871 {
872 mr_trim_args(q->vcnt, argv);
873
874 status = fix_ace(argv[1], &argv[2]);
875 if (status && status != MR_NO_MATCH)
876 return status;
877 }
878
879 return followup_fix_modby(q, sq, v, action, actarg, cl);
880}
881
882
883int _sdl_followup(struct query *q, char *argv[], client *cl)
884{
885 if (atoi(argv[0]))
886 EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
887 else
888 EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
889
890 return MR_SUCCESS;
891}
892
893
894int trigger_dcm(struct query *q, char *argv[], client *cl)
895{
896 pid_t pid;
897 char prog[MAXPATHLEN];
898
899 sprintf(prog, "%s/startdcm", BIN_DIR);
900 pid = vfork();
901 switch (pid)
902 {
903 case 0:
904 execl(prog, "startdcm", 0);
905 exit(1);
906
907 case -1:
908 return errno;
909
910 default:
911 return MR_SUCCESS;
912 }
913}
This page took 0.041141 seconds and 5 git commands to generate.