# include # include # include # include # include # include # include # include # include SCCSID(@(#)help.c 8.5 2/8/85) extern short tTdbu[100]; extern int help(); extern int null_fn(); struct fn_def HelpFn = { "HELP", help, null_fn, /* initialization function */ null_fn, NULL, 0, tTdbu, 100, 'Z', 0 }; /* ** HELP - Provide Information to User ** ** Arguments: ** pv[i] - code ** RELINFO - print relation information ** MANSEC - print manual section ** DELIMLIST - print delim information ** RELIST - print relation list ** ALLRELINFO - print relation info for all accessible ** relations ** ** pv[i+1] - name of entity for modes 0 or 1 ** ** Trace Flags: ** 44 */ help(parmc, parmv) int parmc; PARM parmv[]; { DESC des; int mode; register PARM *pv; register int ret; int i; # ifdef xZTR1 if (tTf(44, -1)) { printf(">>help\n"); if (tTf(44, 0)) prvect(parmc, parmv); } # endif ret = 0; pv = parmv; getuser(-1); /* init getuser for modes RELINFO & MANSEC */ while (pv->pv_type != PV_EOF) { mode = (pv++)->pv_val.pv_int; if (mode < RELIST && pv->pv_type == PV_EOF) syserr("help: mode %d no val", mode); # ifdef xZTR1 if (tTf(44, -1)) { printf("help %d", mode); if (mode != RELIST) printf(" %s", pv->pv_val.pv_str); putchar('\n'); } # endif switch (mode) { case RELINFO: /* help relation */ if (!openr(&des, OR_RELTID, pv->pv_val.pv_str)) { rel_fmt(&des); pv->pv_val.pv_str = NULL; } pv++; break; case MANSEC: /* help manual section */ if (man(pv->pv_val.pv_str)) pv->pv_val.pv_str = NULL; pv++; break; case DELLIST: /* help delim */ if (!openr(&des, OR_READ, "rdelim")) { if ((i = helpdelim(pv->pv_val.pv_str,&des)) == -1) return(error(RDELIMERR, pv->pv_val.pv_str, 0)); closer(&des); pv->pv_val.pv_str = NULL; } pv++; break; case RELIST: case ALLRELINFO: relpr(mode); break; case ALLDELLIST: if (!openr(&des, OR_READ, "rdelim")) { if ((i = alldelims(&des)) == -1) return(error(RDELIMERR, pv->pv_val.pv_str, 0)); closer(&des); pv->pv_val.pv_str = NULL; } pv++; break; default: syserr("HELP: mode %d", mode); } } getuser(0); /* close getuser in case mode RELINFO or MANSEC */ /* now rescan for error messages */ pv = parmv; while (pv->pv_type != PV_EOF) { mode = (pv++)->pv_val.pv_int; if (mode < RELIST) { if (pv->pv_val.pv_str != NULL) ret = nferror(NORELEXIST + mode, pv->pv_val.pv_str, 0); pv++; } } return (ret); } /* ** Nroff Manual Section ** ** The manual section given by 'name' is nroff'ed. Returns one ** on success, zero if the manual section is not found. ** ** Uses trace flag 11 */ int man(name) char *name; { char manual[100]; register int i; int stat; char name_nr[18]; register char *naa; extern char *ztack(); if (length(name) > 14) return (0); /* a null manual name gives table of contents */ if (name[0] == 0) smove("../toc.nr", name_nr); else concat(name, ".nr", name_nr); concat(ztack(Pathname, "/doc/quel/"), name_nr, manual); if ((i = open(manual, O_RDONLY)) < 0) { /* try a unix command instead */ concat(ztack(Pathname, "/doc/unix/"), name_nr, manual); if ((i = open(manual, O_RDONLY)) < 0) return (0); } if (close(i)) syserr("cannot close %s", manual); ruboff(0); /* wait for child's death if rubout occures */ i = fork(); if (i == 0) { signal(SIGINT, SIG_DFL); /* die on rubout */ setuid(getuid()); # ifndef xB_UNIX setgid(getgid()); # endif naa = ztack(Pathname, "/doc/iaa"); execl("/bin/nroff", "nroff", naa, manual, 0); execl("/usr/bin/nroff", "nroff", naa, manual, 0); syserr("help: exec: nroff"); } /* wait for nroff if fork succeeded */ if (i > 0) fullwait(i, "help: nroff"); rubon(); return (1); } /* ** PRINT DATABASE INFORMATION ** ** Prints a list of all the relations in the database, together ** with their owner. ** ** Uses trace flag 12 */ relpr(mode) int mode; { extern DESC Reldes; register DESC *d; register int i; register char *cp; struct tup_id limtid, tid; char buf[MAXLINE + 1]; char lastuser[2]; struct relation rel; opencatalog("relation", OR_READ); d = &Reldes; if (i = find(d, NOKEY, &tid, &limtid)) syserr("help: relpr: find %d", i); lastuser[0] = '\0'; if (mode == RELIST) printf("\n relation name relation owner\n\n"); while ((i = get(d, &tid, &limtid, &rel, 1)) == 0) { if (mode == RELIST) { if (!bequal(lastuser, rel.relowner, 2)) { if (getuser(rel.relowner, buf)) { /* cant find user code */ bmove(" ", buf, 2); cp = &buf[2]; bmove(rel.relowner, cp, 2); cp = &cp[2]; *cp = '\0'; } else { for (cp = buf; *cp != ':'; cp++) ; *cp = '\0'; } bmove(rel.relowner, lastuser, 2); } printf(" %.12s %s\n", rel.relid, buf); } else { if ((rel.relstat & S_CATALOG) || bequal("_SYS", rel.relid, 4)) continue; if (bequal(Usercode, rel.relowner, UCODE_SZ) || bequal(Admin.adhdr.adowner, rel.relowner, 2)) rel_fmt(&rel); } } if (i < 0) syserr("help: relpr: get %d", i); if (mode == RELIST) printf("\n"); return (0); } /* ** Print Relation Information ** ** Prints detailed information regarding the relation. ** ** Uses trace flag 13 */ rel_fmt(r) register struct relation *r; { struct tup_id limtid, tid; char buf[MAXLINE + 1]; struct attribute att; struct index indkey, ind; register int i; int j; extern DESC Attdes, Inddes; char *trim_relname(); printf("\nRelation:\t\t%s\n", trim_relname(r->relid)); i = getuser(r->relowner, buf); if (i) { smove("(xx)", buf); bmove(r->relowner, &buf[1], 2); } else { for (i = 0; buf[i] != ':'; i++) continue; buf[i] = 0; } printf("Owner:\t\t\t%s\n", buf); printf("Tuple width:\t\t%d\n", r->relwid); if (r->relsave != 0) { printf("Saved until:\t\t%s", ctime(&r->relsave)); } if ((r->relstat & S_VIEW) == 0) { printf("Number of tuples:\t%ld\n", r->reltups); printf("Storage structure:\t"); i = r->relspec; if (i < 0) { printf("compressed "); i = -i; } switch (i) { case M_HEAP: printf("paged heap\n"); break; case M_ISAM: printf("ISAM file\n"); break; case M_HASH: printf("random hash\n"); break; default: printf("unknown structure %d\n", i); break; } } printf("Relation type:\t\t"); if (r->relstat & S_CATALOG) printf("system catalog\n"); else if (r->relstat & S_VIEW) printf("view\n"); else if (r->reldim > 0) printf("ordered relation\n"); else if (r->relindxd < 0) { printf("secondary index on "); opencatalog("indexes", OR_READ); setkey(&Inddes, &indkey, r->relowner, IOWNERP); setkey(&Inddes, &indkey, r->relid, IRELIDI); if (!getequal(&Inddes, &indkey, &ind, &tid)) printf("%s\n", trim_relname(ind.irelidp)); else printf("unknown relation\n"); } else { if (r->relstat & S_DISTRIBUTED) printf("distributed "); printf("user relation\n"); } if (r->relindxd > 0) { printf("Secondary Indices:\t"); opencatalog("indexes", OR_READ); setkey(&Inddes, &indkey, r->relid, IRELIDP); setkey(&Inddes, &indkey, r->relowner, IOWNERP); if (i = find(&Inddes, EXACTKEY, &tid, &limtid, &indkey)) syserr("help: find %d indexes", i); j = FALSE; while ((i = get(&Inddes, &tid, &limtid, &ind, 1)) == 0) { if (!bequal(&indkey, &ind, MAXNAME + 2)) continue; if (j) printf(", "); j =TRUE; printf("%s", trim_relname(ind.irelidi)); } if (i < 0) syserr("help:get indexes %d", i); if (!j) printf("unknown"); } printf("\n"); opencatalog("attribute", OR_READ); printf("\n attribute name type length keyno.\n\n"); seq_init(&Attdes, r); while (seq_attributes(&Attdes, r, &att)) { printf(" %.12s %c%8d", att.attname, att.attfrmt, att.attfrml & I1MASK); if (att.attxtra) printf("%7d", att.attxtra); printf("\n"); } printf("\n"); return (0); } /* ** HELPDELIM - print all delims presently defined. ** ** Parameters: ** group - the group of delims to print ** ** Returns: ** 0 - if successful ** -1 - if relation not found */ helpdelim(group,des) char *group; DESC *des; { DELIM_TUP tuple; TID lotid,hitid; int notfound = 1; char delim[12]; int start = 0; int begin = 1; char dstring[1024]; char *dptr; int found=0; if (find(des,LRANGEKEY, &lotid, &hitid, group) < 0) return(-1); find(des,HRANGEKEY, &lotid, &hitid, group); printf("\n \t>>>> %s <<<<\n", group); while (!get(des, &lotid, &hitid, &tuple, 1)) { if (strcmp(tuple.group, group)) continue; if (strcmp(tuple.delim, delim)) start = 1; if (start) { found = 1; if (begin) begin = 0; else print_delim(dstring); /*start a new string*/ strcpy(delim, tuple.delim); start = 0; *dstring = NULL; strcat(dstring, tuple.delim); strcat(dstring, ": "); convert_bitmap(dstring, &tuple); } else { /*add to old string*/ convert_bitmap(dstring, &tuple); } } if (!found) printf("group %s does not exist\n", group); else print_delim(dstring); return(0); } /* ** CONVERT_BITMAP - convert a bitmap back to a BNF expression ** ** Parameters: ** dstring - string to stuff the BNF expression info ** tuple - tuple containing the bitmap ** */ convert_bitmap(dstring, tuple) char *dstring; DELIM_TUP *tuple; { int i,j; char *pntr; pntr = dstring + strlen(dstring); *pntr++ = (tuple->type == ONE ? LBRACKET : LBRACE); i = 0; while (i < 128 ) { if (test(tuple->bitmap, i)) { *pntr++ = i; j = ++i; while ((j < 128) && test(tuple->bitmap, j)) j++; if ( (j - i) >= 5) { j--; *pntr++ = '-'; *pntr++ = j; i = j + 1; } } else i++; } *pntr++ = (tuple->type == ONE ? RBRACKET : RBRACE); *pntr = NULL; } /* ** PRINT_DELIM - print one delim of the rdelim relation ** ** Parameters: ** */ print_delim(delim) char *delim; { printf("%s\n", delim); } /* ** ALLDELIMS - print all the delims currently defined ** */ alldelims(des) DESC *des; { DELIM_TUP tuple; int start=1; char group[12]; TID lotid; TID hitid; printf("Delimitor groups:\n"); if (find(des,LRANGEKEY, &lotid, &hitid, group) < 0) return(-1); find(des,HRANGEKEY, &lotid, &hitid, group); while (!get(des, &lotid, &hitid, &tuple, 1)) { if (strcmp(tuple.group, group)) start = 1; if (start) { strcpy(group, tuple.group); printf("\t\t %s\n", group); /*helpdelim(group, des); */ start = 0; } } }