diff -ur ../man-1.6g.orig/man2html/man2html.c ./man2html/man2html.c --- ../man-1.6g.orig/man2html/man2html.c 2007-08-05 12:15:23.000000000 -0700 +++ ./man2html/man2html.c 2011-12-15 03:28:57.605162107 -0700 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,108 @@ static char charb[3]; +#ifdef GUNZIP +/* from src/utils.c */ +static int +is_shell_safe(const char *ss, int quoted) { + char *bad = " ;'\\\"<>|"; + char *p; + + if (quoted) + bad++; /* allow a space inside quotes */ + for (p = bad; *p; p++) + if (strchr(ss, *p)) + return 0; + return 1; +} +#endif + +/* reads the entire manpage into buffer *buf and returns number of chars read */ +static int +read_manpage_into_buffer(char *path, char **buf) { + int compressed = 0; + FILE * f = NULL; + char * ext; + int l = 0; + struct stat stbuf; + + *buf = NULL; + if (!path) + return -1; + + if (!strcmp(path, "-")) + f = stdin; + else /* strcmp(path, "-") */ + { + char * tmp = NULL; + char * command = NULL; + char * openpath = path; +#ifdef GUNZIP + + if (is_shell_safe(openpath, 1)) { + ext = strrchr(openpath, '.'); + compressed = (ext && !strcmp(ext, ".gz")); + + if (!compressed && stat(openpath, &stbuf)) { + tmp = (char*) xmalloc(strlen(path) + 4); + sprintf(tmp, "%s.gz", path); + if ((compressed = !stat(tmp, &stbuf))) + openpath = tmp; + } + } + + if (compressed) { + command = (char*) xmalloc(strlen(openpath) + sizeof(GUNZIP) + 4); + sprintf(command, GUNZIP " '%s'", openpath); + f = popen(command, "r"); + } else +#endif + f = fopen(openpath, "r"); + + if (tmp) free(tmp); + if (command) free(command); + + if (!f) + return -1; + + } /* strcmp(path, "-") */ + + + /* Read entire file into buf[1..l] */ +#define XTRA 5 + /* buf has 1 extra byte at the start, and XTRA extra bytes at the end */ + if (compressed || f == stdin) { + int sz = 1024; + int ct = 1, tot = 0; + char *p = NULL; + + clearerr(f); + while (ct > 0) { + tot += ct; + if (feof(f)) + break; + sz = 2*sz+tot; + p = xrealloc(p, sz); + ct = fread(p+tot,1,sz-tot-XTRA,f); + } + + *buf = p; + l = tot-1; + } else { + int ct; + + l = 0; + if (fstat(fileno(f), &stbuf) != -1) + l = stbuf.st_size; + *buf = (char *) xmalloc((l+1+XTRA)*sizeof(char)); + ct = fread(*buf+1,1,l,f); + if (ct < l) + l = ct; + } + fclose(f); + return l; +} + static char * expand_char(int nr) { @@ -1817,8 +1920,6 @@ break; case V('s','o'): { - FILE *f; - struct stat stbuf; int l; char *buf; char *name = NULL; @@ -1826,21 +1927,21 @@ c += j; /* skip .so part and whitespace */ if (*c == '/') { h = c; - } else { /* .so man3/cpow.3 -> ../man3/cpow.3 */ - h = c-3; - h[0] = '.'; - h[1] = '.'; - h[2] = '/'; - } + } else { /* .so man3/cpow.3 -> ../man3/cpow.3 */ +/* h = c-3; + h[0] = '.'; + h[1] = '.'; + h[2] = '/'; +*/ + h = c; + } + while (*c != '\n') c++; while (c[-1] == ' ') c--; while (*c != '\n') *c++ = 0; *c = 0; scan_troff(h,1, &name); if (name[3] == '/') h=name+3; else h=name; - l = 0; - if (stat(h, &stbuf)!=-1) l=stbuf.st_size; - buf = (char*) xmalloc((l+4)*sizeof(char)); #if NOCGI if (!out_length) { char *t,*s; @@ -1857,7 +1958,7 @@ #endif { /* this works alright, except for section 3 */ - if (!l || !(f = fopen(h,"r"))) { + if ((l = read_manpage_into_buffer(h, &buf)) < 0) { fprintf(stderr, "man2html: unable to open or read file %s\n", h); out_html("
" @@ -1865,13 +1966,11 @@ out_html(h); out_html("
\n"); } else { - i=fread(buf+1,1,l,f); - fclose(f); buf[0]=buf[l]='\n'; buf[l+1]=buf[l+2]=0; scan_troff(buf+1,0,NULL); + if (buf) free(buf); } - if (buf) free(buf); } *c++='\n'; break; @@ -3073,6 +3172,8 @@ } } + + /* * Call: man2html [-l] [filename] * @@ -3083,8 +3184,6 @@ */ int main(int argc, char **argv) { - FILE *f; - struct stat stbuf; int l, c; char *buf, *filename, *fnam = NULL; @@ -3146,50 +3245,16 @@ /* Open input file */ if (!fnam || !strcmp(fnam, "-")) { - f = stdin; + fnam = "-"; fname = "(stdin)"; } else { /* do a chdir() first, to get .so expansion right */ goto_dir(fnam, &directory, &fnam); - - f = fopen(fnam, "r"); - if (f == NULL) - error_page("File not found", "Could not open %s\n", filename); - fname = fnam; } - /* Read entire file into buf[1..l] */ -#define XTRA 5 - /* buf has 1 extra byte at the start, and XTRA extra bytes at the end */ - if (f == stdin) { - int sz = 1024; - int ct = 1, tot = 0; - char *p = NULL; - - clearerr(stdin); - while (ct > 0) { - tot += ct; - if (feof(stdin)) - break; - sz = 2*sz+tot; - p = xrealloc(p, sz); - ct = fread(p+tot,1,sz-tot-XTRA,stdin); - } - - buf = p; - l = tot-1; - } else { - int ct; - - l = 0; - if (fstat(fileno(f), &stbuf) != -1) - l = stbuf.st_size; - buf = (char *) xmalloc((l+1+XTRA)*sizeof(char)); - ct = fread(buf+1,1,l,f); - if (ct < l) - l = ct; - fclose(f); - } + l = read_manpage_into_buffer(fnam, &buf); + if (l < 0) + error_page("File not found", "Could not open %s\n", fname); buf[0] = '\n'; buf[l+1] = '\n';