|
Lines 481-494
int safe_rename (const char *src, const
|
Link Here
|
|---|
|
return 0; | return 0; |
} | } |
| |
|
/* Create a temporary directory next to a file name */ |
|
|
|
int mutt_mkwrapdir (const char *path, char *newfile, size_t nflen, |
|
char *newdir, size_t ndlen) |
|
{ |
|
const char *basename; |
|
char parent[_POSIX_PATH_MAX]; |
|
char *p; |
|
int rv; |
|
|
|
strfcpy (parent, NONULL (path), sizeof (parent)); |
|
|
|
if ((p = strrchr (parent, '/'))) |
|
{ |
|
*p = '\0'; |
|
basename = p + 1; |
|
} |
|
else |
|
{ |
|
strfcpy (parent, ".", sizeof (parent)); |
|
basename = path; |
|
} |
|
|
|
do |
|
{ |
|
snprintf (newdir, ndlen, "%s/%s", parent, ".muttXXXXXX"); |
|
mktemp (newdir); |
|
} |
|
while ((rv = mkdir (newdir, 0700)) == -1 && errno == EEXIST); |
|
|
|
if (rv == -1) |
|
return -1; |
|
|
|
snprintf (newfile, nflen, "%s/%s", newdir, NONULL(basename)); |
|
return 0; |
|
} |
|
|
|
int mutt_put_file_in_place (const char *path, const char *safe_file, const char *safe_dir) |
|
{ |
|
int rv; |
|
|
|
rv = safe_rename (safe_file, path); |
|
unlink (safe_file); |
|
rmdir (safe_dir); |
|
return rv; |
|
} |
|
|
int safe_open (const char *path, int flags) | int safe_open (const char *path, int flags) |
{ | { |
struct stat osb, nsb; | struct stat osb, nsb; |
int fd; | int fd; |
| |
if ((fd = open (path, flags, 0600)) < 0) |
if (flags & O_EXCL) |
return fd; |
{ |
|
char safe_file[_POSIX_PATH_MAX]; |
|
char safe_dir[_POSIX_PATH_MAX]; |
| |
|
if (mutt_mkwrapdir (path, safe_file, sizeof (safe_file), |
|
safe_dir, sizeof (safe_dir)) == -1) |
|
return -1; |
|
|
|
if ((fd = open (safe_file, flags, 0600)) < 0) |
|
{ |
|
rmdir (safe_dir); |
|
return fd; |
|
} |
|
|
|
if (mutt_put_file_in_place (path, safe_file, safe_dir) == -1) |
|
{ |
|
close (fd); |
|
return -1; |
|
} |
|
} |
|
else |
|
{ |
|
if ((fd = open (path, flags, 0600)) < 0) |
|
return fd; |
|
} |
|
|
/* make sure the file is not symlink */ | /* make sure the file is not symlink */ |
if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 || | if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 || |
compare_stat(&osb, &nsb) == -1) | compare_stat(&osb, &nsb) == -1) |