#include #include #include #include #include #include "globals.h" #include "mbox.h" int count( struct mbox_struct * mb ) { FILE * f = 0; /* Usually the e-mails are wrapped at most at column 79 * This length will speed things up */ char line[81] = ""; int ctotal = 0; int cnew = 0; int status_line; if ( (f = fopen(mb->file, "r")) == NULL ) { return(-1); } while ( fgets(line, 80, f) ) { if (!strncmp(line, "From ", 5)) { ++ctotal; ++cnew; status_line = 0; } else if ( ! status_line ) { if ( !strncmp(line, "Status: ", 8) ) { status_line = 1; if (mb->flags & FLAG_UNREAD_AS_NEW) { if (!strncmp(line, "Status: RO", 10)) --cnew; } else if (!strncmp(line, "Status: R", 9)) { --cnew; } } } while ( !strchr(line, '\n') && fgets(line, 80, f) ) { } } fclose(f); if ( (mb->cnew != cnew) && (cnew != 0) ) { pthread_mutex_lock(&mb->mutex); mb->flags |= FLAG_ARRIVED; pthread_mutex_unlock(&mb->mutex); } mb->ctotal = ctotal; mb->cnew = cnew; return(0); } void mbox_handle( struct mbox_struct * mb ) { struct stat stat_buf; /* Since we never really intend to quit this function, * all "global" stuff may go on the stack here */ time_t mod_time = 0; off_t last_size = 0; if ( ! strlen(mb->file) ) { printf("asmail: mbox_handle: no mailbox file specified.\n"); mb->status = STAT_FAIL; signal_update(); pthread_exit(NULL); } while (1) { mb->status |= STAT_RUN; signal_update(); if ( stat(mb->file, &stat_buf) ) { /* Yes, we have to keep trying. The mailbox * may be on a filesystem that experiences * problems, like NFS. */ printf("asmail: mbox_handle: stat (%s) failed.\n", mb->file); mb->status = STAT_FAIL; signal_update(); } else { /* It seems that mod_time is not quite a reliable * source of file modification check. Let's try * to use other sources of information too. */ if ( ( stat_buf.st_ctime != mod_time ) || ( stat_buf.st_size != last_size ) ) { mod_time = stat_buf.st_ctime; last_size = stat_buf.st_size; if (count(mb)) { mb->status = STAT_FAIL; signal_update(); } else { mb->status = STAT_IDLE; if ( mb->cnew > 0) mb->mail = MAIL_NEW; else if ( mb->ctotal > 0 ) mb->mail = MAIL_OLD; else mb->mail = MAIL_NONE; signal_update(); } } else { mb->status = STAT_IDLE; signal_update(); } } sleep_check(mb->update); } }