From: Ben Gras Date: Sat, 26 Jun 2010 02:33:49 +0000 (+0000) Subject: no more minix man X-Git-Tag: v3.1.8~345 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/named.html?a=commitdiff_plain;h=24cb4e60fc55725b9c6b9d06c8110b6698b8ad6e;p=minix.git no more minix man --- diff --git a/commands/Makefile b/commands/Makefile index 61b67c101..4d6a71215 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -16,7 +16,7 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \ hostaddr id ifconfig ifdef indent install \ intr ipcrm ipcs irdpd isoread join kill last leave \ less lex life loadkeys loadramdisk logger login look lp \ - lpd ls lspci M m4 mail make MAKEDEV man \ + lpd ls lspci M m4 mail make MAKEDEV \ mdb mdocml mesg mined mkdep mkdir mkdist mkfifo mkfs mknod \ mkproto modem mount mt netconf newroot nice nm nohup \ nonamed od packit packman passwd paste patch pax \ diff --git a/commands/man/Makefile b/commands/man/Makefile deleted file mode 100644 index eb8e2f91b..000000000 --- a/commands/man/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -PROG= man -MAN= - -.include diff --git a/commands/man/man.c b/commands/man/man.c deleted file mode 100644 index 5bfc3ffa3..000000000 --- a/commands/man/man.c +++ /dev/null @@ -1,695 +0,0 @@ -/* man 2.5 - display online manual pages Author: Kees J. Bot - * 17 Mar 1993 - */ -#define nil NULL -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Defaults: */ -char MANPATH[]= "/usr/local/man:/usr/man:/usr/gnu/man"; -char PAGER[]= "more"; - -/* Comment at the start to let tbl(1) be run before n/troff. */ -char TBL_MAGIC[] = ".\\\"t\n"; - -#define arraysize(a) (sizeof(a) / sizeof((a)[0])) -#define arraylimit(a) ((a) + arraysize(a)) -#define between(a, c, z) ((unsigned) ((c) - (a)) <= (unsigned) ((z) - (a))) - -/* Section 1x uses special macros under Minix. */ -#if __minix -#define SEC1xSPECIAL 1 -#else -#define SEC1xSPECIAL 0 -#endif - -int searchwhatis(FILE *wf, char *title, char **ppage, char **psection) -/* Search a whatis file for the next occurence of "title". Return the basename - * of the page to read and the section it is in. Return 0 on failure, 1 on - * success, -1 on EOF or error. - */ -{ - static char page[256], section[32]; - char alias[256]; - int found= 0; - int c; - - /* Each whatis line should have the format: - * page, title, title (section) - descriptive text - */ - - /* Search the file for a line with the title. */ - do { - int first= 1; - char *pc= section; - - c= fgetc(wf); - - /* Search the line for the title. */ - do { - char *pa= alias; - - while (c == ' ' || c == '\t' || c == ',') c= fgetc(wf); - - while (c != ' ' && c != '\t' && c != ',' - && c != '(' && c != '\n' && c != EOF - ) { - if (pa < arraylimit(alias)-1) *pa++= c; - c= getc(wf); - } - *pa= 0; - if (first) { strcpy(page, alias); first= 0; } - - if (strcmp(alias, title) == 0) found= 1; - } while (c != '(' && c != '\n' && c != EOF); - - if (c != '(') { - found= 0; - } else { - while ((c= fgetc(wf)) != ')' && c != '\n' && c != EOF) { - if ('A' <= c && c <= 'Z') c= c - 'A' + 'a'; - if (pc < arraylimit(section)-1) *pc++= c; - } - *pc= 0; - if (c != ')' || pc == section) found= 0; - } - while (c != EOF && c != '\n') c= getc(wf); - } while (!found && c != EOF); - - if (found) { - *ppage= page; - *psection= section; - } - return c == EOF ? -1 : found; -} - -int searchwindex(FILE *wf, char *title, char **ppage, char **psection) -/* Search a windex file for the next occurence of "title". Return the basename - * of the page to read and the section it is in. Return 0 on failure, 1 on - * success, -1 on EOF or error. - */ -{ - static char page[256], section[32]; - static long low, high; - long mid0, mid1; - int c; - unsigned char *pt; - char *pc; - - /* Each windex line should have the format: - * title page (section) - descriptive text - * The file is sorted. - */ - - if (ftell(wf) == 0) { - /* First read of this file, initialize. */ - low= 0; - fseek(wf, (off_t) 0, SEEK_END); - high= ftell(wf); - } - - /* Binary search for the title. */ - while (low <= high) { - pt= (unsigned char *) title; - - mid0= mid1= (low + high) >> 1; - if (mid0 == 0) { - if (fseek(wf, (off_t) 0, SEEK_SET) != 0) - return -1; - } else { - if (fseek(wf, (off_t) mid0 - 1, SEEK_SET) != 0) - return -1; - - /* Find the start of a line. */ - while ((c= getc(wf)) != EOF && c != '\n') - mid1++; - if (ferror(wf)) return -1; - } - - /* See if the line has the title we seek. */ - for (;;) { - if ((c= getc(wf)) == ' ' || c == '\t') c= 0; - if (c == 0 || c != *pt) break; - pt++; - } - - /* Halve the search range. */ - if (c == EOF || *pt <= c) { - high= mid0 - 1; - } else { - low= mid1 + 1; - } - } - - /* Look for the title from 'low' onwards. */ - if (fseek(wf, (off_t) low, SEEK_SET) != 0) - return -1; - - do { - if (low != 0) { - /* Find the start of a line. */ - while ((c= getc(wf)) != EOF && c != '\n') - low++; - if (ferror(wf)) return -1; - } - - /* See if the line has the title we seek. */ - pt= (unsigned char *) title; - - for (;;) { - if ((c= getc(wf)) == EOF) return 0; - low++; - if (c == ' ' || c == '\t') c= 0; - if (c == 0 || c != *pt) break; - pt++; - } - } while (c < *pt); - - if (*pt != c) return 0; /* Not found. */ - - /* Get page and section. */ - while ((c= fgetc(wf)) == ' ' || c == '\t') {} - - pc= page; - while (c != ' ' && c != '\t' && c != '(' && c != '\n' && c != EOF) { - if (pc < arraylimit(page)-1) *pc++= c; - c= getc(wf); - } - if (pc == page) return 0; - *pc= 0; - - while (c == ' ' || c == '\t') c= fgetc(wf); - - if (c != '(') return 0; - - pc= section; - while ((c= fgetc(wf)) != ')' && c != '\n' && c != EOF) { - if ('A' <= c && c <= 'Z') c= c - 'A' + 'a'; - if (pc < arraylimit(section)-1) *pc++= c; - } - *pc= 0; - if (c != ')' || pc == section) return 0; - - while (c != EOF && c != '\n') c= getc(wf); - if (c != '\n') return 0; - - *ppage= page; - *psection= section; - return 1; -} - -char ALL[]= ""; /* Magic sequence of all sections. */ - -int all= 0; /* Show all pages with a given title. */ -int whatis= 0; /* man -f word == whatis word. */ -int apropos= 0; /* man -k word == apropos word. */ -int quiet= 0; /* man -q == quietly check. */ -enum ROFF { NROFF, TROFF } rofftype= NROFF; -char *roff[] = { "nroff", "troff" }; - -int shown; /* True if something has been shown. */ -int tty; /* True if displaying on a terminal. */ -char *manpath; /* The manual directory path. */ -char *pager; /* The pager to use. */ - -char *pipeline[8][8]; /* An 8 command pipeline of 7 arguments each. */ -char *(*plast)[8] = pipeline; - -void putinline(char *arg1, ...) -/* Add a command to the pipeline. */ -{ - va_list ap; - char **argv; - - argv= *plast++; - *argv++= arg1; - - va_start(ap, arg1); - while ((*argv++= va_arg(ap, char *)) != nil) {} - va_end(ap); -} - -void execute(int set_mp, char *file) -/* Execute the pipeline build with putinline(). (This is a lot of work to - * avoid a call to system(), but it so much fun to do it right!) - */ -{ - char *(*plp)[8], **argv; - char *mp; - int fd0, pfd[2], err[2]; - pid_t pid; - int r, status; - int last; - void (*isav)(int sig), (*qsav)(int sig), (*tsav)(int sig); - - if (tty) { - /* Must run this through a pager. */ - putinline(pager, (char *) nil); - } - if (plast == pipeline) { - /* No commands at all? */ - putinline("cat", (char *) nil); - } - - /* Add the file as argument to the first command. */ - argv= pipeline[0]; - while (*argv != nil) argv++; - *argv++= file; - *argv= nil; - - /* Start the commands. */ - fd0= 0; - for (plp= pipeline; plp < plast; plp++) { - argv= *plp; - last= (plp+1 == plast); - - /* Create an error pipe and pipe between this command and the next. */ - if (pipe(err) < 0 || (!last && pipe(pfd) < 0)) { - fprintf(stderr, "man: can't create a pipe: %s\n", strerror(errno)); - exit(1); - } - - (void) fcntl(err[1], F_SETFD, fcntl(err[1], F_GETFD) | FD_CLOEXEC); - - if ((pid = fork()) < 0) { - fprintf(stderr, "man: cannot fork: %s\n", strerror(errno)); - exit(1); - } - if (pid == 0) { - /* Child. */ - if (set_mp) { - mp= malloc((8 + strlen(manpath) + 1) * sizeof(*mp)); - if (mp != nil) { - strcpy(mp, "MANPATH="); - strcat(mp, manpath); - (void) putenv(mp); - } - } - - if (fd0 != 0) { - dup2(fd0, 0); - close(fd0); - } - if (!last) { - close(pfd[0]); - if (pfd[1] != 1) { - dup2(pfd[1], 1); - close(pfd[1]); - } - } - close(err[0]); - execvp(argv[0], argv); - (void) write(err[1], &errno, sizeof(errno)); - _exit(1); - } - - close(err[1]); - if (read(err[0], &errno, sizeof(errno)) != 0) { - fprintf(stderr, "man: %s: %s\n", argv[0], - strerror(errno)); - exit(1); - } - close(err[0]); - - if (!last) { - close(pfd[1]); - fd0= pfd[0]; - } - set_mp= 0; - } - - /* Wait for the last command to finish. */ - isav= signal(SIGINT, SIG_IGN); - qsav= signal(SIGQUIT, SIG_IGN); - tsav= signal(SIGTERM, SIG_IGN); - while ((r= wait(&status)) != pid) { - if (r < 0) { - fprintf(stderr, "man: wait(): %s\n", strerror(errno)); - exit(1); - } - } - (void) signal(SIGINT, isav); - (void) signal(SIGQUIT, qsav); - (void) signal(SIGTERM, tsav); - if (status != 0) exit(1); - plast= pipeline; -} - -void keyword(char *keyword) -/* Make an apropos(1) or whatis(1) call. */ -{ - putinline(apropos ? "apropos" : "whatis", - all ? "-a" : (char *) nil, - (char *) nil); - - if (tty) { - printf("Looking for keyword '%s'\n", keyword); - fflush(stdout); - } - - execute(1, keyword); -} - -enum pagetype { CAT, CATZ, MAN, MANZ, SMAN, SMANZ }; - -int showpage(char *page, enum pagetype ptype, char *macros) -/* Show a manual page if it exists using the proper decompression and - * formatting tools. - */ -{ - struct stat st; - - /* We want a normal file without X bits if not a full path. */ - if (stat(page, &st) < 0) return 0; - - if (!S_ISREG(st.st_mode)) return 0; - if ((st.st_mode & 0111) && page[0] != '/') return 0; - - /* Do we only care if it exists? */ - if (quiet) { shown= 1; return 1; } - - if (ptype == CATZ || ptype == MANZ || ptype == SMANZ) { - putinline("zcat", (char *) nil); - } - - if (ptype == SMAN || ptype == SMANZ) { - /* Change SGML into regular *roff. */ - putinline("/usr/lib/sgml/sgml2roff", (char *) nil); - putinline("tbl", (char *) nil); - putinline("eqn", (char *) nil); - } - - if (ptype == MAN) { - /* Do we need tbl? */ - FILE *fp; - int c; - char *tp = TBL_MAGIC; - - if ((fp = fopen(page, "r")) == nil) { - fprintf(stderr, "man: %s: %s\n", page, strerror(errno)); - exit(1); - } - c= fgetc(fp); - for (;;) { - if (c == *tp || (c == '\'' && *tp == '.')) { - if (*++tp == 0) { - /* A match, add tbl. */ - putinline("tbl", (char *) nil); - break; - } - } else { - /* No match. */ - break; - } - while ((c = fgetc(fp)) == ' ' || c == '\t') {} - } - fclose(fp); - } - - if (ptype == MAN || ptype == MANZ || ptype == SMAN || ptype == SMANZ) { - putinline(roff[rofftype], macros, (char *) nil); - } - - if (tty) { - printf("%s %s\n", - ptype == CAT || ptype == CATZ ? "Showing" : "Formatting", page); - fflush(stdout); - } - execute(0, page); - - shown= 1; - return 1; -} - -int member(char *word, char *list) -/* True if word is a member of a comma separated list. */ -{ - size_t len= strlen(word); - - if (list == ALL) return 1; - - while (*list != 0) { - if (strncmp(word, list, len) == 0 - && (list[len] == 0 || list[len] == ',')) - return 1; - while (*list != 0 && *list != ',') list++; - if (*list == ',') list++; - } - return 0; -} - -int trymandir(char *mandir, char *title, char *section) -/* Search the whatis file of the manual directory for a page of the given - * section and display it. - */ -{ - FILE *wf; - char whatis[1024], pagename[1024], *wpage, *wsection; - int rsw, rsp; - int ntries; - int (*searchidx)(FILE *, char *, char **, char **); - struct searchnames { - enum pagetype ptype; - char *pathfmt; - } *sp; - static struct searchnames searchN[] = { - { CAT, "%s/cat%s/%s.%s" }, /* SysV */ - { CATZ, "%s/cat%s/%s.%s.Z" }, - { MAN, "%s/man%s/%s.%s" }, - { MANZ, "%s/man%s/%s.%s.Z" }, - { SMAN, "%s/sman%s/%s.%s" }, /* Solaris */ - { SMANZ,"%s/sman%s/%s.%s.Z" }, - { CAT, "%s/cat%.1s/%s.%s" }, /* BSD */ - { CATZ, "%s/cat%.1s/%s.%s.Z" }, - { MAN, "%s/man%.1s/%s.%s" }, - { MANZ, "%s/man%.1s/%s.%s.Z" }, - }; - - if (strlen(mandir) + 1 + 6 + 1 > arraysize(whatis)) return 0; - - /* Prefer a fast windex database if available. */ - sprintf(whatis, "%s/windex", mandir); - - if ((wf= fopen(whatis, "r")) != nil) { - searchidx= searchwindex; - } else { - /* Use a classic whatis database. */ - sprintf(whatis, "%s/whatis", mandir); - - if ((wf= fopen(whatis, "r")) == nil) return 0; - searchidx= searchwhatis; - } - - rsp= 0; - while (!rsp && (rsw= (*searchidx)(wf, title, &wpage, &wsection)) == 1) { - if (!member(wsection, section)) continue; - - /* When looking for getc(1S) we try: - * cat1s/getc.1s - * cat1s/getc.1s.Z - * man1s/getc.1s - * man1s/getc.1s.Z - * sman1s/getc.1s - * sman1s/getc.1s.Z - * cat1/getc.1s - * cat1/getc.1s.Z - * man1/getc.1s - * man1/getc.1s.Z - */ - - if (strlen(mandir) + 2 * strlen(wsection) + strlen(wpage) - + 10 > arraysize(pagename)) - continue; - - sp= searchN; - ntries= arraysize(searchN); - do { - if (sp->ptype <= CATZ && rofftype != NROFF) - continue; - - sprintf(pagename, sp->pathfmt, - mandir, wsection, wpage, wsection); - - rsp= showpage(pagename, sp->ptype, - (SEC1xSPECIAL && strcmp(wsection, "1x") == 0) ? "-mnx" : "-man"); - } while (sp++, !rsp && --ntries != 0); - - if (all) rsp= 0; - } - if (rsw < 0 && ferror(wf)) { - fprintf(stderr, "man: %s: %s\n", whatis, strerror(errno)); - exit(1); - } - fclose(wf); - return rsp; -} - -int trysubmandir(char *mandir, char *title, char *section) -/* Search the subdirectories of this manual directory for whatis files, they - * may have manual pages that override the ones in the major directory. - */ -{ - char submandir[1024]; - DIR *md; - struct dirent *entry; - - if ((md= opendir(mandir)) == nil) return 0; - - while ((entry= readdir(md)) != nil) { - if (strcmp(entry->d_name, ".") == 0 - || strcmp(entry->d_name, "..") == 0) continue; - if ((strncmp(entry->d_name, "man", 3) == 0 - || strncmp(entry->d_name, "cat", 3) == 0) - && between('0', entry->d_name[3], '9')) continue; - - if (strlen(mandir) + 1 + strlen(entry->d_name) + 1 - > arraysize(submandir)) continue; - - sprintf(submandir, "%s/%s", mandir, entry->d_name); - - if (trymandir(submandir, title, section) && !all) { - closedir(md); - return 1; - } - } - closedir(md); - - return 0; -} - -void searchmanpath(char *title, char *section) -/* Search the manual path for a manual page describing "title." */ -{ - char mandir[1024]; - char *pp= manpath, *pd; - - for (;;) { - while (*pp != 0 && *pp == ':') pp++; - - if (*pp == 0) break; - - pd= mandir; - while (*pp != 0 && *pp != ':') { - if (pd < arraylimit(mandir)) *pd++= *pp; - pp++; - } - if (pd == arraylimit(mandir)) continue; /* forget it */ - - *pd= 0; - if (trysubmandir(mandir, title, section) && !all) break; - if (trymandir(mandir, title, section) && !all) break; - } -} - -void usage(void) -{ - fprintf(stderr, "Usage: man -[antfkq] [-M path] [-s section] title ...\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - char *title, *section= ALL; - int i; - int nomoreopt= 0; - char *opt; - - if ((pager= getenv("PAGER")) == nil) pager= PAGER; - if ((manpath= getenv("MANPATH")) == nil) manpath= MANPATH; - tty= isatty(1); - - i= 1; - do { - while (i < argc && argv[i][0] == '-' && !nomoreopt) { - opt= argv[i++]+1; - if (opt[0] == '-' && opt[1] == 0) { - nomoreopt= 1; - break; - } - while (*opt != 0) { - switch (*opt++) { - case 'a': - all= 1; - break; - case 'f': - whatis= 1; - break; - case 'k': - apropos= 1; - break; - case 'q': - quiet= 1; - break; - case 'n': - rofftype= NROFF; - apropos= whatis= 0; - break; - case 't': - rofftype= TROFF; - apropos= whatis= 0; - break; - case 's': - if (*opt == 0) { - if (i == argc) usage(); - section= argv[i++]; - } else { - section= opt; - opt= ""; - } - break; - case 'M': - if (*opt == 0) { - if (i == argc) usage(); - manpath= argv[i++]; - } else { - manpath= opt; - opt= ""; - } - break; - default: - usage(); - } - } - } - - if (i >= argc) usage(); - - if (between('0', argv[i][0], '9') && i+1 < argc) { - /* Old BSD style section designation? */ - section= argv[i++]; - } - if (i == argc) usage(); - - title= argv[i++]; - - if (whatis || apropos) { - keyword(title); - } else { - shown= 0; - searchmanpath(title, section); - - if (!shown) (void) showpage(title, MAN, "-man"); - - if (!shown) { - if (!quiet) { - fprintf(stderr, - "man: no manual on %s\n", - title); - } - exit(1); - } - } - } while (i < argc); - - return 0; -}