|
|
1.1 ! root 1: /* QWK2SMB.C */ ! 2: ! 3: /* Converts QWK packet to to SMB formatted message bases */ ! 4: ! 5: /* The intention of this source code is an example of how to use the SMBLIB */ ! 6: /* library functions to access an SMB format message base. */ ! 7: ! 8: /* This program and source code are freeware. May be used in part or whole */ ! 9: /* for any purpose without consent or notification of Digital Dynamics. */ ! 10: ! 11: /* Digital Dynamics does request that developers that release products that */ ! 12: /* support the SMB format notify Digital Dynamics so the implementation */ ! 13: /* and contact chapters in the technical specification may be updated. */ ! 14: ! 15: #include "smblib.h" ! 16: #include "crc32.h" ! 17: #include <dos.h> ! 18: ! 19: char sbbs[128]; ! 20: ! 21: /****************************************************************************/ ! 22: /* Updates 16-bit "rcrc" with character 'ch' */ ! 23: /****************************************************************************/ ! 24: void ucrc16(uchar ch, ushort *rcrc) { ! 25: ushort i, cy; ! 26: uchar nch=ch; ! 27: ! 28: for (i=0; i<8; i++) { ! 29: cy=*rcrc & 0x8000; ! 30: *rcrc<<=1; ! 31: if (nch & 0x80) *rcrc |= 1; ! 32: nch<<=1; ! 33: if (cy) *rcrc ^= 0x1021; } ! 34: } ! 35: ! 36: /****************************************************************************/ ! 37: /* Returns 16-crc of string (not counting terminating NULL) */ ! 38: /****************************************************************************/ ! 39: ushort crc16(char *str) ! 40: { ! 41: int i=0; ! 42: ushort crc=0; ! 43: ! 44: ucrc16(0,&crc); ! 45: while(str[i]) ! 46: ucrc16(str[i++],&crc); ! 47: ucrc16(0,&crc); ! 48: ucrc16(0,&crc); ! 49: return(crc); ! 50: } ! 51: ! 52: ! 53: /****************************************************************************/ ! 54: /* Truncates white-space chars off end of 'str' and terminates at first tab */ ! 55: /****************************************************************************/ ! 56: void truncsp(char *str) ! 57: { ! 58: char c; ! 59: ! 60: str[strcspn(str,"\t")]=0; ! 61: c=strlen(str); ! 62: while(c && (uchar)str[c-1]<=' ') c--; ! 63: str[c]=0; ! 64: } ! 65: ! 66: /****************************************************************************/ ! 67: /* Converts an ASCII Hex string into an ulong */ ! 68: /****************************************************************************/ ! 69: ulong ahtoul(char *str) ! 70: { ! 71: ulong l,val=0; ! 72: ! 73: while((l=(*str++)|0x20)!=0x20) ! 74: val=(l&0xf)+(l>>6&1)*9+val*16; ! 75: return(val); ! 76: } ! 77: ! 78: /****************************************************************************/ ! 79: /* Returns the length of the file in 'filespec' */ ! 80: /****************************************************************************/ ! 81: long flength(char *filespec) ! 82: { ! 83: struct ffblk f; ! 84: ! 85: if(findfirst(filespec,&f,0)==0) ! 86: return(f.ff_fsize); ! 87: return(-1L); ! 88: } ! 89: ! 90: /****************************************************************************/ ! 91: /* Returns the FidoNet address kept in str as ASCII. */ ! 92: /****************************************************************************/ ! 93: fidoaddr_t atofaddr(char *str) ! 94: { ! 95: char *p; ! 96: fidoaddr_t addr; ! 97: ! 98: addr.zone=addr.net=addr.node=addr.point=0; ! 99: if((p=strchr(str,':'))!=NULL) { ! 100: addr.zone=atoi(str); ! 101: addr.net=atoi(p+1); } ! 102: else { ! 103: addr.zone=1; ! 104: addr.net=atoi(str); } ! 105: if(!addr.zone) /* no such thing as zone 0 */ ! 106: addr.zone=1; ! 107: if((p=strchr(str,'/'))!=NULL) ! 108: addr.node=atoi(p+1); ! 109: else { ! 110: addr.net=1; ! 111: addr.node=atoi(str); } ! 112: if((p=strchr(str,'.'))!=NULL) ! 113: addr.point=atoi(p+1); ! 114: return(addr); ! 115: } ! 116: ! 117: ! 118: int main(int argc, char **argv) ! 119: { ! 120: uchar *p,str[128],from[128],to[128],subj[128],block[128],*buf; ! 121: ushort xlat; ! 122: ushort i,j,k,msgs,total; ! 123: ulong l,m,length,size,crc; ! 124: FILE *qwk; ! 125: struct date date; ! 126: struct time curtime; ! 127: smbmsg_t msg; ! 128: smbstatus_t status; ! 129: ! 130: if(argc<2) { ! 131: printf("usage: qwk2smb <qwk_dir>\r\n"); ! 132: exit(1); } ! 133: ! 134: sprintf(str,"%s\\MESSAGES.DAT",argv[1]); ! 135: if((qwk=fopen(str,"rb"))==NULL) { ! 136: printf("error opening %s\n",str); ! 137: exit(1); } ! 138: ! 139: size=filelength(fileno(qwk)); ! 140: smb_file[0]=0; ! 141: ! 142: for(l=128,i=1,msgs=total=1;l<size;l+=i*128) { ! 143: fseek(qwk,l,SEEK_SET); ! 144: if(!fread(block,1,128,qwk)) ! 145: break; ! 146: i=atoi(block+116); /* i = number of 128 byte records */ ! 147: if(i<2) { ! 148: i=1; ! 149: continue; } ! 150: ! 151: j=(ushort)block[123]|(((ushort)block[124])<<8); /* conference number */ ! 152: ! 153: if(strcmp(smb_file,itoa(j,str,10))) { /* changed conference */ ! 154: fclose(sdt_fp); ! 155: fclose(shd_fp); ! 156: fclose(sid_fp); ! 157: strcpy(smb_file,str); ! 158: printf("\nConference #%s\n",str); ! 159: msgs=1; ! 160: k=smb_open(10); ! 161: if(k) { ! 162: printf("smb_open returned %d\n",k); ! 163: exit(1); } ! 164: if(!filelength(fileno(shd_fp))) /* new conference */ ! 165: smb_create(2000,2000,0,0,10); } ! 166: ! 167: smb_getstatus(&status); // Initialized for first call to smb_addcrc() ! 168: ! 169: printf("%u (total=%u)\r",msgs,total); ! 170: ! 171: /*****************************/ ! 172: /* Initialize the SMB header */ ! 173: /*****************************/ ! 174: ! 175: memset(&msg,0,sizeof(smbmsg_t)); ! 176: memcpy(msg.hdr.id,"SHD\x1a",4); ! 177: msg.hdr.version=SMB_VERSION; ! 178: ! 179: /**************************/ ! 180: /* Convert the QWK header */ ! 181: /**************************/ ! 182: ! 183: if(block[0]=='*' || block[0]=='+') ! 184: msg.idx.attr|=MSG_PRIVATE; ! 185: if(block[0]=='*' || block[0]=='-' || block[0]=='`') ! 186: msg.idx.attr|=MSG_READ; ! 187: msg.hdr.attr=msg.idx.attr; ! 188: ! 189: date.da_mon=((block[8]&0xf)*10)+(block[9]&0xf); ! 190: date.da_day=((block[11]&0xf)*10)+(block[12]&0xf); ! 191: date.da_year=((block[14]&0xf)*10)+(block[15]&0xf)+1900; ! 192: curtime.ti_hour=((block[16]&0xf)*10)+(block[17]&0xf); ! 193: curtime.ti_min=((block[19]&0xf)*10)+(block[20]&0xf); ! 194: curtime.ti_sec=0; ! 195: msg.hdr.when_written.time=dostounix(&date,&curtime); ! 196: msg.hdr.when_written.zone=PST; /* set to local time zone */ ! 197: msg.hdr.when_imported.time=time(NULL); ! 198: msg.hdr.when_imported.zone=PST; /* set to local time zone */ ! 199: ! 200: sprintf(to,"%25.25s",block+21); /* To user */ ! 201: truncsp(to); ! 202: smb_hfield(&msg,RECIPIENT,strlen(to),to); ! 203: strlwr(to); ! 204: msg.idx.to=crc16(to); ! 205: ! 206: sprintf(from,"%25.25s",block+46); /* From user */ ! 207: truncsp(from); ! 208: smb_hfield(&msg,SENDER,strlen(from),from); ! 209: strlwr(from); ! 210: msg.idx.from=crc16(from); ! 211: ! 212: sprintf(subj,"%25.25s",block+71); /* Subject */ ! 213: truncsp(subj); ! 214: smb_hfield(&msg,SUBJECT,strlen(subj),subj); ! 215: strlwr(subj); ! 216: msg.idx.subj=crc16(subj); ! 217: ! 218: /********************************/ ! 219: /* Convert the QWK message text */ ! 220: /********************************/ ! 221: ! 222: length=0; ! 223: if((buf=MALLOC((i-1)*128*2))==NULL) { ! 224: printf("memory allocation error\n"); ! 225: exit(1); } ! 226: for(j=1;j<i;j++) { ! 227: if(!fread(block,1,128,qwk)) ! 228: break; ! 229: for(k=0;k<128;k++) { ! 230: if(block[k]==0) ! 231: continue; ! 232: if(block[k]==0xE3) { /* expand 0xe3 to crlf */ ! 233: buf[length++]=CR; ! 234: buf[length++]=LF; ! 235: continue; } ! 236: buf[length++]=block[k]; } } ! 237: ! 238: while(length && buf[length-1]<=SP) length--; /* remove trailing garbage */ ! 239: ! 240: /*****************/ ! 241: /* Calculate CRC */ ! 242: /*****************/ ! 243: ! 244: crc=0xffffffffUL; ! 245: for(m=0;m<length;m++) ! 246: crc=ucrc32(buf[m],crc); ! 247: crc=~crc; ! 248: ! 249: /*******************/ ! 250: /* Check for dupes */ ! 251: /*******************/ ! 252: ! 253: j=smb_addcrc(status.max_crcs,crc,10); ! 254: if(j) { ! 255: if(j==1) { ! 256: printf("\nDuplicate message\n"); ! 257: smb_freemsgmem(msg); ! 258: FREE(buf); ! 259: continue; } ! 260: printf("smb_addcrc returned %d\n",j); ! 261: exit(1); } ! 262: ! 263: /*************************************/ ! 264: /* Write SMB message header and text */ ! 265: /*************************************/ ! 266: ! 267: length+=2; /* for translation string */ ! 268: ! 269: if(smb_open_da(10)) { ! 270: printf("error opening %s.SDA\n",smb_file); ! 271: exit(1); } ! 272: msg.hdr.offset=smb_fallocdat(length,1); ! 273: fclose(sda_fp); ! 274: if(msg.hdr.offset && msg.hdr.offset<1L) { ! 275: printf("error %ld allocating blocks\r\n",msg.hdr.offset); ! 276: exit(1); } ! 277: fseek(sdt_fp,msg.hdr.offset,SEEK_SET); ! 278: xlat=XLAT_NONE; ! 279: fwrite(&xlat,2,1,sdt_fp); ! 280: fwrite(buf,length,1,sdt_fp); ! 281: fflush(sdt_fp); ! 282: ! 283: smb_dfield(&msg,TEXT_BODY,length); ! 284: ! 285: k=smb_addmsghdr(&msg,&status,1,10); ! 286: if(k) { ! 287: printf("smb_addmsghdr returned %d\n",k); ! 288: exit(1); } ! 289: smb_freemsgmem(msg); ! 290: FREE(buf); ! 291: msgs++; ! 292: total++; } ! 293: ! 294: return(0); ! 295: } ! 296:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.