Blob Blame History Raw
From 131d4b0988f319736bb36760cee300934bf9bc12 Mon Sep 17 00:00:00 2001
From: astyanax <astyanax@ac9c2fa3-95a5-41e5-9206-2167041ecc6c>
Date: Wed, 14 Jan 2015 02:36:30 +0000
Subject: [PATCH 1/6] 2015-01-13 Chris Allegretta <chrisa@asty.org> *
 src/files.c (open_buffer): Check here for locking and properly handle
 choosing to not open a file when locked instead of in open_file(). Fixes
 Savannah bug 42373 reported by Benno Schulenberg

git-svn-id: file:///home/kdudka/git/nano-svn/nano@5104 ac9c2fa3-95a5-41e5-9206-2167041ecc6c
---
 src/files.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/src/files.c b/src/files.c
index a195e6f..e027d69 100644
--- a/src/files.c
+++ b/src/files.c
@@ -355,9 +355,25 @@ void open_buffer(const char *filename, bool undoable)
 
     /* If we're loading into a new buffer, add a new entry to
      * openfile. */
-    if (new_buffer)
+    if (new_buffer) {
 	make_new_buffer();
 
+#ifndef NANO_TINY
+	if (ISSET(LOCKING) && filename[0] != '\0') {
+	    int lockstatus = do_lockfile(filename);
+	    if (lockstatus < 0) {
+		if (openfile->next) {
+		    close_buffer();
+		    statusbar(_("Cancelled"));
+		    return;
+		} else
+		    filename = "";
+	    }
+ 	}
+#endif
+    }
+
+
     /* If the filename isn't blank, and we are not in NOREAD_MODE,
      * open the file.  Otherwise, treat it as a new file. */
     rc = (filename[0] != '\0' && !ISSET(NOREAD_MODE)) ?
@@ -920,16 +936,6 @@ int open_file(const char *filename, bool newfie, FILE **f)
 	full_filename = mallocstrcpy(NULL, filename);
 
 
-#ifndef NANO_TINY
-    if (ISSET(LOCKING)) {
-	int lockstatus = do_lockfile(full_filename);
-        if (lockstatus < 0)
-	    return -1;
-	else if (lockstatus == 0)
-	    quiet = 1;
-    }
-#endif
-
     if (stat(full_filename, &fileinfo) == -1) {
 	/* Well, maybe we can open the file even if the OS says it's
 	 * not there. */
-- 
2.1.0


From f47060c02f57279445281e9f23079f2bdccdca3a Mon Sep 17 00:00:00 2001
From: astyanax <astyanax@ac9c2fa3-95a5-41e5-9206-2167041ecc6c>
Date: Tue, 20 Jan 2015 06:15:34 +0000
Subject: [PATCH 2/6] Take 2 at file locking fixes. New args to close_buffer()
 and switch_to_prevnext_buffer() to support message passthrough when trying to
 lock files using multibuffer.

git-svn-id: file:///home/kdudka/git/nano-svn/nano@5105 ac9c2fa3-95a5-41e5-9206-2167041ecc6c
---
 src/files.c | 66 ++++++++++++++++++++++++++++++++++++-------------------------
 src/nano.c  |  2 +-
 src/proto.h |  6 +++---
 3 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/src/files.c b/src/files.c
index e027d69..faa2e62 100644
--- a/src/files.c
+++ b/src/files.c
@@ -126,6 +126,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
     pid_t mypid;
     uid_t myuid;
     struct passwd *mypwuid;
+    struct stat fileinfo;
     char *lockdata = charalloc(1024);
     char myhostname[32];
     ssize_t lockdatalen = 1024;
@@ -145,8 +146,10 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
        return -1;
     }
 
-    if (delete_lockfile(lockfilename) < 0)
-        return -1;
+    /* Check if the lock exists before we try to delete it...*/
+    if (stat(lockfilename, &fileinfo) != -1)
+	if (delete_lockfile(lockfilename) < 0)
+	    return -1;
 
     if (ISSET(INSECURE_BACKUP))
         cflags = O_WRONLY | O_CREAT | O_APPEND;
@@ -156,11 +159,13 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
     fd = open(lockfilename, cflags,
 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
 
-    /* Maybe we just don't have write access.  Don't stop us from
-     * opening the file at all, just don't set the lock_filename and
-     * return success. */
-    if (fd < 0 && errno == EACCES)
-        return 1;
+    /* Maybe we just don't have write access.  Print an error message
+       and continue. */
+    if (fd < 0) {
+        statusbar(_("Error writing lock file %s: %s"), lockfilename,
+		    strerror(errno));
+        return 0;
+    }
 
     /* Now we've got a safe file stream.  If the previous open() call
      * failed, this will return NULL. */
@@ -229,8 +234,8 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
 int delete_lockfile(const char *lockfilename)
 {
     if (unlink(lockfilename) < 0 && errno != ENOENT) {
-        statusbar(_("Error deleting lock file %s: %s"), lockfilename,
-		    strerror(errno));
+	statusbar(_("Error deleting lock file %s: %s"), lockfilename,
+		  strerror(errno));
         return -1;
     }
     return 1;
@@ -332,6 +337,7 @@ void stat_if_needed(const char *filename, struct stat **pstat)
  * necessary, and then open and read the file, if applicable. */
 void open_buffer(const char *filename, bool undoable)
 {
+    bool quiet = FALSE;
     bool new_buffer = (openfile == NULL
 #ifndef DISABLE_MULTIBUFFER
 	 || ISSET(MULTIBUFFER)
@@ -362,12 +368,14 @@ void open_buffer(const char *filename, bool undoable)
 	if (ISSET(LOCKING) && filename[0] != '\0') {
 	    int lockstatus = do_lockfile(filename);
 	    if (lockstatus < 0) {
+#ifndef DISABLE_MULTIBUFFER
 		if (openfile->next) {
-		    close_buffer();
-		    statusbar(_("Cancelled"));
+		    close_buffer(TRUE);
 		    return;
-		} else
-		    filename = "";
+		}
+#endif
+	    } else if (lockstatus == 0) {
+		quiet = TRUE;
 	    }
  	}
 #endif
@@ -377,7 +385,7 @@ void open_buffer(const char *filename, bool undoable)
     /* If the filename isn't blank, and we are not in NOREAD_MODE,
      * open the file.  Otherwise, treat it as a new file. */
     rc = (filename[0] != '\0' && !ISSET(NOREAD_MODE)) ?
-		open_file(filename, new_buffer, &f) : -2;
+		open_file(filename, new_buffer, quiet, &f) : -2;
 
     /* If we have a file, and we're loading into a new buffer, update
      * the filename. */
@@ -425,7 +433,7 @@ void replace_buffer(const char *filename)
 
     /* If the filename isn't blank, open the file.  Otherwise, treat it
      * as a new file. */
-    rc = (filename[0] != '\0') ? open_file(filename, TRUE, &f) : -2;
+    rc = (filename[0] != '\0') ? open_file(filename, TRUE, FALSE, &f) : -2;
 
     /* Reinitialize the text of the current buffer. */
     free_filestruct(openfile->fileage);
@@ -461,14 +469,15 @@ void display_buffer(void)
 #ifndef DISABLE_MULTIBUFFER
 /* Switch to the next file buffer if next_buf is TRUE.  Otherwise,
  * switch to the previous file buffer. */
-void switch_to_prevnext_buffer(bool next_buf)
+void switch_to_prevnext_buffer(bool next_buf, bool quiet)
 {
     assert(openfile != NULL);
 
     /* If only one file buffer is open, indicate it on the statusbar and
      * get out. */
     if (openfile == openfile->next) {
-	statusbar(_("No more open file buffers"));
+	if (quiet == FALSE)
+	    statusbar(_("No more open file buffers"));
 	return;
     }
 
@@ -484,9 +493,10 @@ void switch_to_prevnext_buffer(bool next_buf)
     display_buffer();
 
     /* Indicate the switch on the statusbar. */
-    statusbar(_("Switched to %s"),
-	((openfile->filename[0] == '\0') ? _("New Buffer") :
-	openfile->filename));
+    if (quiet == FALSE)
+	statusbar(_("Switched to %s"),
+	    ((openfile->filename[0] == '\0') ? _("New Buffer") :
+	      openfile->filename));
 
 #ifdef DEBUG
     dump_filestruct(openfile->current);
@@ -497,19 +507,21 @@ void switch_to_prevnext_buffer(bool next_buf)
 /* Switch to the previous entry in the openfile filebuffer. */
 void switch_to_prev_buffer_void(void)
 {
-    switch_to_prevnext_buffer(FALSE);
+    switch_to_prevnext_buffer(FALSE, FALSE);
 }
 
 /* Switch to the next entry in the openfile filebuffer. */
 void switch_to_next_buffer_void(void)
 {
-    switch_to_prevnext_buffer(TRUE);
+    switch_to_prevnext_buffer(TRUE, FALSE);
 }
 
 /* Delete an entry from the openfile filebuffer, and switch to the one
  * after it.  Return TRUE on success, or FALSE if there are no more open
- * file buffers. */
-bool close_buffer(void)
+ * file buffers.
+ * quiet - should we print messages switching bufers
+ */
+bool close_buffer(bool quiet)
 {
     assert(openfile != NULL);
 
@@ -522,7 +534,7 @@ bool close_buffer(void)
 #endif
 
     /* Switch to the next file buffer. */
-    switch_to_next_buffer_void();
+     switch_to_prevnext_buffer(TRUE, quiet);
 
     /* Close the file buffer we had open before. */
     unlink_opennode(openfile->prev);
@@ -918,10 +930,10 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable, bool checkw
  * 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)
+int open_file(const char *filename, bool newfie, bool quiet, FILE **f)
 {
     struct stat fileinfo, fileinfo2;
-    int fd, quiet = 0;
+    int fd;
     char *full_filename;
 
     assert(filename != NULL && f != NULL);
diff --git a/src/nano.c b/src/nano.c
index 6c655bc..9635c24 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -1152,7 +1152,7 @@ void do_exit(void)
 
 #ifndef DISABLE_MULTIBUFFER
 	/* Exit only if there are no more open file buffers. */
-	if (!close_buffer())
+	if (!close_buffer(FALSE))
 #endif
 	    finish();
     /* If the user canceled, we go on. */
diff --git a/src/proto.h b/src/proto.h
index 20f1fdb..579e6cf 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -283,15 +283,15 @@ void replace_buffer(const char *filename);
 #endif
 void display_buffer(void);
 #ifndef DISABLE_MULTIBUFFER
-void switch_to_prevnext_buffer(bool next);
+void switch_to_prevnext_buffer(bool next, bool quiet);
 void switch_to_prev_buffer_void(void);
 void switch_to_next_buffer_void(void);
-bool close_buffer(void);
+bool close_buffer(bool quiet);
 #endif
 filestruct *read_line(char *buf, filestruct *prevnode, bool
 	*first_line_ins, size_t buf_len);
 void read_file(FILE *f, int fd, const char *filename, bool undoable, bool checkwritable);
-int open_file(const char *filename, bool newfie, FILE **f);
+int open_file(const char *filename, bool newfie, bool quiet, FILE **f);
 char *get_next_filename(const char *name, const char *suffix);
 void do_insertfile(
 #ifndef NANO_TINY
-- 
2.1.0


From 7fa511ffbd45975e0638ea3497b49081f99c4bc9 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 26 Jan 2015 14:55:39 +0100
Subject: [PATCH 3/6] avoid writing uninitialized bytes to the lock file

The call to null_at() would not initialize the buffer:

Syscall param write(buf) points to uninitialised byte(s)
   at 0x3EA76F0EB0: __write_nocancel (syscall-template.S:81)
   by 0x3EA767949C: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1302)
   by 0x3EA767A948: new_do_write (fileops.c:537)
   by 0x3EA767A948: _IO_do_write@@GLIBC_2.2.5 (fileops.c:510)
   by 0x3EA767A22F: _IO_file_close_it@@GLIBC_2.2.5 (fileops.c:166)
   by 0x3EA766E2C1: fclose@@GLIBC_2.2.5 (iofclose.c:59)
   by 0x40814C: write_lockfile (files.c:221)
   by 0x40847C: do_lockfile (files.c:314)
   by 0x40BC5E: open_buffer (files.c:351)
   by 0x4041D7: main (nano.c:2761)
 Address 0x4c1900c is not stack'd, malloc'd or (recently) free'd
---
 src/files.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/files.c b/src/files.c
index faa2e62..1d0f0a8 100644
--- a/src/files.c
+++ b/src/files.c
@@ -195,7 +195,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
      * our lockfile' message in here...
      *
      * This is likely very wrong, so this is a WIP. */
-    null_at(&lockdata, lockdatalen);
+    memset(lockdata, 0, lockdatalen);
     lockdata[0] = 0x62;
     lockdata[1] = 0x30;
     lockdata[24] = mypid % 256;
-- 
2.1.0


From 0a7248ead64691a1f5f33dd1c7a4a55889110a92 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 27 Jan 2015 17:40:02 +0100
Subject: [PATCH 4/6] do_lockfile: make sure that lockprog and lockuser are
 terminated

strncpy() does not guarantee that on its own!
---
 src/files.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/files.c b/src/files.c
index 1d0f0a8..4468b4a 100644
--- a/src/files.c
+++ b/src/files.c
@@ -253,7 +253,7 @@ int do_lockfile(const char *filename)
 		+ strlen(locking_suffix) + 3;
     char *lockfilename = charalloc(lockfilesize);
     char *lockfiledir = NULL;
-    char lockprog[12], lockuser[16];
+    static char lockprog[11], lockuser[17];
     struct stat fileinfo;
     int lockfd, lockpid;
 
-- 
2.1.0


From f3e979d92659d19eb1f67c75f728cb979061901d Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 27 Jan 2015 17:30:28 +0100
Subject: [PATCH 5/6] do_lockfile: avoid printing wrong PID in status bar

... due to treating serialized PID bytes as singed integers

Bug: https://bugzilla.redhat.com/1186384
Reported-by:  Don Swaner
---
 src/files.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/files.c b/src/files.c
index 4468b4a..8c832ff 100644
--- a/src/files.c
+++ b/src/files.c
@@ -284,7 +284,7 @@ int do_lockfile(const char *filename)
             return -1;
         }
         strncpy(lockprog, &lockbuf[2], 10);
-        lockpid = lockbuf[25] * 256 + lockbuf[24];
+        lockpid = (unsigned char)lockbuf[25] * 256 + (unsigned char)lockbuf[24];
         strncpy(lockuser, &lockbuf[28], 16);
 #ifdef DEBUG
         fprintf(stderr, "lockpid = %d\n", lockpid);
-- 
2.1.0


From a7f011d98358cd8dc0566494c51b8e37269b6752 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 27 Jan 2015 17:27:44 +0100
Subject: [PATCH 6/6] write_filelock: do not trim nano version

... as snprintf() counts the trailing zero into the size limit
---
 src/files.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/files.c b/src/files.c
index 8c832ff..18be123 100644
--- a/src/files.c
+++ b/src/files.c
@@ -200,7 +200,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
     lockdata[1] = 0x30;
     lockdata[24] = mypid % 256;
     lockdata[25] = mypid / 256;
-    snprintf(&lockdata[2], 10, "nano %s", VERSION);
+    snprintf(&lockdata[2], 11, "nano %s", VERSION);
     strncpy(&lockdata[28], mypwuid->pw_name, 16);
     strncpy(&lockdata[68], myhostname, 31);
     strncpy(&lockdata[108], origfilename, 768);
-- 
2.1.0