Imported from ../bash-3.1.tar.gz.
[platform/upstream/bash.git] / mailcheck.c
index 8d3f833..4b7e207 100644 (file)
@@ -1,12 +1,12 @@
 /* mailcheck.c -- The check is in the mail... */
 
 /* mailcheck.c -- The check is in the mail... */
 
-/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
 Bash is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
 Bash is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 1, or (at your option) any later
+Software Foundation; either version 2, or (at your option) any later
 version.
 
 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,35 +16,36 @@ for more details.
 
 You should have received a copy of the GNU General Public License along
 with Bash; see the file COPYING.  If not, write to the Free Software
 
 You should have received a copy of the GNU General Public License along
 with Bash; see the file COPYING.  If not, write to the Free Software
-Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
 
 #include "config.h"
 
 #include <stdio.h>
 #include "bashtypes.h"
 #include "posixstat.h"
 
 #include "config.h"
 
 #include <stdio.h>
 #include "bashtypes.h"
 #include "posixstat.h"
-#include <sys/param.h>
+#ifndef _MINIX
+#  include <sys/param.h>
+#endif
 #if defined (HAVE_UNISTD_H)
 #  include <unistd.h>
 #endif
 #if defined (HAVE_UNISTD_H)
 #  include <unistd.h>
 #endif
+#include "posixtime.h"
 #include "bashansi.h"
 #include "bashansi.h"
+#include "bashintl.h"
 
 #include "shell.h"
 
 #include "shell.h"
-#include "maxpath.h"
 #include "execute_cmd.h"
 #include "mailcheck.h"
 #include <tilde/tilde.h>
 
 #include "execute_cmd.h"
 #include "mailcheck.h"
 #include <tilde/tilde.h>
 
-#ifndef NOW
-#define NOW ((time_t)time ((time_t *)0))
-#endif
+extern int mailstat __P((const char *, struct stat *));
 
 typedef struct {
   char *name;
   char *msg;
   time_t access_time;
   time_t mod_time;
 
 typedef struct {
   char *name;
   char *msg;
   time_t access_time;
   time_t mod_time;
-  long file_size;
+  off_t file_size;
 } FILEINFO;
 
 /* The list of remembered mail files. */
 } FILEINFO;
 
 /* The list of remembered mail files. */
@@ -54,34 +55,34 @@ static FILEINFO **mailfiles = (FILEINFO **)NULL;
 static int mailfiles_count;
 
 /* The last known time that mail was checked. */
 static int mailfiles_count;
 
 /* The last known time that mail was checked. */
-static int last_time_mail_checked;
+static time_t last_time_mail_checked;
 
 /* Non-zero means warn if a mail file has been read since last checked. */
 int mail_warning;
 
 
 /* Non-zero means warn if a mail file has been read since last checked. */
 int mail_warning;
 
+static int find_mail_file __P((char *));
+static void update_mail_file __P((int));
+static int add_mail_file __P((char *, char *));
+
+static int file_mod_date_changed __P((int));
+static int file_access_date_changed __P((int));
+static int file_has_grown __P((int));
+
+static char *parse_mailpath_spec __P((char *));
+
 /* Returns non-zero if it is time to check mail. */
 int
 time_to_check_mail ()
 {
   char *temp;
   time_t now;
 /* Returns non-zero if it is time to check mail. */
 int
 time_to_check_mail ()
 {
   char *temp;
   time_t now;
-  long seconds;
+  intmax_t seconds;
 
   temp = get_string_value ("MAILCHECK");
 
   temp = get_string_value ("MAILCHECK");
-  seconds = -1L;
-
-  /* Skip leading whitespace in MAILCHECK. */
-  if (temp)
-    {
-      while (whitespace (*temp))
-       temp++;
-
-      seconds = atoi (temp);
-    }
 
   /* Negative number, or non-numbers (such as empty string) cause no
      checking to take place. */
 
   /* Negative number, or non-numbers (such as empty string) cause no
      checking to take place. */
-  if (seconds < 0)
+  if (temp == 0 || legal_number (temp, &seconds) == 0 || seconds < 0)
     return (0);
 
   now = NOW;
     return (0);
 
   now = NOW;
@@ -117,7 +118,16 @@ find_mail_file (file)
   do \
     { \
       mailfiles[i]->access_time = mailfiles[i]->mod_time = 0; \
   do \
     { \
       mailfiles[i]->access_time = mailfiles[i]->mod_time = 0; \
-      mailfiles[i]->file_size = 0L; \
+      mailfiles[i]->file_size = 0; \
+    } \
+  while (0)
+
+#define UPDATE_MAIL_FILE(i, finfo) \
+  do \
+    { \
+      mailfiles[i]->access_time = finfo.st_atime; \
+      mailfiles[i]->mod_time = finfo.st_mtime; \
+      mailfiles[i]->file_size = finfo.st_size; \
     } \
   while (0)
 
     } \
   while (0)
 
@@ -129,12 +139,8 @@ update_mail_file (i)
   struct stat finfo;
 
   file = mailfiles[i]->name;
   struct stat finfo;
 
   file = mailfiles[i]->name;
-  if (stat (file, &finfo) == 0)
-    {
-      mailfiles[i]->access_time = finfo.st_atime;
-      mailfiles[i]->mod_time = finfo.st_mtime;
-      mailfiles[i]->file_size = finfo.st_size;
-    }
+  if (mailstat (file, &finfo) == 0)
+    UPDATE_MAIL_FILE (i, finfo);
   else
     RESET_MAIL_FILE (i);
 }
   else
     RESET_MAIL_FILE (i);
 }
@@ -150,15 +156,12 @@ add_mail_file (file, msg)
   int i;
 
   filename = full_pathname (file);
   int i;
 
   filename = full_pathname (file);
-  i = find_mail_file (file);
+  i = find_mail_file (filename);
   if (i >= 0)
     {
   if (i >= 0)
     {
-      if (stat (filename, &finfo) == 0)
-       {
-         mailfiles[i]->mod_time = finfo.st_mtime;
-         mailfiles[i]->access_time = finfo.st_atime;
-         mailfiles[i]->file_size = (long)finfo.st_size;
-       }
+      if (mailstat (filename, &finfo) == 0)
+       UPDATE_MAIL_FILE (i, finfo);
+
       free (filename);
       return i;
     }
       free (filename);
       return i;
     }
@@ -181,9 +184,7 @@ reset_mail_files ()
   register int i;
 
   for (i = 0; i < mailfiles_count; i++)
   register int i;
 
   for (i = 0; i < mailfiles_count; i++)
-    {
-      RESET_MAIL_FILE (i);
-    }
+    RESET_MAIL_FILE (i);
 }
 
 /* Free the information that we have about the remembered mail files. */
 }
 
 /* Free the information that we have about the remembered mail files. */
@@ -207,7 +208,8 @@ free_mail_files ()
 }
 
 /* Return non-zero if FILE's mod date has changed and it has not been
 }
 
 /* Return non-zero if FILE's mod date has changed and it has not been
-   accessed since modified. */
+   accessed since modified.  If the size has dropped to zero, reset
+   the cached mail file info. */
 static int
 file_mod_date_changed (i)
      int i;
 static int
 file_mod_date_changed (i)
      int i;
@@ -219,9 +221,12 @@ file_mod_date_changed (i)
   file = mailfiles[i]->name;
   mtime = mailfiles[i]->mod_time;
 
   file = mailfiles[i]->name;
   mtime = mailfiles[i]->mod_time;
 
-  if ((stat (file, &finfo) == 0) && (finfo.st_size > 0))
+  if ((mailstat (file, &finfo) == 0) && (finfo.st_size > 0))
     return (mtime != finfo.st_mtime);
 
     return (mtime != finfo.st_mtime);
 
+  if (finfo.st_size == 0 && mailfiles[i]->file_size > 0)
+    UPDATE_MAIL_FILE (i, finfo);
+
   return (0);
 }
 
   return (0);
 }
 
@@ -237,7 +242,7 @@ file_access_date_changed (i)
   file = mailfiles[i]->name;
   atime = mailfiles[i]->access_time;
 
   file = mailfiles[i]->name;
   atime = mailfiles[i]->access_time;
 
-  if ((stat (file, &finfo) == 0) && (finfo.st_size > 0))
+  if ((mailstat (file, &finfo) == 0) && (finfo.st_size > 0))
     return (atime != finfo.st_atime);
 
   return (0);
     return (atime != finfo.st_atime);
 
   return (0);
@@ -248,14 +253,14 @@ static int
 file_has_grown (i)
      int i;
 {
 file_has_grown (i)
      int i;
 {
-  long size;
+  off_t size;
   struct stat finfo;
   char *file;
 
   file = mailfiles[i]->name;
   size = mailfiles[i]->file_size;
 
   struct stat finfo;
   char *file;
 
   file = mailfiles[i]->name;
   size = mailfiles[i]->file_size;
 
-  return ((stat (file, &finfo) == 0) && (finfo.st_size > size));
+  return ((mailstat (file, &finfo) == 0) && (finfo.st_size > size));
 }
 
 /* Take an element from $MAILPATH and return the portion from
 }
 
 /* Take an element from $MAILPATH and return the portion from
@@ -281,7 +286,7 @@ parse_mailpath_spec (str)
          continue;
        }
       if (*s == '?' || *s == '%')
          continue;
        }
       if (*s == '?' || *s == '%')
-        return s;
+       return s;
     }
   return ((char *)NULL);
 }
     }
   return ((char *)NULL);
 }
@@ -289,13 +294,18 @@ parse_mailpath_spec (str)
 char *
 make_default_mailpath ()
 {
 char *
 make_default_mailpath ()
 {
+#if defined (DEFAULT_MAIL_DIRECTORY)
   char *mp;
 
   char *mp;
 
-  mp = xmalloc (2 + sizeof (DEFAULT_MAIL_DIRECTORY) + strlen (current_user.user_name));
+  get_current_user_info ();
+  mp = (char *)xmalloc (2 + sizeof (DEFAULT_MAIL_DIRECTORY) + strlen (current_user.user_name));
   strcpy (mp, DEFAULT_MAIL_DIRECTORY);
   mp[sizeof(DEFAULT_MAIL_DIRECTORY) - 1] = '/';
   strcpy (mp + sizeof (DEFAULT_MAIL_DIRECTORY), current_user.user_name);
   return (mp);
   strcpy (mp, DEFAULT_MAIL_DIRECTORY);
   mp[sizeof(DEFAULT_MAIL_DIRECTORY) - 1] = '/';
   strcpy (mp + sizeof (DEFAULT_MAIL_DIRECTORY), current_user.user_name);
   return (mp);
+#else
+  return ((char *)NULL);
+#endif
 }
 
 /* Remember the dates of the files specified by MAILPATH, or if there is
 }
 
 /* Remember the dates of the files specified by MAILPATH, or if there is
@@ -320,8 +330,11 @@ remember_mail_dates ()
   if (mailpaths == 0)
     {
       mailpaths = make_default_mailpath ();
   if (mailpaths == 0)
     {
       mailpaths = make_default_mailpath ();
-      add_mail_file (mailpaths, (char *)NULL);
-      free (mailpaths);
+      if (mailpaths)
+       {
+         add_mail_file (mailpaths, (char *)NULL);
+         free (mailpaths);
+       }
       return;
     }
 
       return;
     }
 
@@ -353,7 +366,6 @@ check_mail ()
   char *current_mail_file, *message;
   int i, use_user_notification;
   char *dollar_underscore, *temp;
   char *current_mail_file, *message;
   int i, use_user_notification;
   char *dollar_underscore, *temp;
-  WORD_LIST *tlist;
 
   dollar_underscore = get_string_value ("_");
   if (dollar_underscore)
 
   dollar_underscore = get_string_value ("_");
   if (dollar_underscore)
@@ -371,9 +383,9 @@ check_mail ()
          int file_is_bigger;
 
          use_user_notification = mailfiles[i]->msg != (char *)NULL;
          int file_is_bigger;
 
          use_user_notification = mailfiles[i]->msg != (char *)NULL;
-         message = mailfiles[i]->msg ? mailfiles[i]->msg : "You have mail in $_";
+         message = mailfiles[i]->msg ? mailfiles[i]->msg : _("You have mail in $_");
 
 
-         bind_variable ("_", current_mail_file);
+         bind_variable ("_", current_mail_file, 0);
 
 #define atime mailfiles[i]->access_time
 #define mtime mailfiles[i]->mod_time
 
 #define atime mailfiles[i]->access_time
 #define mtime mailfiles[i]->mod_time
@@ -396,16 +408,14 @@ check_mail ()
          /* If the mod time is later than the access time and the file
             has grown, note the fact that this is *new* mail. */
          if (use_user_notification == 0 && (atime < mtime) && file_is_bigger)
          /* If the mod time is later than the access time and the file
             has grown, note the fact that this is *new* mail. */
          if (use_user_notification == 0 && (atime < mtime) && file_is_bigger)
-           message = "You have new mail in $_";
+           message = _("You have new mail in $_");
 #undef atime
 #undef mtime
 
 #undef atime
 #undef mtime
 
-         if ((tlist = expand_string (message, Q_DOUBLE_QUOTES)))
+         if (temp = expand_string_to_string (message, Q_DOUBLE_QUOTES))
            {
            {
-             temp = string_list (tlist);
              puts (temp);
              free (temp);
              puts (temp);
              free (temp);
-             dispose_words (tlist);
            }
          else
            putchar ('\n');
            }
          else
            putchar ('\n');
@@ -414,13 +424,13 @@ check_mail ()
       if (mail_warning && file_access_date_changed (i))
        {
          update_mail_file (i);
       if (mail_warning && file_access_date_changed (i))
        {
          update_mail_file (i);
-         printf ("The mail in %s has been read\n", current_mail_file);
+         printf (_("The mail in %s has been read\n"), current_mail_file);
        }
     }
 
   if (dollar_underscore)
     {
        }
     }
 
   if (dollar_underscore)
     {
-      bind_variable ("_", dollar_underscore);
+      bind_variable ("_", dollar_underscore, 0);
       free (dollar_underscore);
     }
   else
       free (dollar_underscore);
     }
   else