|
|
1.1 root 1: /* SMB2SBL */
2:
3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
4:
5: /* Scans SMB message base for messages to "SBL" and adds them to the SBL */
6: /* database. */
7:
8: #define uint unsigned int
9:
10: #include <dos.h>
11: #include "smblib.h"
12: #include "sbldefs.h"
13:
14: extern int daylight=0;
15: extern long timezone=0L;
16: smb_t smb;
17:
18: char *loadmsgtxt(smbmsg_t msg, int tails)
19: {
20: char *buf=NULL,*lzhbuf;
21: ushort xlat;
22: int i,lzh;
23: long l=0,lzhlen,length;
24:
25: for(i=0;i<msg.hdr.total_dfields;i++) {
26: if(!(msg.dfield[i].type==TEXT_BODY
27: || (tails && msg.dfield[i].type==TEXT_TAIL)))
28: continue;
29: fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset
30: ,SEEK_SET);
31: fread(&xlat,2,1,smb.sdt_fp);
32: lzh=0;
33: if(xlat==XLAT_LZH) {
34: lzh=1;
35: fread(&xlat,2,1,smb.sdt_fp); }
36: if(xlat!=XLAT_NONE) /* no other translations supported */
37: continue;
38:
39: length=msg.dfield[i].length-2;
40: if(lzh) {
41: length-=2;
42: if((lzhbuf=MALLOC(length))==NULL) {
43: printf("ERR_ALLOC lzhbuf of %lu\n",length);
44: return(buf); }
45: fread(lzhbuf,1,length,smb.sdt_fp);
46: lzhlen=*(long *)lzhbuf;
47: if((buf=REALLOC(buf,l+lzhlen+3))==NULL) {
48: FREE(lzhbuf);
49: printf("ERR_ALLOC lzhoutbuf of %l\n",l+lzhlen+1);
50: return(buf); }
51: lzh_decode(lzhbuf,length,buf+l);
52: FREE(lzhbuf);
53: l+=lzhlen; }
54: else {
55: if((buf=REALLOC(buf,l+msg.dfield[i].length+3))==NULL) {
56: printf("ERR_ALLOC of %lu\n",l+msg.dfield[i].length+1);
57: return(buf); }
58: l+=fread(buf+l,1,length,smb.sdt_fp); }
59: buf[l]=CR;
60: l++;
61: buf[l]=LF;
62: l++;
63: buf[l]=0; }
64: return(buf);
65: }
66:
67:
68: /***************************************************************************/
69: /* Truncates white-space chars off end of 'str' and terminates at first CR */
70: /****************************************************************************/
71: void truncsp(char *str)
72: {
73: char c;
74:
75: str[strcspn(str,"\r")]=0;
76: c=strlen(str);
77: while(c && (uchar)str[c-1]<=SP) c--;
78: str[c]=0;
79: }
80:
81: /****************************************************************************/
82: /* Checks the disk drive for the existence of a file. Returns 1 if it */
83: /* exists, 0 if it doesn't. */
84: /****************************************************************************/
85: char fexist(char *filespec)
86: {
87: struct ffblk f;
88:
89: if(findfirst(filespec,&f,0)==0)
90: return(1);
91: return(0);
92: }
93:
94: /****************************************************************************/
95: /* Returns the length of the file in 'filespec' */
96: /****************************************************************************/
97: long flength(char *filespec)
98: {
99: struct ffblk f;
100:
101: if(findfirst(filespec,&f,0)==0)
102: return(f.ff_fsize);
103: return(-1L);
104: }
105:
106:
107: /****************************************************************************/
108: /* Converts a date string in format MM/DD/YY into unix time format */
109: /****************************************************************************/
110: time_t dstrtounix(char *str)
111: {
112: struct date date;
113: struct time curtime;
114:
115: if(!strncmp(str,"00/00/00",8))
116: return(0);
117: curtime.ti_hour=curtime.ti_min=curtime.ti_sec=0;
118: if(str[6]<7)
119: date.da_year=2000+((str[6]&0xf)*10)+(str[7]&0xf);
120: else
121: date.da_year=1900+((str[6]&0xf)*10)+(str[7]&0xf);
122: date.da_mon=((str[0]&0xf)*10)+(str[1]&0xf);
123: date.da_day=((str[3]&0xf)*10)+(str[4]&0xf);
124: return(dostounix(&date,&curtime));
125: }
126:
127: /****************************************************************************/
128: /* Updates 16-bit "rcrc" with character 'ch' */
129: /****************************************************************************/
130: void ucrc16(uchar ch, ushort *rcrc) {
131: ushort i, cy;
132: uchar nch=ch;
133:
134: for (i=0; i<8; i++) {
135: cy=*rcrc & 0x8000;
136: *rcrc<<=1;
137: if (nch & 0x80) *rcrc |= 1;
138: nch<<=1;
139: if (cy) *rcrc ^= 0x1021; }
140: }
141:
142: /****************************************************************************/
143: /* Returns 16-crc of string (not counting terminating NULL) */
144: /****************************************************************************/
145: ushort crc16(char *str)
146: {
147: int i=0;
148: ushort crc=0;
149:
150: ucrc16(0,&crc);
151: while(str[i])
152: ucrc16(str[i++],&crc);
153: ucrc16(0,&crc);
154: ucrc16(0,&crc);
155: return(crc);
156: }
157:
158: time_t checktime()
159: {
160: struct tm tm;
161:
162: memset(&tm,0,sizeof(tm));
163: tm.tm_year=94;
164: tm.tm_mday=1;
165: return(mktime(&tm)^0x2D24BD00L);
166: }
167:
168: int main(int argc, char **argv)
169: {
170: uchar str[128],*buf,*p;
171: int i,file,sysop,number,network,terminal,desc;
172: ulong l,last,high;
173: ushort sbl;
174: bbs_t bbs;
175: smbmsg_t msg;
176: FILE *stream;
177:
178: fprintf(stderr,"\nSMB2SBL v2.00 - Updates SBL via SMB - Developed 1994-1997 "
179: "Rob Swindell\n\n");
180:
181: if(checktime()) {
182: printf("Time problem!\n");
183: return(-1); }
184:
185: if(argc<3) {
186: fprintf(stderr,"usage: smb2sbl <smb_file> <sbl.dab>\n\n");
187: fprintf(stderr,"ex: smb2sbl c:\\sbbs\\data\\subs\\syncdata "
188: "c:\\sbbs\\xtrn\\sbl\\sbl.dab \n");
189: return(1); }
190:
191: strcpy(smb.file,argv[1]);
192: strupr(smb.file);
193:
194: strcpy(str,argv[2]);
195: strupr(str);
196: if((file=open(str,O_RDWR|O_BINARY|O_DENYNONE|O_CREAT,S_IWRITE|S_IREAD))==-1) {
197: printf("error opening %s\n",str);
198: return(1); }
199: if((stream=fdopen(file,"r+b"))==NULL) {
200: printf("error fdopening %s\n",str);
201: return(1); }
202: setvbuf(stream,NULL,_IOFBF,4096);
203:
204: sprintf(str,"%s.SBL",smb.file);
205: if((file=open(str,O_RDWR|O_BINARY|O_CREAT,S_IWRITE|S_IREAD))==-1) {
206: printf("error opening %s\n",str);
207: return(1); }
208: if(read(file,&last,4)!=4)
209: last=0;
210: high=last;
211:
212: sprintf(str,"%s.SHD",smb.file);
213: if(!fexist(str)) {
214: printf("%s doesn't exist\n",smb.file);
215: return(0); }
216: sprintf(str,"%s.SID",smb.file);
217: if(!flength(str)) {
218: printf("%s is empty\n",smb.file);
219: return(0); }
220: fprintf(stderr,"Opening %s\n",smb.file);
221: smb.retry_time=30;
222: if((i=smb_open(&smb))!=0) {
223: printf("smb_open returned %d\n",i);
224: return(1); }
225:
226: sbl=crc16("sbl");
227:
228: if((i=smb_locksmbhdr(&smb))!=0) { /* Be sure noone deletes or */
229: printf("Error locking %d\n",i); /* adds while we're reading */
230: return(1); }
231:
232: while(!feof(smb.sid_fp)) {
233: if(!fread(&msg.idx,sizeof(idxrec_t),1,smb.sid_fp))
234: break;
235: fprintf(stderr,"\r%lu ",msg.idx.number);
236: if(msg.idx.number<=last || msg.idx.to!=sbl)
237: continue;
238: high=msg.idx.number;
239: if((i=smb_lockmsghdr(&smb,&msg))!=0) {
240: printf("\7Error %d locking msg #%lu\n",i,msg.idx.number);
241: continue; }
242: if((i=smb_getmsghdr(&smb,&msg))!=0) {
243: smb_unlockmsghdr(&smb,&msg);
244: printf("\7Error %d reading msg #%lu\n",i,msg.idx.number);
245: continue; }
246: smb_unlockmsghdr(&smb,&msg);
247: if(!msg.from_net.type) { /* ignore local message */
248: smb_freemsgmem(&msg);
249: continue; }
250:
251: printf("\nMessage #%lu by %s on %.24s\n"
252: ,msg.hdr.number,msg.from,ctime(&(time_t)msg.hdr.when_written.time));
253:
254: truncsp(msg.subj);
255: if(!msg.subj[0]) {
256: smb_freemsgmem(&msg);
257: continue; }
258: fprintf(stderr,"Searching for %s...",msg.subj);
259: fseek(stream,0L,SEEK_SET);
260: memset(&bbs,0,sizeof(bbs_t));
261: while(1) {
262: l=ftell(stream);
263: if(!fread(&bbs,sizeof(bbs_t),1,stream)) {
264: memset(&bbs,0,sizeof(bbs_t));
265: break; }
266: if(msg.subj[0] && !stricmp(bbs.name,msg.subj)) {
267: fseek(stream,l,SEEK_SET);
268: break; } }
269: fprintf(stderr,"\n");
270: if(bbs.name[0] && strnicmp(bbs.user,msg.from,25)) {
271: printf("%s didn't create the entry for %s\n",msg.from,msg.subj);
272: smb_freemsgmem(&msg);
273: continue; }
274: if(!bbs.name[0]) {
275: fprintf(stderr,"Searching for unused record...");
276: fseek(stream,0L,SEEK_SET);
277: while(1) { /* Find deleted record */
278: l=ftell(stream);
279: if(!fread(&bbs,sizeof(bbs_t),1,stream))
280: break;
281: if(!bbs.name[0]) {
282: fseek(stream,l,SEEK_SET);
283: break; } }
284: fprintf(stderr,"\n");
285: memset(&bbs,0,sizeof(bbs_t));
286: bbs.created=time(NULL);
287: if(!bbs.birth)
288: bbs.birth=bbs.created;
289: sprintf(bbs.user,"%-.25s",msg.from); }
290: sprintf(bbs.name,"%-.25s",msg.subj);
291: bbs.updated=time(NULL);
292: bbs.misc|=FROM_SMB;
293: sprintf(bbs.userupdated,"%-.25s",msg.from);
294: buf=loadmsgtxt(msg,0);
295: sysop=number=network=terminal=desc=0;
296: l=0;
297: while(buf[l]) {
298: while(buf[l] && buf[l]<=SP) /* Find first text on line */
299: l++;
300: if(!strnicmp(buf+l,"NAME:",5)) {
301: l+=5;
302: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
303: l++;
304: sprintf(bbs.name,"%-.25s",buf+l);
305: truncsp(bbs.name); }
306: if(!strnicmp(buf+l,"BIRTH:",6)) {
307: l+=6;
308: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
309: l++;
310: bbs.birth=dstrtounix(buf+l); }
311: if(!strnicmp(buf+l,"SOFTWARE:",9)) {
312: l+=9;
313: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
314: l++;
315: sprintf(bbs.software,"%-.15s",buf+l);
316: truncsp(bbs.software); }
317: if(!strnicmp(buf+l,"SYSOP:",6)) {
318: l+=6;
319: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
320: l++;
321: sprintf(bbs.sysop[sysop],"%-.25s",buf+l);
322: truncsp(bbs.sysop[sysop]);
323: if(sysop<MAX_SYSOPS-1)
324: sysop++; }
325: if(!strnicmp(buf+l,"NUMBER:",7)) {
326: l+=7;
327: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
328: l++;
329: sprintf(bbs.number[number].number,"%-.12s",buf+l);
330: truncsp(bbs.number[number].number);
331: if(number<MAX_NUMBERS-1)
332: number++; }
333: if(!strnicmp(buf+l,"MODEM:",6)) {
334: l+=6;
335: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
336: l++;
337: i=number;
338: if(i) i--;
339: sprintf(bbs.number[i].modem,"%-.15s",buf+l);
340: truncsp(bbs.number[i].modem); }
341: if(!strnicmp(buf+l,"LOCATION:",9)) {
342: l+=9;
343: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
344: l++;
345: i=number;
346: if(i) i--;
347: sprintf(bbs.number[i].location,"%-.30s",buf+l);
348: truncsp(bbs.number[i].location); }
349: if(!strnicmp(buf+l,"MINRATE:",8)) {
350: l+=8;
351: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
352: l++;
353: i=number;
354: if(i) i--;
355: bbs.number[i].min_rate=atoi(buf+l); }
356: if(!strnicmp(buf+l,"MAXRATE:",8)) {
357: l+=8;
358: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
359: l++;
360: i=number;
361: if(i) i--;
362: bbs.number[i].max_rate=atoi(buf+l); }
363: if(!strnicmp(buf+l,"NETWORK:",8)) {
364: l+=8;
365: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
366: l++;
367: sprintf(bbs.network[network],"%-.15s",buf+l);
368: truncsp(bbs.network[network]);
369: if(network<MAX_NETS-1)
370: network++; }
371: if(!strnicmp(buf+l,"ADDRESS:",8)) {
372: l+=8;
373: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
374: l++;
375: i=network;
376: if(i) i--;
377: sprintf(bbs.address[i],"%-.25s",buf+l);
378: truncsp(bbs.address[i]); }
379: if(!strnicmp(buf+l,"TERMINAL:",9)) {
380: l+=9;
381: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
382: l++;
383: sprintf(bbs.terminal[terminal],"%-.15s",buf+l);
384: truncsp(bbs.terminal[terminal]);
385: if(terminal<MAX_TERMS-1)
386: terminal++; }
387: if(!strnicmp(buf+l,"DESC:",5)) {
388: l+=5;
389: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
390: l++;
391: sprintf(bbs.desc[desc],"%-.50s",buf+l);
392: truncsp(bbs.desc[desc]);
393: if(desc<4)
394: desc++; }
395:
396: if(!strnicmp(buf+l,"MEGS:",5)) {
397: l+=5;
398: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
399: l++;
400: bbs.megs=atol(buf+l); }
401: if(!strnicmp(buf+l,"MSGS:",5)) {
402: l+=5;
403: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
404: l++;
405: bbs.msgs=atol(buf+l); }
406: if(!strnicmp(buf+l,"FILES:",6)) {
407: l+=6;
408: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
409: l++;
410: bbs.files=atol(buf+l); }
411: if(!strnicmp(buf+l,"NODES:",6)) {
412: l+=6;
413: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
414: l++;
415: bbs.nodes=atoi(buf+l); }
416: if(!strnicmp(buf+l,"USERS:",6)) {
417: l+=6;
418: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
419: l++;
420: bbs.users=atoi(buf+l); }
421: if(!strnicmp(buf+l,"SUBS:",5)) {
422: l+=5;
423: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
424: l++;
425: bbs.subs=atoi(buf+l); }
426: if(!strnicmp(buf+l,"DIRS:",5)) {
427: l+=5;
428: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
429: l++;
430: bbs.dirs=atoi(buf+l); }
431: if(!strnicmp(buf+l,"XTRNS:",6)) {
432: l+=6;
433: while(buf[l] && buf[l]<=SP && buf[l]!=CR)
434: l++;
435: bbs.xtrns=atoi(buf+l); }
436: while(buf[l] && buf[l]>=SP) { /* Go to end of line */
437: putchar(buf[l]);
438: l++; }
439: printf("\n"); }
440: if(bbs.total_sysops<sysop)
441: bbs.total_sysops=sysop;
442: if(bbs.total_networks<network)
443: bbs.total_networks=network;
444: if(bbs.total_terminals<terminal)
445: bbs.total_terminals=terminal;
446: if(bbs.total_numbers<number)
447: bbs.total_numbers=number;
448: fwrite(&bbs,sizeof(bbs_t),1,stream);
449: FREE(buf);
450: smb_freemsgmem(&msg);
451: }
452: lseek(file,0L,SEEK_SET);
453: write(file,&high,4);
454: close(file);
455: return(0);
456: }
457:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.