|
48 | 48 | #include <regex.h> |
49 | 49 | #include <pthread.h> |
50 | 50 | #include <unistd.h> |
| 51 | +#include <libgen.h> |
| 52 | +#include <limits.h> |
51 | 53 |
|
52 | 54 | #include <netinet/in.h> |
53 | 55 | #include <sys/socket.h> |
@@ -1225,22 +1227,47 @@ unescape_str (const char *src) { |
1225 | 1227 |
|
1226 | 1228 | int |
1227 | 1229 | is_writable_path (const char *path) { |
1228 | | - /* Path is writable */ |
1229 | | - if (access (path, W_OK) == 0) |
| 1230 | + char *copy = NULL, *dir_path = NULL; |
| 1231 | + char dir_path_copy[PATH_MAX] = { 0 }; |
| 1232 | + int result = 0; |
| 1233 | + |
| 1234 | + if (path == NULL) { |
| 1235 | + fprintf (stderr, "Path is NULL\n"); |
| 1236 | + return 0; |
| 1237 | + } |
| 1238 | + /* Make a copy of the path because dirname might modify it */ |
| 1239 | + copy = strdup (path); |
| 1240 | + if (copy == NULL) { |
| 1241 | + fprintf (stderr, "Memory allocation failed\n"); |
| 1242 | + return 0; |
| 1243 | + } |
| 1244 | + /* Get the directory part of the path */ |
| 1245 | + dir_path = dirname (copy); |
| 1246 | + strncpy (dir_path_copy, dir_path, PATH_MAX); |
| 1247 | + |
| 1248 | + /* Check if the directory is writable */ |
| 1249 | + result = access (dir_path, W_OK); |
| 1250 | + free (copy); |
| 1251 | + |
| 1252 | + if (result == 0) { |
| 1253 | + /* Directory exists and is writable */ |
1230 | 1254 | return 1; |
| 1255 | + } |
1231 | 1256 |
|
1232 | 1257 | switch (errno) { |
1233 | 1258 | case ENOENT: |
1234 | | - fprintf (stderr, "Path does not exist: %s\n", path); |
1235 | | - return 0; |
| 1259 | + fprintf (stderr, "Directory does not exist: %s\n", dir_path_copy); |
| 1260 | + break; |
1236 | 1261 | case EACCES: |
1237 | | - fprintf (stderr, "No write permission for path: %s\n", path); |
1238 | | - return 0; |
| 1262 | + fprintf (stderr, "No write permission for directory: %s\n", dir_path_copy); |
| 1263 | + break; |
1239 | 1264 | case EROFS: |
1240 | | - fprintf (stderr, "Path is on a read-only file system: %s\n", path); |
1241 | | - return 0; |
| 1265 | + fprintf (stderr, "Directory is on a read-only file system: %s\n", dir_path_copy); |
| 1266 | + break; |
1242 | 1267 | default: |
1243 | | - fprintf (stderr, "Unknown error (errno %d) for path: %s\n", errno, path); |
1244 | | - return 0; |
| 1268 | + fprintf (stderr, "Unknown error (errno %d) for directory: %s\n", errno, dir_path_copy); |
| 1269 | + break; |
1245 | 1270 | } |
| 1271 | + |
| 1272 | + return 0; |
1246 | 1273 | } |
0 commit comments