home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / SMM / SMB2SMM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-25  |  25.4 KB  |  969 lines

  1. /* SMB2SMM */
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. /* Scans SMB message base for messages to "SMM" and adds them to the SMM    */
  6. /* database. */
  7.  
  8. #define  uint unsigned int
  9.  
  10. #define LOOP_NOPEN 500
  11.  
  12. #include <dos.h>
  13. #include "smblib.h"
  14. #include "smmdefs.h"
  15. #include "nodedefs.h"
  16. #include "crc32.h"
  17.  
  18. #define VERSION "2.01"
  19.  
  20. extern int daylight=0;
  21. extern long timezone=0L;
  22.  
  23. unsigned _stklen=16000;           /* Set stack size in code, not header */
  24.  
  25. char data_dir[128];
  26.  
  27. smb_t smb;
  28. FILE *trashfile=NULL;
  29.  
  30. uchar cryptchar(uchar ch, ulong seed)
  31. {
  32. if(ch==0xfe)
  33.     return(1);
  34. if(ch<0x20 || ch&0x80)    /* Ctrl chars and ex-ASCII are not xlated */
  35.     return(ch);
  36. return(ch^(seed&0x1f));
  37. }
  38.  
  39. void decrypt(char *str, ulong seed)
  40. {
  41.     char out[1024];
  42.     int i,j;
  43.  
  44. j=strlen(str);
  45. for(i=0;i<j;i++)
  46.     out[i]=cryptchar(str[i],seed^(i&7));
  47. out[i]=0;
  48. strcpy(str,out);
  49. }
  50.  
  51. /****************************************************************************/
  52. /* Returns 32-crc of string (not counting terminating NULL)                 */
  53. /****************************************************************************/
  54. ulong crc32(char *str)
  55. {
  56.     int i=0;
  57.     ulong crc=0xffffffffUL;
  58.  
  59.     while(str[i])
  60.         crc=ucrc32(str[i++],crc);
  61.     crc=~crc;
  62.     return(crc);
  63. }
  64.  
  65. /***************************************************************************/
  66. /* Truncates white-space chars off end of 'str' and terminates at first CR  */
  67. /****************************************************************************/
  68. void truncsp(char *str)
  69. {
  70.     char c;
  71.  
  72. str[strcspn(str,"\r")]=0;
  73. c=strlen(str);
  74. while(c && (uchar)str[c-1]<=SP) c--;
  75. str[c]=0;
  76. }
  77.  
  78. /****************************************************************************/
  79. /* Converts an ASCII Hex string into an ulong                       */
  80. /****************************************************************************/
  81. ulong ahtoul(char *str)
  82. {
  83.     ulong l,val=0;
  84.  
  85. while(*str>' ' && (l=(*str++)|0x20)!=0x20)
  86.     val=(l&0xf)+(l>>6&1)*9+val*16;
  87. return(val);
  88. }
  89.  
  90.  
  91. /****************************************************************************/
  92. /* Checks the disk drive for the existence of a file. Returns 1 if it       */
  93. /* exists, 0 if it doesn't.                                                 */
  94. /****************************************************************************/
  95. char fexist(char *filespec)
  96. {
  97.     struct ffblk f;
  98.  
  99. if(findfirst(filespec,&f,0)==0)
  100.     return(1);
  101. return(0);
  102. }
  103.  
  104. /****************************************************************************/
  105. /* Returns the length of the file in 'filespec'                             */
  106. /****************************************************************************/
  107. long flength(char *filespec)
  108. {
  109.     struct ffblk f;
  110.  
  111. if(findfirst(filespec,&f,0)==0)
  112.     return(f.ff_fsize);
  113. return(-1L);
  114. }
  115.  
  116.  
  117. /****************************************************************************/
  118. /* Converts a date string in format MM/DD/YY into unix time format            */
  119. /****************************************************************************/
  120. time_t dstrtounix(char *str)
  121. {
  122.     struct date date;
  123.     struct time curtime;
  124.  
  125. if(!strncmp(str,"00/00/00",8))
  126.     return(0);
  127. curtime.ti_hour=curtime.ti_min=curtime.ti_sec=0;
  128. if(str[6]<7)
  129.     date.da_year=2000+((str[6]&0xf)*10)+(str[7]&0xf);
  130. else
  131.     date.da_year=1900+((str[6]&0xf)*10)+(str[7]&0xf);
  132. date.da_mon=((str[0]&0xf)*10)+(str[1]&0xf);
  133. date.da_day=((str[3]&0xf)*10)+(str[4]&0xf);
  134. return(dostounix(&date,&curtime));
  135. }
  136.  
  137. /****************************************************************************/
  138. /* Updates 16-bit "rcrc" with character 'ch'                                */
  139. /****************************************************************************/
  140. void ucrc16(uchar ch, ushort *rcrc) {
  141.     ushort i, cy;
  142.     uchar nch=ch;
  143.  
  144. for (i=0; i<8; i++) {
  145.     cy=*rcrc & 0x8000;
  146.     *rcrc<<=1;
  147.     if (nch & 0x80) *rcrc |= 1;
  148.     nch<<=1;
  149.     if (cy) *rcrc ^= 0x1021; }
  150. }
  151.  
  152. /****************************************************************************/
  153. /* Returns the age derived from the string 'birth' in the format MM/DD/YY    */
  154. /****************************************************************************/
  155. char getage(char *birth)
  156. {
  157.     char age;
  158.     struct date date;
  159.  
  160. if(birth[0]<=SP)
  161.     return(0);
  162. getdate(&date);
  163. age=(date.da_year-1900)-(((birth[6]&0xf)*10)+(birth[7]&0xf));
  164. if(atoi(birth)>12 || atoi(birth+3)>31)
  165.     return(0);
  166. if(((birth[0]&0xf)*10)+(birth[1]&0xf)>date.da_mon ||
  167.     (((birth[0]&0xf)*10)+(birth[1]&0xf)==date.da_mon &&
  168.     ((birth[3]&0xf)*10)+(birth[4]&0xf)>date.da_day))
  169.     age--;
  170. if(age<0)
  171.     return(0);
  172. return(age);
  173. }
  174.  
  175. /****************************************************************************/
  176. /* Returns 16-crc of string (not counting terminating NULL)                 */
  177. /****************************************************************************/
  178. ushort crc16(char *str)
  179. {
  180.     int     i=0;
  181.     ushort    crc=0;
  182.  
  183. ucrc16(0,&crc);
  184. while(str[i])
  185.     ucrc16(str[i++],&crc);
  186. ucrc16(0,&crc);
  187. ucrc16(0,&crc);
  188. return(crc);
  189. }
  190.  
  191.  
  192. char *base41(unsigned int i, char *str)
  193. {
  194.     char c;
  195.     unsigned int j=41*41,k;
  196.  
  197. for(c=0;c<3;c++) {
  198.     k=i/j;
  199.     str[c]='0'+k;
  200.     i-=(k*j);
  201.     j/=41;
  202.     if(str[c]>=':')
  203.         str[c]='A'+(str[c]-':');
  204.     if(str[c]>='[')
  205.         str[c]='#'+(str[c]-'['); }
  206. str[c]=0;
  207. return(str);
  208. }
  209.  
  210.  
  211. /****************************************************************************/
  212. /* Network open function. Opens all files DENYALL and retries LOOP_NOPEN    */
  213. /* number of times if the attempted file is already open or denying access  */
  214. /* for some other reason.    All files are opened in BINARY mode.            */
  215. /****************************************************************************/
  216. int nopen(char *str, int access)
  217. {
  218.     char logstr[256];
  219.     int file,share,count=0;
  220.  
  221. if(access&O_DENYNONE) share=O_DENYNONE;
  222. else if(access==O_RDONLY) share=O_DENYWRITE;
  223. else share=O_DENYALL;
  224. while(((file=open(str,O_BINARY|share|access,S_IWRITE))==-1)
  225.     && errno==EACCES && count++<LOOP_NOPEN)
  226.     if(count>10)
  227.        delay(55);
  228. if(file==-1 && errno==EACCES)
  229.     puts("\7\nNOPEN: ACCESS DENIED\n\7");
  230. return(file);
  231. }
  232.  
  233.  
  234. /****************************************************************************/
  235. /* Creates a short message for 'usernumber' than contains 'strin'            */
  236. /****************************************************************************/
  237. void putsmsg(int usernumber, char *strin)
  238. {
  239.     char str[256];
  240.     int file,i;
  241.     struct ffblk ff;
  242.     node_t node;
  243.  
  244. sprintf(str,"%sMSGS\\%4.4u.MSG",data_dir,usernumber);
  245. if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
  246.     printf("\7Error opening/creating %s for creat/append access\n",str);
  247.     return; }
  248. i=strlen(strin);
  249. if(write(file,strin,i)!=i) {
  250.     close(file);
  251.     printf("\7Error writing %u bytes to %s\n",i,str);
  252.     return; }
  253. close(file);
  254. }
  255.  
  256. void puttgram(int usernumber, char *strin)
  257. {
  258.     char str[256];
  259.     int file,i;
  260.     struct ffblk ff;
  261.     node_t node;
  262.  
  263. sprintf(str,"%4.4u.MSG",usernumber);
  264. if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
  265.     printf("\7Error opening/creating %s for creat/append access\n",str);
  266.     return; }
  267. i=strlen(strin);
  268. if(write(file,strin,i)!=i) {
  269.     close(file);
  270.     printf("\7Error writing %u bytes to %s\n",i,str);
  271.     return; }
  272. close(file);
  273. }
  274.  
  275. int trash(char *instr)
  276. {
  277.     char str[1024],word[128];
  278.  
  279. if(!trashfile)
  280.     return(0);
  281. strcpy(str,instr);
  282. strupr(str);
  283. rewind(trashfile);
  284. while(!ferror(trashfile)) {
  285.     if(!fgets(word,125,trashfile))
  286.         break;
  287.     truncsp(word);
  288.     if(!word[0])
  289.         continue;
  290.     strupr(word);
  291.     if(strstr(str,word))
  292.         return(1); }
  293. return(0);
  294. }
  295.  
  296. time_t checktime()
  297. {
  298.     struct tm tm;
  299.  
  300. memset(&tm,0,sizeof(tm));
  301. tm.tm_year=94;
  302. tm.tm_mday=1;
  303. return(mktime(&tm)^0x2D24BD00L);
  304. }
  305.  
  306. int main(int argc, char **argv)
  307. {
  308.     uchar    str[256],system[128],telegram[1024],HUGE16 *buf,HUGE16 *hp, *p
  309.             ,min_age,fname[64],path[128],tmp[128],ch;
  310.     int     i,j,file,out,wallfile,msgfile,tgramonly=0,wallonly=0,esc;
  311.     ulong    l,m,last,high,system_crc,crc,length;
  312.     ushort    smm,smm_photo,touser;
  313.     user_t    user;
  314.     wall_t    wall;
  315.     smbmsg_t msg;
  316.     FILE    *stream,*index,*tmpfile;
  317.     ixb_t    ixb;
  318.  
  319. fprintf(stderr,"\nSMB2SMM v%s - Updates SMM via SMB - Developed 1995-1997 "
  320.     "Rob Swindell\n\n",VERSION);
  321.  
  322. if(checktime()) {
  323.     printf("Time problem!\n");
  324.     return(-1); }
  325.  
  326. if(argc<3) {
  327.     fprintf(stderr,"usage: smb2smm <smb_file> <smm.dab>\n\n");
  328.     fprintf(stderr,"example: smb2smm c:\\sbbs\\data\\subs\\syncdata "
  329.         "c:\\sbbs\\xtrn\\smm\\smm.dab\n");
  330.     return(1); }
  331.  
  332. p=getenv("SBBSNODE");
  333. if(p==NULL) {
  334.     printf("\7\nSBBSNODE environment variable not set.\n");
  335.     exit(1); }
  336. strcpy(str,p);
  337. if(str[strlen(str)-1]!='\\')
  338.     strcat(str,"\\");
  339. strcat(str,"XTRN.DAT");
  340. if((file=nopen(str,O_RDONLY))==-1 || (stream=fdopen(file,"rb"))==NULL) {
  341.     printf("\7\nCan't open %s\n",str);
  342.     exit(1); }
  343. fgets(str,81,stream);        /* user name */
  344. fgets(system,81,stream);    /* system name */
  345. truncsp(system);
  346. fgets(str,81,stream);        /* sysop name */
  347. fgets(str,81,stream);        /* guru name */
  348. fgets(str,81,stream);        /* ctrl dir */
  349. fgets(str,81,stream);        /* data dir */
  350. truncsp(str);
  351. if(str[0]=='.') {
  352.     strcpy(data_dir,p);     /* node dir */
  353.     if(data_dir[strlen(data_dir)-1]!='\\')
  354.         strcat(data_dir,"\\");
  355.     strcat(data_dir,str); }
  356. else
  357.     strcpy(data_dir,str);
  358. fclose(stream);
  359.  
  360. if(argc>3 && !stricmp(argv[3],"/t"))
  361.     tgramonly=1;
  362.  
  363. if(argc>3 && !stricmp(argv[3],"/w"))
  364.     wallonly=1;
  365.  
  366. strcpy(smb.file,argv[1]);
  367. strupr(smb.file);
  368.  
  369. strcpy(str,argv[2]);
  370. strupr(str);
  371. if((file=open(str,O_RDWR|O_BINARY|O_DENYNONE|O_CREAT,S_IWRITE|S_IREAD))==-1) {
  372.     printf("error opening %s\n",str);
  373.     return(1); }
  374. if((stream=fdopen(file,"r+b"))==NULL) {
  375.     printf("error fdopening %s\n",str);
  376.     return(1); }
  377. setvbuf(stream,NULL,_IOFBF,4096);
  378.  
  379. p=strrchr(str,'.');
  380. if(!p) p=str;
  381. else p++;
  382. strcpy(p,"IXB");
  383. if((file=open(str,O_RDWR|O_BINARY|O_DENYNONE|O_CREAT,S_IWRITE|S_IREAD))==-1) {
  384.     printf("error opening %s\n",str);
  385.     return(1); }
  386. if((index=fdopen(file,"r+b"))==NULL) {
  387.     printf("error fdopening %s\n",str);
  388.     return(1); }
  389. setvbuf(index,NULL,_IOFBF,1024);
  390.  
  391. p=strrchr(str,'.');
  392. if(!p) p=str;
  393. else p++;
  394. strcpy(p,"CAN");
  395. trashfile=NULL;
  396. if((file=open(str,O_RDONLY|O_DENYNONE))!=-1) {
  397.     trashfile=fdopen(file,"rb");
  398.     setvbuf(trashfile,NULL,_IOFBF,4096); }
  399.  
  400. p=strrchr(str,'.');
  401. if(!p) p=str;
  402. else p++;
  403. strcpy(p,"CFG");
  404. if((file=nopen(str,O_RDONLY))==-1) {
  405.     printf("error opening %s\n",str);
  406.     return(1); }
  407. if((tmpfile=fdopen(file,"rb"))==NULL) {
  408.     printf("error fdopening %s\n",str);
  409.     return(1); }
  410. fgets(str,128,tmpfile); /* Min purity age */
  411. fgets(str,128,tmpfile); /* Min profile age */
  412. truncsp(str);
  413. min_age=atoi(str);
  414. fclose(tmpfile);
  415.  
  416. sprintf(str,"%s.SMM",smb.file);
  417. if((file=open(str,O_RDWR|O_BINARY|O_CREAT,S_IWRITE|S_IREAD))==-1) {
  418.     printf("error opening %s\n",str);
  419.     return(1); }
  420. if(read(file,&last,4)!=4)
  421.     last=0;
  422. high=last;
  423.  
  424. sprintf(str,"%s.SHD",smb.file);
  425. if(!fexist(str)) {
  426.     printf("%s doesn't exist\n",smb.file);
  427.     return(0); }
  428. sprintf(str,"%s.SID",smb.file);
  429. if(!flength(str)) {
  430.     printf("%s is empty\n",smb.file);
  431.     return(0); }
  432. fprintf(stderr,"Opening %s\n",smb.file);
  433. smb.retry_time=30;
  434. if((i=smb_open(&smb))!=0) {
  435.     printf("smb_open returned %d\n",i);
  436.     return(1); }
  437.  
  438. smm=crc16("smm");
  439. smm_photo=crc16("smm photo");
  440.  
  441. if((i=smb_locksmbhdr(&smb))!=0) {                /* Be sure noone deletes or */
  442.     printf("Error locking %d\n",i);             /* adds while we're reading */
  443.     return(1); }
  444.  
  445. rewind(smb.sid_fp);
  446. while(!feof(smb.sid_fp) && !ferror(smb.sid_fp)) {
  447.     if(!fread(&msg.idx,sizeof(idxrec_t),1,smb.sid_fp))
  448.         break;
  449.     fprintf(stderr,"\r#%-5lu  ",msg.idx.number);
  450.     if(msg.idx.to!=smm && msg.idx.to!=smm_photo)
  451.         continue;
  452.     if(msg.idx.number<=last || msg.idx.attr&MSG_DELETE)
  453.         continue;
  454.     high=msg.idx.number;
  455.     if((i=smb_lockmsghdr(&smb,&msg))!=0) {
  456.         printf("\7Error %d locking msg #%lu\n",i,msg.idx.number);
  457.         continue; }
  458.     if((i=smb_getmsghdr(&smb,&msg))!=0) {
  459.         smb_unlockmsghdr(&smb,&msg);
  460.         printf("\7Error %d reading msg #%lu\n",i,msg.idx.number);
  461.         continue; }
  462.  
  463.     smb_unlockmsghdr(&smb,&msg);
  464.     if(!msg.from_net.type || !strnicmp(msg.from,system,25)) { // ignore local msg
  465.         smb_freemsgmem(&msg);
  466.         continue; }
  467.  
  468.     printf("From: %-25.25s  To: %-25.25s  Subj: %s\n"
  469.         ,msg.from,msg.to,msg.subj);
  470.  
  471.     if(msg.idx.to==smm_photo) {
  472.         buf=smb_getmsgtxt(&smb,&msg,0);
  473.         if(!buf) {
  474.             smb_freemsgmem(&msg);
  475.             continue; }
  476.         sprintf(str,"%.4s",msg.subj);
  477.         l=ahtoul(str);
  478.         l^=0x0191;
  479.         sprintf(str,"%.8s",msg.subj+4);
  480.         system_crc=ahtoul(str);
  481.         system_crc^=0x90120e71;
  482.         fprintf(stderr,"Searching...");
  483.  
  484.         rewind(index);
  485.         memset(&user,0,sizeof(user_t));
  486.         while(1) {
  487.             if(!fread(&ixb,sizeof(ixb_t),1,index)) {
  488.                 memset(&user,0,sizeof(user_t));
  489.                 break; }
  490.             if(ixb.number==l && ixb.system==system_crc) {
  491.                 fseek(index,ftell(index)-sizeof(ixb_t),SEEK_SET);
  492.                 fseek(stream,(ftell(index)/sizeof(ixb_t))*sizeof(user_t)
  493.                     ,SEEK_SET);
  494.                 fread(&user,sizeof(user_t),1,stream);
  495.                 break; } }
  496.         fprintf(stderr,"\n");
  497.  
  498.         if(!user.number) {
  499.             printf("Profile Not found\n");
  500.             smb_freemsgmem(&msg);
  501.             continue; }
  502.  
  503.         for(i=0;user.system[i];i++)
  504.             if(isalnum(user.system[i]))
  505.                 break;
  506.         if(!user.system[i])
  507.             fname[0]='~';
  508.         else
  509.             fname[0]=user.system[i];
  510.         for(i=strlen(user.system)-1;i>0;i--)
  511.             if(isalnum(user.system[i]))
  512.                 break;
  513.         if(i<=0)
  514.             fname[1]='~';
  515.         else
  516.             fname[1]=user.system[i];
  517.         fname[2]=0;
  518.         strcpy(str,user.system);
  519.         strupr(str);
  520.         strcat(fname,base41(crc16(str),tmp));
  521.         strcat(fname,base41(user.number,tmp));
  522.         sprintf(str,".%.3s",msg.subj+20);
  523.         strcat(fname,str);
  524.         strupr(fname);
  525.  
  526.         if((out=nopen(fname,O_CREAT|O_WRONLY|O_TRUNC))==-1) {
  527.             printf("Error opening %s\n",fname);
  528.             smb_freemsgmem(&msg);
  529.             continue; }
  530.         
  531.         crc=0xffffffffUL;
  532.         esc=0;
  533.         for(l=0;buf[l]!=CR;l++)
  534.             ;
  535.         buf[l]=0;
  536.         length=ahtoul((char *)buf)^4096;
  537.         l+=2;    /* Skip CRLF */
  538.         for(m=0;buf[l] && m<length;l++) {
  539.             ch=buf[l];
  540.             if(ch<SP)
  541.                 continue;
  542.             if(ch=='`') {
  543.                 if(esc) {
  544.                     write(out,&ch,1);
  545.                     m++;
  546.                     crc=ucrc32(ch,crc);
  547.                     esc=0; }
  548.                 else
  549.                     esc=1;
  550.                 continue; }
  551.             if(esc) {
  552.                 if(isalpha(ch)) {
  553.                     if(isupper(ch))
  554.                         ch-='@';
  555.                     else if(ch=='g')
  556.                         ch=0xe3;
  557.                     else if(ch=='h')
  558.                         ch=0x8d;
  559.                     else if(ch=='i')
  560.                         ch=0xee;
  561.                     else
  562.                         ch=0xfa+(ch-'a'); }
  563.                 else
  564.                     ch=0xf0+(ch-'0');
  565.                 write(out,&ch,1);
  566.                 m++;
  567.                 crc=ucrc32(ch,crc);
  568.                 esc=0;
  569.                 continue; }
  570.             if(ch>=0xf0)
  571.                 ch&=0xf;
  572.             if(ch==0xee)
  573.                 ch=0xff;
  574.             write(out,&ch,1);
  575.             m++;
  576.             crc=ucrc32(ch,crc); }
  577.         close(out);
  578.         crc=~crc;
  579.         crc^=0x05296328L;
  580.         sprintf(str,"%.8s",msg.subj+12);
  581.         smb_freemsgmem(&msg);
  582.         if(crc!=ahtoul(str)) {
  583.             printf("CRC error!\n");
  584.             remove(fname);
  585.             continue; }
  586.         sprintf(path,"PHOTO\\%s",fname);
  587.         mkdir("PHOTO");
  588.         if(rename(fname,path)) {
  589.             printf("Error renaming %s to %s!\n",fname,path);
  590.             remove(fname);
  591.             continue; }
  592.         user.misc|=USER_PHOTO;
  593.         fseek(stream,(ftell(index)/sizeof(ixb_t))*sizeof(user_t),SEEK_SET);
  594.         fwrite(&user,sizeof(user_t),1,stream);
  595.         if(!strnicmp(user.system,system,25))
  596.             putsmsg(user.number
  597.                 ,"\1n\1h\1mYour photo has been imported into "
  598.                     "\1wMatch Maker\1n\7\r\n");
  599.         continue; }
  600.  
  601.     if(!stricmp(msg.subj,"->WALL<-")) {
  602.         buf=smb_getmsgtxt(&smb,&msg,0);
  603.         smb_freemsgmem(&msg);
  604.         if(!buf)
  605.             continue;
  606.         memset(&wall,0,sizeof(wall_t));
  607.         hp=buf;
  608.         while(*hp && *hp<SP) hp++;
  609.         for(i=0;*hp>=SP && i<25;i++,hp++)
  610.             wall.name[i]=*hp;
  611.         wall.name[i]=0;
  612.         hp+=2;     /* Skip CRLF */
  613.         for(i=0;*hp>=SP && i<40;i++,hp++)
  614.             wall.system[i]=*hp;
  615.         wall.system[i]=0;
  616.         hp+=2;     /* Skip CRLF */
  617.         for(i=0;i<5;i++) {
  618.             for(j=0;*hp>=SP && j<70;j++,hp++)
  619.                 wall.text[i][j]=*hp;
  620.             wall.text[i][j]=0;
  621.             hp+=2; }
  622.  
  623.         wall.written=ahtoul((char *)hp);
  624.         wall.imported=time(NULL);
  625.         FREE((char *)buf);
  626.         decrypt(wall.name,wall.written);
  627.         decrypt(wall.system,wall.written);
  628.         for(i=0;i<5;i++) {
  629.             decrypt(wall.text[i],wall.written);
  630.             if(trash(wall.text[i])) {
  631.                 printf("Rejected: Wall writing found in trash!\n");
  632.                 break; } }
  633.         if(i<5)
  634.             continue;
  635.         if((wallfile=sopen("WALL.DAB",O_WRONLY|O_BINARY|O_CREAT,SH_DENYNO
  636.             ,S_IWRITE|S_IREAD))==-1) {
  637.             printf("Couldn't open WALL.DAB!\n");
  638.             continue; }
  639.         lseek(wallfile,0L,SEEK_END);
  640.         write(wallfile,&wall,sizeof(wall_t));
  641.         close(wallfile);
  642.         continue; }
  643.  
  644.     if(wallonly) {
  645.         smb_freemsgmem(&msg);
  646.         continue; }
  647.  
  648.     if(!stricmp(msg.subj,"->ALL<-")
  649.         || !stricmp(msg.subj,"->SYS<-")
  650.         || !stricmp(msg.subj,"->ONE<-")) {
  651.         sprintf(str,"%.3s%05lu.MSG",msg.subj+2,msg.idx.number);
  652.         buf=smb_getmsgtxt(&smb,&msg,0);
  653.         smb_freemsgmem(&msg);
  654.         if(!buf)
  655.             continue;
  656.         l=ahtoul((char *)buf);
  657.         if(!l)
  658.             continue;
  659.         for(i=0;buf[i];i++)
  660.             if(buf[i]==LF)
  661.                 break;
  662.         if(buf[i]!=LF)
  663.             continue;
  664.         if((msgfile=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
  665.             printf("error opening %s\n",str);
  666.             continue; }
  667.         if((tmpfile=fdopen(msgfile,"wb"))==NULL) {
  668.             close(msgfile);
  669.             printf("error fdopening %s\n",str);
  670.             continue; }
  671.         fprintf(tmpfile,"%08lx\r\n",l);
  672.         l^=0x305F6C81UL;
  673.         for(i++;buf[i];i++)
  674.             fputc(cryptchar(buf[i],l^(i&7)),tmpfile);
  675.         fclose(tmpfile);
  676.         putsmsg(1,"\1n\1h\1mNew announcement in \1wMatch Maker\1n\7\r\n");
  677.         continue; }
  678.  
  679.  
  680.     j=strlen(msg.subj);
  681.     for(i=0;i<j;i++)
  682.         if(!isdigit(msg.subj[i]))
  683.             break;
  684.     if(i<j) {                /* at least one non-digit, must be telegram */
  685.         if(strnicmp(msg.subj,system,25)) {
  686.             smb_freemsgmem(&msg);
  687.             continue; }
  688.         buf=smb_getmsgtxt(&smb,&msg,0);
  689.         smb_freemsgmem(&msg);
  690.         if(!buf)
  691.             continue;
  692.         l=0;
  693.         while(buf[l] && buf[l]!='}')         /* Find first text on line */
  694.             l++;
  695.         if(!buf[l] || !buf[++l]) {
  696.             FREE(buf);
  697.             continue; }
  698.         touser=ahtoul((char *)buf+l);
  699.         while(buf[l] && buf[l]>=SP)     /* Go to end of line */
  700.             l++;
  701.         while(buf[l] && buf[l]<=SP)     /* next line */
  702.             l++;
  703.         i=0;
  704.         while(buf[l]) {
  705.             if(buf[l]==LF && buf[l+1]==CR) { /* blank line */
  706.                 telegram[i++]=LF;
  707.                 break; }
  708.             telegram[i++]=buf[l++]; }
  709.         telegram[i]=0;
  710.         decrypt(telegram,touser);
  711.         printf("Telegram to %u\n",touser);
  712.         if(trash(telegram))
  713.             printf("Rejected: Contents in trash!\n");
  714.         else {
  715.             putsmsg(touser,TGRAM_NOTICE);
  716.             puttgram(touser,telegram); }
  717.         FREE(buf);
  718.         continue;
  719.         }
  720.  
  721.     if(tgramonly) {
  722.         smb_freemsgmem(&msg);
  723.         continue; }
  724.  
  725.     if(!msg.from[0]) {
  726.         smb_freemsgmem(&msg);
  727.         printf("Blank 'from' field.\n");
  728.         continue; }
  729.  
  730.     l=atol(msg.subj);
  731.     if(!l || l>65535L) {
  732.         smb_freemsgmem(&msg);
  733.         printf("Invalid profile.\n");
  734.         continue; }
  735.     fprintf(stderr,"Searching for %lu @ %s",l,msg.from);
  736.     sprintf(str,"%.25s",msg.from);
  737.     strupr(str);
  738.     system_crc=crc32(str);
  739.  
  740.     rewind(index);
  741.     memset(&user,0,sizeof(user_t));
  742.     while(1) {
  743.         if(!fread(&ixb,sizeof(ixb_t),1,index)) {
  744.             memset(&user,0,sizeof(user_t));
  745.             break; }
  746.         if(ixb.number==l && ixb.system==system_crc) {
  747.             fseek(index,ftell(index)-sizeof(ixb_t),SEEK_SET);
  748.             fseek(stream,(ftell(index)/sizeof(ixb_t))*sizeof(user_t),SEEK_SET);
  749.             fread(&user,sizeof(user_t),1,stream);
  750.             if(!(user.misc&USER_FROMSMB)) {
  751.                 memset(&user,0,sizeof(user_t));
  752.                 fread(&ixb,sizeof(ixb_t),1,index);
  753.                 continue; }
  754.             break; } }
  755.     fprintf(stderr,"\n");
  756.  
  757.     if(!user.number) {
  758.         fprintf(stderr,"Searching for unused record...");
  759.         rewind(index);
  760.         while(1) {                    /* Find deleted record */
  761.             if(!fread(&ixb,sizeof(ixb_t),1,index))
  762.                 break;
  763.             if(ixb.number==0) {
  764.                 fseek(index,ftell(index)-sizeof(ixb_t),SEEK_SET);
  765.                 break; } }
  766.         user.created=time(NULL);
  767.         user.number=l;
  768.         sprintf(user.system,"%-.40s",msg.from);
  769.         fprintf(stderr,"\n"); }
  770.  
  771.     fseek(stream,(ftell(index)/sizeof(ixb_t))*sizeof(user_t),SEEK_SET);
  772.     user.updated=time(NULL);
  773.     user.misc|=USER_FROMSMB;
  774.     buf=smb_getmsgtxt(&smb,&msg,0);
  775.     l=0;
  776.     while(buf[l]) {
  777.         while(buf[l] && buf[l]<=SP)         /* Find first text on line */
  778.             l++;
  779.         if(!strnicmp((char *)buf+l,"0:",2)) {
  780.             l+=2;
  781.             sprintf(user.name,"%-.25s",(char *)buf+l);
  782.             truncsp(user.name);
  783.             decrypt(user.name,user.number); }
  784.         if(!strnicmp((char *)buf+l,"1:",2)) {
  785.             l+=2;
  786.             sprintf(user.realname,"%-.25s",(char *)buf+l);
  787.             truncsp(user.realname);
  788.             decrypt(user.realname,user.number); }
  789.         if(!strnicmp((char *)buf+l,"2:",2)) {
  790.             l+=2;
  791.             sprintf(user.birth,"%-.8s",(char *)buf+l);
  792.             decrypt(user.birth,user.number); }
  793.         if(!strnicmp((char *)buf+l,"3:",2)) {
  794.             l+=2;
  795.             sprintf(user.location,"%-.30s",(char *)buf+l);
  796.             truncsp(user.location);
  797.             decrypt(user.location,user.number); }
  798.         if(!strnicmp((char *)buf+l,"4:",2)) {
  799.             l+=2;
  800.             sprintf(user.zipcode,"%-.10s",(char *)buf+l);
  801.             truncsp(user.zipcode);
  802.             decrypt(user.zipcode,user.number); }
  803.         if(!strnicmp((char *)buf+l,"5:",2)) {
  804.             l+=2;
  805.             sprintf(user.min_zipcode,"%-.10s",(char *)buf+l);
  806.             truncsp(user.min_zipcode);
  807.             decrypt(user.min_zipcode,user.number); }
  808.         if(!strnicmp((char *)buf+l,"6:",2)) {
  809.             l+=2;
  810.             sprintf(user.max_zipcode,"%-.10s",(char *)buf+l);
  811.             truncsp(user.max_zipcode);
  812.             decrypt(user.max_zipcode,user.number); }
  813.         if(!strnicmp((char *)buf+l,"7:",2)) {
  814.             l+=2;
  815.             sprintf(user.mbtype,"%-.4s",(char *)buf+l);
  816.             truncsp(user.mbtype);
  817.             decrypt(user.mbtype,user.number); }
  818.  
  819.         if(!strnicmp((char *)buf+l,"A:",2)) {
  820.             l+=2;
  821.             sprintf(user.note[0],"%-.50s",(char *)buf+l);
  822.             truncsp(user.note[0]);
  823.             decrypt(user.note[0],user.number); }
  824.         if(!strnicmp((char *)buf+l,"B:",2)) {
  825.             l+=2;
  826.             sprintf(user.note[1],"%-.50s",(char *)buf+l);
  827.             truncsp(user.note[1]);
  828.             decrypt(user.note[1],user.number); }
  829.         if(!strnicmp((char *)buf+l,"C:",2)) {
  830.             l+=2;
  831.             sprintf(user.note[2],"%-.50s",(char *)buf+l);
  832.             truncsp(user.note[2]);
  833.             decrypt(user.note[2],user.number); }
  834.         if(!strnicmp((char *)buf+l,"D:",2)) {
  835.             l+=2;
  836.             sprintf(user.note[3],"%-.50s",(char *)buf+l);
  837.             truncsp(user.note[3]);
  838.             decrypt(user.note[3],user.number); }
  839.         if(!strnicmp((char *)buf+l,"E:",2)) {
  840.             l+=2;
  841.             sprintf(user.note[4],"%-.50s",(char *)buf+l);
  842.             truncsp(user.note[4]);
  843.             decrypt(user.note[4],user.number); }
  844.  
  845.         if(!strnicmp((char *)buf+l,"F:",2)) {
  846.             l+=2;
  847.             user.sex=buf[l];
  848.             user.pref_sex=buf[l+1]; }
  849.  
  850.         if(!strnicmp((char *)buf+l,"G:",2)) {
  851.             l+=2;
  852.             user.marital=ahtoul((char *)buf+l); }
  853.         if(!strnicmp((char *)buf+l,"H:",2)) {
  854.             l+=2;
  855.             user.pref_marital=ahtoul((char *)buf+l); }
  856.  
  857.         if(!strnicmp((char *)buf+l,"I:",2)) {
  858.             l+=2;
  859.             user.race=ahtoul((char *)buf+l); }
  860.         if(!strnicmp((char *)buf+l,"J:",2)) {
  861.             l+=2;
  862.             user.pref_race=ahtoul((char *)buf+l); }
  863.  
  864.         if(!strnicmp((char *)buf+l,"K:",2)) {
  865.             l+=2;
  866.             user.hair=ahtoul((char *)buf+l); }
  867.         if(!strnicmp((char *)buf+l,"L:",2)) {
  868.             l+=2;
  869.             user.pref_hair=ahtoul((char *)buf+l); }
  870.  
  871.         if(!strnicmp((char *)buf+l,"M:",2)) {
  872.             l+=2;
  873.             user.eyes=ahtoul((char *)buf+l); }
  874.         if(!strnicmp((char *)buf+l,"N:",2)) {
  875.             l+=2;
  876.             user.pref_eyes=ahtoul((char *)buf+l); }
  877.  
  878.         if(!strnicmp((char *)buf+l,"O:",2)) {
  879.             l+=2;
  880.             user.weight=ahtoul((char *)buf+l); }
  881.         if(!strnicmp((char *)buf+l,"P:",2)) {
  882.             l+=2;
  883.             user.min_weight=ahtoul((char *)buf+l); }
  884.         if(!strnicmp((char *)buf+l,"Q:",2)) {
  885.             l+=2;
  886.             user.max_weight=ahtoul((char *)buf+l); }
  887.  
  888.         if(!strnicmp((char *)buf+l,"R:",2)) {
  889.             l+=2;
  890.             user.height=ahtoul((char *)buf+l); }
  891.         if(!strnicmp((char *)buf+l,"S:",2)) {
  892.             l+=2;
  893.             user.min_height=ahtoul((char *)buf+l); }
  894.         if(!strnicmp((char *)buf+l,"T:",2)) {
  895.             l+=2;
  896.             user.max_height=ahtoul((char *)buf+l); }
  897.  
  898.         if(!strnicmp((char *)buf+l,"U:",2)) {
  899.             l+=2;
  900.             user.min_age=ahtoul((char *)buf+l); }
  901.         if(!strnicmp((char *)buf+l,"V:",2)) {
  902.             l+=2;
  903.             user.max_age=ahtoul((char *)buf+l); }
  904.  
  905.         if(!strnicmp((char *)buf+l,"W:",2)) {
  906.             l+=2;
  907.             user.purity=ahtoul((char *)buf+l); }
  908.  
  909.         if(!strnicmp((char *)buf+l,"X:",2)) {
  910.             l+=2;
  911.             user.income=ahtoul((char *)buf+l); }
  912.         if(!strnicmp((char *)buf+l,"Y:",2)) {
  913.             l+=2;
  914.             user.min_income=ahtoul((char *)buf+l); }
  915.         if(!strnicmp((char *)buf+l,"Z:",2)) {
  916.             l+=2;
  917.             user.max_income=ahtoul((char *)buf+l); }
  918.  
  919.         if(toupper(buf[l])=='*' && isdigit(buf[l+1])) {  /* Questionnaires */
  920.             i=buf[l+1]-'0';
  921.             l+=2;
  922.             sprintf(user.queans[i].name,"%-.8s",(char *)buf+l);
  923.             truncsp(user.queans[i].name);
  924.             decrypt(user.queans[i].name,user.number);
  925.             while(buf[l] && buf[l]>=SP) l++;    /* Go to end of line */
  926.             for(j=0;j<20;j++) {
  927.                 while(buf[l] && buf[l]<=SP) l++;
  928.                 user.queans[i].self[j]=ahtoul((char *)buf+l);
  929.                 l+=5;
  930.                 user.queans[i].pref[j]=ahtoul((char *)buf+l);
  931.                 l+=5; } }
  932.  
  933.         while(buf[l] && buf[l]>=SP)     /* Go to end of line */
  934.             l++; }
  935.  
  936.     if(getage(user.birth)<min_age)        /* Too young */
  937.         printf("Rejected: User's age (%u) less than minimum age (%u)\n"
  938.             ,getage(user.birth),min_age);
  939.     else if(user.name[0]<SP || user.realname[0]<SP || user.system[0]<SP
  940.         || user.location[0]<SP || user.zipcode[0]<SP || user.birth[0]<SP)
  941.         printf("Rejected: Invalid user string\n");
  942.     else if(trash(user.name))
  943.         printf("Rejected: User's name (%s) in trash!\n",user.name);
  944.     else if(trash(user.location))
  945.         printf("Rejected: User's location (%s) in trash!\n",user.location);
  946.     else if(trash(user.note[0]) || trash(user.note[1]) || trash(user.note[2])
  947.         || trash(user.note[3]) || trash(user.note[4]))
  948.         printf("Rejected: User's personal text in trash!\n");
  949.     else {
  950.         fwrite(&user,sizeof(user_t),1,stream);
  951.         strupr(user.name);
  952.         ixb.name=crc32(user.name);
  953.         strupr(user.system);
  954.         user.system[25]=0;
  955.         ixb.system=crc32(user.system);
  956.         ixb.number=user.number;
  957.         ixb.updated=user.updated;
  958.         fwrite(&ixb,sizeof(ixb_t),1,index); }
  959.     FREE((char *)buf);
  960.     smb_freemsgmem(&msg);
  961.     }
  962.  
  963. lseek(file,0L,SEEK_SET);
  964. write(file,&high,4);
  965. close(file);
  966. return(0);
  967. }
  968.  
  969.