home *** CD-ROM | disk | FTP | other *** search
- /*
- * Name: help.c
- * Purpose: display help about commands & system features
- * Syntax: help [cmd]
- * Comment: Help displays help screens on all user commands
- * as set up in the file /usr/lib/helpfile.
- * It is particularly useful on systems with restricted
- * diskspace, where it is not practical to keep the manuals
- * on-line.
- * The command is patterned after the MKS Toolkit command
- * of the same name. If no /usr/lib/helpindex file exists, or if
- * it is older than the helpfile, a new helpindex will be
- * created to allow faster access to the helpscreens by
- * means of fseek().
- * Desirable enhancements would include the possibility to
- * have help look in an environment variable HELPFILE for
- * an alternate or additional helpfile,
- * [ Done by John Plocher - uses HELPDIR to set the directory
- * where the help file and its index are. It also uses HELPFILE
- * to give the name of the data file ($HELPFILE.idx is the index)
- * defaults are "/usr/lib" and "helpfile" ]
- * and/or to have help look in $HOME/.helpfile if a command
- * is not found in the default helpfile.
- * Another useful feature would be the possibility of using
- * a pager specified by $PAGER to output the help info, since
- * a few entries (stty, vi, ...) are longer than one screen.
- * No doubt the coding could be considerably improved, and
- * any suggestions would be more than welcome.
- * Author: Wolf Paul, ihnp4!killer!dcs!wnp
- * Date: Dec. 18, 1987
- *
- * Revision Control Information
- *
- * Last edited by: $Author: plocher $
- * $Revision: 1.1 $
- * Last modified: $Date: 87/12/26 23:34:50 $
- * Source is in: $Source: /u/microport/src/help/RCS/help.c,v $
- *
- * Release state: $State: Posted $
- *
- * Modification Log
- * ----------------
- *
- * $Log: help.c,v $
- * Revision 1.1 87/12/26 23:34:50 plocher
- * Added enviroment variables for HELPDIR and HELPFILE
- *
- */
-
- #ifndef lint
- static char rcsid[] =
- "$Header: help.c,v 1.1 87/12/26 23:34:50 plocher Posted $";
- #endif
-
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #define MAXLINE 134
- #define HELPDIR "/usr/lib" /* Added by John Plocher */
- #define HELPFILE "helpfile" /* .. */
- #define INDEX ".idx" /* .. */
-
- char helpfilename[128]; /* John Plocher */
- char helpidxname[128]; /* .. */
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- struct
- {
- char name[15];
- long offset;
- } entry; /* helpindex entries for each command */
-
- struct stat sbuf1, sbuf2; /* stat buffers for helpfile & helpindex */
- char *command, *line, Line[MAXLINE];
- register char *cp; /* John Plocher */
- extern char *getenv(); /* .. */
- int status;
- FILE *ifp, *hfp; /* file pointers for helpfile and helpindex */
-
- if ( argc == 1 ) /* If no arguments, ... */
- command = "help"; /* ... default to "help help" */
- else
- command = argv[1]; /* else look for command in argv[1] */
-
-
- /* Added by John Plocher Sat Dec 26 22:02:09 CST 1987
- * Look for:
- * getenv("HELPDIR") + getenv("HELPFILE")
- * getenv("HELPDIR") + "helpfile"
- * "/usr/lib" + getenv("HELPFILE")
- * "/usr/lib" + "helpfile"
- */
- if ((cp = getenv("HELPDIR")) != NULL) /* if a dir is given, use it */
- strcpy(helpidxname, cp);
- else
- strcpy(helpidxname, HELPDIR);
- strcpy(helpfilename, helpidxname);
- strcat(helpfilename, "/");
-
- if ((cp = getenv("HELPFILE")) != NULL) /* if a filename is given, use it */
- strcat(helpfilename, cp);
- else
- strcat(helpfilename, HELPFILE);
-
- strcpy(helpidxname, helpfilename); /* make a name for the index file */
- strcat(helpidxname, INDEX);
-
- stat(helpfilename, &sbuf1); /* get mtime for helpfile */
- status=access(helpidxname, 0);
- if ( status == 0 ) /* if helpindex exists ... */
- {
- stat(helpidxname, &sbuf2); /* get mtime for helpindex */
- }
- if ( (status != 0) || /* if there is no helpindex ... */
- ((time_t)sbuf1.st_mtime > (time_t)sbuf2.st_mtime) )
- /* or if it is older than helpfile */
- {
- buildindex(); /* build a new helpindex */
- }
-
- if ( (ifp=fopen(helpidxname, "r")) == NULL )
- {
- fprintf(stderr, "Can't read %s\n", helpidxname);
- exit(-1);
- }
-
- while ( 1 ) /* look for index entry for "command" */
- {
- status=fread(&entry, sizeof(entry), 1, ifp);
- if ( status==0 ) /* quit at end of index file */
- {
- fprintf(stderr, "No help for %s\n", command);
- fclose(ifp);
- exit(1); }
- if ( strcmp(entry.name, command) == 0 ) /* quit when we find it */
- {
- fclose(ifp);
- break;
- }
- }
-
- if ((hfp=fopen(helpfilename, "r")) == NULL )
- {
- fprintf(stderr, "Can't open %s\n", helpfilename);
- exit(-1);
- }
-
- fseek(hfp, entry.offset, 0); /* go to the help entry */
-
- while ( 1 ) /* just copy lines to stdout */
- {
- line = fgets(Line, MAXLINE, hfp);
- if ( line == (char *) NULL || line[0] == '#' )
- /* until another entry starts */
- break;
- fputs(line,stdout);
- }
-
- fclose(hfp);
- }
-
- buildindex()
- {
- FILE *hfp, *ifp;
- struct {
- char name[15];
- long offset;
- } entry;
- char Line[MAXLINE];
- char *line;
- int i,j;
-
-
- unlink(helpidxname); /* remove old index file */
- if ( (hfp=fopen(helpfilename, "r")) == NULL )
- {
- fprintf(stderr,"buildindex: Can't read %s\n", helpfilename);
- exit(-1);
- }
- if ( (ifp=fopen(helpidxname, "w")) == NULL )
- {
- fprintf(stderr, "buildindex: Can't write %s\n", helpidxname);
- exit(-1);
- }
-
- while (1) /* Read thru helpfile ... */
- {
- entry.offset=(long) 0;
- line = fgets(Line, MAXLINE, hfp);
- if ( line == (char *) NULL ) break;
- if ( line[0] == '#' ) /* and for each help entry ... */
- {
- line++;
- while ( isspace(line[0]) ) line++;
- i=j=0;
- while ( line[i] != '\0' )
- {
- if ( line[i] == '\n' ) break;
- while ( line[i] == ' ' || line[i] == ',' ) i++;
- while ( !isspace(line[i] ) &&
- line[i] != ',') /* save its name ... */
- {
- entry.name[j] = line[i];
- i++; j++;
- }
- while ( j < 15 )
- entry.name[j++] = '\0';
- j = 0;
- entry.offset=ftell(hfp); /* and its offset ... */
- fwrite(&entry, sizeof(entry), 1, ifp);
- /* and write it to indexfile */
- }
- }
- }
- fclose(hfp);
- fclose(ifp);
- }
-