]> andersk Git - moira.git/blob - server/qfollow.dc
Diane Delgado's changes for a fixed table-locking order
[moira.git] / server / qfollow.dc
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Header$
5  *
6  *      Copyright (C) 1987 by the Massachusetts Institute of Technology
7  *      For copying and distribution information, please see the file
8  *      <mit-copyright.h>.
9  *
10  */
11
12 #ifndef lint
13 static char *rcsid_qsupport_dc = "$Header$";
14 #endif lint
15
16 #include <mit-copyright.h>
17 #include "query.h"
18 #include "mr_server.h"
19 #include <ctype.h>
20 #ifdef GDSS
21 #include "gdss.h"
22 #endif /* GDSS */
23 EXEC SQL INCLUDE sqlca;
24 EXEC SQL INCLUDE sqlda;
25 #include "qrtn.h"
26
27 extern char *whoami, *strsave();
28 extern int ingres_errno, mr_errcode;
29
30 EXEC SQL BEGIN DECLARE SECTION;
31 extern char stmt_buf[];
32 EXEC SQL END DECLARE SECTION;
33
34 EXEC SQL WHENEVER SQLERROR CALL ingerr;
35
36
37 /* FOLLOWUP ROUTINES */
38
39 /* generic set_modtime routine.  This takes the table name from the query,
40  * and will update the modtime, modby, and modwho fields in the entry in
41  * the table whose name field matches argv[0].
42  */
43
44 set_modtime(q, argv, cl)
45     struct query *q;
46     char *argv[];
47     client *cl;
48 {
49     char *name, *entity, *table;
50     int who;
51
52     entity = cl->entity;
53     who = cl->client_id;
54     table = q->rtable;
55     name = argv[0];
56
57     sprintf(stmt_buf,"UPDATE %s SET modtime = 'now', modby = %d, modwith = '%s' WHERE %s.name = LEFT('%s',SIZE(%s.name))",table,who,entity,table,name,table);
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 name 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 set_modtime_by_id(q, argv, cl)
70     struct query *q;
71     char **argv;
72     client *cl;
73 {
74     char *entity, *table, *id_name;
75     int who, id;
76
77     entity = cl->entity;
78     who = cl->client_id;
79     table = q->rtable;
80     id_name = q->validate->object_id;
81
82     id = *(int *)argv[0];
83     sprintf(stmt_buf,"UPDATE %s SET modtime = 'now', modby = %d, \
84 modwith = '%s' WHERE %s.%s = %d",table,who,entity,table,id_name,id);
85     EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
86     return(MR_SUCCESS);
87 }
88
89
90 /* Sets the finger modtime on a user record.  The users_id will be in argv[0].
91  */
92
93 set_finger_modtime(q, argv, cl)
94     struct query *q;
95     char *argv[];
96     client *cl;
97 {
98     EXEC SQL BEGIN DECLARE SECTION;
99     int users_id, who;
100     char *entity;
101     EXEC SQL END DECLARE SECTION;
102
103     entity = cl->entity;
104     who = cl->client_id;
105     users_id = *(int *)argv[0];
106
107     EXEC SQL UPDATE users SET fmodtime='now', fmodby = :who, fmodwith = :entity
108       WHERE users.users_id = :users_id;
109
110    return(MR_SUCCESS);
111 }
112
113
114 /* Sets the pobox modtime on a user record.  The users_id will be in argv[0].
115  */
116
117 set_pobox_modtime(q, argv, cl)
118     struct query *q;
119     char **argv;
120     client *cl;
121 {
122     EXEC SQL BEGIN DECLARE SECTION;
123     int users_id, who;
124     char *entity;
125     EXEC SQL END DECLARE SECTION;
126
127     entity = cl->entity;
128     who = cl->client_id;
129     users_id = *(int *)argv[0];
130
131     EXEC SQL UPDATE users SET pmodtime='now', pmodby = :who, pmodwith = :entity
132       WHERE users.users_id = :users_id;
133
134     return(MR_SUCCESS);
135 }
136
137
138 /* Like set_modtime, but uppercases the name first.
139  */
140
141 set_uppercase_modtime(q, argv, cl)
142     struct query *q;
143     char **argv;
144     client *cl;
145 {
146     char *name, *entity, *table;
147     int who;
148
149     entity = cl->entity;
150     who = cl->client_id;
151     table = q->rtable;
152     name = argv[0];
153
154     sprintf(stmt_buf,"UPDATE %s SET modtime = 'now', modby = %d, modwith = '%s' WHERE %s.name = UPPERCASE(LEFT('%s',SIZE(%s.name)))",table,who,entity,table,name,table);
155     EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
156
157     return(MR_SUCCESS);
158 }
159
160
161 /* Sets the modtime on the machine whose mach_id is in argv[0].  This routine
162  * is necessary for add_machine_to_cluster becuase the table that query
163  * operates on is "mcm", not "machine".
164  */
165
166 set_mach_modtime_by_id(q, argv, cl)
167     struct query *q;
168     char **argv;
169     client *cl;
170 {
171     EXEC SQL BEGIN DECLARE SECTION;
172     char *entity;
173     int who, id;
174     EXEC SQL END DECLARE SECTION;
175
176     entity = cl->entity;
177     who = cl->client_id;
178     id = *(int *)argv[0];
179     EXEC SQL UPDATE machine SET modtime='now', modby = :who, modwith = :entity
180       WHERE machine.mach_id = :id;
181
182     return(MR_SUCCESS);
183 }
184
185
186 /* Sets the modtime on the cluster whose mach_id is in argv[0].  This routine
187  * is necessary for add_cluster_data and delete_cluster_data becuase the
188  * table that query operates on is "svc", not "cluster".
189  */
190
191 set_cluster_modtime_by_id(q, argv, cl)
192     struct query *q;
193     char **argv;
194     client *cl;
195 {
196     EXEC SQL BEGIN DECLARE SECTION;
197     char *entity;
198     int who, id;
199     EXEC SQL END DECLARE SECTION;
200
201     entity = cl->entity;
202     who = cl->client_id;
203
204     id = *(int *)argv[0];
205     EXEC SQL UPDATE cluster SET modtime='now', modby = :who, modwith = :entity
206       WHERE cluster.clu_id = :id;
207     return(MR_SUCCESS);
208 }
209
210
211 /* sets the modtime on the serverhost where the service name is in argv[0]
212  * and the mach_id is in argv[1].
213  */
214
215 set_serverhost_modtime(q, argv, cl)
216     struct query *q;
217     char **argv;
218     client *cl;
219 {
220     EXEC SQL BEGIN DECLARE SECTION;
221     char *entity, *serv;
222     int who, id;
223     EXEC SQL END DECLARE SECTION;
224
225     entity = cl->entity;
226     who = cl->client_id;
227
228     serv = argv[0];
229     id = *(int *)argv[1];
230     EXEC SQL UPDATE serverhosts
231       SET modtime = 'now', modby = :who, modwith = :entity
232       WHERE service = :serv AND mach_id = :id;
233     return(MR_SUCCESS);
234 }
235
236
237 /* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
238  * directory name is in argv[1].
239  */
240
241 set_nfsphys_modtime(q, argv, cl)
242     struct query *q;
243     char **argv;
244     client *cl;
245 {
246     EXEC SQL BEGIN DECLARE SECTION;
247     char *entity, *dir;
248     int who, id;
249     EXEC SQL END DECLARE SECTION;
250
251     entity = cl->entity;
252     who = cl->client_id;
253
254     id = *(int *)argv[0];
255     dir = argv[1];
256     EXEC SQL UPDATE nfsphys SET modtime = 'now', modby = :who, modwith = :entity
257       WHERE dir = :dir AND mach_id = :id;
258     return(MR_SUCCESS);
259 }
260
261
262 /* sets the modtime on a filesystem, where argv[0] contains the filesys
263  * label.
264  */
265
266 set_filesys_modtime(q, argv, cl)
267     struct query *q;
268     char *argv[];
269     client *cl;
270 {
271     EXEC SQL BEGIN DECLARE SECTION;
272     char *label, *entity;
273     int who;
274     extern int _var_phys_id;
275
276     EXEC SQL END DECLARE SECTION;
277
278     entity = cl->entity;
279     who = cl->client_id;
280
281     label = argv[0];
282     if (!strcmp(q->shortname, "ufil"))
283       label = argv[1];
284
285     EXEC SQL UPDATE filesys SET modtime = 'now', modby = :who,
286         modwith = :entity, phys_id = :_var_phys_id
287       WHERE label = LEFT(:label,SIZE(label));
288     return(MR_SUCCESS);
289 }
290
291
292 /* sets the modtime on a zephyr class, where argv[0] contains the class
293  * name.
294  */
295
296 set_zephyr_modtime(q, argv, cl)
297     struct query *q;
298     char *argv[];
299     client *cl;
300 {
301     EXEC SQL BEGIN DECLARE SECTION;
302     char *class, *entity;
303     int who;
304     EXEC SQL END DECLARE SECTION;
305
306     entity = cl->entity;
307     who = cl->client_id;
308
309     class = argv[0];
310
311     EXEC SQL UPDATE zephyr SET modtime = 'now', modby = :who, modwith = :entity
312       WHERE class = LEFT(:class,SIZE(class));
313
314     return(MR_SUCCESS);
315 }
316
317
318 /* fixes the modby field.  This will be the second to last thing in the
319  * argv, the argv length is determined from the query structure.  It is
320  * passed as a pointer to an integer.  This will either turn it into a
321  * username, or # + the users_id.
322  */
323 followup_fix_modby(q, sq, v, action, actarg, cl)
324     struct query *q;
325     register struct save_queue *sq;
326     struct validate *v;
327     register int (*action)();
328     register int actarg;
329     client *cl;
330 {
331     register int i, j;
332     char **argv;
333     int id, status;
334
335     i = q->vcnt - 2;
336     while (sq_get_data(sq, &argv)) {
337         id = atoi(argv[i]);
338         if (id > 0)
339           status = id_to_name(id, "USER", &argv[i]);
340         else
341           status = id_to_name(-id, "STRING", &argv[i]);
342         if (status && status != MR_NO_MATCH)
343           return(status);
344         (*action)(q->vcnt, argv, actarg);
345         for (j = 0; j < q->vcnt; j++)
346           free(argv[j]);
347         free(argv);
348     }
349     sq_destroy(sq);
350     return(MR_SUCCESS);
351 }
352
353
354 /* After retrieving a user account, fix the modby field and signature.
355  * The modby field is the second to last thing in the
356  * argv, the argv length is determined from the query structure.  It is
357  * passed as a pointer to an integer.  This will either turn it into a
358  * username, or # + the users_id.  Only "gua*" queries have a signature,
359  * these are ones with U_END return values.  "gub*" queries also use this
360  * routine but don't have a signature.
361  */
362 followup_guax(q, sq, v, action, actarg, cl)
363     struct query *q;
364     register struct save_queue *sq;
365     struct validate *v;
366     register int (*action)();
367     register int actarg;
368     client *cl;
369 {
370     register int i, j;
371     char **argv;
372 #ifdef GDSS
373     unsigned char sigbuf[256];
374     char *kname;
375     SigInfo  si;
376     EXEC SQL BEGIN DECLARE SECTION; 
377     int timestamp, who;
378     char *login;
379     varchar struct { short data_size; char data_buf[257];} rsig;
380     EXEC SQL END DECLARE SECTION; 
381 #endif /* GDSS */
382     int id, status;
383
384     i = q->vcnt - 2;
385     while (sq_get_data(sq, &argv)) {
386 #ifdef DEBUG
387         com_err(whoami, 0, "argv[SIGNATURE] = \"%s\"", argv[U_SIGNATURE]);
388 #endif /* DEBUG */
389         id = atoi(argv[i]);
390         if (id > 0)
391           status = id_to_name(id, "USER", &argv[i]);
392         else
393           status = id_to_name(-id, "STRING", &argv[i]);
394         if (status && status != MR_NO_MATCH)
395           return(status);
396 #ifdef GDSS
397         if (q->vcnt == U_END && strlen(argv[U_SIGNATURE])) {
398             login = argv[U_NAME];
399             EXEC SQL REPEATED SELECT signature, sigdate, sigwho 
400               INTO :rsig, :timestamp, :who FROM users
401               WHERE login = :login;
402             /** What about (INGRES) error handling? **/
403             kname = malloc(1);
404             status = id_to_name(who, "STRING", &kname);
405             si.timestamp = timestamp;
406             si.SigInfoVersion = 0; /* XXXXX this isn't used */
407             kname_parse(si.pname, si.pinst, si.prealm, kname);
408             free(kname);
409             rsig.data_buf[rsig.data_size] = 0;
410             si.rawsig = (unsigned char *)strsave(rsig.data_buf);
411             if (log_flags & LOG_GDSS)
412               com_err(whoami, 0, "rawsig length = %d, sig=\"%s\"", strlen(si.rawsig), si.rawsig);
413             GDSS_Recompose(&si, sigbuf);
414             free(si.rawsig);
415             free(argv[U_SIGNATURE]);
416             argv[U_SIGNATURE] = strsave(sigbuf);
417             if (log_flags & LOG_GDSS)
418               com_err(whoami, 0, "generated signature length %d", strlen(sigbuf));
419         }
420 #endif /* GDSS */
421         (*action)(q->vcnt, argv, actarg);
422         for (j = 0; j < q->vcnt; j++)
423           free(argv[j]);
424         free(argv);
425     }
426     sq_destroy(sq);
427     return(MR_SUCCESS);
428 }
429
430
431 /**
432  ** followup_ausr - add finger and pobox entries, set_user_modtime
433  **
434  ** Inputs:
435  **     argv[0] - login (add_user)
436  **     argv[3] - last name
437  **     argv[4] - first name
438  **     argv[5] - middle name
439  **
440  **/
441
442 followup_ausr(q, argv, cl)
443     struct query *q;
444     char *argv[];
445     client *cl;
446 {
447     EXEC SQL BEGIN DECLARE SECTION;
448     int who, status, id;
449     char *login, *entity, *src, *dst, *name;
450     char fullname[129];
451     EXEC SQL END DECLARE SECTION;
452 #ifdef GDSS
453     char databuf[32], *kname_unparse();
454     EXEC SQL BEGIN DECLARE SECTION;
455     char rawsig[128];
456     int sigwho, timestamp;
457     EXEC SQL END DECLARE SECTION;
458     SigInfo si;
459 #endif /* GDSS */
460
461     /* build fullname */
462     if (strlen(argv[4]) && strlen(argv[5]))
463         sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
464     else if (strlen(argv[4]))
465         sprintf(fullname, "%s %s", argv[4], argv[3]);
466     else
467         sprintf(fullname, "%s", argv[3]);
468
469 #ifdef GDSS
470       if (q->vcnt == U_END && *argv[U_SIGNATURE]) {
471         /* unquote ' chars in signature */
472         for (dst = src = argv[U_SIGNATURE]; *src; ) {
473             if (*src == '\'')
474               src++;
475             *dst++ = *src++;
476         }
477         *dst = 0;
478         sprintf(databuf, "%s:%s", argv[U_NAME], argv[U_MITID]);
479         /* skip bytes for timestamp & kname */
480         si.rawsig = (unsigned char *) rawsig;
481         status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE], &si);
482         if (strlen(rawsig) > mr_sig_length) {
483             com_err(whoami, 0, "GDSS signature would be truncated.");  /** untested **/
484             return(MR_INTERNAL);
485         }
486         if (status == 0) {
487             name = kname_unparse(si.pname, si.pinst, si.prealm);
488             status = name_to_id(name, "STRING", &sigwho);
489             if (status == MR_NO_MATCH) {
490               sigwho=add_string(name);
491             } else if (status)
492               return(status);
493             timestamp = si.timestamp;
494         } else {
495             if (log_flags & LOG_GDSS)
496               hex_dump(argv[U_SIGNATURE]);
497             return(gdss2et(status));
498         }
499       } else {
500         rawsig[0] = 0;
501         sigwho = 0;
502         timestamp = 0;
503       }
504 #endif /* GDSS */
505
506     login = argv[0];
507     who = cl->client_id;
508     entity = cl->entity;
509
510     /* create finger entry, pobox & set modtime on user */
511 #ifdef GDSS
512     EXEC SQL REPEATED UPDATE users
513       SET modtime='now', modby=:who, modwith = :entity,
514           fullname = :fullname, affiliation = type,
515           signature = :rawsig, sigdate = :timestamp, sigwho = :sigwho,
516           fmodtime='now', fmodby = :who, fmodwith = :entity,
517           potype='NONE', pmodtime='now', pmodby = :who, pmodwith = :entity
518       WHERE login = :login;
519 #else /* GDSS */
520     EXEC SQL REPEATED UPDATE users
521       SET modtime='now', modby=:who, modwith = :entity,
522           fullname = :fullname, affiliation = type,
523           fmodtime='now', fmodby = :who, fmodwith = :entity,
524           potype='NONE', pmodtime='now', pmodby = :who, pmodwith = :entity
525       WHERE login = :login;
526 #endif /* GDSS */
527
528     return(MR_SUCCESS);
529 }
530
531
532 /**
533  ** followup_uusr - do signature, set_user_modtime
534  **
535  ** Inputs:
536  **   argv[0] - login (add_user)
537  **   argv[U_SIGNATURE] - sig
538  **
539  **/
540
541 followup_uuac(q, argv, cl)
542     struct query *q;
543     char *argv[];
544     client *cl;
545 {
546     EXEC SQL BEGIN DECLARE SECTION; 
547     int who, status, id;
548     char *entity, *name, *src, *dst;
549     EXEC SQL END DECLARE SECTION; 
550 #ifdef GDSS
551     char databuf[32], *kname_unparse();
552     EXEC SQL BEGIN DECLARE SECTION; 
553     char rawsig[128];
554     char *login;
555     int sigwho, timestamp;
556     EXEC SQL END DECLARE SECTION; 
557     SigInfo si;
558 #endif /* GDSS */
559     
560     id = *(int *)argv[0];
561     who = cl->client_id;
562     entity = cl->entity;
563     
564 #ifdef GDSS
565     if (q->vcnt == U_MODTIME && *argv[U_SIGNATURE + 1]) {
566         /* unquote ' chars in signature */
567         for (dst = src = argv[U_SIGNATURE+1]; *src; ) {
568             if (*src == '\'')
569               src++;
570             *dst++ = *src++;
571         }
572         *dst = 0;
573         login = malloc(1);
574         status = id_to_name(id, "USER", &login);
575         sprintf(databuf, "%s:%s", login, argv[U_MITID+1]);
576         free(login);
577         /* skip bytes for timestamp & kname */
578         si.rawsig = (unsigned char *) rawsig;
579 #ifdef DEBUG
580         com_err(whoami, 0, "verifying sig");
581 #endif /* DEBUG */
582         status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE+1], &si);
583 #ifdef DEBUG
584         com_err(whoami, 0, "verified");
585 #endif /* DEBUG */
586         if (strlen(rawsig) > mr_sig_length) {
587             com_err(whoami, 0, "GDSS signature would be truncated.");  /** untested **/
588             return(MR_INTERNAL);
589         }
590         if (status == 0) {
591             name = kname_unparse(si.pname, si.pinst, si.prealm);
592             status = name_to_id(name, "STRING", &sigwho);
593             if (status == MR_NO_MATCH) {
594               sigwho=add_string(name);
595             } else if (status)
596               return(status);
597             timestamp = si.timestamp;
598         } else {
599             if (log_flags & LOG_GDSS)
600               hex_dump(argv[U_SIGNATURE+1]);
601             return(gdss2et(status));
602         }
603     } else {
604         rawsig[0] = 0;
605         sigwho = 0;
606         timestamp = 0;
607     }
608 #endif /* GDSS */
609  
610     /* create finger entry, pobox & set modtime on user */
611
612 #ifdef GDSS
613     EXEC SQL REPEATED UPDATE users SET modtime='now', modby = :who, modwith = :entity,
614         signature = :rawsig, sigdate = :timestamp, sigwho = :sigwho
615       WHERE users_id = :id;
616 #else /* GDSS */
617     EXEC SQL REPEATED UPDATE users SET modtime='now', modby = :who, modwith = :entity
618       WHERE users_id = :id;
619 #endif /* GDSS */
620     return(MR_SUCCESS);
621 }
622  
623  
624 /* followup_gpob: fixes argv[2] based on the IDs currently there and the
625  * type in argv[1].  Then completes the upcall to the user.
626  *
627  * argv[2] is of the form "123:234" where the first integer is the machine
628  * ID if it is a pop box, and the second is the string ID if it is an SMTP
629  * box.  argv[1] should be "POP", "SMTP", or "NONE".  Boxes of type NONE
630  * are skipped.
631  */
632
633 followup_gpob(q, sq, v, action, actarg, cl)
634     register struct query *q;
635     register struct save_queue *sq;
636     register struct validate *v;
637     register int (*action)();
638     int actarg;
639     client *cl;
640 {
641     char **argv;
642     char *ptype, *p;
643     int mid, sid, status, i;
644
645     /* for each row */
646     while (sq_get_data(sq, &argv)) {
647         mr_trim_args(2, argv);
648         ptype = argv[1];
649         p = index(argv[2], ':');
650         *p++ = 0;
651         mid = atoi(argv[2]);
652         sid = atoi(p);
653
654         if (!strcmp(ptype, "POP")) {
655             status = id_to_name(mid, "MACHINE", &argv[2]);
656             if (status == MR_NO_MATCH)
657               return(MR_MACHINE);
658         } else if (!strcmp(ptype, "SMTP")) {
659             status = id_to_name(sid, "STRING", &argv[2]);
660             if (status == MR_NO_MATCH)
661               return(MR_STRING);
662         } else /* ptype == "NONE" */ {
663             goto skip;
664         }
665         if (status) return(status);
666
667         if (!strcmp(q->shortname, "gpob")) {
668             sid = atoi(argv[4]);
669             if (sid > 0)
670               status = id_to_name(sid, "USER", &argv[4]);
671             else
672               status = id_to_name(-sid, "STRING", &argv[4]);
673         }
674         if (status && status != MR_NO_MATCH) return(status);
675
676         (*action)(q->vcnt, argv, actarg);
677     skip:
678         /* free saved data */
679         for (i = 0; i < q->vcnt; i++)
680             free(argv[i]);
681         free(argv);
682     }
683
684     sq_destroy(sq);
685     return (MR_SUCCESS);
686 }
687
688
689 /* followup_gsnt: fix the ace_name in argv[7].  argv[6] will contain the
690  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[7] into the
691  * proper name based on the type, and repace that string in the argv.
692  * Also fixes the modby field by called followup_fix_modby.
693  */
694
695 followup_gsnt(q, sq, v, action, actarg, cl)
696     register struct query *q;
697     register struct save_queue *sq;
698     register struct validate *v;
699     register int (*action)();
700     int actarg;
701     client *cl;
702 {
703     char **argv, *type;
704     int id, i, idx, status;
705
706     idx = 8;
707
708     while (sq_get_data(sq, &argv)) {
709         mr_trim_args(q->vcnt, argv);
710
711         id = atoi(argv[i = q->vcnt - 2]);
712         if (id > 0)
713           status = id_to_name(id, "USER", &argv[i]);
714         else
715           status = id_to_name(-id, "STRING", &argv[i]);
716         if (status && status != MR_NO_MATCH)
717           return(status);
718
719         id = atoi(argv[idx]);
720         type = argv[idx - 1];
721
722         if (!strcmp(type, "LIST")) {
723             status = id_to_name(id, "LIST", &argv[idx]);
724         } else if (!strcmp(type, "USER")) {
725             status = id_to_name(id, "USER", &argv[idx]);
726         } else if (!strcmp(type, "KERBEROS")) {
727             status = id_to_name(id, "STRING", &argv[idx]);
728         } else if (!strcmp(type, "NONE")) {
729             status = 0;
730             free(argv[idx]);
731             argv[idx] = strsave("NONE");
732         } else {
733             status = 0;
734             free(argv[idx]);
735             argv[idx] = strsave("???");
736         }
737         if (status && status != MR_NO_MATCH)
738           return(status);
739
740         /* send the data */
741         (*action)(q->vcnt, argv, actarg);
742
743         /* free saved data */
744         for (i = 0; i < q->vcnt; i++)
745             free(argv[i]);
746         free(argv);
747     }
748
749     sq_destroy(sq);
750     return (MR_SUCCESS);
751 }
752
753
754 /* followup_ghst: fix the ace_name in argv[12].  argv[11] will contain the
755  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[12] into the
756  * proper name based on the type, and repace that string in the argv.
757  * Also fixes the modby field by called followup_fix_modby.
758  */
759
760 followup_ghst(q, sq, v, action, actarg, cl)
761     register struct query *q;
762     register struct save_queue *sq;
763     register struct validate *v;
764     register int (*action)();
765     int actarg;
766     client *cl;
767 {
768     char **argv, *type;
769     int id, i, idx, status;
770
771     while (sq_get_data(sq, &argv)) {
772         mr_trim_args(q->vcnt, argv);
773
774         id = atoi(argv[i = q->vcnt - 2]);
775         if (id > 0)
776           status = id_to_name(id, "USER", &argv[i]);
777         else
778           status = id_to_name(-id, "STRING", &argv[i]);
779         if (status && status != MR_NO_MATCH)
780           return(status);
781
782         id = atoi(argv[13]);
783         status = id_to_name(id, "STRING", &argv[13]);
784         if (status) return(status);
785         id = atoi(argv[14]);
786         status = id_to_name(id, "STRING", &argv[14]);
787         if (status) return(status);
788         id = atoi(argv[16]);
789         if (id < 0)
790           status = id_to_name(-id, "STRING", &argv[16]);
791         else
792           status = id_to_name(id, "USER", &argv[16]);
793         if (status && status != MR_NO_MATCH)
794           return(status);
795
796         idx = 12;
797         id = atoi(argv[idx]);
798         type = strtrim(argv[idx - 1]);
799
800         if (!strcmp(type, "LIST")) {
801             status = id_to_name(id, "LIST", &argv[idx]);
802         } else if (!strcmp(type, "USER")) {
803             status = id_to_name(id, "USER", &argv[idx]);
804         } else if (!strcmp(type, "KERBEROS")) {
805             status = id_to_name(id, "STRING", &argv[idx]);
806         } else if (!strcmp(type, "NONE")) {
807             status = 0;
808             free(argv[idx]);
809             argv[idx] = strsave("NONE");
810         } else {
811             status = 0;
812             free(argv[idx]);
813             argv[idx] = strsave("???");
814         }
815         if (status && status != MR_NO_MATCH)
816           return(status);
817
818         /* send the data */
819         (*action)(q->vcnt, argv, actarg);
820
821         /* free saved data */
822         for (i = 0; i < q->vcnt; i++)
823             free(argv[i]);
824         free(argv);
825     }
826
827     sq_destroy(sq);
828     return (MR_SUCCESS);
829 }
830
831
832 /* followup_glin: fix the ace_name in argv[8].  argv[7] will contain the
833  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[8] into the
834  * proper name based on the type, and repace that string in the argv.
835  * Also fixes the modby field by called followup_fix_modby.
836  */
837
838 followup_glin(q, sq, v, action, actarg, cl)
839     register struct query *q;
840     register struct save_queue *sq;
841     register struct validate *v;
842     register int (*action)();
843     int actarg;
844     client *cl;
845 {
846     char **argv, *type;
847     int id, i, idx, status;
848
849     idx = 8;
850     if (!strcmp(q->shortname, "gsin"))
851       idx = 12;
852
853     while (sq_get_data(sq, &argv)) {
854         mr_trim_args(q->vcnt, argv);
855
856         id = atoi(argv[i = q->vcnt - 2]);
857         if (id > 0)
858           status = id_to_name(id, "USER", &argv[i]);
859         else
860           status = id_to_name(-id, "STRING", &argv[i]);
861         if (status && status != MR_NO_MATCH)
862           return(status);
863
864         id = atoi(argv[idx]);
865         type = argv[idx - 1];
866
867         if (!strcmp(type, "LIST")) {
868             status = id_to_name(id, "LIST", &argv[idx]);
869         } else if (!strcmp(type, "USER")) {
870             status = id_to_name(id, "USER", &argv[idx]);
871         } else if (!strcmp(type, "KERBEROS")) {
872             status = id_to_name(id, "STRING", &argv[idx]);
873         } else if (!strcmp(type, "NONE")) {
874             status = 0;
875             free(argv[idx]);
876             argv[idx] = strsave("NONE");
877         } else {
878             status = 0;
879             free(argv[idx]);
880             argv[idx] = strsave("???");
881         }
882         if (status && status != MR_NO_MATCH)
883           return(status);
884
885         if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) {
886             argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
887             strcpy(argv[6], UNIQUE_GID);
888         }
889
890         /* send the data */
891         (*action)(q->vcnt, argv, actarg);
892
893         /* free saved data */
894         for (i = 0; i < q->vcnt; i++)
895             free(argv[i]);
896         free(argv);
897     }
898
899     sq_destroy(sq);
900     return (MR_SUCCESS);
901 }
902
903
904 /* followup_gqot: Fix the entity name, directory name & modby fields
905  *   argv[0] = filsys_id
906  *   argv[1] = type
907  *   argv[2] = entity_id
908  *   argv[3] = ascii(quota)
909  */
910
911 followup_gqot(q, sq, v, action, actarg, cl)
912     struct query *q;
913     register struct save_queue *sq;
914     struct validate *v;
915     register int (*action)();
916     register int actarg;
917     client *cl;
918 {
919     register int j;
920     char **argv;
921     EXEC SQL BEGIN DECLARE SECTION;
922     int id;
923     char *name, *label;
924     EXEC SQL END DECLARE SECTION;
925     int status, idx;
926
927     if (!strcmp(q->name, "get_quota") ||
928         !strcmp(q->name, "get_quota_by_filesys"))
929       idx = 4;
930     else
931       idx = 3;
932     while (sq_get_data(sq, &argv)) {
933         if (idx == 4) {
934             switch (argv[1][0]) {
935             case 'U':
936                 status = id_to_name(atoi(argv[2]), "USER", &argv[2]);
937                 break;
938             case 'G':
939             case 'L':
940                 status = id_to_name(atoi(argv[2]), "LIST", &argv[2]);
941                 break;
942             case 'A':
943                 free(argv[2]);
944                 argv[2] = strsave("system:anyuser");
945                 break;
946             default:
947                 id = atoi(argv[2]);
948                 argv[2] = malloc(8);
949                 sprintf(argv[2], "%d", id);
950             }
951         }
952         id = atoi(argv[idx]);
953         free(argv[idx]);
954         argv[idx] = malloc(256);
955         name = argv[idx];
956         if (id == 0) {
957             label = argv[0];
958             EXEC SQL REPEATED SELECT name INTO :name FROM filesys
959               WHERE label = :label;
960         } else {
961             EXEC SQL REPEATED SELECT dir INTO :name FROM nfsphys
962               WHERE nfsphys_id = :id;
963         }
964         if (sqlca.sqlerrd[2] != 1) {
965             sprintf(argv[idx], "#%d", id);
966         }
967
968         id = atoi(argv[idx+3]);
969         if (id > 0)
970           status = id_to_name(id, "USER", &argv[idx+3]);
971         else
972           status = id_to_name(-id, "STRING", &argv[idx+3]);
973         if (status && status != MR_NO_MATCH)
974           return(status);
975         (*action)(q->vcnt, argv, actarg);
976         for (j = 0; j < q->vcnt; j++)
977           free(argv[j]);
978         free(argv);
979     }
980     sq_destroy(sq);
981     return(MR_SUCCESS);
982 }
983
984
985 /* followup_aqot: Add allocation to nfsphys after creating quota.
986  *   argv[0] = filsys_id
987  *   argv[1] = type if "add_quota" or "update_quota"
988  *   argv[2 or 1] = id
989  *   argv[3 or 2] = ascii(quota)
990  */
991
992 followup_aqot(q, argv, cl)
993     struct query  *q;
994     char **argv;
995     client *cl;
996 {
997     EXEC SQL BEGIN DECLARE SECTION;
998     int quota, id, fs, who, physid;
999     char *entity, *qtype, *table_name;
1000     EXEC SQL END DECLARE SECTION;
1001     char incr_qual[60];
1002     char *incr_argv[2];
1003     int status;
1004
1005     table_name=q->rtable;
1006     fs = *(int *)argv[0];
1007     EXEC SQL REPEATED SELECT phys_id INTO :physid FROM filesys
1008       WHERE filsys_id = :fs;
1009     if(ingres_errno)
1010         return(mr_errcode);
1011
1012     if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot")) {
1013         qtype = argv[1];
1014         id = *(int *)argv[2];
1015         quota = atoi(argv[3]);
1016         sprintf(incr_qual,"q.filsys_id = %d",fs);
1017     } else {
1018         qtype = "USER";
1019         id = *(int *)argv[1];
1020         quota = atoi(argv[2]);
1021         sprintf(incr_qual,"q.filsys_id=%d AND q.type='%s' AND q.entity_id=%d",
1022                 fs,qtype,id);
1023     }
1024
1025     /* quota case of incremental_{before|after} only looks at slot 1 */
1026     incr_argv[1]=qtype;
1027
1028     /* Follows one of many possible gross hacks to fix these particular
1029      * conflicts between what is possible in the query table and what 
1030      * is possible in SQL.    
1031      */
1032     if(q->type==APPEND) {
1033         incremental_clear_before();
1034         EXEC SQL INSERT INTO quota 
1035             (filsys_id, type, entity_id, quota, phys_id) 
1036           VALUES (:fs, :qtype, :id, :quota, :physid);
1037         incremental_after(table_name, incr_qual, incr_argv);    
1038     } else {
1039         incremental_before(table_name, incr_qual, incr_argv);
1040         EXEC SQL UPDATE quota SET quota = :quota
1041           WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
1042         status = mr_errcode;
1043         incremental_after(table_name, incr_qual, incr_argv);
1044     }
1045
1046     if (ingres_errno)
1047         return(mr_errcode);
1048     flush_name(argv[0], q->rtable);  
1049     if(q->type==APPEND) {
1050         EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = 'now'
1051           WHERE table_name = :table_name;
1052     } else {
1053         EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = 'now'
1054           WHERE table_name = :table_name;
1055     }
1056         
1057     /* Proceed with original followup */
1058     who = cl->client_id;
1059     entity = cl->entity;
1060
1061     EXEC SQL REPEATED UPDATE quota
1062       SET modtime = 'now', modby = :who, modwith = :entity
1063       WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1064     EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated + :quota
1065       WHERE nfsphys_id = :physid;
1066     if (ingres_errno) return(mr_errcode);
1067     return(MR_SUCCESS);
1068 }
1069
1070
1071 /* Necessitated by the requirement of a correlation name by the incremental
1072  * routines, since query table deletes don't provide one. 
1073  */
1074 followup_dqot(q,argv,cl)
1075     struct query *q;
1076     char **argv;
1077     struct client *cl;
1078 {
1079     char *qtype;
1080     int id, fs;
1081     char *incr_argv[2];
1082     EXEC SQL BEGIN DECLARE SECTION; 
1083     char incr_qual[80];
1084     char *tblname;
1085     EXEC SQL END DECLARE SECTION; 
1086
1087     fs = *(int *)argv[0];
1088     if (!strcmp(q->shortname, "dqot")) {
1089         qtype = argv[1];
1090         id = *(int *)argv[2];
1091     } else {
1092         qtype = "USER";
1093         id = *(int *)argv[1];
1094     }
1095     sprintf(incr_qual,"q.filsys_id=%d AND q.type='%s' AND q.entity_id=%d",
1096             fs,qtype,id);
1097
1098     /* quota case of incremental_{before|after} only looks at slot 1 */
1099     incr_argv[1]=qtype;
1100
1101     incremental_before(q->rtable, incr_qual, incr_argv);
1102     EXEC SQL DELETE FROM quota q WHERE :incr_qual;
1103     incremental_clear_after();
1104
1105     if (ingres_errno) 
1106         return(mr_errcode);
1107     flush_name(argv[0], q->rtable);
1108
1109     tblname = q->rtable;
1110     EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = 'now'
1111       WHERE table_name = :tblname;
1112     return(MR_SUCCESS);
1113 }
1114
1115
1116 followup_gpce(q, sq, v, action, actarg, cl)
1117     struct query *q;
1118     register struct save_queue *sq;
1119     struct validate *v;
1120     register int (*action)();
1121     register int actarg;
1122     client *cl;
1123 {
1124     register int i, j;
1125     char **argv;
1126     int id, status;
1127
1128     i = q->vcnt - 2;
1129     while (sq_get_data(sq, &argv)) {
1130         id = atoi(argv[PCAP_QSERVER]);
1131         status = id_to_name(id, "MACHINE", &argv[PCAP_QSERVER]);
1132         if (status) return (status);
1133         id = atoi(argv[i]);
1134         if (id > 0)
1135           status = id_to_name(id, "USER", &argv[i]);
1136         else
1137           status = id_to_name(-id, "STRING", &argv[i]);
1138         if (status && status != MR_NO_MATCH)
1139           return(status);
1140         (*action)(q->vcnt, argv, actarg);
1141         for (j = 0; j < q->vcnt; j++)
1142           free(argv[j]);
1143         free(argv);
1144     }
1145     sq_destroy(sq);
1146     return(MR_SUCCESS);
1147 }
1148
1149
1150 /* followup_gzcl:
1151  */
1152
1153 followup_gzcl(q, sq, v, action, actarg, cl)
1154     register struct query *q;
1155     register struct save_queue *sq;
1156     register struct validate *v;
1157     register int (*action)();
1158     int actarg;
1159     client *cl;
1160 {
1161     int id, i, status;
1162     char **argv;
1163
1164     while (sq_get_data(sq, &argv)) {
1165         mr_trim_args(q->vcnt, argv);
1166
1167         id = atoi(argv[i = q->vcnt - 2]);
1168         if (id > 0)
1169           status = id_to_name(id, "USER", &argv[i]);
1170         else
1171           status = id_to_name(-id, "STRING", &argv[i]);
1172         if (status && status != MR_NO_MATCH)
1173           return(status);
1174
1175         for (i = 1; i < 8; i+=2) {
1176             id = atoi(argv[i+1]);
1177             if (!strcmp(argv[i], "LIST")) {
1178                 status = id_to_name(id, "LIST", &argv[i+1]);
1179             } else if (!strcmp(argv[i], "USER")) {
1180                 status = id_to_name(id, "USER", &argv[i+1]);
1181             } else if (!strcmp(argv[i], "KERBEROS")) {
1182                 status = id_to_name(id, "STRING", &argv[i+1]);
1183             } else if (!strcmp(argv[i], "NONE")) {
1184                 status = 0;
1185                 free(argv[i+1]);
1186                 argv[i+1] = strsave("NONE");
1187             } else {
1188                 status = 0;
1189                 free(argv[i+1]);
1190                 argv[i+1] = strsave("???");
1191             }
1192             if (status && status != MR_NO_MATCH)
1193               return(status);
1194         }
1195
1196         /* send the data */
1197         (*action)(q->vcnt, argv, actarg);
1198
1199         /* free saved data */
1200         for (i = 0; i < q->vcnt; i++)
1201             free(argv[i]);
1202         free(argv);
1203     }
1204     sq_destroy(sq);
1205     return(MR_SUCCESS);
1206 }
1207
1208
1209 /* followup_gsha:
1210  */
1211
1212 followup_gsha(q, sq, v, action, actarg, cl)
1213     register struct query *q;
1214     register struct save_queue *sq;
1215     register struct validate *v;
1216     register int (*action)();
1217     int actarg;
1218     client *cl;
1219 {
1220     char **argv;
1221     int i, id, status;
1222
1223     while (sq_get_data(sq, &argv)) {
1224         mr_trim_args(q->vcnt, argv);
1225
1226         id = atoi(argv[4]);
1227         if (id > 0)
1228           status = id_to_name(id, "USER", &argv[4]);
1229         else
1230           status = id_to_name(-id, "STRING", &argv[4]);
1231         if (status && status != MR_NO_MATCH)
1232           return(status);
1233
1234         id = atoi(argv[2]);
1235         if (!strcmp(argv[1], "LIST")) {
1236             status = id_to_name(id, "LIST", &argv[2]);
1237         } else if (!strcmp(argv[1], "USER")) {
1238             status = id_to_name(id, "USER", &argv[2]);
1239         } else if (!strcmp(argv[1], "KERBEROS")) {
1240             status = id_to_name(id, "STRING", &argv[2]);
1241         } else if (!strcmp(argv[1], "NONE")) {
1242             status = 0;
1243             free(argv[2]);
1244             argv[2] = strsave("NONE");
1245         } else {
1246             status = 0;
1247             free(argv[2]);
1248             argv[2] = strsave("???");
1249         }
1250         if (status && status != MR_NO_MATCH)
1251           return(status);
1252
1253         /* send the data */
1254         (*action)(q->vcnt, argv, actarg);
1255
1256         /* free saved data */
1257         for (i = 0; i < q->vcnt; i++)
1258             free(argv[i]);
1259         free(argv);
1260     }
1261     sq_destroy(sq);
1262     return(MR_SUCCESS);
1263 }
1264
1265
1266 int _sdl_followup(q, argv, cl)
1267     struct query *q;
1268     char **argv;
1269     client *cl;
1270 {
1271     int i;
1272     i = atoi(argv[0]);
1273     log_flags = i;
1274     if (i & LOG_SQL) {
1275         EXEC SQL set printqry;
1276     } else {
1277         EXEC SQL set noprintqry;
1278     }
1279     return(MR_SUCCESS);
1280 }
1281
1282
1283 static hex_dump(p)
1284 unsigned  char *p;
1285 {
1286     char buf[BUFSIZ];
1287     int i;
1288
1289     fprintf(stderr, "Size: %d\n", strlen(p));
1290     while (strlen(p) >= 8) {
1291         fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
1292                 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
1293         p += 8;
1294     }
1295     switch (strlen(p)) {
1296     case 7:
1297         fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x\n",
1298                 p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
1299         break;
1300     case 6:
1301         fprintf(stderr, "%02x %02x %02x %02x %02x %02x\n",
1302                 p[0], p[1], p[2], p[3], p[4], p[5]);
1303         break;
1304     case 5:
1305         fprintf(stderr, "%02x %02x %02x %02x %02x\n",
1306                 p[0], p[1], p[2], p[3], p[4]);
1307         break;
1308     case 4:
1309         fprintf(stderr, "%02x %02x %02x %02x\n",
1310                 p[0], p[1], p[2], p[3]);
1311         break;
1312     case 3:
1313         fprintf(stderr, "%02x %02x %02x\n",
1314                 p[0], p[1], p[2]);
1315         break;
1316     case 2:
1317         fprintf(stderr, "%02x %02x\n",
1318                 p[0], p[1]);
1319         break;
1320     case 1:
1321         fprintf(stderr, "%02x\n",
1322                 p[0]);
1323         break;
1324     default:
1325         return;
1326     }
1327 }
1328
This page took 0.615453 seconds and 5 git commands to generate.