version 1.160, 2018/10/02 19:41:23 |
version 1.165, 2019/01/31 23:00:23 |
|
|
#include "roff.h" |
#include "roff.h" |
#include "mdoc.h" |
#include "mdoc.h" |
#include "man.h" |
#include "man.h" |
|
#include "mandoc_parse.h" |
#include "main.h" |
#include "main.h" |
#include "manconf.h" |
#include "manconf.h" |
#include "mansearch.h" |
#include "mansearch.h" |
Line 848 resp_format(const struct req *req, const char *file) |
|
Line 849 resp_format(const struct req *req, const char *file) |
|
{ |
{ |
struct manoutput conf; |
struct manoutput conf; |
struct mparse *mp; |
struct mparse *mp; |
struct roff_man *man; |
struct roff_meta *meta; |
void *vp; |
void *vp; |
int fd; |
int fd; |
int usepath; |
int usepath; |
Line 859 resp_format(const struct req *req, const char *file) |
|
Line 860 resp_format(const struct req *req, const char *file) |
|
} |
} |
|
|
mchars_alloc(); |
mchars_alloc(); |
mp = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1, |
mp = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1 | |
MANDOCERR_MAX, NULL, MANDOC_OS_OTHER, req->q.manpath); |
MPARSE_VALIDATE, MANDOC_OS_OTHER, req->q.manpath); |
mparse_readfd(mp, fd, file); |
mparse_readfd(mp, fd, file); |
close(fd); |
close(fd); |
|
meta = mparse_result(mp); |
|
|
memset(&conf, 0, sizeof(conf)); |
memset(&conf, 0, sizeof(conf)); |
conf.fragment = 1; |
conf.fragment = 1; |
Line 873 resp_format(const struct req *req, const char *file) |
|
Line 875 resp_format(const struct req *req, const char *file) |
|
scriptname, *scriptname == '\0' ? "" : "/", |
scriptname, *scriptname == '\0' ? "" : "/", |
usepath ? req->q.manpath : "", usepath ? "/" : ""); |
usepath ? req->q.manpath : "", usepath ? "/" : ""); |
|
|
mparse_result(mp, &man, NULL); |
|
if (man == NULL) { |
|
warnx("fatal mandoc error: %s/%s", req->q.manpath, file); |
|
pg_error_internal(); |
|
mparse_free(mp); |
|
mchars_free(); |
|
return; |
|
} |
|
|
|
vp = html_alloc(&conf); |
vp = html_alloc(&conf); |
|
if (meta->macroset == MACROSET_MDOC) |
|
html_mdoc(vp, meta); |
|
else |
|
html_man(vp, meta); |
|
|
if (man->macroset == MACROSET_MDOC) { |
|
mdoc_validate(man); |
|
html_mdoc(vp, man); |
|
} else { |
|
man_validate(man); |
|
html_man(vp, man); |
|
} |
|
|
|
html_free(vp); |
html_free(vp); |
mparse_free(mp); |
mparse_free(mp); |
mchars_free(); |
mchars_free(); |
|
|
} |
} |
|
|
/* |
/* |
* If PATH_INFO is not a file name, translate it to a query. |
* Translate PATH_INFO to a query. |
*/ |
*/ |
static void |
static void |
parse_path_info(struct req *req, const char *path) |
parse_path_info(struct req *req, const char *path) |
{ |
{ |
char *dir[4]; |
const char *name, *sec, *end; |
int i; |
|
|
|
req->isquery = 0; |
req->isquery = 0; |
req->q.equal = 1; |
req->q.equal = 1; |
req->q.manpath = mandoc_strdup(path); |
req->q.manpath = NULL; |
req->q.arch = NULL; |
req->q.arch = NULL; |
|
|
/* Mandatory manual page name. */ |
/* Mandatory manual page name. */ |
if ((req->q.query = strrchr(req->q.manpath, '/')) == NULL) { |
if ((name = strrchr(path, '/')) == NULL) |
req->q.query = req->q.manpath; |
name = path; |
req->q.manpath = NULL; |
else |
} else |
name++; |
*req->q.query++ = '\0'; |
|
|
|
/* Optional trailing section. */ |
/* Optional trailing section. */ |
if ((req->q.sec = strrchr(req->q.query, '.')) != NULL) { |
sec = strrchr(name, '.'); |
if(isdigit((unsigned char)req->q.sec[1])) { |
if (sec != NULL && isdigit((unsigned char)*++sec)) { |
*req->q.sec++ = '\0'; |
req->q.query = mandoc_strndup(name, sec - name - 1); |
req->q.sec = mandoc_strdup(req->q.sec); |
req->q.sec = mandoc_strdup(sec); |
} else |
} else { |
req->q.sec = NULL; |
req->q.query = mandoc_strdup(name); |
|
req->q.sec = NULL; |
} |
} |
|
|
/* Handle the case of name[.section] only. */ |
/* Handle the case of name[.section] only. */ |
if (req->q.manpath == NULL) |
if (name == path) |
return; |
return; |
req->q.query = mandoc_strdup(req->q.query); |
|
|
|
/* Split directory components. */ |
|
dir[i = 0] = req->q.manpath; |
|
while ((dir[i + 1] = strchr(dir[i], '/')) != NULL) { |
|
if (++i == 3) { |
|
pg_error_badrequest( |
|
"You specified too many directory components."); |
|
exit(EXIT_FAILURE); |
|
} |
|
*dir[i]++ = '\0'; |
|
} |
|
|
|
/* Optional manpath. */ |
/* Optional manpath. */ |
if ((i = validate_manpath(req, req->q.manpath)) == 0) |
end = strchr(path, '/'); |
|
req->q.manpath = mandoc_strndup(path, end - path); |
|
if (validate_manpath(req, req->q.manpath)) { |
|
path = end + 1; |
|
if (name == path) |
|
return; |
|
} else { |
|
free(req->q.manpath); |
req->q.manpath = NULL; |
req->q.manpath = NULL; |
else if (dir[1] == NULL) |
} |
return; |
|
|
|
/* Optional section. */ |
/* Optional section. */ |
if (strncmp(dir[i], "man", 3) == 0) { |
if (strncmp(path, "man", 3) == 0 || strncmp(path, "cat", 3) == 0) { |
|
path += 3; |
|
end = strchr(path, '/'); |
free(req->q.sec); |
free(req->q.sec); |
req->q.sec = mandoc_strdup(dir[i++] + 3); |
req->q.sec = mandoc_strndup(path, end - path); |
|
path = end + 1; |
|
if (name == path) |
|
return; |
} |
} |
if (dir[i] == NULL) { |
|
if (req->q.manpath == NULL) |
/* Optional architecture. */ |
free(dir[0]); |
end = strchr(path, '/'); |
return; |
if (end + 1 != name) { |
|
pg_error_badrequest( |
|
"You specified too many directory components."); |
|
exit(EXIT_FAILURE); |
} |
} |
if (dir[i + 1] != NULL) { |
req->q.arch = mandoc_strndup(path, end - path); |
|
if (validate_arch(req->q.arch) == 0) { |
pg_error_badrequest( |
pg_error_badrequest( |
"You specified an invalid directory component."); |
"You specified an invalid directory component."); |
exit(EXIT_FAILURE); |
exit(EXIT_FAILURE); |
} |
} |
|
|
/* Optional architecture. */ |
|
if (i) { |
|
req->q.arch = mandoc_strdup(dir[i]); |
|
if (req->q.manpath == NULL) |
|
free(dir[0]); |
|
} else |
|
req->q.arch = dir[0]; |
|
} |
} |
|
|
/* |
/* |