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