Commit 7dab0a0f authored by rswindell's avatar rswindell
Browse files

Always lock the entire message base when re-writing existing header and index

records (using smb_putmsg) - keeps the index file from being truncated during
the operation (nightly purging of deleted message indexes?) causing corruption.
parent b41e26b2
......@@ -940,6 +940,12 @@ static void pop3_thread(void* arg)
continue;
}
if(!stricmp(buf, "RSET")) {
if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) {
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) locking message base"
,socket, i, smb.last_error);
sockprintf(socket,"-ERR %d locking message base",i);
continue;
}
for(l=0;l<msgs;l++) {
msg.hdr.number=mail[l].number;
if((i=smb_getmsgidx(&smb,&msg))!=SMB_SUCCESS) {
......@@ -966,6 +972,8 @@ static void pop3_thread(void* arg)
smb_unlockmsghdr(&smb,&msg);
smb_freemsgmem(&msg);
}
smb_unlocksmbhdr(&smb);
if(l<msgs)
sockprintf(socket,"-ERR %d messages reset (ERROR: %d)",l,i);
else
......@@ -1126,17 +1134,28 @@ static void pop3_thread(void* arg)
lprintf(LOG_DEBUG,"%04d POP3 message transfer complete (%lu lines)"
,socket,lines_sent);
msg.hdr.attr|=MSG_READ;
msg.idx.attr=msg.hdr.attr;
msg.hdr.netattr|=MSG_SENT;
if((i=smb_lockmsghdr(&smb,&msg))!=SMB_SUCCESS)
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) locking message header #%lu"
,socket, i, smb.last_error, msg.hdr.number);
if((i=smb_putmsg(&smb,&msg))!=SMB_SUCCESS)
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) marking message #%lu as read"
,socket, i, smb.last_error, msg.hdr.number);
smb_unlockmsghdr(&smb,&msg);
if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) {
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) locking message base"
,socket, i, smb.last_error);
} else {
if((i=smb_getmsgidx(&smb,&msg))!=SMB_SUCCESS) {
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) getting message index"
,socket, i, smb.last_error);
} else {
msg.hdr.attr|=MSG_READ;
msg.idx.attr=msg.hdr.attr;
msg.hdr.netattr|=MSG_SENT;
if((i=smb_lockmsghdr(&smb,&msg))!=SMB_SUCCESS)
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) locking message header #%lu"
,socket, i, smb.last_error, msg.hdr.number);
if((i=smb_putmsg(&smb,&msg))!=SMB_SUCCESS)
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) marking message #%lu as read"
,socket, i, smb.last_error, msg.hdr.number);
smb_unlockmsghdr(&smb,&msg);
}
smb_unlocksmbhdr(&smb);
}
}
smb_freemsgmem(&msg);
smb_freemsgtxt(msgtxt);
......@@ -1158,13 +1177,21 @@ static void pop3_thread(void* arg)
lprintf(LOG_INFO,"%04d POP3 %s deleting message #%ld"
,socket, user.alias, msg.hdr.number);
if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) {
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) locking message base"
,socket, i, smb.last_error);
sockprintf(socket,"-ERR %d locking message base",i);
continue;
}
if((i=smb_getmsgidx(&smb,&msg))!=SMB_SUCCESS) {
smb_unlocksmbhdr(&smb);
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) getting message index"
,socket, i, smb.last_error);
sockprintf(socket,"-ERR %d getting message index",i);
continue;
}
if((i=smb_lockmsghdr(&smb,&msg))!=SMB_SUCCESS) {
smb_unlocksmbhdr(&smb);
lprintf(LOG_WARNING,"%04d !POP3 ERROR %d (%s) locking message header #%lu"
,socket, i, smb.last_error, msg.hdr.number);
sockprintf(socket,"-ERR %d locking message header",i);
......@@ -1172,6 +1199,7 @@ static void pop3_thread(void* arg)
}
if((i=smb_getmsghdr(&smb,&msg))!=SMB_SUCCESS) {
smb_unlockmsghdr(&smb,&msg);
smb_unlocksmbhdr(&smb);
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) getting message header #%lu"
,socket, i, smb.last_error, msg.hdr.number);
sockprintf(socket,"-ERR %d getting message header",i);
......@@ -1179,18 +1207,18 @@ static void pop3_thread(void* arg)
}
msg.hdr.attr|=MSG_DELETE;
msg.idx.attr=msg.hdr.attr;
if((i=smb_putmsg(&smb,&msg))!=SMB_SUCCESS) {
smb_unlockmsghdr(&smb,&msg);
smb_freemsgmem(&msg);
if((i=smb_putmsg(&smb,&msg))==SMB_SUCCESS && msg.hdr.auxattr&MSG_FILEATTACH)
delfattach(&scfg,&msg);
smb_unlockmsghdr(&smb,&msg);
smb_unlocksmbhdr(&smb);
smb_freemsgmem(&msg);
if(i!=SMB_SUCCESS) {
lprintf(LOG_ERR,"%04d !POP3 ERROR %d (%s) marking message as read"
, socket, i, smb.last_error);
sockprintf(socket,"-ERR %d marking message for deletion",i);
continue;
}
if(msg.hdr.auxattr&MSG_FILEATTACH)
delfattach(&scfg,&msg);
smb_unlockmsghdr(&smb,&msg);
smb_freemsgmem(&msg);
sockprintf(socket,"+OK");
if(startup->options&MAIL_OPT_DEBUG_POP3)
lprintf(LOG_INFO,"%04d POP3 message deleted", socket);
......@@ -3325,21 +3353,30 @@ BOOL bounce(smb_t* smb, smbmsg_t* msg, char* err, BOOL immediate)
,msg->from
,msg->to_net.addr);
if((i=smb_locksmbhdr(smb))!=SMB_SUCCESS) {
lprintf(LOG_WARNING,"0000 !BOUNCE ERROR %d (%s) locking message base"
,i, smb->last_error);
return(FALSE);
}
if((i=smb_lockmsghdr(smb,msg))!=SMB_SUCCESS) {
smb_unlocksmbhdr(smb);
lprintf(LOG_WARNING,"0000 !BOUNCE ERROR %d (%s) locking message header #%lu"
,i, smb->last_error, msg->hdr.number);
return(FALSE);
}
if((i=smb_putmsg(smb,msg))!=SMB_SUCCESS) {
smb_unlockmsghdr(smb,msg);
smb_unlocksmbhdr(smb);
lprintf(LOG_ERR,"0000 !BOUNCE ERROR %d (%s) incrementing delivery attempt counter"
,i, smb->last_error);
smb_unlockmsghdr(smb,msg);
return(FALSE);
}
if(!immediate && msg->hdr.delivery_attempts<startup->max_delivery_attempts) {
smb_unlockmsghdr(smb,msg);
smb_unlocksmbhdr(smb);
return(TRUE);
}
......@@ -3347,15 +3384,18 @@ BOOL bounce(smb_t* smb, smbmsg_t* msg, char* err, BOOL immediate)
/* Mark original message as deleted */
msg->hdr.attr|=MSG_DELETE;
msg->idx.attr=msg->hdr.attr;
if((i=smb_putmsg(smb,msg))!=SMB_SUCCESS) {
i=smb_putmsg(smb,msg);
smb_unlockmsghdr(smb,msg);
smb_unlocksmbhdr(smb);
if(i!=SMB_SUCCESS) {
lprintf(LOG_ERR,"0000 !BOUNCE ERROR %d (%s) deleting message"
,i, smb->last_error);
smb_unlockmsghdr(smb,msg);
return(FALSE);
}
if(msg->hdr.auxattr&MSG_FILEATTACH)
delfattach(&scfg,msg);
smb_unlockmsghdr(smb,msg);
if(msg->from_agent!=AGENT_PERSON /* don't bounce 'bounce messages' */
|| (msg->idx.from==0 && msg->from_net.type==NET_NONE)
......@@ -3911,20 +3951,33 @@ static void sendmail_thread(void* arg)
}
lprintf(LOG_DEBUG,"%04d SEND message transfer complete (%lu lines)", sock, lines);
msg.hdr.attr|=MSG_DELETE;
msg.idx.attr=msg.hdr.attr;
msg.hdr.netattr&=~MSG_INTRANSIT;
if((i=smb_lockmsghdr(&smb,&msg))!=SMB_SUCCESS)
lprintf(LOG_ERR,"%04d !SEND ERROR %d (%s) locking message header #%lu"
,sock
,i, smb.last_error, msg.hdr.number);
if((i=smb_putmsg(&smb,&msg))!=SMB_SUCCESS)
lprintf(LOG_ERR,"%04d !SEND ERROR %d (%s) deleting message #%lu"
,sock
,i, smb.last_error, msg.hdr.number);
if(msg.hdr.auxattr&MSG_FILEATTACH)
delfattach(&scfg,&msg);
smb_unlockmsghdr(&smb,&msg);
/* Now lets mark this message for deletion without corrupting the index */
if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS)
lprintf(LOG_ERR,"0000 !SEND ERROR %d (%s) locking message base"
,i, smb.last_error);
else {
/* We need to find the index again incase the offset moved (maintenance?) */
if((i=smb_getmsgidx(&smb,&msg))!=SMB_SUCCESS) {
lprintf(LOG_ERR,"0000 !SEND ERROR %d (%s) getting message index #%lu"
,i, smb.last_error, mail[l].number);
} else {
msg.hdr.attr|=MSG_DELETE;
msg.idx.attr=msg.hdr.attr;
msg.hdr.netattr&=~MSG_INTRANSIT;
if((i=smb_lockmsghdr(&smb,&msg))!=SMB_SUCCESS)
lprintf(LOG_ERR,"%04d !SEND ERROR %d (%s) locking message header #%lu"
,sock
,i, smb.last_error, msg.hdr.number);
if((i=smb_putmsg(&smb,&msg))!=SMB_SUCCESS)
lprintf(LOG_ERR,"%04d !SEND ERROR %d (%s) deleting message #%lu"
,sock
,i, smb.last_error, msg.hdr.number);
if(msg.hdr.auxattr&MSG_FILEATTACH)
delfattach(&scfg,&msg);
smb_unlockmsghdr(&smb,&msg);
}
smb_unlocksmbhdr(&smb);
}
/* QUIT */
sockprintf(sock,"QUIT");
......
......@@ -308,7 +308,7 @@ void sbbs_t::readmail(uint usernumber, int which)
smb_freemsgmem(&msg);
msg.total_hfields=0;
msg.idx.offset=0; /* Search by number */
if(!smb_locksmbhdr(&smb)) { /* Lock the entire base */
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;
......@@ -403,12 +403,16 @@ void sbbs_t::readmail(uint usernumber, int which)
smb_freemsgmem(&msg);
msg.total_hfields=0;
msg.idx.offset=0;
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); }
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)) {
......@@ -425,13 +429,17 @@ void sbbs_t::readmail(uint usernumber, int which)
smb_freemsgmem(&msg);
msg.total_hfields=0;
msg.idx.offset=0;
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); }
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;
......@@ -457,13 +465,17 @@ void sbbs_t::readmail(uint usernumber, int which)
smb_freemsgmem(&msg);
msg.total_hfields=0;
msg.idx.offset=0;
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); }
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':
......@@ -523,11 +535,15 @@ void sbbs_t::readmail(uint usernumber, int which)
smb_freemsgmem(&msg);
msg.total_hfields=0;
msg.idx.offset=0;
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); }
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++)
......
......@@ -716,22 +716,25 @@ int sbbs_t::scanposts(uint subnum, long mode, char *find)
smb_freemsgmem(&msg);
msg.total_hfields=0;
msg.idx.offset=0;
if(loadmsg(&msg,msg.idx.number)) {
msg.idx.attr^=MSG_DELETE;
msg.hdr.attr=msg.idx.attr;
if((i=smb_putmsg(&smb,&msg))!=0)
errormsg(WHERE,ERR_WRITE,smb.file,i);
smb_unlockmsghdr(&smb,&msg);
if(i==0 && msg.idx.attr&MSG_DELETE) {
sprintf(str,"%s removed post from %s %s"
,useron.alias
,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname);
logline("P-",str);
if(!stricmp(cfg.sub[subnum]->misc&SUB_NAME
? useron.name : useron.alias, msg.from))
useron.posts=(ushort)adjustuserrec(&cfg,useron.number
,U_POSTS,5,-1);
}
if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */
if(loadmsg(&msg,msg.idx.number)) {
msg.idx.attr^=MSG_DELETE;
msg.hdr.attr=msg.idx.attr;
if((i=smb_putmsg(&smb,&msg))!=0)
errormsg(WHERE,ERR_WRITE,smb.file,i);
smb_unlockmsghdr(&smb,&msg);
if(i==0 && msg.idx.attr&MSG_DELETE) {
sprintf(str,"%s removed post from %s %s"
,useron.alias
,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname);
logline("P-",str);
if(!stricmp(cfg.sub[subnum]->misc&SUB_NAME
? useron.name : useron.alias, msg.from))
useron.posts=(ushort)adjustuserrec(&cfg,useron.number
,U_POSTS,5,-1);
}
}
smb_unlocksmbhdr(&smb);
}
domsg=1;
if((cfg.sys_misc&SM_SYSVDELM // anyone can view delete msgs
......@@ -906,11 +909,14 @@ int sbbs_t::scanposts(uint subnum, long mode, char *find)
smb_freemsgmem(&msg);
msg.total_hfields=0;
msg.idx.offset=0;
if(loadmsg(&msg,msg.idx.number)) {
msg.hdr.attr=msg.idx.attr=i;
if((i=smb_putmsg(&smb,&msg))!=0)
errormsg(WHERE,ERR_WRITE,smb.file,i);
smb_unlockmsghdr(&smb,&msg);
if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */
if(loadmsg(&msg,msg.idx.number)) {
msg.hdr.attr=msg.idx.attr=i;
if((i=smb_putmsg(&smb,&msg))!=0)
errormsg(WHERE,ERR_WRITE,smb.file,i);
smb_unlockmsghdr(&smb,&msg);
}
smb_unlocksmbhdr(&smb);
}
break;
case 'E': /* edit last post */
......@@ -928,18 +934,21 @@ int sbbs_t::scanposts(uint subnum, long mode, char *find)
smb_freemsgmem(&msg);
msg.total_hfields=0;
msg.idx.offset=0;
if(!loadmsg(&msg,msg.idx.number)) {
errormsg(WHERE,ERR_READ,smb.file,msg.idx.number);
break;
}
sprintf(str,text[DeletePostQ],msg.hdr.number,msg.subj);
if(movemsg(&msg,subnum) && yesno(str)) {
msg.idx.attr|=MSG_DELETE;
msg.hdr.attr=msg.idx.attr;
if((i=smb_putmsg(&smb,&msg))!=0)
errormsg(WHERE,ERR_WRITE,smb.file,i);
if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */
if(!loadmsg(&msg,msg.idx.number)) {
errormsg(WHERE,ERR_READ,smb.file,msg.idx.number);
break;
}
sprintf(str,text[DeletePostQ],msg.hdr.number,msg.subj);
if(movemsg(&msg,subnum) && yesno(str)) {
msg.idx.attr|=MSG_DELETE;
msg.hdr.attr=msg.idx.attr;
if((i=smb_putmsg(&smb,&msg))!=0)
errormsg(WHERE,ERR_WRITE,smb.file,i);
}
smb_unlockmsghdr(&smb,&msg);
}
smb_unlockmsghdr(&smb,&msg);
smb_unlocksmbhdr(&smb);
break;
case 'Q':
......@@ -963,12 +972,15 @@ int sbbs_t::scanposts(uint subnum, long mode, char *find)
smb_freemsgmem(&msg);
msg.total_hfields=0;
msg.idx.offset=0;
if(loadmsg(&msg,msg.idx.number)) {
msg.idx.attr|=MSG_VALIDATED;
msg.hdr.attr=msg.idx.attr;
if((i=smb_putmsg(&smb,&msg))!=0)
errormsg(WHERE,ERR_WRITE,smb.file,i);
smb_unlockmsghdr(&smb,&msg);
if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */
if(loadmsg(&msg,msg.idx.number)) {
msg.idx.attr|=MSG_VALIDATED;
msg.hdr.attr=msg.idx.attr;
if((i=smb_putmsg(&smb,&msg))!=0)
errormsg(WHERE,ERR_WRITE,smb.file,i);
smb_unlockmsghdr(&smb,&msg);
}
smb_unlocksmbhdr(&smb);
}
break;
default:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment