Beispiel #1
0
/*
 * Create file request list for the Hydra or Binkp protocol.
 */
file_list *create_freqlist(fa_list *al)
{
    file_list	*st = NULL, *tmpf;
    fa_list	*tmpa;
    char	*nm, tmpreq[13];
    struct stat	stbuf;

    Syslog('o', "create_freqlist(%s)", al?ascfnode(al->addr, 0x1f):"<none>");
    made_request = 0;

    for (tmpa = al; tmpa; tmpa = tmpa->next) {
	nm = reqname(tmpa->addr);
	if ((nm != NULL) && (stat(nm, &stbuf) == 0)) {
	    snprintf(tmpreq, 13, "%04X%04X.REQ", tmpa->addr->net, tmpa->addr->node);
	    add_list(&st, nm, tmpreq, DSF, 0L, NULL, 1);
	    made_request = 1;
	}
    }

    if (made_request) {
	for (tmpf = st; tmpf; tmpf = tmpf->next)
	    Syslog('o', "flist: \"%s\" -> \"%s\" dsp:%d flofp:%lu floff:%lu",
			MBSE_SS(tmpf->local), MBSE_SS(tmpf->remote), tmpf->disposition, tmpf->flofp, tmpf->floff);
    }

    return st;
}
Beispiel #2
0
void gold_akamatch(FILE *fp)
{
    char    temp[PATH_MAX];
    FILE    *fido;
    faddr   *want, *ta;
    int     i;

    snprintf(temp, PATH_MAX, "%s/etc/fidonet.data", getenv("MBSE_ROOT"));
    if ((fido = fopen(temp, "r")) == NULL)
	return;

    fprintf(fp, "; AKA Matching\n;\n");
    want = (faddr *)malloc(sizeof(faddr));

    fread(&fidonethdr, sizeof(fidonethdr), 1, fido);
    while ((fread(&fidonet, fidonethdr.recsize, 1, fido)) == 1) {

	if (fidonet.available) {
	    for (i = 0; i < 6; i++) {
		if (fidonet.zone[i]) {
		    want->zone   = fidonet.zone[0];
		    want->net    = 0;
		    want->node   = 0;
		    want->point  = 0;
		    want->name   = NULL;
		    want->domain = NULL;
		    ta = bestaka_s(want);
		    fprintf(fp, "AKAMATCH %d:* %s\n", fidonet.zone[i], ascfnode(ta, 0xf));
		    tidy_faddr(ta);
		}
	    }
	}
    }

    free(want);
    fprintf(fp, ";\n");
    fprintf(fp, "AKAMATCHNET   YES\n");
    fprintf(fp, "AKAMATCHECHO  YES\n");
    fprintf(fp, "AKAMATCHLOCAL NO\n\n");

    fprintf(fp, "; NODELISTS\n;\n");
    fprintf(fp, "NODEPATH %s/\n", CFG.nodelists);
    fseek(fido, fidonethdr.hdrsize, SEEK_SET);
    while ((fread(&fidonet, fidonethdr.recsize, 1, fido)) == 1) {
	if (fidonet.available) {
	    fprintf(fp, "NODELIST %s.*\n", fidonet.nodelist);
	    for (i = 0; i < 6; i++)
		if (strlen(fidonet.seclist[i].nodelist) || fidonet.seclist[i].zone)
		    fprintf(fp, "NODELIST %s.*\n", fidonet.seclist[i].nodelist);
	}
    }
//  fprintf(fp, "USERLIST golded.lst\n");
    fprintf(fp, "LOOKUPNET   YES\n");
    fprintf(fp, "LOOKUPECHO  NO\n");
    fprintf(fp, "LOOKUPLOCAL NO\n\n");
    fclose(fido);
}
Beispiel #3
0
char *arcname(faddr *addr, unsigned short Zone, int ARCmailCompat)
{
    static char	*buf;
	char	*p;
	char	*ext;
	time_t	tt;
	struct	tm *ptm;
	faddr	*bestaka;

	tt = time(NULL);
	ptm = localtime(&tt);
	ext = dow[ptm->tm_wday];

	bestaka = bestaka_s(addr);

	buf = prepbuf(addr);
	p = strrchr(buf, '/');

	if (!ARCmailCompat && (Zone != addr->zone)) {
		/*
		 * Generate ARCfile name from the CRC of the ASCII string
		 * of the node address.
		 */
		snprintf(p, PATH_MAX -1, "/%08x.%s0", StringCRC32(ascfnode(addr, 0x1f)), ext);
	} else {
		if (addr->point) {
			snprintf(p, PATH_MAX -1, "/%04x%04x.%s0",
				((bestaka->net) - (addr->net)) & 0xffff,
				((bestaka->node) - (addr->node) + (addr->point)) & 0xffff,
				ext);
		} else if (bestaka->point) {
			/*
			 * Inserted the next code for if we are a point,
			 * I hope this is ARCmail 0.60 compliant. 21-May-1999
			 */
			snprintf(p, PATH_MAX -1, "/%04x%04x.%s0", ((bestaka->net) - (addr->net)) & 0xffff,
				((bestaka->node) - (addr->node) - (bestaka->point)) & 0xffff, ext);
		} else {
			snprintf(p, PATH_MAX -1, "/%04x%04x.%s0", ((bestaka->net) - (addr->net)) & 0xffff,
				((bestaka->node) - (addr->node)) &0xffff, ext);
		}
	}

	tidy_faddr(bestaka);
	return buf;
}
Beispiel #4
0
void CloseMail(FILE *qp, faddr *t)
{
    time_t	Now;
    struct tm	*tm;
    faddr	*ta;

    putc('\r', qp);
    Now = time(NULL);
    tm = gmtime(&Now);
    ta = bestaka_s(t);
    fprintf(qp, "\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, qp);
    fclose(qp);
    net_out++;
}
Beispiel #5
0
int Bounce(faddr *f, faddr *t, FILE *fp, char *reason)
{
    int	    rc = 0, count = 0;
    char    *Buf;
    FILE    *np;
    time_t  Now;
    faddr   *from;

    Now = time(NULL);
    if (SearchFidonet(f->zone))
	f->domain = xstrcpy(fidonet.domain);

    Syslog('+', "Bounce msg from %s", ascfnode(f, 0xff));
    Buf = calloc(MAX_LINE_LENGTH +1, sizeof(char));
    rewind(fp);

    np = tmpfile();
    from = bestaka_s(f);
    from->zone  = t->zone;
    from->net   = t->net;
    from->node  = t->node;
    from->point = t->point;
    from->name  = xstrcpy((char *)"Postmaster");

    if (f->point)
	fprintf(np, "\001TOPT %d\r", f->point);
    if (from->point)
	fprintf(np, "\001FMPT %d\r", from->point);
    fprintf(np, "\001INTL %d:%d/%d %d:%d/%d\r", f->zone, f->net, f->node, from->zone, from->net, from->node);

    /*
     * Add MSGID, REPLY and PID
     */
    fprintf(np, "\001MSGID: %s %08x\r", ascfnode(from, 0x1f), sequencer());
    while ((fgets(Buf, MAX_LINE_LENGTH, fp)) != NULL) {
	Striplf(Buf);
	if (strncmp(Buf, "\001MSGID:", 7) == 0) {
	    fprintf(np, "\001REPLY:%s\r", Buf+7);
	}
    }
    fprintf(np, "\001PID: FTND-FIDO %s (%s-%s)\r", VERSION, OsName(), OsCPU());
    fprintf(np, "\001TZUTC: %s\r", gmtoffset(Now));

    fprintf(np, "     Dear %s\r\r", FTND_SS(f->name));
    fprintf(np, "Your message could not be delevered, reason: %s\r\r", reason);
    fprintf(np, "Here are the first lines of the original message from you:\r\r");
    fprintf(np, "======================================================================\r");

    rewind(fp);
    while ((fgets(Buf, MAX_LINE_LENGTH, fp)) != NULL) {
	Striplf(Buf);
	if (Buf[0] == '\001') {
	    fprintf(np, "^a");
	    fwrite(Buf + 1, strlen(Buf) -1, 1, np);
	} else {
	    fwrite(Buf, strlen(Buf), 1, np);
	}
	fputc('\r', np);
	count++;
	if (count == 50)
	    break;
    }
    fprintf(np, "======================================================================\r");
    if (count == 50) {
	fprintf(np, "\rOnly the first 50 lines are displayed\r");
    }

    fprintf(np, "\rWith regards, %s\r\r", CFG.sysop_name);
    fprintf(np, "%s\r", TearLine());
    Now = time(NULL) - (gmt_offset((time_t)0) * 60);
    rc = postnetmail(np, from, f, NULL, (char *)"Bounced message", Now, 0x0000, FALSE, from->zone, f->zone);
    tidy_faddr(from);

    fclose(np);

    free(Buf);
    return rc;
}
Beispiel #6
0
/*
 * Return codes:
 *  0 - All Seems Well
 *  1 - Invalid type (not 2 or 2+)
 *  2 - Read header error
 *  3 - Not for me
 *  4 - Password error
 *  5 - Unsecure session
 *
 *  If session is TRUE, the password is checked as being the session password,
 *  otherwise it is checked as the mail password.
 */
int getheader(faddr *f, faddr *t, FILE *pkt, char *pname, int session)
{
    unsigned char   buffer[0x3a];
    int		    i, capword, prodx, major, minor = 0, tome = FALSE;
    char	    *p, *prodn = NULL, *fa, *ta, buf[5];
    int		    year, month, day, hour, min, sec;

    f->domain = NULL;
    f->name   = NULL;
    t->domain = NULL;
    t->name   = NULL;

    /*
     * Read type 2+ packet header, see FSC-0039 version 4 and FTS-0001
     */
    if (fread(buffer, 1, 0x3a, pkt) != 0x3a) {
        WriteError("Could not read header (%s)", pname);
        return 2;
    }
    if ((buffer[0x12] + (buffer[0x13] << 8)) != 2) {
        WriteError("Not a type 2 packet (%s)", pname);
        return 1;
    }

    f->node = (buffer[0x01] << 8) + buffer[0x00];
    t->node = (buffer[0x03] << 8) + buffer[0x02];
    f->net  = (buffer[0x15] << 8) + buffer[0x14];
    t->net  = (buffer[0x17] << 8) + buffer[0x16];
    f->zone = (buffer[0x23] << 8) + buffer[0x22];
    t->zone = (buffer[0x25] << 8) + buffer[0x24];

    year    = (buffer[0x05] << 8) + buffer[0x04];
    /*
     * Check for Y2K bugs, if there are any this is not important,
     * it is just for logging!
     */
    if (year < 50)
        year = year + 2000;
    else if (year < 1900)
        year = year + 1900;
    month   = (buffer[0x07] << 8) + buffer[0x06] + 1;
    day     = (buffer[0x09] << 8) + buffer[0x08];
    hour    = (buffer[0x0b] << 8) + buffer[0x0a];
    min     = (buffer[0x0d] << 8) + buffer[0x0c];
    sec     = (buffer[0x0f] << 8) + buffer[0x0e];
    prodx   =  buffer[0x18];
    major   =  buffer[0x19];

    capword = (buffer[0x2d] << 8) + buffer[0x2c];
    if (capword != ((buffer[0x28] << 8) + buffer[0x29]))
        capword = 0;

    if (capword & 0x0001) {
        /*
         * FSC-0039 packet type 2+
         */
        prodx     = prodx + (buffer[0x2a] << 8);
        minor     = buffer[0x2b];
        f->zone   = buffer[0x2e] + (buffer[0x2f] << 8);
        t->zone   = buffer[0x30] + (buffer[0x31] << 8);
        f->point  = buffer[0x32] + (buffer[0x33] << 8);
        t->point  = buffer[0x34] + (buffer[0x35] << 8);
    } else {
        /*
         * Stone age @%#$@
         */
        f->zone   = buffer[0x22] + (buffer[0x23] << 8);
        t->zone   = buffer[0x24] + (buffer[0x25] << 8);
        if ((f->zone == 0) && (t->zone == 0)) {
            /*
             * No zone info, since the packet should be for us, guess the zone
             * against our aka's from the setup using a 2d test.
             */
            for (i = 0; i < 40; i++) {
                if ((CFG.akavalid[i]) && (t->net  == CFG.aka[i].net) && (t->node == CFG.aka[i].node)) {
                    t->zone = CFG.aka[i].zone;
                    f->zone = CFG.aka[i].zone;
                    Syslog('!', "Warning, zone %d assumed", CFG.aka[i].zone);
                    break;
                }
            }
        }
    }

    for (i = 0; i < 8; i++)
        pktpwd[i] = buffer[0x1a + i];
    pktpwd[8]='\0';
    for (p = pktpwd + 7; (p >= pktpwd) && (*p == ' '); p--) *p='\0';
    if (pktpwd[0])
        f->name = pktpwd;

    /*
     * Fill in a default product code in case it doesn't exist
     */
    snprintf(buf, 5, "%04x", prodx);
    prodn = xstrcpy((char *)"Unknown 0x");
    prodn = xstrcat(prodn, buf);
    for (i = 0; ftscprod[i].name; i++)
        if (ftscprod[i].code == prodx) {
            free(prodn);
            prodn = xstrcpy(ftscprod[i].name);
            break;
        }

    pktfrom.name   = NULL;
    pktfrom.domain = NULL;
    pktfrom.zone   = f->zone;
    pktfrom.net    = f->net;
    pktfrom.node   = f->node;
    if (capword & 0x0001)
        pktfrom.point = f->point;
    else
        pktfrom.point = 0;

    for (i = 0; i < 40; i++) {
        if ((CFG.akavalid[i]) && ((t->zone == 0) || (t->zone == CFG.aka[i].zone)) &&
                (t->net  == CFG.aka[i].net) && (t->node == CFG.aka[i].node) &&
                ((!(capword & 0x0001)) || (t->point == CFG.aka[i].point) || (t->point && !CFG.aka[i].point)))
            tome = TRUE;
    }

    fa = xstrcpy(ascfnode(f, 0x1f));
    ta = xstrcpy(ascfnode(t, 0x1f));
    Syslog('+', "Packet   : %s type %s", pname, (capword & 0x0001) ? "2+":"stone-age");
    Syslog('+', "From     : %s to %s", fa, ta);
    Syslog('+', "Dated    : %02u-%02u-%u %02u:%02u:%02u", day, month, year, hour, min, sec);
    Syslog('+', "Program  : %s %d.%d", prodn, major, minor);
    free(ta);
    free(fa);

    if (capword & 0x0001) {
        buf[0] = buffer[0x36];
        buf[1] = buffer[0x37];
        buf[2] = buffer[0x38];
        buf[3] = buffer[0x39];
        buf[4] = '\0';
    }

    if (prodn)
        free(prodn);

    if (!tome)
        return 3;

    if (session) {
        /*
         * FTS-0001 session setup mode.
         */
        if (noderecord(f) && strlen(nodes.Spasswd)) {
            if (strcasecmp(nodes.Spasswd, pktpwd) == 0) {
                return 0; /* Secure session */
            } else {
                Syslog('!', "Password : got \"%s\", expected \"%s\"", pktpwd, nodes.Spasswd);
                return 4; /* Bad password */
            }
        } else {
            Syslog('+', "Node not in setup or no password set");
            return 5; /* Unsecure session */
        }
    } else {
        /*
         * Mail password check
         */
        if (noderecord(f) && nodes.MailPwdCheck && strlen(nodes.Epasswd)) {
            if (strcasecmp(nodes.Epasswd, pktpwd) == 0) {
                return 0; /* Password Ok */
            } else {
                Syslog('!', "Password : got \"%s\", expected \"%s\"", pktpwd, nodes.Epasswd);
                return 4; /* Bad password */
            }
        } else {
            return 0; /* Not checked, still Ok */
        }
    }

    return 0;
}
Beispiel #7
0
int ftnmsgid(char *msgid, char **s, unsigned int *n, char *areaname)
{
    char	    *buf, *l, *r, *p;
    unsigned int    nid = 0L;
    faddr	    *tmp;
    static int	    ftnorigin = 0;

    Syslog('m', "Make ftn msgid from \"%s\"", MBSE_SS(msgid));

    if (msgid == NULL) {
	*s = NULL;
	*n = 0L;
	return ftnorigin;
    }

    buf = malloc(strlen(msgid)+65);
    strcpy(buf, msgid);
    if ((l = strchr(buf,'<'))) 
	l++;
    else 
	l = buf;
    while (isspace(*l)) 
	l++;
    if ((r = strchr(l,'>'))) 
	*r = '\0';
    r = l + strlen(l) - 1;
    while (isspace(*r) && (r > l)) 
	(*r--)='\0';
    if ((tmp = parsefaddr(l))) {
	if (tmp->name) {
	    if (strspn(tmp->name,"0123456789") == strlen(tmp->name))
		nid = atoul(tmp->name);
	    else 
		nid = 0xffffffff;
	    if (nid == 0xffffffff) {
		hash_update_s(&nid, tmp->name);
	    } else
		ftnorigin = 1;
	} else {
	    hash_update_s(&nid,l);
	}
	*s = xstrcpy(ascfnode(tmp, 0x1f));
	tidy_faddr(tmp);
    } else {
	if ((r=strchr(l,'@')) == NULL) { /* should never happen */
	    Syslog('!', "ftnmsgid: should never happen: %s", printable(l, 0));
	    *s = xstrcpy(l);
	    hash_update_s(&nid,l);
	/* <*****@*****.**> */
	} else if (strncmp(l,"MSGID_",6) == 0) {
	    *r = '\0';
	    r = strrchr(l+6,'_');
            if (r) 
		*r++ = '\0';
            *s = xstrcpy(l+6);
	    if (r) 
		sscanf(r,"%x",&nid);
	    ftnorigin = 1;
	/* <*****@*****.**> */
	} else if (strncmp(l,"NOMSGID_",8) == 0) {
	    *s = NULL;
	    *n = 0L;
	    ftnorigin = 1;
	    return ftnorigin;
	/* <[email protected]> */
	} else if (strncmp(l,"ftn_",4) == 0) {
	    *r = '\0';
	    if ((r = strchr(l+4,'$')) || (r=strchr(l+4,'#'))) {
		if (*r=='$') 
		    *r='@';
		if ((r=strchr(l+4,'.')))
		    *r=':';
		if ((r=strchr(l+4,'.')))
		    *r='/';
	    }
	    while ((r=strrchr(l+4,'_')) != strchr(l+4,'_')) 
		*r='\0';
	    r=strchr(l+4,'_');
	    *r++='\0';
	    *s=xstrcpy(l+4);
	    sscanf(r,"%x",&nid);
	    ftnorigin=1;
	/* <[email protected]> */
	} else if (strncmp(l,"wgcid$",6) == 0) {
	    *r='\0';
	    if ((r=strstr(l+6,"$g"))) {
		*r='\0';
		*s=xstrcpy(l+6);
		*s=xstrcat(*s,(char *)":");
		l=r+2;
	    }
	    if ((r=strstr(l,"$h"))) {
		*r++='\0';
		*s=xstrcat(*s,l);
		*s=xstrcat(*s,(char *)"/");
		l=r+2;
	    }
	    if ((r=strstr(l,"$i"))) {
		*r='\0';
		*s=xstrcat(*s,l);
		*s=xstrcat(*s,(char *)".");
		l=r+2;
	    }
	    if ((r=strstr(l,"$k"))) {
		*r='\0';
		*s=xstrcat(*s,l);
		*s=xstrcat(*s,(char *)"@");
		l=r+2;
	    }
	    if ((r=strstr(l,"$j"))) {
		*r='\0';
		*s=xstrcat(*s,l);
		sscanf(r+2,"%x",&nid);
	    }
	} else {
	    *r='\0';
	    if ((p=strchr(l,'%'))) {
		*p='\0';
		if (strspn(l,"0123456789") == strlen(l)) {
		    *r='@';
		    r=p;
		} else 
		    *p='%';
	    }
	    r++;
	    if (strspn(l,"0123456789") == strlen(l))
		nid = atoul(l);
	    else 
		nid = 0xffffffff;
	    if (nid == 0xffffffff)
		hash_update_s(&nid,l);
	    *s=xstrcpy(r);
	}
    }
    *n=nid;

    free(buf);
    return ftnorigin;
}
Beispiel #8
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;
}
Beispiel #9
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;
}
Beispiel #10
0
/*
 * Check TIC group AREAS file if requested area exists.
 * If so, create tic area and if SendUplink is TRUE,
 * send the uplink a FileMgr request to connect this area.
 * The tic group record (fgroup) must be in memory.
 * Return codes:
 *  0  - All Seems Well
 *  1  - Some error
 *
 * The current nodes record may be destroyed after this,
 * make sure it is saved.
 */
int CheckTicGroup(char *Area, int SendUplink, faddr *f)
{
    char        *temp, *buf, *tag = NULL, *desc = NULL, *p, *raid = NULL, *flow = NULL;
    FILE        *ap, *mp, *fp;
    int		offset, AreaNr;
    int         i, rc = 0, Found = FALSE;
    sysconnect  System;
    faddr	*From, *To;
    struct _fdbarea *fdb_area = NULL;

    temp = calloc(PATH_MAX, sizeof(char));
    Syslog('f', "Checking file group \"%s\" \"%s\"", fgroup.Name, fgroup.Comment);
    snprintf(temp, PATH_MAX, "%s/%s", CFG.alists_path , fgroup.AreaFile);
    if ((ap = fopen(temp, "r")) == NULL) {
        WriteError("Filegroup %s: area taglist %s not found", fgroup.Name, temp);
        free(temp);
        return 1;
    }

    buf = calloc(4097, sizeof(char));

    if (fgroup.FileGate) {
	/*
	 * filegate.zxx format
	 */
	while (fgets(buf, 4096, ap)) {
	    /*
	     * Each filegroup starts with "% FDN:      Filegroup Description"
	     */
	    if (strlen(buf) && !strncmp(buf, "% FDN:", 6)) {
		tag = strtok(buf, "\t \r\n\0");
		p = strtok(NULL, "\t \r\n\0");
		p = strtok(NULL, "\r\n\0");
		desc = p;
		while ((*desc == ' ') || (*desc == '\t'))
		    desc++;
		if (!strcmp(desc, fgroup.Comment)) {
		    while (fgets(buf, 4096, ap)) {
			if (!strncasecmp(buf, "Area ", 5)) {
			    tag = strtok(buf, "\t \r\n\0");
			    tag = strtok(NULL, "\t \r\n\0");
			    if (!strcasecmp(tag, Area)) {
				raid = strtok(NULL, "\t \r\n\0");
				flow = strtok(NULL, "\t \r\n\0");
				p = strtok(NULL, "\r\n\0");
				desc = p;
				while ((*desc == ' ') || (*desc == '\t'))
				    desc++;
				Syslog('f', "Found area \"%s\" \"%s\" \"%s\" \"%s\"", tag, raid, flow, desc);
				Found = TRUE;
				break;
			    }
			}
			if (strlen(buf) && !strncmp(buf, "% FDN:", 6)) {
			    /*
			     * All entries in group are seen, the area wasn't there.
			     */
			    break;
			}
		    }
		}
		if (Found)
		    break;
	    }
	}
    } else {
	/*
	 * Normal taglist format
	 */
	while (fgets(buf, 4096, ap)) {
	    if (strlen(buf) && isalnum(buf[0])) {
		tag = strtok(buf, "\t \r\n\0");
		p = strtok(NULL, "\r\n\0");
		if (p == NULL)
		    p = tag; /* If no description after the TAG, use TAG as description */
		desc = p;
		while ((*desc == ' ') || (*desc == '\t'))
		    desc++;
		if (strcasecmp(tag, Area) == 0) {
		    Syslog('f', "Found tag \"%s\" desc \"%s\"", tag, desc);
		    Found = TRUE;
		    break;
		}
	    }
	}
    }
    if (!Found) {
	Syslog('f', "Area %s not found in taglist", Area);
	free(buf);
	fclose(ap);
	free(temp);
	return 1;
    }

    /*
     * Some people write taglists with lowercase tagnames...
     */
    for (i = 0; i < strlen(tag); i++)
	tag[i] = toupper(tag[i]);

    Syslog('m', "Found tag \"%s\" desc \"%s\"", tag, desc);

    /*
     * Area is in AREAS file, now create area.
     * If needed, connect at uplink.
     */
    if (SendUplink && SearchNode(fgroup.UpLink)) {
	if (nodes.UplFmgrBbbs)
	    snprintf(temp, PATH_MAX, "file +%s", tag);
	else
	    snprintf(temp, PATH_MAX, "+%s", tag);

	From = fido2faddr(fgroup.UseAka);
	To   = fido2faddr(fgroup.UpLink);
	if (UplinkRequest(To, From, TRUE, temp)) {
	    WriteError("Can't send netmail to uplink");
	    fclose(ap);
	    free(buf);
	    free(temp);
	    tidy_faddr(From);
	    tidy_faddr(To);
	    return 1;
	}
	tidy_faddr(From);
	tidy_faddr(To);
    }

    /*
     * Open tic area and set filepointer to the end to append
     * a new record.
     */
    snprintf(temp, PATH_MAX, "%s/etc/tic.data", getenv("MBSE_ROOT"));
    if ((mp = fopen(temp, "r+")) == NULL) {
	WriteError("$Can't open %s", temp);
	fclose(ap);
	free(buf);
	free(temp);
	return 1;
    }
    fread(&tichdr, sizeof(tichdr), 1, mp);
    fseek(mp, 0, SEEK_END);
    memset(&tic, 0, sizeof(tic));
    Syslog('f', "TIC area open, filepos %ld", ftell(mp));

    /*
     * Open files area, and find a free slot
     */
    snprintf(temp, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
    if ((fp = fopen(temp, "r+")) == NULL) {
	WriteError("$Can't open %s", temp);
	fclose(ap);
	fclose(mp);
	free(buf);
	free(temp);
	return 1;
    }
    fread(&areahdr, sizeof(areahdr), 1, fp);
    Syslog('f', "File area is open");

    /*
     * Verify the file is large enough
     */
    fseek(fp, 0, SEEK_END);
    offset = areahdr.hdrsize + ((fgroup.StartArea -1) * (areahdr.recsize));
    Syslog('+', "file end at %ld, offset needed %ld", ftell(fp), offset);

    if (ftell(fp) < offset) {
	Syslog('f', "Database too small, expanding...");
	memset(&area, 0, sizeof(area));
	while (TRUE) {
	    fwrite(&area, sizeof(area), 1, fp);
	    if (ftell(fp) >= areahdr.hdrsize + ((fgroup.StartArea -1) * (areahdr.recsize)))
		break;
	}
    } 

    if (fseek(fp, offset, SEEK_SET)) {
	WriteError("$Can't seek in %s to position %ld", temp, offset);
	fclose(ap);
	fclose(mp);
	fclose(fp);
	free(buf);
	free(temp);
	return 1;
    }

    /*
     * Search a free record
     */
    Syslog('f', "Start search record");
    while (fread(&area, sizeof(area), 1, fp) == 1) {
	if (!area.Available) {
	    fseek(fp, - areahdr.recsize, SEEK_CUR);
	    rc = 1;
	    break;
	}
    }
 
    if (!rc) {
	Syslog('f', "No free slot, append after last record");
	fseek(fp, 0, SEEK_END);
	if (ftell(fp) < areahdr.hdrsize + ((fgroup.StartArea -1) * (areahdr.recsize))) {
	    Syslog('f', "Database too small, expanding...");
	    memset(&area, 0, sizeof(area));
	    while (TRUE) {
		fwrite(&area, sizeof(area), 1, fp);
		if (ftell(fp) >= areahdr.hdrsize + ((fgroup.StartArea -1) * (areahdr.recsize)))
		    break;
	    }
	}
	rc = 1;
    }
    AreaNr = ((ftell(fp) - areahdr.hdrsize) / (areahdr.recsize)) + 1;
    Syslog('f', "Found free slot at %ld", AreaNr);

    /*
     * Create the records
     */
    memset(&area, 0, sizeof(area));
    strncpy(area.Name, desc, 44);
    strcpy(temp, tag);
    temp = tl(temp);
    for (i = 0; i < strlen(temp); i++)
	if (temp[i] == '.')
	    temp[i] = '/';
    snprintf(area.Path, 81, "%s/%s", fgroup.BasePath, temp);
    area.DLSec = fgroup.DLSec;
    area.UPSec = fgroup.UPSec;
    area.LTSec = fgroup.LTSec;
    area.New = area.Dupes = area.Free = area.AddAlpha = area.FileFind = area.Available = area.FileReq = TRUE;
    strncpy(area.BbsGroup, fgroup.BbsGroup, 12);
    strncpy(area.NewGroup, fgroup.AnnGroup, 12);
    strncpy(area.Archiver, fgroup.Convert, 5);
    area.Upload = fgroup.Upload;
    fwrite(&area, sizeof(area), 1, fp);
    fclose(fp);

    /*
     * Create download path
     */
    snprintf(temp, PATH_MAX, "%s/foobar", area.Path);
    if (!mkdirs(temp, 0775))
	WriteError("Can't create %s", temp);

    /*
     * Create download database
     */
    if ((fdb_area = mbsedb_OpenFDB(AreaNr, 30)))
	mbsedb_CloseFDB(fdb_area);

    /*
     * Setup new TIC area.
     */
    strncpy(tic.Name, tag, 20);
    strncpy(tic.Comment, desc, 55);
    tic.FileArea = AreaNr;
    strncpy(tic.Group, fgroup.Name, 12);
    tic.AreaStart = time(NULL);
    tic.Aka = fgroup.UseAka;
    strncpy(tic.Convert, fgroup.Convert, 5);
    strncpy(tic.Banner, fgroup.Banner, 14);
    tic.Replace = fgroup.Replace;
    tic.DupCheck = fgroup.DupCheck;
    tic.Secure = fgroup.Secure;
    tic.Touch = fgroup.Touch;
    tic.VirScan = fgroup.VirScan;
    tic.Announce = fgroup.Announce;
    tic.UpdMagic = fgroup.UpdMagic;
    tic.FileId = fgroup.FileId;
    tic.ConvertAll = fgroup.ConvertAll;
    tic.SendOrg = fgroup.SendOrg;
    tic.Active = TRUE;
    tic.LinkSec.level = fgroup.LinkSec.level;
    tic.LinkSec.flags = fgroup.LinkSec.flags;
    tic.LinkSec.notflags = fgroup.LinkSec.notflags;
    fwrite(&tic, sizeof(tic), 1, mp);

    memset(&System, 0, sizeof(System));
    System.aka = fgroup.UpLink;
    if (flow && !strcmp(flow, "*&"))
	/*
	 * Areas direction HQ's go the other way
	 */
	System.sendto = TRUE;
    else
	/*
	 * Normal distribution areas.
	 */
	System.receivefrom = TRUE;
    fwrite(&System, sizeof(System), 1, mp);
    memset(&System, 0, sizeof(System));
    for (i = 1; i < (tichdr.syssize / sizeof(System)); i++)
	fwrite(&System, sizeof(System), 1, mp);   

    fclose(mp);
    fclose(ap);
    free(buf);
    free(temp);
    if (f == NULL)
	Mgrlog("Auto created TIC area %s, group %s, bbs area %ld", tic.Name, tic.Group, AreaNr);
    else
	Mgrlog("Auto created TIC area %s, group %s, bbs area %ld, for node %s",
	    tic.Name, tic.Group, AreaNr, ascfnode(f, 0x1f));

    return 0;
}
Beispiel #11
0
int Post(char *To, int Area, char *Subj, char *File, char *Flavor)
{
    int		    i, rc = FALSE, has_tear = FALSE, has_origin = FALSE;
    char	    *aka, *temp, *sAreas;
    FILE	    *fp, *tp;
    unsigned int    crc = -1;
    time_t	    tt;
    struct tm	    *t;

    ftnd_CleanSubject(Subj);

    if (!do_quiet) {
	ftnd_colour(CYAN, BLACK);
	printf("Post \"%s\" to \"%s\" in area %d\n", File, To, Area);
    }

    IsDoing("Posting");
    Syslog('+', "Post \"%s\" area %d to \"%s\" flavor %s", File, Area, To, Flavor);
    Syslog('+', "Subject: \"%s\"", Subj);

    if ((tp = fopen(File, "r")) == NULL) {
	WriteError("$Can't open %s", File);
	if (!do_quiet)
	    printf("Can't open \"%s\"\n", File);
	return -1;
    }

    sAreas = calloc(PATH_MAX, sizeof(char));
    snprintf(sAreas, PATH_MAX, "%s/etc/mareas.data", getenv("FTND_ROOT"));
    if ((fp = fopen(sAreas, "r")) == NULL) {
	WriteError("$Can't open %s", sAreas);
	free(sAreas);
	fclose(tp);
	return -1;
    }

    fread(&msgshdr, sizeof(msgshdr), 1, fp);
    if (fseek(fp, (msgshdr.recsize + msgshdr.syssize) * (Area - 1), SEEK_CUR) == 0) {
	if (fread(&msgs, msgshdr.recsize, 1, fp) == 1) {
	    rc = TRUE;
	} else {
	    WriteError("$Can't read area %ld", Area);
	}
    } else {
	WriteError("$Can't seek area %ld", Area);
    }

    free(sAreas);
    if (rc == FALSE) {
	fclose(fp);
	fclose(tp);
	return -1;
    }

    if (!msgs.Active) {
	WriteError("Area %s not active", msgs.Name);
	fclose(fp);
	fclose(tp);
	return -1;
    }

    /*
     * Check the proper syntax in the To parameter, in netmail areas
     * it must have a destination address, in all other areas just a
     * full name.
     */
    if (msgs.Type == NETMAIL) {
	if ((strchr(To, '@') == NULL) || (strstr(To, (char *)".n") == NULL) || (strstr(To, (char *)".z") == NULL)) {
	    WriteError("No address in \"%s\" and area is netmail", To);
	    if (!do_quiet)
		printf("No address in \"%s\" and area is netmail\n", To);
	    fclose(fp);
	    fclose(tp);
	    return -1;
	}
    } else {
	if ((strchr(To, '@')) || (strstr(To, (char *)".n")) || (strstr(To, (char *)".z"))) {
	    WriteError("Address present in \"%s\" and area is not netmail", To);
	    if (!do_quiet)
		printf("Address present in \"%s\" and area is not netmail\n", To);
	    fclose(fp);
	    fclose(tp);
	    return -1;
	}
    }

    if (!Msg_Open(msgs.Base)) {
	WriteError("Can't open %s", msgs.Base);
	fclose(fp);
	fclose(tp);
	return -1;
    }

    if (!Msg_Lock(30L)) {
	WriteError("Can't lock %s", msgs.Base);
	Msg_Close();
	fclose(fp);
	fclose(tp);
	return -1;
    }

    tt = time(NULL);
    t = localtime(&tt);
    Diw = t->tm_wday;
    Miy = t->tm_mon;
    memset(&Msg, 0, sizeof(Msg));
    Msg_New();

    /*
     * Update statistic counter for message area
     */
    fseek(fp, - msgshdr.recsize, SEEK_CUR);
    msgs.Posted.total++;
    msgs.Posted.tweek++;
    msgs.Posted.tdow[Diw]++;
    msgs.Posted.month[Miy]++;
    fwrite(&msgs, msgshdr.recsize, 1, fp);
    fclose(fp);

    /*
     * Start writing the message
     */
    snprintf(Msg.From, 101, CFG.sysop_name);
    snprintf(Msg.To, 101, To);

    /*
     * If netmail, clean the To field.
     */
    if ((msgs.Type == NETMAIL) && strchr(To, '@')) {
	for (i = 0; i < strlen(Msg.To); i++) {
	    if (Msg.To[i] == '_')
		Msg.To[i] = ' ';
	    if (Msg.To[i] == '@') {
		Msg.To[i] = '\0';
		break;
	    }
	}
    }

    snprintf(Msg.Subject, 101, "%s", Subj);
    snprintf(Msg.FromAddress, 101, "%s", aka2str(msgs.Aka));
    Msg.Written = Msg.Arrived = time(NULL) - (gmt_offset((time_t)0) * 60);
    Msg.Local = TRUE;

    if (strchr(Flavor, 'c'))
	Msg.Crash = TRUE;
    if (strchr(Flavor, 'p'))
	Msg.Private = TRUE;
    if (strchr(Flavor, 'h'))
	Msg.Hold = TRUE;

    switch (msgs.Type) {
	case LOCALMAIL:	
			Msg.Localmail = TRUE;
			break;

	case NETMAIL:
			Msg.Netmail = TRUE;
			snprintf(Msg.ToAddress, 101, "%s", ascfnode(parsefaddr(To), 0xff));
			break;

	case ECHOMAIL:
			Msg.Echomail = TRUE;
			break;

	case NEWS:
			Msg.News = TRUE;
			break;
    }

    temp = calloc(PATH_MAX, sizeof(char));
    snprintf(temp, PATH_MAX, "\001MSGID: %s %08x", aka2str(msgs.Aka), sequencer());
    MsgText_Add2(temp);
    Msg.MsgIdCRC = upd_crc32(temp, crc, strlen(temp));
    Msg.ReplyCRC = 0xffffffff;
    snprintf(temp, PATH_MAX, "\001PID: FTND-FIDO %s (%s-%s)", VERSION, OsName(), OsCPU());
    MsgText_Add2(temp);
    if (msgs.Charset != FTNC_NONE) {
	snprintf(temp, PATH_MAX, "\001CHRS: %s", getftnchrs(msgs.Charset));
    } else {
	snprintf(temp, PATH_MAX, "\001CHRS: %s", getftnchrs(FTNC_LATIN_1));
    }
    MsgText_Add2(temp);
    snprintf(temp, PATH_MAX, "\001TZUTC: %s", gmtoffset(tt));
    MsgText_Add2(temp);

    while ((Fgets(temp, PATH_MAX, tp)) != NULL) {
	if (strncmp(temp, "--- ", 4) == 0)
	    has_tear = TRUE;
	if (strncmp(temp, " * Origin: ", 11) == 0)
	    has_origin = TRUE;
    }
    rewind(tp);
    Syslog('m', "has tearline=%s, has origin=%s", has_tear?"True":"False", has_origin?"True":"False");

    /*
     * Add the file as text
     */
    Msg_Write(tp);
    fclose(tp);

    /*
     * Finish the message
     */
    if ((! has_tear) && (! has_origin)) {
	MsgText_Add2((char *)"");
	MsgText_Add2(TearLine());
    }

    if (! has_origin) {
	aka = calloc(40, sizeof(char));

	if (msgs.Aka.point)
	    snprintf(aka, 40, "(%d:%d/%d.%d)", msgs.Aka.zone, msgs.Aka.net, msgs.Aka.node, msgs.Aka.point);
	else
	    snprintf(aka, 40, "(%d:%d/%d)", msgs.Aka.zone, msgs.Aka.net, msgs.Aka.node);

	if (strlen(msgs.Origin))
	    snprintf(temp, 81, " * Origin: %s %s", msgs.Origin, aka);
	else
	    snprintf(temp, 81, " * Origin: %s %s", CFG.origin, aka);

	MsgText_Add2(temp);
	free(aka);
    }

    Msg_AddMsg();
    Msg_UnLock();
    Syslog('+', "Posted message %ld", Msg.Id);

    if (msgs.Type != LOCALMAIL) {
	snprintf(temp, PATH_MAX, "%s/tmp/%smail.jam", getenv("FTND_ROOT"), (msgs.Type == ECHOMAIL) ? "echo" : "net");
	if ((fp = fopen(temp, "a")) != NULL) {
	    fprintf(fp, "%s %u\n", msgs.Base, Msg.Id);
	    fclose(fp);
	}
	CreateSema((char *)"mailout");
    }

    free(temp);
    Msg_Close();

    return 0;
}
Beispiel #12
0
/*
 *  Start a netmail to one of our nodes in the setup.
 *  Return a file descriptor if success else NULL.
 *  Later the pack routine will add these mails to the outbound.
 */
FILE *SendMgrMail(faddr *t, int Keep, int FileAttach, char *bymgr, char *subj, char *reply)
{
	FILE		*qp;
	time_t		Now;
	fidoaddr	Orig, Dest;
	faddr		From;
	unsigned	flags = M_PVT;
	char		ext[4];

	From = *bestaka_s(t);
	memset(&Orig, 0, sizeof(Orig));
	Orig.zone  = From.zone;
	Orig.net   = From.net;
	Orig.node  = From.node;
	Orig.point = From.point;
	snprintf(Orig.domain, 13, "%s", From.domain);

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

	if (!SearchNode(Dest)) {
		Syslog('!', "SendMgrMail(): Can't find node %s", aka2str(Dest));
		return NULL;
	}

	Syslog('m', "  Netmail from %s to %s", aka2str(Orig), ascfnode(t, 0x1f));

	Now = time(NULL) - (gmt_offset((time_t)0) * 60);
	flags |= (nodes.Crash)            ? M_CRASH    : 0;
	flags |= (FileAttach)             ? M_FILE     : 0;
	flags |= (nodes.Hold)             ? M_HOLD     : 0;

	/*
	 *  Increase counters, update record and reload.
	 */
	StatAdd(&nodes.MailSent, 1L);
	UpdateNode();
	SearchNode(Dest);

	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 ((qp = OpenPkt(Orig, Dest, (char *)ext)) == NULL)
		return NULL;

	if (AddMsgHdr(qp, &From, t, flags, 0, Now, nodes.Sysop, tlcap(bymgr), subj)) {
		fclose(qp);
		return NULL;
	}

	if (Dest.point)
		fprintf(qp, "\001TOPT %d\r", Dest.point);
	if (Orig.point)
		fprintf(qp, "\001FMPT %d\r", Orig.point);

	fprintf(qp, "\001INTL %d:%d/%d %d:%d/%d\r", Dest.zone, Dest.net, Dest.node, Orig.zone, Orig.net, Orig.node);

	/*
	 * Add MSGID, REPLY and PID
	 */
	fprintf(qp, "\001MSGID: %s %08x\r", aka2str(Orig), sequencer());
	if (reply != NULL)
		fprintf(qp, "\001REPLY: %s\r", reply);
	fprintf(qp, "\001PID: MBSE-FIDO %s (%s-%s)\r", VERSION, OsName(), OsCPU());
	fprintf(qp, "\001TZUTC: %s\r", gmtoffset(Now));
	return qp;
}
Beispiel #13
0
int tx_yoohoo(void)
{
    int		    rc;
    unsigned short  capabilities;
    char	    *pwd;

    y_akas = 0;
    if (strlen(nodes.Spasswd))
	pwd = xstrcpy(nodes.Spasswd);
    else
	pwd = NULL;

    capabilities = LOCALCAPS;
    if (localoptions & NOZMODEM) 
	capabilities &= ~(ZED_ZAPPER|ZED_ZIPPER);
    if (localoptions & NOZEDZAP) 
	capabilities &= ~ZED_ZAPPER;
    if (localoptions & NOHYDRA) 
	capabilities &= ~DOES_HYDRA;
    if ((localoptions & NOFREQS) == 0) 
	capabilities |= WZ_FREQ;
    else 
	emsi_local_opts |= OPT_NRQ;

    fillhello(capabilities,pwd);
    iscaller=1;

    if ((rc = txyoohoo()) == 0) {
	rc = rxyoohoo();
	checkhello();
	capabilities = hello2.capabilities;
	if (capabilities & WZ_FREQ) 
	    session_flags |= SESSION_WAZOO;
	else 
	    session_flags &= ~SESSION_WAZOO;
    }

    if (y_akas == 0) {
	Syslog('+', "All akas busy, abort");
	return FTNERR_SESSION_ERROR;
    }
    if ((rc == 0) && ((capabilities & LOCALCAPS) == 0)) {
	Syslog('+', "No common protocols");
	return FTNERR_SESSION_ERROR;
    }

    if (rc) 
	return FTNERR_YOOHOO;

    IsDoing("Outbound %s", ascfnode(remote->addr, 0x0f));
    session_state = STATE_SECURE;

    session_flags |= SESSION_WAZOO;
    if (capabilities & DOES_HYDRA) 
	return hydra(1);
    else if ((capabilities & ZED_ZAPPER) || (capabilities & ZED_ZIPPER)) {
	if (capabilities & ZED_ZAPPER) 
	    emsi_local_protos = PROT_ZAP;
	else 
	    emsi_local_protos = PROT_ZMO;
	return txwazoo();
    } else if (capabilities & Y_DIETIFNA) 
	return txdietifna();
		
    WriteError("YooHoo internal error - no proto for 0x%04xh",capabilities);
    return FTNERR_YOOHOO;
}
Beispiel #14
0
int rx_yoohoo(void)
{
    int		    rc, protect = FALSE;
    unsigned short  capabilities,localcaps;
    char	    *pwd = NULL;
    callstat	    *cst;

    pwd = NULL;
    y_akas = 0;
    localcaps = LOCALCAPS;
    if (localoptions & NOZMODEM) localcaps &= ~(ZED_ZAPPER|ZED_ZIPPER);
    if (localoptions & NOZEDZAP) localcaps &= ~ZED_ZAPPER;
    if (localoptions & NOHYDRA)  localcaps &= ~DOES_HYDRA;
    emsi_local_opts = 0;
    emsi_remote_opts = 0;
    iscaller = 0;

    if ((rc = rxyoohoo()) == 0) {
	Loaded = checkhello();

	if (y_akas == 0) {
	    Syslog('+', "All akas busy, abort");
	    return FTNERR_SESSION_ERROR;
	}

	capabilities = hello2.capabilities;
	if (capabilities & WZ_FREQ) 
	    session_flags |= SESSION_WAZOO;
	else 
	    session_flags &= ~SESSION_WAZOO;
	localcaps &= capabilities;
	if (localcaps & DOES_HYDRA) 
	    localcaps &= DOES_HYDRA;
	else if (localcaps & ZED_ZAPPER) 
	    localcaps &= ZED_ZAPPER;
	else if (localcaps & ZED_ZIPPER) 
	    localcaps &= ZED_ZIPPER;
	else if (localcaps & FTB_USER)   
	    localcaps &= FTB_USER;
	else if (localcaps & Y_DIETIFNA) 
	    localcaps &= Y_DIETIFNA;
	if ((localoptions & NOFREQS) == 0) 
	    localcaps |= WZ_FREQ;
	else 
	    emsi_local_opts |= OPT_NRQ;

	if (((nlent=getnlent(remote->addr))) && (nlent->pflag != NL_DUMMY)) {
	    Syslog('+', "Remote is a listed system");
	    strncpy(history.location, nlent->location, 35);
	    UserCity(mypid, nlent->sysop, nlent->location);
	}
	cst = getstatus(remote->addr);
	if (cst->trystat)
	    laststat = cst->trystat;
	Syslog('s', "Last session status %d", laststat);

	if (nlent) 
	    rdoptions(Loaded);

	if (strlen(nodes.Spasswd)) {
	    if ((strncasecmp((char*)hello2.my_password, nodes.Spasswd, strlen(nodes.Spasswd)) == 0) &&
		(strlen((char*)hello2.my_password) == strlen(nodes.Spasswd))) {
		Syslog('+', "Password correct, protected mail session");
		protect = TRUE;
		pwd = xstrcpy(nodes.Spasswd);
	    } else {
		if (pwd)
		    free(pwd);
		pwd = xstrcpy((char *)"BAD_PASS");
		Syslog('?', "Remote password \"%s\", expected \"%s\"", (char*)hello2.my_password, nodes.Spasswd);
		localcaps = 0;
	    }
	} else
	    Syslog('s', "No YooHoo password check");
	
	inbound_open(remote->addr, protect, FALSE);

	fillhello(localcaps,pwd);
	
	rc = txyoohoo();
	if (pwd)
	    free(pwd);
    }

    if ((rc == 0) && ((localcaps & LOCALCAPS) == 0)) {
	Syslog('+', "No common protocols or bad password");
	return 0;
    }
    if (rc) 
	return FTNERR_YOOHOO;

    IsDoing("Inbound %s", ascfnode(remote->addr, 0x0f));

    if (protect)
	session_state = STATE_SECURE;
    else
	session_state = STATE_UNSECURE;

    session_flags |= SESSION_WAZOO;
    if (localcaps & DOES_HYDRA) 
	return hydra(0);
    else if ((localcaps & ZED_ZAPPER) || (localcaps & ZED_ZIPPER)) {
	if (localcaps & ZED_ZAPPER) 
	    emsi_local_protos = PROT_ZAP;
	else 
	    emsi_local_protos = PROT_ZMO;
	return rxwazoo();
    } else if (localcaps & Y_DIETIFNA) 
	return rxdietifna();
	
    WriteError("YooHoo internal error - no proto for 0x%04xh",localcaps);
    return FTNERR_YOOHOO;
}
Beispiel #15
0
/*
 *  Input a RFC news message.
 */
int rfc2ftn(FILE *fp)
{
    char            sbe[16], *p, *q, *temp, *origin, newsubj[4 * (MAXSUBJ+1)], *oldsubj;
    int             i, rc, newsmode, seenlen, oldnet;
    rfcmsg          *msg = NULL, *tmsg, *tmp;
    ftnmsg          *fmsg = NULL;
    FILE            *ofp, *qfp;
    fa_list         *sbl = NULL, *ptl = NULL, *tmpl;
    faddr           *ta, *fta;
    int             sot_kludge = FALSE, eot_kludge = FALSE, tinyorigin = FALSE;
    int             needsplit, hdrsize, datasize, splitpart, forbidsplit, rfcheaders;
    time_t          Now;
    struct tm	    *l_date;
    char	    *charset = NULL;

    temp = calloc(4097, sizeof(char));
    Syslog('m', "Entering rfc2ftn");
    rewind(fp);
    msg = parsrfc(fp);

    newsmode = hdr((char *)"Newsgroups", msg) ?TRUE:FALSE;
    if (newsmode == FALSE) {
	WriteError("Not a news article");
	return 1;
    }

    if ((fmsg = mkftnhdr(msg, newsmode, NULL)) == NULL) {
	WriteError("Unable to create FTN headers from RFC ones, aborting");
	tidyrfc(msg);
	return 1;
    }

    fmsg->area = xstrcpy(msgs.Tag);
    if ((p = hdr((char *)"Message-ID",msg))) {
	ftnmsgid(p, &fmsg->msgid_a, &fmsg->msgid_n, fmsg->area);
	hash_update_s(&fmsg->msgid_n, fmsg->area);
    }

    if ((p = hdr((char *)"References",msg))) {
	p = strrchr(p,' ');
	ftnmsgid(p,&fmsg->reply_a, &fmsg->reply_n,fmsg->area);

//Griffin
	fmsg->reply_s=calloc(256,sizeof(char));
	findorigmsg(p,fmsg->reply_s);

	fmsg->to->name=calloc(strlen(Msg.From)+1,sizeof(char));
	strcpy(fmsg->to->name,Msg.From);
	Syslog('m', "fmsg to-name %s",fmsg->to->name);
	Syslog('m', "reply_s %s",fmsg->reply_s);

	if (!chkftnmsgid(p)) {
	    hash_update_s(&fmsg->reply_n, fmsg->area);
	}
    } else if ((p = hdr((char *)"In-Reply-To",msg))) {
	ftnmsgid(p,&fmsg->reply_a, &fmsg->reply_n,fmsg->area);
	if (!chkftnmsgid(p)) {
	    hash_update_s(&fmsg->reply_n, fmsg->area);
	}
    }

    chkftnmsgid(hdr((char *)"Message-ID",msg)); // ??
    removemime       = FALSE;
    removemsgid      = FALSE;
    removeref        = FALSE;
    removeinreply    = FALSE;
    removereplyto    = TRUE;
    removereturnto   = TRUE;
    ftnorigin = fmsg->ftnorigin;

    q = hdr((char *)"Content-Transfer-Encoding",msg);
    if (q) 
	while (*q && isspace(*q)) 
	    q++;
    if (!(q)) 
	q = (char *)"8bit"; 
    if ((p = hdr((char *)"Content-Type",msg))) {
	while (*p && isspace(*p)) 
	    p++;

	/*
	 * Check for mime to remove.
	 */
	if ((strncasecmp(p, "text/plain", 10) == 0) && ((q == NULL) || 
		    (strncasecmp(q,"7bit",4) == 0) || (strncasecmp(q,"8bit",4) == 0))) {
	    removemime = TRUE; /* no need in MIME headers */
	}

	q = strtok(p, " \n\0");
	q = strtok(NULL, "; \n\0");
	if (q) {
	    while (*q && isspace(*q))
		q++;
	    Syslog('m', "charset part: %s", printable(q, 0));
	    if (q && (strncasecmp(q, "charset=", 8) == 0)) {
		/*
		 * google.com quotes the charset name
		 */
		if (strchr(q, '"')) {
		    charset = xstrcpy(q + 9);
		    charset[strlen(charset)-1] = '\0';
		    Syslog('m', "Unquoted charset name");
		} else {
		    charset = xstrcpy(q + 8);
		}
		Syslog('m', "Charset \"%s\"", printable(charset, 0));
	    }
	}
    }

    if (charset == NULL) {
	charset = xstrcpy((char *)"ISO-8859-1");
	Syslog('m', "No charset, setting default to iso-8859-1");
    }

    chartran_init(charset, get_ic_ftn(msgs.Charset), 'm');

    if ((p = hdr((char *)"Message-ID",msg))) {
	if (!removemsgid)
	    removemsgid = chkftnmsgid(p);
    }

    if ((!removeref) && (p = hdr((char *)"References",msg))) {
	p = xstrcpy(p);
	q = strtok(p," \t\n");
	if ((q) && (strtok(NULL," \t\n") == NULL))
	    removeref = chkftnmsgid(q);       
	free(p);
    }

    if ((p = hdr((char *)"Reply-To",msg))) {
	removereplyto = FALSE;
	if ((q = hdr((char *)"From",msg))) {
	    char    *r;
	    r = xstrcpy(p); 
	    p = r;
	    while(*p && isspace(*p)) 
		p++;
	    if (p[strlen(p)-1] == '\n')
		p[strlen(p)-1]='\0';
	    if (strcasestr(q,p))
		removereplyto = TRUE;
	}
    }

    if ((p = hdr((char *)"Return-Receipt-To",msg))) {
	removereturnto = FALSE;
	if ((q = hdr((char *)"From",msg))) {
	    char    *r;

	    r = xstrcpy(p); 
	    p = r;
	    while (*p && isspace(*p)) 
		p++;
	    if (p[strlen(p)-1] == '\n') 
		p[strlen(p)-1]='\0';
	    if (strcasestr(q,p)) 
		removereturnto = TRUE;
	}
    }

    Syslog('m', "removemime=%s removemsgid=%s removeref=%s removeinreply=%s removereplyto=%s removereturnto=%s",
		removemime ?"TRUE ":"FALSE", removemsgid ?"TRUE ":"FALSE", removeref ?"TRUE ":"FALSE",
		removeinreply ?"TRUE ":"FALSE", removereplyto ?"TRUE ":"FALSE", removereturnto ?"TRUE ":"FALSE");

    p = ascfnode(fmsg->from,0x1f);
    i = 79-11-3-strlen(p);
    if (ftnorigin && fmsg->origin && (strlen(fmsg->origin) > i)) {
        /* This is a kludge...  I don't like it too much.  But well,
           if this is a message of FTN origin, the original origin (:)
           line MUST have been short enough to fit in 79 chars...
           So we give it a try.  Probably it would be better to keep
           the information about the address format from the origin
           line in a special X-FTN-... header, but this seems even
           less elegant.  Any _good_ ideas, anyone? */

        /* OK, I am keeping this, though if should never be used
           al long as X-FTN-Origin is used now */

	p = ascfnode(fmsg->from,0x0f);
	Syslog('m', "checkorigin 3");
	i = 79-11-3-strlen(p);
	tinyorigin = TRUE;
    }
    if (tinyorigin)
	Syslog('m', "tinyorigin = %s", tinyorigin ? "True":"False");

    if ((fmsg->origin) && (strlen(fmsg->origin) > i))
	fmsg->origin[i]='\0';
    forbidsplit = (ftnorigin || ((p = hdr((char *)"X-FTN-Split",msg))  && (strcasecmp(p," already\n") == 0)));
    needsplit = 0;
    splitpart = 0;
    hdrsize = 20;
    hdrsize += (fmsg->subj)?strlen(fmsg->subj):0;
    if (fmsg->from)
	hdrsize += (fmsg->from->name)?strlen(fmsg->from->name):0;
    if (fmsg->to)
	hdrsize += (fmsg->to->name)?strlen(fmsg->to->name):0;
    do {
	Syslog('m', "split loop, splitpart = %d", splitpart);
	datasize = 0;

	if (splitpart) {
	    snprintf(newsubj,4 * (MAXSUBJ+1),"[part %d] ",splitpart+1);
	    strncat(newsubj,fmsg->subj,MAXSUBJ-strlen(newsubj));
	} else {
	    strncpy(newsubj,fmsg->subj,MAXSUBJ);
	}
	newsubj[MAXSUBJ]='\0';

	if (splitpart) {
	    hash_update_n(&fmsg->msgid_n,splitpart);
	}
	oldsubj = fmsg->subj;
	fmsg->subj = newsubj;

	/*
	 * Create a new temp message in FTN style format
	 */
	if ((ofp = tmpfile()) == NULL) {
	    WriteError("$Can't open second tmpfile");
	    tidyrfc(msg);
	    return 1;
	}

	if ((fmsg->msgid_a == NULL) && (fmsg->msgid_n == 0)) {
	    Syslog('n', "No Messageid from poster, creating new MSGID");
	    fprintf(ofp, "\001MSGID: %s %08x\n", aka2str(msgs.Aka), sequencer());
	} else {
	    fprintf(ofp, "\001MSGID: %s %08x\n", MBSE_SS(fmsg->msgid_a),fmsg->msgid_n);
	}
	if (fmsg->reply_s) 
	    fprintf(ofp, "\1REPLY: %s\n", fmsg->reply_s);
	else if (fmsg->reply_a)
	    fprintf(ofp, "\1REPLY: %s %08x\n", fmsg->reply_a, fmsg->reply_n);
	Now = time(NULL) - (gmt_offset((time_t)0) * 60);
	fprintf(ofp, "\001TZUTC: %s\n", gmtoffset(Now));
	fprintf(ofp, "\001CHRS: %s\n", getftnchrs(msgs.Charset));
	
	fmsg->subj = oldsubj;
	if ((p = hdr((char *)"X-FTN-REPLYADDR",msg))) {
	    hdrsize += 10+strlen(p);
	    fprintf(ofp,"\1REPLYADDR:");
	    kludgewrite(p,ofp);
	} else if (replyaddr) {
	    hdrsize += 10+strlen(replyaddr);
	    fprintf(ofp,"\1REPLYADDR: ");
	    kludgewrite(replyaddr,ofp);
	}
	if ((p = hdr((char *)"X-FTN-REPLYTO",msg))) {
	    hdrsize += 8+strlen(p);
	    fprintf(ofp,"\1REPLYTO:");
	    kludgewrite(p,ofp);
	} else if (replyaddr) {
	    hdrsize += 15;
	    if (newsmode)
		fprintf(ofp,"\1REPLYTO: %s UUCP\n", aka2str(msgs.Aka));
	    else {
		fta = bestaka_s(fmsg->to);
		fprintf(ofp,"\1REPLYTO: %s UUCP\n", ascfnode(fta, 0x1f));
		tidy_faddr(fta);
	    }
	} else if ((p = hdr((char *)"Reply-To",msg))) {
	    if ((ta = parsefaddr(p))) {
		if ((q = hdr((char *)"From",msg))) {
		    if (!strcasestr(q,p)) {
			fprintf(ofp,"\1REPLYTO: %s %s\n", ascfnode(ta,0x1f), ta->name);
		    }
		}
		tidy_faddr(ta);
	    }
	}
	if ((p=strip_flags(hdr((char *)"X-FTN-FLAGS",msg)))) {
	    hdrsize += 15;
	    fprintf(ofp,"\1FLAGS:%s\n",p);
	    free(p);
	}
	if (!hdr((char *)"X-FTN-PID", msg)) { 
	    p = hdr((char *)"User-Agent", msg);
	    if (p == NULL) 
		p = hdr((char *)"X-Newsreader", msg);
	    if (p == NULL) 
		p = hdr((char *)"X-Mailer", msg);
	    if (p) {
		hdrsize += 4 + strlen(p);
		fprintf(ofp, "\1PID:");
		kludgewrite(p, ofp);
	    } else {
		fprintf(ofp, "\001PID: MBSE-NNTPD %s (%s-%s)\n", VERSION, OsName(), OsCPU());
	    }
	}

	if (!(hdr((char *)"X-FTN-Tearline", msg)) && !(hdr((char *)"X-FTN-TID", msg))) {
	    snprintf(temp, 4096, " MBSE-NNTPD %s (%s-%s)", VERSION, OsName(), OsCPU());
	    hdrsize += 4 + strlen(temp);
	    fprintf(ofp, "\1TID:");
	    kludgewrite(temp, ofp);
	}

	if ((splitpart == 0) || (hdrsize < MAXHDRSIZE)) {
	    for (tmp = msg; tmp; tmp = tmp->next) {
	 	if ((!strncmp(tmp->key,"X-Fsc-",6)) || (!strncmp(tmp->key,"X-FTN-",6) &&
			strcasecmp(tmp->key,"X-FTN-Tearline") &&
			strcasecmp(tmp->key,"X-FTN-Origin") &&
			strcasecmp(tmp->key,"X-FTN-Sender") &&
			strcasecmp(tmp->key,"X-FTN-Split") &&
			strcasecmp(tmp->key,"X-FTN-FLAGS") &&
			strcasecmp(tmp->key,"X-FTN-AREA") &&
			strcasecmp(tmp->key,"X-FTN-MSGID") &&
			strcasecmp(tmp->key,"X-FTN-REPLY") &&
			strcasecmp(tmp->key,"X-FTN-SEEN-BY") &&
			strcasecmp(tmp->key,"X-FTN-PATH") &&
			strcasecmp(tmp->key,"X-FTN-REPLYADDR") &&
			strcasecmp(tmp->key,"X-FTN-REPLYTO") &&
			strcasecmp(tmp->key,"X-FTN-To") &&
			strcasecmp(tmp->key,"X-FTN-From") &&
			strcasecmp(tmp->key,"X-FTN-CHARSET") &&
			strcasecmp(tmp->key,"X-FTN-CHRS") &&
			strcasecmp(tmp->key,"X-FTN-CODEPAGE") &&
			strcasecmp(tmp->key,"X-FTN-ORIGCHRS") &&
			strcasecmp(tmp->key,"X-FTN-SOT") &&
			strcasecmp(tmp->key,"X-FTN-EOT") &&
			strcasecmp(tmp->key,"X-FTN-Via"))) {
		    if ((strcasecmp(tmp->key,"X-FTN-KLUDGE") == 0)) {
			if (!strcasecmp(tmp->val," SOT:\n"))
			    sot_kludge = TRUE;
			else if (!strcasecmp(tmp->val," EOT:\n"))
			    eot_kludge = TRUE;
			else {
			    hdrsize += strlen(tmp->val);
			    fprintf(ofp,"\1");
			    /* we should have restored the original string here... */
			    kludgewrite((tmp->val)+1,ofp);
			}
		    } else {
			hdrsize += strlen(tmp->key)+strlen(tmp->val);
			fprintf(ofp,"\1%s:",tmp->key+6);
			kludgewrite(tmp->val,ofp);
		    }
		}
	    }

	    /* ZConnect are X-ZC-*: in usenet, \1ZC-*: in FTN */
	    for (tmp=msg;tmp;tmp=tmp->next)
		if ((!strncmp(tmp->key,"X-ZC-",5))) {
		    hdrsize += strlen(tmp->key)+strlen(tmp->val);
		    fprintf(ofp,"\1%s:",tmp->key+2);
		    kludgewrite(tmp->val,ofp);
		}

	    /* mondo.org gateway uses ".MSGID: ..." in usenet */
	    for (tmp=msg;tmp;tmp=tmp->next)
		if ((!strncmp(tmp->key,".",1)) && (strcasecmp(tmp->key,".MSGID"))) {
		    hdrsize += strlen(tmp->key)+strlen(tmp->val);
		    fprintf(ofp,"\1%s:",tmp->key+1);
		    kludgewrite(tmp->val,ofp);
		}

	    for (tmp = msg; tmp; tmp = tmp->next) {
		if ((needputrfc(tmp, newsmode) == 1)) {
		    if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) {
			hdrsize += 10+strlen(tmp->val);
			fprintf(ofp,"\1RFC-Newsgroups:");
		    } else {
			hdrsize += strlen(tmp->key)+strlen(tmp->val);
			fprintf(ofp,"\1RFC-%s:",tmp->key);
		    }
		    kludgewrite(tmp->val, ofp);
		}
	    }

	    rfcheaders=0;
	    for (tmp=msg;tmp;tmp=tmp->next) {
		if ((needputrfc(tmp, newsmode) > 1)) {
		    rfcheaders++;
		    if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) {
			hdrsize += 10+strlen(tmp->val);
			fprintf(ofp,"Newsgroups:");
		    } else {
			hdrsize += strlen(tmp->key)+strlen(tmp->val);
			fprintf(ofp,"%s:",tmp->key);
		    }
		    charwrite(tmp->val, ofp);
		}
	    }

	    if (rfcheaders) 
		charwrite((char *)"\n",ofp);
	    if ((hdr((char *)"X-FTN-SOT",msg)) || (sot_kludge))
		fprintf(ofp,"\1SOT:\n");
	}
	if (replyaddr) {
	    replyaddr = NULL;
	}

	if (needsplit) {
	    fprintf(ofp," * Continuation %d of a split message *\n\n", splitpart);
	    needsplit = FALSE;
	} else if ((p=hdr((char *)"X-Body-Start",msg))) {
	    datasize += strlen(p);
	    charwrite(p, ofp);
	}
	while (!(needsplit=(!forbidsplit) && (((splitpart && (datasize > (CFG.new_split * 1024))) ||
		      (!splitpart && ((datasize+hdrsize) > (CFG.new_split * 1024)))))) && (bgets(temp,4096-1,fp))) {
	    datasize += strlen(temp);
	    charwrite(temp, ofp);
	}

	if (needsplit) {
	    fprintf(ofp,"\n * Message split, to be continued *\n");
	    splitpart++;
	}
	if ((p=hdr((char *)"X-FTN-EOT",msg)) || (eot_kludge))
	    fprintf(ofp,"\1EOT:\n");

	if ((p=hdr((char *)"X-FTN-Tearline",msg))) {
	    fprintf(ofp,"---");
	    if (strcasecmp(p," (none)\n") == 0)
		charwrite((char *)"\n",ofp);
	    else
		charwrite(p,ofp);
	} else
	    fprintf(ofp,"\n%s\n", TearLine());

	if ((p = hdr((char *)"X-FTN-Origin",msg))) {
	    if (*(q=p+strlen(p)-1) == '\n') 
		*q='\0';
	    origin = xstrcpy((char *)" * Origin: ");
	    origin = xstrcat(origin, p);
	} else {
	    origin = xstrcpy((char *)" * Origin: ");
	    if (fmsg->origin)
		origin = xstrcat(origin, fmsg->origin);
	    else
		origin = xstrcat(origin, CFG.origin);
	    origin = xstrcat(origin, (char *)" (");
	    origin = xstrcat(origin, ascfnode(fmsg->from,tinyorigin?0x0f:0x1f));
	    origin = xstrcat(origin, (char *)")");
	}
	fprintf(ofp, "%s", origin);

	if (newsmode) {
	    /*
	     * Setup SEEN-BY lines, first SEEN-BY from RFC message, then all matching AKA's
	     */
	    for (tmsg = msg; tmsg; tmsg = tmsg->next)
		if (strcasecmp(tmsg->key, "X-FTN-SEEN-BY") == 0)
		    fill_list(&sbl, tmsg->val, NULL);
	    for (i = 0; i < 40; i++) {
		if (CFG.akavalid[i] && (CFG.aka[i].point == 0) && (msgs.Aka.zone == CFG.aka[i].zone) &&
				    !((msgs.Aka.net == CFG.aka[i].net) && (msgs.Aka.node == CFG.aka[i].node))) {
		    snprintf(sbe, 16, "%u/%u", CFG.aka[i].net, CFG.aka[i].node);
		    fill_list(&sbl, sbe, NULL);
		}
	    }
	    if (msgs.Aka.point == 0) {
		snprintf(sbe, 16, "%u/%u", msgs.Aka.net, msgs.Aka.node);
		fill_list(&sbl, sbe, NULL);
	    }

	    /*
	     *  Only add SEEN-BY lines if there are any
	     */
	    if (sbl != NULL) {
		uniq_list(&sbl);
		sort_list(&sbl);
		seenlen = MAXSEEN + 1;
		memset(&sbe, 0, sizeof(sbe));
		/* ensure it will not match for the first entry */
		oldnet = sbl->addr->net-1;
		for (tmpl = sbl; tmpl; tmpl = tmpl->next) {
		    if (tmpl->addr->net == oldnet)
			snprintf(sbe,16," %u",tmpl->addr->node);
		    else
			snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node);
		    oldnet = tmpl->addr->net;
		    seenlen += strlen(sbe);
		    if (seenlen > MAXSEEN) {
			seenlen = 0;
			fprintf(ofp,"\nSEEN-BY:");
			snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node);
			seenlen = strlen(sbe);
		    }
		    fprintf(ofp,"%s",sbe);
		}
		tidy_falist(&sbl);
	    }

	    /*
	     *  Setup PATH lines
	     */
	    for (tmp = msg; tmp; tmp = tmp->next)
		if (!strcasecmp(tmp->key,"X-FTN-PATH"))
		    fill_path(&ptl,tmp->val);
	    if (msgs.Aka.point == 0) {
	        snprintf(sbe,16,"%u/%u",msgs.Aka.net, msgs.Aka.node);
		fill_path(&ptl,sbe);
	    }

	    /*
	     *  Only add PATH line if there is something
	     */
	    if (ptl != NULL) {
		uniq_list(&ptl);
		seenlen = MAXPATH+1;
		/* ensure it will not match for the first entry */
		oldnet = ptl->addr->net-1;
		for (tmpl = ptl; tmpl; tmpl = tmpl->next) {
		    if (tmpl->addr->net == oldnet)
			snprintf(sbe,16," %u",tmpl->addr->node);
		    else
			snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node);
		    oldnet = tmpl->addr->net;
		    seenlen += strlen(sbe);
		    if (seenlen > MAXPATH) {
			seenlen = 0;
			fprintf(ofp,"\n\1PATH:");
			snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node);
			seenlen = strlen(sbe);
		    }
		    fprintf(ofp,"%s",sbe);
		}
		tidy_falist(&ptl);
	    }
	} /* if (newsmode) */

	/*
	 *  Add newline and message is ready.
	 */
	fprintf(ofp,"\n");
	fflush(ofp);
	rewind(ofp);

	Syslog('m', "========== Fido start");
	while (fgets(temp, 4096, ofp) != NULL) {
	    /*
	     *  Only log kludges, skip the body
	     */
	    if ((temp[0] == '\001') || !strncmp(temp, "AREA:", 5) || !strncmp(temp, "SEEN-BY", 7)) {
		Striplf(temp);
		Syslogp('m', printable(temp, 0));
	    }
	}
	Syslog('m', "========== Fido end");

	if (!Msg_Open(msgs.Base)) {
	    WriteError("Failed to open msgbase \"%s\"", msgs.Base);
	} else {
	    if (!Msg_Lock(30L)) {
		WriteError("Can't lock %s", msgs.Base);
	    } else {
		Msg_New();
		strcpy(Msg.From, fmsg->from->name);
		strcpy(Msg.To, fmsg->to->name);
		strcpy(Msg.FromAddress, ascfnode(fmsg->from,0x1f));
		strcpy(Msg.Subject, fmsg->subj);
		Msg.Written = Msg.Arrived = time(NULL) - (gmt_offset((time_t)0) * 60);
		Msg.Local = TRUE;
		rewind(ofp);
		while (fgets(temp, 4096, ofp) != NULL) {
		    Striplf(temp);
		    MsgText_Add2(temp);
		}

		Msg_AddMsg();
		Msg_UnLock();
		Syslog('+', "Msg (%ld) to \"%s\", \"%s\"", Msg.Id, Msg.To, Msg.Subject);
		do_mailout = TRUE;

		/*
		 * Create fast scan index
		 */
		snprintf(temp, PATH_MAX, "%s/tmp/echomail.jam", getenv("MBSE_ROOT"));
		if ((qfp = fopen(temp, "a")) != NULL) {
		    fprintf(qfp, "%s %u\n", msgs.Base, Msg.Id);
		    fclose(qfp);
		}

		/*
		 * Link messages
		 */
		rc = Msg_Link(msgs.Base, TRUE, CFG.slow_util);
		if (rc != -1)
		    Syslog('+', "Linked %d message%s", rc, (rc != 1) ? "s":"");
		else
		    Syslog('+', "Could not link messages");

		/*
		 * Update statistical counters
		 */
		Now = time(NULL);
		l_date = localtime(&Now);
		msgs.LastPosted = time(NULL);
		msgs.Posted.total++;
		msgs.Posted.tweek++;
		msgs.Posted.tdow[l_date->tm_wday]++;
		msgs.Posted.month[l_date->tm_mon]++;
		mgroup.LastDate = time(NULL);
		mgroup.MsgsSent.total++;
		mgroup.MsgsSent.tweek++;
		mgroup.MsgsSent.tdow[l_date->tm_wday]++;
		mgroup.MsgsSent.month[l_date->tm_mon]++;
		UpdateMsgs();

		snprintf(temp, PATH_MAX, "%s/etc/users.data", getenv("MBSE_ROOT"));
		if ((qfp = fopen(temp, "r+"))) {
		    fread(&usrconfighdr, sizeof(usrconfighdr), 1, qfp);
		    fseek(qfp, usrconfighdr.hdrsize + (grecno * usrconfighdr.recsize), SEEK_SET);
		    if (fread(&usrconfig, usrconfighdr.recsize, 1, qfp) == 1) {
			usrconfig.iPosted++;
			fseek(qfp, usrconfighdr.hdrsize + (grecno * usrconfighdr.recsize), SEEK_SET);
			fwrite(&usrconfig, usrconfighdr.recsize, 1, qfp);
		    }
		    fclose(qfp);
		}
	    }
	    Msg_Close();
	}
	
	free(origin);
        fclose(ofp);
    } while (needsplit);
    free(temp);
    if (charset)
	free(charset);
    chartran_close();
    tidyrfc(msg);
    tidy_ftnmsg(fmsg);
    UpdateMsgs();

    return 0;
}
Beispiel #16
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);
}
Beispiel #17
0
file_list *create_filelist(fa_list *al, char *fl, int create)
{
    file_list	    *st = NULL, *tmpf;
    fa_list	    *tmpa;
    char	    flavor, *tmpfl, *nm, *temp, tmpreq[13], digit[6], *temp2;
    struct stat	    stbuf;
    int		    packets = 0;
    FILE	    *fp;
    unsigned char   buffer[2];
    faddr	    *fa;
    DIR		    *dp = NULL;
    struct dirent   *de;
    struct stat     sb;

    Syslog('o', "Create_filelist(%s,\"%s\",%d)", al?ascfnode(al->addr,0x1f):"<none>", MBSE_SS(fl), create);
    made_request = 0;

    for (tmpa = al; tmpa; tmpa = tmpa->next) {
	Syslog('o', "Check address %s", ascfnode(tmpa->addr, 0x1f));

	/*
	 * For the main aka, check the outbox.
	 */
	if ((tmpa->addr) && Loaded && strlen(nodes.OutBox) &&
	    (tmpa->addr->zone == nodes.Aka[0].zone) && (tmpa->addr->net == nodes.Aka[0].net) &&
	    (tmpa->addr->node == nodes.Aka[0].node) && (tmpa->addr->point == nodes.Aka[0].point)) {
	    check_filebox(nodes.OutBox, &st);
	}

	/*
	 * Check spool files, these are more or less useless but they
	 * create a filelist of files to send which are never send.
	 * It gives the transfer protocols something "to do".
	 */
	if (strchr(fl, 'o')) {
	    nm = splname(tmpa->addr);
	    if ((fp = fopen(nm, "w"))) 
		fclose(fp);
	    if ((nm != NULL) && (stat(nm, &stbuf) == 0))
		add_list(&st, nm, NULL, DSF, 0L, NULL, 1);
	}

	/*
	 * Check .pol files
	 */
	nm = polname(tmpa->addr);
	if ((nm != NULL) && (stat(nm,&stbuf) == 0))
	    add_list(&st,nm,NULL,DSF,0L,NULL,1);

	/*
	 * Check other files, all flavors
	 */
	tmpfl = fl;
	while ((flavor = *tmpfl++)) {

	    Syslog('o', "Check flavor %c", flavor);
	    /*
	     * Check normal mail packets
	     */
	    nm = pktname(tmpa->addr,flavor);
	    if ((nm != NULL) && (stat(nm,&stbuf) == 0)) {
		Syslog('o', "found %s", nm);
		packets++;
		add_list(&st, nm, tmpkname(), KFS, 0L, NULL, 1);
	    }

	    /*
	     * Check .flo files for file attaches
	     */
	    nm = floname(tmpa->addr,flavor);
	    check_flo(&st, nm);
	}

	if ((session_flags & SESSION_WAZOO) &&
	    ((session_flags & SESSION_HYDRA) == 0) && (master || ((session_flags & SESSION_IFNA) == 0))) {
	    /*
	     * we don't distinguish flavoured reqs
	     */
	    nm = reqname(tmpa->addr);
	    if ((nm != NULL) && (stat(nm, &stbuf) == 0)) {
		snprintf(tmpreq, 13, "%04X%04X.REQ", tmpa->addr->net, tmpa->addr->node);
		add_list(&st, nm, tmpreq, DSF, 0L, NULL, 1);
		made_request = 1;
	    }
	}
    }

    /*
     * Check T-Mail style fileboxes
     */
    temp = calloc(PATH_MAX, sizeof(char));
    if (strlen(CFG.tmailshort) && (dp = opendir(CFG.tmailshort))) {
       Syslog('o', "Checking T-Mail short box \"%s\"", CFG.tmailshort);
       while ((de = readdir(dp))) {
           if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {
               snprintf(temp, PATH_MAX -1, "%s/%s", CFG.tmailshort, de->d_name);
               if (stat(temp, &sb) == 0) {
                   Syslog('o' ,"checking \"%s\"", de->d_name);
                   if (S_ISDIR(sb.st_mode)) {
                       int i;
                       char b=0;
                       for (i=0; (i<8) && (!b); ++i) {
                           char c = tolower(de->d_name[i]);
                           if ( (c<'0') || (c>'v') || ((c>'9') && (c<'a')) ) 
			       b=1;
                       }
                       if (de->d_name[8]!='.') 
			   b=1;
                       for (i=9; (i<11) && (!b); ++i) {
                           char c = tolower(de->d_name[i]);
                           if ( (c<'0') || (c>'v') || ((c>'9') && (c<'a')) ) 
			       b=1;
                       }
                       if (b) 
			   continue;
                       if (de->d_name[11]==0) 
			   flavor='o';
                       else if ((tolower(de->d_name[11])=='h') && (de->d_name[12]==0)) 
			   flavor='h';
                       else 
			   continue;
                       fa = (faddr*)malloc(sizeof(faddr));
                       fa->name = NULL;
                       fa->domain = NULL;
                       memset(&digit, 0, sizeof(digit));
                       digit[0] = de->d_name[0];
                       digit[1] = de->d_name[1];
                       fa->zone = strtol(digit, NULL, 32);
                       memset(&digit, 0, sizeof(digit));
                       digit[0] = de->d_name[2];
                       digit[1] = de->d_name[3];
                       digit[2] = de->d_name[4];
                       fa->net = strtol(digit, NULL, 32);
                       memset(&digit, 0, sizeof(digit));
                       digit[0] = de->d_name[5];
                       digit[1] = de->d_name[6];
                       digit[2] = de->d_name[7];
                       fa->node = strtol(digit, NULL, 32);
                       memset(&digit, 0, sizeof(digit));
                       digit[0] = de->d_name[9];
                       digit[1] = de->d_name[10];
                       fa->point = strtol(digit, NULL, 32);
                       for (tmpa = al; tmpa; tmpa = tmpa->next) {
                           if ((fa->zone==tmpa->addr->zone) && (fa->net==tmpa->addr->net) && 
			       (fa->node==tmpa->addr->node) && (fa->point==tmpa->addr->point) && strchr(fl, flavor))
				if (SearchFidonet(tmpa->addr->zone))
				    check_filebox(temp, &st);
                       }
                       tidy_faddr(fa);
                   }
               }
           }
       }
       closedir(dp);
    }

    if (strlen(CFG.tmaillong) && (dp = opendir(CFG.tmaillong))) {
       temp2 = calloc(PATH_MAX, sizeof(char));
       Syslog('o', "Checking T-Mail long box \"%s\"", CFG.tmaillong);
       while ((de = readdir(dp))) {
           if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {
               snprintf(temp, PATH_MAX -1, "%s/%s", CFG.tmaillong, de->d_name);
               if (stat(temp, &sb) == 0) {
                   Syslog('o' ,"checking \"%s\"", de->d_name);
                   if (S_ISDIR(sb.st_mode)) {
                       char c, d;
                       int n;
                       snprintf(temp2, PATH_MAX -1, "%s", de->d_name);
                       fa = (faddr*)malloc(sizeof(faddr));
                       fa->name = NULL;
                       fa->domain = NULL;
                       n = sscanf(temp2, "%u.%u.%u.%u.%c%c", &(fa->zone), &(fa->net), &(fa->node), &(fa->point), &c, &d);
                       if ((n==4) || ((n==5) && (tolower(c)=='h'))) {
                           if (n==4) 
			       flavor = 'o';
                           else 
			       flavor = 'h';
                           for (tmpa = al; tmpa; tmpa = tmpa->next) {
                               if ((fa->zone==tmpa->addr->zone) && (fa->net==tmpa->addr->net) && 
				    (fa->node==tmpa->addr->node) && (fa->point==tmpa->addr->point) && 
				    strchr(fl, flavor))
				  if (SearchFidonet(tmpa->addr->zone)) 
					check_filebox(temp, &st);
                           }
                       }
                       tidy_faddr(fa);
                   }   
               }
           }
       }
       closedir(dp);
       free(temp2);
    }
    free(temp);


    /*
     * For FTS-0001 we need to create at least one packet.
     */
    if (((st == NULL) && (create > 1)) || ((st != NULL) && (packets == 0) && (create > 0))) {
	Syslog('o', "Create packet for %s", ascfnode(al->addr,0x1f));
	if ((fp = openpkt(NULL, al->addr, 'o', TRUE))) {
	    memset(&buffer, 0, sizeof(buffer));
	    fwrite(buffer, 1, 2, fp);
	    fclose(fp);
	}
	add_list(&st, pktname(al->addr,'o'), tmpkname(), KFS, 0L, NULL, 0);
    }

    for (tmpf = st; tmpf; tmpf = tmpf->next)
	Syslog('o',"flist: \"%s\" -> \"%s\" dsp:%d flofp:%p floff:%p",
		MBSE_SS(tmpf->local), MBSE_SS(tmpf->remote), tmpf->disposition,
		tmpf->flofp, tmpf->floff);

    return st;
}
Beispiel #18
0
/*
 *  Input a RFC message.
 */
int rfc2ftn(FILE *fp, faddr *recipient)
{
    char            sbe[128], *p, *q, *temp, *origin, newsubj[4 * (MAXSUBJ+1)], *oldsubj, *acup_a = NULL, *charset = NULL;
    int             i, rc, newsmode, seenlen, oldnet, chars_in = FTNC_NONE, chars_out = FTNC_NONE;
    rfcmsg          *msg = NULL, *tmsg, *tmp;
    ftnmsg          *fmsg = NULL;
    FILE            *ofp;
    fa_list         *sbl = NULL, *ptl = NULL, *tmpl;
    faddr           *ta, *fta;
    unsigned int    acup_n = 0;
    int             sot_kludge = FALSE, eot_kludge = FALSE, tinyorigin = FALSE;
    int             needsplit, hdrsize, datasize, splitpart, forbidsplit, rfcheaders;
    time_t          Now;

    temp = calloc(MAXHDRSIZE +1, sizeof(char));
    Syslog('m', "Entering rfc2ftn");
    if (recipient)
	Syslog('m', "Recipient: %s", ascfnode(recipient, 0xff));
    rewind(fp);
    msg = parsrfc(fp);

    newsmode = hdr((char *)"Newsgroups", msg) ?TRUE:FALSE;
    Syslog('m', "RFC message is %s", newsmode ? "news article":"e-mail message");

    if (newsmode) {
	news_in++;
	snprintf(currentgroup, 81, "%s", msgs.Newsgroup);
    } else
	email_in++;
    
    if (!CFG.allowcontrol) {
	if (hdr((char *)"Control",msg)) {
	    Syslog('+', "Rfc2ftn: Control message skipped");
	    tidyrfc(msg);
	    return 1;
	}
    }
    
    if ((fmsg = mkftnhdr(msg, newsmode, recipient)) == NULL) {
	WriteError("Rfc2ftn: unable to create FTN headers from RFC ones, aborting");
	tidyrfc(msg);
	return 1;
    }
    
    if (newsmode)
	fmsg->area = xstrcpy(msgs.Tag);
    if ((p = hdr((char *)"Message-ID",msg))) {
	ftnmsgid(p, &fmsg->msgid_a, &fmsg->msgid_n, fmsg->area);
	hash_update_s(&fmsg->msgid_n, fmsg->area);
    }

    if ((p = hdr((char *)"References",msg))) {
	p = strrchr(p,' ');
	ftnmsgid(p,&fmsg->reply_a, &fmsg->reply_n,fmsg->area);
	if (!chkftnmsgid(p)) {
	    hash_update_s(&fmsg->reply_n, fmsg->area);
	}
    } else if ((p = hdr((char *)"In-Reply-To",msg))) {
	ftnmsgid(p,&fmsg->reply_a, &fmsg->reply_n,fmsg->area);
	if (!chkftnmsgid(p)) {
	    hash_update_s(&fmsg->reply_n, fmsg->area);
	}
    }
    
    chkftnmsgid(hdr((char *)"Message-ID",msg)); // ??
    removemime       = FALSE;
    removemsgid      = FALSE;
    removeref        = FALSE;
    removeinreply    = FALSE;
    removereplyto    = TRUE;
    removereturnto   = TRUE;
    ftnorigin = fmsg->ftnorigin;
    
    q = hdr((char *)"Content-Transfer-Encoding",msg);
    if (q) 
	while (*q && isspace(*q)) 
	    q++;

    if (!(q)) 
	q = (char *)"8bit"; 
    if ((p = hdr((char *)"Content-Type",msg))) {
	while (*p && isspace(*p)) 
	    p++;

	/*
	 * Check for mime to remove.
	 */
	if ((strncasecmp(p, "text/plain", 10) == 0) && ((q == NULL) || 
		    (strncasecmp(q,"7bit",4) == 0) || (strncasecmp(q,"8bit",4) == 0))) {
	    removemime = TRUE; /* no need in MIME headers */
	}

	q = strtok(p, " \n\0");
	q = strtok(NULL, "; \n\0");
	if (q) {
	    while (*q && isspace(*q))
		q++;
	    Syslog('m', "charset part: %s", printable(q, 0));
	    if (q && (strncasecmp(q, "charset=", 8) == 0)) {
		/*
		 * google.com quotes the charset name
		 */
		if (strchr(q, '"')) {
		    charset = xstrcpy(q + 9);
		    charset[strlen(charset)-1] = '\0';
		} else {
		    charset = xstrcpy(q + 8);
		}
		Syslog('m', "Charset \"%s\"", printable(charset, 0));
	    }
	}
    }

    if (charset == NULL) {
	charset = xstrcpy((char *)"ISO-8859-1");
	Syslog('m', "No charset, setting default to ISO-8859-1");
    }

    if ((p = hdr((char *)"Message-ID",msg))) {
	if (!removemsgid)
	    removemsgid = chkftnmsgid(p);
    }

    if ((!removeref) && (p = hdr((char *)"References",msg))) {
	p = xstrcpy(p);
	q = strtok(p," \t\n");
	if ((q) && (strtok(NULL," \t\n") == NULL))
	    removeref = chkftnmsgid(q);       
	free(p);
    }

    if ((p = hdr((char *)"Reply-To",msg))) {
	removereplyto = FALSE;
	if ((q = hdr((char *)"From",msg))) {
	    char    *r;
	    r = xstrcpy(p); 
	    p = r;
	    while(*p && isspace(*p)) 
		p++;
	    if (p[strlen(p)-1] == '\n')
		p[strlen(p)-1]='\0';
	    if (strcasestr(q,p))
		removereplyto = TRUE;
	}
    }

    if ((p = hdr((char *)"Return-Receipt-To",msg))) {
	removereturnto = FALSE;
	if ((q = hdr((char *)"From",msg))) {
	    char    *r;

	    r = xstrcpy(p); 
	    p = r;
	    while (*p && isspace(*p)) 
		p++;
	    if (p[strlen(p)-1] == '\n') 
		p[strlen(p)-1]='\0';
	    if (strcasestr(q,p)) 
		removereturnto = TRUE;
	}
    }

    Syslog('m', "removemime=%s removemsgid=%s removeref=%s removeinreply=%s removereplyto=%s removereturnto=%s",
	    removemime ?"TRUE ":"FALSE", removemsgid ?"TRUE ":"FALSE", removeref ?"TRUE ":"FALSE",
	    removeinreply ?"TRUE ":"FALSE", removereplyto ?"TRUE ":"FALSE", removereturnto ?"TRUE ":"FALSE");

    p = ascfnode(fmsg->from,0x1f);
    i = 79-11-3-strlen(p);
    if (ftnorigin && fmsg->origin && (strlen(fmsg->origin) > i)) {
        /* This is a kludge...  I don't like it too much.  But well,
           if this is a message of FTN origin, the original origin (:)
           line MUST have been short enough to fit in 79 chars...
           So we give it a try.  Probably it would be better to keep
           the information about the address format from the origin
           line in a special X-FTN-... header, but this seems even
           less elegant.  Any _good_ ideas, anyone? */

        /* OK, I am keeping this, though if should never be used
           al long as X-FTN-Origin is used now */

	p = ascfnode(fmsg->from,0x0f);
	Syslog('m', "checkorigin 3");
	i = 79-11-3-strlen(p);
	tinyorigin = TRUE;
    }
    if (tinyorigin)
	Syslog('m', "tinyorigin = %s", tinyorigin ? "True":"False");

    if ((fmsg->origin) && (strlen(fmsg->origin) > i))
	fmsg->origin[i]='\0';
    forbidsplit = (ftnorigin || ((p = hdr((char *)"X-FTN-Split",msg))  && (strcasecmp(p," already\n") == 0)));
    needsplit = 0;
    splitpart = 0;
    hdrsize = 20;
    hdrsize += (fmsg->subj)?strlen(fmsg->subj):0;
    if (fmsg->from)
	hdrsize += (fmsg->from->name)?strlen(fmsg->from->name):0;
    if (fmsg->to)
	hdrsize += (fmsg->to->name)?strlen(fmsg->to->name):0;

    chars_in = find_rfc_charset(charset);
    chars_out = msgs.Charset;
    if (chars_in == FTNC_ERROR) {
	/*
	 * Not in standard tables, go ahead with the uppercase name
	 * and see if iconv will take it. It doesn't really matter if
	 * we support the incoming rfc charset,
	 */
	tu(charset);
	Syslog('m', "rfc2ftn: charset in: %s charset out: %s", charset, get_ic_ftn(chars_out));
	chartran_init(charset, get_ic_ftn(chars_out), 'm');
    } else {
	Syslog('m', "rfc2ftn: charset in: %s charset out: %s", get_ic_rfc(chars_in), get_ic_ftn(chars_out));
	chartran_init(get_ic_rfc(chars_in), get_ic_ftn(chars_out), 'm');
    }

    do {
	Syslog('m', "rfc2ftn: split loop, splitpart = %d", splitpart);
	datasize = 0;

	if (splitpart) {
	    snprintf(newsubj,4 * MAXSUBJ,"[part %d] ",splitpart+1);
	    strncat(newsubj,fmsg->subj,MAXSUBJ-strlen(newsubj));
	    Syslog('+', "Rfc2ftn: split message part %d", splitpart);
	} else {
	    strncpy(newsubj,fmsg->subj,MAXSUBJ);
	}
	newsubj[MAXSUBJ]='\0';

	if (splitpart) {
	    hash_update_n(&fmsg->msgid_n,splitpart);
	}
	oldsubj = fmsg->subj;
	fmsg->subj = newsubj;

	/*
	 * Create a new temp message in FTN style format
	 */
	if ((ofp = tmpfile()) == NULL) {
	    WriteError("$Rfc2ftn: Can't open second tmpfile");
	    tidyrfc(msg);
	    return 1;
	}

	if (newsmode) {
	    fprintf(ofp, "AREA:%s\n", msgs.Tag);
	} else {
	    if (fmsg->to->point != 0)
		fprintf(ofp, "\001TOPT %d\n", fmsg->to->point);
	    if (fmsg->from->point != 0)
		fprintf(ofp, "\001FMPT %d\n", fmsg->from->point);
		fprintf(ofp, "\001INTL %d:%d/%d %d:%d/%d\n", fmsg->to->zone, fmsg->to->net, fmsg->to->node,
				fmsg->from->zone, fmsg->from->net, fmsg->from->node);
	}

	if ((fmsg->msgid_a == NULL) || (fmsg->msgid_n == 0)) {
	    Syslog('!', "Rfc2ftn: warning, no MSGID %s %08lx", MBSE_SS(fmsg->msgid_a), fmsg->msgid_n);
	}

	fprintf(ofp, "\001MSGID: %s %08x\n", MBSE_SS(fmsg->msgid_a),fmsg->msgid_n);
	if (fmsg->reply_s) 
	    fprintf(ofp, "\1REPLY: %s\n", fmsg->reply_s);
	else if (fmsg->reply_a)
	    fprintf(ofp, "\1REPLY: %s %08x\n", fmsg->reply_a, fmsg->reply_n);
	Now = time(NULL) - (gmt_offset((time_t)0) * 60);
	fprintf(ofp, "\001TZUTC: %s\n", gmtoffset(Now));
	fprintf(ofp, "\001CHRS: %s\n", getftnchrs(msgs.Charset));

	fmsg->subj = oldsubj;
	if ((p = hdr((char *)"X-FTN-REPLYADDR",msg))) {
	    hdrsize += 10+strlen(p);
	    fprintf(ofp,"\1REPLYADDR:");
	    kludgewrite(p,ofp);
	} else if (replyaddr) {
	    hdrsize += 10+strlen(replyaddr);
	    fprintf(ofp,"\1REPLYADDR: ");
	    kludgewrite(replyaddr,ofp);
	}
	if ((p = hdr((char *)"X-FTN-REPLYTO",msg))) {
	    hdrsize += 8+strlen(p);
	    fprintf(ofp,"\1REPLYTO:");
	    kludgewrite(p,ofp);
	} else if (replyaddr) {
	    hdrsize += 15;
	    if (newsmode)
		fprintf(ofp,"\1REPLYTO: %s UUCP\n", aka2str(msgs.Aka));
	    else {
		fta = bestaka_s(fmsg->to);
		fprintf(ofp,"\1REPLYTO: %s UUCP\n", ascfnode(fta, 0x1f));
		tidy_faddr(fta);
	    }
	} else if ((p = hdr((char *)"Reply-To",msg))) {
	    if ((ta = parsefaddr(p))) {
		if ((q = hdr((char *)"From",msg))) {
		    if (!strcasestr(q,p)) {
			fprintf(ofp,"\1REPLYTO: %s %s\n", ascfnode(ta,0x1f), ta->name);
		    }
		}
		tidy_faddr(ta);
	    }
	}
	if ((p=strip_flags(hdr((char *)"X-FTN-FLAGS",msg)))) {
	    hdrsize += 15;
	    fprintf(ofp,"\1FLAGS:%s\n",p);
	    free(p);
	}
	if (!hdr((char *)"X-FTN-PID", msg)) { 
	    p = hdr((char *)"User-Agent", msg);
	    if (p == NULL) 
		p = hdr((char *)"X-Newsreader", msg);
	    if (p == NULL) 
		p = hdr((char *)"X-Mailer", msg);
	    if (p) {
		hdrsize += 4 + strlen(p);
		fprintf(ofp, "\1PID:");
		kludgewrite(p, ofp);
	    } else {
		fprintf(ofp, "\001PID: MBSE-FIDO %s (%s-%s)\n", VERSION, OsName(), OsCPU());
	    }
	}

	if (CFG.allowcontrol && (!hdr((char *)"X-FTN-ACUPDATE",msg)) && (p=hdr((char *)"Control",msg))) {
	    if (strstr(p,"cancel")) {
		ftnmsgid(p,&acup_a,&acup_n,fmsg->area);
		if (acup_a) {
		    hash_update_s(&acup_n,fmsg->area);
		    hdrsize += 26 + strlen(acup_a);
		    fprintf(ofp,"\1ACUPDATE: DELETE %s %08x\n", acup_a,acup_n);
		}
	    }
	}
	if ((!hdr((char *)"X-FTN-ACUPDATE",msg)) && (p=hdr((char *)"Supersedes",msg))) {
	    ftnmsgid(p,&acup_a,&acup_n,fmsg->area);
	    if (acup_a) {
		hash_update_s(&acup_n,fmsg->area);
		hdrsize += 26 + strlen(acup_a);
		fprintf(ofp,"\1ACUPDATE: MODIFY %s %08x\n", acup_a,acup_n);
	    }
	}
	if (!(hdr((char *)"X-FTN-Tearline", msg)) && !(hdr((char *)"X-FTN-TID", msg))) {
	    snprintf(temp, MAXHDRSIZE, " MBSE-FIDO %s (%s-%s)", VERSION, OsName(), OsCPU());
	    hdrsize += 4 + strlen(temp);
	    fprintf(ofp, "\1TID:");
	    kludgewrite(temp, ofp);
	}

	if ((splitpart == 0) || (hdrsize < MAXHDRSIZE)) {
	    for (tmp = msg; tmp; tmp = tmp->next) {
	 	if ((!strncmp(tmp->key,"X-Fsc-",6)) || (!strncmp(tmp->key,"X-FTN-",6) &&
			strcasecmp(tmp->key,"X-FTN-Tearline") &&
			strcasecmp(tmp->key,"X-FTN-Origin") &&
			strcasecmp(tmp->key,"X-FTN-Sender") &&
			strcasecmp(tmp->key,"X-FTN-Split") &&
			strcasecmp(tmp->key,"X-FTN-FLAGS") &&
			strcasecmp(tmp->key,"X-FTN-AREA") &&
			strcasecmp(tmp->key,"X-FTN-MSGID") &&
			strcasecmp(tmp->key,"X-FTN-REPLY") &&
			strcasecmp(tmp->key,"X-FTN-SEEN-BY") &&
			strcasecmp(tmp->key,"X-FTN-PATH") &&
			strcasecmp(tmp->key,"X-FTN-REPLYADDR") &&
			strcasecmp(tmp->key,"X-FTN-REPLYTO") &&
			strcasecmp(tmp->key,"X-FTN-To") &&
			strcasecmp(tmp->key,"X-FTN-From") &&
			strcasecmp(tmp->key,"X-FTN-CHARSET") &&
			strcasecmp(tmp->key,"X-FTN-CHRS") &&
			strcasecmp(tmp->key,"X-FTN-CODEPAGE") &&
			strcasecmp(tmp->key,"X-FTN-ORIGCHRS") &&
			strcasecmp(tmp->key,"X-FTN-SOT") &&
			strcasecmp(tmp->key,"X-FTN-EOT") &&
			strcasecmp(tmp->key,"X-FTN-Via"))) {
		    if ((strcasecmp(tmp->key,"X-FTN-KLUDGE") == 0)) {
			if (!strcasecmp(tmp->val," SOT:\n"))
			    sot_kludge = TRUE;
			else if (!strcasecmp(tmp->val," EOT:\n"))
			    eot_kludge = TRUE;
			else {
			    hdrsize += strlen(tmp->val);
			    fprintf(ofp,"\1");
			    /* we should have restored the original string here... */
			    kludgewrite((tmp->val)+1,ofp);
			}
		    } else {
			hdrsize += strlen(tmp->key)+strlen(tmp->val);
			fprintf(ofp,"\1%s:",tmp->key+6);
			kludgewrite(tmp->val,ofp);
		    }
		}
	    }

	    /* ZConnect are X-ZC-*: in usenet, \1ZC-*: in FTN */
	    for (tmp=msg;tmp;tmp=tmp->next)
		if ((!strncmp(tmp->key,"X-ZC-",5))) {
		    hdrsize += strlen(tmp->key)+strlen(tmp->val);
		    fprintf(ofp,"\1%s:",tmp->key+2);
		    kludgewrite(tmp->val,ofp);
		}

	    /* mondo.org gateway uses ".MSGID: ..." in usenet */
	    for (tmp=msg;tmp;tmp=tmp->next)
		if ((!strncmp(tmp->key,".",1)) && (strcasecmp(tmp->key,".MSGID"))) {
		    hdrsize += strlen(tmp->key)+strlen(tmp->val);
		    fprintf(ofp,"\1%s:",tmp->key+1);
		    kludgewrite(tmp->val,ofp);
		}


	    /*
	     *  Add the Received: header from this system to the mesage.
	     */
	    if (!newsmode) {
		Now = time(NULL);
		fprintf(ofp, "\1RFC-Received: by %s (mbfido) via RFC2FTN; %s\n", CFG.sysdomain, rfcdate(Now));
		hdrsize += 72+strlen(CFG.sysdomain);
	    }

	    for (tmp = msg; tmp; tmp = tmp->next) {
		if ((needputrfc(tmp, newsmode) == 1)) {
		    if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) {
			hdrsize += 10+strlen(tmp->val);
			fprintf(ofp,"\1RFC-Newsgroups:");
		    } else {
			hdrsize += strlen(tmp->key)+strlen(tmp->val);
			fprintf(ofp,"\1RFC-%s:",tmp->key);
		    }
		    kludgewrite(tmp->val, ofp);
		}
	    }

	    rfcheaders=0;
	    for (tmp=msg;tmp;tmp=tmp->next) {
		if ((needputrfc(tmp, newsmode) > 1)) {
		    rfcheaders++;
		    if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) {
			hdrsize += 10+strlen(tmp->val);
			fprintf(ofp,"Newsgroups:");
		    } else {
			hdrsize += strlen(tmp->key)+strlen(tmp->val);
			fprintf(ofp,"%s:",tmp->key);
		    }
		    charwrite(tmp->val, ofp);
		}
	    }

	    if (rfcheaders) 
		charwrite((char *)"\n",ofp);
	    if ((hdr((char *)"X-FTN-SOT",msg)) || (sot_kludge))
		fprintf(ofp,"\1SOT:\n");
	}
	if (replyaddr) {
	    replyaddr = NULL;
	}

	if (needsplit) {
	    fprintf(ofp," * Continuation %d of a split message *\n\n", splitpart);
	    needsplit = FALSE;
	} else if ((p=hdr((char *)"X-Body-Start",msg))) {
	    datasize += strlen(p);
	    charwrite(p, ofp);
	}
	while (!(needsplit=(!forbidsplit) && (((splitpart && (datasize > (CFG.new_split * 1024))) ||
		      (!splitpart && ((datasize+hdrsize) > (CFG.new_split * 1024)))))) && (bgets(temp,4096-1,fp))) {
	    datasize += strlen(temp);
	    charwrite(temp, ofp);
	}

	if (needsplit) {
	    fprintf(ofp,"\n * Message split, to be continued *\n");
	    splitpart++;
	}
	if ((p=hdr((char *)"X-FTN-EOT",msg)) || (eot_kludge))
	    fprintf(ofp,"\1EOT:\n");

	if ((p=hdr((char *)"X-FTN-Tearline",msg))) {
	    fprintf(ofp,"---");
	    if (strcasecmp(p," (none)\n") == 0)
		charwrite((char *)"\n",ofp);
	    else
		charwrite(p,ofp);
	} else
	    fprintf(ofp,"\n%s\n", TearLine());

	if ((p = hdr((char *)"X-FTN-Origin",msg))) {
	    if (*(q=p+strlen(p)-1) == '\n') 
		*q='\0';
	    origin = xstrcpy((char *)" * Origin: ");
	    origin = xstrcat(origin, p);
	} else {
	    origin = xstrcpy((char *)" * Origin: ");
	    if (fmsg->origin)
		origin = xstrcat(origin, fmsg->origin);
	    else
		origin = xstrcat(origin, CFG.origin);
	    origin = xstrcat(origin, (char *)" (");
	    origin = xstrcat(origin, ascfnode(fmsg->from,tinyorigin?0x0f:0x1f));
	    origin = xstrcat(origin, (char *)")");
	}
	fprintf(ofp, "%s", origin);

	if (newsmode) {
	    /*
	     * Setup SEEN-BY lines, first SEEN-BY from RFC message, then all matching AKA's
	     */
	    for (tmsg = msg; tmsg; tmsg = tmsg->next)
		if (strcasecmp(tmsg->key, "X-FTN-SEEN-BY") == 0)
		    fill_list(&sbl, tmsg->val, NULL);
	    for (i = 0; i < 40; i++) {
		if (CFG.akavalid[i] && (CFG.aka[i].point == 0) && (msgs.Aka.zone == CFG.aka[i].zone) &&
				    !((msgs.Aka.net == CFG.aka[i].net) && (msgs.Aka.node == CFG.aka[i].node))) {
		    snprintf(sbe, 128, "%u/%u", CFG.aka[i].net, CFG.aka[i].node);
		    fill_list(&sbl, sbe, NULL);
		}
	    }
	    if (msgs.Aka.point == 0) {
		snprintf(sbe, 128, "%u/%u", msgs.Aka.net, msgs.Aka.node);
		fill_list(&sbl, sbe, NULL);
	    }

	    /*
	     *  Only add SEEN-BY lines if there are any
	     */
	    if (sbl != NULL) {
		uniq_list(&sbl);
		sort_list(&sbl);
		seenlen = MAXSEEN + 1;
		memset(&sbe, 0, sizeof(sbe));
		/* ensure it will not match for the first entry */
		oldnet = sbl->addr->net-1;
		for (tmpl = sbl; tmpl; tmpl = tmpl->next) {
		    if (tmpl->addr->net == oldnet)
			snprintf(sbe,128," %u",tmpl->addr->node);
		    else
			snprintf(sbe,128," %u/%u",tmpl->addr->net, tmpl->addr->node);
		    oldnet = tmpl->addr->net;
		    seenlen += strlen(sbe);
		    if (seenlen > MAXSEEN) {
			seenlen = 0;
			fprintf(ofp,"\nSEEN-BY:");
			snprintf(sbe,128," %u/%u",tmpl->addr->net, tmpl->addr->node);
			seenlen = strlen(sbe);
		    }
		    fprintf(ofp,"%s",sbe);
		}
		tidy_falist(&sbl);
	    }

	    /*
	     *  Setup PATH lines
	     */
	    for (tmp = msg; tmp; tmp = tmp->next)
		if (!strcasecmp(tmp->key,"X-FTN-PATH"))
		    fill_path(&ptl,tmp->val);
		if (msgs.Aka.point == 0) {
		    snprintf(sbe,128,"%u/%u",msgs.Aka.net, msgs.Aka.node);
		    fill_path(&ptl,sbe);
		}

	    /*
	     *  Only add PATH line if there is something
	     */
	    if (ptl != NULL) {
		uniq_list(&ptl);
		seenlen = MAXPATH+1;
		/* ensure it will not match for the first entry */
		oldnet = ptl->addr->net-1;
		for (tmpl = ptl; tmpl; tmpl = tmpl->next) {
		    if (tmpl->addr->net == oldnet)
			snprintf(sbe,128," %u",tmpl->addr->node);
		    else
			snprintf(sbe,128," %u/%u",tmpl->addr->net, tmpl->addr->node);
		    oldnet = tmpl->addr->net;
		    seenlen += strlen(sbe);
		    if (seenlen > MAXPATH) {
			seenlen = 0;
			fprintf(ofp,"\n\1PATH:");
			snprintf(sbe,128," %u/%u",tmpl->addr->net, tmpl->addr->node);
			seenlen = strlen(sbe);
		    }
		    fprintf(ofp,"%s",sbe);
		}
		tidy_falist(&ptl);
	    }
	} /* if (newsmode) */

	/*
	 *  Add newline and message is ready.
	 */
	fprintf(ofp,"\n");
	fflush(ofp);
	rewind(ofp);

	Syslog('m', "========== Fido start");
	while (fgets(temp, 4096, ofp) != NULL) {
	    /*
	     *  Only log kludges, skip the body
	     */
	    if ((temp[0] == '\001') || !strncmp(temp, "AREA:", 5) || !strncmp(temp, "SEEN-BY", 7)) {
		Striplf(temp);
		Syslogp('m', printable(temp, 0));
	    }
	}
	Syslog('m', "========== Fido end");

	if (newsmode)
	    rc = postecho(NULL, fmsg->from, fmsg->to, origin, fmsg->subj, fmsg->date, fmsg->flags, 0, ofp, FALSE, 0);
	else
	    rc = postnetmail(ofp, fmsg->from, fmsg->to, origin, fmsg->subj, fmsg->date, 
		    fmsg->flags, FALSE, fmsg->from->zone, fmsg->to->zone);

	Syslog('m', "rfc2ftn: message posted rc=%d", rc);

	free(origin);
        fclose(ofp);
    } while (needsplit);

    Syslog('m', "rfc2ftn: out of splitloop");
    chartran_close();

    free(temp);
    if (charset)
	free(charset);
    tidyrfc(msg);
    tidy_ftnmsg(fmsg);

    Syslog('m', "rfc2ftn: memory freed");

    UpdateMsgs();

    return 0;
}
Beispiel #19
0
void ForwardFile(fidoaddr Node, fa_list *sbl)
{
    char	*subject = NULL, *fwdfile = NULL, *queuedir, *listfile, *ticfile = NULL, *ticname, flavor;
    FILE	*fp, *fi, *fl, *net;
    faddr	*dest, *routeto, *Fa, *Temp, *ba;
    int		i, z, n;
    time_t	now, ftime;
    fa_list	*tmp;

    if (!SearchNode(Node)) {
	WriteError("TIC forward in %s, node %s not in setup but defined in area setup", TIC.TicIn.Area, aka2str(Node));
	return;
    }
    Syslog('+', "Forward file to %s %s netmail", aka2str(Node), nodes.Message?"with":"without");

    fwdfile  = calloc(PATH_MAX, sizeof(char));
    queuedir = calloc(PATH_MAX, sizeof(char));
    listfile = calloc(PATH_MAX, sizeof(char));
    snprintf(queuedir, PATH_MAX, "%s/%d.%d.%d.%d", CFG.out_queue, Node.zone, Node.net, Node.node, Node.point);
    snprintf(listfile, PATH_MAX, "%s/.filelist", queuedir);
    mkdirs(listfile, 0750);
    if ((fl = fopen(listfile, "a+")) == NULL) {
	WriteError("$Can't open %s", listfile);
	free(fwdfile);
	free(listfile);
	free(queuedir);
	return;
    }
    
    /*
     * Create the full filename
     */
    if (TIC.PassThru || TIC.SendOrg) {
	snprintf(fwdfile, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File);
	subject = xstrcpy(TIC.TicIn.File);
    } else {
	/*
	 * Make sure the file attach is the 8.3 filename
	 */
	snprintf(fwdfile, PATH_MAX, "%s/%s", TIC.BBSpath, TIC.NewFile);
	subject = xstrcpy(TIC.NewFile);
    }

    flavor = 'f';
    if (nodes.Crash) 
	flavor = 'c';
    if (nodes.Hold)
	flavor = 'h';

    fprintf(fl, "%c LEAVE FDN %s\n", flavor, fwdfile);

    if (nodes.RouteVia.zone)
	routeto = fido2faddr(nodes.RouteVia);
    else
	routeto = fido2faddr(Node);
    dest = fido2faddr(Node);

    ticfile = calloc(PATH_MAX, sizeof(char));
    ticname = calloc(15, sizeof(char));
    if (nodes.Tic) {
	snprintf(ticname, 15, "%08x.tic", sequencer());
	subject = xstrcat(subject, (char *)" ");
	subject = xstrcat(subject, ticname);
	snprintf(ticfile, PATH_MAX, "%s/%s", CFG.ticout, ticname);
    }
    free(ticname);

    /*
     *  Send netmail message if the node has it turned on.
     */
    if (nodes.Message) {
	Temp = fido2faddr(Node);
	if ((net = SendMgrMail(Temp, CFG.ct_KeepMgr, TRUE, (char *)"Filemgr", subject, NULL)) != NULL) {
	    if ((fi = OpenMacro("forward.tic", nodes.Language, FALSE)) != NULL) {
		ftime = TIC.FileDate;
		MacroVars("a", "s", TIC.TicIn.Area);
		MacroVars("b", "s", tic.Comment);
		MacroVars("c", "d", TIC.FileCost);
		MacroVars("d", "s", fgroup.Comment);
		if (TIC.PassThru || TIC.SendOrg)
		    MacroVars("f", "s", TIC.TicIn.FullName);
		else
		    MacroVars("f", "s", TIC.NewFullName);
		MacroVars("g", "d", TIC.FileSize);
		MacroVars("h", "d", (TIC.FileSize / 1024));
		MacroVars("i", "s", TIC.TicIn.Crc);
		MacroVars("j", "s", TIC.TicIn.Origin);
		MacroVars("m", "s", rfcdate(ftime));
		MacroVars("n", "s", TIC.TicIn.Desc);
		MacroVars("s", "s", nodes.Sysop);
		if (TIC.PassThru || TIC.SendOrg)
		    MacroVars("e", "s", TIC.TicIn.File);
		else
		    MacroVars("e", "s", TIC.NewFile);
		if (strlen(TIC.TicIn.Magic))
		    MacroVars("k", "s", TIC.TicIn.Magic);
		if (strlen(TIC.TicIn.Replace))
		    MacroVars("l", "s", TIC.TicIn.Replace);
		MacroRead(fi, net);
		fprintf(net, "%s\r", TearLine());
		CloseMail(net, Temp);
	    }
	} else {
	    WriteError("Can't create netmail");
	}
	tidy_faddr(Temp);
    }
    free(subject);

    /*
     * If we need a .TIC file, start creating it.
     */
    if (nodes.Tic) {
	mkdirs(ticfile, 0770);
	if ((fp = fopen(ticfile, "a+")) != NULL) {
	    fprintf(fp, "Area %s\r\n", TIC.TicIn.Area);
	    fprintf(fp, "Origin %s\r\n", TIC.TicIn.Origin);
	    Fa = fido2faddr(tic.Aka);
	    fprintf(fp, "From %s\r\n", ascfnode(Fa, 0x0f));
	    free(Fa);
	    if (strlen(TIC.TicIn.Replace))
		fprintf(fp, "Replaces %s\r\n", TIC.TicIn.Replace);
	    if (strlen(TIC.TicIn.Magic))
		fprintf(fp, "Magic %s\r\n", TIC.TicIn.Magic);

	    if ((TIC.PassThru) || (TIC.SendOrg)) {
		fprintf(fp, "File %s\r\n", TIC.TicIn.File);
		if (strlen(TIC.TicIn.FullName))
		    fprintf(fp, "Lfile %s\r\n", TIC.TicIn.FullName);
	    } else {
		fprintf(fp, "File %s\r\n", TIC.NewFile);
		if (strlen(TIC.NewFullName))
		    fprintf(fp, "Lfile %s\r\n", TIC.NewFullName);
	    }
	    fprintf(fp, "Size %d\r\n", (int)(TIC.FileSize));
	    fprintf(fp, "Desc %s\r\n", TIC.TicIn.Desc);
	    fprintf(fp, "Crc %s\r\n", TIC.TicIn.Crc);
	    if (nodes.TIC_To) {
		fprintf(fp, "To %s, %s\r\n", nodes.Sysop, ascfnode(dest, 0x1f));
	    }
	    if (nodes.AdvTic) {
		fprintf(fp, "Areadesc %s\r\n", tic.Comment);
		fprintf(fp, "Fdn %s\r\n", fgroup.Comment);
		if (TIC.TicIn.TotLDesc)
		    for (i = 0; i < TIC.TicIn.TotLDesc; i++)
			fprintf(fp, "LDesc %s\r\n", TIC.TicIn.LDesc[i]);
	    }
	    fprintf(fp, "Created by MBSE BBS %s %s\r\n", VERSION, SHORTRIGHT);
	    if (TIC.TicIn.TotPath)
		for (i = 0; i < TIC.TicIn.TotPath; i++)
		    fprintf(fp, "Path %s\r\n", TIC.TicIn.Path[i]);
	    /*
	     * Add our system to the path
	     */
	    now = time(NULL);
	    subject = ctime(&now);
	    Striplf(subject);
	    ba = bestaka_s(dest);
	    fprintf(fp, "Path %s %u %s %s\r\n", ascfnode(ba, 0x1f), (int)mktime(localtime(&now)), subject, tzname[0]);
	    tidy_faddr(ba);

	    if (nodes.TIC_AdvSB) {
		/*
		 * In advanced TIC mode we send multiple seenby
		 * addresses on one line in stead of one line
		 * per system.
		 */
		z = 0;
		n = 0;
		subject = xstrcpy((char *)"Seenby");
		for (tmp = sbl; tmp; tmp = tmp->next) {
		    if (strlen(subject) > 70) {
			fprintf(fp, "%s\r\n", subject);
			z = 0;
			n = 0;
			free(subject);
			subject = xstrcpy((char *)"Seenby ");
		    } else {
			subject = xstrcat(subject, (char *)" ");
		    }

		    if (z != tmp->addr->zone) {
			if (nodes.Tic4d)
			    subject = xstrcat(subject, ascfnode(tmp->addr, 0x0f));
			else
			    subject = xstrcat(subject, ascfnode(tmp->addr, 0x0e));
			z = tmp->addr->zone;
		    } else { 
			if (n != tmp->addr->net) {
			    if (nodes.Tic4d)
				subject = xstrcat(subject, ascfnode(tmp->addr, 0x07));
			    else
				subject = xstrcat(subject, ascfnode(tmp->addr, 0x06));
			    n = tmp->addr->net;
			} else {
			    if (nodes.Tic4d)
				subject = xstrcat(subject, ascfnode(tmp->addr, 0x03));
			    else
				subject = xstrcat(subject, ascfnode(tmp->addr, 0x02));
			}
		    }
		}
		if (strlen(subject) > 7) {
		    fprintf(fp, "%s\r\n", subject);
		    free(subject);
		}
	    } else {
		/*
		 * Old style seenby lines
		 */
		for (tmp = sbl; tmp; tmp = tmp->next) {
		    fprintf(fp, "Seenby %s\r\n", ascfnode(tmp->addr, 0x0f));
		}
	    }

	    /*
	     * Now append all passthru ticlines
	     */
	    if (TIC.TicIn.Unknowns)
		for (i = 0; i < TIC.TicIn.Unknowns; i++)
		    fprintf(fp, "%s\r\n", TIC.TicIn.Unknown[i]);

	    fprintf(fp, "Pw %s\r\n", nodes.Fpasswd);
	    fclose(fp);
	    fprintf(fl, "%c KFS NOR %s\n", flavor, ticfile);
	} else {
	    WriteError("$Can't create %s", ticfile);
	}
    }
    fsync(fileno(fl));
    fclose(fl);
    
    /*
     * Update the nodes statistic counters
     */
    StatAdd(&nodes.FilesSent, 1L);
    StatAdd(&nodes.F_KbSent, T_File.SizeKb);
    UpdateNode();
    SearchNode(Node);
    free(ticfile);
    free(fwdfile);
    free(queuedir);
    free(listfile);
    tidy_faddr(routeto);
}
Beispiel #20
0
void flush_dir(char *ndir)
{
    struct dirent   *de;
    DIR		    *dp;
    FILE	    *fp, *inf, *ouf;
    faddr	    noden, *bestaka;
    fidoaddr	    nodenr;
    int		    flavor, mode, Attach, fage, first, bread, rc;
    int		    fsize;
    char	    *p, *temp, *fname, *arcfile, *pktfile, *ext, maxnr, nr, oldnr, *buf;
    time_t	    Now;
    struct tm	    *ptm;
    struct stat	    sbuf;
    fd_list	    *fdl = NULL;

    temp = calloc(PATH_MAX, sizeof(char));
    snprintf(temp, PATH_MAX, "%s/%s", CFG.out_queue, ndir);
    if (chdir(temp) == -1) {
	WriteError("$Error chdir to %s", temp);
	free(temp);
	return;
    }

    /*
     * Get the nodenumber from the filename
     */
    noden.domain = NULL;
    noden.name   = NULL;
    noden.zone   = atoi(strtok(ndir, "."));
    noden.net    = atoi(strtok(NULL, "."));
    noden.node   = atoi(strtok(NULL, "."));
    noden.point  = atoi(strtok(NULL, "\0"));
    if (SearchFidonet(noden.zone))
	noden.domain = xstrcpy(fidonet.domain);

    memset(&nodenr, 0, sizeof(nodenr));
    nodenr.zone  = noden.zone;
    nodenr.net   = noden.net;
    nodenr.node  = noden.node;
    nodenr.point = noden.point;
    snprintf(nodenr.domain, 13, "%s", noden.domain);

    if (!SearchNode(nodenr)) {
	/*
	 * Node not in setup, blank noderecord and fill in some details
	 * so that we are able to send mail crash or immediate.
	 */
	Syslog('+', "Node %s not in setup, using default settings", aka2str(nodenr));
	memset(&nodes, 0, sizeof(nodes));
	nodes.Aka[0].zone  = noden.zone;
	nodes.Aka[0].net   = noden.net;
	nodes.Aka[0].node  = noden.node;
	nodes.Aka[0].point = noden.point;
	snprintf(nodes.Archiver, 6, (char *)"ZIP");
    }

    /*
     * If we route via another aka, change everything.
     */
    if (nodes.RouteVia.zone) {
	p = xstrcpy(aka2str(nodenr));
	Syslog('+', "Route to %s via %s", p, aka2str(nodes.RouteVia));
	free(p);
	noden.zone   = nodes.RouteVia.zone;
	noden.net    = nodes.RouteVia.net;
	noden.node   = nodes.RouteVia.node;
	noden.point  = nodes.RouteVia.point;
	if (noden.domain)
	    free(noden.domain);
	noden.domain = xstrcpy(nodes.RouteVia.domain);
	/*
	 * Load routevia noderecord to get the correct flavor.
	 * If there is no noderecord, reload the old one.
	 */
	if (!SearchNode(nodes.RouteVia))
	    SearchNode(nodenr);
    }

    /*
     * At this point we are ready to add everything to the real outbound.
     * Lock the node, if this fails because the node is busy we abort
     * and try to add at a later time.
     */
    if (nodes.Session_out == S_DIR) {
	if (islocked(nodes.Dir_out_clock, nodes.Dir_out_chklck, nodes.Dir_out_waitclr, 'p')) {
	    Syslog('+', "Mail and files stay in queue, will be added later");
	    if (noden.domain)
		free(noden.domain);
	    free(temp);
	    return;
	} else {
	    if (! setlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck, 'p')) {
		Syslog('+', "Mail and files stay in queue, will be added later");
		if (noden.domain)
		    free(noden.domain);
		free(temp);
		return;
	    }
	}
    } else {
	if (nodelock(&noden, mypid)) {
	    Syslog('+', "Mail and files stay in queue, will be added later");
	    if (noden.domain)
		free(noden.domain);
	    free(temp);
	    return;
	}
    }

    /*
     * Create arcmail filename for this node.
     */
    Now = time(NULL);
    arcfile = calloc(PATH_MAX, sizeof(char));
    if (nodes.Session_out == S_DIR) {

	ptm = localtime(&Now);
	ext = dow[ptm->tm_wday];

	if (!nodes.ARCmailCompat && (nodes.Aka[0].zone != noden.zone)) {
	    /*
	     * Generate ARCfile name from the CRC of the ASCII string of the node address.
	     */
	    snprintf(arcfile, PATH_MAX, "%s/%08x.%s0", nodes.Dir_out_path, StringCRC32(ascfnode(&noden, 0x1f)), ext);
	} else {
	    bestaka = bestaka_s(&noden);

	    if (noden.point) {
		snprintf(arcfile, PATH_MAX, "%s/%04x%04x.%s0", nodes.Dir_out_path, ((bestaka->net) - (noden.net)) & 0xffff,
			((bestaka->node) - (noden.node) + (noden.point)) & 0xffff, ext);
	    } else if (bestaka->point) {
		/*
		 * Inserted the next code for if we are a point,
		 * I hope this is ARCmail 0.60 compliant. 21-May-1999
		 */
		snprintf(arcfile, PATH_MAX, "%s/%04x%04x.%s0", nodes.Dir_out_path, ((bestaka->net) - (noden.net)) & 0xffff,
			((bestaka->node) - (noden.node) - (bestaka->point)) & 0xffff, ext);
	    } else {
		snprintf(arcfile, PATH_MAX, "%s/%04x%04x.%s0", nodes.Dir_out_path, ((bestaka->net) - (noden.net)) & 0xffff,
			((bestaka->node) - (noden.node)) &0xffff, ext);
	    }
	}
    } else {
	snprintf(arcfile, PATH_MAX, "%s", arcname(&noden, nodes.Aka[0].zone, nodes.ARCmailCompat));
    }

    /*
     * If there is a mailpkt.qqq file, close it and rename it.
     */
    pktfile = calloc(PATH_MAX, sizeof(char));
    fname   = calloc(PATH_MAX, sizeof(char));
    snprintf(fname, PATH_MAX, "%s/mailpkt.qqq", temp);
    if (access(fname, W_OK) == 0) {
	snprintf(pktfile, PATH_MAX, "%s/%08x.pkt", temp, sequencer());
	if (rename(fname, pktfile)) {
	    WriteError("$Can't rename %s to %s", fname, pktfile);
	} else {
	    /*
	     * Add zero word to end of .pkt file
	     */
	    if ((fp = fopen(pktfile, "a+")) == NULL) {
		WriteError("$Can't open %s", pktfile);
	    }
	    putc('\0', fp);
	    putc('\0', fp);
	    fsync(fileno(fp));
	    fclose(fp);
	}
    }
    free(fname);

    /*
     * Now all mail pkts are ready to archive
     */
    if ((dp = opendir(temp)) == NULL) {
	WriteError("$Can't open %s", temp);
	free(temp);
	free(arcfile);
	if (nodes.Session_out == S_DIR)
	    remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck, 'p');
	else
	    nodeulock(&noden, mypid);
	if (noden.domain)
	    free(noden.domain);
	return;
    }

    /*
     * Read all .pkt filenames, get the timestamp and add them
     * to the memory array for later sort on filedate.
     */ 
    while ((de = readdir(dp)))
	if ((strlen(de->d_name) == 12) && (strncasecmp(de->d_name+8,".pkt",4) == 0)) {
	    stat(de->d_name, &sbuf);
	    Syslog('p', "Adding %s to filelist", de->d_name);
	    fill_fdlist(&fdl, de->d_name, sbuf.st_mtime);
	}

    closedir(dp);
    sort_fdlist(&fdl);

    if (getarchiver(nodes.Archiver)) {
	flavor = 'f';
	if (nodes.Crash)
	    flavor = 'c';
	if (nodes.Hold)
	    flavor = 'h';
    } else {
	WriteError("Archiver %s not found", nodes.Archiver);
	if (noden.domain)
	    free(noden.domain);
	free(temp);
	free(arcfile);
	return;
    }

    first = TRUE;
    while ((fname = pull_fdlist(&fdl)) != NULL) {
	/*
	 *  Check the size of the existing archive if there is a size limit.
	 *  Change to new archive names if the existing is too large.
	 *  If the archive size is zero, it's an already sent archive, the
	 *  number will be bumped also.
	 *  If the archive is older then 6 days, the name is also bumped.
	 *  Do this until we find a new name or if the last digit is a '9' or 'z'.
	 *  Purge archives older then toss_days.
	 */
	nr = oldnr = '0';
	if (nodes.ARCmailAlpha)
	    maxnr = 'z';
	else
	    maxnr = '9';
	Attach = FALSE;

	for (;;) {
	    fsize = file_size(arcfile);
	    fage  = (int)((Now - file_time(arcfile)) / 86400);

	    if (fsize == -1L) {
		Attach = TRUE;
		break;
	    }

	    if (fsize == 0L) {
		if ((fage > 6) && (nr < maxnr)) {
		    /*
		     * Remove truncated ARCmail files older then 6 days.
		     */
		    unlink(arcfile);
		    fsize = -1L;
		    Attach = TRUE;
		    break;
		}

		/*
		 * Increase filename extension if there is a truncated file of today.
		 */
		if (nr < maxnr) {
		    nr++;
		    if (nr == ('9' +1))
			nr = 'a';
		    arcfile[strlen(arcfile) -1] = nr;
		} else {
		    Syslog('!', "Warning: archive filename extensions exhausted for today");
		    break;
		}
	    } else if (CFG.maxarcsize && (fsize > (CFG.maxarcsize * 1024)) && (nr < maxnr)) {
		/*
		 * Use a new ARCmail file if the last one is too big.
		 */
		nr++;
		if (nr == ('9' +1))
		    nr = 'a';
		arcfile[strlen(arcfile) -1] = nr;
	    }

	    fsize = file_size(arcfile);
	    fage  = (int)((Now - file_time(arcfile)) / 86400);

	    if ((fsize > 0L) && (fage > 6) && (nr < maxnr)) {
		/*
		 * If there is ARCmail of a week old or older, add mail
		 * to a new ARCmail bundle.
		 */
		nr++;
		if (nr == ('9' +1))
		    nr = 'a';
		arcfile[strlen(arcfile) -1] = nr;
	    }

	    if (oldnr == nr)
		break;
	    else
		oldnr = nr;
	}

	fsize = file_size(arcfile);

	/*
	 * If arcfile names were exhausted then the file ending on a z could still
	 * be in the outbound but truncated if it has been sent. Since we are
	 * reusing that filename (not a good solution) we must erase it or the
	 * archiver program will complain.
	 */
	if (fsize == 0L) {
	    unlink(arcfile);
	    Attach = TRUE;
	}

	if (first) {
	    Syslog('+', "Pack ARCmail for %s via %s with %s", aka2str(nodenr), ascfnode(&noden, 0x1f), nodes.Archiver);
	    if (!do_quiet) {
		printf("\rAdding ARCmail for %s                      ", ascfnode(&noden, 0x1f));
		fflush(stdout);
	    }
	    first = FALSE;
	    flushed = TRUE;
	}

	if (execute_str(archiver.marc, arcfile, fname, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") == 0) {
	    unlink(fname);
	} else {
	    WriteError("Can't add %s to ARCmail archive", fname);
	    Attach = FALSE;
	}

	/*
	 * Change filemode so downlink has rights to the file.
	 */
	if (nodes.Session_out == S_DIR)
	    chmod(arcfile, 0660);
	
	/*
	 * Attach file to .flo, not for FTP or Directory sessions.
	 */
	if (Attach && nodes.Session_out == S_DIRECT)
	    attach(noden, arcfile, TFS, flavor);
    }

    /*
     * Open directory again.
     */
    if ((dp = opendir(temp)) == NULL) {
	WriteError("$Can't open %s", temp);
	free(temp);
	free(arcfile);
	if (nodes.Session_out == S_DIR)
	    remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck, 'p');
	else
	    nodeulock(&noden, mypid);
	if (noden.domain)
	    free(noden.domain);
	return;
    }

    /*
     * Read all other mail filenames, get the timestamp and add them
     * to the memory array for later sort on filedate.
     */ 
    while ((de = readdir(dp)))
	if ((strlen(de->d_name) == 11) && (strncasecmp(de->d_name,"mailpkt.",8) == 0)) {
	    stat(de->d_name, &sbuf);
	    Syslog('p', "Adding %s to filelist", de->d_name);
	    fill_fdlist(&fdl, de->d_name, sbuf.st_mtime);
	}

    closedir(dp);
    sort_fdlist(&fdl);

    first = TRUE;
    while ((fname = pull_fdlist(&fdl)) != NULL) {
	if (first) {
	    Syslog('+', "Pack unpacked mail for %s via %s", aka2str(nodenr), ascfnode(&noden, 0x1f));
	    if (!do_quiet) {
		printf("\rAdding netmail for %s                      ", ascfnode(&noden, 0x1f));
		fflush(stdout);
	    }
	    first = FALSE;
	    flushed = TRUE;
	}

	snprintf(pktfile, PATH_MAX, "%s/%s", temp, fname);

	if (strstr(fname, ".ddd"))
	    flavor = 'd';
	else if (strstr(fname, ".ccc"))
	    flavor = 'c';
	else if (strstr(fname, ".hhh"))
	    flavor = 'h';
	else
	    flavor = 'o';

	if (nodes.Session_out == S_DIR) {
	    snprintf(arcfile, PATH_MAX, "%s/%08x.pkt", nodes.Dir_out_path, sequencer());
	} else {
	    snprintf(arcfile, PATH_MAX, "%s", pktname(&noden, flavor));
	}

	/*
	 *  Now we must see if there is already mail in the outbound.
	 *  If that's the case, we must skip the .pkt header from the queue
	 *  because there is already a .pkt header also, append to the
	 *  outbound 2 bytes before the end of file, this is the zero word.
	 */
	if ((inf = fopen(pktfile, "r")) != NULL) {
	    if (access(arcfile, R_OK) == -1) {
		ouf = fopen(arcfile, "w");  /* create new  */
		Syslog('p', "Create new %s", arcfile);
	    } else {
		ouf = fopen(arcfile, "r+"); /* open R/W    */
		fseek(ouf, -2, SEEK_END);   /* b4 0 word   */
		fseek(inf, 58, SEEK_SET);   /* skip header */
		Syslog('p', "Append to %s", arcfile);
	    }

	    if (ouf != NULL) {
		buf = malloc(16384);

		do {
		    bread = fread(buf, 1, 16384, inf);
		    fwrite(buf, 1, bread, ouf);
		} while (bread);

		free(buf);
		putc('\0', ouf);
		putc('\0', ouf);
		fsync(fileno(ouf));
		fclose(ouf);
		fclose(inf);
		unlink(pktfile);
	    } else {
		WriteError("$Can't open %s", arcfile);
		fclose(inf);
	    }
	}

	/*
	 * Change filemode so downlink has rights to the file.
	 */
	if (nodes.Session_out == S_DIR)
	    chmod(arcfile, 0660);
    }

    /*
     * Now add the files for the node, information is in the .filelist
     * file, this tells the location of the file and what to do with
     * it after it is sent.
     */
    snprintf(pktfile, PATH_MAX, "%s/.filelist", temp);
    if ((fp = fopen(pktfile, "r")) != NULL) {

	Syslog('+', "Adding files for %s via %s", aka2str(nodenr), ascfnode(&noden, 0x1f));
	if (!do_quiet) {
	    printf("\rAdding files for %s                        ", ascfnode(&noden, 0x1f));
	    fflush(stdout);
	    flushed = TRUE;
	}

	buf = calloc(PATH_MAX + 1, sizeof(char));

	while (fgets(buf, PATH_MAX, fp)) {
	    Striplf(buf);
	    Syslog('p', ".filelist: %s", buf);
	    flavor = buf[0];
	    p = strchr(buf, ' ');
	    p++;
	    if (strncmp(p, "LEAVE ", 6) == 0)
		mode = LEAVE;
	    else if (strncmp(p, "KFS ", 4) == 0)
		mode = KFS;
	    else if (strncmp(p, "TFS ", 4) == 0)
		mode = TFS;
	    else {
		WriteError("Syntax error in filelist \"%s\"", buf);
		mode = LEAVE;
	    }
	    p = strchr(p, ' ');
	    p++;
	    // Here is a extra now unused keyword.
	    p = strchr(p, ' ');
	    p++;

	    Syslog('p', "File attach %s to %s", p, ascfnode(&noden, 0x1f));
	    if (nodes.Session_out == S_DIRECT) {
		attach(noden, p, mode, flavor);
	    } else if (nodes.Session_out == S_DIR) {
		snprintf(arcfile, PATH_MAX, "%s/%s", nodes.Dir_out_path, Basename(p));
		if (mode == LEAVE) {
		    /*
		     * LEAVE file, so we copy this one.
		     */
		    rc = file_cp(p, arcfile);
		    Syslog('p', "file_cp(%s, %s) rc=%d", p, arcfile, rc);
		} else {
		    /*
		     * KFS or TFS, move file to node directory
		     */
		    rc = file_mv(p, arcfile);
		    Syslog('p', "file_mv(%s, %s) rc=%d", p, arcfile, rc);
		}
		chmod(arcfile, 0660);
	    }
	}

	free(buf);
	fclose(fp);
	unlink(pktfile);
    }

    /*
     * We are done, the queue is flushed, unlock the node.
     */
    if (nodes.Session_out == S_DIR)
	remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck, 'p');
    else
	nodeulock(&noden, mypid);

    if (noden.domain)
	free(noden.domain);
    free(temp);
    free(arcfile);
    free(pktfile);
    return;
}