]> andersk Git - moira.git/blob - server/qfollow.pc
6ae39f92014324f7d6edcdbc6c4a84e00309f76c
[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 /* sets the modtime on an entry in services table, where argv[0] contains
284  * the service name.
285  */
286
287 int 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  */
311 int 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
349 int 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
389 int 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, eid;
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, exchange_id INTO :pid, :iid, :bid, :eid
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 = eid = 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       if (eid)
444         {
445           /* EXCHANGE, or SPLIT with EXCHANGE */
446           EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
447             WHERE u.users_id = :users_id AND u.exchange_id = m.mach_id;
448           if (sqlca.sqlcode)
449             return MR_MACHINE;
450         }
451
452       free(argv[2]);
453       free(argv[3]);
454
455       /* Now assemble the right answer. */
456       if (!strcmp(ptype, "POP") || !strcmp(ptype, "EXCHANGE"))
457         {
458           argv[2] = xstrdup(strtrim(mach));
459           argv[3] = xmalloc(strlen(argv[0]) + strlen(argv[2]) + 2);
460           sprintf(argv[3], "%s@%s", argv[0], argv[2]);
461         }
462       else if (!strcmp(ptype, "SMTP"))
463         {
464           argv[2] = xstrdup(strtrim(str));
465           argv[3] = xstrdup(str);
466         }
467       else if (!strcmp(ptype, "IMAP"))
468         {
469           argv[2] = xstrdup(strtrim(fs));
470           argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + 2);
471           sprintf(argv[3], "%s@%s", argv[0], mach);
472         }
473       else if (!strcmp(ptype, "SPLIT"))
474         {
475           argv[2] = xstrdup(strtrim(str));
476           argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) +
477                             strlen(str) + 4);
478           sprintf(argv[3], "%s@%s, %s", argv[0], mach, str);
479         }
480       else /* ptype == "NONE" */
481         goto skip;
482
483       if (!strcmp(q->shortname, "gpob"))
484         {
485           sid = atoi(argv[5]);
486           if (sid > 0)
487             status = id_to_name(sid, USERS_TABLE, &argv[5]);
488           else
489             status = id_to_name(-sid, STRINGS_TABLE, &argv[5]);
490           if (status && status != MR_NO_MATCH)
491             return status;
492         }
493
494       (*action)(q->vcnt, argv, actarg);
495     skip:
496       /* free saved data */
497       for (i = 0; i < q->vcnt; i++)
498         free(argv[i]);
499       free(argv);
500     }
501
502   sq_destroy(sq);
503   return MR_SUCCESS;
504 }
505
506 /* Fix an ace_name, based on its type. */
507
508 static int fix_ace(char *type, char **name)
509 {
510   int id = atoi(*name);
511
512   if (!strcmp(type, "LIST"))
513     return id_to_name(id, LIST_TABLE, name);
514   else if (!strcmp(type, "USER"))
515     return id_to_name(id, USERS_TABLE, name);
516   else if (!strcmp(type, "KERBEROS"))
517     return id_to_name(id, STRINGS_TABLE, name);
518   else
519     {
520       free(*name);
521       if (!strcmp(type, "NONE"))
522         *name = xstrdup("NONE");
523       else
524         *name = xstrdup("???");
525       return MR_SUCCESS;
526     }
527 }
528
529
530 /* followup_gsnt: fix the ace_name and modby */
531
532 int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
533                   int (*action)(int, char *[], void *), void *actarg,
534                   client *cl)
535 {
536   char **argv;
537   int status, idx;
538
539   if (q->version < 8)
540     idx = 0;
541   else
542     idx = 3;
543
544   while (sq_get_data(sq, &argv))
545     {
546       mr_trim_args(q->vcnt, argv);
547
548       status = fix_ace(argv[7 + idx], &argv[8 + idx]);
549       if (status && status != MR_NO_MATCH)
550         return status;
551     }
552
553   return followup_fix_modby(q, sq, v, action, actarg, cl);
554 }
555
556
557 /* followup_ghst: fix the ace_name, strings and modby */
558
559 int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
560                   int (*action)(int, char *[], void *), void *actarg,
561                   client *cl)
562 {
563   char **argv;
564   int id, status, idx;
565
566   if (q->version < 6)
567     idx = 0;
568   else if (q->version >= 6 && q->version < 8)
569     idx = 1;
570   else
571     idx = 2;
572
573   while (sq_get_data(sq, &argv))
574     {
575       mr_trim_args(q->vcnt, argv);
576
577       id = atoi(argv[13 + idx]);
578       status = id_to_name(id, STRINGS_TABLE, &argv[13 + idx]);
579       if (status)
580         return status;
581       id = atoi(argv[14 + idx]);
582       status = id_to_name(id, STRINGS_TABLE, &argv[14 + idx]);
583       if (status)
584         return status;
585       id = atoi(argv[16 + idx]);
586       if (id < 0)
587         status = id_to_name(-id, STRINGS_TABLE, &argv[16 + idx]);
588       else
589         status = id_to_name(id, USERS_TABLE, &argv[16 + idx]);
590       if (status && status != MR_NO_MATCH)
591         return status;
592
593       status = fix_ace(argv[11 + idx], &argv[12 + idx]);
594       if (status && status != MR_NO_MATCH)
595         return status;
596     }
597
598   return followup_fix_modby(q, sq, v, action, actarg, cl);
599 }
600
601
602 /* followup_glin: fix the ace_name, modace_name, expiration, and modby */
603
604 int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
605                   int (*action)(int, char *[], void *), void *actarg,
606                   client *cl)
607 {
608   char **argv;
609   int status;
610
611   while (sq_get_data(sq, &argv))
612     {
613       mr_trim_args(q->vcnt, argv);
614
615       if (q->version == 2)
616         status = fix_ace(argv[7], &argv[8]);
617       else if (q->version > 2 && q->version < 10)
618         status = fix_ace(argv[8], &argv[9]);
619       else
620         status = fix_ace(argv[10], &argv[11]);
621
622       if (status && status != MR_NO_MATCH)
623         return status;
624
625       if (q->version > 3)
626         {
627           if (q->version < 10)
628             status = fix_ace(argv[10], &argv[11]);
629           else if (q->version >= 10)
630             status = fix_ace(argv[12], &argv[13]); 
631       
632           if (status && status != MR_NO_MATCH)
633             return status;
634         }
635
636       if (atoi(argv[6]) == -1)
637         {
638           argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
639           strcpy(argv[6], UNIQUE_GID);
640         }
641     }
642
643   return followup_fix_modby(q, sq, v, action, actarg, cl);
644 }
645
646 /* followup_gsin: fix the ace_name and modby. */
647 int followup_gsin(struct query *q, struct save_queue *sq, struct validate *v,
648                   int (*action)(int, char *[], void *), void *actarg,
649                   client *cl)
650 {
651   char **argv;
652   int status;
653
654   while (sq_get_data(sq, &argv))
655     {
656       mr_trim_args(q->vcnt, argv);
657
658       status = fix_ace(argv[11], &argv[12]);
659       if (status && status != MR_NO_MATCH)
660         return status;
661     }
662
663   return followup_fix_modby(q, sq, v, action, actarg, cl);
664 }
665
666 int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
667                   int (*action)(int, char *[], void *), void *actarg,
668                   client *cl)
669 {
670   char **argv;
671   int status;
672
673   while (sq_get_data(sq, &argv))
674     {
675       mr_trim_args(q->vcnt, argv);
676
677       status = fix_ace(argv[PRINTSERVER_OWNER_TYPE],
678                        &argv[PRINTSERVER_OWNER_NAME]);
679       if (status && status != MR_NO_MATCH)
680         return status;
681     }
682
683   return followup_fix_modby(q, sq, v, action, actarg, cl);
684 }
685   
686
687 /* followup_gqot: Fix the entity name, directory name & modby fields
688  *   argv[0] = filsys_id
689  *   argv[1] = type
690  *   argv[2] = entity_id
691  *   argv[3] = ascii(quota)
692  */
693
694 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
695                   int (*action)(int, char *[], void *), void *actarg,
696                   client *cl)
697 {
698   int j;
699   char **argv;
700   EXEC SQL BEGIN DECLARE SECTION;
701   int id;
702   char *name, *label;
703   EXEC SQL END DECLARE SECTION;
704   int status, idx;
705
706   if (!strcmp(q->name, "get_quota") ||
707       !strcmp(q->name, "get_quota_by_filesys"))
708     idx = 4;
709   else
710     idx = 3;
711
712   while (sq_get_data(sq, &argv))
713     {
714       if (idx == 4)
715         {
716           switch (argv[1][0])
717             {
718             case 'U':
719               status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
720               break;
721             case 'G':
722             case 'L':
723               status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
724               break;
725             case 'A':
726               free(argv[2]);
727               argv[2] = xstrdup("system:anyuser");
728               break;
729             default:
730               id = atoi(argv[2]);
731               argv[2] = xmalloc(8);
732               sprintf(argv[2], "%d", id);
733             }
734         }
735       id = atoi(argv[idx]);
736       free(argv[idx]);
737       argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
738       name = argv[idx];
739       name[0] = '\0';
740       if (id == 0)
741         {
742           label = argv[0];
743           EXEC SQL SELECT name INTO :name FROM filesys
744             WHERE label = :label;
745         }
746       else
747         {
748           EXEC SQL SELECT dir INTO :name FROM nfsphys
749             WHERE nfsphys_id = :id;
750         }
751       if (sqlca.sqlerrd[2] != 1)
752         sprintf(argv[idx], "#%d", id);
753
754       id = atoi(argv[idx + 3]);
755       if (id > 0)
756         status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
757       else
758         status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
759       if (status && status != MR_NO_MATCH)
760         return status;
761       (*action)(q->vcnt, argv, actarg);
762       for (j = 0; j < q->vcnt; j++)
763         free(argv[j]);
764       free(argv);
765     }
766   sq_destroy(sq);
767   return MR_SUCCESS;
768 }
769
770
771 /* followup_aqot: Add allocation to nfsphys after creating quota.
772  *   argv[0] = filsys_id
773  *   argv[1] = type if "add_quota" or "update_quota"
774  *   argv[2 or 1] = id
775  *   argv[3 or 2] = ascii(quota)
776  */
777
778 int followup_aqot(struct query *q, char *argv[], client *cl)
779 {
780   EXEC SQL BEGIN DECLARE SECTION;
781   int quota, id, fs, who, physid, table;
782   char *entity, *qtype, *tname;
783   EXEC SQL END DECLARE SECTION;
784   char incr_qual[60];
785   char *incr_argv[2];
786   int status;
787
788   table = q->rtable;
789   tname = table_name[table];
790   fs = *(int *)argv[0];
791   EXEC SQL SELECT phys_id INTO :physid FROM filesys
792     WHERE filsys_id = :fs;
793   if (dbms_errno)
794     return mr_errcode;
795
796   if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
797     {
798       qtype = argv[1];
799       id = *(int *)argv[2];
800       quota = atoi(argv[3]);
801       sprintf(incr_qual, "q.filsys_id = %d", fs);
802     }
803   else
804     {
805       qtype = "USER";
806       id = *(int *)argv[1];
807       quota = atoi(argv[2]);
808       sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
809               "q.entity_id = %d", fs, qtype, id);
810     }
811
812   /* quota case of incremental_{before|after} only looks at slot 1 */
813   incr_argv[1] = qtype;
814
815   /* Follows one of many possible gross hacks to fix these particular
816    * conflicts between what is possible in the query table and what
817    * is possible in SQL.
818    */
819   if (q->type == MR_Q_APPEND)
820     {
821       incremental_clear_before();
822       EXEC SQL INSERT INTO quota
823         (filsys_id, type, entity_id, quota, phys_id)
824         VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
825       incremental_after(table, incr_qual, incr_argv);
826     }
827   else
828     {
829       incremental_before(table, incr_qual, incr_argv);
830       EXEC SQL UPDATE quota SET quota = :quota
831         WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
832       status = mr_errcode;
833       incremental_after(table, incr_qual, incr_argv);
834     }
835
836   if (dbms_errno)
837     return mr_errcode;
838   if (q->type == MR_Q_APPEND)
839     {
840       EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
841         WHERE table_name = :tname;
842     }
843   else
844     {
845       EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
846         WHERE table_name = :tname;
847     }
848
849   /* Proceed with original followup */
850   who = cl->client_id;
851   entity = cl->entity;
852
853   EXEC SQL UPDATE quota
854     SET modtime = SYSDATE, modby = :who, modwith = :entity
855     WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
856   EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
857     WHERE nfsphys_id = :physid;
858   if (dbms_errno)
859     return mr_errcode;
860   return MR_SUCCESS;
861 }
862
863
864 /* Necessitated by the requirement of a correlation name by the incremental
865  * routines, since query table deletes don't provide one.
866  */
867 int followup_dqot(struct query *q, char **argv, client *cl)
868 {
869   char *qtype;
870   int id, fs, table;
871   char *incr_argv[2];
872   EXEC SQL BEGIN DECLARE SECTION;
873   char incr_qual[80], *tname;
874   EXEC SQL END DECLARE SECTION;
875
876   table = q->rtable;
877   tname = table_name[table];
878   fs = *(int *)argv[0];
879   if (!strcmp(q->shortname, "dqot"))
880     {
881       qtype = argv[1];
882       id = *(int *)argv[2];
883     }
884   else
885     {
886       qtype = "USER";
887       id = *(int *)argv[1];
888     }
889   sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
890           fs, qtype, id);
891
892   /* quota case of incremental_{before|after} only looks at slot 1 */
893   incr_argv[1] = qtype;
894
895   incremental_before(table, incr_qual, incr_argv);
896   EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
897     AND q.entity_id = :id;
898   incremental_clear_after();
899
900   if (dbms_errno)
901     return mr_errcode;
902
903   EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
904     WHERE table_name = :tname;
905   return MR_SUCCESS;
906 }
907
908 /* followup_gzcl:
909  */
910
911 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
912                   int (*action)(int, char *[], void *), void *actarg,
913                   client *cl)
914 {
915   int i, n, status;
916   char **argv;
917
918   if (q->version < 5)
919     n = 8;
920   else
921     n = 10;
922
923   while (sq_get_data(sq, &argv))
924     {
925       mr_trim_args(q->vcnt, argv);
926
927       for (i = 1; i < n; i += 2)
928         {
929           status = fix_ace(argv[i], &argv[i + 1]);
930           if (status && status != MR_NO_MATCH)
931             return status;
932         }
933     }
934
935   return followup_fix_modby(q, sq, v, action, actarg, cl);
936 }
937
938
939 /* followup_gsha:
940  */
941
942 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
943                   int (*action)(int, char *[], void *), void *actarg,
944                   client *cl)
945 {
946   char **argv;
947   int status;
948
949   while (sq_get_data(sq, &argv))
950     {
951       mr_trim_args(q->vcnt, argv);
952
953       status = fix_ace(argv[1], &argv[2]);
954       if (status && status != MR_NO_MATCH)
955         return status;
956     }
957
958   return followup_fix_modby(q, sq, v, action, actarg, cl);
959 }
960
961
962 int _sdl_followup(struct query *q, char *argv[], client *cl)
963 {
964   if (atoi(argv[0]))
965     EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
966   else
967     EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
968
969   return MR_SUCCESS;
970 }
971
972
973 int trigger_dcm(struct query *q, char *argv[], client *cl)
974 {
975   pid_t pid;
976   char prog[MAXPATHLEN];
977
978   sprintf(prog, "%s/startdcm", BIN_DIR);
979   pid = vfork();
980   switch (pid)
981     {
982     case 0:
983       execl(prog, "startdcm", 0);
984       exit(1);
985
986     case -1:
987       return errno;
988
989     default:
990       return MR_SUCCESS;
991     }
992 }
993
994 /* followup_gcon: fix the ace_name, memace_name, and modby */
995
996 int followup_gcon(struct query *q, struct save_queue *sq, struct validate *v,
997                   int (*action)(int, char *[], void *), void *actarg,
998                   client *cl)
999 {
1000   char **argv;
1001   int status, idx = 0;
1002
1003   if (q->version >= 9)
1004     idx = 1;
1005
1006   while (sq_get_data(sq, &argv))
1007   {
1008     mr_trim_args(q->vcnt, argv);
1009
1010     status = fix_ace(argv[4 + idx], &argv[5 + idx]);
1011     if (status && status != MR_NO_MATCH)
1012             return status;
1013       
1014           status = fix_ace(argv[6 + idx], &argv[7 + idx]);
1015           if (status && status != MR_NO_MATCH)
1016             return status;
1017         }
1018
1019   return followup_fix_modby(q, sq, v, action, actarg, cl);
1020 }
1021
1022 /* followup_get_user:  fix the modby and creator.
1023  * This assumes that the modby and creator fields are always 
1024  * in the same relative position in the argv.
1025  */
1026
1027 int followup_get_user(struct query *q, struct save_queue *sq, struct 
1028                       validate *v, int (*action)(int, char *[], void *),
1029                       void *actarg, client *cl)
1030 {
1031   char **argv;
1032   int i, j, k, status, id;
1033
1034   i = q->vcnt - 4;
1035   j = q->vcnt - 1;
1036   while (sq_get_data(sq, &argv))
1037     {
1038       mr_trim_args(q->vcnt, argv);
1039
1040       id = atoi(argv[i]);
1041       if (id > 0)
1042         status = id_to_name(id, USERS_TABLE, &argv[i]);
1043       else
1044         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1045       if (status && status != MR_NO_MATCH)
1046         return status;
1047
1048       id = atoi(argv[j]);
1049       if (id > 0)
1050         status = id_to_name(id, USERS_TABLE, &argv[j]);
1051       else
1052         status = id_to_name(-id, STRINGS_TABLE, &argv[j]);
1053       if (status && status != MR_NO_MATCH)
1054         return status;
1055
1056       if (q->version > 11)
1057         {
1058           status = fix_ace(argv[15], &argv[16]);
1059           if (status && status != MR_NO_MATCH)
1060             return status;
1061         }
1062
1063       (*action)(q->vcnt, argv, actarg);
1064       for (k = 0; k < q->vcnt; k++)
1065         free(argv[k]);
1066       free(argv);
1067     }
1068   sq_destroy(sq);
1069   return MR_SUCCESS;
1070 }
This page took 0.107933 seconds and 3 git commands to generate.