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