Index: files.c =================================================================== --- files.c (revision 5581) +++ files.c (working copy) @@ -33,6 +33,39 @@ #include #include +/* If component of path is file check for read permission, if directory check + * read and execute permissions, both. */ +bool check_permissions(const char *filename) +{ + char *parentdir; + struct stat parentinfo; + bool validity = TRUE; + + if (strrchr(filename, '/') == NULL) + parentdir = mallocstrcpy(NULL, "."); + else + parentdir = dirname(mallocstrcpy(NULL, filename)); + + stat(parentdir, &parentinfo); + while (strcmp(parentdir, ".") != 0 && strcmp(parentdir, "/") != 0) { + if ((S_ISDIR(parentinfo.st_mode) + ? (access(parentdir, R_OK | X_OK) == -1) + : (access(parentdir, R_OK) == -1))) { + statusbar(_("'%s': Permission denied"), parentdir); + validity = FALSE; + beep(); + break; + } + parentdir = dirname(parentdir); + stat(parentdir, &parentinfo); + } + + if (strcmp(parentdir, ".") == 0) + parentdir = mallocstrcpy(NULL, filename); + free(parentdir); + return validity; +} + /* Verify that the containing directory of the given filename exists. */ bool has_valid_path(const char *filename) { @@ -48,9 +81,12 @@ if (stat(parentdir, &parentinfo) == -1 || !S_ISDIR(parentinfo.st_mode)) { statusbar(_("Directory '%s' does not exist"), parentdir); validity = FALSE; + goto end; beep(); } + validity = check_permissions(filename); + end: free(parentdir); return validity; } Index: proto.h =================================================================== --- proto.h (revision 5581) +++ proto.h (working copy) @@ -281,6 +281,7 @@ void do_uncut_text(void); /* All functions in files.c. */ +bool check_permissions(const char *filename); void verify_path(const char *filename); void make_new_buffer(void); void initialize_buffer_text(void);