tech@mandoc.bsd.lv
 help / color / mirror / Atom feed
From: Ingo Schwarze <schwarze@usta.de>
To: tech@mdocml.bsd.lv
Subject: Re: implement .so
Date: Tue, 26 Oct 2010 19:59:13 +0200	[thread overview]
Message-ID: <20101026175913.GF27536@iris.usta.de> (raw)
In-Reply-To: <20101025221017.GA6533@britannica.bec.de>

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

  reply	other threads:[~2010-10-26 17:59 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-24 16:40 Ingo Schwarze
2010-10-24 16:49 ` Joerg Sonnenberger
2010-10-24 17:29   ` Ingo Schwarze
2010-10-24 17:38     ` Joerg Sonnenberger
2010-10-24 18:00       ` Ingo Schwarze
2010-10-24 18:15         ` Joerg Sonnenberger
2010-10-24 18:17           ` Joerg Sonnenberger
2010-10-24 19:41           ` Ingo Schwarze
2010-10-24 19:51             ` Joerg Sonnenberger
2010-10-25 21:55               ` Ingo Schwarze
2010-10-25 22:10                 ` Joerg Sonnenberger
2010-10-26 17:59                   ` Ingo Schwarze [this message]
2010-10-26 18:12                     ` Joerg Sonnenberger
2010-10-26 21:48                       ` Ingo Schwarze
2010-10-26 21:56                         ` Joerg Sonnenberger
2010-10-26 23:10                       ` Ingo Schwarze
2010-10-26 23:30                         ` Joerg Sonnenberger
2010-10-26 23:41                           ` Ingo Schwarze
2010-10-27  9:34                             ` Kristaps Dzonsons

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20101026175913.GF27536@iris.usta.de \
    --to=schwarze@usta.de \
    --cc=tech@mdocml.bsd.lv \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).