ftp.nice.ch/pub/next/unix/mail/tnextmail.1.0.s.tar.gz#/tnextmail/batch.c

This is batch.c in view mode; [Download] [Up]

/* $Id: batch.c,v 1.3 91/05/25 15:32:20 cap Exp $
 * Make a connection to tar, compress, and uuencode to batch up the 
 * message and all its attachments.
 */

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#ifdef USG
#include <sys/unistd.h>
#else
#include <sys/param.h>
#include <sys/file.h>
#endif
#include <sys/stat.h>
#include "config.h"
#include "tnextmail.h"

char command[MAXPATHLEN], attach_name[64], tar_uu_name[MAXPATHLEN];
char **tolist;			/* list of addressees */
char *construct_attach_header();
extern int lastattach;
extern struct attach *attachments;

/* 
 * batch_message - make a system(3) call to tar, compress, and uuencode
 *                 to create the body of the message to be mailed. 
 *                 Output is written to the file tar.uu in the temp 
 *                 directory.
 */

batch_message(tmpdir_name)
     char *tmpdir_name;
{
    sprintf(tar_uu_name, "%s/tar.uu", tmpdir_name);
    sprintf(command, "%s cf - -C %s %s ", TAR, tmpdir_name, RTF_NAME);
    construct_filelist();
    strcat(command, "| compress | uuencode ");
    construct_batch_name();
    strcat(command, attach_name);
    strcat(command, " > ");
    strcat(command, tar_uu_name);
#ifdef DEBUG
    fprintf(stderr, "I will run \"%s\"\n", command);
#endif
    if (system(command) == 127) {
	perror("batching");
	fatalerrors++;
	return;
    }
}

/* 
 * construct_filelist - make a list of the form
 *                      -C where index.rtf -C dir1 attach1
 *                      where 'where' is the location of the rtf 
 *                      file, index.rtf is the rtf file, dir1 is the 
 *                      directory in which attach1 is located, etc.
 */

construct_filelist()
{
    int i;
    char *cend;

    for (i = 0; i < lastattach; i++) {
	cend = &command[strlen(command)];
	sprintf(cend, "-C %s %s ", attachments[i].pathname, attachments[i].basename);
    }
}

/* 
 * construct_batch_name - make the weird file name from the subject 
 *                        line. The weird name is placed in the 
 *                        global variable attach_name.
 */

construct_batch_name()
{
    int i;
    char *sp = message_subject, *bp = attach_name;
    
    if (message_subject[0])
	sp = message_subject;
    else
	sp = "No subject";
    sprintf(bp, ".tar.%d.", getpid());
    bp = &attach_name[strlen(attach_name)];
    for (i = 0; i < 17 && *sp; i++, sp++) {
	if (isalnum(*sp))
	    *bp++ = *sp;
	else
	    *bp++ = '_';
    }
    strcpy(bp, ".attach");
}

/* 
 * check_file_access - make sure all attachments are readable. Print 
 *                     out an error message and increment fatalerrors 
 *                     for each unreadable file
 */

check_file_access()
{
    int i;
    char filename[MAXPATHLEN];
    struct stat stbuf;

    for (i = 0; i < lastattach; i++) {
	sprintf(filename, "%s%s", attachments[i].pathname,
		attachments[i].basename);
	if (access(filename, R_OK)) {
	    perror(filename);
	    fatalerrors++;
	} else if (stat(filename, &stbuf)) {
	    perror(filename);
	    fatalerrors++;
	}
#if 0
	/* 
	 * I'm not sure we want this restriction at all. For one 
	 * thing, NeXT mail allows you to attach directories.
	 * [cap 8/6/92]
	 */
	else if (!(stbuf.st_mode & S_IFREG)) {
	    fprintf(stderr, "Cannot mail %s; can mail only regular files.\n",
		    filename);
	    fatalerrors++;
	}
#endif
    }
}

/* 
 * construct_attach_header -
 *     Make the "Next-Attachment:" line for the mail header. It is 
 *     constructed in static string space, and a pointer to it is 
 *     returned.
 */

char *construct_attach_header()
{
    static char header[128];
    struct stat stbuf;
    long blocks;		/* weird NeXT blocks */

    if (stat(tar_uu_name, &stbuf)) {
	perror(tar_uu_name);
	fatalerrors++;
	return NULL;
    }
    /* 
     * I don't know what the blocks field is used for, but according 
     * to NeXT's specifications, it should be ceil(stbuf.st_size / 48) * 66
     */
    blocks = stbuf.st_size / 48;
    if (stbuf.st_size % 48)
	blocks++;
    blocks *= 66;
    sprintf(header, "Next-Attachment: %s, %ld, 1/1, %ld, 0",
	    attach_name,
	    stbuf.st_size,
	    blocks);
    return header;
}

/* 
 * mail_message - create the headers we add and send the message to 
 *                the mailer.
 */

mail_message(tmpdir_name)
     char tmpdir_name[];
{
    char *attach_header = construct_attach_header();
    char mailcmd[10240];
    char **tp;
    int c;
    FILE *mailpipe, *message;

    strcpy(mailcmd, MAILER);
    for (tp = tolist; *tp != NULL; tp++) {
	strcat(mailcmd, " ");
	strcat(mailcmd, *tp);
    }
#if 0
    fprintf(stderr, "Mail command is \"%s\"\n", mailcmd);
    sprintf(mailcmd, "cat > /tmp/sent_to_mailer");
#endif
    if ((mailpipe = popen(mailcmd, "w")) == NULL) {
	perror(mailcmd);
	fatalerrors++;
	return;
    }
    fprintf(mailpipe, "To:");
    for (tp = tolist; *tp != NULL; tp++)
	fprintf(mailpipe, " %s", *tp);
    if (message_subject[0])
	fprintf(mailpipe, "\nSubject: %s\n", message_subject);
    else
	putc('\n', mailpipe);
    fprintf(mailpipe, "%s\n\n", attach_header);
    if ((message = fopen(tar_uu_name, "r")) == NULL) {
	perror(tar_uu_name);
	pclose(mailpipe);
	fatalerrors++;
	return;
    }
    while ((c = getc(message)) != EOF)
	putc(c, mailpipe);
    fclose(message);
    pclose(mailpipe);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.