|
|
1.1 root 1: /* pack_rep.cpp */
2:
3: /* Synchronet QWK reply (REP) packet creation routine */
4:
1.1.1.2 ! root 5: /* $Id: pack_rep.cpp,v 1.38 2011/09/21 03:10:53 rswindell Exp $ */
1.1 root 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: * *
1.1.1.2 ! root 11: * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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: /* Creates an REP packet for upload to QWK hub 'hubnum'. */
43: /* Returns 1 if successful, 0 if not. */
44: /****************************************************************************/
45: bool sbbs_t::pack_rep(uint hubnum)
46: {
1.1.1.2 ! root 47: char str[MAX_PATH+1];
! 48: char tmp[MAX_PATH+1],tmp2[MAX_PATH+1];
! 49: char hubid_upper[LEN_QWKID+1];
! 50: char hubid_lower[LEN_QWKID+1];
! 51: int file,mode;
! 52: uint i,j,k;
! 53: long l,msgcnt,submsgs,packedmail,netfiles=0,deleted;
! 54: int32_t posts;
! 55: int32_t mailmsgs;
! 56: ulong msgs;
! 57: uint32_t last;
! 58: post_t* post;
! 59: mail_t* mail;
! 60: FILE* rep;
! 61: FILE* hdrs=NULL;
! 62: DIR* dir;
! 63: DIRENT* dirent;
! 64: smbmsg_t msg;
1.1 root 65:
66: msgcnt=0L;
67: delfiles(cfg.temp_dir,ALLFILES);
1.1.1.2 ! root 68:
! 69: SAFECOPY(hubid_upper,cfg.qhub[hubnum]->id);
! 70: strupr(hubid_upper);
! 71: SAFECOPY(hubid_lower,cfg.qhub[hubnum]->id);
! 72: strlwr(hubid_lower);
! 73:
! 74: SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper);
! 75: if(fexistcase(str)) {
1.1 root 76: eprintf(LOG_INFO,"Updating %s", str);
77: external(cmdstr(cfg.qhub[hubnum]->unpack,str,ALLFILES,NULL),EX_OFFLINE);
78: } else
79: eprintf(LOG_INFO,"Creating %s", str);
80: /*************************************************/
81: /* Create SYSID.MSG, write header and leave open */
82: /*************************************************/
1.1.1.2 ! root 83: SAFEPRINTF2(str,"%s%s.MSG",cfg.temp_dir,hubid_upper);
! 84: fexistcase(str);
1.1 root 85: if((rep=fnopen(&file,str,O_CREAT|O_WRONLY|O_TRUNC))==NULL) {
86: errormsg(WHERE,ERR_CREATE,str,O_CREAT|O_WRONLY|O_TRUNC);
1.1.1.2 ! root 87: return(false);
! 88: }
1.1 root 89: if(filelength(file)<1) { /* New REP packet */
1.1.1.2 ! root 90: SAFEPRINTF2(str,"%-*s"
! 91: ,QWK_BLOCK_LEN,hubid_upper); /* So write header */
1.1 root 92: fwrite(str,QWK_BLOCK_LEN,1,rep);
93: }
94: fseek(rep,0L,SEEK_END);
1.1.1.2 ! root 95:
! 96: /* Always includes HEADERS.DAT in .REP packets which are only for QWKnet hubs */
! 97: /* And *usually* a Synchronet system */
! 98: SAFEPRINTF(str,"%sHEADERS.DAT",cfg.temp_dir);
! 99: fexistcase(str);
! 100: if((hdrs=fopen(str,"a"))==NULL)
! 101: errormsg(WHERE,ERR_CREATE,str,0);
! 102:
1.1 root 103: /*********************/
104: /* Pack new messages */
105: /*********************/
1.1.1.2 ! root 106: SAFEPRINTF(smb.file,"%smail",cfg.data_dir);
1.1 root 107: smb.retry_time=cfg.smb_retry_time;
108: smb.subnum=INVALID_SUB;
109: if((i=smb_open(&smb))!=0) {
110: fclose(rep);
1.1.1.2 ! root 111: if(hdrs!=NULL)
! 112: fclose(hdrs);
1.1 root 113: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
1.1.1.2 ! root 114: return(false);
! 115: }
1.1 root 116:
117: /***********************/
118: /* Pack E-mail, if any */
119: /***********************/
120: qwkmail_last=0;
121: mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0);
122: packedmail=0;
123: if(mailmsgs) {
124: eprintf(LOG_INFO,"Packing NetMail for %s", cfg.qhub[hubnum]->id);
125: for(l=0;l<mailmsgs;l++) {
126: // bprintf("\b\b\b\b\b%-5lu",l+1);
127:
128: memset(&msg,0,sizeof(msg));
129: msg.idx=mail[l];
130: if(msg.idx.number>qwkmail_last)
131: qwkmail_last=msg.idx.number;
132: if(!loadmsg(&msg,mail[l].number))
133: continue;
134:
1.1.1.2 ! root 135: SAFEPRINTF(str,"%s/",cfg.qhub[hubnum]->id);
1.1 root 136: if(msg.to_net.type!=NET_QWK
137: || (strcmp((char *)msg.to_net.addr,cfg.qhub[hubnum]->id)
138: && strncmp((char *)msg.to_net.addr,str,strlen(str)))) {
139: smb_unlockmsghdr(&smb,&msg);
140: smb_freemsgmem(&msg);
1.1.1.2 ! root 141: continue;
! 142: }
1.1 root 143:
1.1.1.2 ! root 144: msgtoqwk(&msg,rep,QM_TO_QNET|QM_REP|A_LEAVE,INVALID_SUB,0,hdrs);
1.1 root 145: packedmail++;
146: smb_unlockmsghdr(&smb,&msg);
147: smb_freemsgmem(&msg);
148: YIELD(); /* yield */
149: }
150: eprintf(LOG_INFO,"Packed %d NetMail messages",packedmail);
151: }
152: smb_close(&smb); /* Close the e-mail */
153: if(mailmsgs)
154: free(mail);
155:
156: for(i=0;i<cfg.qhub[hubnum]->subs;i++) {
157: j=cfg.qhub[hubnum]->sub[i]; /* j now equals the real sub num */
158: msgs=getlastmsg(j,&last,0);
159: lncntr=0; /* defeat pause */
160: if(!msgs || last<=subscan[j].ptr) {
161: if(subscan[j].ptr>last) {
162: subscan[j].ptr=last;
1.1.1.2 ! root 163: subscan[j].last=last;
! 164: }
1.1 root 165: eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp)
166: ,cfg.grp[cfg.sub[j]->grp]->sname
167: ,cfg.sub[j]->lname,0L,msgs);
1.1.1.2 ! root 168: continue;
! 169: }
1.1 root 170:
1.1.1.2 ! root 171: SAFEPRINTF2(smb.file,"%s%s"
1.1 root 172: ,cfg.sub[j]->data_dir,cfg.sub[j]->code);
173: smb.retry_time=cfg.smb_retry_time;
174: smb.subnum=j;
175: if((k=smb_open(&smb))!=0) {
176: errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error);
1.1.1.2 ! root 177: continue;
! 178: }
1.1 root 179:
180: post=loadposts(&posts,j,subscan[j].ptr,LP_BYSELF|LP_OTHERS|LP_PRIVATE|LP_REP);
181: eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp)
182: ,cfg.grp[cfg.sub[j]->grp]->sname
183: ,cfg.sub[j]->lname,posts,msgs);
184: if(!posts) { /* no new messages */
185: smb_close(&smb);
1.1.1.2 ! root 186: continue;
! 187: }
1.1 root 188:
189: subscan[j].ptr=last; /* set pointer */
190: eprintf(LOG_INFO,"%s",remove_ctrl_a(text[QWKPackingSubboard],tmp)); /* ptr to last msg */
191: submsgs=0;
192: for(l=0;l<posts;l++) {
193: // bprintf("\b\b\b\b\b%-5lu",l+1);
194:
195: memset(&msg,0,sizeof(msg));
196: msg.idx=post[l];
197: if(!loadmsg(&msg,post[l].number))
198: continue;
199:
200: if(msg.from_net.type && msg.from_net.type!=NET_QWK &&
201: !(cfg.sub[j]->misc&SUB_GATE)) {
202: smb_freemsgmem(&msg);
203: smb_unlockmsghdr(&smb,&msg);
1.1.1.2 ! root 204: continue;
! 205: }
1.1 root 206:
207: if(!strnicmp(msg.subj,"NE:",3) || (msg.from_net.type==NET_QWK &&
208: route_circ((char *)msg.from_net.addr,cfg.qhub[hubnum]->id))) {
209: smb_freemsgmem(&msg);
210: smb_unlockmsghdr(&smb,&msg);
1.1.1.2 ! root 211: continue;
! 212: }
1.1 root 213:
214: mode=cfg.qhub[hubnum]->mode[i]|QM_TO_QNET|QM_REP;
215: if(mode&A_LEAVE) mode|=(QM_VIA|QM_TZ|QM_MSGID);
216: if(msg.from_net.type!=NET_QWK)
217: mode|=QM_TAGLINE;
218:
1.1.1.2 ! root 219: msgtoqwk(&msg,rep,mode,j,cfg.qhub[hubnum]->conf[i],hdrs);
1.1 root 220:
221: smb_freemsgmem(&msg);
222: smb_unlockmsghdr(&smb,&msg);
223: msgcnt++;
224: submsgs++;
225: if(!(l%50))
226: YIELD(); /* yield */
227: }
228: eprintf(LOG_INFO,remove_ctrl_a(text[QWKPackedSubboard],tmp),submsgs,msgcnt);
229: free(post);
230: smb_close(&smb);
231: YIELD(); /* yield */
232: }
233:
1.1.1.2 ! root 234: if(hdrs!=NULL)
! 235: fclose(hdrs);
1.1 root 236: fclose(rep); /* close HUB_ID.MSG */
237: CRLF;
238: /* Look for extra files to send out */
1.1.1.2 ! root 239: SAFEPRINTF2(str,"%sqnet/%s.out",cfg.data_dir,hubid_lower);
1.1 root 240: dir=opendir(str);
241: while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
1.1.1.2 ! root 242: SAFEPRINTF3(str,"%sqnet/%s.out/%s",cfg.data_dir,hubid_lower,dirent->d_name);
1.1 root 243: if(isdir(str))
244: continue;
1.1.1.2 ! root 245: SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,dirent->d_name);
1.1 root 246: eprintf(LOG_INFO,remove_ctrl_a(text[RetrievingFile],tmp),str);
1.1.1.2 ! root 247: if(!mv(str,tmp2,/* copy: */TRUE))
1.1 root 248: netfiles++;
249: }
250: if(dir!=NULL)
251: closedir(dir);
252: if(netfiles)
253: CRLF;
254:
255: if(!msgcnt && !netfiles && !packedmail) {
256: eprintf(LOG_INFO,remove_ctrl_a(text[QWKNoNewMessages],tmp));
257: return(true); // Changed from false Mar-11-2005 (needs to be true to save updated ptrs)
258: }
259:
260: /*******************/
261: /* Compress Packet */
262: /*******************/
1.1.1.2 ! root 263: SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper);
! 264: SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,ALLFILES);
1.1 root 265: i=external(cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL)
266: ,EX_OFFLINE|EX_WILDCARD);
1.1.1.2 ! root 267: if(!fexistcase(str)) {
1.1 root 268: eprintf(LOG_WARNING,"%s",remove_ctrl_a(text[QWKCompressionFailed],tmp));
269: if(i)
270: errormsg(WHERE,ERR_EXEC,cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL),i);
271: else
1.1.1.2 ! root 272: lprintf(LOG_ERR, "Couldn't compress REP packet");
! 273: return(false);
! 274: }
! 275: SAFEPRINTF2(str,"%sqnet/%s.out/",cfg.data_dir,hubid_lower);
1.1 root 276: delfiles(str,ALLFILES);
277:
278: if(packedmail) { /* Delete NetMail */
1.1.1.2 ! root 279: SAFEPRINTF(smb.file,"%smail",cfg.data_dir);
1.1 root 280: smb.retry_time=cfg.smb_retry_time;
281: smb.subnum=INVALID_SUB;
282: if((i=smb_open(&smb))!=0) {
283: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
1.1.1.2 ! root 284: return(true);
! 285: }
1.1 root 286:
287: mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0);
288:
289: if((i=smb_locksmbhdr(&smb))!=0) { /* Lock the base, so nobody */
290: if(mailmsgs)
291: free(mail);
292: smb_close(&smb);
293: errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); /* messes with the index */
1.1.1.2 ! root 294: return(true);
! 295: }
1.1 root 296:
297: if((i=smb_getstatus(&smb))!=0) {
298: if(mailmsgs)
299: free(mail);
300: smb_close(&smb);
301: errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
1.1.1.2 ! root 302: return(true);
! 303: }
1.1 root 304:
305: deleted=0;
306: /* Mark as READ and DELETE */
307: for(l=0;l<mailmsgs;l++) {
308: if(mail[l].number>qwkmail_last)
309: continue;
310: memset(&msg,0,sizeof(msg));
311: /* !IMPORTANT: search by number (do not initialize msg.idx.offset) */
312: if(!loadmsg(&msg,mail[l].number))
313: continue;
314:
1.1.1.2 ! root 315: SAFEPRINTF(str,"%s/",cfg.qhub[hubnum]->id);
1.1 root 316: if(msg.to_net.type!=NET_QWK
317: || (strcmp((char *)msg.to_net.addr,cfg.qhub[hubnum]->id)
318: && strncmp((char *)msg.to_net.addr,str,strlen(str)))) {
319: smb_unlockmsghdr(&smb,&msg);
320: smb_freemsgmem(&msg);
1.1.1.2 ! root 321: continue;
! 322: }
1.1 root 323:
324: msg.hdr.attr|=MSG_DELETE;
325: msg.idx.attr=msg.hdr.attr;
326: if((i=smb_putmsg(&smb,&msg))!=0)
327: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
328: else
329: deleted++;
330: smb_unlockmsghdr(&smb,&msg);
331: smb_freemsgmem(&msg);
332: }
333:
334: if(deleted && cfg.sys_misc&SM_DELEMAIL)
335: delmail(0,MAIL_YOUR);
336: smb_close(&smb);
337: if(mailmsgs)
338: free(mail);
339: eprintf(LOG_INFO,"Deleted %d sent NetMail messages",deleted);
340: }
341:
342: return(true);
343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.