Mercurial > emacs
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); |