Example #1
0
int main()
{
struct	rfc822t *t1, *t2, *t3, *t4;
struct	rfc822a *a1, *a2, *a3, *a4;

	t1=tokenize("[email protected] (Nobody (is) here\\) right)");
	t2=tokenize("Distribution  list: [email protected] [email protected]");
	t3=tokenize("Mr Nobody <*****@*****.**>, Mr. Nobody <*****@*****.**>");
	t4=tokenize("[email protected], <*****@*****.**>, Mr. Nobody <*****@*****.**>");

	a1=doaddr(t1);
	a2=doaddr(t2);
	a3=doaddr(t3);
	a4=doaddr(t4);

	rfc822a_free(a4);
	rfc822a_free(a3);
	rfc822a_free(a2);
	rfc822a_free(a1);
	rfc822t_free(t4);
	rfc822t_free(t3);
	rfc822t_free(t2);
	rfc822t_free(t1);
	return (0);
}
Example #2
0
static void check_recips()
{
	char *buf;
	struct rfc822t *t;
	struct rfc822a *a;
	struct header *h;

	if (!recips || !*recips)
		return;

	buf=strdup(recips);
	if (!buf)
	{
		perror("strdup");
		exit(EX_TEMPFAIL);
	}

	for (h=header_list; h; h=h->next)
	{
		int i;

		if (strncasecmp(h->buf, "to:", 3) &&
		    strncasecmp(h->buf, "cc:", 3))
			continue;

		t=rfc822t_alloc_new(h->buf+3, NULL, NULL);
		if (!t || !(a=rfc822a_alloc(t)))
		{
			perror("malloc");
			exit(EX_TEMPFAIL);
		}

		for (i=0; i<a->naddrs; i++)
		{
			char *p=rfc822_getaddr(a, i);
			char *q;

			strcpy(buf, recips);

			for (q=buf; (q=strtok(q, ", ")) != 0; q=0)
			{
				if (p && strcasecmp(p, q) == 0)
				{
					free(p);
					free(buf);
					rfc822a_free(a);
					rfc822t_free(t);
					return;
				}
			}

			free(p);
		}
		rfc822a_free(a);
		rfc822t_free(t);
	}
	free(buf);
	exit(0);
}
Example #3
0
static int knownkey(const char *shortname, const char *known_keys)
{
	struct rfc822t *t=rfc822t_alloc_new(shortname, NULL, NULL);
	struct rfc822a *a;
	int i;

	if (!t)
		return (0);

	a=rfc822a_alloc(t);

	if (!a)
	{
		rfc822t_free(t);
		return (0);
	}

	for (i=0; i<a->naddrs; i++)
	{
		char *p=rfc822_getaddr(a, i);
		int plen;
		const char *q;

		if (!p)
			continue;

		if (!*p)
		{
			free(p);
			continue;
		}

		plen=strlen(p);

		for (q=known_keys; *q; )
		{
			if (strncasecmp(q, p, plen) == 0 && q[plen] == '\n')
			{
				free(p);
				rfc822a_free(a);
				rfc822t_free(t);
				return (1);
			}

			while (*q)
				if (*q++ == '\n')
					break;
		}
		free(p);
	}
	rfc822a_free(a);
	rfc822t_free(t);
	return (0);
}
Example #4
0
static void check_sender()
{
	const char *h=hdr("reply-to");
	struct rfc822t *t;
	struct rfc822a *a;

	if (!h || !*h)
		h=hdr("from");

	if (!h || !*h)
		exit(0);

	t=rfc822t_alloc_new(h, NULL, NULL);

	if (!t || !(a=rfc822a_alloc(t)))
	{
		perror("malloc");
		exit(EX_TEMPFAIL);
	}

	if (a->naddrs <= 0)
		exit (0);
	sender=rfc822_getaddr(a, 0);
	rfc822a_free(a);
	rfc822t_free(t);

	if (!sender || !*sender)
		exit(0);
}
Example #5
0
char *rfc2045_related_start(const struct rfc2045 *p)
{
const char *cb=rfc2045_getattr( p->content_type_attr, "start");
struct	rfc822t *t;
struct	rfc822a	*a;
int	i;

	if (!cb || !*cb)	return (0);

	t=rfc822t_alloc_new(cb, 0, NULL);
	if (!t)
	{
		rfc2045_enomem();
		return(0);
	}

	a=rfc822a_alloc(t);
	if (!a)
	{
		rfc822t_free(t);
		rfc2045_enomem();
		return (0);
	}
	for (i=0; i<a->naddrs; i++)
		if (a->addrs[i].tokens)
		{
		char	*s=rfc822_getaddr(a, i);

			rfc822a_free(a);
			rfc822t_free(t);
			if (!s)
				rfc2045_enomem();
			return (s);
		}

	rfc822a_free(a);
	rfc822t_free(t);
	return (0);
}
Example #6
0
drvinfo *msgq::getdelinfo(struct rfc822token *sendert,
			  const char *receipient, std::string &host,
			  std::string &addr, std::string &errmsg)
{
	struct getdelinfo_struct gdis(0, host, addr);
	struct	rw_info	rwi;
	struct rfc822t *rfcp=rw_rewrite_tokenize(receipient);

	rw_info_init(&rwi, rfcp->tokens, gdi_err_func);
	rwi.sender=sendert;
	rwi.mode=RW_OUTPUT|RW_ENVRECIPIENT;
	rwi.udata= (void *)&gdis;
	rw_searchdel(&rwi, &found_module);
	rfc822t_free(rfcp);
	if (!gdis.drvinfop && gdis.errmsg.size() == 0)
		gdis.errmsg="550 User unknown.";
	errmsg=gdis.errmsg;
	return (gdis.drvinfop);

}
Example #7
0
static void newmsg_header_rfc822(const char *label, const char *field,
				 const char *encoded, const char *val,
				 int is_readonly)
{
int		hdrmaxlen=512;
const char	*p=getarg("HDRMAXLEN");

	if (p && (atoi(p) > hdrmaxlen))
		hdrmaxlen=atoi(p);

	printf("<tr><th align=\"right\"><p class=\"new-message-header\">"
	       "<span class=\"new-message-header-%s\">%s</span></p></th>"
	       "<td width=\"6\">&nbsp;</td>",
	       field, label);

	printf("<td><input type=\"text\" name=\"%s\" size=\"50\" maxlength=\"%d\""
	       " class=\"new-message-header-text\" value=\"",
		field, hdrmaxlen);
	if (encoded)
	{
		struct rfc822t *t=rfc822t_alloc_new(encoded, NULL, NULL);
		struct rfc822a *a=t ? rfc822a_alloc(t):NULL;

		if (a)
		{
			rfc2047_print_unicodeaddr(a, sqwebmail_content_charset,
						  printc,
						  printsep, NULL);
			rfc822a_free(a);
		}

		if (t)
			rfc822t_free(t);
	}
	else if (val)
		output_attrencoded(val);
	printf("\"%s /></td></tr>\n",
		is_readonly ? " readonly=\"readonly\"":"");
}
Example #8
0
File: newmsg.c Project: zixia/wmail
char *newmsg_alladdrs(FILE *fp)
{
	char	*headers=NULL;
	struct rfc822t *t;
	struct rfc822a *a;
	char *p, *q;
	int l, i;

	if (fp)
	{
		char *header, *value;

		rewind(fp);

		/* First, combine all the headers into one header. */

		while ((header=maildir_readheader(fp, &value, 1)) != 0)
		{
			char *newh;

			if (strcmp(header, "from") &&
			    strcmp(header, "to") &&
			    strcmp(header, "cc") &&
			    strcmp(header, "bcc"))
				continue;

			if (headers)
			{
				newh=realloc(headers, strlen(headers)
					     +strlen(value)+2);
				if (!newh)
					continue;
				strcat(newh, ",");
				headers=newh;
			}
			else
			{
				newh=malloc(strlen(value)+1);
				if (!newh)
					continue;
				*newh=0;
				headers=newh;
			}
			strcat(headers, value);
		}

	}

	/* Now, parse the header, and extract the addresses */

	t=rfc822t_alloc_new(headers ? headers:"", NULL, NULL);
	a= t ? rfc822a_alloc(t):NULL;

	l=1;
	for (i=0; i < (a ? a->naddrs:0); i++)
	{
		p=rfc822_getaddr(a, i);
		if (p)
		{
			++l;
			l +=strlen(p);
			free(p);
		}
	}
	p=malloc(l);
	if (p)
		*p=0;

	for (i=0; i < (a ? a->naddrs:0); i++)
	{
		q=rfc822_getaddr(a, i);
		if (q)
		{
			if (p)
			{
				strcat(strcat(p, q), "\n");
			}
			free(q);
		}
	}

	rfc822a_free(a);
	rfc822t_free(t);
	free(headers);
	return (p);
}
Example #9
0
static void doenva(void (*writefunc)(const char *, size_t), char *s)
{
struct rfc822t *t;
struct rfc822a *a;
int	i;
char	*q, *r;

	if (!s)
	{
		(*writefunc)("NIL", 3);
		return;
	}

	t=rfc822t_alloc_new(s, 0, 0);
	if (!t)
	{
		perror("malloc");
		exit(0);
	}
	a=rfc822a_alloc(t);
	if (!a)
	{
		perror("malloc");
		exit(1);
	}

	if (a->naddrs == 0)
	{
		rfc822a_free(a);
		rfc822t_free(t);
		free(s);
		(*writefunc)("NIL", 3);
		return;
	}

	(*writefunc)("(", 1);
	for (i=0; i<a->naddrs; i++)
	{
		(*writefunc)("(", 1);

		q=rfc822_display_name_tobuf(a, i, NULL);

		if (!q)
		{
			perror("malloc");
			exit(1);
		}
		if (a->addrs[i].tokens == 0)
		{
			if (strcmp(q, ";") == 0)
			{
				(*writefunc)("NIL NIL NIL NIL)", 16);
				free(q);
				continue;
			}
			r=strrchr(q, ':');
			if (r && r[1] == 0)	*r=0;

			(*writefunc)("NIL NIL \"", 9);
			msgappends(writefunc, q, strlen(q));
			(*writefunc)("\" NIL)", 6);
			free(q);
			continue;
		}

		if (a->addrs[i].name == 0)
			*q=0;
		/* rfc822_display_name_tobuf() defaults to addr, ignore. */

		doenvs(writefunc, q);
		(*writefunc)(" NIL \"", 6);	/* TODO @domain list */
		q=rfc822_gettok(a->addrs[i].tokens);
		if (!q)
		{
			perror("malloc");
			exit(1);
		}
		r=strrchr(q, '@');
		if (r)	*r++=0;
		msgappends(writefunc, q, strlen(q));
		(*writefunc)("\" \"", 3);
		if (r)
			msgappends(writefunc, r, strlen(r));
		(*writefunc)("\")", 2);
		free(q);
	}
	(*writefunc)(")", 1);
	rfc822a_free(a);
	rfc822t_free(t);
	free(s);
}
Example #10
0
static char *rewrite_from(const char *oldfrom, const char *newuser,
	const char *newhost, const char *newname)
{
struct rfc822t *rfct;
struct rfc822a *rfca;
struct rfc822t *usert, *hostt, *namet;
struct rfc822token attoken, **tp;
char	*p;
const char *q;
char	*gecosname=0;

	if (!oldfrom)
	{
	char	*p=courier_malloc(
			(newuser ? strlen(newuser):0)+
			(newhost ? strlen(newhost):0)+4);
		strcpy(p, "<");
		if (newuser)	strcat(p, newuser);
		if (newuser && newhost)
			strcat(strcat(p, "@"), newhost);
		strcat(p, ">");
		if (newname)
		{
		char *q, *r;

			namet=tokenize_name(newname);
			q=rfc822_gettok(namet->tokens);
			rfc822t_free(namet);
			r=courier_malloc(strlen(p)+strlen(q)+2);
			strcat(strcat(strcpy(r, q), " "), p);
			free(p);
			p=r;
			free(q);
		}
		return (p);
	}

	if ((rfct=rfc822t_alloc_new(oldfrom, NULL, NULL)) == 0 ||
		(rfca=rfc822a_alloc(rfct)) == 0)
	{
		clog_msg_errno();
		return(0);
	}

	if ((q=env("MAILNAME")) || (q=env("NAME")))
		newname=q;

	if (!newname && rfca->naddrs == 0)
		newname=gecosname=get_gecos();

	if ((rfca->naddrs == 0 || rfca->addrs[0].tokens == 0) && newuser == 0)
	{
	struct	passwd *pw=mypwd();

		if (pw)	newuser=pw->pw_name;
	}

	namet=newname ? tokenize_name(newname):0;
	usert=newuser ? rw_rewrite_tokenize(newuser):0;
	hostt=newhost ? rw_rewrite_tokenize(newhost):0;

	if (rfca->naddrs == 0 || rfca->addrs[0].tokens == 0)
	{
	struct rfc822addr a;
	struct rfc822a	fakea;

		if (hostt)
		{
		struct rfc822token *t;

			attoken.token='@';
			attoken.next=hostt->tokens;
			attoken.ptr=0;
			attoken.len=0;

			for (t=usert->tokens; t->next; t=t->next)
				;
			t->next=&attoken;
		}
		fakea.naddrs=1;
		fakea.addrs= &a;

		if (!namet)	namet=tokenize_name("");
		if (!usert)	usert=rw_rewrite_tokenize("");
		a.name=namet->tokens;
		a.tokens=usert->tokens;
		p=rfc822_getaddrs(&fakea);
	}
	else
	{
	struct	rfc822token *t, *u;

		rfca->naddrs=1;
		if (usert)
		{
			for (t=rfca->addrs[0].tokens; t; t=t->next)
				if (t->token == '@')	break;
			
			for (u=usert->tokens; u->next; u=u->next)
				;
			u->next=t;
			rfca->addrs[0].tokens=usert->tokens;;
		}

		if (hostt && rfca->addrs[0].tokens)
		{
			for (tp= &rfca->addrs[0].tokens; *tp;
				tp= &(*tp)->next)
				if ( (*tp)->token == '@')	break;
			*tp=&attoken;
			attoken.token='@';
			attoken.next=hostt->tokens;
			attoken.ptr=0;
			attoken.len=0;
		}
		if (namet)
			rfca->addrs[0].name=namet->tokens;

		p=rfc822_getaddrs(rfca);
	}

	if (!p)	clog_msg_errno();

	if (usert)	rfc822t_free(usert);
	if (hostt)	rfc822t_free(hostt);
	if (namet)	rfc822t_free(namet);
	rfc822t_free(rfct);
	rfc822a_free(rfca);
	if (gecosname)	free(gecosname);
	return (p);
}
Example #11
0
static void do_header(struct rfc2045 *p)
{
struct rfc822t *header;
char	*t;

	if (p->headerlen == 0)	return;
	rfc2045_add_buf( &p->header, &p->headersize, &p->headerlen, "", 1);
				/* 0 terminate */

	/* Parse the header line according to RFC822 */

	header=rfc822t_alloc_new(p->header, NULL, NULL);

	if (!header)	return;	/* Broken header */

	if (header->ntokens < 2 ||
		header->tokens[0].token ||
		header->tokens[1].token != ':')
	{
		rfc822t_free(header);
		return;	/* Broken header */
	}

	t=lower_paste_token(header, 0);

	if (t == 0)
		;
	else if (strcmp(t, "mime-version") == 0)
	{
		free(t);
		mime_version(p, header);
	}
	else if (strcmp(t, "content-type") == 0)
	{
		free(t);
		content_type(p, header);
	} else if (strcmp(t, "content-transfer-encoding") == 0)
	{
		free(t);
		content_transfer_encoding(p, header);
	} else if (strcmp(t, "content-disposition") == 0)
	{
		free(t);
		content_disposition(p, header);
	} else if (strcmp(t, "content-id") == 0)
	{
		free(t);
		content_id(p, header);
	} else if (strcmp(t, "content-description") == 0)
	{
		free(t);
		t=strchr(p->header, ':');
		if (t)	++t;
		while (t && isspace((int)(unsigned char)*t))
			++t;
		content_description(p, t);
	} else if (strcmp(t, "content-language") == 0)
	{
		free(t);
		t=strchr(p->header, ':');
		if (t)	++t;
		while (t && isspace((int)(unsigned char)*t))
			++t;
		content_language(p, t);
	} else if (strcmp(t, "content-base") == 0)
	{
		free(t);
		content_base(p, header);
	} else if (strcmp(t, "content-location") == 0)
	{
		free(t);
		content_location(p, header);
	} else if (strcmp(t, "content-md5") == 0)
	{
		free(t);
		t=strchr(p->header, ':');
		if (t)	++t;
		while (t && isspace((int)(unsigned char)*t))
			++t;
		content_md5(p, t);
	}
	else	free(t);
	rfc822t_free(header);
}
Example #12
0
static void dodel(const char *username, const char *userhome,
	FILE *c, char *ctl,
	const char *extension, const char *sender, const char *receipient,
	const char *defaultext, const char *quota, const char *defaultmail,
	int recursion_level)
{
char	*ufromline;
char	*dtline;
char	*rpline;
time_t	t;
const char *curtime;

	time(&t);
	curtime=ctime(&t);
	if ((ufromline=malloc(strlen(curtime)+strlen(sender)+30))==0||
		(dtline=malloc(strlen(receipient)+
			sizeof("Delivered-To: "))) == 0 ||
		(rpline=malloc(strlen(sender) +
			sizeof("Return-Path: <>"))) == 0)
	{
		perror("malloc");
		exit(EX_TEMPFAIL);
	}

	if ( (!ctl || !*ctl) && recursion_level == 0)
	{
	const char *p= *defaultmail ? defaultmail:config_defaultdelivery();

		if ((ctl=malloc(strlen(p)+1)) == 0)
		{
			perror("malloc");
			exit(EX_TEMPFAIL);
		}
		strcpy(ctl, p);
	}

	sprintf(ufromline, "From %s %s", sender, curtime);

	{
	char *p;

		if ((p=strchr(ufromline, '\n')) != 0)
			*p=0;
	}

	strcat(strcpy(dtline, "Delivered-To: "), receipient);
	strcat(strcat(strcpy(rpline, "Return-Path: <"), sender), ">");

	while (*ctl)
	{
		if (*ctl == '#' || *ctl == '\n')
		{
			while (*ctl)
				if (*ctl++ == '\n')	break;
			continue;
		}

		/*
		** The fd hack is needed for BSD, whose C lib doesn't like
		** mixing stdio and unistd seek calls.
		*/

		if (*ctl == '.' || *ctl == '/')
		{
		const char *filename=ctl;
		int fd_hack=dup(fileno(stdin));
		FILE *fp_hack;

			if (fd_hack < 0 || lseek(fd_hack, 0L, SEEK_SET) < 0 ||
				(fp_hack=fdopen(fd_hack, "r")) == NULL)
			{
				perror("dup");
				exit(EX_TEMPFAIL);
			}

			while (*ctl)
			{
				if (*ctl == '/' && (ctl[1] == '\n' ||
					ctl[1] == 0))
					*ctl=0; /* Strip trailing / */
				if (*ctl == '\n')
				{
					*ctl++='\0';
					break;
				}
				++ctl;
			}

			if (savemessage(extension, sender, receipient,
				fp_hack, filename,
				ufromline,
				dtline,
				rpline, quota))
				exit(EX_TEMPFAIL);
			fclose(fp_hack);
			close(fd_hack);
			continue;
		}
		if (*ctl == '|')
		{
		const char *command=++ctl;
		int	rc;
		int fd_hack=dup(fileno(stdin));
		FILE *fp_hack;

			if (fd_hack < 0 || lseek(fd_hack, 0L, SEEK_SET) < 0 ||
				(fp_hack=fdopen(fd_hack, "r")) == NULL)
			{
				perror("dup");
				exit(EX_TEMPFAIL);
			}

			ctl=skip_eol(ctl, 0);
			while (*command == ' ' || *command == '\t')
				++command;

			rc=docommand(extension, sender, receipient, defaultext,
				fp_hack, username, userhome, command,
				dtline,
				rpline,
				ufromline,
				quota, defaultmail,
				recursion_level);
			if (rc)
				exit(rc);
			fclose(fp_hack);
			close(fd_hack);
			continue;
		}

		/* Forwarding instructions, parse RFC822 addresses */

		if (*ctl == '&' || *ctl == '!')	++ctl;	/* Legacy */
		{
			const char *addresses=ctl;
			struct rfc822t *tokens;
			struct rfc822a *addrlist;
			int n;

			ctl=skip_eol(ctl, 1);
			if ((tokens=rfc822t_alloc_new(addresses, NULL,
						      NULL)) == 0 ||
				(addrlist=rfc822a_alloc(tokens)) == 0)
			{
				perror("malloc");
				exit(EX_TEMPFAIL);
			}

			for (n=0; n<addrlist->naddrs; ++n)
			{
				char *p;

				if (addrlist->addrs[n].tokens == NULL)
					continue;

				p=rfc822_display_addr_tobuf(addrlist, n,
							    NULL);

				if (!p)
				{
					perror(addresses);
					exit(EX_TEMPFAIL);
				}

				printf("%s\n", p);
				free(p);
			}
			rfc822a_free(addrlist);
			rfc822t_free(tokens);
			fflush(stdout);
		}
	}
			
	free(rpline);
	free(dtline);
	free(ufromline);
}
Example #13
0
int msgq::queuescan3(std::string subdir, std::string name,
		     const char *isnewmsg)
{
	struct ctlfile	ctlinfo;
	ino_t	inum;
	time_t	deltime, delsendtime;
	const char *p=name.c_str();
	struct	stat	stat_buf;

	++p;
	inum=strtoino(p);
	while (isdigit(*p))	p++;
	++p;
	deltime=strtotime(p);
	name= subdir + '/' + name;
	if (ctlfile_openfn(name.c_str(), &ctlinfo, 0, 1))
	{
		if (errno)
		{
			clog_msg_start_err();
			clog_msg_str("Cannot read ");
			clog_msg_str(name.c_str());
			clog_msg_send();
			clog_msg_prerrno();
		}
		return (0);
	}
	delsendtime=deltime;
	if (flushtime && ctlinfo.mtime < flushtime && flushtime < deltime)
		delsendtime=flushtime;

	if (!queuefree)
	{
	msgq	*p;

//
// msgq array is full.  See if we can remove the last message from the
// pending queue.

		p=queuetail;
		if (p && p->nextsenddel > delsendtime)
		{

#if 0
clog_msg_start_info();
clog_msg_str("Removing ");
clog_msg_uint(p->msgnum);
clog_msg_str(" to make room for this message.");
clog_msg_send();
#endif

			p->removewq();
			p->removeq();
		}
	}

msgq	*newq=queuefree;

	if (!newq)
	{
		ctlfile_close(&ctlinfo);

		if (queuefill && nextqueuefill == 0)
		{
			nextqueuefill=current_time + queuefill;
		}
		return (1);
	}

	const char *cn=qmsgsctlname(inum);

	if ( stat(cn, &stat_buf) == -1 )
	{
		unlink(name.c_str());
		unlink(qmsgsdatname(inum));
		unlink(cn);
		ctlfile_close(&ctlinfo);
		return (0);
	}


#if 0
clog_msg_start_info();
clog_msg_str("Adding ");
clog_msg_uint(inum);
clog_msg_str(" to queue.");
clog_msg_send();
#endif

	queuefree=newq->next;
	++queuedelivering;

	ino_t	hashbucket=inum % queuehashfirst.size();

	if (queuehashfirst[hashbucket])
		queuehashfirst[hashbucket]->prevhash=newq;
	else
		queuehashlast[hashbucket]=newq;

	newq->nexthash=queuehashfirst[hashbucket];
	newq->prevhash=0;
	queuehashfirst[hashbucket]=newq;

	newq->nksize= (unsigned long)stat_buf.st_size;
	ctlinfo.starttime=stat_buf.st_mtime;

int	k=ctlfile_searchfirst(&ctlinfo, COMCTLFILE_MSGID);

	newq->msgid= k < 0 ? "": ctlinfo.lines[k]+1;

	newq->msgnum=inum;
	newq->nextdel=deltime;
	newq->nextsenddel=delsendtime;
	newq->rcptinfo_list.resize(0);
	newq->rcptcount=0;
	newq->cancelled=ctlinfo.cancelled;

	if (isnewmsg)
	{
		int auth;

		clog_msg_start_info();
		clog_msg_str("newmsg,id=");
		logmsgid(newq);

		auth=ctlfile_searchfirst(&ctlinfo, COMCTLFILE_AUTHNAME);

		if (auth >= 0)
		{
			clog_msg_str(", auth=");
			clog_msg_str(ctlinfo.lines[auth]+1);
		}

		int m=ctlfile_searchfirst(&ctlinfo, COMCTLFILE_FROMMTA);

		if (m >= 0)
		{
			clog_msg_str(": ");
			clog_msg_str(ctlinfo.lines[m]+1);
		}

		clog_msg_send();
	}

	unsigned	i, j;
	std::string host, addr;

	k=ctlfile_searchfirst(&ctlinfo, COMCTLFILE_SENDER);

	struct rfc822t *sendert=rw_rewrite_tokenize(k < 0 ? "":ctlinfo.lines[k]+1);
	std::string	errmsg;

	for (i=0; i<ctlinfo.nreceipients; i++)
	{
		for (j=0; ctlinfo.lines[j]; j++)
		{
			switch (ctlinfo.lines[j][0])	{
			case COMCTLFILE_DELSUCCESS:
			case COMCTLFILE_DELFAIL:
				if ((unsigned)atoi(ctlinfo.lines[j]+1) == i)
					break;
				// This one has been delivered
			default:
				continue;
			}
			break;
		}
		if (ctlinfo.lines[j])	continue;

	drvinfo *module=getdelinfo(sendert->tokens,
			ctlinfo.receipients[i], host, addr, errmsg);

		if (!module)
		{
			ctlfile_append_reply(&ctlinfo, i, errmsg.c_str(),
					     SMTPREPLY_TYPE(errmsg.c_str()),
					     0);
			continue;
		}

		/* Check if it's time to move the message to a backup relay */

		if (backup_relay_driver &&
			ctlfile_searchfirst(&ctlinfo, COMCTLFILE_WARNINGSENT)
			>= 0 &&
		    strcmp(module->module->name,
			   backup_relay_driver->module->name) == 0)
		{
			// module=backup_relay_driver;
			host=backup_relay;
		}

		/* Group all recipients for the same driver and host together */

		for (j=0; j<newq->rcptcount; j++)
			if (strcmp(module->module->name,
				   newq->rcptinfo_list[j].delmodule->
				   module->name) == 0 &&
			    newq->rcptinfo_list[j].delhost == host &&
			    newq->rcptinfo_list[j].addresses.size()
			    < module->maxrcpt )
				break;
		if (j == newq->rcptcount)
		{
#if 0
clog_msg_start_info();
clog_msg_str("id=");
logmsgid(newq);
clog_msg_str(",new rcpt list - module=");
clog_msg_str(module->module->name);
clog_msg_str(", host=");
clog_msg_str(host);
clog_msg_send();
#endif
			newq->rcptinfo_list.resize(++newq->rcptcount);

		struct	rw_info_rewrite rwir;
		struct	rw_info	rwi;

			rwir.buf=0;
			rwir.errmsg=0;
			rw_info_init(&rwi, sendert->tokens, rw_err_func);
			rwi.sender=0;
			rwi.mode=RW_OUTPUT|RW_ENVSENDER;
			rwi.udata= (void *)&rwir;
			rw_rewrite_module(module->module, &rwi,
				rw_rewrite_chksyn_print);

		char *address=((struct rw_info_rewrite *)rwi.udata)->buf;
		char *errmsg= ((struct rw_info_rewrite *)rwi.udata)->errmsg;

			if (!address)
			{
				ctlfile_append_reply(&ctlinfo, i, errmsg,
					SMTPREPLY_TYPE(errmsg), 0);
				newq->rcptinfo_list.resize(--newq->rcptcount);
				free(errmsg);
				continue;
			}

			if (errmsg)	free(errmsg);
			newq->rcptinfo_list[j].init(newq, module, host, address);
			free(address);
		}
#if 0
clog_msg_start_info();
clog_msg_str("id=");
logmsgid(newq);
clog_msg_str(",module=");
clog_msg_str(module->module->name);
clog_msg_str(", host=");
clog_msg_str(host);
clog_msg_str(", addr=<");
clog_msg_str(addr);
clog_msg_str(">");
clog_msg_send();
#endif

		newq->rcptinfo_list[j].addresses.push_back(addr);
		newq->rcptinfo_list[j].addressesidx.push_back(i);
	}
	rfc822t_free(sendert);
	ctlfile_close(&ctlinfo);

	if (newq->nextsenddel <= current_time ||

/*
** If there are no more recipients, we want to call done() via
** start_message.  HOWEVER, if DSN injection FAILED, we want to respect
** the rescheduled delivery attempt time.  We can detect that if isnewmsg == 0
*/
		(newq->rcptinfo_list.size() == 0 && isnewmsg))
	{
		newq->start_message();
		return (0);
	}

msgq	*qp, *qprev;

	for (qprev=queuetail, qp=0; qprev; qp=qprev, qprev=qp->prev)
		if (qprev->nextsenddel < newq->nextsenddel)
			break;

	newq->next=qp;
	newq->prev=qprev;

	if (qprev)	qprev->next=newq;
	else		queuehead=newq;

	if (qp)	qp->prev=newq;
	else	queuetail=newq;
	++queuewaiting;
	return (0);
}
Example #14
0
static void readforward(FILE *f, int n)
{
char	buf[BUFSIZ];
char	*p;
struct	rfc822t *t;
struct	rfc822a *a;
int	i;
char	*sep;

	while (fgets(buf, sizeof(buf), f))
	{
		p=strchr(buf, '\n');
		if (p)	*p=0;
		p=buf;
		while (*p && isspace((int)(unsigned char)*p))	++p;
		if (strncmp(p, ":include:",  9) == 0)
		{
		FILE	*g;

			if (n > 10)
			{
				fprintf(stderr, "dotforward: too many :include files.\n");
				exit(EX_NOUSER);
			}

			p += 9;
			while (*p && isspace((int)(unsigned char)*p))	++p;
			if (!*p)	continue;
			g=fopen(p, "r");
			if (!g)
			{
				perror(p);
				exit(EX_NOUSER);
			}
			readforward(g, n+1);
			fclose(g);
			continue;
		}
		if (*p == '|' || *p == '/' || *p == '.')
		{
			printf("%s\n", p);
			continue;
		}
		t=rfc822t_alloc_new(p, NULL, NULL);
		if (!t || !(a=rfc822a_alloc(t)))
		{
			perror("malloc");
			exit(EX_NOUSER);
		}

		for (i=0; i<a->naddrs; i++)
		{
			if (a->addrs[i].tokens &&
			    a->addrs[i].tokens->token == '"' &&
			    a->addrs[i].tokens->next == NULL)
				a->addrs[i].tokens->token=0;

			p=rfc822_getaddr(a, i);
			if (!p)
			{
				perror("malloc");
				exit(EX_NOUSER);
			}
			if (*p == '|' || *p == '/')
			{
				printf("%s\n", p);
			}
			free(p);
		}
		sep=0;
		for (i=0; i<a->naddrs; i++)
		{
		char	*q, *r;
		struct delivered_to *s;
		char	*t;
		char	*orig;

			p=rfc822_getaddr(a, i);
			if (!p)
			{
				perror("malloc");
				exit(EX_NOUSER);
			}
			if (*p == '|' || *p == '/' || *p == '.')
			{
				free(p);
				continue;
			}
			q=p;
			if (*q == '\\')
				++q;

			r=strchr(q, '@');
			if (!r || config_islocal(r+1, 0))
				locallower(q);
			domainlower(q);
			t=0;
			orig=q;

			if (strchr(q, '@') == 0)
			{
				t=malloc(strlen(q)+1+strlen(myaddr));
					/* overkill, yeah */
				if (!t)
				{
					perror("malloc");
					exit(EX_NOUSER);
				}
				strcat(strcpy(t, q), strchr(myaddr, '@'));
				q=t;
			}

			if (strcmp(myaddr, q) == 0)
			{
				exit_code=0;
				free(p);
				if (t)	free(t);
				continue;
			}

			for (s=delivtolist; s; s=s->next)
			{
				if (strcmp(s->addr, q) == 0)
					break;
			}
			if (!s)
			{
				if (sep)	printf("%s", sep);
				else	printf("!");
				sep=", ";
				printf("%s", orig);
			}
			free(p);
			if (t)	free(t);
		}
		if (sep)	printf("\n");
		rfc822a_free(a);
		rfc822t_free(t);
	}
}
Example #15
0
struct imap_refmsg *rfc822_threadmsg(struct imap_refmsgtable *mt,
				     const char *msgidhdr,
				     const char *refhdr,
				     const char *subjheader,
				     const char *dateheader,
				     unsigned long seqnum)
{
	struct rfc822t *t;
	struct rfc822a *a;
	struct imap_refmsg *m;

	char *msgid_s;

	t=rfc822t_alloc(msgidhdr ? msgidhdr:"", 0);
	if (!t)
		return (0);
	a=rfc822a_alloc(t);
	if (!a)
	{
		rfc822t_free(t);
		return (0);
	}

	msgid_s=a->naddrs > 0 ? rfc822_getaddr(a, 0):strdup("");

	rfc822a_free(a);
	rfc822t_free(t);

	if (!msgid_s)
		return (0);

	t=rfc822t_alloc(refhdr ? refhdr:"", 0);
	if (!t)
	{
		free(msgid_s);
		return (0);
	}

	a=rfc822a_alloc(t);
	if (!a)
	{
		rfc822t_free(t);
		free(msgid_s);
		return (0);
	}

	m=dorefcreate(mt, msgid_s, a);

	rfc822a_free(a);
	rfc822t_free(t);
	free(msgid_s);

	if (!m)
		return (0);

	if (subjheader && (m->subj=strdup(subjheader)) == 0)
		return (0);	/* Cleanup in rfc822_threadfree() */

	m->timestamp=dateheader ? rfc822_parsedt(dateheader):0;

	m->seqnum=seqnum;

	return (m);
}