]> source.dussan.org Git - tigervnc.git/commitdiff
Create common recursive mkdir() 1760/head
authorPierre Ossman <ossman@cendio.se>
Thu, 30 May 2024 14:05:35 +0000 (16:05 +0200)
committerPierre Ossman <ossman@cendio.se>
Thu, 30 May 2024 14:33:02 +0000 (16:33 +0200)
Avoid duplicating this complexity in too many places.

At the same time make the interface more identical to regular mkdir(),
for familiarity.

common/os/os.cxx
common/os/os.h
unix/vncpasswd/vncpasswd.cxx
unix/vncserver/vncsession.c
vncviewer/vncviewer.cxx

index 35f87b033b0cd626feab166c58fb54745bf5ec49..83995d0d3147d3400aba0fb4ebd8a819d1445c97 100644 (file)
@@ -24,6 +24,7 @@
 #include <os/os.h>
 
 #include <assert.h>
+#include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -39,6 +40,7 @@
 #include <wininet.h> /* MinGW needs it */
 #include <shlobj.h>
 #define stat _stat
+#define mkdir(path, mode) mkdir(path)
 #endif
 
 static const char* getvncdir(bool userDir, const char *xdg_env, const char *xdg_def)
@@ -126,3 +128,35 @@ const char* os::getvncstatedir()
 {
   return getvncdir(false, "XDG_STATE_HOME", ".local/state");
 }
+
+int os::mkdir_p(const char *path_, mode_t mode)
+{
+  char *path = strdup(path_);
+  char *p;
+
+#ifdef WIN32
+  (void)mode;
+#endif
+
+  for (p = path + 1; *p; p++) {
+    if (*p == '/') {
+      *p = '\0';
+      if (mkdir(path, mode) == -1) {
+        if (errno != EEXIST) {
+          free(path);
+          return -1;
+        }
+      }
+      *p = '/';
+    }
+  }
+
+  if (mkdir(path, mode) == -1) {
+    free(path);
+    return -1;
+  }
+
+  free(path);
+
+  return 0;
+}
index 8e522676457858bf3e33c850fbd7059cf2995962..a3448070edc825af8b0c9ec8b52f9c70ca7a7248 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef OS_OS_H
 #define OS_OS_H
 
+#include <sys/stat.h>
+
 namespace os {
 
   /*
@@ -62,6 +64,11 @@ namespace os {
    */
   const char* getvncstatedir();
 
+  /*
+   * Create directory recursively. Useful to create the nested directory
+   * structures needed for the above directories.
+   */
+  int mkdir_p(const char *path, mode_t mode);
 }
 
 #endif /* OS_OS_H */
index 68c44289ea089a0c7a8434eab5e0cd8cde8c646a..30091a3db6078aec71d688fbb6efee7a7db8c005 100644 (file)
@@ -23,6 +23,7 @@
 #include <config.h>
 #endif
 
+#include <errno.h>
 #include <limits.h>
 #include <stdio.h>
 #include <string.h>
@@ -161,16 +162,10 @@ int main(int argc, char** argv)
       fprintf(stderr, "Can't obtain VNC config directory\n");
       exit(1);
     }
-    strcpy(fname, configDir);
-    char *p = NULL;
-    for (p = fname + 1; *p; p++) {
-        if (*p == '/') {
-            *p = '\0';
-            mkdir(fname, 0777);
-            *p = '/';
-        }
+    if (os::mkdir_p(configDir, 0777) == -1) {
+      fprintf(stderr, "Could not create VNC config directory: %s\n", strerror(errno));
+      exit(1);
     }
-    mkdir(fname, 0777);
     snprintf(fname, sizeof(fname), "%s/passwd", configDir);
   }
 
index 31dee57d7f563db9bdab4ab7ec19788697bddf2d..1ee096c7c54b0e4467758abf478f491dda4e8899 100644 (file)
@@ -358,33 +358,33 @@ switch_user(const char *username, uid_t uid, gid_t gid)
     }
 }
 
-static void
-mkvncdir(const char *dir)
+static int
+mkdir_p(const char *path_, mode_t mode)
 {
-    if (mkdir(dir, 0755) == -1) {
-        if (errno != EEXIST) {
-            syslog(LOG_CRIT, "Failure creating \"%s\": %s", dir, strerror(errno));
-            _exit(EX_OSERR);
-        }
-    }
-}
+  char *path = strdup(path_);
+  char *p;
 
-static void
-mkdirrecursive(const char *dir)
-{
-    char *path = strdup(dir);
-    char *p;
-
-    for (p = path + 1; *p; p++) {
-        if (*p == '/') {
-            *p = '\0';
-            mkvncdir(path);
-            *p = '/';
+  for (p = path + 1; *p; p++) {
+    if (*p == '/') {
+      *p = '\0';
+      if (mkdir(path, mode) == -1) {
+        if (errno != EEXIST) {
+          free(path);
+          return -1;
         }
+      }
+      *p = '/';
     }
+  }
 
-    mkvncdir(path);
+  if (mkdir(path, mode) == -1) {
     free(path);
+    return -1;
+  }
+
+  free(path);
+
+  return 0;
 }
 
 static void
@@ -431,7 +431,12 @@ redir_stdio(const char *homedir, const char *display, char **envp)
 #endif
     }
 
-    mkdirrecursive(logfile);
+    if (mkdir_p(logfile, 0755) == -1) {
+        if (errno != EEXIST) {
+            syslog(LOG_CRIT, "Failure creating \"%s\": %s", logfile, strerror(errno));
+            _exit(EX_OSERR);
+        }
+    }
 
     hostlen = sysconf(_SC_HOST_NAME_MAX);
     if (hostlen < 0) {
index 59be48120e9b881f18cd1a764c66909a07350c5b..91e2be3b2d71a76d36085150242e2771d588fa3f 100644 (file)
@@ -37,7 +37,6 @@
 #ifdef WIN32
 #include <os/winerrno.h>
 #include <direct.h>
-#define mkdir(path, mode) _mkdir(path)
 #endif
 
 #ifdef __APPLE__
@@ -429,36 +428,6 @@ static void init_fltk()
 #endif
 }
 
-static int mkvncdir(const char *dir)
-{
-  int result = mkdir(dir, 0755);
-  if (result == -1 && errno != EEXIST) {
-    vlog.error(_("Could not create VNC directory %s: %s"), dir, strerror(errno));
-    return result;
-  }
-  return 0;
-}
-
-static void mkdirrecursive(const char *dir)
-{
-  char *path = strdup(dir);
-  char *p;
-
-  for (p = path + 1; *p; p++) {
-    if (*p == '/') {
-      *p = '\0';
-      if (mkvncdir(path) != 0) {
-        free(path);
-        return;
-      }
-      *p = '/';
-    }
-  }
-
-  mkvncdir(path);
-  free(path);
-}
-
 static void usage(const char *programName)
 {
 #ifdef WIN32
@@ -755,9 +724,21 @@ int main(int argc, char** argv)
   if (vncdir != NULL && strcmp(vncdir, "vnc") == 0)
     vlog.info(_("%%APPDATA%%\\vnc is deprecated, please switch to the %%APPDATA%%\\TigerVNC location."));
 #endif
-  mkdirrecursive(os::getvncconfigdir());
-  mkdirrecursive(os::getvncdatadir());
-  mkdirrecursive(os::getvncstatedir());
+
+  if (os::mkdir_p(os::getvncconfigdir(), 0755) == -1) {
+    if (errno != EEXIST)
+      vlog.error(_("Could not create VNC config directory: %s"), strerror(errno));
+  }
+
+  if (os::mkdir_p(os::getvncdatadir(), 0755) == -1) {
+    if (errno != EEXIST)
+      vlog.error(_("Could not create VNC data directory: %s"), strerror(errno));
+  }
+
+  if (os::mkdir_p(os::getvncstatedir(), 0755) == -1) {
+    if (errno != EEXIST)
+      vlog.error(_("Could not create VNC state directory: %s"), strerror(errno));
+  }
 
   CSecurity::upg = &dlg;
 #if defined(HAVE_GNUTLS) || defined(HAVE_NETTLE)