Ejemplo n.º 1
0
ftnmsg *mkftnhdr(rfcmsg *msg, int newsmode, faddr *recipient)
{
    char	    *freename = NULL, *rfcfrom = NULL, *p, *q, *l, *r;
    char	    *fbuf = NULL, *ftnfrom=NULL;
    static ftnmsg   *tmsg;
    int		    needreplyaddr = 1;
    faddr	    *tmp, *tmp2;

    tmsg=(ftnmsg *)malloc(sizeof(ftnmsg));
    memset(tmsg, 0, sizeof(ftnmsg));

    if (newsmode) {
	p = xstrcpy(hdr((char *)"Comment-To",msg));
	if (p == NULL) 
	    p = xstrcpy(hdr((char *)"X-Comment-To",msg));
	if (p == NULL) 
	    p = xstrcpy(hdr((char *)"X-FTN-To",msg));
	if (p == NULL) 
	    p = xstrcpy(hdr((char *)"X-Fidonet-Comment-To",msg));
	if (p == NULL) 
	    p = xstrcpy(hdr((char *)"X-Apparently-To",msg));
	if (p == NULL)
	    p = xstrcpy(hdr((char *)"To", msg));  /* 14-Aug-2001 MB */
	if (p) {
	    Syslog('m', "Getting `to' address from \"%s\"", MBSE_SS(p));

	    if ((tmsg->to = parsefaddr(p)) == NULL)
		tmsg->to = parsefaddr((char *)"[email protected]");
	    if ((l = strrchr(p,'<')) && (r = strchr(p,'>')) && (l < r)) {
		r = l;
		*r-- = '\0';
		if ((l = strchr(p,'"')) && (r = strrchr(p,'"')) && (l < r)) {
		    l++;
		    *r-- = '\0';
		}
		while (isspace(*r)) 
		    *r-- = '\0';
		if (!l) 
		    l = p;
		while (isspace(*l)) 
		    l++;
	    } else if ((l = strrchr(p,'(')) && (r = strchr(p,')')) && (l < r)) {
		*r-- = '\0';
		while (isspace(*r)) 
		    *r-- = '\0';
		l++;
		while (isspace(*l)) 
		    l++;
	    } else {
		l = p;
		while (isspace(*l)) 
		    l++;
		r = p + strlen(p) -1;
		if (*r == '\n') 
		    *r-- = '\0';
		while (isspace(*r)) 
		    *r-- = '\0';
	    }

	    if (*l) {
		if (strlen(l) > MAXNAME)
		    l[MAXNAME]='\0';
		free(tmsg->to->name);
		tmsg->to->name=xstrcpy(l);
	    }
	    free(p);
	    /*
	     *  It will become echomail, the destination FTN address must
	     *  be our address.  14-Aug-2001 MB.
	     */
	    tmsg->to->zone   = msgs.Aka.zone;
	    tmsg->to->net    = msgs.Aka.net;
	    tmsg->to->node   = msgs.Aka.node;
	    tmsg->to->point  = msgs.Aka.point;
	    tmsg->to->domain = xstrcpy(msgs.Aka.domain);
	} else {
	    /*
	     *  Filling a default To: address.
	     */
	    tmsg->to = (faddr*)malloc(sizeof(faddr));
	    tmsg->to->name   = xstrcpy((char *)"All");
	    tmsg->to->zone   = msgs.Aka.zone;
	    tmsg->to->net    = msgs.Aka.net;
	    tmsg->to->node   = msgs.Aka.node;
	    tmsg->to->point  = msgs.Aka.point;
	    tmsg->to->domain = xstrcpy(msgs.Aka.domain);
	}
    } else {
	if (recipient) {
	    /*
	     *  In mbmail mode the recipient is valid and must be used 
	     *  as the destination address. The To: field is probably
	     *  an RFC address an cannot be used to route the message.
	     */
	    tmsg->to = (faddr *)malloc(sizeof(faddr));
	    tmsg->to->point = recipient->point;
	    tmsg->to->node  = recipient->node;
	    tmsg->to->net   = recipient->net;
	    tmsg->to->zone  = recipient->zone;
	    tmsg->to->name  = xstrcpy(recipient->name);
	    if (tmsg->to->name && (strlen(tmsg->to->name) > MAXNAME))
		tmsg->to->name[MAXNAME]='\0';
	    tmsg->to->domain = xstrcpy(recipient->domain);
	    Syslog('m', "Recipient TO: %s", ascfnode(tmsg->to,0xff));
	} else {
	    p = xstrcpy(hdr((char *)"To",msg));
	    if (p == NULL)
		p = xstrcpy(hdr((char *)"X-Apparently-To",msg));
	    if (p) {
		if ((tmsg->to = parsefaddr(p)) == NULL)
		    WriteError("Unparsable destination address");
		else
		    Syslog('m', "RFC parsed TO: %s",ascfnode(tmsg->to,0xff));
	    }
	}
    } /* else (newsmode) */

    p = fbuf = xstrcpy(hdr((char *)"Reply-To", msg));
    if (fbuf == NULL) 
	p = fbuf = xstrcpy(hdr((char *)"From", msg));
    if (fbuf == NULL) 
	p = fbuf = xstrcpy(hdr((char *)"X-UUCP-From", msg));
    if (p) {
	q = p;
	while (isspace(*q)) 
	    q++;
	fbuf = parserfcaddr(q).remainder;
	if (parserfcaddr(q).target) {
	    fbuf = xstrcat(fbuf, (char *)"@");
	    fbuf = xstrcat(fbuf, parserfcaddr(q).target);
	}	
	rfcfrom = fbuf;
    }
    if (p)
	free(p);
    p = NULL;
    if (!rfcfrom) 
	rfcfrom = xstrcpy((char *)"postmaster");
    p = fbuf = xstrcpy(hdr((char *)"From", msg));
    if (fbuf == NULL) 
	p = fbuf = xstrcpy(hdr((char *)"X-UUCP-From", msg));
    if (p) {
	q = p;
	while (isspace(*q)) 
	    q++;
        if ((q) && (*q !=  '\0'))
            freename = parserfcaddr(q).comment;
        else 
	    freename = NULL;
    } else 
	freename = xstrcpy((char *)"Unidentified User");
    if (freename) {
	while (isspace(*freename)) 
	    freename++;
    }

    if (rfcfrom) {
	while (isspace(*rfcfrom)) 
	    rfcfrom++;
	p = rfcfrom + strlen(rfcfrom) -1;
	while ((isspace(*p)) || (*p == '\n')) 
	    *(p--)='\0';
    }

    if ((freename) && (*freename != '\0')) {
	while (isspace(*freename)) 
	    freename++;
	p = freename + strlen(freename) -1;
	while ((isspace(*p)) || (*p == '\n')) 
	    *(p--)='\0';
	if ((*freename == '\"') && (*(p=freename+strlen(freename)-1) == '\"')) {
	    freename++;
	    *p='\0';
	}
    }
    // if (*freename == '\0') freename=rfcfrom;
    if ((!freename) || ((freename) && (*freename == '\0')) || (strcmp(freename,".")==0)) 
	freename=rfcfrom;

    if (! newsmode)
	Syslog('+', "from: %s <%s>",freename,rfcfrom);

    needreplyaddr = 1;
    if ((tmsg->from=parsefaddr(rfcfrom)) == NULL) {
	if (freename && rfcfrom)
	    if (!strchr(freename,'@') && !strchr(freename,'%') && 
			    strncasecmp(freename,rfcfrom,MAXNAME) &&
			    strncasecmp(freename,"uucp",4) &&
			    strncasecmp(freename,"usenet",6) &&
			    strncasecmp(freename,"news",4) &&
			    strncasecmp(freename,"super",5) &&
			    strncasecmp(freename,"admin",5) &&
			    strncasecmp(freename,"postmaster",10) &&
			    strncasecmp(freename,"sys",3)) 
		needreplyaddr=registrate(freename,rfcfrom);
    } else {
	tmsg->ftnorigin = 1;
	tmsg->from->name = xstrcpy(freename);
	if (strlen(tmsg->from->name) > MAXNAME)
	    tmsg->from->name[MAXNAME]='\0';
    }
    if (replyaddr) {
	free(replyaddr);
	replyaddr=NULL;
    }
    if (needreplyaddr && (tmsg->from == NULL)) {
	replyaddr=xstrcpy(rfcfrom);
    }

    if (tmsg->from)
	Syslog('m', "From address was%s distinguished as ftn", tmsg->from ? "" : " not");

    if (newsmode) {
	tmp2 = fido2faddr(msgs.Aka);
	bestaka = bestaka_s(tmp2);
	tidy_faddr(tmp2);
    } else
	bestaka = bestaka_s(tmsg->to);

    if ((tmsg->from == NULL) && (bestaka)) {
	if (CFG.dontregate) {
	    p = xstrcpy(hdr((char *)"X-FTN-Sender",msg));
	    if (p == NULL) {
		if ((p = hdr((char *)"X-FTN-From",msg))) {
		    tmp = parsefnode(p);
		    p = xstrcpy(ascinode(tmp, 0xff));
		    tidy_faddr(tmp);
		}
	    }
	    if (p) {
	        q = p;
		while (isspace(*q)) 
		    q++;
		ftnfrom = parserfcaddr(q).remainder;
		if (parserfcaddr(q).target) {
		    ftnfrom = xstrcat(ftnfrom,(char *)"@");
		    ftnfrom = xstrcat(ftnfrom,parserfcaddr(q).target);
		}	
		Syslog('m', "Ftn gateway: \"%s\"", ftnfrom);
		Syslog('+', "Ftn sender: %s",ftnfrom);
		if (ftnfrom) 
		    tmsg->from = parsefaddr(ftnfrom);
		if ((tmsg->from) && (!tmsg->from->name))
		    tmsg->from->name = xstrcpy(rfcfrom);
	    }
	    if (p)
		free(p);
	    p = NULL;
	    if (tmsg->from == NULL) {
		tmsg->from=(faddr *)malloc(sizeof(faddr));
		tmsg->from->name=xstrcpy(freename);
		if (tmsg->from->name && (strlen(tmsg->from->name) > MAXNAME))
		    tmsg->from->name[MAXNAME]='\0';
		tmsg->from->point=bestaka->point;
		tmsg->from->node=bestaka->node;
		tmsg->from->net=bestaka->net;
		tmsg->from->zone=bestaka->zone;
		tmsg->from->domain=xstrcpy(bestaka->domain);
	    }
	} else {
	    tmsg->from=(faddr *)xmalloc(sizeof(faddr));
	    tmsg->from->name=xstrcpy(freename);
	    if (tmsg->from->name && (strlen(tmsg->from->name) > MAXNAME))
		tmsg->from->name[MAXNAME]='\0';
	    tmsg->from->point=bestaka->point;
	    tmsg->from->node=bestaka->node;
	    tmsg->from->net=bestaka->net;
	    tmsg->from->zone=bestaka->zone;
	    tmsg->from->domain=xstrcpy(bestaka->domain);
	}
    }
    if (fbuf) 
	free(fbuf); 
    fbuf = NULL;

    p = hdr((char *)"Subject", msg);
    if (p) {
	while (isspace(*p)) 
	    p++;
	tmsg->subj = xstrcpy(p);
	if (*(p=tmsg->subj+strlen(tmsg->subj)-1) == '\n') 
	    *p='\0';
	if (strlen(tmsg->subj) > MAXSUBJ) 
	    tmsg->subj[MAXSUBJ]='\0';
    } else {
	tmsg->subj = xstrcpy((char *)" ");
    }

    if ((p = hdr((char *)"X-FTN-FLAGS",msg))) 
	tmsg->flags |= flagset(p);
    if (hdr((char *)"Return-Receipt-To",msg)) 
	tmsg->flags |= M_RRQ;
    if (hdr((char *)"Notice-Requested-Upon-Delivery-To",msg)) 
	tmsg->flags |= M_RRQ;
    if (!newsmode) {
	tmsg->flags |= M_PVT;
	tmsg->flags |= M_KILLSENT;
    }

    if ((p = hdr((char *)"X-Origin-Date",msg))) 
	tmsg->date = parsedate(p, NULL) - (gmt_offset((time_t)0) * 60);
    else if ((p = hdr((char *)"Date",msg))) 
	tmsg->date = parsedate(p, NULL) - (gmt_offset((time_t)0) * 60);
    else 
	tmsg->date = time((time_t *)NULL);

    /*
     * SunMail 1.0 creates invalid date formats like: Wed, 19 Jun 2002 18:21:07 GMT-08:00
     *                                                                                ^---- not allowed.
     */
    if (tmsg->date == -1) {
	Syslog('!', "Parsing date \"%s\" failed, using current date", p);
	tmsg->date = time((time_t *)NULL);
    }
	
    if ((p = hdr((char *)"X-FTN-MSGID", msg))) {
	tmsg->ftnorigin &= 1;
	while (isspace(*p)) 
	    p++;
	tmsg->msgid_s = xstrcpy(p);
	if (*(p = tmsg->msgid_s + strlen(tmsg->msgid_s) -1) == '\n') 
	    *p='\0';
    } else if ((p = hdr((char *)".MSGID",msg))) {
	tmsg->ftnorigin &= 1;
	while (isspace(*p)) 
	    p++;
	tmsg->msgid_s = xstrcpy(p);
	if (*(p = tmsg->msgid_s + strlen(tmsg->msgid_s) -1) == '\n') 
	    *p='\0';
    } else if ((p = hdr((char *)"Message-ID",msg))) {
	tmsg->ftnorigin &= ftnmsgid(p,&(tmsg->msgid_a),&(tmsg->msgid_n),tmsg->area);
    } else
	tmsg->msgid_a = NULL;

    if ((p = hdr((char *)"X-FTN-REPLY",msg))) {
	while (isspace(*p)) 
	    p++;
	tmsg->reply_s = xstrcpy(p);
	if (*(p=tmsg->reply_s + strlen(tmsg->reply_s) -1) == '\n') 
	    *p='\0';
    } else {
	if (newsmode) {
	    p = hdr((char *)"References",msg);
	    if (p) {       
		l = xstrcpy(p);
		r = strtok(l," \t\n");
		while ((l=strtok(NULL," \t\n")) != NULL) 
		    r = l;
		p = r;
		free(l);
	    }
	} else
	    p = hdr((char *)"In-Reply-To",msg);
    }
    if (p)
	(void)ftnmsgid(p,&(tmsg->reply_a),&(tmsg->reply_n),NULL);
    else
	tmsg->reply_a=NULL;

    p = hdr((char *)"Organization",msg);
    if (p == NULL)
	p = hdr((char *)"Organisation",msg);
    if (p) {
	while (isspace(*p)) 
	    p++;
	tmsg->origin = xstrcpy(p);
	if (tmsg->origin)
	    if (*(p = tmsg->origin + strlen(tmsg->origin)-1) == '\n') 
		*p='\0';
    } else {
	/*
	 *  No Organization header, insert the default BBS origin.
	 */
	tmsg->origin = xstrcpy(CFG.origin);
    }

    return tmsg;
}
Ejemplo n.º 2
0
/*
 * Process one message from message packet.
 *
 *  0   - no more messages
 *  1   - more messages
 *  2   - bad file
 *  3   - bad message header
 *  4   - unable to open temp file
 *  5   - unexpected end of packet
 *  >10 - import error
 */
int getmessage(FILE *pkt, faddr *p_from, faddr *p_to)
{
    char	    buf[MAX_LINE_LENGTH +1], *orig = NULL, *p, *l, *r, *subj = NULL;
    int		    tmp, rc, maxrc = 0, result, flags, cost;
    static faddr    f, t;
    faddr	    *o;
    time_t	    mdate = 0L;
    FILE	    *fp;
    unsigned char   buffer[0x0e];

    Nopper();

    result = fread(&buffer, 1, sizeof(buffer), pkt);
    if (result == 0) {
	Syslog('m', "Zero bytes message, assume end of pkt");
	return 0;
    }

    switch (tmp = (buffer[0x01] << 8) + buffer[0x00]) {
	case 0:	if (result == 2)
		    return 0;
		else {
		    Syslog('!', "Junk after logical end of packet, skipped");
		    return 5;

		}
	case 2:	break;

	default:Syslog('!', "bad message type: 0x%04x",tmp);
		return 2;
    }

    if (result != 14) {
	Syslog('!', "Unexpected end of packet");
	return 5;
    }

    memset(&f, 0, sizeof(f));
    memset(&t, 0, sizeof(t));
    f.node = (buffer[0x03] << 8) + buffer[0x02];
    t.node = (buffer[0x05] << 8) + buffer[0x04];
    f.net  = (buffer[0x07] << 8) + buffer[0x06];
    t.net  = (buffer[0x09] << 8) + buffer[0x08];
    flags  = (buffer[0x0b] << 8) + buffer[0x0a];
    cost   = (buffer[0x0d] << 8) + buffer[0x0c];

    /*
     * Read the DateTime, toUserName, fromUserName and subject fields
     * from the packed message. The stringlength is +1 for the right
     * check. This is different then in ifmail's original code.
     */
    if (aread(buf, sizeof(buf)-1, pkt)) {
	if (strlen(buf) > 20)
	    Syslog('!', "date too long (%d) \"%s\"", strlen(buf), printable(buf, 0));
	mdate = parsefdate(buf, NULL);
	if (aread(buf, sizeof(buf)-1, pkt)) {
	    Syslog('!', "date not null-terminated: \"%s\"",buf);
	    return 3;
	}
    }

    if (aread(buf, sizeof(buf)-1, pkt)) {
	if (strlen(buf) > 36)
	    Syslog('!', "to name too long (%d) \"%s\"", strlen(buf), printable(buf, 0));
	t.name = xstrcpy(buf);
	if (aread(buf, sizeof(buf)-1, pkt)) {
	    if (*(p=t.name+strlen(t.name)-1) == '\n')
		*p = '\0';
	    Syslog('!', "to name not null-terminated: \"%s\"",buf);
	    return 3;
	}
    }

    if (aread(buf, sizeof(buf)-1, pkt)) {
	if (strlen(buf) > 36)
	    Syslog('!', "from name too long (%d) \"%s\"", strlen(buf), printable(buf, 0));
	f.name = xstrcpy(buf);
	if (aread(buf, sizeof(buf)-1, pkt)) {
	    if (*(p=f.name+strlen(f.name)-1) == '\n') 
		*p = '\0';
	    Syslog('!', "from name not null-terminated: \"%s\"",buf);
	    return 3;
	}
    }
	
    if (aread(buf, sizeof(buf)-1, pkt)) {
	if (strlen(buf) > 72)
	    Syslog('!', "subject too long (%d) \"%s\"", strlen(buf), printable(buf, 0));
	subj = xstrcpy(buf);
	if (aread(buf, sizeof(buf)-1, pkt)) {
	    if (*(p=subj+strlen(subj)-1) == '\n') 
		*p = '\0';
	    subj = xstrcat(subj,(char *)"\\n");
	    subj = xstrcat(subj,buf);
	    Syslog('!', "subj not null-terminated: \"%s\"",buf);
	    return 3;
	}
    }

    if (feof(pkt) || ferror(pkt)) {
	Syslog('!', "Could not read message header, aborting");
	return 3;
    }

    if ((fp = tmpfile()) == NULL) {
	WriteError("$unable to open temporary file");
	return 4;
    }

    /*
     * Read the text from the .pkt file
     */
    while (aread(buf,sizeof(buf)-1,pkt)) {

	fputs(buf, fp);

	/*
	 * Extract info from Origin line if found.
	 */
	if (!strncmp(buf," * Origin:",10)) {
	    p=buf+10;
	    while (*p == ' ') 
		p++;
	    if ((l=strrchr(p,'(')) && (r=strrchr(p,')')) && (l < r)) {
		*l = '\0';
		*r = '\0';
		l++;
		if ((o = parsefnode(l))) {
		    f.point = o->point;
		    f.node = o->node;
		    f.net = o->net;
		    f.zone = o->zone;
		    if (o->domain) 
			f.domain=o->domain;
		    o->domain=NULL;
		    tidy_faddr(o);
		}
	    } else
		if (*(l=p+strlen(p)-1) == '\n')
		    *l='\0';
		for (l=p+strlen(p)-1;*l == ' ';l--) 
		    *l='\0'; 
		orig = xstrcpy(p);
	}
    }

    rc = importmsg(p_from, &f, &t, orig, subj, mdate, flags, cost, fp, p_to->zone);
    if (rc)
	rc+=10;
    if (rc > maxrc) 
	maxrc = rc;

    fclose(fp);

    if(f.name) 
	free(f.name); 
    f.name=NULL;

    if(t.name) 
	free(t.name); 
    t.name=NULL;

    if(f.domain) 
	free(f.domain); 
    f.domain=NULL;

    if(t.domain) 
	free(t.domain); 
    t.domain=NULL;

    if (subj)
	free(subj);
    subj = NULL;

    if (orig)
	free(orig);
    orig = NULL;

    if (feof(pkt) || ferror(pkt)) {
	WriteError("Unexpected end of packet");
	return 5;
    }
    return 1;
}
Ejemplo n.º 3
0
char *route(char *adr0)
{
FILE *f1;
char *a1;
int i=0;
char adr1[100];
char *adr2=adr1;
char *adrp;
char *routeadr;


	tfaddr=parsefaddr(adr0);
	adr2=ascfnode(tfaddr, 0x6);

	if (strcmp(adr2, my_addr) == 0)
		return(adr0);

	f1=fopen(ROUTE_CFG,"r");
	while(fgets(adr[i],100,f1) != NULL)
		{
		a[i]=adr[i];
		i++;
		}
	if(i==0) i++;
	a[i]=NULL;
/*
	i=0;
	while(a[i]!=NULL)
		printf("%s",a[i++]);
*/

	fclose(f1);

/*	printf("\n%s\n", adr2);*/

	if ((adrp=strchr(adr2, '.')) != NULL)
		*adrp='\0';

	if ((routeadr=routea(adr2)) == NULL)
		{
		adrp=(strchr(adr2, '/'));
		*(adrp+1)='*';
		*(adrp+2)='\0';
		if ((routeadr=routea(adr2)) == NULL)
			{
			strcpy(adr2, "*/*");
			if ((routeadr=routea(adr2)) == NULL)
				{
				printf("\nerror in route table\n");
				}
			}
		}

	if (routeadr != NULL)	
		{
		strcpy(adr1, routeadr);
		tfaddr=parsefnode(adr1);
		routeadr=adr1;
		routeadr=ascinode(tfaddr, 0x6);
		}

/*	printf("\nrouteaddr = %s\n", routeadr);*/

	return(routeadr);
}
Ejemplo n.º 4
0
/*
 *  Post netmail message for temp file. The tempfile is an FTN style message.
 *
 *  0 - All seems well.
 *  1 - Can't access messagebase.
 *  2 - Can't find netmail board.
 *
 */
int postnetmail(FILE *fp, faddr *f, faddr *t, char *orig, char *subject, time_t mdate, 
	int flags, int DoPing, unsigned int fzone, unsigned int tzone)
{
    char    	*p, *msgid = NULL, *reply = NULL, *flagstr = NULL;
    char    	name[37], *buf, *l, *r, *q, System[37], ext[4];
    int		result = 1, email = FALSE, fmpt = 0, topt = 0;
    faddr	*ta, *ra;
    fidoaddr	na, routeto, Orig;
    FILE	*sfp, *net;
    time_t	now;
    struct tm	*tm;

    Syslog('m', "Post netmail from: %s", ascfnode(f, 0xff));
    Syslog('m', "Post netmail to  : %s", ascfnode(t, 0xff));
    Syslog('m', "Post netmail subj: %s", MBSE_SS(subject));
    net_in++;

    /*
     *  Extract MSGID and REPLY kludges from this netmail.
     */
    buf = calloc(MAX_LINE_LENGTH +1, sizeof(char));
    rewind(fp);
    while ((fgets(buf, MAX_LINE_LENGTH, fp)) != NULL) {
	Striplf(buf);
	Syslogp('M', printable(buf, 0));
	if (!strncmp(buf, "\001MSGID: ", 8)) {
	    msgid = xstrcpy(buf + 8);
	    /*
	     *  Extra test to see if the mail comes from a pointaddress.
	     */
	    l = strtok(buf," \n");
	    l = strtok(NULL," \n");
	    if ((ta = parsefnode(l))) {
		if (ta->net == f->net && ta->node == f->node && !fmpt && ta->point) {
		    Syslog('m', "Setting pointinfo (%d) from MSGID", ta->point);
		    fmpt = f->point = ta->point;
		}
		if ((ta->net == f->net) && (ta->node == f->node) && (f->zone == 0)) {
		    /*
		     * Missing zone info, maybe later we will see a INTL kludge or so, but for
		     * now, just in case we fix it. And we need that for some Aka collecting
		     * sysop who doesn't know how to configure his system right.
		     */
		    Syslog('m', "No from zone set, setting zone %d from MSGID", ta->zone);
		    f->zone = ta->zone;
		    /*
		     * 99.9 % chance that the destination zone is also missing.
		     */
		    if (t->zone == 0) {
			t->zone = ta->zone;
			Syslog('m', "No dest zone set, setting zone %d from MSGID", ta->zone);
		    }
		}
		tidy_faddr(ta);
	    }
	    if (msgid)
		free(msgid);
	    msgid = NULL;
	}
	if (!strncmp(buf, "\001FMPT", 5)) {
	    p = strtok(buf, " \n");
	    p = strtok(NULL, " \n");
	    fmpt = atoi(p);
	}
	if (!strncmp(buf, "\001TOPT", 5)) {
	    p = strtok(buf, " \n");
	    p = strtok(NULL, " \n");
	    topt = atoi(p);
	}
	if (!strncmp(buf, "\001REPLY: ", 8))
	    reply = xstrcpy(buf + 8);

	/*
	 * Check DOMAIN and INTL kludges
	 */
	if (!strncmp(buf, "\001DOMAIN", 7)) {
	    l = strtok(buf," \n");
	    l = strtok(NULL," \n");
	    p = strtok(NULL," \n");
	    r = strtok(NULL," \n");
	    q = strtok(NULL," \n");
	    if ((ta = parsefnode(p))) {
		t->point = ta->point;
		t->node = ta->node;
		t->net = ta->net;
		t->zone = ta->zone;
		tidy_faddr(ta);
	    }
	    t->domain = xstrcpy(l);
	    if ((ta = parsefnode(q))) {
		f->point = ta->point;
		f->node = ta->node;
		f->net = ta->net;
		f->zone = ta->zone;
		tidy_faddr(ta);
	    }
	    f->domain = xstrcpy(r);
	} else {
	    if (!strncmp(buf, "\001INTL", 5)) {
		l = strtok(buf," \n");
		l = strtok(NULL," \n");
		r = strtok(NULL," \n");
		if ((ta = parsefnode(l))) {
		    t->point = ta->point;
		    t->node = ta->node;
		    t->net = ta->net;
		    t->zone = ta->zone;
		    if (ta->domain) {
			if (t->domain)
			    free(t->domain);
			t->domain = ta->domain;
			ta->domain = NULL;
		    }
		    tidy_faddr(ta);
		}
		if ((ta = parsefnode(r))) {
		    f->point = ta->point;
		    f->node = ta->node;
		    f->net = ta->net;
		    f->zone = ta->zone;
		    if (ta->domain) {
			if (f->domain)
			    free(f->domain);
			f->domain = ta->domain;
			ta->domain = NULL;
		    }
		    tidy_faddr(ta);
		}
	    }
	}

	/*
	 * Check FLAGS kludge
	 */
	if (!strncmp(buf, "\001FLAGS ", 7)) {
	    flagstr = xstrcpy(buf + 7);
	    Syslog('m', "^aFLAGS %s", flagstr);
	}
	if (!strncmp(buf, "\001FLAGS: ", 8)) {
	    flagstr = xstrcpy(buf + 8);
	    Syslog('m', "^aFLAGS: %s", flagstr);
	}

	/*
	 * Check for X-FTN- kludges, this could be gated email.
	 * This should be impossible.
	 */
	if (!strncmp(buf, "\001X-FTN-", 7)) {
	    email = TRUE;
	    Syslog('?', "Warning: detected ^aX-FTN- kludge in netmail");
	}
    }
    free(buf);

    /*
     *  Only set point info if there was any info.
     *  GoldED doesn't set FMPT and TOPT kludges.
     */
    if (fmpt)
	f->point = fmpt;
    if (topt)
	t->point = topt;

    /*
     * If zone info is still missing, set the defaults which came from the
     * original mail packet addressing.
     */
    if (fzone && (f->zone == 0))
	f->zone = fzone;
    if (tzone && (t->zone == 0))
	t->zone = tzone;

    l = xstrcpy(ascfnode(f, 0xff));
    r = xstrcpy(ascfnode(t, 0xff));
    Syslog('+', "Netmail from \"%s\" to \"%s\"", l, r);
    free(l);
    free(r);

    memset(&na, 0, sizeof(na));
    na.zone  = t->zone;
    na.net   = t->net;
    na.node  = t->node;
    na.point = t->point;
    if (SearchFidonet(na.zone))
	snprintf(na.domain, 13, "%s", fidonet.domain);

    switch(TrackMail(na, &routeto)) {
	case R_LOCAL:
	    /*
	     *  Check the To: field.
	     */
	    if (strchr(t->name, '@') != NULL) {
		snprintf(name, 36, "%s", strtok(t->name, "@"));
		snprintf(System, 36, "%s", strtok(NULL, "\000"));
		email = TRUE;
	    } else {
		snprintf(name, 36, "%s", t->name);
		snprintf(System, 36, "%s", CFG.sysdomain);
	    }

	    if (email) {
		/*
		 * Send this netmail via ftn2rfc -> postemail.
		 */
		return result = ftn2rfc(f, t, subject, orig, mdate, flags, fp);
	    }

	    /*
	     * If message to "sysop" or "postmaster" replace it
	     * with the sysops real name.
	     */
	    if ((strncasecmp(name, "sysop", 5) == 0) || 
		(strcasecmp(name, "postmaster") == 0) ||
		(strcasecmp(name, "coordinator") == 0)) {
		Syslog('+', "  Readdress from %s to %s", name, CFG.sysop_name);
		snprintf(name, 36, "%s", CFG.sysop_name);
	    }

	    /*
	     * If the message is a service message, check the
	     * services database to see what action is needed.
	     * First make sure that the right noderecord is loaded.
	     */
	    (void)noderecord(f);
	    p = calloc(PATH_MAX, sizeof(char));
	    snprintf(p, PATH_MAX, "%s/etc/service.data", getenv("MBSE_ROOT"));
	    if ((sfp = fopen(p, "r")) == NULL) {
		WriteError("$Can't open %s", p);
	    } else {
		fread(&servhdr, sizeof(servhdr), 1, sfp);
		while (fread(&servrec, servhdr.recsize, 1, sfp) == 1) {
		    if ((strncasecmp(servrec.Service, name, strlen(servrec.Service)) == 0) && servrec.Active) {
			switch (servrec.Action) {
			    case AREAMGR:   result = AreaMgr(f, t, msgid, subject, mdate, flags, fp);
					    break;
			    case FILEMGR:   result = FileMgr(f, t, msgid, subject, mdate, flags, fp);
					    break;
			    case EMAIL:     result = ftn2rfc(f, t, subject, orig, mdate, flags, fp);
					    if (result) {
						if (result == 2)
						    Bounce(f, t, fp, (char *)"Could not post email");
						else
						    Bounce(f, t, fp, (char *)"Could not convert to email");
					    }
					    break;
			}
			Syslog('m', "Handled service %s, rc=%d", servrec.Service, result);
			fclose(sfp);
			return result;
		    }
		}
		fclose(sfp);
	    }
	    free(p);

	    /*
	     * Ping function
	     */
	    if (!strcasecmp(name, (char *)"ping") && DoPing) {
		return Ping(f, t, fp, FALSE);
	    }

	    /*
	     * Check userlist real names, handles, unix names.
	     * Import if one fits.
	     */
	    if (SearchUser(name)) {
		return storenet(f, t, mdate, flags, subject, msgid, reply, fp, flagstr);
	    }

	    Syslog('+', "  \"%s\" is not a known BBS user", name);
	    /*
	     *  Unknown, readdress it to the sysop.
	     */
	    net_bad++;
	    Syslog('+', "  Readdress from %s to %s", name, CFG.sysop_name);
	    snprintf(name, 36, "%s", CFG.sysop_name);
	    if (SearchUser(name)) {
		return storenet(f, t, mdate, flags, subject, msgid, reply, fp, flagstr);
	    } else {
		WriteError("Readdress import failed, sysop doesn't exist. CHECK YOUR SETUP");
		return 0;
	    }
	    break;

	case R_DIRECT:
	case R_ROUTE:
	    Syslog('+', "Route netmail via %s", aka2str(routeto));
            if (!strcasecmp(t->name, (char *)"ping") && DoPing) {
                Syslog('+', "In transit \"Ping\" message detected");
                Ping(f, t, fp, TRUE);
                (void)noderecord(f);
            }

	    /*
	     * Forward this message. Will not work for unknown
	     * direct links.
	     */
	    if (SearchNode(routeto)) {
		memset(&Orig, 0, sizeof(Orig));
		ra = fido2faddr(routeto);
		ta = bestaka_s(ra);
		Orig.zone  = ta->zone;
		Orig.net   = ta->net;
		Orig.node  = ta->node;
		Orig.point = ta->point;
		tidy_faddr(ra);
		tidy_faddr(ta);

		memset(&ext, 0, sizeof(ext));
		if (nodes.PackNetmail)
		    snprintf(ext, 4, (char *)"qqq");
		else if (nodes.Crash)
		    snprintf(ext, 4, (char *)"ccc");
		else if (nodes.Hold)
		    snprintf(ext, 4, (char *)"hhh");
		else 
		    snprintf(ext, 4, (char *)"nnn");

		if ((net = OpenPkt(Orig , routeto, (char *)ext)) == NULL) {
		    net_bad++;
		    WriteError("Can't create netmail");
		    return 0;
		}
	    } else {
		/*
		 * If it's not a direct link, create a outbound
		 * .pkt anyway, better then that this mail is 
		 * lost. It gets the normal status, it might
		 * get delivered during ZMH this way.
		 */
		Syslog('!', "Warning: not a direct link, check setup");
		memset(&Orig, 0, sizeof(Orig));
		ra = fido2faddr(routeto);
		ta = bestaka_s(ra);
		Orig.zone  = ta->zone;
		Orig.net   = ta->net;
		Orig.node  = ta->node;
		Orig.point = ta->point;
		tidy_faddr(ra);
		tidy_faddr(ta);

		if ((net = OpenPkt(Orig , routeto, (char *)"nnn")) == NULL) {
		    net_bad++;
		    WriteError("Can't create netmail");
		    return 0;
		}
	    }

	    /*
	     * Now start forward.
	     */
	    Syslog('m', "Net from  %s", ascfnode(f, 0xff));
	    Syslog('m', "Net to    %s", ascfnode(t, 0xff));
	    Syslog('m', "Net flags %08x", flags);
	    Syslog('m', "Net subj  %s", subject);

	    if (AddMsgHdr(net, f, t, flags, 0, mdate, t->name, f->name, subject)) {
		WriteError("Can't write message header");
		net_bad++;
		return 0;
	    }
	    rewind(fp);

	    /*
	     * Copy all text including kludges, when
	     * finished, insert our ^aVia line.
	     */
	    buf = calloc(MAX_LINE_LENGTH +1, sizeof(char));
	    while ((fgets(buf, MAX_LINE_LENGTH, fp)) != NULL)
		fprintf(net, "%s\r", buf);

	    now = time(NULL);
	    tm = gmtime(&now);
	    ta = bestaka_s(t);
	    fprintf(net, "\001Via %s @%d%02d%02d.%02d%02d%02d.UTC mbfido %s\r", 
		ascfnode(ta, 0x1f), tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
		tm->tm_hour, tm->tm_min, tm->tm_sec, VERSION);
	    tidy_faddr(ta);

	    putc(0, net);
	    fclose(net);
	    free(buf);
	    net_out++;
	    Syslog('m', "Forward done.");
	    return 0;

	default:
	    /*
	     * If we came this far, there's definitly something wrong
	     * with this netmail.
	     */
	    WriteError("No ROUTE for this netmail");
	    net_bad++;
	    flags |= M_ORPHAN;
	    return storenet(f, t, mdate, flags, subject, msgid, reply, fp, flagstr);
	    break;
    }

    /* Never reached */
    return result;
}