void listmsgs(ulong start, ulong count) { int i; ulong l=0; smbmsg_t msg; if(!start) start=1; if(!count) count=~0; fseek(smb.sid_fp,(start-1L)*sizeof(idxrec_t),SEEK_SET); while(l<count) { if(!fread(&msg.idx,1,sizeof(idxrec_t),smb.sid_fp)) break; i=smb_lockmsghdr(&smb,&msg); if(i) { fprintf(errfp,"\n%s!smb_lockmsghdr returned %d: %s\n" ,beep,i,smb.last_error); break; } i=smb_getmsghdr(&smb,&msg); smb_unlockmsghdr(&smb,&msg); if(i) { fprintf(errfp,"\n%s!smb_getmsghdr returned %d: %s\n" ,beep,i,smb.last_error); break; } printf("%4"PRIu32" %-25.25s %-25.25s %s\n" ,msg.hdr.number,msg.from,msg.to,msg.subj); smb_freemsgmem(&msg); l++; } }
void sbbs_t::delallmail(uint usernumber, int which, bool permanent) { int i; long deleted=0; uint32_t msgs,u; mail_t *mail; smbmsg_t msg; if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { errormsg(WHERE,ERR_OPEN,"MAIL",i); return; } sprintf(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); smb_stack(&smb,SMB_STACK_POP); return; } mail=loadmail(&smb,&msgs,usernumber,which,0); if(!msgs) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); return; } if((i=smb_locksmbhdr(&smb))!=0) { /* Lock the base, so nobody */ smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); free(mail); errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); /* messes with the index */ return; } for(u=0;u<msgs;u++) { msg.idx.offset=0; /* search by number */ if((mail[u].attr&MSG_PERMANENT) && !permanent) continue; if(loadmsg(&msg,mail[u].number)) { /* message still there */ msg.hdr.attr|=MSG_DELETE; msg.hdr.attr&=~MSG_PERMANENT; msg.idx.attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); else deleted++; smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); } } if(msgs) free(mail); if(permanent && deleted && (cfg.sys_misc&SM_DELEMAIL)) delmail(usernumber,MAIL_ANY); smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); }
int sbbs_t::loadmsg(smbmsg_t *msg, ulong number) { char str[128]; int i; if(msg->idx.offset) { /* Load by offset if specified */ if((i=smb_lockmsghdr(&smb,msg))!=0) { errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); return(0); } i=smb_getmsghdr(&smb,msg); if(i==SMB_SUCCESS) { if(msg->hdr.number==number) return(1); /* Wrong offset */ smb_freemsgmem(msg); } smb_unlockmsghdr(&smb,msg); } msg->hdr.number=number; if((i=smb_getmsgidx(&smb,msg))!=SMB_SUCCESS) /* Message is deleted */ return(0); if((i=smb_lockmsghdr(&smb,msg))!=SMB_SUCCESS) { errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); return(0); } if((i=smb_getmsghdr(&smb,msg))!=SMB_SUCCESS) { sprintf(str,"(%06"PRIX32") #%"PRIu32"/%lu %s",msg->idx.offset,msg->idx.number ,number,smb.file); smb_unlockmsghdr(&smb,msg); errormsg(WHERE,ERR_READ,str,i,smb.last_error); return(0); } return(msg->total_hfields); }
int SMBCALL smb_getmsghdr_by_hash(smb_t* smb, smbmsg_t* msg, unsigned source ,unsigned flags, const void* data, size_t length) { int retval; if((retval=smb_getmsgidx_by_hash(smb,msg,source,flags,data,length))!=SMB_SUCCESS) return(retval); if((retval=smb_lockmsghdr(smb,msg))!=SMB_SUCCESS) return(retval); retval=smb_getmsghdr(smb,msg); smb_unlockmsghdr(smb,msg); return(retval); }
void viewmsgs(ulong start, ulong count) { int i; ulong l=0; smbmsg_t msg; if(!start) start=1; if(!count) count=~0; fseek(smb.sid_fp,(start-1L)*sizeof(idxrec_t),SEEK_SET); while(l<count) { if(!fread(&msg.idx,1,sizeof(idxrec_t),smb.sid_fp)) break; i=smb_lockmsghdr(&smb,&msg); if(i) { fprintf(errfp,"\n%s!smb_lockmsghdr returned %d: %s\n" ,beep,i,smb.last_error); break; } i=smb_getmsghdr(&smb,&msg); smb_unlockmsghdr(&smb,&msg); if(i) { fprintf(errfp,"\n%s!smb_getmsghdr returned %d: %s\n" ,beep,i,smb.last_error); break; } printf("--------------------\n"); printf("%-20.20s %ld\n" ,"index record",ftell(smb.sid_fp)/sizeof(idxrec_t)); smb_dump_msghdr(stdout,&msg); printf("\n"); smb_freemsgmem(&msg); l++; } }
int fixsmb(char* sub) { char* p; char* text; char c; int i,w; ulong l,length,size,n; smbmsg_t msg; memset(&smb,0,sizeof(smb)); SAFECOPY(smb.file,sub); if((p=getfext(smb.file))!=NULL && stricmp(p,".shd")==0) *p=0; /* Chop off .shd extension, if supplied on command-line */ printf("Opening %s\n",smb.file); if((i=smb_open(&smb))!=0) { printf("smb_open returned %d: %s\n",i,smb.last_error); exit(1); } if((i=smb_lock(&smb))!=0) { printf("smb_lock returned %d: %s\n",i,smb.last_error); exit(1); } if((i=smb_locksmbhdr(&smb))!=0) { smb_close(&smb); printf("smb_locksmbhdr returned %d: %s\n",i,smb.last_error); exit(1); } if((i=smb_getstatus(&smb))!=0) { smb_unlocksmbhdr(&smb); smb_close(&smb); printf("smb_getstatus returned %d: %s\n",i,smb.last_error); exit(1); } if(!(smb.status.attr&SMB_HYPERALLOC)) { if((i=smb_open_ha(&smb))!=0) { smb_close(&smb); printf("smb_open_ha returned %d: %s\n",i,smb.last_error); exit(1); } if((i=smb_open_da(&smb))!=0) { smb_close(&smb); printf("smb_open_da returned %d: %s\n",i,smb.last_error); exit(1); } rewind(smb.sha_fp); chsize(fileno(smb.sha_fp),0L); /* Truncate the header allocation file */ rewind(smb.sda_fp); chsize(fileno(smb.sda_fp),0L); /* Truncate the data allocation file */ } rewind(smb.sid_fp); chsize(fileno(smb.sid_fp),0L); /* Truncate the index */ if(!(smb.status.attr&SMB_HYPERALLOC)) { length=filelength(fileno(smb.sdt_fp)); w=0; for(l=0;l<length;l+=SDT_BLOCK_LEN) /* Init .SDA file to NULL */ fwrite(&w,2,1,smb.sda_fp); length=filelength(fileno(smb.shd_fp)); c=0; for(l=0;l<length;l+=SHD_BLOCK_LEN) /* Init .SHD file to NULL */ fwrite(&c,1,1,smb.sha_fp); } else length=filelength(fileno(smb.shd_fp)); n=0; /* messsage offset */ for(l=smb.status.header_offset;l<length;l+=size) { size=SHD_BLOCK_LEN; printf("\r%2lu%% ",(long)(100.0/((float)length/l))); msg.idx.offset=l; if((i=smb_lockmsghdr(&smb,&msg))!=0) { printf("\n(%06lX) smb_lockmsghdr returned %d:\n%s\n",l,i,smb.last_error); continue; } i=smb_getmsghdr(&smb,&msg); smb_unlockmsghdr(&smb,&msg); if(i!=0) { printf("\n(%06lX) smb_getmsghdr returned %d:\n%s\n",l,i,smb.last_error); continue; } size=smb_hdrblocks(smb_getmsghdrlen(&msg))*SHD_BLOCK_LEN; printf("#%-5lu (%06lX) %-25.25s ",msg.hdr.number,l,msg.from); /* Create hash record */ if(msg.hdr.attr&MSG_DELETE) text=NULL; else text=smb_getmsgtxt(&smb,&msg,GETMSGTXT_BODY_ONLY); i=smb_hashmsg(&smb,&msg,text,TRUE /* update */); if(i!=SMB_SUCCESS) printf("!ERROR %d hashing message\n", i); if(text!=NULL) free(text); /* Index the header */ if(msg.hdr.attr&MSG_DELETE) printf("Not indexing deleted message\n"); else if(msg.hdr.number==0) printf("Not indexing invalid message number (0)!\n"); else { msg.offset=n; if(renumber) msg.hdr.number=n+1; if(msg.hdr.netattr&MSG_INTRANSIT) { printf("Removing 'in transit' attribute\n"); msg.hdr.netattr&=~MSG_INTRANSIT; } if((i=smb_putmsg(&smb,&msg))!=0) { printf("\nsmb_putmsg returned %d: %s\n",i,smb.last_error); continue; } n++; } if(!(smb.status.attr&SMB_HYPERALLOC)) { /**************************/ /* Allocate header blocks */ /**************************/ fseek(smb.sha_fp,(l-smb.status.header_offset)/SHD_BLOCK_LEN,SEEK_SET); if(msg.hdr.attr&MSG_DELETE) c=0; /* mark as free */ else c=1; /* or allocated */ for(i=0;i<(int)(size/SHD_BLOCK_LEN);i++) fputc(c,smb.sha_fp); /************************/ /* Allocate data blocks */ /************************/ if(!(msg.hdr.attr&MSG_DELETE)) smb_incmsg_dfields(&smb,&msg,1); } smb_freemsgmem(&msg); } printf("\r%79s\r100%%\n",""); smb.status.total_msgs=n; if(renumber) smb.status.last_msg=n; else sort_index(&smb); printf("Saving message base status (%lu total messages).\n",n); if((i=smb_putstatus(&smb))!=0) printf("\nsmb_putstatus returned %d: %s\n",i,smb.last_error); smb_unlocksmbhdr(&smb); printf("Closing message base.\n"); smb_close(&smb); unlock_msgbase(); printf("Done.\n"); return(0); }
bool sbbs_t::pack_rep(uint hubnum) { char str[MAX_PATH+1]; char tmp[MAX_PATH+1],tmp2[MAX_PATH+1]; char hubid_upper[LEN_QWKID+1]; char hubid_lower[LEN_QWKID+1]; int file,mode; uint i,j,k; long msgcnt,submsgs,packedmail,netfiles=0,deleted; uint32_t u; uint32_t posts; uint32_t mailmsgs; ulong msgs; uint32_t last; post_t* post; mail_t* mail; FILE* rep; FILE* hdrs=NULL; DIR* dir; DIRENT* dirent; smbmsg_t msg; msgcnt=0L; delfiles(cfg.temp_dir,ALLFILES); SAFECOPY(hubid_upper,cfg.qhub[hubnum]->id); strupr(hubid_upper); SAFECOPY(hubid_lower,cfg.qhub[hubnum]->id); strlwr(hubid_lower); SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper); if(fexistcase(str)) { eprintf(LOG_INFO,"Updating %s", str); external(cmdstr(cfg.qhub[hubnum]->unpack,str,ALLFILES,NULL),EX_OFFLINE); } else eprintf(LOG_INFO,"Creating %s", str); /*************************************************/ /* Create SYSID.MSG, write header and leave open */ /*************************************************/ SAFEPRINTF2(str,"%s%s.MSG",cfg.temp_dir,hubid_upper); fexistcase(str); if((rep=fnopen(&file,str,O_CREAT|O_WRONLY|O_TRUNC))==NULL) { errormsg(WHERE,ERR_CREATE,str,O_CREAT|O_WRONLY|O_TRUNC); return(false); } if(filelength(file)<1) { /* New REP packet */ SAFEPRINTF2(str,"%-*s" ,QWK_BLOCK_LEN,hubid_upper); /* So write header */ fwrite(str,QWK_BLOCK_LEN,1,rep); } fseek(rep,0L,SEEK_END); /* Always includes HEADERS.DAT in .REP packets which are only for QWKnet hubs */ /* And *usually* a Synchronet system */ SAFEPRINTF(str,"%sHEADERS.DAT",cfg.temp_dir); fexistcase(str); if((hdrs=fopen(str,"a"))==NULL) errormsg(WHERE,ERR_CREATE,str,0); /*********************/ /* Pack new messages */ /*********************/ SAFEPRINTF(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { fclose(rep); if(hdrs!=NULL) fclose(hdrs); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(false); } /***********************/ /* Pack E-mail, if any */ /***********************/ qwkmail_last=0; mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0); packedmail=0; if(mailmsgs) { eprintf(LOG_INFO,"Packing NetMail for %s", cfg.qhub[hubnum]->id); for(u=0;u<mailmsgs;u++) { // bprintf("\b\b\b\b\b%-5lu",u+1); memset(&msg,0,sizeof(msg)); msg.idx=mail[u]; if(msg.idx.number>qwkmail_last) qwkmail_last=msg.idx.number; if(!loadmsg(&msg,mail[u].number)) continue; SAFEPRINTF(str,"%s/",cfg.qhub[hubnum]->id); if(msg.to_net.type!=NET_QWK || (strcmp((char *)msg.to_net.addr,cfg.qhub[hubnum]->id) && strncmp((char *)msg.to_net.addr,str,strlen(str)))) { smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); continue; } msgtoqwk(&msg,rep,QM_TO_QNET|QM_REP|A_LEAVE,INVALID_SUB,0,hdrs); packedmail++; smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); YIELD(); /* yield */ } eprintf(LOG_INFO,"Packed %d NetMail messages",packedmail); } smb_close(&smb); /* Close the e-mail */ if(mailmsgs) free(mail); for(i=0;i<cfg.qhub[hubnum]->subs;i++) { j=cfg.qhub[hubnum]->sub[i]; /* j now equals the real sub num */ msgs=getlastmsg(j,&last,0); lncntr=0; /* defeat pause */ if(!msgs || last<=subscan[j].ptr) { if(subscan[j].ptr>last) { subscan[j].ptr=last; subscan[j].last=last; } eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp) ,cfg.grp[cfg.sub[j]->grp]->sname ,cfg.sub[j]->lname,0L,msgs); continue; } SAFEPRINTF2(smb.file,"%s%s" ,cfg.sub[j]->data_dir,cfg.sub[j]->code); smb.retry_time=cfg.smb_retry_time; smb.subnum=j; if((k=smb_open(&smb))!=0) { errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error); continue; } post=loadposts(&posts,j,subscan[j].ptr,LP_BYSELF|LP_OTHERS|LP_PRIVATE|LP_REP,NULL); eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp) ,cfg.grp[cfg.sub[j]->grp]->sname ,cfg.sub[j]->lname,posts,msgs); if(!posts) { /* no new messages */ smb_close(&smb); continue; } subscan[j].ptr=last; /* set pointer */ eprintf(LOG_INFO,"%s",remove_ctrl_a(text[QWKPackingSubboard],tmp)); /* ptr to last msg */ submsgs=0; for(u=0;u<posts;u++) { // bprintf("\b\b\b\b\b%-5lu",u+1); memset(&msg,0,sizeof(msg)); msg.idx=post[u]; if(!loadmsg(&msg,post[u].number)) continue; if(msg.from_net.type && msg.from_net.type!=NET_QWK && !(cfg.sub[j]->misc&SUB_GATE)) { smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); continue; } if(!strnicmp(msg.subj,"NE:",3) || (msg.from_net.type==NET_QWK && route_circ((char *)msg.from_net.addr,cfg.qhub[hubnum]->id))) { smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); continue; } mode=cfg.qhub[hubnum]->mode[i]|QM_TO_QNET|QM_REP; if(mode&A_LEAVE) mode|=(QM_VIA|QM_TZ|QM_MSGID); if(msg.from_net.type!=NET_QWK) mode|=QM_TAGLINE; msgtoqwk(&msg,rep,mode,j,cfg.qhub[hubnum]->conf[i],hdrs); smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); msgcnt++; submsgs++; if(!(u%50)) YIELD(); /* yield */ } eprintf(LOG_INFO,remove_ctrl_a(text[QWKPackedSubboard],tmp),submsgs,msgcnt); free(post); smb_close(&smb); YIELD(); /* yield */ } if(hdrs!=NULL) fclose(hdrs); fclose(rep); /* close HUB_ID.MSG */ CRLF; /* Look for extra files to send out */ SAFEPRINTF2(str,"%sqnet/%s.out",cfg.data_dir,hubid_lower); dir=opendir(str); while(dir!=NULL && (dirent=readdir(dir))!=NULL) { SAFEPRINTF3(str,"%sqnet/%s.out/%s",cfg.data_dir,hubid_lower,dirent->d_name); if(isdir(str)) continue; SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,dirent->d_name); eprintf(LOG_INFO,remove_ctrl_a(text[RetrievingFile],tmp),str); if(!mv(str,tmp2,/* copy: */TRUE)) netfiles++; } if(dir!=NULL) closedir(dir); if(netfiles) CRLF; if(!msgcnt && !netfiles && !packedmail) { eprintf(LOG_INFO,remove_ctrl_a(text[QWKNoNewMessages],tmp)); return(true); // Changed from false Mar-11-2005 (needs to be true to save updated ptrs) } /*******************/ /* Compress Packet */ /*******************/ SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper); SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,ALLFILES); i=external(cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL) ,EX_OFFLINE|EX_WILDCARD); if(!fexistcase(str)) { eprintf(LOG_WARNING,"%s",remove_ctrl_a(text[QWKCompressionFailed],tmp)); if(i) errormsg(WHERE,ERR_EXEC,cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL),i); else lprintf(LOG_ERR, "Couldn't compress REP packet"); return(false); } SAFEPRINTF2(str,"%sqnet/%s.out/",cfg.data_dir,hubid_lower); delfiles(str,ALLFILES); if(packedmail) { /* Delete NetMail */ SAFEPRINTF(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(true); } mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0); if((i=smb_locksmbhdr(&smb))!=0) { /* Lock the base, so nobody */ if(mailmsgs) free(mail); smb_close(&smb); errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); /* messes with the index */ return(true); } if((i=smb_getstatus(&smb))!=0) { if(mailmsgs) free(mail); smb_close(&smb); errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error); return(true); } deleted=0; /* Mark as READ and DELETE */ for(u=0;u<mailmsgs;u++) { if(mail[u].number>qwkmail_last) continue; memset(&msg,0,sizeof(msg)); /* !IMPORTANT: search by number (do not initialize msg.idx.offset) */ if(!loadmsg(&msg,mail[u].number)) continue; SAFEPRINTF(str,"%s/",cfg.qhub[hubnum]->id); if(msg.to_net.type!=NET_QWK || (strcmp((char *)msg.to_net.addr,cfg.qhub[hubnum]->id) && strncmp((char *)msg.to_net.addr,str,strlen(str)))) { smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); continue; } msg.hdr.attr|=MSG_DELETE; msg.idx.attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); else deleted++; smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); } if(deleted && cfg.sys_misc&SM_DELEMAIL) delmail(0,MAIL_YOUR); smb_close(&smb); if(mailmsgs) free(mail); eprintf(LOG_INFO,"Deleted %d sent NetMail messages",deleted); } return(true); }
void sbbs_t::readmail(uint usernumber, int which) { char str[256],str2[256],str3[256],done=0,domsg=1 ,*p,*tp,*sp,ch; char tmp[512]; int i,j; int error; int mismatches=0,act; long length,l,lm_mode; ulong last; bool replied; file_t fd; mail_t *mail; smbmsg_t msg; if(which==MAIL_SENT && useron.rest&FLAG('K')) { bputs(text[R_ReadSentMail]); return; } msg.total_hfields=0; /* init to NULL, cause not allocated yet */ fd.dir=cfg.total_dirs+1; /* temp dir for file attachments */ if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { errormsg(WHERE,ERR_OPEN,"MAIL",i); return; } sprintf(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return; } if(cfg.sys_misc&SM_SYSVDELM && (SYSOP || cfg.sys_misc&SM_USRVDELM)) lm_mode=LM_INCDEL; else lm_mode=0; mail=loadmail(&smb,&smb.msgs,usernumber,which,lm_mode); if(!smb.msgs) { if(which==MAIL_SENT) bputs(text[NoMailSent]); else if(which==MAIL_ALL) bputs(text[NoMailOnSystem]); else bputs(text[NoMailWaiting]); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); return; } last=smb.status.last_msg; if(which==MAIL_SENT) act=NODE_RSML; else if(which==MAIL_ALL) act=NODE_SYSP; else act=NODE_RMAL; action=act; if(smb.msgs>1 && which!=MAIL_ALL) { if(which==MAIL_SENT) bputs(text[MailSentLstHdr]); else bputs(text[MailWaitingLstHdr]); for(smb.curmsg=0;smb.curmsg<smb.msgs && !msgabort();smb.curmsg++) { if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=mail[smb.curmsg].offset; if(!loadmsg(&msg,mail[smb.curmsg].number)) continue; smb_unlockmsghdr(&smb,&msg); bprintf(text[MailWaitingLstFmt],smb.curmsg+1 ,which==MAIL_SENT ? msg.to : (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP ? text[Anonymous] : msg.from ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R' : msg.hdr.attr&MSG_READ ? ' ' : msg.from_net.type || msg.to_net.type ? 'N':'*' ,msg.subj); smb_freemsgmem(&msg); msg.total_hfields=0; } ASYNC; if(!(sys_status&SS_ABORT)) { bprintf(text[StartWithN],1L); if((long)(smb.curmsg=getnum(smb.msgs))>0) smb.curmsg--; else if((long)smb.curmsg==-1) { free(mail); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); return; } } sys_status&=~SS_ABORT; } else { smb.curmsg=0; if(which==MAIL_ALL) domsg=0; } if(which==MAIL_SENT) { sprintf(str,"%s read sent mail",useron.alias); logline("E",str); } else if(which==MAIL_ALL) { sprintf(str,"%s read all mail",useron.alias); logline("S+",str); } else { sprintf(str,"%s read mail",useron.alias); logline("E",str); } if(useron.misc&RIP) { strcpy(str,which==MAIL_YOUR ? "mailread" : which==MAIL_ALL ? "allmail" : "sentmail"); menu(str); } while(online && !done) { action=act; if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=mail[smb.curmsg].offset; msg.idx.number=mail[smb.curmsg].number; msg.idx.to=mail[smb.curmsg].to; msg.idx.from=mail[smb.curmsg].from; msg.idx.subj=mail[smb.curmsg].subj; if((i=smb_locksmbhdr(&smb))!=0) { errormsg(WHERE,ERR_LOCK,smb.file,i); break; } if((i=smb_getstatus(&smb))!=0) { smb_unlocksmbhdr(&smb); errormsg(WHERE,ERR_READ,smb.file,i); break; } smb_unlocksmbhdr(&smb); if(smb.status.last_msg!=last) { /* New messages */ last=smb.status.last_msg; free(mail); mail=loadmail(&smb,&smb.msgs,usernumber,which,lm_mode); /* So re-load */ if(!smb.msgs) break; for(smb.curmsg=0;smb.curmsg<smb.msgs;smb.curmsg++) if(mail[smb.curmsg].number==msg.idx.number) break; if(smb.curmsg>=smb.msgs) smb.curmsg=(smb.msgs-1); continue; } if(!loadmsg(&msg,mail[smb.curmsg].number)) { /* Message header gone */ if(mismatches>5) { /* We can't do this too many times in a row */ errormsg(WHERE,ERR_CHK,"message number",mail[smb.curmsg].number); break; } free(mail); mail=loadmail(&smb,&smb.msgs,usernumber,which,lm_mode); if(!smb.msgs) break; if(smb.curmsg>(smb.msgs-1)) smb.curmsg=(smb.msgs-1); mismatches++; continue; } smb_unlockmsghdr(&smb,&msg); msg.idx.attr=msg.hdr.attr; mismatches=0; if(domsg && !(sys_status&SS_ABORT)) { show_msg(&msg ,msg.from_ext && msg.idx.from==1 && !msg.from_net.type ? 0:P_NOATCODES); if(msg.hdr.auxattr&MSG_FILEATTACH) { /* Attached file */ smb_getmsgidx(&smb,&msg); strcpy(str,msg.subj); /* filenames in title */ // strupr(str); tp=str; while(online) { p=strchr(tp,' '); if(p) *p=0; sp=strrchr(tp,'/'); /* sp is slash pointer */ if(!sp) sp=strrchr(tp,'\\'); if(sp) tp=sp+1; padfname(tp,fd.name); sprintf(str2,"%sfile/%04u.in/%s" /* str2 is path/fname */ ,cfg.data_dir,msg.idx.to,tp); length=flength(str2); if(length<1) bputs(text[FileNotFound]); else if(!(useron.exempt&FLAG('T')) && cur_cps && !SYSOP && length/(long)cur_cps>(time_t)timeleft) bputs(text[NotEnoughTimeToDl]); else { sprintf(str3,text[DownloadAttachedFileQ] ,tp,ultoac(length,tmp)); if(length>0L && yesno(str3)) { #if 0 /* no such thing as local logon */ if(online==ON_LOCAL) { bputs(text[EnterPath]); if(getstr(str3,60,K_LINE)) { backslashcolon(str3); sprintf(tmp,"%s%s",str3,tp); if(!mv(str2,tmp,which!=MAIL_YOUR)) { logon_dlb+=length; logon_dls++; useron.dls=(ushort)adjustuserrec(&cfg,useron.number ,U_DLS,5,1); useron.dlb=adjustuserrec(&cfg,useron.number ,U_DLB,10,length); bprintf(text[FileNBytesSent] ,fd.name,ultoac(length,tmp)); } } } else #endif { /* Remote User */ xfer_prot_menu(XFER_DOWNLOAD); mnemonics(text[ProtocolOrQuit]); strcpy(str3,"Q"); for(i=0;i<cfg.total_prots;i++) if(cfg.prot[i]->dlcmd[0] && chk_ar(cfg.prot[i]->ar,&useron)) { sprintf(tmp,"%c",cfg.prot[i]->mnemonic); strcat(str3,tmp); } ch=(char)getkeys(str3,0); for(i=0;i<cfg.total_prots;i++) if(cfg.prot[i]->dlcmd[0] && ch==cfg.prot[i]->mnemonic && chk_ar(cfg.prot[i]->ar,&useron)) break; if(i<cfg.total_prots) { error=protocol(cfg.prot[i],XFER_DOWNLOAD,str2,nulstr,false); if(checkprotresult(cfg.prot[i],error,&fd)) { if(which==MAIL_YOUR) remove(str2); logon_dlb+=length; /* Update stats */ logon_dls++; useron.dls=(ushort)adjustuserrec(&cfg,useron.number ,U_DLS,5,1); useron.dlb=adjustuserrec(&cfg,useron.number ,U_DLB,10,length); bprintf(text[FileNBytesSent] ,fd.name,ultoac(length,tmp)); sprintf(str3 ,"%s downloaded attached file: %s" ,useron.alias ,fd.name); logline("D-",str3); } autohangup(); } } } } if(!p) break; tp=p+1; while(*tp==' ') tp++; } sprintf(str,"%sfile/%04u.in",cfg.data_dir,usernumber); rmdir(str); } if(which==MAIL_YOUR && !(msg.hdr.attr&MSG_READ)) { mail[smb.curmsg].attr|=MSG_READ; if(thisnode.status==NODE_INUSE) telluser(&msg); if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=0; /* Search by number */ if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */ if(loadmsg(&msg,msg.idx.number)) { msg.hdr.attr|=MSG_READ; msg.idx.attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i); smb_unlockmsghdr(&smb,&msg); } smb_unlocksmbhdr(&smb); } if(!msg.total_hfields) { /* unsuccessful reload */ domsg=0; continue; } } } else domsg=1; if(useron.misc&WIP) { strcpy(str,which==MAIL_YOUR ? "mailread" : which==MAIL_ALL ? "allmail" : "sentmail"); menu(str); } ASYNC; if(which==MAIL_SENT) bprintf(text[ReadingSentMail],smb.curmsg+1,smb.msgs); else if(which==MAIL_ALL) bprintf(text[ReadingAllMail],smb.curmsg+1,smb.msgs); else bprintf(text[ReadingMail],smb.curmsg+1,smb.msgs); sprintf(str,"ADFLNQRT?<>[]{}-+"); if(SYSOP) strcat(str,"CUSPH"); if(which!=MAIL_YOUR) strcat(str,"E"); l=getkeys(str,smb.msgs); if(l&0x80000000L) { if(l==-1) /* ctrl-c */ break; smb.curmsg=(l&~0x80000000L)-1; continue; } switch(l) { case 'A': /* Auto-reply to last piece */ case 'R': if(l==(cfg.sys_misc&SM_RA_EMU ? 'A' : 'R')) /* re-read last message */ break; if(which==MAIL_SENT) break; if((msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP) { bputs(text[CantReplyToAnonMsg]); break; } quotemsg(&msg,1); if(msg.from_net.addr==NULL) SAFECOPY(str,msg.from); else if(msg.from_net.type==NET_FIDO) /* FidoNet type */ SAFEPRINTF2(str,"%s@%s",msg.from ,smb_faddrtoa((faddr_t *)msg.from_net.addr,tmp)); else if(msg.from_net.type==NET_INTERNET) { if(msg.replyto_net.type==NET_INTERNET) SAFECOPY(str,(char *)msg.replyto_net.addr); else SAFECOPY(str,(char *)msg.from_net.addr); } else SAFEPRINTF2(str,"%s@%s",msg.from,(char*)msg.from_net.addr); SAFECOPY(str2,str); bputs(text[Email]); if(!getstr(str,64,K_EDIT|K_AUTODEL)) break; msg.hdr.number=msg.idx.number; smb_getmsgidx(&smb,&msg); if(!stricmp(str2,str)) /* Reply to sender */ sprintf(str2,text[Regarding],msg.subj); else /* Reply to other */ sprintf(str2,text[RegardingByOn],msg.subj,msg.from ,timestr((time_t *)&msg.hdr.when_written.time)); p=strrchr(str,'@'); if(p) { /* name @addr */ replied=netmail(str,msg.subj,WM_QUOTE); sprintf(str2,text[DeleteMailQ],msg.from); } else { if(!msg.from_net.type && !stricmp(str,msg.from)) replied=email(msg.idx.from,str2,msg.subj,WM_EMAIL|WM_QUOTE); else if(!stricmp(str,"SYSOP")) replied=email(1,str2,msg.subj,WM_EMAIL|WM_QUOTE); else if((i=finduser(str))!=0) replied=email(i,str2,msg.subj,WM_EMAIL|WM_QUOTE); else replied=false; sprintf(str2,text[DeleteMailQ],msg.from); } if(replied==true && !(msg.hdr.attr&MSG_REPLIED)) { if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=0; if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */ if(loadmsg(&msg,msg.idx.number)) { msg.hdr.attr|=MSG_REPLIED; msg.idx.attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i); smb_unlockmsghdr(&smb,&msg); } smb_unlocksmbhdr(&smb); } } if(msg.hdr.attr&MSG_DELETE || !yesno(str2)) { if(smb.curmsg<smb.msgs-1) smb.curmsg++; else done=1; break; } /* Case 'D': must follow! */ case 'D': /* Delete last piece (toggle) */ if(msg.hdr.attr&MSG_PERMANENT) { bputs("\r\nPermanent message.\r\n"); domsg=0; break; } if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=0; if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */ if(loadmsg(&msg,msg.idx.number)) { msg.hdr.attr^=MSG_DELETE; msg.idx.attr=msg.hdr.attr; // mail[smb.curmsg].attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i); smb_unlockmsghdr(&smb,&msg); } smb_unlocksmbhdr(&smb); } if(smb.curmsg<smb.msgs-1) smb.curmsg++; else done=1; break; case 'F': /* Forward last piece */ domsg=0; bputs(text[ForwardMailTo]); if(!getstr(str,LEN_ALIAS,cfg.uq&UQ_NOUPRLWR ? K_NONE:K_UPRLWR)) break; i=finduser(str); if(!i) break; domsg=1; if(smb.curmsg<smb.msgs-1) smb.curmsg++; else done=1; smb_getmsgidx(&smb,&msg); forwardmail(&msg,i); if(msg.hdr.attr&MSG_PERMANENT) break; sprintf(str2,text[DeleteMailQ],msg.from); if(!yesno(str2)) break; if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=0; if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */ if(loadmsg(&msg,msg.idx.number)) { msg.hdr.attr|=MSG_DELETE; msg.idx.attr=msg.hdr.attr; // mail[smb.curmsg].attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i); smb_unlockmsghdr(&smb,&msg); } smb_unlocksmbhdr(&smb); } break; case 'H': domsg=0; msghdr(&msg); break; case 'L': /* List mail */ domsg=0; bprintf(text[StartWithN],(long)smb.curmsg+1); if((i=getnum(smb.msgs))>0) i--; else if(i==-1) break; else i=smb.curmsg; if(which==MAIL_SENT) bputs(text[MailSentLstHdr]); else if(which==MAIL_ALL) bputs(text[MailOnSystemLstHdr]); else bputs(text[MailWaitingLstHdr]); for(;i<smb.msgs && !msgabort();i++) { if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=mail[i].offset; if(!loadmsg(&msg,mail[i].number)) continue; smb_unlockmsghdr(&smb,&msg); if(which==MAIL_ALL) bprintf(text[MailOnSystemLstFmt] ,i+1,msg.from,msg.to ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R' : msg.hdr.attr&MSG_READ ? ' ' : msg.from_net.type || msg.to_net.type ? 'N':'*' ,msg.subj); else bprintf(text[MailWaitingLstFmt],i+1 ,which==MAIL_SENT ? msg.to : (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP ? text[Anonymous] : msg.from ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R' : msg.hdr.attr&MSG_READ ? ' ' : msg.from_net.type || msg.to_net.type ? 'N':'*' ,msg.subj); smb_freemsgmem(&msg); msg.total_hfields=0; } break; case 'Q': done=1; break; case 'C': /* Change attributes of last piece */ i=chmsgattr(msg.hdr.attr); if(msg.hdr.attr==i) break; if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=0; if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */ if(loadmsg(&msg,msg.idx.number)) { msg.hdr.attr=msg.idx.attr=(ushort)i; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i); smb_unlockmsghdr(&smb,&msg); } smb_unlocksmbhdr(&smb); } break; case '>': for(i=smb.curmsg+1;i<smb.msgs;i++) if(mail[i].subj==msg.idx.subj) break; if(i<smb.msgs) smb.curmsg=i; else domsg=0; break; case '<': /* Search Title backward */ for(i=smb.curmsg-1;i>-1;i--) if(mail[i].subj==msg.idx.subj) break; if(i>-1) smb.curmsg=i; else domsg=0; break; case '}': /* Search Author forward */ strcpy(str,msg.from); for(i=smb.curmsg+1;i<smb.msgs;i++) if(mail[i].from==msg.idx.from) break; if(i<smb.msgs) smb.curmsg=i; else domsg=0; break; case 'N': /* Got to next un-read message */ for(i=smb.curmsg+1;i<smb.msgs;i++) if(!(mail[i].attr&MSG_READ)) break; if(i<smb.msgs) smb.curmsg=i; else domsg=0; break; case '{': /* Search Author backward */ strcpy(str,msg.from); for(i=smb.curmsg-1;i>-1;i--) if(mail[i].from==msg.idx.from) break; if(i>-1) smb.curmsg=i; else domsg=0; break; case ']': /* Search To User forward */ strcpy(str,msg.to); for(i=smb.curmsg+1;i<smb.msgs;i++) if(mail[i].to==msg.idx.to) break; if(i<smb.msgs) smb.curmsg=i; else domsg=0; break; case '[': /* Search To User backward */ strcpy(str,msg.to); for(i=smb.curmsg-1;i>-1;i--) if(mail[i].to==msg.idx.to) break; if(i>-1) smb.curmsg=i; else domsg=0; break; case 0: case '+': if(smb.curmsg<smb.msgs-1) smb.curmsg++; else done=1; break; case '-': if(smb.curmsg>0) smb.curmsg--; break; case 'S': domsg=0; /* if(!yesno(text[SaveMsgToFile])) break; */ bputs(text[FileToWriteTo]); if(getstr(str,40,K_LINE)) msgtotxt(&msg,str,1,1); break; case 'E': editmsg(&msg,INVALID_SUB); break; case 'T': domsg=0; i=smb.curmsg; if(i) i++; j=i+10; if(j>smb.msgs) j=smb.msgs; if(which==MAIL_SENT) bputs(text[MailSentLstHdr]); else if(which==MAIL_ALL) bputs(text[MailOnSystemLstHdr]); else bputs(text[MailWaitingLstHdr]); for(;i<j;i++) { if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=mail[i].offset; if(!loadmsg(&msg,mail[i].number)) continue; smb_unlockmsghdr(&smb,&msg); if(which==MAIL_ALL) bprintf(text[MailOnSystemLstFmt] ,i+1,msg.from,msg.to ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R' : msg.hdr.attr&MSG_READ ? ' ' : msg.from_net.type || msg.to_net.type ? 'N':'*' ,msg.subj); else bprintf(text[MailWaitingLstFmt],i+1 ,which==MAIL_SENT ? msg.to : (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP ? text[Anonymous] : msg.from ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R' : msg.hdr.attr&MSG_READ ? ' ' : msg.from_net.type || msg.to_net.type ? 'N':'*' ,msg.subj); smb_freemsgmem(&msg); msg.total_hfields=0; } smb.curmsg=(i-1); break; case 'U': /* user edit */ msg.hdr.number=msg.idx.number; smb_getmsgidx(&smb,&msg); useredit(which==MAIL_SENT ? msg.idx.to : msg.idx.from); break; case 'P': /* Purge author and all mail to/from */ if(noyes(text[AreYouSureQ])) break; msg.hdr.number=msg.idx.number; smb_getmsgidx(&smb,&msg); purgeuser(msg.idx.from); if(smb.curmsg<smb.msgs-1) smb.curmsg++; break; case '?': strcpy(str,which==MAIL_YOUR ? "mailread" : which==MAIL_ALL ? "allmail" : "sentmail"); menu(str); if(SYSOP && which==MAIL_SENT) menu("syssmail"); else if(SYSOP && which==MAIL_YOUR) menu("sysmailr"); /* Sysop Mail Read */ domsg=0; break; } } if(msg.total_hfields) smb_freemsgmem(&msg); if(smb.msgs) free(mail); /***************************************/ /* Delete messages marked for deletion */ /***************************************/ if(cfg.sys_misc&SM_DELEMAIL) { if((i=smb_locksmbhdr(&smb))!=0) /* Lock the base, so nobody */ errormsg(WHERE,ERR_LOCK,smb.file,i); /* messes with the index */ else delmail(usernumber,which); } smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); }
void maint(void) { int i; ulong l,m,n,f,flagged=0; time_t now; smbmsg_t msg; idxrec_t *idx; printf("Maintaining %s\r\n",smb.file); now=time(NULL); i=smb_locksmbhdr(&smb); if(i) { fprintf(errfp,"\n%s!smb_locksmbhdr returned %d: %s\n" ,beep,i,smb.last_error); return; } i=smb_getstatus(&smb); if(i) { smb_unlocksmbhdr(&smb); fprintf(errfp,"\n%s!smb_getstatus returned %d: %s\n" ,beep,i,smb.last_error); return; } if(smb_open_hash(&smb) == SMB_SUCCESS) { ulong max_hashes=0; printf("Maintaining %s hash file\r\n", smb.file); if((smb.status.attr&(SMB_EMAIL|SMB_NOHASH)) == 0) { max_hashes = smb.status.max_msgs; if(smb.status.max_crcs > max_hashes) max_hashes = smb.status.max_crcs; } if(!max_hashes) { CHSIZE_FP(smb.hash_fp,0); } else if(filelength(fileno(smb.hash_fp)) > (long)(max_hashes * SMB_HASH_SOURCE_TYPES * sizeof(hash_t))) { if(fseek(smb.hash_fp, -((long)(max_hashes * SMB_HASH_SOURCE_TYPES * sizeof(hash_t))), SEEK_END) == 0) { hash_t* hashes = malloc(max_hashes * SMB_HASH_SOURCE_TYPES * sizeof(hash_t)); if(hashes != NULL) { if(fread(hashes, sizeof(hash_t), max_hashes * SMB_HASH_SOURCE_TYPES, smb.hash_fp) == max_hashes * SMB_HASH_SOURCE_TYPES) { CHSIZE_FP(smb.hash_fp,0); rewind(smb.hash_fp); fwrite(hashes, sizeof(hash_t), max_hashes * SMB_HASH_SOURCE_TYPES, smb.hash_fp); } free(hashes); } } } smb_close_hash(&smb); } if(!smb.status.total_msgs) { smb_unlocksmbhdr(&smb); printf("Empty\n"); return; } printf("Loading index...\n"); if((idx=(idxrec_t *)malloc(sizeof(idxrec_t)*smb.status.total_msgs)) ==NULL) { smb_unlocksmbhdr(&smb); fprintf(errfp,"\n%s!Error allocating %u bytes of memory\n" ,beep,sizeof(idxrec_t)*smb.status.total_msgs); return; } fseek(smb.sid_fp,0L,SEEK_SET); for(l=0;l<smb.status.total_msgs;l++) { printf("%lu of %"PRIu32"\r" ,l+1,smb.status.total_msgs); if(!fread(&idx[l],1,sizeof(idxrec_t),smb.sid_fp)) break; } printf("\nDone.\n\n"); printf("Scanning for pre-flagged messages...\n"); for(m=0;m<l;m++) { printf("\r%2lu%%",m ? (long)(100.0/((float)l/m)) : 0); if(idx[m].attr&MSG_DELETE) flagged++; } printf("\r100%% (%lu pre-flagged for deletion)\n",flagged); if(smb.status.max_age) { printf("Scanning for messages more than %u days old...\n" ,smb.status.max_age); for(m=f=0;m<l;m++) { printf("\r%2lu%%",m ? (long)(100.0/((float)l/m)) : 0); if(idx[m].attr&(MSG_PERMANENT|MSG_DELETE)) continue; if((ulong)now>idx[m].time && (now-idx[m].time)/(24L*60L*60L) >smb.status.max_age) { f++; flagged++; idx[m].attr|=MSG_DELETE; } } /* mark for deletion */ printf("\r100%% (%lu flagged for deletion due to age)\n",f); } printf("Scanning for read messages to be killed...\n"); for(m=f=0;m<l;m++) { printf("\r%2lu%%",m ? (long)(100.0/((float)l/m)) : 0); if(idx[m].attr&(MSG_PERMANENT|MSG_DELETE)) continue; if((idx[m].attr&(MSG_READ|MSG_KILLREAD))==(MSG_READ|MSG_KILLREAD)) { f++; flagged++; idx[m].attr|=MSG_DELETE; } } printf("\r100%% (%lu flagged for deletion due to read status)\n",f); if(smb.status.max_msgs && l-flagged>smb.status.max_msgs) { printf("Flagging excess messages for deletion...\n"); for(m=n=0,f=flagged;l-flagged>smb.status.max_msgs && m<l;m++) { if(idx[m].attr&(MSG_PERMANENT|MSG_DELETE)) continue; printf("%lu of %lu\r",++n,(l-f)-smb.status.max_msgs); flagged++; idx[m].attr|=MSG_DELETE; } /* mark for deletion */ printf("\nDone.\n\n"); } if(!flagged) { /* No messages to delete */ free(idx); smb_unlocksmbhdr(&smb); return; } if(!(mode&NOANALYSIS)) { printf("Freeing allocated header and data blocks for deleted messages...\n"); if(!(smb.status.attr&SMB_HYPERALLOC)) { i=smb_open_da(&smb); if(i) { smb_unlocksmbhdr(&smb); fprintf(errfp,"\n%s!smb_open_da returned %d: %s\n" ,beep,i,smb.last_error); bail(1); } i=smb_open_ha(&smb); if(i) { smb_unlocksmbhdr(&smb); fprintf(errfp,"\n%s!smb_open_ha returned %d: %s\n" ,beep,i,smb.last_error); bail(1); } } for(m=n=0;m<l;m++) { if(idx[m].attr&MSG_DELETE) { printf("%lu of %lu\r",++n,flagged); msg.idx=idx[m]; msg.hdr.number=msg.idx.number; if((i=smb_getmsgidx(&smb,&msg))!=0) { fprintf(errfp,"\n%s!smb_getmsgidx returned %d: %s\n" ,beep,i,smb.last_error); continue; } i=smb_lockmsghdr(&smb,&msg); if(i) { fprintf(errfp,"\n%s!smb_lockmsghdr returned %d: %s\n" ,beep,i,smb.last_error); break; } if((i=smb_getmsghdr(&smb,&msg))!=0) { smb_unlockmsghdr(&smb,&msg); fprintf(errfp,"\n%s!smb_getmsghdr returned %d: %s\n" ,beep,i,smb.last_error); break; } msg.hdr.attr|=MSG_DELETE; /* mark header as deleted */ if((i=smb_putmsg(&smb,&msg))!=0) { smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); fprintf(errfp,"\n%s!smb_putmsg returned %d: %s\n" ,beep,i,smb.last_error); break; } smb_unlockmsghdr(&smb,&msg); if((i=smb_freemsg(&smb,&msg))!=0) { smb_freemsgmem(&msg); fprintf(errfp,"\n%s!smb_freemsg returned %d: %s\n" ,beep,i,smb.last_error); break; } smb_freemsgmem(&msg); } } if(!(smb.status.attr&SMB_HYPERALLOC)) { smb_close_ha(&smb); smb_close_da(&smb); } printf("\nDone.\n\n"); } printf("Re-writing index...\n"); rewind(smb.sid_fp); CHSIZE_FP(smb.sid_fp,0); for(m=n=0;m<l;m++) { if(idx[m].attr&MSG_DELETE) continue; printf("%lu of %lu\r",++n,l-flagged); fwrite(&idx[m],sizeof(idxrec_t),1,smb.sid_fp); } printf("\nDone.\n\n"); fflush(smb.sid_fp); free(idx); smb.status.total_msgs-=flagged; smb_putstatus(&smb); smb_unlocksmbhdr(&smb); }
bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) { char str[MAX_PATH+1],ch,*p; char tmp[MAX_PATH+1],tmp2[MAX_PATH+1]; char* fname; char* fmode; int mode; uint i,j,k,conf; long l,size,msgndx,posts,ex; long mailmsgs=0; ulong totalcdt,totaltime,lastmsg ,files,submsgs,msgs,netfiles=0,preqwk=0; ulong subs_scanned=0; float f; /* Sparky is responsible */ time_t start; node_t node; mail_t *mail; post_t *post; glob_t g; FILE *stream,*qwk,*personal,*ndx; DIR* dir; DIRENT* dirent; struct tm tm; smbmsg_t msg; ex=EX_OUTL|EX_OUTR; /* Need sh for wildcard expansion */ if(prepack) ex|=EX_OFFLINE; delfiles(cfg.temp_dir,ALLFILES); sprintf(str,"%sfile/%04u.qwk",cfg.data_dir,useron.number); if(fexistcase(str)) { for(k=0;k<cfg.total_fextrs;k++) if(!stricmp(cfg.fextr[k]->ext,useron.tmpext) && chk_ar(cfg.fextr[k]->ar,&useron)) break; if(k>=cfg.total_fextrs) k=0; p=cmdstr(cfg.fextr[k]->cmd,str,ALLFILES,NULL); if((i=external(p,ex))==0) preqwk=1; else errormsg(WHERE,ERR_EXEC,p,i); } if(useron.rest&FLAG('Q') && useron.qwk&QWK_RETCTLA) useron.qwk|=(QWK_NOINDEX|QWK_NOCTRL|QWK_VIA|QWK_TZ|QWK_MSGID); if(useron.qwk&QWK_EXPCTLA) mode=A_EXPAND; else if(useron.qwk&QWK_RETCTLA) mode=A_LEAVE; else mode=0; if(useron.qwk&QWK_TZ) mode|=QM_TZ; if(useron.qwk&QWK_VIA) mode|=QM_VIA; if(useron.qwk&QWK_MSGID) mode|=QM_MSGID; (*msgcnt)=0L; if(/* !prepack && */ !(useron.qwk&QWK_NOCTRL)) { /***************************/ /* Create CONTROL.DAT file */ /***************************/ sprintf(str,"%sCONTROL.DAT",cfg.temp_dir); if((stream=fopen(str,"wb"))==NULL) { errormsg(WHERE,ERR_OPEN,str,0); return(false); } now=time(NULL); if(localtime_r(&now,&tm)==NULL) return(false); fprintf(stream,"%s\r\n%s\r\n%s\r\n%s, Sysop\r\n0000,%s\r\n" "%02u-%02u-%u,%02u:%02u:%02u\r\n" ,cfg.sys_name ,cfg.sys_location ,cfg.node_phone ,cfg.sys_op ,cfg.sys_id ,tm.tm_mon+1,tm.tm_mday,tm.tm_year+1900 ,tm.tm_hour,tm.tm_min,tm.tm_sec); k=0; for(i=0;i<usrgrps;i++) for(j=0;j<usrsubs[i];j++) k++; /* k is how many subs */ fprintf(stream,"%s\r\n\r\n0\r\n0\r\n%u\r\n",useron.alias,k); fprintf(stream,"0\r\nE-mail\r\n"); /* first conference is e-mail */ char confname[256]; for(i=0;i<usrgrps;i++) for(j=0;j<usrsubs[i];j++) { if(useron.qwk&QWK_EXT) /* 255 char max */ sprintf(confname,"%s %s" ,cfg.grp[cfg.sub[usrsub[i][j]]->grp]->sname ,cfg.sub[usrsub[i][j]]->lname); else /* 10 char max */ strcpy(confname,cfg.sub[usrsub[i][j]]->qwkname); fprintf(stream,"%u\r\n%s\r\n" ,cfg.sub[usrsub[i][j]]->qwkconf ? cfg.sub[usrsub[i][j]]->qwkconf : ((i+1)*1000)+j+1,confname); } fprintf(stream,"HELLO\r\nBBSNEWS\r\nGOODBYE\r\n"); fclose(stream); /***********************/ /* Create DOOR.ID File */ /***********************/ sprintf(str,"%sDOOR.ID",cfg.temp_dir); if((stream=fopen(str,"wb"))==NULL) { errormsg(WHERE,ERR_OPEN,str,0); return(false); } p="CONTROLTYPE = "; fprintf(stream,"DOOR = %.10s\r\nVERSION = %s%c\r\n" "SYSTEM = %s\r\n" "CONTROLNAME = SBBS\r\n" "%sADD\r\n" "%sDROP\r\n" "%sYOURS\r\n" "%sRESET\r\n" "%sRESETALL\r\n" "%sFILES\r\n" "%sATTACH\r\n" "%sOWN\r\n" "%smail\r\n" "%sDELMAIL\r\n" "%sCTRL-A\r\n" "%sFREQ\r\n" "%sNDX\r\n" "%sTZ\r\n" "%sVIA\r\n" "%sCONTROL\r\n" "MIXEDCASE = YES\r\n" ,VERSION_NOTICE ,VERSION,REVISION ,VERSION_NOTICE ,p,p,p,p ,p,p,p,p ,p,p,p,p ,p,p,p,p ); fclose(stream); if(useron.rest&FLAG('Q')) { /***********************/ /* Create NETFLAGS.DAT */ /***********************/ sprintf(str,"%sNETFLAGS.DAT",cfg.temp_dir); if((stream=fopen(str,"wb"))==NULL) { errormsg(WHERE,ERR_CREATE,str,0); return(false); } ch=1; /* Net enabled */ if(usrgrps) for(i=0;i<(usrgrps*1000)+usrsubs[usrgrps-1];i++) fputc(ch,stream); fclose(stream); } } /****************************************************/ /* Create MESSAGES.DAT, write header and leave open */ /****************************************************/ sprintf(str,"%sMESSAGES.DAT",cfg.temp_dir); if(fexistcase(str)) fmode="r+b"; else fmode="w+b"; if((qwk=fopen(str,fmode))==NULL) { errormsg(WHERE,ERR_OPEN,str,0); return(false); } l=filelength(fileno(qwk)); if(l<1) { fprintf(qwk,"%-128.128s","Produced by " VERSION_NOTICE " " COPYRIGHT_NOTICE); msgndx=1; } else { msgndx=l/QWK_BLOCK_LEN; fseek(qwk,0,SEEK_END); } sprintf(str,"%sNEWFILES.DAT",cfg.temp_dir); remove(str); if(!(useron.rest&FLAG('T')) && useron.qwk&QWK_FILES) files=create_filelist("NEWFILES.DAT",FL_ULTIME); else files=0; start=time(NULL); if(useron.rest&FLAG('Q')) useron.qwk|=(QWK_EMAIL|QWK_ALLMAIL|QWK_DELMAIL); if(!(useron.qwk&QWK_NOINDEX)) { sprintf(str,"%sPERSONAL.NDX",cfg.temp_dir); if((personal=fopen(str,"ab"))==NULL) { fclose(qwk); errormsg(WHERE,ERR_OPEN,str,0); return(false); } } else personal=NULL; if(useron.qwk&(QWK_EMAIL|QWK_ALLMAIL) /* && !prepack */) { sprintf(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { fclose(qwk); if(personal) fclose(personal); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(false); } /***********************/ /* Pack E-mail, if any */ /***********************/ qwkmail_last=0; mail=loadmail(&smb,&mailmsgs,useron.number,0,useron.qwk&QWK_ALLMAIL ? 0 : LM_UNREAD); if(mailmsgs && !(sys_status&SS_ABORT)) { bputs(text[QWKPackingEmail]); if(!(useron.qwk&QWK_NOINDEX)) { sprintf(str,"%s000.NDX",cfg.temp_dir); if((ndx=fopen(str,"ab"))==NULL) { fclose(qwk); if(personal) fclose(personal); smb_close(&smb); errormsg(WHERE,ERR_OPEN,str,0); free(mail); return(false); } } else ndx=NULL; if(useron.rest&FLAG('Q')) mode|=QM_TO_QNET; else mode&=~QM_TO_QNET; for(l=0;l<mailmsgs;l++) { bprintf("\b\b\b\b\b\b\b\b\b\b\b\b%4lu of %-4lu" ,l+1,mailmsgs); memset(&msg,0,sizeof(msg)); msg.idx=mail[l]; if(msg.idx.number>qwkmail_last) qwkmail_last=msg.idx.number; if(!loadmsg(&msg,mail[l].number)) continue; if(msg.hdr.auxattr&MSG_FILEATTACH && useron.qwk&QWK_ATTACH) { sprintf(str,"%sfile/%04u.in/%s" ,cfg.data_dir,useron.number,msg.subj); sprintf(tmp,"%s%s",cfg.temp_dir,msg.subj); if(fexistcase(str) && !fexistcase(tmp)) mv(str,tmp,1); } size=msgtoqwk(&msg,qwk,mode,INVALID_SUB,0); smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); if(ndx) { msgndx++; f=ltomsbin(msgndx); /* Record number */ ch=0; /* Sub number, not used */ if(personal) { fwrite(&f,4,1,personal); fwrite(&ch,1,1,personal); } fwrite(&f,4,1,ndx); fwrite(&ch,1,1,ndx); msgndx+=size/QWK_BLOCK_LEN; } YIELD(); /* yield */ } bprintf(text[QWKPackedEmail],mailmsgs); if(ndx) fclose(ndx); } smb_close(&smb); /* Close the e-mail */ if(mailmsgs) free(mail); } /*********************/ /* Pack new messages */ /*********************/ for(i=0;i<usrgrps;i++) { for(j=0;j<usrsubs[i] && !msgabort();j++) { if(subscan[usrsub[i][j]].cfg&SUB_CFG_NSCAN || (!(useron.rest&FLAG('Q')) && cfg.sub[usrsub[i][j]]->misc&SUB_FORCED)) { if(!chk_ar(cfg.sub[usrsub[i][j]]->read_ar,&useron)) continue; lncntr=0; /* defeat pause */ if(useron.rest&FLAG('Q') && !(cfg.sub[usrsub[i][j]]->misc&SUB_QNET)) continue; /* QWK Net Node and not QWK networked, so skip */ subs_scanned++; msgs=getlastmsg(usrsub[i][j],&lastmsg,0); if(!msgs || lastmsg<=subscan[usrsub[i][j]].ptr) { /* no msgs */ if(subscan[usrsub[i][j]].ptr>lastmsg) { /* corrupted ptr */ outchar('*'); subscan[usrsub[i][j]].ptr=lastmsg; /* so fix automatically */ subscan[usrsub[i][j]].last=lastmsg; } bprintf(text[NScanStatusFmt] ,cfg.grp[cfg.sub[usrsub[i][j]]->grp]->sname ,cfg.sub[usrsub[i][j]]->lname,0L,msgs); continue; } sprintf(smb.file,"%s%s" ,cfg.sub[usrsub[i][j]]->data_dir,cfg.sub[usrsub[i][j]]->code); smb.retry_time=cfg.smb_retry_time; smb.subnum=usrsub[i][j]; if((k=smb_open(&smb))!=0) { errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error); continue; } k=0; if(useron.qwk&QWK_BYSELF) k|=LP_BYSELF; if(useron.rest&FLAG('Q') || !(subscan[usrsub[i][j]].cfg&SUB_CFG_YSCAN)) k|=LP_OTHERS; post=loadposts(&posts,usrsub[i][j],subscan[usrsub[i][j]].ptr,k); bprintf(text[NScanStatusFmt] ,cfg.grp[cfg.sub[usrsub[i][j]]->grp]->sname ,cfg.sub[usrsub[i][j]]->lname,posts,msgs); if(!posts) { /* no new messages */ smb_close(&smb); continue; } bputs(text[QWKPackingSubboard]); submsgs=0; conf=cfg.sub[usrsub[i][j]]->qwkconf; if(!conf) conf=((i+1)*1000)+j+1; if(!(useron.qwk&QWK_NOINDEX)) { sprintf(str,"%s%u.NDX",cfg.temp_dir,conf); if((ndx=fopen(str,"ab"))==NULL) { fclose(qwk); if(personal) fclose(personal); smb_close(&smb); errormsg(WHERE,ERR_OPEN,str,0); free(post); return(false); } } else ndx=NULL; for(l=0;l<posts && !msgabort();l++) { bprintf("\b\b\b\b\b%-5lu",l+1); subscan[usrsub[i][j]].ptr=post[l].number; /* set ptr */ subscan[usrsub[i][j]].last=post[l].number; /* set last read */ memset(&msg,0,sizeof(msg)); msg.idx=post[l]; if(!loadmsg(&msg,post[l].number)) continue; if(useron.rest&FLAG('Q')) { if(msg.from_net.type && msg.from_net.type!=NET_QWK && !(cfg.sub[usrsub[i][j]]->misc&SUB_GATE)) { /* From other */ smb_freemsgmem(&msg); /* net, don't gate */ smb_unlockmsghdr(&smb,&msg); continue; } mode|=(QM_TO_QNET|QM_TAGLINE); if(msg.from_net.type==NET_QWK) { mode&=~QM_TAGLINE; if(route_circ((char *)msg.from_net.addr,useron.alias) || !strnicmp(msg.subj,"NE:",3)) { smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); continue; } } } else mode&=~(QM_TAGLINE|QM_TO_QNET); size=msgtoqwk(&msg,qwk,mode,usrsub[i][j],conf); smb_unlockmsghdr(&smb,&msg); if(ndx) { msgndx++; f=ltomsbin(msgndx); /* Record number */ ch=0; /* Sub number, not used */ if(personal && (!stricmp(msg.to,useron.alias) || !stricmp(msg.to,useron.name))) { fwrite(&f,4,1,personal); fwrite(&ch,1,1,personal); } fwrite(&f,4,1,ndx); fwrite(&ch,1,1,ndx); msgndx+=size/QWK_BLOCK_LEN; } smb_freemsgmem(&msg); (*msgcnt)++; submsgs++; if(cfg.max_qwkmsgs && !(useron.exempt&FLAG('O')) && (*msgcnt)>=cfg.max_qwkmsgs) { bputs(text[QWKmsgLimitReached]); break; } if(!(l%50)) YIELD(); /* yield */ } if(!(sys_status&SS_ABORT)) bprintf(text[QWKPackedSubboard],submsgs,(*msgcnt)); if(ndx) { fclose(ndx); sprintf(str,"%s%u.NDX",cfg.temp_dir,conf); if(!flength(str)) remove(str); } smb_close(&smb); free(post); if(l<posts) break; YIELD(); /* yield */ } } if(j<usrsubs[i]) /* if sub aborted, abort all */ break; } if(online==ON_LOCAL) /* event */ eprintf(LOG_INFO,"%s scanned %lu sub-boards for new messages" ,useron.alias,subs_scanned); else lprintf(LOG_INFO,"Node %d %s scanned %lu sub-boards for new messages" ,cfg.node_num,useron.alias,subs_scanned); if((*msgcnt)+mailmsgs && time(NULL)-start) { bprintf("\r\n\r\n\1n\1hPacked %lu messages (%lu bytes) in %lu seconds " "(%lu messages/second)." ,(*msgcnt)+mailmsgs ,ftell(qwk) ,time(NULL)-start ,((*msgcnt)+mailmsgs)/(time(NULL)-start)); sprintf(str,"Packed %lu messages (%lu bytes) in %lu seconds (%lu msgs/sec)" ,(*msgcnt)+mailmsgs ,ftell(qwk) ,(ulong)(time(NULL)-start) ,((*msgcnt)+mailmsgs)/(time(NULL)-start)); if(online==ON_LOCAL) /* event */ eprintf(LOG_INFO,"%s",str); else lprintf(LOG_INFO,"%s",str); } fclose(qwk); /* close MESSAGE.DAT */ if(personal) { fclose(personal); /* close PERSONAL.NDX */ sprintf(str,"%sPERSONAL.NDX",cfg.temp_dir); if(!flength(str)) remove(str); } CRLF; if(!prepack && (sys_status&SS_ABORT || !online)) return(false); if(/*!prepack && */ useron.rest&FLAG('Q')) { /* If QWK Net node, check for files */ sprintf(str,"%sqnet/%s.out/",cfg.data_dir,useron.alias); dir=opendir(str); while(dir!=NULL && (dirent=readdir(dir))!=NULL) { /* Move files into temp dir */ sprintf(str,"%sqnet/%s.out/%s",cfg.data_dir,useron.alias,dirent->d_name); if(isdir(str)) continue; sprintf(tmp2,"%s%s",cfg.temp_dir,dirent->d_name); lncntr=0; /* Default pause */ if(online==ON_LOCAL) eprintf(LOG_INFO,"Including %s in packet",str); else lprintf(LOG_INFO,"Including %s in packet",str); bprintf(text[RetrievingFile],str); if(!mv(str,tmp2,1)) netfiles++; } if(dir!=NULL) closedir(dir); if(netfiles) CRLF; } if(batdn_total) { for(i=0,totalcdt=0;i<batdn_total;i++) if(!is_download_free(&cfg,batdn_dir[i],&useron)) totalcdt+=batdn_cdt[i]; if(totalcdt>useron.cdt+useron.freecdt) { bprintf(text[YouOnlyHaveNCredits] ,ultoac(useron.cdt+useron.freecdt,tmp)); } else { for(i=0,totaltime=0;i<batdn_total;i++) { if(!(cfg.dir[batdn_dir[i]]->misc&DIR_TFREE) && cur_cps) totaltime+=batdn_size[i]/(ulong)cur_cps; } if(!(useron.exempt&FLAG('T')) && !SYSOP && totaltime>timeleft) bputs(text[NotEnoughTimeToDl]); else { for(i=0;i<batdn_total;i++) { lncntr=0; unpadfname(batdn_name[i],tmp); sprintf(tmp2,"%s%s",cfg.temp_dir,tmp); if(!fexistcase(tmp2)) { seqwait(cfg.dir[batdn_dir[i]]->seqdev); bprintf(text[RetrievingFile],tmp); sprintf(str,"%s%s" ,batdn_alt[i]>0 && batdn_alt[i]<=cfg.altpaths ? cfg.altpath[batdn_alt[i]-1] : cfg.dir[batdn_dir[i]]->path ,tmp); mv(str,tmp2,1); /* copy the file to temp dir */ getnodedat(cfg.node_num,&thisnode,1); thisnode.aux=0xfe; putnodedat(cfg.node_num,&thisnode); CRLF; } } } } } if(!(*msgcnt) && !mailmsgs && !files && !netfiles && !batdn_total && (prepack || !preqwk)) { bputs(text[QWKNoNewMessages]); return(false); } if(!(useron.rest&FLAG('Q'))) { /* Don't include in network */ /***********************/ /* packets */ /* Copy QWK Text files */ /***********************/ sprintf(str,"%sQWK/HELLO",cfg.text_dir); if(fexistcase(str)) { sprintf(tmp2,"%sHELLO",cfg.temp_dir); mv(str,tmp2,1); } sprintf(str,"%sQWK/BBSNEWS",cfg.text_dir); if(fexistcase(str)) { sprintf(tmp2,"%sBBSNEWS",cfg.temp_dir); mv(str,tmp2,1); } sprintf(str,"%sQWK/GOODBYE",cfg.text_dir); if(fexistcase(str)) { sprintf(tmp2,"%sGOODBYE",cfg.temp_dir); mv(str,tmp2,1); } sprintf(str,"%sQWK/BLT-*",cfg.text_dir); glob(str,0,NULL,&g); for(i=0;i<(uint)g.gl_pathc;i++) { /* Copy BLT-*.* files */ fname=getfname(g.gl_pathv[i]); padfname(fname,str); if(isdigit(str[4]) && isdigit(str[9])) { sprintf(str,"%sQWK/%s",cfg.text_dir,fname); sprintf(tmp2,"%s%s",cfg.temp_dir,fname); mv(str,tmp2,1); } } globfree(&g); } if(prepack) { for(i=1;i<=cfg.sys_nodes;i++) { getnodedat(i,&node,0); if((node.status==NODE_INUSE || node.status==NODE_QUIET || node.status==NODE_LOGON) && node.useron==useron.number) break; } if(i<=cfg.sys_nodes) /* Don't pre-pack with user online */ return(false); } /*******************/ /* Compress Packet */ /*******************/ sprintf(tmp2,"%s%s",cfg.temp_dir,ALLFILES); i=external(cmdstr(temp_cmd(),packet,tmp2,NULL) ,ex|EX_WILDCARD); if(!fexist(packet)) { bputs(text[QWKCompressionFailed]); if(i) errormsg(WHERE,ERR_EXEC,cmdstr(temp_cmd(),packet,tmp2,NULL),i); else errorlog("Couldn't compress QWK packet"); return(false); } if(prepack) /* Early return if pre-packing */ return(true); l=flength(packet); sprintf(str,"%s.qwk",cfg.sys_id); bprintf(text[FiFilename],str); bprintf(text[FiFileSize],ultoac(l,tmp)); if(l>0L && cur_cps) i=l/(ulong)cur_cps; else i=0; bprintf(text[FiTransferTime],sectostr(i,tmp)); CRLF; if(!(useron.exempt&FLAG('T')) && i>timeleft) { bputs(text[NotEnoughTimeToDl]); return(false); } if(useron.rest&FLAG('Q')) { sprintf(str,"%s.qwk",cfg.sys_id); dir=opendir(cfg.temp_dir); while(dir!=NULL && (dirent=readdir(dir))!=NULL) { if(!stricmp(str,dirent->d_name)) /* QWK packet */ continue; sprintf(tmp,"%s%s",cfg.temp_dir,dirent->d_name); if(!isdir(tmp)) remove(tmp); } if(dir!=NULL) closedir(dir); } return(true); }