|
|
1.1.1.2 ! root 1: /* $Id: qwknodes.c,v 1.19 2008/06/04 04:38:47 deuce Exp $ */ 1.1 root 2: 3: /* Synchronet QWKnet node list or route.dat file generator */ 4: 5: /**************************************************************************** 6: * @format.tab-size 4 (Plain Text/Source Code File Header) * 7: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * 8: * * 1.1.1.2 ! root 9: * Copyright 2008 Rob Swindell - http://www.synchro.net/copyright.html * 1.1 root 10: * * 11: * This program is free software; you can redistribute it and/or * 12: * modify it under the terms of the GNU General Public License * 13: * as published by the Free Software Foundation; either version 2 * 14: * of the License, or (at your option) any later version. * 15: * See the GNU General Public License for more details: gpl.txt or * 16: * http://www.fsf.org/copyleft/gpl.html * 17: * * 18: * Anonymous FTP access to the most recent released source is available at * 19: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * 20: * * 21: * Anonymous CVS access to the development source and modification history * 22: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * 23: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * 24: * (just hit return, no password is necessary) * 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * 26: * * 27: * For Synchronet coding style and modification guidelines, see * 28: * http://www.synchro.net/source.html * 29: * * 30: * You are encouraged to submit any modifications (preferably in Unix diff * 31: * format) via e-mail to [email protected] * 32: * * 33: * Note: If this box doesn't appear square, then you need to fix your tabs. * 34: ****************************************************************************/ 35: 36: #include "sbbs.h" 37: #include "nopen.h" 38: #include "crc16.h" 39: #include "crc32.h" 40: #include "conwrap.h" /* kbhit */ 41: 42: unsigned _stklen=10000; 43: smb_t smb; 44: scfg_t cfg; 45: 46: void stripctrla(uchar *str) 47: { 48: uchar out[256]; 49: int i,j; 50: 51: for(i=j=0;str[i] && j<sizeof(out)-1;i++) { 52: if(str[i]==CTRL_A && str[i+1]!=0) 53: i++; 54: else 55: out[j++]=str[i]; 56: } 57: out[j]=0; 58: strcpy(str,out); 59: } 60: 61: int lputs(char* str) 62: { 63: char tmp[256]; 64: int i,j,k; 65: 66: j=strlen(str); 67: for(i=k=0;i<j;i++) /* remove CRs */ 68: if(str[i]==CR && str[i+1]==LF) 69: continue; 70: else 71: tmp[k++]=str[i]; 72: tmp[k]=0; 73: return(fputs(tmp,stderr)); 74: } 75: /****************************************************************************/ 76: /* Performs printf() through local assembly routines */ 77: /* Called from everywhere */ 78: /****************************************************************************/ 1.1.1.2 ! root 79: int lprintf(const char *fmat, ...) 1.1 root 80: { 81: va_list argptr; 82: char sbuf[256]; 83: int chcount; 84: 85: va_start(argptr,fmat); 86: chcount=vsnprintf(sbuf,sizeof(sbuf),fmat,argptr); 87: sbuf[sizeof(sbuf)-1]=0; 88: va_end(argptr); 89: lputs(sbuf); 90: return(chcount); 91: } 92: void bail(int code) 93: { 94: exit(code); 95: } 96: 97: char *loadmsgtail(smbmsg_t msg) 98: { 99: char *buf=NULL; 1.1.1.2 ! root 100: uint16_t xlat; 1.1 root 101: int i; 102: long l=0,length; 103: 104: for(i=0;i<msg.hdr.total_dfields;i++) { 105: if(msg.dfield[i].type!=TEXT_TAIL) 106: continue; 107: fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset 108: ,SEEK_SET); 109: fread(&xlat,2,1,smb.sdt_fp); 110: if(xlat!=XLAT_NONE) /* no translations supported */ 111: continue; 112: length=msg.dfield[i].length-2; 113: if((buf=realloc(buf,l+msg.dfield[i].length+1))==NULL) 114: return(buf); 115: l+=fread(buf+l,1,length,smb.sdt_fp); 116: buf[l]=0; 117: } 118: return(buf); 119: } 120: 121: 122: void gettag(smbmsg_t msg, char *tag) 123: { 124: char *buf,*p; 125: 126: tag[0]=0; 127: buf=loadmsgtail(msg); 128: if(buf==NULL) 129: return; 130: truncsp(buf); 131: stripctrla(buf); 132: p=strrchr(buf,LF); 133: if(!p) p=buf; 134: else p++; 135: if(!strnicmp(p," � Synchronet � ",16)) 136: p+=16; 137: if(!strnicmp(p," * Synchronet * ",16)) 138: p+=16; 139: while(*p && *p<=' ') p++; 140: strcpy(tag,p); 141: free(buf); 142: } 143: 144: 145: #define FEED (1<<0) 146: #define LOCAL (1<<1) 147: #define APPEND (1<<2) 148: #define TAGS (1<<3) 149: 150: #define ROUTE (1<<1) 151: #define NODES (1<<2) 152: #define USERS (1<<3) 153: 154: char *usage="\nusage: qwknodes [-opts] cmds" 155: "\n" 156: "\n cmds: r = create route.dat" 157: "\n u = create users.dat" 158: "\n n = create nodes.dat" 159: "\n" 160: "\n opts: f = format addresses for nodes that feed from this system" 161: "\n a = append existing output files" 162: "\n t = include tag lines in nodes.dat" 163: "\n l = include local users in users.dat" 164: "\n m# = maximum message age set to # days" 165: "\n"; 166: 167: int main(int argc, char **argv) 168: { 169: char str[256],tmp[128],tag[256],addr[256],*p; 170: int i,j,mode=0,cmd=0,o_mode,max_age=0; 171: ushort smm,sbl; 172: ulong *crc=NULL,curcrc,total_crcs=0,l; 173: FILE *route,*users,*nodes; 174: time_t now; 175: smbmsg_t msg; 176: char *ctrl_dir; 177: char revision[16]; 178: 1.1.1.2 ! root 179: sscanf("$Revision: 1.19 $", "%*s %s", revision); 1.1 root 180: 181: fprintf(stderr,"\nSynchronet QWKnet Node/Route/User List Generator v%s-%s\n" 182: ,revision, PLATFORM_DESC); 183: 184: for(i=1;i<argc;i++) 185: for(j=0;argv[i][j];j++) 186: switch(toupper(argv[i][j])) { 187: case '/': 188: case '-': 189: while(argv[i][++j]) 190: switch(toupper(argv[i][j])) { 191: case 'F': 192: mode|=FEED; 193: break; 194: case 'L': 195: mode|=LOCAL; 196: break; 197: case 'A': 198: mode|=APPEND; 199: break; 200: case 'T': 201: mode|=TAGS; 202: break; 203: case 'M': 204: j++; 205: max_age=atoi(argv[i]+j); 206: while(isdigit(argv[i][j+1])) j++; 207: break; 208: default: 209: printf(usage); 210: return(1); 211: } 212: j--; 213: break; 214: case 'R': 215: cmd|=ROUTE; 216: break; 217: case 'U': 218: cmd|=USERS; 219: break; 220: case 'N': 221: cmd|=NODES; 222: break; 223: default: 224: printf(usage); 225: return(1); 226: } 227: 228: if(!cmd) { 229: printf(usage); 230: return(1); 231: } 232: 233: if(mode&APPEND) 234: o_mode=O_WRONLY|O_CREAT|O_APPEND; 235: else 236: o_mode=O_WRONLY|O_CREAT|O_TRUNC; 237: 238: if(cmd&NODES) 239: if((nodes=fnopen(&i,"nodes.dat",o_mode))==NULL) { 240: printf("\7\nError opening nodes.dat\n"); 241: return(1); 242: } 243: 244: if(cmd&USERS) 245: if((users=fnopen(&i,"users.dat",o_mode))==NULL) { 246: printf("\7\nError opening users.dat\n"); 247: return(1); 248: } 249: 250: if(cmd&ROUTE) 251: if((route=fnopen(&i,"route.dat",o_mode))==NULL) { 252: printf("\7\nError opening route.dat\n"); 253: return(1); 254: } 255: 256: cfg.size=sizeof(cfg); 257: ctrl_dir=getenv("SBBSCTRL"); 258: if(ctrl_dir==NULL || ctrl_dir[0]==0) { 259: ctrl_dir="/sbbs/ctrl"; /* Not set? Use default */ 260: printf("!SBBSCTRL environment variable not set, using default value: %s\n\n" 261: ,ctrl_dir); 262: } 263: SAFECOPY(cfg.ctrl_dir, ctrl_dir); 264: 265: if(!load_cfg(&cfg, NULL, TRUE, str)) { 266: printf("\7\n%s\n",str); 267: } 268: 269: now=time(NULL); 270: smm=crc16("smm",0); 271: sbl=crc16("sbl",0); 272: fprintf(stderr,"\n\n"); 273: for(i=0;i<cfg.total_subs;i++) { 274: if(!(cfg.sub[i]->misc&SUB_QNET)) 275: continue; 276: fprintf(stderr,"%-*s %s\n" 277: ,LEN_GSNAME,cfg.grp[cfg.sub[i]->grp]->sname,cfg.sub[i]->lname); 278: sprintf(smb.file,"%s%s",cfg.sub[i]->data_dir,cfg.sub[i]->code); 279: smb.retry_time=30; 280: smb.subnum=i; 281: if((j=smb_open(&smb))!=0) { 282: printf("smb_open returned %d\n",j); 283: continue; 284: } 285: if((j=smb_locksmbhdr(&smb))!=0) { 286: printf("smb_locksmbhdr returned %d\n",j); 287: smb_close(&smb); 288: continue; 289: } 290: if((j=smb_getstatus(&smb))!=0) { 291: printf("smb_getstatus returned %d\n",j); 292: smb_close(&smb); 293: continue; 294: } 295: smb_unlocksmbhdr(&smb); 296: msg.offset=smb.status.total_msgs; 297: if(!msg.offset) { 298: smb_close(&smb); 299: printf("Empty.\n"); 300: continue; 301: } 302: while(!kbhit() && !ferror(smb.sid_fp) && msg.offset) { 303: msg.offset--; 304: fseek(smb.sid_fp,msg.offset*sizeof(idxrec_t),SEEK_SET); 305: if(!fread(&msg.idx,1,sizeof(idxrec_t),smb.sid_fp)) 306: break; 307: fprintf(stderr,"%-5lu\r",msg.offset+1); 308: if(msg.idx.to==smm || msg.idx.to==sbl) 309: continue; 310: if(max_age && now-msg.idx.time>((ulong)max_age*24UL*60UL*60UL)) 311: continue; 312: if((j=smb_lockmsghdr(&smb,&msg))!=0) { 313: printf("smb_lockmsghdr returned %d\n",j); 314: break; 315: } 316: if((j=smb_getmsghdr(&smb,&msg))!=0) { 317: printf("smb_getmsghdr returned %d\n",j); 318: break; 319: } 320: smb_unlockmsghdr(&smb,&msg); 321: if((mode&LOCAL && msg.from_net.type==NET_NONE) 1.1.1.2 ! root 322: || (msg.from_net.type==NET_QWK && msg.from_net.addr!=NULL)) { 1.1 root 323: if(msg.from_net.type!=NET_QWK) 324: msg.from_net.addr=""; 325: if(cmd&USERS) { 326: sprintf(str,"%s%s",msg.from_net.addr,msg.from); 327: curcrc=crc32(str,0); 328: } 329: else 330: curcrc=crc32(msg.from_net.addr,0); 331: for(l=0;l<total_crcs;l++) 332: if(curcrc==crc[l]) 333: break; 334: if(l==total_crcs) { 335: total_crcs++; 336: if((crc=(ulong *)realloc(crc 337: ,sizeof(ulong)*total_crcs))==NULL) { 338: printf("Error allocating %lu bytes\n" 339: ,sizeof(ulong)*total_crcs); 340: break; 341: } 342: crc[l]=curcrc; 343: if(cmd&ROUTE && msg.from_net.type==NET_QWK) { 344: strcpy(addr,msg.from_net.addr); 345: if(mode&FEED) { 346: p=strrchr(addr,'/'); 347: if(!p) 348: p=addr; 349: else 350: *(p++)=0; 351: sprintf(str,"%s %s:%s%c%s" 352: ,unixtodstr(&cfg,msg.hdr.when_written.time,tmp) 353: ,p,cfg.sys_id,p==addr ? 0 : '/' 354: ,addr); 355: fprintf(route,"%s\r\n",str); 356: } 357: else { 358: p=strrchr(addr,'/'); 359: if(p) { 360: *(p++)=0; 361: fprintf(route,"%s %s:%.*s\r\n" 362: ,unixtodstr(&cfg,msg.hdr.when_written.time,str) 363: ,p 364: ,(uint)(p-addr) 365: ,addr); 366: } 367: } 368: } 369: if(cmd&USERS) { 370: if(msg.from_net.type!=NET_QWK) 371: strcpy(str,cfg.sys_id); 372: else if(mode&FEED) 373: sprintf(str,"%s/%s",cfg.sys_id,msg.from_net.addr); 374: else 375: strcpy(str,msg.from_net.addr); 376: p=strrchr(str,'/'); 377: if(p) 378: fprintf(users,"%-25.25s %-8.8s %s (%s)\r\n" 379: ,msg.from,p+1 380: ,unixtodstr(&cfg,msg.hdr.when_written.time,tmp) 381: ,str); 382: else 383: fprintf(users,"%-25.25s %-8.8s %s\r\n" 384: ,msg.from,str 385: ,unixtodstr(&cfg,msg.hdr.when_written.time,tmp)); 386: } 387: if(cmd&NODES && msg.from_net.type==NET_QWK) { 388: if(mode&TAGS) 389: gettag(msg,tag); 390: if(mode&FEED) 391: sprintf(str,"%s/%s",cfg.sys_id,msg.from_net.addr); 392: else 393: strcpy(str,msg.from_net.addr); 394: p=strrchr(str,'/'); 395: if(p) { 396: if(mode&TAGS) 397: fprintf(nodes,"%-8.8s %s\r\n" 398: ,p+1 399: ,tag); 400: else 401: fprintf(nodes,"%-8.8s %s (%s)\r\n" 402: ,p+1 403: ,unixtodstr(&cfg,msg.hdr.when_written.time,tmp) 404: ,str); 405: } 406: else 407: fprintf(nodes,"%-8.8s %s\r\n" 408: ,str 409: ,mode&TAGS 410: ? tag 411: : unixtodstr(&cfg,msg.hdr.when_written.time,tmp)); 412: } 413: } 414: } 415: smb_freemsgmem(&msg); 416: } 417: 418: smb_close(&smb); 419: if(kbhit()) { 420: getch(); 421: fprintf(stderr,"Key pressed.\n"); 422: break; 423: } 424: } 425: fprintf(stderr,"Done.\n"); 426: 427: return(0); 428: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.