Ejemplo n.º 1
0
int main(int argc, char **argv)
{
	int argn;
	FILE *tmpfp;
	struct rfc2045 *rfcp;
	struct mimeautoreply_s replyinfo;
	const char *subj=0;
	const char *txtfile=0, *mimefile=0;
	const char *mimedsn=0;
	int nosend=0;
	const char *replymode="reply";
	int replytoenvelope=0;
	int donotquote=0;
	const char *forwardsep="--- Forwarded message ---";
	const char *replysalut="%F writes:";
	struct rfc2045src *src;

	setlocale(LC_ALL, "");
	charset=unicode_default_chset();

	sender=NULL;
	for (argn=1; argn < argc; argn++)
	{
		char optc;
		char *optarg;

		if (argv[argn][0] != '-')
			break;

		if (strcmp(argv[argn], "--") == 0)
		{
			++argn;
			break;
		}

		optc=argv[argn][1];
		optarg=argv[argn]+2;

		if (!*optarg)
			optarg=NULL;

		switch (optc) {
		case 'c':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			if (optarg && *optarg)
			{
				char *p=libmail_u_convert_tobuf("",
								optarg,
								libmail_u_ucs4_native,
								NULL);

				if (!p)
				{
					fprintf(stderr, "Unknown charset: %s\n",
						charset);
					exit(1);
				}
				free(p);
				charset=optarg;
			}
			continue;
		case 't':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			txtfile=optarg;
			continue;
		case 'm':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			mimefile=optarg;
			continue;
		case 'r':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			recips=optarg;
			continue;
		case 'M':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			mimedsn=optarg;
			continue;
		case 'd':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			dbfile=optarg;
			continue;
		case 'e':
			replytoenvelope=1;
			continue;
		case 'T':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			if (optarg && *optarg)
				replymode=optarg;
			continue;
		case 'N':
			donotquote=1;
			continue;
		case 'F':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			if (optarg && *optarg)
				forwardsep=optarg;
			continue;
		case 'S':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			if (optarg && *optarg)
				replysalut=optarg;
			continue;
		case 'D':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			interval=optarg ? atoi(optarg):1;
			continue;
		case 'A':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			if (optarg)
			{
				struct header **h;

				for (h= &extra_headers; *h;
				     h= &(*h)->next)
					;

				if ((*h=malloc(sizeof(struct header))) == 0 ||
				    ((*h)->buf=strdup(optarg)) == 0)
				{
					perror("malloc");
					exit(EX_TEMPFAIL);
				}
				(*h)->next=0;
			}
			continue;
		case 's':
			if (!optarg && argn+1 < argc)
				optarg=argv[++argn];

			subj=optarg;
			continue;

		case 'f':
			if (optarg && *optarg)
			{
				sender=strdup(optarg);
			}
			else
			{
				sender=getenv("SENDER");
				if (!sender)
					continue;
				sender=strdup(sender);
			}
			if (sender == NULL)
			{
				perror("malloc");
				exit(1);
			}
			continue;
		case 'n':
			nosend=1;
			continue;
		default:
			usage();
		}
	}

	if (!txtfile && !mimefile)
		usage();

	if (txtfile && mimefile)
		usage();

	tmpfp=tmpfile();

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

	rfcp=savemessage(tmpfp);

	if (fseek(tmpfp, 0L, SEEK_SET) < 0)
	{
		perror("fseek(tempfile)");
		exit(1);
	}

	read_headers(tmpfp);

	if (sender == NULL || *sender == 0)
		check_sender();

	check_dsn();
	check_recips();
#ifdef DbObj
	check_db();
#endif

	src=rfc2045src_init_fd(fileno(tmpfp));

	memset(&replyinfo, 0, sizeof(replyinfo));

	replyinfo.info.src=src;
	replyinfo.info.rfc2045partp=rfcp;
	replyinfo.info.voidarg=&replyinfo;

	replyinfo.info.write_func=mimeautoreply_write_func;

	replyinfo.info.writesig_func=mimeautoreply_writesig_func;

	replyinfo.info.myaddr_func=mimeautoreply_myaddr_func;

	replyinfo.info.replymode=replymode;
	replyinfo.info.replytoenvelope=replytoenvelope;
	replyinfo.info.donotquote=donotquote;

	replyinfo.info.replysalut=replysalut;
	replyinfo.info.forwarddescr="Forwarded message";
	replyinfo.info.mailinglists="";
	replyinfo.info.charset=charset;
	replyinfo.info.subject=subj;
	replyinfo.info.forwardsep=forwardsep;

	if (mimedsn && *mimedsn)
	{
		replyinfo.info.dsnfrom=mimedsn;
		replyinfo.info.replymode="replydsn";
	}

	if (mimefile)
	{
		if ((replyinfo.contentf=fopen(mimefile, "r")) == NULL)
		{
			perror(mimefile);
			exit(1);
		}

		{
			struct rfc2045 *rfcp=rfc2045_alloc();
			static const char mv[]="Mime-Version: 1.0\n";
			char buf[BUFSIZ];
			int l;
			const char *content_type;
			const char *content_transfer_encoding;
			const char *charset;

			rfc2045_parse(rfcp, mv, sizeof(mv)-1);

			while ((l=fread(buf, 1, sizeof(buf), replyinfo.contentf)
				) > 0)
			{
				rfc2045_parse(rfcp, buf, l);
			}

			if (l < 0 ||
			    fseek(replyinfo.contentf, 0L, SEEK_SET) < 0)
			{
				perror(mimefile);
				exit(1);
			}

			rfc2045_mimeinfo(rfcp, &content_type,
					 &content_transfer_encoding,
					 &charset);

			if (strcasecmp(content_type, "text/plain"))
			{
				fprintf(stderr,
					"%s must specify text/plain MIME type\n",
					mimefile);
				exit(1);
			}
			{
				char *p=NULL;

				if (charset)
					p=libmail_u_convert_tobuf("",
								  charset,
								  libmail_u_ucs4_native,
								  NULL);

				if (!p)
				{
					fprintf(stderr, "Unknown charset in %s\n",
						mimefile);
					exit(1);
				}
				free(p);
				replyinfo.info.charset=strdup(charset);
			}
			rfc2045_free(rfcp);
		}
		replyinfo.info.content_set_charset=copy_headers;
		replyinfo.info.content_specify=copy_body;
	}
	else if (txtfile)
	{
		if ((replyinfo.contentf=fopen(txtfile, "r")) == NULL)
		{
			perror(mimefile);
			exit(1);
		}
		replyinfo.info.content_specify=copy_body;
	}

	if (replyinfo.contentf)
		fcntl(fileno(replyinfo.contentf), F_SETFD, FD_CLOEXEC);

	if (nosend)
		replyinfo.outf=stdout;
	else
	{
		replyinfo.outf=tmpfile();

		if (replyinfo.outf == NULL)
		{
			perror("tmpfile");
			exit(1);
		}
	}

	{
		struct header *h;

		for (h=extra_headers; h; h=h->next)
			fprintf(replyinfo.outf, "%s\n", h->buf);
	}
	fprintf(replyinfo.outf,
		"Precedence: junk\n"
		"Auto-Submitted: auto-replied\n");

	if (rfc2045_makereply(&replyinfo.info) < 0 ||
	    fflush(replyinfo.outf) < 0 || ferror(replyinfo.outf) ||
	    (!nosend &&
	     (
	      fseek(replyinfo.outf, 0L, SEEK_SET) < 0 ||
	      (close(0), dup(fileno(replyinfo.outf))) < 0)
	     ))
	{
		perror("tempfile");
		exit(1);
	}
	fclose(replyinfo.outf);
	fcntl(0, F_SETFD, 0);

	rfc2045_free(rfcp);
	rfc2045src_deinit(src);

	if (!nosend)
		opensendmail(argn, argc, argv);
	return (0);
}
Ejemplo n.º 2
0
char *newmsg_newdraft(const char *folder, const char *pos,
			const char *forwardsep, const char *replysalut)
{
char	*filename=0;
char	*replymode;
size_t	pos_n;
FILE	*fp;

const	char *mimeidptr;
char	*draftfilename;
struct	rfc2045 *rfc2045p, *rfc2045partp;
int	x;

	if (*cgi(replymode="reply") ||
		*cgi(replymode="replyall") ||
		*cgi(replymode="replylist") ||
		*cgi(replymode="forward") ||
		*cgi(replymode="forwardatt"))
	{
		pos_n=atol(pos);

		filename=get_msgfilename(folder, &pos_n);
	}

	if (!filename)	return (0);

	fp=0;
	x=maildir_semisafeopen(filename, O_RDONLY, 0);

	if (x >= 0)
		if ((fp=fdopen(x, "r")) == 0)
			close(x);

	if (fp == 0)
	{
		free(filename);
		return (0);
	}

	rfc2045p=rfc2045_fromfp(fp);

	if (!rfc2045p)
	{
		fclose(fp);
		enomem();
	}

	mimeidptr=cgi("mimeid");

	rfc2045partp=0;

	if (*mimeidptr)
	{
		rfc2045partp=rfc2045_find(rfc2045p, mimeidptr);
		if (rfc2045partp)
		{
		const char      *content_type, *dummy;

			rfc2045_mimeinfo(rfc2045partp, &content_type,
				&dummy, &dummy);

			if (!content_type || strcmp(content_type, "message/rfc822"))
				rfc2045partp=0;
			else
				rfc2045partp=rfc2045partp->firstpart;
		}
	}

	if (!rfc2045partp)
		rfc2045partp=rfc2045p;


	draftfd=maildir_createmsg(DRAFTS, 0, &draftfilename);
	if (draftfd < 0)
	{
		fclose(fp);
		rfc2045_free(rfc2045p);
		enomem();
	}

	maildir_writemsgstr(draftfd, "From: ");
	{
	const char *f=pref_from;

		if (!f || !*f)	f=login_fromhdr();
		if (!f)	f="";
		maildir_writemsgstr(draftfd, f);
		maildir_writemsgstr(draftfd, "\n");
	}

	{
		char *ml=getmailinglists();
		struct rfc2045_mkreplyinfo ri;
		int rc;

		memset(&ri, 0, sizeof(ri));
		ri.fd=fileno(fp);
		ri.rfc2045partp=rfc2045partp;
		ri.replymode=replymode;
		ri.replysalut=replysalut;
		ri.forwardsep=forwardsep;
		ri.myaddr_func=ismyaddr;
		ri.write_func=writefunc;
		ri.writesig_func=newmsg_writesig;
		ri.mailinglists=ml;
		ri.charset=sqwebmail_content_charset;

		if (strcmp(replymode, "forward") == 0
		    || strcmp(replymode, "forwardatt") == 0)
		{
#if	HAVE_SQWEBMAIL_UNICODE
			rc=rfc2045_makereply_unicode(&ri);
#else
			rc=rfc2045_makereply(&ri);
#endif
		}
		else
		{
		char *basename=maildir_basename(filename);

			maildir_writemsgstr(draftfd, "X-Reply-To-Folder: ");
			maildir_writemsgstr(draftfd, folder);
			maildir_writemsgstr(draftfd, "\nX-Reply-To-Msg: ");

			maildir_writemsgstr(draftfd, basename);
			free(basename);
			maildir_writemsgstr(draftfd, "\n");

#if	HAVE_SQWEBMAIL_UNICODE
			rc=rfc2045_makereply_unicode(&ri);
#else
			rc=rfc2045_makereply(&ri);
#endif
		}
		free(ml);

		if (rc)
		{
			fclose(fp);
			close(draftfd);
			rfc2045_free(rfc2045p);
			enomem();
		}
	}

	fclose(fp);
	if (maildir_closemsg(draftfd, DRAFTS, draftfilename, 1, 0))
	{
		free(draftfilename);
		draftfilename=0;
		cgi_put("error", "quota");
	}
	free(filename);
	rfc2045_free(rfc2045p);
	return(draftfilename);
}