|
|
1.1 root 1: #line 1 "PACK_QWK.C"
2:
3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
4:
5: #include "sbbs.h"
6: #include "qwk.h"
7: #include "post.h"
8: #include "etext.h"
9:
10: /****************************************************************************/
11: /* Creates QWK packet, returning 1 if successful, 0 if not. */
12: /****************************************************************************/
13: char pack_qwk(char *packet, ulong *msgcnt, int prepack)
14: {
15: uchar str[256],tmp2[256],ch,*p;
16: uchar HUGE16 *qwkbuf;
17: int file,mode;
18: uint i,j,k,n,conf;
19: long l,size,msgndx;
20: ulong totalcdt,totalsize,totaltime,lastmsg
21: ,mailmsgs=0,files,submsgs,msgs,posts,netfiles=0,preqwk=0;
22: float f; /* Sparky is responsible */
23: time_t start;
24: node_t node;
25: mail_t *mail;
26: post_t HUGE16 *post;
27: FILE *stream,*qwk,*personal,*ndx;
28: struct ffblk ff;
29: smbmsg_t msg;
30:
31: delfiles(temp_dir,"*.*");
32: sprintf(str,"%sFILE\\%04u.QWK",data_dir,useron.number);
33: if(fexist(str)) {
34: for(k=0;k<total_fextrs;k++)
35: if(!stricmp(fextr[k]->ext,useron.tmpext)
36: && chk_ar(fextr[k]->ar,useron))
37: break;
38: if(k>=total_fextrs)
39: k=0;
40: i=external(cmdstr(fextr[k]->cmd,str,"*.*",NULL),EX_OUTL|EX_OUTR);
41: if(!i)
42: preqwk=1; }
43:
44: if(useron.rest&FLAG('Q') && useron.qwk&QWK_RETCTLA)
45: useron.qwk|=(QWK_NOINDEX|QWK_NOCTRL|QWK_VIA|QWK_TZ);
46:
47: if(useron.qwk&QWK_EXPCTLA)
48: mode=A_EXPAND;
49: else if(useron.qwk&QWK_RETCTLA)
50: mode=A_LEAVE;
51: else mode=0;
52: if(useron.qwk&QWK_TZ)
53: mode|=TZ;
54: if(useron.qwk&QWK_VIA)
55: mode|=VIA;
56: (*msgcnt)=0L;
57: if(!prepack && !(useron.qwk&QWK_NOCTRL)) {
58: /***************************/
59: /* Create CONTROL.DAT file */
60: /***************************/
61: sprintf(str,"%sCONTROL.DAT",temp_dir);
62: if((stream=fnopen(&file,str,O_WRONLY|O_CREAT|O_TRUNC))==NULL) {
63: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
64: return(0); }
65:
66: now=time(NULL);
67: unixtodos(now,&date,&curtime);
68:
69: fprintf(stream,"%s\r\n%s\r\n%s\r\n%s, Sysop\r\n0000,%s\r\n"
70: "%02u-%02u-%u,%02u:%02u:%02u\r\n"
71: ,sys_name
72: ,sys_location
73: ,node_phone
74: ,sys_op
75: ,sys_id
76: ,date.da_mon,date.da_day,date.da_year
77: ,curtime.ti_hour,curtime.ti_min,curtime.ti_sec);
78: k=0;
79: for(i=0;i<usrgrps;i++)
80: for(j=0;j<usrsubs[i];j++)
81: k++; /* k is how many subs */
82: fprintf(stream,"%s\r\n\r\n0\r\n0\r\n%u\r\n",useron.alias,k);
83: fprintf(stream,"0\r\nE-mail\r\n"); /* first conference is e-mail */
84: for(i=0;i<usrgrps;i++)
85: for(j=0;j<usrsubs[i];j++)
86: fprintf(stream,"%u\r\n%s\r\n"
87: ,sub[usrsub[i][j]]->qwkconf ? sub[usrsub[i][j]]->qwkconf
88: : ((i+1)*1000)+j+1,sub[usrsub[i][j]]->qwkname);
89: fprintf(stream,"HELLO\r\nBBSNEWS\r\nGOODBYE\r\n");
90: fclose(stream);
91: /***********************/
92: /* Create DOOR.ID File */
93: /***********************/
94: sprintf(str,"%sDOOR.ID",temp_dir);
95: if((stream=fnopen(&file,str,O_WRONLY|O_CREAT|O_TRUNC))==NULL) {
96: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
97: return(0); }
98: p="CONTROLTYPE = ";
99: fprintf(stream,"DOOR = %s\r\nVERSION = %s\r\n"
100: "SYSTEM = %s v%s\r\n"
101: "CONTROLNAME = SBBS\r\n"
102: "%sADD\r\n"
103: "%sDROP\r\n"
104: "%sYOURS\r\n"
105: "%sRESET\r\n"
106: "%sRESETALL\r\n"
107: "%sFILES\r\n"
108: "%sATTACH\r\n"
109: "%sOWN\r\n"
110: "%sMAIL\r\n"
111: "%sDELMAIL\r\n"
112: "%sCTRL-A\r\n"
113: "%sFREQ\r\n"
114: "%sNDX\r\n"
115: "%sTZ\r\n"
116: "%sVIA\r\n"
117: "%sCONTROL\r\n"
118: "MIXEDCASE = YES\r\n"
119: ,decrypt(Synchronet,0)
120: ,VERSION
121: ,decrypt(Synchronet,0)
122: ,VERSION
123: ,p,p,p,p
124: ,p,p,p,p
125: ,p,p,p,p
126: ,p,p,p,p
127: );
128: fclose(stream);
129: if(useron.rest&FLAG('Q')) {
130: /***********************/
131: /* Create NETFLAGS.DAT */
132: /***********************/
133: sprintf(str,"%sNETFLAGS.DAT",temp_dir);
134: if((stream=fnopen(&file,str,O_WRONLY|O_CREAT))==NULL) {
135: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT);
136: return(0); }
137: ch=1; /* Net enabled */
138: if(usrgrps)
139: for(i=0;i<(usrgrps*1000)+usrsubs[usrgrps-1];i++)
140: fputc(ch,stream);
141: fclose(stream); }
142: } /* !prepack */
143:
144: /****************************************************/
145: /* Create MESSAGES.DAT, write header and leave open */
146: /****************************************************/
147: sprintf(str,"%sMESSAGES.DAT",temp_dir);
148: if((qwk=fnopen(&file,str,O_CREAT|O_WRONLY|O_TRUNC))==NULL) {
149: errormsg(WHERE,ERR_OPEN,str,O_CREAT|O_WRONLY|O_TRUNC);
150: return(0); }
151: l=filelength(file);
152: if(!l) {
153: fprintf(qwk,"%-128s",decrypt(QWKheader,0));
154: msgndx=1; }
155: else
156: msgndx=l/128L;
157: fseek(qwk,0,SEEK_END);
158: sprintf(str,"%sNEWFILES.DAT",temp_dir);
159: remove(str);
160: if(!(useron.rest&FLAG('T')) && useron.qwk&QWK_FILES)
161: files=create_filelist("NEWFILES.DAT",FL_ULTIME);
162: else
163: files=0;
164:
165: start=time(NULL);
166:
167: if(useron.rest&FLAG('Q'))
168: useron.qwk|=(QWK_EMAIL|QWK_ALLMAIL|QWK_DELMAIL);
169:
170: if(!(useron.qwk&QWK_NOINDEX)) {
171: sprintf(str,"%sPERSONAL.NDX",temp_dir);
172: if((personal=fnopen(&file,str,O_CREAT|O_WRONLY|O_APPEND))==NULL) {
173: fclose(qwk);
174: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND);
175: return(0); }
176: fseek(personal,0L,SEEK_END); }
177: else
178: personal=NULL;
179:
180: if(useron.qwk&(QWK_EMAIL|QWK_ALLMAIL) && !prepack) {
181: sprintf(smb.file,"%sMAIL",data_dir);
182: smb.retry_time=smb_retry_time;
183: if((i=smb_open(&smb))!=0) {
184: fclose(qwk);
185: if(personal)
186: fclose(personal);
187: errormsg(WHERE,ERR_OPEN,smb.file,i);
188: return(0); }
189:
190: /***********************/
191: /* Pack E-mail, if any */
192: /***********************/
193: qwkmail_time=time(NULL);
194: mailmsgs=loadmail(&mail,useron.number,0,useron.qwk&QWK_ALLMAIL ? LM_QWK
195: : LM_UNREAD|LM_QWK);
196: if(mailmsgs && !(sys_status&SS_ABORT)) {
197: bputs(text[QWKPackingEmail]);
198: if(!(useron.qwk&QWK_NOINDEX)) {
199: sprintf(str,"%s000.NDX",temp_dir);
200: if((ndx=fnopen(&file,str,O_CREAT|O_WRONLY|O_APPEND))==NULL) {
201: fclose(qwk);
202: if(personal)
203: fclose(personal);
204: smb_close(&smb);
205: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND);
206: FREE(mail);
207: return(0); }
208: fseek(ndx,0L,SEEK_END); }
209: else
210: ndx=NULL;
211:
212: if(useron.rest&FLAG('Q'))
213: mode|=TO_QNET;
214: else
215: mode&=~TO_QNET;
216:
217: for(l=0;l<mailmsgs;l++) {
218: bprintf("\b\b\b\b\b\b\b\b\b\b\b\b%4lu of %-4lu"
219: ,l+1,mailmsgs);
220:
221: msg.idx.offset=mail[l].offset;
222: if(!loadmsg(&msg,mail[l].number))
223: continue;
224:
225: if(msg.hdr.auxattr&MSG_FILEATTACH && useron.qwk&QWK_ATTACH) {
226: sprintf(str,"%sFILE\\%04u.IN\\%s"
227: ,data_dir,useron.number,msg.subj);
228: sprintf(tmp,"%s%s",temp_dir,msg.subj);
229: if(fexist(str) && !fexist(tmp))
230: mv(str,tmp,1); }
231:
232: size=msgtoqwk(msg,qwk,mode,INVALID_SUB,0);
233: smb_unlockmsghdr(&smb,&msg);
234: smb_freemsgmem(&msg);
235: if(ndx) {
236: msgndx++;
237: f=ltomsbin(msgndx); /* Record number */
238: ch=0; /* Sub number, not used */
239: if(personal) {
240: fwrite(&f,4,1,personal);
241: fwrite(&ch,1,1,personal); }
242: fwrite(&f,4,1,ndx);
243: fwrite(&ch,1,1,ndx);
244: msgndx+=size/128L; } }
245: bprintf(text[QWKPackedEmail],mailmsgs);
246: if(ndx)
247: fclose(ndx); }
248: smb_close(&smb); /* Close the e-mail */
249: if(mailmsgs)
250: FREE(mail);
251: }
252:
253: /*********************/
254: /* Pack new messages */
255: /*********************/
256: for(i=0;i<usrgrps;i++) {
257: for(j=0;j<usrsubs[i] && !msgabort();j++)
258: if(sub[usrsub[i][j]]->misc&SUB_NSCAN
259: || (!(useron.rest&FLAG('Q'))
260: && sub[usrsub[i][j]]->misc&SUB_FORCED)) {
261: if(!chk_ar(sub[usrsub[i][j]]->read_ar,useron))
262: continue;
263: lncntr=0; /* defeat pause */
264: if(useron.rest&FLAG('Q') && !(sub[usrsub[i][j]]->misc&SUB_QNET))
265: continue; /* QWK Net Node and not QWK networked, so skip */
266:
267: msgs=getlastmsg(usrsub[i][j],&lastmsg,0);
268: if(!msgs || lastmsg<=sub[usrsub[i][j]]->ptr) { /* no msgs */
269: if(sub[usrsub[i][j]]->ptr>lastmsg) { /* corrupted ptr */
270: sub[usrsub[i][j]]->ptr=lastmsg; /* so fix automatically */
271: sub[usrsub[i][j]]->last=lastmsg; }
272: bprintf(text[NScanStatusFmt]
273: ,grp[sub[usrsub[i][j]]->grp]->sname
274: ,sub[usrsub[i][j]]->lname,0L,msgs);
275: continue; }
276:
277: sprintf(smb.file,"%s%s"
278: ,sub[usrsub[i][j]]->data_dir,sub[usrsub[i][j]]->code);
279: smb.retry_time=smb_retry_time;
280: if((k=smb_open(&smb))!=0) {
281: errormsg(WHERE,ERR_OPEN,smb.file,k);
282: continue; }
283:
284: k=0;
285: if(useron.qwk&QWK_BYSELF)
286: k|=LP_BYSELF;
287: if(!(sub[usrsub[i][j]]->misc&SUB_YSCAN))
288: k|=LP_OTHERS;
289: post=loadposts(&posts,usrsub[i][j],sub[usrsub[i][j]]->ptr,k);
290:
291: bprintf(text[NScanStatusFmt]
292: ,grp[sub[usrsub[i][j]]->grp]->sname
293: ,sub[usrsub[i][j]]->lname,posts,msgs);
294: if(!posts) { /* no new messages */
295: smb_close(&smb);
296: continue; }
297: bputs(text[QWKPackingSubboard]);
298: submsgs=0;
299: conf=sub[usrsub[i][j]]->qwkconf;
300: if(!conf)
301: conf=((i+1)*1000)+j+1;
302:
303: if(!(useron.qwk&QWK_NOINDEX)) {
304: sprintf(str,"%s%u.NDX",temp_dir,conf);
305: if((ndx=fnopen(&file,str,O_CREAT|O_WRONLY|O_APPEND))==NULL) {
306: fclose(qwk);
307: if(personal)
308: fclose(personal);
309: smb_close(&smb);
310: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND);
311: LFREE(post);
312: return(0); }
313: fseek(ndx,0L,SEEK_END); }
314: else
315: ndx=NULL;
316:
317: for(l=0;l<posts && !msgabort();l++) {
318: bprintf("\b\b\b\b\b%-5lu",l+1);
319:
320: sub[usrsub[i][j]]->ptr=post[l].number; /* set ptr */
321: sub[usrsub[i][j]]->last=post[l].number; /* set last read */
322:
323: msg.idx.offset=post[l].offset;
324: if(!loadmsg(&msg,post[l].number))
325: continue;
326:
327: if(useron.rest&FLAG('Q')) {
328: if(msg.from_net.type && msg.from_net.type!=NET_QWK &&
329: !(sub[usrsub[i][j]]->misc&SUB_GATE)) { /* From other */
330: smb_freemsgmem(&msg); /* net, don't gate */
331: smb_unlockmsghdr(&smb,&msg);
332: continue; }
333: mode|=(TO_QNET|TAGLINE);
334: if(msg.from_net.type==NET_QWK) {
335: mode&=~TAGLINE;
336: if(route_circ(msg.from_net.addr,useron.alias)
337: || !strnicmp(msg.subj,"NE:",3)) {
338: smb_freemsgmem(&msg);
339: smb_unlockmsghdr(&smb,&msg);
340: continue; } } }
341: else
342: mode&=~(TAGLINE|TO_QNET);
343:
344: size=msgtoqwk(msg,qwk,mode,usrsub[i][j],conf);
345: smb_unlockmsghdr(&smb,&msg);
346:
347: if(ndx) {
348: msgndx++;
349: f=ltomsbin(msgndx); /* Record number */
350: ch=0; /* Sub number, not used */
351: if(personal
352: && (!stricmp(msg.to,useron.alias)
353: || !stricmp(msg.to,useron.name))) {
354: fwrite(&f,4,1,personal);
355: fwrite(&ch,1,1,personal); }
356: fwrite(&f,4,1,ndx);
357: fwrite(&ch,1,1,ndx);
358: msgndx+=size/128L; }
359:
360: smb_freemsgmem(&msg);
361: (*msgcnt)++;
362: submsgs++;
363: if(max_qwkmsgs
364: && !(useron.rest&FLAG('Q')) && (*msgcnt)>=max_qwkmsgs) {
365: bputs(text[QWKmsgLimitReached]);
366: break; } }
367: if(!(sys_status&SS_ABORT))
368: bprintf(text[QWKPackedSubboard],submsgs,(*msgcnt));
369: if(ndx) {
370: fclose(ndx);
371: sprintf(str,"%s%u.NDX",temp_dir,conf);
372: if(!flength(str))
373: remove(str); }
374: smb_close(&smb);
375: LFREE(post);
376: if(l<posts)
377: break; }
378: if(j<usrsubs[i]) /* if sub aborted, abort all */
379: break; }
380:
381: if((*msgcnt)+mailmsgs && time(NULL)-start)
382: bprintf("\r\n\r\n\1n\1hPacked %lu messages in %lu seconds "
383: "(%lu messages/second)."
384: ,(*msgcnt)+mailmsgs,time(NULL)-start
385: ,((*msgcnt)+mailmsgs)/(time(NULL)-start));
386:
387: fclose(qwk); /* close MESSAGE.DAT */
388: if(personal) {
389: fclose(personal); /* close PERSONAL.NDX */
390: sprintf(str,"%sPERSONAL.NDX",temp_dir);
391: if(!flength(str))
392: remove(str); }
393: CRLF;
394:
395: if(!prepack && (sys_status&SS_ABORT || !online))
396: return(0);
397:
398: if(!prepack && useron.rest&FLAG('Q')) { /* If QWK Net node, check for files */
399: sprintf(str,"%sQNET\\%s.OUT\\*.*",data_dir,useron.alias);
400: i=findfirst(str,&ff,0);
401: while(!i) { /* Move files into temp dir */
402: sprintf(str,"%sQNET\\%s.OUT\\%s",data_dir,useron.alias,ff.ff_name);
403: strupr(str);
404: sprintf(tmp2,"%s%s",temp_dir,ff.ff_name);
405: lncntr=0; /* Default pause */
406: bprintf(text[RetrievingFile],str);
407: if(!mv(str,tmp2,1))
408: netfiles++;
409: i=findnext(&ff); }
410: if(netfiles)
411: CRLF; }
412:
413: if(batdn_total) {
414: for(i=0,totalcdt=0;i<batdn_total;i++)
415: totalcdt+=batdn_cdt[i];
416: if(!(useron.exempt&FLAG('D'))
417: && totalcdt>useron.cdt+useron.freecdt) {
418: bprintf(text[YouOnlyHaveNCredits]
419: ,ultoac(useron.cdt+useron.freecdt,tmp)); }
420: else {
421: for(i=0,totalsize=totaltime=0;i<batdn_total;i++) {
422: totalsize+=batdn_size[i];
423: if(!(dir[batdn_dir[i]]->misc&DIR_TFREE) && cur_cps)
424: totaltime+=batdn_size[i]/(ulong)cur_cps; }
425: if(!(useron.exempt&FLAG('T')) && !SYSOP && totaltime>timeleft)
426: bputs(text[NotEnoughTimeToDl]);
427: else {
428: for(i=0;i<batdn_total;i++) {
429: lncntr=0;
430: unpadfname(batdn_name[i],tmp);
431: sprintf(tmp2,"%s%s",temp_dir,tmp);
432: if(!fexist(tmp2)) {
433: seqwait(dir[batdn_dir[i]]->seqdev);
434: bprintf(text[RetrievingFile],tmp);
435: sprintf(str,"%s%s"
436: ,batdn_alt[i]>0 && batdn_alt[i]<=altpaths
437: ? altpath[batdn_alt[i]-1]
438: : dir[batdn_dir[i]]->path
439: ,tmp);
440: mv(str,tmp2,1); /* copy the file to temp dir */
441: getnodedat(node_num,&thisnode,1);
442: thisnode.aux=0xfe;
443: putnodedat(node_num,thisnode);
444: CRLF; } } } } }
445:
446: if(!(*msgcnt) && !mailmsgs && !files && !netfiles && !batdn_total
447: && (prepack || !preqwk)) {
448: bputs(text[QWKNoNewMessages]);
449: return(0); }
450:
451: if(!prepack && !(useron.rest&FLAG('Q'))) { /* Don't include in network */
452: /***********************/ /* packets */
453: /* Copy QWK Text files */
454: /***********************/
455: sprintf(str,"%sQWK\\HELLO",text_dir);
456: if(fexist(str)) {
457: sprintf(tmp2,"%sHELLO",temp_dir);
458: mv(str,tmp2,1); }
459: sprintf(str,"%sQWK\\BBSNEWS",text_dir);
460: if(fexist(str)) {
461: sprintf(tmp2,"%sBBSNEWS",temp_dir);
462: mv(str,tmp2,1); }
463: sprintf(str,"%sQWK\\GOODBYE",text_dir);
464: if(fexist(str)) {
465: sprintf(tmp2,"%sGOODBYE",temp_dir);
466: mv(str,tmp2,1); }
467: sprintf(str,"%sQWK\\BLT-*.*",text_dir);
468: i=findfirst(str,&ff,0);
469: while(!i) { /* Copy BLT-*.* files */
470: padfname(ff.ff_name,str);
471: if(isdigit(str[4]) && isdigit(str[9])) {
472: sprintf(str,"%sQWK\\%s",text_dir,ff.ff_name);
473: sprintf(tmp2,"%s%s",temp_dir,ff.ff_name);
474: mv(str,tmp2,1); }
475: i=findnext(&ff); } }
476:
477: if(prepack) {
478: for(i=1;i<=sys_nodes;i++) {
479: getnodedat(i,&node,0);
480: if((node.status==NODE_INUSE || node.status==NODE_QUIET
481: || node.status==NODE_LOGON) && node.useron==useron.number)
482: break; }
483: if(i<=sys_nodes) /* Don't pre-pack with user online */
484: return(0); }
485:
486: /*******************/
487: /* Compress Packet */
488: /*******************/
489: sprintf(tmp2,"%s*.*",temp_dir);
490: i=external(cmdstr(temp_cmd(),packet,tmp2,NULL),EX_OUTL|EX_OUTR);
491: if(!fexist(packet)) {
492: bputs(text[QWKCompressionFailed]);
493: if(i)
494: errormsg(WHERE,ERR_EXEC,cmdstr(temp_cmd(),packet,tmp2,NULL),i);
495: else
496: errorlog("Couldn't compress QWK packet");
497: return(0); }
498:
499: if(prepack) /* Early return if pre-packing */
500: return(1);
501:
502: l=flength(packet);
503: sprintf(str,"%s.QWK",sys_id);
504: bprintf(text[FiFilename],str);
505: bprintf(text[FiFileSize],ultoac(l,tmp));
506: if(l>0L && cur_cps)
507: i=l/(ulong)cur_cps;
508: else
509: i=0;
510: bprintf(text[FiTransferTime],sectostr(i,tmp));
511: CRLF;
512: if(!(useron.exempt&FLAG('T')) && i>timeleft) {
513: bputs(text[NotEnoughTimeToDl]);
514: return(0); }
515:
516: if(useron.rest&FLAG('Q')) {
517: sprintf(str,"%s.QWK",sys_id);
518: sprintf(tmp,"%s*.*",temp_dir);
519: i=findfirst(tmp,&ff,0);
520: while(!i) {
521: if(stricmp(str,ff.ff_name)) {
522: sprintf(tmp,"%s%s",temp_dir,ff.ff_name);
523: remove(tmp); }
524: i=findnext(&ff); } }
525:
526: return(1);
527: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.