/* * Copyright (C) 1996-8 Michael R. Elkins * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Everything in this file was "borrowed" from gbuffy (by Brandon Long et al.) who "borrowed" from mutt. I take less than no credit for this code, and thanks to the above people for their excellent work. -- mej */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define ISSPACE(c) isspace((unsigned char) c) #define SKIPWS(c) while (*(c) && isspace((unsigned char) *(c))) c++; #define strfcpy(A,B,C) strncpy(A,B,C), *(A+(C)-1)=0 #ifndef TRUE #define TRUE (1) #endif #ifndef FALSE #define FALSE (0) #endif #define BUFFSIZE 256 #ifndef _POSIX_PATH_MAX #define _POSIX_PATH_MAX 255 #endif #define NONULL(x) ((x) ? (x) : "") #if 0 #define D(x) do {printf("%10s | %7d: [debug] ", __FILE__, __LINE__); printf x; fflush(stdout);} while (0) #else #define D(x) ((void) 0) #endif int mail_folder_count(char *path, int force); unsigned long new_cnt, total_cnt; static int mbox_folder_count(char *path, int force); static int maildir_folder_count(char *path, int force); static const char *const Weekdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static const char *const Months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "ERR" }; static size_t file_size; static time_t file_mtime; static int ebiff_utimes(const char *file, struct timeval tvp[2]) { struct utimbuf ut; time_t now; now = time((time_t *) NULL); if (tvp == (struct timeval *)NULL) { ut.actime = now; ut.modtime = now; } else { ut.actime = tvp[0].tv_sec; ut.modtime = tvp[1].tv_sec; } return (utime(file, &ut)); } static void safe_realloc(void **p, size_t siz) { void *r; if (siz == 0) { if (*p) { free(*p); *p = NULL; } return; } if (*p) r = (void *)realloc(*p, siz); else { /* realloc(NULL, nbytes) doesn't seem to work under SunOS 4.1.x */ r = (void *)malloc(siz); } *p = r; } /* Reads an arbitrarily long header field, and looks ahead for continuation * lines. ``line'' must point to a dynamically allocated string; it is * increased if more space is required to fit the whole line. */ static char * read_rfc822_line(FILE * f, char *line, size_t *linelen) { char *buf = line; char ch; size_t offset = 0; for (; 1;) { if (!fgets(buf, *linelen - offset, f) || /* end of file or */ (ISSPACE(*line) && !offset)) { /* end of headers */ *line = 0; return (line); } buf += strlen(buf) - 1; if (*buf == '\n') { /* we did get a full line. remove trailing space */ while (ISSPACE(*buf)) *buf-- = 0; /* we cannot come beyond line's beginning because * it begins with a non-space */ /* check to see if the next line is a continuation line */ if ((ch = fgetc(f)) != ' ' && ch != '\t') { ungetc(ch, f); return (line); /* next line is a separate header field or EOH */ } /* eat tabs and spaces from the beginning of the continuation line */ while ((ch = fgetc(f)) == ' ' || ch == '\t'); ungetc(ch, f); *++buf = ' '; /* string is still terminated because we removed * at least one whitespace char above */ } buf++; offset = buf - line; if (*linelen < offset + BUFFSIZE) { /* grow the buffer */ *linelen += BUFFSIZE; safe_realloc((void **)&line, *linelen); buf = line + offset; } } /* not reached */ } static const char * next_word(const char *s) { while (*s && !ISSPACE(*s)) s++; SKIPWS(s); return s; } static int check_month(const char *s) { int i; for (i = 0; i < 12; i++) if (strncasecmp(s, Months[i], 3) == 0) return (i); return (-1); /* error */ } static int is_day_name(const char *s) { int i; if (!ISSPACE(*(s + 3))) return 0; for (i = 0; i < 7; i++) if (strncasecmp(s, Weekdays[i], 3) == 0) return 1; return 0; } /* * A valid message separator looks like: * * From [ ]