QI_QUERY 1-SEP-1993 10:04:04 VAX C V3.2-044 Page 1 V1.0 26-AUG-1993 19:15:04 X$SRC:[CSO]QI_QUERY.C;2 (1) 1 /* qi_query - module for query command */ 2 /* Bruce Tanner - Cerritos College */ 3 4 #include stdio 266 #include string 312 #include ctype 375 #include ssdef 1017 #include descrip 1450 #include rms 4016 #include psldef 4073 #include "qi.h" 4169 4170 struct FAB idxfab, datfab; 4171 struct RAB idxrab, datrab; 4172 struct XABKEY idxxab, datxab; 4173 char idx_record[IDX_RECORD_SIZE + 1]; 4174 char idx_key[IDX_KEY_SIZE + 1]; 4175 char dat_record[DAT_RECORD_SIZE + 1]; 4176 char dat_key[DAT_KEY_SIZE + 1]; 4177 int db_status; 4178 4179 typedef struct rstruct { 4180 int id, field; 4181 } Result; 4182 4183 #define NotRet(x) ((x->type & TYPE_RETURN) == 0) 4184 4185 void writestring(int, char *); 4186 void qiabort(int, char *); 4187 char *new_string(char *); 4188 Arg *make_arg(char *, int, char *, int); 4189 void free_args(Arg *); 4190 void qilog(int, char *, ...); 4191 void *my_realloc(void *, int); 4192 char *getlogical(char *); 4193 4194 extern Fields fields[]; 4195 extern int debug; 4196 4197 4198 int find_exact(int sock, char *query, int field) 4199 { 4200 1 char *cp, temp[100]; 4201 1 int status; 4202 1 4203 1 idxrab.rab$b_rac = RAB$C_KEY; 4204 1 idxrab.rab$l_rop = 0; /* set up exact match */ 4205 1 idxrab.rab$b_ksz = KEYWORD_SIZE; 4206 1 if (cp = strchr(query, ' ')) 4207 1 *cp = '\0'; /* strip trailing spaces */ 4208 1 sprintf(idx_key, "%-*s%0*dA", KEYWORD_SIZE, query, 4209 1 FIELD_SIZE, field); 4210 1 4211 1 status = sys$get(&idxrab); 4212 1 if (debug) { QI_QUERY 1-SEP-1993 10:04:04 VAX C V3.2-044 Page 2 V1.0 26-AUG-1993 19:15:04 X$SRC:[CSO]QI_QUERY.C;2 (1) 4213 2 sprintf(temp,"exact match returns %d\r\n", status); 4214 2 writestring(sock, temp); 4215 2 } 4216 1 return (status & 1); 4217 1 } 4218 4219 #if APPROX_MATCH 4220 4221 int find_approx(int sock, char *query, int field) 4222 { 4223 1 char temp[100]; 4224 1 int status; 4225 1 4226 1 idxrab.rab$b_rac = RAB$C_KEY; 4227 1 idxrab.rab$l_rop = RAB$M_KGE; /* set up approximate generic match */ 4228 1 idxrab.rab$b_ksz = strlen(query); /* actual key size */ 4229 1 sprintf(idx_key, "%-*s%0*dA", KEYWORD_SIZE, query, 4230 1 FIELD_SIZE, field); 4231 1 4232 1 status = sys$get(&idxrab); 4233 1 if (debug) { 4234 2 sprintf(temp,"approx match returns %d\r\n", status); 4235 2 writestring(sock, temp); 4236 2 } 4237 1 status &= 1; 4238 1 if (status == 0) 4239 1 return status; 4240 1 /* this sould always find something, is it the right record? */ 4241 1 return (strncmp(idx_record, query, strlen(query)) == 0); 4242 1 } 4243 4244 4245 int find_soundex(int sock, char *query, int field) 4246 { 4247 1 char temp[100]; 4248 1 int status; 4249 1 4250 1 idxrab.rab$b_rac = RAB$C_KEY; 4251 1 idxrab.rab$l_rop = 0; /* set up exact match */ 4252 1 idxrab.rab$b_ksz = KEYWORD_SIZE; 4253 1 sprintf(idx_key, "%-*s%0*dS", KEYWORD_SIZE, 4254 1 soundex(query, query, SOUNDEX_SIZE), 4255 1 FIELD_SIZE, field); 4256 1 4257 1 status = sys$get(&idxrab); 4258 1 if (debug) { 4259 2 sprintf(temp,"soundex match returns %d\r\n", status); 4260 2 writestring(sock, temp); 4261 2 } 4262 1 return (status & 1); 4263 1 } 4264 #endif 4265 4266 4267 int find(int sock, Arg *arg, Result **result, int size) 4268 { 4269 1 int status, id; QI_QUERY 1-SEP-1993 10:04:04 VAX C V3.2-044 Page 3 V1.0 26-AUG-1993 19:15:04 X$SRC:[CSO]QI_QUERY.C;2 (1) 4270 1 char *cp, query[DATA_SIZE + 1], wild_query[DATA_SIZE + 1]; 4271 1 char temp[IDX_RECORD_SIZE + 30]; 4272 1 char found_keyword[KEYWORD_SIZE + 1], found_id[ID_SIZE + 1]; 4273 1 char found_field[FIELD_SIZE + 1]; 4274 1 Result *rptr, *pptr; 4275 1 $DESCRIPTOR(wild_dsc, wild_query); 4276 1 $DESCRIPTOR(found_dsc, found_keyword); 4277 1 4278 1 /* find() only works on indexed fields */ 4279 1 if ((fields[arg->field].attrib & ATTR_INDEXED) == 0) 4280 1 return size; 4281 1 4282 1 strcpy(query, arg->value); 4283 1 wild_query[0] = '\0'; 4284 1 4285 1 if ((cp = strchr(query, '*')) || (cp = strchr(query, '?'))) { /* wildcard? */ 4286 2 strcpy(wild_query, query); /* make a copy with the wildcard */ 4287 2 *cp = '\0'; /* truncate at the wildcard */ 4288 2 if (!find_approx(sock, query, arg->field)) /* try to find the first part */ 4289 2 return size; /* no match */ 4290 2 } 4291 1 else 4292 1 if (!find_exact(sock, query, arg->field)) /* no wildcard, find the item */ 4293 1 #if APPROX_MATCH 4294 1 if (!find_approx(sock, query, arg->field)) /* no exact match, try approx match */ 4295 1 if (!find_soundex(sock, query, arg->field)) /* no approx, try soundex */ 4296 1 #endif 4297 1 return size; /* no match */ 4298 1 4299 1 4300 1 idxrab.rab$b_rac = RAB$C_SEQ; 4301 1 do { 4302 2 strncpy(found_keyword, idx_record, KEYWORD_SIZE); 4303 2 found_keyword[KEYWORD_SIZE] = '\0'; 4304 2 if (cp = strchr(found_keyword, ' ')) *cp = '\0'; 4305 2 if ((idxrab.rab$l_rop == 0) && /* if exact match, */ 4306 2 strcmp(found_keyword, query)) /* do exact compare */ 4307 2 break; /* no match */ 4308 2 if ((idxrab.rab$l_rop == RAB$M_KGE) && /* if approx match, */ 4309 2 strncmp(found_keyword, query, strlen(query))) /* approx compare */ 4310 2 break; /* no match */ 4311 2 if (strlen(wild_query)) { /* if wildcard match, */ 4312 3 found_dsc.dsc$w_length = (short) strlen(found_keyword); 4313 3 wild_dsc.dsc$w_length = (short) strlen(wild_query); 4314 3 if ((str$match_wild(&found_dsc, &wild_dsc) & 1) == 0) /* wild compare */ 4315 3 continue; /* no match, try again */ 4316 3 } 4317 2 sprintf(found_field, "%0*d", FIELD_SIZE, arg->field); 4318 2 if (strncmp(found_field, idx_record + KEYWORD_SIZE, FIELD_SIZE) != 0) 4319 2 continue; /* this isn't the field we're looking for */ 4320 2 strncpy(found_id, idx_record + KEYWORD_SIZE + FIELD_SIZE + TYPE_SIZE, 4321 2 ID_SIZE); 4322 2 found_id[ID_SIZE] = '\0'; 4323 2 if (debug) { 4324 3 sprintf(temp, "-100: Find >> %s\r\n", idx_record); 4325 3 writestring(sock, temp); 4326 3 } QI_QUERY 1-SEP-1993 10:04:04 VAX C V3.2-044 Page 4 V1.0 26-AUG-1993 19:15:04 X$SRC:[CSO]QI_QUERY.C;2 (1) 4327 2 *result = (Result *) my_realloc((Result *) *result, (size + 1) * sizeof(Result)); 4328 2 id = atoi(found_id); 4329 2 (*result)[size].id = id; 4330 2 (*result)[size].field = atoi(found_field); 4331 2 size++; 4332 2 } while (((status = sys$get(&idxrab)) & 1) == SS$_NORMAL); 4333 1 4334 1 return size; 4335 1 } 4336 4337 4338 /* this routine handles the rare case where a name= query 4339 matches both name and nickname (inflating the match count) 4340 and another indexed query has no matches; 4341 thus a false matched == iq in resolve() 4342 */ 4343 int validate_match(Result *results, int end, int matched, Arg *list) 4344 { 4345 1 Arg *ptr; 4346 1 int ind; 4347 1 4348 1 /* look for an indexed query without a corresponding result */ 4349 1 for (ptr = list; ptr && NotRet(ptr); ptr = ptr->next) { /* all queries */ 4350 2 if ((fields[ptr->field].attrib & ATTR_INDEXED) && /* this is indexed */ 4351 2 (ptr->field != atoi(NAME_FIELD)) && 4352 2 (ptr->field != atoi(NICKNAME_FIELD))) { /* that isn't name= */ 4353 3 for (ind = end - matched; ind < end; ind++) 4354 3 if (results[ind].field == ptr->field) 4355 3 break; /* a result matched this query */ 4356 3 if (ind == end) /* didn't find a match */ 4357 3 return False; /* for this query */ 4358 3 } 4359 2 } 4360 1 return True; 4361 1 } 4362 4363 4364 /* see if a query field matches the id */ 4365 int lookup(int sock, int id, Arg *arg) 4366 { 4367 1 int status; 4368 1 char *cp, value[DATA_SIZE + 1], data[DATA_SIZE + 1], temp[DATA_SIZE + 20]; 4369 1 $DESCRIPTOR(value_dsc, value); 4370 1 $DESCRIPTOR(data_dsc, data); 4371 1 4372 1 if (debug) { 4373 2 sprintf(temp, "lookup %d\r\n", id); 4374 2 writestring(sock, temp); 4375 2 } 4376 1 4377 1 /* first, read the data record */ 4378 1 datrab.rab$b_rac = RAB$C_KEY; 4379 1 datrab.rab$b_ksz = ID_SIZE + FIELD_SIZE; /* partial key size */ 4380 1 datrab.rab$l_rop = RAB$M_KGE; /* find any sequence number */ 4381 1 sprintf(dat_key, "%0*d%0*d%*s", ID_SIZE, id, 4382 1 FIELD_SIZE, arg->field, SEQ_SIZE, ""); 4383 1 while ((status = sys$get(&datrab)) & 1) { QI_QUERY 1-SEP-1993 10:04:04 VAX C V3.2-044 Page 5 V1.0 26-AUG-1993 19:15:04 X$SRC:[CSO]QI_QUERY.C;2 (1) 4384 2 datrab.rab$b_rac = RAB$C_SEQ; 4385 2 if (strncmp(dat_key, dat_record, ID_SIZE + FIELD_SIZE)) 4386 2 break; /* finished with this id/field */ 4387 2 dat_record[datrab.rab$w_rsz] = '\0'; /* terminate string */ 4388 2 strcpy(data, dat_record + ID_SIZE + FIELD_SIZE + SEQ_SIZE + ATTR_SIZE); 4389 2 data_dsc.dsc$w_length = (short) strlen(data); 4390 2 if (debug) { 4391 3 sprintf(temp, "-100: Lookup >> %s\r\n", dat_record); 4392 3 writestring(sock, temp); 4393 3 } 4394 2 /* force case for compare; there's no case-blind flag to match_wild */ 4395 2 for (cp = data; *cp; cp++) *cp = _tolower(*cp); 4396 2 sprintf(value, "*%s*", arg->value); 4397 2 value_dsc.dsc$w_length = (short) strlen(value); 4398 2 if (str$match_wild(&data_dsc, &value_dsc) & 1) 4399 2 return True; /* one match is good enough */ 4400 2 } 4401 1 return False; 4402 1 } 4403 4404 4405 /* find the non-indexed query fields in the data file 4406 and see if id will match them 4407 */ 4408 int find_non_indexed(int sock, int id, Arg *list) 4409 { 4410 1 Arg *ptr; 4411 1 4412 1 for (ptr = list; ptr && NotRet(ptr); ptr = ptr->next) { 4413 2 if (fields[ptr->field].attrib & ATTR_INDEXED) 4414 2 continue; /* already did indexed fields */ 4415 2 if (!lookup(sock, id, ptr)) 4416 2 return False; /* no match, you loose */ 4417 2 } 4418 1 return True; /* all fields matched */ 4419 1 } 4420 4421 4422 int compar(Result *a, Result *b) 4423 { 4424 1 if (a->id < b->id) return (-1); 4425 1 if (a->id > b->id) return (1); 4426 1 if (a->field < b->field) return (-1); 4427 1 if (a->field > b->field) return (1); 4428 1 return (0); 4429 1 } 4430 4431 4432 /* display the requested fields associated with id */ 4433 void display_id(int sock, int id, Arg *list, int match) 4434 { 4435 1 Arg *ptr; 4436 1 int request[MAX_FIELD], use_defaults = True; 4437 1 int max, ind, status, num, seq, attrib; 4438 1 char data[DATA_SIZE + 1], field[20], temp[DATA_SIZE * 2]; 4439 1 4440 1 /* first we need to know whether there are any requested fields */ QI_QUERY 1-SEP-1993 10:04:04 VAX C V3.2-044 Page 6 V1.0 26-AUG-1993 19:15:04 X$SRC:[CSO]QI_QUERY.C;2 (1) 4441 1 4442 1 for (ind = 0; ind < MAX_FIELD; ind++) 4443 1 request[ind] = False; 4444 1 for (ptr = list; ptr; ptr = ptr->next) { 4445 2 if (ptr->type & TYPE_RETURN) 4446 2 use_defaults = False; 4447 2 else if (strcmp(ptr->value, "all") == 0) 4448 2 for (ind = 0; ind < MAX_FIELD; ind++) 4449 2 request[ind] = True; /* mark all as requested */ 4450 2 else if (!use_defaults) 4451 2 request[ptr->field] = True; 4452 2 } 4453 1 4454 1 /* if use_defaults = true, the Default fields will be used 4455 1 otherwise, request[] contains the fields requested, 4456 1 */ 4457 1 4458 1 /* find the max field name size */ 4459 1 for (ind = 0, max = 0; ind < MAX_FIELD; ind++) 4460 1 if (fields[ind].name && (strlen(fields[ind].name) > max)) 4461 1 max = strlen(fields[ind].name); 4462 1 4463 1 datrab.rab$b_rac = RAB$C_KEY; 4464 1 datrab.rab$b_ksz = ID_SIZE; /* partial key size */ 4465 1 datrab.rab$l_rop = RAB$M_KGE; /* find all records */ 4466 1 sprintf(dat_key, "%0*d%0*d%*s", ID_SIZE, id, 4467 1 FIELD_SIZE, 0, SEQ_SIZE, ""); 4468 1 while ((status = sys$get(&datrab)) & 1) { 4469 2 datrab.rab$b_rac = RAB$C_SEQ; 4470 2 if (strncmp(dat_key, dat_record, ID_SIZE)) 4471 2 break; /* finished with this id */ 4472 2 dat_record[datrab.rab$w_rsz] = '\0'; /* terminate string */ 4473 2 strncpy(field, dat_record + ID_SIZE, FIELD_SIZE); 4474 2 field[FIELD_SIZE] = '\0'; 4475 2 num = atoi(field); 4476 2 strncpy(field, dat_record + ID_SIZE + FIELD_SIZE, SEQ_SIZE); 4477 2 field[SEQ_SIZE] = '\0'; 4478 2 seq = atoi(field); 4479 2 strncpy(field, dat_record + ID_SIZE + FIELD_SIZE + SEQ_SIZE, ATTR_SIZE); 4480 2 field[SEQ_SIZE] = '\0'; 4481 2 attrib = atoi(field); 4482 2 strcpy(data, dat_record + ID_SIZE + FIELD_SIZE + SEQ_SIZE + ATTR_SIZE); 4483 2 4484 2 /* if a public field is requested OR no fields were requested and the 4485 2 field is a default AND the field isn't suppressed OR the field may 4486 2 not be suppressed (ForcePub) then print the record 4487 2 */ 4488 2 if (((request[num] && (fields[num].attrib & ATTR_PUBLIC)) || 4489 2 (use_defaults && (fields[num].attrib & ATTR_DEFAULT))) && /* Default implies Public */ 4490 2 (((attrib & ATTR_SUPPRESS) == 0) || (fields[num].attrib & ATTR_FORCEPUB))) { 4491 3 sprintf(temp, "-200:%d:%*s: %s\r\n", match, max, 4492 3 seq ? "" : fields[num].name, data); 4493 3 writestring(sock, temp); 4494 3 } 4495 2 } 4496 1 } 4497 QI_QUERY 1-SEP-1993 10:04:04 VAX C V3.2-044 Page 7 V1.0 26-AUG-1993 19:15:04 X$SRC:[CSO]QI_QUERY.C;2 (1) 4498 4499 4500 /* 4501 given an array of indexed fields that match indexed part of query, 4502 return the count of actual matches with the list in results[] 4503 */ 4504 int resolve(int sock, Result *results, int size, Arg *list) 4505 { 4506 1 char temp[50]; 4507 1 Arg *ptr; 4508 1 int ind, iq, matches, count = 0; 4509 1 4510 1 qsort((char *) results, size, sizeof(Result), compar); /* sort the hits */ 4511 1 for (ptr = list, iq = 0; ptr && NotRet(ptr); ptr = ptr->next) { 4512 2 if (fields[ptr->field].attrib & ATTR_INDEXED) 4513 2 iq++; /* Get count of indexed queries (iq) */ 4514 2 } 4515 1 4516 1 if (debug) 4517 1 for (ind = 0; ind < size; ind++) { 4518 2 sprintf(temp, "-100: Resolve >> field %d id %d\r\n", 4519 2 results[ind].field, results[ind].id); 4520 2 writestring(sock, temp); 4521 2 } 4522 1 4523 1 /* find sequences of 'iq' matches of one id */ 4524 1 for (ind = 1, matches = 1; ind < (size + 1); ind++) { 4525 2 if ((ind < size) && (results[ind-1].id == results[ind].id)) 4526 2 matches++; 4527 2 else 4528 2 if ( (matches >= iq) && /* if everything matches */ 4529 2 validate_match(results, ind, matches, list) && 4530 2 find_non_indexed(sock, results[ind-1].id, list) ) { 4531 3 results[count++] = results[ind-1]; /* save the id */ 4532 3 matches = 1; 4533 3 } 4534 2 } 4535 1 return count; 4536 1 } 4537 4538 4539 /* 4540 return number of indexed fields 4541 ensure that and all fields exist and have lookup attribute 4542 */ 4543 int validate_fields(int sock, Arg *list) 4544 { 4545 1 int highest = 0, indexed = 0; 4546 1 Arg *ptr, *new; 4547 1 char *cp; 4548 1 4549 1 for (ptr = list; ptr && NotRet(ptr); ptr = ptr->next) { 4550 2 if (ptr->name && (ptr->field == -1)) { 4551 3 writestring(sock, "507:Field does not exist.\r\n"); 4552 3 return (0); /* force failure */ 4553 3 } 4554 2 if (ptr->field == -1) { /* null field name is 'name' field */ QI_QUERY 1-SEP-1993 10:04:04 VAX C V3.2-044 Page 8 V1.0 26-AUG-1993 19:15:04 X$SRC:[CSO]QI_QUERY.C;2 (1) 4555 3 ptr->field = atoi(NAME_FIELD); 4556 3 ptr->name = new_string(fields[ptr->field].name); 4557 3 } 4558 2 #if NAME_HACK 4559 2 /* compensate for the code in build.c */ 4560 2 if (ptr->field == atoi(NAME_FIELD)) { 4561 3 cp = strchr(ptr->value, '\''); 4562 3 if (cp) strcpy(cp, cp+1); /* squeeze out apostrophe */ 4563 3 cp = strchr(ptr->value, '-'); 4564 3 if (cp) { 4565 4 *cp = '\0'; 4566 4 new = make_arg(ptr->name, ptr->field, cp + 1, ptr->type); /* copy second name */ 4567 4 new->next = ptr->next; 4568 4 ptr->next = new; 4569 4 } 4570 3 } 4571 2 #endif 4572 2 if (fields[ptr->field].attrib & ATTR_INDEXED) 4573 2 indexed++; 4574 2 if ((fields[ptr->field].attrib & ATTR_LOOKUP) == 0) { 4575 3 writestring(sock, "516:No authorization for request.\r\n"); 4576 3 return (0); /* force failure */ 4577 3 } 4578 2 } 4579 1 return indexed; 4580 1 } 4581 4582 4583 int query(char *cmd, int sock) 4584 { 4585 1 int status, ind, hits, size = 0; 4586 1 Arg *list, *listp, *nick; 4587 1 Result *results = NULL; 4588 1 4589 1 list = parse_cmd(cmd, sock); /* build query struct from cmd */ 4590 1 4591 1 if (validate_fields(sock, list) == 0) 4592 1 writestring(sock, "515:No indexed field in query.\r\n"); 4593 1 else { 4594 2 for (listp = list; listp && NotRet(listp); listp = listp->next) { 4595 3 size = find(sock, listp, &results, size); /* record ids that match query */ 4596 3 /* if this is a name field, lookup nickname. Problems with resolver? */ 4597 3 if (listp->field == atoi(NAME_FIELD)) { 4598 4 nick = make_arg(listp->name, atoi(NICKNAME_FIELD), listp->value, listp->type), 4599 4 size = find(sock, nick, &results, size); 4600 4 free_args(nick); 4601 4 } 4602 3 } 4603 2 } 4604 1 if (size == 0) /* no index matches */ 4605 1 writestring(sock, "501:No matches to query.\r\n"); 4606 1 else { 4607 2 hits = resolve(sock, results, size, list); 4608 2 if (hits == 0) 4609 2 writestring(sock, "501:No matches to query.\r\n"); 4610 2 else if (hits > MAX_RECORDS) { 4611 3 writestring(sock, "502:Too many matches to query.\r\n"); QI_QUERY 1-SEP-1993 10:04:04 VAX C V3.2-044 Page 9 V1.0 26-AUG-1993 19:15:04 X$SRC:[CSO]QI_QUERY.C;2 (1) 4612 3 qilog(sock, "Too many matches (%d)", hits); 4613 3 } 4614 2 else { 4615 3 for (ind = 0; ind < hits; ind++) 4616 3 display_id(sock, results[ind].id, list, ind+1); 4617 3 qilog(sock, "Returned %d out of %d", hits, size); 4618 3 writestring(sock, "200:Ok.\r\n"); 4619 3 } 4620 2 } 4621 1 4622 1 free_args(list); 4623 1 free(results); 4624 1 return True; 4625 1 } 4626 4627 4628 void db_open() 4629 { 4630 1 idxfab = cc$rms_fab; 4631 1 idxfab.fab$b_fac = FAB$M_GET; 4632 1 idxfab.fab$l_fna = INDEX_NAME; 4633 1 idxfab.fab$b_fns = strlen(INDEX_NAME); 4634 1 idxfab.fab$b_shr = FAB$M_SHRGET; 4635 1 idxfab.fab$v_lnm_mode = PSL$C_EXEC; 4636 1 idxfab.fab$l_xab = &idxxab; 4637 1 4638 1 idxrab = cc$rms_rab; 4639 1 idxrab.rab$l_fab = &idxfab; 4640 1 idxrab.rab$l_kbf = idx_key; 4641 1 idxrab.rab$b_ksz = IDX_KEY_SIZE; 4642 1 idxrab.rab$b_rac = RAB$C_KEY; 4643 1 idxrab.rab$w_usz = IDX_RECORD_SIZE; 4644 1 idxrab.rab$l_ubf = idx_record; 4645 1 4646 1 idxxab = cc$rms_xabkey; 4647 1 idxxab.xab$w_pos0 = 0; 4648 1 idxxab.xab$b_siz0 = IDX_KEY_SIZE; 4649 1 4650 1 datfab = cc$rms_fab; 4651 1 datfab.fab$b_fac = FAB$M_GET; 4652 1 datfab.fab$l_fna = DATA_NAME; 4653 1 datfab.fab$b_fns = strlen(DATA_NAME); 4654 1 datfab.fab$b_shr = FAB$M_SHRGET; 4655 1 datfab.fab$v_lnm_mode = PSL$C_EXEC; 4656 1 datfab.fab$l_xab = &datxab; 4657 1 4658 1 datrab = cc$rms_rab; 4659 1 datrab.rab$l_fab = &datfab; 4660 1 datrab.rab$l_kbf = dat_key; 4661 1 datrab.rab$b_ksz = DAT_KEY_SIZE; 4662 1 datrab.rab$b_rac = RAB$C_KEY; 4663 1 datrab.rab$w_usz = DAT_RECORD_SIZE; 4664 1 datrab.rab$l_ubf = dat_record; 4665 1 4666 1 datxab = cc$rms_xabkey; 4667 1 datxab.xab$w_pos0 = 0; 4668 1 datxab.xab$b_siz0 = DAT_KEY_SIZE; QI_QUERY 1-SEP-1993 10:04:04 VAX C V3.2-044 Page 10 V1.0 26-AUG-1993 19:15:04 X$SRC:[CSO]QI_QUERY.C;2 (1) 4669 1 4670 1 4671 1 if (((db_status = sys$open(&idxfab)) & 1) != SS$_NORMAL) 4672 1 return; 4673 1 4674 1 if (((db_status = sys$connect(&idxrab)) & 1) != SS$_NORMAL) 4675 1 return; 4676 1 4677 1 if (idxfab.fab$b_org != FAB$C_IDX) { 4678 2 db_status = 0; 4679 2 return; 4680 2 } 4681 1 4682 1 if (((db_status = sys$open(&datfab)) & 1) != SS$_NORMAL) 4683 1 return; 4684 1 4685 1 if (((db_status = sys$connect(&datrab)) & 1) != SS$_NORMAL) 4686 1 return; 4687 1 4688 1 if (datfab.fab$b_org != FAB$C_IDX) { 4689 2 db_status = 0; 4690 2 return; 4691 2 } 4692 1 } 4693 4694 4695 void db_close() 4696 { 4697 1 sys$close(&idxfab); 4698 1 sys$close(&datfab); 4699 1 } Command Line ------------ CC/DEBUG/NOOP/LIST QI_QUERY .