|
|
1.1 ! root 1: /* un_qwk.cpp */ ! 2: ! 3: /* Synchronet QWK unpacking routine */ ! 4: ! 5: /* $Id: un_qwk.cpp,v 1.30 2006/05/08 17:02:29 deuce Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "sbbs.h" ! 39: #include "qwk.h" ! 40: ! 41: /****************************************************************************/ ! 42: /* Unpacks .QWK packet, hubnum is the number of the QWK net hub */ ! 43: /****************************************************************************/ ! 44: bool sbbs_t::unpack_qwk(char *packet,uint hubnum) ! 45: { ! 46: char str[MAX_PATH+1],fname[MAX_PATH+1]; ! 47: char tmp[512]; ! 48: char from[26]; ! 49: char to[26]; ! 50: char inbox[MAX_PATH+1]; ! 51: uchar block[QWK_BLOCK_LEN]; ! 52: int k,file; ! 53: uint i,j,n,lastsub=INVALID_SUB; ! 54: uint blocks; ! 55: long l,size,misc; ! 56: ulong t; ! 57: ulong msgs=0; ! 58: ulong tmsgs=0; ! 59: time_t start; ! 60: time_t startsub; ! 61: DIR* dir; ! 62: DIRENT* dirent; ! 63: FILE* qwk; ! 64: BOOL twit_list; ! 65: ! 66: sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir); ! 67: twit_list=fexist(fname); ! 68: ! 69: start=time(NULL); ! 70: if((l=flength(packet))<1) { ! 71: errormsg(WHERE,ERR_LEN,packet,l); ! 72: return(false); ! 73: } ! 74: i=external(cmdstr(cfg.qhub[hubnum]->unpack,packet,ALLFILES,NULL),EX_OFFLINE); ! 75: if(i) { ! 76: errormsg(WHERE,ERR_EXEC,cmdstr(cfg.qhub[hubnum]->unpack,packet,ALLFILES,NULL),i); ! 77: return(false); ! 78: } ! 79: sprintf(str,"%sMESSAGES.DAT",cfg.temp_dir); ! 80: if(!fexistcase(str)) { ! 81: sprintf(str,"%s doesn't contain MESSAGES.DAT (%s)",packet,str); ! 82: errorlog(str); ! 83: return(false); ! 84: } ! 85: if((qwk=fnopen(&file,str,O_RDONLY))==NULL) { ! 86: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 87: return(false); ! 88: } ! 89: size=filelength(file); ! 90: /********************/ ! 91: /* Process messages */ ! 92: /********************/ ! 93: eprintf(LOG_INFO,"Importing QWK Network Packet: %s",packet); ! 94: ! 95: for(l=QWK_BLOCK_LEN;l<size;l+=blocks*QWK_BLOCK_LEN) { ! 96: if(terminated) { ! 97: eprintf(LOG_NOTICE,"!Terminated"); ! 98: break; ! 99: } ! 100: fseek(qwk,l,SEEK_SET); ! 101: fread(block,QWK_BLOCK_LEN,1,qwk); ! 102: if(block[0]<' ' || block[0]&0x80) { ! 103: eprintf(LOG_NOTICE,"!Invalid message status (%02X) at offset %lu in %s" ! 104: ,block[0], l, packet); ! 105: blocks=1; ! 106: continue; ! 107: } ! 108: sprintf(tmp,"%.6s",block+116); ! 109: blocks=atoi(tmp); /* i = number of blocks */ ! 110: if(blocks<2) { ! 111: eprintf(LOG_NOTICE,"!Invalid number of blocks (%d) at offset %lu in %s" ! 112: ,blocks, l+116, packet); ! 113: blocks=1; ! 114: continue; ! 115: } ! 116: /*********************************/ ! 117: /* public message on a sub-board */ ! 118: /*********************************/ ! 119: n=(uint)block[123]|(((uint)block[124])<<8); /* conference number */ ! 120: ! 121: if(!n) { /* NETMAIL */ ! 122: sprintf(str,"%25.25s",block+21); ! 123: truncsp(str); ! 124: eprintf(LOG_INFO,"NetMail from %s to %s", cfg.qhub[hubnum]->id, str); ! 125: if(!stricmp(str,"NETMAIL")) { /* QWK to FidoNet NetMail */ ! 126: qwktonetmail(qwk,(char *)block,NULL,hubnum+1); ! 127: continue; ! 128: } ! 129: if(strchr(str,'@')) { ! 130: qwktonetmail(qwk,(char *)block,str,hubnum+1); ! 131: continue; ! 132: } ! 133: j=atoi(str); ! 134: if(j && j>lastuser(&cfg)) ! 135: j=0; ! 136: if(!j) ! 137: j=matchuser(&cfg,str,TRUE /* sysop_alias */); ! 138: if(!j) { ! 139: eprintf(LOG_NOTICE,"!NetMail from %s to UNKNOWN USER: %s", cfg.qhub[hubnum]->id, str); ! 140: continue; ! 141: } ! 142: ! 143: getuserrec(&cfg,j,U_MISC,8,str); ! 144: misc=ahtoul(str); ! 145: if(misc&NETMAIL && cfg.sys_misc&SM_FWDTONET) { ! 146: getuserrec(&cfg,j,U_NETMAIL,LEN_NETMAIL,str); ! 147: qwktonetmail(qwk,(char*)block,str,hubnum+1); ! 148: continue; ! 149: } ! 150: ! 151: smb_stack(&smb,SMB_STACK_PUSH); ! 152: sprintf(smb.file,"%smail",cfg.data_dir); ! 153: smb.retry_time=cfg.smb_retry_time; ! 154: smb.subnum=INVALID_SUB; ! 155: if((k=smb_open(&smb))!=0) { ! 156: errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error); ! 157: smb_stack(&smb,SMB_STACK_POP); ! 158: continue; ! 159: } ! 160: if(!filelength(fileno(smb.shd_fp))) { ! 161: smb.status.max_crcs=cfg.mail_maxcrcs; ! 162: smb.status.max_msgs=0; ! 163: smb.status.max_age=cfg.mail_maxage; ! 164: smb.status.attr=SMB_EMAIL; ! 165: if((k=smb_create(&smb))!=0) { ! 166: smb_close(&smb); ! 167: errormsg(WHERE,ERR_CREATE,smb.file,k); ! 168: smb_stack(&smb,SMB_STACK_POP); ! 169: continue; ! 170: } ! 171: } ! 172: if((k=smb_locksmbhdr(&smb))!=0) { ! 173: smb_close(&smb); ! 174: errormsg(WHERE,ERR_LOCK,smb.file,k); ! 175: smb_stack(&smb,SMB_STACK_POP); ! 176: continue; ! 177: } ! 178: if((k=smb_getstatus(&smb))!=0) { ! 179: smb_close(&smb); ! 180: errormsg(WHERE,ERR_READ,smb.file,k); ! 181: smb_stack(&smb,SMB_STACK_POP); ! 182: continue; ! 183: } ! 184: smb_unlocksmbhdr(&smb); ! 185: if(qwktomsg(qwk,(char *)block,hubnum+1,INVALID_SUB,j)) { ! 186: sprintf(tmp,"%-25.25s",block+46); ! 187: truncsp(tmp); ! 188: sprintf(str,text[UserSentYouMail],tmp); ! 189: putsmsg(&cfg,j,str); ! 190: tmsgs++; ! 191: } ! 192: smb_close(&smb); ! 193: smb_stack(&smb,SMB_STACK_POP); ! 194: continue; ! 195: } ! 196: ! 197: for(j=0;j<cfg.qhub[hubnum]->subs;j++) ! 198: if(cfg.qhub[hubnum]->conf[j]==n) ! 199: break; ! 200: if(j>=cfg.qhub[hubnum]->subs) { /* ignore messages for subs not in config */ ! 201: eprintf(LOG_NOTICE,"!Message from %s on UNKNOWN CONFERENCE NUMBER: %u" ! 202: ,cfg.qhub[hubnum]->id, n); ! 203: continue; ! 204: } ! 205: ! 206: j=cfg.qhub[hubnum]->sub[j]; ! 207: ! 208: /* TWIT FILTER */ ! 209: if(twit_list) { ! 210: sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir); ! 211: ! 212: sprintf(from,"%25.25s",block+46); /* From user */ ! 213: truncsp(from); ! 214: sprintf(to,"%25.25s",block+21); /* To user */ ! 215: truncsp(to); ! 216: ! 217: if(findstr(from,fname) || findstr(to,fname)) { ! 218: eprintf(LOG_NOTICE,"!Filtering post from %s to %s on %s %s" ! 219: ,from ! 220: ,to ! 221: ,cfg.grp[cfg.sub[j]->grp]->sname,cfg.sub[j]->lname); ! 222: continue; ! 223: } ! 224: } ! 225: ! 226: if(j!=lastsub) { ! 227: ! 228: if(msgs) { ! 229: t=time(NULL)-startsub; ! 230: if(t<1) ! 231: t=1; ! 232: eprintf(LOG_INFO,"Imported %lu msgs in %lu seconds (%lu msgs/sec)", msgs,t,msgs/t); ! 233: } ! 234: msgs=0; ! 235: startsub=time(NULL); ! 236: ! 237: eprintf(LOG_INFO,"Importing messages from %s into %s %s" ! 238: ,cfg.qhub[hubnum]->id, cfg.grp[cfg.sub[j]->grp]->sname,cfg.sub[j]->lname); ! 239: ! 240: if(lastsub!=INVALID_SUB) ! 241: smb_close(&smb); ! 242: lastsub=INVALID_SUB; ! 243: sprintf(smb.file,"%s%s",cfg.sub[j]->data_dir,cfg.sub[j]->code); ! 244: smb.retry_time=cfg.smb_retry_time; ! 245: smb.subnum=j; ! 246: if((k=smb_open(&smb))!=0) { ! 247: errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error); ! 248: continue; ! 249: } ! 250: if(!filelength(fileno(smb.shd_fp))) { ! 251: smb.status.max_crcs=cfg.sub[j]->maxcrcs; ! 252: smb.status.max_msgs=cfg.sub[j]->maxmsgs; ! 253: smb.status.max_age=cfg.sub[j]->maxage; ! 254: smb.status.attr=cfg.sub[j]->misc&SUB_HYPER ? SMB_HYPERALLOC :0; ! 255: if((k=smb_create(&smb))!=0) { ! 256: smb_close(&smb); ! 257: errormsg(WHERE,ERR_CREATE,smb.file,k); ! 258: continue; ! 259: } ! 260: } ! 261: if((k=smb_locksmbhdr(&smb))!=0) { ! 262: smb_close(&smb); ! 263: errormsg(WHERE,ERR_LOCK,smb.file,k); ! 264: continue; ! 265: } ! 266: if((k=smb_getstatus(&smb))!=0) { ! 267: smb_close(&smb); ! 268: errormsg(WHERE,ERR_READ,smb.file,k); ! 269: continue; ! 270: } ! 271: smb_unlocksmbhdr(&smb); ! 272: lastsub=j; ! 273: } ! 274: ! 275: if(!qwktomsg(qwk,(char *)block,hubnum+1,j,0)) { ! 276: // eprintf("!QWKTOMSG failed"); ! 277: continue; ! 278: } ! 279: ! 280: signal_sub_sem(&cfg,j); ! 281: /* ! 282: eprintf("Message from %s Posted on %s %s" ! 283: ,cfg.qhub[hubnum]->id,cfg.grp[cfg.sub[j]->grp]->sname,cfg.sub[j]->lname); ! 284: */ ! 285: msgs++; ! 286: tmsgs++; ! 287: } ! 288: ! 289: update_qwkroute(NULL); /* Write ROUTE.DAT */ ! 290: ! 291: fclose(qwk); ! 292: if(lastsub!=INVALID_SUB) ! 293: smb_close(&smb); ! 294: ! 295: delfiles(cfg.temp_dir,"*.NDX"); ! 296: sprintf(str,"%sMESSAGES.DAT",cfg.temp_dir); ! 297: remove(str); ! 298: sprintf(str,"%sDOOR.ID",cfg.temp_dir); ! 299: remove(str); ! 300: sprintf(str,"%sCONTROL.DAT",cfg.temp_dir); ! 301: remove(str); ! 302: sprintf(str,"%sNETFLAGS.DAT",cfg.temp_dir); ! 303: remove(str); ! 304: ! 305: dir=opendir(cfg.temp_dir); ! 306: while(dir!=NULL && (dirent=readdir(dir))!=NULL) { ! 307: sprintf(str,"%s%s",cfg.temp_dir,dirent->d_name); ! 308: if(isdir(str)) /* sub-dir */ ! 309: continue; ! 310: ! 311: // Create directory if necessary ! 312: sprintf(inbox,"%sqnet/%s.in",cfg.data_dir,cfg.qhub[hubnum]->id); ! 313: MKDIR(inbox); ! 314: ! 315: // Copy files ! 316: sprintf(fname,"%s/%s",inbox,dirent->d_name); ! 317: mv(str,fname,1 /* overwrite */); ! 318: sprintf(str,text[ReceivedFileViaQWK],dirent->d_name,cfg.qhub[hubnum]->id); ! 319: putsmsg(&cfg,1,str); ! 320: eprintf(LOG_INFO,"Received %s from %s", dirent->d_name, cfg.qhub[hubnum]->id); ! 321: } ! 322: if(dir!=NULL) ! 323: closedir(dir); ! 324: ! 325: t=time(NULL)-start; ! 326: if(tmsgs) { ! 327: if(t<1) ! 328: t=1; ! 329: eprintf(LOG_INFO,"Finished Importing QWK Network Packet from %s: " ! 330: "(%lu msgs) in %lu seconds (%lu msgs/sec)" ! 331: ,cfg.qhub[hubnum]->id, tmsgs, t, tmsgs/t); ! 332: } ! 333: delfiles(cfg.temp_dir,ALLFILES); ! 334: return(true); ! 335: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.