return 0;
}
-int safe_symlink(const char *oldpath, const char *newpath)
-{
- struct stat osb, nsb;
-
- if (!oldpath || !newpath)
- return -1;
-
- if (unlink(newpath) == -1 && errno != ENOENT)
- return -1;
-
- if (oldpath[0] == '/')
- {
- if (symlink (oldpath, newpath) == -1)
- return -1;
- }
- else
- {
- char abs_oldpath[_POSIX_PATH_MAX];
-
- if ((getcwd (abs_oldpath, sizeof abs_oldpath) == NULL) ||
- (strlen (abs_oldpath) + 1 + strlen (oldpath) + 1 > sizeof abs_oldpath))
- return -1;
-
- strcat (abs_oldpath, "/"); /* __STRCAT_CHECKED__ */
- strcat (abs_oldpath, oldpath); /* __STRCAT_CHECKED__ */
- if (symlink (abs_oldpath, newpath) == -1)
- return -1;
- }
-
- if (stat(oldpath, &osb) == -1 || stat(newpath, &nsb) == -1
- || compare_stat(&osb, &nsb) == -1)
- {
- unlink(newpath);
- return -1;
- }
-
- return 0;
-}
-
/*
}
-/* Create a temporary directory next to a file name */
-
-static 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;
-
- strfcpy (parent, NONULL (path), sizeof (parent));
-
- if ((p = strrchr (parent, '/')))
- {
- *p = '\0';
- basename = p + 1;
- }
- else
- {
- strfcpy (parent, ".", sizeof (parent));
- basename = path;
- }
-
- snprintf (newdir, ndlen, "%s/%s", parent, ".muttXXXXXX");
- if (mkdtemp(newdir) == NULL)
- {
- dprint(1, (debugfile, "mutt_mkwrapdir: mkdtemp() failed\n"));
- return -1;
- }
-
- if (snprintf (newfile, nflen, "%s/%s", newdir, NONULL(basename)) >= nflen)
- {
- rmdir(newdir);
- dprint(1, (debugfile, "mutt_mkwrapdir: string was truncated\n"));
- return -1;
- }
- return 0;
-}
-
-/* remove a directory and everything under it */
-int mutt_rmtree (const char* path)
-{
- DIR* dirp;
- struct dirent* de;
- char cur[_POSIX_PATH_MAX];
- struct stat statbuf;
- int rc = 0;
-
- if (!(dirp = opendir (path)))
- {
- dprint (1, (debugfile, "mutt_rmtree: error opening directory %s\n", path));
- return -1;
- }
- while ((de = readdir (dirp)))
- {
- if (!strcmp (".", de->d_name) || !strcmp ("..", de->d_name))
- continue;
-
- snprintf (cur, sizeof (cur), "%s/%s", path, de->d_name);
- /* XXX make nonrecursive version */
-
- if (stat(cur, &statbuf) == -1)
- {
- rc = 1;
- continue;
- }
-
- if (S_ISDIR (statbuf.st_mode))
- rc |= mutt_rmtree (cur);
- else
- rc |= unlink (cur);
- }
- closedir (dirp);
-
- rc |= rmdir (path);
-
- return rc;
-}
-
-static 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)
-{
- struct stat osb, nsb;
- int fd;
-
- if (flags & O_EXCL)
- {
- 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;
- }
-
- /* NFS and I believe cygwin do not handle movement of open files well */
- close (fd);
- if (mutt_put_file_in_place (path, safe_file, safe_dir) == -1)
- return -1;
- }
-
- if ((fd = open (path, flags & ~O_EXCL, 0600)) < 0)
- return fd;
-
- /* make sure the file is not symlink */
- if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 ||
- compare_stat(&osb, &nsb) == -1)
- {
-/* dprint (1, (debugfile, "safe_open(): %s is a symlink!\n", path)); */
- close (fd);
- return (-1);
- }
-
- return (fd);
-}
-
-/* when opening files for writing, make sure the file doesn't already exist
- * to avoid race conditions.
- */
-FILE *safe_fopen (const char *path, const char *mode)
-{
- if (mode[0] == 'w')
- {
- int fd;
- int flags = O_CREAT | O_EXCL;
-
-#ifdef O_NOFOLLOW
- flags |= O_NOFOLLOW;
-#endif
-
- if (mode[1] == '+')
- flags |= O_RDWR;
- else
- flags |= O_WRONLY;
-
- if ((fd = safe_open (path, flags)) < 0)
- return (NULL);
-
- return (fdopen (fd, mode));
- }
- else
- return (fopen (path, mode));
-}
-
static const char safe_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+@{}._-:%/";
void mutt_sanitize_filename (char *f, short slash)
/* The actual library functions. */
-FILE *safe_fopen (const char *, const char *);
-
char *mutt_concatn_path (char *, size_t, const char *, size_t, const char *, size_t);
char *mutt_concat_path (char *, const char *, const char *, size_t);
char *mutt_read_line (char *, size_t *, FILE *, int *, int);
int mutt_strncmp (const char *, const char *, size_t);
int mutt_strcoll (const char *, const char *);
int safe_asprintf (char **, const char *, ...);
-int safe_open (const char *, int);
int safe_rename (const char *, const char *);
-int safe_symlink (const char *, const char *);
int safe_fclose (FILE **);
int safe_fsync_close (FILE **);
-int mutt_rmtree (const char *);
size_t mutt_quote_filename (char *, size_t, const char *);
size_t mutt_strlen (const char *);
#include <time.h>
#include <sys/types.h>
#include <utime.h>
+#include <dirent.h>
BODY *mutt_new_body (void)
{
strfcpy (dest, (rc == 0) ? NONULL(p) : NONULL(src), dlen);
FREE (&p);
}
+
+
+/************************************************************************
+ * These functions are transplanted from lib.c, in order to modify them *
+ * to use BUFFERs. *
+ ************************************************************************/
+
+/* remove a directory and everything under it */
+int mutt_rmtree (const char* path)
+{
+ DIR* dirp;
+ struct dirent* de;
+ char cur[_POSIX_PATH_MAX];
+ struct stat statbuf;
+ int rc = 0;
+
+ if (!(dirp = opendir (path)))
+ {
+ dprint (1, (debugfile, "mutt_rmtree: error opening directory %s\n", path));
+ return -1;
+ }
+ while ((de = readdir (dirp)))
+ {
+ if (!strcmp (".", de->d_name) || !strcmp ("..", de->d_name))
+ continue;
+
+ snprintf (cur, sizeof (cur), "%s/%s", path, de->d_name);
+ /* XXX make nonrecursive version */
+
+ if (stat(cur, &statbuf) == -1)
+ {
+ rc = 1;
+ continue;
+ }
+
+ if (S_ISDIR (statbuf.st_mode))
+ rc |= mutt_rmtree (cur);
+ else
+ rc |= unlink (cur);
+ }
+ closedir (dirp);
+
+ rc |= rmdir (path);
+
+ return rc;
+}
+
+/* Create a temporary directory next to a file name */
+
+static 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;
+
+ strfcpy (parent, NONULL (path), sizeof (parent));
+
+ if ((p = strrchr (parent, '/')))
+ {
+ *p = '\0';
+ basename = p + 1;
+ }
+ else
+ {
+ strfcpy (parent, ".", sizeof (parent));
+ basename = path;
+ }
+
+ snprintf (newdir, ndlen, "%s/%s", parent, ".muttXXXXXX");
+ if (mkdtemp(newdir) == NULL)
+ {
+ dprint(1, (debugfile, "mutt_mkwrapdir: mkdtemp() failed\n"));
+ return -1;
+ }
+
+ if (snprintf (newfile, nflen, "%s/%s", newdir, NONULL(basename)) >= nflen)
+ {
+ rmdir(newdir);
+ dprint(1, (debugfile, "mutt_mkwrapdir: string was truncated\n"));
+ return -1;
+ }
+ return 0;
+}
+
+static 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)
+{
+ struct stat osb, nsb;
+ int fd;
+
+ if (flags & O_EXCL)
+ {
+ 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;
+ }
+
+ /* NFS and I believe cygwin do not handle movement of open files well */
+ close (fd);
+ if (mutt_put_file_in_place (path, safe_file, safe_dir) == -1)
+ return -1;
+ }
+
+ if ((fd = open (path, flags & ~O_EXCL, 0600)) < 0)
+ return fd;
+
+ /* make sure the file is not symlink */
+ if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 ||
+ compare_stat(&osb, &nsb) == -1)
+ {
+/* dprint (1, (debugfile, "safe_open(): %s is a symlink!\n", path)); */
+ close (fd);
+ return (-1);
+ }
+
+ return (fd);
+}
+
+/* when opening files for writing, make sure the file doesn't already exist
+ * to avoid race conditions.
+ */
+FILE *safe_fopen (const char *path, const char *mode)
+{
+ if (mode[0] == 'w')
+ {
+ int fd;
+ int flags = O_CREAT | O_EXCL;
+
+#ifdef O_NOFOLLOW
+ flags |= O_NOFOLLOW;
+#endif
+
+ if (mode[1] == '+')
+ flags |= O_RDWR;
+ else
+ flags |= O_WRONLY;
+
+ if ((fd = safe_open (path, flags)) < 0)
+ return (NULL);
+
+ return (fdopen (fd, mode));
+ }
+ else
+ return (fopen (path, mode));
+}
+
+int safe_symlink(const char *oldpath, const char *newpath)
+{
+ struct stat osb, nsb;
+
+ if (!oldpath || !newpath)
+ return -1;
+
+ if (unlink(newpath) == -1 && errno != ENOENT)
+ return -1;
+
+ if (oldpath[0] == '/')
+ {
+ if (symlink (oldpath, newpath) == -1)
+ return -1;
+ }
+ else
+ {
+ char abs_oldpath[_POSIX_PATH_MAX];
+
+ if ((getcwd (abs_oldpath, sizeof abs_oldpath) == NULL) ||
+ (strlen (abs_oldpath) + 1 + strlen (oldpath) + 1 > sizeof abs_oldpath))
+ return -1;
+
+ strcat (abs_oldpath, "/"); /* __STRCAT_CHECKED__ */
+ strcat (abs_oldpath, oldpath); /* __STRCAT_CHECKED__ */
+ if (symlink (abs_oldpath, newpath) == -1)
+ return -1;
+ }
+
+ if (stat(oldpath, &osb) == -1 || stat(newpath, &nsb) == -1
+ || compare_stat(&osb, &nsb) == -1)
+ {
+ unlink(newpath);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* END lib.c transplant functions */
ADDRESS *alias_reverse_lookup (ADDRESS *);
+/* lib.c files transplanted to muttlib.c */
+int mutt_rmtree (const char *);
+FILE *safe_fopen (const char *, const char *);
+int safe_open (const char *, int);
+int safe_symlink (const char *, const char *);
+
/* base64.c */
void mutt_to_base64 (unsigned char*, const unsigned char*, size_t, size_t);
int mutt_from_base64 (char*, const char*, size_t);