|
|
1.1 ! root 1: /* QWKNODES.C */ ! 2: ! 3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ ! 4: ! 5: /* Generates QWKnet node list or ROUTE.DAT file from Synchronet message base */ ! 6: ! 7: #include "sbbs.h" ! 8: #include "crc32.h" ! 9: #include "crc16.c" ! 10: ! 11: unsigned _stklen=10000; ! 12: smb_t smb; ! 13: ! 14: /****************************************************************************/ ! 15: /* Returns 32-crc of string (not counting terminating NULL) */ ! 16: /****************************************************************************/ ! 17: ulong crc32(char *str) ! 18: { ! 19: int i=0; ! 20: ulong crc=0xffffffffUL; ! 21: ! 22: while(str[i]) ! 23: crc=ucrc32(str[i++],crc); ! 24: crc=~crc; ! 25: return(crc); ! 26: } ! 27: ! 28: /****************************************************************************/ ! 29: /* Converts unix time format (long - time_t) into a char str MM/DD/YY */ ! 30: /****************************************************************************/ ! 31: char *unixtodstr(time_t unix, char *str) ! 32: { ! 33: struct date date; ! 34: struct time curtime; ! 35: ! 36: if(!unix) ! 37: strcpy(str,"00/00/00"); ! 38: else { ! 39: unixtodos(unix,&date,&curtime); ! 40: if((unsigned)date.da_mon>12) { /* DOS leap year bug */ ! 41: date.da_mon=1; ! 42: date.da_year++; } ! 43: if((unsigned)date.da_day>31) ! 44: date.da_day=1; ! 45: if(sys_misc&SM_EURODATE) ! 46: sprintf(str,"%02u/%02u/%02u",date.da_day,date.da_mon ! 47: ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); ! 48: else ! 49: sprintf(str,"%02u/%02u/%02u",date.da_mon,date.da_day ! 50: ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); } ! 51: return(str); ! 52: } ! 53: ! 54: /****************************************************************************/ ! 55: /* Puts a backslash on path strings */ ! 56: /****************************************************************************/ ! 57: void backslash(char *str) ! 58: { ! 59: int i; ! 60: ! 61: i=strlen(str); ! 62: if(i && str[i-1]!='\\') { ! 63: str[i]='\\'; str[i+1]=0; } ! 64: } ! 65: /****************************************************************************/ ! 66: /* Network open function. Opens all files DENYALL and retries LOOP_NOPEN */ ! 67: /* number of times if the attempted file is already open or denying access */ ! 68: /* for some other reason. All files are opened in BINARY mode. */ ! 69: /****************************************************************************/ ! 70: int nopen(char *str, int access) ! 71: { ! 72: char logstr[256]; ! 73: int file,share,count=0; ! 74: ! 75: if(access==O_RDONLY) share=SH_DENYWR; ! 76: else share=SH_DENYRW; ! 77: while(((file=sopen(str,O_BINARY|access,share,S_IWRITE))==-1) ! 78: && errno==EACCES && count++<LOOP_NOPEN); ! 79: if(file==-1 && errno==EACCES) ! 80: lputs("\7\r\nNOPEN: ACCESS DENIED\r\n\7"); ! 81: return(file); ! 82: } ! 83: /****************************************************************************/ ! 84: /* This function performs an nopen, but returns a file stream with a buffer */ ! 85: /* allocated. */ ! 86: /****************************************************************************/ ! 87: FILE *fnopen(int *file, char *str, int access) ! 88: { ! 89: char mode[128]; ! 90: FILE *stream; ! 91: ! 92: if(((*file)=nopen(str,access))==-1) ! 93: return(NULL); ! 94: ! 95: if(access&O_APPEND) { ! 96: if(access&O_RDONLY) ! 97: strcpy(mode,"a+"); ! 98: else ! 99: strcpy(mode,"a"); } ! 100: else { ! 101: if(access&O_WRONLY) ! 102: strcpy(mode,"r+"); ! 103: else ! 104: strcpy(mode,"r"); } ! 105: stream=fdopen((*file),mode); ! 106: if(stream==NULL) { ! 107: close(*file); ! 108: return(NULL); } ! 109: setvbuf(stream,NULL,_IOFBF,16*1024); ! 110: return(stream); ! 111: } ! 112: ! 113: /****************************************************************************/ ! 114: /* Truncates white-space chars off end of 'str' and terminates at first tab */ ! 115: /****************************************************************************/ ! 116: void truncsp(char *str) ! 117: { ! 118: uchar c; ! 119: ! 120: c=strlen(str); ! 121: while(c && (uchar)str[c-1]<=SP) c--; ! 122: str[c]=0; ! 123: } ! 124: ! 125: void stripctrla(uchar *str) ! 126: { ! 127: uchar out[256]; ! 128: int i,j; ! 129: ! 130: for(i=j=0;str[i];i++) { ! 131: if(str[i]==1) ! 132: i++; ! 133: else ! 134: out[j++]=str[i]; } ! 135: out[j]=0; ! 136: strcpy(str,out); ! 137: } ! 138: ! 139: ! 140: long lputs(char FAR16 *str) ! 141: { ! 142: char tmp[256]; ! 143: int i,j,k; ! 144: ! 145: j=strlen(str); ! 146: for(i=k=0;i<j;i++) /* remove CRs */ ! 147: if(str[i]==CR && str[i+1]==LF) ! 148: continue; ! 149: else ! 150: tmp[k++]=str[i]; ! 151: tmp[k]=0; ! 152: return(fputs(tmp,stderr)); ! 153: } ! 154: /****************************************************************************/ ! 155: /* Performs printf() through local assembly routines */ ! 156: /* Called from everywhere */ ! 157: /****************************************************************************/ ! 158: int lprintf(char *fmat, ...) ! 159: { ! 160: va_list argptr; ! 161: char sbuf[256]; ! 162: int chcount; ! 163: ! 164: va_start(argptr,fmat); ! 165: chcount=vsprintf(sbuf,fmat,argptr); ! 166: va_end(argptr); ! 167: lputs(sbuf); ! 168: return(chcount); ! 169: } ! 170: void bail(int code) ! 171: { ! 172: exit(code); ! 173: } ! 174: ! 175: ! 176: char *loadmsgtail(smbmsg_t msg) ! 177: { ! 178: char *buf=NULL; ! 179: ushort xlat; ! 180: int i; ! 181: long l=0,length; ! 182: ! 183: for(i=0;i<msg.hdr.total_dfields;i++) { ! 184: if(msg.dfield[i].type!=TEXT_TAIL) ! 185: continue; ! 186: fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset ! 187: ,SEEK_SET); ! 188: fread(&xlat,2,1,smb.sdt_fp); ! 189: if(xlat!=XLAT_NONE) /* no translations supported */ ! 190: continue; ! 191: length=msg.dfield[i].length-2; ! 192: if((buf=REALLOC(buf,l+msg.dfield[i].length+1))==NULL) ! 193: return(buf); ! 194: l+=fread(buf+l,1,length,smb.sdt_fp); ! 195: buf[l]=0; } ! 196: return(buf); ! 197: } ! 198: ! 199: ! 200: void gettag(smbmsg_t msg, char *tag) ! 201: { ! 202: char *buf,*p; ! 203: ! 204: tag[0]=0; ! 205: buf=loadmsgtail(msg); ! 206: if(buf==NULL) ! 207: return; ! 208: truncsp(buf); ! 209: stripctrla(buf); ! 210: p=strrchr(buf,LF); ! 211: if(!p) p=buf; ! 212: else p++; ! 213: if(!strnicmp(p," � Synchronet � ",16)) ! 214: p+=16; ! 215: if(!strnicmp(p," * Synchronet * ",16)) ! 216: p+=16; ! 217: while(*p && *p<=SP) p++; ! 218: strcpy(tag,p); ! 219: FREE(buf); ! 220: } ! 221: ! 222: ! 223: #define FEED (1<<0) ! 224: #define LOCAL (1<<1) ! 225: #define APPEND (1<<2) ! 226: #define TAGS (1<<3) ! 227: ! 228: #define ROUTE (1<<1) ! 229: #define NODES (1<<2) ! 230: #define USERS (1<<3) ! 231: ! 232: char *usage="\nusage: qwknodes [/opts] cmds" ! 233: "\n" ! 234: "\n cmds: r = create ROUTE.DAT" ! 235: "\n u = create USERS.DAT" ! 236: "\n n = create NODES.DAT" ! 237: "\n" ! 238: "\n opts: f = format addresses for nodes that feed from this system" ! 239: "\n a = append existing output files" ! 240: "\n t = include tag lines in NODES.DAT" ! 241: "\n l = include local users in USERS.DAT" ! 242: "\n m# = maximum message age set to # days" ! 243: "\n"; ! 244: ! 245: void main(int argc, char **argv) ! 246: { ! 247: char str[256],tmp[128],tag[256],addr[256],*p; ! 248: int i,j,mode=0,cmd=0,o_mode,max_age=0; ! 249: ushort smm,sbl; ! 250: ulong *crc=NULL,curcrc,total_crcs=0,l; ! 251: FILE *route,*users,*nodes; ! 252: time_t now; ! 253: read_cfg_text_t txt; ! 254: smbstatus_t status; ! 255: smbmsg_t msg; ! 256: ! 257: txt.openerr="\7\r\nError opening %s for read.\r\n"; ! 258: txt.reading="\r\nReading %s..."; ! 259: txt.readit="\rRead %s "; ! 260: txt.allocerr="\7\r\nError allocating %u bytes of memory\r\n"; ! 261: txt.error="\7\r\nERROR: Offset %lu in %s\r\n\r\n"; ! 262: ! 263: fprintf(stderr,"\nSynchronet QWKnet Node/Route/User List v1.20 " ! 264: "Developed 1995-1997 Rob Swindell\n"); ! 265: ! 266: ! 267: for(i=1;i<argc;i++) ! 268: for(j=0;argv[i][j];j++) ! 269: switch(toupper(argv[i][j])) { ! 270: case '/': ! 271: case '-': ! 272: while(argv[i][++j]) ! 273: switch(toupper(argv[i][j])) { ! 274: case 'F': ! 275: mode|=FEED; ! 276: break; ! 277: case 'L': ! 278: mode|=LOCAL; ! 279: break; ! 280: case 'A': ! 281: mode|=APPEND; ! 282: break; ! 283: case 'T': ! 284: mode|=TAGS; ! 285: break; ! 286: case 'M': ! 287: j++; ! 288: max_age=atoi(argv[i]+j); ! 289: while(isdigit(argv[i][j+1])) j++; ! 290: break; ! 291: default: ! 292: printf(usage); ! 293: exit(1); } ! 294: j--; ! 295: break; ! 296: case 'R': ! 297: cmd|=ROUTE; ! 298: break; ! 299: case 'U': ! 300: cmd|=USERS; ! 301: break; ! 302: case 'N': ! 303: cmd|=NODES; ! 304: break; ! 305: default: ! 306: printf(usage); ! 307: exit(1); } ! 308: ! 309: if(!cmd) { ! 310: printf(usage); ! 311: exit(1); } ! 312: ! 313: if(mode&APPEND) ! 314: o_mode=O_WRONLY|O_CREAT|O_APPEND; ! 315: else ! 316: o_mode=O_WRONLY|O_CREAT|O_TRUNC; ! 317: ! 318: if(cmd&NODES) ! 319: if((nodes=fnopen(&i,"NODES.DAT",o_mode))==NULL) { ! 320: printf("\7\nError opening NODES.DAT\n"); ! 321: exit(1); } ! 322: ! 323: if(cmd&USERS) ! 324: if((users=fnopen(&i,"USERS.DAT",o_mode))==NULL) { ! 325: printf("\7\nError opening USERS.DAT\n"); ! 326: exit(1); } ! 327: ! 328: if(cmd&ROUTE) ! 329: if((route=fnopen(&i,"ROUTE.DAT",o_mode))==NULL) { ! 330: printf("\7\nError opening ROUTE.DAT\n"); ! 331: exit(1); } ! 332: ! 333: if(!node_dir[0]) { ! 334: p=getenv("SBBSNODE"); ! 335: if(p==NULL) { ! 336: printf("\7\nSBBSNODE environment variable not set.\n"); ! 337: exit(1); } ! 338: strcpy(node_dir,p); } ! 339: ! 340: strupr(node_dir); ! 341: ! 342: if(node_dir[strlen(node_dir)-1]!='\\') ! 343: strcat(node_dir,"\\"); ! 344: ! 345: read_node_cfg(txt); ! 346: if(ctrl_dir[0]=='.') { /* Relative path */ ! 347: strcpy(str,ctrl_dir); ! 348: sprintf(ctrl_dir,"%s%s",node_dir,str); ! 349: if(_fullpath(str,ctrl_dir,40)) ! 350: strcpy(ctrl_dir,str); } ! 351: backslash(ctrl_dir); ! 352: ! 353: read_main_cfg(txt); ! 354: if(data_dir[0]=='.') { /* Relative path */ ! 355: strcpy(str,data_dir); ! 356: sprintf(data_dir,"%s%s",node_dir,str); ! 357: if(_fullpath(str,data_dir,40)) ! 358: strcpy(data_dir,str); } ! 359: backslash(data_dir); ! 360: read_msgs_cfg(txt); ! 361: ! 362: now=time(NULL); ! 363: smm=crc16("smm"); ! 364: sbl=crc16("sbl"); ! 365: fprintf(stderr,"\n\n"); ! 366: for(i=0;i<total_subs;i++) { ! 367: if(!(sub[i]->misc&SUB_QNET)) ! 368: continue; ! 369: fprintf(stderr,"%-*s %s\n" ! 370: ,LEN_GSNAME,grp[sub[i]->grp]->sname,sub[i]->lname); ! 371: sprintf(smb.file,"%s%s",sub[i]->data_dir,sub[i]->code); ! 372: smb.retry_time=30; ! 373: if((j=smb_open(&smb))!=0) { ! 374: printf("smb_open returned %d\n",j); ! 375: continue; } ! 376: if((j=smb_locksmbhdr(&smb))!=0) { ! 377: printf("smb_locksmbhdr returned %d\n",j); ! 378: smb_close(&smb); ! 379: continue; } ! 380: if((j=smb_getstatus(&smb))!=0) { ! 381: printf("smb_getstatus returned %d\n",j); ! 382: smb_close(&smb); ! 383: continue; } ! 384: smb_unlocksmbhdr(&smb); ! 385: msg.offset=status.total_msgs; ! 386: if(!msg.offset) { ! 387: smb_close(&smb); ! 388: printf("Empty.\n"); ! 389: continue; } ! 390: while(!kbhit() && !ferror(smb.sid_fp) && msg.offset) { ! 391: msg.offset--; ! 392: fseek(smb.sid_fp,msg.offset*sizeof(idxrec_t),SEEK_SET); ! 393: if(!fread(&msg.idx,1,sizeof(idxrec_t),smb.sid_fp)) ! 394: break; ! 395: fprintf(stderr,"%-5lu\r",msg.offset+1); ! 396: if(msg.idx.to==smm || msg.idx.to==sbl) ! 397: continue; ! 398: if(max_age && now-msg.idx.time>((ulong)max_age*24UL*60UL*60UL)) ! 399: continue; ! 400: if((j=smb_lockmsghdr(&smb,&msg))!=0) { ! 401: printf("smb_lockmsghdr returned %d\n",j); ! 402: break; } ! 403: if((j=smb_getmsghdr(&smb,&msg))!=0) { ! 404: printf("smb_getmsghdr returned %d\n",j); ! 405: break; } ! 406: smb_unlockmsghdr(&smb,&msg); ! 407: if((mode&LOCAL && msg.from_net.type==NET_NONE) ! 408: || msg.from_net.type==NET_QWK) { ! 409: if(msg.from_net.type!=NET_QWK) ! 410: msg.from_net.addr=""; ! 411: if(cmd&USERS) { ! 412: sprintf(str,"%s%s",msg.from_net.addr,msg.from); ! 413: curcrc=crc32(str); } ! 414: else ! 415: curcrc=crc32(msg.from_net.addr); ! 416: for(l=0;l<total_crcs;l++) ! 417: if(curcrc==crc[l]) ! 418: break; ! 419: if(l==total_crcs) { ! 420: total_crcs++; ! 421: if((crc=(ulong *)REALLOC(crc ! 422: ,sizeof(ulong)*total_crcs))==NULL) { ! 423: printf("Error allocating %lu bytes\n" ! 424: ,sizeof(ulong)*total_crcs); ! 425: break; } ! 426: crc[l]=curcrc; ! 427: if(cmd&ROUTE && msg.from_net.type==NET_QWK) { ! 428: strcpy(addr,msg.from_net.addr); ! 429: if(mode&FEED) { ! 430: p=strrchr(addr,'/'); ! 431: if(!p) ! 432: p=addr; ! 433: else ! 434: *(p++)=0; ! 435: sprintf(str,"%s %s:%s%c%s" ! 436: ,unixtodstr(msg.hdr.when_written.time,tmp) ! 437: ,p,sys_id,p==addr ? 0 : '/' ! 438: ,addr); ! 439: fprintf(route,"%s\r\n",str); } ! 440: else { ! 441: p=strrchr(addr,'/'); ! 442: if(p) { ! 443: *(p++)=0; ! 444: fprintf(route,"%s %s:%.*s\r\n" ! 445: ,unixtodstr(msg.hdr.when_written.time,str) ! 446: ,p ! 447: ,(uint)(p-addr) ! 448: ,addr); } } } ! 449: if(cmd&USERS) { ! 450: if(msg.from_net.type!=NET_QWK) ! 451: strcpy(str,sys_id); ! 452: else if(mode&FEED) ! 453: sprintf(str,"%s/%s",sys_id,msg.from_net.addr); ! 454: else ! 455: strcpy(str,msg.from_net.addr); ! 456: p=strrchr(str,'/'); ! 457: if(p) ! 458: fprintf(users,"%-25.25s %-8.8s %s (%s)\r\n" ! 459: ,msg.from,p+1 ! 460: ,unixtodstr(msg.hdr.when_written.time,tmp) ! 461: ,str); ! 462: else ! 463: fprintf(users,"%-25.25s %-8.8s %s\r\n" ! 464: ,msg.from,str ! 465: ,unixtodstr(msg.hdr.when_written.time,tmp)); } ! 466: if(cmd&NODES && msg.from_net.type==NET_QWK) { ! 467: if(mode&TAGS) ! 468: gettag(msg,tag); ! 469: if(mode&FEED) ! 470: sprintf(str,"%s/%s",sys_id,msg.from_net.addr); ! 471: else ! 472: strcpy(str,msg.from_net.addr); ! 473: p=strrchr(str,'/'); ! 474: if(p) { ! 475: if(mode&TAGS) ! 476: fprintf(nodes,"%-8.8s %s\r\n" ! 477: ,p+1 ! 478: ,tag); ! 479: else ! 480: fprintf(nodes,"%-8.8s %s (%s)\r\n" ! 481: ,p+1 ! 482: ,unixtodstr(msg.hdr.when_written.time,tmp) ! 483: ,str); } ! 484: else ! 485: fprintf(nodes,"%-8.8s %s\r\n" ! 486: ,str ! 487: ,mode&TAGS ! 488: ? tag ! 489: : unixtodstr(msg.hdr.when_written.time,tmp)); } ! 490: } } ! 491: smb_freemsgmem(&msg); } ! 492: ! 493: smb_close(&smb); ! 494: if(kbhit()) { ! 495: getch(); ! 496: fprintf(stderr,"Key pressed.\n"); ! 497: break; } } ! 498: fprintf(stderr,"Done.\n"); ! 499: } ! 500:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.