home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / ECHO / SBBSECHO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-18  |  151.6 KB  |  5,033 lines

  1. /* SBBSECHO.C */
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885    */
  4.  
  5. /* Portions written by Allen Christiansen 1994-1996                         */
  6.  
  7. /* Synchronet FidoNet EchoMail Scanning/Tossing and NetMail Tossing Utility */
  8.  
  9. #include <dos.h>
  10. #include <mem.h>
  11. #include <time.h>
  12. #include <errno.h>
  13. #include <stdio.h>
  14. #include <conio.h>
  15. #include <ctype.h>
  16. #include <fcntl.h>
  17. #include <share.h>
  18. #include <malloc.h>
  19. #include <stdarg.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <process.h>
  23. #include <sys\stat.h>
  24.  
  25. #include "sbbsdefs.h"
  26. #include "smblib.h"
  27. #include "scfglib.h"
  28. #define GLOBAL extern    /* turn vars.c and scfgvars.c files into headers */
  29. #include "scfgvars.c"
  30. #include "post.h"
  31. #include "lzh.h"
  32. #include "sbbsecho.h"
  33.  
  34. extern long crc32tbl[];
  35. ulong crc32(char *str);
  36.  
  37. #ifndef __FLAT__
  38.     #include "..\..\spawno\spawno.h"
  39. #endif
  40.  
  41. #ifdef __TURBOC__
  42.     unsigned _stklen=20000;
  43. #endif
  44.  
  45. #ifdef __WATCOMC__
  46.     #define O_DENYNONE SH_DENYNO
  47. #endif
  48.  
  49. char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
  50. char *mon[]={"Jan","Feb","Mar","Apr","May","Jun"
  51.             ,"Jul","Aug","Sep","Oct","Nov","Dec"};
  52.  
  53. smb_t *smb,*email;
  54. long misc=(IMPORT_PACKETS|IMPORT_NETMAIL|IMPORT_ECHOMAIL|EXPORT_ECHOMAIL
  55.             |DELETE_NETMAIL|DELETE_PACKETS);
  56. ulong netmail=0;
  57. char tmp[256],pkt_type=0;
  58. faddr_t sys_faddr;
  59. config_t cfg;
  60. int nodefile,secure,cur_smb=0;
  61. FILE *fidologfile=NULL;
  62. two_two_t two_two;
  63. two_plus_t two_plus;
  64.  
  65. #ifdef __WATCOMC__
  66. /******************************************************************************
  67.  A DOS to Unix function - because WATCOM doesn't have one
  68. ******************************************************************************/
  69. time_t dostounix(struct date *d,struct time *t)
  70. {
  71.     struct tm tm;
  72.  
  73. tm.tm_sec=t->ti_sec;
  74. tm.tm_min=t->ti_min;
  75. tm.tm_hour=t->ti_hour;
  76. tm.tm_mday=d->da_day;
  77. tm.tm_mon=(d->da_mon-1);
  78. tm.tm_year=d->da_year-1900;
  79. tm.tm_isdst=0;
  80.  
  81. return(mktime(&tm));
  82. }
  83. #endif
  84.  
  85. #ifndef __NT__
  86. #define delfile(x) remove(x)
  87. #else
  88. int delfile(char *filename)
  89. {
  90.     int i=0;
  91.  
  92. while(remove(filename) && i++<120)    /* Wait up to 60 seconds to delete file */
  93.     delay(500);                     /* for Win95 bug fix */
  94. return(i);
  95. }
  96. #endif
  97.  
  98. /******************************************************************************
  99.  This turns the DOS file date garbage into a long
  100. ******************************************************************************/
  101. long ddtol(ushort ftim, ushort fdat)
  102. {
  103.     struct date date;
  104.     struct time time;
  105.  
  106.     date.da_year=((fdat&0xfe00)>>9)+1980;
  107.     date.da_mon=((fdat&0x01e0)>>5);
  108.     date.da_day=(fdat&0x001f);
  109.     time.ti_hour=((ftim&0xf800)>>11);
  110.     time.ti_min=((ftim&0x07e0)>>5);
  111.     time.ti_sec=((ftim&0x001f)<<1);
  112.     time.ti_hund=0;
  113.     return(dostounix(&date,&time));
  114. }
  115. void checkmem(void)
  116. {
  117. #ifdef __WATCOMC__
  118.     char *p=NULL;
  119.     long size=640L*1024L,over;
  120.  
  121.     while(size>0) {
  122.         p=(char *)LMALLOC(size);
  123.         if(p)
  124.             break;
  125.         size-=1024L; }
  126.  
  127.     printf("\nAvailable Memory = %ld bytes",size);
  128.     if(p)
  129.         LFREE(p);
  130. #elif !defined(__OS2__)
  131.     printf("\nAvailable Memory = %ld bytes",farcoreleft());
  132. #endif
  133. }
  134.  
  135. /**********************/
  136. /* Log print function */
  137. /**********************/
  138. void logprintf(char *str, ...)
  139. {
  140.     va_list argptr;
  141.     char buf[256];
  142.     time_t now;
  143.     struct tm *gm;
  144.  
  145. if(!(misc&LOGFILE) || fidologfile==NULL)
  146.     return;
  147. va_start(argptr,str);
  148. vsprintf(buf,str,argptr);
  149. va_end(argptr);
  150. now=time(NULL);
  151. gm=localtime(&now);
  152. fseek(fidologfile,0L,SEEK_END);
  153. fprintf(fidologfile,"%02u/%02u/%02u %02u:%02u:%02u %s\r\n"
  154.     ,gm->tm_mon+1,gm->tm_mday,gm->tm_year,gm->tm_hour,gm->tm_min,gm->tm_sec
  155.     ,buf);
  156. fflush(fidologfile);
  157. }
  158.  
  159. /****************************************************************************/
  160. /* Puts a backslash on path strings                                         */
  161. /****************************************************************************/
  162. void backslash(char *str)
  163. {
  164.     int i;
  165.  
  166. i=strlen(str);
  167. if(i && str[i-1]!='\\') {
  168.     str[i]='\\'; str[i+1]=0; }
  169. }
  170.  
  171. /*****************************************************************************/
  172. /* Returns command line generated from instr with %c replacments             */
  173. /*****************************************************************************/
  174. char *cmdstr(char *instr, char *fpath, char *fspec)
  175. {
  176.     static char cmd[128];
  177.     char str[256],str2[128];
  178.     int i,j,len;
  179.  
  180. len=strlen(instr);
  181. for(i=j=0;i<len && j<128;i++) {
  182.     if(instr[i]=='%') {
  183.         i++;
  184.         cmd[j]=0;
  185.         switch(toupper(instr[i])) {
  186.             case 'F':   /* File path */
  187.                 strcat(cmd,fpath);
  188.                 break;
  189.             case 'G':   /* Temp directory */
  190.                 if(temp_dir[0]!='\\' && temp_dir[1]!=':') {
  191.                     strcpy(str,node_dir);
  192.                     strcat(str,temp_dir);
  193.                     if(_fullpath(str2,str,40))
  194.                         strcpy(str,str2);
  195.                     backslash(str);
  196.                     strcat(cmd,str);}
  197.                 else
  198.                     strcat(cmd,temp_dir);
  199.                 break;
  200.             case 'J':
  201.                 if(data_dir[0]!='\\' && data_dir[1]!=':') {
  202.                     strcpy(str,node_dir);
  203.                     strcat(str,data_dir);
  204.                     if(_fullpath(str2,str,40))
  205.                         strcpy(str,str2);
  206.                     backslash(str);
  207.                     strcat(cmd,str); }
  208.                 else
  209.                     strcat(cmd,data_dir);
  210.                 break;
  211.             case 'K':
  212.                 if(ctrl_dir[0]!='\\' && ctrl_dir[1]!=':') {
  213.                     strcpy(str,node_dir);
  214.                     strcat(str,ctrl_dir);
  215.                     if(_fullpath(str2,str,40))
  216.                         strcpy(str,str2);
  217.                     backslash(str);
  218.                     strcat(cmd,str); }
  219.                 else
  220.                     strcat(cmd,ctrl_dir);
  221.                 break;
  222.             case 'N':   /* Node Directory (same as SBBSNODE environment var) */
  223.                 strcat(cmd,node_dir);
  224.                 break;
  225.             case 'O':   /* SysOp */
  226.                 strcat(cmd,sys_op);
  227.                 break;
  228.             case 'Q':   /* QWK ID */
  229.                 strcat(cmd,sys_id);
  230.                 break;
  231.             case 'S':   /* File Spec */
  232.                 strcat(cmd,fspec);
  233.                 break;
  234.             case '!':   /* EXEC Directory */
  235.                 if(exec_dir[0]!='\\' && exec_dir[1]!=':') {
  236.                     strcpy(str,node_dir);
  237.                     strcat(str,exec_dir);
  238.                     if(_fullpath(str2,str,40))
  239.                         strcpy(str,str2);
  240.                     backslash(str);
  241.                     strcat(cmd,str); }
  242.                 else
  243.                     strcat(cmd,exec_dir);
  244.                 break;
  245.             case '#':   /* Node number (same as SBBSNNUM environment var) */
  246.                 sprintf(str,"%d",node_num);
  247.                 strcat(cmd,str);
  248.                 break;
  249.             case '*':
  250.                 sprintf(str,"%03d",node_num);
  251.                 strcat(cmd,str);
  252.                 break;
  253.             case '%':   /* %% for percent sign */
  254.                 strcat(cmd,"%");
  255.                 break;
  256.             default:    /* unknown specification */
  257.                 printf("ERROR Checking Command Line '%s'\n",instr);
  258.                 logprintf("ERROR line %d Checking Command Line '%s'",__LINE__
  259.                     ,instr);
  260.                 exit(1);
  261.                 break; }
  262.         j=strlen(cmd); }
  263.     else
  264.         cmd[j++]=instr[i]; }
  265. cmd[j]=0;
  266.  
  267. return(cmd);
  268. }
  269.  
  270. /****************************************************************************/
  271. /* Runs an external program directly using spawnvp                            */
  272. /****************************************************************************/
  273. int execute(char *cmdline)
  274. {
  275.     char c,d,e,cmdlen,*arg[30],str[256];
  276.     int i;
  277.  
  278. strcpy(str,cmdline);
  279. arg[0]=str;    /* point to the beginning of the string */
  280. cmdlen=strlen(str);
  281. for(c=0,d=1,e=0;c<cmdlen;c++,e++)    /* Break up command line */
  282.     if(str[c]==SP) {
  283.         str[c]=0;            /* insert nulls */
  284.         arg[d++]=str+c+1;    /* point to the beginning of the next arg */
  285.         e=0; }
  286. arg[d]=0;
  287. #ifndef __FLAT__
  288. if(node_swap) {
  289.     printf("Swapping...\n");
  290.     i=spawnvpo(".\\",(const char *)arg[0],(const char **)arg); }
  291. else
  292. #endif
  293.     i=spawnvp(P_WAIT,arg[0],arg);
  294. return(i);
  295. }
  296. /******************************************************************************
  297.  Returns the system address with the same zone as the address passed
  298. ******************************************************************************/
  299. faddr_t getsysfaddr(short zone)
  300. {
  301.     int i;
  302.     faddr_t sysfaddr;
  303.  
  304. sysfaddr.zone=sysfaddr.net=sysfaddr.node=1;
  305. sysfaddr.point=0;
  306. if(!total_faddrs)
  307.     return(sys_faddr);
  308. sysfaddr=faddr[0];
  309. if(total_faddrs==1)
  310.     return(sysfaddr);
  311. for(i=0;i<total_faddrs;i++)
  312.     if(faddr[i].zone==zone)
  313.         return(faddr[i]);
  314. return(sysfaddr);
  315. }
  316. /******************************************************************************
  317.  This function creates or appends on existing Binkley compatible .?LO file
  318.  attach file.
  319.  Returns 0 on success.
  320. ******************************************************************************/
  321. int write_flofile(char *attachment, faddr_t dest)
  322. {
  323.     char fname[256],outbound[128],str[128],ch;
  324.     ushort attr=0;
  325.     int i,file;
  326.     FILE *stream;
  327.  
  328. i=matchnode(dest,0);
  329. if(i<cfg.nodecfgs)
  330.     attr=cfg.nodecfg[i].attr;
  331.  
  332. if(attr&ATTR_CRASH) ch='C';
  333. else if(attr&ATTR_HOLD) ch='H';
  334. else if(attr&ATTR_DIRECT) ch='D';
  335. else ch='F';
  336. if(dest.zone==faddr[0].zone)        /* Default zone, use default outbound */
  337.     strcpy(outbound,cfg.outbound);
  338. else                                /* Inter-zone outbound is OUTBOUND.XXX */
  339.     sprintf(outbound,"%.*s.%03X\\"
  340.         ,strlen(cfg.outbound)-1,cfg.outbound,dest.zone);
  341. if(dest.point) {                    /* Point destination is OUTBOUND\*.PNT */
  342.     sprintf(str,"%04X%04X.PNT"
  343.         ,dest.net,dest.node);
  344.     strcat(outbound,str); }
  345. if(outbound[strlen(outbound)-1]=='\\')
  346.     outbound[strlen(outbound)-1]=0;
  347. mkdir(outbound);
  348. strcat(outbound,"\\");
  349. if(dest.point)
  350.     sprintf(fname,"%s%08X.%cLO",outbound,dest.point,ch);
  351. else
  352.     sprintf(fname,"%s%04X%04X.%cLO",outbound,dest.net,dest.node,ch);
  353. if((stream=fnopen(&file,fname,O_WRONLY|O_CREAT))==NULL) {
  354.     printf("\7ERROR opening %s %s\n",fname,sys_errlist[errno]);
  355.     logprintf("ERROR line %d opening %s %s",__LINE__,fname,sys_errlist[errno]);
  356.     return(-1); }
  357.  
  358. fseek(stream,0L,SEEK_END);
  359. fprintf(stream,"^%s\r\n",attachment);
  360. fclose(stream);
  361. return(0);
  362. }
  363.  
  364. /******************************************************************************
  365.  This function will create a netmail message (.MSG format).
  366.  If file is non-zero, will set file attachment bit (for bundles).
  367.  Returns 0 on success.
  368. ******************************************************************************/
  369. int create_netmail(char *to,char *subject,char *body,faddr_t dest,int file)
  370. {
  371.     FILE *fstream;
  372.     char str[256],fname[256];
  373.     ushort attr=0;
  374.     int fmsg;
  375.     uint i;
  376.     static uint startmsg;
  377.     time_t t;
  378.     fmsghdr_t hdr;
  379.     struct tm *tm;
  380.  
  381. if(!startmsg) startmsg=1;
  382. i=matchnode(dest,0);
  383. if(i<cfg.nodecfgs) {
  384.     attr=cfg.nodecfg[i].attr;
  385.     if(!attr) {
  386.         i=matchnode(dest,2);
  387.         if(i<cfg.nodecfgs)
  388.             attr=cfg.nodecfg[i].attr; } }
  389.  
  390. do {
  391.     for(i=startmsg;i;i++) {
  392.         sprintf(fname,"%s%u.MSG",netmail_dir,i);
  393.         if(!fexist(fname))
  394.             break; }
  395.     if(!i) {
  396.         printf("\7%s directory full!\n",netmail_dir);
  397.         logprintf("Directory full: %s",netmail_dir);
  398.         return(-1); }
  399.     startmsg=i+1;
  400.     strupr(fname);
  401.     if((fstream=fnopen(&fmsg,fname,O_RDWR|O_CREAT))==NULL) {
  402.         printf("\7ERROR opening %s %s\n",fname,sys_errlist[errno]);
  403.         logprintf("ERROR line %d opening %s %s",__LINE__,fname,sys_errlist[errno]);
  404.         return(-1); }
  405.  
  406.     memset(&hdr,0,sizeof(fmsghdr_t));
  407.     hdr.origzone=faddr[0].zone;
  408.     hdr.orignet=faddr[0].net;
  409.     hdr.orignode=faddr[0].node;
  410.     hdr.origpoint=faddr[0].point;
  411.     hdr.destzone=dest.zone;
  412.     hdr.destnet=dest.net;
  413.     hdr.destnode=dest.node;
  414.     hdr.destpoint=dest.point;
  415.  
  416.     hdr.attr=(FIDO_PRIVATE|FIDO_KILLSENT|FIDO_LOCAL);
  417.     if(file)
  418.         hdr.attr|=FIDO_FILE;
  419.  
  420.     if(attr&ATTR_HOLD)
  421.         hdr.attr|=FIDO_HOLD;
  422.     if(attr&ATTR_CRASH)
  423.         hdr.attr|=FIDO_CRASH;
  424.  
  425.     sprintf(hdr.from,"SBBSecho");
  426.  
  427.     t=time(NULL);
  428.     tm=gmtime(&t);
  429.     sprintf(hdr.time,"%02u %3.3s %02u  %02u:%02u:%02u"
  430.         ,tm->tm_mday,mon[tm->tm_mon],tm->tm_year
  431.         ,tm->tm_hour,tm->tm_min,tm->tm_sec);
  432.  
  433.     if(to)
  434.         sprintf(hdr.to,"%s",to);
  435.     else
  436.         sprintf(hdr.to,"SYSOP");
  437.  
  438.     sprintf(hdr.subj,"%.71s",subject);
  439.  
  440.     fwrite(&hdr,sizeof(fmsghdr_t),1,fstream);
  441.     sprintf(str,"\1INTL %u:%u/%u %u:%u/%u\r"
  442.         ,hdr.destzone,hdr.destnet,hdr.destnode
  443.         ,hdr.origzone,hdr.orignet,hdr.orignode);
  444.     fwrite(str,strlen(str),1,fstream);
  445.     if(attr&ATTR_DIRECT) {
  446.         fwrite("\1FLAGS DIR",10,1,fstream);
  447.         if(file)
  448.             fwrite(" KFS\r",5,1,fstream);
  449.         else
  450.             fwrite("\r",1,1,fstream); }
  451.     if(hdr.destpoint) {
  452.         sprintf(str,"\1TOPT %u\r",hdr.destpoint);
  453.         fwrite(str,strlen(str),1,fstream); }
  454.     if(hdr.origpoint) {
  455.         sprintf(str,"\1FMPT %u\r",hdr.origpoint);
  456.         fwrite(str,strlen(str),1,fstream); }
  457.     if(!file || (!(attr&ATTR_DIRECT) && file))
  458.         fwrite(body,strlen(body)+1,1,fstream);    /* Write additional NULL */
  459.     else
  460.         fwrite("\0",1,1,fstream);               /* Write NULL */
  461.     fclose(fstream);
  462. } while(!fexist(fname));
  463. return(0);
  464. }
  465.  
  466. /******************************************************************************
  467.  This function takes the contents of 'infile' and puts it into a netmail
  468.  message bound for addr.
  469. ******************************************************************************/
  470. void file_to_netmail(FILE *infile,char *title,faddr_t addr,char *to)
  471. {
  472.     char *buf,*p;
  473.     long l,m,len;
  474.  
  475. l=len=ftell(infile);
  476. if(len>8192L)
  477.     len=8192L;
  478. rewind(infile);
  479. if((buf=(char *)MALLOC(len+1))==NULL) {
  480.     printf("ERROR allocating %lu bytes for file to netmail buffer.\n",len);
  481.     logprintf("ERROR line %d allocating %lu for file to netmail buf",__LINE__
  482.         ,len);
  483.     return; }
  484. while((m=fread(buf,1,(len>8064L) ? 8064L:len,infile))>0) {
  485.     buf[m]=0;
  486.     if(l>8064L && (p=strrchr(buf,'\n'))!=NULL) {
  487.         p++;
  488.         if(*p) {
  489.             *p=0;
  490.             p++;
  491.             fseek(infile,-1L,SEEK_CUR);
  492.             while(*p) {             /* Seek back to end of last line */
  493.                 p++;
  494.                 fseek(infile,-1L,SEEK_CUR); } } }
  495.     if(ftell(infile)<l)
  496.         strcat(buf,"\r\nContinued in next message...\r\n");
  497.     create_netmail(to,title,buf,addr,0); }
  498. FREE(buf);
  499. }
  500. /******************************************************************************
  501.  This function sends a notify list to applicable nodes, this list includes the
  502.  settings configured for the node, as well as a list of areas the node is
  503.  connected to.
  504. ******************************************************************************/
  505. void notify_list(void)
  506. {
  507.     FILE *tmpf;
  508.     char str[256];
  509.     int i,j,k;
  510.  
  511. for(k=0;k<cfg.nodecfgs;k++) {
  512.  
  513.     if(!(cfg.nodecfg[k].attr&SEND_NOTIFY))
  514.         continue;
  515.  
  516.     if((tmpf=tmpfile())==NULL) {
  517.         printf("\7ERROR couldn't open tmpfile.\n");
  518.         logprintf("ERROR line %d couldn't open tmpfile",__LINE__);
  519.         return; }
  520.  
  521.     fprintf(tmpf,"Following are the options set for your system and a list "
  522.         "of areas\r\nyou are connected to.  Please make sure everything "
  523.         "is correct.\r\n\r\n");
  524.     fprintf(tmpf,"Packet Type       %s\r\n"
  525.         ,cfg.nodecfg[k].pkt_type==PKT_TWO ? "2"
  526.         :cfg.nodecfg[k].pkt_type==PKT_TWO_TWO ? "2.2":"2+");
  527.     fprintf(tmpf,"Archive Type      %s\r\n"
  528.         ,(cfg.nodecfg[k].arctype>cfg.arcdefs) ?
  529.          "None":cfg.arcdef[cfg.nodecfg[k].arctype].name);
  530.     fprintf(tmpf,"Mail Status       %s\r\n"
  531.         ,cfg.nodecfg[k].attr&ATTR_CRASH ? "Crash"
  532.         :cfg.nodecfg[k].attr&ATTR_HOLD ? "Hold" : "None");
  533.     fprintf(tmpf,"Direct            %s\r\n"
  534.         ,cfg.nodecfg[k].attr&ATTR_DIRECT ? "Yes":"No");
  535.     fprintf(tmpf,"Passive           %s\r\n"
  536.         ,cfg.nodecfg[k].attr&ATTR_PASSIVE ? "Yes":"No");
  537.     fprintf(tmpf,"Remote AreaMgr    %s\r\n\r\n"
  538.         ,cfg.nodecfg[k].password[0] ? "Yes" : "No");
  539.  
  540.     fprintf(tmpf,"Connected Areas\r\n---------------\r\n");
  541.     for(i=0;i<cfg.areas;i++) {
  542.         sprintf(str,"%s\r\n",cfg.area[i].name);
  543.         if(str[0]=='*')
  544.             continue;
  545.         for(j=0;j<cfg.area[i].uplinks;j++)
  546.             if(!memcmp(&cfg.nodecfg[k].faddr,&cfg.area[i].uplink[j]
  547.                 ,sizeof(faddr_t)))
  548.                 break;
  549.         if(j<cfg.area[i].uplinks)
  550.             fprintf(tmpf,"%s",str); }
  551.  
  552.     if(ftell(tmpf))
  553.         file_to_netmail(tmpf,"SBBSecho Notify List",cfg.nodecfg[k].faddr,0);
  554.     fclose(tmpf); }
  555. }
  556. /******************************************************************************
  557.  This function creates a netmail to addr showing a list of available areas (0),
  558.  a list of connected areas (1), or a list of removed areas (2).
  559. ******************************************************************************/
  560. void netmail_arealist(char type,faddr_t addr)
  561. {
  562.     FILE *stream,*tmpf;
  563.     char str[256],temp[256],title[81],match,*p;
  564.     int file,i,j,k,x,y;
  565.  
  566. if(!type)
  567.     strcpy(title,"List of Available Areas");
  568. else if(type==1)
  569.     strcpy(title,"List of Connected Areas");
  570. else
  571.     strcpy(title,"List of Unlinked Areas");
  572.  
  573. if((tmpf=tmpfile())==NULL) {
  574.     printf("\7ERROR couldn't open tmpfile.\n");
  575.     logprintf("ERROR line %d couldn't open tmpfile",__LINE__);
  576.     return; }
  577.  
  578. if(type==1 || (type!=1 && !(misc&ELIST_ONLY))) {
  579.     for(i=0;i<cfg.areas;i++) {
  580.         sprintf(str,"%s\r\n",cfg.area[i].name);
  581.         if(type) {
  582.             for(j=0;j<cfg.area[i].uplinks;j++)
  583.                 if(!memcmp(&addr,&cfg.area[i].uplink[j],sizeof(faddr_t)))
  584.                     break;
  585.             if((type==1 && j<cfg.area[i].uplinks) ||
  586.                 (type==2 && j==cfg.area[i].uplinks))
  587.                     fprintf(tmpf,"%s",str); }
  588.         else
  589.             fprintf(tmpf,"%s",str); } }
  590.  
  591. if(!type) {
  592.     i=matchnode(addr,0);
  593.     if(i<cfg.nodecfgs) {
  594.         for(j=0;j<cfg.listcfgs;j++) {
  595.             match=0;
  596.             for(k=0;k<cfg.listcfg[j].numflags;k++) {
  597.                 if(match) break;
  598.                 for(x=0;x<cfg.nodecfg[i].numflags;x++)
  599.                     if(!stricmp(cfg.listcfg[j].flag[k].flag
  600.                         ,cfg.nodecfg[i].flag[x].flag)) {
  601.                         if((stream=fnopen(&file
  602.                             ,cfg.listcfg[j].listpath,O_RDONLY))==NULL) {
  603.                             printf("\7ERROR couldn't open %s.\n"
  604.                                 ,cfg.listcfg[j].listpath);
  605.                             logprintf("ERROR line %d couldn't open %s %s"
  606.                                 ,__LINE__,cfg.listcfg[j].listpath
  607.                                 ,sys_errlist[errno]);
  608.                             match=1;
  609.                             break; }
  610.                         while(!feof(stream)) {
  611.                             if(!fgets(str,255,stream))
  612.                                 break;
  613.                             truncsp(str);
  614.                             strcat(str,"\r\n");
  615.                             p=str;
  616.                             while(*p && *p<=SP) p++;
  617.                             if(*p==';')     /* Ignore Comment Lines */
  618.                                 continue;
  619.                             strcpy(temp,p);
  620.                             p=temp;
  621.                             while(*p && *p>SP) p++;
  622.                             *p=0;
  623.                             if(!(misc&ELIST_ONLY)) {
  624.                                 for(y=0;y<cfg.areas;y++)
  625.                                     if(!stricmp(cfg.area[y].name,temp))
  626.                                         break;
  627.                                 if(y==cfg.areas)
  628.                                     fprintf(tmpf,"%s",str); }
  629.                             else
  630.                                 fprintf(tmpf,"%s",str); }
  631.                         fclose(stream);
  632.                         match=1;
  633.                         break; } } } } }
  634.  
  635. if(!ftell(tmpf))
  636.     create_netmail(0,title,"None.",addr,0);
  637. else
  638.     file_to_netmail(tmpf,title,addr,0);
  639. fclose(tmpf);
  640. }
  641. /******************************************************************************
  642.  Imitation of Borland's tempnam function because Watcom doesn't have it
  643. ******************************************************************************/
  644. //#ifdef __WATCOMC__
  645. char *tempname(char *dir, char *prefix)
  646. {
  647.     char str[256],*p;
  648.     int i;
  649.  
  650. for(i=0;i<1000;i++) {
  651.     sprintf(str,"%s%s%03u.$$$",dir,prefix,i);
  652.     if(!fexist(str))
  653.         break; }
  654. if(i>=1000) {
  655.     logprintf("tempnam: too many files");
  656.     return(NULL); }
  657. p=malloc(strlen(str)+1);
  658. if(!p) {
  659.     logprintf("tempnam: couldn't malloc %u",strlen(str)+1);
  660.     return(NULL); }
  661. strcpy(p,str);
  662. return(p);
  663. }
  664. //#endif
  665.  
  666. char check_elists(char *areatag,faddr_t addr)
  667. {
  668.     FILE *stream;
  669.     char str[1025],quit=0,match=0,*p;
  670.     int i,j,k,x,file;
  671.  
  672. i=matchnode(addr,0);
  673. if(i<cfg.nodecfgs) {
  674.     for(j=0;j<cfg.listcfgs;j++) {
  675.         quit=0;
  676.         for(k=0;k<cfg.listcfg[j].numflags;k++) {
  677.             if(quit) break;
  678.             for(x=0;x<cfg.nodecfg[i].numflags;x++)
  679.                 if(!stricmp(cfg.listcfg[j].flag[k].flag
  680.                     ,cfg.nodecfg[i].flag[x].flag)) {
  681.                     if((stream=fnopen(&file
  682.                         ,cfg.listcfg[j].listpath,O_RDONLY))==NULL) {
  683.                         printf("\7ERROR couldn't open %s.\n"
  684.                             ,cfg.listcfg[j].listpath);
  685.                         logprintf("ERROR line %d opening %s"
  686.                             ,__LINE__,cfg.listcfg[j].listpath);
  687.                         quit=1;
  688.                         break; }
  689.                     while(!feof(stream)) {
  690.                         if(!fgets(str,255,stream))
  691.                             break;
  692.                         truncsp(str);
  693.                         strcat(str,"\r\n");
  694.                         p=str;
  695.                         while(*p && *p<=SP) p++;
  696.                         if(*p==';')     /* Ignore Comment Lines */
  697.                             continue;
  698.                         strcpy(str,p);
  699.                         p=str;
  700.                         while(*p && *p>SP) p++;
  701.                         *p=0;
  702.                         if(!stricmp(areatag,str)) {
  703.                             match=1;
  704.                             break; } }
  705.                     fclose(stream);
  706.                     quit=1;
  707.                     if(match)
  708.                         return(match);
  709.                     break; } } } }
  710. return(match);
  711. }
  712. /******************************************************************************
  713.  Used by AREAFIX to add/remove/change areas in the areas file
  714. ******************************************************************************/
  715. void alter_areas(area_t add_area,area_t del_area,faddr_t addr)
  716. {
  717.     FILE *nmfile,*afilein,*afileout,*reqfile,*fwdfile;
  718.     char str[1025],fields[1025],field1[81],field2[81],field3[81]
  719.         ,drive[3],dir[66],name[9],ext[5],outpath[128]
  720.         ,*outname,*p,*tp,nomatch=0,match=0;
  721.     int i,j,k,x,y,file;
  722.     ulong tagcrc;
  723.  
  724. _splitpath(cfg.areafile,drive,dir,name,ext);
  725. sprintf(outpath,"%s%s",drive,dir);
  726. if((outname=tempname(outpath,"AREAS"))==NULL) {
  727.     printf("\7ERROR creating temp file name for %s.\n",outpath);
  728.     logprintf("ERROR tempnam(%s,AREAS)",outpath);
  729.     return; }
  730. if((nmfile=tmpfile())==NULL) {
  731.     printf("\7ERROR couldn't open NetMail temp file.\n");
  732.     logprintf("ERROR in tmpfile()");
  733.     free(outname);
  734.     return; }
  735. if((afileout=fopen(outname,"w+b"))==NULL) {
  736.     printf("\7ERROR couldn't open %s.\n",outname);
  737.     logprintf("ERROR line %d opening %s %s",__LINE__,outname
  738.         ,sys_errlist[errno]);
  739.     fclose(nmfile);
  740.     free(outname);
  741.     return; }
  742. if((afilein=fnopen(&file,cfg.areafile,O_RDONLY))==NULL) {
  743.     printf("\7ERROR couldn't open %s.\n",cfg.areafile);
  744.     logprintf("ERROR line %d opening %s %s",__LINE__,cfg.areafile
  745.         ,sys_errlist[errno]);
  746.     fclose(afileout);
  747.     fclose(nmfile);
  748.     free(outname);
  749.     return; }
  750. while(!feof(afilein)) {
  751.     if(!fgets(fields,1024,afilein))
  752.         break;
  753.     truncsp(fields);
  754.     strcat(fields,"\r\n");
  755.     p=fields;
  756.     while(*p && *p<=SP) p++;
  757.     if(*p==';') {    /* Skip Comment Lines */
  758.         fprintf(afileout,"%s",fields);
  759.         continue; }
  760.     sprintf(field1,"%-.81s",p);         /* Internal Code Field */
  761.     tp=field1;
  762.     while(*tp && *tp>SP) tp++;
  763.     *tp=0;
  764.     while(*p && *p>SP) p++;
  765.     while(*p && *p<=SP) p++;
  766.     sprintf(field2,"%-.81s",p);         /* Areatag Field */
  767.     tp=field2;
  768.     while(*tp && *tp>SP) tp++;
  769.     *tp=0;
  770.     while(*p && *p>SP) p++;
  771.     while(*p && *p<=SP) p++;
  772.     if((tp=strchr(p,';'))!=NULL) {
  773.         sprintf(field3,"%-.81s",p);     /* Comment Field (if any) */
  774.         while(*tp && *tp>SP) tp++;
  775.         *tp=0; }
  776.     else
  777.         field3[0]=0;
  778.     if(del_area.tags) {                 /* Check for areas to remove */
  779.         for(i=0;i<del_area.tags;i++) {
  780.             if(!stricmp(del_area.tag[i],field2) ||
  781.                 !stricmp(del_area.tag[0],"-ALL"))     /* Match Found */
  782.                 break; }
  783.         if(i<del_area.tags) {
  784.             for(i=0;i<cfg.areas;i++) {
  785.                 if(!stricmp(field2,cfg.area[i].name)) {
  786.                     for(j=0;j<cfg.area[i].uplinks;j++)
  787.                         if(!memcmp(&cfg.area[i].uplink[j],&addr
  788.                             ,sizeof(faddr_t)))
  789.                             break;
  790.                     if(j==cfg.area[i].uplinks &&
  791.                         stricmp(del_area.tag[0],"-ALL")) {
  792.                         fprintf(afileout,"%s",fields);
  793.                         fprintf(nmfile,"%s not connected.\r\n",field2);
  794.                         break; }
  795.  
  796.                     /* Added 12/4/95 to remove uplink from connected uplinks */
  797.  
  798.                     for(k=j;k<cfg.area[i].uplinks-1;k++)
  799.                         memcpy(&cfg.area[i].uplink[k],&cfg.area[i].uplink[k+1]
  800.                             ,sizeof(faddr_t));
  801.                     --cfg.area[i].uplinks;
  802.                     if((cfg.area[i].uplink=(faddr_t *)
  803.                         REALLOC(cfg.area[i].uplink,sizeof(faddr_t)
  804.                         *(cfg.area[i].uplinks)))==NULL) {
  805.                         printf("ERROR allocating memory for area #%u "
  806.                             "uplinks.\n",i+1);
  807.                         logprintf("ERROR line %d allocating memory for area "
  808.                             "#%u uplinks.\n",__LINE__,i+1);
  809.                         exit(1); }
  810.  
  811.                     fprintf(afileout,"%-16s%-23s ",field1,field2);
  812.                     for(j=0;j<cfg.area[i].uplinks;j++) {
  813.                         if(!memcmp(&cfg.area[i].uplink[j],&addr
  814.                             ,sizeof(faddr_t)))
  815.                             continue;
  816.                         fprintf(afileout,"%s "
  817.                             ,faddrtoa(cfg.area[i].uplink[j])); }
  818.                     if(field3[0])
  819.                         fprintf(afileout,"%s",field3);
  820.                     fprintf(afileout,"\r\n");
  821.                     fprintf(nmfile,"%s removed.\r\n",field2);
  822.                     break; } }
  823.             if(i==cfg.areas)            /* Something screwy going on */
  824.                 fprintf(afileout,"%s",fields);
  825.             continue; } }                /* Area match so continue on */
  826.     if(add_area.tags) {                 /* Check for areas to add */
  827.         for(i=0;i<add_area.tags;i++)
  828.             if(!stricmp(add_area.tag[i],field2) ||
  829.                 !stricmp(add_area.tag[0],"+ALL"))      /* Match Found */
  830.                 break;
  831.         if(i<add_area.tags) {
  832.             if(stricmp(add_area.tag[i],"+ALL"))
  833.                 add_area.tag[i][0]=0;  /* So we can check other lists */
  834.             for(i=0;i<cfg.areas;i++) {
  835.                 if(!stricmp(field2,cfg.area[i].name)) {
  836.                     for(j=0;j<cfg.area[i].uplinks;j++)
  837.                         if(!memcmp(&cfg.area[i].uplink[j],&addr
  838.                             ,sizeof(faddr_t)))
  839.                             break;
  840.                     if(j<cfg.area[i].uplinks) {
  841.                         fprintf(afileout,"%s",fields);
  842.                         fprintf(nmfile,"%s already connected.\r\n",field2);
  843.                         break; }
  844.                     if(misc&ELIST_ONLY && !check_elists(field2,addr)) {
  845.                         fprintf(afileout,"%s",fields);
  846.                         break; }
  847.  
  848.                     /* Added 12/4/95 to add uplink to connected uplinks */
  849.  
  850.                     ++cfg.area[i].uplinks;
  851.                     if((cfg.area[i].uplink=(faddr_t *)
  852.                         REALLOC(cfg.area[i].uplink,sizeof(faddr_t)
  853.                         *(cfg.area[i].uplinks)))==NULL) {
  854.                         printf("ERROR allocating memory for area #%u "
  855.                             "uplinks.\n",i+1);
  856.                         logprintf("ERROR line %d allocating memory for area "
  857.                             "#%u uplinks.\n",__LINE__,i+1);
  858.                         exit(1); }
  859.                     memcpy(&cfg.area[i].uplink[j],&addr,sizeof(faddr_t));
  860.  
  861.                     fprintf(afileout,"%-16s%-23s ",field1,field2);
  862.                     for(j=0;j<cfg.area[i].uplinks;j++)
  863.                         fprintf(afileout,"%s "
  864.                             ,faddrtoa(cfg.area[i].uplink[j]));
  865. #if 0 // Removed (02/26/96) rrs
  866.                     fprintf(afileout,"%s ",faddrtoa(addr));
  867. #endif
  868.                     if(field3[0])
  869.                         fprintf(afileout,"%s",field3);
  870.                     fprintf(afileout,"\r\n");
  871.                     fprintf(nmfile,"%s added.\r\n",field2);
  872.                     break; } }
  873.             if(i==cfg.areas)            /* Something screwy going on */
  874.                 fprintf(afileout,"%s",fields);
  875.             continue; }                 /* Area match so continue on */
  876.         nomatch=1; }                    /* This area wasn't in there */
  877.     fprintf(afileout,"%s",fields); }    /* No match so write back line */
  878. fclose(afilein);
  879. if(nomatch || (add_area.tags && !stricmp(add_area.tag[0],"+ALL"))) {
  880.     i=matchnode(addr,0);
  881.     if(i<cfg.nodecfgs) {
  882.         for(j=0;j<cfg.listcfgs;j++) {
  883.             match=0;
  884.             for(k=0;k<cfg.listcfg[j].numflags;k++) {
  885.                 if(match) break;
  886.                 for(x=0;x<cfg.nodecfg[i].numflags;x++)
  887.                     if(!stricmp(cfg.listcfg[j].flag[k].flag
  888.                         ,cfg.nodecfg[i].flag[x].flag)) {
  889.                         if((fwdfile=tmpfile())==NULL) {
  890.                             printf("\7ERROR couldn't open forwarding temp "
  891.                                 "file.\n");
  892.                             logprintf("ERROR line %d opening forward temp "
  893.                                 "file",__LINE__);
  894.                             match=1;
  895.                             break; }
  896.                         if((afilein=fnopen(&file
  897.                             ,cfg.listcfg[j].listpath,O_RDONLY))==NULL) {
  898.                             printf("\7ERROR couldn't open %s.\n"
  899.                                 ,cfg.listcfg[j].listpath);
  900.                             logprintf("ERROR line %d opening %s"
  901.                                 ,__LINE__,cfg.listcfg[j].listpath);
  902.                             fclose(fwdfile);
  903.                             match=1;
  904.                             break; }
  905.                         while(!feof(afilein)) {
  906.                             if(!fgets(str,255,afilein))
  907.                                 break;
  908.                             truncsp(str);
  909.                             strcat(str,"\r\n");
  910.                             p=str;
  911.                             while(*p && *p<=SP) p++;
  912.                             if(*p==';')     /* Ignore Comment Lines */
  913.                                 continue;
  914.                             strcpy(str,p);
  915.                             p=str;
  916.                             while(*p && *p>SP) p++;
  917.                             *p=0;
  918.                             if(!stricmp(add_area.tag[0],"+ALL")) {
  919.                                 sprintf(fields,"%.1024s",str);
  920.                                 tagcrc=crc32(strupr(fields));
  921.                                 for(y=0;y<cfg.areas;y++)
  922.                                     if(tagcrc==cfg.area[y].tag)
  923.                                         break;
  924.                                 if(y<cfg.areas)
  925.                                     continue; }
  926.                             for(y=0;y<add_area.tags;y++)
  927.                                 if((!stricmp(add_area.tag[y],str) &&
  928.                                     add_area.tag[y][0]) ||
  929.                                     !stricmp(add_area.tag[0],"+ALL"))
  930.                                     break;
  931.                             if(y<add_area.tags) {
  932.                                 fprintf(afileout,"%-16s%-23s","P",str);
  933.                                 if(cfg.listcfg[j].forward.zone)
  934.                                     fprintf(afileout," %s"
  935.                                         ,faddrtoa(cfg.listcfg[j].forward));
  936.                                 fprintf(afileout," %s\r\n",faddrtoa(addr));
  937.                                 fprintf(nmfile,"%s added.\r\n",str);
  938.                                 if(stricmp(add_area.tag[0],"+ALL"))
  939.                                     add_area.tag[y][0]=0;
  940.                                 if(!(cfg.listcfg[j].misc&NOFWD)
  941.                                     && cfg.listcfg[j].forward.zone)
  942.                                     fprintf(fwdfile,"%s\r\n",str); } }
  943.                         fclose(afilein);
  944.                         if(!(cfg.listcfg[j].misc&NOFWD) && ftell(fwdfile)>0)
  945.                             file_to_netmail(fwdfile,cfg.listcfg[j].password
  946.                                 ,cfg.listcfg[j].forward,"Areafix");
  947.                         fclose(fwdfile);
  948.                         match=1;
  949.                         break; } } } } }
  950. if(add_area.tags && stricmp(add_area.tag[0],"+ALL")) {
  951.     for(i=0;i<add_area.tags;i++)
  952.         if(add_area.tag[i][0])
  953.             fprintf(nmfile,"%s not found.\r\n",add_area.tag[i]); }
  954. if(!ftell(nmfile))
  955.     create_netmail(0,"Area Change Request","No changes made.",addr,0);
  956. else
  957.     file_to_netmail(nmfile,"Area Change Request",addr,0);
  958. fclose(nmfile);
  959. fclose(afileout);
  960. if(delfile(cfg.areafile))                    /* Delete AREAS.BBS */
  961.     logprintf("ERROR line %d removing %s %s",__LINE__,cfg.areafile
  962.         ,sys_errlist[errno]);
  963. if(rename(outname,cfg.areafile))           /* Rename new AREAS.BBS file */
  964.     logprintf("ERROR line %d renaming %s to %s",__LINE__,outname,cfg.areafile);
  965. free(outname);
  966. }
  967. /******************************************************************************
  968.  Used by AREAFIX to add/remove/change uplink info in the configuration file
  969.  old = the old setting for this option, new = what the setting is changing to
  970.  option = 0 for compression type change
  971.           1 for areafix password change
  972.           2 to set this node to passive
  973.           3 to set this node to active (remove passive)
  974. ******************************************************************************/
  975. void alter_config(faddr_t addr,char *old,char *new,char option)
  976. {
  977.     FILE *outfile,*cfgfile;
  978.     char str[257],outpath[128],tmp[257],tmp2[257],*outname,*p,*tp
  979.         ,drive[3],dir[66],name[9],ext[5],match=0;
  980.     int i,j,k,file;
  981.     faddr_t taddr;
  982.  
  983. i=matchnode(addr,0);                  /* i = config number from here on */
  984. _splitpath(cfg.cfgfile,drive,dir,name,ext);
  985. sprintf(outpath,"%s%s",drive,dir);
  986. if((outname=tempname(outpath,"CFG"))==NULL) {
  987.     printf("\7ERROR creating temporary file name for %s.\n",outpath);
  988.     logprintf("ERROR tempnam(%s,CFG)",outpath);
  989.     return; }
  990. if((outfile=fopen(outname,"w+b"))==NULL) {
  991.     printf("\7ERROR couldn't open %s.\n",outname);
  992.     logprintf("ERROR line %d opening %s %s",__LINE__,outname
  993.         ,sys_errlist[errno]);
  994.     free(outname);
  995.     return; }
  996. if((cfgfile=fnopen(&file,cfg.cfgfile,O_RDONLY))==NULL) {
  997.     printf("\7ERROR couldn't open %s.\n",cfg.cfgfile);
  998.     logprintf("ERROR line %d opening %s",__LINE__,cfg.cfgfile
  999.         ,sys_errlist[errno]);
  1000.     fclose(outfile);
  1001.     free(outname);
  1002.     return; }
  1003.  
  1004. while(!feof(cfgfile)) {
  1005.     if(!fgets(str,256,cfgfile))
  1006.         break;
  1007.     truncsp(str);
  1008.     p=str;
  1009.     while(*p && *p<=SP) p++;
  1010.     if(*p==';') {
  1011.         fprintf(outfile,"%s\r\n",str);
  1012.         continue; }
  1013.     sprintf(tmp,"%-.25s",p);
  1014.     tp=strchr(tmp,SP);
  1015.     if(tp)
  1016.         *tp=0;                                /* Chop off at space */
  1017.     strupr(tmp);                            /* Convert code to uppercase */
  1018.     while(*p>SP) p++;                        /* Skip code */
  1019.     while(*p && *p<=SP) p++;                /* Skip white space */
  1020.  
  1021.     if(option==0 && !strcmp(tmp,"USEPACKER")) {     /* Change Compression */
  1022.         if(!*p)
  1023.             continue;
  1024.         strcpy(tmp2,p);
  1025.         p=tmp2;
  1026.         while(*p && *p>SP) p++;
  1027.         *p=0;
  1028.         p++;
  1029.         if(!stricmp(new,tmp2)) {   /* Add to new definition */
  1030.             fprintf(outfile,"%-10s %s %s %s\r\n",tmp,tmp2
  1031.                 ,faddrtoa(cfg.nodecfg[i].faddr)
  1032.                 ,(*p) ? p : "");
  1033.             match=1;
  1034.             continue; }
  1035.         else if(!stricmp(old,tmp2)) {    /* Remove from old def */
  1036.             for(j=k=0;j<cfg.nodecfgs;j++) {
  1037.                 if(j==i)
  1038.                     continue;
  1039.                 if(!stricmp(cfg.arcdef[cfg.nodecfg[j].arctype].name,tmp2)) {
  1040.                     if(!k) {
  1041.                         fprintf(outfile,"%-10s %s",tmp,tmp2);
  1042.                         k++; }
  1043.                     fprintf(outfile," %s"
  1044.                         ,faddrtoa(cfg.nodecfg[j].faddr)); } }
  1045.             fprintf(outfile,"\r\n");
  1046.             continue; } }
  1047.  
  1048.     if(option==1 && !strcmp(tmp,"AREAFIX")) {       /* Change Password */
  1049.         if(!*p)
  1050.             continue;
  1051.         taddr=atofaddr(p);
  1052.         if(!memcmp(&cfg.nodecfg[i].faddr,&taddr,sizeof(faddr_t))) {
  1053.             while(*p && *p>SP) p++;     /* Skip over address */
  1054.             while(*p && *p<=SP) p++;    /* Skip over whitespace */
  1055.             while(*p && *p>SP) p++;     /* Skip over password */
  1056.             while(*p && *p<=SP) p++;    /* Skip over whitespace */
  1057.             fprintf(outfile,"%-10s %s %s %s\r\n",tmp
  1058.                 ,faddrtoa(cfg.nodecfg[i].faddr),new,p);
  1059.             continue; } }
  1060.  
  1061.     if(option>1 && !strcmp(tmp,"PASSIVE")) {        /* Toggle Passive Areas */
  1062.         match=1;
  1063.         for(j=k=0;j<cfg.nodecfgs;j++) {
  1064.             if(option==2 && j==i) {
  1065.                 if(!k) fprintf(outfile,"%-10s",tmp);
  1066.                 fprintf(outfile," %s",faddrtoa(cfg.nodecfg[j].faddr));
  1067.                 k++;
  1068.                 continue; }
  1069.             if(option==3 && j==i)
  1070.                 continue;
  1071.             if(cfg.nodecfg[j].attr&ATTR_PASSIVE) {
  1072.                 if(!k) fprintf(outfile,"%-10s",tmp);
  1073.                 fprintf(outfile," %s",faddrtoa(cfg.nodecfg[j].faddr));
  1074.                 k++; } }
  1075.         if(k) fprintf(outfile,"\r\n");
  1076.         continue; }
  1077.     fprintf(outfile,"%s\r\n",str); }
  1078.  
  1079. if(!match) {
  1080.     if(option==0)
  1081.         fprintf(outfile,"%-10s %s %s\r\n","USEPACKER",new
  1082.             ,faddrtoa(cfg.nodecfg[i].faddr));
  1083.     if(option==2)
  1084.         fprintf(outfile,"%-10s %s\r\n","PASSIVE"
  1085.             ,faddrtoa(cfg.nodecfg[i].faddr)); }
  1086.  
  1087. fclose(cfgfile);
  1088. fclose(outfile);
  1089. if(delfile(cfg.cfgfile))
  1090.     logprintf("ERROR line %d removing %s %s",__LINE__,cfg.cfgfile
  1091.         ,sys_errlist[errno]);
  1092. if(rename(outname,cfg.cfgfile))
  1093.     logprintf("ERROR line %d renaming %s to %s",__LINE__,outname,cfg.cfgfile);
  1094. free(outname);
  1095. }
  1096. /******************************************************************************
  1097.  Used by AREAFIX to process any '%' commands that come in via netmail
  1098. ******************************************************************************/
  1099. void command(char *instr,faddr_t addr)
  1100. {
  1101.     FILE *stream,*tmpf;
  1102.     char str[256],temp[256],match,*buf,*p;
  1103.     int  file,i,j,node;
  1104.     long l;
  1105.     area_t add_area,del_area;
  1106.  
  1107. node=matchnode(addr,0);
  1108. if(node==cfg.nodecfgs)
  1109.     return;
  1110. memset(&add_area,0,sizeof(area_t));
  1111. memset(&del_area,0,sizeof(area_t));
  1112. strupr(instr);
  1113. if((p=strstr(instr,"HELP"))!=NULL) {
  1114.     sprintf(str,"%s%sAREAMGR.HLP",(exec_dir[0]=='.') ? node_dir:"",exec_dir);
  1115.     if(!fexist(str))
  1116.         return;
  1117.     if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
  1118.         printf("\7ERROR couldn't open %s.\n",str);
  1119.         logprintf("ERROR line %d opening %s %s",__LINE__,str
  1120.             ,sys_errlist[errno]);
  1121.         return; }
  1122.     l=filelength(file);
  1123.     if((buf=(char *)LMALLOC(l+1L))==NULL) {
  1124.         printf("ERROR line %d allocating %lu bytes for %s\n",__LINE__,l,str);
  1125.         return; }
  1126.     fread(buf,l,1,stream);
  1127.     fclose(stream);
  1128.     buf[l]=0;
  1129.     create_netmail(0,"Area Manager Help",buf,addr,0);
  1130.     LFREE(buf);
  1131.     return; }
  1132.  
  1133. if((p=strstr(instr,"LIST"))!=NULL) {
  1134.     netmail_arealist(0,addr);
  1135.     return; }
  1136.  
  1137. if((p=strstr(instr,"QUERY"))!=NULL) {
  1138.     netmail_arealist(1,addr);
  1139.     return; }
  1140.  
  1141. if((p=strstr(instr,"UNLINKED"))!=NULL) {
  1142.     netmail_arealist(2,addr);
  1143.     return; }
  1144.  
  1145. if((p=strstr(instr,"COMPRESSION"))!=NULL) {
  1146.     while(*p && *p>SP) p++;
  1147.     while(*p && *p<=SP) p++;
  1148.     for(i=0;i<cfg.arcdefs;i++)
  1149.         if(!stricmp(p,cfg.arcdef[i].name))
  1150.             break;
  1151.     if(!stricmp(p,"NONE"))
  1152.         i=0xffff;
  1153.     if(i==cfg.arcdefs) {
  1154.         if((tmpf=tmpfile())==NULL) {
  1155.             printf("\7ERROR couldn't open tmpfile.\n");
  1156.             logprintf("ERROR line %d opening tmpfile()",__LINE__);
  1157.             return; }
  1158.         fprintf(tmpf,"Compression type unavailable.\r\n\r\n"
  1159.             "Available types are:\r\n");
  1160.         for(i=0;i<cfg.arcdefs;i++)
  1161.             fprintf(tmpf,"                     %s\r\n",cfg.arcdef[i].name);
  1162.         file_to_netmail(tmpf,"Compression Type Change",addr,0);
  1163.         fclose(tmpf);
  1164.         LFREE(buf);
  1165.         return; }
  1166.     alter_config(addr,cfg.arcdef[cfg.nodecfg[node].arctype].name
  1167.         ,cfg.arcdef[i].name,0);
  1168.     cfg.nodecfg[node].arctype=i;
  1169.     sprintf(str,"Compression type changed to %s.",cfg.arcdef[i].name);
  1170.     create_netmail(0,"Compression Type Change",str,addr,0);
  1171.     return; }
  1172.  
  1173. if((p=strstr(instr,"PASSWORD"))!=NULL) {
  1174.     while(*p && *p>SP) p++;
  1175.     while(*p && *p<=SP) p++;
  1176.     sprintf(temp,"%-.25s",p);
  1177.     p=temp;
  1178.     while(*p && *p>SP) p++;
  1179.     *p=0;
  1180.     if(node==cfg.nodecfgs)           /* Should never happen */
  1181.         return;
  1182.     if(!stricmp(temp,cfg.nodecfg[node].password)) {
  1183.         sprintf(str,"Your password was already set to %s."
  1184.             ,cfg.nodecfg[node].password);
  1185.         create_netmail(0,"Password Change Request",str,addr,0);
  1186.         return; }
  1187.     alter_config(addr,cfg.nodecfg[node].password,temp,1);
  1188.     sprintf(str,"Your password has been changed from %s to %.25s."
  1189.         ,cfg.nodecfg[node].password,temp);
  1190.     sprintf(cfg.nodecfg[node].password,"%.25s",temp);
  1191.     create_netmail(0,"Password Change Request",str,addr,0);
  1192.     return; }
  1193.  
  1194. if((p=strstr(instr,"RESCAN"))!=NULL) {
  1195.     export_echomail("",addr);
  1196.     create_netmail(0,"Rescan Areas"
  1197.         ,"All connected areas carried by your hub have been rescanned."
  1198.         ,addr,0);
  1199.     return; }
  1200.  
  1201. if((p=strstr(instr,"ACTIVE"))!=NULL) {
  1202.     if(!(cfg.nodecfg[node].attr&ATTR_PASSIVE)) {
  1203.         create_netmail(0,"Reconnect Disconnected Areas"
  1204.             ,"Your areas are already connected.",addr,0);
  1205.         return; }
  1206.     alter_config(addr,0,0,3);
  1207.     create_netmail(0,"Reconnect Disconnected Areas"
  1208.         ,"Temporarily disconnected areas have been reconnected.",addr,0);
  1209.     return; }
  1210.  
  1211. if((p=strstr(instr,"PASSIVE"))!=NULL) {
  1212.     if(cfg.nodecfg[node].attr&ATTR_PASSIVE) {
  1213.         create_netmail(0,"Temporarily Disconnect Areas"
  1214.             ,"Your areas are already temporarily disconnected.",addr,0);
  1215.         return; }
  1216.     alter_config(addr,0,0,2);
  1217.     create_netmail(0,"Temporarily Disconnect Areas"
  1218.         ,"Your areas have been temporarily disconnected.",addr,0);
  1219.     return; }
  1220.  
  1221. if((p=strstr(instr,"FROM"))!=NULL);
  1222.  
  1223. if((p=strstr(instr,"+ALL"))!=NULL) {
  1224.     if((add_area.tag=(char **)REALLOC(add_area.tag
  1225.         ,sizeof(char *)*add_area.tags+1))==NULL) {
  1226.         printf("ERROR allocating memory for add area tag #%u.\n"
  1227.             ,add_area.tags+1);
  1228.         logprintf("ERROR line %d allocating memory for add area tag #%u"
  1229.             ,__LINE__,add_area.tags+1);
  1230.         exit(1); }
  1231.     if((add_area.tag[add_area.tags]=(char *)LMALLOC(strlen(instr)+1))==NULL) {
  1232.         printf("ERROR allocating memory for add area tag #%u.\n"
  1233.             ,add_area.tags+1);
  1234.         logprintf("ERROR line %d allocating memory for add area tag #%u"
  1235.             ,__LINE__,add_area.tags+1);
  1236.         exit(1); }
  1237.     strcpy(add_area.tag[add_area.tags],instr);
  1238.     add_area.tags++;
  1239.     alter_areas(add_area,del_area,addr);
  1240.     for(i=0;i<add_area.tags;i++)
  1241.         LFREE(add_area.tag[i]);
  1242.     FREE(add_area.tag);
  1243.     return; }
  1244.  
  1245. if((p=strstr(instr,"-ALL"))!=NULL) {
  1246.     if((del_area.tag=(char **)REALLOC(del_area.tag
  1247.         ,sizeof(char *)*del_area.tags+1))==NULL) {
  1248.         printf("ERROR allocating memory for del area tag #%u.\n"
  1249.             ,del_area.tags+1);
  1250.         logprintf("ERROR line %d allocating memory for del area tag #%u"
  1251.             ,__LINE__,del_area.tags+1);
  1252.         exit(1); }
  1253.     if((del_area.tag[del_area.tags]=(char *)LMALLOC(strlen(instr)+1))==NULL) {
  1254.         printf("ERROR allocating memory for del area tag #%u.\n"
  1255.             ,del_area.tags+1);
  1256.         logprintf("ERROR line %d allocating memory for del area tag #%u"
  1257.             ,__LINE__,del_area.tags+1);
  1258.         exit(1); }
  1259.     strcpy(del_area.tag[del_area.tags],instr);
  1260.     del_area.tags++;
  1261.     alter_areas(add_area,del_area,addr);
  1262.     for(i=0;i<del_area.tags;i++)
  1263.         LFREE(del_area.tag[i]);
  1264.     FREE(del_area.tag);
  1265.     return; }
  1266. }
  1267. /******************************************************************************
  1268.  This is where we're gonna process any netmail that comes in for areafix.
  1269.  Returns text for message body for the local sysop if necessary.
  1270. ******************************************************************************/
  1271. char *process_areafix(faddr_t addr,char HUGE16 *inbuf,char *password)
  1272. {
  1273.     static char body[512],str[81];
  1274.     char *p,*tp,action,percent=0;
  1275.     int i;
  1276.     ulong l,m;
  1277.     area_t add_area,del_area;
  1278.  
  1279. p=(char *)inbuf;
  1280.  
  1281. while(*p==1) {                /* Skip kludge lines 11/05/95 */
  1282.     while(*p && *p!=CR)
  1283.         p++;                /* Skip meat */
  1284.     if(*p)
  1285.         p++; }                /* Skip CR */
  1286.  
  1287. #if 0 // Removed 11/05/95
  1288. while(*p && (tp=strchr(p,'\1'))!=NULL) {    /* Remove ^A kludge lines */
  1289.     p=tp;
  1290.     while(*p && *p!=CR) p++; }
  1291. if(*p==CR)
  1292.     p++;
  1293. #endif
  1294.  
  1295. if(((tp=strstr(p,"---\r"))!=NULL || (tp=strstr(p,"--- "))!=NULL) &&
  1296.     (*(tp-1)==10 || *(tp-1)==13))
  1297.     *tp=0;
  1298.  
  1299. if(!strnicmp(p,"%FROM",5)) {    /* Remote Remote Maintenance (must be first) */
  1300.     sprintf(str,"%.80s",p+6);
  1301.     if((tp=strchr(str,CR))!=NULL)
  1302.         *tp=0;
  1303.     logprintf("Remote maintenance for %s requested via %s",str,faddrtoa(addr));
  1304.     addr=atofaddr(str); }
  1305.  
  1306. i=matchnode(addr,0);
  1307. if(i==cfg.nodecfgs) {
  1308.     sprintf(body,"Your node is not configured for Areafix, please "
  1309.         "contact your hub.\r\n");
  1310.     create_netmail(0,"Areafix Request",body,addr,0);
  1311.     sprintf(body,"An areafix request was made by node %s.\r\nThis node "
  1312.         "is not currently configured for areafix.\r\n",faddrtoa(addr));
  1313.     return(body); }
  1314.  
  1315. if(stricmp(cfg.nodecfg[i].password,password)) {
  1316.     create_netmail(0,"Areafix Request","Invalid Password.",addr,0);
  1317.     sprintf(body,"Node %s attempted an areafix request using an invalid "
  1318.         "password.\r\nThe password attempted was %s.\r\nThe correct password "
  1319.         "for this node is %s.\r\n",faddrtoa(addr),password
  1320.         ,(cfg.nodecfg[i].password[0]) ? cfg.nodecfg[i].password
  1321.          : "[None Defined]");
  1322.     return(body); }
  1323.  
  1324. m=strlen(p);
  1325. add_area.tags=0;
  1326. add_area.tag=NULL;
  1327. del_area.tags=0;
  1328. del_area.tag=NULL;
  1329. for(l=0;l<m;l++) {
  1330.     while(*(p+l) && *(p+l)<=SP) l++;
  1331.     if(!(*(p+l))) break;
  1332.     if(*(p+l)=='+' || *(p+l)=='-' || *(p+l)=='%') {
  1333.         action=*(p+l);
  1334.         l++; }
  1335.     else
  1336.         action='+';
  1337.     sprintf(str,"%.80s",p+l);
  1338.     if((tp=strchr(str,CR))!=NULL)
  1339.         *tp=0;
  1340.     switch(action) {
  1341.         case '+':                       /* Add Area */
  1342.             if((add_area.tag=(char **)REALLOC(add_area.tag
  1343.                 ,sizeof(char *)*add_area.tags+1))==NULL) {
  1344.                 printf("ERROR allocating memory for add area tag #%u.\n"
  1345.                     ,add_area.tags+1);
  1346.                 logprintf("ERROR line %d allocating memory for add area "
  1347.                     "tag #%u",__LINE__,add_area.tags+1);
  1348.                 exit(1); }
  1349.             if((add_area.tag[add_area.tags]=(char *)LMALLOC(strlen(str)+1))
  1350.                 ==NULL) {
  1351.                 printf("ERROR allocating memory for add area tag #%u.\n"
  1352.                     ,add_area.tags+1);
  1353.                 logprintf("ERROR line %d allocating memory for add area "
  1354.                     "tag #%u",__LINE__,add_area.tags+1);
  1355.                 exit(1); }
  1356.             strcpy(add_area.tag[add_area.tags],str);
  1357.             add_area.tags++;
  1358.             break;
  1359.         case '-':                       /* Remove Area */
  1360.             if((del_area.tag=(char **)REALLOC(del_area.tag
  1361.                 ,sizeof(char *)*del_area.tags+1))==NULL) {
  1362.                 printf("ERROR allocating memory for del area tag #%u.\n"
  1363.                     ,del_area.tags+1);
  1364.                 logprintf("ERROR line %d allocating memory for del area "
  1365.                     "tag #%u",__LINE__,del_area.tags+1);
  1366.                 exit(1); }
  1367.             if((del_area.tag[del_area.tags]=(char *)LMALLOC(strlen(str)+1))
  1368.                 ==NULL) {
  1369.                 printf("ERROR allocating memory for del area tag #%u.\n"
  1370.                     ,del_area.tags+1);
  1371.                 logprintf("ERROR line %d allocating memory for del area "
  1372.                     "tag #%u",__LINE__,del_area.tags+1);
  1373.                 exit(1); }
  1374.             strcpy(del_area.tag[del_area.tags],str);
  1375.             del_area.tags++;
  1376.             break;
  1377.         case '%':                       /* Process Command */
  1378.             command(str,addr);
  1379.             percent++;
  1380.             break; }
  1381.  
  1382.     while(*(p+l) && *(p+l)!=CR) l++; }
  1383.  
  1384. if(!percent && !add_area.tags && !del_area.tags) {
  1385.     create_netmail(0,"Areafix Request","No commands to process.",addr,0);
  1386.     sprintf(body,"Node %s attempted an areafix request with an empty message "
  1387.         "body or with no valid commands.\r\n",faddrtoa(addr));
  1388.     return(body); }
  1389. if(add_area.tags || del_area.tags)
  1390.     alter_areas(add_area,del_area,addr);
  1391. if(add_area.tags) {
  1392.     for(i=0;i<add_area.tags;i++)
  1393.         LFREE(add_area.tag[i]);
  1394.     FREE(add_area.tag); }
  1395. if(del_area.tags) {
  1396.     for(i=0;i<del_area.tags;i++)
  1397.         LFREE(del_area.tag[i]);
  1398.     FREE(del_area.tag); }
  1399. return(0);
  1400. }
  1401. /******************************************************************************
  1402.  This function will compare the archive signatures defined in the CFG file and
  1403.  extract 'infile' using the appropriate de-archiver.
  1404. ******************************************************************************/
  1405. int unpack(char *infile)
  1406. {
  1407.     FILE *stream;
  1408.     char str[256],tmp[3];
  1409.     int i,j,k,ch,file;
  1410.  
  1411. if((stream=fnopen(&file,infile,O_RDONLY))==NULL) {
  1412.     printf("\7ERROR couldn't open %s.\n",infile);
  1413.     logprintf("ERROR line %d opening %s %s",__LINE__,infile
  1414.         ,sys_errlist[errno]);
  1415.     exit(1); }
  1416. for(i=0;i<cfg.arcdefs;i++) {
  1417.     str[0]=0;
  1418.     fseek(stream,cfg.arcdef[i].byteloc,SEEK_SET);
  1419.     for(j=0;j<strlen(cfg.arcdef[i].hexid)/2;j++) {
  1420.         ch=fgetc(stream);
  1421.         if(ch==EOF) {
  1422.             i=cfg.arcdefs;
  1423.             break; }
  1424.         sprintf(tmp,"%02X",ch);
  1425.         strcat(str,tmp); }
  1426.     if(!stricmp(str,cfg.arcdef[i].hexid))
  1427.         break; }
  1428. fclose(stream);
  1429.  
  1430. if(i==cfg.arcdefs) {
  1431.     printf("\7ERROR couldn't determine filetype of %s.\n",infile);
  1432.     logprintf("ERROR line %d determining filetype of %s",__LINE__,infile);
  1433.     return(1); }
  1434.  
  1435. j=execute(cmdstr(cfg.arcdef[i].unpack,infile
  1436.     ,secure ? cfg.secure : cfg.inbound));
  1437. if(j) {
  1438.     printf("\7ERROR %d (%d) executing %s\n"
  1439.         ,j,errno,cmdstr(cfg.arcdef[i].unpack,infile
  1440.             ,secure ? cfg.secure : cfg.inbound));
  1441.     logprintf("ERROR %d (%d) line %d executing %s"
  1442.         ,j,errno,__LINE__,cmdstr(cfg.arcdef[i].unpack,infile
  1443.             ,secure ? cfg.secure : cfg.inbound));
  1444.     return(j); }
  1445. return(0);
  1446. }
  1447. /******************************************************************************
  1448.  This function will check the 'dest' for the type of archiver to use (as
  1449.  defined in the CFG file) and compress 'srcfile' into 'destfile' using the
  1450.  appropriate archive program.
  1451. ******************************************************************************/
  1452. void pack(char *srcfile,char *destfile,faddr_t dest)
  1453. {
  1454.     int i,j;
  1455.     uint use=0;
  1456.  
  1457. i=matchnode(dest,0);
  1458. if(i<cfg.nodecfgs)
  1459.     use=cfg.nodecfg[i].arctype;
  1460.  
  1461. j=execute(cmdstr(cfg.arcdef[use].pack,destfile,srcfile));
  1462. if(j) {
  1463.     printf("\7ERROR %d (%d) executing %s\n"
  1464.         ,j,errno,cmdstr(cfg.arcdef[use].pack,destfile,srcfile));
  1465.     logprintf("ERROR %d (%d) line %d executing %s"
  1466.         ,j,errno,__LINE__,cmdstr(cfg.arcdef[use].pack,destfile,srcfile)); }
  1467. }
  1468.  
  1469. char attachment(char *bundlename,faddr_t dest,char cleanup)
  1470. {
  1471.     FILE *fidomsg,*stream;
  1472.     char str[1025],path[512],fname[129],*p;
  1473.     int last,fmsg,file,error=0L;
  1474.     long fncrc,*mfncrc=0L,num_mfncrc=0L;
  1475.     struct find_t ff;
  1476.     attach_t attach;
  1477.     fmsghdr_t hdr;
  1478.  
  1479. sprintf(fname,"%sBUNDLES.SBE",cfg.outbound);
  1480. if((stream=fnopen(&file,fname,O_RDWR|O_CREAT))==NULL) {
  1481.     printf("\7ERROR opening %s %s\n",fname,sys_errlist[errno]);
  1482.     logprintf("ERROR line %d opening %s %s",__LINE__,fname,sys_errlist[errno]);
  1483.     return(1); }
  1484.  
  1485. if(cleanup==2) {                /* Check for existance in BUNDLES.SBE */
  1486.     while(!feof(stream)) {
  1487.         if(!fread(&attach,1,sizeof(attach_t),stream))
  1488.             break;
  1489.         if(!stricmp(attach.fname,bundlename)) {
  1490.             fclose(stream);
  1491.             return(1); } }
  1492.     fclose(stream);
  1493.     return(0); }
  1494.  
  1495. if(cleanup==1) {                /* Create netmail attaches */
  1496.  
  1497. if(!filelength(file)) {
  1498.     fclose(stream);
  1499.     return(0); }
  1500.                                 /* Get attach names from existing MSGs */
  1501. sprintf(str,"%s*.MSG",netmail_dir);
  1502. for(last=_dos_findfirst(str,0,&ff);!last;last=_dos_findnext(&ff)) {
  1503.     sprintf(path,"%s%s",netmail_dir,ff.name);
  1504.     strupr(path);
  1505.     if((fidomsg=fnopen(&fmsg,path,O_RDWR))==NULL) {
  1506.         printf("\7ERROR opening %s\n",path);
  1507.         logprintf("ERROR line %d opening %s %s",__LINE__,path
  1508.             ,sys_errlist[errno]);
  1509.         continue; }
  1510.     if(filelength(fmsg)<sizeof(fmsghdr_t)) {
  1511.         printf("\7ERROR %s has invalid length of %u bytes\n",path
  1512.             ,filelength(fmsg));
  1513.         logprintf("ERROR line %d %s has invalid length of %u bytes"
  1514.             ,__LINE__,path,filelength(fmsg));
  1515.         fclose(fidomsg);
  1516.         continue; }
  1517.     if(fread(&hdr,sizeof(fmsghdr_t),1,fidomsg)!=1) {
  1518.         fclose(fidomsg);
  1519.         printf("\7ERROR reading %u bytes from %s"
  1520.             ,sizeof(fmsghdr_t),path);
  1521.         logprintf("ERROR line %d reading %u bytes from %s"
  1522.             ,__LINE__,sizeof(fmsghdr_t),path);
  1523.         continue; }
  1524.     fclose(fidomsg);
  1525.     if(!(hdr.attr&FIDO_FILE))        /* Not a file attach */
  1526.         continue;
  1527.     num_mfncrc++;
  1528.     if((p=strrchr(hdr.subj,'\\'))!=NULL)
  1529.         p++;
  1530.     else
  1531.         p=hdr.subj;
  1532.     if((mfncrc=(long *)REALLOC(mfncrc,num_mfncrc*sizeof(long)))==NULL) {
  1533.         printf("ERROR allocating %lu bytes for bundle name crc.\n"
  1534.             ,num_mfncrc*sizeof(long));
  1535.         logprintf("ERROR line %d allocating %lu for bundle name crc"
  1536.             ,__LINE__,num_mfncrc*sizeof(long));
  1537.         continue; }
  1538.     mfncrc[num_mfncrc-1]=crc32(strupr(p)); }
  1539.  
  1540.     while(!feof(stream)) {
  1541.         if(!fread(&attach,1,sizeof(attach_t),stream))
  1542.             break;
  1543.         sprintf(str,"%s%s",cfg.outbound,attach.fname);
  1544.         if(!fexist(str))
  1545.             continue;
  1546.         fncrc=crc32(strupr(attach.fname));
  1547.         for(last=0;last<num_mfncrc;last++)
  1548.             if(mfncrc[last]==fncrc)
  1549.                 break;
  1550.         if(last==num_mfncrc)
  1551.             if(create_netmail(0,str,"\1FLAGS KFS\r",attach.dest,1))
  1552.                 error=1; }
  1553.     if(!error)                /* don't truncate if an error occured */
  1554.         chsize(file,0L);
  1555.     fclose(stream);
  1556.     if(num_mfncrc)
  1557.         FREE(mfncrc);
  1558. #ifdef __WATCOMC__
  1559.    _dos_findclose(&ff);
  1560. #endif
  1561.     return(0); }
  1562.  
  1563. while(!feof(stream)) {
  1564.     if(!fread(&attach,1,sizeof(attach_t),stream))
  1565.         break;
  1566.     if(!stricmp(attach.fname,bundlename)) {
  1567.         fclose(stream);
  1568.         return(0); } }
  1569.  
  1570. memcpy(&attach.dest,&dest,sizeof(faddr_t));
  1571. strcpy(attach.fname,bundlename);
  1572. fwrite(&attach,sizeof(attach_t),1,stream);
  1573. fclose(stream);
  1574. return(0);
  1575. }
  1576.  
  1577. /******************************************************************************
  1578.  This function is called when a message packet has reached it's maximum size.
  1579.  It places packets into a bundle until that bundle is full, at which time the
  1580.  last character of the extension increments (1 thru 0 and then A thru Z).  If
  1581.  all bundles have reached their maximum size remaining packets are placed into
  1582.  the Z bundle.
  1583. ******************************************************************************/
  1584. void pack_bundle(char *infile,faddr_t dest)
  1585. {
  1586.     char str[256],fname[256],outbound[128],day[3],ch,*p;
  1587.     int i,j,file,node;
  1588.     time_t now;
  1589.  
  1590. node=matchnode(dest,0);
  1591. strcpy(str,infile);
  1592. str[strlen(str)-1]='T';
  1593. if(rename(infile,str))                   /* Change .PK_ file to .PKT file */
  1594.     logprintf("ERROR line %d renaming %s to %s",__LINE__,infile,str);
  1595. infile[strlen(infile)-1]='T';
  1596. time(&now);
  1597. sprintf(day,"%-.2s",ctime(&now));
  1598. strupr(day);
  1599. if(misc&FLO_MAILER) {
  1600.     if(node<cfg.nodecfgs && cfg.nodecfg[node].route.zone)
  1601.         dest=cfg.nodecfg[node].route;
  1602.     if(dest.zone==faddr[0].zone)    /* Default zone, use default outbound */
  1603.         strcpy(outbound,cfg.outbound);
  1604.     else                            /* Inter-zone outbound is OUTBOUND.XXX */
  1605.         sprintf(outbound,"%.*s.%03X\\"
  1606.             ,strlen(cfg.outbound)-1,cfg.outbound,dest.zone);
  1607.     if(dest.point) {                /* Point destination is OUTBOUND\*.PNT */
  1608.         sprintf(str,"%04X%04X.PNT"
  1609.             ,dest.net,dest.node);
  1610.         strcat(outbound,str); }
  1611.     }
  1612. else
  1613.     strcpy(outbound,cfg.outbound);
  1614. if(outbound[strlen(outbound)-1]=='\\')
  1615.     outbound[strlen(outbound)-1]=0;
  1616. mkdir(outbound);
  1617. strcat(outbound,"\\");
  1618.  
  1619. if(node<cfg.nodecfgs)
  1620.     if(cfg.nodecfg[node].arctype==0xffff) {    /* Uncompressed! */
  1621.         if(misc&FLO_MAILER)
  1622.             i=write_flofile(infile,dest);
  1623.         else
  1624.             i=create_netmail(0,infile,"\1FLAGS KFS\r",dest,1);
  1625.         if(i) exit(1);
  1626.         return; }
  1627.  
  1628. sprintf(fname,"%s%04hX%04hX.%s",outbound,(short)(faddr[0].net-dest.net)
  1629.     ,(short)(faddr[0].node-dest.node),day);
  1630. if(dest.point && !(misc&FLO_MAILER))
  1631.     sprintf(fname,"%s%04hXP%03hX.%s",outbound,0,(short)dest.point,day);
  1632. for(i='0';i<='Z';i++) {
  1633.     if(i==':')
  1634.         i='A';
  1635.     sprintf(str,"%s%c",fname,i);
  1636.     if(flength(str)==0)
  1637.         if(delfile(str))
  1638.             logprintf("ERROR line %d removing %s %s",__LINE__,str
  1639.                 ,sys_errlist[errno]);
  1640.     if(fexist(str)) {
  1641.         if((p=strrchr(str,'\\'))!=NULL)
  1642.             p++;
  1643.         else
  1644.             p=str;
  1645.         if(flength(str)>=cfg.maxbdlsize)
  1646.             continue;
  1647.         file=sopen(str,O_WRONLY,SH_DENYRW);
  1648.         if(file==-1)        /* Can't open?!? Probably being sent */
  1649.             continue;
  1650.         close(file);
  1651.         if(!attachment(p,dest,2))
  1652.             attachment(p,dest,0);
  1653.         pack(infile,str,dest);
  1654.         if(delfile(infile))
  1655.             logprintf("ERROR line %d removing %s %s",__LINE__,infile
  1656.                 ,sys_errlist[errno]);
  1657.         return; }
  1658.     else {
  1659.         if(misc&FLO_MAILER)
  1660.             j=write_flofile(str,dest);
  1661.         else {
  1662.             if((p=strrchr(str,'\\'))!=NULL)
  1663.                 p++;
  1664.             else
  1665.                 p=str;
  1666.             j=attachment(p,dest,0); }
  1667.         if(j)
  1668.             exit(1);
  1669.         pack(infile,str,dest);
  1670.         if(delfile(infile))
  1671.             logprintf("ERROR line %d removing %s %s",__LINE__,infile
  1672.                 ,sys_errlist[errno]);
  1673.         return; } }
  1674.  
  1675. pack(infile,str,dest);    /* Won't get here unless all bundles are full */
  1676. }
  1677.  
  1678. /******************************************************************************
  1679.  This function checks the inbound directory for the first bundle it finds, it
  1680.  will then unpack and delete the bundle.  If no bundles exist this function
  1681.  returns a 0, otherwise a 1 is returned.
  1682. ******************************************************************************/
  1683. int unpack_bundle(void)
  1684. {
  1685.     char str[256];
  1686.     static char fname[256];
  1687.     int i,j;
  1688.     static struct find_t ff;
  1689.  
  1690. for(i=0;i<7;i++) {
  1691.     sprintf(str,"%s*.%s?",secure ? cfg.secure : cfg.inbound
  1692.         ,(i==0) ? "SU" : (i==1) ? "MO" : (i==2) ? "TU" : (i==3) ? "WE" : (i==4)
  1693.         ? "TH" : (i==5) ? "FR" : "SA");
  1694.     if(!ff.name[0])
  1695.         j=_dos_findfirst(str,0,&ff);
  1696.     else {
  1697.         j=_dos_findnext(&ff);
  1698.         if(j) {
  1699. #ifdef __WATCOMC__
  1700.             _dos_findclose(&ff);
  1701. #endif
  1702.             j=_dos_findfirst(str,0,&ff); } }
  1703.     if(!j) {
  1704.         sprintf(fname,"%s%s",secure ? cfg.secure : cfg.inbound,ff.name);
  1705.         if(unpack(fname)) {
  1706.             if((ddtol(ff.wr_time,ff.wr_date)+(48L*60L*60L))>time(NULL)) {
  1707.                 strcpy(str,fname);
  1708.                 str[strlen(str)-2]='_';
  1709.                 if(fexist(str))
  1710.                     str[strlen(str)-2]='-';
  1711.                 if(fexist(str))
  1712.                     delfile(str);
  1713.                 if(rename(fname,str))
  1714.                     logprintf("ERROR line %d renaming %s to %s"
  1715.                         ,__LINE__,fname,str); } }
  1716.         else if(delfile(fname))
  1717.             logprintf("ERROR line %d removing %s %s",__LINE__,fname
  1718.                 ,sys_errlist[errno]);
  1719.         return(1); } }
  1720.  
  1721. #ifdef __WATCOMC__
  1722. _dos_findclose(&ff);
  1723. #endif
  1724. return(0);
  1725. }
  1726.  
  1727.  
  1728. /******************************************************************************
  1729.  Displays characters locally
  1730. ******************************************************************************/
  1731. long lputs(char *str)
  1732. {
  1733.     char tmp[256];
  1734.     int i,j,k;
  1735.  
  1736.  
  1737. j=strlen(str);
  1738. for(i=k=0;i<j;i++)      /* remove CRs */
  1739.     if(str[i]==CR && str[i+1]==LF)
  1740.         continue;
  1741.     else
  1742.         tmp[k++]=str[i];
  1743. tmp[k]=0;
  1744. return(fputs(tmp,stdout));
  1745. }
  1746.  
  1747. /******************************************/
  1748. /* CRC-16 routines required for SMB index */
  1749. /******************************************/
  1750.  
  1751. /***********************************************)**********************)*****/
  1752. /* Updates 16-bit "rcrc" with character 'ch'                                */
  1753. /****************************************************************************/
  1754. void ucrc16(uchar ch, ushort *rcrc) {
  1755.     ushort i, cy;
  1756.     uchar nch=ch;
  1757.  
  1758. for (i=0; i<8; i++) {
  1759.     cy=*rcrc & 0x8000;
  1760.     *rcrc<<=1;
  1761.     if (nch & 0x80) *rcrc |= 1;
  1762.     nch<<=1;
  1763.     if (cy) *rcrc ^= 0x1021; }
  1764. }
  1765.  
  1766. /****************************************************************************/
  1767. /* Returns 16-crc of string (not counting terminating NULL)                 */
  1768. /****************************************************************************/
  1769. ushort crc16(char *str)
  1770. {
  1771.     int     i=0;
  1772.     ushort    crc=0;
  1773.  
  1774. ucrc16(0,&crc);
  1775. while(str[i])
  1776.     ucrc16(str[i++],&crc);
  1777. ucrc16(0,&crc);
  1778. ucrc16(0,&crc);
  1779. return(crc);
  1780. }
  1781.  
  1782. /****************************************************************************/
  1783. /* Performs printf() through local assembly routines                        */
  1784. /* Called from everywhere                                                   */
  1785. /****************************************************************************/
  1786. int lprintf(char *fmat, ...)
  1787. {
  1788.     va_list argptr;
  1789.     char sbuf[256];
  1790.     int chcount;
  1791.  
  1792. va_start(argptr,fmat);
  1793. chcount=vsprintf(sbuf,fmat,argptr);
  1794. va_end(argptr);
  1795. lputs(sbuf);
  1796. return(chcount);
  1797. }
  1798.  
  1799. /****************************************************************************/
  1800. /* Reads the data for node number 'number' into the structure 'node'        */
  1801. /* from NODE.DAB                                                            */
  1802. /* if lockit is non-zero, locks this node's record. putnodedat() unlocks it */
  1803. /****************************************************************************/
  1804. void getnodedat(uint number, node_t *node, char lockit)
  1805. {
  1806.     char str[256];
  1807.     int count=0;
  1808.  
  1809. number--;    /* make zero based */
  1810. while(count<LOOP_NODEDAB) {
  1811.     lseek(nodefile,(long)number*sizeof(node_t),SEEK_SET);
  1812.     if(lockit
  1813.         && lock(nodefile,(long)number*sizeof(node_t),sizeof(node_t))==-1) {
  1814.         count++;
  1815.         continue; }
  1816.     if(read(nodefile,node,sizeof(node_t))==sizeof(node_t))
  1817.         break;
  1818.     count++; }
  1819. if(count==LOOP_NODEDAB) {
  1820.     printf("\7ERROR unlocking and reading NODE.DAB\n");
  1821.     logprintf("ERROR line %d unlocking and reading NODE.DAB",__LINE__); }
  1822. }
  1823.  
  1824. /****************************************************************************/
  1825. /* Write the data from the structure 'node' into NODE.DAB                      */
  1826. /* getnodedat(num,&node,1); must have been called before calling this func  */
  1827. /*          NOTE: ------^   the indicates the node record has been locked   */
  1828. /****************************************************************************/
  1829. void putnodedat(uint number, node_t node)
  1830. {
  1831.     char str[256];
  1832.     int count;
  1833.  
  1834. number--;    /* make zero based */
  1835. lseek(nodefile,(long)number*sizeof(node_t),SEEK_SET);
  1836. if(write(nodefile,&node,sizeof(node_t))!=sizeof(node_t)) {
  1837.     unlock(nodefile,(long)number*sizeof(node_t),sizeof(node_t));
  1838.     printf("\7ERROR writing NODE.DAB for node %u\n",number+1);
  1839.     logprintf("ERROR line %d writing NODE.DAB for node %u",__LINE__,number+1);
  1840.     return; }
  1841. unlock(nodefile,(long)number*sizeof(node_t),sizeof(node_t));
  1842. }
  1843.  
  1844. /****************************************************************************/
  1845. /* Creates a short message for 'usernumber' than contains 'strin'            */
  1846. /****************************************************************************/
  1847. void putsmsg(int usernumber, char *strin)
  1848. {
  1849.     char str[256];
  1850.     int file,i;
  1851.     node_t node;
  1852.  
  1853. sprintf(str,"%sMSGS\\%4.4u.MSG",data_dir,usernumber);
  1854. if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
  1855.     printf("\7ERROR opening/creating %s for create/append access\n",str);
  1856.     logprintf("ERROR line %d opening/creating %s",__LINE__,str);
  1857.     return; }
  1858. i=strlen(strin);
  1859. if(write(file,strin,i)!=i) {
  1860.     close(file);
  1861.     printf("\7ERROR writing %u bytes to %s\n",i,str);
  1862.     logprintf("ERROR line %d writing to %s",__LINE__,str);
  1863.     return; }
  1864. close(file);
  1865. for(i=1;i<=sys_nodes;i++) {        /* flag node if user on that msg waiting */
  1866.     getnodedat(i,&node,0);
  1867.     if(node.useron==usernumber
  1868.         && (node.status==NODE_INUSE || node.status==NODE_QUIET)
  1869.         && !(node.misc&NODE_MSGW)) {
  1870.         getnodedat(i,&node,1);
  1871.         node.misc|=NODE_MSGW;
  1872.         putnodedat(i,node); } }
  1873. }
  1874.  
  1875. /****************************************************************************/
  1876. /* Converts an ASCII Hex string into an ulong                       */
  1877. /****************************************************************************/
  1878. ulong ahtoul(char *str)
  1879. {
  1880.     ulong l,val=0;
  1881.  
  1882. while((l=(*str++)|0x20)!=0x20)
  1883.     val=(l&0xf)+(l>>6&1)*9+val*16;
  1884. return(val);
  1885. }
  1886.  
  1887. /****************************************************************************/
  1888. /* Truncates white-space chars off end of 'str' and terminates at first tab */
  1889. /****************************************************************************/
  1890. void truncsp(char *str)
  1891. {
  1892.     int c;
  1893.  
  1894. c=strlen(str);
  1895. while(c && (uchar)str[c-1]<=SP) c--;
  1896. str[c]=0;
  1897. }
  1898.  
  1899.  
  1900. void remove_re(char *str)
  1901. {
  1902. while(!strnicmp(str,"RE:",3)) {
  1903.     strcpy(str,str+3);
  1904.     while(str[0]==SP)
  1905.         strcpy(str,str+1); }
  1906. }
  1907.  
  1908. /****************************************************************************/
  1909. /* Moves or copies a file from one dir to another                           */
  1910. /* both 'src' and 'dest' must contain full path and filename                */
  1911. /* returns 0 if successful, -1 if error                                     */
  1912. /****************************************************************************/
  1913. int mv(char *src, char *dest, char copy)
  1914. {
  1915.     char buf[4096],str[256];
  1916.     int  ind,outd;
  1917.     long length,chunk=4096,l;
  1918. #ifdef __WATCOMC__
  1919.     unsigned short ftime,fdate;
  1920. #else
  1921.     unsigned ftime,fdate;
  1922. #endif
  1923.     FILE *inp,*outp;
  1924.  
  1925. if(!strcmp(src,dest))    /* source and destination are the same! */
  1926.     return(0);
  1927. if(!fexist(src)) {
  1928.     logprintf("MV ERROR: Source doesn't exist '%s",src);
  1929.     return(-1); }
  1930. if(!copy && fexist(dest)) {
  1931.     logprintf("MV ERROR: Destination already exists '%s'",dest);
  1932.     return(-1); }
  1933. if(!copy && ((src[1]!=':' && dest[1]!=':')
  1934.     || (src[1]==':' && dest[1]==':' && toupper(src[0])==toupper(dest[0])))) {
  1935.     if(rename(src,dest)) {                        /* same drive, so move */
  1936.         logprintf("MV ERROR: Error renaming %s to %s",src,dest);
  1937.         return(-1); }
  1938.     return(0); }
  1939. if((ind=nopen(src,O_RDONLY))==-1) {
  1940.     logprintf("MV ERROR: ERR_OPEN %s",src);
  1941.     return(-1); }
  1942. if((inp=fdopen(ind,"rb"))==NULL) {
  1943.     close(ind);
  1944.     logprintf("MV ERROR: ERR_FDOPEN %s",str);
  1945.     return(-1); }
  1946. setvbuf(inp,NULL,_IOFBF,8*1024);
  1947. if((outd=nopen(dest,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
  1948.     fclose(inp);
  1949.     logprintf("MV ERROR: ERR_OPEN %s",dest);
  1950.     return(-1); }
  1951. if((outp=fdopen(outd,"wb"))==NULL) {
  1952.     close(outd);
  1953.     fclose(inp);
  1954.     logprintf("MV ERROR: ERR_FDOPEN %s",str);
  1955.     return(-1); }
  1956. setvbuf(outp,NULL,_IOFBF,8*1024);
  1957. length=filelength(ind);
  1958. l=0L;
  1959. while(l<length) {
  1960.     if(l+chunk>length)
  1961.         chunk=length-l;
  1962.     fread(buf,chunk,1,inp);
  1963.     fwrite(buf,chunk,1,outp);
  1964.     l+=chunk; }
  1965. _dos_getftime(ind,&fdate,&ftime);
  1966. _dos_setftime(outd,fdate,ftime);
  1967. fclose(inp);
  1968. fclose(outp);
  1969. if(!copy && delfile(src)) {
  1970.     logprintf("ERROR line %d removing %s %s",__LINE__,src,sys_errlist[errno]);
  1971.     return(-1); }
  1972. return(0);
  1973. }
  1974.  
  1975. /****************************************************************************/
  1976. /* Returns the total number of msgs in the sub-board and sets 'ptr' to the  */
  1977. /* date of the last message in the sub (0) if no messages.                    */
  1978. /****************************************************************************/
  1979. ulong getlastmsg(uint subnum, ulong *ptr, time_t *t)
  1980. {
  1981.     char str[256];
  1982.     int i;
  1983.     smb_t smbfile;
  1984.  
  1985. if(subnum>=total_subs) {
  1986.     printf("\nERROR getlastmsg, subnum=%d\n",subnum);
  1987.     logprintf("ERROR line %d getlastmsg %d",__LINE__,subnum);
  1988.     exit(1); }
  1989. sprintf(smbfile.file,"%s%s",sub[subnum]->data_dir,sub[subnum]->code);
  1990. smbfile.retry_time=smb_retry_time;
  1991. if((i=smb_open(&smbfile))!=0) {
  1992.     printf("ERROR %d opening %s\n",i,smbfile.file);
  1993.     logprintf("ERROR %d line %d opening %s",i,__LINE__,smbfile.file);
  1994.     return(0); }
  1995.  
  1996. if(!filelength(fileno(smbfile.shd_fp))) {            /* Empty base */
  1997.     if(ptr) (*ptr)=0;
  1998.     smb_close(&smbfile);
  1999.     return(0); }
  2000. #if 0    // Not necessary with SMBLIB v2.0
  2001. if((i=smb_locksmbhdr(&smbfile))!=0) {
  2002.     smb_close(&smbfile);
  2003.     printf("ERROR %d locking %s\n",i,smbfile.file);
  2004.     logprintf("ERROR %d line %d locking %s smbhdr",i,__LINE__
  2005.         ,smbfile.file);
  2006.     return(0); }
  2007. if((i=smb_getstatus(&smbfile))!=0) {
  2008.     smb_unlocksmbhdr(&smbfile);
  2009.     smb_close(&smbfile);
  2010.     printf("ERROR %d reading %s\n",i,smbfile.file);
  2011.     logprintf("ERROR %d line %d reading %s",i,__LINE__,smbfile.file);
  2012.     return(0); }
  2013. smb_unlocksmbhdr(&smbfile);
  2014. #endif
  2015. smb_close(&smbfile);
  2016. if(ptr) (*ptr)=smbfile.status.last_msg;
  2017. return(smbfile.status.total_msgs);
  2018. }
  2019.  
  2020.  
  2021. ulong loadmsgs(post_t HUGE16 **post, ulong ptr)
  2022. {
  2023.     int i;
  2024.     long l=0,total;
  2025.     idxrec_t idx;
  2026.  
  2027.  
  2028. if((i=smb_locksmbhdr(&smb[cur_smb]))!=0) {
  2029.     printf("ERROR %d locking %s\n",i,smb[cur_smb].file);
  2030.     logprintf("ERROR %d line %d locking %s",i,__LINE__,smb[cur_smb].file);
  2031.     return(0L); }
  2032.  
  2033. /* total msgs in sub */
  2034. total=filelength(fileno(smb[cur_smb].sid_fp))/sizeof(idxrec_t);
  2035.  
  2036. if(!total) {            /* empty */
  2037.     smb_unlocksmbhdr(&smb[cur_smb]);
  2038.     return(0); }
  2039.  
  2040. if(((*post)=(post_t HUGE16 *)LMALLOC(sizeof(post_t)*total))    /* alloc for max */
  2041.     ==NULL) {
  2042.     smb_unlocksmbhdr(&smb[cur_smb]);
  2043.     printf("ERROR allocating %lu bytes for %s\n",sizeof(post_t *)*total
  2044.         ,smb[cur_smb].file);
  2045.     logprintf("ERROR line %d allocating %lu bytes for %s",__LINE__
  2046.         ,sizeof(post_t *)*total,smb[cur_smb].file);
  2047.     return(0); }
  2048.  
  2049. fseek(smb[cur_smb].sid_fp,0L,SEEK_SET);
  2050. while(!feof(smb[cur_smb].sid_fp)) {
  2051.     if(!fread(&idx,sizeof(idxrec_t),1,smb[cur_smb].sid_fp))
  2052.         break;
  2053.  
  2054.     if(idx.number<=ptr || idx.attr&MSG_DELETE)
  2055.         continue;
  2056.  
  2057.     if(idx.attr&MSG_MODERATED && !(idx.attr&MSG_VALIDATED))
  2058.         break;
  2059.  
  2060.     (*post)[l].offset=idx.offset;
  2061.     (*post)[l].number=idx.number;
  2062.     (*post)[l].to=idx.to;
  2063.     (*post)[l].from=idx.from;
  2064.     (*post)[l].subj=idx.subj;
  2065.     l++; }
  2066. smb_unlocksmbhdr(&smb[cur_smb]);
  2067. if(!l)
  2068.     LFREE(*post);
  2069. return(l);
  2070. }
  2071.  
  2072. void allocfail(uint size)
  2073. {
  2074. printf("\7ERROR allocating %u bytes of memory.\n",size);
  2075. bail(1);
  2076. }
  2077.  
  2078. void bail(int code)
  2079. {
  2080. exit(code);
  2081. }
  2082.  
  2083. /****************************************************************************/
  2084. /* Returns the length of the file in 'filespec'                             */
  2085. /****************************************************************************/
  2086. long flength(char *filespec)
  2087. {
  2088.     struct find_t f;
  2089.     uint i;
  2090.  
  2091. i=_dos_findfirst(filespec,0,&f);
  2092. #ifdef __WATCOMC__
  2093. _dos_findclose(&f);
  2094. #endif
  2095. if(!i)
  2096.     return(f.size);
  2097. return(-1L);
  2098. }
  2099.  
  2100. /****************************************************************************/
  2101. /* Checks the disk drive for the existence of a file. Returns 1 if it       */
  2102. /* exists, 0 if it doesn't.                                                 */
  2103. /* Called from upload                                                       */
  2104. /****************************************************************************/
  2105. char fexist(char *filespec)
  2106. {
  2107.     struct find_t f;
  2108.     uint i;
  2109.  
  2110. i=_dos_findfirst(filespec,0,&f);
  2111. #ifdef __WATCOMC__
  2112. _dos_findclose(&f);
  2113. #endif
  2114. if(!i)
  2115.     return(1);
  2116. return(0);
  2117. }
  2118.  
  2119. typedef struct {
  2120.     ulong    alias,
  2121.             real;
  2122.             } username_t;
  2123.  
  2124. /****************************************************************************/
  2125. /* Note: Wrote another version of this function that read all userdata into */
  2126. /****************************************************************************/
  2127. /* Looks for a perfect match amoung all usernames (not deleted users)        */
  2128. /* Returns the number of the perfect matched username or 0 if no match        */
  2129. /* Called from functions waitforcall and newuser                            */
  2130. /* memory then scanned it from memory... took longer - always.              */
  2131. /****************************************************************************/
  2132. ulong matchname(char *inname)
  2133. {
  2134.     static ulong total_users;
  2135.     static username_t *username;
  2136.     ulong last_user;
  2137.     int userdat,i;
  2138.     char str[256],name[LEN_NAME+1],alias[LEN_ALIAS+1],c;
  2139.     ulong l,crc;
  2140.  
  2141. if(!total_users) {        /* Load CRCs */
  2142.     fprintf(stderr,"\n%-25s","Loading user names...");
  2143.     sprintf(str,"%sUSER\\USER.DAT",data_dir);
  2144.     if((userdat=nopen(str,O_RDONLY|O_DENYNONE))==-1)
  2145.         return(0);
  2146.     last_user=filelength(userdat)/U_LEN;
  2147.     for(total_users=0;total_users<last_user;total_users++) {
  2148.         printf("%5ld\b\b\b\b\b",total_users);
  2149.         if((username=(username_t *)REALLOC(username
  2150.             ,(total_users+1L)*sizeof(username_t)))==NULL)
  2151.             break;
  2152.         username[total_users].alias=0;
  2153.         username[total_users].real=0;
  2154.         i=0;
  2155.         while(i<LOOP_NODEDAB
  2156.             && lock(userdat,(long)((long)(total_users)*U_LEN)+U_ALIAS
  2157.                 ,LEN_ALIAS+LEN_NAME)==-1)
  2158.             i++;
  2159.         if(i>=LOOP_NODEDAB) {       /* Couldn't lock USER.DAT record */
  2160.             logprintf("ERROR locking USER.DAT record #%ld",total_users);
  2161.             continue; }
  2162.         lseek(userdat,(long)((long)(total_users)*U_LEN)+U_ALIAS,SEEK_SET);
  2163.         read(userdat,alias,LEN_ALIAS);
  2164.         read(userdat,name,LEN_NAME);
  2165.         lseek(userdat,(long)(((long)total_users)*U_LEN)+U_MISC,SEEK_SET);
  2166.         read(userdat,tmp,8);
  2167.         for(c=0;c<8;c++)
  2168.             if(tmp[c]==ETX || tmp[c]==CR) break;
  2169.         tmp[c]=0;
  2170.         unlock(userdat,(long)((long)(total_users)*U_LEN)+U_ALIAS
  2171.             ,LEN_ALIAS+LEN_NAME);
  2172.         if(ahtoul(tmp)&DELETED)
  2173.             continue;
  2174.         for(c=0;c<LEN_ALIAS;c++)
  2175.             if(alias[c]==ETX || alias[c]==CR) break;
  2176.         alias[c]=0;
  2177.         strupr(alias);
  2178.         for(c=0;c<LEN_NAME;c++)
  2179.             if(name[c]==ETX || name[c]==CR) break;
  2180.         name[c]=0;
  2181.         strupr(name);
  2182.         username[total_users].alias=crc32(alias);
  2183.         username[total_users].real=crc32(name); }
  2184.     close(userdat);
  2185.     fprintf(stderr,"     \b\b\b\b\b");  // Clear counter
  2186.     fprintf(stderr,
  2187.         "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
  2188.         "%25s"
  2189.         "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
  2190.         ,""); }
  2191.  
  2192. strcpy(str,inname);
  2193. strupr(str);
  2194. crc=crc32(str);
  2195. for(l=0;l<total_users;l++)
  2196.     if((crc==username[l].alias || crc==username[l].real))
  2197.         return(l+1);
  2198. return(0);
  2199. }
  2200.  
  2201. /****************************************************************************/
  2202. /* Converts goofy FidoNet time format into Unix format                        */
  2203. /****************************************************************************/
  2204. time_t fmsgtime(char *str)
  2205. {
  2206.     char month[4];
  2207.     struct tm tm;
  2208.  
  2209. memset(&tm,0,sizeof(tm));
  2210. if(isdigit(str[1])) {    /* Regular format: "01 Jan 86  02:34:56" */
  2211.     tm.tm_mday=atoi(str);
  2212.     sprintf(month,"%3.3s",str+3);
  2213.     if(!stricmp(month,"jan"))
  2214.         tm.tm_mon=0;
  2215.     else if(!stricmp(month,"feb"))
  2216.         tm.tm_mon=1;
  2217.     else if(!stricmp(month,"mar"))
  2218.         tm.tm_mon=2;
  2219.     else if(!stricmp(month,"apr"))
  2220.         tm.tm_mon=3;
  2221.     else if(!stricmp(month,"may"))
  2222.         tm.tm_mon=4;
  2223.     else if(!stricmp(month,"jun"))
  2224.         tm.tm_mon=5;
  2225.     else if(!stricmp(month,"jul"))
  2226.         tm.tm_mon=6;
  2227.     else if(!stricmp(month,"aug"))
  2228.         tm.tm_mon=7;
  2229.     else if(!stricmp(month,"sep"))
  2230.         tm.tm_mon=8;
  2231.     else if(!stricmp(month,"oct"))
  2232.         tm.tm_mon=9;
  2233.     else if(!stricmp(month,"nov"))
  2234.         tm.tm_mon=10;
  2235.     else
  2236.         tm.tm_mon=11;
  2237.     tm.tm_year=atoi(str+7);
  2238.     tm.tm_hour=atoi(str+11);
  2239.     tm.tm_min=atoi(str+14);
  2240.     tm.tm_sec=atoi(str+17); }
  2241.  
  2242. else {                    /* SEAdog  format: "Mon  1 Jan 86 02:34" */
  2243.     tm.tm_mday=atoi(str+4);
  2244.     sprintf(month,"%3.3s",str+7);
  2245.     if(!stricmp(month,"jan"))
  2246.         tm.tm_mon=0;
  2247.     else if(!stricmp(month,"feb"))
  2248.         tm.tm_mon=1;
  2249.     else if(!stricmp(month,"mar"))
  2250.         tm.tm_mon=2;
  2251.     else if(!stricmp(month,"apr"))
  2252.         tm.tm_mon=3;
  2253.     else if(!stricmp(month,"may"))
  2254.         tm.tm_mon=4;
  2255.     else if(!stricmp(month,"jun"))
  2256.         tm.tm_mon=5;
  2257.     else if(!stricmp(month,"jul"))
  2258.         tm.tm_mon=6;
  2259.     else if(!stricmp(month,"aug"))
  2260.         tm.tm_mon=7;
  2261.     else if(!stricmp(month,"sep"))
  2262.         tm.tm_mon=8;
  2263.     else if(!stricmp(month,"oct"))
  2264.         tm.tm_mon=9;
  2265.     else if(!stricmp(month,"nov"))
  2266.         tm.tm_mon=10;
  2267.     else
  2268.         tm.tm_mon=11;
  2269.     tm.tm_year=atoi(str+11);
  2270.     tm.tm_hour=atoi(str+14);
  2271.     tm.tm_min=atoi(str+17);
  2272.     tm.tm_sec=0; }
  2273. return(mktime(&tm));
  2274. }
  2275.  
  2276. #if 1        /* Old way */
  2277.  
  2278. char HUGE16 *getfmsg(FILE *stream, ulong *outlen)
  2279. {
  2280.     uchar HUGE16 *fbuf;
  2281.     int ch;
  2282.     ulong l,length,start;
  2283.  
  2284. length=0L;
  2285. start=ftell(stream);                        /* Beginning of Message */
  2286. while(1) {
  2287.     ch=fgetc(stream);                        /* Look for Terminating NULL */
  2288.     if(!ch || ch==EOF)                        /* Found end of message */
  2289.         break;
  2290.     length++; }                             /* Increment the Length */
  2291.  
  2292. if((fbuf=(char *)LMALLOC(length+1))==NULL) {
  2293.     printf("Unable to allocate %lu bytes for message.\n",length+1);
  2294.     logprintf("ERROR line %d allocating %lu bytes of memory",__LINE__,length+1);
  2295.     exit(0); }
  2296.  
  2297. fseek(stream,start,SEEK_SET);
  2298. for(l=0;l<length;l++)
  2299.     fbuf[l]=fgetc(stream);
  2300. fbuf[length]=0;
  2301. if(!ch)
  2302.     fgetc(stream);        /* Read NULL */
  2303. if(outlen)
  2304.     *outlen=length;
  2305. return(fbuf);
  2306. }
  2307.  
  2308. #else
  2309.  
  2310. #define FBUF_BLOCK 4096
  2311.  
  2312. char *getfmsg(FILE *stream)
  2313. {
  2314.     uchar *fbuf,*p;
  2315.     ulong l,n,length,start;
  2316.  
  2317. length=0L;
  2318. start=ftell(stream);                        /* Beginning of Message */
  2319. if((fbuf=LMALLOC(FBUF_BLOCK))==NULL)
  2320.     return(fbuf);
  2321. while(!feof(stream)) {
  2322.     l=fread(fbuf+length,1,FBUF_BLOCK,stream);
  2323.     if(l<1)
  2324.         break;
  2325.     *(fbuf+length+l)=0;
  2326.     n=strlen(fbuf+length);
  2327.     if(n<l) {
  2328.         length+=(n+1);
  2329.         break; }
  2330.     printf(",");
  2331.     length+=l;
  2332.     if(l<FBUF_BLOCK)
  2333.         break;
  2334.     printf("<");
  2335.     if((p=REALLOC(fbuf,length+FBUF_BLOCK+1))==NULL) {
  2336.         LFREE(fbuf);
  2337.         printf("!");
  2338.         fseek(stream,-l,SEEK_CUR);
  2339.         return(NULL); }
  2340.     fbuf=p;
  2341.     printf(">");
  2342.     }
  2343. printf(".");
  2344.  
  2345. fseek(stream,start+length,SEEK_SET);
  2346. return(fbuf);
  2347. }
  2348.  
  2349. #endif
  2350.  
  2351. #define MAX_TAILLEN 1024
  2352.  
  2353. /****************************************************************************/
  2354. /* Coverts a FidoNet message into a Synchronet message                        */
  2355. /* Returns 1 on success, 0 on failure, -1 on dupe.                            */
  2356. /****************************************************************************/
  2357. int fmsgtosmsg(uchar HUGE16 *fbuf, fmsghdr_t fmsghdr, uint user, uint subnum)
  2358. {
  2359.     uchar    ch,HUGE16 *sbody,HUGE16 *stail,HUGE16 *outbuf
  2360.             ,done,col,esc,cr,*p,str[128];
  2361.     int     i,chunk,lzh=0,storage;
  2362.     ushort    xlat,net;
  2363.     ulong    l,m,length,lzhlen,bodylen,taillen,crc;
  2364.     faddr_t faddr,origaddr,destaddr;
  2365.     smbmsg_t    msg;
  2366.     smb_t    *smbfile;
  2367.  
  2368. memset(&msg,0,sizeof(smbmsg_t));
  2369. memcpy(msg.hdr.id,"SHD\x1a",4);
  2370. msg.hdr.version=SMB_VERSION;
  2371. if(fmsghdr.attr&FIDO_PRIVATE)
  2372.     msg.idx.attr|=MSG_PRIVATE;
  2373. msg.hdr.attr=msg.idx.attr;
  2374.  
  2375. if(fmsghdr.attr&FIDO_FILE)
  2376.     msg.hdr.auxattr|=MSG_FILEATTACH;
  2377.  
  2378. msg.hdr.when_imported.time=time(NULL);
  2379. msg.hdr.when_imported.zone=sys_timezone;
  2380. msg.hdr.when_written.time=fmsgtime(fmsghdr.time);
  2381.  
  2382. origaddr.zone=fmsghdr.origzone;     /* only valid if NetMail */
  2383. origaddr.net=fmsghdr.orignet;
  2384. origaddr.node=fmsghdr.orignode;
  2385. origaddr.point=fmsghdr.origpoint;
  2386.  
  2387. destaddr.zone=fmsghdr.destzone;     /* only valid if NetMail */
  2388. destaddr.net=fmsghdr.destnet;
  2389. destaddr.node=fmsghdr.destnode;
  2390. destaddr.point=fmsghdr.destpoint;
  2391.  
  2392. smb_hfield(&msg,SENDER,strlen(fmsghdr.from),fmsghdr.from);
  2393. strlwr(fmsghdr.from);
  2394. if(subnum==INVALID_SUB)
  2395.     msg.idx.from=0;
  2396. else
  2397.     msg.idx.from=crc16(fmsghdr.from);
  2398.  
  2399. smb_hfield(&msg,RECIPIENT,strlen(fmsghdr.to),fmsghdr.to);
  2400. strlwr(fmsghdr.to);
  2401. msg.idx.to=crc16(fmsghdr.to);
  2402.  
  2403. if(user) {
  2404.     sprintf(str,"%u",user);
  2405.     smb_hfield(&msg,RECIPIENTEXT,strlen(str),str);
  2406.     msg.idx.to=user; }
  2407.  
  2408. smb_hfield(&msg,SUBJECT,strlen(fmsghdr.subj),fmsghdr.subj);
  2409. remove_re(fmsghdr.subj);
  2410. strlwr(fmsghdr.subj);
  2411. msg.idx.subj=crc16(fmsghdr.subj);
  2412. if(fbuf==NULL) {
  2413.     printf("ERROR allocating fbuf\n");
  2414.     logprintf("ERROR line %d allocating fbuf",__LINE__);
  2415.     smb_freemsgmem(&msg);
  2416.     return(0); }
  2417. length=strlen((char *)fbuf);
  2418. if((sbody=(char HUGE16 *)LMALLOC((length+1)*2))==NULL) {
  2419.     printf("ERROR allocating %lu bytes for body",(length+1)*2L);
  2420.     logprintf("ERROR line %d allocating %lu bytes for body",__LINE__
  2421.         ,(length+1)*2L);
  2422.     smb_freemsgmem(&msg);
  2423.     return(0); }
  2424. if((stail=(char HUGE16 *)LMALLOC(MAX_TAILLEN))==NULL) {
  2425.     printf("ERROR allocating %lu bytes\n",MAX_TAILLEN);
  2426.     logprintf("ERROR line %d allocating %lu bytes for tail",__LINE__
  2427.         ,MAX_TAILLEN);
  2428.     LFREE(sbody);
  2429.     smb_freemsgmem(&msg);
  2430.     return(0); }
  2431.  
  2432. for(col=l=esc=done=bodylen=taillen=0,cr=1;l<length;l++) {
  2433.  
  2434.     if(!l && !strncmp((char *)fbuf,"AREA:",5)) {
  2435.         l+=5;
  2436.         while(l<length && fbuf[l]<=SP) l++;
  2437.         m=l;
  2438.         while(m<length && fbuf[m]!=CR) m++;
  2439.         while(m && fbuf[m-1]<=SP) m--;
  2440.         if(m>l)
  2441.             smb_hfield(&msg,FIDOAREA,m-l,fbuf+l);
  2442.         while(l<length && fbuf[l]!=CR) l++;
  2443.         continue; }
  2444.  
  2445.     ch=fbuf[l];
  2446.     if(ch==1 && cr) {    /* kludge line */
  2447.  
  2448.         if(!strncmp((char *)fbuf+l+1,"TOPT ",5))
  2449.             destaddr.point=atoi((char *)fbuf+l+6);
  2450.  
  2451.         else if(!strncmp((char *)fbuf+l+1,"FMPT ",5))
  2452.             origaddr.point=atoi((char *)fbuf+l+6);
  2453.  
  2454.         else if(!strncmp((char *)fbuf+l+1,"INTL ",5)) {
  2455.             faddr=atofaddr((char *)fbuf+l+6);
  2456.             destaddr.zone=faddr.zone;
  2457.             destaddr.net=faddr.net;
  2458.             destaddr.node=faddr.node;
  2459.             l+=6;
  2460.             while(l<length && fbuf[l]!=SP) l++;
  2461.             faddr=atofaddr((char *)fbuf+l+1);
  2462.             origaddr.zone=faddr.zone;
  2463.             origaddr.net=faddr.net;
  2464.             origaddr.node=faddr.node; }
  2465.  
  2466.         else if(!strncmp((char *)fbuf+l+1,"MSGID:",6)) {
  2467.             l+=7;
  2468.             while(l<length && fbuf[l]<=SP) l++;
  2469.             m=l;
  2470.             while(m<length && fbuf[m]!=CR) m++;
  2471.             while(m && fbuf[m-1]<=SP) m--;
  2472.             if(m>l)
  2473.                 smb_hfield(&msg,FIDOMSGID,m-l,fbuf+l); }
  2474.  
  2475.         else if(!strncmp((char *)fbuf+l+1,"REPLY:",6)) {
  2476.             l+=7;
  2477.             while(l<length && fbuf[l]<=SP) l++;
  2478.             m=l;
  2479.             while(m<length && fbuf[m]!=CR) m++;
  2480.             while(m && fbuf[m-1]<=SP) m--;
  2481.             if(m>l)
  2482.                 smb_hfield(&msg,FIDOREPLYID,m-l,fbuf+l); }
  2483.  
  2484.         else if(!strncmp((char *)fbuf+l+1,"FLAGS:",6)) {
  2485.             l+=7;
  2486.             while(l<length && fbuf[l]<=SP) l++;
  2487.             m=l;
  2488.             while(m<length && fbuf[m]!=CR) m++;
  2489.             while(m && fbuf[m-1]<=SP) m--;
  2490.             if(m>l)
  2491.                 smb_hfield(&msg,FIDOFLAGS,m-l,fbuf+l); }
  2492.  
  2493.         else if(!strncmp((char *)fbuf+l+1,"PATH:",5)) {
  2494.             l+=6;
  2495.             while(l<length && fbuf[l]<=SP) l++;
  2496.             m=l;
  2497.             while(m<length && fbuf[m]!=CR) m++;
  2498.             while(m && fbuf[m-1]<=SP) m--;
  2499.             if(m>l && misc&STORE_PATH)
  2500.                 smb_hfield(&msg,FIDOPATH,m-l,fbuf+l); }
  2501.  
  2502.         else if(!strncmp((char *)fbuf+l+1,"PID:",4)) {
  2503.             l+=5;
  2504.             while(l<length && fbuf[l]<=SP) l++;
  2505.             m=l;
  2506.             while(m<length && fbuf[m]!=CR) m++;
  2507.             while(m && fbuf[m-1]<=SP) m--;
  2508.             if(m>l)
  2509.                 smb_hfield(&msg,FIDOPID,m-l,fbuf+l); }
  2510.  
  2511.         else {        /* Unknown kludge line */
  2512.             while(l<length && fbuf[l]<=SP) l++;
  2513.             m=l;
  2514.             while(m<length && fbuf[m]!=CR) m++;
  2515.             while(m && fbuf[m-1]<=SP) m--;
  2516.             if(m>l && misc&STORE_KLUDGE)
  2517.                 smb_hfield(&msg,FIDOCTRL,m-l,fbuf+l); }
  2518.  
  2519.         while(l<length && fbuf[l]!=CR) l++;
  2520.         continue; }
  2521.  
  2522.     if(ch!=LF && ch!=0x8d) {    /* ignore LF and soft CRs */
  2523.         if(cr && (!strncmp((char *)fbuf+l,"--- ",4)
  2524.             || !strncmp((char *)fbuf+l,"---\r",4)))
  2525.             done=1;             /* tear line and down go into tail */
  2526.         if(done && cr && !strncmp((char *)fbuf+l,"SEEN-BY:",8)) {
  2527.             l+=8;
  2528.             while(l<length && fbuf[l]<=SP) l++;
  2529.             m=l;
  2530.             while(m<length && fbuf[m]!=CR) m++;
  2531.             while(m && fbuf[m-1]<=SP) m--;
  2532.             if(m>l && misc&STORE_SEENBY)
  2533.                 smb_hfield(&msg,FIDOSEENBY,m-l,fbuf+l);
  2534.             while(l<length && fbuf[l]!=CR) l++;
  2535.             continue; }
  2536.         if(done) {
  2537.             if(taillen<MAX_TAILLEN)
  2538.                 stail[taillen++]=ch; }
  2539.         else
  2540.             sbody[bodylen++]=ch;
  2541.         col++;
  2542.         if(ch==CR) {
  2543.             cr=1;
  2544.             col=0;
  2545.             if(done) {
  2546.                 if(taillen<MAX_TAILLEN)
  2547.                     stail[taillen++]=LF; }
  2548.             else
  2549.                 sbody[bodylen++]=LF; }
  2550.         else {
  2551.             cr=0;
  2552.             if(col==1 && !strncmp((char *)fbuf+l," * Origin: ",11)) {
  2553.                 p=(char *)fbuf+l+11;
  2554.                 while(*p && *p!=CR) p++;     /* Find CR */
  2555.                 while(p && *p!='(') p--;     /* rewind to '(' */
  2556.                 if(p)
  2557.                     origaddr=atofaddr(p+1);     /* get orig address */
  2558.                 done=1; }
  2559.             if(done)
  2560.                 continue;
  2561.  
  2562.             if(ch==ESC) esc=1;        /* ANSI codes */
  2563.             if(ch==SP && col>40 && !esc) {    /* word wrap */
  2564.                 for(m=l+1;m<length;m++)     /* find next space */
  2565.                     if(fbuf[m]<=SP)
  2566.                         break;
  2567.                 if(m<length && m-l>80-col) {  /* if it's beyond the eol */
  2568.                     sbody[bodylen++]=CR;
  2569.                     sbody[bodylen++]=LF;
  2570.                     col=0; } }
  2571.             } } }
  2572.  
  2573. if(bodylen>=2 && sbody[bodylen-2]==CR && sbody[bodylen-1]==LF)
  2574.     bodylen-=2;                         /* remove last CRLF if present */
  2575.  
  2576. if(smb[cur_smb].status.max_crcs) {
  2577.     for(l=0,crc=0xffffffff;l<bodylen;l++)
  2578.         crc=ucrc32(sbody[l],crc);
  2579.     crc=~crc;
  2580.     i=smb_addcrc(&smb[cur_smb],crc);
  2581.     if(i) {
  2582.         if(i==1)
  2583.             printf("Duplicate ");
  2584.         else
  2585.             printf("smb_addcrc returned %d ",i);
  2586.         smb_freemsgmem(&msg);
  2587.         LFREE(sbody);
  2588.         LFREE(stail);
  2589.         if(i==1)
  2590.             return(-1);
  2591.         return(0); } }
  2592.  
  2593. while(taillen && stail[taillen-1]<=SP)    /* trim all garbage off the tail */
  2594.     taillen--;
  2595.  
  2596. if(!origaddr.zone && subnum==INVALID_SUB)
  2597.     net=NET_NONE;                        /* Message from SBBSecho */
  2598. else
  2599.     net=NET_FIDO;                        /* Record origin address */
  2600.  
  2601. if(net) {
  2602.     smb_hfield(&msg,SENDERNETTYPE,sizeof(ushort),&net);
  2603.     smb_hfield(&msg,SENDERNETADDR,sizeof(fidoaddr_t),&origaddr); }
  2604.  
  2605. if(subnum==INVALID_SUB) {
  2606.     smbfile=email;
  2607.     if(net) {
  2608.         smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(ushort),&net);
  2609.         smb_hfield(&msg,RECIPIENTNETADDR,sizeof(fidoaddr_t),&destaddr); } }
  2610. else
  2611.     smbfile=&smb[cur_smb];
  2612.  
  2613. if(subnum!=INVALID_SUB && sub[subnum]->misc&SUB_LZH
  2614.     && bodylen+2L+taillen+2L>=SDT_BLOCK_LEN && bodylen) {
  2615.     if((outbuf=(char *)LMALLOC(bodylen*2L))==NULL) {
  2616.         printf("ERROR allocating %lu bytes for lzh\n",bodylen*2);
  2617.         logprintf("ERROR line %d allocating %lu bytes for lzh",__LINE__
  2618.             ,bodylen*2);
  2619.         smb_freemsgmem(&msg);
  2620.         LFREE(sbody);
  2621.         LFREE(stail);
  2622.         return(0); }
  2623.     lzhlen=lzh_encode((uchar *)sbody,bodylen,(uchar *)outbuf);
  2624.     if(lzhlen>1 &&
  2625.         smb_datblocks(lzhlen+4L+taillen+2L)<
  2626.         smb_datblocks(bodylen+2L+taillen+2L)) {
  2627.         bodylen=lzhlen;     /* Compressable */
  2628.         l=bodylen+4;
  2629.         LFREE(sbody);
  2630.         lzh=1;
  2631.         sbody=outbuf; }
  2632.     else {                    /* Uncompressable */
  2633.         l=bodylen+2;
  2634.         LFREE(outbuf); } }
  2635. else
  2636.     l=bodylen+2;
  2637.  
  2638. if(taillen)
  2639.     l+=(taillen+2);
  2640.  
  2641. if(l&0xfff00000) {
  2642.     printf("ERROR checking msg len %lu\n",l);
  2643.     logprintf("ERROR line %d checking msg len %lu",__LINE__,l);
  2644.     smb_freemsgmem(&msg);
  2645.     LFREE(sbody);
  2646.     LFREE(stail);
  2647.     return(0); }
  2648.  
  2649. if(smbfile->status.attr&SMB_HYPERALLOC) {
  2650.     if((i=smb_locksmbhdr(smbfile))!=0) {
  2651.         printf("ERROR %d locking %s\n",i,smbfile->file);
  2652.         logprintf("ERROR %d line %d locking %s",i,__LINE__,smbfile->file);
  2653.         smb_freemsgmem(&msg);
  2654.         LFREE(sbody);
  2655.         LFREE(stail);
  2656.         return(0); }
  2657.     msg.hdr.offset=smb_hallocdat(smbfile);
  2658.     storage=SMB_HYPERALLOC; }
  2659. else {
  2660.     if((i=smb_open_da(smbfile))!=0) {
  2661.         smb_freemsgmem(&msg);
  2662.         printf("ERROR %d opening %s.SDA\n",i,smbfile->file);
  2663.         logprintf("ERROR %d line %d opening %s.SDA",i,__LINE__
  2664.             ,smbfile->file);
  2665.         LFREE(sbody);
  2666.         LFREE(stail);
  2667.         return(0); }
  2668.     if(subnum!=INVALID_SUB && sub[subnum]->misc&SUB_FAST) {
  2669.         msg.hdr.offset=smb_fallocdat(smbfile,l,1);
  2670.         storage=SMB_FASTALLOC; }
  2671.     else {
  2672.         msg.hdr.offset=smb_allocdat(smbfile,l,1);
  2673.         storage=SMB_SELFPACK; }
  2674.     smb_close_da(smbfile); }
  2675.  
  2676. if(msg.hdr.offset && msg.hdr.offset<1L) {
  2677.     if(smbfile->status.attr&SMB_HYPERALLOC)
  2678.         smb_unlocksmbhdr(smbfile);
  2679.     smb_freemsgmem(&msg);
  2680.     LFREE(sbody);
  2681.     LFREE(stail);
  2682.     printf("ERROR %ld allocating records\n",msg.hdr.offset);
  2683.     logprintf("ERROR line %d %ld allocating records",__LINE__,msg.hdr.offset);
  2684.     return(0); }
  2685. fseek(smbfile->sdt_fp,msg.hdr.offset,SEEK_SET);
  2686. if(lzh) {
  2687.     xlat=XLAT_LZH;
  2688.     fwrite(&xlat,2,1,smbfile->sdt_fp); }
  2689. xlat=XLAT_NONE;
  2690. fwrite(&xlat,2,1,smbfile->sdt_fp);
  2691. chunk=30000;
  2692. for(l=0;l<bodylen;l+=chunk) {
  2693.     if(l+chunk>bodylen)
  2694.         chunk=bodylen-l;
  2695.     fwrite(sbody+l,1,chunk,smbfile->sdt_fp); }
  2696. if(taillen) {
  2697.     fwrite(&xlat,2,1,smbfile->sdt_fp);
  2698.     fwrite(stail,1,taillen,smbfile->sdt_fp); }
  2699. LFREE(sbody);
  2700. LFREE(stail);
  2701. fflush(smbfile->sdt_fp);
  2702. if(smbfile->status.attr&SMB_HYPERALLOC)
  2703.     smb_unlocksmbhdr(smbfile);
  2704.  
  2705. if(lzh)
  2706.     bodylen+=2;
  2707. bodylen+=2;
  2708. smb_dfield(&msg,TEXT_BODY,bodylen);
  2709. if(taillen)
  2710.     smb_dfield(&msg,TEXT_TAIL,taillen+2);
  2711.  
  2712. i=smb_addmsghdr(smbfile,&msg,storage);
  2713. smb_freemsgmem(&msg);
  2714. if(i) {
  2715.     printf("ERROR smb_addmsghdr returned %d\n",i);
  2716.     logprintf("ERROR line %d smb_addmsghdr returned %d"
  2717.         ,__LINE__,i);
  2718.     return(0); }
  2719. return(1);
  2720. }
  2721.  
  2722. /***********************************************************************/
  2723. /* Get zone and point from kludge lines from the stream  if they exist */
  2724. /***********************************************************************/
  2725. void getzpt(FILE *stream, fmsghdr_t *hdr)
  2726. {
  2727.     char buf[0x1000];
  2728.     int i,len,cr=0;
  2729.     long pos;
  2730.     faddr_t faddr;
  2731.  
  2732. pos=ftell(stream);
  2733. len=fread(buf,1,0x1000,stream);
  2734. for(i=0;i<len;i++) {
  2735.     if((!i || cr) && buf[i]==1) {    /* kludge */
  2736.         if(!strncmp(buf+i+1,"TOPT ",5))
  2737.             hdr->destpoint=atoi(buf+i+6);
  2738.         else if(!strncmp(buf+i+1,"FMPT ",5))
  2739.             hdr->origpoint=atoi(buf+i+6);
  2740.         else if(!strncmp(buf+i+1,"INTL ",5)) {
  2741.             faddr=atofaddr(buf+i+6);
  2742.             hdr->destzone=faddr.zone;
  2743.             hdr->destnet=faddr.net;
  2744.             hdr->destnode=faddr.node;
  2745.             i+=6;
  2746.             while(buf[i] && buf[i]!=SP) i++;
  2747.             faddr=atofaddr(buf+i+1);
  2748.             hdr->origzone=faddr.zone;
  2749.             hdr->orignet=faddr.net;
  2750.             hdr->orignode=faddr.node; }
  2751.         while(i<len && buf[i]!=CR) i++;
  2752.         cr=1;
  2753.         continue; }
  2754.     if(buf[i]==CR)
  2755.         cr=1;
  2756.     else
  2757.         cr=0; }
  2758. fseek(stream,pos,SEEK_SET);
  2759. }
  2760. /******************************************************************************
  2761.  This function will seek to the next NULL found in stream
  2762. ******************************************************************************/
  2763. void seektonull(FILE *stream)
  2764. {
  2765.     char ch;
  2766.  
  2767. while(!feof(stream)) {
  2768.     if(!fread(&ch,1,1,stream))
  2769.         break;
  2770.     if(!ch)
  2771.         break; }
  2772.  
  2773. }
  2774.  
  2775. /******************************************************************************
  2776.  This function returns a packet name - used for outgoing packets
  2777. ******************************************************************************/
  2778. char *pktname(void)
  2779. {
  2780.     static char str[128];
  2781.     int i;
  2782.     time_t now;
  2783.     struct tm *tm;
  2784.  
  2785. now=time(NULL);
  2786. for(i=0;i<MAX_TOTAL_PKTS*2;i++) {
  2787.     now+=i;
  2788.     tm=gmtime(&now);
  2789.     sprintf(str,"%s%02u%02u%02u%02u.PK_",cfg.outbound,tm->tm_mday,tm->tm_hour
  2790.         ,tm->tm_min,tm->tm_sec);
  2791.     if(!fexist(str))                /* Add 1 second if name exists */
  2792.         break; }
  2793. return(str);
  2794. }
  2795. /******************************************************************************
  2796.  This function puts a message into a Fido packet, writing both the header
  2797.  information and the message body
  2798. ******************************************************************************/
  2799. void putfmsg(FILE *stream,uchar HUGE16 *fbuf,fmsghdr_t fmsghdr,areasbbs_t area
  2800.     ,addrlist_t seenbys,addrlist_t paths)
  2801. {
  2802.     char str[256],seenby[256],*p;
  2803.     short i,j,lastlen=0,net_exists=0;
  2804.     faddr_t addr,sysaddr;
  2805.  
  2806. addr=getsysfaddr(fmsghdr.destzone);
  2807.  
  2808. i=0x0002;
  2809. fwrite(&i,2,1,stream);
  2810. fwrite(&addr.node,2,1,stream);
  2811. fwrite(&fmsghdr.destnode,2,1,stream);
  2812. fwrite(&addr.net,2,1,stream);
  2813. fwrite(&fmsghdr.destnet,2,1,stream);
  2814. fwrite(&fmsghdr.attr,2,1,stream);
  2815. fwrite(&fmsghdr.cost,2,1,stream);
  2816. fwrite(fmsghdr.time,strlen(fmsghdr.time)+1,1,stream);
  2817. fwrite(fmsghdr.to,strlen(fmsghdr.to)+1,1,stream);
  2818. fwrite(fmsghdr.from,strlen(fmsghdr.from)+1,1,stream);
  2819. fwrite(fmsghdr.subj,strlen(fmsghdr.subj)+1,1,stream);
  2820. if(area.name)
  2821.     if(strncmp((char *)fbuf,"AREA:",5))                     /* No AREA: Line */
  2822.         fprintf(stream,"AREA:%s\r",area.name);              /* So add one */
  2823. fwrite(fbuf,strlen((char *)fbuf),1,stream);
  2824. lastlen=9;
  2825. if(fbuf[strlen((char *)fbuf)-1]!=CR)
  2826.     fputc(CR,stream);
  2827.  
  2828. if(area.name && addr.zone!=fmsghdr.destzone)    /* Zone Gate */
  2829.     fprintf(stream,"SEEN-BY: %d/%d\r",fmsghdr.destnet,fmsghdr.destnode);
  2830.  
  2831. if(area.name && addr.zone==fmsghdr.destzone) {    /* Not NetMail */
  2832.     fprintf(stream,"SEEN-BY:");
  2833.     for(i=0;i<seenbys.addrs;i++) {              /* Put back original SEEN-BYs */
  2834.         strcpy(seenby," ");
  2835.         if(seenbys.addr[i].zone!=addr.zone)
  2836.             continue;
  2837.         if(seenbys.addr[i].net!=addr.net || !net_exists) {
  2838.             net_exists=1;
  2839.             addr.net=seenbys.addr[i].net;
  2840.             sprintf(str,"%d/",addr.net);
  2841.             strcat(seenby,str); }
  2842.         sprintf(str,"%d",seenbys.addr[i].node);
  2843.         strcat(seenby,str);
  2844.         if(lastlen+strlen(seenby)<80) {
  2845.             fwrite(seenby,strlen(seenby),1,stream);
  2846.             lastlen+=strlen(seenby); }
  2847.         else {
  2848.             --i;
  2849.             lastlen=9; /* +strlen(seenby); */
  2850.             net_exists=0;
  2851.             fprintf(stream,"\rSEEN-BY:"); } }
  2852.  
  2853.     for(i=0;i<area.uplinks;i++) {            /* Add all uplinks to SEEN-BYs */
  2854.         strcpy(seenby," ");
  2855.         if(area.uplink[i].zone!=addr.zone || area.uplink[i].point)
  2856.             continue;
  2857.         for(j=0;j<seenbys.addrs;j++)
  2858.             if(!memcmp(&area.uplink[i],&seenbys.addr[j],sizeof(faddr_t)))
  2859.                 break;
  2860.         if(j==seenbys.addrs) {
  2861.             if(area.uplink[i].net!=addr.net || !net_exists) {
  2862.                 net_exists=1;
  2863.                 addr.net=area.uplink[i].net;
  2864.                 sprintf(str,"%d/",addr.net);
  2865.                 strcat(seenby,str); }
  2866.             sprintf(str,"%d",area.uplink[i].node);
  2867.             strcat(seenby,str);
  2868.             if(lastlen+strlen(seenby)<80) {
  2869.                 fwrite(seenby,strlen(seenby),1,stream);
  2870.                 lastlen+=strlen(seenby); }
  2871.             else {
  2872.                 --i;
  2873.                 lastlen=9; /* +strlen(seenby); */
  2874.                 net_exists=0;
  2875.                 fprintf(stream,"\rSEEN-BY:"); } } }
  2876.  
  2877.     for(i=0;i<total_faddrs;i++) {                /* Add AKAs to SEEN-BYs */
  2878.         strcpy(seenby," ");
  2879.         if(faddr[i].zone!=addr.zone || faddr[i].point)
  2880.             continue;
  2881.         for(j=0;j<seenbys.addrs;j++)
  2882.             if(!memcmp(&faddr[i],&seenbys.addr[j],sizeof(faddr_t)))
  2883.                 break;
  2884.         if(j==seenbys.addrs) {
  2885.             if(faddr[i].net!=addr.net || !net_exists) {
  2886.                 net_exists=1;
  2887.                 addr.net=faddr[i].net;
  2888.                 sprintf(str,"%d/",addr.net);
  2889.                 strcat(seenby,str); }
  2890.             sprintf(str,"%d",faddr[i].node);
  2891.             strcat(seenby,str);
  2892.             if(lastlen+strlen(seenby)<80) {
  2893.                 fwrite(seenby,strlen(seenby),1,stream);
  2894.                 lastlen+=strlen(seenby); }
  2895.             else {
  2896.                 --i;
  2897.                 lastlen=9; /* +strlen(seenby); */
  2898.                 net_exists=0;
  2899.                 fprintf(stream,"\rSEEN-BY:"); } } }
  2900.  
  2901.     lastlen=7;
  2902.     net_exists=0;
  2903.     fprintf(stream,"\r\1PATH:");
  2904.     addr=getsysfaddr(fmsghdr.destzone);
  2905.     for(i=0;i<paths.addrs;i++) {              /* Put back the original PATH */
  2906.         strcpy(seenby," ");
  2907.         if(paths.addr[i].zone!=addr.zone || paths.addr[i].point)
  2908.             continue;
  2909.         if(paths.addr[i].net!=addr.net || !net_exists) {
  2910.             net_exists=1;
  2911.             addr.net=paths.addr[i].net;
  2912.             sprintf(str,"%d/",addr.net);
  2913.             strcat(seenby,str); }
  2914.         sprintf(str,"%d",paths.addr[i].node);
  2915.         strcat(seenby,str);
  2916.         if(lastlen+strlen(seenby)<80) {
  2917.             fwrite(seenby,strlen(seenby),1,stream);
  2918.             lastlen+=strlen(seenby); }
  2919.         else {
  2920.             --i;
  2921.             lastlen=7; /* +strlen(seenby); */
  2922.             net_exists=0;
  2923.             fprintf(stream,"\r\1PATH:"); } }
  2924.  
  2925.     strcpy(seenby," ");         /* Add first address with same zone to PATH */
  2926.     sysaddr=getsysfaddr(fmsghdr.destzone);
  2927.     if(!sysaddr.point) {
  2928.         if(sysaddr.net!=addr.net || !net_exists) {
  2929.             net_exists=1;
  2930.             addr.net=sysaddr.net;
  2931.             sprintf(str,"%d/",addr.net);
  2932.             strcat(seenby,str); }
  2933.         sprintf(str,"%d",sysaddr.node);
  2934.         strcat(seenby,str);
  2935.         if(lastlen+strlen(seenby)<80)
  2936.             fwrite(seenby,strlen(seenby),1,stream);
  2937.         else {
  2938.             fprintf(stream,"\r\1PATH:");
  2939.             fwrite(seenby,strlen(seenby),1,stream); } }
  2940.  
  2941.     fputc(CR,stream); }
  2942.  
  2943. fputc(0,stream);
  2944. }
  2945.  
  2946. /******************************************************************************
  2947.  This function creates a binary list of the message seen-bys and path from
  2948.  inbuf.
  2949. ******************************************************************************/
  2950. void gen_psb(addrlist_t *seenbys,addrlist_t *paths,char HUGE16 *inbuf
  2951.     ,ushort zone)
  2952. {
  2953.     char str[128],seenby[256],*p,*p1,*p2,HUGE16 *fbuf;
  2954.     int i,j,len;
  2955.     faddr_t addr;
  2956.  
  2957. if(!inbuf)
  2958.     return;
  2959. fbuf=strstr((char *)inbuf,"\r * Origin: ");
  2960. if(!fbuf)
  2961. fbuf=strstr((char *)inbuf,"\n * Origin: ");
  2962. if(!fbuf)
  2963.     fbuf=inbuf;
  2964. if(seenbys->addr) {
  2965.     FREE(seenbys->addr);
  2966.     seenbys->addr=0;
  2967.     seenbys->addrs=0; }
  2968. addr.zone=addr.net=addr.node=addr.point=seenbys->addrs=0;
  2969. p=strstr((char *)fbuf,"\rSEEN-BY:");
  2970. if(!p) p=strstr((char *)fbuf,"\nSEEN-BY:");
  2971. if(p) {
  2972.     while(1) {
  2973.         sprintf(str,"%-.100s",p+10);
  2974.         if((p1=strchr(str,CR))!=NULL)
  2975.             *p1=0;
  2976.         p1=str;
  2977.         i=j=0;
  2978.         len=strlen(str);
  2979.         while(i<len) {
  2980.             j=i;
  2981.             while(i<len && *(p1+i)!=SP)
  2982.                 ++i;
  2983.             if(j>len)
  2984.                 break;
  2985.             sprintf(seenby,"%-.*s",(i-j),p1+j);
  2986.             if((p2=strchr(seenby,':'))!=NULL) {
  2987.                 addr.zone=atoi(seenby);
  2988.                 addr.net=atoi(p2+1); }
  2989.             else if((p2=strchr(seenby,'/'))!=NULL)
  2990.                 addr.net=atoi(seenby);
  2991.             if((p2=strchr(seenby,'/'))!=NULL)
  2992.                 addr.node=atoi(p2+1);
  2993.             else
  2994.                 addr.node=atoi(seenby);
  2995.             if((p2=strchr(seenby,'.'))!=NULL)
  2996.                 addr.point=atoi(p2+1);
  2997.             if(!addr.zone)
  2998.                 addr.zone=zone;         /* Was 1 */
  2999.             if((seenbys->addr=(faddr_t *)REALLOC(seenbys->addr
  3000.                 ,sizeof(faddr_t)*(seenbys->addrs+1)))==NULL) {
  3001.                 printf("ERROR allocating memory for seenbys\n");
  3002.                 logprintf("ERROR line %d allocating memory for message "
  3003.                     "seenbys.",__LINE__);
  3004.                 exit(1); }
  3005.             memcpy(&seenbys->addr[seenbys->addrs],&addr,sizeof(faddr_t));
  3006.             seenbys->addrs++;
  3007.             ++i; }
  3008.         p1=strstr(p+10,"\rSEEN-BY:");
  3009.         if(!p1)
  3010.             p1=strstr(p+10,"\nSEEN-BY:");
  3011.         if(!p1)
  3012.             break;
  3013.         p=p1; } }
  3014. else {
  3015.     if((seenbys->addr=(faddr_t *)REALLOC(seenbys->addr
  3016.         ,sizeof(faddr_t)))==NULL) {
  3017.         printf("ERROR allocating memory for seenbys\n");
  3018.         logprintf("ERROR line %d allocating memory for message seenbys."
  3019.             ,__LINE__);
  3020.         exit(1); }
  3021.     memset(&seenbys->addr[0],0,sizeof(faddr_t)); }
  3022.  
  3023. if(paths->addr) {
  3024.     FREE(paths->addr);
  3025.     paths->addr=0;
  3026.     paths->addrs=0; }
  3027. addr.zone=addr.net=addr.node=addr.point=paths->addrs=0;
  3028. if((p=strstr((char *)fbuf,"\1PATH:"))!=NULL) {
  3029.     while(1) {
  3030.         sprintf(str,"%-.100s",p+7);
  3031.         if((p1=strchr(str,CR))!=NULL)
  3032.             *p1=0;
  3033.         p1=str;
  3034.         i=j=0;
  3035.         len=strlen(str);
  3036.         while(i<len) {
  3037.             j=i;
  3038.             while(i<len && *(p1+i)!=SP)
  3039.                 ++i;
  3040.             if(j>len)
  3041.                 break;
  3042.             sprintf(seenby,"%-.*s",(i-j),p1+j);
  3043.             if((p2=strchr(seenby,':'))!=NULL) {
  3044.                 addr.zone=atoi(seenby);
  3045.                 addr.net=atoi(p2+1); }
  3046.             else if((p2=strchr(seenby,'/'))!=NULL)
  3047.                 addr.net=atoi(seenby);
  3048.             if((p2=strchr(seenby,'/'))!=NULL)
  3049.                 addr.node=atoi(p2+1);
  3050.             else
  3051.                 addr.node=atoi(seenby);
  3052.             if((p2=strchr(seenby,'.'))!=NULL)
  3053.                 addr.point=atoi(p2+1);
  3054.             if(!addr.zone)
  3055.                 addr.zone=zone;         /* Was 1 */
  3056.             if((paths->addr=(faddr_t *)REALLOC(paths->addr
  3057.                 ,sizeof(faddr_t)*(paths->addrs+1)))==NULL) {
  3058.                 printf("ERROR allocating memory for paths\n");
  3059.                 logprintf("ERROR line %d allocating memory for message "
  3060.                     "paths.",__LINE__);
  3061.                 exit(1); }
  3062.             memcpy(&paths->addr[paths->addrs],&addr,sizeof(faddr_t));
  3063.             paths->addrs++;
  3064.             ++i; }
  3065.         if((p1=strstr(p+7,"\1PATH:"))==NULL)
  3066.             break;
  3067.         p=p1; } }
  3068. else {
  3069.     if((paths->addr=(faddr_t *)REALLOC(paths->addr
  3070.         ,sizeof(faddr_t)))==NULL) {
  3071.         printf("ERROR allocating memory for paths\n");
  3072.         logprintf("ERROR line %d allocating memory for message paths."
  3073.             ,__LINE__);
  3074.         exit(1); }
  3075.     memset(&paths->addr[0],0,sizeof(faddr_t)); }
  3076. }
  3077.  
  3078. /******************************************************************************
  3079.  This function takes the addrs passed to it and compares them to the address
  3080.  passed in inaddr.    1 is returned if inaddr matches any of the addrs
  3081.  otherwise a 0 is returned.
  3082. ******************************************************************************/
  3083. char check_psb(addrlist_t addrlist,faddr_t inaddr)
  3084. {
  3085.     int i;
  3086.  
  3087. for(i=0;i<addrlist.addrs;i++) {
  3088.     if(!memcmp(&addrlist.addr[i],&inaddr,sizeof(faddr_t)))
  3089.         return(1); }
  3090. return(0);
  3091. }
  3092. /******************************************************************************
  3093.  This function strips the message seen-bys and path from inbuf.
  3094. ******************************************************************************/
  3095. void strip_psb(char HUGE16 *inbuf)
  3096. {
  3097.     char *p,HUGE16 *fbuf;
  3098.  
  3099. if(!inbuf)
  3100.     return;
  3101. fbuf=strstr((char *)inbuf,"\r * Origin: ");
  3102. if(!fbuf)
  3103.     fbuf=inbuf;
  3104. if((p=strstr((char *)fbuf,"\rSEEN-BY:"))!=NULL)
  3105.     *(p)=0;
  3106. if((p=strstr((char *)fbuf,"\r\1PATH:"))!=NULL)
  3107.     *(p)=0;
  3108. }
  3109. void attach_bundles()
  3110. {
  3111.     FILE *fidomsg;
  3112.     char str[1025],path[512],packet[128];
  3113.     int fmsg;
  3114.     ulong l;
  3115.     faddr_t pkt_faddr;
  3116.     pkthdr_t pkthdr;
  3117.     struct find_t ff;
  3118.  
  3119. sprintf(path,"%s*.PK_",cfg.outbound);
  3120. for(l=_dos_findfirst(path,0,&ff);!l && !kbhit();l=_dos_findnext(&ff)) {
  3121.     sprintf(packet,"%s%s",cfg.outbound,ff.name);
  3122.     printf("%21s: %s ","Outbound Packet",packet);
  3123.     if((fmsg=sopen(packet,O_RDWR,SH_DENYRW))==-1) {
  3124.         printf("ERROR opening.\n");
  3125.         logprintf("ERROR line %d opening %s",__LINE__,packet);
  3126.         continue; }
  3127.     if((fidomsg=fdopen(fmsg,"r+b"))==NULL) {
  3128.         close(fmsg);
  3129.         printf("\7ERROR fdopening.\n");
  3130.         logprintf("ERROR line %d fdopening %s",__LINE__,packet);
  3131.         continue; }
  3132.     if(filelength(fmsg)<sizeof(pkthdr_t)) {
  3133.         printf("ERROR invalid length of %u bytes for %s\n",filelength(fmsg)
  3134.             ,packet);
  3135.         logprintf("ERROR line %d invalid length of %u bytes for %s"
  3136.             ,__LINE__,filelength(fmsg),packet);
  3137.         fclose(fidomsg);
  3138.         if(delfile(packet))
  3139.             logprintf("ERROR line %d removing %s %s",__LINE__,packet
  3140.                 ,sys_errlist[errno]);
  3141.         continue; }
  3142.     if(fread(&pkthdr,sizeof(pkthdr_t),1,fidomsg)!=1) {
  3143.         fclose(fidomsg);
  3144.         printf("\7ERROR reading %u bytes from %s\n",sizeof(pkthdr_t),packet);
  3145.         logprintf("ERROR line %d reading %u bytes from %s",__LINE__
  3146.             ,sizeof(pkthdr_t),packet);
  3147.         continue; }
  3148.     fseek(fidomsg,-2L,SEEK_END);
  3149.     fread(str,2,1,fidomsg);
  3150.     fclose(fidomsg);
  3151.     if(!str[0] && !str[1]) {    /* Check for two nulls at end of packet */
  3152.         pkt_faddr.zone=pkthdr.destzone;
  3153.         pkt_faddr.net=pkthdr.destnet;
  3154.         pkt_faddr.node=pkthdr.destnode;
  3155.         pkt_faddr.point=0;                /* No point info in the 2.0 hdr! */
  3156.         memcpy(&two_plus,&pkthdr.empty,20);
  3157.         if(two_plus.cword==_rotr(two_plus.cwcopy,8)  /* 2+ Packet Header */
  3158.             && two_plus.cword && two_plus.cword&1)
  3159.             pkt_faddr.point=two_plus.destpoint;
  3160.         else if(pkthdr.baud==2) {                /* Type 2.2 Packet Header */
  3161.             memcpy(&two_two,&pkthdr.empty,20);
  3162.             pkt_faddr.point=pkthdr.month; }
  3163.         printf("Sending to %s\n",faddrtoa(pkt_faddr));
  3164.         pack_bundle(packet,pkt_faddr); }
  3165.     else {
  3166.         fclose(fidomsg);
  3167.         printf("Possibly still in use\n"); } }
  3168. #ifdef __WATCOMC__
  3169. _dos_findclose(&ff);
  3170. #endif
  3171. }
  3172. /******************************************************************************
  3173.  This is where we put outgoing messages into packets.  Set the 'cleanup'
  3174.  parameter to 1 to force all the remaining packets closed and stuff them into
  3175.  a bundle.
  3176. ******************************************************************************/
  3177. void pkt_to_pkt(uchar HUGE16 *fbuf,areasbbs_t area,faddr_t faddr
  3178.     ,fmsghdr_t fmsghdr,addrlist_t seenbys,addrlist_t paths,char cleanup)
  3179. {
  3180.     int i,j,k,file;
  3181.     short node;
  3182.     time_t now;
  3183.     struct tm *tm;
  3184.     pkthdr_t pkthdr;
  3185.     static ushort openpkts,totalpkts;
  3186.     static outpkt_t outpkt[MAX_TOTAL_PKTS];
  3187.     faddr_t sysaddr;
  3188.     two_two_t two;
  3189.     two_plus_t two_p;
  3190.  
  3191.  
  3192. if(cleanup==1) {
  3193.     for(i=0;i<totalpkts;i++) {
  3194.         if(outpkt[i].curopen) {
  3195.             fputc(0,outpkt[i].stream);
  3196.             fputc(0,outpkt[i].stream);
  3197.             fclose(outpkt[i].stream); }
  3198.         else {
  3199.             if((outpkt[i].stream=fnopen(&file,outpkt[i].filename
  3200.                 ,O_WRONLY|O_APPEND))==NULL) {
  3201.                 printf("ERROR opening %s for write.\n",outpkt[i].filename);
  3202.                 logprintf("ERROR line %d opening %s %s",__LINE__
  3203.                     ,outpkt[i].filename,sys_errlist[errno]);
  3204.                 continue; }
  3205.             fputc(0,outpkt[i].stream);
  3206.             fputc(0,outpkt[i].stream);
  3207.             fclose(outpkt[i].stream); }
  3208. //          pack_bundle(outpkt[i].filename,outpkt[i].uplink);
  3209.         memset(&outpkt[i],0,sizeof(outpkt_t)); }
  3210.     totalpkts=openpkts=0;
  3211.     attach_bundles();
  3212.     attachment(0,faddr,1);
  3213.     return; }
  3214.  
  3215. if(fbuf==NULL) {
  3216.     printf("ERROR allocating fbuf\n");
  3217.     logprintf("ERROR line %d allocating fbuf",__LINE__);
  3218.     return; }
  3219. /* We want to see if there's already a packet open for this area.   */
  3220. /* If not, we'll open a new one.  Once we have a packet, we'll add  */
  3221. /* messages to it as they come in.    If necessary, we'll close an    */
  3222. /* open packet to open a new one.                                    */
  3223.  
  3224. for(j=0;j<area.uplinks;j++) {
  3225.     if((cleanup==2 && memcmp(&faddr,&area.uplink[j],sizeof(faddr_t))) ||
  3226.         (!cleanup && (!memcmp(&faddr,&area.uplink[j],sizeof(faddr_t)) ||
  3227.         check_psb(seenbys,area.uplink[j]))))
  3228.         continue;
  3229.     node=matchnode(area.uplink[j],0);
  3230.     if(node<cfg.nodecfgs && cfg.nodecfg[node].attr&ATTR_PASSIVE)
  3231.         continue;
  3232.     sysaddr=getsysfaddr(area.uplink[j].zone);
  3233.     printf("%s ",faddrtoa(area.uplink[j]));
  3234.     for(i=0;i<totalpkts;i++) {
  3235.         if(!memcmp(&area.uplink[j],&outpkt[i].uplink,sizeof(faddr_t))) {
  3236.             if(!outpkt[i].curopen) {
  3237.                 if(openpkts==DFLT_OPEN_PKTS)
  3238.                     for(k=0;k<totalpkts;k++) {
  3239.                         if(outpkt[k].curopen) {
  3240.                             fclose(outpkt[k].stream);
  3241.                             outpkt[k].curopen=0;
  3242.                             break; } }
  3243.                 if((outpkt[i].stream=fnopen(&file,outpkt[i].filename
  3244.                     ,O_WRONLY|O_APPEND))==NULL) {
  3245.                     printf("Unable to open %s for write.\n"
  3246.                         ,outpkt[i].filename);
  3247.                     logprintf("ERROR line %d opening %s %s",__LINE__
  3248.                         ,outpkt[i].filename,sys_errlist[errno]);
  3249.                     exit(1); }
  3250.                 outpkt[i].curopen=1; }
  3251.             if((strlen((char *)fbuf)+1+ftell(outpkt[i].stream))
  3252.                 <=cfg.maxpktsize) {
  3253.                 fmsghdr.destnode=area.uplink[j].node;
  3254.                 fmsghdr.destnet=area.uplink[j].net;
  3255.                 fmsghdr.destzone=area.uplink[j].zone;
  3256.                 putfmsg(outpkt[i].stream,fbuf,fmsghdr,area,seenbys,paths); }
  3257.             else {
  3258.                 fputc(0,outpkt[i].stream);
  3259.                 fputc(0,outpkt[i].stream);
  3260.                 fclose(outpkt[i].stream);
  3261. //                  pack_bundle(outpkt[i].filename,outpkt[i].uplink);
  3262.                 outpkt[i].stream=outpkt[totalpkts-1].stream;
  3263.                 memcpy(&outpkt[i],&outpkt[totalpkts-1],sizeof(outpkt_t));
  3264.                 memset(&outpkt[totalpkts-1],0,sizeof(outpkt_t));
  3265.                 --totalpkts;
  3266.                 --openpkts;
  3267.                 i=totalpkts; }
  3268.             break; } }
  3269.         if(i==totalpkts) {
  3270.             if(openpkts==DFLT_OPEN_PKTS)
  3271.                 for(k=0;k<totalpkts;k++) {
  3272.                     if(outpkt[k].curopen) {
  3273.                         fclose(outpkt[k].stream);
  3274.                         outpkt[k].curopen=0;
  3275.                         --openpkts;
  3276.                         break; } }
  3277.             strcpy(outpkt[i].filename,pktname());
  3278.             now=time(NULL);
  3279.             tm=gmtime(&now);
  3280.             if((outpkt[i].stream=fnopen(&file,outpkt[i].filename
  3281.                 ,O_WRONLY|O_CREAT))==NULL) {
  3282.                 printf("Unable to open %s for write.\n"
  3283.                     ,outpkt[i].filename);
  3284.                 logprintf("ERROR line %d opening %s %s"
  3285.                     ,__LINE__,outpkt[i].filename,sys_errlist[errno]);
  3286.                 exit(1); }
  3287.             pkthdr.orignode=sysaddr.node;
  3288.             fmsghdr.destnode=pkthdr.destnode=area.uplink[j].node;
  3289.             if(cfg.nodecfg[node].pkt_type==PKT_TWO_TWO) {
  3290.                 pkthdr.year=sysaddr.point;
  3291.                 pkthdr.month=area.uplink[j].point;
  3292.                 pkthdr.day=0;
  3293.                 pkthdr.hour=0;
  3294.                 pkthdr.min=0;
  3295.                 pkthdr.sec=0;
  3296.                 pkthdr.baud=0x0002; }
  3297.             else {
  3298.                 pkthdr.year=tm->tm_year;
  3299.                 pkthdr.month=tm->tm_mon;
  3300.                 pkthdr.day=tm->tm_mday;
  3301.                 pkthdr.hour=tm->tm_hour;
  3302.                 pkthdr.min=tm->tm_min;
  3303.                 pkthdr.sec=tm->tm_sec;
  3304.                 pkthdr.baud=0; }
  3305.             pkthdr.pkttype=0x0002;
  3306.             pkthdr.orignet=sysaddr.net;
  3307.             fmsghdr.destnet=pkthdr.destnet=area.uplink[j].net;
  3308.             pkthdr.prodcode=0;
  3309.             pkthdr.sernum=0;
  3310.             if(node<cfg.nodecfgs)
  3311.                 memcpy(pkthdr.password,cfg.nodecfg[node].pktpwd,8);
  3312.             else
  3313.                 memset(pkthdr.password,0,8);
  3314.             pkthdr.origzone=sysaddr.zone;
  3315.             fmsghdr.destzone=pkthdr.destzone=area.uplink[j].zone;
  3316.             memset(pkthdr.empty,0,sizeof(two_two_t));
  3317.  
  3318.             if(cfg.nodecfg[node].pkt_type==PKT_TWO_TWO) {
  3319.                 memset(&two,0,20);
  3320.                 strcpy(two.origdomn,"fidonet");
  3321.                 strcpy(two.destdomn,"fidonet");
  3322.                 memcpy(&pkthdr.empty,&two,20); }
  3323.             else if(cfg.nodecfg[node].pkt_type==PKT_TWO_PLUS) {
  3324.                 memset(&two_p,0,20);
  3325.                 if(sysaddr.point) {
  3326.                     pkthdr.orignet=-1;
  3327.                     two_p.auxnet=sysaddr.net; }
  3328.                 two_p.cwcopy=0x0100;
  3329.                 two_p.prodcode=pkthdr.prodcode;
  3330.                 two_p.revision=pkthdr.sernum;
  3331.                 two_p.cword=0x0001;
  3332.                 two_p.origzone=pkthdr.origzone;
  3333.                 two_p.destzone=pkthdr.destzone;
  3334.                 two_p.origpoint=sysaddr.point;
  3335.                 two_p.destpoint=area.uplink[j].point;
  3336.                 memcpy(&pkthdr.empty,&two_p,sizeof(two_plus_t)); }
  3337.  
  3338.             fwrite(&pkthdr,sizeof(pkthdr_t),1,outpkt[totalpkts].stream);
  3339.             putfmsg(outpkt[totalpkts].stream,fbuf,fmsghdr,area,seenbys,paths);
  3340.             outpkt[totalpkts].curopen=1;
  3341.             memcpy(&outpkt[totalpkts].uplink,&area.uplink[j]
  3342.                 ,sizeof(faddr_t));
  3343.             ++openpkts;
  3344.             ++totalpkts;
  3345.             if(totalpkts>=MAX_TOTAL_PKTS) {
  3346.                 fclose(outpkt[totalpkts-1].stream);
  3347. //                  pack_bundle(outpkt[totalpkts-1].filename
  3348. //                      ,outpkt[totalpkts-1].uplink);
  3349.                 --totalpkts;
  3350.                 --openpkts; }
  3351.             } }
  3352. }
  3353.  
  3354. /**************************************/
  3355. /* Send netmail, returns 0 on success */
  3356. /**************************************/
  3357. int import_netmail(char *path,fmsghdr_t hdr, FILE *fidomsg)
  3358. {
  3359.     uchar info[512],str[256],tmp[256],subj[256]
  3360.         ,HUGE16 *fmsgbuf=NULL,*p,*tp,*sp;
  3361.     int i,match,usernumber;
  3362.     ulong l;
  3363.     faddr_t addr;
  3364.  
  3365. hdr.destzone=hdr.origzone=sys_faddr.zone;
  3366. hdr.destpoint=hdr.origpoint=0;
  3367. getzpt(fidomsg,&hdr);                /* use kludge if found */
  3368. for(match=0;match<total_faddrs;match++)
  3369.     if((hdr.destzone==faddr[match].zone || misc&FUZZY_ZONE)
  3370.         && hdr.destnet==faddr[match].net
  3371.         && hdr.destnode==faddr[match].node
  3372.         && hdr.destpoint==faddr[match].point)
  3373.         break;
  3374. if(match<total_faddrs && misc&FUZZY_ZONE)
  3375.     hdr.origzone=hdr.destzone=faddr[match].zone;
  3376. if(hdr.origpoint)
  3377.     sprintf(tmp,".%u",hdr.origpoint);
  3378. else
  3379.     tmp[0]=0;
  3380. if(hdr.destpoint)
  3381.     sprintf(str,".%u",hdr.destpoint);
  3382. else
  3383.     str[0]=0;
  3384. sprintf(info,"%s%s%s (%u:%u/%u%s) To: %s (%u:%u/%u%s)"
  3385.     ,path,path[0] ? " ":""
  3386.     ,hdr.from,hdr.origzone,hdr.orignet,hdr.orignode,tmp
  3387.     ,hdr.to,hdr.destzone,hdr.destnet,hdr.destnode,str);
  3388. printf("%s ",info);
  3389.  
  3390. if(!(misc&IMPORT_NETMAIL)) {
  3391.     if(!path[0]) {
  3392.         fmsgbuf=getfmsg(fidomsg,&l);
  3393.         if(!fmsgbuf) {
  3394.             printf("ERROR Netmail allocation");
  3395.             logprintf("ERROR line %d netmail allocation",__LINE__);
  3396.             return(2); }
  3397.  
  3398.         if(!l && misc&KILL_EMPTY_MAIL)
  3399.             printf("Empty NetMail - ");
  3400.         else {
  3401.             for(i=1;i;i++) {
  3402.                 sprintf(str,"%s%u.MSG",netmail_dir,i);
  3403.                 if(!fexist(str))
  3404.                     break; }
  3405.             if(!i) {
  3406.                 printf("Too many netmail messages");
  3407.                 logprintf("Too many netmail messages");
  3408.                 return(2); }
  3409.             if((i=nopen(str,O_WRONLY|O_CREAT))==-1) {
  3410.                 printf("ERROR opening %s",str);
  3411.                 logprintf("ERROR opening %s",str);
  3412.                 return(2); }
  3413.             write(i,&hdr,sizeof(hdr));
  3414.             write(i,fmsgbuf,strlen((char *)fmsgbuf)+1); /* Write the NULL too */
  3415.             close(i); }
  3416.         FREE(fmsgbuf); }
  3417.     printf("Ignored");
  3418.     if(cfg.log&LOG_IGNORED)
  3419.         logprintf("%s Ignored",info);
  3420.     return(-1); }
  3421.  
  3422. if(hdr.attr&FIDO_ORPHAN) {
  3423.     printf("Orphaned");
  3424.     return(1); }
  3425. if(!(misc&IGNORE_ADDRESS) && match==total_faddrs && path[0]) {
  3426.     printf("Skipped");
  3427.     return(2); }
  3428. if(!(misc&IGNORE_RECV) && hdr.attr&FIDO_RECV) {
  3429.     printf("Already received");
  3430.     return(3); }
  3431. if(hdr.attr&FIDO_LOCAL && !(misc&LOCAL_NETMAIL)) {
  3432.     printf("Created locally");
  3433.     return(4); }
  3434.  
  3435. if(email->shd_fp==NULL) {
  3436.     sprintf(email->file,"%sMAIL",data_dir);
  3437.     email->retry_time=smb_retry_time;
  3438.     if((i=smb_open(email))!=0) {
  3439.         printf("ERROR %d opening %s\n",i,email->file);
  3440.         logprintf("ERROR %d line %d opening %s",i,__LINE__,email->file);
  3441.         exit(1); } }
  3442.  
  3443. if(!filelength(fileno(email->shd_fp))) {
  3444.     email->status.max_crcs=mail_maxcrcs;
  3445.     email->status.max_msgs=MAX_SYSMAIL;
  3446.     email->status.max_age=mail_maxage;
  3447.     email->status.attr=SMB_EMAIL;
  3448.     if((i=smb_create(email))!=0) {
  3449.         sprintf(str,"ERROR %d creating %s",i,email->file);
  3450.         printf("%s\n",str);
  3451.         logprintf(str);
  3452.         exit(1); } }
  3453.  
  3454. if(!stricmp(hdr.to,"AREAFIX") || !stricmp(hdr.to,"SBBSECHO")) {
  3455.     fmsgbuf=getfmsg(fidomsg,NULL);
  3456.     if(path[0]) {
  3457.         if(misc&DELETE_NETMAIL) {
  3458.             fclose(fidomsg);
  3459.             if(delfile(path))
  3460.                 logprintf("ERROR line %d removing %s %s",__LINE__,path
  3461.                     ,sys_errlist[errno]); }
  3462.         else {
  3463.             hdr.attr|=FIDO_RECV;
  3464.             fseek(fidomsg,0L,SEEK_SET);
  3465.             fwrite(&hdr,sizeof(fmsghdr_t),1,fidomsg);
  3466.             fclose(fidomsg); } }    /* Gotta close it here for areafix stuff */
  3467.     addr.zone=hdr.origzone;
  3468.     addr.net=hdr.orignet;
  3469.     addr.node=hdr.orignode;
  3470.     addr.point=hdr.origpoint;
  3471.     strcpy(hdr.to,sys_op);
  3472.     strcpy(hdr.from,"SBBSecho");
  3473.     strcpy(str,hdr.subj);
  3474.     strcpy(hdr.subj,"Areafix Request");
  3475.     hdr.origzone=hdr.orignet=hdr.orignode=hdr.origpoint=0;
  3476.     p=process_areafix(addr,fmsgbuf,str);
  3477. #if 0 // Not necessary with SMBLIB v2.0
  3478.     if((i=smb_locksmbhdr(email))!=0) {
  3479.         printf("ERROR %d locking %s smbhdr",i,email->file);
  3480.         logprintf("ERROR %d line %d locking %s smbhdr",i,__LINE__,email->file);
  3481.         exit(1); }
  3482.     if((i=smb_getstatus(email))!=0) {
  3483.         printf("ERROR %d reading %s status header",i,email->file);
  3484.         logprintf("ERROR %d line %d reading %s status header",i,__LINE__
  3485.             ,email->file);
  3486.         exit(1); }
  3487. #endif
  3488.     if(p && cfg.notify)
  3489.         if(fmsgtosmsg(p,hdr,cfg.notify,INVALID_SUB)==1) {
  3490.             sprintf(str,"\7\1n\1hSBBSecho \1n\1msent you mail\r\n");
  3491.             putsmsg(cfg.notify,str); }
  3492. //      smb_unlocksmbhdr(email);
  3493.     if(fmsgbuf)
  3494.         FREE(fmsgbuf);
  3495.     if(cfg.log&LOG_AREAFIX)
  3496.         logprintf(info);
  3497.     return(-2); }
  3498.  
  3499. usernumber=atoi(hdr.to);
  3500. if(!stricmp(hdr.to,"SYSOP"))  /* NetMail to "sysop" goes to #1 */
  3501.     usernumber=1;
  3502. if(!usernumber && match<total_faddrs)
  3503.     usernumber=matchname(hdr.to);
  3504. if(!usernumber) {
  3505.     if(misc&UNKNOWN_NETMAIL && match<total_faddrs)    /* receive unknown user */
  3506.         usernumber=1;                                /* mail to 1 */
  3507.     else {
  3508.         if(match<total_faddrs) {
  3509.             printf("Unknown user ");
  3510.             if(cfg.log&LOG_UNKNOWN)
  3511.                 logprintf("%s Unknown user",info); }
  3512. /***
  3513.         hdr.attr|=FIDO_ORPHAN;
  3514.         fseek(fidomsg,0L,SEEK_SET);
  3515.         fwrite(&hdr,sizeof(fmsghdr_t),1,fidomsg);
  3516. ***/
  3517.         if(!path[0]) {
  3518.             fmsgbuf=getfmsg(fidomsg,&l);
  3519.             if(!fmsgbuf) {
  3520.                 printf("ERROR Netmail allocation");
  3521.                 logprintf("ERROR line %d netmail allocation",__LINE__);
  3522.                 return(2); }
  3523.             if(!l && misc&KILL_EMPTY_MAIL) {
  3524.                 printf("Empty NetMail - Ignored");
  3525.                 if(cfg.log&LOG_IGNORED)
  3526.                     logprintf("%s Empty - Ignored",info); }
  3527.             else {
  3528.                 for(i=1;i;i++) {
  3529.                     sprintf(str,"%s%u.MSG",netmail_dir,i);
  3530.                     if(!fexist(str))
  3531.                         break; }
  3532.                 if(!i) {
  3533.                     printf("Too many netmail messages");
  3534.                     logprintf("Too many netmail messages");
  3535.                     return(2); }
  3536.                 if((i=nopen(str,O_WRONLY|O_CREAT))==-1) {
  3537.                     printf("ERROR opening %s",str);
  3538.                     logprintf("ERROR opening %s",str);
  3539.                     return(2); }
  3540.                 write(i,&hdr,sizeof(hdr));
  3541.                 write(i,fmsgbuf,strlen((char *)fmsgbuf)+1); /* Write the NULL too */
  3542.                 close(i); }
  3543.             FREE(fmsgbuf); }
  3544.         return(2); } }
  3545.  
  3546. /*********************/
  3547. /* Importing NetMail */
  3548. /*********************/
  3549.  
  3550. fmsgbuf=getfmsg(fidomsg,&l);
  3551.  
  3552. #if 0 // Unnecessary with SMBLIB v2.0
  3553. if((i=smb_locksmbhdr(email))!=0) {
  3554.     printf("ERROR %d locking %s smbhdr",i,email->file);
  3555.     logprintf("ERROR %d line %d locking %s smbhdr",i,__LINE__,email->file);
  3556.     exit(1); }
  3557. if((i=smb_getstatus(email))!=0) {
  3558.     printf("ERROR %d reading %s status header",i,email->file);
  3559.     logprintf("ERROR %d line %d reading %s status header"
  3560.         ,i,__LINE__,email->file);
  3561.     exit(1); }
  3562. #endif
  3563.  
  3564. if(!l && misc&KILL_EMPTY_MAIL) {
  3565.     printf("Empty NetMail - Ignored");
  3566.     if(cfg.log&LOG_IGNORED)
  3567.         logprintf("%s Empty - Ignored",info);
  3568.     if(fmsgbuf)
  3569.         FREE(fmsgbuf);
  3570.     return(0); }
  3571.  
  3572. i=fmsgtosmsg(fmsgbuf,hdr,usernumber,INVALID_SUB);
  3573. if(i!=1) {
  3574.     printf("ERROR (%d) Importing",i);
  3575.     logprintf("ERROR (%d) Importing %s",i,info);
  3576.     if(fmsgbuf)
  3577.         FREE(fmsgbuf);
  3578.     return(10); }
  3579.  
  3580. addr.zone=hdr.origzone;
  3581. addr.net=hdr.orignet;
  3582. addr.node=hdr.orignode;
  3583. addr.point=hdr.origpoint;
  3584. sprintf(str,"\7\1n\1hSBBSecho: \1m%.36s \1n\1msent you NetMail from "
  3585.     "\1h%s\1n\r\n",hdr.from,faddrtoa(addr));
  3586. putsmsg(usernumber,str);
  3587.  
  3588. if(hdr.attr&FIDO_FILE) {    /* File attachment */
  3589.     strcpy(subj,hdr.subj);
  3590.     tp=subj;
  3591.     while(1) {
  3592.         p=strchr(tp,SP);
  3593.         if(p) *p=0;
  3594.         sp=strrchr(tp,'/');              /* sp is slash pointer */
  3595.         if(!sp) sp=strrchr(tp,'\\');
  3596.         if(sp) tp=sp+1;
  3597.         sprintf(str,"%s%s",fidofile_dir,tp);
  3598.         sprintf(tmp,"%sFILE\\%04u.IN",data_dir,usernumber);
  3599.         mkdir(tmp);
  3600.         strcat(tmp,"\\");
  3601.         strcat(tmp,tp);
  3602.         mv(str,tmp,0);
  3603.         if(!p)
  3604.             break;
  3605.         tp=p+1; } }
  3606. netmail++;
  3607.  
  3608. if(fmsgbuf)
  3609.     FREE(fmsgbuf);
  3610.  
  3611. /***************************/
  3612. /* Updating message header */
  3613. /***************************/
  3614. /***    NOT packet compatible
  3615. if(!(misc&DONT_SET_RECV)) {
  3616.     hdr.attr|=FIDO_RECV;
  3617.     fseek(fidomsg,0L,SEEK_SET);
  3618.     fwrite(&hdr,sizeof(fmsghdr_t),1,fidomsg); }
  3619. ***/
  3620. if(cfg.log&LOG_IMPORTED)
  3621.     logprintf("%s Imported",info);
  3622. return(0);
  3623. }
  3624.  
  3625. /******************************************************************************
  3626.  This is where we export echomail.    This was separated from function main so
  3627.  it could be used for the remote rescan function.  Passing anything but an
  3628.  empty address as 'addr' designates that a rescan should be done for that
  3629.  address.
  3630. ******************************************************************************/
  3631. void export_echomail(char *sub_code,faddr_t addr)
  3632. {
  3633.     char str[1025],tear,cr,HUGE16 *buf;
  3634.     uchar HUGE16 *fmsgbuf=NULL;
  3635.     int g,i,j,k,file;
  3636.     ulong f,l,m,exp,ptr,msgs,lastmsg,posts,exported=0;
  3637.     float export_time;
  3638.     smbmsg_t msg;
  3639.     fmsghdr_t hdr;
  3640.     struct    tm *tm;
  3641.     faddr_t pkt_faddr;
  3642.     post_t HUGE16 *post;
  3643.     areasbbs_t fakearea,curarea;
  3644.     addrlist_t msg_seen,msg_path;
  3645.     clock_t start_tick=0,export_ticks=0;
  3646.  
  3647. memset(&msg_seen,0,sizeof(addrlist_t));
  3648. memset(&msg_path,0,sizeof(addrlist_t));
  3649. memset(&pkt_faddr,0,sizeof(faddr_t));
  3650. start_tick=0;
  3651.  
  3652. printf("\nScanning for Outbound EchoMail...\n");
  3653.  
  3654. for(g=0;g<total_grps;g++)
  3655. for(i=0;i<total_subs;i++)
  3656.     if(sub[i]->misc&SUB_FIDO && sub[i]->grp==g) {
  3657.         for(j=0;j<cfg.areas;j++)    /* Skip areas with no uplinks */
  3658.             if(cfg.area[j].sub==i)
  3659.                 break;
  3660.         if(j==cfg.areas || (j<cfg.areas && !cfg.area[j].uplinks))
  3661.             continue;
  3662.         if(addr.zone) {         /* Skip areas not meant for this address */
  3663.             if(j<cfg.areas)
  3664.                 for(k=0;k<cfg.area[j].uplinks;k++)
  3665.                     if(!memcmp(&cfg.area[j].uplink[k],&addr,sizeof(faddr_t)))
  3666.                         break;
  3667.             if(k==cfg.area[j].uplinks)
  3668.                 continue; }
  3669.         if(sub_code[0] && stricmp(sub_code,sub[i]->code))
  3670.             continue;
  3671.         printf("\nScanning %-15.15s %s\n"
  3672.             ,grp[sub[i]->grp]->sname,sub[i]->lname);
  3673.         ptr=0;
  3674.         if(!addr.zone && !(misc&IGNORE_MSGPTRS)) {
  3675.             sprintf(str,"%s%s.SFP",sub[i]->data_dir,sub[i]->code);
  3676.             if((file=nopen(str,O_RDONLY))!=-1) {
  3677.                 read(file,&ptr,sizeof(time_t));
  3678.                 close(file); } }
  3679.  
  3680.         msgs=getlastmsg(i,&lastmsg,0);
  3681.         if(!msgs || (!addr.zone && !(misc&IGNORE_MSGPTRS) && ptr>=lastmsg)) {
  3682.             printf("No new messages.");
  3683.             if(ptr>lastmsg && !addr.zone && !(misc&LEAVE_MSGPTRS)) {
  3684.                 printf("Fixing new-scan pointer.");
  3685.                 sprintf(str,"%s%s.SFP",sub[i]->data_dir,sub[i]->code);
  3686.                 if((file=nopen(str,O_WRONLY|O_CREAT))==-1) {
  3687.                     printf("\7ERROR opening/creating %s",str);
  3688.                     logprintf("ERROR line %d opening/creating %s"
  3689.                         ,__LINE__,str); }
  3690.                 else {
  3691.                     write(file,&lastmsg,4);
  3692.                     close(file); } }
  3693.             continue; }
  3694.  
  3695.         sprintf(smb[cur_smb].file,"%s%s"
  3696.             ,sub[i]->data_dir,sub[i]->code);
  3697.         smb[cur_smb].retry_time=smb_retry_time;
  3698.         if((j=smb_open(&smb[cur_smb]))!=0) {
  3699.             printf("ERROR %d opening %s\n",j,smb[cur_smb].file);
  3700.             logprintf("ERROR %d line %d opening %s",j,__LINE__
  3701.                 ,smb[cur_smb].file);
  3702.             continue; }
  3703.  
  3704.         post=NULL;
  3705.         posts=loadmsgs(&post,ptr);
  3706.  
  3707.         if(!posts)    { /* no new messages */
  3708.             smb_close(&smb[cur_smb]);
  3709.             if(post)
  3710.                 LFREE(post);
  3711.             continue; }
  3712.  
  3713.         if(start_tick)
  3714.             export_ticks+=clock()-start_tick;
  3715.         start_tick=clock();
  3716.  
  3717.         for(m=exp=0;m<posts;m++) {
  3718.             printf("\r%8s %5lu of %-5lu  "
  3719.                 ,sub[i]->code,m+1,posts);
  3720.             msg.idx.offset=post[m].offset;
  3721.             if((k=smb_lockmsghdr(&smb[cur_smb],&msg))!=0) {
  3722.                 printf("ERROR %d locking %s msghdr\n",k,smb[cur_smb].file);
  3723.                 logprintf("ERROR %d line %d locking %s msghdr\n"
  3724.                     ,k,__LINE__,smb[cur_smb].file);
  3725.                 continue; }
  3726.             k=smb_getmsghdr(&smb[cur_smb],&msg);
  3727.             if(k || msg.hdr.number!=post[m].number) {
  3728.                 smb_unlockmsghdr(&smb[cur_smb],&msg);
  3729.                 smb_freemsgmem(&msg);
  3730.  
  3731.                 msg.hdr.number=post[m].number;
  3732.                 if((k=smb_getmsgidx(&smb[cur_smb],&msg))!=0) {
  3733.                     printf("ERROR %d reading %s index\n",k,smb[cur_smb].file);
  3734.                     logprintf("ERROR %d line %d reading %s index",k,__LINE__
  3735.                         ,smb[cur_smb].file);
  3736.                     continue; }
  3737.                 if((k=smb_lockmsghdr(&smb[cur_smb],&msg))!=0) {
  3738.                     printf("ERROR %d locking %s msghdr\n",k,smb[cur_smb].file);
  3739.                     logprintf("ERROR %d line %d locking %s msghdr",k,__LINE__
  3740.                         ,smb[cur_smb].file);
  3741.                     continue; }
  3742.                 if((k=smb_getmsghdr(&smb[cur_smb],&msg))!=0) {
  3743.                     smb_unlockmsghdr(&smb[cur_smb],&msg);
  3744.                     printf("ERROR %d reading %s msghdr\n",k,smb[cur_smb].file);
  3745.                     logprintf("ERROR %d line %d reading %s msghdr",k,__LINE__
  3746.                         ,smb[cur_smb].file);
  3747.                     continue; } }
  3748.  
  3749.             if((!addr.zone && !(misc&EXPORT_ALL)
  3750.                 && msg.from_net.type==NET_FIDO)
  3751.                 || !strnicmp(msg.subj,"NE:",3)) {   /* no echo */
  3752.                 smb_unlockmsghdr(&smb[cur_smb],&msg);
  3753.                 smb_freemsgmem(&msg);
  3754.                 continue; }  /* From a Fido node, ignore it */
  3755.  
  3756.             if(msg.from_net.type && msg.from_net.type!=NET_FIDO
  3757.                 && !(sub[i]->misc&SUB_GATE)) {
  3758.                 smb_unlockmsghdr(&smb[cur_smb],&msg);
  3759.                 smb_freemsgmem(&msg);
  3760.                 continue; }
  3761.  
  3762.             memset(&hdr,0,sizeof(fmsghdr_t));     /* Zero the header */
  3763.             hdr.origzone=sub[i]->faddr.zone;
  3764.             hdr.orignet=sub[i]->faddr.net;
  3765.             hdr.orignode=sub[i]->faddr.node;
  3766.             hdr.origpoint=sub[i]->faddr.point;
  3767.  
  3768.             hdr.attr=FIDO_LOCAL;
  3769.             if(msg.hdr.attr&MSG_PRIVATE)
  3770.                 hdr.attr|=FIDO_PRIVATE;
  3771.  
  3772.             sprintf(hdr.from,"%.35s",msg.from);
  3773.  
  3774.             tm=gmtime((time_t *)&msg.hdr.when_written.time);
  3775.             sprintf(hdr.time,"%02u %3.3s %02u  %02u:%02u:%02u"
  3776.                 ,tm->tm_mday,mon[tm->tm_mon],tm->tm_year
  3777.                 ,tm->tm_hour,tm->tm_min,tm->tm_sec);
  3778.  
  3779.             sprintf(hdr.to,"%.35s",msg.to);
  3780.  
  3781.             sprintf(hdr.subj,"%.71s",msg.subj);
  3782.  
  3783.             buf=smb_getmsgtxt(&smb[cur_smb],&msg,GETMSGTXT_TAILS);
  3784.             if(!buf) {
  3785.                 smb_unlockmsghdr(&smb[cur_smb],&msg);
  3786.                 smb_freemsgmem(&msg);
  3787.                 continue; }
  3788.             fmsgbuf=MALLOC(strlen((char *)buf)+512);
  3789.             if(!fmsgbuf) {
  3790.                 printf("ERROR allocating %lu bytes for fmsgbuf\n");
  3791.                 logprintf("ERROR line %d allocating %lu bytes for fmsgbuf"
  3792.                     ,__LINE__,strlen((char *)buf)+512);
  3793.                 smb_unlockmsghdr(&smb[cur_smb],&msg);
  3794.                 smb_freemsgmem(&msg);
  3795.                 continue; }
  3796.  
  3797.             tear=0;
  3798.             for(l=f=0,cr=1;buf[l];l++) {
  3799.                 if(buf[l]==1) { /* Ctrl-A, so skip it and the next char */
  3800.                     l++;
  3801.                     if(!buf[l])
  3802.                         break;
  3803.                     continue; }
  3804.                 if(buf[l]==LF)    /* Ignore line feeds */
  3805.                     continue;
  3806.                 if(cr) {
  3807.                     if(buf[l]=='-' && buf[l+1]=='-'
  3808.                         && buf[l+2]=='-'
  3809.                         && (buf[l+3]==SP || buf[l+3]==CR)) {
  3810.                         if(misc&CONVERT_TEAR)    /* Convert to === */
  3811.                             buf[l]=buf[l+1]=buf[l+2]='=';
  3812.                         else
  3813.                             tear=1; }
  3814.                     else if(!strncmp((char *)buf+l," * Origin: ",11))
  3815.                         buf[l+1]='#'; } /* Convert * Origin into # Origin */
  3816.  
  3817.                 if(buf[l]==CR)
  3818.                     cr=1;
  3819.                 else
  3820.                     cr=0;
  3821.                 if(sub[i]->misc&SUB_ASCII || misc&ASCII_ONLY) {
  3822.                     if(buf[l]<SP && buf[l]!=CR) /* Ctrl ascii */
  3823.                         buf[l]='.';             /* converted to '.' */
  3824.                     if((uchar)buf[l]>0x7f)        /* extended ASCII */
  3825.                         buf[l]='*'; }           /* converted to '*' */
  3826.  
  3827.                 fmsgbuf[f++]=buf[l]; }
  3828.  
  3829.             FREE(buf);
  3830.             fmsgbuf[f]=0;
  3831.  
  3832.             if(!(sub[i]->misc&SUB_NOTAG)) {
  3833.                 if(!tear) {  /* No previous tear line */
  3834.                     sprintf(str,"--- Synchronet+SBBSecho v%s\r",SBBSECHO_VER);
  3835.                     strcat((char *)fmsgbuf,str); }
  3836.  
  3837.                 sprintf(str," * Origin: %s (%s)\r"
  3838.                     ,sub[i]->origline[0] ? sub[i]->origline : origline
  3839.                     ,faddrtoa(sub[i]->faddr));
  3840.                 strcat((char *)fmsgbuf,str); }
  3841.  
  3842.             for(k=0;k<cfg.areas;k++)
  3843.                 if(cfg.area[k].sub==i) {
  3844.                     cfg.area[k].exported++;
  3845.                     pkt_to_pkt(fmsgbuf,cfg.area[k]
  3846.                         ,(addr.zone) ? addr:pkt_faddr,hdr,msg_seen
  3847.                         ,msg_path,(addr.zone) ? 2:0);
  3848.                     break; }
  3849.             FREE(fmsgbuf);
  3850.             exported++;
  3851.             exp++;
  3852.             printf("Exp: %lu ",exp);
  3853.             smb_unlockmsghdr(&smb[cur_smb],&msg);
  3854.             smb_freemsgmem(&msg); }
  3855.  
  3856.         smb_close(&smb[cur_smb]);
  3857.         LFREE(post);
  3858.  
  3859.         /***********************/
  3860.         /* Update FIDO_PTR.DAB */
  3861.         /***********************/
  3862.         if(!addr.zone && !(misc&LEAVE_MSGPTRS) && lastmsg>ptr) {
  3863.             sprintf(str,"%s%s.SFP",sub[i]->data_dir,sub[i]->code);
  3864.             if((file=nopen(str,O_WRONLY|O_CREAT))==-1) {
  3865.                 printf("\7ERROR opening/creating %s",str);
  3866.                 logprintf("ERROR line %d opening/creating %s",__LINE__,str); }
  3867.             else {
  3868.                 write(file,&lastmsg,4);
  3869.                 close(file); } } }
  3870.  
  3871. printf("\n");
  3872. if(start_tick)    /* Last possible increment of export_ticks */
  3873.     export_ticks+=clock()-start_tick;
  3874.  
  3875. pkt_to_pkt(buf,fakearea,pkt_faddr,hdr,msg_seen,msg_path,1);
  3876.  
  3877. if(!addr.zone && cfg.log&LOG_AREA_TOTALS && exported)
  3878.     for(i=0;i<cfg.areas;i++)
  3879.         if(cfg.area[i].exported)
  3880.             logprintf("Exported: %5u msgs %8s -> %s"
  3881.                 ,cfg.area[i].exported,sub[cfg.area[i].sub]->code
  3882.                 ,cfg.area[i].name);
  3883.  
  3884. export_time=((float)export_ticks)/(float)CLK_TCK;
  3885. if(cfg.log&LOG_TOTALS && exported && export_time) {
  3886.     printf("\nExported %lu EchoMail messages in %.1f seconds "
  3887.         ,exported,export_time);
  3888.     logprintf("Exported: %5lu msgs in %.1f sec (%.1f/min %.1f/sec)"
  3889.         ,exported,export_time
  3890.         ,export_time/60.0 ? (float)exported/(export_time/60.0) :(float)exported
  3891.         ,(float)exported/export_time);
  3892.     if(export_time/60.0)
  3893.         printf("(%.1f/min) ",(float)exported/(export_time/60.0));
  3894.     printf("(%.1f/sec)\n",(float)exported/export_time); }
  3895.  
  3896. }
  3897. /***********************************/
  3898. /* Synchronet/FidoNet Message util */
  3899. /***********************************/
  3900. int main(int argc, char **argv)
  3901. {
  3902.     FILE    *fidomsg;
  3903.     char    ch,str[1025],fname[256],path[512],sub_code[9]
  3904.             ,*p,*tp,*sp,*buf,cr,tear,lzh
  3905.             ,areatagstr[129],packet[128],outbound[128];
  3906.     uchar    HUGE16 *fmsgbuf=NULL;
  3907.     ushort    xlat,attr;
  3908.     int     i,j,k,n,x,y,z,last,file,fmsg,g,grunged;
  3909.     uint    subnum[MAX_OPEN_SMBS]={INVALID_SUB};
  3910.     ulong    files,msgfiles,echomail=0,crc,ptr,
  3911.             l,m,f,length,lastmsg,posts,msgs,exp,areatag;
  3912.     time_t    now;
  3913.     float    import_time;
  3914.     clock_t start_tick=0,import_ticks=0;
  3915.     read_cfg_text_t txt;
  3916.     struct    find_t ff;
  3917.     struct    tm *tm;
  3918.     fmsghdr_t hdr;
  3919.     faddr_t addr,pkt_faddr;
  3920.     post_t    HUGE16 *post;
  3921.     FILE    *stream,*fstream;
  3922.     smbmsg_t msg;
  3923.     pkthdr_t pkthdr;
  3924.     addrlist_t msg_seen,msg_path;
  3925.     areasbbs_t fakearea,curarea;
  3926.     char *usage="\n"
  3927. "usage: sbbsecho [cfg_file] [/switches] [sub_code]\n"
  3928. "\n"
  3929. "where: cfg_file is the filename of config file (default is ctrl\\sbbsecho.cfg)\n"
  3930. "       sub_code is the internal code for a sub-board (default is ALL subs)\n"
  3931. "\n"
  3932. "valid switches:\n"
  3933. "\n"
  3934. "p: do not import packets                 x: do not delete packets after import\n"
  3935. "n: do not import netmail                 d: do not delete netmail after import\n"
  3936. "i: do not import echomail                e: do not export echomail\n"
  3937. "m: ignore echomail ptrs (export all)     u: update echomail ptrs (export none)\n"
  3938. "j: ignore recieved bit on netmail        t: do not update echomail ptrs\n"
  3939. "l: create log file (data\\sbbsecho.log)   r: create report of import totals\n"
  3940. "h: export all echomail (hub rescan)      b: import locally created netmail too\n"
  3941. "a: export ASCII characters only          f: create packets for outbound netmail\n"
  3942. "g: generate notify lists                 =: change existing tear lines to ===\n"
  3943. "y: import netmail for unknown users to sysop\n"
  3944. "o: import all netmail regardless of destination address\n"
  3945. "s: import private echomail override (strip private status)\n"
  3946. "!: notify users of received echomail\n";
  3947.  
  3948. if((email=(smb_t *)MALLOC(sizeof(smb_t)))==NULL) {
  3949.     printf("ERROR allocating memory for email.\n");
  3950.     exit(1); }
  3951. memset(email,0,sizeof(smb_t));
  3952. if((smb=(smb_t *)MALLOC(MAX_OPEN_SMBS*sizeof(smb_t)))==NULL) {
  3953.     printf("ERROR allocating memory for smbs.\n");
  3954.     exit(1); }
  3955. for(i=0;i<MAX_OPEN_SMBS;i++)
  3956.     memset(&smb[i],0,sizeof(smb_t));
  3957. memset(&cfg,0,sizeof(config_t));
  3958. memset(&msg_seen,0,sizeof(addrlist_t));
  3959. memset(&msg_path,0,sizeof(addrlist_t));
  3960. printf("\nSBBSecho Version %s (%s) SMBLIB %s · Synchronet FidoNet Packet "
  3961.     "Tosser\n"
  3962.     ,SBBSECHO_VER
  3963. #if defined(__OS2__)
  3964.     ,"OS/2"
  3965. #elif defined(__NT__)
  3966.     ,"Win32"
  3967. #elif defined(__DOS4G__)
  3968.     ,"DOS4G"
  3969. #elif defined(__FLAT__)
  3970.     ,"DOS32"
  3971. #else
  3972.     ,"DOS16"
  3973. #endif
  3974.     ,SMBLIB_VERSION
  3975.     );
  3976.  
  3977. putenv("TZ=UCT0");
  3978. putenv("TMP=");
  3979. _fmode=O_BINARY;
  3980. setvbuf(stdout,NULL,_IONBF,0);
  3981.  
  3982. txt.openerr="\7\nError opening %s for read.\n";
  3983. txt.reading="\nReading %s...";
  3984. txt.readit="\rRead %s       ";
  3985. txt.allocerr="\7\nError allocating %u bytes of memory\n";
  3986. txt.error="\7\nERROR: Offset %lu in %s\n\n";
  3987.  
  3988. node_dir[0]=sub_code[0]=0;
  3989. for(i=1;i<argc;i++) {
  3990.     if(argv[i][0]=='/') {
  3991.         j=1;
  3992.         while(argv[i][j]) {
  3993.             switch(toupper(argv[i][j])) {
  3994.                 case 'A':
  3995.                     misc|=ASCII_ONLY;
  3996.                     break;
  3997.                 case 'B':
  3998.                     misc|=LOCAL_NETMAIL;
  3999.                     break;
  4000.                 case 'D':
  4001.                     misc&=~DELETE_NETMAIL;
  4002.                     break;
  4003.                 case 'E':
  4004.                     misc&=~EXPORT_ECHOMAIL;
  4005.                     break;
  4006.                 case 'F':
  4007.                     misc|=PACK_NETMAIL;
  4008.                     break;
  4009.                 case 'G':
  4010.                     misc|=GEN_NOTIFY_LIST;
  4011.                     break;
  4012.                 case 'H':
  4013.                     misc|=EXPORT_ALL;
  4014.                     break;
  4015.                 case 'I':
  4016.                     misc&=~IMPORT_ECHOMAIL;
  4017.                     break;
  4018.                 case 'J':
  4019.                     misc|=IGNORE_RECV;
  4020.                     break;
  4021.                 case 'L':
  4022.                     misc|=LOGFILE;
  4023.                     break;
  4024.                 case 'M':
  4025.                     misc|=IGNORE_MSGPTRS;
  4026.                     break;
  4027.                 case 'N':
  4028.                     misc&=~IMPORT_NETMAIL;
  4029.                     break;
  4030.                 case 'O':
  4031.                     misc|=IGNORE_ADDRESS;
  4032.                     break;
  4033.                 case 'P':
  4034.                     misc&=~IMPORT_PACKETS;
  4035.                     break;
  4036.                 case 'R':
  4037.                     misc|=REPORT;
  4038.                     break;
  4039.                 case 'S':
  4040.                     misc|=IMPORT_PRIVATE;
  4041.                     break;
  4042.                 case 'T':
  4043.                     misc|=LEAVE_MSGPTRS;
  4044.                     break;
  4045.                 case 'U':
  4046.                     misc|=UPDATE_MSGPTRS;
  4047.                     misc&=~EXPORT_ECHOMAIL;
  4048.                     break;
  4049.                 case 'X':
  4050.                     misc&=~DELETE_PACKETS;
  4051.                     break;
  4052.                 case 'Y':
  4053.                     misc|=UNKNOWN_NETMAIL;
  4054.                     break;
  4055.                 case '=':
  4056.                     misc|=CONVERT_TEAR;
  4057.                     break;
  4058.                 case '!':
  4059.                     misc|=NOTIFY_RECEIPT;
  4060.                     break;
  4061.                 case 'Q':
  4062.                     exit(0);
  4063.                 default:
  4064.                     printf(usage);
  4065.                     exit(0); }
  4066.             j++; } }
  4067.     else {
  4068.         if(strchr(argv[i],'\\') || argv[i][1]==':' || strchr(argv[i],'.'))
  4069.             sprintf(cfg.cfgfile,"%.100s",argv[i]);
  4070.         else
  4071.             sprintf(sub_code,"%.8s",argv[i]); }  }
  4072.  
  4073. if(!(misc&(IMPORT_NETMAIL|IMPORT_ECHOMAIL)))
  4074.     misc&=~IMPORT_PACKETS;
  4075. if(!node_dir[0]) {
  4076.     p=getenv("SBBSNODE");
  4077.     if(p==NULL) {
  4078.         printf("\7\nSBBSNODE environment variable not set.\n");
  4079.         exit(1); }
  4080.     strcpy(node_dir,p); }
  4081.  
  4082. strupr(node_dir);
  4083.  
  4084. if(node_dir[strlen(node_dir)-1]!='\\')
  4085.     strcat(node_dir,"\\");
  4086.  
  4087. read_node_cfg(txt);
  4088. if(ctrl_dir[0]=='.') {   /* Relative path */
  4089.     strcpy(str,ctrl_dir);
  4090.     sprintf(ctrl_dir,"%s%s",node_dir,str);
  4091.     if(_fullpath(str,ctrl_dir,40))
  4092.         strcpy(ctrl_dir,str); }
  4093. backslash(ctrl_dir);
  4094.  
  4095. read_main_cfg(txt);
  4096. if(data_dir[0]=='.') {   /* Relative path */
  4097.     strcpy(str,data_dir);
  4098.     sprintf(data_dir,"%s%s",node_dir,str);
  4099.     if(_fullpath(str,data_dir,40))
  4100.         strcpy(data_dir,str); }
  4101. backslash(data_dir);
  4102. if(text_dir[0]=='.') {   /* Relative path */
  4103.     strcpy(str,text_dir);
  4104.     sprintf(text_dir,"%s%s",node_dir,str);
  4105.     if(_fullpath(str,text_dir,40))
  4106.         strcpy(text_dir,str); }
  4107. backslash(text_dir);
  4108. read_msgs_cfg(txt);
  4109.  
  4110. #ifndef __FLAT__
  4111.  
  4112. __spawn_ext = (node_swap & SWAP_EXT) != 0 ;
  4113. __spawn_ems = (node_swap & SWAP_EMS) != 0 ;
  4114. __spawn_xms = (node_swap & SWAP_XMS) != 0 ;
  4115.  
  4116. #endif
  4117.  
  4118. if(total_faddrs<1) {
  4119.     sys_faddr.zone=sys_faddr.net=sys_faddr.node=1;
  4120.     sys_faddr.point=0; }
  4121. else
  4122.     sys_faddr=faddr[0];
  4123.  
  4124. sprintf(str,"%s%s",ctrl_dir,"NODE.DAB");
  4125. if((nodefile=sopen(str,O_BINARY|O_RDWR,SH_DENYNO))==-1) {
  4126.     printf("\n\7ERROR opening %s\n",str);
  4127.     exit(1); }
  4128.  
  4129. if(!cfg.cfgfile[0])
  4130.     sprintf(cfg.cfgfile,"%sSBBSECHO.CFG",ctrl_dir);
  4131. strcpy(cfg.inbound,fidofile_dir);
  4132. sprintf(cfg.areafile,"%sAREAS.BBS",data_dir);
  4133. sprintf(cfg.logfile,"%sSBBSECHO.LOG",data_dir);
  4134.  
  4135. read_cfg();
  4136.  
  4137. if(misc&LOGFILE)
  4138.     if((fidologfile=_fsopen(cfg.logfile,"ab",SH_DENYNO))==NULL) {
  4139.         printf("\7ERROR opening %s\n",cfg.logfile);
  4140.         exit(1); }
  4141.  
  4142.  
  4143. if(exec_dir[0]!='\\' && exec_dir[1]!=':') {
  4144.     strcpy(path,node_dir);
  4145.     strcat(path,exec_dir);
  4146.     if(_fullpath(str,path,40))
  4147.         strcpy(path,str);
  4148.     backslash(path); }
  4149. else
  4150.     strcpy(path,exec_dir);
  4151.  
  4152. /******* READ IN AREAS.BBS FILE *********/
  4153.  
  4154. printf("Reading %s",cfg.areafile);
  4155. if((stream=fnopen(&file,cfg.areafile,O_RDONLY))==NULL) {
  4156.     printf("Unable to open %s for read.\n",cfg.areafile);
  4157.     exit(1); }
  4158. cfg.areas=0;        /* Total number of areas in AREAS.BBS */
  4159. cfg.area=NULL;
  4160. while(1) {
  4161.     if(!fgets(str,1024,stream))
  4162.         break;
  4163.     truncsp(str);
  4164.     p=str;
  4165.     while(*p && *p<=SP) p++;    /* Find first printable char */
  4166.     if(*p==';' || !*p)          /* Ignore blank lines or start with ; */
  4167.         continue;
  4168.     if((cfg.area=(areasbbs_t *)REALLOC(cfg.area,sizeof(areasbbs_t)*
  4169.         (cfg.areas+1)))==NULL) {
  4170.         printf("ERROR allocating memory for area #%u.\n",cfg.areas+1);
  4171.         exit(1); }
  4172.     memset(&cfg.area[cfg.areas],0,sizeof(areasbbs_t));
  4173.  
  4174.     cfg.area[cfg.areas].sub=INVALID_SUB;    /* Default to passthru */
  4175.  
  4176.     sprintf(tmp,"%-.8s",p);
  4177.     tp=tmp;
  4178.     while(*tp>SP) tp++;
  4179.     *tp=0;
  4180.     for(i=0;i<total_subs;i++)
  4181.         if(!stricmp(tmp,sub[i]->code))
  4182.             break;
  4183.     if(i<total_subs)
  4184.         cfg.area[cfg.areas].sub=i;
  4185.     else if(stricmp(tmp,"P")) {
  4186.         printf("\n%s: Unrecongized internal code, assumed passthru",tmp);
  4187.         logprintf("%s: Unrecognized internal code, assumed passthru",tmp); }
  4188.  
  4189.     while(*p>SP) p++;                /* Skip code */
  4190.     while(*p && *p<=SP) p++;        /* Skip white space */
  4191.     sprintf(tmp,"%-.50s",p);        /* Area tag */
  4192.     if((tp=strchr(tmp,TAB))!=NULL)    /* Chop off any TABs */
  4193.         *tp=0;
  4194.     if((tp=strchr(tmp,SP))!=NULL)    /* Chop off any spaces */
  4195.         *tp=0;
  4196.     strupr(tmp);
  4197.     if(tmp[0]=='*')         /* UNKNOWN-ECHO area */
  4198.         cfg.badecho=cfg.areas;
  4199.     if((cfg.area[cfg.areas].name=(char *)MALLOC(strlen(tmp)+1))==NULL) {
  4200.         printf("ERROR allocating memory for area #%u tag name.\n"
  4201.             ,cfg.areas+1);
  4202.         exit(1); }
  4203.     strcpy(cfg.area[cfg.areas].name,tmp);
  4204.     strupr(tmp);
  4205.     cfg.area[cfg.areas].tag=crc32(tmp);
  4206.  
  4207.     while(*p>SP) p++;                /* Skip tag */
  4208.     while(*p && *p<=SP) p++;        /* Skip white space */
  4209.  
  4210.     while(*p && *p!=';') {
  4211.         if((cfg.area[cfg.areas].uplink=(faddr_t *)
  4212.             REALLOC(cfg.area[cfg.areas].uplink
  4213.             ,sizeof(faddr_t)*(cfg.area[cfg.areas].uplinks+1)))==NULL) {
  4214.             printf("ERROR allocating memory for area #%u uplinks.\n"
  4215.                 ,cfg.areas+1);
  4216.             exit(1); }
  4217.         cfg.area[cfg.areas].uplink[cfg.area[cfg.areas].uplinks]=atofaddr(p);
  4218.         while(*p>SP) p++;            /* Skip address */
  4219.         while(*p && *p<=SP) p++;    /* Skip white space */
  4220.         cfg.area[cfg.areas].uplinks++; }
  4221.  
  4222.     if(cfg.area[cfg.areas].sub!=INVALID_SUB || cfg.area[cfg.areas].uplinks)
  4223.         cfg.areas++;        /* Don't allocate if no tossing */
  4224.     }
  4225. fclose(stream);
  4226.  
  4227. printf("\n");
  4228.  
  4229. if(!cfg.areas) {
  4230.     printf("No areas defined!\n");
  4231.     exit(1); }
  4232.  
  4233. #if 0
  4234.     /* AREAS.BBS DEBUG */
  4235.     for(i=0;i<cfg.areas;i++) {
  4236.         printf("%4u: %-8s"
  4237.             ,i+1
  4238.             ,cfg.area[i].sub==INVALID_SUB ? "Passthru" :
  4239.             sub[cfg.area[i].sub]->code);
  4240.         for(j=0;j<cfg.area[i].uplinks;j++)
  4241.             printf(" %s",faddrtoa(cfg.area[i].uplink[j]));
  4242.         printf("\n"); }
  4243. #endif
  4244.  
  4245. if(misc&GEN_NOTIFY_LIST) {
  4246. printf("\nGenerating Notify Lists...\n");
  4247. notify_list(); }
  4248.  
  4249. /* Find any packets that have been left behind in the OUTBOUND directory */
  4250. printf("\nScanning for Stray Outbound Packets...\n");
  4251. sprintf(path,"%s*.PK_",cfg.outbound);
  4252. for(l=_dos_findfirst(path,0,&ff);!l && !kbhit();l=_dos_findnext(&ff)) {
  4253.     sprintf(packet,"%s%s",cfg.outbound,ff.name);
  4254.     printf("%21s: %s ","Outbound Packet",packet);
  4255.     if((fmsg=sopen(packet,O_RDWR,SH_DENYRW))==-1) {
  4256.         printf("ERROR opening.\n");
  4257.         logprintf("ERROR line %d opening %s",__LINE__,packet);
  4258.         continue; }
  4259.     if((fidomsg=fdopen(fmsg,"r+b"))==NULL) {
  4260.         close(fmsg);
  4261.         printf("\7ERROR fdopening.\n");
  4262.         logprintf("ERROR line %d fdopening %s",__LINE__,packet);
  4263.         continue; }
  4264.     if(filelength(fmsg)<sizeof(pkthdr_t)) {
  4265.         printf("ERROR invalid length of %u bytes for %s\n",filelength(fmsg)
  4266.             ,packet);
  4267.         logprintf("ERROR line %d invalid length of %u bytes for %s"
  4268.             ,__LINE__,filelength(fmsg),packet);
  4269.         fclose(fidomsg);
  4270.         if(delfile(packet))
  4271.             logprintf("ERROR line %d removing %s %s",__LINE__,packet
  4272.                 ,sys_errlist[errno]);
  4273.         continue; }
  4274.     if(fread(&pkthdr,sizeof(pkthdr_t),1,fidomsg)!=1) {
  4275.         fclose(fidomsg);
  4276.         printf("\7ERROR reading %u bytes from %s\n",sizeof(pkthdr_t),packet);
  4277.         logprintf("ERROR line %d reading %u bytes from %s",__LINE__
  4278.             ,sizeof(pkthdr_t),packet);
  4279.         continue; }
  4280.     if((ddtol(ff.wr_time,ff.wr_date)+(60L*60L))<=time(NULL)) {
  4281.         fseek(fidomsg,-3L,SEEK_END);
  4282.         fread(str,3,1,fidomsg);
  4283.         if(str[2])                        /* No ending NULL, probably junk */
  4284.             fputc(0,fidomsg);
  4285.         if(str[1])
  4286.             fputc(0,fidomsg);
  4287.         if(str[0])
  4288.             fputc(0,fidomsg);
  4289.         fclose(fidomsg);
  4290.         pkt_faddr.zone=pkthdr.destzone;
  4291.         pkt_faddr.net=pkthdr.destnet;
  4292.         pkt_faddr.node=pkthdr.destnode;
  4293.         pkt_faddr.point=0;                /* No point info in the 2.0 hdr! */
  4294.         memcpy(&two_plus,&pkthdr.empty,20);
  4295.         if(two_plus.cword==_rotr(two_plus.cwcopy,8)  /* 2+ Packet Header */
  4296.             && two_plus.cword && two_plus.cword&1)
  4297.             pkt_faddr.point=two_plus.destpoint;
  4298.         else if(pkthdr.baud==2) {                /* Type 2.2 Packet Header */
  4299.             memcpy(&two_two,&pkthdr.empty,20);
  4300.             pkt_faddr.point=pkthdr.month; }
  4301.         printf("Sending to %s\n",faddrtoa(pkt_faddr));
  4302.         pack_bundle(packet,pkt_faddr); }
  4303.     else {
  4304.         fclose(fidomsg);
  4305.         printf("Possibly still in use\n"); } }
  4306. #ifdef __WATCOMC__
  4307. _dos_findclose(&ff);
  4308. #endif
  4309.  
  4310. if(misc&IMPORT_PACKETS) {
  4311.  
  4312. printf("\nScanning for Inbound Packets...\n");
  4313.  
  4314. /* We want to loop while there are bundles waiting for us, but first we want */
  4315. /* to take care of any packets that may already be hanging around for some     */
  4316. /* reason or another (thus the do/while loop) */
  4317.  
  4318. echomail=0;
  4319. for(secure=0;secure<2;secure++) {
  4320.     if(secure && !cfg.secure[0])
  4321.         break;
  4322. do {
  4323. /****** START OF IMPORT PKT ROUTINE ******/
  4324.  
  4325. sprintf(path,"%s*.PKT",secure ? cfg.secure : cfg.inbound);
  4326. for(l=_dos_findfirst(path,0,&ff);!l && !kbhit();l=_dos_findnext(&ff)) {
  4327.  
  4328.     sprintf(packet,"%s%s",secure ? cfg.secure : cfg.inbound,ff.name);
  4329.  
  4330.     if((fidomsg=fnopen(&fmsg,packet,O_RDWR))==NULL) {
  4331.         printf("\7ERROR opening %s\n",packet);
  4332.         logprintf("ERROR line %d opening %s %s",__LINE__,packet
  4333.             ,sys_errlist[errno]);
  4334.         continue; }
  4335.     if(filelength(fmsg)<sizeof(pkthdr_t)) {
  4336.         printf("\7Invalid length of %u bytes\n",filelength(fmsg));
  4337.         fclose(fidomsg);
  4338.         continue; }
  4339.  
  4340.     fseek(fidomsg,-2L,SEEK_END);
  4341.     fread(str,2,1,fidomsg);
  4342.     if((str[0] || str[1]) &&
  4343.         (ddtol(ff.wr_time,ff.wr_date)+(48L*60L*60L))<=time(NULL)) {
  4344.         fclose(fidomsg);
  4345.         printf("\7ERROR packet %s not terminated correctly\n",packet);
  4346.         logprintf("ERROR line %d packet %s not terminated correctly",__LINE__
  4347.             ,packet);
  4348.         continue; }
  4349.     fseek(fidomsg,0L,SEEK_SET);
  4350.     if(fread(&pkthdr,sizeof(pkthdr_t),1,fidomsg)!=1) {
  4351.         fclose(fidomsg);
  4352.         printf("\7ERROR reading %u bytes\n",sizeof(pkthdr_t));
  4353.         logprintf("ERROR line %d reading %u bytes from %s",__LINE__
  4354.             ,sizeof(pkthdr_t),packet);
  4355.         continue; }
  4356.  
  4357.     pkt_faddr.zone=pkthdr.origzone ? pkthdr.origzone:sys_faddr.zone;
  4358.     pkt_faddr.net=pkthdr.orignet;
  4359.     pkt_faddr.node=pkthdr.orignode;
  4360.     pkt_faddr.point=0;
  4361.  
  4362.     printf("%21s: %s "
  4363.         ,secure ? "Importing Secure Pkt" : "Importing Packet",ff.name);
  4364.     memcpy(&two_plus,&pkthdr.empty,20);
  4365.     if(two_plus.cword==_rotr(two_plus.cwcopy,8)  /* 2+ Packet Header */
  4366.         && two_plus.cword && two_plus.cword&1) {
  4367.         pkt_type=PKT_TWO_PLUS;
  4368.         pkt_faddr.point=two_plus.origpoint ? two_plus.origpoint:0;
  4369.         if(pkt_faddr.point && pkthdr.orignet==-1)
  4370.             pkt_faddr.net=two_plus.auxnet ? two_plus.auxnet:sys_faddr.zone;
  4371.         printf("(Type 2+)");
  4372.         if(cfg.log&LOG_PACKETS)
  4373.             logprintf("Importing %s%s (Type 2+) from %s"
  4374.                 ,secure ? "(secure) ":"",ff.name,faddrtoa(pkt_faddr)); }
  4375.     else if(pkthdr.baud==2) {                /* Type 2.2 Packet Header */
  4376.         pkt_type=PKT_TWO_TWO;
  4377.         memcpy(&two_two,&pkthdr.empty,20);
  4378.         pkt_faddr.point=pkthdr.year ? pkthdr.year:0;
  4379.         printf("(Type 2.2)");
  4380.         if(cfg.log&LOG_PACKETS)
  4381.             logprintf("Importing %s%s (Type 2.2) from %s"
  4382.                 ,secure ? "(secure) ":"",ff.name,faddrtoa(pkt_faddr)); }
  4383.     else {
  4384.         pkt_type=PKT_TWO;
  4385.         printf("(Type 2)");
  4386.         if(cfg.log&LOG_PACKETS)
  4387.             logprintf("Importing %s%s (Type 2) from %s"
  4388.                 ,secure ? "(secure) ":"",ff.name,faddrtoa(pkt_faddr)); }
  4389.  
  4390.     printf(" from %s\n",faddrtoa(pkt_faddr));
  4391.  
  4392.     if(misc&SECURE) {
  4393.         k=matchnode(pkt_faddr,1);
  4394.         if(k<cfg.nodecfgs && cfg.nodecfg[k].pktpwd[0] &&
  4395.             stricmp(pkthdr.password,cfg.nodecfg[k].pktpwd)) {
  4396.             sprintf(str,"Packet %s from %s - "
  4397.                 "Incorrect password ('%s' instead of '%s')"
  4398.                 ,ff.name,faddrtoa(pkt_faddr)
  4399.                 ,pkthdr.password,cfg.nodecfg[k].pktpwd);
  4400.             printf("Security Violation (Incorrect Password)\n");
  4401.             if(cfg.log&LOG_SECURITY)
  4402.                 logprintf(str);
  4403.             fclose(fidomsg);
  4404.             continue; } }
  4405.  
  4406.     while(!feof(fidomsg)) {
  4407.  
  4408.         memset(&hdr,0,sizeof(fmsghdr_t));
  4409.  
  4410.         if(start_tick)
  4411.             import_ticks+=clock()-start_tick;
  4412.         start_tick=clock();
  4413.  
  4414.         if(fmsgbuf) {
  4415.             FREE(fmsgbuf);
  4416.             fmsgbuf=0; }
  4417.         if(misc&CHECKMEM)
  4418.             checkmem();
  4419.         if(!fread(&ch,1,1,fidomsg))          /* Message type (0200h) */
  4420.             break;
  4421.         if(ch!=02)
  4422.             continue;
  4423.         if(!fread(&ch,1,1,fidomsg))
  4424.             break;
  4425.         if(ch!=00)
  4426.             continue;
  4427.         fread(&hdr.orignode,2,1,fidomsg);
  4428.         fread(&hdr.destnode,2,1,fidomsg);
  4429.         fread(&hdr.orignet,2,1,fidomsg);
  4430.         fread(&hdr.destnet,2,1,fidomsg);
  4431.         fread(&hdr.attr,2,1,fidomsg);
  4432.         fread(&hdr.cost,2,1,fidomsg);
  4433.  
  4434.         grunged=0;
  4435.  
  4436.         for(i=0;i<sizeof(hdr.time);i++)         /* Read in the Date/Time */
  4437.             if(!fread(hdr.time+i,1,1,fidomsg) || !hdr.time[i])
  4438.                 break;
  4439.         if(i==sizeof(hdr.time)) grunged=1;
  4440.  
  4441.         for(i=0;!grunged && i<sizeof(hdr.to);i++) /* Read in the 'To' Field */
  4442.             if(!fread(hdr.to+i,1,1,fidomsg) || !hdr.to[i])
  4443.                 break;
  4444.         if(i==sizeof(hdr.to)) grunged=1;
  4445.  
  4446.         for(i=0;!grunged && i<sizeof(hdr.from);i++) /* Read in 'From' Field */
  4447.             if(!fread(hdr.from+i,1,1,fidomsg) || !hdr.from[i])
  4448.                 break;
  4449.         if(i==sizeof(hdr.from)) grunged=1;
  4450.  
  4451.         for(i=0;!grunged && i<sizeof(hdr.subj);i++) /* Read in 'Subj' Field */
  4452.             if(!fread(hdr.subj+i,1,1,fidomsg) || !hdr.subj[i])
  4453.                 break;
  4454.         if(i==sizeof(hdr.subj)) grunged=1;
  4455.  
  4456.         str[0]=0;
  4457.         for(i=0;!grunged && i<sizeof(str);i++)    /* Read in the 'AREA' Field */
  4458.             if(!fread(str+i,1,1,fidomsg) || str[i]==CR)
  4459.                 break;
  4460.         if(i<sizeof(str))
  4461.             str[i]=0;
  4462.         else
  4463.             grunged=1;
  4464.  
  4465.         if(!str[0] || grunged) {
  4466.             start_tick=0;
  4467.             if(cfg.log&LOG_GRUNGED)
  4468.                 logprintf("Grunged message");
  4469.             seektonull(fidomsg);
  4470.             printf("Grunged message!\n");
  4471.             continue; }
  4472.  
  4473.         if(i)
  4474.             fseek(fidomsg,(long)-(i+1),SEEK_CUR);
  4475.  
  4476.         truncsp(str);
  4477.         strupr(str);
  4478.         p=strstr(str,"AREA:");
  4479.         if(!p) {                    /* Netmail */
  4480.             start_tick=0;
  4481.             if(import_netmail("",hdr,fidomsg))
  4482.                 seektonull(fidomsg);
  4483.             printf("\n");
  4484.             continue; }
  4485.  
  4486.         if(!(misc&IMPORT_ECHOMAIL)) {
  4487.             start_tick=0;
  4488.             printf("EchoMail Ignored");
  4489.             seektonull(fidomsg);
  4490.             printf("\n");
  4491.             continue; }
  4492.  
  4493.         p+=5;                                /* Skip "AREA:" */
  4494.         while(*p && *p<=SP) p++;            /* Skip any white space */
  4495.         printf("%21s: ",p);                 /* Show areaname: */
  4496.         sprintf(areatagstr,"%.128s",p);
  4497.         strupr(p);
  4498.         areatag=crc32(p);
  4499.  
  4500.         for(i=0;i<cfg.areas;i++)                /* Do we carry this area? */
  4501.             if(cfg.area[i].tag==areatag) {
  4502.                 if(cfg.area[i].sub!=INVALID_SUB)
  4503.                     printf("%s ",sub[cfg.area[i].sub]->code);
  4504.                 else
  4505.                     printf("(Passthru) ");
  4506.                 fmsgbuf=getfmsg(fidomsg,NULL);
  4507.                 gen_psb(&msg_seen,&msg_path,fmsgbuf,pkthdr.destzone);
  4508.                 break; }
  4509.  
  4510.         if(i==cfg.areas) {
  4511.             printf("(Unknown) ");
  4512.             if(cfg.badecho>=0) {
  4513.                 i=cfg.badecho;
  4514.                 if(cfg.area[i].sub!=INVALID_SUB)
  4515.                     printf("%s ",sub[cfg.area[i].sub]->code);
  4516.                 else
  4517.                     printf("(Passthru) ");
  4518.                 fmsgbuf=getfmsg(fidomsg,NULL);
  4519.                 gen_psb(&msg_seen,&msg_path,fmsgbuf,pkthdr.destzone); }
  4520.             else {
  4521.                 start_tick=0;
  4522.                 printf("Skipped\n");
  4523.                 seektonull(fidomsg);
  4524.                 continue; } }
  4525.  
  4526.         if(misc&SECURE && cfg.area[i].sub!=INVALID_SUB) {
  4527.             for(j=0;j<cfg.area[i].uplinks;j++)
  4528.                 if(!memcmp(&cfg.area[i].uplink[j],&pkt_faddr,sizeof(faddr_t)))
  4529.                     break;
  4530.             if(j==cfg.area[i].uplinks) {
  4531.                 if(cfg.log&LOG_SECURITY)
  4532.                     logprintf("%s: Security violation - %s not in AREAS.BBS"
  4533.                         ,areatagstr,faddrtoa(pkt_faddr));
  4534.                 printf("Security Violation (Not in AREAS.BBS)\n");
  4535.                 seektonull(fidomsg);
  4536.                 continue; } }
  4537.  
  4538.         /* From here on out, i = area number and area[i].sub = sub number */
  4539.  
  4540.         memcpy(&curarea,&cfg.area[i],sizeof(areasbbs_t));
  4541.         curarea.name=areatagstr;
  4542.  
  4543.         if(cfg.area[i].sub==INVALID_SUB) {            /* Passthru */
  4544.             start_tick=0;
  4545.             strip_psb(fmsgbuf);
  4546.             pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen,msg_path,0);
  4547.             printf("\n");
  4548.             continue; }                         /* On to the next message */
  4549.  
  4550.  
  4551.         for(j=0;j<total_faddrs;j++)
  4552.             if(check_psb(msg_path,faddr[j]))
  4553.                 break;
  4554.         if(j<total_faddrs) {
  4555.             start_tick=0;
  4556.             printf("Circular path (%s) ",faddrtoa(faddr[j]));
  4557.             cfg.area[i].circular++;
  4558.             if(cfg.log&LOG_CIRCULAR)
  4559.                 logprintf("%s: Circular path detected for %s"
  4560.                     ,areatagstr,faddrtoa(faddr[j]));
  4561.             strip_psb(fmsgbuf);
  4562.             pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen,msg_path,0);
  4563.             printf("\n");
  4564.             continue; }
  4565.  
  4566. #if 0 // Allen's way (broken?)
  4567.         for(j=0;j<num_open;j++)
  4568.             if(openbase[j]==cfg.area[i].sub)
  4569.                 break;
  4570.         if(j && j<num_open) {
  4571.             cur_smb=j;
  4572.             k=openbase[0];
  4573.             openbase[0]=openbase[j];
  4574.             openbase[j]=k; }
  4575.         else if(j && j==num_open && j<MAX_OPEN_SMBS) {
  4576.             cur_smb=j;
  4577.             openbase[j]=openbase[0];
  4578.             openbase[0]=INVALID_SUB; }
  4579.         else if(j==num_open && j>=MAX_OPEN_SMBS) {
  4580.             cur_smb=j-1;
  4581.             k=openbase[0];
  4582.             openbase[0]=openbase[j-1];
  4583.             openbase[j-1]=k; }
  4584.  
  4585.         if(openbase[0]!=cfg.area[i].sub) {
  4586.             if(openbase[0]!=INVALID_SUB) {
  4587.                 smb_close(&smb[cur_smb]);
  4588.                 --num_open; }
  4589. #endif
  4590.  
  4591.         // Rob's way
  4592.         for(j=0;j<MAX_OPEN_SMBS;j++)
  4593.             if(subnum[j]==cfg.area[i].sub)
  4594.                 break;
  4595.         if(j<MAX_OPEN_SMBS)                 /* already open */
  4596.             cur_smb=j;
  4597.         else {
  4598.             if(smb[cur_smb].shd_fp)         /* If open */
  4599.                 cur_smb=!cur_smb;            /* toggle between 0 and 1 */
  4600.             smb_close(&smb[cur_smb]);        /* close, if open */
  4601.             subnum[cur_smb]=INVALID_SUB; }    /* reset subnum (just incase) */
  4602.  
  4603.         if(smb[cur_smb].shd_fp==NULL) {     /* Currently closed */
  4604.             sprintf(smb[cur_smb].file,"%s%s",sub[cfg.area[i].sub]->data_dir
  4605.                 ,sub[cfg.area[i].sub]->code);
  4606.             smb[cur_smb].retry_time=smb_retry_time;
  4607.             if((j=smb_open(&smb[cur_smb]))!=0) {
  4608.                 sprintf(str,"ERROR %d opening %s area #%d, sub #%d)"
  4609.                     ,j,smb[cur_smb].file,i+1,cfg.area[i].sub+1);
  4610.                 printf(str);
  4611.                 logprintf(str);
  4612.                 strip_psb(fmsgbuf);
  4613.                 pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen
  4614.                     ,msg_path,0);
  4615.                 printf("\n");
  4616.                 continue; }
  4617.             if(!filelength(fileno(smb[cur_smb].shd_fp))) {
  4618.                 smb[cur_smb].status.max_crcs=sub[cfg.area[i].sub]->maxcrcs;
  4619.                 smb[cur_smb].status.max_msgs=sub[cfg.area[i].sub]->maxmsgs;
  4620.                 smb[cur_smb].status.max_age=sub[cfg.area[i].sub]->maxage;
  4621.                 smb[cur_smb].status.attr=sub[cfg.area[i].sub]->misc&SUB_HYPER
  4622.                         ? SMB_HYPERALLOC:0;
  4623.                 if((j=smb_create(&smb[cur_smb]))!=0) {
  4624.                     sprintf(str,"ERROR %d creating %s",j,smb[cur_smb].file);
  4625.                     printf(str);
  4626.                     logprintf(str);
  4627.                     smb_close(&smb[cur_smb]);
  4628.                     strip_psb(fmsgbuf);
  4629.                     pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen
  4630.                         ,msg_path,0);
  4631.                     printf("\n");
  4632.                     continue; } }
  4633.  
  4634. #if 0    // Unnecessary with SMBLIB v2.0
  4635.  
  4636.             if((j=smb_locksmbhdr(&smb[cur_smb]))!=0) {
  4637.                 printf("ERROR %d locking %s smbhdr\n",j,smb[cur_smb].file);
  4638.                 logprintf("ERROR %d line %d locking %s smbhdr",j,__LINE__
  4639.                     ,smb[cur_smb].file);
  4640.                 smb_close(&smb[cur_smb]);
  4641.                 strip_psb(fmsgbuf);
  4642.                 pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen
  4643.                     ,msg_path,0);
  4644.                 printf("\n");
  4645.                 continue; }
  4646.  
  4647.             if((j=smb_getstatus(&smb[cur_smb]))!=0) {
  4648.                 sprintf(str,"ERROR %d reading %s SMB header",j
  4649.                     ,smb[cur_smb].file);
  4650.                 printf(str);
  4651.                 logprintf(str);
  4652.                 smb_unlocksmbhdr(&smb[cur_smb]);
  4653.                 smb_close(&smb[cur_smb]);
  4654.                 strip_psb(fmsgbuf);
  4655.                 pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen
  4656.                     ,msg_path,0);
  4657.                 printf("\n");
  4658.                 continue; }
  4659.  
  4660.             smb_unlocksmbhdr(&smb[cur_smb]);
  4661. #endif
  4662.             //openbase[0]=cfg.area[i].sub;
  4663.             //++num_open;
  4664.             subnum[cur_smb]=cfg.area[i].sub;
  4665.             }
  4666.  
  4667.         if(hdr.attr&FIDO_PRIVATE && !(sub[cfg.area[i].sub]->misc&SUB_PRIV)) {
  4668.             if(misc&IMPORT_PRIVATE)
  4669.                 hdr.attr&=~FIDO_PRIVATE;
  4670.             else {
  4671.                 start_tick=0;
  4672.                 printf("Private posts disallowed.");
  4673.                 if(cfg.log&LOG_PRIVATE)
  4674.                     logprintf("%s: Private posts disallowed"
  4675.                         ,areatagstr);
  4676.                 strip_psb(fmsgbuf);
  4677.                 pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen
  4678.                     ,msg_path,0);
  4679.                 printf("\n");
  4680.                 continue; } }
  4681.  
  4682.         if(!(hdr.attr&FIDO_PRIVATE) && sub[cfg.area[i].sub]->misc&SUB_PONLY)
  4683.             hdr.attr|=MSG_PRIVATE;
  4684.  
  4685.         /**********************/
  4686.         /* Importing EchoMail */
  4687.         /**********************/
  4688.         j=fmsgtosmsg(fmsgbuf,hdr,0,cfg.area[i].sub);
  4689.  
  4690.         if(start_tick) {
  4691.             import_ticks+=clock()-start_tick;
  4692.             start_tick=0; }
  4693.  
  4694.         if(j==-1) {
  4695.             if(cfg.log&LOG_DUPES)
  4696.                 logprintf("%s Duplicate message",areatagstr);
  4697.             cfg.area[i].dupes++; }
  4698.         else {       /* Not a dupe */
  4699.             strip_psb(fmsgbuf);
  4700.             pkt_to_pkt(fmsgbuf,curarea,pkt_faddr
  4701.                 ,hdr,msg_seen,msg_path,0); }
  4702.  
  4703.         if(j==1) {        /* Successful import */
  4704.             echomail++;
  4705.             cfg.area[i].imported++;
  4706.             if(misc&NOTIFY_RECEIPT && (m=matchname(hdr.to))!=0) {
  4707.                 sprintf(str
  4708.                 ,"\7\1n\1hSBBSecho: \1m%.36s \1n\1msent you EchoMail on "
  4709.                     "\1h%s \1n\1m%s\1n\r\n"
  4710.                     ,hdr.from
  4711.                     ,grp[sub[cfg.area[i].sub]->grp]->sname
  4712.                     ,sub[cfg.area[i].sub]->sname);
  4713.                 putsmsg(m,str); } }
  4714.         printf("\n");
  4715.         }
  4716.     fclose(fidomsg);
  4717.     if(misc&DELETE_PACKETS)
  4718.         if(delfile(packet))
  4719.             logprintf("ERROR line %d removing %s %s",__LINE__,packet
  4720.                 ,sys_errlist[errno]); }
  4721. #ifdef __WATCOMC__
  4722. _dos_findclose(&ff);
  4723. #endif
  4724.  
  4725. if(start_tick) {
  4726.     import_ticks+=clock()-start_tick;
  4727.     start_tick=0; }
  4728.  
  4729. } while(!kbhit() && unpack_bundle());
  4730.  
  4731. if(kbhit()) printf("\nKey pressed - premature termination\n");
  4732. while(kbhit()) getch();
  4733.  
  4734. }    /* End of Secure : Inbound loop */
  4735.  
  4736. if(start_tick)    /* Last possible increment of import_ticks */
  4737.     import_ticks+=clock()-start_tick;
  4738.  
  4739. for(j=MAX_OPEN_SMBS;j>0;j--)        /* Close open bases */
  4740.     if(smb[j].shd_fp)
  4741.         smb_close(&smb[j]);
  4742.  
  4743. pkt_to_pkt(fmsgbuf,fakearea,pkt_faddr,hdr,msg_seen,msg_path,1);
  4744.  
  4745. /******* END OF IMPORT PKT ROUTINE *******/
  4746.  
  4747. if(cfg.log&LOG_AREA_TOTALS) {
  4748.     for(i=0;i<cfg.areas;i++) {
  4749.         if(cfg.area[i].imported)
  4750.             logprintf("Imported: %5u msgs %8s <- %s"
  4751.                 ,cfg.area[i].imported,sub[cfg.area[i].sub]->code
  4752.                 ,cfg.area[i].name); }
  4753.     for(i=0;i<cfg.areas;i++) {
  4754.         if(cfg.area[i].circular)
  4755.             logprintf("Circular: %5u detected in %s"
  4756.                 ,cfg.area[i].circular,cfg.area[i].name); }
  4757.     for(i=0;i<cfg.areas;i++) {
  4758.         if(cfg.area[i].dupes)
  4759.             logprintf("Duplicate: %5u detected in %s"
  4760.                 ,cfg.area[i].dupes,cfg.area[i].name); } }
  4761.  
  4762. import_time=((float)import_ticks)/(float)CLK_TCK;
  4763. if(cfg.log&LOG_TOTALS && import_time && echomail) {
  4764.     printf("\nImported %lu EchoMail messages in %.1f seconds "
  4765.         ,echomail,import_time);
  4766.     logprintf("Imported: %5lu msgs in %.1f sec (%.1f/min %.1f/sec)"
  4767.         ,echomail,import_time
  4768.         ,import_time/60.0 ? (float)echomail/(import_time/60.0) :(float)echomail
  4769.         ,(float)echomail/import_time);
  4770.     if(import_time/60.0)
  4771.         printf("(%.1f/min) ",(float)echomail/(import_time/60.0));
  4772.     printf("(%.1f/sec)\n",(float)echomail/import_time); }
  4773. if(fmsgbuf) {
  4774.     FREE(fmsgbuf);
  4775.     fmsgbuf=0; }
  4776.  
  4777. }
  4778.  
  4779. if(misc&IMPORT_NETMAIL) {
  4780.  
  4781. printf("\nScanning for Inbound NetMail Messages...\n");
  4782.  
  4783. sprintf(str,"%s*.MSG",netmail_dir);
  4784.  
  4785. for(last=_dos_findfirst(str,0,&ff);!last;last=_dos_findnext(&ff)) {
  4786.     sprintf(path,"%s%s",netmail_dir,ff.name);
  4787.     strupr(path);
  4788.     if((fidomsg=fnopen(&fmsg,path,O_RDWR))==NULL) {
  4789.         printf("\7ERROR opening %s\n",path);
  4790.         logprintf("ERROR line %d opening %s %s",__LINE__,path
  4791.             ,sys_errlist[errno]);
  4792.         continue; }
  4793.     if(filelength(fmsg)<sizeof(fmsghdr_t)) {
  4794.         printf("\7ERROR invalid length of %u bytes for %s\n",filelength(fmsg)
  4795.             ,path);
  4796.         logprintf("ERROR line %d invalid length of %u bytes for %s",__LINE__
  4797.             ,filelength(fmsg),path);
  4798.         fclose(fidomsg);
  4799.         continue; }
  4800.     if(fread(&hdr,sizeof(fmsghdr_t),1,fidomsg)!=1) {
  4801.         fclose(fidomsg);
  4802.         printf("\7ERROR reading %u bytes from %s"
  4803.             ,sizeof(fmsghdr_t),path);
  4804.         logprintf("ERROR line %d reading %u bytes from %s",__LINE__
  4805.             ,sizeof(fmsghdr_t),path);
  4806.         continue; }
  4807.     i=import_netmail(path,hdr,fidomsg);
  4808.     /**************************************/
  4809.     /* Delete source netmail if specified */
  4810.     /**************************************/
  4811.     if(i==0) {
  4812.         if(misc&DELETE_NETMAIL) {
  4813.             fclose(fidomsg);
  4814.             if(delfile(path))
  4815.                 logprintf("ERROR line %d removing %s %s",__LINE__,path
  4816.                     ,sys_errlist[errno]); }
  4817.         else {
  4818.             hdr.attr|=FIDO_RECV;
  4819.             fseek(fidomsg,0L,SEEK_SET);
  4820.             fwrite(&hdr,sizeof(fmsghdr_t),1,fidomsg);
  4821.             fclose(fidomsg); } }
  4822.     else if(i!=-2)
  4823.         fclose(fidomsg);
  4824.     printf("\n"); }
  4825. #ifdef __WATCOMC__
  4826. _dos_findclose(&ff);
  4827. #endif
  4828. }
  4829.  
  4830.  
  4831. if(misc&EXPORT_ECHOMAIL) {
  4832.     memset(&addr,0,sizeof(faddr_t));
  4833.     export_echomail(sub_code,addr);
  4834. }
  4835.  
  4836.  
  4837. if(misc&PACK_NETMAIL) {
  4838.  
  4839. memset(&msg_seen,0,sizeof(addrlist_t));
  4840. memset(&msg_path,0,sizeof(addrlist_t));
  4841. memset(&fakearea,0,sizeof(areasbbs_t));
  4842.  
  4843. printf("\nPacking Outbound NetMail...\n");
  4844.  
  4845. sprintf(str,"%s*.MSG",netmail_dir);
  4846.  
  4847. for(last=_dos_findfirst(str,0,&ff);!last;last=_dos_findnext(&ff)) {
  4848.     sprintf(path,"%s%s",netmail_dir,ff.name);
  4849.     strupr(path);
  4850.     if((fidomsg=fnopen(&fmsg,path,O_RDWR))==NULL) {
  4851.         printf("\7ERROR opening %s\n",path);
  4852.         logprintf("ERROR line %d opening %s %s",__LINE__,path
  4853.             ,sys_errlist[errno]);
  4854.         continue; }
  4855.     if(filelength(fmsg)<sizeof(fmsghdr_t)) {
  4856.         printf("\7%s Invalid length of %u bytes\n",path,filelength(fmsg));
  4857.         fclose(fidomsg);
  4858.         continue; }
  4859.     if(fread(&hdr,sizeof(fmsghdr_t),1,fidomsg)!=1) {
  4860.         fclose(fidomsg);
  4861.         printf("\7ERROR reading %u bytes from %s"
  4862.             ,sizeof(fmsghdr_t),path);
  4863.         logprintf("ERROR line %d reading %u bytes from %s",__LINE__
  4864.             ,sizeof(fmsghdr_t),path);
  4865.         continue; }
  4866.     hdr.destzone=hdr.origzone=sys_faddr.zone;
  4867.     hdr.destpoint=hdr.origpoint=0;
  4868.     getzpt(fidomsg,&hdr);                /* use kludge if found */
  4869.     addr.zone=hdr.destzone;
  4870.     addr.net=hdr.destnet;
  4871.     addr.node=hdr.destnode;
  4872.     addr.point=hdr.destpoint;
  4873.     for(i=0;i<total_faddrs;i++)
  4874.         if(!memcmp(&addr,&faddr[i],sizeof(faddr_t)))
  4875.             break;
  4876.     if(i<total_faddrs)                      /* In-bound, so ignore */
  4877.         continue;
  4878.     printf("\n%s to %s ",path,faddrtoa(addr));
  4879.     if(cfg.log&LOG_PACKING)
  4880.         logprintf("Packing %s (%s)",path,faddrtoa(addr));
  4881.     fmsgbuf=getfmsg(fidomsg,NULL);
  4882.     if(!fmsgbuf) {
  4883.         printf("ERROR allocating memory for NetMail fmsgbuf\n");
  4884.         logprintf("ERROR line %d allocating memory for NetMail fmsgbuf"
  4885.             ,__LINE__);
  4886.         exit(1); }
  4887.     fclose(fidomsg);
  4888.  
  4889.     if(misc&FLO_MAILER) {
  4890.         attr=0;
  4891.         i=matchnode(addr,0);
  4892.         if(i<cfg.nodecfgs)
  4893.             if(cfg.nodecfg[i].route.zone
  4894.                 && !(hdr.attr&(FIDO_CRASH|FIDO_HOLD))) {
  4895.                 addr=cfg.nodecfg[i].route;        /* Routed */
  4896.                 if(cfg.log&LOG_ROUTING)
  4897.                     logprintf("Routing %s to %s",path,faddrtoa(addr));
  4898.                 i=matchnode(addr,0); }
  4899.         if(i<cfg.nodecfgs)
  4900.             attr=cfg.nodecfg[i].attr;
  4901.         if(hdr.attr&FIDO_CRASH)
  4902.             attr|=ATTR_CRASH;
  4903.         else if(hdr.attr&FIDO_HOLD)
  4904.             attr|=ATTR_HOLD;
  4905.         if(attr&ATTR_CRASH) ch='C';
  4906.         else if(attr&ATTR_HOLD) ch='H';
  4907.         else if(attr&ATTR_DIRECT) ch='D';
  4908.         else ch='O';
  4909.         if(addr.zone==faddr[0].zone) /* Default zone, use default outbound */
  4910.             strcpy(outbound,cfg.outbound);
  4911.         else                         /* Inter-zone outbound is OUTBOUND.XXX */
  4912.             sprintf(outbound,"%.*s.%03X\\"
  4913.                 ,strlen(cfg.outbound)-1,cfg.outbound,addr.zone);
  4914.         if(addr.point) {            /* Point destination is OUTBOUND.PNT */
  4915.             sprintf(str,"%04X%04X.PNT"
  4916.                 ,addr.net,addr.node);
  4917.             strcat(outbound,str); }
  4918.         if(outbound[strlen(outbound)-1]=='\\')
  4919.             outbound[strlen(outbound)-1]=0;
  4920.         mkdir(outbound);
  4921.         strcat(outbound,"\\");
  4922.         if(addr.point)
  4923.             sprintf(packet,"%s%08X.%cUT",outbound,addr.point,ch);
  4924.         else
  4925.             sprintf(packet,"%s%04X%04X.%cUT",outbound,addr.net,addr.node,ch);
  4926.         if(hdr.attr&FIDO_FILE)
  4927.             if(write_flofile(hdr.subj,addr))
  4928.                 exit(1); }
  4929.     else
  4930.         strcpy(packet,pktname());
  4931.  
  4932.     now=time(NULL);
  4933.     tm=gmtime(&now);
  4934.     if((stream=fnopen(&file,packet,O_WRONLY|O_APPEND|O_CREAT))==NULL) {
  4935.         printf("Unable to open %s for write.\n"
  4936.             ,packet);
  4937.         logprintf("ERROR line %d opening %s %s",__LINE__,packet
  4938.             ,sys_errlist[errno]);
  4939.         exit(1); }
  4940.  
  4941.     if(!filelength(file)) {
  4942.         pkthdr.orignode=hdr.orignode;
  4943.         pkthdr.destnode=hdr.destnode;
  4944.         pkthdr.year=tm->tm_year;
  4945.         pkthdr.month=tm->tm_mon;
  4946.         pkthdr.day=tm->tm_mday;
  4947.         pkthdr.hour=tm->tm_hour;
  4948.         pkthdr.min=tm->tm_min;
  4949.         pkthdr.sec=tm->tm_sec;
  4950.         pkthdr.baud=0x00;
  4951.         pkthdr.pkttype=0x0002;
  4952.         pkthdr.orignet=hdr.orignet;
  4953.         pkthdr.destnet=hdr.destnet;
  4954.         pkthdr.prodcode=0x00;
  4955.         pkthdr.sernum=0;
  4956.         i=matchnode(addr,0);
  4957.         if(i<cfg.nodecfgs)
  4958.             memcpy(pkthdr.password,cfg.nodecfg[i].pktpwd,8);
  4959.         else
  4960.             memset(pkthdr.password,0,8);
  4961.         pkthdr.origzone=hdr.origzone;
  4962.         pkthdr.destzone=hdr.destzone;
  4963.         memset(pkthdr.empty,0,20);
  4964.         fwrite(&pkthdr,sizeof(pkthdr_t),1,stream); }
  4965.  
  4966.     putfmsg(stream,fmsgbuf,hdr,fakearea,msg_seen,msg_path);
  4967.  
  4968.     FREE(fmsgbuf);
  4969.     fclose(stream);
  4970.     /**************************************/
  4971.     /* Delete source netmail if specified */
  4972.     /**************************************/
  4973.     if(misc&DELETE_NETMAIL)
  4974.         if(delfile(path))
  4975.             logprintf("ERROR line %d removing %s %s",__LINE__,path
  4976.                 ,sys_errlist[errno]);
  4977.     printf("\n"); }
  4978. #ifdef __WATCOMC__
  4979. _dos_findclose(&ff);
  4980. #endif
  4981. }
  4982.  
  4983.  
  4984. if(misc&UPDATE_MSGPTRS) {
  4985.  
  4986. printf("\nUpdating Message Pointers to Last Posted Message...\n");
  4987.  
  4988. for(g=0;g<total_grps;g++)
  4989. for(i=0;i<total_subs;i++)
  4990.     if(sub[i]->misc&SUB_FIDO && sub[i]->grp==g) {
  4991.         printf("\n%-15.15s %s\n"
  4992.             ,grp[sub[i]->grp]->sname,sub[i]->lname);
  4993.         getlastmsg(i,&l,0);
  4994.         sprintf(str,"%s%s.SFP",sub[i]->data_dir,sub[i]->code);
  4995.         if((file=nopen(str,O_WRONLY|O_CREAT))==-1) {
  4996.             printf("\7ERROR opening/creating %s",str);
  4997.             logprintf("ERROR line %d opening/creating %s",__LINE__,str); }
  4998.         else {
  4999.             write(file,&l,sizeof(time_t));
  5000.             close(file); } } }
  5001.  
  5002. if(misc&(IMPORT_NETMAIL|IMPORT_ECHOMAIL) && misc&REPORT) {
  5003.     now=time(NULL);
  5004.     sprintf(str,"%sSBBSECHO.MSG",text_dir);
  5005.     if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
  5006.         printf("ERROR opening %s\n",str);
  5007.         logprintf("ERROR line %d opening %s",__LINE__,str);
  5008.         exit(1); }
  5009.     sprintf(fname,"\1c\1h               "
  5010.         "▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\r\n");
  5011.     sprintf(path,"\1c\1h               "
  5012.         "▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\r\n");
  5013.     write(file,fname,strlen(fname));
  5014.     sprintf(str,"               \1n\1k\0016"
  5015.         " Last FidoNet Transfer on %.24s \1n\r\n",ctime(&now));
  5016.     write(file,str,strlen(str));
  5017.     write(file,path,strlen(path));
  5018.     write(file,fname,strlen(fname));
  5019.     sprintf(tmp,"Imported %lu EchoMail and %lu NetMail Messages"
  5020.         ,echomail,netmail);
  5021.     sprintf(str,"               \1n\1k\0016 %-50.50s\1n\r\n",tmp);
  5022.     write(file,str,strlen(str));
  5023.     write(file,path,strlen(path));
  5024.     close(file); }
  5025.  
  5026. pkt_to_pkt(buf,fakearea,pkt_faddr,hdr,msg_seen,msg_path,1);
  5027. if(email->shd_fp)
  5028.     smb_close(email);
  5029. FREE(smb);
  5030. FREE(email);
  5031. return(0);
  5032. }
  5033.