diff --git a/src/sbbs3/sbbsecho.c b/src/sbbs3/sbbsecho.c index 350b889d94b4fdcb0a4542a18688a365d6f99269..b3f8db06de518090a621680eb7b7a52b051931bc 100644 --- a/src/sbbs3/sbbsecho.c +++ b/src/sbbs3/sbbsecho.c @@ -89,6 +89,8 @@ char compiler[32]; BOOL pause_on_exit=FALSE; BOOL pause_on_abend=FALSE; +str_list_t locked_bso_nodes; + /* FTN-compliant "Program Identifier"/PID (also used as a "Tosser Identifier"/TID) */ const char* sbbsecho_pid(void) { @@ -170,11 +172,15 @@ void logprintf(char *str, ...) ,buf); } -void delfile(const char *filename, int line) +BOOL delfile(const char *filename, int line) { - if(remove(filename) != 0) + lprintf(LOG_DEBUG, "Deleting %s", filename); + if(remove(filename) != 0) { lprintf(LOG_ERR, "ERROR %u (%s) line %u removing file %s" ,errno, strerror(errno), line, filename); + return FALSE; + } + return TRUE; } /*****************************************************************************/ @@ -352,6 +358,32 @@ int get_flo_outbound(faddr_t dest, char* outbound, size_t maxlen) return mkpath(outbound); } +BOOL bso_lock_node(faddr_t dest) +{ + char outbound[MAX_PATH+1]; + char fname[MAX_PATH+1]; + + if(!(misc&FLO_MAILER)) + return TRUE; + + get_flo_outbound(dest, outbound, sizeof(outbound)-2); + + if(dest.point) + SAFEPRINTF2(fname,"%s%08x.bsy",outbound,dest.point); + else + SAFEPRINTF3(fname,"%s%04x%04x.bsy",outbound,dest.net,dest.node); + + if(strListFind(locked_bso_nodes, fname, /* case_sensitive: */TRUE) >= 0) + return TRUE; + if(!fmutex(fname, sbbsecho_pid(), 12*60*60)) { + lprintf(LOG_NOTICE, "Node (%s) externally locked via: %s", smb_faddrtoa(&dest, NULL), fname); + return FALSE; + } + strListPush(&locked_bso_nodes, fname); + lprintf(LOG_DEBUG, "Node (%s) successfully locked via: %s", smb_faddrtoa(&dest, NULL), fname); + return TRUE; +} + /****************************************************************************** This function creates or appends on existing Binkley compatible .?LO file attach file. @@ -377,10 +409,14 @@ int write_flofile(char *attachment, faddr_t dest, BOOL bundle) else ch='f'; get_flo_outbound(dest, outbound, sizeof(outbound)-2); + + if(!bso_lock_node(dest)) + return 1; + if(dest.point) - sprintf(fname,"%s%08x.%clo",outbound,dest.point,ch); + SAFEPRINTF3(fname,"%s%08x.%clo",outbound,dest.point,ch); else - sprintf(fname,"%s%04x%04x.%clo",outbound,dest.net,dest.node,ch); + SAFEPRINTF4(fname,"%s%04x%04x.%clo",outbound,dest.net,dest.node,ch); if(bundle && (misc&TRUNC_BUNDLES)) ch='#'; else @@ -388,7 +424,7 @@ int write_flofile(char *attachment, faddr_t dest, BOOL bundle) if(*attachment == '^') /* work-around for BRE/FE inter-BBS attachment bug */ attachment++; fexistcase(attachment); /* just in-case it's the wrong case for a Unix file system */ - sprintf(searchstr,"%c%s",ch,attachment); + SAFEPRINTF2(searchstr,"%c%s",ch,attachment); if(findstr(searchstr,fname)) /* file already in FLO file */ return(0); if((stream=fopen(fname,"a"))==NULL) { @@ -568,8 +604,9 @@ int create_netmail(char *to, smbmsg_t* msg, char *subject, char *body, faddr_t d else fwrite("\0",1,1,fp); /* Write NULL */ if(cfg.log&LOG_NETMAIL) - lprintf(LOG_INFO, "Created NetMail (%s)%s from: %s, to: %s (%s), subject: %s" - ,fname, file_attached ? " with attachment" : "", from, to, smb_faddrtoa(&dest, NULL), subject); + lprintf(LOG_INFO, "Created NetMail (%s)%s from %s (%s) to %s (%s), attr: %04hX, subject: %s" + ,fname, file_attached ? " with attachment" : "" + ,from, smb_faddrtoa(&faddr, tmp), to, smb_faddrtoa(&dest, NULL), hdr.attr, subject); return fclose(fp); } @@ -1295,7 +1332,7 @@ void command(char* instr, faddr_t addr, char* to) if(!stricmp(p,cfg.arcdef[i].name)) break; if(!stricmp(p,"NONE")) - i=0xffff; + i=SBBSECHO_ARCTYPE_NONE; if(i==cfg.arcdefs) { if((tmpf=tmpfile())==NULL) { lprintf(LOG_ERR,"ERROR line %d opening tmpfile()",__LINE__); @@ -1749,6 +1786,9 @@ void pack_bundle(char *infile,faddr_t dest) return; } + if(!bso_lock_node(dest)) + bail(1); + node=matchnode(dest,0); strcpy(str,infile); str[strlen(str)-1]='t'; @@ -1771,7 +1811,7 @@ void pack_bundle(char *infile,faddr_t dest) strcpy(outbound,cfg.outbound); if(node<cfg.nodecfgs) - if(cfg.nodecfg[node].arctype==0xffff) { /* Uncompressed! */ + if(cfg.nodecfg[node].arctype==SBBSECHO_ARCTYPE_NONE) { /* Uncompressed! */ if(misc&FLO_MAILER) i=write_flofile(infile,dest,TRUE /* bundle */); else @@ -1944,6 +1984,7 @@ int mv(char *src, char *dest, BOOL copy) if(!strcmp(src,dest)) /* source and destination are the same! */ return(0); + lprintf(LOG_DEBUG, "%s file from %s to %s", copy ? "Copying":"Moving", src, dest); if(!fexistcase(src)) { lprintf(LOG_WARNING,"MV ERROR: Source doesn't exist '%s",src); return(-1); @@ -2085,6 +2126,11 @@ ulong loadmsgs(post_t** post, ulong ptr) void bail(int code) { + size_t u; + + for(u=0; locked_bso_nodes[u]!=NULL; u++) + delfile(locked_bso_nodes[u], __LINE__); + if(code || netmail || exported_netmail || packed_netmail || echomail || exported_echomail) lprintf(LOG_INFO ,"SBBSecho exiting with error level %d, " @@ -4175,10 +4221,6 @@ int export_netmail(void) exported++; } smb_freemsgmem(&msg); - if(cfg.log&LOG_NETMAIL) - lprintf(exported ? LOG_INFO : LOG_DEBUG - ,"Exported NetMail (%u messages) from %smail to %s*.msg" - ,exported, scfg.data_dir, scfg.netmail_dir); exported_netmail += exported; return smb_unlocksmbhdr(email); } @@ -4204,6 +4246,29 @@ char* freadstr(FILE* fp, char* str, size_t maxlen) return(str); } +BOOL netmail_sent(const char* fname) +{ + FILE* fp; + fmsghdr_t hdr; + + if(misc&DELETE_NETMAIL) + return delfile(fname, __LINE__); + if((fp=fopen(fname, "r+b")) == NULL) { + lprintf(LOG_ERR, "ERROR %d (%s) opening %s", errno, strerror(errno), fname); + return FALSE; + } + if(!fread_fmsghdr(&hdr,fp)) { + fclose(fp); + lprintf(LOG_ERR, "ERROR line %u reading header from %s", __LINE__, fname); + return FALSE; + } + hdr.attr|=FIDO_SENT; + rewind(fp); + fwrite(&hdr, sizeof(hdr), 1, fp); + fclose(fp); + return TRUE; +} + /***********************************/ /* Synchronet/FidoNet Message util */ /***********************************/ @@ -4263,6 +4328,8 @@ int main(int argc, char **argv) "!: notify users of received echomail @: prompt for key upon exiting (debug)\n" "c: do not export netmail (to *.msg) W: prompt for key upon abnormal exit"; + locked_bso_nodes = strListInit(); + if((email=(smb_t *)malloc(sizeof(smb_t)))==NULL) { printf("ERROR allocating memory for email.\n"); bail(1); @@ -4562,7 +4629,7 @@ int main(int argc, char **argv) SAFECOPY(packet,(char*)g.gl_pathv[f]); - lprintf(LOG_DEBUG,"%21s: %s ","Outbound Packet",packet); + printf("%21s: %s ","Outbound Packet",packet); if((fmsg=sopen(packet,O_RDWR|O_BINARY,SH_DENYRW))==-1) { lprintf(LOG_ERR,"ERROR %u (%s) line %d opening %s",errno,strerror(errno),__LINE__,packet); continue; @@ -5133,6 +5200,7 @@ int main(int argc, char **argv) #endif glob(str,0,NULL,&g); for(f=0;f<g.gl_pathc && !kbhit();f++) { + fidoaddr_t srcaddr; SAFECOPY(path,g.gl_pathv[f]); @@ -5153,10 +5221,14 @@ int main(int argc, char **argv) hdr.destzone=hdr.origzone=sys_faddr.zone; hdr.destpoint=hdr.origpoint=0; getzpt(fidomsg,&hdr); /* use kludge if found */ - addr.zone=hdr.destzone; - addr.net=hdr.destnet; - addr.node=hdr.destnode; - addr.point=hdr.destpoint; + addr.zone = hdr.destzone; + addr.net = hdr.destnet; + addr.node = hdr.destnode; + addr.point = hdr.destpoint; + srcaddr.zone = hdr.origzone; + srcaddr.net = hdr.orignet; + srcaddr.node = hdr.orignode; + srcaddr.point = hdr.origpoint; for(i=0;i<scfg.total_faddrs;i++) if(!memcmp(&addr,&scfg.faddr[i],sizeof(faddr_t))) break; @@ -5170,20 +5242,15 @@ int main(int argc, char **argv) fclose(fidomsg); continue; } - if(!(misc&DELETE_NETMAIL)) { - hdr.attr|=FIDO_SENT; - rewind(fidomsg); - fseek(fidomsg,offsetof(fmsghdr_t,attr),SEEK_SET); - fwrite(&hdr.attr,sizeof(hdr.attr),1,fidomsg); - fseek(fidomsg,sizeof(fmsghdr_t),SEEK_SET); - } if((misc&FLO_MAILER) && (hdr.attr&FIDO_FREQ)) { char req[MAX_PATH+1]; FILE* fp; - printf("file request: %s\n", hdr.subj); fclose(fidomsg); - + lprintf(LOG_INFO, "BSO file request from %s (%s) to %s (%s): %s" + ,hdr.from, smb_faddrtoa(&srcaddr, tmp), hdr.to, smb_faddrtoa(&addr, NULL), hdr.subj); + if(!bso_lock_node(addr)) + continue; get_flo_outbound(addr, outbound, sizeof(outbound)); if(addr.point) SAFEPRINTF2(req,"%s%08x.req",outbound,addr.point); @@ -5196,22 +5263,22 @@ int main(int argc, char **argv) fclose(fp); if(write_flofile(req, addr, /* bundle: */FALSE)) bail(1); + netmail_sent(path); } continue; } if(cfg.log&LOG_PACKING) - lprintf(LOG_INFO, "Packing NetMail (%s) from %s (%u:%u/%u.%u) to %s (%s), attr: %04hX, subject: %s" - ,path,hdr.from,hdr.origzone,hdr.orignet,hdr.orignode,hdr.origpoint - ,hdr.to,smb_faddrtoa(&addr,NULL),hdr.attr,hdr.subj); + lprintf(LOG_INFO, "Packing NetMail (%s) from %s (%s) to %s (%s), attr: %04hX, subject: %s" + ,path, hdr.from, smb_faddrtoa(&srcaddr,tmp), hdr.to, smb_faddrtoa(&addr,NULL), hdr.attr, hdr.subj); fmsgbuf=getfmsg(fidomsg,NULL); + fclose(fidomsg); if(!fmsgbuf) { lprintf(LOG_ERR,"ERROR line %d allocating memory for NetMail fmsgbuf" ,__LINE__); bail(1); return -1; } - fclose(fidomsg); attr=0; node=matchnode(addr,0); @@ -5222,6 +5289,9 @@ int main(int argc, char **argv) lprintf(LOG_INFO, "Routing NetMail (%s) to %s",path,smb_faddrtoa(&addr,NULL)); node=matchnode(addr,0); } + if(!bso_lock_node(addr)) + continue; + if(node<cfg.nodecfgs) attr=cfg.nodecfg[node].attr; @@ -5308,8 +5378,7 @@ int main(int argc, char **argv) /**************************************/ /* Delete source netmail if specified */ /**************************************/ - if(misc&DELETE_NETMAIL) - delfile(path, __LINE__); + netmail_sent(path); printf("\n"); packed_netmail++; } diff --git a/src/sbbs3/sbbsecho.h b/src/sbbs3/sbbsecho.h index 4040c5bc5b5a1545d004f72190ad8c166d8efe7d..fd262cdd3807f681710d9902e2c97c24fe0adb45 100644 --- a/src/sbbs3/sbbsecho.h +++ b/src/sbbs3/sbbsecho.h @@ -38,7 +38,7 @@ /* Portions written by Allen Christiansen 1994-1996 */ #define SBBSECHO_VERSION_MAJOR 2 -#define SBBSECHO_VERSION_MINOR 31 +#define SBBSECHO_VERSION_MINOR 32 #define SBBSECHO_PRODUCT_CODE 0x12FF /* from http://ftsc.org/docs/ftscprod.013 */ @@ -110,56 +110,56 @@ #define NOFWD (1<<0) /* Do not forward requests */ -typedef struct { /* Fidonet Packet Header */ - short orignode, /* Origination Node of Packet */ - destnode, /* Destination Node of Packet */ - year, /* Year of Packet Creation e.g. 1995 */ - month, /* Month of Packet Creation 0-11 */ - day, /* Day of Packet Creation 1-31 */ - hour, /* Hour of Packet Creation 0-23 */ - min, /* Minute of Packet Creation 0-59 */ - sec, /* Second of Packet Creation 0-59 */ - baud, /* Max Baud Rate of Orig & Dest */ - pkttype, /* Packet Type (-1 is obsolete) */ - orignet, /* Origination Net of Packet */ - destnet; /* Destination Net of Packet */ - uchar prodcode, /* Product Code (00h is Fido) */ - sernum, /* Binary Serial Number or NULL */ - password[8]; /* Session Password or NULL */ - short origzone, /* Origination Zone of Packet or NULL */ - destzone; /* Destination Zone of Packet or NULL */ - uchar empty[20]; /* Fill Characters */ +typedef struct { /* Fidonet Packet Header */ + int16_t orignode, /* Origination Node of Packet */ + destnode, /* Destination Node of Packet */ + year, /* Year of Packet Creation e.g. 1995 */ + month, /* Month of Packet Creation 0-11 */ + day, /* Day of Packet Creation 1-31 */ + hour, /* Hour of Packet Creation 0-23 */ + min, /* Minute of Packet Creation 0-59 */ + sec, /* Second of Packet Creation 0-59 */ + baud, /* Max Baud Rate of Orig & Dest */ + pkttype, /* Packet Type (-1 is obsolete) */ + orignet, /* Origination Net of Packet */ + destnet; /* Destination Net of Packet */ + uint8_t prodcode, /* Product Code (00h is Fido) */ + sernum, /* Binary Serial Number or NULL */ + password[8]; /* Session Password or NULL */ + int16_t origzone, /* Origination Zone of Packet or NULL */ + destzone; /* Destination Zone of Packet or NULL */ + uint8_t empty[20]; /* Fill Characters */ } pkthdr_t; -typedef struct { /* Type 2+ Packet Header Info */ - short auxnet, /* Orig Net if Origin is a Point */ - cwcopy; /* Must be Equal to cword */ - uchar prodcode, /* Product Code */ - revision; /* Revision */ - short cword, /* Compatibility Word */ - origzone, /* Zone of Packet Sender or NULL */ - destzone, /* Zone of Packet Receiver or NULL */ - origpoint, /* Origination Point of Packet */ - destpoint; /* Destination Point of Packet */ - uchar empty[4]; +typedef struct { /* Type 2+ Packet Header Info */ + int16_t auxnet, /* Orig Net if Origin is a Point */ + cwcopy; /* Must be Equal to cword */ + uint8_t prodcode, /* Product Code */ + revision; /* Revision */ + int16_t cword, /* Compatibility Word */ + origzone, /* Zone of Packet Sender or NULL */ + destzone, /* Zone of Packet Receiver or NULL */ + origpoint, /* Origination Point of Packet */ + destpoint; /* Destination Point of Packet */ + uint8_t empty[4]; } two_plus_t; -typedef struct { /* Type 2.2 Packet Header Info */ - char origdomn[8], /* Origination Domain */ - destdomn[8]; /* Destination Domain */ - uchar empty[4]; /* Product Specific Data */ +typedef struct { /* Type 2.2 Packet Header Info */ + char origdomn[8], /* Origination Domain */ + destdomn[8]; /* Destination Domain */ + uint8_t empty[4]; /* Product Specific Data */ } two_two_t; typedef struct { - uint sub; /* Set to INVALID_SUB if pass-thru */ - ulong tag; /* CRC-32 of tag name */ - char *name; /* Area tag name */ - uint uplinks; /* Total number of uplinks for this echo */ - uint imported; /* Total messages imported this run */ - uint exported; /* Total messages exported this run */ - uint circular; /* Total circular paths detected */ - uint dupes; /* Total duplicate messages detected */ - faddr_t *uplink; /* Each uplink */ + uint sub; /* Set to INVALID_SUB if pass-thru */ + uint32_t tag; /* CRC-32 of tag name */ + char* name; /* Area tag name */ + uint uplinks; /* Total number of uplinks for this echo */ + uint imported; /* Total messages imported this run */ + uint exported; /* Total messages exported this run */ + uint circular; /* Total circular paths detected */ + uint dupes; /* Total duplicate messages detected */ + faddr_t* uplink; /* Each uplink */ } areasbbs_t; typedef struct { @@ -173,8 +173,8 @@ typedef struct { } outpkt_t; typedef struct { - uint addrs; /* Total number of uplinks */ - faddr_t *addr; /* Each uplink */ + uint addrs; /* Total number of uplinks */ + faddr_t * addr; /* Each uplink */ } addrlist_t; typedef struct { @@ -186,28 +186,29 @@ typedef struct { } arcdef_t; typedef struct { - faddr_t faddr /* Fido address of this node */ - ,route; /* Address to route FLO stuff through */ - ushort arctype /* De/archiver to use for this node */ - ,numflags /* Number of flags defined for this node */ - ,pkt_type; /* Packet type to use for outgoing PKTs */ - /* Packet types for nodecfg_t.pkt_type value ONLY: */ -#define PKT_TWO_PLUS 0 /* Type 2+ Packet Header */ -#define PKT_TWO_TWO 1 /* Type 2.2 Packet Header */ -#define PKT_TWO 2 /* Old Type Packet Header */ + faddr_t faddr /* Fido address of this node */ + ,route; /* Address to route FLO stuff through */ +#define SBBSECHO_ARCTYPE_NONE 0xffff + uint16_t arctype /* De/archiver to use for this node */ + ,numflags /* Number of flags defined for this node */ + ,pkt_type; /* Packet type to use for outgoing PKTs */ + /* Packet types for nodecfg_t.pkt_type value ONLY: */ +#define PKT_TWO_PLUS 0 /* Type 2+ Packet Header */ +#define PKT_TWO_TWO 1 /* Type 2.2 Packet Header */ +#define PKT_TWO 2 /* Old Type Packet Header */ - ushort attr; /* Message bits to set for this node */ - char password[26]; /* Areafix password for this node */ - char pktpwd[9]; /* Packet password for this node */ - flag_t *flag; /* Areafix flags for this node */ + int16_t attr; /* Message bits to set for this node */ + char password[26]; /* Areafix password for this node */ + char pktpwd[9]; /* Packet password for this node */ + flag_t *flag; /* Areafix flags for this node */ } nodecfg_t; typedef struct { - char listpath[129]; /* Path to this echolist */ - uint numflags,misc; /* Number of flags for this echolist */ - flag_t *flag; /* Flags to access this echolist */ - faddr_t forward; /* Where to forward requests */ - char password[72]; /* Password to use for forwarding req's */ + char listpath[129]; /* Path to this echolist */ + uint numflags,misc; /* Number of flags for this echolist */ + flag_t *flag; /* Flags to access this echolist */ + faddr_t forward; /* Where to forward requests */ + char password[72]; /* Password to use for forwarding req's */ } echolist_t; typedef struct {