Back to index

courier  0.68.2
Classes | Functions
makemime.c File Reference
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <ctype.h>
#include <pwd.h>
#include <fcntl.h>
#include "rfc822/encode.h"
#include "rfc2045.h"
#include "rfc2045charset.h"
#include "numlib/numlib.h"

Go to the source code of this file.

Classes

struct  arg_list
struct  mimestruct

Functions

int gethostname (const char *, size_t)
static FILE * openfile_or_pipe (const char *filename, const char *mode)
static FILE * openfile (const char *filename)
static void read_args (int *argcp, char ***argvp, const char *file)
static void usage ()
static void createsimplemime (struct mimestruct *)
static void createmultipartmime (struct mimestruct *)
static void joinmultipart (struct mimestruct *)
static void opencreatesimplemime (struct mimestruct *)
static void opencreatemultipartmime (struct mimestruct *)
static void openjoinmultipart (struct mimestruct *)
struct mimestructparseargs (int *argcp, char ***argvp)
static void goodexit (struct mimestruct *m, int exitcode)
int main (int argc, char **argv)
static int encode_outfp (const char *p, size_t n, void *vp)
static int do_printRfc2231Attr (const char *param, const char *value, void *voidArg)
static int tryboundary (struct mimestruct *m, FILE *f, const char *bbuf)
static const char * mkboundary (struct mimestruct *m, FILE *f)
static FILE * openchild (struct mimestruct *parent, struct mimestruct *child, pid_t *pidptr, int usescratch)
static void openoutput (struct mimestruct *m)

Class Documentation

struct arg_list

Definition at line 44 of file makemime.c.

Collaboration diagram for arg_list:
Class Members
char * arg
struct arg_list * next

Function Documentation

static void createmultipartmime ( struct mimestruct m) [static]

Definition at line 807 of file makemime.c.

{
const char *b=mkboundary(m, m->inputfp1);
struct arg_list *a;
int    c;

       if (m->mimeencoding == 0)
              m->mimeencoding="8bit";

       for (a=m->a_first; a; a=a->next)
              fprintf(m->outputfp, "%s\n", a->arg);
       fprintf(m->outputfp, "Content-Type: %s; boundary=\"%s\"\n"
                     "Content-Transfer-Encoding: %s\n\n"
                     RFC2045MIMEMSG
                     "\n--%s\n",
              m->mimetype, b,
              m->mimeencoding,
              b);
       while ((c=getc(m->inputfp1)) != EOF)
              putc(c, m->outputfp);
       fprintf(m->outputfp, "\n--%s--\n", b);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void createsimplemime ( struct mimestruct m) [static]

Definition at line 648 of file makemime.c.

{
struct arg_list *a;
struct libmail_encode_info encode_info;
const char *orig_charset=m->textplaincharset;

       /* Determine encoding by reading the file, as follows:
       **
       ** Default to 7bit.  Use 8bit if high-ascii bytes found.  Use
       ** quoted printable if lines more than 200 characters found.
       ** Use base64 if a null byte is found.
       */

       if (m->mimeencoding == 0)
       {
              long   orig_pos=ftell(m->inputfp1);
              int    binaryflag;

              if (orig_pos == -1)
              {
                     perror("ftell");
                     goodexit(m, 1);
              }

              m->mimeencoding=libmail_encode_autodetect_fpoff(m->inputfp1,
                                                        0,
                                                        0, -1,
                                                        &binaryflag);

              if (ferror(m->inputfp1)
                     || fseek(m->inputfp1, orig_pos, SEEK_SET)<0)
              {
                     perror("fseek");
                     goodexit(m, 1);
              }

              if (strcmp(m->mimetype, "auto") == 0)
                     m->mimetype=binaryflag
                            ? (orig_charset=0,
                               "application/octet-stream"):"text/plain";
       }

       for (a=m->a_first; a; a=a->next)
              fprintf(m->outputfp, "%s\n", a->arg);

       fprintf(m->outputfp, "Content-Type: %s", m->mimetype);
       if (orig_charset && *orig_charset)
       {
              const char *c;

              fprintf(m->outputfp, "; charset=\"");
              for (c=orig_charset; *c; c++)
              {
                     if (*c != '"' && *c != '\\')
                            putc(*c, m->outputfp);
              }
              fprintf(m->outputfp, "\"");
       }

       if (m->contentname && *m->contentname)
       {
              const char *chset=m->textplaincharset ? m->textplaincharset
                     : "iso-8859-1";

              rfc2231_attrCreate("name", m->contentname, chset, NULL,
                               do_printRfc2231Attr, m);
       }

       fprintf(m->outputfp, "\nContent-Transfer-Encoding: %s\n\n",
              m->mimeencoding);

       libmail_encode_start(&encode_info, m->mimeencoding,
                          &encode_outfp,
                          &m->outputfp);
       {
              char input_buf[BUFSIZ];
              int n;

              while ((n=fread(input_buf, 1, sizeof(input_buf),
                            m->inputfp1)) > 0)
              {
                     if ( libmail_encode(&encode_info, input_buf, n))
                            break;
              }

              libmail_encode_end(&encode_info);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int do_printRfc2231Attr ( const char *  param,
const char *  value,
void *  voidArg 
) [static]

Definition at line 639 of file makemime.c.

{
       fprintf( ((struct mimestruct *)voidArg)->outputfp,
               ";\n  %s=%s", param, value);
       return 0;
}

Here is the caller graph for this function:

static int encode_outfp ( const char *  p,
size_t  n,
void *  vp 
) [static]

Definition at line 632 of file makemime.c.

{
       if (fwrite(p, n, 1, *(FILE **)vp) != 1)
              return -1;
       return 0;
}

Here is the caller graph for this function:

int gethostname ( const char *  ,
size_t   
)
static void goodexit ( struct mimestruct m,
int  exitcode 
) [static]

Definition at line 553 of file makemime.c.

{
       if (m->outputfp && (fflush(m->outputfp) || ferror(m->outputfp)))
       {
              perror("makemime");
              exit(1);
       }

       /*
       ** Drain any leftover input, so that the child doesn't get
       ** a SIGPIPE.
       */

       while (m->inputfp1 && !feof(m->inputfp1) && !ferror(m->inputfp1))
              getc(m->inputfp1);

       while (m->inputfp2 && !feof(m->inputfp2) && !ferror(m->inputfp2))
              getc(m->inputfp2);

       if (m->inputfp1)
       {
              if (ferror(m->inputfp1))
              {
                     perror("makemime");
                     exitcode=1;
              }

              fclose(m->inputfp1);
       }
       if (m->inputfp2)
       {
              if (ferror(m->inputfp2))
              {
                     perror("makemime");
                     exitcode=1;
              }

              fclose(m->inputfp2);
       }

       while (m->child1 > 0 && m->child2 > 0)
       {
       int    waitstat;
       pid_t  p=wait(&waitstat);

              if (p <= 0 && errno == ECHILD)     break;

              if (p == m->child1)
                     m->child1=0;
              else if (p == m->child2)
                     m->child2=0;
              else   continue;
              if (waitstat) exitcode=1;
       }
       exit(exitcode);
}

Here is the caller graph for this function:

static void joinmultipart ( struct mimestruct m) [static]

Definition at line 830 of file makemime.c.

{
const char *new_boundary;
char   *old_boundary=0;
int    old_boundary_len=0;
char   buffer[BUFSIZ];
char   *p;
int    c;

       do
       {
              new_boundary=mkboundary(m, m->inputfp1);
       } while (tryboundary(m, m->inputfp2, new_boundary));

       /* Copy the header */

       for (;;)
       {
              if (fgets(buffer, sizeof(buffer), m->inputfp2) == 0)
              {
                     buffer[0]=0;
                     break;
              }

              if (strcmp(buffer, "\r\n") == 0 ||
                  buffer[0] == '\n' || strncmp(buffer, "--", 2) == 0)
                     break;

              if (strncasecmp(buffer, "content-type:", 13))
              {
                     fprintf(m->outputfp, "%s", buffer);
                     if ((p=strchr(buffer, '\n')) != 0) continue;
                     while ((c=getc(m->inputfp2)) != EOF && c != '\n')
                            putc(c, m->outputfp);
                     continue;
              }

              if ((p=strchr(buffer, '\n')) == 0)
                     while ((c=getc(m->inputfp2)) != EOF && c != '\n')
                            ;

              p=strchr(buffer+13, ';');
              if (p) *p=0;
              fprintf(m->outputfp, "Content-Type:%s; boundary=\"%s\"\n",
                     buffer+13, new_boundary);

              for (;;)
              {
                     c=getc(m->inputfp2);
                     if (c != EOF) ungetc(c, m->inputfp2);
                     if (c == '\n' || !isspace((int)(unsigned char)c))
                            break;
                     while ((c=getc(m->inputfp2)) != EOF && c != '\n')
                            ;
              }
       }

       do
       {
              if (strncmp(buffer, "--", 2) == 0)
              {
                     if (old_boundary == 0)
                     {
                            old_boundary=malloc(strlen(buffer)+1);
                            if (!old_boundary)
                            {
                                   perror("malloc");
                                   exit(1);
                            }
                            strcpy(old_boundary, buffer);
                            if ((p=strchr(old_boundary, '\n')) != 0)
                            {
                                   if (p > old_boundary && p[-1] == '\r')
                                          --p;
                                   *p=0;
                            }
                            p=old_boundary+strlen(old_boundary);
                            if (p >= old_boundary+4 &&
                                   strcmp(p-2, "--") == 0)
                                   p[-2]=0;
                            old_boundary_len=strlen(old_boundary);
                     }


                     if (strncasecmp(buffer, old_boundary,
                            old_boundary_len) == 0)
                     {
                            if ((p=strchr(buffer, '\n')) != 0)
                                   *p=0;
                            else while ((c=getc(m->inputfp2)) != '\n'
                                   && c != EOF)
                                   ;

                            c=strlen(buffer);
                            if (c > 0 && buffer[c-1] == '\r')
                                   buffer[--c]=0;

                            if (c >= 4 && strcmp(buffer+(c-2), "--") == 0)
                                   break;
                            fprintf(m->outputfp, "--%s\n",
                                   new_boundary);
                            continue;
                     }
              }
              fprintf(m->outputfp, "%s", buffer);
              if ((p=strchr(buffer, '\n')) == 0)
                     while ((c=getc(m->inputfp2)) != '\n' && c != EOF)
                            ;
       } while (fgets(buffer, sizeof(buffer), m->inputfp2) != 0);

       fprintf(m->outputfp, "--%s\n", new_boundary);

       while ((c=getc(m->inputfp1)) != EOF)
              putc(c, m->outputfp);

       fprintf(m->outputfp, "\n--%s--\n", new_boundary);
       goodexit(m, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 610 of file makemime.c.

{
struct mimestruct *m;

       signal(SIGCHLD, SIG_DFL);
       if (argc > 1 && argv[1][0] == '@')
              read_args(&argc, &argv, argv[1]+1);
       else if (argc > 1)
       {
              --argc;
              ++argv;
       }

       m=parseargs(&argc, &argv);
       if (argc)     usage();      /* Some arguments left */

       (*m->open_func)(m);
       (*m->handler_func)(m);
       goodexit(m, 0);
       return (0);
}

Here is the call graph for this function:

static const char* mkboundary ( struct mimestruct m,
FILE *  f 
) [static]

Definition at line 785 of file makemime.c.

{
pid_t  pid=getpid();
time_t t;
static unsigned n=0;
static char bbuf[NUMBUFSIZE*4];
char   buf[NUMBUFSIZE];

       time(&t);

       do
       {
              strcpy(bbuf, "=_");
              strcat(bbuf, libmail_str_size_t(++n, buf));
              strcat(bbuf, "_");
              strcat(bbuf, libmail_str_time_t(t, buf));
              strcat(bbuf, "_");
              strcat(bbuf, libmail_str_pid_t(pid, buf));
       } while (tryboundary(m, f, bbuf));
       return (bbuf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static FILE* openchild ( struct mimestruct parent,
struct mimestruct child,
pid_t *  pidptr,
int  usescratch 
) [static]

Definition at line 955 of file makemime.c.

{
int    pipefd[2];
char   buf[NUMBUFSIZE];
char   buf2[NUMBUFSIZE+1];
FILE   *fp;

       if (pipe(pipefd) < 0)
       {
              perror("pipe");
              exit(1);
       }

       *pidptr=fork();

       if (*pidptr < 0)
       {
              perror("fork");
              exit(1);
       }

       if (*pidptr == 0)
       {
              /* Duplicate pipe on stdout */

              close(pipefd[0]);
              dup2(pipefd[1], 1);
              close(pipefd[1]);

              /* Close any input files opened by parent */

              if (parent->inputfp1)       fclose(parent->inputfp1);
              if (parent->inputfp2)       fclose(parent->inputfp2);

              /* Open, then execute the child process */

              (*child->open_func)(child);
              (*child->handler_func)(child);
              goodexit(child, 0);
       }
       close(pipefd[1]);

       /*
       ** Open the pipe by calling openfile(), automatically creating
       ** the scratch file, if necessary.
       */

       buf[0]='&';
       strcpy(buf+1, libmail_str_size_t(pipefd[0], buf2));

       fp= usescratch ? openfile(buf):openfile_or_pipe(buf, "r");
       close(pipefd[0]);    /* fd was duped by openfile */
       return (fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void opencreatemultipartmime ( struct mimestruct m) [static]

Definition at line 1048 of file makemime.c.

{
       if (m->inputchild1)
              m->inputfp1=openchild(m, m->inputchild1, &m->child1, 1);
       else
              m->inputfp1=openfile_or_pipe(m->inputfile1, "r");
       openoutput(m);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void opencreatesimplemime ( struct mimestruct m) [static]

Definition at line 1036 of file makemime.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static FILE* openfile ( const char *  filename) [static]

Definition at line 87 of file makemime.c.

{
FILE   *fp=openfile_or_pipe(filename, "r");
int    fd=fileno(fp);
off_t  orig_pos;

       if ((orig_pos=lseek(fd, 0L, SEEK_CUR)) == -1 ||
              lseek(fd, 0L, SEEK_END) == -1 ||
              lseek(fd, 0L, SEEK_CUR) == -1 ||
              lseek(fd, orig_pos, SEEK_SET) == -1)      /* Must be a pipe */
       {
       FILE *t=tmpfile();
       int    c;

              if (!t)
              {
                     perror("tmpfile");
                     exit(1);
              }

              while ((c=getc(fp)) != EOF)
                     putc(c, t);
              if (ferror(fp) || fflush(t)
                     || ferror(t) || fseek(t, 0L, SEEK_SET) == -1)
              {
                     perror("write");
                     exit(1);
              }
              fclose(fp);
              fp=t;
       }
       return (fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static FILE* openfile_or_pipe ( const char *  filename,
const char *  mode 
) [static]

Definition at line 55 of file makemime.c.

{
int    fd;
FILE   *fp;

       if (strcmp(filename, "-") == 0)    /* stdin or stdout */
              fd=dup( strcmp(mode, "r") ? 1:0);
       else if (*filename == '&')
              fd=dup( atoi(filename+1));  /* file descriptor */
       else fd=open(filename, (strcmp(mode, "r") ? O_WRONLY|O_CREAT|O_TRUNC:
                     O_RDONLY), 0666);    /* or a file */
       if (fd < 0)
       {
              perror(filename);
              exit(1);
       }
       fp=fdopen(fd, mode);
       if (!fp)
       {
              perror("fdopen");
              exit(1);
       }
       return (fp);
}

Here is the caller graph for this function:

static void openjoinmultipart ( struct mimestruct m) [static]

Definition at line 1020 of file makemime.c.

{
       /* number two is the multipart section */
       if (m->inputchild2)
              m->inputfp2=openchild(m, m->inputchild2, &m->child2, 1);
       else
              m->inputfp2=openfile(m->inputfile2);


       if (m->inputchild1)
              m->inputfp1=openchild(m, m->inputchild1, &m->child1, 1);
       else
              m->inputfp1=openfile(m->inputfile1);
       openoutput(m);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void openoutput ( struct mimestruct m) [static]

Definition at line 1012 of file makemime.c.

{
       if (!m->outputfile)
              m->outputfile="-";

       m->outputfp= openfile_or_pipe(m->outputfile, "w");
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct mimestruct* parseargs ( int *  argcp,
char ***  argvp 
) [read]

Definition at line 281 of file makemime.c.

{
struct mimestruct *m=malloc(sizeof(struct mimestruct));
int argc= *argcp;
char **argv= *argvp;

       if (!m)
       {
              perror("malloc");
              exit(1);
       }
       memset(m, 0, sizeof(*m));

       if (argc == 0 || argv[0][0] != '-')       usage();

       if (strncmp(argv[0], "-c", 2) == 0)
       {
              m->handler_func= &createsimplemime;
              m->open_func= &opencreatesimplemime;
              if (argv[0][2])
              {
                     m->mimetype=argv[0]+2;
                     --argc;
                     ++argv;
              }
              else
              {
                     --argc;
                     ++argv;
                     if (argc && argv[0][0] != '-' && argv[0][0] != ')')
                     {
                            m->mimetype=argv[0];
                            --argc;
                            ++argv;
                     }
                     else
                            m->mimetype="application/octet-stream";
              }

              while (isspace((int)(unsigned char)*m->mimetype))
                     ++m->mimetype;
       }
       else if (strncmp(argv[0], "-m", 2) == 0)
       {
              m->handler_func= &createmultipartmime;
              m->open_func= &opencreatemultipartmime;
              if (argv[0][2])
              {
                     m->mimetype=argv[0]+2;
                     --argc;
                     ++argv;
              }
              else
              {
                     --argc;
                     ++argv;
                     if (argc && argv[0][0] != '-' && argv[0][0] != ')')
                     {
                            m->mimetype=argv[0];
                            --argc;
                            ++argv;
                     }
                     else
                            m->mimetype="multipart/mixed";
              }
              while (isspace((int)(unsigned char)*m->mimetype))
                     ++m->mimetype;
       }
       else if (strncmp(argv[0], "-j", 2) == 0)
       {
       const char *filename;

              m->handler_func= &joinmultipart;
              m->open_func= &openjoinmultipart;
              if (argv[0][2])
              {
                     filename=argv[0]+2;
                     --argc;
                     ++argv;
              }
              else
              {
                     --argc;
                     ++argv;
                     if (argc == 0)       usage();
                     filename=argv[0];
                     --argc;
                     ++argv;
              }

              while (isspace((int)(unsigned char)*filename))
                     ++filename;

              if (strcmp(filename, "(") == 0)
              {
                     m->inputchild2=parseargs(&argc, &argv);
                     if (argc == 0 || strcmp(argv[0], ")"))
                            usage();
                     --argc;
                     ++argv;
              }
              else
                     m->inputfile2=filename;
       }
       else
              usage();

       /* Handle common options */

       while (argc)
       {
              if (strncmp(argv[0], "-o", 2) == 0)
              {
              const char *f=argv[0]+2;

                     ++argv;
                     --argc;
                     if (*f == 0)
                     {
                            if (!argc)    usage();
                            f=argv[0];
                            ++argv;
                            --argc;
                     }
                     while (isspace((int)(unsigned char)*f))
                            ++f;
                     m->outputfile=f;
                     continue;
              }

              if (strncmp(argv[0], "-C", 2) == 0)
              {
                     char *f=argv[0]+2;

                     ++argv;
                     --argc;


                     if (*f == 0)
                     {
                            if (!argc)    usage();
                            f=argv[0];
                            ++argv;
                            --argc;
                     }
                     while (isspace((int)(unsigned char)*f))
                            ++f;
                     m->textplaincharset=f;
                     continue;
              }

              if (strncmp(argv[0], "-N", 2) == 0)
              {
                     char *f=argv[0]+2;

                     ++argv;
                     --argc;


                     if (*f == 0)
                     {
                            if (!argc)    usage();
                            f=argv[0];
                            ++argv;
                            --argc;
                     }
                     while (isspace((int)(unsigned char)*f))
                            ++f;
                     m->contentname=f;
                     continue;
              }

              if (strncmp(argv[0], "-e", 2) == 0)
              {
              char *f=argv[0]+2, *q;

                     ++argv;
                     --argc;

                     if (*f == 0)
                     {
                            if (!argc)    usage();
                            f=argv[0];
                            ++argv;
                            --argc;
                     }

                     for (q=f; *q; q++)
                            *q=tolower((int)(unsigned char)*q);

                     while (isspace((int)(unsigned char)*f))
                            ++f;

                     if (strcmp(f, "7bit") && strcmp(f, "8bit") &&
                            strcmp(f, "quoted-printable") &&
                            strcmp(f, "base64"))
                            usage();

                     m->mimeencoding=f;
                     continue;
              }

              if (strncmp(argv[0], "-a", 2) == 0)
              {
              char *f=argv[0]+2;
              struct arg_list *a;

                     ++argv;
                     --argc;

                     if (*f == 0)
                     {
                            if (!argc)    usage();
                            f=argv[0];
                            ++argv;
                            --argc;
                     }

                     while (isspace((int)(unsigned char)*f))
                            ++f;

                     a=malloc(sizeof(struct arg_list));
                     if (!a)
                     {
                            perror("malloc");
                            exit(1);
                     }
                     if (m->a_last)
                            m->a_last->next=a;
                     else   m->a_first=a;
                     m->a_last=a;
                     a->arg=f;
                     a->next=0;
                     continue;
              }
              break;
       }

       /* We must now have the input file argument */

       if (!argc)    usage();

       if (strcmp(argv[0], "(") == 0)
       {
              --argc;
              ++argv;
              m->inputchild1=parseargs(&argc, &argv);
              if (argc == 0 || strcmp(argv[0], ")"))
                     usage();
              --argc;
              ++argv;
       }
       else
       {
              m->inputfile1=argv[0];
              --argc;
              ++argv;
       }

       *argcp=argc;
       *argvp=argv;
       return (m);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void read_args ( int *  argcp,
char ***  argvp,
const char *  file 
) [static]

Definition at line 127 of file makemime.c.

{
FILE   *fp=openfile_or_pipe(file, "r");
struct arg_list *argfirst=0, *arglast=0, *argp;
char   buffer[BUFSIZ];
char   *p;
int    c;

       *argcp=0;
       while (fgets(buffer, sizeof(buffer), fp) != 0)
       {
       const  char *q;

              if ((p=strchr(buffer, '\n')) != 0)
                     *p=0;
              else while ((c=getc(fp)) != '\n' && c != EOF)
                     ;      /* Just dump the excess */

              /* Skip the filler. */

              q=buffer;
              while (*q && isspace((int)(unsigned char)*q))
                     ++q;
              if (!*q)      continue;
              if (*q == '#')       continue;
              if (strcmp(buffer, "-") == 0)      break;

              argp=(struct arg_list *)malloc(sizeof(struct arg_list)+1+
                     strlen(q));
              if (!argp)
              {
                     perror("malloc");
                     exit(1);
              }
              if (arglast)
                     arglast->next=argp;
              else
                     argfirst=argp;
              arglast=argp;
              ++*argcp;
              argp->next=0;
              argp->arg=strcpy((char *)(argp+1), q);
       }

       if ((*argvp=malloc(sizeof (char *) * (*argcp+1))) == 0)
       {
              perror("malloc");
              exit(1);
       }
       c=0;
       for (argp=argfirst; argp; argp=argp->next)
       {
              (*argvp)[c]= argp->arg;
              ++c;
       }
       (*argvp)[c]=0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int tryboundary ( struct mimestruct m,
FILE *  f,
const char *  bbuf 
) [static]

Definition at line 744 of file makemime.c.

{
char   buf[BUFSIZ];
char   *p;
int    l=strlen(bbuf);
int    c;
long   orig_pos=ftell(f);

       if (orig_pos == -1)
       {
              perror("ftell");
              goodexit(m, 1);
       }

       while ((p=fgets(buf, sizeof(buf), f)) != 0)
       {
              if (p[0] == '-' && p[1] == '-' &&
                     strncmp(p+2, bbuf, l) == 0)
                     break;

              if ((p=strchr(buf, '\n')) != 0)
                     *p=0;
              else while ((c=getc(f)) != EOF && c != '\n')
                     ;
       }

       if (ferror(f) || fseek(f, orig_pos, SEEK_SET)<0)
       {
              perror("fseek");
              goodexit(m, 1);
       }

       return (p ? 1:0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void usage ( ) [static]

Definition at line 185 of file makemime.c.

{
       fprintf(stderr,
"Usage:\n"
"  makemime -c type [-o file] [-e encoding] [-C charset] [-N name] \\\n"
"                   [-a \"Header: Contents\"] file\n"
"           -m [ type ] [-o file] [-e encoding] [-a \"Header: Contents\"] file\n"
"           -j [-o file] file1 file2\n"
"           @file\n"
"\n"
"   file:  filename    - read or write from filename\n"
"          -           - read or write from stdin or stdout\n"
"          &n          - read or write from file descriptor n\n"
"          \\( opts \\)  - read from child process, that generates [ opts ]\n"
              "\n");

       fprintf(stderr,
"Options:\n"
"\n"
"  -c type         - create a new MIME section from \"file\" with this\n"
"                    Content-Type: (default is application/octet-stream).\n"
"  -C charset      - MIME charset of a new text/plain section.\n"
              "  -N name         - MIME content name of the new mime section.\n");

       fprintf(stderr,
"  -m [ type ]     - create a multipart mime section from \"file\" of this\n"
"                    Content-Type: (default is multipart/mixed).\n"
"  -e encoding     - use the given encoding (7bit, 8bit, quoted-printable,\n"
"                    or base64), instead of guessing.  Omit \"-e\" and use\n"
"                    -c auto to set Content-Type: to text/plain or\n"
              "                    application/octet-stream based on picked encoding.\n");

       fprintf(stderr,
"  -j file1 file2  - join mime section file2 to multipart section file1.\n"
"  -o file         - write ther result to file, instead of stdout (not\n"
"                    allowed in child processes).\n"
"  -a header       - prepend an additional header to the output.\n"
"\n"
"  @file - read all of the above options from file, one option or\n"
"          value on each line.\n"
       );
       exit (0);
}