]>
Commit | Line | Data |
---|---|---|
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 | ||
73 | diff -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 |