|
|
1.1 root 1: /* pack_qwk.cpp */
2:
3: /* Synchronet pack QWK packet routine */
4:
1.1.1.2 ! root 5: /* $Id: pack_qwk.cpp,v 1.63 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 QWK packet, returning 1 if successful, 0 if not. */
43: /****************************************************************************/
44: bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack)
45: {
1.1.1.2 ! root 46: char str[MAX_PATH+1],ch;
1.1 root 47: char tmp[MAX_PATH+1],tmp2[MAX_PATH+1];
48: char* fname;
49: int mode;
50: uint i,j,k,conf;
1.1.1.2 ! root 51: long l,size,msgndx,ex;
! 52: int32_t posts;
! 53: int32_t mailmsgs=0;
! 54: ulong totalcdt,totaltime
1.1 root 55: ,files,submsgs,msgs,netfiles=0,preqwk=0;
1.1.1.2 ! root 56: uint32_t lastmsg;
1.1 root 57: ulong subs_scanned=0;
58: float f; /* Sparky is responsible */
59: time_t start;
60: node_t node;
61: mail_t *mail;
62: post_t *post;
63: glob_t g;
64: FILE *stream,*qwk,*personal,*ndx;
1.1.1.2 ! root 65: FILE* hdrs=NULL;
1.1 root 66: DIR* dir;
67: DIRENT* dirent;
68: struct tm tm;
69: smbmsg_t msg;
1.1.1.2 ! root 70: const char* p;
! 71: const char* fmode;
1.1 root 72:
1.1.1.2 ! root 73: ex=EX_STDOUT;
1.1 root 74: if(prepack)
75: ex|=EX_OFFLINE;
76:
77: delfiles(cfg.temp_dir,ALLFILES);
1.1.1.2 ! root 78: SAFEPRINTF2(str,"%sfile/%04u.qwk",cfg.data_dir,useron.number);
1.1 root 79: if(fexistcase(str)) {
80: for(k=0;k<cfg.total_fextrs;k++)
81: if(!stricmp(cfg.fextr[k]->ext,useron.tmpext)
1.1.1.2 ! root 82: && chk_ar(cfg.fextr[k]->ar,&useron,&client))
1.1 root 83: break;
84: if(k>=cfg.total_fextrs)
85: k=0;
86: p=cmdstr(cfg.fextr[k]->cmd,str,ALLFILES,NULL);
87: if((i=external(p,ex))==0)
88: preqwk=1;
89: else
90: errormsg(WHERE,ERR_EXEC,p,i);
91: }
92:
93: if(useron.rest&FLAG('Q') && useron.qwk&QWK_RETCTLA)
94: useron.qwk|=(QWK_NOINDEX|QWK_NOCTRL|QWK_VIA|QWK_TZ|QWK_MSGID);
95:
96: if(useron.qwk&QWK_EXPCTLA)
97: mode=A_EXPAND;
98: else if(useron.qwk&QWK_RETCTLA)
99: mode=A_LEAVE;
100: else mode=0;
101: if(useron.qwk&QWK_TZ)
102: mode|=QM_TZ;
103: if(useron.qwk&QWK_VIA)
104: mode|=QM_VIA;
105: if(useron.qwk&QWK_MSGID)
106: mode|=QM_MSGID;
107:
108: (*msgcnt)=0L;
109: if(/* !prepack && */ !(useron.qwk&QWK_NOCTRL)) {
110: /***************************/
111: /* Create CONTROL.DAT file */
112: /***************************/
1.1.1.2 ! root 113: SAFEPRINTF(str,"%sCONTROL.DAT",cfg.temp_dir);
1.1 root 114: if((stream=fopen(str,"wb"))==NULL) {
115: errormsg(WHERE,ERR_OPEN,str,0);
116: return(false);
117: }
118:
119: now=time(NULL);
120: if(localtime_r(&now,&tm)==NULL)
121: return(false);
122:
123: fprintf(stream,"%s\r\n%s\r\n%s\r\n%s, Sysop\r\n0000,%s\r\n"
124: "%02u-%02u-%u,%02u:%02u:%02u\r\n"
125: ,cfg.sys_name
126: ,cfg.sys_location
127: ,cfg.node_phone
128: ,cfg.sys_op
129: ,cfg.sys_id
130: ,tm.tm_mon+1,tm.tm_mday,tm.tm_year+1900
131: ,tm.tm_hour,tm.tm_min,tm.tm_sec);
132: k=0;
133: for(i=0;i<usrgrps;i++)
134: for(j=0;j<usrsubs[i];j++)
135: k++; /* k is how many subs */
136: fprintf(stream,"%s\r\n\r\n0\r\n0\r\n%u\r\n",useron.alias,k);
137: fprintf(stream,"0\r\nE-mail\r\n"); /* first conference is e-mail */
138: char confname[256];
139: for(i=0;i<usrgrps;i++)
140: for(j=0;j<usrsubs[i];j++) {
141: if(useron.qwk&QWK_EXT) /* 255 char max */
1.1.1.2 ! root 142: SAFEPRINTF2(confname,"%s %s"
1.1 root 143: ,cfg.grp[cfg.sub[usrsub[i][j]]->grp]->sname
144: ,cfg.sub[usrsub[i][j]]->lname);
145: else /* 10 char max */
1.1.1.2 ! root 146: SAFECOPY(confname,cfg.sub[usrsub[i][j]]->qwkname);
1.1 root 147: fprintf(stream,"%u\r\n%s\r\n"
148: ,cfg.sub[usrsub[i][j]]->qwkconf ? cfg.sub[usrsub[i][j]]->qwkconf
149: : ((i+1)*1000)+j+1,confname);
150: }
151: fprintf(stream,"HELLO\r\nBBSNEWS\r\nGOODBYE\r\n");
152: fclose(stream);
153: /***********************/
154: /* Create DOOR.ID File */
155: /***********************/
1.1.1.2 ! root 156: SAFEPRINTF(str,"%sDOOR.ID",cfg.temp_dir);
1.1 root 157: if((stream=fopen(str,"wb"))==NULL) {
158: errormsg(WHERE,ERR_OPEN,str,0);
159: return(false);
160: }
161: p="CONTROLTYPE = ";
162: fprintf(stream,"DOOR = %.10s\r\nVERSION = %s%c\r\n"
163: "SYSTEM = %s\r\n"
164: "CONTROLNAME = SBBS\r\n"
165: "%sADD\r\n"
166: "%sDROP\r\n"
167: "%sYOURS\r\n"
168: "%sRESET\r\n"
169: "%sRESETALL\r\n"
170: "%sFILES\r\n"
171: "%sATTACH\r\n"
172: "%sOWN\r\n"
1.1.1.2 ! root 173: "%sMAIL\r\n"
1.1 root 174: "%sDELMAIL\r\n"
175: "%sCTRL-A\r\n"
176: "%sFREQ\r\n"
177: "%sNDX\r\n"
178: "%sTZ\r\n"
179: "%sVIA\r\n"
180: "%sCONTROL\r\n"
181: "MIXEDCASE = YES\r\n"
182: ,VERSION_NOTICE
183: ,VERSION,REVISION
184: ,VERSION_NOTICE
185: ,p,p,p,p
186: ,p,p,p,p
187: ,p,p,p,p
188: ,p,p,p,p
189: );
190: fclose(stream);
191: if(useron.rest&FLAG('Q')) {
192: /***********************/
193: /* Create NETFLAGS.DAT */
194: /***********************/
1.1.1.2 ! root 195: SAFEPRINTF(str,"%sNETFLAGS.DAT",cfg.temp_dir);
1.1 root 196: if((stream=fopen(str,"wb"))==NULL) {
197: errormsg(WHERE,ERR_CREATE,str,0);
198: return(false);
199: }
200: ch=1; /* Net enabled */
201: if(usrgrps)
202: for(i=0;i<(usrgrps*1000)+usrsubs[usrgrps-1];i++)
203: fputc(ch,stream);
204: fclose(stream);
205: }
206: }
207:
1.1.1.2 ! root 208: if(useron.qwk&QWK_EXT) {
! 209: /****************************/
! 210: /* Create TOREADER.EXT file */
! 211: /****************************/
! 212: SAFEPRINTF(str,"%sTOREADER.EXT",cfg.temp_dir);
! 213: if((stream=fopen(str,"wb"))==NULL) {
! 214: errormsg(WHERE,ERR_OPEN,str,0);
! 215: return(false);
! 216: }
! 217:
! 218: fprintf(stream,"ALIAS %s\r\n", useron.alias);
! 219:
! 220: /* Double-checked with multimail (qwk.cc): */
! 221: for(i=0;i<usrgrps;i++)
! 222: for(j=0;j<usrsubs[i];j++) {
! 223: fprintf(stream,"AREA %u "
! 224: ,cfg.sub[usrsub[i][j]]->qwkconf ? cfg.sub[usrsub[i][j]]->qwkconf : ((i+1)*1000)+j+1);
! 225: switch(subscan[usrsub[i][j]].cfg&(SUB_CFG_NSCAN|SUB_CFG_YSCAN)) {
! 226: case SUB_CFG_NSCAN|SUB_CFG_YSCAN:
! 227: fputc('p', stream); // p for personal messages
! 228: break;
! 229: case SUB_CFG_NSCAN:
! 230: fputc('a', stream); // a for all messages
! 231: break;
! 232: }
! 233: switch(cfg.sub[usrsub[i][j]]->misc&(SUB_PRIV|SUB_PONLY)) {
! 234: case SUB_PRIV|SUB_PONLY:
! 235: fputc('P', stream); // P if the area is private mail only
! 236: break;
! 237: case SUB_PRIV:
! 238: fputc('X', stream); // X if either private or public mail is allowed
! 239: break;
! 240: default:
! 241: fputc('O', stream); // O if the area is public mail only
! 242: break;
! 243: }
! 244: if(useron.qwk&QWK_BYSELF)
! 245: fputc('w', stream); // w if this area should include mail written by themselves
! 246: if(cfg.sub[usrsub[i][j]]->misc&SUB_FORCED)
! 247: fputc('F', stream); // F if this area is forced to be read
! 248: if(!chk_ar(cfg.sub[usrsub[i][j]]->post_ar,&useron,&client))
! 249: fputc('R', stream); // R if the area is read-only (no posting at all allowed)
! 250: if(cfg.sub[usrsub[i][j]]->misc&SUB_QNET)
! 251: fputc('Q', stream); // I if the area is an internet area
! 252: if(cfg.sub[usrsub[i][j]]->misc&SUB_INET)
! 253: fputc('I', stream); // I if the area is an internet area
! 254: if(cfg.sub[usrsub[i][j]]->misc&SUB_FIDO)
! 255: fputc('E', stream); // E if the area is an echomail area
! 256: if((cfg.sub[usrsub[i][j]]->misc&(SUB_FIDO|SUB_INET|SUB_QNET))==0)
! 257: fputc('L', stream); // L if the area is a local message area
! 258: if((cfg.sub[usrsub[i][j]]->misc&SUB_NAME)==0)
! 259: fputc('H', stream); // H if the area is an handles only message area
! 260: if(cfg.sub[usrsub[i][j]]->misc&SUB_ANON)
! 261: fputc('A', stream); // A if the area allows messages 'from' any name (pick-an-alias)
! 262:
! 263: fprintf(stream,"\r\n");
! 264: }
! 265: fclose(stream);
! 266: }
! 267:
1.1 root 268: /****************************************************/
269: /* Create MESSAGES.DAT, write header and leave open */
270: /****************************************************/
1.1.1.2 ! root 271: SAFEPRINTF(str,"%sMESSAGES.DAT",cfg.temp_dir);
1.1 root 272: if(fexistcase(str))
273: fmode="r+b";
274: else
275: fmode="w+b";
276: if((qwk=fopen(str,fmode))==NULL) {
277: errormsg(WHERE,ERR_OPEN,str,0);
278: return(false);
279: }
1.1.1.2 ! root 280: if(useron.qwk&QWK_HEADERS) {
! 281: SAFEPRINTF(str,"%sHEADERS.DAT",cfg.temp_dir);
! 282: if((hdrs=fopen(str,"a"))==NULL) {
! 283: fclose(qwk);
! 284: errormsg(WHERE,ERR_OPEN,str,0);
! 285: return(false);
! 286: }
! 287: }
! 288: l=(long)filelength(fileno(qwk));
1.1 root 289: if(l<1) {
290: fprintf(qwk,"%-128.128s","Produced by " VERSION_NOTICE " " COPYRIGHT_NOTICE);
291: msgndx=1;
292: } else {
293: msgndx=l/QWK_BLOCK_LEN;
294: fseek(qwk,0,SEEK_END);
295: }
1.1.1.2 ! root 296: SAFEPRINTF(str,"%sNEWFILES.DAT",cfg.temp_dir);
1.1 root 297: remove(str);
298: if(!(useron.rest&FLAG('T')) && useron.qwk&QWK_FILES)
299: files=create_filelist("NEWFILES.DAT",FL_ULTIME);
300: else
301: files=0;
302:
303: start=time(NULL);
304:
305: if(useron.rest&FLAG('Q'))
306: useron.qwk|=(QWK_EMAIL|QWK_ALLMAIL|QWK_DELMAIL);
307:
308: if(!(useron.qwk&QWK_NOINDEX)) {
1.1.1.2 ! root 309: SAFEPRINTF(str,"%sPERSONAL.NDX",cfg.temp_dir);
1.1 root 310: if((personal=fopen(str,"ab"))==NULL) {
311: fclose(qwk);
1.1.1.2 ! root 312: if(hdrs!=NULL)
! 313: fclose(hdrs);
1.1 root 314: errormsg(WHERE,ERR_OPEN,str,0);
315: return(false);
316: }
317: }
318: else
319: personal=NULL;
320:
321: if(useron.qwk&(QWK_EMAIL|QWK_ALLMAIL) /* && !prepack */) {
1.1.1.2 ! root 322: SAFEPRINTF(smb.file,"%smail",cfg.data_dir);
1.1 root 323: smb.retry_time=cfg.smb_retry_time;
324: smb.subnum=INVALID_SUB;
325: if((i=smb_open(&smb))!=0) {
326: fclose(qwk);
1.1.1.2 ! root 327: if(hdrs!=NULL)
! 328: fclose(hdrs);
1.1 root 329: if(personal)
330: fclose(personal);
331: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
332: return(false);
333: }
334:
335: /***********************/
336: /* Pack E-mail, if any */
337: /***********************/
338: qwkmail_last=0;
339: mail=loadmail(&smb,&mailmsgs,useron.number,0,useron.qwk&QWK_ALLMAIL ? 0
340: : LM_UNREAD);
1.1.1.2 ! root 341: if(mailmsgs && (online==ON_LOCAL || !(sys_status&SS_ABORT))) {
1.1 root 342: bputs(text[QWKPackingEmail]);
343: if(!(useron.qwk&QWK_NOINDEX)) {
1.1.1.2 ! root 344: SAFEPRINTF(str,"%s000.NDX",cfg.temp_dir);
1.1 root 345: if((ndx=fopen(str,"ab"))==NULL) {
346: fclose(qwk);
1.1.1.2 ! root 347: if(hdrs!=NULL)
! 348: fclose(hdrs);
1.1 root 349: if(personal)
350: fclose(personal);
351: smb_close(&smb);
352: errormsg(WHERE,ERR_OPEN,str,0);
353: free(mail);
354: return(false);
355: }
356: }
357: else
358: ndx=NULL;
359:
360: if(useron.rest&FLAG('Q'))
361: mode|=QM_TO_QNET;
362: else
363: mode&=~QM_TO_QNET;
364:
365: for(l=0;l<mailmsgs;l++) {
366: bprintf("\b\b\b\b\b\b\b\b\b\b\b\b%4lu of %-4lu"
367: ,l+1,mailmsgs);
368:
369: memset(&msg,0,sizeof(msg));
370: msg.idx=mail[l];
371: if(msg.idx.number>qwkmail_last)
372: qwkmail_last=msg.idx.number;
373: if(!loadmsg(&msg,mail[l].number))
374: continue;
375:
376: if(msg.hdr.auxattr&MSG_FILEATTACH && useron.qwk&QWK_ATTACH) {
1.1.1.2 ! root 377: SAFEPRINTF3(str,"%sfile/%04u.in/%s"
1.1 root 378: ,cfg.data_dir,useron.number,msg.subj);
1.1.1.2 ! root 379: SAFEPRINTF2(tmp,"%s%s",cfg.temp_dir,msg.subj);
1.1 root 380: if(fexistcase(str) && !fexistcase(tmp))
1.1.1.2 ! root 381: mv(str,tmp,/* copy: */TRUE);
1.1 root 382: }
383:
1.1.1.2 ! root 384: size=msgtoqwk(&msg,qwk,mode,INVALID_SUB,0,hdrs);
1.1 root 385: smb_unlockmsghdr(&smb,&msg);
386: smb_freemsgmem(&msg);
387: if(ndx) {
388: msgndx++;
389: f=ltomsbin(msgndx); /* Record number */
390: ch=0; /* Sub number, not used */
391: if(personal) {
392: fwrite(&f,4,1,personal);
393: fwrite(&ch,1,1,personal);
394: }
395: fwrite(&f,4,1,ndx);
396: fwrite(&ch,1,1,ndx);
397: msgndx+=size/QWK_BLOCK_LEN;
398: }
399: YIELD(); /* yield */
400: }
401: bprintf(text[QWKPackedEmail],mailmsgs);
402: if(ndx)
403: fclose(ndx);
404: }
405: smb_close(&smb); /* Close the e-mail */
406: if(mailmsgs)
407: free(mail);
408: }
409:
410: /*********************/
411: /* Pack new messages */
412: /*********************/
413: for(i=0;i<usrgrps;i++) {
414: for(j=0;j<usrsubs[i] && !msgabort();j++) {
415: if(subscan[usrsub[i][j]].cfg&SUB_CFG_NSCAN
416: || (!(useron.rest&FLAG('Q'))
417: && cfg.sub[usrsub[i][j]]->misc&SUB_FORCED)) {
1.1.1.2 ! root 418: if(!chk_ar(cfg.sub[usrsub[i][j]]->read_ar,&useron,&client))
1.1 root 419: continue;
420: lncntr=0; /* defeat pause */
421: if(useron.rest&FLAG('Q') && !(cfg.sub[usrsub[i][j]]->misc&SUB_QNET))
422: continue; /* QWK Net Node and not QWK networked, so skip */
423:
424: subs_scanned++;
425: msgs=getlastmsg(usrsub[i][j],&lastmsg,0);
426: if(!msgs || lastmsg<=subscan[usrsub[i][j]].ptr) { /* no msgs */
427: if(subscan[usrsub[i][j]].ptr>lastmsg) { /* corrupted ptr */
428: outchar('*');
429: subscan[usrsub[i][j]].ptr=lastmsg; /* so fix automatically */
430: subscan[usrsub[i][j]].last=lastmsg;
431: }
432: bprintf(text[NScanStatusFmt]
433: ,cfg.grp[cfg.sub[usrsub[i][j]]->grp]->sname
434: ,cfg.sub[usrsub[i][j]]->lname,0L,msgs);
435: continue;
436: }
437:
1.1.1.2 ! root 438: SAFEPRINTF2(smb.file,"%s%s"
1.1 root 439: ,cfg.sub[usrsub[i][j]]->data_dir,cfg.sub[usrsub[i][j]]->code);
440: smb.retry_time=cfg.smb_retry_time;
441: smb.subnum=usrsub[i][j];
442: if((k=smb_open(&smb))!=0) {
443: errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error);
444: continue;
445: }
446:
447: k=0;
448: if(useron.qwk&QWK_BYSELF)
449: k|=LP_BYSELF;
450: if(useron.rest&FLAG('Q') || !(subscan[usrsub[i][j]].cfg&SUB_CFG_YSCAN))
451: k|=LP_OTHERS;
452: post=loadposts(&posts,usrsub[i][j],subscan[usrsub[i][j]].ptr,k);
453:
454: bprintf(text[NScanStatusFmt]
455: ,cfg.grp[cfg.sub[usrsub[i][j]]->grp]->sname
456: ,cfg.sub[usrsub[i][j]]->lname,posts,msgs);
457: if(!posts) { /* no new messages */
458: smb_close(&smb);
459: continue;
460: }
461: bputs(text[QWKPackingSubboard]);
462: submsgs=0;
463: conf=cfg.sub[usrsub[i][j]]->qwkconf;
464: if(!conf)
465: conf=((i+1)*1000)+j+1;
466:
467: if(!(useron.qwk&QWK_NOINDEX)) {
1.1.1.2 ! root 468: SAFEPRINTF2(str,"%s%u.NDX",cfg.temp_dir,conf);
1.1 root 469: if((ndx=fopen(str,"ab"))==NULL) {
470: fclose(qwk);
1.1.1.2 ! root 471: if(hdrs!=NULL)
! 472: fclose(hdrs);
1.1 root 473: if(personal)
474: fclose(personal);
475: smb_close(&smb);
476: errormsg(WHERE,ERR_OPEN,str,0);
477: free(post);
478: return(false);
479: }
480: }
481: else
482: ndx=NULL;
483:
484: for(l=0;l<posts && !msgabort();l++) {
485: bprintf("\b\b\b\b\b%-5lu",l+1);
486:
487: subscan[usrsub[i][j]].ptr=post[l].number; /* set ptr */
488: subscan[usrsub[i][j]].last=post[l].number; /* set last read */
489:
490: memset(&msg,0,sizeof(msg));
491: msg.idx=post[l];
492: if(!loadmsg(&msg,post[l].number))
493: continue;
494:
495: if(useron.rest&FLAG('Q')) {
496: if(msg.from_net.type && msg.from_net.type!=NET_QWK &&
497: !(cfg.sub[usrsub[i][j]]->misc&SUB_GATE)) { /* From other */
498: smb_freemsgmem(&msg); /* net, don't gate */
499: smb_unlockmsghdr(&smb,&msg);
500: continue;
501: }
502: mode|=(QM_TO_QNET|QM_TAGLINE);
503: if(msg.from_net.type==NET_QWK) {
504: mode&=~QM_TAGLINE;
505: if(route_circ((char *)msg.from_net.addr,useron.alias)
506: || !strnicmp(msg.subj,"NE:",3)) {
507: smb_freemsgmem(&msg);
508: smb_unlockmsghdr(&smb,&msg);
509: continue;
510: }
511: }
512: }
513: else
514: mode&=~(QM_TAGLINE|QM_TO_QNET);
515:
1.1.1.2 ! root 516: size=msgtoqwk(&msg,qwk,mode,usrsub[i][j],conf,hdrs);
1.1 root 517: smb_unlockmsghdr(&smb,&msg);
518:
519: if(ndx) {
520: msgndx++;
521: f=ltomsbin(msgndx); /* Record number */
522: ch=0; /* Sub number, not used */
523: if(personal
524: && (!stricmp(msg.to,useron.alias)
525: || !stricmp(msg.to,useron.name))) {
526: fwrite(&f,4,1,personal);
527: fwrite(&ch,1,1,personal);
528: }
529: fwrite(&f,4,1,ndx);
530: fwrite(&ch,1,1,ndx);
531: msgndx+=size/QWK_BLOCK_LEN;
532: }
533:
534: smb_freemsgmem(&msg);
535: (*msgcnt)++;
536: submsgs++;
537: if(cfg.max_qwkmsgs
538: && !(useron.exempt&FLAG('O')) && (*msgcnt)>=cfg.max_qwkmsgs) {
539: bputs(text[QWKmsgLimitReached]);
540: break;
541: }
542: if(!(l%50))
543: YIELD(); /* yield */
544: }
545: if(!(sys_status&SS_ABORT))
546: bprintf(text[QWKPackedSubboard],submsgs,(*msgcnt));
547: if(ndx) {
548: fclose(ndx);
1.1.1.2 ! root 549: SAFEPRINTF2(str,"%s%u.NDX",cfg.temp_dir,conf);
1.1 root 550: if(!flength(str))
551: remove(str);
552: }
553: smb_close(&smb);
554: free(post);
555: if(l<posts)
556: break;
557: YIELD(); /* yield */
558: }
559: }
560: if(j<usrsubs[i]) /* if sub aborted, abort all */
561: break;
562: }
563:
564: if(online==ON_LOCAL) /* event */
565: eprintf(LOG_INFO,"%s scanned %lu sub-boards for new messages"
566: ,useron.alias,subs_scanned);
567: else
568: lprintf(LOG_INFO,"Node %d %s scanned %lu sub-boards for new messages"
569: ,cfg.node_num,useron.alias,subs_scanned);
570:
571: if((*msgcnt)+mailmsgs && time(NULL)-start) {
572: bprintf("\r\n\r\n\1n\1hPacked %lu messages (%lu bytes) in %lu seconds "
573: "(%lu messages/second)."
574: ,(*msgcnt)+mailmsgs
575: ,ftell(qwk)
576: ,time(NULL)-start
577: ,((*msgcnt)+mailmsgs)/(time(NULL)-start));
1.1.1.2 ! root 578: SAFEPRINTF4(str,"Packed %lu messages (%lu bytes) in %lu seconds (%lu msgs/sec)"
1.1 root 579: ,(*msgcnt)+mailmsgs
580: ,ftell(qwk)
581: ,(ulong)(time(NULL)-start)
582: ,((*msgcnt)+mailmsgs)/(time(NULL)-start));
583: if(online==ON_LOCAL) /* event */
584: eprintf(LOG_INFO,"%s",str);
585: else
586: lprintf(LOG_INFO,"%s",str);
587: }
588:
589: fclose(qwk); /* close MESSAGE.DAT */
1.1.1.2 ! root 590: if(hdrs!=NULL)
! 591: fclose(hdrs); /* close HEADERS.DAT */
1.1 root 592: if(personal) {
593: fclose(personal); /* close PERSONAL.NDX */
1.1.1.2 ! root 594: SAFEPRINTF(str,"%sPERSONAL.NDX",cfg.temp_dir);
1.1 root 595: if(!flength(str))
596: remove(str);
597: }
598: CRLF;
599:
1.1.1.2 ! root 600: if(!prepack && online!=ON_LOCAL && ((sys_status&SS_ABORT) || !online)) {
! 601: bputs(text[Aborted]);
1.1 root 602: return(false);
1.1.1.2 ! root 603: }
1.1 root 604:
605: if(/*!prepack && */ useron.rest&FLAG('Q')) { /* If QWK Net node, check for files */
1.1.1.2 ! root 606: char id[LEN_QWKID+1];
! 607: SAFECOPY(id,useron.alias);
! 608: strlwr(id);
! 609: SAFEPRINTF2(str,"%sqnet/%s.out/",cfg.data_dir,id);
1.1 root 610: dir=opendir(str);
611: while(dir!=NULL && (dirent=readdir(dir))!=NULL) { /* Move files into temp dir */
1.1.1.2 ! root 612: SAFEPRINTF3(str,"%sqnet/%s.out/%s",cfg.data_dir,id,dirent->d_name);
1.1 root 613: if(isdir(str))
614: continue;
1.1.1.2 ! root 615: SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,dirent->d_name);
! 616: lncntr=0; /* Defeat pause */
1.1 root 617: if(online==ON_LOCAL)
618: eprintf(LOG_INFO,"Including %s in packet",str);
619: else
620: lprintf(LOG_INFO,"Including %s in packet",str);
621: bprintf(text[RetrievingFile],str);
1.1.1.2 ! root 622: if(!mv(str,tmp2,/* copy: */TRUE))
1.1 root 623: netfiles++;
624: }
625: if(dir!=NULL)
626: closedir(dir);
627: if(netfiles)
628: CRLF;
629: }
630:
631: if(batdn_total) {
632: for(i=0,totalcdt=0;i<batdn_total;i++)
1.1.1.2 ! root 633: if(!is_download_free(&cfg,batdn_dir[i],&useron,&client))
1.1 root 634: totalcdt+=batdn_cdt[i];
635: if(totalcdt>useron.cdt+useron.freecdt) {
636: bprintf(text[YouOnlyHaveNCredits]
637: ,ultoac(useron.cdt+useron.freecdt,tmp));
638: }
639: else {
640: for(i=0,totaltime=0;i<batdn_total;i++) {
641: if(!(cfg.dir[batdn_dir[i]]->misc&DIR_TFREE) && cur_cps)
642: totaltime+=batdn_size[i]/(ulong)cur_cps;
643: }
644: if(!(useron.exempt&FLAG('T')) && !SYSOP && totaltime>timeleft)
645: bputs(text[NotEnoughTimeToDl]);
646: else {
647: for(i=0;i<batdn_total;i++) {
648: lncntr=0;
649: unpadfname(batdn_name[i],tmp);
1.1.1.2 ! root 650: SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,tmp);
1.1 root 651: if(!fexistcase(tmp2)) {
652: seqwait(cfg.dir[batdn_dir[i]]->seqdev);
653: bprintf(text[RetrievingFile],tmp);
1.1.1.2 ! root 654: SAFEPRINTF2(str,"%s%s"
1.1 root 655: ,batdn_alt[i]>0 && batdn_alt[i]<=cfg.altpaths
656: ? cfg.altpath[batdn_alt[i]-1]
657: : cfg.dir[batdn_dir[i]]->path
658: ,tmp);
1.1.1.2 ! root 659: mv(str,tmp2,/* copy: */TRUE); /* copy the file to temp dir */
! 660: getnodedat(cfg.node_num,&thisnode,/* copy: */TRUE);
1.1 root 661: thisnode.aux=0xfe;
662: putnodedat(cfg.node_num,&thisnode);
663: CRLF;
664: }
665: }
666: }
667: }
668: }
669:
670: if(!(*msgcnt) && !mailmsgs && !files && !netfiles && !batdn_total
671: && (prepack || !preqwk)) {
672: bputs(text[QWKNoNewMessages]);
673: return(false);
674: }
675:
676: if(!(useron.rest&FLAG('Q'))) { /* Don't include in network */
677: /***********************/ /* packets */
678: /* Copy QWK Text files */
679: /***********************/
1.1.1.2 ! root 680: SAFEPRINTF(str,"%sQWK/HELLO",cfg.text_dir);
1.1 root 681: if(fexistcase(str)) {
1.1.1.2 ! root 682: SAFEPRINTF(tmp2,"%sHELLO",cfg.temp_dir);
! 683: mv(str,tmp2,/* copy: */TRUE);
1.1 root 684: }
1.1.1.2 ! root 685: SAFEPRINTF(str,"%sQWK/BBSNEWS",cfg.text_dir);
1.1 root 686: if(fexistcase(str)) {
1.1.1.2 ! root 687: SAFEPRINTF(tmp2,"%sBBSNEWS",cfg.temp_dir);
! 688: mv(str,tmp2,/* copy: */TRUE);
1.1 root 689: }
1.1.1.2 ! root 690: SAFEPRINTF(str,"%sQWK/GOODBYE",cfg.text_dir);
1.1 root 691: if(fexistcase(str)) {
1.1.1.2 ! root 692: SAFEPRINTF(tmp2,"%sGOODBYE",cfg.temp_dir);
! 693: mv(str,tmp2,/* copy: */TRUE);
1.1 root 694: }
1.1.1.2 ! root 695: SAFEPRINTF(str,"%sQWK/BLT-*",cfg.text_dir);
1.1 root 696: glob(str,0,NULL,&g);
697: for(i=0;i<(uint)g.gl_pathc;i++) { /* Copy BLT-*.* files */
698: fname=getfname(g.gl_pathv[i]);
699: padfname(fname,str);
700: if(isdigit(str[4]) && isdigit(str[9])) {
1.1.1.2 ! root 701: SAFEPRINTF2(str,"%sQWK/%s",cfg.text_dir,fname);
! 702: SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,fname);
! 703: mv(str,tmp2,/* copy: */TRUE);
1.1 root 704: }
705: }
706: globfree(&g);
707: }
708:
709: if(prepack) {
710: for(i=1;i<=cfg.sys_nodes;i++) {
711: getnodedat(i,&node,0);
712: if((node.status==NODE_INUSE || node.status==NODE_QUIET
713: || node.status==NODE_LOGON) && node.useron==useron.number)
714: break;
715: }
716: if(i<=cfg.sys_nodes) /* Don't pre-pack with user online */
717: return(false);
718: }
719:
720: /*******************/
721: /* Compress Packet */
722: /*******************/
1.1.1.2 ! root 723: SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,ALLFILES);
1.1 root 724: i=external(cmdstr(temp_cmd(),packet,tmp2,NULL)
725: ,ex|EX_WILDCARD);
726: if(!fexist(packet)) {
727: bputs(text[QWKCompressionFailed]);
728: if(i)
729: errormsg(WHERE,ERR_EXEC,cmdstr(temp_cmd(),packet,tmp2,NULL),i);
730: else
1.1.1.2 ! root 731: lprintf(LOG_ERR, "Couldn't compress QWK packet");
1.1 root 732: return(false);
733: }
734:
1.1.1.2 ! root 735: if(!prepack && useron.rest&FLAG('Q')) {
1.1 root 736: dir=opendir(cfg.temp_dir);
737: while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
1.1.1.2 ! root 738: if(!stricmp(getfname(packet),dirent->d_name)) /* QWK packet */
1.1 root 739: continue;
1.1.1.2 ! root 740: SAFEPRINTF2(tmp,"%s%s",cfg.temp_dir,dirent->d_name);
1.1 root 741: if(!isdir(tmp))
742: remove(tmp);
743: }
744: if(dir!=NULL)
745: closedir(dir);
746: }
747:
748: return(true);
749: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.