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