|
|
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');
}