|
|
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.