]> andersk Git - moira.git/blob - server/qfollow.pc
kill GDSS
[moira.git] / server / qfollow.pc
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
21 EXEC SQL INCLUDE sqlca;
22
23 RCSID("$Header$");
24
25 extern char *whoami, *table_name[];
26 extern int dbms_errno, mr_errcode;
27
28 EXEC SQL BEGIN DECLARE SECTION;
29 extern char stmt_buf[];
30 EXEC SQL END DECLARE SECTION;
31
32 EXEC 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
42 int 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
65 int 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
86 int 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
107 int 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
128 int 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
151 int 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
173 int 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
194 int 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
217 int 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
239 int 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
265 int 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  */
289 int 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
327 int 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
366 int 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;
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       if (!strcmp(ptype, "POP"))
387         {
388           EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
389             WHERE u.users_id = :users_id AND u.pop_id = m.mach_id;
390           if (sqlca.sqlcode)
391             return MR_MACHINE;
392           free(argv[2]);
393           argv[2] = xstrdup(strtrim(mach));
394           free(argv[3]);
395           argv[3] = xmalloc(strlen(argv[0]) + strlen(argv[2]) + 2);
396           sprintf(argv[3], "%s@%s", argv[0], argv[2]);
397         }
398       else if (!strcmp(ptype, "SMTP"))
399         {
400           EXEC SQL SELECT s.string INTO :str FROM strings s, users u
401             WHERE u.users_id = :users_id AND u.box_id = s.string_id;
402           if (sqlca.sqlcode)
403             return MR_STRING;
404           free(argv[2]);
405           free(argv[3]);
406           argv[2] = xstrdup(strtrim(str));
407           argv[3] = xstrdup(str);
408         }
409       else if (!strcmp(ptype, "IMAP"))
410         {
411           EXEC SQL SELECT f.label, m.name INTO :fs, :mach
412             FROM filesys f, machine m, users u
413             WHERE u.users_id = :users_id AND f.filsys_id = u.imap_id
414             AND f.mach_id = m.mach_id;
415           if (sqlca.sqlcode)
416             return MR_FILESYS;
417           free(argv[2]);
418           argv[2] = xstrdup(strtrim(fs));
419           free(argv[3]);
420           argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + 2);
421           sprintf(argv[3], "%s@%s", argv[0], mach);
422         }
423       else /* ptype == "NONE" */
424         goto skip;
425
426       if (!strcmp(q->shortname, "gpob"))
427         {
428           sid = atoi(argv[5]);
429           if (sid > 0)
430             status = id_to_name(sid, USERS_TABLE, &argv[5]);
431           else
432             status = id_to_name(-sid, STRINGS_TABLE, &argv[5]);
433           if (status && status != MR_NO_MATCH)
434             return status;
435         }
436
437       (*action)(q->vcnt, argv, actarg);
438     skip:
439       /* free saved data */
440       for (i = 0; i < q->vcnt; i++)
441         free(argv[i]);
442       free(argv);
443     }
444
445   sq_destroy(sq);
446   return MR_SUCCESS;
447 }
448
449 /* Fix an ace_name, based on its type. */
450
451 static int fix_ace(char *type, char **name)
452 {
453   int id = atoi(*name);
454
455   if (!strcmp(type, "LIST"))
456     return id_to_name(id, LIST_TABLE, name);
457   else if (!strcmp(type, "USER"))
458     return id_to_name(id, USERS_TABLE, name);
459   else if (!strcmp(type, "KERBEROS"))
460     return id_to_name(id, STRINGS_TABLE, name);
461   else
462     {
463       free(*name);
464       if (!strcmp(type, "NONE"))
465         *name = xstrdup("NONE");
466       else
467         *name = xstrdup("???");
468       return MR_SUCCESS;
469     }
470 }
471
472
473 /* followup_gsnt: fix the ace_name and modby */
474
475 int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
476                   int (*action)(int, char *[], void *), void *actarg,
477                   client *cl)
478 {
479   char **argv;
480   int status;
481
482   while (sq_get_data(sq, &argv))
483     {
484       mr_trim_args(q->vcnt, argv);
485
486       status = fix_ace(argv[7], &argv[8]);
487       if (status && status != MR_NO_MATCH)
488         return status;
489     }
490
491   return followup_fix_modby(q, sq, v, action, actarg, cl);
492 }
493
494
495 /* followup_ghst: fix the ace_name, strings and modby */
496
497 int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
498                   int (*action)(int, char *[], void *), void *actarg,
499                   client *cl)
500 {
501   char **argv;
502   int id, status;
503
504   while (sq_get_data(sq, &argv))
505     {
506       mr_trim_args(q->vcnt, argv);
507
508       id = atoi(argv[13]);
509       status = id_to_name(id, STRINGS_TABLE, &argv[13]);
510       if (status)
511         return status;
512       id = atoi(argv[14]);
513       status = id_to_name(id, STRINGS_TABLE, &argv[14]);
514       if (status)
515         return status;
516       id = atoi(argv[16]);
517       if (id < 0)
518         status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
519       else
520         status = id_to_name(id, USERS_TABLE, &argv[16]);
521       if (status && status != MR_NO_MATCH)
522         return status;
523
524       status = fix_ace(argv[11], &argv[12]);
525       if (status && status != MR_NO_MATCH)
526         return status;
527     }
528
529   return followup_fix_modby(q, sq, v, action, actarg, cl);
530 }
531
532
533 /* followup_glin: fix the ace_name, modace_name, expiration, and modby */
534
535 int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
536                   int (*action)(int, char *[], void *), void *actarg,
537                   client *cl)
538 {
539   char **argv;
540   int id, i, idx, status;
541
542   idx = 7;
543   if (!strcmp(q->shortname, "gsin"))
544     idx = 11;
545
546   while (sq_get_data(sq, &argv))
547     {
548       mr_trim_args(q->vcnt, argv);
549
550       status = fix_ace(argv[idx], &argv[idx + 1]);
551       if (status && status != MR_NO_MATCH)
552         return status;
553
554       if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
555         {
556           argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
557           strcpy(argv[6], UNIQUE_GID);
558         }
559     }
560
561   return followup_fix_modby(q, sq, v, action, actarg, cl);
562 }
563
564 int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
565                   int (*action)(int, char *[], void *), void *actarg,
566                   client *cl)
567 {
568   char **argv;
569   int status;
570
571   while (sq_get_data(sq, &argv))
572     {
573       mr_trim_args(q->vcnt, argv);
574
575       status = fix_ace(argv[PRINTSERVER_OWNER_TYPE],
576                        &argv[PRINTSERVER_OWNER_NAME]);
577       if (status && status != MR_NO_MATCH)
578         return status;
579     }
580
581   return followup_fix_modby(q, sq, v, action, actarg, cl);
582 }
583   
584
585 /* followup_gqot: Fix the entity name, directory name & modby fields
586  *   argv[0] = filsys_id
587  *   argv[1] = type
588  *   argv[2] = entity_id
589  *   argv[3] = ascii(quota)
590  */
591
592 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
593                   int (*action)(int, char *[], void *), void *actarg,
594                   client *cl)
595 {
596   int j;
597   char **argv;
598   EXEC SQL BEGIN DECLARE SECTION;
599   int id;
600   char *name, *label;
601   EXEC SQL END DECLARE SECTION;
602   int status, idx;
603
604   if (!strcmp(q->name, "get_quota") ||
605       !strcmp(q->name, "get_quota_by_filesys"))
606     idx = 4;
607   else
608     idx = 3;
609
610   while (sq_get_data(sq, &argv))
611     {
612       if (idx == 4)
613         {
614           switch (argv[1][0])
615             {
616             case 'U':
617               status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
618               break;
619             case 'G':
620             case 'L':
621               status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
622               break;
623             case 'A':
624               free(argv[2]);
625               argv[2] = xstrdup("system:anyuser");
626               break;
627             default:
628               id = atoi(argv[2]);
629               argv[2] = xmalloc(8);
630               sprintf(argv[2], "%d", id);
631             }
632         }
633       id = atoi(argv[idx]);
634       free(argv[idx]);
635       argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
636       name = argv[idx];
637       name[0] = '\0';
638       if (id == 0)
639         {
640           label = argv[0];
641           EXEC SQL SELECT name INTO :name FROM filesys
642             WHERE label = :label;
643         }
644       else
645         {
646           EXEC SQL SELECT dir INTO :name FROM nfsphys
647             WHERE nfsphys_id = :id;
648         }
649       if (sqlca.sqlerrd[2] != 1)
650         sprintf(argv[idx], "#%d", id);
651
652       id = atoi(argv[idx + 3]);
653       if (id > 0)
654         status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
655       else
656         status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
657       if (status && status != MR_NO_MATCH)
658         return status;
659       (*action)(q->vcnt, argv, actarg);
660       for (j = 0; j < q->vcnt; j++)
661         free(argv[j]);
662       free(argv);
663     }
664   sq_destroy(sq);
665   return MR_SUCCESS;
666 }
667
668
669 /* followup_aqot: Add allocation to nfsphys after creating quota.
670  *   argv[0] = filsys_id
671  *   argv[1] = type if "add_quota" or "update_quota"
672  *   argv[2 or 1] = id
673  *   argv[3 or 2] = ascii(quota)
674  */
675
676 int followup_aqot(struct query *q, char *argv[], client *cl)
677 {
678   EXEC SQL BEGIN DECLARE SECTION;
679   int quota, id, fs, who, physid, table;
680   char *entity, *qtype, *tname;
681   EXEC SQL END DECLARE SECTION;
682   char incr_qual[60];
683   char *incr_argv[2];
684   int status;
685
686   table = q->rtable;
687   tname = table_name[table];
688   fs = *(int *)argv[0];
689   EXEC SQL SELECT phys_id INTO :physid FROM filesys
690     WHERE filsys_id = :fs;
691   if (dbms_errno)
692     return mr_errcode;
693
694   if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
695     {
696       qtype = argv[1];
697       id = *(int *)argv[2];
698       quota = atoi(argv[3]);
699       sprintf(incr_qual, "q.filsys_id = %d", fs);
700     }
701   else
702     {
703       qtype = "USER";
704       id = *(int *)argv[1];
705       quota = atoi(argv[2]);
706       sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
707               "q.entity_id = %d", fs, qtype, id);
708     }
709
710   /* quota case of incremental_{before|after} only looks at slot 1 */
711   incr_argv[1] = qtype;
712
713   /* Follows one of many possible gross hacks to fix these particular
714    * conflicts between what is possible in the query table and what
715    * is possible in SQL.
716    */
717   if (q->type == APPEND)
718     {
719       incremental_clear_before();
720       EXEC SQL INSERT INTO quota
721         (filsys_id, type, entity_id, quota, phys_id)
722         VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
723       incremental_after(table, incr_qual, incr_argv);
724     }
725   else
726     {
727       incremental_before(table, incr_qual, incr_argv);
728       EXEC SQL UPDATE quota SET quota = :quota
729         WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
730       status = mr_errcode;
731       incremental_after(table, incr_qual, incr_argv);
732     }
733
734   if (dbms_errno)
735     return mr_errcode;
736   flush_name(argv[0], table);
737   if (q->type == APPEND)
738     {
739       EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
740         WHERE table_name = :tname;
741     }
742   else
743     {
744       EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
745         WHERE table_name = :tname;
746     }
747
748   /* Proceed with original followup */
749   who = cl->client_id;
750   entity = cl->entity;
751
752   EXEC SQL UPDATE quota
753     SET modtime = SYSDATE, modby = :who, modwith = :entity
754     WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
755   EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
756     WHERE nfsphys_id = :physid;
757   if (dbms_errno)
758     return mr_errcode;
759   return MR_SUCCESS;
760 }
761
762
763 /* Necessitated by the requirement of a correlation name by the incremental
764  * routines, since query table deletes don't provide one.
765  */
766 int followup_dqot(struct query *q, char **argv, client *cl)
767 {
768   char *qtype;
769   int id, fs, table;
770   char *incr_argv[2];
771   EXEC SQL BEGIN DECLARE SECTION;
772   char incr_qual[80], *tname;
773   EXEC SQL END DECLARE SECTION;
774
775   table = q->rtable;
776   tname = table_name[table];
777   fs = *(int *)argv[0];
778   if (!strcmp(q->shortname, "dqot"))
779     {
780       qtype = argv[1];
781       id = *(int *)argv[2];
782     }
783   else
784     {
785       qtype = "USER";
786       id = *(int *)argv[1];
787     }
788   sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
789           fs, qtype, id);
790
791   /* quota case of incremental_{before|after} only looks at slot 1 */
792   incr_argv[1] = qtype;
793
794   incremental_before(table, incr_qual, incr_argv);
795   EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
796     AND q.entity_id = :id;
797   incremental_clear_after();
798
799   if (dbms_errno)
800     return mr_errcode;
801   flush_name(argv[0], table);
802
803   EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
804     WHERE table_name = :tname;
805   return MR_SUCCESS;
806 }
807
808 /* followup_gzcl:
809  */
810
811 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
812                   int (*action)(int, char *[], void *), void *actarg,
813                   client *cl)
814 {
815   int i, status;
816   char **argv;
817
818   while (sq_get_data(sq, &argv))
819     {
820       mr_trim_args(q->vcnt, argv);
821
822       for (i = 1; i < 8; i += 2)
823         {
824           status = fix_ace(argv[i], &argv[i + 1]);
825           if (status && status != MR_NO_MATCH)
826             return status;
827         }
828     }
829
830   return followup_fix_modby(q, sq, v, action, actarg, cl);
831 }
832
833
834 /* followup_gsha:
835  */
836
837 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
838                   int (*action)(int, char *[], void *), void *actarg,
839                   client *cl)
840 {
841   char **argv;
842   int status;
843
844   while (sq_get_data(sq, &argv))
845     {
846       mr_trim_args(q->vcnt, argv);
847
848       status = fix_ace(argv[1], &argv[2]);
849       if (status && status != MR_NO_MATCH)
850         return status;
851     }
852
853   return followup_fix_modby(q, sq, v, action, actarg, cl);
854 }
855
856
857 int _sdl_followup(struct query *q, char *argv[], client *cl)
858 {
859   if (atoi(argv[0]))
860     EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
861   else
862     EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
863
864   return MR_SUCCESS;
865 }
866
867
868 int trigger_dcm(struct query *q, char *argv[], client *cl)
869 {
870   pid_t pid;
871   char prog[MAXPATHLEN];
872
873   sprintf(prog, "%s/startdcm", BIN_DIR);
874   pid = vfork();
875   switch (pid)
876     {
877     case 0:
878       execl(prog, "startdcm", 0);
879       exit(1);
880
881     case -1:
882       return errno;
883
884     default:
885       return MR_SUCCESS;
886     }
887 }
This page took 0.109862 seconds and 5 git commands to generate.