Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 1 | /* mailcheck.c -- The check is in the mail... */ |
| 2 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 3 | /* Copyright (C) 1987-2009 Free Software Foundation, Inc. |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 4 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 5 | This file is part of GNU Bash, the Bourne Again SHell. |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 6 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 7 | Bash is free software: you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by |
| 9 | the Free Software Foundation, either version 3 of the License, or |
| 10 | (at your option) any later version. |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 11 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 12 | Bash is distributed in the hope that it will be useful, |
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | GNU General Public License for more details. |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 16 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 17 | You should have received a copy of the GNU General Public License |
| 18 | along with Bash. If not, see <http://www.gnu.org/licenses/>. |
| 19 | */ |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 20 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 21 | #include "config.h" |
| 22 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 23 | #include <stdio.h> |
| 24 | #include "bashtypes.h" |
| 25 | #include "posixstat.h" |
Chet Ramey | ac50fba | 2014-02-26 09:36:43 -0500 | [diff] [blame] | 26 | #if defined (HAVE_SYS_PARAM_H) |
Jari Aalto | cce855b | 1998-04-17 19:52:44 +0000 | [diff] [blame] | 27 | # include <sys/param.h> |
| 28 | #endif |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 29 | #if defined (HAVE_UNISTD_H) |
| 30 | # include <unistd.h> |
| 31 | #endif |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 32 | #include "posixtime.h" |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 33 | #include "bashansi.h" |
Jari Aalto | b80f644 | 2004-07-27 13:29:18 +0000 | [diff] [blame] | 34 | #include "bashintl.h" |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 35 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 36 | #include "shell.h" |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 37 | #include "execute_cmd.h" |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 38 | #include "mailcheck.h" |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 39 | #include <tilde/tilde.h> |
| 40 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 41 | /* Values for flags word in struct _fileinfo */ |
| 42 | #define MBOX_INITIALIZED 0x01 |
| 43 | |
| 44 | extern time_t shell_start_time; |
| 45 | |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 46 | extern int mailstat __P((const char *, struct stat *)); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 47 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 48 | typedef struct _fileinfo { |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 49 | char *name; |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 50 | char *msg; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 51 | time_t access_time; |
| 52 | time_t mod_time; |
Jari Aalto | cce855b | 1998-04-17 19:52:44 +0000 | [diff] [blame] | 53 | off_t file_size; |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 54 | int flags; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 55 | } FILEINFO; |
| 56 | |
| 57 | /* The list of remembered mail files. */ |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 58 | static FILEINFO **mailfiles = (FILEINFO **)NULL; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 59 | |
| 60 | /* Number of mail files that we have. */ |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 61 | static int mailfiles_count; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 62 | |
| 63 | /* The last known time that mail was checked. */ |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 64 | static time_t last_time_mail_checked = 0; |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 65 | |
| 66 | /* Non-zero means warn if a mail file has been read since last checked. */ |
| 67 | int mail_warning; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 68 | |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 69 | static int find_mail_file __P((char *)); |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 70 | static void init_mail_file __P((int)); |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 71 | static void update_mail_file __P((int)); |
| 72 | static int add_mail_file __P((char *, char *)); |
| 73 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 74 | static FILEINFO *alloc_mail_file __P((char *, char *)); |
| 75 | static void dispose_mail_file __P((FILEINFO *)); |
| 76 | |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 77 | static int file_mod_date_changed __P((int)); |
| 78 | static int file_access_date_changed __P((int)); |
| 79 | static int file_has_grown __P((int)); |
| 80 | |
| 81 | static char *parse_mailpath_spec __P((char *)); |
| 82 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 83 | /* Returns non-zero if it is time to check mail. */ |
| 84 | int |
| 85 | time_to_check_mail () |
| 86 | { |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 87 | char *temp; |
| 88 | time_t now; |
Jari Aalto | 7117c2d | 2002-07-17 14:10:11 +0000 | [diff] [blame] | 89 | intmax_t seconds; |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 90 | |
| 91 | temp = get_string_value ("MAILCHECK"); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 92 | |
| 93 | /* Negative number, or non-numbers (such as empty string) cause no |
| 94 | checking to take place. */ |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 95 | if (temp == 0 || legal_number (temp, &seconds) == 0 || seconds < 0) |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 96 | return (0); |
| 97 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 98 | now = NOW; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 99 | /* Time to check if MAILCHECK is explicitly set to zero, or if enough |
| 100 | time has passed since the last check. */ |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 101 | return (seconds == 0 || ((now - last_time_mail_checked) >= seconds)); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 102 | } |
| 103 | |
| 104 | /* Okay, we have checked the mail. Perhaps I should make this function |
| 105 | go away. */ |
| 106 | void |
| 107 | reset_mail_timer () |
| 108 | { |
| 109 | last_time_mail_checked = NOW; |
| 110 | } |
| 111 | |
| 112 | /* Locate a file in the list. Return index of |
| 113 | entry, or -1 if not found. */ |
| 114 | static int |
| 115 | find_mail_file (file) |
| 116 | char *file; |
| 117 | { |
| 118 | register int i; |
| 119 | |
| 120 | for (i = 0; i < mailfiles_count; i++) |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 121 | if (STREQ (mailfiles[i]->name, file)) |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 122 | return i; |
| 123 | |
| 124 | return -1; |
| 125 | } |
| 126 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 127 | #define RESET_MAIL_FILE(i) \ |
| 128 | do \ |
| 129 | { \ |
| 130 | mailfiles[i]->access_time = mailfiles[i]->mod_time = 0; \ |
Jari Aalto | cce855b | 1998-04-17 19:52:44 +0000 | [diff] [blame] | 131 | mailfiles[i]->file_size = 0; \ |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 132 | mailfiles[i]->flags = 0; \ |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 133 | } \ |
| 134 | while (0) |
| 135 | |
Jari Aalto | 95732b4 | 2005-12-07 14:08:12 +0000 | [diff] [blame] | 136 | #define UPDATE_MAIL_FILE(i, finfo) \ |
| 137 | do \ |
| 138 | { \ |
| 139 | mailfiles[i]->access_time = finfo.st_atime; \ |
| 140 | mailfiles[i]->mod_time = finfo.st_mtime; \ |
| 141 | mailfiles[i]->file_size = finfo.st_size; \ |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 142 | mailfiles[i]->flags |= MBOX_INITIALIZED; \ |
Jari Aalto | 95732b4 | 2005-12-07 14:08:12 +0000 | [diff] [blame] | 143 | } \ |
| 144 | while (0) |
| 145 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 146 | static void |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 147 | init_mail_file (i) |
| 148 | int i; |
| 149 | { |
| 150 | mailfiles[i]->access_time = mailfiles[i]->mod_time = last_time_mail_checked ? last_time_mail_checked : shell_start_time; |
| 151 | mailfiles[i]->file_size = 0; |
| 152 | mailfiles[i]->flags = 0; |
| 153 | } |
| 154 | |
| 155 | static void |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 156 | update_mail_file (i) |
| 157 | int i; |
| 158 | { |
| 159 | char *file; |
| 160 | struct stat finfo; |
| 161 | |
| 162 | file = mailfiles[i]->name; |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 163 | if (mailstat (file, &finfo) == 0) |
Jari Aalto | 95732b4 | 2005-12-07 14:08:12 +0000 | [diff] [blame] | 164 | UPDATE_MAIL_FILE (i, finfo); |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 165 | else |
| 166 | RESET_MAIL_FILE (i); |
| 167 | } |
| 168 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 169 | /* Add this file to the list of remembered files and return its index |
| 170 | in the list of mail files. */ |
| 171 | static int |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 172 | add_mail_file (file, msg) |
| 173 | char *file, *msg; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 174 | { |
| 175 | struct stat finfo; |
| 176 | char *filename; |
| 177 | int i; |
| 178 | |
| 179 | filename = full_pathname (file); |
Jari Aalto | e8ce775 | 1997-09-22 20:22:27 +0000 | [diff] [blame] | 180 | i = find_mail_file (filename); |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 181 | if (i >= 0) |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 182 | { |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 183 | if (mailstat (filename, &finfo) == 0) |
Jari Aalto | 95732b4 | 2005-12-07 14:08:12 +0000 | [diff] [blame] | 184 | UPDATE_MAIL_FILE (i, finfo); |
| 185 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 186 | free (filename); |
| 187 | return i; |
| 188 | } |
| 189 | |
| 190 | i = mailfiles_count++; |
| 191 | mailfiles = (FILEINFO **)xrealloc |
| 192 | (mailfiles, mailfiles_count * sizeof (FILEINFO *)); |
| 193 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 194 | mailfiles[i] = alloc_mail_file (filename, msg); |
| 195 | init_mail_file (i); |
| 196 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 197 | return i; |
| 198 | } |
| 199 | |
| 200 | /* Reset the existing mail files access and modification times to zero. */ |
| 201 | void |
| 202 | reset_mail_files () |
| 203 | { |
| 204 | register int i; |
| 205 | |
| 206 | for (i = 0; i < mailfiles_count; i++) |
Jari Aalto | 95732b4 | 2005-12-07 14:08:12 +0000 | [diff] [blame] | 207 | RESET_MAIL_FILE (i); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 208 | } |
| 209 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 210 | static FILEINFO * |
| 211 | alloc_mail_file (filename, msg) |
| 212 | char *filename, *msg; |
| 213 | { |
| 214 | FILEINFO *mf; |
| 215 | |
| 216 | mf = (FILEINFO *)xmalloc (sizeof (FILEINFO)); |
| 217 | mf->name = filename; |
| 218 | mf->msg = msg ? savestring (msg) : (char *)NULL; |
| 219 | mf->flags = 0; |
| 220 | |
| 221 | return mf; |
| 222 | } |
| 223 | |
| 224 | static void |
| 225 | dispose_mail_file (mf) |
| 226 | FILEINFO *mf; |
| 227 | { |
| 228 | free (mf->name); |
| 229 | FREE (mf->msg); |
| 230 | free (mf); |
| 231 | } |
| 232 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 233 | /* Free the information that we have about the remembered mail files. */ |
| 234 | void |
| 235 | free_mail_files () |
| 236 | { |
| 237 | register int i; |
| 238 | |
| 239 | for (i = 0; i < mailfiles_count; i++) |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 240 | dispose_mail_file (mailfiles[i]); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 241 | |
| 242 | if (mailfiles) |
| 243 | free (mailfiles); |
| 244 | |
| 245 | mailfiles_count = 0; |
| 246 | mailfiles = (FILEINFO **)NULL; |
| 247 | } |
| 248 | |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 249 | void |
| 250 | init_mail_dates () |
| 251 | { |
| 252 | if (mailfiles == 0) |
| 253 | remember_mail_dates (); |
| 254 | } |
| 255 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 256 | /* Return non-zero if FILE's mod date has changed and it has not been |
Jari Aalto | 95732b4 | 2005-12-07 14:08:12 +0000 | [diff] [blame] | 257 | accessed since modified. If the size has dropped to zero, reset |
| 258 | the cached mail file info. */ |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 259 | static int |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 260 | file_mod_date_changed (i) |
| 261 | int i; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 262 | { |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 263 | time_t mtime; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 264 | struct stat finfo; |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 265 | char *file; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 266 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 267 | file = mailfiles[i]->name; |
| 268 | mtime = mailfiles[i]->mod_time; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 269 | |
Chet Ramey | ac50fba | 2014-02-26 09:36:43 -0500 | [diff] [blame] | 270 | if (mailstat (file, &finfo) != 0) |
| 271 | return (0); |
| 272 | |
| 273 | if (finfo.st_size > 0) |
Chet Ramey | 0001803 | 2011-11-21 20:51:19 -0500 | [diff] [blame] | 274 | return (mtime < finfo.st_mtime); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 275 | |
Jari Aalto | 95732b4 | 2005-12-07 14:08:12 +0000 | [diff] [blame] | 276 | if (finfo.st_size == 0 && mailfiles[i]->file_size > 0) |
| 277 | UPDATE_MAIL_FILE (i, finfo); |
| 278 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 279 | return (0); |
| 280 | } |
| 281 | |
| 282 | /* Return non-zero if FILE's access date has changed. */ |
| 283 | static int |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 284 | file_access_date_changed (i) |
| 285 | int i; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 286 | { |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 287 | time_t atime; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 288 | struct stat finfo; |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 289 | char *file; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 290 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 291 | file = mailfiles[i]->name; |
| 292 | atime = mailfiles[i]->access_time; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 293 | |
Chet Ramey | ac50fba | 2014-02-26 09:36:43 -0500 | [diff] [blame] | 294 | if (mailstat (file, &finfo) != 0) |
| 295 | return (0); |
| 296 | |
| 297 | if (finfo.st_size > 0) |
Chet Ramey | 0001803 | 2011-11-21 20:51:19 -0500 | [diff] [blame] | 298 | return (atime < finfo.st_atime); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 299 | |
| 300 | return (0); |
| 301 | } |
| 302 | |
| 303 | /* Return non-zero if FILE's size has increased. */ |
| 304 | static int |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 305 | file_has_grown (i) |
| 306 | int i; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 307 | { |
Jari Aalto | cce855b | 1998-04-17 19:52:44 +0000 | [diff] [blame] | 308 | off_t size; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 309 | struct stat finfo; |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 310 | char *file; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 311 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 312 | file = mailfiles[i]->name; |
| 313 | size = mailfiles[i]->file_size; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 314 | |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 315 | return ((mailstat (file, &finfo) == 0) && (finfo.st_size > size)); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 316 | } |
| 317 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 318 | /* Take an element from $MAILPATH and return the portion from |
| 319 | the first unquoted `?' or `%' to the end of the string. This is the |
| 320 | message to be printed when the file contents change. */ |
| 321 | static char * |
| 322 | parse_mailpath_spec (str) |
| 323 | char *str; |
| 324 | { |
| 325 | char *s; |
| 326 | int pass_next; |
| 327 | |
| 328 | for (s = str, pass_next = 0; s && *s; s++) |
| 329 | { |
| 330 | if (pass_next) |
| 331 | { |
| 332 | pass_next = 0; |
| 333 | continue; |
| 334 | } |
| 335 | if (*s == '\\') |
| 336 | { |
| 337 | pass_next++; |
| 338 | continue; |
| 339 | } |
| 340 | if (*s == '?' || *s == '%') |
Jari Aalto | 28ef6c3 | 2001-04-06 19:14:31 +0000 | [diff] [blame] | 341 | return s; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 342 | } |
| 343 | return ((char *)NULL); |
| 344 | } |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 345 | |
| 346 | char * |
| 347 | make_default_mailpath () |
| 348 | { |
Jari Aalto | b80f644 | 2004-07-27 13:29:18 +0000 | [diff] [blame] | 349 | #if defined (DEFAULT_MAIL_DIRECTORY) |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 350 | char *mp; |
| 351 | |
Jari Aalto | cce855b | 1998-04-17 19:52:44 +0000 | [diff] [blame] | 352 | get_current_user_info (); |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 353 | mp = (char *)xmalloc (2 + sizeof (DEFAULT_MAIL_DIRECTORY) + strlen (current_user.user_name)); |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 354 | strcpy (mp, DEFAULT_MAIL_DIRECTORY); |
Jari Aalto | d166f04 | 1997-06-05 14:59:13 +0000 | [diff] [blame] | 355 | mp[sizeof(DEFAULT_MAIL_DIRECTORY) - 1] = '/'; |
| 356 | strcpy (mp + sizeof (DEFAULT_MAIL_DIRECTORY), current_user.user_name); |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 357 | return (mp); |
Jari Aalto | b80f644 | 2004-07-27 13:29:18 +0000 | [diff] [blame] | 358 | #else |
| 359 | return ((char *)NULL); |
| 360 | #endif |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 361 | } |
| 362 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 363 | /* Remember the dates of the files specified by MAILPATH, or if there is |
| 364 | no MAILPATH, by the file specified in MAIL. If neither exists, use a |
| 365 | default value, which we randomly concoct from using Unix. */ |
Jari Aalto | 3185942 | 2009-01-12 13:36:28 +0000 | [diff] [blame] | 366 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 367 | void |
| 368 | remember_mail_dates () |
| 369 | { |
| 370 | char *mailpaths; |
| 371 | char *mailfile, *mp; |
| 372 | int i = 0; |
| 373 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 374 | mailpaths = get_string_value ("MAILPATH"); |
| 375 | |
| 376 | /* If no $MAILPATH, but $MAIL, use that as a single filename to check. */ |
| 377 | if (mailpaths == 0 && (mailpaths = get_string_value ("MAIL"))) |
| 378 | { |
| 379 | add_mail_file (mailpaths, (char *)NULL); |
| 380 | return; |
| 381 | } |
| 382 | |
| 383 | if (mailpaths == 0) |
| 384 | { |
| 385 | mailpaths = make_default_mailpath (); |
Jari Aalto | b80f644 | 2004-07-27 13:29:18 +0000 | [diff] [blame] | 386 | if (mailpaths) |
| 387 | { |
| 388 | add_mail_file (mailpaths, (char *)NULL); |
| 389 | free (mailpaths); |
| 390 | } |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 391 | return; |
| 392 | } |
| 393 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 394 | while (mailfile = extract_colon_unit (mailpaths, &i)) |
| 395 | { |
| 396 | mp = parse_mailpath_spec (mailfile); |
| 397 | if (mp && *mp) |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 398 | *mp++ = '\0'; |
| 399 | add_mail_file (mailfile, mp); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 400 | free (mailfile); |
| 401 | } |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 402 | } |
| 403 | |
| 404 | /* check_mail () is useful for more than just checking mail. Since it has |
| 405 | the paranoids dream ability of telling you when someone has read your |
| 406 | mail, it can just as easily be used to tell you when someones .profile |
| 407 | file has been read, thus letting one know when someone else has logged |
| 408 | in. Pretty good, huh? */ |
| 409 | |
| 410 | /* Check for mail in some files. If the modification date of any |
| 411 | of the files in MAILPATH has changed since we last did a |
| 412 | remember_mail_dates () then mention that the user has mail. |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 413 | Special hack: If the variable MAIL_WARNING is non-zero and the |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 414 | mail file has been accessed since the last time we remembered, then |
| 415 | the message "The mail in <mailfile> has been read" is printed. */ |
| 416 | void |
| 417 | check_mail () |
| 418 | { |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 419 | char *current_mail_file, *message; |
| 420 | int i, use_user_notification; |
| 421 | char *dollar_underscore, *temp; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 422 | |
| 423 | dollar_underscore = get_string_value ("_"); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 424 | if (dollar_underscore) |
| 425 | dollar_underscore = savestring (dollar_underscore); |
| 426 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 427 | for (i = 0; i < mailfiles_count; i++) |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 428 | { |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 429 | current_mail_file = mailfiles[i]->name; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 430 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 431 | if (*current_mail_file == '\0') |
| 432 | continue; |
| 433 | |
| 434 | if (file_mod_date_changed (i)) |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 435 | { |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 436 | int file_is_bigger; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 437 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 438 | use_user_notification = mailfiles[i]->msg != (char *)NULL; |
Jari Aalto | b80f644 | 2004-07-27 13:29:18 +0000 | [diff] [blame] | 439 | message = mailfiles[i]->msg ? mailfiles[i]->msg : _("You have mail in $_"); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 440 | |
Jari Aalto | 95732b4 | 2005-12-07 14:08:12 +0000 | [diff] [blame] | 441 | bind_variable ("_", current_mail_file, 0); |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 442 | |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 443 | #define atime mailfiles[i]->access_time |
| 444 | #define mtime mailfiles[i]->mod_time |
| 445 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 446 | /* Have to compute this before the call to update_mail_file, which |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 447 | resets all the information. */ |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 448 | file_is_bigger = file_has_grown (i); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 449 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 450 | update_mail_file (i); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 451 | |
| 452 | /* If the user has just run a program which manipulates the |
| 453 | mail file, then don't bother explaining that the mail |
| 454 | file has been manipulated. Since some systems don't change |
| 455 | the access time to be equal to the modification time when |
| 456 | the mail in the file is manipulated, check the size also. If |
| 457 | the file has not grown, continue. */ |
Jari Aalto | b80f644 | 2004-07-27 13:29:18 +0000 | [diff] [blame] | 458 | if ((atime >= mtime) && !file_is_bigger) |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 459 | continue; |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 460 | |
| 461 | /* If the mod time is later than the access time and the file |
| 462 | has grown, note the fact that this is *new* mail. */ |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 463 | if (use_user_notification == 0 && (atime < mtime) && file_is_bigger) |
Jari Aalto | b80f644 | 2004-07-27 13:29:18 +0000 | [diff] [blame] | 464 | message = _("You have new mail in $_"); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 465 | #undef atime |
| 466 | #undef mtime |
| 467 | |
Jari Aalto | f73dda0 | 2001-11-13 17:56:06 +0000 | [diff] [blame] | 468 | if (temp = expand_string_to_string (message, Q_DOUBLE_QUOTES)) |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 469 | { |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 470 | puts (temp); |
| 471 | free (temp); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 472 | } |
| 473 | else |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 474 | putchar ('\n'); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 475 | } |
| 476 | |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 477 | if (mail_warning && file_access_date_changed (i)) |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 478 | { |
Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame] | 479 | update_mail_file (i); |
Jari Aalto | b80f644 | 2004-07-27 13:29:18 +0000 | [diff] [blame] | 480 | printf (_("The mail in %s has been read\n"), current_mail_file); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 481 | } |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 482 | } |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 483 | |
| 484 | if (dollar_underscore) |
| 485 | { |
Jari Aalto | 95732b4 | 2005-12-07 14:08:12 +0000 | [diff] [blame] | 486 | bind_variable ("_", dollar_underscore, 0); |
Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 487 | free (dollar_underscore); |
| 488 | } |
| 489 | else |
| 490 | unbind_variable ("_"); |
| 491 | } |