/*
* mhbuildsbr.c -- routines to expand/translate MIME composition files
*
- * $Id$
- *
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
* complete copyright information.
#include <h/mhparse.h>
#include <h/utils.h>
-#ifdef TIME_WITH_SYS_TIME
+#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
-# include <time.h>
-#else
-# ifdef TM_IN_SYS_TIME
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
#endif
+#include <time.h>
extern int debugsw;
/* mhmisc.c */
-int make_intermediates (char *);
void content_error (char *, CT, char *, ...);
/* mhcachesbr.c */
int find_cache (CT, int, int *, char *, char *, int);
-/* ftpsbr.c */
-int ftp_get (char *, char *, char *, char *, char *, char *, int, int);
-
/* mhfree.c */
void free_content (CT);
void free_ctinfo (CT);
/*
* prototypes
*/
-CT build_mime (char *);
+CT build_mime (char *, int);
/*
* static prototypes
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
*/
CT
-build_mime (char *infile)
+build_mime (char *infile, int directives)
{
int compnum, state;
char buf[BUFSIZ], name[NAMESZ];
CT ct;
FILE *in;
+ directive_init(directives);
+
umask (~m_gmprot ());
/* open the composition draft */
fgetstr (char *s, int n, FILE *stream)
{
char *cp, *ep;
+ int o_n = n;
- for (ep = (cp = s) + n; cp < ep; ) {
- int i;
+ while(1) {
+ for (ep = (cp = s) + o_n; cp < ep; ) {
+ int i;
- if (!fgets (cp, n, stream))
- return (cp != s ? s : NULL);
- if (cp == s && *cp != '#')
- return s;
+ if (!fgets (cp, n, stream))
+ return (cp != s ? s : NULL);
+
+ if (cp == s && *cp != '#')
+ return s;
+
+ cp += (i = strlen (cp)) - 1;
+ if (i <= 1 || *cp-- != '\n' || *cp != '\\')
+ break;
+ *cp = '\0';
+ n -= (i - 2);
+ }
- cp += (i = strlen (cp)) - 1;
- if (i <= 1 || *cp-- != '\n' || *cp != '\\')
+ 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;
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;
}
* 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;
char content[BUFSIZ];
FILE *out;
+ char *cp;
+
+ cp = m_mktemp2(NULL, invo_name, NULL, &out);
+ if (cp == NULL) adios("mhbuildsbr", "unable to create temporary file");
/* use a temp file to collect the plain text lines */
- ce->ce_file = add (m_tmpfil (invo_name), NULL);
+ ce->ce_file = add (cp, NULL);
ce->ce_unlink = 1;
- if ((out = fopen (ce->ce_file, "w")) == NULL)
- adios (ce->ce_file, "unable to open for writing");
-
- if (buf[0] == '#' && buf[1] == '<') {
+ if (do_direct() && (buf[0] == '#' && buf[1] == '<')) {
strncpy (content, buf + 2, sizeof(content));
inlineD = 1;
goto rock_and_roll;
/* 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;
}
}
- if (headers >= 0 && uprf (buffer, DISPO_FIELD)
+ if (headers >= 0 && do_direct() && uprf (buffer, DISPO_FIELD)
&& buffer[i = strlen (DISPO_FIELD)] == ':') {
headers = 1;
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] != '#')
if (clock == 0) {
time (&clock);
snprintf (msgid, sizeof(msgid), "<%d.%ld.%%d@%s>\n",
- (int) getpid(), (long) clock, LocalName());
+ (int) getpid(), (long) clock, LocalName(1));
partno = 0;
msgfmt = getcpy(msgid);
}
char *vec[4], buffer[BUFSIZ];
FILE *out;
CI ci = &ct->c_ctinfo;
+ char *tfile = NULL;
if (!(cp = ci->ci_magic))
adios (NULL, "internal error(5)");
- ce->ce_file = add (m_tmpfil (invo_name), NULL);
+ tfile = m_mktemp2(NULL, invo_name, NULL, NULL);
+ if (tfile == NULL) {
+ adios("mhbuildsbr", "unable to create temporary file");
+ }
+ ce->ce_file = add (tfile, NULL);
ce->ce_unlink = 1;
xstdout = 0;
scan_content (CT ct)
{
int len;
- int check8bit, contains8bit = 0; /* check if contains 8bit data */
- int checklinelen, linelen = 0; /* check for long lines */
- int checkboundary, boundaryclash = 0; /* check if clashes with multipart boundary */
- int checklinespace, linespace = 0; /* check if any line ends with space */
- int checkebcdic, ebcdicunsafe = 0; /* check if contains ebcdic unsafe characters */
- unsigned char *cp, buffer[BUFSIZ];
- struct text *t;
- FILE *in;
+ int check8bit = 0, contains8bit = 0; /* check if contains 8bit data */
+ int checklinelen = 0, linelen = 0; /* check for long lines */
+ int checkboundary = 0, boundaryclash = 0; /* check if clashes with multipart boundary */
+ int checklinespace = 0, linespace = 0; /* check if any line ends with space */
+ int checkebcdic = 0, ebcdicunsafe = 0; /* check if contains ebcdic unsafe characters */
+ unsigned char *cp = NULL, buffer[BUFSIZ];
+ struct text *t = NULL;
+ FILE *in = NULL;
CE ce = ct->c_cefile;
/*
unsigned char *dp;
unsigned char digest[16];
unsigned char outbuf[25];
- FILE *in;
MD5_CTX mdContext;
CE ce = ct->c_cefile;
+ char *infilename = ce->ce_file ? ce->ce_file : ct->c_file;
+ FILE *in;
/* open content */
- if ((in = fopen (ce->ce_file, "r")) == NULL)
- adios (ce->ce_file, "unable to open for reading");
+ if ((in = fopen (infilename, "r")) == NULL)
+ adios (infilename, "unable to open for reading");
/* Initialize md5 context */
MD5Init (&mdContext);