|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 4880 (0x1310) Types: TextFile Notes: UNIX file Names: »help.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─⟦this⟧ »cmd/help.c«
/* * Command to give help on various command's usages. * Also, this command allows user-specific information * to be kept. */ #include <stdio.h> #include <sys/stat.h> #define NLINE 512 /* Longest helpfile line */ char doc[50]; char buf[BUFSIZ]; char *list[2]; char helpline[NLINE]; char helpfile[] = "/etc/helpfile"; FILE *shf; /* System helpfile */ FILE *uhf; /* User helpfile */ /* * Structure to speed lookup time. */ struct look { long l_seek; char *l_name; }; struct look *lread(); char helpuse[] = "\ The 'help' command prints a brief description of the usage of a command.\n\ For example, to get information about the 'who' command, type:\n\ help who\n\ The 'man' command provides more detailed descriptions of commands.\n\ \n\ "; char noinf[] = "No information on %s\n"; char *getenv(); main(argc, argv) char *argv[]; { register char **ap; register int estat = 0; char *fn; shf = fopen(helpfile, "r"); if ((fn = getenv("HELP")) != NULL) uhf = fopen(fn, "r"); setbuf(stdout, buf); ap = argv+1; if (argc < 2) { fprintf(stderr, helpuse); ap = list; if ((*ap = getenv("LASTERROR")) == NULL) exit(0); } while (*ap != NULL) { if (help(*ap)) { printf(noinf, *ap); estat |= 1; } if (*++ap != NULL) putchar('\n'); fflush(stdout); } exit(estat); } /* * This routine looks for information * in the on-line documentation for * the specified command. * The information is bracketed by `.HS' * and `.HE'. * If nothing is found, search the other two places. */ help(command) char *command; { register int bad = 1; register FILE *hf; sprintf(doc, "/usr/man/cmd/%s", command); if ((hf = fopen(doc, "r")) == NULL) { strcat(doc, "m"); if ((hf = fopen(doc, "r")) == NULL) goto other; } for (;;) { if (fgets(helpline, NLINE, hf) == NULL) break; if (strcmp(helpline, ".HS\n") == 0) { bad = 0; break; } } if (!bad) while (fgets(helpline, NLINE, hf) != NULL && strcmp(helpline, ".HE\n") != 0) fputs(helpline, stdout); fclose(hf); other: if (bad) if (bad = lookup(command, shf, "/etc/helpindex")) bad = lookup(command, uhf, NULL); return (bad); } /* * Lookup a command in the given file. * The format is to look for # lines. * The index-file is provided to speed up * the lookup in situations where there is a very * large system help file. */ lookup(com, fp, ind) register char *com; FILE *fp; char *ind; { if (fp == NULL) return (1); if (fastlook(com, fp, ind)) return (1); while (fgets(helpline, NLINE, fp) != NULL) if (helpline[0] == '#') { helpline[strlen(helpline)-1] = '\0'; if (strcmp(com, helpline+1) == 0) { while (fgets(helpline, NLINE, fp) != NULL) { if (helpline[0] == '#') break; fputs(helpline, stdout); } return (0); } } return (1); } /* * Possibly seek the helpfile to the right place * based on an index file. * Return non-zero only when it is impossible to * find it. * If the index file is out of date, re-build it. */ fastlook(com, fp, ind) char *com; FILE *fp; char *ind; { register char *cp, *ep; register struct look *lp; struct look look; FILE *ifp; long seek = 0; int found = 0; static struct stat sb; long htime; fstat(fileno(fp), &sb); htime = sb.st_mtime; if (stat(ind, &sb) < 0) goto rebuild; if (htime < sb.st_mtime) { if ((ifp = fopen(ind, "r")) == NULL) goto rebuild; while ((lp = lread(ifp)) != NULL) if (strcmp(com, lp->l_name) == 0) { seek = lp->l_seek; found++; break; } fclose(ifp); if (found) { fseek(fp, seek, 0); return (0); } return (1); } rebuild: /* * Re-build the index file. */ if ((ifp = fopen(ind, "w")) == NULL) return (0); for (;;) { look.l_seek = ftell(fp); if (fgets(helpline, NLINE, fp) == NULL) break; cp = helpline; if (*cp++ != '#') continue; while (*cp==' ' && *cp=='\t') cp++; ep = cp; while (*ep!='\n' && *ep!='\0' && *ep!=' ' && *ep!='\t') ep++; *ep = '\0'; look.l_name = cp; if (strcmp(com, cp) == 0) { seek = look.l_seek; found++; } lwrite(&look, ifp); } fclose(ifp); if (found) { fseek(fp, seek, 0); return (0); } return (1); } /* * Read in a look structure. Return NULL * on end of file or error. */ struct look * lread(fp) register FILE *fp; { register char *cp; register int c; static struct look look; static char name[50]; look.l_name = name; if (fread(&look.l_seek, sizeof look.l_seek, 1, fp) != 1) return (NULL); for (cp = name; cp<&name[49]; cp++) { if ((c = getc(fp)) == EOF) return (NULL); *cp = c; if (c == '\0') break; } return (&look); } /* * Write out a structure to the * given file pointer. */ lwrite(lp, fp) register struct look *lp; FILE *fp; { register char *cp; fwrite(&lp->l_seek, 1, sizeof lp->l_seek, fp); cp = lp->l_name; do { putc(*cp, fp); } while (*cp++ != '\0'); }