예제 #1
0
파일: mhshowsbr.c 프로젝트: dscho/nmh
void
show_all_messages (CT *cts)
{
    CT ct, *ctp;

    /*
     * If form is not specified, then get default form
     * for showing headers of MIME messages.
     */
    if (!formsw)
	formsw = getcpy (etcpath ("mhl.headers"));

    /*
     * If form is "mhl.null", suppress display of header.
     */
    if (!strcmp (formsw, "mhl.null"))
	formsw = NULL;

    for (ctp = cts; *ctp; ctp++) {
	ct = *ctp;

	/* if top-level type is ok, then display message */
	if (type_ok (ct, 1))
	    show_single_message (ct, formsw);
    }
}
예제 #2
0
파일: seq_read.c 프로젝트: dscho/nmh
static void
seq_private (struct msgs *mp)
{
    int i, j, alen, plen;
    char *cp;
    struct node *np;

    alen = strlen ("atr-");
    plen = strlen (mp->foldpath) + 1;

    for (np = m_defs; np; np = np->n_next) {
	if (ssequal ("atr-", np->n_name)
		&& (j = strlen (np->n_name) - plen) > alen
		&& *(np->n_name + j) == '-'
		&& strcmp (mp->foldpath, np->n_name + j + 1) == 0) {
	    cp = getcpy (np->n_name + alen);
	    *(cp + j - alen) = '\0';
	    if ((i = seq_init (mp, cp, getcpy (np->n_field))) != -1)
		make_seq_private (mp, i);
	}
    }
}
예제 #3
0
파일: mhshowsbr.c 프로젝트: dscho/nmh
static void
DisplayMsgHeader (CT ct, char *form)
{
    pid_t child_id;
    int i, vecp;
    char **vec;
    char *file;

    vec = argsplit(mhlproc, &file, &vecp);
    vec[vecp++] = getcpy("-form");
    vec[vecp++] = getcpy(form);
    vec[vecp++] = getcpy("-nobody");
    vec[vecp++] = getcpy(ct->c_file);

    /*
     * If we've specified -(no)moreproc,
     * then just pass that along.
     */
    if (nomore) {
	vec[vecp++] = getcpy("-nomoreproc");
    } else if (progsw) {
	vec[vecp++] = getcpy("-moreproc");
	vec[vecp++] = getcpy(progsw);
    }
    vec[vecp] = NULL;

    fflush (stdout);

    for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
	sleep (5);

    switch (child_id) {
    case NOTOK:
	adios ("fork", "unable to");
	/* NOTREACHED */

    case OK:
	execvp (file, vec);
	fprintf (stderr, "unable to exec ");
	perror (mhlproc);
	_exit (-1);
	/* NOTREACHED */

    default:
	xpid = -child_id;
	break;
    }

    arglist_free(file, vec);
}
예제 #4
0
파일: seq_read.c 프로젝트: dscho/nmh
void
seq_read (struct msgs *mp, int lockflag)
{
    /*
     * Initialize the list of sequence names.  Go ahead and
     * add the "cur" sequence to the list of sequences.
     */
    svector_push_back (mp->msgattrs, getcpy (current));
    make_all_public (mp);	/* initially, make all public */

    /* If folder is empty, don't scan for sequence information */
    if (mp->nummsg == 0)
	return;

    /* Initialize the public sequences */
    seq_public (mp, lockflag);

    /* Initialize the private sequences */
    seq_private (mp);
}
예제 #5
0
파일: mhstore.c 프로젝트: dscho/nmh
int
main (int argc, char **argv)
{
    int msgnum, *icachesw;
    char *cp, *file = NULL, *outfile = NULL, *folder = NULL;
    char *maildir, buf[100], **argp;
    char **arguments;
    struct msgs_array msgs = { 0, 0, NULL };
    struct msgs *mp = NULL;
    CT ct, *ctp;
    FILE *fp;

    if (nmh_init(argv[0], 1)) { return 1; }

    done=freects_done;

    arguments = getarguments (invo_name, argc, argv, 1);
    argp = arguments;

    /*
     * Parse arguments
     */
    while ((cp = *argp++)) {
	if (*cp == '-') {
	    switch (smatch (++cp, switches)) {
	    case AMBIGSW: 
		ambigsw (cp, switches);
		done (1);
	    case UNKWNSW: 
		adios (NULL, "-%s unknown", cp);

	    case HELPSW: 
		snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]",
			invo_name);
		print_help (buf, switches, 1);
		done (0);
	    case VERSIONSW:
		print_version(invo_name);
		done (0);

	    case AUTOSW:
		autosw++;
		continue;
	    case NAUTOSW:
		autosw = 0;
		continue;

	    case RCACHESW:
		icachesw = &rcachesw;
		goto do_cache;
	    case WCACHESW:
		icachesw = &wcachesw;
do_cache:
		if (!(cp = *argp++) || *cp == '-')
		    adios (NULL, "missing argument to %s", argp[-2]);
		switch (*icachesw = smatch (cp, caches)) {
		case AMBIGSW:
		    ambigsw (cp, caches);
		    done (1);
		case UNKWNSW:
		    adios (NULL, "%s unknown", cp);
		default:
		    break;
		}
		continue;

	    case CHECKSW:
		checksw++;
		continue;
	    case NCHECKSW:
		checksw = 0;
		continue;

	    case PARTSW:
		if (!(cp = *argp++) || *cp == '-')
		    adios (NULL, "missing argument to %s", argp[-2]);
		if (npart >= NPARTS)
		    adios (NULL, "too many parts (starting with %s), %d max",
			   cp, NPARTS);
		parts[npart++] = cp;
		continue;

	    case TYPESW:
		if (!(cp = *argp++) || *cp == '-')
		    adios (NULL, "missing argument to %s", argp[-2]);
		if (ntype >= NTYPES)
		    adios (NULL, "too many types (starting with %s), %d max",
			   cp, NTYPES);
		types[ntype++] = cp;
		continue;

	    case FILESW:
		if (!(cp = *argp++) || (*cp == '-' && cp[1]))
		    adios (NULL, "missing argument to %s", argp[-2]);
		file = *cp == '-' ? cp : path (cp, TFILE);
		continue;

	    case OUTFILESW:
		if (!(cp = *argp++) || (*cp == '-' && cp[1]))
		    adios (NULL, "missing argument to %s", argp[-2]);
		outfile = *cp == '-' ? cp : path (cp, TFILE);
		continue;

	    case VERBSW: 
		verbosw = 1;
		continue;
	    case NVERBSW: 
		verbosw = 0;
		continue;
            case CLOBBERSW:
		if (!(cp = *argp++) || *cp == '-')
		    adios (NULL, "missing argument to %s", argp[-2]);
                if (save_clobber_policy (cp)) {
                  adios (NULL, "invalid argument, %s, to %s", argp[-1],
                         argp[-2]);
                }
		continue;
	    case DEBUGSW:
		debugsw = 1;
		continue;
	    }
	}
	if (*cp == '+' || *cp == '@') {
	    if (folder)
		adios (NULL, "only one folder at a time!");
	    else
		folder = pluspath (cp);
	} else
		app_msgarg(&msgs, cp);
    }

    /* null terminate the list of acceptable parts/types */
    parts[npart] = NULL;
    types[ntype] = NULL;

    /*
     * Check if we've specified an additional profile
     */
    if ((cp = getenv ("MHSTORE"))) {
	if ((fp = fopen (cp, "r"))) {
	    readconfig ((struct node **) 0, fp, cp, 0);
	    fclose (fp);
	} else {
	    admonish ("", "unable to read $MHSTORE profile (%s)", cp);
	}
    }

    /*
     * Read the standard profile setup
     */
    if ((fp = fopen (cp = etcpath ("mhn.defaults"), "r"))) {
	readconfig ((struct node **) 0, fp, cp, 0);
	fclose (fp);
    }

    /* Check for public cache location */
    if ((cache_public = context_find (nmhcache)) && *cache_public != '/')
	cache_public = NULL;

    /* Check for private cache location */
    if (!(cache_private = context_find (nmhprivcache)))
	cache_private = ".cache";
    cache_private = getcpy (m_maildir (cache_private));

    /*
     * Cache the current directory before we do any chdirs()'s.
     */
    cwd = getcpy (pwd());

    if (!context_find ("path"))
	free (path ("./", TFOLDER));

    if (file && msgs.size)
	adios (NULL, "cannot specify msg and file at same time!");

    /*
     * check if message is coming from file
     */
    if (file) {
	if (!(cts = (CT *) calloc ((size_t) 2, sizeof(*cts))))
	    adios (NULL, "out of memory");
	ctp = cts;

	if ((ct = parse_mime (file))) {
	    *ctp++ = ct;
	    if (outfile) {
		ct->c_storage = outfile;
	    }
        }
    } else {
	/*
	 * message(s) are coming from a folder
	 */
	if (!msgs.size)
	    app_msgarg(&msgs, "cur");
	if (!folder)
	    folder = getfolder (1);
	maildir = m_maildir (folder);

	if (chdir (maildir) == NOTOK)
	    adios (maildir, "unable to change directory to");

	/* read folder and create message structure */
	if (!(mp = folder_read (folder, 1)))
	    adios (NULL, "unable to read folder %s", folder);

	/* check for empty folder */
	if (mp->nummsg == 0)
	    adios (NULL, "no messages in %s", folder);

	/* parse all the message ranges/sequences and set SELECTED */
	for (msgnum = 0; msgnum < msgs.size; msgnum++)
	    if (!m_convert (mp, msgs.msgs[msgnum]))
		done (1);
	seq_setprev (mp);	/* set the previous-sequence */

	if (!(cts = (CT *) calloc ((size_t) (mp->numsel + 1), sizeof(*cts))))
	    adios (NULL, "out of memory");
	ctp = cts;

	for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
	    if (is_selected(mp, msgnum)) {
		char *msgnam;

		msgnam = m_name (msgnum);
		if ((ct = parse_mime (msgnam))) {
		    *ctp++ = ct;
		    if (outfile) {
			ct->c_storage = add (outfile, NULL);
		    }
                }
	    }
	}
    }

    if (!*cts)
	done (1);

    userrs = 1;
    SIGNAL (SIGQUIT, quitser);
    SIGNAL (SIGPIPE, pipeser);

    /*
     * Get the associated umask for the relevant contents.
     */
    for (ctp = cts; *ctp; ctp++) {
	struct stat st;

	ct = *ctp;
	if (type_ok (ct, 1) && !ct->c_umask) {
	    if (stat (ct->c_file, &st) != NOTOK)
		ct->c_umask = ~(st.st_mode & 0777);
	    else
		ct->c_umask = ~m_gmprot();
	}
    }

    /*
     * Store the message content
     */
    store_all_messages (cts);

    /* Now free all the structures for the content */
    for (ctp = cts; *ctp; ctp++)
	free_content (*ctp);

    free ((char *) cts);
    cts = NULL;

    /* If reading from a folder, do some updating */
    if (mp) {
	context_replace (pfolder, folder);/* update current folder  */
	seq_setcur (mp, mp->hghsel);	  /* update current message */
	seq_save (mp);			  /* synchronize sequences  */
	context_save ();		  /* save the context file  */
    }

    done (files_not_clobbered);
    return 1;
}
예제 #6
0
파일: scansbr.c 프로젝트: dscho/nmh
int
scan (FILE *inb, int innum, int outnum, char *nfs, int width, int curflg,
      int unseen, char *folder, long size, int noisy)
{
    int i, compnum, encrypted, state;
    char *cp, *tmpbuf, *startbody, **nxtbuf;
    char *saved_c_text = NULL;
    struct comp *cptr;
    struct comp **savecomp;
    char *scnmsg = NULL;
    FILE *scnout = NULL;
    char name[NAMESZ];
    int bufsz;
    static int rlwidth, slwidth;
    static size_t scanl_size;

    /* first-time only initialization */
    if (!scanl) {
	if (width == 0) {
	    if ((width = sc_width ()) < WIDTH/2)
		width = WIDTH/2;
	    else if (width > MAXSCANL)
		width = MAXSCANL;
	}
	dat[3] = slwidth = width;
	/* Arbitrarily allocate 20 * slwidth to provide room for lots
	   of escape sequences. */
	scanl_size = SCAN_CHARWIDTH * (20 * slwidth + 2);
	scanl = (char *) mh_xmalloc (scanl_size);
	if (outnum)
	    umask(~m_gmprot());

	/* Compile format string */
	ncomps = fmt_compile (nfs, &fmt, 1) + 2;

	bodycomp = fmt_findcomp("body");
	datecomp = fmt_findcomp("date");
	cptr = fmt_findcomp("folder");
	if (cptr && folder)
	    cptr->c_text = getcpy(folder);
	if (fmt_addcompentry("encrypted")) {
		ncomps++;
	}
	cptr =  fmt_findcomp("dtimenow");
	if (cptr)
	    cptr->c_text = getcpy(dtimenow (0));

	/*
	 * In other programs I got rid of this complicated buffer switching,
	 * but since scan reads lots of messages at once and this complicated
	 * memory management, I decided to keep it; otherwise there was
	 * the potential for a lot of malloc() and free()s, and I could
	 * see the malloc() pool really getting fragmented.  Maybe it
	 * wouldn't be an issue in practice; perhaps this will get
	 * revisited someday.
	 *
	 * So, some notes for what's going on:
	 *
	 * nxtbuf is an array of pointers that contains malloc()'d buffers
	 * to hold our component text.  used_buf is an array of struct comp
	 * pointers that holds pointers to component structures we found while
	 * processing a message.
	 *
	 * We read in the message with m_getfld(), using "tmpbuf" as our
	 * input buffer.  tmpbuf is set at the start of message processing
	 * to the first buffer in our buffer pool (nxtbuf).
	 *
	 * Every time we find a component we care about, we set that component's
	 * text buffer to the current value of tmpbuf, and then switch tmpbuf
	 * to the next buffer in our pool.  We also add that component to
	 * our used_buf pool.
	 *
	 * When we're done, we go back and zero out all of the component
	 * text buffer pointers that we saved in used_buf.
	 *
	 * Note that this means c_text memory is NOT owned by the fmt_module
	 * and it's our responsibility to free it.
	 */

	nxtbuf = compbuffers = (char **) calloc((size_t) ncomps, sizeof(char *));
	if (nxtbuf == NULL)
	    adios (NULL, "unable to allocate component buffers");
	used_buf = (struct comp **) calloc((size_t) (ncomps+1),
	    sizeof(struct comp *));
	if (used_buf == NULL)
	    adios (NULL, "unable to allocate component buffer stack");
	used_buf += ncomps+1; *--used_buf = 0;
	rlwidth = bodycomp && (width > SBUFSIZ) ? width : SBUFSIZ;
	for (i = ncomps; i--; )
	    *nxtbuf++ = mh_xmalloc(rlwidth);
    }

    /*
     * each-message initialization
     */
    nxtbuf = compbuffers;
    savecomp = used_buf;
    tmpbuf = *nxtbuf++;
    startbody = NULL;
    dat[0] = innum ? innum : outnum;
    dat[1] = curflg;
    dat[4] = unseen;

    /*
     * Get the first field.  If the message is non-empty
     * and we're doing an "inc", open the output file.
     */
    bufsz = rlwidth;
    m_getfld_state_reset (&gstate);
    if ((state = m_getfld (&gstate, name, tmpbuf, &bufsz, inb)) == FILEEOF) {
	if (ferror(inb)) {
	    advise("read", "unable to"); /* "read error" */
	    return SCNFAT;
	} else {
	    return SCNEOF;
	}
    }

    if (outnum) {
	if (outnum > 0) {
	    scnmsg = m_name (outnum);
	    if (*scnmsg == '?')		/* msg num out of range */
		return SCNNUM;
	} else {
	    scnmsg = "/dev/null";
	}
	if ((scnout = fopen (scnmsg, "w")) == NULL)
	    adios (scnmsg, "unable to write");
    }

    /* scan - main loop */
    for (compnum = 1; ;
	bufsz = rlwidth, state = m_getfld (&gstate, name, tmpbuf, &bufsz, inb)) {
	switch (state) {
	    case FLD: 
	    case FLDPLUS: 
		compnum++;
		if (outnum) {
		    FPUTS (name);
		    if ( putc (':', scnout) == EOF) DIEWRERR();
		    FPUTS (tmpbuf);
		}
		/*
		 * if we're interested in this component, save a pointer
		 * to the component text, then start using our next free
		 * buffer as the component temp buffer (buffer switching
		 * saves an extra copy of the component text).
		 */
		if ((cptr = fmt_findcasecomp(name))) {
		    if (! cptr->c_text) {
			cptr->c_text = tmpbuf;
			for (cp = tmpbuf + strlen (tmpbuf) - 1; 
					cp >= tmpbuf; cp--)
			    if (isspace ((unsigned char) *cp))
				*cp = 0;
			    else
				break;
			*--savecomp = cptr;
			tmpbuf = *nxtbuf++;
		    }
		}

		while (state == FLDPLUS) {
		    bufsz = rlwidth;
		    state = m_getfld (&gstate, name, tmpbuf, &bufsz, inb);
		    if (outnum)
			FPUTS (tmpbuf);
		}
		break;

	    case BODY: 
		compnum = -1;
		/*
		 * A slight hack ... if we have less than rlwidth characters
		 * in the buffer, call m_getfld again.
		 */

		if ((i = strlen(tmpbuf)) < rlwidth) {
		    bufsz = rlwidth - i;
		    state = m_getfld (&gstate, name, tmpbuf + i, &bufsz, inb);
		}

		if (! outnum) {
		    state = FILEEOF; /* stop now if scan cmd */
		    if (bodycomp && startbody == NULL)
		    	startbody = tmpbuf;
		    goto finished;
		}
		if (putc ('\n', scnout) == EOF) DIEWRERR();
		FPUTS (tmpbuf);
		/*
                 * The previous code here used to call m_getfld() using
                 * pointers to the underlying output stdio buffers to
                 * avoid the extra copy.  Tests by Markus Schnalke show
                 * no noticable performance loss on larger mailboxes
                 * if we incur an extra copy, and messing around with
                 * internal stdio buffers is becoming more and more
                 * unportable as times go on.  So from now on just deal
                 * with the overhead of an extra copy.
		 *
		 * Subtle change - with the previous code tmpbuf wasn't
		 * used, so we could reuse it for the {body} component.
		 * Now since we're using tmpbuf as our read buffer we
		 * need to save the beginning of the body for later.
		 * See the above (and below) use of startbody.
		 */
body:;
		if (bodycomp && startbody == NULL) {
		    startbody = tmpbuf;
		    tmpbuf = *nxtbuf++;
		}

		while (state == BODY) {
		    bufsz = rlwidth;
		    state = m_getfld (&gstate, name, tmpbuf, &bufsz, inb);
		    FPUTS(tmpbuf);
		}
		goto finished;

	    case LENERR: 
	    case FMTERR: 
	    	if (innum)
		    fprintf (stderr, "??Format error (message %d) in ",
			     outnum ? outnum : innum);
		else
		    fprintf (stderr, "??Format error in ");

		fprintf (stderr, "component %d\n", compnum);

		if (outnum) {
		    FPUTS ("\n\nBAD MSG:\n");
		    FPUTS (name);
		    if (putc ('\n', scnout) == EOF) DIEWRERR();
		    state = BODY;
		    goto body;
		}
		/* fall through */

	    case FILEEOF:
		goto finished;

	    default: 
		adios (NULL, "getfld() returned %d", state);
	}
    }

    /*
     * format and output the scan line.
     */
finished:
    if (ferror(inb)) {
	advise("read", "unable to"); /* "read error" */
	return SCNFAT;
    }

    /* Save and restore buffer so we don't trash our dynamic pool! */
    if (bodycomp) {
	saved_c_text = bodycomp->c_text;
	bodycomp->c_text = startbody;
    }

    if (size)
	dat[2] = size;
    else if (outnum > 0)
    {
	dat[2] = ftell(scnout);
	if (dat[2] == EOF) DIEWRERR();
    }

    if ((datecomp && !datecomp->c_text) || (!size && !outnum)) {
	struct stat st;

	fstat (fileno(inb), &st);
	if (!size && !outnum)
	    dat[2] = st.st_size;
	if (datecomp) {
	    if (! datecomp->c_text) {
		if (datecomp->c_tws == NULL)
		    datecomp->c_tws = (struct tws *)
			calloc((size_t) 1, sizeof(*datecomp->c_tws));
		if (datecomp->c_tws == NULL)
		    adios (NULL, "unable to allocate tws buffer");
		*datecomp->c_tws = *dlocaltime ((time_t *) &st.st_mtime);
		datecomp->c_flags |= CF_DATEFAB|CF_TRUE;
	    } else {
		datecomp->c_flags &= ~CF_DATEFAB;
	    }
	}
    }

    fmt_scan (fmt, scanl, scanl_size, slwidth, dat, NULL);

    if (bodycomp)
	bodycomp->c_text = saved_c_text;

    if (noisy)
	fputs (scanl, stdout);

    cptr = fmt_findcomp ("encrypted");
    encrypted = cptr && cptr->c_text;

    /* return dynamically allocated buffers to pool */
    while ((cptr = *savecomp++)) {
	cptr->c_text = NULL;
    }

    if (outnum && (ferror(scnout) || fclose (scnout) == EOF))
	DIEWRERR();

    return (state != FILEEOF ? SCNERR : encrypted ? SCNENC : SCNMSG);
}
예제 #7
0
파일: dist.c 프로젝트: ella13/nmh
int
main (int argc, char **argv)
{
    int anot = 0, inplace = 1, nedit = 0;
    int nwhat = 0, i, in, isdf = 0, out;
    char *cp, *cwd, *maildir, *msgnam, *dfolder = NULL;
    char *dmsg = NULL, *ed = NULL, *file = NULL, *folder = NULL;
    char *form = NULL, *msg = NULL, buf[BUFSIZ], drft[BUFSIZ];
    char **argp, **arguments;
    struct msgs *mp = NULL;
    struct stat st;

#ifdef LOCALE
    setlocale(LC_ALL, "");
#endif
    invo_name = r1bindex (argv[0], '/');

    /* read user profile/context */
    context_read();

    arguments = getarguments (invo_name, argc, argv, 1);
    argp = arguments;

    while ((cp = *argp++)) {
	if (*cp == '-') {
	    switch (smatch (++cp, switches)) {
		case AMBIGSW: 
		    ambigsw (cp, switches);
		    done (1);
		case UNKWNSW: 
		    adios (NULL, "-%s unknown", cp);

		case HELPSW: 
		    snprintf (buf, sizeof(buf), "%s [+folder] [msg] [switches]",
			invo_name);
		    print_help (buf, switches, 1);
		    done (1);
		case VERSIONSW:
		    print_version(invo_name);
		    done (1);

		case ANNOSW: 
		    anot++;
		    continue;
		case NANNOSW: 
		    anot = 0;
		    continue;

		case EDITRSW: 
		    if (!(ed = *argp++) || *ed == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    nedit = 0;
		    continue;
		case NEDITSW:
		    nedit++;
		    continue;
		    
		case WHATSW: 
		    if (!(whatnowproc = *argp++) || *whatnowproc == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    nwhat = 0;
		    continue;
		case NWHATSW: 
		    nwhat++;
		    continue;

		case FILESW: 
		    if (file)
			adios (NULL, "only one file at a time!");
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    file = path (cp, TFILE);
		    continue;
		case FORMSW: 
		    if (!(form = *argp++) || *form == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    continue;

		case INPLSW: 
		    inplace++;
		    continue;
		case NINPLSW: 
		    inplace = 0;
		    continue;

		case DFOLDSW: 
		    if (dfolder)
			adios (NULL, "only one draft folder at a time!");
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
			    *cp != '@' ? TFOLDER : TSUBCWF);
		    continue;
		case DMSGSW: 
		    if (dmsg)
			adios (NULL, "only one draft message at a time!");
		    if (!(dmsg = *argp++) || *dmsg == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    continue;
		case NDFLDSW: 
		    dfolder = NULL;
		    isdf = NOTOK;
		    continue;
	    }
	}
	if (*cp == '+' || *cp == '@') {
	    if (folder)
		adios (NULL, "only one folder at a time!");
	    else
		folder = pluspath (cp);
	} else {
	    if (msg)
		adios (NULL, "only one message at a time!");
	    else
		msg = cp;
	}
    }

    cwd = getcpy (pwd ());

    if (!context_find ("path"))
	free (path ("./", TFOLDER));
    if (file && (msg || folder))
	adios (NULL, "can't mix files and folders/msgs");

    in = open_form(&form, distcomps);

try_it_again:
    strncpy (drft, m_draft (dfolder, dmsg, NOUSE, &isdf), sizeof(drft));

    /* Check if draft already exists */
    if (stat (drft, &st) != NOTOK) {
	printf ("Draft \"%s\" exists (%ld bytes).", drft, (long) st.st_size);
	for (i = LISTDSW; i != YESW;) {
	    if (!(argp = getans ("\nDisposition? ", isdf ? aqrnl : aqrl)))
		done (1);
	    switch (i = smatch (*argp, isdf ? aqrnl : aqrl)) {
		case NOSW: 
		    done (0);
		case NEWSW: 
		    dmsg = NULL;
		    goto try_it_again;
		case YESW: 
		    break;
		case LISTDSW: 
		    showfile (++argp, drft);
		    break;
		case REFILSW: 
		    if (refile (++argp, drft) == 0)
			i = YESW;
		    break;
		default: 
		    advise (NULL, "say what?");
		    break;
	    }
	}
    }
    if ((out = creat (drft, m_gmprot ())) == NOTOK)
	adios (drft, "unable to create");

    cpydata (in, out, form, drft);
    close (in);
    close (out);

    if (file) {
	/*
	 * Dist a file
	 */
	anot = 0;	/* don't want to annotate a file */
    } else {
	/*
	 * Dist a message
	 */
	if (!msg)
	    msg = "cur";
	if (!folder)
	    folder = getfolder (1);
	maildir = m_maildir (folder);

	if (chdir (maildir) == NOTOK)
	    adios (maildir, "unable to change directory to");

	/* read folder and create message structure */
	if (!(mp = folder_read (folder)))
	    adios (NULL, "unable to read folder %s", folder);

	/* check for empty folder */
	if (mp->nummsg == 0)
	    adios (NULL, "no messages in %s", folder);

	/* parse the message range/sequence/name and set SELECTED */
	if (!m_convert (mp, msg))
	    done (1);
	seq_setprev (mp);	/* set the previous-sequence */

	if (mp->numsel > 1)
	    adios (NULL, "only one message at a time!");
    }

    msgnam = file ? file : getcpy (m_name (mp->lowsel));
    if ((in = open (msgnam, O_RDONLY)) == NOTOK)
	adios (msgnam, "unable to open message");

    if (!file) {
	context_replace (pfolder, folder);/* update current folder  */
	seq_setcur (mp, mp->lowsel);	  /* update current message */
	seq_save (mp);			  /* synchronize sequences  */
	context_save ();		  /* save the context file  */
    }

    if (nwhat)
	done (0);
    what_now (ed, nedit, NOUSE, drft, msgnam, 1, mp,
	anot ? "Resent" : NULL, inplace, cwd);
    done (1);
    return 1;
}
예제 #8
0
파일: mhbuild.c 프로젝트: ella13/nmh
int
main (int argc, char **argv)
{
    int sizesw = 1, headsw = 1;
    int *icachesw;
    char *cp, buf[BUFSIZ];
    char buffer[BUFSIZ], *compfile = NULL;
    char **argp, **arguments;
    CT ct, cts[2];
    FILE *fp = NULL;
    FILE *fp_out = NULL;

    done=unlink_done;

#ifdef LOCALE
    setlocale(LC_ALL, "");
#endif
    invo_name = r1bindex (argv[0], '/');

    /* read user profile/context */
    context_read();

    arguments = getarguments (invo_name, argc, argv, 1);
    argp = arguments;

    while ((cp = *argp++)) {
	if (cp[0] == '-' && cp[1] == '\0') {
	    if (compfile)
		adios (NULL, "cannot specify both standard input and a file");
	    else
		compfile = cp;
	    listsw = 0;		/* turn off -list if using standard in/out */
	    verbosw = 0;	/* turn off -verbose listings */
	    break;
	}
	if (*cp == '-') {
	    switch (smatch (++cp, switches)) {
	    case AMBIGSW: 
		ambigsw (cp, switches);
		done (1);
	    case UNKWNSW: 
		adios (NULL, "-%s unknown", cp);

	    case HELPSW: 
		snprintf (buf, sizeof(buf), "%s [switches] file", invo_name);
		print_help (buf, switches, 1);
		done (1);
	    case VERSIONSW:
		print_version(invo_name);
		done (1);

	    case RCACHESW:
		icachesw = &rcachesw;
		goto do_cache;
	    case WCACHESW:
		icachesw = &wcachesw;
	    do_cache: ;
		if (!(cp = *argp++) || *cp == '-')
		    adios (NULL, "missing argument to %s", argp[-2]);
		switch (*icachesw = smatch (cp, caches)) {
		case AMBIGSW:
		    ambigsw (cp, caches);
		    done (1);
		case UNKWNSW:
		    adios (NULL, "%s unknown", cp);
		default:
		    break;
		}
		continue;

	    case CHECKSW:
		checksw++;
		continue;
	    case NCHECKSW:
		checksw = 0;
		continue;

	    case EBCDICSW:
		ebcdicsw++;
		continue;
	    case NEBCDICSW:
		ebcdicsw = 0;
		continue;

	    case HEADSW:
		headsw++;
		continue;
	    case NHEADSW:
		headsw = 0;
		continue;

	    case LISTSW:
		listsw++;
		continue;
	    case NLISTSW:
		listsw = 0;
		continue;

	    case RFC934SW:
		rfc934sw++;
		continue;
	    case NRFC934SW:
		rfc934sw = 0;
		continue;

	    case SIZESW:
		sizesw++;
		continue;
	    case NSIZESW:
		sizesw = 0;
		continue;

	    case CONTENTIDSW:
		contentidsw = 1;
		continue;
	    case NCONTENTIDSW:
		contentidsw = 0;
		continue;

	    case VERBSW: 
		verbosw++;
		continue;
	    case NVERBSW: 
		verbosw = 0;
		continue;
	    case DEBUGSW:
		debugsw = 1;
		continue;
	    }
	}
	if (compfile)
	    adios (NULL, "only one composition file allowed");
	else
	    compfile = cp;
    }

    set_endian ();

    if ((cp = getenv ("MM_NOASK")) && !strcmp (cp, "1"))
	listsw  = 0;

    /*
     * Check if we've specified an additional profile
     */
    if ((cp = getenv ("MHBUILD"))) {
	if ((fp = fopen (cp, "r"))) {
	    readconfig ((struct node **) 0, fp, cp, 0);
	    fclose (fp);
	} else {
	    admonish ("", "unable to read $MHBUILD profile (%s)", cp);
	}
    }

    /*
     * Read the standard profile setup
     */
    if ((fp = fopen (cp = etcpath ("mhn.defaults"), "r"))) {
	readconfig ((struct node **) 0, fp, cp, 0);
	fclose (fp);
    }

    /* Check for public cache location */
    if ((cache_public = context_find (nmhcache)) && *cache_public != '/')
	cache_public = NULL;

    /* Check for private cache location */
    if (!(cache_private = context_find (nmhprivcache)))
	cache_private = ".cache";
    cache_private = getcpy (m_maildir (cache_private));

    /*
     * Check for storage directory.  If defined, we
     * will store temporary files there.  Else we
     * store them in standard nmh directory.
     */
    if ((cp = context_find (nmhstorage)) && *cp)
	tmp = concat (cp, "/", invo_name, NULL);
    else
	tmp = add (m_maildir (invo_name), NULL);

    if (!context_find ("path"))
	free (path ("./", TFOLDER));

    /* Check if we have a file to process */
    if (!compfile)
	adios (NULL, "need to specify a %s composition file", invo_name);

    /*
     * Process the composition file from standard input.
     */
    if (compfile[0] == '-' && compfile[1] == '\0') {
	/* copy standard input to temporary file */
	strncpy (infile, m_mktemp(invo_name, NULL, &fp), sizeof(infile));
	while (fgets (buffer, BUFSIZ, stdin))
	    fputs (buffer, fp);
	fclose (fp);
	unlink_infile = 1;

	/* build the content structures for MIME message */
	ct = build_mime (infile);
	cts[0] = ct;
	cts[1] = NULL;

	/* output MIME message to this temporary file */
	strncpy (outfile, m_mktemp(invo_name, NULL, &fp_out), sizeof(outfile));
	unlink_outfile = 1;

	/* output the message */
	output_message_fp (ct, fp_out, outfile);
        fclose(fp_out);

	/* output the temp file to standard output */
	if ((fp = fopen (outfile, "r")) == NULL)
	    adios (outfile, "unable to open");
	while (fgets (buffer, BUFSIZ, fp))
	    fputs (buffer, stdout);
	fclose (fp);

	unlink (infile);
	unlink_infile = 0;

	unlink (outfile);
	unlink_outfile = 0;

	free_content (ct);
	done (0);
    }

    /*
     * Process the composition file from a file.
     */

    /* build the content structures for MIME message */
    ct = build_mime (compfile);
    cts[0] = ct;
    cts[1] = NULL;

    /* output MIME message to this temporary file */
    strncpy(outfile, m_mktemp2(compfile, invo_name, NULL, &fp_out),
            sizeof(outfile));
    unlink_outfile = 1;

    /* output the message */
    output_message_fp (ct, fp_out, outfile);
    fclose(fp_out);

    /*
     * List the message info
     */
    if (listsw)
	list_all_messages (cts, headsw, sizesw, verbosw, debugsw);

    /* Rename composition draft */
    snprintf (buffer, sizeof(buffer), "%s.orig", m_backup (compfile));
    if (rename (compfile, buffer) == NOTOK) {
	adios (compfile, "unable to rename comp draft %s to", buffer);
    }

    /* Rename output file to take its place */
    if (rename (outfile, compfile) == NOTOK) {
	advise (outfile, "unable to rename output %s to", compfile);
	rename (buffer, compfile);
	done (1);
    }
    unlink_outfile = 0;

    free_content (ct);
    done (0);
    return 1;
}
예제 #9
0
파일: seq_read.c 프로젝트: dscho/nmh
static void
seq_public (struct msgs *mp, int lockflag)
{
    int state;
    char *cp, seqfile[PATH_MAX];
    char name[NAMESZ], field[BUFSIZ];
    FILE *fp;
    m_getfld_state_t gstate = 0;

    /*
     * If mh_seq == NULL or if *mh_seq == '\0' (the user has defined
     * the "mh-sequences" profile entry, but left it empty),
     * then just return, and do not initialize any public sequences.
     */
    if (mh_seq == NULL || *mh_seq == '\0')
	return;

    /* get filename of sequence file */
    snprintf (seqfile, sizeof(seqfile), "%s/%s", mp->foldpath, mh_seq);

    if ((fp = lkfopendata (seqfile, lockflag ? "r+" : "r")) == NULL)
	return;

    /* Use m_getfld to scan sequence file */
    for (;;) {
	int fieldsz = sizeof field;
	switch (state = m_getfld (&gstate, name, field, &fieldsz, fp)) {
	    case FLD: 
	    case FLDPLUS:
		if (state == FLDPLUS) {
		    cp = getcpy (field);
		    while (state == FLDPLUS) {
			fieldsz = sizeof field;
			state = m_getfld (&gstate, name, field, &fieldsz, fp);
			cp = add (field, cp);
		    }
		    seq_init (mp, getcpy (name), trimcpy (cp));
		    free (cp);
		} else {
		    seq_init (mp, getcpy (name), trimcpy (field));
		}
		continue;

	    case BODY:
	    	lkfclosedata (fp, seqfile);
		adios (NULL, "no blank lines are permitted in %s", seqfile);
		/* fall */

	    case FILEEOF:
		break;

	    default: 
	    	lkfclosedata (fp, seqfile);
		adios (NULL, "%s is poorly formatted", seqfile);
	}
	break;	/* break from for loop */
    }
    m_getfld_state_destroy (&gstate);

    if (lockflag) {
	mp->seqhandle = fp;
	mp->seqname = getcpy(seqfile);
    } else {
	lkfclosedata (fp, seqfile);
    }
}
예제 #10
0
파일: picksbr.c 프로젝트: ella13/nmh
static struct nexus *
nexp3 (void)
{
    int i;
    register char *cp, *dp;
    char buffer[BUFSIZ], temp[64];
    register struct nexus *n;

    if ((cp = nxtarg ()) == NULL)
	return NULL;

    if (*cp != '-') {
	padvise (NULL, "%s unexpected", cp);
	return NULL;
    }

    if (*++cp == '-') {
	dp = ++cp;
	goto header;
    }
    switch (i = smatch (cp, parswit)) {
	case AMBIGSW: 
	    ambigsw (cp, parswit);
	    talked++;
	    return NULL;
	case UNKWNSW: 
	    fprintf (stderr, "-%s unknown\n", cp);
	    talked++;
	    return NULL;

	case PRLBR: 
	    if ((n = parse ()) == NULL) {
		padvise (NULL, "missing group");
		return NULL;
	    }
	    if ((cp = nxtarg ()) == NULL) {
		padvise (NULL, "missing -rbrace");
		return NULL;
	    }
	    if (*cp++ == '-' && smatch (cp, parswit) == PRRBR)
		return n;
	    padvise (NULL, "%s unexpected", --cp);
	    return NULL;

	default: 
	    prvarg ();
	    return NULL;

	case PRCC: 
	case PRDATE: 
	case PRFROM: 
	case PRTO: 
	case PRSUBJ: 
	    strncpy(temp, parswit[i].sw, sizeof(temp));
	    temp[sizeof(temp) - 1] = '\0';
	    dp = *brkstring (temp, " ", NULL);
    header: ;
	    if (!(cp = nxtarg ())) {/* allow -xyz arguments */
		padvise (NULL, "missing argument to %s", argp[-2]);
		return NULL;
	    }
	    n = newnexus (GREPaction);
	    n->n_header = 1;
	    snprintf (buffer, sizeof(buffer), "^%s[ \t]*:.*%s", dp, cp);
	    dp = buffer;
	    goto pattern;

	case PRSRCH: 
	    n = newnexus (GREPaction);
	    n->n_header = 0;
	    if (!(cp = nxtarg ())) {/* allow -xyz arguments */
		padvise (NULL, "missing argument to %s", argp[-2]);
		return NULL;
	    }
	    dp = cp;
    pattern: ;
	    if (!gcompile (n, dp)) {
		padvise (NULL, "pattern error in %s %s", argp[-2], cp);
		return NULL;
	    }
	    n->n_patbuf = getcpy (dp);
	    return n;

	case PROTHR: 
	    padvise (NULL, "internal error!");
	    return NULL;

	case PRDATF: 
	    if (!(datesw = nxtarg ()) || *datesw == '-') {
		padvise (NULL, "missing argument to %s", argp[-2]);
		return NULL;
	    }
	    return nexp3 ();

	case PRAFTR: 
	case PRBEFR: 
	    if (!(cp = nxtarg ())) {/* allow -xyz arguments */
		padvise (NULL, "missing argument to %s", argp[-2]);
		return NULL;
	    }
	    n = newnexus (TWSaction);
	    n->n_datef = datesw;
	    if (!tcompile (cp, &n->n_tws, n->n_after = i == PRAFTR)) {
		padvise (NULL, "unable to parse %s %s", argp[-2], cp);
		return NULL;
	    }
	    return n;
    }
}
예제 #11
0
파일: forw.c 프로젝트: dscho/nmh
static void
mhl_draft (int out, char *digest, int volume, int issue,
            char *file, char *filter, int dashstuff)
{
    pid_t child_id;
    int i, msgnum, pd[2];
    char buf1[BUFSIZ];
    char buf2[BUFSIZ];
    char *program;
    struct msgs_array vec = { 0, 0, NULL };

    if (pipe (pd) == NOTOK)
	adios ("pipe", "unable to create");

    argsplit_msgarg(&vec, mhlproc, &program);

    for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
	sleep (5);

    switch (child_id) {
	case NOTOK: 
	    adios ("fork", "unable to");

	case OK: 
	    close (pd[0]);
	    dup2 (pd[1], 1);
	    close (pd[1]);

	    i = 1;
	    app_msgarg(&vec, "-forwall");
	    app_msgarg(&vec, "-form");
	    app_msgarg(&vec, filter);

	    if (digest) {
		app_msgarg(&vec, "-digest");
		app_msgarg(&vec, digest);
		app_msgarg(&vec, "-issue");
		snprintf (buf1, sizeof(buf1), "%d", issue);
		app_msgarg(&vec, buf1);
		app_msgarg(&vec, "-volume");
		snprintf (buf2, sizeof(buf2), "%d", volume);
		app_msgarg(&vec, buf2);
	    }

	    /*
	     * Are we dashstuffing (quoting) the lines that begin
	     * with `-'.  We use the mhl default (don't add any flag)
	     * unless the user has specified a specific flag.
	     */
	    if (dashstuff > 0)
		app_msgarg(&vec, "-dashstuffing");
	    else if (dashstuff < 0)
		app_msgarg(&vec, "-nodashstuffing");

	    for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
		if (is_selected (mp, msgnum))
		    app_msgarg(&vec, getcpy (m_name (msgnum)));
	    }

	    app_msgarg(&vec, NULL);

	    execvp (program, vec.msgs);
	    fprintf (stderr, "unable to exec ");
	    perror (mhlproc);
	    _exit (-1);

	default: 
	    close (pd[1]);
	    cpydata (pd[0], out, vec.msgs[0], file);
	    close (pd[0]);
	    pidXwait(child_id, mhlproc);
	    break;
    }
}
예제 #12
0
파일: forw.c 프로젝트: dscho/nmh
int
main (int argc, char **argv)
{
    int anot = 0, inplace = 1, mime = 0;
    int issue = 0, volume = 0, dashstuff = 0;
    int nedit = 0, nwhat = 0, i, in;
    int out, isdf = 0, msgnum = 0;
    int outputlinelen = OUTPUTLINELEN;
    int dat[5];
    char *cp, *cwd, *maildir, *dfolder = NULL;
    char *dmsg = NULL, *digest = NULL, *ed = NULL;
    char *file = NULL, *filter = NULL, *folder = NULL, *fwdmsg = NULL;
    char *from = NULL, *to = NULL, *cc = NULL, *subject = NULL, *fcc = NULL;
    char *form = NULL, buf[BUFSIZ], value[10];
    char **argp, **arguments;
    struct stat st;
    struct msgs_array msgs = { 0, 0, NULL };
    int buildsw = 0;

    if (nmh_init(argv[0], 1)) { return 1; }

    arguments = getarguments (invo_name, argc, argv, 1);
    argp = arguments;

    while ((cp = *argp++)) {
	if (*cp == '-') {
	    switch (smatch (++cp, switches)) {
		case AMBIGSW: 
		    ambigsw (cp, switches);
		    done (1);
		case UNKWNSW: 
		    adios (NULL, "-%s unknown", cp);

		case HELPSW: 
		    snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]",
			invo_name);
		    print_help (buf, switches, 1);
		    done (0);
		case VERSIONSW:
		    print_version(invo_name);
		    done (0);

		case ANNOSW: 
		    anot++;
		    continue;
		case NANNOSW: 
		    anot = 0;
		    continue;

		case EDITRSW: 
		    if (!(ed = *argp++) || *ed == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    nedit = 0;
		    continue;
		case NEDITSW:
		    nedit++;
		    continue;

		case WHATSW: 
		    if (!(whatnowproc = *argp++) || *whatnowproc == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    nwhat = 0;
		    continue;
		case BILDSW:
		    buildsw++;	/* fall... */
		case NWHATSW: 
		    nwhat++;
		    continue;

		case FILESW: 
		    if (file)
			adios (NULL, "only one file at a time!");
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    file = path (cp, TFILE);
		    continue;
		case FILTSW:
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    filter = getcpy (etcpath (cp));
		    mime = 0;
		    continue;
		case FORMSW: 
		    if (!(form = *argp++) || *form == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    continue;

		case FRMTSW:
		    filter = getcpy (etcpath (mhlforward));
		    continue;
		case NFRMTSW:
		    filter = NULL;
		    continue;

		case INPLSW: 
		    inplace++;
		    continue;
		case NINPLSW: 
		    inplace = 0;
		    continue;

		case MIMESW:
		    mime++;
		    filter = NULL;
		    continue;
		case NMIMESW: 
		    mime = 0;
		    continue;

		case DGSTSW: 
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    digest = getcpy(cp);
		    mime = 0;
		    continue;
		case ISSUESW:
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    if ((issue = atoi (cp)) < 1)
			adios (NULL, "bad argument %s %s", argp[-2], cp);
		    continue;
		case VOLUMSW:
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    if ((volume = atoi (cp)) < 1)
			adios (NULL, "bad argument %s %s", argp[-2], cp);
		    continue;

		case DFOLDSW: 
		    if (dfolder)
			adios (NULL, "only one draft folder at a time!");
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
				    *cp != '@' ? TFOLDER : TSUBCWF);
		    continue;
		case DMSGSW:
		    if (dmsg)
			adios (NULL, "only one draft message at a time!");
		    if (!(dmsg = *argp++) || *dmsg == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    continue;
		case NDFLDSW: 
		    dfolder = NULL;
		    isdf = NOTOK;
		    continue;

		case BITSTUFFSW: 
		    dashstuff = 1;	/* trinary logic */
		    continue;
		case NBITSTUFFSW: 
		    dashstuff = -1;	/* trinary logic */
		    continue;

		case FROMSW:
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    from = addlist(from, cp);
		    continue;
		case TOSW:
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    to = addlist(to, cp);
		    continue;
		case CCSW:
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    cc = addlist(cc, cp);
		    continue;
		case FCCSW:
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    fcc = addlist(fcc, cp);
		    continue;
		case SUBJECTSW:
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    subject = getcpy(cp);
		    continue;

		case WIDTHSW:
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    if ((outputlinelen = atoi(cp)) < 10)
			adios (NULL, "impossible width %d", outputlinelen);
		    continue;
	    }
	}
	if (*cp == '+' || *cp == '@') {
	    if (folder)
		adios (NULL, "only one folder at a time!");
	    else
		folder = pluspath (cp);
	} else {
	    app_msgarg(&msgs, cp);
	}
    }

    cwd = getcpy (pwd ());

    if (!context_find ("path"))
	free (path ("./", TFOLDER));
    if (file && (msgs.size || folder))
	adios (NULL, "can't mix files and folders/msgs");

try_it_again:

    strncpy (drft, buildsw ? m_maildir ("draft")
			  : m_draft (dfolder, NULL, NOUSE, &isdf), sizeof(drft));

    /* Check if a draft already exists */
    if (!buildsw && stat (drft, &st) != NOTOK) {
	printf ("Draft \"%s\" exists (%ld bytes).", drft, (long) st.st_size);
	for (i = LISTDSW; i != YESW;) {
	    if (!(argp = getans ("\nDisposition? ", isdf ? aqrnl : aqrl)))
		done (1);
	    switch (i = smatch (*argp, isdf ? aqrnl : aqrl)) {
		case NOSW: 
		    done (0);
		case NEWSW: 
		    dmsg = NULL;
		    goto try_it_again;
		case YESW: 
		    break;
		case LISTDSW: 
		    showfile (++argp, drft);
		    break;
		case REFILSW: 
		    if (refile (++argp, drft) == 0)
			i = YESW;
		    break;
		default: 
		    advise (NULL, "say what?");
		    break;
	    }
	}
    }

    if (file) {
	/*
	 * Forwarding a file.
         */
	anot = 0;	/* don't want to annotate a file */
    } else {
	/*
	 * Forwarding a message.
	 */
	if (!msgs.size)
	    app_msgarg(&msgs, "cur");
	if (!folder)
	    folder = getfolder (1);
	maildir = m_maildir (folder);

	if (chdir (maildir) == NOTOK)
	    adios (maildir, "unable to change directory to");

	/* read folder and create message structure */
	if (!(mp = folder_read (folder, 1)))
	    adios (NULL, "unable to read folder %s", folder);

	/* check for empty folder */
	if (mp->nummsg == 0)
	    adios (NULL, "no messages in %s", folder);

	/* parse all the message ranges/sequences and set SELECTED */
	for (msgnum = 0; msgnum < msgs.size; msgnum++)
	    if (!m_convert (mp, msgs.msgs[msgnum]))
		done (1);

	seq_setprev (mp);	/* set the previous sequence */

	/*
	 * Find the first message in our set and use it as the input
	 * for the component scanner
	 */

	for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
	    if (is_selected (mp, msgnum)) {
	    	fwdmsg = strdup(m_name(msgnum));
		break;
	    }

	if (! fwdmsg)
	    adios (NULL, "Unable to find input message");
    }

    if (filter && access (filter, R_OK) == NOTOK)
	adios (filter, "unable to read");

    /*
     * Open form (component) file.
     */
    if (digest) {
	if (issue == 0) {
	    snprintf (buf, sizeof(buf), IFORMAT, digest);
	    if (volume == 0
		    && (cp = context_find (buf))
		    && ((issue = atoi (cp)) < 0))
		issue = 0;
	    issue++;
	}
	if (volume == 0) {
	    snprintf (buf, sizeof(buf), VFORMAT, digest);
	    if ((cp = context_find (buf)) == NULL || (volume = atoi (cp)) <= 0)
		volume = 1;
	}
	if (!form)
	    form = digestcomps;
    } else {
    	if (!form)
    	    form = forwcomps;
    }

    dat[0] = digest ? issue : msgnum;
    dat[1] = volume;
    dat[2] = 0;
    dat[3] = outputlinelen;
    dat[4] = 0;


    in = build_form (form, digest, dat, from, to, cc, fcc, subject,
    		     file ? file : fwdmsg);

    if ((out = creat (drft, m_gmprot ())) == NOTOK)
	adios (drft, "unable to create");

    /*
     * copy the components into the draft
     */
    cpydata (in, out, form, drft);
    close (in);

    if (file) {
	/* just copy the file into the draft */
	if ((in = open (file, O_RDONLY)) == NOTOK)
	    adios (file, "unable to open");
	cpydata (in, out, file, drft);
	close (in);
	close (out);
    } else {
	/*
	 * If filter file is defined, then format the
	 * messages into the draft using mhlproc.
	 */
	if (filter)
	    mhl_draft (out, digest, volume, issue, drft, filter, dashstuff);
	else if (mime)
	    copy_mime_draft (out);
	else
	    copy_draft (out, digest, drft, volume, issue, dashstuff);
	close (out);

	if (digest) {
	    snprintf (buf, sizeof(buf), IFORMAT, digest);
	    snprintf (value, sizeof(value), "%d", issue);
	    context_replace (buf, getcpy (value));
	    snprintf (buf, sizeof(buf), VFORMAT, digest);
	    snprintf (value, sizeof(value), "%d", volume);
	    context_replace (buf, getcpy (value));
	}

	context_replace (pfolder, folder);	/* update current folder   */
	seq_setcur (mp, mp->lowsel);		/* update current message  */
	seq_save (mp);				/* synchronize sequences   */
	context_save ();			/* save the context file   */
    }

    if (nwhat)
	done (0);
    what_now (ed, nedit, NOUSE, drft, NULL, 0, mp,
	anot ? "Forwarded" : NULL, inplace, cwd, 0);
    done (1);
    return 1;
}
예제 #13
0
파일: send.c 프로젝트: dscho/nmh
int
main (int argc, char **argv)
{
    int msgp = 0, distsw = 0, vecp;
    int isdf = 0, mime = 0;
    int msgnum, status;
    char *cp, *dfolder = NULL, *maildir = NULL;
    char buf[BUFSIZ], **ap, **argp, **arguments, *program;
    char *msgs[MAXARGS], **vec;
    struct msgs *mp;
    struct stat st;

    if (nmh_init(argv[0], 1)) { return 1; }

    arguments = getarguments (invo_name, argc, argv, 1);
    argp = arguments;

    vec = argsplit(postproc, &program, &vecp);

    vec[vecp++] = "-library";
    vec[vecp++] = getcpy (m_maildir (""));

    if ((cp = context_find ("fileproc"))) {
	vec[vecp++] = "-fileproc";
	vec[vecp++] = cp;
    }

    if ((cp = context_find ("mhlproc"))) {
	vec[vecp++] = "-mhlproc";
	vec[vecp++] = cp;
    }

    if ((cp = context_find ("credentials"))) {
	/* post doesn't read context so need to pass credentials. */
	vec[vecp++] = "-credentials";
	vec[vecp++] = cp;
    }

    while ((cp = *argp++)) {
	if (*cp == '-') {
	    switch (smatch (++cp, switches)) {
		case AMBIGSW: 
		    ambigsw (cp, switches);
		    done (1);
		case UNKWNSW: 
		    adios (NULL, "-%s unknown\n", cp);

		case HELPSW: 
		    snprintf (buf, sizeof(buf), "%s [file] [switches]", invo_name);
		    print_help (buf, switches, 1);
		    done (0);
		case VERSIONSW:
		    print_version(invo_name);
		    done (0);

		case DRAFTSW: 
		    msgs[msgp++] = draft;
		    continue;

		case DFOLDSW: 
		    if (dfolder)
			adios (NULL, "only one draft folder at a time!");
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
			    *cp != '@' ? TFOLDER : TSUBCWF);
		    continue;
		case DMSGSW: 
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    msgs[msgp++] = cp;
		    continue;
		case NDFLDSW: 
		    dfolder = NULL;
		    isdf = NOTOK;
		    continue;

		case PUSHSW: 
		    pushsw++;
		    continue;
		case NPUSHSW: 
		    pushsw = 0;
		    continue;

		case SPLITSW: 
		    if (!(cp = *argp++) || sscanf (cp, "%d", &splitsw) != 1)
			adios (NULL, "missing argument to %s", argp[-2]);
		    continue;

		case UNIQSW: 
		    unique++;
		    continue;
		case NUNIQSW: 
		    unique = 0;
		    continue;

		case FORWSW:
		    forwsw++;
		    continue;
		case NFORWSW:
		    forwsw = 0;
		    continue;

		case VERBSW: 
		    verbsw++;
		    vec[vecp++] = --cp;
		    continue;
		case NVERBSW:
		    verbsw = 0;
		    vec[vecp++] = --cp;
		    continue;

		case MIMESW:
		    mime++;
		    vec[vecp++] = --cp;
		    continue;
		case NMIMESW:
		    mime = 0;
		    vec[vecp++] = --cp;
		    continue;

		case DEBUGSW: 
		    debugsw++;	/* fall */
		case NFILTSW: 
		case FRMTSW: 
		case NFRMTSW: 
		case BITSTUFFSW:
		case NBITSTUFFSW:
		case MSGDSW: 
		case NMSGDSW: 
		case WATCSW: 
		case NWATCSW: 
		case SNOOPSW: 
		case SASLSW:
		case NOSASLSW:
		case TLSSW:
		case INITTLSSW:
		case NTLSSW:
		    vec[vecp++] = --cp;
		    continue;

		case ALIASW: 
		case FILTSW: 
		case WIDTHSW: 
		case CLIESW: 
		case SERVSW: 
		case SASLMECHSW:
		case SASLMXSSFSW:
		case USERSW:
		case PORTSW:
		case MTSSW:
		case MESSAGEIDSW:
		    vec[vecp++] = --cp;
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    vec[vecp++] = cp;
		    continue;
		
		case ATTACHSW:
		    advise(NULL, "The -attach switch is deprecated");
		    continue;
		case NOATTACHSW:
		    advise(NULL, "The -noattach switch is deprecated");
		    continue;

		case ATTACHFORMATSW:
		    advise(NULL, "The -attachformat switch is deprecated");
		    continue;
	    }
	} else {
	    msgs[msgp++] = cp;
	}
    }

    /*
     * check for "Aliasfile:" profile entry
     */
    if ((cp = context_find ("Aliasfile"))) {
	char *dp = NULL;

	for (ap = brkstring(dp = getcpy(cp), " ", "\n"); ap && *ap; ap++) {
	    vec[vecp++] = "-alias";
	    vec[vecp++] = *ap;
	}
    }

    if (dfolder == NULL) {
	if (msgp == 0) {
	    msgs[msgp++] = getcpy (m_draft (NULL, NULL, 1, &isdf));
	    if (stat (msgs[0], &st) == NOTOK)
		adios (msgs[0], "unable to stat draft file");
	    cp = concat ("Use \"", msgs[0], "\"? ", NULL);
	    for (status = LISTDSW; status != YESW;) {
		if (!(argp = getans (cp, anyl)))
		    done (1);
		switch (status = smatch (*argp, anyl)) {
		    case NOSW: 
			done (0);
		    case YESW: 
			break;
		    case LISTDSW: 
			showfile (++argp, msgs[0]);
			break;
		    default:
			advise (NULL, "say what?");
			break;
		}
	    }
	} else {
	    for (msgnum = 0; msgnum < msgp; msgnum++)
		msgs[msgnum] = getcpy (m_maildir (msgs[msgnum]));
	}
    } else {
	if (!context_find ("path"))
	    free (path ("./", TFOLDER));

	if (!msgp)
	    msgs[msgp++] = "cur";
	maildir = m_maildir (dfolder);

	if (chdir (maildir) == NOTOK)
	    adios (maildir, "unable to change directory to");

	/* read folder and create message structure */
	if (!(mp = folder_read (dfolder, 1)))
	    adios (NULL, "unable to read folder %s", dfolder);

	/* check for empty folder */
	if (mp->nummsg == 0)
	    adios (NULL, "no messages in %s", dfolder);

	/* parse all the message ranges/sequences and set SELECTED */
	for (msgnum = 0; msgnum < msgp; msgnum++)
	    if (!m_convert (mp, msgs[msgnum]))
		done (1);
	seq_setprev (mp);	/* set the previous-sequence */

	for (msgp = 0, msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
	    if (is_selected (mp, msgnum)) {
		msgs[msgp++] = getcpy (m_name (msgnum));
		unset_exists (mp, msgnum);
	    }
	}

	mp->msgflags |= SEQMOD;
	seq_save (mp);
    }

#ifdef WHATNOW
go_to_it:
#endif /* WHATNOW */

    if ((cp = getenv ("SIGNATURE")) == NULL || *cp == 0)
	if ((cp = context_find ("signature")) && *cp)
	    m_putenv ("SIGNATURE", cp);

    for (msgnum = 0; msgnum < msgp; msgnum++)
	if (stat (msgs[msgnum], &st) == NOTOK)
	    adios (msgs[msgnum], "unable to stat draft file");

    if ((annotext = getenv ("mhannotate")) == NULL || *annotext == 0)
	annotext = NULL;
    if (annotext && ((cp = getenv ("mhinplace")) != NULL && *cp != 0))
	inplace = atoi (cp);
    if ((altmsg = getenv ("mhaltmsg")) == NULL || *altmsg == 0)
	altmsg = NULL;	/* used by dist interface - see below */

    if ((cp = getenv ("mhdist"))
	    && *cp
	    && (distsw = atoi (cp))
	    && altmsg) {
	vec[vecp++] = "-dist";
	if ((cp = m_mktemp2(altmsg, invo_name, NULL, NULL)) == NULL) {
	    adios(NULL, "unable to create temporary file in %s",
		  get_temp_dir());
	}
	distfile = getcpy (cp);
	(void) m_unlink(distfile);
	if (link (altmsg, distfile) == NOTOK) {
	    /* Cygwin with FAT32 filesystem produces EPERM. */
	    if (errno != EXDEV  &&  errno != EPERM
#ifdef EISREMOTE
		    && errno != EISREMOTE
#endif /* EISREMOTE */
		)
		adios (distfile, "unable to link %s to", altmsg);
	    free (distfile);
	    if ((cp = m_mktemp2(NULL, invo_name, NULL, NULL)) == NULL) {
		adios(NULL, "unable to create temporary file in %s",
		      get_temp_dir());
	    }
	    distfile = getcpy (cp);
	    {
		int in, out;
		struct stat st;

		if ((in = open (altmsg, O_RDONLY)) == NOTOK)
		    adios (altmsg, "unable to open");
		fstat(in, &st);
		if ((out = creat (distfile, (int) st.st_mode & 0777)) == NOTOK)
		    adios (distfile, "unable to write");
		cpydata (in, out, altmsg, distfile);
		close (in);
		close (out);
	    }	
	}
    } else {
	distfile = NULL;
    }

    if (altmsg == NULL || stat (altmsg, &st) == NOTOK) {
	st.st_mtime = 0;
	st.st_dev = 0;
	st.st_ino = 0;
    }
    if (pushsw)
	push ();

    status = 0;
    closefds (3);

    for (msgnum = 0; msgnum < msgp; msgnum++) {
	switch (sendsbr (vec, vecp, program, msgs[msgnum], &st, 1)) {
	    case DONE: 
		done (++status);
	    case NOTOK: 
		status++;	/* fall */
	    case OK:
		break;
	}
    }

    context_save ();	/* save the context file */
    done (status);
    return 1;
}
예제 #14
0
파일: readconfig.c 프로젝트: ella13/nmh
void
readconfig (struct node **npp, FILE *ib, char *file, int ctx)
{
    register int state;
    register char *cp;
    char name[NAMESZ], field[BUFSIZ];
    register struct node *np;
    register struct procstr *ps;

    if (npp == NULL && (npp = opp) == NULL) {
	admonish (NULL, "bug: readconfig called but pump not primed");
	return;
    }

    for (state = FLD;;) {
	switch (state = m_getfld (state, name, field, sizeof(field), ib)) {
	    case FLD:
	    case FLDPLUS:
	    case FLDEOF:
		np = (struct node *) mh_xmalloc (sizeof(*np));
		*npp = np;
		*(npp = &np->n_next) = NULL;
		np->n_name = getcpy (name);
		if (state == FLDPLUS) {
		    cp = getcpy (field);
		    while (state == FLDPLUS) {
			state = m_getfld (state, name, field, sizeof(field), ib);
			cp = add (field, cp);
		    }
		    np->n_field = trimcpy (cp);
		    free (cp);
		} else {
		    np->n_field = trimcpy (field);
		}
		np->n_context = ctx;

		/*
		 * Now scan the list of `procs' and link in the
		 * field value to the global variable.
		 */
		for (ps = procs; ps->procname; ps++)
		    if (strcmp (np->n_name, ps->procname) == 0) {
			*ps->procnaddr = np->n_field;
			break;
		    }
		if (state == FLDEOF)
		    break;
		continue;

	    case BODY:
	    case BODYEOF:
		adios (NULL, "no blank lines are permitted in %s", file);

	    case FILEEOF:
		break;

	    default:
		adios (NULL, "%s is poorly formatted", file);
	}
	break;
    }

    opp = npp;
}
예제 #15
0
파일: whom.c 프로젝트: dscho/nmh
int
main (int argc, char **argv)
{
    pid_t child_id = OK;
    int i, status, isdf = 0;
    int distsw = 0, vecp = 0;
    char *cp, *dfolder = NULL, *dmsg = NULL;
    char *msg = NULL, **ap, **argp, backup[BUFSIZ];
    char buf[BUFSIZ], **arguments, *vec[MAXARGS];

    if (nmh_init(argv[0], 1)) { return 1; }

    arguments = getarguments (invo_name, argc, argv, 1);
    argp = arguments;

    vec[vecp++] = invo_name;
    vec[vecp++] = "-whom";
    vec[vecp++] = "-library";
    vec[vecp++] = getcpy (m_maildir (""));

    /* Don't need to feed fileproc or mhlproc to post because
       it doesn't use them when used for whom. */

    while ((cp = *argp++)) {
	if (*cp == '-') {
	    switch (smatch (++cp, switches)) {
		case AMBIGSW: 
		    ambigsw (cp, switches);
		    done (1);
		case UNKWNSW: 
		    adios (NULL, "-%s unknown", cp);

		case HELPSW: 
		    snprintf (buf, sizeof(buf), "%s [switches] [file]", invo_name);
		    print_help (buf, switches, 1);
		    done (0);
		case VERSIONSW:
		    print_version(invo_name);
		    done (0);

		case CHKSW: 
		case NOCHKSW: 
		case SNOOPSW:
		case SASLSW:
		case TLSSW:
		case INITTLSSW:
		case NTLSSW:
		    vec[vecp++] = --cp;
		    continue;

		case DRAFTSW:
		    msg = draft;
		    continue;

		case DFOLDSW: 
		    if (dfolder)
			adios (NULL, "only one draft folder at a time!");
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
			    *cp != '@' ? TFOLDER : TSUBCWF);
		    continue;
		case DMSGSW: 
		    if (dmsg)
			adios (NULL, "only one draft message at a time!");
		    if (!(dmsg = *argp++) || *dmsg == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    continue;
		case NDFLDSW: 
		    dfolder = NULL;
		    isdf = NOTOK;
		    continue;

		case ALIASW: 
		case CLIESW: 
		case SERVSW: 
		case USERSW:
		case PORTSW:
		case SASLMECHSW:
		case MTSSW:
		    vec[vecp++] = --cp;
		    if (!(cp = *argp++) || *cp == '-')
			adios (NULL, "missing argument to %s", argp[-2]);
		    vec[vecp++] = cp;
		    continue;
	    }
	}
	if (msg)
	    adios (NULL, "only one draft at a time!");
	else
	    vec[vecp++] = msg = cp;
    }

    /* allow Aliasfile: profile entry */
    if ((cp = context_find ("Aliasfile"))) {
	char *dp = NULL;

	for (ap = brkstring(dp = getcpy(cp), " ", "\n"); ap && *ap; ap++) {
	    vec[vecp++] = "-alias";
	    vec[vecp++] = *ap;
	}
    }

    if (msg == NULL) {
	    cp  = getcpy (m_draft (dfolder, dmsg, 1, &isdf));
	msg = vec[vecp++] = cp;
    }
    if ((cp = getenv ("mhdist"))
	    && *cp
	    && (distsw = atoi (cp))
	    && (cp = getenv ("mhaltmsg"))
	    && *cp) {
	if (distout (msg, cp, backup) == NOTOK)
	    done (1);
	vec[vecp++] = "-dist";
	distsw++;
    }
    vec[vecp] = NULL;

    closefds (3);

    if (distsw) {
	for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
	    sleep (5);
    }

    switch (distsw ? child_id : OK) {
	case NOTOK:
    	    advise (NULL, "unable to fork, so checking directly...");
	case OK:
	    execvp (postproc, vec);
	    fprintf (stderr, "unable to exec ");
	    perror (postproc);
	    _exit (-1);

	default:
	    SIGNAL (SIGHUP, SIG_IGN);
	    SIGNAL (SIGINT, SIG_IGN);
	    SIGNAL (SIGQUIT, SIG_IGN);
	    SIGNAL (SIGTERM, SIG_IGN);

	    status = pidwait(child_id, OK);

	    (void) m_unlink (msg);
	    if (rename (backup, msg) == NOTOK)
		adios (msg, "unable to rename %s to", backup);
	    done (status);
    }

    return 0;  /* dead code to satisfy the compiler */
}