From: Paul Fox Date: Thu, 31 May 2012 19:15:36 +0000 (-0400) Subject: Implement the following changes: X-Git-Url: http://git.marmaro.de/?a=commitdiff_plain;h=c43afcbaf482a3e7227ca839633c0f7488944895;p=mmh Implement the following changes: - Special #on/#off/#pop directives to control the MIME directive processing state - A flag (-directives) to control whether or not mhbuild will honor MIME directives by default. --- diff --git a/man/mhbuild.man b/man/mhbuild.man index cd7e7fd..d127de8 100644 --- a/man/mhbuild.man +++ b/man/mhbuild.man @@ -12,6 +12,7 @@ mhbuild \- translate MIME composition draft .RB [ \-list " | " \-nolist ] .RB [ \-realsize " | " \-norealsize ] .RB [ \-headers " | " \-noheaders ] +.RB [ \-directives " | " \-nodirectives ] .RB [ \-ebcdicsafe " | " \-noebcdicsafe ] .RB [ \-rfc934mode " | " \-norfc934mode ] .RB [ \-contentid " | " \-nocontentid ] @@ -115,12 +116,36 @@ than one line, e.g., .fi .RE .PP -There are four kinds of directives: \*(lqtype\*(rq directives, which +There are five kinds of directives: \*(lqtype\*(rq directives, which name the type and subtype of the content; \*(lqexternal-type\*(rq directives, which also name the type and subtype of the content; the \*(lqmessage\*(rq directive (#forw), which is used to forward one or -more messages; and, the \*(lqbegin\*(rq directive (#begin), which is -used to create a multipart content. +more messages; the \*(lqbegin\*(rq directive (#begin), which is +used to create a multipart content; and the \*(lqon/off/pop\*(rq +directives (#on, #off, #pop) which control whether any other +directives are honored at all. +.PP +The +.B \-directives +switch allows control over whether mhbuild will honor any of the +\*(lq#\*(rq-directives. This can also be affected with the #on or +#off directives, and #pop, which restores the state of processing to +that preceding the most recent #on or #off. (The #on, #off, and #pop +directives are always honored, of course.) This allows inclusion of +plain text which looks like mhbuild directives, without causing +errors: +.PP +.RS 5 +.nf +#off +#include + +printf("Hello, World!); +#pop +.fi +.RE +.PP +Currently the stack depth for the #on/off/pop directives is 32. .PP The \*(lqtype\*(rq directive is used to directly specify the type and subtype of a content. You may only specify discrete types in this manner diff --git a/uip/mhbuild.c b/uip/mhbuild.c index ad674f4..020512d 100644 --- a/uip/mhbuild.c +++ b/uip/mhbuild.c @@ -25,43 +25,47 @@ static struct swit switches[] = { { "check", 0 }, #define NCHECKSW 1 { "nocheck", 0 }, -#define EBCDICSW 2 +#define DIRECTIVES 2 + { "directives", 0 }, +#define NDIRECTIVES 3 + { "nodirectives", 0 }, +#define EBCDICSW 4 { "ebcdicsafe", 0 }, -#define NEBCDICSW 3 +#define NEBCDICSW 5 { "noebcdicsafe", 0 }, -#define HEADSW 4 +#define HEADSW 6 { "headers", 0 }, -#define NHEADSW 5 +#define NHEADSW 7 { "noheaders", 0 }, -#define LISTSW 6 +#define LISTSW 8 { "list", 0 }, -#define NLISTSW 7 +#define NLISTSW 9 { "nolist", 0 }, -#define SIZESW 8 +#define SIZESW 10 { "realsize", 0 }, -#define NSIZESW 9 +#define NSIZESW 11 { "norealsize", 0 }, -#define RFC934SW 10 +#define RFC934SW 12 { "rfc934mode", 0 }, -#define NRFC934SW 11 +#define NRFC934SW 13 { "norfc934mode", 0 }, -#define VERBSW 12 +#define VERBSW 14 { "verbose", 0 }, -#define NVERBSW 13 +#define NVERBSW 15 { "noverbose", 0 }, -#define RCACHESW 14 +#define RCACHESW 16 { "rcache policy", 0 }, -#define WCACHESW 15 +#define WCACHESW 17 { "wcache policy", 0 }, -#define CONTENTIDSW 16 +#define CONTENTIDSW 18 { "contentid", 0 }, -#define NCONTENTIDSW 17 +#define NCONTENTIDSW 19 { "nocontentid", 0 }, -#define VERSIONSW 18 +#define VERSIONSW 20 { "version", 0 }, -#define HELPSW 19 +#define HELPSW 21 { "help", 0 }, -#define DEBUGSW 20 +#define DEBUGSW 22 { "debug", -5 }, { NULL, 0 } }; @@ -96,7 +100,7 @@ static int unlink_outfile = 0; static void unlink_done (int) NORETURN; /* mhbuildsbr.c */ -CT build_mime (char *); +CT build_mime (char *, int); int output_message (CT, char *); int output_message_fp (CT, FILE *, char*); @@ -110,7 +114,7 @@ void free_content (CT); int main (int argc, char **argv) { - int sizesw = 1, headsw = 1; + int sizesw = 1, headsw = 1, directives = 1; int *icachesw; char *cp, buf[BUFSIZ]; char buffer[BUFSIZ], *compfile = NULL; @@ -198,6 +202,13 @@ main (int argc, char **argv) headsw = 0; continue; + case DIRECTIVES: + directives = 1; + continue; + case NDIRECTIVES: + directives = 0; + continue; + case LISTSW: listsw++; continue; @@ -306,7 +317,7 @@ main (int argc, char **argv) unlink_infile = 1; /* build the content structures for MIME message */ - ct = build_mime (infile); + ct = build_mime (infile, directives); cts[0] = ct; cts[1] = NULL; @@ -340,7 +351,7 @@ main (int argc, char **argv) */ /* build the content structures for MIME message */ - ct = build_mime (compfile); + ct = build_mime (compfile, directives); cts[0] = ct; cts[1] = NULL; diff --git a/uip/mhbuildsbr.c b/uip/mhbuildsbr.c index fd6a974..93f1647 100644 --- a/uip/mhbuildsbr.c +++ b/uip/mhbuildsbr.c @@ -72,7 +72,7 @@ void free_encoding (CT, int); /* * prototypes */ -CT build_mime (char *); +CT build_mime (char *, int); /* * static prototypes @@ -87,6 +87,37 @@ static int build_headers (CT); static char *calculate_digest (CT, int); +static unsigned char directives_stack[32]; +static unsigned int directives_index; + +static int do_direct(void) +{ + return directives_stack[directives_index]; +} + +static void directive_onoff(int onoff) +{ + if (directives_index >= sizeof(directives_stack)) { + fprintf(stderr, "mhbuild: #on/off overflow, continuing\n"); + return; + } + directives_stack[++directives_index] = onoff; +} + +static void directive_init(int onoff) +{ + directives_index = 0; + directives_stack[0] = onoff; +} + +static void directive_pop(void) +{ + if (directives_index > 0) + directives_index--; + else + fprintf(stderr, "mhbuild: #pop underflow, continuing\n"); +} + /* * Main routine for translating composition file * into valid MIME message. It translates the draft @@ -97,7 +128,7 @@ static char *calculate_digest (CT, int); */ CT -build_mime (char *infile) +build_mime (char *infile, int directives) { int compnum, state; char buf[BUFSIZ], name[NAMESZ]; @@ -107,6 +138,8 @@ build_mime (char *infile) CT ct; FILE *in; + directive_init(directives); + umask (~m_gmprot ()); /* open the composition draft */ @@ -327,20 +360,34 @@ static char * fgetstr (char *s, int n, FILE *stream) { char *cp, *ep; + int o_n = n; + + while(1) { + for (ep = (cp = s) + o_n; cp < ep; ) { + int i; - for (ep = (cp = s) + n; cp < ep; ) { - int i; + if (!fgets (cp, n, stream)) + return (cp != s ? s : NULL); - if (!fgets (cp, n, stream)) - return (cp != s ? s : NULL); - if (cp == s && *cp != '#') - return s; + if (cp == s && *cp != '#') + return s; - cp += (i = strlen (cp)) - 1; - if (i <= 1 || *cp-- != '\n' || *cp != '\\') + cp += (i = strlen (cp)) - 1; + if (i <= 1 || *cp-- != '\n' || *cp != '\\') + break; + *cp = '\0'; + n -= (i - 2); + } + + if (strcmp(s, "#on\n") == 0) { + directive_onoff(1); + } else if (strcmp(s, "#off\n") == 0) { + directive_onoff(0); + } else if (strcmp(s, "#pop\n") == 0) { + directive_pop(); + } else { break; - *cp = '\0'; - n -= (i - 2); + } } return s; @@ -367,7 +414,7 @@ user_content (FILE *in, char *file, char *buf, CT *ctp) CT ct; CE ce; - if (buf[0] == '\n' || strcmp (buf, "#\n") == 0) { + if (buf[0] == '\n' || (do_direct() && strcmp (buf, "#\n") == 0)) { *ctp = NULL; return OK; } @@ -392,7 +439,7 @@ user_content (FILE *in, char *file, char *buf, CT *ctp) * 2) begins with "##" (implicit directive) * 3) begins with "#<" */ - if (buf[0] != '#' || buf[1] == '#' || buf[1] == '<') { + if (!do_direct() || buf[0] != '#' || buf[1] == '#' || buf[1] == '<') { int headers; int inlineD; long pos; @@ -407,7 +454,7 @@ user_content (FILE *in, char *file, char *buf, CT *ctp) ce->ce_file = add (cp, NULL); ce->ce_unlink = 1; - if (buf[0] == '#' && buf[1] == '<') { + if (do_direct() && (buf[0] == '#' && buf[1] == '<')) { strncpy (content, buf + 2, sizeof(content)); inlineD = 1; goto rock_and_roll; @@ -418,11 +465,11 @@ user_content (FILE *in, char *file, char *buf, CT *ctp) /* the directive is implicit */ strncpy (content, "text/plain", sizeof(content)); headers = 0; - strncpy (buffer, buf[0] != '#' ? buf : buf + 1, sizeof(buffer)); + strncpy (buffer, (!do_direct() || buf[0] != '#') ? buf : buf + 1, sizeof(buffer)); for (;;) { int i; - if (headers >= 0 && uprf (buffer, DESCR_FIELD) + if (headers >= 0 && do_direct() && uprf (buffer, DESCR_FIELD) && buffer[i = strlen (DESCR_FIELD)] == ':') { headers = 1; @@ -445,7 +492,7 @@ again_descr: } } - if (headers >= 0 && uprf (buffer, DISPO_FIELD) + if (headers >= 0 && do_direct() && uprf (buffer, DISPO_FIELD) && buffer[i = strlen (DISPO_FIELD)] == ':') { headers = 1; @@ -476,7 +523,7 @@ rock_and_roll: pos = ftell (in); if ((cp = fgetstr (buffer, sizeof(buffer) - 1, in)) == NULL) break; - if (buffer[0] == '#') { + if (do_direct() && buffer[0] == '#') { char *bp; if (buffer[1] != '#')