E-Biff 0.3.
Features a new layout, a new icon, and config file support. SVN revision: 830
This commit is contained in:
parent
db2fbd36ad
commit
cb07d706f8
|
@ -0,0 +1,223 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include "epplet.h"
|
||||
|
||||
extern void Epplet_redraw(void);
|
||||
|
||||
#define MAIL_PATH "/var/spool/mail"
|
||||
#define MAIL_PROG "Eterm -t mutt"
|
||||
#define POLL_INTERVAL 2.0
|
||||
#define NOMAIL_IMAGE EROOT "/epplet_icons/nomail.png"
|
||||
#define NEWMAIL_IMAGE EROOT "/epplet_icons/newmail.png"
|
||||
|
||||
#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
|
||||
#define BEGMATCH(a, b) (!strncasecmp((a), (b), (sizeof(b) - 1)))
|
||||
#define NONULL(x) ((x) ? (x) : (""))
|
||||
|
||||
Epplet_gadget close_button, mp_button, help_button, nomail, newmail, label;
|
||||
unsigned long new_cnt, total_cnt;
|
||||
size_t file_size;
|
||||
time_t file_mtime;
|
||||
char *folder_path = NULL, *mailprog = MAIL_PROG, *sound = NULL,
|
||||
*nomail_image = NOMAIL_IMAGE, *newmail_image = NEWMAIL_IMAGE;
|
||||
int mp_pid = 0;
|
||||
int beep = 1;
|
||||
double interval = POLL_INTERVAL;
|
||||
|
||||
static void mailcheck_cb(void *data);
|
||||
static void close_cb(void *data);
|
||||
static void mailprog_cb(void *data);
|
||||
static void help_cb(void *data);
|
||||
static void in_cb(void *data, Window w);
|
||||
static void out_cb(void *data, Window w);
|
||||
static void save_conf(void);
|
||||
static void load_conf(void);
|
||||
static void save_cb(void *data);
|
||||
|
||||
static void
|
||||
mailcheck_cb(void *data)
|
||||
{
|
||||
char label_text[64];
|
||||
|
||||
D(("mailcheck_cb() called.\n"));
|
||||
if ((mbox_folder_count(folder_path, 0)) != 0) {
|
||||
if (new_cnt != 0) {
|
||||
Epplet_gadget_hide(nomail);
|
||||
Epplet_gadget_show(newmail);
|
||||
if (beep) {
|
||||
XBell(Epplet_get_display(), 0);
|
||||
} else if (sound != NULL) {
|
||||
Epplet_run_command(sound);
|
||||
}
|
||||
} else {
|
||||
Epplet_gadget_hide(newmail);
|
||||
Epplet_gadget_show(nomail);
|
||||
}
|
||||
sprintf(label_text, "%lu / %lu", new_cnt, total_cnt);
|
||||
Epplet_change_label(label, label_text);
|
||||
}
|
||||
Epplet_timer(mailcheck_cb, NULL, POLL_INTERVAL, "TIMER");
|
||||
}
|
||||
|
||||
static void
|
||||
close_cb(void *data)
|
||||
{
|
||||
Epplet_unremember();
|
||||
Esync();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
mailprog_cb(void *data)
|
||||
{
|
||||
mp_pid = Epplet_spawn_command(MAIL_PROG);
|
||||
}
|
||||
|
||||
static void
|
||||
help_cb(void *data)
|
||||
{
|
||||
Epplet_show_about("E-Biff");
|
||||
}
|
||||
|
||||
static void
|
||||
in_cb(void *data, Window w)
|
||||
{
|
||||
Epplet_gadget_show(close_button);
|
||||
Epplet_gadget_show(mp_button);
|
||||
Epplet_gadget_show(help_button);
|
||||
}
|
||||
|
||||
static void
|
||||
out_cb(void *data, Window w)
|
||||
{
|
||||
Epplet_gadget_hide(close_button);
|
||||
Epplet_gadget_hide(mp_button);
|
||||
Epplet_gadget_hide(help_button);
|
||||
}
|
||||
|
||||
static void
|
||||
save_conf(void) {
|
||||
|
||||
FILE *fp;
|
||||
char buff[255];
|
||||
static const char *homedir = NULL;
|
||||
|
||||
if (homedir == NULL) {
|
||||
homedir = (getenv("HOME") ? getenv("HOME") : ".");
|
||||
}
|
||||
sprintf(buff, "%s/.ebiffrc", homedir);
|
||||
if ((fp = fopen(buff, "wt")) == NULL) {
|
||||
char err[255];
|
||||
|
||||
sprintf(err, "Unable to open %s for writing -- %s. Config file cannot be saved.\n",
|
||||
buff, strerror(errno));
|
||||
Epplet_dialog_ok(err);
|
||||
return;
|
||||
}
|
||||
fprintf(fp, "mailbox %s\n", folder_path);
|
||||
fprintf(fp, "mailprog %s\n", mailprog);
|
||||
fprintf(fp, "interval %3.1f\n", interval);
|
||||
fprintf(fp, "beep %d\n", beep);
|
||||
fprintf(fp, "no mail image %s\n", nomail_image);
|
||||
fprintf(fp, "new mail image %s\n", newmail_image);
|
||||
if (sound != NULL) {
|
||||
fprintf(fp, "sound %s\n", sound);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static void
|
||||
load_conf(void) {
|
||||
|
||||
FILE *fp;
|
||||
char buff[1024], name[255], *p;
|
||||
unsigned char line = 0;
|
||||
static const char *homedir = NULL;
|
||||
|
||||
if (homedir == NULL) {
|
||||
homedir = (getenv("HOME") ? getenv("HOME") : ".");
|
||||
}
|
||||
sprintf(name, "%s/.ebiffrc", homedir);
|
||||
if ((fp = fopen(name, "rt")) == NULL) {
|
||||
return;
|
||||
}
|
||||
for (; fgets(buff, sizeof(buff), fp);) {
|
||||
line++;
|
||||
p = strchr(buff, '\n');
|
||||
*p = 0;
|
||||
if (BEGMATCH(buff, "mailbox ")) {
|
||||
folder_path = strdup(buff + sizeof("mailbox ") - 1);
|
||||
} else if (BEGMATCH(buff, "mailprog ")) {
|
||||
mailprog = strdup(buff + sizeof("mailprog ") - 1);
|
||||
} else if (BEGMATCH(buff, "interval ")) {
|
||||
sscanf(buff, "%*s %lf", &interval);
|
||||
} else if (BEGMATCH(buff, "beep ")) {
|
||||
sscanf(buff, "%*s %d", &beep);
|
||||
} else if (BEGMATCH(buff, "no mail image ")) {
|
||||
nomail_image = strdup(buff + sizeof("no mail image ") - 1);
|
||||
} else if (BEGMATCH(buff, "new mail image ")) {
|
||||
newmail_image = strdup(buff + sizeof("new mail image ") - 1);
|
||||
} else if (BEGMATCH(buff, "sound ")) {
|
||||
sound = strdup(buff + sizeof("sound ") - 1);
|
||||
} else {
|
||||
char err[255];
|
||||
|
||||
sprintf(err, "Unrecognized identifier at line %d, file %s: %s\n", line, name, buff);
|
||||
Epplet_dialog_ok(err);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int prio;
|
||||
|
||||
prio = getpriority(PRIO_PROCESS, getpid());
|
||||
setpriority(PRIO_PROCESS, getpid(), prio + 10);
|
||||
atexit(save_conf);
|
||||
Epplet_Init("E-Biff", "0.3", "Enlightenment Mailbox Checker Epplet", 3, 3, argc, argv, 0);
|
||||
load_conf();
|
||||
if (folder_path == NULL) {
|
||||
if ((folder_path = getenv("MAIL")) == NULL) {
|
||||
char *username = getenv("LOGNAME");
|
||||
|
||||
if (!username) {
|
||||
username = getenv("USER");
|
||||
if (!username) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
folder_path = (char *) malloc(sizeof(MAIL_PATH "/") + strlen(username) + 1);
|
||||
sprintf(folder_path, MAIL_PATH "/%s", username);
|
||||
D(("Generated folder path of \"%s\"\n", folder_path));
|
||||
}
|
||||
}
|
||||
close_button = Epplet_create_button(NULL, NULL, 2, 2, 0, 0, "CLOSE", 0, NULL, close_cb, NULL);
|
||||
help_button = Epplet_create_button(NULL, NULL, 18, 2, 0, 0, "HELP", 0, NULL, help_cb, NULL);
|
||||
mp_button = Epplet_create_button(NULL, NULL, 34, 2, 0, 0, "CONFIGURE", 0, NULL, mailprog_cb, NULL);
|
||||
|
||||
nomail = Epplet_create_image(2, 3, 44, 30, NOMAIL_IMAGE);
|
||||
newmail = Epplet_create_image(2, 3, 44, 30, NEWMAIL_IMAGE);
|
||||
Epplet_gadget_show(nomail);
|
||||
|
||||
label = Epplet_create_label(6, 34, "- / -", 2);
|
||||
Epplet_gadget_show(label);
|
||||
Epplet_show();
|
||||
|
||||
Epplet_register_focus_in_handler(in_cb, NULL);
|
||||
Epplet_register_focus_out_handler(out_cb, NULL);
|
||||
mailcheck_cb(NULL); /* Set everything up */
|
||||
Epplet_Loop();
|
||||
|
||||
return 0;
|
||||
}
|
Binary file not shown.
|
@ -2,7 +2,7 @@
|
|||
|
||||
bindir = $(EBIN)
|
||||
|
||||
bin_PROGRAMS = E-Load.epplet E-Clock.epplet E-Time.epplet E-Net.epplet E-Cpu.epplet EppletTest.epplet
|
||||
bin_PROGRAMS = E-Load.epplet E-Clock.epplet E-Time.epplet E-Net.epplet E-Cpu.epplet EppletTest.epplet E-Biff.epplet
|
||||
|
||||
E_Load_epplet_SOURCES = E-Load.c
|
||||
E_Load_epplet_DEPENDENCIES = $(top_srcdir)/api/libepplet.la
|
||||
|
@ -28,13 +28,17 @@ EppletTest_epplet_SOURCES = TestEpplet.c
|
|||
EppletTest_epplet_DEPENDENCIES = $(top_srcdir)/api/libepplet.la
|
||||
EppletTest_epplet_LDFLAGS = -rpath $(libdir):$(pkglibdir)
|
||||
|
||||
E_Biff_epplet_SOURCES = E-Biff.c mbox.c
|
||||
E_Biff_epplet_DEPENDENCIES = $(top_srcdir)/api/libepplet.la
|
||||
E_Biff_epplet_LDFLAGS = -rpath $(libdir):$(pkglibdir)
|
||||
|
||||
INCLUDES = -DEBIN=\"$(EBIN)\" -DEROOT=\"$(EROOT)\" -I. -I$(top_srcdir)/api -I$(top_srcdir) -I.. -I$(includedir) -I$(prefix)/include $(X_CFLAGS)
|
||||
LDADD = $(top_builddir)/api/libepplet.la -L$(libdir) -L$(prefix)/lib $(LIBS) $(X_LIBS)
|
||||
|
||||
ABOUT_DOCS = E-Cpu.ABOUT/MAIN E-Cpu.ABOUT/bg.png E-Cpu.ABOUT/aircut3.ttf \
|
||||
E-Clock.ABOUT/MAIN E-Clock.ABOUT/bg.png E-Clock.ABOUT/aircut3.ttf
|
||||
ICONS = E-Load.icon E-Clock.icon E-Net.icon E-Cpu.icon
|
||||
IMAGES = E-Clock-Image.png
|
||||
ICONS = E-Load.icon E-Clock.icon E-Net.icon E-Cpu.icon E-Biff.icon
|
||||
IMAGES = E-Clock-Image.png nomail.png newmail.png
|
||||
|
||||
EXTRA_DIST = ${ICONS} ${ABOUT_DOCS} ${IMAGES}
|
||||
|
||||
|
|
|
@ -0,0 +1,453 @@
|
|||
/*
|
||||
* Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <utime.h>
|
||||
|
||||
#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
|
||||
|
||||
const char *Weekdays[] =
|
||||
{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||
const char *Months[] =
|
||||
{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "ERR"};
|
||||
|
||||
extern unsigned long new_cnt, total_cnt;
|
||||
extern size_t file_size;
|
||||
extern time_t file_mtime;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void
|
||||
safe_free(void **p)
|
||||
{
|
||||
if (*p) {
|
||||
free(*p);
|
||||
*p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
safe_strdup(const char *s)
|
||||
{
|
||||
char *p;
|
||||
size_t l;
|
||||
|
||||
if (!s || !*s)
|
||||
return 0;
|
||||
l = strlen(s) + 1;
|
||||
p = (char *) malloc(l);
|
||||
memcpy(p, s, l);
|
||||
return (p);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void *
|
||||
safe_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (!nmemb || !size)
|
||||
return NULL;
|
||||
p = (void *) calloc(nmemb, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
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) == NULL || /* 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;
|
||||
}
|
||||
|
||||
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 [ <return-path> ] <weekday> <month> <day> <time> [ <timezone> ] <year>
|
||||
*/
|
||||
int
|
||||
is_from(const char *s, char *path, size_t pathlen)
|
||||
{
|
||||
struct tm tm;
|
||||
int yr;
|
||||
|
||||
if (path)
|
||||
*path = 0;
|
||||
|
||||
if (strncmp("From ", s, 5) != 0)
|
||||
return 0;
|
||||
|
||||
s = next_word(s); /* skip over the From part. */
|
||||
if (!*s)
|
||||
return 0;
|
||||
|
||||
if (!is_day_name(s)) {
|
||||
const char *p;
|
||||
size_t len;
|
||||
|
||||
/* looks like we got the return-path, so extract it */
|
||||
if (*s == '"') {
|
||||
/* sometimes we see bogus addresses like
|
||||
* From "/foo/bar baz/"@dumbdar.com Sat Nov 22 15:29:32 PST 1997
|
||||
*/
|
||||
p = s;
|
||||
p++; /* skip over the quote */
|
||||
do {
|
||||
if (!(p = strpbrk(p, "\\\"")))
|
||||
return 0;
|
||||
if (*p == '\\')
|
||||
p += 2;
|
||||
}
|
||||
while (*p != '"');
|
||||
while (*p && !ISSPACE(*p))
|
||||
p++;
|
||||
} else {
|
||||
if ((p = strchr(s, ' ')) == NULL)
|
||||
return 0;
|
||||
}
|
||||
if (path) {
|
||||
len = (size_t) (p - s);
|
||||
if (len + 1 > pathlen)
|
||||
len = pathlen - 1;
|
||||
memcpy(path, s, len);
|
||||
path[len] = 0;
|
||||
}
|
||||
s = p + 1;
|
||||
SKIPWS(s);
|
||||
if (!*s)
|
||||
return 0;
|
||||
|
||||
if (!is_day_name(s)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
s = next_word(s);
|
||||
if (!*s)
|
||||
return 0;
|
||||
|
||||
/* do a quick check to make sure that this isn't really the day of the week.
|
||||
* this could happen when receiving mail from a local user whose login name
|
||||
* is the same as a three-letter abbreviation of the day of the week.
|
||||
*/
|
||||
if (is_day_name(s)) {
|
||||
s = next_word(s);
|
||||
if (!*s)
|
||||
return 0;
|
||||
}
|
||||
/* now we should be on the month. */
|
||||
if ((tm.tm_mon = check_month(s)) < 0)
|
||||
return 0;
|
||||
|
||||
/* day */
|
||||
s = next_word(s);
|
||||
if (!*s)
|
||||
return 0;
|
||||
if (sscanf(s, "%d", &tm.tm_mday) != 1)
|
||||
return 0;
|
||||
|
||||
/* time */
|
||||
s = next_word(s);
|
||||
if (!*s)
|
||||
return 0;
|
||||
|
||||
/* Accept either HH:MM or HH:MM:SS */
|
||||
if (sscanf(s, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 3);
|
||||
else if (sscanf(s, "%d:%d", &tm.tm_hour, &tm.tm_min) == 2)
|
||||
tm.tm_sec = 0;
|
||||
else
|
||||
return 0;
|
||||
|
||||
s = next_word(s);
|
||||
if (!*s)
|
||||
return 0;
|
||||
|
||||
/* timezone? */
|
||||
if (isalpha((unsigned char) *s) || *s == '+' || *s == '-') {
|
||||
s = next_word(s);
|
||||
if (!*s)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* some places have two timezone fields after the time, e.g.
|
||||
* From xxxx@yyyyyyy.fr Wed Aug 2 00:39:12 MET DST 1995
|
||||
*/
|
||||
if (isalpha((unsigned char) *s)) {
|
||||
s = next_word(s);
|
||||
if (!*s)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* year */
|
||||
if (sscanf(s, "%d", &yr) != 1)
|
||||
return 0;
|
||||
tm.tm_year = yr > 1900 ? yr - 1900 : yr;
|
||||
|
||||
tm.tm_isdst = 0;
|
||||
tm.tm_yday = 0;
|
||||
tm.tm_wday = 0;
|
||||
|
||||
/* return (mutt_mktime (&tm, 0)); */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
parse_mime_header(FILE *fp)
|
||||
{
|
||||
static char *buffer = NULL;
|
||||
static size_t buflen = BUFFSIZE;
|
||||
int status = FALSE;
|
||||
int is_new = FALSE;
|
||||
|
||||
if (buffer == NULL)
|
||||
buffer = (char *) malloc(buflen);
|
||||
|
||||
while (*(buffer = read_rfc822_line(fp, buffer, &buflen)) != 0) {
|
||||
if (!strncmp(buffer, "Status:", 7)) {
|
||||
status = TRUE;
|
||||
if (!strchr(buffer, 'R') && !strchr(buffer, 'O')) {
|
||||
new_cnt++;
|
||||
is_new = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (status == FALSE) {
|
||||
new_cnt++;
|
||||
is_new = TRUE;
|
||||
} else {
|
||||
status = FALSE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 0 on no change/failure, 1 on change
|
||||
*/
|
||||
int
|
||||
mbox_folder_count(char *path, int force)
|
||||
{
|
||||
FILE *fp;
|
||||
char buffer[BUFFSIZE];
|
||||
char garbage[BUFFSIZE];
|
||||
int in_header = TRUE;
|
||||
struct stat s;
|
||||
struct timeval t[2];
|
||||
|
||||
D(("mbox_folder_count(%s, %d) called.\n", NONULL(path), force));
|
||||
|
||||
if (path == NULL)
|
||||
return 0;
|
||||
|
||||
if (stat(path, &s) != 0) {
|
||||
D((" -> Unable to stat mailbox.\n"));
|
||||
file_size = 0;
|
||||
file_mtime = 0;
|
||||
return 0;
|
||||
}
|
||||
if (!force && (s.st_size == file_size) && (s.st_mtime == file_mtime)) {
|
||||
D((" -> Mailbox unchanged.\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((s.st_size == 0) || (!S_ISREG(s.st_mode))) {
|
||||
D((" -> Mailbox has zero size or is not a regular file.\n"));
|
||||
if (file_size == 0 && file_mtime == 0 && total_cnt == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
file_size = 0;
|
||||
file_mtime = 0;
|
||||
total_cnt = 0;
|
||||
new_cnt = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((fp = fopen(path, "r")) == NULL) {
|
||||
D((" -> Mailbox cannot be opened for reading.\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if a folder by checking for From as first thing in file */
|
||||
fgets(buffer, sizeof(buffer), fp);
|
||||
if (!is_from(buffer, garbage, sizeof(garbage))) {
|
||||
D((" -> Mailbox does not appear to be in mbox format.\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
total_cnt = 1;
|
||||
new_cnt = 0;
|
||||
file_mtime = s.st_mtime;
|
||||
file_size = s.st_size;
|
||||
|
||||
parse_mime_header(fp);
|
||||
while (fgets(buffer, sizeof(buffer), fp) != 0) {
|
||||
if (is_from(buffer, garbage, sizeof(garbage))) {
|
||||
total_cnt++;
|
||||
parse_mime_header(fp);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
/* Restore the access time of the mailbox for other checking programs */
|
||||
t[0].tv_sec = s.st_atime;
|
||||
t[0].tv_usec = 0;
|
||||
t[1].tv_sec = s.st_mtime;
|
||||
t[1].tv_usec = 0;
|
||||
|
||||
ebiff_utimes(path, t);
|
||||
D((" -> Mailbox check complete. Found %lu new messages of %lu total.\n", new_cnt, total_cnt));
|
||||
return 1;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue