diff --git a/ChangeLog b/ChangeLog index e2c77b32..01eda06f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ $Id$ + WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! + + Inbound file handling is changed, this version is under test and should NOT + be used on production systems + + WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! + WARNING, users of Sparc and HP-PA systems should be carefull, some menus do not work. All other users on Intel machines (99,9% I think) can use this version. @@ -12,6 +19,16 @@ v0.37.6 10-Aug-2003 Removed memwatch debugger. Changed all gif and jpg images to png images. + mbcico: + Completly changed the files inbound receive, all files are now + first stored in a unique per node temporary inbound directory. + Only after a successfull session all received files are moved + to the final inbound directory. Hopefully this will solve the + resync problems. + The other goodie is that this is more safe on busy multiline + systems. + Fixed the binkp escape sequence which is wrong in the FSP. + v0.37.5 12-Jul-2003 - 10-Aug-2003 diff --git a/Makefile b/Makefile index ba0b0213..06df58f5 100644 --- a/Makefile +++ b/Makefile @@ -162,6 +162,10 @@ install: mkdir ${PREFIX}/var/run ; \ ${CHOWN} ${OWNER}:${GROUP} ${PREFIX}/var/run ; \ fi + @if [ -d ${PREFIX}/var/inbound/tmp ]; then \ + rmdir ${PREFIX}/var/inbound/tmp ; \ + echo "Removed ${PREFIX}/var/inbound/tmp" ; \ + fi chmod 0770 ${PREFIX}/var/rules chmod 0770 ${PREFIX}/var/run @if [ ! -d ${PREFIX}/var/unknown ] ; then \ diff --git a/TODO b/TODO index 74854799..af4ea188 100644 --- a/TODO +++ b/TODO @@ -110,6 +110,9 @@ mbcico: N: Implement binkp resync when getting files. Transmit works. + N: FTS-0001 sessions always are secure, the password check is not + good. + mbfile: L: Add a check to see if the magic filenames are (still) valid. diff --git a/mbcico/Makefile b/mbcico/Makefile index d597e968..cc6b2993 100644 --- a/mbcico/Makefile +++ b/mbcico/Makefile @@ -5,7 +5,7 @@ include ../Makefile.global SRCS = zmmisc.c zmrle.c zmrecv.c zmsend.c binkp.c md5b.c \ - xmsend.c xmrecv.c m7recv.c m7send.c hydra.c \ + xmsend.c xmrecv.c m7recv.c m7send.c hydra.c inbound.c \ answer.c chat.c dial.c dietifna.c emsidat.c filelist.c \ openfile.c openport.c opentcp.c rdoptions.c yoohoo.c \ recvbark.c respfreq.c sendbark.c tcp.c tcpproto.c wazoo.c \ @@ -14,7 +14,7 @@ SRCS = zmmisc.c zmrle.c zmrecv.c zmsend.c binkp.c md5b.c \ callstat.c session.c call.c mbcico.c \ outstat.c nlinfo.c mbout.c HDRS = zmodem.h binkp.h config.h statetbl.h md5b.h \ - xmsend.h xmrecv.h m7recv.h m7send.h hydra.h \ + xmsend.h xmrecv.h m7recv.h m7send.h hydra.h inbound.h \ answer.h chat.h dial.h dietifna.h emsidat.h filelist.h \ openfile.h openport.h opentcp.h rdoptions.h yoohoo.h \ recvbark.h respfreq.h sendbark.h tcp.h tcpproto.h wazoo.h \ @@ -23,7 +23,7 @@ HDRS = zmodem.h binkp.h config.h statetbl.h md5b.h \ callstat.h session.h call.h mbcico.h \ outstat.h nlinfo.h MBCICO_OBJS = zmmisc.o zmrle.o zmrecv.o zmsend.o binkp.o md5b.o \ - xmsend.o xmrecv.o m7recv.o m7send.o hydra.o \ + xmsend.o xmrecv.o m7recv.o m7send.o hydra.o inbound.o \ answer.o chat.o dial.o dietifna.o emsidat.o filelist.o \ openfile.o openport.o opentcp.o rdoptions.o yoohoo.o \ recvbark.o respfreq.o sendbark.o tcp.o tcpproto.o wazoo.o \ @@ -91,13 +91,14 @@ zmmisc.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/node zmrle.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/clcomm.h ../lib/common.h ../lib/nodelist.h ttyio.h session.h zmodem.h zmrecv.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/clcomm.h ../lib/common.h ../lib/nodelist.h lutil.h ttyio.h session.h zmodem.h config.h emsi.h openfile.h filelist.h openport.h zmsend.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ttyio.h session.h zmodem.h lutil.h emsi.h filelist.h -binkp.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/dbnode.h ../lib/clcomm.h ../lib/mberrors.h ttyio.h session.h statetbl.h config.h emsi.h openfile.h respfreq.h filelist.h opentcp.h rdoptions.h lutil.h binkp.h config.h md5b.h +binkp.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/dbnode.h ../lib/clcomm.h ../lib/mberrors.h ttyio.h session.h statetbl.h config.h emsi.h openfile.h respfreq.h filelist.h opentcp.h rdoptions.h lutil.h binkp.h config.h md5b.h inbound.h md5b.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h lutil.h md5b.h xmsend.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h session.h ttyio.h statetbl.h xmsend.h m7send.h filelist.h filetime.h xmrecv.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h session.h ttyio.h statetbl.h config.h lutil.h openfile.h m7recv.h xmrecv.h filelist.h filetime.h m7recv.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h statetbl.h ttyio.h m7recv.h m7send.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h statetbl.h ttyio.h m7send.h hydra.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/mberrors.h session.h filelist.h filetime.h ttyio.h statetbl.h config.h emsi.h openfile.h lutil.h respfreq.h mbcico.h hydra.h +inbound.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h inbound.h answer.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/dbnode.h ../lib/mberrors.h lutil.h session.h config.h answer.h openport.h portsel.h dial.h rdoptions.h mbcico.h chat.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h config.h chat.h ttyio.h dial.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/dbnode.h ../lib/mberrors.h config.h chat.h ttyio.h session.h dial.h @@ -116,17 +117,17 @@ tcp.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/nodelis tcpproto.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/mberrors.h ttyio.h session.h config.h emsi.h lutil.h openfile.h filelist.h tcpproto.h wazoo.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/mberrors.h ttyio.h session.h statetbl.h config.h emsi.h respfreq.h filelist.h wazoo.h zmodem.h filetime.o: ../config.h ../lib/libs.h filetime.h -ftsc.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/mberrors.h session.h ttyio.h statetbl.h config.h ftsc.h rdoptions.h recvbark.h filelist.h sendbark.h respfreq.h xmrecv.h xmsend.h +ftsc.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/mberrors.h session.h ttyio.h statetbl.h config.h ftsc.h rdoptions.h recvbark.h filelist.h sendbark.h respfreq.h xmrecv.h xmsend.h inbound.h atoul.o: ../config.h ../lib/libs.h atoul.h portsel.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h portsel.h ttyio.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ttyio.h lutil.h lutil.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h lutil.h scanout.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbftn.h config.h scanout.h lutil.h -emsi.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/dbnode.h ../lib/clcomm.h ../lib/mberrors.h ttyio.h session.h statetbl.h config.h emsi.h emsidat.h hydra.h rdoptions.h tcp.h wazoo.h +emsi.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/dbnode.h ../lib/clcomm.h ../lib/mberrors.h ttyio.h session.h statetbl.h config.h emsi.h emsidat.h hydra.h rdoptions.h tcp.h wazoo.h inbound.h ulock.o: ../config.h ../lib/libs.h ../lib/clcomm.h callstat.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/clcomm.h ../lib/common.h callstat.h -session.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/mberrors.h ttyio.h statetbl.h emsi.h ftsc.h session.h yoohoo.h mbcico.h binkp.h callstat.h -call.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/dbnode.h ../lib/mberrors.h session.h callstat.h call.h config.h dial.h lutil.h portsel.h openport.h opentcp.h rdoptions.h +session.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/nodelist.h ../lib/mberrors.h ttyio.h statetbl.h emsi.h ftsc.h session.h yoohoo.h mbcico.h binkp.h callstat.h inbound.h +call.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/dbnode.h ../lib/mberrors.h session.h callstat.h call.h config.h dial.h lutil.h portsel.h openport.h opentcp.h rdoptions.h inbound.h mbcico.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/dbcfg.h ../lib/dbnode.h ../lib/dbftn.h ../lib/mberrors.h config.h answer.h call.h lutil.h mbcico.h session.h outstat.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h ../lib/dbcfg.h ../lib/dbnode.h ../lib/dbftn.h ../lib/mberrors.h scanout.h callstat.h outstat.h nlinfo.o: ../config.h ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/nodelist.h ../lib/clcomm.h nlinfo.h diff --git a/mbcico/answer.c b/mbcico/answer.c index b174280a..7c498061 100644 --- a/mbcico/answer.c +++ b/mbcico/answer.c @@ -4,7 +4,7 @@ * Purpose ...............: Fidonet mailer - awnser a call * ***************************************************************************** - * Copyright (C) 1997-2002 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -96,10 +96,6 @@ int answer(char *stype) c_start = time(NULL); rdoptions(FALSE); - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.inbound); /* slave session is unsecure by default */ - if (stype == NULL) { st=SESSION_UNKNOWN; } else if (strcmp(stype,"tsync") == 0) { diff --git a/mbcico/binkp.c b/mbcico/binkp.c index 1645838f..60af14ba 100644 --- a/mbcico/binkp.c +++ b/mbcico/binkp.c @@ -53,6 +53,7 @@ #include "binkp.h" #include "config.h" #include "md5b.h" +#include "inbound.h" /* @@ -246,7 +247,7 @@ char *unix2binkp(char *fn) *q++ = *p; *q = '\0'; } else { - sprintf(q, "\\%2x", p[0]); + sprintf(q, "\\x%2x", p[0]); } while (*q) q++; @@ -283,7 +284,8 @@ char *binkp2unix(char *fn) *q = '\0'; } else { /* - * If remote sends \x0a method instead of \0a, eat the x character + * If remote sends \x0a method instead of \0a, eat the x character. + * Remotes should send the x character, But some (Argus) don't. */ if ((*p == 'x') || (*p == 'X')) p++; @@ -847,9 +849,6 @@ SM_STATE(waitaddr) for (tmpa = remote; tmpa; tmpa = tmpa->next) { if (((nlent = getnlent(tmpa->addr))) && (nlent->pflag != NL_DUMMY)) { Syslog('+', "Binkp: remote is a listed system"); - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.inbound); UserCity(mypid, nlent->sysop, nlent->location); break; } @@ -913,6 +912,7 @@ SM_STATE(waitpwd) SM_STATE(pwdack) + tmpa = remote; if ((strncmp(&rbuf[1], "CRAM-", 5) == 0) && CRAMflag && Loaded) { char *sp, *pw; pw = xstrcpy(nodes.Spasswd); @@ -929,9 +929,7 @@ SM_STATE(pwdack) free(sp); sp = NULL; Syslog('+', "Binkp: MD5 password OK, protected session"); - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.pinbound); + inbound_open(tmpa->addr, TRUE); binkp_send_control(MM_OK, "secure"); SM_SUCCESS; } @@ -942,17 +940,17 @@ SM_STATE(pwdack) } } else if ((strcmp(&rbuf[1], "-") == 0) && !Loaded) { Syslog('+', "Binkp: node not in setup, unprotected session"); + inbound_open(tmpa->addr, FALSE); binkp_send_control(MM_OK, ""); SM_SUCCESS; } else if ((strcmp(&rbuf[1], "-") == 0) && Loaded && !strlen(nodes.Spasswd)) { Syslog('+', "Binkp: node in setup but no session password, unprotected session"); + inbound_open(tmpa->addr, FALSE); binkp_send_control(MM_OK, ""); SM_SUCCESS; } else if ((strcmp(&rbuf[1], nodes.Spasswd) == 0) && Loaded) { Syslog('+', "Binkp: password OK, protected session"); - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.pinbound); + inbound_open(tmpa->addr, TRUE); binkp_send_control(MM_OK, "secure"); SM_SUCCESS; } else { @@ -1364,7 +1362,7 @@ int binkp_batch(file_list *to_send, int role) rxcrc = rxcrc ^ 0xffffffff; if (rcrc == rxcrc) { binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc); - closefile(TRUE); + closefile(); } else { rxerror = TRUE; crc_errors++; @@ -1376,14 +1374,14 @@ int binkp_batch(file_list *to_send, int role) RxState = RxDone; rc = MBERR_FTRANSFER; } - closefile(FALSE); + closefile(); } } else { /* * ACK without CRC check */ binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime); - closefile(TRUE); + closefile(); } rxpos = rxpos - rxbytes; gettimeofday(&rxtvend, &tz); @@ -1504,6 +1502,15 @@ int binkp_batch(file_list *to_send, int role) free(rname); free(lname); free(gname); + + /* + * If there was an error, try to close a possible incomplete file in + * the temp inbound so we can resume the next time we have a session + * with this node. + */ + if (rc) + closefile(); + Syslog('+', "Binkp: batch %d completed rc=%d", batchnr, rc); return rc; } diff --git a/mbcico/call.c b/mbcico/call.c index d7193de2..146261ea 100644 --- a/mbcico/call.c +++ b/mbcico/call.c @@ -48,6 +48,8 @@ #include "openport.h" #include "opentcp.h" #include "rdoptions.h" +#include "inbound.h" + extern int tcp_mode; @@ -205,16 +207,13 @@ int call(faddr *addr) Syslog('?', "Warning: calling non-CM system outside ZMH"); } - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.pinbound); /* master sessions are secure */ + inbound_open(addr, TRUE); /* master sessions are secure */ /* * Call when: * there is a phone number and node is not down, hold or pvt * or * there is a fqdn/ip-address and node is not down or hold - * * and * nocall is false */ diff --git a/mbcico/emsi.c b/mbcico/emsi.c index 0cb4c2bb..5d882a67 100644 --- a/mbcico/emsi.c +++ b/mbcico/emsi.c @@ -4,7 +4,7 @@ * Purpose ...............: Fidonet mailer * ***************************************************************************** - * Copyright (C) 1997-2002 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -48,6 +48,7 @@ #include "rdoptions.h" #include "tcp.h" #include "wazoo.h" +#include "inbound.h" #define LOCAL_PROTOS (PROT_ZMO | PROT_ZAP | PROT_HYD | PROT_TCP) @@ -74,7 +75,7 @@ char emsi_remote_comm[4]="8N1"; int rx_emsi(char *data) { - int rc; + int rc, protect = FALSE; fa_list *tmr; int denypw=0; @@ -135,9 +136,6 @@ int rx_emsi(char *data) for (tmr = remote; tmr; tmr = tmr->next) if (((nlent = getnlent(tmr->addr))) && (nlent->pflag != NL_DUMMY)) { Syslog('+', "Remote is a listed system"); - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.inbound); UserCity(mypid, nlent->sysop, nlent->location); break; } @@ -162,9 +160,7 @@ int rx_emsi(char *data) if ((strncasecmp(emsi_remote_password, nodes.Spasswd, strlen(nodes.Spasswd)) == 0) && (strlen(emsi_remote_password) == strlen(nodes.Spasswd))) { emsi_local_password = xstrcpy(nodes.Spasswd); - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.pinbound); + protect = TRUE; Syslog('+', "Password correct, protected EMSI session"); } else { denypw = 1; @@ -177,6 +173,7 @@ int rx_emsi(char *data) Syslog('?', "Unexpected remote password \"%s\"", MBSE_SS(emsi_local_password)); } + inbound_open(remote->addr, protect); Syslog('i', "local lcodes 0x%04x, protos 0x%04x, opts 0x%04x", emsi_local_lcodes,emsi_local_protos,emsi_local_opts); if ((rc=txemsi())) diff --git a/mbcico/ftsc.c b/mbcico/ftsc.c index 9d0c7f84..a9c8a957 100644 --- a/mbcico/ftsc.c +++ b/mbcico/ftsc.c @@ -4,7 +4,7 @@ * Purpose ...............: Fidonet mailer * ***************************************************************************** - * Copyright (C) 1997-2001 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -49,7 +49,7 @@ #include "respfreq.h" #include "xmrecv.h" #include "xmsend.h" - +#include "inbound.h" extern int master; @@ -375,7 +375,7 @@ SM_NAMES (char *)"scan_packet", (char *)"recv_file" SM_EDECL - int rc=0; + int rc = 0, protect = FALSE; char recvpktname[16]; char *fpath; FILE *fp; @@ -402,9 +402,15 @@ SM_STATE(recv_packet) SM_STATE(scan_packet) + /* + * We cannot use the temp inbound per node yet, FTS-0001 does it's + * handshake by sending us a .pkt file, we store this in the old + * style ../tmp/ dir in the unprotected inbound. + */ fpath = xstrcpy(inbound); fpath = xstrcat(fpath,(char *)"/"); fpath = xstrcat(fpath,recvpktname); + mkdirs(fpath, 0700); fp = fopen(fpath,"r"); free(fpath); if (fp == NULL) { @@ -444,9 +450,6 @@ SM_STATE(scan_packet) if (((nlent=getnlent(remote->addr))) && (nlent->pflag != NL_DUMMY)) { Syslog('+', "remote is a listed system"); - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.inbound); strncpy(history.system_name, nlent->name, 35); strncpy(history.location, nlent->location, 35); strncpy(history.sysop, nlent->sysop, 35); @@ -467,11 +470,10 @@ SM_STATE(scan_packet) */ if (f.name) { Syslog('+', "Password correct, protected FTS-0001 session"); - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.pinbound); + protect = TRUE; } - + inbound_open(remote->addr, protect); + tosend = create_filelist(remote,(char *)ALL_MAIL,1); if (rc == 0) { SM_PROCEED(recv_file); diff --git a/mbcico/hydra.c b/mbcico/hydra.c index 88119cdd..c8c7a892 100644 --- a/mbcico/hydra.c +++ b/mbcico/hydra.c @@ -5,7 +5,7 @@ * Remark ................: See below for more copyright details and credits. * ***************************************************************************** - * Copyright (C) 1997-2001 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -1417,7 +1417,7 @@ int hydra_batch(int role, file_list *to_send) if (rxpos >= 0) { rxfp = NULL; - if (!closefile(1)) { + if (!closefile()) { srxpos = rxpos - srxpos; Syslog('+', "Hydra: OK %s", @@ -1439,7 +1439,7 @@ int hydra_batch(int role, file_list *to_send) rxendtime.tv_sec - rxstarttime.tv_sec); if (rxfp) { - closefile(0); + closefile(); rxfp = NULL; } @@ -1447,7 +1447,7 @@ int hydra_batch(int role, file_list *to_send) } } else if (longnum == -2) { if (rxfp) { - closefile(0); + closefile(); rxfp = NULL; } @@ -1577,7 +1577,7 @@ int hydra_batch(int role, file_list *to_send) /* check if file is still open */ if (rxfp) { rxfp = NULL; - closefile(0); + closefile(); } Syslog('+', "Hydra: signal CAN to remote"); diff --git a/mbcico/inbound.c b/mbcico/inbound.c new file mode 100644 index 00000000..e9a00c4a --- /dev/null +++ b/mbcico/inbound.c @@ -0,0 +1,170 @@ +/***************************************************************************** + * + * $Id$ + * File ..................: mbcico/inbound.c + * Purpose ...............: Fidonet mailer, inbound functions + * + ***************************************************************************** + * Copyright (C) 1997-2003 + * + * Michiel Broek FIDO: 2:280/2802 + * Beekmansbos 10 + * 1971 BV IJmuiden + * the Netherlands + * + * This file is part of MBSE BBS. + * + * This BBS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * MBSE BBS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MBSE BBS; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + *****************************************************************************/ + +#include "../config.h" +#include "../lib/libs.h" +#include "../lib/structs.h" +#include "../lib/users.h" +#include "../lib/records.h" +#include "../lib/common.h" +#include "../lib/clcomm.h" +#include "inbound.h" + + +extern char *inbound; +extern char *tempinbound; +extern int gotfiles; + + +/* + * Open the inbound directory, set the temp inbound for the node + * so that this is true multiline safe. All files received from + * the node during the session are stored here. + */ + + + + + +int inbound_open(faddr *addr, int protected) +{ + char *temp; + + if (inbound) + free(inbound); + inbound = NULL; + if (protected) + inbound = xstrcpy(CFG.pinbound); + else + inbound = xstrcpy(CFG.inbound); + + temp = calloc(PATH_MAX, sizeof(char)); + sprintf(temp, "%s/tmp.%d.%d.%d.%d", inbound, addr->zone, addr->net, addr->node, addr->point); + tempinbound = xstrcpy(temp); + sprintf(temp, "%s/foobar", tempinbound); + mkdirs(temp, 0700); + free(temp); + + Syslog('+', "Inbound set to \"%s\"", tempinbound); + return 0; +} + + + +/* + * Close the temp inbound, if the session is successfull, move all + * received files to the real inbound, else leave them there for + * the next attempt. Set a semafore if we did receive anything. + * Clean and remove the temp inbound if it is empty. + */ +int inbound_close(int success) +{ + DIR *dp; + struct dirent *de; + char *source, *dest; + struct stat stb; + int rc; + + Syslog('+', "Closing temp inbound after a %s session", success?"good":"failed"); + if (! success) { + if (tempinbound) + free(tempinbound); + return 0; + } + + if (tempinbound == NULL) { + Syslog('!', "Temp inbound was not open"); + return 0; + } + + if ((dp = opendir(tempinbound)) == NULL) { + WriteError("$Can't open %s", tempinbound); + return 1; + } + + source = calloc(PATH_MAX, sizeof(char)); + dest = calloc(PATH_MAX, sizeof(char)); + + while ((de = readdir(dp))) { + Syslog('s', "inbound_close() checking \"%s\"", MBSE_SS(de->d_name)); + sprintf(source, "%s/%s", tempinbound, de->d_name); + sprintf(dest, "%s/%s", inbound, de->d_name); + if ((lstat(source, &stb) == 0) && (S_ISREG(stb.st_mode))) { + Syslog('s', "Regular file"); + if (file_exist(dest, F_OK) == 0) { + Syslog('!', "Cannot move %s to %s, file exists", de->d_name, inbound); + } else { + if ((rc = file_mv(source, dest))) { + WriteError("Can't move %s to %s: %s", source, dest, strerror(rc)); + } else { + Syslog('s', "Moved %s to %s", de->d_name, inbound); + gotfiles = TRUE; + } + } + } else { + Syslog('s', "Not a regular file"); + } + } + + closedir(dp); + free(source); + free(dest); + + /* + * Try to clean the temp inbound, if it fails log this, maybe the + * next time it will work. + */ + if ((rc = rmdir(tempinbound))) { + WriteError("Can't remove %s: %s", tempinbound, strerror(rc)); + } + free(tempinbound); + tempinbound = NULL; + + return 0; +} + + + +/* + * Get the free space size in the temp inbound directory. + */ +long inbound_space(void) +{ + struct statfs sfs; + + if (statfs(tempinbound, &sfs) != 0) { + Syslog('!', "Cannot statfs \"%s\", assume enough space", tempinbound); + return -1L; + } else + return (sfs.f_bsize * sfs.f_bfree); +} + + diff --git a/mbcico/inbound.h b/mbcico/inbound.h new file mode 100644 index 00000000..9e9cd7d0 --- /dev/null +++ b/mbcico/inbound.h @@ -0,0 +1,40 @@ +/***************************************************************************** + * + * $Id$ + * File ..................: mbcico/inbound.h + * Purpose ...............: Fidonet mailer, inbound functions + * + ***************************************************************************** + * Copyright (C) 1997-2003 + * + * Michiel Broek FIDO: 2:280/2802 + * Beekmansbos 10 + * 1971 BV IJmuiden + * the Netherlands + * + * This file is part of MBSE BBS. + * + * This BBS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * MBSE BBS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MBSE BBS; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + *****************************************************************************/ + +#ifndef _INBOUND_H +#define _INBOUND_H + + +int inbound_open(faddr *, int); /* Open temp inbound */ +int inbound_close(int); /* Close temp inbound */ +long inbound_space(void); /* Get free inbound space */ + +#endif diff --git a/mbcico/mbcico.c b/mbcico/mbcico.c index dd9139de..b7159c1e 100644 --- a/mbcico/mbcico.c +++ b/mbcico/mbcico.c @@ -69,6 +69,7 @@ int Loaded = FALSE; extern char *myname; char *inbound; +char *tempinbound = NULL; char *uxoutbound; char *name; char *phone; @@ -336,11 +337,6 @@ int main(int argc, char *argv[]) umask(066); /* packets may contain confidential information */ - p = xstrcpy(inbound); - p = xstrcat(p,(char *)"/tmp/fooinb"); - mkdirs(p, 0700); - free(p); - maxrc=0; if (master) { /* diff --git a/mbcico/openfile.c b/mbcico/openfile.c index 236d400c..6e09b119 100644 --- a/mbcico/openfile.c +++ b/mbcico/openfile.c @@ -44,6 +44,7 @@ static time_t intime; static int isfreq; char *freqname=NULL; int gotfiles = FALSE; +extern char *tempinbound; /* @@ -57,227 +58,166 @@ int gotfiles = FALSE; */ FILE *openfile(char *fname, time_t remtime, off_t remsize, off_t *resofs, int(*resync)(off_t)) { - char *opentype; - char *p, x; - char ctt[32]; - int rc, ncount; - struct stat st; - struct flock fl; - char tmpfname[16]; + char *opentype, *p, x, ctt[32], tmpfname[16]; + int rc, ncount; + struct stat st; - fl.l_type = F_WRLCK; - fl.l_whence = 0; - fl.l_start = 0L; - fl.l_len = 0L; - strcpy(ctt,date(remtime)); + strcpy(ctt,date(remtime)); - Syslog('S', "openfile(\"%s\",%s,%lu,...)", MBSE_SS(fname), MBSE_SS(ctt),(unsigned long)remsize); + Syslog('s', "openfile(\"%s\",%s,%lu,...)", MBSE_SS(fname), MBSE_SS(ctt),(unsigned long)remsize); - if ((fname == NULL) || (fname[0] == '\0')) { - sprintf(tmpfname,"%08lx.pkt",(unsigned long)sequencer()); - fname=tmpfname; + if ((fname == NULL) || (fname[0] == '\0')) { + sprintf(tmpfname,"%08lx.pkt",(unsigned long)sequencer()); + fname=tmpfname; + } + + if ((strlen(fname) == 12) && (strspn(fname,"0123456789abcdefABCDEF") == 8) && (strcasecmp(fname+8,".req") == 0)) { + Syslog('s', "Received wazoo freq file"); + isfreq = TRUE; + } else + isfreq = FALSE; + + /* + * First check if the file is already in the inbound directory. + * If it's there, resoffs will be set equal to remsize to signal the + * receiving protocol to skip the file. + */ + infpath = xstrcpy(tempinbound); + infpath = xstrcat(infpath, (char *)"/"); + infpath = xstrcat(infpath, fname); + if (stat(infpath, &st) == 0) { + /* FIXME: temp normal logging now! */ + Syslog('-', "remtine=%ld, st_time=%ld, remsize=%ld, st_size=%ld", remtime, st.st_mtime, remsize, st.st_size); + + if ((remtime == st.st_mtime) && (remsize == st.st_size)) { + Syslog('+', "File %s is already here", fname); + *resofs = st.st_size; + free(infpath); + infpath = NULL; + return NULL; + } + } + + /* + * If the file is in the inbound with a zero length, erase the + * file as if it wasn't there at all. + */ + if (((rc = stat(infpath, &st)) == 0) && (st.st_size == 0)) { + Syslog('+', "Zero bytes file in the inbound, unlinking"); + unlink(infpath); + } + + /* + * If the file is not already in the inbound, but there is a file + * with the same name, the new file will be renamed if the file + * has another timestamp as the file we expect. + * + * Renaming algorythm is as follows: start with the present name, + * increase the last character of the file name, jumping from + * '9' to 'a', from 'z' to 'A', from 'Z' to '0'. If _all_ these + * names are occupied, create random name. + */ + p = infpath + strlen(infpath) -1; + x = *p; + ncount = 0; + while (((rc = stat(infpath, &st)) == 0) && (remtime != st.st_mtime) && (ncount++ < 62)) { + if (x == '9') + x = 'a'; + else if (x == 'z') + x = 'A'; + else if (x == 'Z') + x = '0'; + else + x++; + *p = x; + } + + if (ncount >= 62) { /* names exhausted */ + rc = 1; + p = strrchr(infpath,'/'); + *p = '\0'; + sprintf(ctt,"%08lx.doe",(unsigned long)sequencer()); + free(infpath); + infpath = xstrcpy(p); + infpath = xstrcat(infpath, ctt); + } + if (ncount) + Syslog('s', "File renamed to %s", infpath); + + *resofs = 0L; + opentype = (char *)"w"; + if ((rc == 0) && (remsize != 0)) { + Syslog('+', "Resyncing at offset %lu of \"%s\"", (unsigned long)st.st_size, infpath); + if (resync(st.st_size) == 0) { + opentype = (char *)"a"; + *resofs = st.st_size; + Syslog('s', "resync == 0"); + } else { + Syslog('s', "resync != 0"); } + } + Syslog('s', "try fopen(\"%s\",\"%s\")", infpath, opentype); - if ((strlen(fname) == 12) && (strspn(fname,"0123456789abcdefABCDEF") == 8) && (strcasecmp(fname+8,".req") == 0)) { - Syslog('s', "Received wazoo freq file"); - isfreq = TRUE; - } else - isfreq = FALSE; + if ((infp = fopen(infpath, opentype)) == NULL) { + WriteError("$Cannot open local file \"%s\" for \"%s\"", infpath,opentype); + free(infpath); + infpath=NULL; + return NULL; + } + intime = remtime; - /* - * First check if the file is already in the real inbound directory. - * If it's there, resoffs will be set equal to remsize to signal the - * receiving protocol to skip the file. - */ - if (infpath) - free(infpath); - infpath = xstrcpy(inbound); - infpath = xstrcat(infpath, (char *)"/"); - infpath = xstrcat(infpath, fname); - if (stat(infpath, &st) == 0) { - /* FIXME: temp normal logging now! */ - Syslog('-', "remtine=%ld, st_time=%ld, remsize=%ld, st_size=%ld", remtime, st.st_mtime, remsize, st.st_size); + if (isfreq) { + if (freqname) + free(freqname); + freqname = xstrcpy(infpath); + } - if ((remtime == st.st_mtime) && (remsize == st.st_size)) { - Syslog('+', "File %s is already here", fname); - *resofs = st.st_size; - free(infpath); - infpath = NULL; - return NULL; - } - } - - /* - * If the file is not already in the inbound, but there is a file - * with the same name, the new file will be renamed. - * - * If the file is 0 bytes, erase it so it can be received again. - * - * Renaming algorythm is as follows: start with the present name, - * increase the last character of the file name, jumping from - * '9' to 'a', from 'z' to 'A', from 'Z' to '0'. If _all_ these - * names are occupied, create random name. - */ - if (infpath) - free(infpath); - infpath = xstrcpy(inbound); - infpath = xstrcat(infpath, (char *)"/tmp/"); - infpath = xstrcat(infpath, fname); - - if (((rc = stat(infpath, &st)) == 0) && (st.st_size == 0)) { - Syslog('+', "Zero bytes file in the inbound, unlinking"); - unlink(infpath); - } - - p = infpath + strlen(infpath) -1; - x = *p; - ncount = 0; - while (((rc = stat(infpath, &st)) == 0) && (remtime != st.st_mtime) && (ncount++ < 62)) { - if (x == '9') - x = 'a'; - else if (x == 'z') - x = 'A'; - else if (x == 'Z') - x = '0'; - else - x++; - *p = x; - } - - if (ncount >= 62) { /* names exhausted */ - rc = 1; - p = strrchr(infpath,'/'); - *p = '\0'; - sprintf(ctt,"%08lx.doe",(unsigned long)sequencer()); - free(infpath); - infpath = xstrcpy(p); - infpath = xstrcat(infpath, ctt); - } - - *resofs = 0L; - opentype = (char *)"w"; - if ((rc == 0) && (remsize != 0)) { - Syslog('+', "Resyncing at offset %lu of \"%s\"", (unsigned long)st.st_size, infpath); - if (resync(st.st_size) == 0) { - opentype = (char *)"a"; - *resofs = st.st_size; - } - } - - Syslog('S', "try fopen(\"%s\",\"%s\")",infpath,opentype); - - /* - * If first attempt doesn't succeed, create tmp directory - * and try again. - */ - if ((infp = fopen(infpath,opentype)) == NULL) { - mkdirs(infpath, 0770); - if ((infp = fopen(infpath, opentype)) == NULL) { - WriteError("$Cannot open local file \"%s\" for \"%s\"", infpath,opentype); - free(infpath); - infpath=NULL; - return NULL; - } - } - - fl.l_pid = getpid(); - if (fcntl(fileno(infp),F_SETLK,&fl) != 0) { - Syslog('+', "$cannot lock local file \"%s\"",infpath); - fclose(infp); - infp = NULL; - free(infpath); - infpath = NULL; - return NULL; - } - intime=remtime; - - if (isfreq) { - if (freqname) - free(freqname); - freqname = xstrcpy(infpath); - } - - Syslog('S', "opened file \"%s\" for \"%s\", restart at %lu", infpath,opentype,(unsigned long)*resofs); - return infp; + Syslog('s', "opened file \"%s\" for \"%s\", restart at %lu", infpath,opentype,(unsigned long)*resofs); + return infp; } /* - * close file and if (success) { move it to the final location } + * close file, even if the file is partial received, we set the date on the + * file so that in a next session we know we must append to that file instead of + * trying to get the file again. */ -int closefile(int success) +int closefile(void) { - char *newpath, *p, ctt[32]; - int rc=0,ncount; - char x; - struct stat st; - struct utimbuf ut; + int rc = 0; + struct utimbuf ut; - Syslog('S', "closefile(%d), for file \"%s\"",success, MBSE_SS(infpath)); + Syslog('s', "closefile(), for file \"%s\"", MBSE_SS(infpath)); - if ((infp == NULL) || (infpath == NULL)) { - WriteError("Internal error: try close unopened file!"); - return 1; + if ((infp == NULL) || (infpath == NULL)) { + Syslog('+', "closefile(), nothing to close"); + return 1; + } + + rc = fclose(infp); + infp = NULL; + + if (rc == 0) { + ut.actime = intime; + ut.modtime = intime; + if ((rc = utime(infpath,&ut))) + WriteError("$utime failed"); + } + + if (isfreq) { + if (rc != 0) { + Syslog('+', "Removing unsuccessfuly received wazoo freq"); + unlink(freqname); + free(freqname); + freqname=NULL; } - - rc = fclose(infp); - infp = NULL; - - if (rc == 0) { - ut.actime = intime; - ut.modtime = intime; - if ((rc = utime(infpath,&ut))) - WriteError("$utime failed"); - } - - if (isfreq) { - if ((rc != 0) || (!success)) { - Syslog('+', "Removing unsuccessfuly received wazoo freq"); - unlink(freqname); - free(freqname); - freqname=NULL; - } - isfreq = FALSE; - } else if ((rc == 0) && success) { - newpath = xstrcpy(inbound); - newpath = xstrcat(newpath, strrchr(infpath,'/')); - - p = newpath + strlen(newpath) - 1; - x = *p; - ncount = 0; - while (((rc = stat(newpath, &st)) == 0) && (ncount++ < 62)) { - if (x == '9') - x = 'a'; - else if (x == 'z') - x = 'A'; - else if (x == 'Z') - x = '0'; - else - x++; - *p = x; - } - if (ncount >= 62) { /* names exhausted */ - rc = 1; - p = strrchr(newpath,'/'); - *p = '\0'; - sprintf(ctt,"%08lx.doe",(unsigned long)sequencer()); - free(newpath); - newpath = xstrcpy(p); - newpath = xstrcat(newpath, ctt); - } - - Syslog('S', "moving \"%s\" -> \"%s\"", MBSE_SS(infpath), MBSE_SS(newpath)); - rc = rename(infpath, newpath); - if (rc) - WriteError("$error renaming \"%s\" -> \"%s\"", MBSE_SS(infpath),MBSE_SS(newpath)); - else - gotfiles = TRUE; - free(newpath); - } - free(infpath); - infpath = NULL; - return rc; + isfreq = FALSE; + } + + free(infpath); + infpath = NULL; + return rc; } diff --git a/mbcico/openfile.h b/mbcico/openfile.h index 3d1ee023..d63e63aa 100644 --- a/mbcico/openfile.h +++ b/mbcico/openfile.h @@ -1,9 +1,9 @@ +/* $Id$ */ + #ifndef _OPENFILE_H #define _OPENFILE_H FILE *openfile(char *, time_t, off_t, off_t *, int(*)(off_t)); -int closefile(int); - +int closefile(void); #endif - diff --git a/mbcico/session.c b/mbcico/session.c index 15de39f6..411d422d 100644 --- a/mbcico/session.c +++ b/mbcico/session.c @@ -4,7 +4,7 @@ * Purpose ...............: Fidonet mailer * ***************************************************************************** - * Copyright (C) 1997-2002 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -46,6 +46,7 @@ #include "mbcico.h" #include "binkp.h" #include "callstat.h" +#include "inbound.h" extern int tcp_mode; @@ -192,6 +193,7 @@ int session(faddr *a, node *nl, int role, int tp, char *dt) if (nlent->addr.domain) free(nlent->addr.domain); + inbound_close(rc == 0); return rc; } diff --git a/mbcico/tcpproto.c b/mbcico/tcpproto.c index 2cbfd8e6..81127c32 100644 --- a/mbcico/tcpproto.c +++ b/mbcico/tcpproto.c @@ -284,7 +284,7 @@ static int closeit(int success) { int rc; - rc = closefile(success); + rc = closefile(); fout = NULL; sbytes = rxbytes - sbytes; gettimeofday(&endtime, &tz); diff --git a/mbcico/xmrecv.c b/mbcico/xmrecv.c index f0bbbcc4..71a68ab7 100644 --- a/mbcico/xmrecv.c +++ b/mbcico/xmrecv.c @@ -4,7 +4,7 @@ * Purpose ...............: Fidonet mailer * ***************************************************************************** - * Copyright (C) 1997-2001 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -99,7 +99,7 @@ int closeit(int success) Syslog('+', "Xmodem: dropped after %ld bytes", endofs-startofs); rcvdbytes += (unsigned long)(endofs-startofs); fp = NULL; - return closefile(success); + return closefile(); } diff --git a/mbcico/yoohoo.c b/mbcico/yoohoo.c index 1df59a46..a8658ec8 100644 --- a/mbcico/yoohoo.c +++ b/mbcico/yoohoo.c @@ -4,7 +4,7 @@ * Purpose ...............: Fidonet mailer * ***************************************************************************** - * Copyright (C) 1997-2002 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -123,7 +123,7 @@ Hello gethello2(unsigned char[]); int rx_yoohoo(void) { - int rc; + int rc, protect = FALSE; unsigned short capabilities,localcaps; char *pwd = NULL; @@ -163,9 +163,6 @@ int rx_yoohoo(void) if (((nlent=getnlent(remote->addr))) && (nlent->pflag != NL_DUMMY)) { Syslog('+', "Remote is a listed system"); - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.inbound); strncpy(history.location, nlent->location, 35); UserCity(mypid, nlent->sysop, nlent->location); } @@ -176,9 +173,7 @@ int rx_yoohoo(void) 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"); - if (inbound) - free(inbound); - inbound = xstrcpy(CFG.pinbound); + protect = TRUE; pwd = xstrcpy(nodes.Spasswd); } else { if (pwd) @@ -190,6 +185,8 @@ int rx_yoohoo(void) } else Syslog('s', "No YooHoo password check"); + inbound_open(remote->addr, protect); + fillhello(localcaps,pwd); rc = txyoohoo(); diff --git a/mbcico/zmrecv.c b/mbcico/zmrecv.c index 41c1d5ff..fdaba3cd 100644 --- a/mbcico/zmrecv.c +++ b/mbcico/zmrecv.c @@ -438,7 +438,7 @@ int closeit(int success) { int rc; - rc = closefile(success); + rc = closefile(); fout = NULL; sbytes = rxbytes - sbytes; gettimeofday(&endtime, &tz);