![]() ![]() | ![]() |
version 1.2, 2012/06/09 14:11:16 | version 1.14, 2016/07/09 15:24:19 | ||
---|---|---|---|
|
|
||
/* $Id$ */ | /* $Id$ */ | ||
/* | /* | ||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv> | * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv> | ||
* Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org> | |||
* | * | ||
* Permission to use, copy, modify, and distribute this software for any | * Permission to use, copy, modify, and distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | * purpose with or without fee is hereby granted, provided that the above | ||
|
|
||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | */ | ||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | #include "config.h" | ||
#endif | |||
#include <sys/param.h> | |||
#include <sys/types.h> | |||
#include <assert.h> | #include <assert.h> | ||
#include <getopt.h> | #include <limits.h> | ||
#include <stdint.h> | |||
#include <stdio.h> | #include <stdio.h> | ||
#include <stdlib.h> | #include <stdlib.h> | ||
#include <string.h> | #include <string.h> | ||
#include <unistd.h> | #include <unistd.h> | ||
#include "manpath.h" | #include "manconf.h" | ||
#include "mansearch.h" | #include "mansearch.h" | ||
static void show(const char *, const char *); | static void show(const char *, const char *); | ||
|
|
||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||
{ | { | ||
int ch, term; | int ch, term; | ||
size_t i, sz, len; | size_t i, sz, linesz; | ||
ssize_t len; | |||
struct mansearch search; | struct mansearch search; | ||
struct manpage *res; | struct manpage *res; | ||
char *conf_file, *defpaths, *auxpaths, *cp; | char *conf_file, *defpaths, *auxpaths, *line; | ||
char buf[MAXPATHLEN]; | char buf[PATH_MAX]; | ||
const char *cmd; | const char *cmd; | ||
struct manpaths paths; | struct manconf conf; | ||
char *progname; | char *progname; | ||
extern char *optarg; | extern char *optarg; | ||
extern int optind; | extern int optind; | ||
|
|
||
++progname; | ++progname; | ||
auxpaths = defpaths = conf_file = NULL; | auxpaths = defpaths = conf_file = NULL; | ||
memset(&paths, 0, sizeof(struct manpaths)); | memset(&conf, 0, sizeof(conf)); | ||
memset(&search, 0, sizeof(struct mansearch)); | memset(&search, 0, sizeof(struct mansearch)); | ||
while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:"))) | while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:"))) | ||
|
|
||
if (0 == argc) | if (0 == argc) | ||
goto usage; | goto usage; | ||
search.deftype = TYPE_Nm | TYPE_Nd; | search.outkey = "Nd"; | ||
search.argmode = ARG_EXPR; | |||
manpath_parse(&paths, conf_file, defpaths, auxpaths); | manconf_parse(&conf, conf_file, defpaths, auxpaths); | ||
ch = mansearch(&search, &paths, argc, argv, &res, &sz); | ch = mansearch(&search, &conf.manpath, argc, argv, &res, &sz); | ||
manpath_free(&paths); | manconf_free(&conf); | ||
if (0 == ch) | if (0 == ch) | ||
goto usage; | goto usage; | ||
if (0 == sz) { | if (0 == sz) { | ||
free(res); | free(res); | ||
return(EXIT_FAILURE); | return EXIT_FAILURE; | ||
} else if (1 == sz && term) { | } else if (1 == sz && term) { | ||
i = 1; | i = 1; | ||
goto show; | goto show; | ||
} else if (NULL == res) | } else if (NULL == res) | ||
return(EXIT_FAILURE); | return EXIT_FAILURE; | ||
for (i = 0; i < sz; i++) { | for (i = 0; i < sz; i++) { | ||
printf("%6zu %s: %s\n", | printf("%6zu %s: %s\n", | ||
i + 1, res[i].file, res[i].desc); | i + 1, res[i].names, res[i].output); | ||
free(res[i].desc); | free(res[i].names); | ||
free(res[i].output); | |||
} | } | ||
if (0 == term) { | if (0 == term) { | ||
for (i = 0; i < sz; i++) | |||
free(res[i].file); | |||
free(res); | free(res); | ||
return(EXIT_SUCCESS); | return EXIT_SUCCESS; | ||
} | } | ||
i = 1; | i = 1; | ||
printf("Enter a choice [1]: "); | printf("Enter a choice [1]: "); | ||
fflush(stdout); | fflush(stdout); | ||
if (NULL != (cp = fgetln(stdin, &len))) | line = NULL; | ||
if ('\n' == cp[--len] && len > 0) { | linesz = 0; | ||
cp[len] = '\0'; | if ((len = getline(&line, &linesz, stdin)) != -1) { | ||
if ((i = atoi(cp)) < 1 || i > sz) | if ('\n' == line[--len] && len > 0) { | ||
line[len] = '\0'; | |||
if ((i = atoi(line)) < 1 || i > sz) | |||
i = 0; | i = 0; | ||
} | } | ||
} | |||
free(line); | |||
if (0 == i) { | if (0 == i) { | ||
for (i = 0; i < sz; i++) | |||
free(res[i].file); | |||
free(res); | free(res); | ||
return(EXIT_SUCCESS); | return EXIT_SUCCESS; | ||
} | } | ||
show: | show: | ||
cmd = res[i - 1].form ? "mandoc" : "cat"; | cmd = res[i - 1].form ? "mandoc" : "cat"; | ||
strlcpy(buf, res[i - 1].file, MAXPATHLEN); | strlcpy(buf, res[i - 1].file, PATH_MAX); | ||
for (i = 0; i < sz; i++) | |||
free(res[i].file); | |||
free(res); | free(res); | ||
show(cmd, buf); | show(cmd, buf); | ||
/* NOTREACHED */ | /* NOTREACHED */ | ||
usage: | usage: | ||
fprintf(stderr, "usage: %s [-C conf] " | fprintf(stderr, "usage: %s [-C conf] " | ||
"[-M paths] " | "[-M paths] " | ||
"[-m paths] " | "[-m paths] " | ||
"[-S arch] " | "[-S arch] " | ||
"[-s section] " | "[-s section] " | ||
"expr ...\n", | "expr ...\n", | ||
progname); | progname); | ||
return(EXIT_FAILURE); | return EXIT_FAILURE; | ||
} | } | ||
static void | static void | ||
|
|
||
} else if (pid > 0) { | } else if (pid > 0) { | ||
dup2(fds[0], STDIN_FILENO); | dup2(fds[0], STDIN_FILENO); | ||
close(fds[1]); | close(fds[1]); | ||
cmd = NULL != getenv("MANPAGER") ? | cmd = NULL != getenv("MANPAGER") ? | ||
getenv("MANPAGER") : | getenv("MANPAGER") : | ||
(NULL != getenv("PAGER") ? | (NULL != getenv("PAGER") ? | ||
getenv("PAGER") : "more"); | getenv("PAGER") : "more"); | ||
execlp(cmd, cmd, (char *)NULL); | execlp(cmd, cmd, (char *)NULL); | ||
perror(cmd); | perror(cmd); |