comparison lib-src/movemail.c @ 5435:d7408b99b88f

Include syswait.h. Fork a subprocess and use it to copy the mail file.
author Richard M. Stallman <rms@gnu.org>
date Tue, 04 Jan 1994 06:46:12 +0000
parents 60fa1ee0c98c
children 726a3dc867a6
comparison
equal deleted inserted replaced
5434:c89fd1fbf068 5435:d7408b99b88f
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 Copyright (C) 1986, 1992 Free Software Foundation, Inc. 3 Copyright (C) 1986, 1992, 1993 Free Software Foundation, Inc.
4 4
5 This file is part of GNU Emacs. 5 This file is part of GNU Emacs.
6 6
7 GNU Emacs is free software; you can redistribute it and/or modify 7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
52 #include <sys/stat.h> 52 #include <sys/stat.h>
53 #include <sys/file.h> 53 #include <sys/file.h>
54 #include <errno.h> 54 #include <errno.h>
55 #define NO_SHORTNAMES /* Tell config not to load remap.h */ 55 #define NO_SHORTNAMES /* Tell config not to load remap.h */
56 #include <../src/config.h> 56 #include <../src/config.h>
57 #include <../src/syswait.h>
57 58
58 #ifdef USG 59 #ifdef USG
59 #include <fcntl.h> 60 #include <fcntl.h>
60 #include <unistd.h> 61 #include <unistd.h>
61 #ifndef F_OK 62 #ifndef F_OK
96 char **argv; 97 char **argv;
97 { 98 {
98 char *inname, *outname; 99 char *inname, *outname;
99 int indesc, outdesc; 100 int indesc, outdesc;
100 int nread; 101 int nread;
102 WAITTYPE status;
101 103
102 #ifndef MAIL_USE_FLOCK 104 #ifndef MAIL_USE_FLOCK
103 struct stat st; 105 struct stat st;
104 long now; 106 long now;
105 int tem; 107 int tem;
197 199
198 while (1) 200 while (1)
199 { 201 {
200 /* Create the lock file, but not under the lock file name. */ 202 /* Create the lock file, but not under the lock file name. */
201 /* Give up if cannot do that. */ 203 /* Give up if cannot do that. */
202 desc = open (tempname, O_WRONLY | O_CREAT, 0666); 204 desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0666);
203 if (desc < 0) 205 if (desc < 0)
204 pfatal_with_name ("lock file--see source file lib-src/movemail.c"); 206 pfatal_with_name ("lock file--see source file lib-src/movemail.c");
205 close (desc); 207 close (desc);
206 208
207 tem = link (tempname, lockname); 209 tem = link (tempname, lockname);
208 unlink (tempname); 210 unlink (tempname);
209 if (tem >= 0) 211 if (tem >= 0)
220 } 222 }
221 223
222 delete_lockname = lockname; 224 delete_lockname = lockname;
223 #endif /* not MAIL_USE_FLOCK */ 225 #endif /* not MAIL_USE_FLOCK */
224 226
227 if (fork () == 0)
228 {
229 seteuid (getuid ());
230
225 #ifdef MAIL_USE_FLOCK 231 #ifdef MAIL_USE_FLOCK
226 indesc = open (inname, O_RDWR); 232 indesc = open (inname, O_RDWR);
227 #else /* if not MAIL_USE_FLOCK */ 233 #else /* if not MAIL_USE_FLOCK */
228 indesc = open (inname, O_RDONLY); 234 indesc = open (inname, O_RDONLY);
229 #endif /* not MAIL_USE_FLOCK */ 235 #endif /* not MAIL_USE_FLOCK */
230 #else /* MAIL_USE_MMDF */ 236 #else /* MAIL_USE_MMDF */
231 indesc = lk_open (inname, O_RDONLY, 0, 0, 10); 237 indesc = lk_open (inname, O_RDONLY, 0, 0, 10);
232 #endif /* MAIL_USE_MMDF */ 238 #endif /* MAIL_USE_MMDF */
233 239
234 if (indesc < 0) 240 if (indesc < 0)
235 pfatal_with_name (inname); 241 pfatal_with_name (inname);
236 242
237 #if defined (BSD) || defined (XENIX) 243 #if defined (BSD) || defined (XENIX)
238 /* In case movemail is setuid to root, make sure the user can 244 /* In case movemail is setuid to root, make sure the user can
239 read the output file. */ 245 read the output file. */
240 /* This is desirable for all systems 246 /* This is desirable for all systems
241 but I don't want to assume all have the umask system call */ 247 but I don't want to assume all have the umask system call */
242 umask (umask (0) & 0333); 248 umask (umask (0) & 0333);
243 #endif /* BSD or Xenix */ 249 #endif /* BSD or Xenix */
244 outdesc = open (outname, O_WRONLY | O_CREAT | O_EXCL, 0666); 250 outdesc = open (outname, O_WRONLY | O_CREAT | O_EXCL, 0666);
245 if (outdesc < 0) 251 if (outdesc < 0)
246 pfatal_with_name (outname); 252 pfatal_with_name (outname);
247 #ifdef MAIL_USE_FLOCK 253 #ifdef MAIL_USE_FLOCK
248 #ifdef XENIX 254 #ifdef XENIX
249 if (locking (indesc, LK_RLCK, 0L) < 0) pfatal_with_name (inname); 255 if (locking (indesc, LK_RLCK, 0L) < 0) pfatal_with_name (inname);
250 #else 256 #else
251 if (flock (indesc, LOCK_EX) < 0) pfatal_with_name (inname); 257 if (flock (indesc, LOCK_EX) < 0) pfatal_with_name (inname);
252 #endif 258 #endif
253 #endif /* MAIL_USE_FLOCK */ 259 #endif /* MAIL_USE_FLOCK */
254 260
255 {
256 char buf[1024];
257
258 while (1)
259 { 261 {
260 nread = read (indesc, buf, sizeof buf); 262 char buf[1024];
261 if (nread != write (outdesc, buf, nread)) 263
264 while (1)
262 { 265 {
263 int saved_errno = errno; 266 nread = read (indesc, buf, sizeof buf);
264 unlink (outname); 267 if (nread != write (outdesc, buf, nread))
265 errno = saved_errno; 268 {
266 pfatal_with_name (outname); 269 int saved_errno = errno;
270 unlink (outname);
271 errno = saved_errno;
272 pfatal_with_name (outname);
273 }
274 if (nread < sizeof buf)
275 break;
267 } 276 }
268 if (nread < sizeof buf)
269 break;
270 } 277 }
271 }
272 278
273 #ifdef BSD 279 #ifdef BSD
274 if (fsync (outdesc) < 0) 280 if (fsync (outdesc) < 0)
275 pfatal_and_delete (outname); 281 pfatal_and_delete (outname);
276 #endif 282 #endif
277 283
278 /* Check to make sure no errors before we zap the inbox. */ 284 /* Check to make sure no errors before we zap the inbox. */
279 if (close (outdesc) != 0) 285 if (close (outdesc) != 0)
280 pfatal_and_delete (outname); 286 pfatal_and_delete (outname);
281 287
282 #ifdef MAIL_USE_FLOCK 288 #ifdef MAIL_USE_FLOCK
283 #if defined (STRIDE) || defined (XENIX) 289 #if defined (STRIDE) || defined (XENIX)
284 /* Stride, xenix have file locking, but no ftruncate. This mess will do. */ 290 /* Stride, xenix have file locking, but no ftruncate. This mess will do. */
285 close (open (inname, O_CREAT | O_TRUNC | O_RDWR, 0666)); 291 close (open (inname, O_CREAT | O_TRUNC | O_RDWR, 0666));
286 #else 292 #else
287 ftruncate (indesc, 0L); 293 ftruncate (indesc, 0L);
288 #endif /* STRIDE or XENIX */ 294 #endif /* STRIDE or XENIX */
289 #endif /* MAIL_USE_FLOCK */ 295 #endif /* MAIL_USE_FLOCK */
290 296
291 #ifdef MAIL_USE_MMDF 297 #ifdef MAIL_USE_MMDF
292 lk_close (indesc, 0, 0, 0); 298 lk_close (indesc, 0, 0, 0);
293 #else 299 #else
294 close (indesc); 300 close (indesc);
295 #endif 301 #endif
296 302
297 #ifndef MAIL_USE_FLOCK 303 #ifndef MAIL_USE_FLOCK
298 /* Delete the input file; if we can't, at least get rid of its contents. */ 304 /* Delete the input file; if we can't, at least get rid of its contents. */
299 #ifdef MAIL_UNLINK_SPOOL 305 #ifdef MAIL_UNLINK_SPOOL
300 /* This is generally bad to do, because it destroys the permissions 306 /* This is generally bad to do, because it destroys the permissions
301 that were set on the file. Better to just empty the file. */ 307 that were set on the file. Better to just empty the file. */
302 if (unlink (inname) < 0 && errno != ENOENT) 308 if (unlink (inname) < 0 && errno != ENOENT)
303 #endif /* MAIL_UNLINK_SPOOL */ 309 #endif /* MAIL_UNLINK_SPOOL */
304 creat (inname, 0600); 310 creat (inname, 0600);
311
312 exit (0);
313 }
314
315 wait (&status);
316 if (!WIFEXITED (status))
317 exit (1);
318 else if (WRETCODE (status) != 0)
319 exit (WRETCODE (status));
320
305 #ifndef MAIL_USE_MMDF 321 #ifndef MAIL_USE_MMDF
306 unlink (lockname); 322 unlink (lockname);
307 #endif /* not MAIL_USE_MMDF */ 323 #endif /* not MAIL_USE_MMDF */
308 #endif /* not MAIL_USE_FLOCK */ 324 #endif /* not MAIL_USE_FLOCK */
309 exit (0); 325 exit (0);