OpenCoverage

mailcheck.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/bash/src/mailcheck.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* mailcheck.c -- The check is in the mail... */-
2-
3/* Copyright (C) 1987-2009 Free Software Foundation, Inc.-
4-
5 This file is part of GNU Bash, the Bourne Again SHell.-
6-
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.-
11-
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.-
16-
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*/-
20-
21#include "config.h"-
22-
23#include <stdio.h>-
24#include "bashtypes.h"-
25#include "posixstat.h"-
26#if defined (HAVE_SYS_PARAM_H)-
27# include <sys/param.h>-
28#endif-
29#if defined (HAVE_UNISTD_H)-
30# include <unistd.h>-
31#endif-
32#include "posixtime.h"-
33#include "bashansi.h"-
34#include "bashintl.h"-
35-
36#include "shell.h"-
37#include "execute_cmd.h"-
38#include "mailcheck.h"-
39#include <tilde/tilde.h>-
40-
41/* Values for flags word in struct _fileinfo */-
42#define MBOX_INITIALIZED 0x01-
43-
44extern time_t shell_start_time;-
45-
46extern int mailstat __P((const char *, struct stat *));-
47-
48typedef struct _fileinfo {-
49 char *name;-
50 char *msg;-
51 time_t access_time;-
52 time_t mod_time;-
53 off_t file_size;-
54 int flags;-
55} FILEINFO;-
56-
57/* The list of remembered mail files. */-
58static FILEINFO **mailfiles = (FILEINFO **)NULL;-
59-
60/* Number of mail files that we have. */-
61static int mailfiles_count;-
62-
63/* The last known time that mail was checked. */-
64static time_t last_time_mail_checked = 0;-
65-
66/* Non-zero means warn if a mail file has been read since last checked. */-
67int mail_warning;-
68-
69static int find_mail_file __P((char *));-
70static void init_mail_file __P((int));-
71static void update_mail_file __P((int));-
72static int add_mail_file __P((char *, char *));-
73-
74static FILEINFO *alloc_mail_file __P((char *, char *));-
75static void dispose_mail_file __P((FILEINFO *));-
76-
77static int file_mod_date_changed __P((int));-
78static int file_access_date_changed __P((int));-
79static int file_has_grown __P((int));-
80-
81static char *parse_mailpath_spec __P((char *));-
82-
83/* Returns non-zero if it is time to check mail. */-
84int-
85time_to_check_mail ()-
86{-
87 char *temp;-
88 time_t now;-
89 intmax_t seconds;-
90-
91 temp = get_string_value ("MAILCHECK");-
92-
93 /* Negative number, or non-numbers (such as empty string) cause no-
94 checking to take place. */-
95 if (temp == 0 || legal_number (temp, &seconds) == 0 || seconds < 0)
temp == 0Description
TRUEnever evaluated
FALSEnever evaluated
legal_number (...&seconds) == 0Description
TRUEnever evaluated
FALSEnever evaluated
seconds < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
96 return (0);
never executed: return (0);
0
97-
98 now = NOW;-
99 /* Time to check if MAILCHECK is explicitly set to zero, or if enough-
100 time has passed since the last check. */-
101 return (seconds == 0 || ((now - last_time_mail_checked) >= seconds));
never executed: return (seconds == 0 || ((now - last_time_mail_checked) >= seconds));
0
102}-
103-
104/* Okay, we have checked the mail. Perhaps I should make this function-
105 go away. */-
106void-
107reset_mail_timer ()-
108{-
109 last_time_mail_checked = NOW;-
110}
executed 1 time by 1 test: end of block
Executed by:
  • Self test
1
111-
112/* Locate a file in the list. Return index of-
113 entry, or -1 if not found. */-
114static int-
115find_mail_file (file)-
116 char *file;-
117{-
118 register int i;-
119-
120 for (i = 0; i < mailfiles_count; i++)
i < mailfiles_countDescription
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test
0-1
121 if (STREQ (mailfiles[i]->name, file))
never executed: __result = (((const unsigned char *) (const char *) ( mailfiles[i]->name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( file ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
(mailfiles[i]-...] == (file)[0]Description
TRUEnever evaluated
FALSEnever evaluated
__extension__ ... )))); }) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
122 return i;
never executed: return i;
0
123-
124 return -1;
executed 1 time by 1 test: return -1;
Executed by:
  • Self test
1
125}-
126-
127#define RESET_MAIL_FILE(i) \-
128 do \-
129 { \-
130 mailfiles[i]->access_time = mailfiles[i]->mod_time = 0; \-
131 mailfiles[i]->file_size = 0; \-
132 mailfiles[i]->flags = 0; \-
133 } \-
134 while (0)-
135-
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; \-
142 mailfiles[i]->flags |= MBOX_INITIALIZED; \-
143 } \-
144 while (0)-
145-
146static void-
147init_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;
last_time_mail_checkedDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-1
151 mailfiles[i]->file_size = 0;-
152 mailfiles[i]->flags = 0;-
153}
executed 1 time by 1 test: end of block
Executed by:
  • Self test
1
154-
155static void-
156update_mail_file (i)-
157 int i;-
158{-
159 char *file;-
160 struct stat finfo;-
161-
162 file = mailfiles[i]->name;-
163 if (mailstat (file, &finfo) == 0)
mailstat (file, &finfo) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
164 UPDATE_MAIL_FILE (i, finfo);
never executed: end of block
0
165 else-
166 RESET_MAIL_FILE (i);
never executed: end of block
0
167}-
168-
169/* Add this file to the list of remembered files and return its index-
170 in the list of mail files. */-
171static int-
172add_mail_file (file, msg)-
173 char *file, *msg;-
174{-
175 struct stat finfo;-
176 char *filename;-
177 int i;-
178-
179 filename = full_pathname (file);-
180 i = find_mail_file (filename);-
181 if (i >= 0)
i >= 0Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test
0-1
182 {-
183 if (mailstat (filename, &finfo) == 0)
mailstat (file..., &finfo) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
184 UPDATE_MAIL_FILE (i, finfo);
never executed: end of block
0
185-
186 free (filename);-
187 return i;
never executed: return i;
0
188 }-
189-
190 i = mailfiles_count++;-
191 mailfiles = (FILEINFO **)xrealloc-
192 (mailfiles, mailfiles_count * sizeof (FILEINFO *));-
193-
194 mailfiles[i] = alloc_mail_file (filename, msg);-
195 init_mail_file (i);-
196-
197 return i;
executed 1 time by 1 test: return i;
Executed by:
  • Self test
1
198}-
199-
200/* Reset the existing mail files access and modification times to zero. */-
201void-
202reset_mail_files ()-
203{-
204 register int i;-
205-
206 for (i = 0; i < mailfiles_count; i++)
i < mailfiles_countDescription
TRUEnever evaluated
FALSEnever evaluated
0
207 RESET_MAIL_FILE (i);
never executed: end of block
0
208}
never executed: end of block
0
209-
210static FILEINFO *-
211alloc_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;
msgDescription
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test
0-1
219 mf->flags = 0;-
220-
221 return mf;
executed 1 time by 1 test: return mf;
Executed by:
  • Self test
1
222}-
223-
224static void-
225dispose_mail_file (mf)-
226 FILEINFO *mf;-
227{-
228 free (mf->name);-
229 FREE (mf->msg);
never executed: sh_xfree((mf->msg), "mailcheck.c", 229);
mf->msgDescription
TRUEnever evaluated
FALSEnever evaluated
0
230 free (mf);-
231}
never executed: end of block
0
232-
233/* Free the information that we have about the remembered mail files. */-
234void-
235free_mail_files ()-
236{-
237 register int i;-
238-
239 for (i = 0; i < mailfiles_count; i++)
i < mailfiles_countDescription
TRUEnever evaluated
FALSEnever evaluated
0
240 dispose_mail_file (mailfiles[i]);
never executed: dispose_mail_file (mailfiles[i]);
0
241-
242 if (mailfiles)
mailfilesDescription
TRUEnever evaluated
FALSEnever evaluated
0
243 free (mailfiles);
never executed: sh_xfree((mailfiles), "mailcheck.c", 243);
0
244-
245 mailfiles_count = 0;-
246 mailfiles = (FILEINFO **)NULL;-
247}
never executed: end of block
0
248-
249void-
250init_mail_dates ()-
251{-
252 if (mailfiles == 0)
mailfiles == 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-1
253 remember_mail_dates ();
executed 1 time by 1 test: remember_mail_dates ();
Executed by:
  • Self test
1
254}
executed 1 time by 1 test: end of block
Executed by:
  • Self test
1
255-
256/* Return non-zero if FILE's mod date has changed and it has not been-
257 accessed since modified. If the size has dropped to zero, reset-
258 the cached mail file info. */-
259static int-
260file_mod_date_changed (i)-
261 int i;-
262{-
263 time_t mtime;-
264 struct stat finfo;-
265 char *file;-
266-
267 file = mailfiles[i]->name;-
268 mtime = mailfiles[i]->mod_time;-
269-
270 if (mailstat (file, &finfo) != 0)
mailstat (file, &finfo) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
271 return (0);
never executed: return (0);
0
272-
273 if (finfo.st_size > 0)
finfo.st_size > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
274 return (mtime < finfo.st_mtime);
never executed: return (mtime < finfo. st_mtim.tv_sec );
0
275-
276 if (finfo.st_size == 0 && mailfiles[i]->file_size > 0)
finfo.st_size == 0Description
TRUEnever evaluated
FALSEnever evaluated
mailfiles[i]->file_size > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
277 UPDATE_MAIL_FILE (i, finfo);
never executed: end of block
0
278-
279 return (0);
never executed: return (0);
0
280}-
281-
282/* Return non-zero if FILE's access date has changed. */-
283static int-
284file_access_date_changed (i)-
285 int i;-
286{-
287 time_t atime;-
288 struct stat finfo;-
289 char *file;-
290-
291 file = mailfiles[i]->name;-
292 atime = mailfiles[i]->access_time;-
293-
294 if (mailstat (file, &finfo) != 0)
mailstat (file, &finfo) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
295 return (0);
never executed: return (0);
0
296-
297 if (finfo.st_size > 0)
finfo.st_size > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
298 return (atime < finfo.st_atime);
never executed: return (atime < finfo. st_atim.tv_sec );
0
299-
300 return (0);
never executed: return (0);
0
301}-
302-
303/* Return non-zero if FILE's size has increased. */-
304static int-
305file_has_grown (i)-
306 int i;-
307{-
308 off_t size;-
309 struct stat finfo;-
310 char *file;-
311-
312 file = mailfiles[i]->name;-
313 size = mailfiles[i]->file_size;-
314-
315 return ((mailstat (file, &finfo) == 0) && (finfo.st_size > size));
never executed: return ((mailstat (file, &finfo) == 0) && (finfo.st_size > size));
0
316}-
317-
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. */-
321static char *-
322parse_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++)
sDescription
TRUEnever evaluated
FALSEnever evaluated
*sDescription
TRUEnever evaluated
FALSEnever evaluated
0
329 {-
330 if (pass_next)
pass_nextDescription
TRUEnever evaluated
FALSEnever evaluated
0
331 {-
332 pass_next = 0;-
333 continue;
never executed: continue;
0
334 }-
335 if (*s == '\\')
*s == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
336 {-
337 pass_next++;-
338 continue;
never executed: continue;
0
339 }-
340 if (*s == '?' || *s == '%')
*s == '?'Description
TRUEnever evaluated
FALSEnever evaluated
*s == '%'Description
TRUEnever evaluated
FALSEnever evaluated
0
341 return s;
never executed: return s;
0
342 }
never executed: end of block
0
343 return ((char *)NULL);
never executed: return ((char *) ((void *)0) );
0
344}-
345-
346char *-
347make_default_mailpath ()-
348{-
349#if defined (DEFAULT_MAIL_DIRECTORY)-
350 char *mp;-
351-
352 get_current_user_info ();-
353 mp = (char *)xmalloc (2 + sizeof (DEFAULT_MAIL_DIRECTORY) + strlen (current_user.user_name));-
354 strcpy (mp, DEFAULT_MAIL_DIRECTORY);-
355 mp[sizeof(DEFAULT_MAIL_DIRECTORY) - 1] = '/';-
356 strcpy (mp + sizeof (DEFAULT_MAIL_DIRECTORY), current_user.user_name);-
357 return (mp);
never executed: return (mp);
0
358#else-
359 return ((char *)NULL);-
360#endif-
361}-
362-
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. */-
366-
367void-
368remember_mail_dates ()-
369{-
370 char *mailpaths;-
371 char *mailfile, *mp;-
372 int i = 0;-
373-
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")))
mailpaths == 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
(mailpaths = g...alue ("MAIL"))Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-1
378 {-
379 add_mail_file (mailpaths, (char *)NULL);-
380 return;
executed 1 time by 1 test: return;
Executed by:
  • Self test
1
381 }-
382-
383 if (mailpaths == 0)
mailpaths == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
384 {-
385 mailpaths = make_default_mailpath ();-
386 if (mailpaths)
mailpathsDescription
TRUEnever evaluated
FALSEnever evaluated
0
387 {-
388 add_mail_file (mailpaths, (char *)NULL);-
389 free (mailpaths);-
390 }
never executed: end of block
0
391 return;
never executed: return;
0
392 }-
393-
394 while (mailfile = extract_colon_unit (mailpaths, &i))
mailfile = ext...mailpaths, &i)Description
TRUEnever evaluated
FALSEnever evaluated
0
395 {-
396 mp = parse_mailpath_spec (mailfile);-
397 if (mp && *mp)
mpDescription
TRUEnever evaluated
FALSEnever evaluated
*mpDescription
TRUEnever evaluated
FALSEnever evaluated
0
398 *mp++ = '\0';
never executed: *mp++ = '\0';
0
399 add_mail_file (mailfile, mp);-
400 free (mailfile);-
401 }
never executed: end of block
0
402}
never executed: end of block
0
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.-
413 Special hack: If the variable MAIL_WARNING is non-zero and the-
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. */-
416void-
417check_mail ()-
418{-
419 char *current_mail_file, *message;-
420 int i, use_user_notification;-
421 char *dollar_underscore, *temp;-
422-
423 dollar_underscore = get_string_value ("_");-
424 if (dollar_underscore)
dollar_underscoreDescription
TRUEnever evaluated
FALSEnever evaluated
0
425 dollar_underscore = savestring (dollar_underscore);
never executed: dollar_underscore = (char *)strcpy (sh_xmalloc((1 + strlen (dollar_underscore)), "mailcheck.c", 425), (dollar_underscore));
0
426-
427 for (i = 0; i < mailfiles_count; i++)
i < mailfiles_countDescription
TRUEnever evaluated
FALSEnever evaluated
0
428 {-
429 current_mail_file = mailfiles[i]->name;-
430-
431 if (*current_mail_file == '\0')
*current_mail_file == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
432 continue;
never executed: continue;
0
433-
434 if (file_mod_date_changed (i))
file_mod_date_changed (i)Description
TRUEnever evaluated
FALSEnever evaluated
0
435 {-
436 int file_is_bigger;-
437-
438 use_user_notification = mailfiles[i]->msg != (char *)NULL;-
439 message = mailfiles[i]->msg ? mailfiles[i]->msg : _("You have mail in $_");
mailfiles[i]->msgDescription
TRUEnever evaluated
FALSEnever evaluated
0
440-
441 bind_variable ("_", current_mail_file, 0);-
442-
443#define atime mailfiles[i]->access_time-
444#define mtime mailfiles[i]->mod_time-
445-
446 /* Have to compute this before the call to update_mail_file, which-
447 resets all the information. */-
448 file_is_bigger = file_has_grown (i);-
449-
450 update_mail_file (i);-
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. */-
458 if ((atime >= mtime) && !file_is_bigger)
(mailfiles[i]-...[i]->mod_time)Description
TRUEnever evaluated
FALSEnever evaluated
!file_is_biggerDescription
TRUEnever evaluated
FALSEnever evaluated
0
459 continue;
never executed: continue;
0
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. */-
463 if (use_user_notification == 0 && (atime < mtime) && file_is_bigger)
use_user_notification == 0Description
TRUEnever evaluated
FALSEnever evaluated
(mailfiles[i]-...[i]->mod_time)Description
TRUEnever evaluated
FALSEnever evaluated
file_is_biggerDescription
TRUEnever evaluated
FALSEnever evaluated
0
464 message = _("You have new mail in $_");
never executed: message = dcgettext (((void *)0), "You have new mail in $_" , 5) ;
0
465#undef atime-
466#undef mtime-
467-
468 if (temp = expand_string_to_string (message, Q_DOUBLE_QUOTES))
temp = expand_...essage, 0x001)Description
TRUEnever evaluated
FALSEnever evaluated
0
469 {-
470 puts (temp);-
471 free (temp);-
472 }
never executed: end of block
0
473 else-
474 putchar ('\n');
never executed: putchar ('\n');
0
475 }-
476-
477 if (mail_warning && file_access_date_changed (i))
mail_warningDescription
TRUEnever evaluated
FALSEnever evaluated
file_access_date_changed (i)Description
TRUEnever evaluated
FALSEnever evaluated
0
478 {-
479 update_mail_file (i);-
480 printf (_("The mail in %s has been read\n"), current_mail_file);-
481 }
never executed: end of block
0
482 }
never executed: end of block
0
483-
484 if (dollar_underscore)
dollar_underscoreDescription
TRUEnever evaluated
FALSEnever evaluated
0
485 {-
486 bind_variable ("_", dollar_underscore, 0);-
487 free (dollar_underscore);-
488 }
never executed: end of block
0
489 else-
490 unbind_variable ("_");
never executed: unbind_variable ("_");
0
491}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2