]> git.ipfire.org Git - thirdparty/bash.git/blame - CWRU/maildir-patch
Imported from ../bash-2.05.tar.gz.
[thirdparty/bash.git] / CWRU / maildir-patch
CommitLineData
28ef6c31
JA
1# DP: From: Miquel van Smoorenburg <miquels@cistron.nl>
2# DP: A patch that adds support for Maildir type mailboxes.
3
4--- ./mailcheck.c.orig Wed Feb 4 21:30:33 1998
5+++ ./mailcheck.c Sun Nov 14 15:35:07 1999
6@@ -21,8 +21,10 @@
7 #include "config.h"
8
9 #include <stdio.h>
10+#include <errno.h>
11 #include "bashtypes.h"
12 #include "posixstat.h"
13+#include "posixdir.h"
14 #ifndef _MINIX
15 # include <sys/param.h>
16 #endif
17@@ -37,6 +39,8 @@
18 #include "mailcheck.h"
19 #include <tilde/tilde.h>
20
21+#include "mailstat.c"
22+
23 #ifndef NOW
24 #define NOW ((time_t)time ((time_t *)0))
25 #endif
26@@ -131,7 +135,7 @@
27 struct stat finfo;
28
29 file = mailfiles[i]->name;
30- if (stat (file, &finfo) == 0)
31+ if (mailstat (file, &finfo) == 0)
32 {
33 mailfiles[i]->access_time = finfo.st_atime;
34 mailfiles[i]->mod_time = finfo.st_mtime;
35@@ -155,7 +159,7 @@
36 i = find_mail_file (filename);
37 if (i >= 0)
38 {
39- if (stat (filename, &finfo) == 0)
40+ if (mailstat (filename, &finfo) == 0)
41 {
42 mailfiles[i]->mod_time = finfo.st_mtime;
43 mailfiles[i]->access_time = finfo.st_atime;
44@@ -221,7 +225,7 @@
45 file = mailfiles[i]->name;
46 mtime = mailfiles[i]->mod_time;
47
48- if ((stat (file, &finfo) == 0) && (finfo.st_size > 0))
49+ if ((mailstat (file, &finfo) == 0) && (finfo.st_size > 0))
50 return (mtime != finfo.st_mtime);
51
52 return (0);
53@@ -239,7 +243,7 @@
54 file = mailfiles[i]->name;
55 atime = mailfiles[i]->access_time;
56
57- if ((stat (file, &finfo) == 0) && (finfo.st_size > 0))
58+ if ((mailstat (file, &finfo) == 0) && (finfo.st_size > 0))
59 return (atime != finfo.st_atime);
60
61 return (0);
62@@ -257,7 +261,7 @@
63 file = mailfiles[i]->name;
64 size = mailfiles[i]->file_size;
65
66- return ((stat (file, &finfo) == 0) && (finfo.st_size > size));
67+ return ((mailstat (file, &finfo) == 0) && (finfo.st_size > size));
68 }
69
70 /* Take an element from $MAILPATH and return the portion from
71
72
73diff -ruN bash-2.01.1.b4/mailstat.c bash-2.01.1/mailstat.c
74--- bash-2.01.1.b4/mailstat.c Thu Jan 1 01:00:00 1970
75+++ bash-2.01.1/mailstat.c Wed Jun 2 12:05:04 1999
76@@ -0,0 +1,98 @@
77+/*
78+ * Stat a file. If it's a maildir, check all messages
79+ * in the maildir and present the grand total as a file.
80+ * The fields in the 'struct stat' are from the mail directory.
81+ * The following fields are emulated:
82+ *
83+ * st_nlink always 1
84+ * st_size total number of bytes in all files
85+ * st_blocks total number of messages
86+ * st_atime access time of newest file in maildir
87+ * st_mtime modify time of newest file in maildir
88+ * st_mode S_IFDIR changed to S_IFREG
89+ *
90+ * This is good enough for most mail-checking applications.
91+ */
92+int
93+mailstat(char *path, struct stat *st)
94+{
95+ DIR *dd;
96+ struct dirent *fn;
97+ struct stat st_ret, st_tmp;
98+ static struct stat st_new_last, st_ret_last;
99+ char dir[PATH_MAX * 2];
100+ char file[PATH_MAX * 2];
101+ int i, l;
102+ time_t atime = 0, mtime = 0;
103+
104+ /* First see if it's a directory. */
105+ if ((i = stat(path, st)) != 0 || !S_ISDIR(st->st_mode))
106+ return i;
107+ if (strlen(path) > sizeof(dir) - 5) {
108+ errno = ENAMETOOLONG;
109+ return -1;
110+ }
111+
112+ st_ret = *st;
113+ st_ret.st_nlink = 1;
114+ st_ret.st_size = 0;
115+ st_ret.st_blocks = 0;
116+ st_ret.st_mode &= ~S_IFDIR;
117+ st_ret.st_mode |= S_IFREG;
118+
119+ /* See if cur/ is present */
120+ sprintf(dir, "%s/cur", path);
121+ if (stat(dir, &st_tmp) || !S_ISDIR(st_tmp.st_mode)) return 0;
122+ st_ret.st_atime = st_tmp.st_atime;
123+
124+ /* See if tmp/ is present */
125+ sprintf(dir, "%s/tmp", path);
126+ if (stat(dir, &st_tmp) || !S_ISDIR(st_tmp.st_mode)) return 0;
127+ st_ret.st_mtime = st_tmp.st_mtime;
128+
129+ /* And new/ */
130+ sprintf(dir, "%s/new", path);
131+ if (stat(dir, &st_tmp) || !S_ISDIR(st_tmp.st_mode)) return 0;
132+ st_ret.st_mtime = st_tmp.st_mtime;
133+
134+ /* Optimization - if new/ didn't change, nothing else did. */
135+ if (st_tmp.st_dev == st_new_last.st_dev &&
136+ st_tmp.st_ino == st_new_last.st_ino &&
137+ st_tmp.st_atime == st_new_last.st_atime &&
138+ st_tmp.st_mtime == st_new_last.st_mtime) {
139+ *st = st_ret_last;
140+ return 0;
141+ }
142+ st_new_last = st_tmp;
143+
144+ /* Loop over new/ and cur/ */
145+ for (i = 0; i < 2; i++) {
146+ sprintf(dir, "%s/%s", path, i ? "cur" : "new");
147+ sprintf(file, "%s/", dir);
148+ l = strlen(file);
149+ if ((dd = opendir(dir)) == NULL)
150+ return 0;
151+ while ((fn = readdir(dd)) != NULL) {
152+ if (fn->d_name[0] == '.' ||
153+ strlen(fn->d_name) + l >= sizeof(file))
154+ continue;
155+ strcpy(file + l, fn->d_name);
156+ if (stat(file, &st_tmp) != 0)
157+ continue;
158+ st_ret.st_size += st_tmp.st_size;
159+ st_ret.st_blocks++;
160+ if (st_tmp.st_atime != st_tmp.st_mtime &&
161+ st_tmp.st_atime > atime)
162+ atime = st_tmp.st_atime;
163+ if (st_tmp.st_mtime > mtime)
164+ mtime = st_tmp.st_mtime;
165+ }
166+ closedir(dd);
167+ }
168+
169+ if (atime) st_ret.st_atime = atime;
170+ if (mtime) st_ret.st_mtime = mtime;
171+
172+ *st = st_ret_last = st_ret;
173+ return 0;
174+}
175