]> andersk Git - moira.git/blob - server/qrtn.qc
a709f57a02bc81085169a4264e48acd92daab7d5
[moira.git] / server / qrtn.qc
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Header$
5  *
6  *      Copyright (C) 1987, 1988 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_qrtn_qc = "$Header$";
14 #endif lint
15
16 #include <mit-copyright.h>
17 #include "query.h"
18 #include "sms_server.h"
19
20 char *Argv[16];
21
22 int ingres_errno = 0;
23 int sms_errcode = 0;
24 ## int query_timeout = 30;
25 extern char *whoami;
26 extern FILE *journal;
27
28 #define INGRES_BAD_INT 4111
29 #define INGRES_BAD_DATE 4302
30 #define INGRES_DEADLOCK 4700
31 #define INGRES_TIMEOUT 4702
32
33 /*
34  * ingerr: (supposedly) called when Ingres indicates an error.
35  * I have not yet been able to get this to work to intercept a
36  * database open error.
37  */
38
39 static int ingerr(num)
40     int *num;
41 {
42     ingres_errno = *num;
43
44     switch (*num) {
45     case INGRES_BAD_INT:
46         sms_errcode = SMS_INTEGER;
47         break;
48     case INGRES_BAD_DATE:
49         sms_errcode = SMS_DATE;
50         break;
51     case INGRES_DEADLOCK:
52         sms_errcode = SMS_DEADLOCK;
53         com_err(whoami, 0, "INGRES deadlock detected");
54         break;
55     case INGRES_TIMEOUT:
56         sms_errcode = SMS_BUSY;
57         com_err(whoami, 0, "timed out getting lock");
58         break;
59     default:
60         sms_errcode = SMS_INGRES_ERR;
61         com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
62         critical_alert("SMS", "SMS server encountered INGRES ERROR %d", *num);
63         return (*num);
64     }
65     return (0);
66 }
67
68 int sms_open_database()
69 {
70     register int i;
71     char *malloc();
72
73     /* initialize local argv */
74     for (i = 0; i < 16; i++)
75         Argv[i] = malloc(ARGLEN);
76     incremental_init();
77
78     IIseterr(ingerr);
79         
80     ingres_errno = 0;
81         
82     /* open the database */
83 ##  ingres sms
84 ##  set lockmode session where level = table, timeout = query_timeout
85 ##  set lockmode on capacls where readlock = shared
86 ##  set lockmode on alias where readlock = shared
87     return ingres_errno;
88 }
89
90 int sms_close_database()
91 {
92 ##  exit
93 }
94
95 sms_check_access(cl, name, argc, argv_ro)
96     client *cl;
97     char *name;
98     int argc;
99     char *argv_ro[];
100 {
101     struct query *q;
102     struct query *get_query_by_name();
103
104     ingres_errno = 0;
105
106     q = get_query_by_name(name, cl->args->sms_version_no);
107     if (q == (struct query *)0)
108         return(SMS_NO_HANDLE);
109
110     return(sms_verify_query(cl, q, argc, argv_ro));
111 }
112
113 sms_process_query(cl, name, argc, argv_ro, action, actarg)
114     client *cl;
115     char *name;
116     int argc;
117     char *argv_ro[];
118     int (*action)();
119     char *actarg;
120 {
121     register struct query *q;
122     register int status;
123     register struct validate *v;
124     char qual[256];
125     char sort[32];
126     char *pqual;
127     char *psort;
128 ##  char *table;
129     struct save_queue *sq;
130     struct query *get_query_by_name();
131     int sq_save_args();
132     struct save_queue *sq_create();
133     char *build_sort();
134
135     ingres_errno = 0;
136
137     /* list queries command */
138     if (!strcmp(name, "_list_queries")) {
139         list_queries(cl->args->sms_version_no, action, actarg);
140         return(SMS_SUCCESS);
141     }
142
143     /* help query command */
144     if (!strcmp(name, "_help")) {
145         if (argc < 1)
146             return(SMS_ARGS);
147         q = get_query_by_name(argv_ro[0], cl->args->sms_version_no);
148         if (q == (struct query *)0) return(SMS_NO_HANDLE);
149         help_query(q, action, actarg);
150         return(SMS_SUCCESS);
151     }
152
153     /* get query structure, return error if named query does not exist */
154     q = get_query_by_name(name, cl->args->sms_version_no);
155     if (q == (struct query *)0) return(SMS_NO_HANDLE);
156     v = q->validate;
157
158     if (q->type != RETRIEVE) {
159 ##      begin transaction
160     }
161
162     /* setup argument vector, verify access and arguments */
163     if ((status = sms_verify_query(cl, q, argc, argv_ro)) != SMS_SUCCESS)
164         goto out;
165
166     /* perform any special query pre-processing */
167     if (v && v->pre_rtn) {
168         status = (*v->pre_rtn)(q, Argv, cl, 0);
169         if (status != SMS_SUCCESS)
170             goto out;
171     }
172
173     switch (q->type) {
174     case RETRIEVE:
175         /* for queries that do not permit wildcarding, check if row
176            uniquely exists */
177         if (v && v->field) {
178             status = validate_row(q, Argv, v);
179             if (status != SMS_EXISTS) break;
180         }
181
182         /* build "where" clause if needed */
183         if (q->qual) {
184             build_qual(q->qual, q->argc, Argv, qual);
185             pqual = qual;
186         } else {
187             pqual = 0;
188         }
189
190         /* build "sort" clause if needed */
191         if (v && v->valobj) {
192             psort = build_sort(v, sort);
193         } else {
194             psort = 0;
195         }
196
197         /* if there is a followup routine, then we must save the results */
198         /* of the first query for use by the followup routine */
199         /* if q->rvar = NULL, perform post_rtn only */
200         if (q->rvar) {
201             if (v && v->post_rtn) {
202                 sq = sq_create();
203                 status = do_retrieve(q, pqual, psort, sq_save_args, sq);
204                 if (status != SMS_SUCCESS) {
205                     sq_destroy(sq);
206                     break;
207                 }
208                 status = (*v->post_rtn)(q, sq, v, action, actarg, cl);
209             } else {
210                 /* normal retrieve */
211                 status = do_retrieve(q, pqual, psort, action, actarg);
212             }
213             if (status != SMS_SUCCESS) break;
214         } else {
215             status = (*v->post_rtn)(q, Argv, cl, action, actarg);
216         }
217
218         break;
219
220     case UPDATE:
221         /* see if row already exists */
222         if (v->field) {
223             status = validate_row(q, Argv, v);
224             if (status != SMS_EXISTS) break;
225         }
226
227         /* build "where" clause and perform update */
228         /* if q->rvar = NULL, perform post_rtn only */
229         if (q->rvar) {
230             build_qual(q->qual, q->argc, Argv, qual);
231             incremental_before(q->rtable, qual, argv_ro);
232             status = do_update(q, &Argv[q->argc], qual, action, actarg);
233             incremental_after(q->rtable, qual, argv_ro);
234             if (status != SMS_SUCCESS) break;
235             table = q->rtable;
236             if (strcmp(q->shortname, "sshi") && strcmp(q->shortname, "ssif")) {
237 ##              repeat replace tblstats (updates = tblstats.updates + 1,
238 ##                                       modtime = "now")
239 ##                  where tblstats.#table = @table
240             }
241         }
242
243         /* execute followup routine (if any) */
244         if (v->post_rtn) status = (*v->post_rtn)(q, Argv, cl);
245
246         break;
247
248     case APPEND:
249         /* see if row already exists */
250         if (v->field) {
251             status = validate_row(q, Argv, v);
252             if (status != SMS_NO_MATCH) break;
253         }
254
255         /* increment id number if necessary */
256         if (v->object_id) {
257             status = set_next_object_id(v->object_id, q->rtable);
258             if (status != SMS_SUCCESS) break;
259         }
260
261         /* build "where" clause if needed */
262         if (q->qual) {
263             build_qual(q->qual, q->argc, Argv, qual);
264             pqual = qual;
265         } else {
266             pqual = 0;
267         }
268
269         /* perform the append */
270         /* if q->rvar = NULL, perform post_rtn only */
271         if (q->rvar) {
272             incremental_clear_before();
273             status = do_append(q, &Argv[q->argc], pqual, action, actarg);
274             if (status != SMS_SUCCESS) break;
275             if (v && v->object_id) {
276                 sprintf(qual, "%s.%s = values.value and values.name = \"%s\"",
277                         q->rvar, v->object_id, v->object_id);
278                 incremental_after(q->rtable, qual, argv_ro);
279             } else
280               incremental_after(q->rtable, pqual, argv_ro);
281
282             table = q->rtable;
283 ##          repeat replace tblstats (appends = tblstats.appends + 1,
284 ##                                   modtime = "now")
285 ##              where tblstats.#table = @table
286         }
287         
288         /* execute followup routine */
289         if (v->post_rtn) status = (*v->post_rtn)(q, Argv, cl);
290         break;
291
292     case DELETE:
293         /* see if row already exists */
294         if (v->field) {
295             status = validate_row(q, Argv, v);
296             if (status != SMS_EXISTS) break;
297         }
298
299         /* build "where" clause and perform delete */
300         /* if q->rvar = NULL, perform post_rtn only */
301         if (q->rvar) {
302             build_qual(q->qual, q->argc, Argv, qual);
303             incremental_before(q->rtable, qual, argv_ro);
304             status = do_delete(q, qual, action, actarg);
305             incremental_clear_after();
306             if (status != SMS_SUCCESS) break;
307             table = q->rtable;
308 ##          repeat replace tblstats (deletes = tblstats.deletes + 1,
309 ##                                   modtime = "now")
310 ##              where tblstats.#table = @table
311         }
312
313         /* execute followup routine */
314         if (v->post_rtn) status = (*v->post_rtn)(q, Argv, cl);
315         break;
316
317     }
318
319 out:
320     if (q->type != RETRIEVE) {
321         if (status == SMS_SUCCESS) {
322 ##          end transaction     /* commit to this */
323             if (journal) {
324                 char buf[1024], *bp;
325                 int i;
326                 extern time_t now;
327
328                 fprintf(journal, "%% %s %s %s",
329                         cl->clname, cl->entity, ctime(&now));
330                 fprintf(journal, "%s[%d] ", q->name, cl->args->sms_version_no);
331                 for (i = 0; i < argc; i++) {
332                     if (i != 0) {
333                         putc(' ', journal);
334                     }
335                     requote(buf, argv_ro[i], sizeof(buf));
336                     fputs(buf, journal);
337                 }
338                 putc('\n', journal);
339                 fflush(journal);
340             }
341             incremental_update();
342         } else {
343             if (ingres_errno != INGRES_DEADLOCK) {
344 ##              abort           /* it never happened */
345             }
346             incremental_flush();
347         }
348 ##      set lockmode session where readlock = system
349     }
350
351     if (status == SMS_SUCCESS && ingres_errno != 0) {
352         critical_alert("SMS", "Server didn't notice INGRES ERROR %d",
353                        ingres_errno);
354         status = SMS_INTERNAL;
355     }
356
357     if (status != SMS_SUCCESS && log_flags & LOG_RES)
358         com_err(whoami, status, " (Query failed)");
359     return(status);
360 }
361
362 build_qual(fmt, argc, argv, qual)
363         char *fmt;
364         int argc;
365         char *argv[];
366         char *qual;
367 {
368     register char *c;
369     register int i;
370     char *args[4];
371     char *index();
372
373     c = fmt;
374     for (i = 0; i < argc; i++) {
375         c = index(c, '%');
376         if (c++ == (char *)0) return(SMS_ARGS);
377         if (*c == 's')
378             args[i] = argv[i];
379         else if (*c == 'd')
380             *(int *)&args[i] = *(int *)argv[i]; /* sigh */
381         else
382             return(SMS_INGRES_ERR);
383     }
384
385     switch (argc) {
386     case 0:
387         strcpy(qual, fmt);
388         break;
389
390     case 1:
391         sprintf(qual, fmt, args[0]);
392         break;
393
394     case 2:
395         sprintf(qual, fmt, args[0], args[1]);
396         break;
397
398     case 3:
399         sprintf(qual, fmt, args[0], args[1], args[2]);
400         break;
401
402     case 4:
403         sprintf(qual, fmt, args[0], args[1], args[2], args[3]);
404         break;
405     }
406     return(SMS_SUCCESS);
407 }
408
409 char *
410 build_sort(v, sort)
411     register struct validate *v;
412     char *sort;
413 {
414     register struct valobj *vo;
415     register int n;
416     char elem[16];
417
418     n = v->objcnt;
419     vo = v->valobj;
420     *sort = 0;
421
422     while (--n >= 0) {
423         if (vo->type == V_SORT) {
424             sprintf(elem, "RET_VAR%d", vo->index + 1);
425             if (*sort) strcat(sort, ", ");
426             strcat(sort, elem);
427         }
428         vo++;
429     }
430
431     return ((*sort) ? sort : 0);
432 }
433
434
435 /* Build arguement vector, verify query and arguments */
436
437 sms_verify_query(cl, q, argc, argv_ro)
438     client *cl;
439     struct query *q;
440     int argc;
441     char *argv_ro[];
442 {
443     register int argreq;
444     register int status;
445     register struct validate *v = q->validate;
446     register int i;
447     register int privileged = 0;
448     int len;
449
450     /* copy the arguments into a local argv that we can modify */
451     if (argc >= QMAXARGS)
452       return(SMS_ARGS);
453     for (i = 0; i < argc; i++) {
454         if ((len = strlen(argv_ro[i])) < ARGLEN)
455             strcpy(Argv[i], argv_ro[i]);
456         else
457             return(SMS_ARG_TOO_LONG);
458         if (Argv[i][len-1] == '\\')
459           return(SMS_BAD_CHAR);
460     }
461
462     /* check initial query access */
463     status = check_query_access(q, Argv, cl);
464     if (status != SMS_SUCCESS && status != SMS_PERM)
465         return(status);
466     if (status == SMS_SUCCESS)
467         privileged++;
468
469     /* check argument count */
470     argreq = q->argc;
471     if (q->type == UPDATE || q->type == APPEND) argreq += q->vcnt;
472     if (argc != argreq) return(SMS_ARGS);
473
474     /* validate arguments */
475     if (v && v->valobj) {
476         status = validate_fields(q, Argv, v->valobj, v->objcnt);
477         if (status != SMS_SUCCESS) return(status);
478     }
479
480     /* perform special query access check */
481     if (!privileged && v && v->acs_rtn) {
482         status = (*v->acs_rtn)(q, Argv, cl);
483         if (status != SMS_SUCCESS && status != SMS_PERM)
484             return(status);
485         if (status == SMS_SUCCESS)
486             privileged++;
487     }
488
489     return(privileged ? SMS_SUCCESS : SMS_PERM);
490 }
491
492
493 /* This routine caches info from the database.  Each query acl is stored
494  * in the query structure, and whether that acl contains everybody.
495  */
496
497 check_query_access(q, argv, cl)
498     struct query *q;
499     char *argv[];
500     client *cl;
501 ##{
502 ##  char *name;
503 ##  int acl_id;
504 ##  int exists;
505 ##  int rowcount;
506 ##  int errorno;
507 ##  static int def_uid;
508     int status;
509     int client_id;
510     char *client_type;
511
512     /* initialize default uid */
513     if (def_uid == 0) {
514 ##      retrieve (def_uid = users.users_id) where users.login = "default"
515     }
516
517     /* get query access control list */
518     if (q->acl != 0)
519       acl_id = q->acl;
520     else {
521         name = q->shortname;
522 ##      repeat retrieve (acl_id = capacls.list_id) where capacls.tag = @name
523 ##      inquire_equel (rowcount = "rowcount", errorno = "errorno")
524         if (errorno != 0) return(SMS_INGRES_ERR);
525         if (rowcount == 0) return(SMS_PERM);
526         q->acl = acl_id;
527
528         /* check for default access */
529 ##      repeat retrieve (exists = any(imembers.#member_id where
530 ##                                    imembers.list_id = @acl_id and
531 ##                                    imembers.member_type = "USER" and
532 ##                                    imembers.#member_id = def_uid))
533         q->everybody = exists;
534     }
535
536     if (q->everybody)
537       return(SMS_SUCCESS);
538
539     if (get_client(cl, &client_type, &client_id) != SMS_SUCCESS)
540       return(SMS_PERM);
541     if (find_member("LIST", acl_id, client_type, client_id, 0))
542       return(SMS_SUCCESS);
543     else
544       return(SMS_PERM);
545 ##}
546
547
548 get_client(cl, client_type, client_id)
549     client *cl;
550     char **client_type;
551     int *client_id;
552 {
553     if (cl->users_id > 0) {
554         *client_id = cl->users_id;
555         *client_type = "USER";
556         return(SMS_SUCCESS);
557     }
558
559     if (cl->client_id < 0) {
560         *client_id = -cl->users_id;
561         *client_type = "KERBEROS";
562         return(SMS_SUCCESS);
563     }
564
565     return(SMS_PERM);
566 }
567
568 ##find_member(list_type, list_id, member_type, member_id)
569     char *list_type;
570 ##  int list_id;
571 ##  char *member_type;
572 ##  int member_id;
573 ##{
574 ##  int exists, errorno;
575
576     if (!strcmp(strtrim(list_type), strtrim(member_type)) &&
577         list_id == member_id)
578         return(1);
579
580     /* see if client is a direct member of list */
581 ##  repeat retrieve (exists = any(imembers.#member_id where 
582 ##                                imembers.#list_id = @list_id and
583 ##                                imembers.#member_type = @member_type and 
584 ##                                imembers.#member_id = @member_id))
585 ##  inquire_equel(errorno = "errorno")
586     if (errorno == 0)
587       return(exists);
588     else
589       return(0);
590 ##}
591
592
593 do_retrieve(q, pqual, psort, action, actarg)
594     register struct query *q;
595     char *pqual;
596     char *psort;
597     int (*action)();
598     char *actarg;
599 ##{
600 ##  char *rvar;
601 ##  char *rtable;
602 ##  char *cqual;
603 ##  char *csort;
604 ##  int rowcount;
605 ##  int errorno;
606     static char **vaddrs = (char **)NULL;
607
608     if (!vaddrs) {
609         register int i;
610
611         if ((vaddrs = (char **)malloc(sizeof(char *) * QMAXARGS)) == NULL) {
612             com_err(whoami, SMS_NO_MEM, "setting up static argv");
613             exit(1);
614         }
615         for (i = 0; i < QMAXARGS; i++) {
616             if ((vaddrs[i] = malloc(QMAXARGSIZE)) == NULL) {
617                 com_err(whoami, SMS_NO_MEM, "setting up static argv");
618                 exit(1);
619             }
620         }
621     }
622
623     if (q->rvar) {
624         rvar = q->rvar;
625         rtable = q->rtable;
626 ##      range of rvar is rtable
627     }
628
629     if (psort) {
630         csort = psort;
631         if (pqual) {
632             cqual = pqual;
633 ##          retrieve unique (param (q->tlist, vaddrs)) where cqual
634 ##                   sort by csort
635 ##          {
636                  (*action)(q->vcnt, vaddrs, actarg);
637 ##          }
638         } else {
639 ##          retrieve unique (param (q->tlist, vaddrs))
640 ##                   sort by csort
641 ##          {
642                  (*action)(q->vcnt, vaddrs, actarg);
643 ##          }
644         }
645
646     } else {
647         if (pqual) {
648             cqual = pqual;
649 ##          retrieve unique (param (q->tlist, vaddrs)) where cqual
650 ##          {
651                  (*action)(q->vcnt, vaddrs, actarg);
652 ##          }
653         } else {
654 ##          retrieve unique (param (q->tlist, vaddrs))
655 ##          {
656                  (*action)(q->vcnt, vaddrs, actarg);
657 ##          }
658         }
659     }
660
661 ##  inquire_equel (rowcount = "rowcount", errorno = "errorno")
662     if (errorno != 0) return(SMS_INGRES_ERR);
663     return ((rowcount == 0) ? SMS_NO_MATCH : SMS_SUCCESS);
664 ##}
665
666 do_update(q, argv, qual, action, actarg)
667     register struct query *q;
668     char *argv[];
669     char *qual;
670     int (*action)();
671     char *actarg;
672 ##{
673 ##  char *rvar;
674 ##  char *rtable;
675 ##  char *cqual;
676 ##  int errorno;
677       
678     rvar = q->rvar;
679     rtable = q->rtable;
680 ##  range of rvar is rtable
681
682     cqual = qual;
683 ##  replace rvar (param (q->tlist, argv))
684 ##  where cqual
685
686 ##  inquire_equel (errorno = "errorno")
687     if (errorno == INGRES_BAD_INT)
688         return(SMS_INTEGER);
689     else if (errorno != 0)
690         return(SMS_INGRES_ERR);
691     return(SMS_SUCCESS);
692 ##}
693
694 do_append(q, argv, pqual, action, actarg)
695     register struct query *q;
696     char *argv[];
697     char *pqual;
698     int (*action)();
699     char *actarg;
700 ##{
701 ##  char *rvar;
702 ##  char *rtable;
703 ##  char *cqual;
704 ##  int errorno;
705
706     rvar = q->rvar;
707     rtable = q->rtable;
708 ##  range of rvar is rtable
709
710     if (pqual) {
711         cqual = pqual;
712 ##      append to rtable (param (q->tlist, argv)) where cqual
713     } else {
714 ##      append to rtable (param (q->tlist, argv))
715     }
716
717 ##  inquire_equel (errorno = "errorno")
718     if (errorno == INGRES_BAD_INT)
719         return(SMS_INTEGER);
720     else if (errorno != 0)
721         return(SMS_INGRES_ERR);
722     return(SMS_SUCCESS);
723 ##}
724
725 do_delete(q, qual, action, actarg)
726     register struct query *q;
727     char *qual;
728     int (*action)();
729     char *actarg;
730 ##{
731 ##  char *rvar;
732 ##  char *rtable;
733 ##  char *cqual;
734 ##  int errorno;
735
736     rvar = q->rvar;
737     rtable = q->rtable;
738 ##  range of rvar is rtable
739
740     cqual = qual;
741 ##  delete rvar where cqual
742
743 ##  inquire_equel (errorno = "errorno")
744     if (errorno != 0) return(SMS_INGRES_ERR);
745     return(SMS_SUCCESS);
746 ##}
747
748
749 /**
750  ** set_next_object_id - set next object id in values table
751  **
752  ** Inputs: object - object name in values table and in objects
753  **         table - name of table objects are found in
754  **
755  ** - called before an APPEND operation to set the next object id to
756  **   be used for the new record to the next free value
757  **
758  **/
759
760 set_next_object_id(object, table)
761     char *object;
762     char *table;
763 ##{
764 ##  char *name, *tbl;
765 ##  int rowcount, exists, value;
766
767     name = object;
768     tbl = table;
769 ##  range of v is values
770 ##  repeat retrieve (value = v.#value) where v.#name = @name
771 ##  inquire_equel(rowcount = "rowcount")
772     if (rowcount != 1)
773         return(SMS_NO_ID);
774
775 ##  retrieve (exists = any(tbl.name where tbl.name = value))
776 ##  inquire_equel(rowcount = "rowcount")
777     if (rowcount != 1)
778         return(SMS_NO_ID);
779     while (exists) {
780         value++;
781         if (value > MAX_ID_VALUE)
782             value = MIN_ID_VALUE;
783 ##      retrieve (exists = any(tbl.name where tbl.name = value))
784     }
785
786     if (LOG_RES)
787         com_err(whoami, 0, "setting ID %s to %d", name, value);
788 ##  repeat replace v (#value = @value) where v.#name = @name
789     return(SMS_SUCCESS);
790 ##}
791
792
793 /* This looks up a login name and returns the SMS internal ID.  It is used
794  * by authenticate to put the users_id in the client structure.
795  */
796
797 int get_users_id(name)
798 char *name;
799 ##{
800 ##  int id, rowcount;
801 ##  char *login;
802
803     login = name;
804
805 ##  range of u is users
806 ##  repeat retrieve (id = u.#users_id) where u.#login = @login
807 ##  inquire_equel (rowcount = "rowcount")
808     
809     if (rowcount == 1)
810         return(id);
811     else
812         return(0);
813 ##}
814
815
816 /* Turn a kerberos name into the user's ID of the account that principal
817  * owns.  Sets the kerberos ID and user ID.
818  */
819
820 set_krb_mapping(name, login, ok, kid, uid)
821 char *name;
822 char *login;
823 int ok;
824 int *kid;
825 int *uid;
826 ##{
827 ##  int u_id, k_id, rowcount;
828 ##  char *krbname;
829
830     krbname = name;
831     *kid = 0;
832     *uid = 0;
833
834 ##  range of k is krbmap
835 ##  range of s is strings
836 ##  repeat retrieve (u_id = k.#users_id, k_id = k.#string_id)
837 ##      where k.string_id = s.string_id and s.string = @krbname
838 ##  inquire_equel (rowcount = "rowcount")
839     
840     if (rowcount == 1) {
841         *kid = -k_id;
842         *uid = u_id;
843         return;
844     }
845
846 ##  repeat retrieve (k_id = s.#string_id) where s.string = @krbname
847 ##  inquire_equel (rowcount = "rowcount")
848
849     if (rowcount == 1) {
850         *kid = -k_id;
851     }
852
853     if (!ok) {
854         *uid = *kid;
855         return;
856     }
857
858     *uid = get_users_id(login);
859     if (*kid == 0)
860       *kid = *uid;
861 ##}
862
863
864 /* For now this just checks the argc's.  It should also see that there
865  * are no duplicate names.
866  */
867
868 sanity_check_queries()
869 {
870     register int i;
871     int maxv = 0, maxa = 0;
872 #ifdef MULTIPROTOCOLS
873     extern int QueryCount1, QueryCount2;
874     extern struct query Queries1[], Queries2[];
875 #else
876     extern int QueryCount2;
877     extern struct query Queries2[];
878 #endif MULTIPROTOCOLS
879
880 #define MAX(x,y) ((x) > (y) ? (x) : (y))
881
882 #ifdef MULTIPROTOCOLS
883     for (i = 0; i < QueryCount1; i++) {
884         maxv = MAX(maxv, Queries1[i].vcnt);
885         maxa = MAX(maxa, Queries1[i].argc);
886     }
887 #endif MULTIPROTOCOLS
888     for (i = 0; i < QueryCount2; i++) {
889         maxv = MAX(maxv, Queries2[i].vcnt);
890         maxa = MAX(maxa, Queries2[i].argc);
891     }
892     if (MAX(maxv, maxa) > QMAXARGS) {
893         com_err(whoami, 0, "A query has more args than QMAXARGS");
894         exit(1);
895     }
896 }
This page took 0.097367 seconds and 3 git commands to generate.