]> andersk Git - moira.git/blob - server/qfollow.dc
lint
[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, *malloc();
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, *malloc();
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, *index();
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, *malloc(), *realloc(), *type;
704     int id, i, idx, status;
705
706     idx = 7;
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_glin: fix the ace_name in argv[8].  argv[7] will contain the
755  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[8] 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_glin(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, *malloc(), *realloc(), *type;
769     int id, i, idx, status;
770
771     idx = 8;
772     if (!strcmp(q->shortname, "gsin"))
773       idx = 12;
774
775     while (sq_get_data(sq, &argv)) {
776         mr_trim_args(q->vcnt, argv);
777
778         id = atoi(argv[i = q->vcnt - 2]);
779         if (id > 0)
780           status = id_to_name(id, "USER", &argv[i]);
781         else
782           status = id_to_name(-id, "STRING", &argv[i]);
783         if (status && status != MR_NO_MATCH)
784           return(status);
785
786         id = atoi(argv[idx]);
787         type = argv[idx - 1];
788
789         if (!strcmp(type, "LIST")) {
790             status = id_to_name(id, "LIST", &argv[idx]);
791         } else if (!strcmp(type, "USER")) {
792             status = id_to_name(id, "USER", &argv[idx]);
793         } else if (!strcmp(type, "KERBEROS")) {
794             status = id_to_name(id, "STRING", &argv[idx]);
795         } else if (!strcmp(type, "NONE")) {
796             status = 0;
797             free(argv[idx]);
798             argv[idx] = strsave("NONE");
799         } else {
800             status = 0;
801             free(argv[idx]);
802             argv[idx] = strsave("???");
803         }
804         if (status && status != MR_NO_MATCH)
805           return(status);
806
807         if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) {
808             argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
809             strcpy(argv[6], UNIQUE_GID);
810         }
811
812         /* send the data */
813         (*action)(q->vcnt, argv, actarg);
814
815         /* free saved data */
816         for (i = 0; i < q->vcnt; i++)
817             free(argv[i]);
818         free(argv);
819     }
820
821     sq_destroy(sq);
822     return (MR_SUCCESS);
823 }
824
825
826 /* followup_gqot: Fix the entity name, directory name & modby fields
827  *   argv[0] = filsys_id
828  *   argv[1] = type
829  *   argv[2] = entity_id
830  *   argv[3] = ascii(quota)
831  */
832
833 followup_gqot(q, sq, v, action, actarg, cl)
834     struct query *q;
835     register struct save_queue *sq;
836     struct validate *v;
837     register int (*action)();
838     register int actarg;
839     client *cl;
840 {
841     register int j;
842     char **argv, *malloc();
843     EXEC SQL BEGIN DECLARE SECTION;
844     int id;
845     char *name, *label;
846     EXEC SQL END DECLARE SECTION;
847     int status, idx;
848
849     if (!strcmp(q->name, "get_quota") ||
850         !strcmp(q->name, "get_quota_by_filesys"))
851       idx = 4;
852     else
853       idx = 3;
854     while (sq_get_data(sq, &argv)) {
855         if (idx == 4) {
856             switch (argv[1][0]) {
857             case 'U':
858                 status = id_to_name(atoi(argv[2]), "USER", &argv[2]);
859                 break;
860             case 'G':
861             case 'L':
862                 status = id_to_name(atoi(argv[2]), "LIST", &argv[2]);
863                 break;
864             case 'A':
865                 free(argv[2]);
866                 argv[2] = strsave("system:anyuser");
867                 break;
868             default:
869                 id = atoi(argv[2]);
870                 argv[2] = malloc(8);
871                 sprintf(argv[2], "%d", id);
872             }
873         }
874         id = atoi(argv[idx]);
875         free(argv[idx]);
876         argv[idx] = malloc(256);
877         name = argv[idx];
878         if (id == 0) {
879             label = argv[0];
880             EXEC SQL REPEATED SELECT name INTO :name FROM filesys
881               WHERE label = :label;
882         } else {
883             EXEC SQL REPEATED SELECT dir INTO :name FROM nfsphys
884               WHERE nfsphys_id = :id;
885         }
886         if (sqlca.sqlerrd[2] != 1) {
887             sprintf(argv[idx], "#%d", id);
888         }
889
890         id = atoi(argv[idx+3]);
891         if (id > 0)
892           status = id_to_name(id, "USER", &argv[idx+3]);
893         else
894           status = id_to_name(-id, "STRING", &argv[idx+3]);
895         if (status && status != MR_NO_MATCH)
896           return(status);
897         (*action)(q->vcnt, argv, actarg);
898         for (j = 0; j < q->vcnt; j++)
899           free(argv[j]);
900         free(argv);
901     }
902     sq_destroy(sq);
903     return(MR_SUCCESS);
904 }
905
906
907 /* followup_aqot: Add allocation to nfsphys after creating quota.
908  *   argv[0] = filsys_id
909  *   argv[1] = type if "add_quota" or "update_quota"
910  *   argv[2 or 1] = id
911  *   argv[3 or 2] = ascii(quota)
912  */
913
914 followup_aqot(q, argv, cl)
915     struct query  *q;
916     char **argv;
917     client *cl;
918 {
919     EXEC SQL BEGIN DECLARE SECTION;
920     int quota, id, fs, who, physid;
921     char *entity, *qtype, *table_name;
922     EXEC SQL END DECLARE SECTION;
923     char incr_qual[60];
924     char *incr_argv[2];
925     int status;
926
927     table_name=q->rtable;
928     fs = *(int *)argv[0];
929     EXEC SQL REPEATED SELECT phys_id INTO :physid FROM filesys
930       WHERE filsys_id = :fs;
931     if(ingres_errno)
932         return(mr_errcode);
933
934     if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot")) {
935         qtype = argv[1];
936         id = *(int *)argv[2];
937         quota = atoi(argv[3]);
938         sprintf(incr_qual,"q.filsys_id = %d",fs);
939     } else {
940         qtype = "USER";
941         id = *(int *)argv[1];
942         quota = atoi(argv[2]);
943         sprintf(incr_qual,"q.filsys_id=%d AND q.type='%s' AND q.entity_id=%d",
944                 fs,qtype,id);
945     }
946
947     /* quota case of incremental_{before|after} only looks at slot 1 */
948     incr_argv[1]=qtype;
949
950     /* Follows one of many possible gross hacks to fix these particular
951      * conflicts between what is possible in the query table and what 
952      * is possible in SQL.    
953      */
954     if(q->type==APPEND) {
955         incremental_clear_before();
956         EXEC SQL INSERT INTO quota 
957             (filsys_id, type, entity_id, quota, phys_id) 
958           VALUES (:fs, :qtype, :id, :quota, :physid);
959         incremental_after(table_name, incr_qual, incr_argv);    
960     } else {
961         incremental_before(table_name, incr_qual, incr_argv);
962         EXEC SQL UPDATE quota SET quota = :quota
963           WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
964         status = mr_errcode;
965         incremental_after(table_name, incr_qual, incr_argv);
966     }
967
968     if (ingres_errno)
969         return(mr_errcode);
970     flush_name(argv[0], q->rtable);  
971     if(q->type==APPEND) {
972         EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = 'now'
973           WHERE table_name = :table_name;
974     } else {
975         EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = 'now'
976           WHERE table_name = :table_name;
977     }
978         
979     /* Proceed with original followup */
980     who = cl->client_id;
981     entity = cl->entity;
982
983     EXEC SQL REPEATED UPDATE quota
984       SET modtime = 'now', modby = :who, modwith = :entity
985       WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
986     EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated + :quota
987       WHERE nfsphys_id = :physid;
988     if (ingres_errno) return(mr_errcode);
989     return(MR_SUCCESS);
990 }
991
992
993 /* Necessitated by the requirement of a correlation name by the incremental
994  * routines, since query table deletes don't provide one. 
995  */
996 followup_dqot(q,argv,cl)
997     struct query *q;
998     char **argv;
999     struct client *cl;
1000 {
1001     char *qtype;
1002     int id, fs;
1003     char *incr_argv[2];
1004     EXEC SQL BEGIN DECLARE SECTION; 
1005     char incr_qual[80];
1006     char *tblname;
1007     EXEC SQL END DECLARE SECTION; 
1008
1009     fs = *(int *)argv[0];
1010     if (!strcmp(q->shortname, "dqot")) {
1011         qtype = argv[1];
1012         id = *(int *)argv[2];
1013     } else {
1014         qtype = "USER";
1015         id = *(int *)argv[1];
1016     }
1017     sprintf(incr_qual,"q.filsys_id=%d AND q.type='%s' AND q.entity_id=%d",
1018             fs,qtype,id);
1019
1020     /* quota case of incremental_{before|after} only looks at slot 1 */
1021     incr_argv[1]=qtype;
1022
1023     incremental_before(q->rtable, incr_qual, incr_argv);
1024     EXEC SQL DELETE FROM quota q WHERE :incr_qual;
1025     incremental_clear_after();
1026
1027     if (ingres_errno) 
1028         return(mr_errcode);
1029     flush_name(argv[0], q->rtable);
1030
1031     tblname = q->rtable;
1032     EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = 'now'
1033       WHERE table_name = :tblname;
1034     return(MR_SUCCESS);
1035 }
1036
1037
1038 followup_gpce(q, sq, v, action, actarg, cl)
1039     struct query *q;
1040     register struct save_queue *sq;
1041     struct validate *v;
1042     register int (*action)();
1043     register int actarg;
1044     client *cl;
1045 {
1046     register int i, j;
1047     char **argv, *malloc();
1048     int id, status;
1049
1050     i = q->vcnt - 2;
1051     while (sq_get_data(sq, &argv)) {
1052         id = atoi(argv[PCAP_QSERVER]);
1053         status = id_to_name(id, "MACHINE", &argv[PCAP_QSERVER]);
1054         if (status) return (status);
1055         id = atoi(argv[i]);
1056         if (id > 0)
1057           status = id_to_name(id, "USER", &argv[i]);
1058         else
1059           status = id_to_name(-id, "STRING", &argv[i]);
1060         if (status && status != MR_NO_MATCH)
1061           return(status);
1062         (*action)(q->vcnt, argv, actarg);
1063         for (j = 0; j < q->vcnt; j++)
1064           free(argv[j]);
1065         free(argv);
1066     }
1067     sq_destroy(sq);
1068     return(MR_SUCCESS);
1069 }
1070
1071
1072 /* followup_gzcl:
1073  */
1074
1075 followup_gzcl(q, sq, v, action, actarg, cl)
1076     register struct query *q;
1077     register struct save_queue *sq;
1078     register struct validate *v;
1079     register int (*action)();
1080     int actarg;
1081     client *cl;
1082 {
1083     int id, i, status;
1084     char **argv;
1085
1086     while (sq_get_data(sq, &argv)) {
1087         mr_trim_args(q->vcnt, argv);
1088
1089         id = atoi(argv[i = q->vcnt - 2]);
1090         if (id > 0)
1091           status = id_to_name(id, "USER", &argv[i]);
1092         else
1093           status = id_to_name(-id, "STRING", &argv[i]);
1094         if (status && status != MR_NO_MATCH)
1095           return(status);
1096
1097         for (i = 1; i < 8; i+=2) {
1098             id = atoi(argv[i+1]);
1099             if (!strcmp(argv[i], "LIST")) {
1100                 status = id_to_name(id, "LIST", &argv[i+1]);
1101             } else if (!strcmp(argv[i], "USER")) {
1102                 status = id_to_name(id, "USER", &argv[i+1]);
1103             } else if (!strcmp(argv[i], "KERBEROS")) {
1104                 status = id_to_name(id, "STRING", &argv[i+1]);
1105             } else if (!strcmp(argv[i], "NONE")) {
1106                 status = 0;
1107                 free(argv[i+1]);
1108                 argv[i+1] = strsave("NONE");
1109             } else {
1110                 status = 0;
1111                 free(argv[i+1]);
1112                 argv[i+1] = strsave("???");
1113             }
1114             if (status && status != MR_NO_MATCH)
1115               return(status);
1116         }
1117
1118         /* send the data */
1119         (*action)(q->vcnt, argv, actarg);
1120
1121         /* free saved data */
1122         for (i = 0; i < q->vcnt; i++)
1123             free(argv[i]);
1124         free(argv);
1125     }
1126     sq_destroy(sq);
1127     return(MR_SUCCESS);
1128 }
1129
1130
1131 /* followup_gsha:
1132  */
1133
1134 followup_gsha(q, sq, v, action, actarg, cl)
1135     register struct query *q;
1136     register struct save_queue *sq;
1137     register struct validate *v;
1138     register int (*action)();
1139     int actarg;
1140     client *cl;
1141 {
1142     char **argv;
1143     int i, id, status;
1144
1145     while (sq_get_data(sq, &argv)) {
1146         mr_trim_args(q->vcnt, argv);
1147
1148         id = atoi(argv[4]);
1149         if (id > 0)
1150           status = id_to_name(id, "USER", &argv[4]);
1151         else
1152           status = id_to_name(-id, "STRING", &argv[4]);
1153         if (status && status != MR_NO_MATCH)
1154           return(status);
1155
1156         id = atoi(argv[2]);
1157         if (!strcmp(argv[1], "LIST")) {
1158             status = id_to_name(id, "LIST", &argv[2]);
1159         } else if (!strcmp(argv[1], "USER")) {
1160             status = id_to_name(id, "USER", &argv[2]);
1161         } else if (!strcmp(argv[1], "KERBEROS")) {
1162             status = id_to_name(id, "STRING", &argv[2]);
1163         } else if (!strcmp(argv[1], "NONE")) {
1164             status = 0;
1165             free(argv[2]);
1166             argv[2] = strsave("NONE");
1167         } else {
1168             status = 0;
1169             free(argv[2]);
1170             argv[2] = strsave("???");
1171         }
1172         if (status && status != MR_NO_MATCH)
1173           return(status);
1174
1175         /* send the data */
1176         (*action)(q->vcnt, argv, actarg);
1177
1178         /* free saved data */
1179         for (i = 0; i < q->vcnt; i++)
1180             free(argv[i]);
1181         free(argv);
1182     }
1183     sq_destroy(sq);
1184     return(MR_SUCCESS);
1185 }
1186
1187
1188 int _sdl_followup(q, argv, cl)
1189     struct query *q;
1190     char **argv;
1191     client *cl;
1192 {
1193     int i;
1194     i = atoi(argv[0]);
1195     log_flags = i;
1196     if (i & LOG_SQL) {
1197         EXEC SQL set printqry;
1198     } else {
1199         EXEC SQL set noprintqry;
1200     }
1201     return(MR_SUCCESS);
1202 }
1203
1204
1205 static hex_dump(p)
1206 unsigned  char *p;
1207 {
1208     char buf[BUFSIZ];
1209     int i;
1210
1211     fprintf(stderr, "Size: %d\n", strlen(p));
1212     while (strlen(p) >= 8) {
1213         fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
1214                 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
1215         p += 8;
1216     }
1217     switch (strlen(p)) {
1218     case 7:
1219         fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x\n",
1220                 p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
1221         break;
1222     case 6:
1223         fprintf(stderr, "%02x %02x %02x %02x %02x %02x\n",
1224                 p[0], p[1], p[2], p[3], p[4], p[5]);
1225         break;
1226     case 5:
1227         fprintf(stderr, "%02x %02x %02x %02x %02x\n",
1228                 p[0], p[1], p[2], p[3], p[4]);
1229         break;
1230     case 4:
1231         fprintf(stderr, "%02x %02x %02x %02x\n",
1232                 p[0], p[1], p[2], p[3]);
1233         break;
1234     case 3:
1235         fprintf(stderr, "%02x %02x %02x\n",
1236                 p[0], p[1], p[2]);
1237         break;
1238     case 2:
1239         fprintf(stderr, "%02x %02x\n",
1240                 p[0], p[1]);
1241         break;
1242     case 1:
1243         fprintf(stderr, "%02x\n",
1244                 p[0]);
1245         break;
1246     default:
1247         return;
1248     }
1249 }
1250
This page took 0.133178 seconds and 5 git commands to generate.