]> andersk Git - moira.git/blob - server/qfollow.pc
bump version number of alis, ulis, and glin, adding support for the
[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, 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
477 static 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
501 int 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
523 int 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
561 int 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, "glin")  && q->version > 2)
570     idx = 8;
571   if (!strcmp(q->shortname, "gsin"))
572     idx = 11;
573
574   while (sq_get_data(sq, &argv))
575     {
576       mr_trim_args(q->vcnt, argv);
577
578       status = fix_ace(argv[idx], &argv[idx + 1]);
579       if (status && status != MR_NO_MATCH)
580         return status;
581
582       if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
583         {
584           argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
585           strcpy(argv[6], UNIQUE_GID);
586         }
587     }
588
589   return followup_fix_modby(q, sq, v, action, actarg, cl);
590 }
591
592 int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
593                   int (*action)(int, char *[], void *), void *actarg,
594                   client *cl)
595 {
596   char **argv;
597   int status;
598
599   while (sq_get_data(sq, &argv))
600     {
601       mr_trim_args(q->vcnt, argv);
602
603       status = fix_ace(argv[PRINTSERVER_OWNER_TYPE],
604                        &argv[PRINTSERVER_OWNER_NAME]);
605       if (status && status != MR_NO_MATCH)
606         return status;
607     }
608
609   return followup_fix_modby(q, sq, v, action, actarg, cl);
610 }
611   
612
613 /* followup_gqot: Fix the entity name, directory name & modby fields
614  *   argv[0] = filsys_id
615  *   argv[1] = type
616  *   argv[2] = entity_id
617  *   argv[3] = ascii(quota)
618  */
619
620 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
621                   int (*action)(int, char *[], void *), void *actarg,
622                   client *cl)
623 {
624   int j;
625   char **argv;
626   EXEC SQL BEGIN DECLARE SECTION;
627   int id;
628   char *name, *label;
629   EXEC SQL END DECLARE SECTION;
630   int status, idx;
631
632   if (!strcmp(q->name, "get_quota") ||
633       !strcmp(q->name, "get_quota_by_filesys"))
634     idx = 4;
635   else
636     idx = 3;
637
638   while (sq_get_data(sq, &argv))
639     {
640       if (idx == 4)
641         {
642           switch (argv[1][0])
643             {
644             case 'U':
645               status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
646               break;
647             case 'G':
648             case 'L':
649               status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
650               break;
651             case 'A':
652               free(argv[2]);
653               argv[2] = xstrdup("system:anyuser");
654               break;
655             default:
656               id = atoi(argv[2]);
657               argv[2] = xmalloc(8);
658               sprintf(argv[2], "%d", id);
659             }
660         }
661       id = atoi(argv[idx]);
662       free(argv[idx]);
663       argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
664       name = argv[idx];
665       name[0] = '\0';
666       if (id == 0)
667         {
668           label = argv[0];
669           EXEC SQL SELECT name INTO :name FROM filesys
670             WHERE label = :label;
671         }
672       else
673         {
674           EXEC SQL SELECT dir INTO :name FROM nfsphys
675             WHERE nfsphys_id = :id;
676         }
677       if (sqlca.sqlerrd[2] != 1)
678         sprintf(argv[idx], "#%d", id);
679
680       id = atoi(argv[idx + 3]);
681       if (id > 0)
682         status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
683       else
684         status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
685       if (status && status != MR_NO_MATCH)
686         return status;
687       (*action)(q->vcnt, argv, actarg);
688       for (j = 0; j < q->vcnt; j++)
689         free(argv[j]);
690       free(argv);
691     }
692   sq_destroy(sq);
693   return MR_SUCCESS;
694 }
695
696
697 /* followup_aqot: Add allocation to nfsphys after creating quota.
698  *   argv[0] = filsys_id
699  *   argv[1] = type if "add_quota" or "update_quota"
700  *   argv[2 or 1] = id
701  *   argv[3 or 2] = ascii(quota)
702  */
703
704 int followup_aqot(struct query *q, char *argv[], client *cl)
705 {
706   EXEC SQL BEGIN DECLARE SECTION;
707   int quota, id, fs, who, physid, table;
708   char *entity, *qtype, *tname;
709   EXEC SQL END DECLARE SECTION;
710   char incr_qual[60];
711   char *incr_argv[2];
712   int status;
713
714   table = q->rtable;
715   tname = table_name[table];
716   fs = *(int *)argv[0];
717   EXEC SQL SELECT phys_id INTO :physid FROM filesys
718     WHERE filsys_id = :fs;
719   if (dbms_errno)
720     return mr_errcode;
721
722   if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
723     {
724       qtype = argv[1];
725       id = *(int *)argv[2];
726       quota = atoi(argv[3]);
727       sprintf(incr_qual, "q.filsys_id = %d", fs);
728     }
729   else
730     {
731       qtype = "USER";
732       id = *(int *)argv[1];
733       quota = atoi(argv[2]);
734       sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
735               "q.entity_id = %d", fs, qtype, id);
736     }
737
738   /* quota case of incremental_{before|after} only looks at slot 1 */
739   incr_argv[1] = qtype;
740
741   /* Follows one of many possible gross hacks to fix these particular
742    * conflicts between what is possible in the query table and what
743    * is possible in SQL.
744    */
745   if (q->type == APPEND)
746     {
747       incremental_clear_before();
748       EXEC SQL INSERT INTO quota
749         (filsys_id, type, entity_id, quota, phys_id)
750         VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
751       incremental_after(table, incr_qual, incr_argv);
752     }
753   else
754     {
755       incremental_before(table, incr_qual, incr_argv);
756       EXEC SQL UPDATE quota SET quota = :quota
757         WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
758       status = mr_errcode;
759       incremental_after(table, incr_qual, incr_argv);
760     }
761
762   if (dbms_errno)
763     return mr_errcode;
764   flush_name(argv[0], table);
765   if (q->type == APPEND)
766     {
767       EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
768         WHERE table_name = :tname;
769     }
770   else
771     {
772       EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
773         WHERE table_name = :tname;
774     }
775
776   /* Proceed with original followup */
777   who = cl->client_id;
778   entity = cl->entity;
779
780   EXEC SQL UPDATE quota
781     SET modtime = SYSDATE, modby = :who, modwith = :entity
782     WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
783   EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
784     WHERE nfsphys_id = :physid;
785   if (dbms_errno)
786     return mr_errcode;
787   return MR_SUCCESS;
788 }
789
790
791 /* Necessitated by the requirement of a correlation name by the incremental
792  * routines, since query table deletes don't provide one.
793  */
794 int followup_dqot(struct query *q, char **argv, client *cl)
795 {
796   char *qtype;
797   int id, fs, table;
798   char *incr_argv[2];
799   EXEC SQL BEGIN DECLARE SECTION;
800   char incr_qual[80], *tname;
801   EXEC SQL END DECLARE SECTION;
802
803   table = q->rtable;
804   tname = table_name[table];
805   fs = *(int *)argv[0];
806   if (!strcmp(q->shortname, "dqot"))
807     {
808       qtype = argv[1];
809       id = *(int *)argv[2];
810     }
811   else
812     {
813       qtype = "USER";
814       id = *(int *)argv[1];
815     }
816   sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
817           fs, qtype, id);
818
819   /* quota case of incremental_{before|after} only looks at slot 1 */
820   incr_argv[1] = qtype;
821
822   incremental_before(table, incr_qual, incr_argv);
823   EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
824     AND q.entity_id = :id;
825   incremental_clear_after();
826
827   if (dbms_errno)
828     return mr_errcode;
829   flush_name(argv[0], table);
830
831   EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
832     WHERE table_name = :tname;
833   return MR_SUCCESS;
834 }
835
836 /* followup_gzcl:
837  */
838
839 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
840                   int (*action)(int, char *[], void *), void *actarg,
841                   client *cl)
842 {
843   int i, status;
844   char **argv;
845
846   while (sq_get_data(sq, &argv))
847     {
848       mr_trim_args(q->vcnt, argv);
849
850       for (i = 1; i < 8; i += 2)
851         {
852           status = fix_ace(argv[i], &argv[i + 1]);
853           if (status && status != MR_NO_MATCH)
854             return status;
855         }
856     }
857
858   return followup_fix_modby(q, sq, v, action, actarg, cl);
859 }
860
861
862 /* followup_gsha:
863  */
864
865 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
866                   int (*action)(int, char *[], void *), void *actarg,
867                   client *cl)
868 {
869   char **argv;
870   int status;
871
872   while (sq_get_data(sq, &argv))
873     {
874       mr_trim_args(q->vcnt, argv);
875
876       status = fix_ace(argv[1], &argv[2]);
877       if (status && status != MR_NO_MATCH)
878         return status;
879     }
880
881   return followup_fix_modby(q, sq, v, action, actarg, cl);
882 }
883
884
885 int _sdl_followup(struct query *q, char *argv[], client *cl)
886 {
887   if (atoi(argv[0]))
888     EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
889   else
890     EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
891
892   return MR_SUCCESS;
893 }
894
895
896 int trigger_dcm(struct query *q, char *argv[], client *cl)
897 {
898   pid_t pid;
899   char prog[MAXPATHLEN];
900
901   sprintf(prog, "%s/startdcm", BIN_DIR);
902   pid = vfork();
903   switch (pid)
904     {
905     case 0:
906       execl(prog, "startdcm", 0);
907       exit(1);
908
909     case -1:
910       return errno;
911
912     default:
913       return MR_SUCCESS;
914     }
915 }
This page took 0.10841 seconds and 5 git commands to generate.