/* * Copyright 1995 by Devin Reade . For distribution * information see the README file that is part of the manpack archive, * or contact the author, above. */ segment "apropos2__"; #include #include #include #include #include #include #include #include "util.h" #include "man.h" /* * orcapadding -- return a suitable number of padding tabs based on the * length of the command */ static char *orcapadding (char *command) { int i; static char *two ="\t\t"; static char *one ="\t"; static char *zero =" "; i = strlen(command); if (i<8) return two; if (i<16) return one; return zero; } /* * orcacomment -- return the start of the comment field in a line of * the Orca SYSCMND file. This _must_ be called before * orcacommand() is called on the same buffer, because * orcacommand() modifies the buffer. */ static char *orcacomment (char *buffer) { char *p; static char *bad_line="malformed SYSCMND line\n"; p = buffer; /* get past the command name */ while ((*p != ' ') && (*p != '\t') && *p) p++; if (!*p) return bad_line; /* get past space */ while ((*p == ' ') || (*p == '\t') && *p) p++; if (!*p) return bad_line; if (*p == '*') p++; switch (*p) { case 'U': /*FALLTHROUGH*/ case 'u': p++; break; case 'C': /*FALLTHROUGH*/ case 'L': /*FALLTHROUGH*/ case 'c': /*FALLTHROUGH*/ case 'l': p++; /* get past space */ while ((*p == ' ') || (*p == '\t') && *p) p++; if (!*p) return bad_line; /* get past command or language number */ while (isdigit(*p)) p++; break; default: return bad_line; break; } /* get past any remaining space */ while ((*p == ' ') || (*p == '\t')) p++; if (!*p) return bad_line; return p; } /* * orcacommand -- returns the command name that starts the buffer. * This _must_ be called after orcacomment because it * modifies the buffer. */ static char *orcacommand(char *buffer) { char *p; p = buffer; while (*p && !isspace(*p)) p++; *p = '\0'; return buffer; } /* * apropos -- print matching lines from WHATIS database. Returns the * number of matching lines, or -1 on error. * * Argv is an array of argc strings, each of which is a keyword. * Apropos will print out any line that matches any of the * keywords in argv. The match algorithm depends on the value * of apropos_mode, which may be one of the following. For the * first three modes, global variable must be set. * * MAN_K_MODE -- this is the one used by apropos(1). A * match is considered to be made if the keyword * appears anywhere in the WHATIS database line. * The match is case insensitive. * * MAN_F_MODE -- Any leading path component is stripped from * the keywords, and then a match is attempted * for any part of the WHATIS database line. The * match is case insensitive. * * WHATIS_MODE -- The WHATIS database line is parsed up to the * first occurance of a '(' character. If any * of the keywords are found, then the line is * printed. The search is case sensitive. * * ORCA_K_MODE -- Like MAN_K_MODE but instead of checking * the various WHATIS databases, it checks * 15/syscmnd. * * ORCA_W_MODE -- Like WHATIS_MODE but instead of checking * the various WHATIS databases, it checks * 15/syscmnd. * * WARNING: Use of the MAN_F_MODE may alter the contents of argv[]. */ int apropos(int argc, char **argv, int apropos_mode) { char **manpath_array; char *current_path, *p, *q, *r, *keyword; FILE *fp; char dirbrk; int i, j, matches; #ifdef DEBUG assert ((apropos_mode == WHATIS_MODE) || (apropos_mode == MAN_K_MODE) || (apropos_mode == MAN_F_MODE) || (apropos_mode == ORCA_K_MODE) || (apropos_mode == ORCA_F_MODE) || (apropos_mode == ORCA_W_MODE)); #endif matches = 0; /* * if we're doing 'man -f', get the basename for all keywords */ if ((apropos_mode == MAN_F_MODE) || (apropos_mode == ORCA_F_MODE)) { for (i=0; i