aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src/movemail.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib-src/movemail.c')
-rw-r--r--lib-src/movemail.c150
1 files changed, 45 insertions, 105 deletions
diff --git a/lib-src/movemail.c b/lib-src/movemail.c
index b6ea51f6341..264b3d292c6 100644
--- a/lib-src/movemail.c
+++ b/lib-src/movemail.c
@@ -1,7 +1,7 @@
1/* movemail foo bar -- move file foo to file bar, 1/* movemail foo bar -- move file foo to file bar,
2 locking file foo the way /bin/mail respects. 2 locking file foo the way /bin/mail respects.
3 3
4Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2011 4Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2012
5 Free Software Foundation, Inc. 5 Free Software Foundation, Inc.
6 6
7This file is part of GNU Emacs. 7This file is part of GNU Emacs.
@@ -22,7 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 22
23/* Important notice: defining MAIL_USE_FLOCK or MAIL_USE_LOCKF *will 23/* Important notice: defining MAIL_USE_FLOCK or MAIL_USE_LOCKF *will
24 cause loss of mail* if you do it on a system that does not normally 24 cause loss of mail* if you do it on a system that does not normally
25 use flock as its way of interlocking access to inbox files. The 25 use flock/lockf as its way of interlocking access to inbox files. The
26 setting of MAIL_USE_FLOCK and MAIL_USE_LOCKF *must agree* with the 26 setting of MAIL_USE_FLOCK and MAIL_USE_LOCKF *must agree* with the
27 system's own conventions. It is not a choice that is up to you. 27 system's own conventions. It is not a choice that is up to you.
28 28
@@ -65,9 +65,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
65 65
66#include <getopt.h> 66#include <getopt.h>
67#include <unistd.h> 67#include <unistd.h>
68#ifdef HAVE_FCNTL_H
69#include <fcntl.h> 68#include <fcntl.h>
70#endif
71#include <string.h> 69#include <string.h>
72#include "syswait.h" 70#include "syswait.h"
73#ifdef MAIL_USE_POP 71#ifdef MAIL_USE_POP
@@ -98,17 +96,15 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
98#include <fcntl.h> 96#include <fcntl.h>
99#endif /* WINDOWSNT */ 97#endif /* WINDOWSNT */
100 98
101#ifndef F_OK
102#define F_OK 0
103#define X_OK 1
104#define W_OK 2
105#define R_OK 4
106#endif
107
108#ifdef WINDOWSNT 99#ifdef WINDOWSNT
109#include <sys/locking.h> 100#include <sys/locking.h>
110#endif 101#endif
111 102
103/* If your system uses the `flock' or `lockf' system call for mail locking,
104 define MAIL_USE_SYSTEM_LOCK. If your system type should always define
105 MAIL_USE_LOCKF or MAIL_USE_FLOCK but configure does not do this,
106 please make a bug report. */
107
112#ifdef MAIL_USE_LOCKF 108#ifdef MAIL_USE_LOCKF
113#define MAIL_USE_SYSTEM_LOCK 109#define MAIL_USE_SYSTEM_LOCK
114#endif 110#endif
@@ -133,16 +129,10 @@ static char *mail_spool_name (char *);
133#endif 129#endif
134#endif 130#endif
135 131
136#ifndef HAVE_STRERROR 132static _Noreturn void fatal (const char *s1, const char *s2, const char *s3);
137char *strerror (int);
138#endif
139
140static void fatal (const char *s1, const char *s2, const char *s3) NO_RETURN;
141static void error (const char *s1, const char *s2, const char *s3); 133static void error (const char *s1, const char *s2, const char *s3);
142static void pfatal_with_name (char *name) NO_RETURN; 134static _Noreturn void pfatal_with_name (char *name);
143static void pfatal_and_delete (char *name) NO_RETURN; 135static _Noreturn void pfatal_and_delete (char *name);
144static char *concat (const char *s1, const char *s2, const char *s3);
145static long *xmalloc (unsigned int size);
146#ifdef MAIL_USE_POP 136#ifdef MAIL_USE_POP
147static int popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse_order); 137static int popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse_order);
148static int pop_retr (popserver server, int msgno, FILE *arg); 138static int pop_retr (popserver server, int msgno, FILE *arg);
@@ -151,6 +141,21 @@ static int mbx_delimit_begin (FILE *mbf);
151static int mbx_delimit_end (FILE *mbf); 141static int mbx_delimit_end (FILE *mbf);
152#endif 142#endif
153 143
144#if (defined MAIL_USE_MAILLOCK \
145 || (!defined DISABLE_DIRECT_ACCESS && !defined MAIL_USE_MMDF \
146 && !defined MAIL_USE_SYSTEM_LOCK))
147/* Like malloc but get fatal error if memory is exhausted. */
148
149static void *
150xmalloc (size_t size)
151{
152 void *result = malloc (size);
153 if (!result)
154 fatal ("virtual memory exhausted", 0, 0);
155 return result;
156}
157#endif
158
154/* Nonzero means this is name of a lock file to delete on fatal error. */ 159/* Nonzero means this is name of a lock file to delete on fatal error. */
155static char *delete_lockname; 160static char *delete_lockname;
156 161
@@ -168,7 +173,7 @@ main (int argc, char **argv)
168 int tem; 173 int tem;
169 char *lockname; 174 char *lockname;
170 char *tempname; 175 char *tempname;
171 size_t inname_dirlen; 176 size_t inname_len, inname_dirlen;
172 int desc; 177 int desc;
173#endif /* not MAIL_USE_SYSTEM_LOCK */ 178#endif /* not MAIL_USE_SYSTEM_LOCK */
174 179
@@ -266,13 +271,6 @@ main (int argc, char **argv)
266 else 271 else
267#endif 272#endif
268 { 273 {
269 #ifndef DIRECTORY_SEP
270 #define DIRECTORY_SEP '/'
271 #endif
272 #ifndef IS_DIRECTORY_SEP
273 #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
274 #endif
275
276 /* Use a lock file named after our first argument with .lock appended: 274 /* Use a lock file named after our first argument with .lock appended:
277 If it exists, the mail file is locked. */ 275 If it exists, the mail file is locked. */
278 /* Note: this locking mechanism is *required* by the mailer 276 /* Note: this locking mechanism is *required* by the mailer
@@ -281,27 +279,23 @@ main (int argc, char **argv)
281 On systems that use a lock file, extracting the mail without locking 279 On systems that use a lock file, extracting the mail without locking
282 WILL occasionally cause loss of mail due to timing errors! 280 WILL occasionally cause loss of mail due to timing errors!
283 281
284 So, if creation of the lock file fails 282 So, if creation of the lock file fails due to access
285 due to access permission on the mail spool directory, 283 permission on the mail spool directory, you simply MUST
286 you simply MUST change the permission 284 change the permission and/or make movemail a setgid program
287 and/or make movemail a setgid program
288 so it can create lock files properly. 285 so it can create lock files properly.
289 286
290 You might also wish to verify that your system is one 287 You might also wish to verify that your system is one which
291 which uses lock files for this purpose. Some systems use other methods. 288 uses lock files for this purpose. Some systems use other methods. */
292 289
293 If your system uses the `flock' system call for mail locking, 290 inname_len = strlen (inname);
294 define MAIL_USE_SYSTEM_LOCK in config.h or the s-*.h file 291 lockname = xmalloc (inname_len + sizeof ".lock");
295 and recompile movemail. If the s- file for your system 292 strcpy (lockname, inname);
296 should define MAIL_USE_SYSTEM_LOCK but does not, send a bug report 293 strcpy (lockname + inname_len, ".lock");
297 to bug-gnu-emacs@prep.ai.mit.edu so we can fix it. */ 294 for (inname_dirlen = inname_len;
298
299 lockname = concat (inname, ".lock", "");
300 for (inname_dirlen = strlen (inname);
301 inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]); 295 inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]);
302 inname_dirlen--) 296 inname_dirlen--)
303 continue; 297 continue;
304 tempname = (char *) xmalloc (inname_dirlen + sizeof "EXXXXXX"); 298 tempname = xmalloc (inname_dirlen + sizeof "EXXXXXX");
305 299
306 while (1) 300 while (1)
307 { 301 {
@@ -334,11 +328,8 @@ main (int argc, char **argv)
334 328
335 tem = link (tempname, lockname); 329 tem = link (tempname, lockname);
336 330
337#ifdef EPERM 331 if (tem < 0 && errno != EEXIST)
338 if (tem < 0 && errno == EPERM) 332 pfatal_with_name (lockname);
339 fatal ("Unable to create hard link between %s and %s",
340 tempname, lockname);
341#endif
342 333
343 unlink (tempname); 334 unlink (tempname);
344 if (tem >= 0) 335 if (tem >= 0)
@@ -548,8 +539,8 @@ main (int argc, char **argv)
548 wait (&wait_status); 539 wait (&wait_status);
549 if (!WIFEXITED (wait_status)) 540 if (!WIFEXITED (wait_status))
550 exit (EXIT_FAILURE); 541 exit (EXIT_FAILURE);
551 else if (WRETCODE (wait_status) != 0) 542 else if (WEXITSTATUS (wait_status) != 0)
552 exit (WRETCODE (wait_status)); 543 exit (WEXITSTATUS (wait_status));
553 544
554#if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK) 545#if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK)
555#ifdef MAIL_USE_MAILLOCK 546#ifdef MAIL_USE_MAILLOCK
@@ -583,8 +574,8 @@ mail_spool_name (char *inname)
583 if (stat (MAILDIR, &stat1) < 0) 574 if (stat (MAILDIR, &stat1) < 0)
584 return NULL; 575 return NULL;
585 576
586 indir = (char *) xmalloc (fname - inname + 1); 577 indir = xmalloc (fname - inname + 1);
587 strncpy (indir, inname, fname - inname); 578 memcpy (indir, inname, fname - inname);
588 indir[fname-inname] = '\0'; 579 indir[fname-inname] = '\0';
589 580
590 581
@@ -643,33 +634,6 @@ pfatal_and_delete (char *name)
643 unlink (name); 634 unlink (name);
644 fatal ("%s for %s", s, name); 635 fatal ("%s for %s", s, name);
645} 636}
646
647/* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */
648
649static char *
650concat (const char *s1, const char *s2, const char *s3)
651{
652 size_t len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
653 char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
654
655 strcpy (result, s1);
656 strcpy (result + len1, s2);
657 strcpy (result + len1 + len2, s3);
658 *(result + len1 + len2 + len3) = 0;
659
660 return result;
661}
662
663/* Like malloc but get fatal error if memory is exhausted. */
664
665static long *
666xmalloc (unsigned int size)
667{
668 long *result = (long *) malloc (size);
669 if (!result)
670 fatal ("virtual memory exhausted", 0, 0);
671 return result;
672}
673 637
674/* This is the guts of the interface to the Post Office Protocol. */ 638/* This is the guts of the interface to the Post Office Protocol. */
675 639
@@ -851,10 +815,7 @@ pop_retr (popserver server, int msgno, FILE *arg)
851 815
852 if (pop_retrieve_first (server, msgno, &line)) 816 if (pop_retrieve_first (server, msgno, &line))
853 { 817 {
854 char *msg = concat ("Error from POP server: ", pop_error, ""); 818 snprintf (Errmsg, sizeof Errmsg, "Error from POP server: %s", pop_error);
855 strncpy (Errmsg, msg, sizeof (Errmsg));
856 Errmsg[sizeof (Errmsg)-1] = '\0';
857 free (msg);
858 return (NOTOK); 819 return (NOTOK);
859 } 820 }
860 821
@@ -873,10 +834,7 @@ pop_retr (popserver server, int msgno, FILE *arg)
873 834
874 if (ret) 835 if (ret)
875 { 836 {
876 char *msg = concat ("Error from POP server: ", pop_error, ""); 837 snprintf (Errmsg, sizeof Errmsg, "Error from POP server: %s", pop_error);
877 strncpy (Errmsg, msg, sizeof (Errmsg));
878 Errmsg[sizeof (Errmsg)-1] = '\0';
879 free (msg);
880 return (NOTOK); 838 return (NOTOK);
881 } 839 }
882 840
@@ -939,21 +897,3 @@ mbx_delimit_end (FILE *mbf)
939} 897}
940 898
941#endif /* MAIL_USE_POP */ 899#endif /* MAIL_USE_POP */
942
943#ifndef HAVE_STRERROR
944char *
945strerror (errnum)
946 int errnum;
947{
948 extern char *sys_errlist[];
949 extern int sys_nerr;
950
951 if (errnum >= 0 && errnum < sys_nerr)
952 return sys_errlist[errnum];
953 return (char *) "Unknown error";
954}
955
956#endif /* ! HAVE_STRERROR */
957
958
959/* movemail.c ends here */