e82cfd73a27e9c29001aeac3b0ed687aba0c223d
2 Copyright (C) 2001-2011 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 02110-1301 USA
25 #include <sys/types.h>
42 #ifdef HAVE_SYS_MMAN_H
54 #define _PATH_MAILDIR "/var/mail"
62 #include "../strsep.c"
69 #define MAIL_OPTION_ORDER "smrfa"
70 #define MAIL_OPTION_STRING "Mfrsam"
72 static char options
[6]; /* NULL terminated. */
73 static char *aliasbuf
;
74 static char **strings
;
76 void add_string(char ***, const char *);
77 char *stamp(time_t, const char *);
78 char *safe_strncat(char *, const char *, size_t);
80 void ui_module_init(int *chainable
)
88 munmap(aliasbuf
, strlen(aliasbuf
));
93 /* Remove characters (rm) from string (str). */
94 static char *stripstr(char *str
, char *rm
)
96 static char buf
[LINE_MAX
];
100 if (rm
== NULL
|| str
== NULL
)
122 /* Return a string of mail aliases for the user. Looks in /etc/aliases (or
123 * whatever was specified at compile-time). The file is read into a buffer
124 * only once (mmap(2)). */
125 static char *mail_aliases(const char *user
, const int multi
)
128 static char aliases
[LINE_MAX
], *p
;
132 char m
[2] = { multi
, '\0' };
137 if ((!aliasbuf
&& firstrun
) || aliasbuf
== MAP_FAILED
)
143 if (stat(ALIAS_FILE
, &st
) == -1)
146 if ((fd
= open(ALIAS_FILE
, O_RDONLY
)) == -1)
149 if ((aliasbuf
= mmap(0, st
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
,
151 warn("%s", "mmap()");
158 for (i
= n
= 0; aliasbuf
[i
]; i
++) {
159 char *last
, *name
, *tmp
;
161 while (aliasbuf
[i
] != '\n')
162 t
[n
++] = aliasbuf
[i
++];
167 if (t
[0] == '#' || t
[0] == '\0')
172 if ((name
= strsep(&last
, ":")) == NULL
)
175 if (strcmp(user
, name
) == 0) {
176 while ((tmp
= strsep(&last
, ",")) != NULL
) {
177 tmp
= stripstr(tmp
, " \n\t");
179 safe_strncat(aliases
, tmp
, sizeof(aliases
));
180 safe_strncat(aliases
, m
, sizeof(aliases
));
186 while ((tmp
= strsep(&last
, ",")) != NULL
) {
187 tmp
= stripstr(tmp
, " \n\t");
189 if (strcmp(user
, tmp
) == 0) {
190 safe_strncat(aliases
, name
, sizeof(aliases
));
191 safe_strncat(aliases
, m
, sizeof(aliases
));
196 if (aliases
[0] == '\0')
199 aliases
[strlen(aliases
) - 1] = '\0';
205 /* Returns a string of forward aliases for the user. Reads ~/.forward if it
206 * exists and is readable. */
207 static char *forwards(const char *dir
, const int multi
)
210 char buf
[LINE_MAX
], *s
;
211 static char buf2
[LINE_MAX
];
213 char m
[2] = { multi
, '\0' };
215 snprintf(buf2
, sizeof(buf2
), "%s/.forward", dir
);
217 if ((fp
= fopen(buf2
, "r")) == NULL
) {
226 while ((s
= fgets(buf
, sizeof(buf
), fp
)) != NULL
) {
230 if (buf
[strlen(buf
) - 1] == '\n')
231 buf
[strlen(buf
) - 1] = '\0';
234 safe_strncat(buf2
, m
, sizeof(buf2
));
236 safe_strncat(buf2
, buf
, sizeof(buf2
));
248 /* /var/mail/username folder size in bytes. */
249 static char *foldersize(struct stat st
)
251 static char str
[33], *p
;
253 snprintf(str
, sizeof(str
), "%lu", (unsigned long) st
.st_size
);
258 /* This is output if the -h command line option is passed to the main program.
260 void ui_module_help()
262 printf(" Mail information [-M (-%s)]:\n", MAIL_OPTION_ORDER
);
263 printf("\t-f forwarding addresses\t");
264 printf("-a mail aliases\n");
265 printf("\t-r folder access (read) time\t");
266 printf("-m folder modification time\n");
267 printf("\t-s folder size\n\n");
270 /* This is the equivalent to main() only without argc and argv available. */
271 int ui_module_exec(char ***s
, const struct passwd
*pw
, const int multi_char
,
272 const int verbose
, char *tf
)
277 char folder
[PATH_MAX
];
281 snprintf(folder
, sizeof(folder
), "%s/%s", _PATH_MAILDIR
, pw
->pw_name
);
283 if (stat(folder
, &st
) != -1)
289 add_string(&strings
, (gotstat
) ? foldersize(st
) : "!");
292 add_string(&strings
, (gotstat
) ? stamp(st
.st_atime
, tf
) : "!");
295 add_string(&strings
, (gotstat
) ? stamp(st
.st_mtime
, tf
) : "!");
298 add_string(&strings
, forwards(pw
->pw_dir
, multi_char
));
301 add_string(&strings
, mail_aliases(pw
->pw_name
, multi_char
));
312 char *ui_module_options_init(char **defaults
)
315 return MAIL_OPTION_STRING
;
318 /* Check module option validity. */
319 int ui_module_options(int argc
, char **argv
)
324 while ((opt
= getopt(argc
, argv
, MAIL_OPTION_STRING
)) != -1) {
327 strncpy(options
, MAIL_OPTION_ORDER
, sizeof(options
));
336 warnx("mail: invalid option -- %c", optopt
);