More string and buffer functions.
[apps/madmutt.git] / lib-lib / file.c
index 978895a..ed74aad 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "lib-lib.h"
 
+#include <utime.h>
+
 #ifndef O_NOFOLLOW
 #  define O_NOFOLLOW  0
 #endif
@@ -68,7 +70,7 @@ int safe_open(const char *path, int flags)
         return -1;
     }
 
-    return (fd);
+    return fd;
 }
 
 
@@ -200,7 +202,7 @@ void mutt_unlink(const char *s)
                 fwrite(buf, 1, MIN(ssizeof(buf), sb.st_size), f);
                 sb.st_size -= MIN(ssizeof(buf), sb.st_size);
             }
-            fclose (f);
+            m_fclose(&f);
         }
     }
 }
@@ -224,7 +226,7 @@ FILE *safe_fopen(const char *path, const char *mode)
         flags |= (mode[1] == '+' ? O_RDWR : O_WRONLY);
 
         if ((fd = safe_open(path, flags)) < 0)
-            return (NULL);
+            return NULL;
 
         return fdopen (fd, mode);
     }
@@ -232,16 +234,6 @@ FILE *safe_fopen(const char *path, const char *mode)
     return fopen(path, mode);
 }
 
-int safe_fclose(FILE **f)
-{
-    int r = 0;
-
-    if (*f)
-        r = fclose (*f);
-    *f = NULL;
-    return r;
-}
-
 /* If rfc1524_expand_command() is used on a recv'd message, then
  * the filename doesn't exist yet, but if its used while sending a message,
  * then we need to rename the existing file.
@@ -268,13 +260,13 @@ int mutt_rename_file(char *oldfile, char *newfile)
 
     nfp = safe_fopen(newfile, "w");
     if (!nfp) {
-        fclose (ofp);
+        m_fclose(&ofp);
         return 3;
     }
 
     mutt_copy_stream(ofp, nfp);
-    fclose(nfp);
-    fclose(ofp);
+    m_fclose(&nfp);
+    m_fclose(&ofp);
     mutt_unlink(oldfile);
     return 0;
 }
@@ -363,7 +355,7 @@ int mutt_copy_bytes(FILE *in, FILE *out, ssize_t size)
 
 
 /****************************************************************************/
-/* ligben-like funcs                                                        */
+/* path manipulations                                                       */
 /****************************************************************************/
 
 const char *mutt_basename(const char *f)
@@ -372,6 +364,26 @@ const char *mutt_basename(const char *f)
     return p ? p + 1 : f;
 }
 
+ssize_t m_dirname(char *dst, ssize_t dlen, const char *path)
+{
+    ssize_t plen = m_strlen(path);
+
+    while (plen > 0 && path[plen - 1] == '/')
+        plen--;
+
+    while (plen > 0 && path[plen - 1] != '/')
+        plen--;
+
+    while (plen > 0 && path[plen - 1] == '/')
+        plen--;
+
+    if (plen)
+        return m_strncpy(dst, dlen, path, plen);
+
+    if (*path == '/')
+        return m_strcpy(dst, dlen, "/");
+    return m_strcpy(dst, dlen, ".");
+}
 
 char *
 mutt_concat_path(char *d, ssize_t n, const char *dir, const char *fname)
@@ -465,6 +477,14 @@ ssize_t m_file_fmt(char *dst, ssize_t n, const char *fmt, const char *src)
     return pos;
 }
 
+ssize_t
+m_quotefile_fmt(char *dst, ssize_t n, const char *fmt, const char *src)
+{
+    char tmp[LONG_STRING];
+    mutt_quote_filename(tmp, sizeof(tmp), src);
+    return m_file_fmt(dst, n, fmt, tmp);
+}
+
 static ssize_t
 m_tempftplize(char *dst, ssize_t dlen, const char *fmt, const char *s)
 {
@@ -506,7 +526,7 @@ int m_tempfd(char *dst, ssize_t n, const char *dir, const char *fmt)
         m_tempftplize(tpl, sizeof(tpl), fmt, raw);
     }
 
-    fd = open(path, O_CREAT | O_EXCL | O_WRONLY | O_NOFOLLOW, 0600);
+    fd = open(path, O_CREAT | O_EXCL | O_RDWR | O_NOFOLLOW, 0600);
 
     if (fd < 0) {
         if (errno == EEXIST)
@@ -523,3 +543,31 @@ FILE *m_tempfile(char *dst, ssize_t n, const char *dir, const char *fmt)
     int fd = m_tempfd(dst, n, dir, fmt);
     return fd < 0 ? NULL : fdopen(fd, "w+");
 }
+
+/****************************************************************************/
+/* misc                                                                     */
+/****************************************************************************/
+
+/* Decrease a file's modification time by 1 second */
+time_t m_decrease_mtime(const char *path, struct stat *st)
+{
+    struct utimbuf utim;
+    struct stat _st;
+    time_t mtime;
+
+    if (!st) {
+        if (stat(path, &_st) == -1)
+            return -1;
+        st = &_st;
+    }
+
+    if ((mtime = st->st_mtime) == time(NULL)) {
+        mtime -= 1;
+        utim.actime = mtime;
+        utim.modtime = mtime;
+        utime(path, &utim);
+    }
+
+    return mtime;
+}
+