#include "process.h" #include "lock_maildrop.h" #include "rw.h" #include "md5.h" #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif static struct mail * mails; static int number_mails; extern const char * tmp_dir; void get_stats(long * msg, long * size) { long s = 0, m = 0; int i; for (i=0;i= number_mails || mails[num-1].deleted==1) { write_line(fd,"-ERR no such message\r\n"); return; } snprintf(line,sizeof(line),"+OK %u %ld\r\n",num,mails[num-1].adjsize); write_line(fd,line); } void do_list(int fd, char * line) { unsigned int msg_num = 0; if (sscanf(line+5,"%u",&msg_num)!=1) { list_all(fd); } else { list_msg(fd,msg_num); } } static void print_msg(int fd, unsigned int msg_num) { char line[MAXLINE+1]; int done = 0; char * ptr; FILE * f = fopen( mails[msg_num].filename, "a+b" ); if (!f) { /* print some kind of warning */ syslog( LOG_ERR, "Failed to open tmp file `%s': %s", mails[msg_num].filename, strerror(errno)); return; } rewind(f); line[0] = 0; fgets(line,MAXLINE,f); while (!feof(f)) { if ((line[0]=='\n' || line[0]=='\r') && !done) { write_line(fd,"\r\n"); done = 1; } else { ptr = strchr(line, '\r'); if (ptr == NULL) ptr = strchr(line, '\n'); if (ptr != NULL) ptr[0] = 0; if (line[0] == '.') write_line(fd, "."); write_line(fd, line); write_line(fd, "\r\n"); } fgets(line,MAXLINE,f); } fclose( f ); } void retrieve_msg(int fd, char * line) { unsigned int msg_num; if (sscanf(line+5,"%u",&msg_num)!=1) { write_line(fd,"-ERR invalid arguments\r\n"); return; } if (msg_num<1 || (msg_num-1) >= number_mails || mails[msg_num-1].deleted==1) { write_line(fd,"-ERR no such message\r\n"); return; } write_line(fd,"+OK\r\n"); print_msg(fd,msg_num-1); write_line(fd,".\r\n"); } void show_top_msg(int fd, char * l) { unsigned int msg_num, lines, i; char line[MAXLINE+1]; char * ptr; FILE *f; if (sscanf(l+4,"%u %u",&msg_num,&lines)!=2) { write_line(fd,"-ERR invalid arguments\r\n"); return; } if (msg_num<1 || (msg_num-1) >= number_mails || mails[msg_num-1].deleted==1) { write_line(fd,"-ERR no such message\r\n"); return; } write_line(fd,"+OK\r\n"); f = fopen( mails[msg_num-1].filename, "a+b" ); if (!f) { /* throw some kind of warning */ syslog( LOG_ERR, "Failed to open tmp file `%s': %s", mails[msg_num].filename, strerror(errno)); return; } rewind( f ); line[0] = 0; fgets(line,MAXLINE,f); while ((line[0]!='\n' && line[0]!='\r') && !feof(f)) { ptr = strchr(line, '\r'); if (ptr == NULL) ptr = strchr(line, '\n'); if (ptr != NULL) ptr[0] = 0; if (line[0] == '.') write_line(fd, "."); write_line(fd, line); write_line(fd, "\r\n"); fgets(line,MAXLINE,f); } if (!feof(f)) { write_line(fd,"\r\n"); fgets(line,MAXLINE,f); for (i=0;i= number_mails) { write_line(fd,"-ERR no such message\r\n"); return; } mails[msg_num-1].deleted = 1; write_line(fd,"+OK\r\n"); } void reset_msg(void) { int i; for (i=0;i0) { mails[number_mails-1].size = ftell(fTmp); mails[number_mails-1].adjsize = mails[number_mails-1].size + adj; fclose( fTmp ); } adj = 0; number_mails++; mails = realloc(mails,number_mails*sizeof(struct mail)); if (mails==NULL) { return 0; } memset( mails[number_mails-1].filename, '\0', sizeof(mails[number_mails-1].filename)); snprintf( mails[number_mails-1].filename, sizeof(mails[number_mails-1].filename), "%s/.akpop3d_%u_%u_XXXXXX", tmp_dir, getpid(), rand()); iTmpFile = mkstemp( mails[number_mails-1].filename ); if (iTmpFile == -1) { syslog(LOG_ERR, "Failed to open tmp file `%s': %s", mails[number_mails-1].filename, strerror(errno)); return(0); } close( iTmpFile ); fTmp = fopen( mails[number_mails-1].filename, "w+b" ); if ( !fTmp ) { syslog( LOG_ERR, "Failed to open tmp file `%s': %s", mails[number_mails-1].filename, strerror(errno)); return( 0 ); } mails[number_mails-1].deleted = 0; } fputs(line,fTmp); fgets(line,MAXLINE,f); if (strchr(line, '\r') != NULL) { had_cr_or_nl = 1; } else if (strchr(line, '\n') != NULL) { had_cr_or_nl = 1; adj++; } else { had_cr_or_nl = 0; } } unlock_fd(fileno(f)); fclose(f); fputs(line,fTmp); mails[number_mails-1].size = ftell(fTmp); mails[number_mails-1].adjsize = mails[number_mails-1].size + adj; fclose( fTmp ); return 1; } static void fcopy(FILE * f1, FILE * f2) { char line[MAXLINE+1]; fgets(line,MAXLINE,f2); while (!feof(f2)) { fputs(line,f1); fgets(line,MAXLINE,f2); } } void do_update(char * maildrop) { int i; FILE * f = fopen(maildrop,"w"); if (f==NULL) { syslog(LOG_ERR,"%s: %s: %s","failed to write to maildrop",maildrop,strerror(errno)); return; } lock_fd(fileno(f)); for (i=0;i number_mails) || (mails[msgnum-1].deleted)) { write_line(fd, "-ERR no such message\r\n"); return; } write_line(fd, "+OK "); output_uidl(fd, msgnum-1); } else { write_line(fd, "+OK\r\n"); for (msgnum=0;msgnum