2 Copyright (C) 2001-2006 Ben Kibbey <bjk@luxsci.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <sys/types.h>
42 #ifdef HAVE_SYS_MMAN_H
54 #define _PATH_MAILDIR "/var/mail"
62 #include "../strsep.c"
71 #define MAIL_OPTION_ORDER "smrfa"
72 #define MAIL_OPTION_STRING "Mfrsam"
74 static char options
[6]; /* NULL terminated. */
75 static char *aliasbuf
;
76 static char **strings
;
78 void add_string(char ***, const char *);
79 char *stamp(time_t, const char *);
81 void ui_module_init(int *chainable
)
89 munmap(aliasbuf
, strlen(aliasbuf
));
94 /* Remove characters (rm) from string (str). */
95 static char *stripstr(char *str
, char *rm
)
97 static char buf
[LINE_MAX
];
101 if (rm
== NULL
|| str
== NULL
)
123 /* Return a string of mail aliases for the user. Looks in /etc/aliases (or
124 * whatever was specified at compile-time). The file is read into a buffer
125 * only once (mmap(2)). */
126 static char *mail_aliases(const char *user
, const int multi
)
129 static char aliases
[LINE_MAX
], *p
;
133 char m
[2] = { multi
, '\0' };
138 if ((!aliasbuf
&& firstrun
) || aliasbuf
== MAP_FAILED
)
144 if (stat(ALIAS_FILE
, &st
) == -1)
147 if ((fd
= open(ALIAS_FILE
, O_RDONLY
)) == -1)
150 if ((aliasbuf
= mmap(0, st
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
,
152 warn("%s", "mmap()");
159 for (i
= n
= 0; aliasbuf
[i
]; i
++) {
160 char *last
, *name
, *tmp
;
162 while (aliasbuf
[i
] != '\n')
163 t
[n
++] = aliasbuf
[i
++];
168 if (t
[0] == '#' || t
[0] == '\0')
173 if ((name
= strsep(&last
, ":")) == NULL
)
176 if (strcmp(user
, name
) == 0) {
177 while ((tmp
= strsep(&last
, ",")) != NULL
) {
178 tmp
= stripstr(tmp
, " \n\t");
180 safe_strncat(aliases
, tmp
, sizeof(aliases
));
181 safe_strncat(aliases
, m
, sizeof(aliases
));
187 while ((tmp
= strsep(&last
, ",")) != NULL
) {
188 tmp
= stripstr(tmp
, " \n\t");
190 if (strcmp(user
, tmp
) == 0) {
191 safe_strncat(aliases
, name
, sizeof(aliases
));
192 safe_strncat(aliases
, m
, sizeof(aliases
));
197 if (aliases
[0] == '\0')
200 aliases
[strlen(aliases
) - 1] = '\0';
206 /* Returns a string of forward aliases for the user. Reads ~/.forward if it
207 * exists and is readable. */
208 static char *forwards(const char *dir
, const int multi
)
211 char buf
[LINE_MAX
], *s
;
212 static char buf2
[LINE_MAX
];
214 char m
[2] = { multi
, '\0' };
216 snprintf(buf2
, sizeof(buf2
), "%s/.forward", dir
);
218 if ((fp
= fopen(buf2
, "r")) == NULL
) {
227 while ((s
= fgets(buf
, sizeof(buf
), fp
)) != NULL
) {
231 if (buf
[strlen(buf
) - 1] == '\n')
232 buf
[strlen(buf
) - 1] = '\0';
235 safe_strncat(buf2
, m
, sizeof(buf2
));
237 safe_strncat(buf2
, buf
, sizeof(buf2
));
249 /* /var/mail/username folder size in bytes. */
250 static char *foldersize(struct stat st
)
252 static char str
[33], *p
;
254 snprintf(str
, sizeof(str
), "%lu", (unsigned long) st
.st_size
);
259 /* This is output if the -h command line option is passed to the main program.
261 void ui_module_help()
263 printf(" Mail information [-M (-%s)]:\n", MAIL_OPTION_ORDER
);
264 printf("\t-f forwarding addresses\t");
265 printf("-a mail aliases\n");
266 printf("\t-r folder access (read) time\t");
267 printf("-m folder modification time\n");
268 printf("\t-s folder size\n\n");
271 /* This is the equivalent to main() only without argc and argv available. */
272 int ui_module_exec(char ***s
, const struct passwd
*pw
, const int multi_char
,
273 const int verbose
, char *tf
)
278 char folder
[FILENAME_MAX
];
282 snprintf(folder
, sizeof(folder
), "%s/%s", _PATH_MAILDIR
, pw
->pw_name
);
284 if (stat(folder
, &st
) != -1)
290 add_string(&strings
, (gotstat
) ? foldersize(st
) : "!");
293 add_string(&strings
, (gotstat
) ? stamp(st
.st_atime
, tf
) : "!");
296 add_string(&strings
, (gotstat
) ? stamp(st
.st_mtime
, tf
) : "!");
299 add_string(&strings
, forwards(pw
->pw_dir
, multi_char
));
302 add_string(&strings
, mail_aliases(pw
->pw_name
, multi_char
));
313 char *ui_module_options_init(char **defaults
)
316 return MAIL_OPTION_STRING
;
319 /* Check module option validity. */
320 int ui_module_options(int argc
, char **argv
)
325 while ((opt
= getopt(argc
, argv
, MAIL_OPTION_STRING
)) != -1) {
328 strncpy(options
, MAIL_OPTION_ORDER
, sizeof(options
));
337 warnx("mail: invalid option -- %c", optopt
);