struct rfc2045 *rfc2045_searchcontenttype(struct rfc2045 *rfc, const char *ct)
{
	const	char *content_type, *dummy;
	struct rfc2045 *p;

        rfc2045_mimeinfo(rfc, &content_type, &dummy, &dummy);
	if (strcmp(content_type, ct) == 0)
		return (rfc);

	for (p=rfc->firstpart; p; p=p->next)
	{
		if (p->isdummy)	continue;
		rfc2045_mimeinfo(p, &content_type, &dummy, &dummy);
		if (strcmp(content_type, ct) == 0)
			break;
		if (strncmp(content_type, "multipart/", 10) == 0)
			return(rfc2045_searchcontenttype(p, ct));
	}

	return (p);
}
示例#2
0
文件: newmsg.c 项目: MhdAlyan/courier
void newmsg_showfp(FILE *fp, int *attachcnt)
{
	struct	rfc2045 *p=rfc2045_fromfp(fp), *q;

	if (!p)	enomem();

	/* Here's a nice opportunity to count all attachments */

	*attachcnt=0;

	for (q=p->firstpart; q; q=q->next)
		if (!q->isdummy)	++*attachcnt;
	if (*attachcnt)	--*attachcnt;
	/* Not counting the 1st MIME part */

	{
		const char *content_type;
		const char *content_transfer_encoding;
		const char *charset;

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

		if (content_type &&
		    strcmp(content_type, "multipart/alternative") == 0)
			*attachcnt=0;
	}

	q=rfc2045_searchcontenttype(p, "text/plain");

	if (q)
	{
		struct rfc2045src *src=rfc2045src_init_fd(fileno(fp));

		if (src)
		{
			struct show_textarea_info info;

			show_textarea_init(&info, 1);

			rfc2045_decodetextmimesection(src, q,
						      sqwebmail_content_charset,
						      NULL,
						      &show_textarea_trampoline,
						      &info);
			rfc2045src_deinit(src);
			show_textarea(&info, "\n", 1);
		}
	}
	rfc2045_free(p);
}
示例#3
0
文件: sqispell.c 项目: zixia/wmail
static struct rfc2045 *findtext(struct rfc2045 *rfcp)
{
struct rfc2045 *textp;
const char *content_type;
const char *content_transfer_encoding;
const char *charset;

	rfc2045_mimeinfo(rfcp, &content_type,
		&content_transfer_encoding, &charset);
	if (strncmp(content_type, "text/", 5) == 0)
		textp=rfcp;
	else
	{
		for (textp=rfcp->firstpart; textp; textp=textp->next)
		{
			if (textp->isdummy)	continue;
			rfc2045_mimeinfo(textp, &content_type,
				&content_transfer_encoding, &charset);
			if (strncmp(content_type, "text/", 5) == 0)
				break;
		}
	}
	return (textp);
}
int rfc2045_decodetextmimesection(struct rfc2045src *src,
				  struct rfc2045 *rfc,
				  const char *mychset,
				  int *conv_err,
				  int (*handler)(const char *,
						 size_t, void *),
				  void *voidarg)
{
	const char *dummy;
	const char *src_chset;

	libmail_u_convert_handle_t ci;
	int rc;
	int dummy_flag;

	if (!conv_err)
		conv_err= &dummy_flag;

	rfc2045_mimeinfo(rfc, &dummy, &dummy, &src_chset);

	*conv_err=0;

	if ((ci=libmail_u_convert_init(src_chset, mychset, handler, voidarg))
	    == NULL)
	{
		*conv_err=1;
		return -1;
	}

	rc=rfc2045_decodemimesection(src, rfc, &myhandler, &ci);

	dummy_flag=0;
	if (libmail_u_convert_deinit(ci, &dummy_flag))
		rc= -1;

	if (dummy_flag)
		*conv_err=1;
	return (rc);
}
示例#5
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);
}
示例#6
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);
}
示例#7
0
static void dsn(struct rfc2045 *p, int do_orig)
{
const char *content_type_s;
const char *content_transfer_encoding_s;
const char *charset_s;
off_t start_pos, end_pos, start_body;
off_t dummy;
const char *q;
char	buf[BUFSIZ];
unsigned i;
int	ch;
char *recip;
char *action;
char *orecip;

	rfc2045_mimeinfo(p, &content_type_s, &content_transfer_encoding_s,
		&charset_s);
	if (strcasecmp(content_type_s, "multipart/report") ||
		(q=rfc2045_getattr(p->content_type_attr, "report-type")) == 0 ||
		strcasecmp(q, "delivery-status") ||
		!p->firstpart || !p->firstpart->next ||
		!p->firstpart->next->next)
		_exit(1);
	p=p->firstpart->next->next;
	rfc2045_mimeinfo(p, &content_type_s, &content_transfer_encoding_s,
		&charset_s);
	rfc2045_mimepos(p, &start_pos, &end_pos, &start_body, &dummy, &dummy);
	if (strcasecmp(content_type_s, "message/delivery-status") ||
		fseek(stdin, start_body, SEEK_SET) == -1)
		_exit(1);

	i=0;
	recip=0;
	orecip=0;
	action=0;
	while (start_body < end_pos)
	{
		if ((ch=getchar()) == EOF)	break;
		++start_body;
		if (i < sizeof(buf)-1)
			buf[i++]= ch;
		if (ch != '\n')	continue;
		ch=getchar();
		if (ch != EOF)	ungetc(ch, stdin);
		if (ch != '\n' && isspace((int)(unsigned char)ch))
			continue;
		buf[i-1]=0;
		if (buf[0] == 0)
		{
			if (orecip)
			{
				if (recip)	free(recip);
				recip=orecip;
				orecip=0;
			}
			print_dsn_recip(recip, action);
			recip=0;
			action=0;
		}
		if (strncasecmp(buf, "Final-Recipient:", 16) == 0 &&
			recip == 0)
		{
			recip=strdup(buf+16);
			if (!recip)
			{
				perror("strdup");
				exit(2);
			}
		}
		if (strncasecmp(buf, "Original-Recipient:", 19) == 0 &&
			orecip == 0 && do_orig)
		{
			orecip=strdup(buf+19);
			if (!orecip)
			{
				perror("strdup");
				exit(2);
			}
		}
		if (strncasecmp(buf, "Action:", 7) == 0 && action == 0)
		{
			action=strdup(buf+7);
			if (!action)
			{
				perror("strdup");
				exit(2);
			}
		}
		i=0;
	}
	if (orecip)
	{
		if (recip)	free(recip);
		recip=orecip;
		orecip=0;
	}
	print_dsn_recip(recip, action);
}
示例#8
0
static void extract_pipe(struct rfc2045 *p,
	const char *filename,
	int argc, char **argv)
{
char	*f=get_suitable_filename(p, "FILENAME=", 0);
int	pipefd[2];
pid_t	pid, p2;
FILE	*fp;
int	waitstat;

	if (argc == 0)
	{
		fprintf(stderr, "reformime: Invalid -X option.\n");
		exit(1);
	}

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

	if ((fp=fdopen(pipefd[1], "w")) == 0)
	{
		perror("fdopen");
		exit(1);
	}

	while ((pid=fork()) == -1)
	{
		sleep(2);
	}

	if (pid == 0)
	{
        const char *content_type_s;
        const char *content_transfer_encoding_s;
        const char *charset_s;

		if (!f)	f="FILENAME=attachment.dat";
		putenv(f);
		rfc2045_mimeinfo(p, &content_type_s,
			&content_transfer_encoding_s, &charset_s);
		f=malloc(strlen(content_type_s)
			+sizeof("CONTENT_TYPE="));
		if (!f)
		{
			perror("malloc");
			exit(1);
		}
		strcat(strcpy(f, "CONTENT_TYPE="), content_type_s);
		putenv(f);
		close(0);
		dup(pipefd[0]);
		close(pipefd[0]);
		close(pipefd[1]);
		execv(argv[0], argv);
		perror("exec");
		_exit(1);
	}
	close(pipefd[0]);
	signal(SIGPIPE, SIG_IGN);
	do_print_section(p, fp);
	signal(SIGPIPE, SIG_DFL);
	fclose(fp);
	close(pipefd[1]);

	while ((p2=wait(&waitstat)) != pid && p2 != -1)
		;
	free(f);
}
示例#9
0
static char *get_suitable_filename(struct rfc2045 *r, const char *pfix,
	int ignore_filename)
{
const char *disposition_s;
const char *disposition_name_s;
const char *disposition_filename_s;
char	*filename_buf;
const char *content_name_s;
char	*p, *q;
char	*dyn_disp_name=0;

	rfc2045_dispositioninfo(r, &disposition_s, &disposition_name_s,
		&disposition_filename_s);

	content_name_s=rfc2045_contentname(r);

	if (!disposition_filename_s || !*disposition_filename_s)
		disposition_filename_s=disposition_name_s;
	if (!disposition_filename_s || !*disposition_filename_s)
		disposition_filename_s=content_name_s;

	filename_buf=rfc2047_decode_simple(disposition_filename_s);

	if (!filename_buf)
	{
		perror("rfc2047_decode_simple");
		exit(1);
	}

	if (strlen(filename_buf) > 32)
	{
		p=filename_buf;
		q=filename_buf + strlen(filename_buf)-32;
		while ( (*p++ = *q++) != 0)
			;
	}

	disposition_filename_s=filename_buf;

	if (ignore_filename)
	{
	char	numbuf[NUMBUFSIZE];
	static size_t counter=0;
	const char *p=str_size_t(++counter, numbuf);

		dyn_disp_name=malloc(strlen(disposition_filename_s)
			+ strlen(p)+2);
		if (!dyn_disp_name)
		{
			perror("malloc");
			exit(1);
		}
		disposition_filename_s=strcat(strcat(strcpy(
			dyn_disp_name, p), "-"),
			disposition_filename_s);
	}
	else if (!disposition_filename_s || !*disposition_filename_s)
	{
		dyn_disp_name=tempname(".");
		disposition_filename_s=dyn_disp_name+2;	/* Skip over ./ */
	}

	p=malloc((pfix ? strlen(pfix):0)+strlen(disposition_filename_s)+1);
	if (!p)
	{
		perror("malloc");
		exit(1);
	}
	*p=0;
	if (pfix)	strcpy(p, pfix);
	q=p+strlen(p);
	for (strcpy(q, disposition_filename_s); *q; q++)
		if (!isalnum(*q) && *q != '.' && *q != '-')
			*q='_';

	if (dyn_disp_name)	free(dyn_disp_name);

	if (!pfix)
	{
        const char *content_type_s;
        const char *content_transfer_encoding_s;
        const char *charset_s;
	int c;
	static char filenamebuf[256];
	char	*t;
	FILE	*tty;

		if ((tty=fopen("/dev/tty", "r+")) == 0)
		{
			perror("/dev/tty");
			exit(1);
		}

		rfc2045_mimeinfo(r, &content_type_s,
			&content_transfer_encoding_s, &charset_s);

		fprintf (tty, "Extract %s? ", content_type_s);
		fflush(tty);
		c=getc(tty);
		if (c != '\n' && c != EOF)
		{
		int	cc;

			while ((cc=getc(tty)) != '\n' && cc != EOF)
				;
		}
		if (c != 'y' && c != 'Y')
		{
			free(p);
			fclose(tty);
			free(filename_buf);
			return (0);
		}
		fprintf (tty, "Filename [%s]: ", p);
		fgets(filenamebuf, sizeof(filenamebuf)-1, tty);
		fclose(tty);
		t=strchr(filenamebuf, '\n');
		if (t)	*t=0;
		else
		{
			fprintf(stderr, "Filename too long.\n");
			exit(1);
		}
		if (filenamebuf[0])
		{
			free(p);
			p=strdup(filenamebuf);
			if (!p)
			{
				perror("malloc");
				exit(1);
			}
		}
	}
	free(filename_buf);
	return (p);
}
示例#10
0
static void do_print_info(struct rfc2045 *s)
{
const char *content_type, *transfer_encoding, *charset;
off_t start, end, body;
const char *disposition;
const char *disposition_name;
const char *disposition_filename;
const char *content_name;
off_t nlines, nbodylines;
const char *p;

	rfc2045_mimeinfo(s, &content_type, &transfer_encoding, &charset);
	rfc2045_mimepos(s, &start, &end, &body, &nlines, &nbodylines);
	rfc2045_dispositioninfo(s, &disposition, &disposition_name,
		&disposition_filename);
	content_name=rfc2045_contentname(s);
	printf("content-type: %s\n", content_type);
	if (content_name)
	{
	char *s=rfc2047_decode_simple(content_name);

		if (!s)
		{
			perror("rfc2047_decode_simple");
			exit(1);
		}
		printf("content-name: %s\n", s);
		free(s);
	}

	printf("content-transfer-encoding: %s\n", transfer_encoding);
	printf("charset: %s\n", charset);
	if (disposition && *disposition)
		printf("content-disposition: %s\n", disposition);
	if (disposition_name && *disposition_name)
	{
	char *s=rfc2047_decode_simple(disposition_name);

		if (!s)
		{
			perror("rfc2047_decode_simple");
			exit(1);
		}
		printf("content-disposition-name: %s\n", s);
		free(s);
	}

	if (disposition_filename && *disposition_filename)
	{
	char *s=rfc2047_decode_simple(disposition_filename);

		if (!s)
		{
			perror("rfc2047_decode_simple");
			exit(1);
		}
		printf("content-disposition-filename: %s\n", s);
		free(s);
	}

	if (*(p=rfc2045_content_id(s)))
		printf("content-id: <%s>\n", p);
	if (*(p=rfc2045_content_description(s)))
	{
	char *s=rfc2047_decode_simple(p);

		if (!s)
		{
			perror("rfc2047_decode_simple");
			exit(1);
		}
		printf("content-description: %s\n", s);
		free(s);
	}
	if (*(p=rfc2045_content_language(s)))
		printf("content-language: %s\n", p);
	if (*(p=rfc2045_content_md5(s)))
		printf("content-md5: %s\n", p);

	printf("starting-pos: %lu\n", (unsigned long)start);
	printf("starting-pos-body: %lu\n", (unsigned long)body);
	printf("ending-pos: %lu\n", (unsigned long)end);
	printf("line-count: %lu\n", (unsigned long)nlines);
	printf("body-line-count: %lu\n", (unsigned long)nbodylines);
}
示例#11
0
void msgbodystructure( void (*writefunc)(const char *, size_t), int dox,
	FILE *fp, struct rfc2045 *mimep)
{
const char *content_type_s;
const char *content_transfer_encoding_s;
const char *charset_s;
off_t start_pos, end_pos, start_body;
off_t nlines, nbodylines;
const char *disposition_s;

char	*p, *q;

	rfc2045_mimeinfo(mimep, &content_type_s, &content_transfer_encoding_s,
		&charset_s);
	rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
		&nlines, &nbodylines);

	disposition_s=mimep->content_disposition;

	(*writefunc)("(", 1);

	if (mimep->firstpart && mimep->firstpart->isdummy &&
		mimep->firstpart->next)
		/* MULTIPART */
	{
	struct rfc2045	*childp;

		for (childp=mimep->firstpart; (childp=childp->next) != 0; )
			msgbodystructure(writefunc, dox, fp, childp);

		(*writefunc)(" \"", 2);
		p=strchr(content_type_s, '/');
		if (p)
			msgappends(writefunc, p+1, strlen(p+1));
		(*writefunc)("\"", 1);

		if (dox)
		{
			(*writefunc)(" ", 1);
			do_param_list(writefunc, mimep->content_type_attr);

			(*writefunc)(" ", 1);
			do_disposition(writefunc, disposition_s,
				mimep->content_disposition_attr);

			(*writefunc)(" ", 1);
			contentstr(writefunc, rfc2045_content_language(mimep));
		}
	}
	else
	{
	char	*mybuf;
	char	buf[40];
	const	char *cp;

		mybuf=my_strdup(content_type_s);
		q=strtok(mybuf, " /");
		(*writefunc)("\"", 1);
		if (q)
			msgappends(writefunc, q, strlen(q));
		(*writefunc)("\" \"", 3);
		if (q)	q=strtok(0, " /");
		if (q)
			msgappends(writefunc, q, strlen(q));
		free(mybuf);
		(*writefunc)("\" ", 2);

		do_param_list(writefunc, mimep->content_type_attr);

		(*writefunc)(" ", 1);
		cp=rfc2045_content_id(mimep);
		if (!cp || !*cp)
			contentstr(writefunc, cp);
		else
		{
			(*writefunc)("\"<", 2);
			msgappends(writefunc, cp, strlen(cp));
			(*writefunc)(">\"", 2);
		}
		(*writefunc)(" ", 1);
		contentstr(writefunc, rfc2045_content_description(mimep));

		(*writefunc)(" \"", 2);
		msgappends(writefunc, content_transfer_encoding_s,
			strlen(content_transfer_encoding_s));
		(*writefunc)("\" ", 2);

		sprintf(buf, "%lu", (unsigned long)
			(end_pos-start_body+nbodylines));
			/* nbodylines added for CRs */
		(*writefunc)(buf, strlen(buf));

		if (
		(content_type_s[0] == 't' || content_type_s[0] == 'T') &&
		(content_type_s[1] == 'e' || content_type_s[1] == 'E') &&
		(content_type_s[2] == 'x' || content_type_s[2] == 'X') &&
		(content_type_s[3] == 't' || content_type_s[3] == 'T') &&
			(content_type_s[4] == '/' ||
			 content_type_s[4] == 0))
		{
			(*writefunc)(" ", 1);
			sprintf(buf, "%lu", (unsigned long)nbodylines);
			(*writefunc)(buf, strlen(buf));
		}

		if (mimep->firstpart && !mimep->firstpart->isdummy)
			/* message/rfc822 */
		{
			(*writefunc)(" ", 1);
			msgenvelope(writefunc, fp, mimep->firstpart);
			(*writefunc)(" ", 1);
			msgbodystructure(writefunc, dox, fp, mimep->firstpart);
			(*writefunc)(" ", 1);
			sprintf(buf, "%lu", (unsigned long)nbodylines);
			(*writefunc)(buf, strlen(buf));
		}

		if (dox)
		{
			(*writefunc)(" ", 1);
			contentstr(writefunc, rfc2045_content_md5(mimep));

			(*writefunc)(" ", 1);
			do_disposition(writefunc, disposition_s,
				mimep->content_disposition_attr);

			(*writefunc)(" NIL", 4);
				/* TODO Content-Language: */
		}
	}
	(*writefunc)(")", 1);
}
int rfc2045_decodemsgtoutf8(struct rfc2045src *src,
			    struct rfc2045 *p,
			    struct rfc2045_decodemsgtoutf8_cb *callback)
{
	struct rfc2045headerinfo *hi;
	int rc;

	hi=rfc2045header_start(src, p);

	if (hi)
	{
		char *header;
		char *value;

		while (rfc2045header_get(hi, &header, &value,
					 RFC2045H_NOLC |
					 RFC2045H_KEEPNL) == 0 && header)
		{
			if (callback->flags & RFC2045_DECODEMSG_NOHEADERS)
				continue;

			if (doconvtoutf8_rfc822hdr(header, value,
						   callback) < 0)
				return -1;
		}
		rfc2045header_end(hi);
	}

	if (p->firstpart)
	{
		for (p=p->firstpart; p; p=p->next)
		{
			if (!p->isdummy)
			{
				if ((rc=rfc2045_decodemsgtoutf8(src, p,
								callback))
				    != 0)
					return rc;
			}
		}
	}
	else
	{
		const char *content_type;
		const char *transfer_encoding;
		const char *charset;
		struct doconvtoutf8_info info;

		info.callback=callback;

		rfc2045_mimeinfo(p, &content_type, &transfer_encoding,
				 &charset);

		if ((strncmp(content_type, "text/", 5) == 0 ||
		     strncmp(content_type, "message/", 8) == 0) &&
		    (callback->flags & RFC2045_DECODEMSG_NOBODY) == 0 &&
		    (rc=rfc2045_decodetextmimesection(src, p, "utf-8", NULL,
						      decode_handler,
						      &info)) != 0)
			return rc;
	}
	return 0;
}
示例#13
0
文件: fetch.c 项目: MhdAlyan/courier
static void dofetchmsgbody(FILE *fp, struct fetchinfo *fi,
	struct imapscaninfo *i, unsigned long msgnum,
	struct rfc2045 *mimep)
{
const char *p=fi->bodysection;
off_t start_pos, end_pos, start_body;
off_t nlines, nbodylines;
unsigned long cnt;
char	buf[BUFSIZ];
char	rbuf[BUFSIZ];
char	*rbufptr;
int	rbufleft;
unsigned long bufptr;
unsigned long skipping;
int	ismsgrfc822=1;

off_t start_seek_pos;
 struct rfc2045 *headermimep;

/*
** To optimize consecutive FETCHes, we cache our virtual and physical
** position.  What we do is that on the first fetch we count off the
** characters we read, and keep track of both the physical and the CRLF-based
** offset into the message.  Then, on subsequent FETCHes, we attempt to
** use that information.
*/

off_t cnt_virtual_chars;
off_t cnt_phys_chars;

off_t cache_virtual_chars;
off_t cache_phys_chars;

	headermimep=mimep;
 
	while (p && isdigit((int)(unsigned char)*p))
	{
	unsigned long n=0;

		headermimep=mimep;

		do
		{
			n=n*10 + (*p++ - '0');
		} while (isdigit((int)(unsigned char)*p));

		if (mimep)
		{
			if (ismsgrfc822)
			{
				const char *ct, *dummy;

				if (mimep->firstpart == 0)
				{
					/* Not a multipart, n must be 1 */
					if (n != 1)
						mimep=0;
					if (*p == '.')
						++p;
					continue;
				}
				ismsgrfc822=0;

				rfc2045_mimeinfo(mimep, &ct,
						 &dummy,
						 &dummy);

				if (ct && strcasecmp(ct, "message/rfc822"
						     ) == 0)
					ismsgrfc822=1;
				/* The content is another message/rfc822 */
			}

			mimep=mimep->firstpart;
			while (mimep)
			{
				if (!mimep->isdummy && --n == 0)
					break;
				mimep=mimep->next;
			}
			headermimep=mimep;

			if (mimep && mimep->firstpart &&
				!mimep->firstpart->isdummy)
				/* This is a message/rfc822 part */
			{
				if (!*p)
					break;

				mimep=mimep->firstpart;
				ismsgrfc822=1;
			}
		}
		if (*p == '.')
			++p;
	}

	if (p && strcmp(p, "MIME") == 0)
		mimep=headermimep;

	if (mimep == 0)
	{
		writes("{0}\r\n");
		return;
	}

	rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
		&nlines, &nbodylines);


	if (p && strcmp(p, "TEXT") == 0)
	{
		start_seek_pos=start_body;
		cnt=end_pos - start_body + nbodylines;
	}
	else if (p && strcmp(p, "HEADER") == 0)
	{
		start_seek_pos=start_pos;
		cnt= start_body - start_pos + (nlines - nbodylines);
	}
	else if (p && strcmp(p, "HEADER.FIELDS") == 0)
	{
		if (start_body - start_pos <= BUFSIZ)
			dofetchheadersbuf(fp, fi, i, msgnum, mimep,
				&dofetchheaderfields);
		else
			dofetchheadersfile(fp, fi, i, msgnum, mimep,
				&dofetchheaderfields);
		return;
	}
	else if (p && strcmp(p, "HEADER.FIELDS.NOT") == 0)
	{
		if (start_body - start_pos <= BUFSIZ)
			dofetchheadersbuf(fp, fi, i, msgnum, mimep,
				&dofetchheadernotfields);
		else
			dofetchheadersfile(fp, fi, i, msgnum, mimep,
				&dofetchheadernotfields);
		return;
	}
	else if (p && strcmp(p, "MIME") == 0)
	{
		if (start_body - start_pos <= BUFSIZ)
			dofetchheadersbuf(fp, fi, i, msgnum, mimep,
				&dofetchheadermime);
		else
			dofetchheadersfile(fp, fi, i, msgnum, mimep,
				&dofetchheadermime);
		return;
	}
	else if (*fi->bodysection == 0)
	{
		start_seek_pos=start_pos;

		cnt= end_pos - start_pos + nlines;
	}
	else	/* Last possibility: entire body */
	{
		start_seek_pos=start_body;

		cnt= end_pos - start_body + nbodylines;
	}

	skipping=0;
	if (fi->ispartial)
	{
		skipping=fi->partialstart;
		if (skipping > cnt)	skipping=cnt;
		cnt -= skipping;
		if (fi->ispartial > 1 && cnt > fi->partialend)
			cnt=fi->partialend;
	}

	if (get_cached_offsets(start_seek_pos, &cnt_virtual_chars,
			       &cnt_phys_chars) == 0 &&
	    cnt_virtual_chars <= skipping)	/* Yeah - cache it, baby! */
	{
		if (fseek(fp, start_seek_pos+cnt_phys_chars, SEEK_SET) == -1)
		{
			writes("{0}\r\n");
			fetcherror("fseek", fi, i, msgnum);
			return;
		}
		skipping -= cnt_virtual_chars;
	}
	else
	{
		if (fseek(fp, start_seek_pos, SEEK_SET) == -1)
		{
			writes("{0}\r\n");
			fetcherror("fseek", fi, i, msgnum);
			return;
		}

		cnt_virtual_chars=0;
		cnt_phys_chars=0;
	}

	cache_virtual_chars=cnt_virtual_chars;
	cache_phys_chars=cnt_phys_chars;

	writes("{");
	writen(cnt);
	writes("}\r\n");
	bufptr=0;
	writeflush();

	rbufptr=0;
	rbufleft=0;

	while (cnt)
	{
	int	c;

		if (!rbufleft)
		{
			rbufleft=fread(rbuf, 1, sizeof(rbuf), fp);
			if (rbufleft < 0)	rbufleft=0;
			rbufptr=rbuf;
		}

		if (!rbufleft)
		{
			fetcherror("unexpected EOF", fi, i, msgnum);
			_exit(1);
		}

		--rbufleft;
		c=(int)(unsigned char)*rbufptr++;
		++cnt_phys_chars;

		if (c == '\n')
		{
			++cnt_virtual_chars;

			if (skipping)
				--skipping;
			else
			{
				if (bufptr >= sizeof(buf))
				{
					writemem(buf, sizeof(buf));
					bufptr=0;
					/*writeflush();*/
				}
				buf[bufptr++]='\r';
				--cnt;

				if (cnt == 0)
					break;
			}
		}

		++cnt_virtual_chars;
		if (skipping)
			--skipping;
		else
		{
			++body_count;

			if (bufptr >= sizeof(buf))
			{
				writemem(buf, sizeof(buf));
				bufptr=0;
				/*writeflush();*/
			}
			buf[bufptr++]=c;
			--cnt;
		}
		cache_virtual_chars=cnt_virtual_chars;
		cache_phys_chars=cnt_phys_chars;
	}
	writemem(buf, bufptr);
	writeflush();
	save_cached_offsets(start_seek_pos, cache_virtual_chars,
			    cache_phys_chars);
}