#include <popper.h>
RCSID("$Id$");
static const char standard_error[] =
"Error error updating primary drop. Mailbox unchanged";
int
pop_updt (POP *p)
{
FILE * md;
int mfd;
char buffer[BUFSIZ];
MsgInfoList * mp;
int msg_num;
int status_written;
int nchar;
long offset;
int blank_line;
#ifdef DEBUG
if (p->debug) {
pop_log(p,POP_DEBUG,"Performing maildrop update...");
pop_log(p,POP_DEBUG,"Checking to see if all messages were deleted");
}
#endif
if(IS_MAILDIR(p))
return pop_maildir_update(p);
if (p->msgs_deleted == p->msg_count) {
ftruncate ((int)fileno(p->drop),0);
fclose(p->drop) ;
return (POP_SUCCESS);
}
#ifdef DEBUG
if (p->debug)
pop_log(p,POP_DEBUG,"Opening mail drop \"%s\"",p->drop_name);
#endif
if ((mfd = open(p->drop_name,O_RDWR|O_CREAT,0600)) == -1 ||
(md = fdopen(mfd,"r+")) == NULL) {
return pop_msg(p,POP_FAILURE,standard_error);
}
if ( flock(mfd, LOCK_EX) == -1 ) {
fclose(md) ;
return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop,
strerror(errno));
}
offset = lseek((int)fileno(p->drop),0,SEEK_END) ;
while ((nchar=read(mfd,buffer,BUFSIZ)) > 0)
if ( nchar != write((int)fileno(p->drop),buffer,nchar) ) {
nchar = -1;
break ;
}
if ( nchar != 0 ) {
fclose(md) ;
ftruncate((int)fileno(p->drop),(int)offset) ;
fclose(p->drop) ;
return pop_msg(p,POP_FAILURE,standard_error);
}
rewind(md);
lseek(mfd,0,SEEK_SET);
ftruncate(mfd,0) ;
rewind(p->drop);
lseek((int)fileno(p->drop),0,SEEK_SET);
#ifdef DEBUG
if (p->debug)
pop_log(p,POP_DEBUG,"Creating new maildrop \"%s\" from \"%s\"",
p->drop_name,p->temp_drop);
#endif
for (msg_num = 0; msg_num < p->msg_count; ++msg_num) {
int doing_body;
mp = &p->mlp[msg_num];
if (mp->flags & DEL_FLAG) {
#ifdef DEBUG
if(p->debug)
pop_log(p,POP_DEBUG,
"Message %d flagged for deletion.",mp->number);
#endif
continue;
}
fseek(p->drop,mp->offset,0);
#ifdef DEBUG
if(p->debug)
pop_log(p,POP_DEBUG,"Copying message %d.",mp->number);
#endif
blank_line = 1;
for(status_written = doing_body = 0 ;
fgets(buffer,MAXMSGLINELEN,p->drop);) {
if (doing_body == 0) {
if (strncasecmp(buffer,"Status:",7) == 0) {
if (mp->flags & RETR_FLAG)
fputs("Status: RO\n",md);
else
fputs(buffer, md);
status_written++;
continue;
}
if (*buffer == '\n') {
doing_body = 1;
if (status_written == 0) {
if (mp->flags & RETR_FLAG)
fputs("Status: RO\n\n",md);
else
fputs("Status: U\n\n",md);
}
else fputs ("\n", md);
continue;
}
fputs (buffer, md);
}
else {
if (blank_line && strncmp(buffer,"From ",5) == 0) break;
fputs (buffer, md);
blank_line = (*buffer == '\n');
}
}
}
fflush(md) ;
if (ferror(md)) {
ftruncate(mfd,0) ;
fclose(md) ;
fclose(p->drop) ;
return pop_msg(p,POP_FAILURE,standard_error);
}
lseek((int)fileno(p->drop),offset,SEEK_SET);
while((nchar=read((int)fileno(p->drop),buffer,BUFSIZ)) > 0)
if ( nchar != write(mfd,buffer,nchar) ) {
nchar = -1;
break ;
}
if ( nchar != 0 ) {
ftruncate(mfd,0) ;
fclose(md) ;
fclose(p->drop) ;
return pop_msg(p,POP_FAILURE,standard_error);
}
fclose(md);
ftruncate((int)fileno(p->drop),0);
fclose(p->drop);
return(pop_quit(p));
}