1: # include "../ingres.h" 2: # include "../aux.h" 3: # include "../catalog.h" 4: # include "../access.h" 5: 6: /* 7: ** HELP - Provide Information to User 8: ** 9: ** Arguments: 10: ** pv[i] - code 11: ** 0 - print relation information 12: ** 1 - print manual section 13: ** 2 - print relation list 14: ** 3 - print relation info for all accessible relations 15: ** pv[i+1] - name of entity for modes 0 or 1 16: ** 17: ** Uses trace flags 10, 11, 12, and 13 18: */ 19: 20: help(parmc, parmv) 21: int parmc; 22: char **parmv; 23: { 24: struct descriptor des; 25: int mode; 26: register char **pv; 27: register int ret; 28: 29: ret = 0; 30: pv = parmv; 31: getuser(-1); /* init getuser for modes 1 & 2 */ 32: while (*pv != -1) 33: { 34: 35: if (atoi(*pv++, &mode)) 36: { 37: badmode: 38: syserr("HELP: mode %s", *--pv); 39: } 40: 41: # ifdef xZTR1 42: if (tTf(10, -1) || tTf(0, 10)) 43: { 44: printf("help %d", mode); 45: if (mode != 2) 46: printf(" %s", *pv); 47: putchar('\n'); 48: } 49: # endif 50: switch (mode) 51: { 52: 53: case 0: /* help relation */ 54: if (!openr(&des, -1, *pv)) 55: { 56: rel_fmt(&des); 57: *pv = 0; 58: } 59: pv++; 60: break; 61: 62: case 1: /* help manual section */ 63: if (man(*pv)) 64: *pv = 0; 65: pv++; 66: break; 67: 68: case 2: 69: case 3: 70: relpr(mode); 71: break; 72: 73: default: 74: goto badmode; 75: } 76: } 77: getuser(0); /* close getuser in case mode 1 or 2 */ 78: 79: /* now rescan for error messages */ 80: pv = parmv; 81: while (*pv != -1) 82: { 83: atoi(*pv++, &mode); 84: 85: switch (mode) 86: { 87: 88: case 0: 89: case 1: 90: if (*pv) 91: ret = error(5401 + mode, *pv, 0); 92: break; 93: 94: case 2: 95: case 3: 96: continue; 97: } 98: pv++; 99: } 100: return (ret); 101: } 102: 103: 104: /* 105: ** Nroff Manual Section 106: ** 107: ** The manual section given by 'name' is nroff'ed. Returns one 108: ** on success, zero if the manual section is not found. 109: ** 110: ** Uses trace flag 11 111: */ 112: 113: man(name) 114: char *name; 115: { 116: char manual[100]; 117: register int i; 118: int stat; 119: char name_nr[18]; 120: register char *naa; 121: char *ztack(); 122: 123: if (length(name) > 14) 124: return (0); 125: 126: /* a null manual name gives table of contents */ 127: if (name[0] == 0) 128: smove("../toc.nr", name_nr); 129: else 130: concat(name, ".nr", name_nr); 131: 132: concat(ztack(Pathname, "/doc/quel/"), name_nr, manual); 133: if ((i = open(manual, 0)) < 0) 134: { 135: /* try a unix command instead */ 136: concat(ztack(Pathname, "/doc/unix/"), name_nr, manual); 137: if ((i = open(manual, 0)) < 0) 138: return (0); 139: } 140: if (close(i)) 141: syserr("cannot close %s", manual); 142: ruboff(0); /* wait for child's death if rubout occures */ 143: i = fork(); 144: if (i == 0) 145: { 146: signal(2, 0); /* die on rubout */ 147: setuid(getuid()); 148: # ifndef xB_UNIX 149: setgid(getgid()); 150: # endif 151: naa = ztack(Pathname, "/doc/iaa"); 152: execl("/bin/nroff", "nroff", naa, manual, 0); 153: execl("/usr/bin/nroff", "nroff", naa, manual, 0); 154: syserr("help: exec: nroff"); 155: } 156: /* wait for nroff if fork succeeded */ 157: if (i > 0) 158: fullwait(i, "help: nroff"); 159: rubon(); 160: return (1); 161: } 162: 163: 164: /* 165: ** PRINT DATABASE INFORMATION 166: ** 167: ** Prints a list of all the relations in the database, together 168: ** with their owner. 169: ** 170: ** Uses trace flag 12 171: */ 172: 173: relpr(mode) 174: int mode; 175: { 176: extern struct descriptor Reldes; 177: register struct descriptor *d; 178: register int i; 179: register char *cp; 180: struct tup_id limtid, tid; 181: char buf[MAXLINE + 1]; 182: char lastuser[2]; 183: struct relation rel; 184: char *bmove(); 185: 186: opencatalog("relation", 0); 187: d = &Reldes; 188: if (i = find(d, NOKEY, &tid, &limtid)) 189: syserr("help: relpr: find %d", i); 190: 191: lastuser[0] = '\0'; 192: 193: if (mode == 2) 194: printf("\n relation name relation owner\n\n"); 195: 196: while ((i = get(d, &tid, &limtid, &rel, 1)) == 0) 197: { 198: if (mode == 2) 199: { 200: if (!bequal(lastuser, rel.relowner, 2)) 201: { 202: if (getuser(rel.relowner, buf)) 203: { 204: /* cant find user code */ 205: cp = bmove(" ", buf, 2); 206: cp = bmove(rel.relowner, cp, 2); 207: *cp = '\0'; 208: } 209: else 210: { 211: for (cp = buf; *cp != ':'; cp++) 212: ; 213: *cp = '\0'; 214: } 215: bmove(rel.relowner, lastuser, 2); 216: } 217: printf(" %.12s %s\n", rel.relid, buf); 218: } 219: else 220: { 221: if ((rel.relstat & S_CATALOG) || bequal("_SYS", rel.relid, 4)) 222: continue; 223: if (bequal(Usercode, rel.relowner, 2) || bequal(Admin.adhdr.adowner, rel.relowner, 2)) 224: rel_fmt(&rel); 225: } 226: } 227: 228: if (i < 0) 229: syserr("help: relpr: get %d", i); 230: if (mode == 2) 231: printf("\n"); 232: return (0); 233: } 234: 235: 236: 237: /* 238: ** Print Relation Information 239: ** 240: ** Prints detailed information regarding the relation. 241: ** 242: ** Uses trace flag 13 243: */ 244: 245: rel_fmt(rel) 246: struct relation *rel; 247: { 248: struct tup_id limtid, tid; 249: char buf[MAXLINE + 1]; 250: struct attribute att; 251: struct index indkey, ind; 252: register int i; 253: int j; 254: extern struct descriptor Attdes, Inddes; 255: register struct relation *r; 256: char *trim_relname(); 257: 258: r = rel; 259: printf("\nRelation:\t\t%s\n", trim_relname(r->relid)); 260: i = getuser(r->relowner, buf); 261: if (i) 262: { 263: smove("(xx)", buf); 264: bmove(r->relowner, &buf[1], 2); 265: } 266: else 267: { 268: for (i = 0; buf[i] != ':'; i++) 269: continue; 270: buf[i] = 0; 271: } 272: printf("Owner:\t\t\t%s\n", buf); 273: printf("Tuple width:\t\t%d\n", r->relwid); 274: if (r->relsave != 0) 275: { 276: printf("Saved until:\t\t%s", ctime(&r->relsave)); 277: } 278: if ((r->relstat & S_VIEW) == 0) 279: { 280: printf("Number of tuples:\t%s\n", locv(r->reltups)); 281: printf("Storage structure:\t"); 282: i = r->relspec; 283: if (i < 0) 284: { 285: printf("compressed "); 286: i = -i; 287: } 288: switch (i) 289: { 290: 291: case M_HEAP: 292: printf("paged heap\n"); 293: break; 294: 295: case M_ISAM: 296: printf("ISAM file\n"); 297: break; 298: 299: case M_HASH: 300: printf("random hash\n"); 301: break; 302: 303: default: 304: printf("unknown structure %d\n", i); 305: break; 306: 307: } 308: } 309: 310: printf("Relation type:\t\t"); 311: if (r->relstat & S_CATALOG) 312: printf("system catalog\n"); 313: else if (r->relstat & S_VIEW) 314: printf("view\n"); 315: else 316: if (r->relindxd < 0) 317: { 318: printf("secondary index on "); 319: opencatalog("indexes", 0); 320: setkey(&Inddes, &indkey, r->relowner, IOWNERP); 321: setkey(&Inddes, &indkey, r->relid, IRELIDI); 322: if (!getequal(&Inddes, &indkey, &ind, &tid)) 323: printf("%s\n", trim_relname(ind.irelidp)); 324: else 325: printf("unknown relation\n"); 326: } 327: else 328: { 329: if (r->relstat & S_DISTRIBUTED) 330: printf("distributed "); 331: printf("user relation\n"); 332: } 333: if (r->relindxd > 0) 334: { 335: printf("Secondary Indices:\t"); 336: opencatalog("indexes", 0); 337: setkey(&Inddes, &indkey, r->relid, IRELIDP); 338: setkey(&Inddes, &indkey, r->relowner, IOWNERP); 339: if (i = find(&Inddes, EXACTKEY, &tid, &limtid, &indkey)) 340: syserr("help: find %d indexes", i); 341: j = FALSE; 342: while ((i = get(&Inddes, &tid, &limtid, &ind, 1)) == 0) 343: { 344: if (!bequal(&indkey, &ind, MAXNAME + 2)) 345: continue; 346: if (j) 347: printf(", "); 348: j =TRUE; 349: printf("%s", trim_relname(ind.irelidi)); 350: } 351: if (i < 0) 352: syserr("help:get indexes %d", i); 353: if (!j) 354: printf("unknown"); 355: } 356: printf("\n"); 357: 358: opencatalog("attribute", 0); 359: printf("\n attribute name type length keyno.\n\n"); 360: seq_init(&Attdes, r); 361: while (seq_attributes(&Attdes, r, &att)) 362: { 363: printf(" %.12s %c%8d", 364: att.attname, typeunconv(att.attfrmt), att.attfrml & 0377); 365: if (att.attxtra) 366: printf("%7d", att.attxtra); 367: printf("\n"); 368: } 369: 370: printf("\n"); 371: return (0); 372: }