📄 man.c
字号:
* Search the manuals for the pages. */static intmanual(page, tag, pg) char *page; TAG *tag; glob_t *pg;{ ENTRY *ep, *e_sufp, *e_tag; TAG *missp, *sufp; int anyfound, cnt, found; char *p, buf[128]; anyfound = 0; buf[0] = '*'; /* For each element in the list... */ e_tag = tag == NULL ? NULL : tag->list.tqh_first; for (; e_tag != NULL; e_tag = e_tag->q.tqe_next) { (void)snprintf(buf, sizeof(buf), "%s/%s.*", e_tag->s, page); if (glob(buf, GLOB_APPEND | GLOB_BRACE | GLOB_NOSORT | GLOB_QUOTE, NULL, pg)) { warn("globbing"); (void)cleanup(); exit(1); } if (pg->gl_matchc == 0) continue; /* Find out if it's really a man page. */ for (cnt = pg->gl_pathc - pg->gl_matchc; cnt < pg->gl_pathc; ++cnt) { /* * Try the _suffix key words first. * * XXX * Older versions of man.conf didn't have the suffix * key words, it was assumed that everything was a .0. * We just test for .0 first, it's fast and probably * going to hit. */ (void)snprintf(buf, sizeof(buf), "*/%s.0", page); if (!fnmatch(buf, pg->gl_pathv[cnt], 0)) goto next; e_sufp = (sufp = getlist("_suffix")) == NULL ? NULL : sufp->list.tqh_first; for (found = 0; e_sufp != NULL; e_sufp = e_sufp->q.tqe_next) { (void)snprintf(buf, sizeof(buf), "*/%s%s", page, e_sufp->s); if (!fnmatch(buf, pg->gl_pathv[cnt], 0)) { found = 1; break; } } if (found) goto next; /* Try the _build key words next. */ e_sufp = (sufp = getlist("_build")) == NULL ? NULL : sufp->list.tqh_first; for (found = 0; e_sufp != NULL; e_sufp = e_sufp->q.tqe_next) { for (p = e_sufp->s; *p != '\0' && !isspace(*p); ++p); if (*p == '\0') continue; *p = '\0'; (void)snprintf(buf, sizeof(buf), "*/%s%s", page, e_sufp->s); if (!fnmatch(buf, pg->gl_pathv[cnt], 0)) { if (!f_where) build_page(p + 1, &pg->gl_pathv[cnt]); *p = ' '; found = 1; break; } *p = ' '; } if (found) {next: anyfound = 1; if (!f_all) { /* Delete any other matches. */ while (++cnt< pg->gl_pathc) pg->gl_pathv[cnt] = ""; break; } continue; } /* It's not a man page, forget about it. */ pg->gl_pathv[cnt] = ""; } if (anyfound && !f_all) break; } /* If not found, enter onto the missing list. */ if (!anyfound) { if ((missp = getlist("_missing")) == NULL) missp = addlist("_missing"); if ((ep = malloc(sizeof(ENTRY))) == NULL || (ep->s = strdup(page)) == NULL) { warn(NULL); (void)cleanup(); exit(1); } TAILQ_INSERT_TAIL(&missp->list, ep, q); } return (anyfound);}/* * build_page -- * Build a man page for display. */static voidbuild_page(fmt, pathp) char *fmt, **pathp;{ static int warned; ENTRY *ep; TAG *intmpp; int fd; char buf[MAXPATHLEN], cmd[MAXPATHLEN], tpath[sizeof(_PATH_TMP)]; /* Let the user know this may take awhile. */ if (!warned) { warned = 1; warnx("Formatting manual page..."); } /* Add a remove-when-done list. */ if ((intmpp = getlist("_intmp")) == NULL) intmpp = addlist("_intmp"); /* Move to the printf(3) format string. */ for (; *fmt && isspace(*fmt); ++fmt); /* * Get a temporary file and build a version of the file * to display. Replace the old file name with the new one. */ (void)strcpy(tpath, _PATH_TMP); if ((fd = mkstemp(tpath)) == -1) { warn("%s", tpath); (void)cleanup(); exit(1); } (void)snprintf(buf, sizeof(buf), "%s > %s", fmt, tpath); (void)snprintf(cmd, sizeof(cmd), buf, *pathp); (void)system(cmd); (void)close(fd); if ((*pathp = strdup(tpath)) == NULL) { warn(NULL); (void)cleanup(); exit(1); } /* Link the built file into the remove-when-done list. */ if ((ep = malloc(sizeof(ENTRY))) == NULL) { warn(NULL); (void)cleanup(); exit(1); } ep->s = *pathp; TAILQ_INSERT_TAIL(&intmpp->list, ep, q);}/* * how -- * display how information */static voidhow(fname) char *fname;{ FILE *fp; int lcnt, print; char *p, buf[256]; if (!(fp = fopen(fname, "r"))) { warn("%s", fname); (void)cleanup(); exit (1); }#define S1 "SYNOPSIS"#define S2 "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS"#define D1 "DESCRIPTION"#define D2 "D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN" for (lcnt = print = 0; fgets(buf, sizeof(buf), fp);) { if (!strncmp(buf, S1, sizeof(S1) - 1) || !strncmp(buf, S2, sizeof(S2) - 1)) { print = 1; continue; } else if (!strncmp(buf, D1, sizeof(D1) - 1) || !strncmp(buf, D2, sizeof(D2) - 1)) return; if (!print) continue; if (*buf == '\n') ++lcnt; else { for(; lcnt; --lcnt) (void)putchar('\n'); for (p = buf; isspace(*p); ++p); (void)fputs(p, stdout); } } (void)fclose(fp);}/* * cat -- * cat out the file */static voidcat(fname) char *fname;{ int fd, n; char buf[2048]; if ((fd = open(fname, O_RDONLY, 0)) < 0) { warn("%s", fname); (void)cleanup(); exit(1); } while ((n = read(fd, buf, sizeof(buf))) > 0) if (write(STDOUT_FILENO, buf, n) != n) { warn("write"); (void)cleanup(); exit (1); } if (n == -1) { warn("read"); (void)cleanup(); exit(1); } (void)close(fd);}/* * check_pager -- * check the user supplied page information */static char *check_pager(name) char *name;{ char *p, *save; /* * if the user uses "more", we make it "more -s"; watch out for * PAGER = "mypager /usr/ucb/more" */ for (p = name; *p && !isspace(*p); ++p); for (; p > name && *p != '/'; --p); if (p != name) ++p; /* make sure it's "more", not "morex" */ if (!strncmp(p, "more", 4) && (!p[4] || isspace(p[4]))){ save = name; /* allocate space to add the "-s" */ if (!(name = malloc((u_int)(strlen(save) + sizeof("-s") + 1)))) err(1, NULL); (void)sprintf(name, "%s %s", save, "-s"); } return(name);}/* * jump -- * strip out flag argument and jump */static voidjump(argv, flag, name) char **argv, *flag, *name;{ char **arg; argv[0] = name; for (arg = argv + 1; *arg; ++arg) if (!strcmp(*arg, flag)) break; for (; *arg; ++arg) arg[0] = arg[1]; execvp(name, argv); (void)fprintf(stderr, "%s: Command not found.\n", name); exit(1);}/* * onsig -- * If signaled, delete the temporary files. */static voidonsig(signo) int signo;{ (void)cleanup(); (void)signal(signo, SIG_DFL); (void)kill(getpid(), signo); /* NOTREACHED */ exit (1);}/* * cleanup -- * Clean up temporary files, show any error messages. */static intcleanup(){ TAG *intmpp, *missp; ENTRY *ep; int rval; rval = 0; ep = (missp = getlist("_missing")) == NULL ? NULL : missp->list.tqh_first; if (ep != NULL) for (; ep != NULL; ep = ep->q.tqe_next) { warnx("no entry for %s in the manual.", ep->s); rval = 1; } ep = (intmpp = getlist("_intmp")) == NULL ? NULL : intmpp->list.tqh_first; for (; ep != NULL; ep = ep->q.tqe_next) (void)unlink(ep->s); return (rval);}/* * usage -- * print usage message and die */static voidusage(){ (void)fprintf(stderr, "usage: man [-achw] [-C file] [-M path] [-m path] [section] title ...\n"); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -