[5/10] winemenubuilder: If a unix link is a directory, remove it recursively. (resend)

Per Johansson per at morth.org
Wed Mar 20 02:43:29 CDT 2013


---
 programs/winemenubuilder/winemenubuilder.c | 56 +++++++++++++++++++++++++++++-
 programs/winemenubuilder/winemenubuilder.h |  1 +
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index bc1bae3..2eccd69 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -77,6 +77,8 @@
 #ifdef HAVE_FNMATCH_H
 #include <fnmatch.h>
 #endif
+#include <dirent.h>
+#include <limits.h>
 
 #define COBJMACROS
 #define NONAMELESSUNION
@@ -288,6 +290,58 @@ BOOL create_directories(char *directory)
     return ret;
 }
 
+BOOL remove_unix_link(const char *unix_link)
+{
+    struct stat st;
+
+    if (lstat(unix_link, &st))
+        return FALSE;
+
+    if (S_ISDIR(st.st_mode))
+    {
+        char path[PATH_MAX], *epath;
+        DIR *dir = opendir(unix_link);
+        struct dirent *ent;
+        int pathlen;
+
+        if (!dir)
+            return FALSE;
+
+        pathlen = snprintf(path, sizeof(path), "%s", unix_link);
+        if (pathlen < 0 || pathlen >= PATH_MAX - 2)
+            return FALSE;
+        path[pathlen++] = '/';
+        epath = path + pathlen;
+
+        while ((ent = readdir(dir)))
+        {
+            if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+                continue;
+            if (pathlen + ent->d_namlen >= PATH_MAX)
+            {
+                closedir(dir);
+                return FALSE;
+            }
+            strcpy(epath, ent->d_name);
+            if (!remove_unix_link(path))
+            {
+                closedir(dir);
+                return FALSE;
+            }
+        }
+        closedir(dir);
+
+        if (rmdir(unix_link))
+            return FALSE;
+    }
+    else
+    {
+        if (unlink(unix_link))
+            return FALSE;
+    }
+    return TRUE;
+}
+
 char* wchars_to_utf8_chars(LPCWSTR string)
 {
     char *ret;
@@ -2660,7 +2714,7 @@ static void cleanup_menus(void)
                     if (stat(windows_file, &filestats) < 0 && errno == ENOENT)
                     {
                         WINE_TRACE("removing menu related file %s\n", unix_file);
-                        remove(unix_file);
+                        remove_unix_link(unix_file);
                         RegDeleteValueW(hkey, value);
                     }
                     else
diff --git a/programs/winemenubuilder/winemenubuilder.h b/programs/winemenubuilder/winemenubuilder.h
index 708b0d2..9cc3939 100644
--- a/programs/winemenubuilder/winemenubuilder.h
+++ b/programs/winemenubuilder/winemenubuilder.h
@@ -38,6 +38,7 @@ typedef struct
 char *strdupA( const char *str );
 char* heap_printf(const char *format, ...);
 BOOL create_directories(char *directory);
+BOOL remove_unix_link(const char *unix_link);
 DWORD register_menus_entry(const char *unix_file, const char *windows_file);
 char* wchars_to_utf8_chars(LPCWSTR string);
 HRESULT read_ico_direntries(IStream *icoStream, ICONDIRENTRY **ppIconDirEntries, int *numEntries);
-- 
1.8.0.2




More information about the wine-patches mailing list