From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp1.rz.uni-karlsruhe.de (Debian-exim@smtp1.rz.uni-karlsruhe.de [129.13.185.217]) by krisdoz.my.domain (8.14.3/8.14.3) with ESMTP id o9QHxH7i021281 for ; Tue, 26 Oct 2010 13:59:19 -0400 (EDT) Received: from hekate.usta.de (asta-nat.asta.uni-karlsruhe.de [172.22.63.82]) by smtp1.rz.uni-karlsruhe.de with esmtp (Exim 4.63 #1) id 1PAnnm-0008Um-06; Tue, 26 Oct 2010 19:59:14 +0200 Received: from donnerwolke.usta.de ([172.24.96.3]) by hekate.usta.de with esmtp (Exim 4.71) (envelope-from ) id 1PAnnl-0006Ou-UT; Tue, 26 Oct 2010 19:59:13 +0200 Received: from iris.usta.de ([172.24.96.5] helo=usta.de) by donnerwolke.usta.de with esmtp (Exim 4.69) (envelope-from ) id 1PAnnl-00053c-TK; Tue, 26 Oct 2010 19:59:13 +0200 Received: from schwarze by usta.de with local (Exim 4.71) (envelope-from ) id 1PAnnl-0001L4-J2; Tue, 26 Oct 2010 19:59:13 +0200 Date: Tue, 26 Oct 2010 19:59:13 +0200 From: Ingo Schwarze To: tech@mdocml.bsd.lv Subject: Re: implement .so Message-ID: <20101026175913.GF27536@iris.usta.de> References: <20101024164057.GF20876@iris.usta.de> <20101024164945.GA25275@britannica.bec.de> <20101024172914.GH20876@iris.usta.de> <20101024173857.GA18657@britannica.bec.de> <20101024180019.GI20876@iris.usta.de> <20101024181502.GA13039@britannica.bec.de> <20101024194129.GJ20876@iris.usta.de> <20101024195135.GA1809@britannica.bec.de> <20101025215506.GA12557@iris.usta.de> <20101025221017.GA6533@britannica.bec.de> X-Mailinglist: mdocml-tech Reply-To: tech@mdocml.bsd.lv MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20101025221017.GA6533@britannica.bec.de> User-Agent: Mutt/1.5.20 (2009-06-14) Hi Joerg, Joerg Sonnenberger wrote on Tue, Oct 26, 2010 at 12:10:17AM +0200: > On Mon, Oct 25, 2010 at 11:55:06PM +0200, Ingo Schwarze wrote: >> Actually, it is even worse. >> All ports in the OpenBSD ports tree using the feature give the path >> relative to the *parent* directory of the directory containing the >> manual page having the .so directive. >> >> So these are neither absolute paths (relative to the root of the >> file system) nor relative paths (relative to the current working >> directory). > The current working directory for man is /usr/share/man etc. and that's > inherited by the renderer. Um. Right. While what i did is minimally more flexible - you can then call mandoc from anywhere, as long as the source file is in the right place - that is probably not worth the extra complexity. So, here is a simplified patch (less than 50 new lines of code, all very simple) relying on the current working directory. diff -Napur mandoc.pdesc/main.c mandoc/main.c --- mandoc.pdesc/main.c Sun Oct 24 13:47:06 2010 +++ mandoc/main.c Tue Oct 26 11:34:33 2010 @@ -173,6 +173,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "argument count wrong, violates syntax", "child violates parent syntax", "argument count wrong, violates syntax", + "invalid path in include directive", "no document body", "no document prologue", "static buffer exhausted", @@ -181,6 +182,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = static void pdesc(struct curparse *); static void fdesc(struct curparse *); static void ffile(const char *, struct curparse *); +static int pfile(const char *, struct curparse *, int); static int moptions(enum intt *, char *); static int mmsg(enum mandocerr, void *, int, int, const char *); @@ -306,7 +308,36 @@ ffile(const char *file, struct curparse *curp) perror(curp->file); } +static int +pfile(const char *file, struct curparse *curp, int ln) +{ + const char *savefile; + int fd, savefd; + if (-1 == (fd = open(file, O_RDONLY, 0))) { + perror(file); + exit_status = MANDOCLEVEL_SYSERR; + return(0); + } + + savefile = curp->file; + savefd = curp->fd; + + curp->file = file; + curp->fd = fd; + + pdesc(curp); + + curp->file = savefile; + curp->fd = savefd; + + if (-1 == close(fd)) + perror(file); + + return(MANDOCLEVEL_FATAL > exit_status ? 1 : 0); +} + + static void resize_buf(struct buf *buf, size_t initial) { @@ -629,6 +660,11 @@ pdesc(struct curparse *curp) } else if (ROFF_ERR == re) { assert(MANDOCLEVEL_FATAL <= exit_status); break; + } else if (ROFF_SO == re) { + if (pfile(ln.buf + of, curp, lnn_start)) + continue; + else + break; } /* diff -Napur mandoc.pdesc/mandoc.h mandoc/mandoc.h --- mandoc.pdesc/mandoc.h Sun Oct 24 13:47:06 2010 +++ mandoc/mandoc.h Tue Oct 26 11:34:44 2010 @@ -114,6 +114,7 @@ enum mandocerr { MANDOCERR_SYNTARGVCOUNT, /* argument count wrong, violates syntax */ MANDOCERR_SYNTCHILD, /* child violates parent syntax */ MANDOCERR_SYNTARGCOUNT, /* argument count wrong, violates syntax */ + MANDOCERR_SOPATH, /* invalid path in include directive */ MANDOCERR_NODOCBODY, /* no document body */ MANDOCERR_NODOCPROLOG, /* no document prologue */ MANDOCERR_MEM, /* static buffer exhausted */ diff -Napur mandoc.pdesc/roff.c mandoc/roff.c --- mandoc.pdesc/roff.c Wed Oct 20 09:22:11 2010 +++ mandoc/roff.c Tue Oct 26 11:44:30 2010 @@ -48,11 +48,12 @@ enum rofft { ROFF_ie, ROFF_if, ROFF_ig, + ROFF_nr, ROFF_rm, + ROFF_so, ROFF_tr, ROFF_cblock, ROFF_ccond, /* FIXME: remove this. */ - ROFF_nr, ROFF_MAX }; @@ -128,6 +129,7 @@ static int roff_res(struct roff *, char **, size_t *, int); static void roff_setstr(struct roff *, const char *, const char *); +static enum rofferr roff_so(ROFF_ARGS); static char *roff_strdup(const char *); /* See roff_hash_find() */ @@ -150,11 +152,12 @@ static struct roffmac roffs[ROFF_MAX] = { { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, { "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL }, + { "nr", roff_nr, NULL, NULL, 0, NULL }, { "rm", roff_line, NULL, NULL, 0, NULL }, + { "so", roff_so, NULL, NULL, 0, NULL }, { "tr", roff_line, NULL, NULL, 0, NULL }, { ".", roff_cblock, NULL, NULL, 0, NULL }, { "\\}", roff_ccond, NULL, NULL, 0, NULL }, - { "nr", roff_nr, NULL, NULL, 0, NULL }, }; static void roff_free1(struct roff *); @@ -1005,6 +1008,23 @@ roff_nr(ROFF_ARGS) } return(ROFF_IGN); +} + + +/* ARGSUSED */ +static enum rofferr +roff_so(ROFF_ARGS) +{ + char *name; + + name = *bufp + pos; + if ('/' == *name || strstr(name, "../") || strstr(name, "/..")) { + (*r->msg)(MANDOCERR_SOPATH, r->data, ln, pos, NULL); + return(ROFF_ERR); + } + + *offs = pos; + return(ROFF_SO); } diff -Napur mandoc.pdesc/roff.h mandoc/roff.h --- mandoc.pdesc/roff.h Wed Oct 20 09:22:11 2010 +++ mandoc/roff.h Mon Oct 25 03:48:01 2010 @@ -20,6 +20,7 @@ enum rofferr { ROFF_CONT, /* continue processing line */ ROFF_RERUN, /* re-run roff interpreter with offset */ + ROFF_SO, /* include another file */ ROFF_IGN, /* ignore current line */ ROFF_ERR /* badness: puke and stop */ }; -- To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv