]> code.delx.au - gnu-emacs/blobdiff - lib-src/fakemail.c
Johannes Weiner <hannes at saeurebad.de>
[gnu-emacs] / lib-src / fakemail.c
index d9af25d7dae1cc3f16172c035095229b1606a8a4..003f2da886c055ce92007b0037bf14c696d15917 100644 (file)
@@ -1,11 +1,12 @@
 /* sendmail-like interface to /bin/mail for system V,
 /* sendmail-like interface to /bin/mail for system V,
-   Copyright (C) 1985, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1994, 1999, 2001, 2002, 2003, 2004,
+                 2005, 2006, 2007  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 
 This file is part of GNU Emacs.
 
 GNU Emacs 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 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -15,14 +16,17 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #define NO_SHORTNAMES
 
 #define NO_SHORTNAMES
-#include <../src/config.h>
+#define _XOPEN_SOURCE 500      /* for cuserid */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 
-#if defined (BSD) && !defined (BSD4_1) && !defined (USE_FAKEMAIL)
+#if defined (BSD_SYSTEM) && !defined (BSD4_1) && !defined (USE_FAKEMAIL)
 /* This program isnot used in BSD, so just avoid loader complaints.  */
 int
 main ()
 /* This program isnot used in BSD, so just avoid loader complaints.  */
 int
 main ()
@@ -45,13 +49,6 @@ main ()
 #undef static
 #endif
 
 #undef static
 #endif
 
-#ifdef read
-#undef read
-#undef write
-#undef open
-#undef close
-#endif
-
 #ifdef WINDOWSNT
 #include "ntlib.h"
 #endif
 #ifdef WINDOWSNT
 #include "ntlib.h"
 #endif
@@ -61,6 +58,11 @@ main ()
 #include <ctype.h>
 #include <time.h>
 #include <pwd.h>
 #include <ctype.h>
 #include <time.h>
 #include <pwd.h>
+
+/* This is to declare cuserid.  */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 \f
 /* Type definitions */
 
 \f
 /* Type definitions */
 
@@ -68,6 +70,15 @@ main ()
 #define true 1
 #define false 0
 
 #define true 1
 #define false 0
 
+#define TM_YEAR_BASE 1900
+
+/* Nonzero if TM_YEAR is a struct tm's tm_year value that causes
+   asctime to have well-defined behavior.  */
+#ifndef TM_YEAR_IN_ASCTIME_RANGE
+# define TM_YEAR_IN_ASCTIME_RANGE(tm_year) \
+    (1000 - TM_YEAR_BASE <= (tm_year) && (tm_year) <= 9999 - TM_YEAR_BASE)
+#endif
+
 /* Various lists */
 
 struct line_record
 /* Various lists */
 
 struct line_record
@@ -84,7 +95,7 @@ struct header_record
   struct header_record *previous;
 };
 typedef struct header_record *header;
   struct header_record *previous;
 };
 typedef struct header_record *header;
-                       
+
 struct stream_record
 {
   FILE *handle;
 struct stream_record
 {
   FILE *handle;
@@ -164,11 +175,11 @@ error (s1, s2)
 /* Print error message and exit.  */
 
 static void
 /* Print error message and exit.  */
 
 static void
-fatal (s1, s2)
-     char *s1, *s2;
+fatal (s1)
+     char *s1;
 {
 {
-  error (s1, s2);
-  exit (1);
+  error ("%s", s1);
+  exit (EXIT_FAILURE);
 }
 
 /* Like malloc but get fatal error if memory is exhausted.  */
 }
 
 /* Like malloc but get fatal error if memory is exhausted.  */
@@ -179,7 +190,7 @@ xmalloc (size)
 {
   long *result = (long *) malloc (((unsigned) size));
   if (result == ((long *) NULL))
 {
   long *result = (long *) malloc (((unsigned) size));
   if (result == ((long *) NULL))
-    fatal ("virtual memory exhausted", 0);
+    fatal ("virtual memory exhausted");
   return result;
 }
 
   return result;
 }
 
@@ -205,8 +216,7 @@ init_linebuffer (linebuffer)
 }
 
 /* Read a line of text from `stream' into `linebuffer'.
 }
 
 /* Read a line of text from `stream' into `linebuffer'.
- * Return the length of the line.  
- */
+   Return the length of the line.  */
 
 long
 readline (linebuffer, stream)
 
 long
 readline (linebuffer, stream)
@@ -223,7 +233,7 @@ readline (linebuffer, stream)
       if (p == end)
        {
          linebuffer->size *= 2;
       if (p == end)
        {
          linebuffer->size *= 2;
-         buffer = ((char *) xrealloc (buffer, linebuffer->size));
+         buffer = ((char *) xrealloc ((long *)buffer, linebuffer->size));
          p = buffer + (p - linebuffer->buffer);
          end = buffer + linebuffer->size;
          linebuffer->buffer = buffer;
          p = buffer + (p - linebuffer->buffer);
          end = buffer + linebuffer->size;
          linebuffer->buffer = buffer;
@@ -252,18 +262,18 @@ get_keyword (field, rest)
 {
   static char keyword[KEYWORD_SIZE];
   register char *ptr;
 {
   static char keyword[KEYWORD_SIZE];
   register char *ptr;
-  register char c;
+  register int c;
 
   ptr = &keyword[0];
 
   ptr = &keyword[0];
-  c = *field++;
+  c = (unsigned char) *field++;
   if (isspace (c) || c == ':')
     return ((char *) NULL);
   *ptr++ = (islower (c) ? toupper (c) : c);
   if (isspace (c) || c == ':')
     return ((char *) NULL);
   *ptr++ = (islower (c) ? toupper (c) : c);
-  while (((c = *field++) != ':') && ! isspace (c))
+  while (((c = (unsigned char) *field++) != ':') && ! isspace (c))
     *ptr++ = (islower (c) ? toupper (c) : c);
   *ptr++ = '\0';
   while (isspace (c))
     *ptr++ = (islower (c) ? toupper (c) : c);
   *ptr++ = '\0';
   while (isspace (c))
-    c = *field++;
+    c = (unsigned char) *field++;
   if (c != ':')
     return ((char *) NULL);
   *rest = field;
   if (c != ':')
     return ((char *) NULL);
   *rest = field;
@@ -353,6 +363,7 @@ make_file_preface ()
 {
   char *the_string, *temp;
   long idiotic_interface;
 {
   char *the_string, *temp;
   long idiotic_interface;
+  struct tm *tm;
   long prefix_length;
   long user_length;
   long date_length;
   long prefix_length;
   long user_length;
   long date_length;
@@ -360,7 +371,13 @@ make_file_preface ()
 
   prefix_length = strlen (FROM_PREFIX);
   time (&idiotic_interface);
 
   prefix_length = strlen (FROM_PREFIX);
   time (&idiotic_interface);
-  the_date = ctime (&idiotic_interface);
+  /* Convert to a string, checking for out-of-range time stamps.
+     Don't use 'ctime', as that might dump core if the hardware clock
+     is set to a bizarre value.  */
+  tm = localtime (&idiotic_interface);
+  if (! (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year)
+        && (the_date = asctime (tm))))
+    fatal ("current time is out of range");
   /* the_date has an unwanted newline at the end */
   date_length = strlen (the_date) - 1;
   the_date[date_length] = '\0';
   /* the_date has an unwanted newline at the end */
   date_length = strlen (the_date) - 1;
   the_date[date_length] = '\0';
@@ -368,9 +385,9 @@ make_file_preface ()
   user_length = strlen (temp);
   the_user = alloc_string (user_length + 1);
   strcpy (the_user, temp);
   user_length = strlen (temp);
   the_user = alloc_string (user_length + 1);
   strcpy (the_user, temp);
-  the_string = alloc_string (3 + prefix_length +
-                            user_length +
-                            date_length);
+  the_string = alloc_string (3 + prefix_length
+                            + user_length
+                            date_length);
   temp = the_string;
   strcpy (temp, FROM_PREFIX);
   temp = &temp[prefix_length];
   temp = the_string;
   strcpy (temp, FROM_PREFIX);
   temp = &temp[prefix_length];
@@ -410,7 +427,7 @@ close_the_streams ()
     no_problems = (no_problems &&
                   ((*rem->action) (rem->handle) == 0));
   the_streams = ((stream_list) NULL);
     no_problems = (no_problems &&
                   ((*rem->action) (rem->handle) == 0));
   the_streams = ((stream_list) NULL);
-  return (no_problems ? 0 : 1);
+  return (no_problems ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
 void
 }
 
 void
@@ -594,6 +611,7 @@ args_size (the_header)
 
    Also, if the header has any FCC fields, call setup_files for each one.  */
 
 
    Also, if the header has any FCC fields, call setup_files for each one.  */
 
+void
 parse_header (the_header, where)
      header the_header;
      register char *where;
 parse_header (the_header, where)
      header the_header;
      register char *where;
@@ -620,13 +638,13 @@ parse_header (the_header, where)
   *where = '\0';
   return;
 }
   *where = '\0';
   return;
 }
-\f    
+\f
 /* Read lines from the input until we get a blank line.
    Create a list of `header' objects, one for each header field,
    each of which points to a list of `line_list' objects,
    one for each line in that field.
    Continuation lines are grouped in the headers they continue.  */
 /* Read lines from the input until we get a blank line.
    Create a list of `header' objects, one for each header field,
    each of which points to a list of `line_list' objects,
    one for each line in that field.
    Continuation lines are grouped in the headers they continue.  */
-   
+
 header
 read_header ()
 {
 header
 read_header ()
 {
@@ -666,7 +684,7 @@ read_header ()
       if (next_line == ((line_list *) NULL))
        {
          /* Not a valid header */
       if (next_line == ((line_list *) NULL))
        {
          /* Not a valid header */
-         exit (1);
+         exit (EXIT_FAILURE);
        }
       *next_line = new_list ();
       (*next_line)->string = alloc_string (length);
        }
       *next_line = new_list ();
       (*next_line)->string = alloc_string (length);
@@ -676,6 +694,8 @@ read_header ()
 
     } while (true);
 
 
     } while (true);
 
+  if (! the_header)
+    fatal ("input message has no header");
   return the_header->next;
 }
 \f
   return the_header->next;
 }
 \f
@@ -726,7 +746,7 @@ main (argc, argv)
   command_line = alloc_string (name_length + args_size (the_header));
   strcpy (command_line, mail_program_name);
   parse_header (the_header, &command_line[name_length]);
   command_line = alloc_string (name_length + args_size (the_header));
   strcpy (command_line, mail_program_name);
   parse_header (the_header, &command_line[name_length]);
-  
+
   the_pipe = popen (command_line, "w");
   if (the_pipe == ((FILE *) NULL))
     fatal ("cannot open pipe to real mailer");
   the_pipe = popen (command_line, "w");
   if (the_pipe == ((FILE *) NULL))
     fatal ("cannot open pipe to real mailer");
@@ -749,3 +769,8 @@ main (argc, argv)
 
 #endif /* not MSDOS */
 #endif /* not BSD 4.2 (or newer) */
 
 #endif /* not MSDOS */
 #endif /* not BSD 4.2 (or newer) */
+
+/* arch-tag: acb0afa6-315a-4c5b-b9e3-def5725c8783
+   (do not change this comment) */
+
+/* fakemail.c ends here */