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.c129
1 files changed, 77 insertions, 52 deletions
diff --git a/lib-src/movemail.c b/lib-src/movemail.c
index 682aa10aa39..e8c09f090f3 100644
--- a/lib-src/movemail.c
+++ b/lib-src/movemail.c
@@ -80,13 +80,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
80#undef access 80#undef access
81#endif /* MSDOS */ 81#endif /* MSDOS */
82 82
83#ifndef DIRECTORY_SEP
84#define DIRECTORY_SEP '/'
85#endif
86#ifndef IS_DIRECTORY_SEP
87#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
88#endif
89
90#ifdef WINDOWSNT 83#ifdef WINDOWSNT
91#include "ntlib.h" 84#include "ntlib.h"
92#undef access 85#undef access
@@ -138,7 +131,7 @@ extern int lk_open (), lk_close ();
138 files appear in. */ 131 files appear in. */
139#ifdef MAILDIR 132#ifdef MAILDIR
140#define MAIL_USE_MAILLOCK 133#define MAIL_USE_MAILLOCK
141static char *mail_spool_name (); 134static char *mail_spool_name (char *);
142#endif 135#endif
143#endif 136#endif
144 137
@@ -161,7 +154,7 @@ static int mbx_delimit_end (FILE *mbf);
161#endif 154#endif
162 155
163/* Nonzero means this is name of a lock file to delete on fatal error. */ 156/* Nonzero means this is name of a lock file to delete on fatal error. */
164char *delete_lockname; 157static char *delete_lockname;
165 158
166int 159int
167main (int argc, char **argv) 160main (int argc, char **argv)
@@ -169,15 +162,15 @@ main (int argc, char **argv)
169 char *inname, *outname; 162 char *inname, *outname;
170 int indesc, outdesc; 163 int indesc, outdesc;
171 ssize_t nread; 164 ssize_t nread;
172 int status; 165 int wait_status;
173 int c, preserve_mail = 0; 166 int c, preserve_mail = 0;
174 167
175#ifndef MAIL_USE_SYSTEM_LOCK 168#ifndef MAIL_USE_SYSTEM_LOCK
176 struct stat st; 169 struct stat st;
177 long now;
178 int tem; 170 int tem;
179 char *lockname, *p; 171 char *lockname;
180 char *tempname; 172 char *tempname;
173 size_t inname_dirlen;
181 int desc; 174 int desc;
182#endif /* not MAIL_USE_SYSTEM_LOCK */ 175#endif /* not MAIL_USE_SYSTEM_LOCK */
183 176
@@ -266,9 +259,22 @@ main (int argc, char **argv)
266#ifndef MAIL_USE_SYSTEM_LOCK 259#ifndef MAIL_USE_SYSTEM_LOCK
267#ifdef MAIL_USE_MAILLOCK 260#ifdef MAIL_USE_MAILLOCK
268 spool_name = mail_spool_name (inname); 261 spool_name = mail_spool_name (inname);
269 if (! spool_name) 262 if (spool_name)
263 {
264#ifdef lint
265 lockname = 0;
266#endif
267 }
268 else
270#endif 269#endif
271 { 270 {
271 #ifndef DIRECTORY_SEP
272 #define DIRECTORY_SEP '/'
273 #endif
274 #ifndef IS_DIRECTORY_SEP
275 #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
276 #endif
277
272 /* Use a lock file named after our first argument with .lock appended: 278 /* Use a lock file named after our first argument with .lock appended:
273 If it exists, the mail file is locked. */ 279 If it exists, the mail file is locked. */
274 /* Note: this locking mechanism is *required* by the mailer 280 /* Note: this locking mechanism is *required* by the mailer
@@ -293,26 +299,38 @@ main (int argc, char **argv)
293 to bug-gnu-emacs@prep.ai.mit.edu so we can fix it. */ 299 to bug-gnu-emacs@prep.ai.mit.edu so we can fix it. */
294 300
295 lockname = concat (inname, ".lock", ""); 301 lockname = concat (inname, ".lock", "");
296 tempname = (char *) xmalloc (strlen (inname) + strlen ("EXXXXXX") + 1); 302 for (inname_dirlen = strlen (inname);
297 strcpy (tempname, inname); 303 inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]);
298 p = tempname + strlen (tempname); 304 inname_dirlen--)
299 while (p != tempname && !IS_DIRECTORY_SEP (p[-1])) 305 continue;
300 p--; 306 tempname = (char *) xmalloc (inname_dirlen + sizeof "EXXXXXX");
301 *p = 0;
302 strcpy (p, "EXXXXXX");
303 mktemp (tempname);
304 unlink (tempname);
305 307
306 while (1) 308 while (1)
307 { 309 {
308 /* Create the lock file, but not under the lock file name. */ 310 /* Create the lock file, but not under the lock file name. */
309 /* Give up if cannot do that. */ 311 /* Give up if cannot do that. */
310 desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0666); 312
313 memcpy (tempname, inname, inname_dirlen);
314 strcpy (tempname + inname_dirlen, "EXXXXXX");
315#ifdef HAVE_MKSTEMP
316 desc = mkstemp (tempname);
317#else
318 mktemp (tempname);
319 if (!*tempname)
320 desc = -1;
321 else
322 {
323 unlink (tempname);
324 desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0600);
325 }
326#endif
311 if (desc < 0) 327 if (desc < 0)
312 { 328 {
329 int mkstemp_errno = errno;
313 char *message = (char *) xmalloc (strlen (tempname) + 50); 330 char *message = (char *) xmalloc (strlen (tempname) + 50);
314 sprintf (message, "creating %s, which would become the lock file", 331 sprintf (message, "creating %s, which would become the lock file",
315 tempname); 332 tempname);
333 errno = mkstemp_errno;
316 pfatal_with_name (message); 334 pfatal_with_name (message);
317 } 335 }
318 close (desc); 336 close (desc);
@@ -336,7 +354,7 @@ main (int argc, char **argv)
336 by time differences between machines. */ 354 by time differences between machines. */
337 if (stat (lockname, &st) >= 0) 355 if (stat (lockname, &st) >= 0)
338 { 356 {
339 now = time (0); 357 time_t now = time (0);
340 if (st.st_ctime < now - 300) 358 if (st.st_ctime < now - 300)
341 unlink (lockname); 359 unlink (lockname);
342 } 360 }
@@ -352,7 +370,10 @@ main (int argc, char **argv)
352 int lockcount = 0; 370 int lockcount = 0;
353 int status = 0; 371 int status = 0;
354#if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) 372#if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK)
355 time_t touched_lock, now; 373 time_t touched_lock;
374# ifdef lint
375 touched_lock = 0;
376# endif
356#endif 377#endif
357 378
358 if (setuid (getuid ()) < 0 || setregid (-1, real_gid) < 0) 379 if (setuid (getuid ()) < 0 || setregid (-1, real_gid) < 0)
@@ -462,7 +483,7 @@ main (int argc, char **argv)
462#if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) 483#if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK)
463 if (spool_name) 484 if (spool_name)
464 { 485 {
465 now = time (0); 486 time_t now = time (0);
466 if (now - touched_lock > 60) 487 if (now - touched_lock > 60)
467 { 488 {
468 touchlock (); 489 touchlock ();
@@ -527,11 +548,11 @@ main (int argc, char **argv)
527 exit (EXIT_SUCCESS); 548 exit (EXIT_SUCCESS);
528 } 549 }
529 550
530 wait (&status); 551 wait (&wait_status);
531 if (!WIFEXITED (status)) 552 if (!WIFEXITED (wait_status))
532 exit (EXIT_FAILURE); 553 exit (EXIT_FAILURE);
533 else if (WRETCODE (status) != 0) 554 else if (WRETCODE (wait_status) != 0)
534 exit (WRETCODE (status)); 555 exit (WRETCODE (wait_status));
535 556
536#if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK) 557#if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK)
537#ifdef MAIL_USE_MAILLOCK 558#ifdef MAIL_USE_MAILLOCK
@@ -670,14 +691,8 @@ xmalloc (unsigned int size)
670 691
671#define NOTOK (-1) 692#define NOTOK (-1)
672#define OK 0 693#define OK 0
673#define DONE 1 694
674 695static char Errmsg[200]; /* POP errors, at least, can exceed
675char *progname;
676FILE *sfi;
677FILE *sfo;
678char ibuffer[BUFSIZ];
679char obuffer[BUFSIZ];
680char Errmsg[200]; /* POP errors, at least, can exceed
681 the original length of 80. */ 696 the original length of 80. */
682 697
683/* 698/*
@@ -736,7 +751,18 @@ popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse
736 error ("Error in open: %s, %s", strerror (errno), outfile); 751 error ("Error in open: %s, %s", strerror (errno), outfile);
737 return EXIT_FAILURE; 752 return EXIT_FAILURE;
738 } 753 }
739 fchown (mbfi, getuid (), -1); 754
755 if (fchown (mbfi, getuid (), -1) != 0)
756 {
757 int fchown_errno = errno;
758 struct stat st;
759 if (fstat (mbfi, &st) != 0 || st.st_uid != getuid ())
760 {
761 pop_close (server);
762 error ("Error in fchown: %s, %s", strerror (fchown_errno), outfile);
763 return EXIT_FAILURE;
764 }
765 }
740 766
741 if ((mbf = fdopen (mbfi, "wb")) == NULL) 767 if ((mbf = fdopen (mbfi, "wb")) == NULL)
742 { 768 {
@@ -828,10 +854,10 @@ pop_retr (popserver server, int msgno, FILE *arg)
828 854
829 if (pop_retrieve_first (server, msgno, &line)) 855 if (pop_retrieve_first (server, msgno, &line))
830 { 856 {
831 char *error = concat ("Error from POP server: ", pop_error, ""); 857 char *msg = concat ("Error from POP server: ", pop_error, "");
832 strncpy (Errmsg, error, sizeof (Errmsg)); 858 strncpy (Errmsg, msg, sizeof (Errmsg));
833 Errmsg[sizeof (Errmsg)-1] = '\0'; 859 Errmsg[sizeof (Errmsg)-1] = '\0';
834 free(error); 860 free (msg);
835 return (NOTOK); 861 return (NOTOK);
836 } 862 }
837 863
@@ -850,27 +876,26 @@ pop_retr (popserver server, int msgno, FILE *arg)
850 876
851 if (ret) 877 if (ret)
852 { 878 {
853 char *error = concat ("Error from POP server: ", pop_error, ""); 879 char *msg = concat ("Error from POP server: ", pop_error, "");
854 strncpy (Errmsg, error, sizeof (Errmsg)); 880 strncpy (Errmsg, msg, sizeof (Errmsg));
855 Errmsg[sizeof (Errmsg)-1] = '\0'; 881 Errmsg[sizeof (Errmsg)-1] = '\0';
856 free(error); 882 free (msg);
857 return (NOTOK); 883 return (NOTOK);
858 } 884 }
859 885
860 return (OK); 886 return (OK);
861} 887}
862 888
863/* Do this as a macro instead of using strcmp to save on execution time. */
864#define IS_FROM_LINE(a) ((a[0] == 'F') \
865 && (a[1] == 'r') \
866 && (a[2] == 'o') \
867 && (a[3] == 'm') \
868 && (a[4] == ' '))
869
870static int 889static int
871mbx_write (char *line, int len, FILE *mbf) 890mbx_write (char *line, int len, FILE *mbf)
872{ 891{
873#ifdef MOVEMAIL_QUOTE_POP_FROM_LINES 892#ifdef MOVEMAIL_QUOTE_POP_FROM_LINES
893 /* Do this as a macro instead of using strcmp to save on execution time. */
894 # define IS_FROM_LINE(a) ((a[0] == 'F') \
895 && (a[1] == 'r') \
896 && (a[2] == 'o') \
897 && (a[3] == 'm') \
898 && (a[4] == ' '))
874 if (IS_FROM_LINE (line)) 899 if (IS_FROM_LINE (line))
875 { 900 {
876 if (fputc ('>', mbf) == EOF) 901 if (fputc ('>', mbf) == EOF)