diff --git a/lib/getheader.c b/lib/getheader.c index ac560fcf..9a3ae4ab 100644 --- a/lib/getheader.c +++ b/lib/getheader.c @@ -52,137 +52,134 @@ char pktpwd[9]; */ int getheader(faddr *f, faddr *t, FILE *pkt, char *pname) { - unsigned char buffer[0x3a]; - int i, pwdok; - int capword, prodx; - int major, minor = 0; - int tome = FALSE; - char *p, *prodn = NULL; - char buf[5]; - long year, month, day, hour, min, sec; + unsigned char buffer[0x3a]; + int i, pwdok, capword, prodx, major, minor = 0, tome = FALSE; + char *p, *prodn = NULL, *fa, *ta, buf[5]; + long year, month, day, hour, min, sec; - f->domain = NULL; - f->name = NULL; - t->domain = NULL; - t->name = NULL; + 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]; + 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) { /* - * Read type 2+ packet header, see FSC-0039 version 4 - * and FTS-0001 + * FSC-0039 packet type 2+ */ - 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; + 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); + } + + 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 + */ + sprintf(buf, "%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; } - 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]; + 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; - year = (buffer[0x05] << 8) + buffer[0x04]; - 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]; + 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))) + tome = TRUE; + } - capword = (buffer[0x2d] << 8) + buffer[0x2c]; - if (capword != ((buffer[0x28] << 8) + buffer[0x29])) - capword = 0; + 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) { - /* - * 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); + if (capword & 0x0001) { + buf[0] = buffer[0x36]; + buf[1] = buffer[0x37]; + buf[2] = buffer[0x38]; + buf[3] = buffer[0x39]; + buf[4] = '\0'; + } + + pwdok = TRUE; + if (noderecord(f)) { + if (strcasecmp(nodes.Epasswd, pktpwd) != 0) { + pwdok = FALSE; + if (strlen(pktpwd)) + Syslog('!', "Password : got \"%s\", expected \"%s\"", pktpwd, nodes.Epasswd); } + } else { + Syslog('+', "Node not in setup"); + } - 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; + if (prodn) + free(prodn); - /* - * Fill in a default product code in case it doesn't exist - */ - sprintf(buf, "%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))) - tome = TRUE; - } - - Syslog('+', "Packet : %s type %s", pname, (capword & 0x0001) ? "2+":"stone-age"); - Syslog('+', "From : %s to %s", xstrcpy(ascfnode(f, 0x1f)), xstrcpy(ascfnode(t,0x1f))); - Syslog('+', "Dated : %02u-%02u-%u %02u:%02u:%02u", day, month, year, hour, min, sec); - Syslog('+', "Program : %s %d.%d", prodn, major, minor); - - if (capword & 0x0001) { - buf[0] = buffer[0x36]; - buf[1] = buffer[0x37]; - buf[2] = buffer[0x38]; - buf[3] = buffer[0x39]; - buf[4] = '\0'; - } - - pwdok = TRUE; - if (noderecord(f)) { - if (strcasecmp(nodes.Epasswd, pktpwd) != 0) { - pwdok = FALSE; - if (strlen(pktpwd)) - Syslog('!', "Password : got \"%s\", expected \"%s\"", pktpwd, nodes.Epasswd); - } - } else { - Syslog('+', "Node not in setup"); - } - - if (prodn) - free(prodn); - - if (!tome) - return 3; - else if (!pwdok && nodes.MailPwdCheck) - return 4; - else - return 0; + if (!tome) + return 3; + else if (!pwdok && nodes.MailPwdCheck) + return 4; + else + return 0; } diff --git a/mbfido/mbfido.c b/mbfido/mbfido.c index 1329b4af..1afa7c9a 100644 --- a/mbfido/mbfido.c +++ b/mbfido/mbfido.c @@ -676,9 +676,8 @@ int TossPkts(void) * 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)) { + while ((de = readdir(dp))) + if ((strlen(de->d_name) == 12) && (strncasecmp(de->d_name+8,".pkt",4) == 0)) { stat(de->d_name, &sbuf); fill_fdlist(&fdl, de->d_name, sbuf.st_mtime); } diff --git a/mbfido/postecho.c b/mbfido/postecho.c index a429e546..0709ba94 100644 --- a/mbfido/postecho.c +++ b/mbfido/postecho.c @@ -68,8 +68,7 @@ extern int echo_bad; /* Bad echomail */ void tidy_qualify(qualify **); void fill_qualify(qualify **, fidoaddr, int, int); -void dlog_qualify(qualify **, char *); -int EchoOut(fidoaddr, char *, char *, char *, FILE *, int, int, time_t); +int EchoOut(fidoaddr, char *, char *, char *, FILE *, int, int, time_t); @@ -79,81 +78,67 @@ int EchoOut(fidoaddr, char *, char *, char *, FILE *, int, int, time_t); */ int EchoOut(fidoaddr aka, char *toname, char *fromname, char *subj, FILE *fp, int flags, int cost, time_t date) { - char *buf; - FILE *qp; - faddr *From, *To; - int rc; + char *buf; + FILE *qp; + faddr *From, *To; + int rc; - if ((qp = OpenPkt(msgs.Aka, aka, (char *)"qqq")) == NULL) { - WriteError("EchoOut(): OpenPkt failed"); - return 1; - } + if ((qp = OpenPkt(msgs.Aka, aka, (char *)"qqq")) == NULL) { + WriteError("EchoOut(): OpenPkt failed"); + return 1; + } - From = fido2faddr(msgs.Aka); - To = fido2faddr(aka); - rc = AddMsgHdr(qp, From, To, flags, cost, date, toname, fromname, subj); - tidy_faddr(To); - tidy_faddr(From); - if (rc) { - WriteError("EchoOut(): AddMsgHdr failed"); - return 1; - } + From = fido2faddr(msgs.Aka); + To = fido2faddr(aka); + rc = AddMsgHdr(qp, From, To, flags, cost, date, toname, fromname, subj); + tidy_faddr(To); + tidy_faddr(From); + if (rc) { + WriteError("EchoOut(): AddMsgHdr failed"); + return 1; + } - rewind(fp); - buf = calloc(2048, sizeof(char)); + rewind(fp); + buf = calloc(2049, sizeof(char)); - while ((fgets(buf, 2048, fp)) != NULL) { - Striplf(buf); - fprintf(qp, "%s\r", buf); - } + while ((fgets(buf, 2048, fp)) != NULL) { + Striplf(buf); + fprintf(qp, "%s\r", buf); + } - free(buf); - putc(0, qp); - fsync(fileno(qp)); - fclose(qp); - return 0; + free(buf); + putc(0, qp); + fsync(fileno(qp)); + fclose(qp); + return 0; } void tidy_qualify(qualify **qal) { - qualify *tmp, *old; + qualify *tmp, *old; - for (tmp = *qal; tmp; tmp = old) { - old = tmp->next; - free(tmp); - } - *qal = NULL; + for (tmp = *qal; tmp; tmp = old) { + old = tmp->next; + free(tmp); + } + *qal = NULL; } void fill_qualify(qualify **qal, fidoaddr aka, int orig, int insb) { - qualify *tmp; + qualify *tmp; - tmp = (qualify *)malloc(sizeof(qualify)); - tmp->next = *qal; - tmp->aka = aka; - tmp->inseenby = insb; - tmp->send = ((!insb) && (!orig)); - tmp->orig = orig; - *qal = tmp; -} - - - -void dlog_qualify(qualify **qal, char *msg) -{ - qualify *tmpl; - - for (tmpl = *qal; tmpl; tmpl = tmpl->next) { - Syslog('m', "%s InSB=%s Snd=%s Org=%s", - aka2str(tmpl->aka), tmpl->inseenby ? "True":"False", - tmpl->send ? "True":"False", - tmpl->orig ? "True":"False"); - } + tmp = (qualify *)malloc(sizeof(qualify)); + tmp->next = *qal; + tmp->aka = aka; + tmp->inseenby = insb; + tmp->send = ((!insb) && (!orig)); + tmp->orig = orig; + *qal = tmp; } @@ -169,413 +154,396 @@ void dlog_qualify(qualify **qal, char *msg) * For echomail, the crc32 is calculated over the ^AREA kludge, subject, * message date, origin line, message id. */ -int postecho(faddr *p_from, faddr *f, faddr *t, char *orig, char *subj, - time_t mdate, int flags, int cost, FILE *fp, int tonews) +int postecho(faddr *p_from, faddr *f, faddr *t, char *orig, char *subj, time_t mdate, int flags, int cost, FILE *fp, int tonews) { - char *buf, *msgid = NULL, *reply = NULL, *p, *q, sbe[16]; - int First = TRUE, rc = 0, i, kludges = TRUE; - int dupe = FALSE, bad = TRUE, seenlen, oldnet; - faddr *Faddr; - unsigned long crc; - sysconnect Link; - fa_list *sbl = NULL, *ptl = NULL, *tmpl; - qualify *qal = NULL, *tmpq; - FILE *nfp, *qp; + char *buf, *msgid = NULL, *reply = NULL, *p, *q, sbe[16]; + int First = TRUE, rc = 0, i, kludges = TRUE; + int dupe = FALSE, bad = TRUE, seenlen, oldnet; + faddr *Faddr; + unsigned long crc; + sysconnect Link; + fa_list *sbl = NULL, *ptl = NULL, *tmpl; + qualify *qal = NULL, *tmpq; + FILE *nfp, *qp; -// Syslog('M', "Entering postecho, area %s %s", msgs.Tag, msgs.Name); -// Syslog('M', "p_from: %s", ascfnode(p_from, 0xff)); -// Syslog('M', "from : %s", ascfnode(f, 0xff)); -// Syslog('M', "to : %s", ascfnode(t, 0xff)); -// Syslog('M', "subj : %s", printable(subj, 0)); -// Syslog('M', "origin: %s", orig); -// Syslog('M', "date : %s", rfcdate(mdate)); -// Syslog('M', "flags : %08x", flags); -// Syslog('M', "cost : %d", cost); -// Syslog('M', "tonews: %s", tonews ? "True":"False"); + memset(&Link, 0, sizeof(Link)); + crc = 0xffffffff; + echo_in++; - memset(&Link, 0, sizeof(Link)); - crc = 0xffffffff; - echo_in++; - - /* - * p_from is set for tossed echomail, it is NULL for local posted echomail and gated news. - */ - if (p_from) { - while (GetMsgSystem(&Link, First)) { - First = FALSE; - if ((p_from->zone == Link.aka.zone) && (p_from->net == Link.aka.net) && (p_from->node == Link.aka.node)) { - bad = FALSE; - break; - } - } - if (bad && (msgs.UnSecure || do_unsec)) { - bad = FALSE; - memset(&Link, 0, sizeof(Link)); - } - if (bad) { - Syslog('+', "Node %s not connected to area %s", ascfnode(p_from, 0x1f), msgs.Tag); - echo_bad++; - return 4; - } - if (Link.cutoff && !bad) { - Syslog('+', "Echomail from %s in %s refused, cutoff", ascfnode(p_from, 0x1f), msgs.Tag); - bad = TRUE; - echo_bad++; - return 4; - } - if (!Link.receivefrom && !bad) { - Syslog('+', "Echomail from %s in %s refused, read only", ascfnode(p_from, 0x1f), msgs.Tag); - bad = TRUE; - echo_bad++; - return 4; - } - } else { - /* - * Fake the zone entry to be our own zone, this prevents - * zonegate behaviour. It's also not a bad message yet. - */ - Link.aka.zone = msgs.Aka.zone; - bad = FALSE; - } - - if (CFG.toss_old && ((t_start - mdate) / 86400) > CFG.toss_old) { - Syslog('+', "Rejecting msg: too old, %s", rfcdate(mdate)); - bad = TRUE; - echo_bad++; - return 4; - } - - /* - * Read the message for kludges we need. - */ - buf = calloc(2048, sizeof(char)); - First = TRUE; - rewind(fp); - while ((fgets(buf, 2048, fp)) != NULL) { - - Striplf(buf); -// Syslogp('M', printable(buf, 0)); - - if (First && (!strncmp(buf, "AREA:", 5))) { - crc = upd_crc32(buf, crc, strlen(buf)); - First = FALSE; - } - if (!strncmp(buf, "\001MSGID: ", 8)) - msgid = xstrcpy(buf + 8); - if (!strncmp(buf, "\001REPLY: ", 8)) - reply = xstrcpy(buf + 8); - if (!strncmp(buf, "SEEN-BY:", 8)) { - if (Link.aka.zone == msgs.Aka.zone) { - p = xstrcpy(buf + 9); - fill_list(&sbl, p, NULL); - free(p); - } else - Syslog('m', "Strip zone SB lines"); - } - if (!strncmp(buf, "\001PATH:", 6)) { - p = xstrcpy(buf + 7); - fill_path(&ptl, p); - free(p); - } - } /* end of checking kludges */ - - - /* - * Further dupe checking. - */ - crc = upd_crc32(subj, crc, strlen(subj)); - if (orig == NULL) - Syslog('!', "No origin line found"); - else - crc = upd_crc32(orig, crc, strlen(orig)); - crc = upd_crc32((char *)&mdate, crc, sizeof(mdate)); - if (msgid != NULL) { - crc = upd_crc32(msgid, crc, strlen(msgid)); - } else { - if (check_dupe) { - /* - * If a MSGID is missing it is possible that dupes from some offline - * readers slip through because these readers use the same date for - * each message. In this case the message text is included in the - * dupecheck. Redy Rodriguez. - */ - rewind(fp); - while ((fgets(buf, 2048, fp)) != NULL) { - Striplf(buf); - if (strncmp(buf, "---", 3) == 0) - break; - if ((strncmp(buf, "\001", 1) != 0 ) && (strncmp(buf,"AREA:",5) != 0 )) - crc = upd_crc32(buf, crc , strlen(buf)); - } - } - } - if (check_dupe) - dupe = CheckDupe(crc, D_ECHOMAIL, CFG.toss_dupes); - else - dupe = FALSE; - - - if (!dupe && !msgs.UnSecure && !do_unsec) { - /* - * Check if the message is for us. Don't check point address, - * echomail messages don't have point destination set. - */ - if ((msgs.Aka.zone != t->zone) || (msgs.Aka.net != t->net) || (msgs.Aka.node != t->node)) { - bad = TRUE; - /* - * If we are a hub or host and have all our echomail - * connected to the hub/host aka, echomail from points - * under a nodenumber aka isn't accepted. The match - * must be further tested. - */ - if ((msgs.Aka.zone == t->zone) && (msgs.Aka.net == t->net)) { - for (i = 0; i < 40; i++) { - if ((CFG.akavalid[i]) && - (CFG.aka[i].zone == t->zone) && - (CFG.aka[i].net == t->net) && - (CFG.aka[i].node == t->node)) - bad = FALSE; /* Undo the result */ - } - } - } - if (bad) { - echo_bad++; - WriteError("Msg in %s not for us (%s) but for %s", msgs.Tag, aka2str(msgs.Aka), ascfnode(t,0x1f)); - free(buf); - if (msgid) - free(msgid); - if (reply) - free(reply); - return 4; - } - } - - - /* - * The echomail message is accepted for post/forward/gate - */ - if (!dupe) { - - if (msgs.Aka.zone != Link.aka.zone) { - /* - * If it is a zonegated echomailmessage the SEEN-BY lines - * are stripped off including that of the other zone's - * gate. Add the gate's aka to the SEEN-BY - */ - Syslog('m', "Gated echomail, clean SB"); - tidy_falist(&sbl); - sprintf(sbe, "%u/%u", Link.aka.net, Link.aka.node); - Syslog('m', "Add gate SB %s", sbe); - fill_list(&sbl, sbe, NULL); - } - - /* - * Add more aka's to SEENBY if in the same zone as our system. - * When ready filter dupe's, there is at least one. - */ - for (i = 0; i < 40; i++) { - if (CFG.akavalid[i] && (msgs.Aka.zone == CFG.aka[i].zone) && (CFG.aka[i].point == 0) && - !((msgs.Aka.net == CFG.aka[i].net) && (msgs.Aka.node == CFG.aka[i].node))) { - sprintf(sbe, "%u/%u", CFG.aka[i].net, CFG.aka[i].node); - fill_list(&sbl, sbe, NULL); - } - } - uniq_list(&sbl); - } - - - /* - * Add our system to the path for later export. - */ - sprintf(sbe, "%u/%u", msgs.Aka.net, msgs.Aka.node); - fill_path(&ptl, sbe); - uniq_list(&ptl); /* remove possible duplicate own aka */ - - /* - * Build a list of qualified systems to receive this message. - * Complete the SEEN-BY lines. - */ - First = TRUE; + /* + * p_from is set for tossed echomail, it is NULL for local posted echomail and gated news. + */ + if (p_from) { while (GetMsgSystem(&Link, First)) { - First = FALSE; - if ((Link.aka.zone) && (Link.sendto) && (!Link.pause) && (!Link.cutoff)) { - Faddr = fido2faddr(Link.aka); - if (p_from == NULL) { - fill_qualify(&qal, Link.aka, FALSE, in_list(Faddr, &sbl, FALSE)); - } else { - fill_qualify(&qal, Link.aka, ((p_from->zone == Link.aka.zone) && - (p_from->net == Link.aka.net) && (p_from->node == Link.aka.node) && - (p_from->point == Link.aka.point)), in_list(Faddr, &sbl, FALSE)); - } - tidy_faddr(Faddr); + First = FALSE; + if ((p_from->zone == Link.aka.zone) && (p_from->net == Link.aka.net) && (p_from->node == Link.aka.node)) { + bad = FALSE; + break; + } + } + if (bad && (msgs.UnSecure || do_unsec)) { + bad = FALSE; + memset(&Link, 0, sizeof(Link)); + } + if (bad) { + Syslog('+', "Node %s not connected to area %s", ascfnode(p_from, 0x1f), msgs.Tag); + echo_bad++; + return 4; + } + if (Link.cutoff && !bad) { + Syslog('+', "Echomail from %s in %s refused, cutoff", ascfnode(p_from, 0x1f), msgs.Tag); + bad = TRUE; + echo_bad++; + return 4; + } + if (!Link.receivefrom && !bad) { + Syslog('+', "Echomail from %s in %s refused, read only", ascfnode(p_from, 0x1f), msgs.Tag); + bad = TRUE; + echo_bad++; + return 4; + } + } else { + /* + * Fake the zone entry to be our own zone, this prevents + * zonegate behaviour. It's also not a bad message yet. + */ + Link.aka.zone = msgs.Aka.zone; + bad = FALSE; + } + + if (CFG.toss_old && ((t_start - mdate) / 86400) > CFG.toss_old) { + Syslog('+', "Rejecting msg: too old, %s", rfcdate(mdate)); + bad = TRUE; + echo_bad++; + return 4; + } + + /* + * Read the message for kludges we need. + */ + buf = calloc(2049, sizeof(char)); + First = TRUE; + rewind(fp); + while ((fgets(buf, 2048, fp)) != NULL) { + + Striplf(buf); + + if (First && (!strncmp(buf, "AREA:", 5))) { + crc = upd_crc32(buf, crc, strlen(buf)); + First = FALSE; + } + if (!strncmp(buf, "\001MSGID: ", 8)) + msgid = xstrcpy(buf + 8); + if (!strncmp(buf, "\001REPLY: ", 8)) + reply = xstrcpy(buf + 8); + if (!strncmp(buf, "SEEN-BY:", 8)) { + if (Link.aka.zone == msgs.Aka.zone) { + p = xstrcpy(buf + 9); + fill_list(&sbl, p, NULL); + free(p); + } else + Syslog('m', "Strip zone SB lines"); + } + if (!strncmp(buf, "\001PATH:", 6)) { + p = xstrcpy(buf + 7); + fill_path(&ptl, p); + free(p); + } + } /* end of checking kludges */ + + + /* + * Further dupe checking. + */ + crc = upd_crc32(subj, crc, strlen(subj)); + if (orig == NULL) + Syslog('!', "No origin line found"); + else + crc = upd_crc32(orig, crc, strlen(orig)); + crc = upd_crc32((char *)&mdate, crc, sizeof(mdate)); + if (msgid != NULL) { + crc = upd_crc32(msgid, crc, strlen(msgid)); + } else { + if (check_dupe) { + /* + * If a MSGID is missing it is possible that dupes from some offline + * readers slip through because these readers use the same date for + * each message. In this case the message text is included in the + * dupecheck. Redy Rodriguez. + */ + rewind(fp); + while ((fgets(buf, 2048, fp)) != NULL) { + Striplf(buf); + if (strncmp(buf, "---", 3) == 0) + break; + if ((strncmp(buf, "\001", 1) != 0 ) && (strncmp(buf,"AREA:",5) != 0 )) + crc = upd_crc32(buf, crc , strlen(buf)); + } + } + } + if (check_dupe) + dupe = CheckDupe(crc, D_ECHOMAIL, CFG.toss_dupes); + else + dupe = FALSE; + + + if (!dupe && !msgs.UnSecure && !do_unsec) { + /* + * Check if the message is for us. Don't check point address, + * echomail messages don't have point destination set. + */ + if ((msgs.Aka.zone != t->zone) || (msgs.Aka.net != t->net) || (msgs.Aka.node != t->node)) { + bad = TRUE; + /* + * If we are a hub or host and have all our echomail + * connected to the hub/host aka, echomail from points + * under a nodenumber aka isn't accepted. The match + * must be further tested. + */ + if ((msgs.Aka.zone == t->zone) && (msgs.Aka.net == t->net)) { + for (i = 0; i < 40; i++) { + if ((CFG.akavalid[i]) && (CFG.aka[i].zone == t->zone) && + (CFG.aka[i].net == t->net) && (CFG.aka[i].node == t->node)) + bad = FALSE; /* Undo the result */ } + } + } + if (bad) { + echo_bad++; + WriteError("Msg in %s not for us (%s) but for %s", msgs.Tag, aka2str(msgs.Aka), ascfnode(t,0x1f)); + free(buf); + if (msgid) + free(msgid); + if (reply) + free(reply); + return 4; + } + } + + + /* + * The echomail message is accepted for post/forward/gate + */ + if (!dupe) { + + if (msgs.Aka.zone != Link.aka.zone) { + /* + * If it is a zonegated echomailmessage the SEEN-BY lines + * are stripped off including that of the other zone's + * gate. Add the gate's aka to the SEEN-BY + */ + Syslog('m', "Gated echomail, clean SB"); + tidy_falist(&sbl); + sprintf(sbe, "%u/%u", Link.aka.net, Link.aka.node); + Syslog('m', "Add gate SB %s", sbe); + fill_list(&sbl, sbe, NULL); } - /* - * Add SEEN-BY for nodes qualified to receive this message. - * When ready, filter the dupes and sort the SEEN-BY entries. + * Add more aka's to SEENBY if in the same zone as our system. + * When ready filter dupe's, there is at least one. */ - for (tmpq = qal; tmpq; tmpq = tmpq->next) { - if (tmpq->send) { - sprintf(sbe, "%u/%u", tmpq->aka.net, tmpq->aka.node); - fill_list(&sbl, sbe, NULL); - } + for (i = 0; i < 40; i++) { + if (CFG.akavalid[i] && (msgs.Aka.zone == CFG.aka[i].zone) && (CFG.aka[i].point == 0) && + !((msgs.Aka.net == CFG.aka[i].net) && (msgs.Aka.node == CFG.aka[i].node))) { + sprintf(sbe, "%u/%u", CFG.aka[i].net, CFG.aka[i].node); + fill_list(&sbl, sbe, NULL); + } } uniq_list(&sbl); - sort_list(&sbl); + } - /* - * Create a new tmpfile with a copy of the message - * without original PATH and SEENBY lines, add the - * new PATH and SEENBY lines. - */ - rewind(fp); - if ((nfp = tmpfile()) == NULL) - WriteError("$Unable to open tmpfile"); - while ((fgets(buf, 2048, fp)) != NULL) { - Striplf(buf); - fprintf(nfp, "%s", buf); - /* - * Don't write SEEN-BY and PATH lines - */ - if (strncmp(buf, " * Origin:", 10) == 0) - break; - fprintf(nfp, "\n"); + /* + * Add our system to the path for later export. + */ + sprintf(sbe, "%u/%u", msgs.Aka.net, msgs.Aka.node); + fill_path(&ptl, sbe); + uniq_list(&ptl); /* remove possible duplicate own aka */ + + /* + * Build a list of qualified systems to receive this message. + * Complete the SEEN-BY lines. + */ + First = TRUE; + while (GetMsgSystem(&Link, First)) { + First = FALSE; + if ((Link.aka.zone) && (Link.sendto) && (!Link.pause) && (!Link.cutoff)) { + Faddr = fido2faddr(Link.aka); + if (p_from == NULL) { + fill_qualify(&qal, Link.aka, FALSE, in_list(Faddr, &sbl, FALSE)); + } else { + fill_qualify(&qal, Link.aka, ((p_from->zone == Link.aka.zone) && + (p_from->net == Link.aka.net) && (p_from->node == Link.aka.node) && + (p_from->point == Link.aka.point)), in_list(Faddr, &sbl, FALSE)); + } + tidy_faddr(Faddr); } + } - /* - * Now add new SEEN-BY and PATH lines - */ - seenlen = MAXSEEN + 1; - /* - * Ensure that 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) - sprintf(sbe, " %u", tmpl->addr->node); - else - sprintf(sbe, " %u/%u", tmpl->addr->net, tmpl->addr->node); - oldnet = tmpl->addr->net; - seenlen += strlen(sbe); - if (seenlen > MAXSEEN) { - seenlen = 0; - fprintf(nfp, "\nSEEN-BY:"); - sprintf(sbe, " %u/%u", tmpl->addr->net, tmpl->addr->node); - seenlen = strlen(sbe); - } - fprintf(nfp, "%s", sbe); + /* + * Add SEEN-BY for nodes qualified to receive this message. + * When ready, filter the dupes and sort the SEEN-BY entries. + */ + for (tmpq = qal; tmpq; tmpq = tmpq->next) { + if (tmpq->send) { + sprintf(sbe, "%u/%u", tmpq->aka.net, tmpq->aka.node); + fill_list(&sbl, sbe, NULL); } + } + uniq_list(&sbl); + sort_list(&sbl); - seenlen = MAXPATH + 1; - /* - * Ensure it will not match for the first entry + + /* + * Create a new tmpfile with a copy of the message + * without original PATH and SEENBY lines, add the + * new PATH and SEENBY lines. + */ + rewind(fp); + if ((nfp = tmpfile()) == NULL) + WriteError("$Unable to open tmpfile"); + while ((fgets(buf, 2048, fp)) != NULL) { + Striplf(buf); + fprintf(nfp, "%s", buf); + /* + * Don't write SEEN-BY and PATH lines */ - oldnet = ptl->addr->net - 1; - for (tmpl = ptl; tmpl; tmpl = tmpl->next) { - if (tmpl->addr->net == oldnet) - sprintf(sbe, " %u", tmpl->addr->node); - else - sprintf(sbe, " %u/%u", tmpl->addr->net, tmpl->addr->node); - oldnet = tmpl->addr->net; - seenlen += strlen(sbe); - if (seenlen > MAXPATH) { - seenlen = 0; - fprintf(nfp, "\n\001PATH:"); - sprintf(sbe, " %u/%u", tmpl->addr->net, tmpl->addr->node); - seenlen = strlen(sbe); - } - fprintf(nfp, "%s", sbe); - } + if (strncmp(buf, " * Origin:", 10) == 0) + break; fprintf(nfp, "\n"); - fflush(nfp); - rewind(nfp); + } - /* - * Import this echomail, even if it's bad or a dupe. - */ - if ((rc = storeecho(f, t, mdate, flags, subj, msgid, reply, bad, dupe, nfp)) || bad || dupe) { - /* - * Store failed or it was bad or a dupe. Only log failed store. - */ - if (rc) - WriteError("Store echomail in JAM base failed"); - tidy_falist(&sbl); - tidy_falist(&ptl); - tidy_qualify(&qal); - free(buf); - if (msgid) - free(msgid); - if (reply) - free(reply); - return rc; + /* + * Now add new SEEN-BY and PATH lines + */ + seenlen = MAXSEEN + 1; + /* + * Ensure that 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) + sprintf(sbe, " %u", tmpl->addr->node); + else + sprintf(sbe, " %u/%u", tmpl->addr->net, tmpl->addr->node); + oldnet = tmpl->addr->net; + seenlen += strlen(sbe); + if (seenlen > MAXSEEN) { + seenlen = 0; + fprintf(nfp, "\nSEEN-BY:"); + sprintf(sbe, " %u/%u", tmpl->addr->net, tmpl->addr->node); + seenlen = strlen(sbe); } + fprintf(nfp, "%s", sbe); + } - /* - * Forward to other links - */ - for (tmpq = qal; tmpq; tmpq = tmpq->next) { - if (tmpq->send) { - if (SearchNode(tmpq->aka)) { - StatAdd(&nodes.MailSent, 1L); - UpdateNode(); - SearchNode(tmpq->aka); - } - echo_out++; - if (EchoOut(tmpq->aka, t->name, f->name, subj, nfp, flags, cost, mdate)) - WriteError("Forward echomail to %s failed", aka2str(tmpq->aka)); - } + 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) + sprintf(sbe, " %u", tmpl->addr->node); + else + sprintf(sbe, " %u/%u", tmpl->addr->net, tmpl->addr->node); + oldnet = tmpl->addr->net; + seenlen += strlen(sbe); + if (seenlen > MAXPATH) { + seenlen = 0; + fprintf(nfp, "\n\001PATH:"); + sprintf(sbe, " %u/%u", tmpl->addr->net, tmpl->addr->node); + seenlen = strlen(sbe); } + fprintf(nfp, "%s", sbe); + } + fprintf(nfp, "\n"); + fflush(nfp); + rewind(nfp); + + /* + * Import this echomail, even if it's bad or a dupe. + */ + if ((rc = storeecho(f, t, mdate, flags, subj, msgid, reply, bad, dupe, nfp)) || bad || dupe) { /* - * Gate to newsserver - */ - if (strlen(msgs.Newsgroup) && tonews) { - rewind(nfp); - qp = tmpfile(); - while ((fgets(buf, 2048, nfp)) != NULL) { - Striplf(buf); - if (kludges && (buf[0] != '\001') && strncmp(buf, "AREA:", 5)) { - kludges = FALSE; - q = xstrcpy(Msg.From); - for (i = 0; i < strlen(q); i++) - if (q[i] == ' ') - q[i] = '_'; - fprintf(qp, "From: %s@%s\n", q, ascinode(f, 0x1f)); - fprintf(qp, "Subject: %s\n", Msg.Subject); - fprintf(qp, "To: %s\n", Msg.To); - - // FIXME: hier nog X-...-To: ?? - - fprintf(qp, "\n"); - } - fprintf(qp, "%s\n", buf); - } - rewind(qp); - ftn2rfc(f, t, subj, orig, mdate, flags, qp); - fclose(qp); - } - fclose(nfp); - - /* - * Free memory used by SEEN-BY, ^APATH and Qualified lines. + * Store failed or it was bad or a dupe. Only log failed store. */ + if (rc) + WriteError("Store echomail in JAM base failed"); tidy_falist(&sbl); tidy_falist(&ptl); tidy_qualify(&qal); - - if (rc < 0) - rc =-rc; free(buf); if (msgid) - free(msgid); + free(msgid); if (reply) - free(reply); + free(reply); return rc; + } + + /* + * Forward to other links + */ + for (tmpq = qal; tmpq; tmpq = tmpq->next) { + if (tmpq->send) { + if (SearchNode(tmpq->aka)) { + StatAdd(&nodes.MailSent, 1L); + UpdateNode(); + SearchNode(tmpq->aka); + } + echo_out++; + if (EchoOut(tmpq->aka, t->name, f->name, subj, nfp, flags, cost, mdate)) + WriteError("Forward echomail to %s failed", aka2str(tmpq->aka)); + } + } + + /* + * Gate to newsserver + */ + if (strlen(msgs.Newsgroup) && tonews) { + rewind(nfp); + qp = tmpfile(); + while ((fgets(buf, 2048, nfp)) != NULL) { + Striplf(buf); + if (kludges && (buf[0] != '\001') && strncmp(buf, "AREA:", 5)) { + kludges = FALSE; + q = xstrcpy(Msg.From); + for (i = 0; i < strlen(q); i++) + if (q[i] == ' ') + q[i] = '_'; + fprintf(qp, "From: %s@%s\n", q, ascinode(f, 0x1f)); + fprintf(qp, "Subject: %s\n", Msg.Subject); + fprintf(qp, "To: %s\n", Msg.To); + free(q); + fprintf(qp, "\n"); + } + fprintf(qp, "%s\n", buf); + } + rewind(qp); + ftn2rfc(f, t, subj, orig, mdate, flags, qp); + fclose(qp); + } + fclose(nfp); + + /* + * Free memory used by SEEN-BY, ^APATH and Qualified lines. + */ + tidy_falist(&sbl); + tidy_falist(&ptl); + tidy_qualify(&qal); + + if (rc < 0) + rc =-rc; + free(buf); + if (msgid) + free(msgid); + if (reply) + free(reply); + return rc; } diff --git a/mbfido/storeecho.c b/mbfido/storeecho.c index ab4b8b25..a38eb08c 100644 --- a/mbfido/storeecho.c +++ b/mbfido/storeecho.c @@ -151,7 +151,7 @@ int storeecho(faddr *f, faddr *t, time_t mdate, int flags, char *subj, char *msg * If not a bad or dupe message, eat the first * line (AREA:tag). */ - buf = calloc(2048, sizeof(char)); + buf = calloc(2049, sizeof(char)); rewind(fp); if (!dupe && !bad) fgets(buf , 2048, fp);