|
|
1.1 ! root 1: /* $Id: qwknodes.c,v 1.16 2005/12/04 20:41:51 rswindell Exp $ */ ! 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: * * ! 9: * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * ! 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: /****************************************************************************/ ! 79: int lprintf(char *fmat, ...) ! 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; ! 100: ushort xlat; ! 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: ! 179: sscanf("$Revision: 1.16 $", "%*s %s", revision); ! 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) ! 322: || msg.from_net.type==NET_QWK) { ! 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.