# include "../ingres.h" # include "../aux.h" # include "../catalog.h" # include "../access.h" /* ** HELP - Provide Information to User ** ** Arguments: ** pv[i] - code ** 0 - print relation information ** 1 - print manual section ** 2 - print relation list ** 3 - print relation info for all accessible relations ** pv[i+1] - name of entity for modes 0 or 1 ** ** Uses trace flags 10, 11, 12, and 13 */ help(parmc, parmv) int parmc; char **parmv; { struct descriptor des; int mode; register char **pv; register int ret; ret = 0; pv = parmv; getuser(-1); /* init getuser for modes 1 & 2 */ while (*pv != -1) { if (atoi(*pv++, &mode)) { badmode: syserr("HELP: mode %s", *--pv); } # ifdef xZTR1 if (tTf(10, -1) || tTf(0, 10)) { printf("help %d", mode); if (mode != 2) printf(" %s", *pv); putchar('\n'); } # endif switch (mode) { case 0: /* help relation */ if (!openr(&des, -1, *pv)) { rel_fmt(&des); *pv = 0; } pv++; break; case 1: /* help manual section */ if (man(*pv)) *pv = 0; pv++; break; case 2: case 3: relpr(mode); break; default: goto badmode; } } getuser(0); /* close getuser in case mode 1 or 2 */ /* now rescan for error messages */ pv = parmv; while (*pv != -1) { atoi(*pv++, &mode); switch (mode) { case 0: case 1: if (*pv) ret = error(5401 + mode, *pv, 0); break; case 2: case 3: continue; } 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 */ man(name) char *name; { char manual[100]; register int i; int stat; char name_nr[18]; register char *naa; 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, 0)) < 0) { /* try a unix command instead */ concat(ztack(Pathname, "/doc/unix/"), name_nr, manual); if ((i = open(manual, 0)) < 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(2, 0); /* 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 struct descriptor Reldes; register struct descriptor *d; register int i; register char *cp; struct tup_id limtid, tid; char buf[MAXLINE + 1]; char lastuser[2]; struct relation rel; char *bmove(); opencatalog("relation", 0); d = &Reldes; if (i = find(d, NOKEY, &tid, &limtid)) syserr("help: relpr: find %d", i); lastuser[0] = '\0'; if (mode == 2) printf("\n relation name relation owner\n\n"); while ((i = get(d, &tid, &limtid, &rel, 1)) == 0) { if (mode == 2) { if (!bequal(lastuser, rel.relowner, 2)) { if (getuser(rel.relowner, buf)) { /* cant find user code */ cp = bmove(" ", buf, 2); cp = bmove(rel.relowner, 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, 2) || bequal(Admin.adhdr.adowner, rel.relowner, 2)) rel_fmt(&rel); } } if (i < 0) syserr("help: relpr: get %d", i); if (mode == 2) printf("\n"); return (0); } /* ** Print Relation Information ** ** Prints detailed information regarding the relation. ** ** Uses trace flag 13 */ rel_fmt(rel) struct relation *rel; { struct tup_id limtid, tid; char buf[MAXLINE + 1]; struct attribute att; struct index indkey, ind; register int i; int j; extern struct descriptor Attdes, Inddes; register struct relation *r; char *trim_relname(); r = rel; 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%s\n", locv(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->relindxd < 0) { printf("secondary index on "); opencatalog("indexes", 0); 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", 0); 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", 0); 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, typeunconv(att.attfrmt), att.attfrml & 0377); if (att.attxtra) printf("%7d", att.attxtra); printf("\n"); } printf("\n"); return (0); }