]> git.wh0rd.org Git - nano.git/commitdiff
2009-09-02 Chris Allegretta <chrisa@asty.org>
authorChris Allegretta <chrisa@asty.org>
Thu, 3 Sep 2009 05:45:13 +0000 (05:45 +0000)
committerChris Allegretta <chrisa@asty.org>
Thu, 3 Sep 2009 05:45:13 +0000 (05:45 +0000)
        * Attempt to check file writability and emit a warning on the status bar
          if nano doesn't think the file can be written to.  Feature originally
          requested by Damien Jolders <madamien@skullsquad.com> et al.

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4407 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
src/files.c
src/nano.c
src/proto.h
src/text.c

index 16107fe66596d6d8ef0f347306c64bba97658403..59ec727a910cc78ac10d0541dc3a4e5f525b478a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-09-02 Chris Allegretta <chrisa@asty.org>
+       * Attempt to check file writability and emit a warning on the status bar
+         if nano doesn't think the file can be written to.  Feature originally
+         requested by Damien Jolders <madamien@skullsquad.com> et al.
+
 2009-08-29 Chris Allegretta <chrisa@asty.org>
        * Fix more soft wrapping issues, particularly with scrolling,
          discovered by Hannes <mr_creosote@mutantwatch.de>.
index ccd3c8dedab02cebb6211b0bd77eb8592fb98689..bf96960d75e2c2c3954fcf1eeff55f5e4cff4983 100644 (file)
@@ -145,8 +145,8 @@ void open_buffer(const char *filename, bool undoable)
 
     /* If we have a non-new file, read it in.  Then, if the buffer has
      * no stat, update the stat, if applicable. */
-    if (rc == 0) {
-       read_file(f, filename, undoable);
+    if (rc > 0) {
+       read_file(f, rc, filename, undoable);
 #ifndef NANO_TINY
        if (openfile->current_stat == NULL) {
            openfile->current_stat =
@@ -195,8 +195,8 @@ void replace_buffer(const char *filename)
     initialize_buffer_text();
 
     /* If we have a non-new file, read it in. */
-    if (rc == 0)
-       read_file(f, filename, FALSE);
+    if (rc > 0)
+       read_file(f, rc, filename, FALSE);
 
     /* Move back to the beginning of the first line of the buffer. */
     openfile->current = openfile->fileage;
@@ -348,8 +348,10 @@ filestruct *read_line(char *buf, filestruct *prevnode, bool
 
 /* Read an open file into the current buffer.  f should be set to the
  * open file, and filename should be set to the name of the file.
-   undoable  means do we want to create undo records to try and undo this */
-void read_file(FILE *f, const char *filename, bool undoable)
+ * undoable  means do we want to create undo records to try and undo this.
+ * Will also attempt to check file writability if fd > 0
+ */
+void read_file(FILE *f, int fd, const char *filename, bool undoable)
 {
     size_t num_lines = 0;
        /* The number of lines in the file. */
@@ -370,6 +372,8 @@ void read_file(FILE *f, const char *filename, bool undoable)
     int input_int;
        /* The current value we read from the file, whether an input
         * character or EOF. */
+    bool writable = TRUE;
+       /* Is the file writable (if we care) */
 #ifndef NANO_TINY
     int format = 0;
        /* 0 = *nix, 1 = DOS, 2 = Mac, 3 = both DOS and Mac. */
@@ -469,6 +473,11 @@ void read_file(FILE *f, const char *filename, bool undoable)
     if (ferror(f))
        nperror(filename);
     fclose(f);
+    if (fd > 0) {
+       int closecode = close(fd);
+       fprintf(stderr, "Closecode = %d\n", closecode);
+       writable = is_file_writable(filename);
+    }
 
 #ifndef NANO_TINY
     /* If file conversion isn't disabled and the last character in this
@@ -578,24 +587,45 @@ void read_file(FILE *f, const char *filename, bool undoable)
     if (undoable)
        update_undo(INSERT);
 
-    if (format == 3)
-       statusbar(
+    if (format == 3) {
+       if (writable)
+           statusbar(
                P_("Read %lu line (Converted from DOS and Mac format)",
                "Read %lu lines (Converted from DOS and Mac format)",
                (unsigned long)num_lines), (unsigned long)num_lines);
-    else if (format == 2) {
+       else
+           statusbar(
+               P_("Read %lu line (Converted from DOS and Mac format - Warning: No write permission)",
+               "Read %lu lines (Converted from DOS and Mac format - Warning: No write permission)",
+               (unsigned long)num_lines), (unsigned long)num_lines);
+    } else if (format == 2) {
        openfile->fmt = MAC_FILE;
-       statusbar(P_("Read %lu line (Converted from Mac format)",
+       if (writable)
+           statusbar(P_("Read %lu line (Converted from Mac format)",
                "Read %lu lines (Converted from Mac format)",
                (unsigned long)num_lines), (unsigned long)num_lines);
+       else
+           statusbar(P_("Read %lu line (Converted from Mac format - Warning: No write permission)",
+               "Read %lu lines (Converted from Mac format - Warning: No write permission)",
+               (unsigned long)num_lines), (unsigned long)num_lines);
     } else if (format == 1) {
        openfile->fmt = DOS_FILE;
-       statusbar(P_("Read %lu line (Converted from DOS format)",
+       if (writable)
+           statusbar(P_("Read %lu line (Converted from DOS format)",
                "Read %lu lines (Converted from DOS format)",
                (unsigned long)num_lines), (unsigned long)num_lines);
+       else
+           statusbar(P_("Read %lu line (Converted from DOS format - Warning: No write permission)",
+               "Read %lu lines (Converted from DOS format - Warning: No write permission)",
+               (unsigned long)num_lines), (unsigned long)num_lines);
     } else
 #endif
-       statusbar(P_("Read %lu line", "Read %lu lines",
+       if (writable)
+           statusbar(P_("Read %lu line", "Read %lu lines",
+               (unsigned long)num_lines), (unsigned long)num_lines);
+       else
+           statusbar(P_("Read %lu line ( Warning: No write permission)",
+               "Read %lu lines (Warning: No write permission)",
                (unsigned long)num_lines), (unsigned long)num_lines);
 }
 
@@ -603,9 +633,9 @@ void read_file(FILE *f, const char *filename, bool undoable)
  * "New File" if the file is missing.  Otherwise, say "[filename] not
  * found".
  *
- * Return -2 if we say "New File", -1 if the file isn't opened, and 0
- * otherwise.  The file might still have an error while reading with a 0
- * return value.  *f is set to the opened file. */
+ * Return -2 if we say "New File", -1 if the file isn't opened, and the
+ * fd opened otherwise.  The file might still have an error while reading 
+ * with a 0 return value.  *f is set to the opened file. */
 int open_file(const char *filename, bool newfie, FILE **f)
 {
     struct stat fileinfo, fileinfo2;
@@ -668,9 +698,51 @@ int open_file(const char *filename, bool newfie, FILE **f)
 
     free(full_filename);
 
-    return 0;
+    return fd;
 }
 
+/* A bit of a copy and paste from open_file(), is_file_writable()
+ * just checks whether the file is appendable as a quick
+ * permissions check, and we tend to err on the side of permissiveness
+ * (reporting TRUE when it might be wrong) to not fluster users
+ * editing on odd filesystems by printing incorrect warnings.
+ */
+int is_file_writable(const char *filename)
+{
+    struct stat fileinfo, fileinfo2;
+    int fd;
+    FILE *f;
+    char *full_filename;
+    bool ans = TRUE;
+
+
+    if (ISSET(VIEW_MODE))
+       return TRUE;
+
+    assert(filename != NULL && f != NULL);
+
+    /* Get the specified file's full path. */
+    full_filename = get_full_path(filename);
+
+    /* Okay, if we can't stat the path due to a component's
+       permissions, just try the relative one */
+    if (full_filename == NULL
+        || (stat(full_filename, &fileinfo) == -1 && stat(filename, &fileinfo2) != -1))
+        full_filename = mallocstrcpy(NULL, filename);
+
+    if ((fd = open(full_filename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR |
+                S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1
+       || (f = fdopen(fd, "a")) == NULL)
+       ans = FALSE;
+    else
+        fclose(f);
+    close(fd);
+
+    free(full_filename);
+    return ans;
+}
+
+
 /* This function will return the name of the first available extension
  * of a filename (starting with [name][suffix], then [name][suffix].1,
  * etc.).  Memory is allocated for the return value.  If no writable
index 9d1e011f5d83f3555c65a0e14c1d44f301a4af1a..802315db010791d11701e66a48c16e918ecdffdd 100644 (file)
@@ -1060,7 +1060,7 @@ void finish_stdin_pager(void)
        if (f == NULL)
         nperror("fopen");
 
-    read_file(f, "stdin", TRUE);
+    read_file(f, 0, "stdin", TRUE);
     ttystdin = open("/dev/tty", O_RDONLY);
     if (!ttystdin)
         die(_("Couldn't reopen stdin from keyboard, sorry\n"));
index 19b3881dda21f6df28ec533178164f1c1611953b..740ba8091786ebe915ef97026a77a7cf9c6c7d0b 100644 (file)
@@ -270,7 +270,7 @@ bool close_buffer(void);
 #endif
 filestruct *read_line(char *buf, filestruct *prevnode, bool
        *first_line_ins, size_t buf_len);
-void read_file(FILE *f, const char *filename, bool undoable);
+void read_file(FILE *f, int fd, const char *filename, bool undoable);
 int open_file(const char *filename, bool newfie, FILE **f);
 char *get_next_filename(const char *name, const char *suffix);
 void do_insertfile(
index 51ad00b23fb75474d52d3477d30f94382afa2015..f70f31d6b0c07d8c3ed50691884ba27ddcc62352 100644 (file)
@@ -812,7 +812,7 @@ bool execute_command(const char *command)
     if (f == NULL)
        nperror("fdopen");
 
-    read_file(f, "stdin", TRUE);
+    read_file(f, 0, "stdin", TRUE);
 
     if (wait(NULL) == -1)
        nperror("wait");