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