]> andersk Git - moira.git/blame - server/qvalidate.pc
eliminate use of the `register' keyword: let the compiler decide
[moira.git] / server / qvalidate.pc
CommitLineData
73cf66ba 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
13static char *rcsid_qsupport_dc = "$Header$";
14#endif lint
15
16#include <mit-copyright.h>
17#include <unistd.h>
73cf66ba 18#include "mr_server.h"
03c05291 19#include "query.h"
73cf66ba 20#include <ctype.h>
03c05291 21#include <string.h>
73cf66ba 22EXEC SQL INCLUDE sqlca;
23EXEC SQL INCLUDE sqlda;
24#include "qrtn.h"
25
03c05291 26extern char *whoami, *table_name[], *sqlbuffer[QMAXARGS];
27extern int dbms_errno, mr_errcode;
73cf66ba 28
29EXEC SQL BEGIN DECLARE SECTION;
30extern char stmt_buf[];
31EXEC SQL END DECLARE SECTION;
32
03c05291 33int validate_chars(char *argv[], struct valobj *vo);
34int validate_id(struct query *, char *argv[], struct valobj *vo);
35int validate_name(char *argv[], struct valobj *vo);
36int validate_rename(char *argv[], struct valobj *vo);
37int validate_type(char *argv[], struct valobj *vo);
38int validate_typedata(struct query *, char *argv[], struct valobj *vo);
39int validate_len(char *argv[], struct valobj *vo);
40int lock_table(struct valobj *vo);
41int readlock_table(struct valobj *vo);
42int convert_wildcards_uppercase(char *arg);
73cf66ba 43
5eaef520 44extern SQLDA *sqlald(int, int, int);
960b073b 45
03c05291 46EXEC SQL WHENEVER SQLERROR DO dbmserr();
73cf66ba 47
48/* Validation Routines */
49
44d12d58 50int validate_row(struct query *q, char *argv[], struct validate *v)
73cf66ba 51{
5eaef520 52 EXEC SQL BEGIN DECLARE SECTION;
53 char qual[128];
54 int rowcount;
55 EXEC SQL END DECLARE SECTION;
56
57 /* build where clause */
58 build_qual(v->qual, v->argc, argv, qual);
59
60 if (log_flags & LOG_VALID)
61 /* tell the logfile what we're doing */
62 com_err(whoami, 0, "validating row: %s", qual);
63
64 /* look for the record */
65 sprintf(stmt_buf, "SELECT COUNT (*) FROM %s WHERE %s",
66 table_name[q->rtable], qual);
67 dosql(sqlbuffer);
68 if (dbms_errno)
69 return mr_errcode;
70
71 rowcount = atoi(sqlbuffer[0]);
72 if (rowcount == 0)
73 return MR_NO_MATCH;
74 if (rowcount > 1)
75 return MR_NOT_UNIQUE;
76 return MR_EXISTS;
73cf66ba 77}
78
44d12d58 79int validate_fields(struct query *q, char *argv[], struct valobj *vo, int n)
73cf66ba 80{
44d12d58 81 int status;
73cf66ba 82
5eaef520 83 while (--n >= 0)
84 {
85 switch (vo->type)
86 {
73cf66ba 87 case V_NAME:
5eaef520 88 if (log_flags & LOG_VALID)
89 {
90 com_err(whoami, 0, "validating %s in %s: %s",
91 vo->namefield, table_name[vo->table], argv[vo->index]);
92 }
93 status = validate_name(argv, vo);
94 break;
73cf66ba 95
96 case V_ID:
5eaef520 97 if (log_flags & LOG_VALID)
98 {
99 com_err(whoami, 0, "validating %s in %s: %s",
100 vo->idfield, table_name[vo->table], argv[vo->index]);
101 }
102 status = validate_id(q, argv, vo);
103 break;
73cf66ba 104
105 case V_TYPE:
5eaef520 106 if (log_flags & LOG_VALID)
107 {
108 com_err(whoami, 0, "validating %s type: %s",
109 table_name[vo->table], argv[vo->index]);
110 }
111 status = validate_type(argv, vo);
112 break;
73cf66ba 113
114 case V_TYPEDATA:
5eaef520 115 if (log_flags & LOG_VALID)
116 {
117 com_err(whoami, 0, "validating typed data (%s): %s",
118 argv[vo->index - 1], argv[vo->index]);
119 }
120 status = validate_typedata(q, argv, vo);
121 break;
73cf66ba 122
123 case V_RENAME:
5eaef520 124 if (log_flags & LOG_VALID)
125 {
126 com_err(whoami, 0, "validating rename %s in %s",
127 argv[vo->index], table_name[vo->table]);
128 }
129 status = validate_rename(argv, vo);
130 break;
73cf66ba 131
132 case V_CHAR:
5eaef520 133 if (log_flags & LOG_VALID)
134 com_err(whoami, 0, "validating chars: %s", argv[vo->index]);
135 status = validate_chars(argv, vo);
136 break;
03c05291 137
138 case V_LEN:
5eaef520 139 if (log_flags & LOG_VALID)
140 com_err(whoami, 0, "validating length: %s", argv[vo->index]);
141 status = validate_len(argv, vo);
142 break;
73cf66ba 143
144 case V_SORT:
5eaef520 145 status = MR_EXISTS;
146 break;
73cf66ba 147
148 case V_LOCK:
5eaef520 149 status = lock_table(vo);
150 break;
73cf66ba 151
03c05291 152 case V_RLOCK:
5eaef520 153 status = readlock_table(vo);
154 break;
03c05291 155
156 case V_WILD:
5eaef520 157 status = convert_wildcards(argv[vo->index]);
158 break;
73cf66ba 159
160 case V_UPWILD:
5eaef520 161 status = convert_wildcards_uppercase(argv[vo->index]);
162 break;
73cf66ba 163
164 }
165
5eaef520 166 if (status != MR_EXISTS)
167 return status;
168 vo++;
73cf66ba 169 }
170
5eaef520 171 if (dbms_errno)
172 return mr_errcode;
173 return MR_SUCCESS;
73cf66ba 174}
175
176
177/* validate_chars: verify that there are no illegal characters in
178 * the string. Legal characters are printing chars other than
179 * ", *, ?, \, [ and ].
180 */
181static int illegalchars[] = {
5eaef520 182 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
183 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
184 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */
186 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* : - O */
187 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */
188 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
189 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
190 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
191 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
192 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
193 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
194 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
195 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
196 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
197 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
73cf66ba 198};
199
44d12d58 200int validate_chars(char *argv[], struct valobj *vo)
73cf66ba 201{
5eaef520 202 char *s = argv[vo->index];
203 int arg;
204 EXEC SQL BEGIN DECLARE SECTION;
205 int len;
206 char *tname, *cname;
207 EXEC SQL END DECLARE SECTION;
208
209 /* check for bad characters */
210 while (*s)
211 {
73cf66ba 212 if (illegalchars[*s++])
5eaef520 213 return MR_BAD_CHAR;
214 }
03c05291 215
5eaef520 216 /* check for length */
217 tname = table_name[vo->table];
218 cname = vo->namefield;
219 EXEC SQL SELECT data_length INTO :len FROM user_tab_columns
220 WHERE table_name = UPPER(:tname) AND column_name = UPPER(:cname);
03c05291 221
5eaef520 222 if ((strlen(argv[vo->index]) > len) &&
223 strcmp(argv[vo->index], UNIQUE_LOGIN)) /* kludge... sigh */
224 argv[vo->index][len] = '\0'; /* truncate */
03c05291 225
5eaef520 226 return MR_EXISTS;
73cf66ba 227}
228
229
44d12d58 230int validate_id(struct query *q, char *argv[], struct valobj *vo)
73cf66ba 231{
5eaef520 232 EXEC SQL BEGIN DECLARE SECTION;
233 char *name, *namefield, *idfield;
234 int id, rowcount, tbl;
235 EXEC SQL END DECLARE SECTION;
236 int status;
44d12d58 237 char *c;
5eaef520 238
239 name = argv[vo->index];
240 tbl = vo->table;
241 namefield = vo->namefield;
242 idfield = vo->idfield;
243
244 if ((tbl == USERS_TABLE && !strcmp(namefield, "login")) ||
245 tbl == MACHINE_TABLE || tbl == SUBNET_TABLE || tbl == FILESYS_TABLE ||
246 tbl == LIST_TABLE || tbl == CLUSTER_TABLE || tbl == STRINGS_TABLE)
247 {
248 if (tbl == MACHINE_TABLE || tbl == SUBNET_TABLE)
249 {
250 for (c = name; *c; c++)
251 {
252 if (islower(*c))
253 *c = toupper(*c);
254 }
255 }
03c05291 256 status = name_to_id(name, tbl, &id);
5eaef520 257 if (status == 0)
258 {
259 *(int *)argv[vo->index] = id;
260 return MR_EXISTS;
261 }
262 else if (status == MR_NO_MATCH && tbl == STRINGS_TABLE &&
263 (q->type == APPEND || q->type == UPDATE))
264 {
265 id = add_string(name);
266 cache_entry(name, STRINGS_TABLE, id);
267 *(int *)argv[vo->index] = id;
268 return MR_EXISTS;
269 }
270 else if (status == MR_NO_MATCH || status == MR_NOT_UNIQUE)
271 return vo->error;
03c05291 272 else
5eaef520 273 return status;
274 }
275 else
276 {
03c05291 277 /* else, it's `dubu', which uses unix_uid from users */
278 EXEC SQL SELECT COUNT(*) INTO :rowcount FROM users
279 WHERE unix_uid = :name;
5eaef520 280 if (dbms_errno)
281 return mr_errcode;
282 if (rowcount != 1)
283 return vo->error;
03c05291 284 EXEC SQL SELECT users_id INTO :id FROM users
285 WHERE unix_uid = :name;
286 *(int *)argv[vo->index] = id;
5eaef520 287 return MR_EXISTS;
73cf66ba 288 }
73cf66ba 289}
290
44d12d58 291int validate_name(char *argv[], struct valobj *vo)
73cf66ba 292{
5eaef520 293 char *name, *namefield;
44d12d58 294 char *c;
5eaef520 295
296 name = argv[vo->index];
297 namefield = vo->namefield;
298 if (vo->table == SERVERS_TABLE && !strcmp(namefield, "name"))
299 {
300 for (c = name; *c; c++)
301 {
73cf66ba 302 if (islower(*c))
303 *c = toupper(*c);
5eaef520 304 }
73cf66ba 305 }
5eaef520 306 sprintf(stmt_buf, "SELECT DISTINCT COUNT(*) FROM %s WHERE %s.%s = '%s'",
307 table_name[vo->table], table_name[vo->table], namefield, name);
308 dosql(sqlbuffer);
03c05291 309
5eaef520 310 if (dbms_errno)
311 return mr_errcode;
312 return (atoi(sqlbuffer[0]) == 1) ? MR_EXISTS : vo->error;
73cf66ba 313}
314
5eaef520 315int validate_rename(char *argv[], struct valobj *vo)
73cf66ba 316{
5eaef520 317 EXEC SQL BEGIN DECLARE SECTION;
318 char *name, *namefield, *idfield;
319 int id;
320 EXEC SQL END DECLARE SECTION;
321 int status;
44d12d58 322 char *c;
5eaef520 323
324 status = validate_chars(argv, vo);
325 if (status != MR_EXISTS)
326 return status;
327 name = argv[vo->index];
328 /* minor kludge to upcasify machine names */
329 if (vo->table == MACHINE_TABLE)
330 {
331 for (c = name; *c; c++)
332 {
333 if (islower(*c))
334 *c = toupper(*c);
335 }
336 }
337 namefield = vo->namefield;
338 idfield = vo->idfield;
339 id = -1;
340 if (idfield == 0)
341 {
342 if (!strcmp(argv[vo->index], argv[vo->index - 1]))
343 return MR_EXISTS;
344 sprintf(stmt_buf, "SELECT %s FROM %s WHERE %s = '%s'",
345 namefield, table_name[vo->table], namefield, name);
346 dosql(sqlbuffer);
347
348 if (dbms_errno)
349 return mr_errcode;
350 if (sqlca.sqlcode == SQL_NO_MATCH)
351 return MR_EXISTS; /* how's _that_ for intuitive? */
352 else
353 return vo->error;
73cf66ba 354 }
5eaef520 355 status = name_to_id(name, vo->table, &id);
356 if (status == MR_NO_MATCH || id == *(int *)argv[vo->index - 1])
357 return MR_EXISTS;
358 else
359 return vo->error;
73cf66ba 360}
361
362
44d12d58 363int validate_type(char *argv[], struct valobj *vo)
73cf66ba 364{
5eaef520 365 EXEC SQL BEGIN DECLARE SECTION;
366 char *typename;
367 char *val;
368 int cnt;
369 EXEC SQL END DECLARE SECTION;
44d12d58 370 char *c;
5eaef520 371
372 typename = vo->namefield;
373 c = val = argv[vo->index];
374 while (*c)
375 {
376 if (illegalchars[*c++])
377 return MR_BAD_CHAR;
73cf66ba 378 }
379
5eaef520 380 /* uppercase type fields */
381 for (c = val; *c; c++)
382 {
383 if (islower(*c))
384 *c = toupper(*c);
385 }
73cf66ba 386
5eaef520 387 EXEC SQL SELECT COUNT(trans) INTO :cnt FROM alias
388 WHERE name = :typename AND type = 'TYPE' AND trans = :val;
389 if (dbms_errno)
390 return mr_errcode;
391 return cnt ? MR_EXISTS : vo->error;
73cf66ba 392}
393
394/* validate member or type-specific data field */
395
44d12d58 396int validate_typedata(struct query *q, char *argv[], struct valobj *vo)
73cf66ba 397{
5eaef520 398 EXEC SQL BEGIN DECLARE SECTION;
399 char *name;
400 char *field_type;
401 char data_type[129];
402 int id;
403 EXEC SQL END DECLARE SECTION;
404 int status;
44d12d58 405 char *c;
5eaef520 406
407 /* get named object */
408 name = argv[vo->index];
409
410 /* get field type string (known to be at index-1) */
411 field_type = argv[vo->index - 1];
412
413 /* get corresponding data type associated with field type name */
414 EXEC SQL SELECT trans INTO :data_type FROM alias
415 WHERE name = :field_type AND type = 'TYPEDATA';
416 if (dbms_errno)
417 return mr_errcode;
418 if (sqlca.sqlerrd[2] != 1)
419 return MR_TYPE;
420
421 /* now retrieve the record id corresponding to the named object */
422 if (strchr(data_type, ' '))
423 *strchr(data_type, ' ') = '\0';
424 if (!strcmp(data_type, "user"))
425 {
426 /* USER */
427 if (strchr(name, '@'))
428 return MR_USER;
429 status = name_to_id(name, USERS_TABLE, &id);
430 if (status && (status == MR_NO_MATCH || status == MR_NOT_UNIQUE))
431 return MR_USER;
432 if (status)
433 return status;
434 }
435 else if (!strcmp(data_type, "list"))
436 {
437 /* LIST */
438 status = name_to_id(name, LIST_TABLE, &id);
439 if (status && status == MR_NOT_UNIQUE)
440 return MR_LIST;
441 if (status == MR_NO_MATCH)
442 {
443 /* if idfield is non-zero, then if argv[0] matches the string
444 * that we're trying to resolve, we should get the value of
445 * numvalues.[idfield] for the id.
446 */
447 if (vo->idfield && !strcmp(argv[0], argv[vo->index]))
448 {
449 set_next_object_id(q->validate->object_id, q->rtable, 0);
450 name = vo->idfield;
451 EXEC SQL SELECT value INTO :id FROM numvalues
452 WHERE name = :name;
453 if (sqlca.sqlerrd[2] != 1)
454 return MR_LIST;
455 }
456 else
457 return MR_LIST;
458 }
459 else if (status)
460 return status;
461 }
462 else if (!strcmp(data_type, "machine"))
463 {
464 /* MACHINE */
465 for (c = name; *c; c++)
466 {
467 if (islower(*c))
468 *c = toupper(*c);
469 }
470 status = name_to_id(name, MACHINE_TABLE, &id);
471 if (status && (status == MR_NO_MATCH || status == MR_NOT_UNIQUE))
472 return MR_MACHINE;
473 if (status)
474 return status;
475 }
476 else if (!strcmp(data_type, "string"))
477 {
478 /* STRING */
479 status = name_to_id(name, STRINGS_TABLE, &id);
480 if (status && status == MR_NOT_UNIQUE)
481 return MR_STRING;
482 if (status == MR_NO_MATCH)
483 {
484 if (q->type != APPEND && q->type != UPDATE)
485 return MR_STRING;
486 id = add_string(name);
487 cache_entry(name, STRINGS_TABLE, id);
488 }
489 else if (status)
490 return status;
73cf66ba 491 }
5eaef520 492 else if (!strcmp(data_type, "none"))
493 id = 0;
494 else
495 return MR_TYPE;
73cf66ba 496
5eaef520 497 /* now set value in argv */
498 *(int *)argv[vo->index] = id;
73cf66ba 499
5eaef520 500 return MR_EXISTS;
73cf66ba 501}
502
503
03c05291 504/* Make sure the data fits in the field */
44d12d58 505int validate_len(char *argv[], struct valobj *vo)
03c05291 506{
5eaef520 507 EXEC SQL BEGIN DECLARE SECTION;
508 int len;
509 char *tname, *cname;
510 EXEC SQL END DECLARE SECTION;
03c05291 511
5eaef520 512 tname = table_name[vo->table];
513 cname = vo->namefield;
514 EXEC SQL SELECT data_length INTO :len FROM user_tab_columns
515 WHERE table_name = UPPER(:tname) AND column_name = UPPER(:cname);
03c05291 516
5eaef520 517 if ((strlen(argv[vo->index]) > len) &&
518 strcmp(argv[vo->index], UNIQUE_LOGIN)) /* kludge... sigh */
519 argv[vo->index][len] = '\0'; /* truncate */
03c05291 520
5eaef520 521 return MR_EXISTS;
03c05291 522}
523
73cf66ba 524/* Lock the table named by the validation object */
525
5eaef520 526int lock_table(struct valobj *vo)
73cf66ba 527{
03c05291 528#ifdef DO_LOCKING
5eaef520 529 sprintf(stmt_buf, "LOCK TABLE %s IN EXCLUSIVE MODE", table_name[vo->table]);
530 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
531 if (dbms_errno)
532 return mr_errcode;
533 else
03c05291 534#endif
5eaef520 535 return MR_EXISTS;
73cf66ba 536}
537
03c05291 538/*
539 * Get a read lock on the table by accessing the magic lock
540 * record. Certain tables are constructed so that they contain
5eaef520 541 * an id field whose value is zero and a modtime field. We
542 * manipulate the modtime field of the id 0 record to effect
03c05291 543 * locking of the table
73cf66ba 544 */
545
5eaef520 546int readlock_table(struct valobj *vo)
73cf66ba 547{
03c05291 548#ifdef DO_LOCKING
5eaef520 549 sprintf(stmt_buf, "LOCK TABLE %s IN SHARE MODE", table_name[vo->table]);
550 EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
03c05291 551
5eaef520 552 if (dbms_errno)
553 return mr_errcode;
554 if (sqlca.sqlcode)
555 return vo->error;
03c05291 556#endif
5eaef520 557 return MR_EXISTS; /* validate_fields expects us to return
558 * this value if everything went okay
559 */
73cf66ba 560}
561
695afd0d 562/* Check the database at startup time. */
03c05291 563
564void sanity_check_database(void)
565{
5eaef520 566 EXEC SQL BEGIN DECLARE SECTION;
567 int oid, id;
568 EXEC SQL END DECLARE SECTION;
695afd0d 569
5eaef520 570 /* Sometimes a crash can leave strings_id in numvalues in an
571 incorrect state. Check for that and fix it. */
695afd0d 572
5eaef520 573 EXEC SQL SELECT value INTO :oid FROM numvalues WHERE name = 'strings_id';
695afd0d 574
5eaef520 575 for (id = oid + 1; sqlca.sqlcode == 0; id++)
576 {
577 EXEC SQL SELECT string_id INTO :id FROM strings
578 WHERE string_id = :id;
579 }
695afd0d 580
5eaef520 581 if (id != oid + 1)
582 EXEC SQL UPDATE numvalues SET value = :id - 1 WHERE name = 'strings_id';
03c05291 583}
584
585
586char *sqlbuffer[QMAXARGS];
73cf66ba 587
588/* Dynamic SQL support routines */
03c05291 589SQLDA *mr_alloc_sqlda()
73cf66ba 590{
5eaef520 591 SQLDA *it;
44d12d58 592 int j;
5eaef520 593
594 it = sqlald(QMAXARGS, ARGLEN, 0);
595 if (!it)
596 {
597 com_err(whoami, MR_NO_MEM, "setting up SQLDA");
598 exit(1);
73cf66ba 599 }
600
5eaef520 601 for (j = 0; j < QMAXARGS; j++)
602 {
603 it->V[j] = sqlbuffer[j] = malloc(ARGLEN);
604 it->T[j] = 97; /* 97 = CHARZ = null-terminated string */
605 it->L[j] = ARGLEN;
73cf66ba 606 }
03c05291 607
5eaef520 608 return it;
73cf66ba 609}
610
611
73cf66ba 612/* Convert normal Unix-style wildcards to SQL voodoo */
5eaef520 613int convert_wildcards(char *arg)
73cf66ba 614{
5eaef520 615 static char buffer[ARGLEN];
44d12d58 616 char *s, *d;
5eaef520 617
618 for (d = buffer, s = arg; *s; s++)
619 {
620 switch (*s)
621 {
622 case '*':
623 *d++ = '%';
624 *d++ = '%';
625 break;
626 case '?':
627 *d++ = '_';
628 break;
629 case '_':
630 *d++ = '*';
631 *d++ = *s;
632 break;
633 case '%':
634 *d++ = '*';
635 *d++ = '%';
636 *d++ = '%';
637 break;
638 default:
639 *d++ = *s;
640 break;
73cf66ba 641 }
642 }
5eaef520 643 *d = '\0';
73cf66ba 644
5eaef520 645 /* Copy back into argv */
646 strcpy(arg, buffer);
73cf66ba 647
5eaef520 648 return MR_EXISTS;
73cf66ba 649}
650
651/* This version includes uppercase conversion, for things like gmac.
652 * This is necessary because "LIKE" doesn't work with "uppercase()".
653 * Including it in a wildcard routine saves making two passes over
654 * the argument string.
655 */
5eaef520 656int convert_wildcards_uppercase(char *arg)
73cf66ba 657{
5eaef520 658 static char buffer[ARGLEN];
44d12d58 659 char *s, *d;
5eaef520 660
661 for (d = buffer, s = arg; *s; s++)
662 {
663 switch (*s)
664 {
665 case '*':
666 *d++ = '%';
667 *d++ = '%';
668 break;
669 case '?':
670 *d++ = '_';
671 break;
672 case '_':
673 *d++ = '*';
674 *d++ = *s;
675 break;
676 case '%':
677 *d++ = '*';
678 *d++ = '%';
679 *d++ = '%';
680 break;
681 default:
682 *d++ = toupper(*s); /* This is the only diff. */
683 break;
73cf66ba 684 }
685 }
5eaef520 686 *d = '\0';
73cf66ba 687
5eaef520 688 /* Copy back into argv */
689 strcpy(arg, buffer);
73cf66ba 690
5eaef520 691 return MR_EXISTS;
73cf66ba 692}
693
694
73cf66ba 695/* Adds a string to the string table. Returns the id number.
5eaef520 696 *
73cf66ba 697 */
5eaef520 698int add_string(char *nm)
73cf66ba 699{
5eaef520 700 EXEC SQL BEGIN DECLARE SECTION;
701 char buf[256], *name = nm;
702 int id;
703 EXEC SQL END DECLARE SECTION;
704
705 EXEC SQL SELECT value INTO :id FROM numvalues WHERE name = 'strings_id';
706 id++;
707 EXEC SQL UPDATE numvalues SET value = :id WHERE name = 'strings_id';
708
709 EXEC SQL INSERT INTO strings (string_id, string) VALUES (:id, :nm);
710
711 return id;
73cf66ba 712}
This page took 1.442841 seconds and 5 git commands to generate.