]> git.wh0rd.org Git - nano.git/commitdiff
Martin Ehmsen's backup directory patch, with a few minor changes
authorDavid Lawrence Ramsey <pooka109@gmail.com>
Sat, 28 Feb 2004 16:24:31 +0000 (16:24 +0000)
committerDavid Lawrence Ramsey <pooka109@gmail.com>
Sat, 28 Feb 2004 16:24:31 +0000 (16:24 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1674 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
doc/man/nano.1
doc/man/nanorc.5
doc/nanorc.sample
doc/texinfo/nano.texi
src/files.c
src/global.c
src/nano.c
src/proto.h
src/rcfile.c

index df7d735d9f7206f2e61817b1680ed20f5313e3a2..d240b3f7ac1850e8986f5b900c0f4ef1ab3fee34 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -23,6 +23,13 @@ CVS code -
        - Decouple the paragraph searching code and the justifying code.
          Removed function do_para_operation(); new function
          do_para_search(); changes to do_justify(). (DLR)
+       - Add -E/--backupdir option.  When used with -B/--backup, backup
+         files will be saved in the specified directory with their
+         canonical pathnames encoded in their names (all '/'s replaced
+         with '!'s).  Changes to write_file(). (Martin Ehmsen)  DLR:
+         Add function init_backup_dir() to handle relative paths
+         correctly, use get_full_path() to get the canonical pathname,
+         and use tail() to get the filename if get_full_path() fails.
 - files.c:
   add_open_files()
        - Make the saving of marked status in open_files->file_flags
@@ -199,6 +206,11 @@ CVS code -
          not 1.1.12. (DLR)
 - nano.1, nanorc.5, nano.texi
        - Clarify the description for -T/--tabsize a bit. (DLR)
+       - Add -E/--backupdir description. (Martin Ehmsen; minor cosmetic
+         fixes by DLR)
+- nanorc.sample:
+       - Add backupdir description. (Martin Ehmsen; minor cosmetic
+         fixes by DLR)
 - README:
        - Reformat to 72 characters per line, fix wording in one spot,
          and fix spacing in several spots. (DLR)
index a8b7e63007d1ef27210c140ac7d9547e609ca011..889732c02a78e95bf71096a6ced643e12ae885d3 100644 (file)
@@ -42,6 +42,10 @@ filename suffixed with a ~.
 .B \-D (\-\-dos)
 Write file in DOS format.
 .TP
+.B \-E \fIdir\fP (\-\-backupdir=\fIdir\fP)
+Set the directory where \fBnano\fP puts the backup files if file backups
+are enabled.
+.TP
 .B \-F (\-\-multibuffer)
 Enable multiple file buffers, if available.
 .TP
index 05873459a872f83da1452cf5d5c0477c486b6bdd..924da881ee72adee5964784180f827a1178e88af 100644 (file)
@@ -47,6 +47,10 @@ Use auto-indentation.
 Create backup files in
 .IR filename~ .
 .TP
+\fBset backupdir "\fIdirectory\fP"\fP
+Set the directory where \fBnano\fP puts the backup files if file backups
+are enabled.
+.TP
 \fBset/unset const\fP
 Constantly display the cursor position in the status bar.
 .TP
index eee7cdb36621c554a4ffc479b2ba7494d7f5c63d..98bb6a8a2573833e5e5f79df0696ec6d56f4d224 100644 (file)
@@ -14,6 +14,9 @@
 ## Backup files to filename~
 # set backup
 
+## The directory to put the backup files in.
+# set backupdir ""
+
 ## Constantly display the cursor position in the status bar.
 # set const
 
index 487f555de281f85211e509af08a64a0afe7e1a73..1158d28ab244e7eaca5e7609395b07617c88968a 100644 (file)
@@ -114,6 +114,10 @@ filename suffixed with a ~.
 @item -D, --dos
 Write file in DOS format.
 
+@item -E, --backupdir=[dir]
+Set the directory where @code{nano) puts the backup files if file
+backups are enabled.
+
 @item -F, --multibuffer
 Enable multiple file buffers, if available.
 
index 04d043d7497321ebb02c3dda8d99f2d0e7fc3615..d69c46b8734f6fcd953a80a4c99499ab3a40ac13 100644 (file)
@@ -1026,7 +1026,7 @@ int close_open_file(void)
 }
 #endif /* MULTIBUFFER */
 
-#if !defined(DISABLE_SPELLER) || !defined(DISABLE_OPERATINGDIR)
+#if !defined(DISABLE_SPELLER) || !defined(DISABLE_OPERATINGDIR) || !defined(NANO_SMALL)
 /*
  * When passed "[relative path]" or "[relative path][filename]" in
  * origpath, return "[full path]" or "[full path][filename]" on success,
@@ -1333,6 +1333,30 @@ int check_operating_dir(const char *currpath, int allow_tabcomp)
 }
 #endif
 
+#ifndef NANO_SMALL
+void init_backup_dir(void)
+{
+    char *full_backup_dir;
+
+    if (backup_dir == NULL)
+       return;
+
+    full_backup_dir = get_full_path(backup_dir);
+
+    /* If get_full_path() failed or the backup directory is
+     * inaccessible, unset backup_dir. */
+    if (full_backup_dir == NULL ||
+       full_backup_dir[strlen(full_backup_dir) - 1] != '/') {
+       free(full_backup_dir);
+       free(backup_dir);
+       backup_dir = NULL;
+    } else {
+       free(backup_dir);
+       backup_dir = full_backup_dir;
+    }
+}
+#endif
+
 /* Read from inn, write to out.  We assume inn is opened for reading,
  * and out for writing.  We return 0 on success, -1 on read error, -2 on
  * write error. */
@@ -1465,8 +1489,38 @@ int write_file(const char *name, int tmp, int append, int nonamechange)
            goto cleanup_and_exit;
        }
 
-       backupname = charalloc(strlen(realname) + 2);
-       sprintf(backupname, "%s~", realname);
+       /* If backup_dir is set, we set backupname to
+        * backup_dir/backupname~, where backupnae is the canonicalized
+        * absolute pathname of realname with every '/' replaced with a
+        * '!'.  This means that /home/foo/file is backed up in
+        * backup_dir/!home!foo!file~. */
+       if (backup_dir != NULL) {
+           char *canon_realname = get_full_path(realname);
+           size_t i;
+
+           if (canon_realname == NULL)
+               /* If get_full_path() failed, we don't have a
+                * canonicalized absolute pathname, so just use the
+                * filename portion of the pathname.  We use tail() so
+                * that e.g. ../backupname will be backed up in
+                * backupdir/backupname~ instead of
+                * backupdir/../backupname~. */
+               canon_realname = mallocstrcpy(NULL, tail(realname));
+           else {
+               for (i = 0; canon_realname[i] != '\0'; i++) {
+                   if (canon_realname[i] == '/')
+                       canon_realname[i] = '!';
+               }
+           }
+
+           backupname = charalloc(strlen(backup_dir) +
+               strlen(canon_realname) + 2);
+           sprintf(backupname, "%s%s~", backup_dir, canon_realname);
+           free(canon_realname);
+       } else {
+           backupname = charalloc(strlen(realname) + 2);
+           sprintf(backupname, "%s~", realname);
+       }
 
        /* Open the destination backup file.  Before we write to it, we
         * set its permissions, so no unauthorized person can read it as
@@ -2370,6 +2424,23 @@ char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
 }
 #endif /* !DISABLE_TABCOMP */
 
+#if !defined(DISABLE_BROWSER) || !defined(NANO_SMALL)
+/* Only print the last part of a path; isn't there a shell
+ * command for this? */
+const char *tail(const char *foo)
+{
+    const char *tmp = foo + strlen(foo);
+
+    while (*tmp != '/' && tmp != foo)
+       tmp--;
+
+    if (*tmp == '/')
+       tmp++;
+
+    return tmp;
+}
+#endif
+
 #ifndef DISABLE_BROWSER
 /* Our sort routine for file listings -- sort directories before
  * files, and then alphabetically. */ 
@@ -2396,21 +2467,6 @@ void free_charptrarray(char **array, int len)
     free(array);
 }
 
-/* Only print the last part of a path; isn't there a shell 
- * command for this? */
-const char *tail(const char *foo)
-{
-    const char *tmp = foo + strlen(foo);
-
-    while (*tmp != '/' && tmp != foo)
-       tmp--;
-
-    if (*tmp == '/')
-       tmp++;
-
-    return tmp;
-}
-
 /* Strip one dir from the end of a string. */
 void striponedir(char *foo)
 {
index 4e4ec3774106e8d2fedd09eb1c1c0c6b450e1095..34d27aa04b072b85ffa8319f33a22419958dd87a 100644 (file)
@@ -72,6 +72,10 @@ char *quotestr = NULL;               /* Quote string.  The default value is
                                   set in main(). */
 #endif
 
+#ifndef NANO_SMALL
+char *backup_dir = NULL;       /* Backup directory. */
+#endif
+
 int resetstatuspos;            /* Hack for resetting the status bar 
                                   cursor position */
 char *answer = NULL;           /* Answer str to many questions */
@@ -932,6 +936,10 @@ void thanks_for_all_the_fish(void)
     if (quotestr != NULL)
        free(quotestr);
 #endif
+#ifndef NANO_SMALL
+    if (backup_dir != NULL)
+        free(backup_dir);
+#endif
 #ifndef DISABLE_OPERATINGDIR
     if (operating_dir != NULL)
        free(operating_dir);
index e2dc353ecb0a639d69149a9e03b1ae0edc973b10..15c1fe5eb4361083d583a069f9382203b89539cb 100644 (file)
@@ -629,6 +629,7 @@ void usage(void)
 #ifndef NANO_SMALL
     print1opt("-B", "--backup", _("Backup existing files on save"));
     print1opt("-D", "--dos", _("Write file in DOS format"));
+    print1opt("-E", "--backupdir=[dir]", _("Directory for writing backup files"));
 #endif
 #ifdef ENABLE_MULTIBUFFER
     print1opt("-F", "--multibuffer", _("Enable multiple file buffers"));
@@ -3152,6 +3153,7 @@ int main(int argc, char *argv[])
 #ifndef NANO_SMALL
        {"backup", 0, 0, 'B'},
        {"dos", 0, 0, 'D'},
+       {"backupdir", 1, 0, 'E'},
        {"mac", 0, 0, 'M'},
        {"noconvert", 0, 0, 'N'},
        {"smooth", 0, 0, 'S'},
@@ -3176,11 +3178,11 @@ int main(int argc, char *argv[])
 #endif
 
 #ifdef HAVE_GETOPT_LONG
-    while ((optchr = getopt_long(argc, argv, "h?BDFHIMNQ:RST:VY:abcdefgijklmo:pr:s:tvwxz",
+    while ((optchr = getopt_long(argc, argv, "h?BDE:FHIMNQ:RST:VY:abcdefgijklmo:pr:s:tvwxz",
                                 long_options, NULL)) != -1) {
 #else
     while ((optchr =
-           getopt(argc, argv, "h?BDFHIMNQ:RST:VY:abcdefgijklmo:pr:s:tvwxz")) != -1) {
+           getopt(argc, argv, "h?BDE:FHIMNQ:RST:VY:abcdefgijklmo:pr:s:tvwxz")) != -1) {
 #endif
 
        switch (optchr) {
@@ -3200,6 +3202,9 @@ int main(int argc, char *argv[])
        case 'D':
            SET(DOS_FILE);
            break;
+       case 'E':
+           backup_dir = mallocstrcpy(backup_dir, optarg);
+           break;
 #endif
 #ifdef ENABLE_MULTIBUFFER
        case 'F':
@@ -3350,6 +3355,9 @@ int main(int argc, char *argv[])
 #ifndef DISABLE_WRAPPING
        int wrap_at_cpy = wrap_at;
 #endif
+#ifndef NANO_SMALL
+       char *backup_dir_cpy = backup_dir;
+#endif
 #ifndef DISABLE_JUSTIFY
        char *quotestr_cpy = quotestr;
 #endif
@@ -3362,6 +3370,9 @@ int main(int argc, char *argv[])
 #ifndef DISABLE_OPERATINGDIR
        operating_dir = NULL;
 #endif
+#ifndef NANO_SMALL
+       backup_dir = NULL;
+#endif
 #ifndef DISABLE_JUSTIFY
        quotestr = NULL;
 #endif
@@ -3381,6 +3392,12 @@ int main(int argc, char *argv[])
        if (fill_flag_used)
            wrap_at = wrap_at_cpy;
 #endif
+#ifndef NANO_SMALL
+       if (backup_dir_cpy != NULL) {
+           free(backup_dir);
+           backup_dir = backup_dir_cpy;
+       }
+#endif 
 #ifndef DISABLE_JUSTIFY
        if (quotestr_cpy != NULL) {
            free(quotestr);
@@ -3411,6 +3428,12 @@ int main(int argc, char *argv[])
 #endif
 #endif
 
+#ifndef NANO_SMALL
+    /* Set up the backup directory.  This entails making sure it exists
+     * and is a directory, so that backup files will be saved there. */
+    init_backup_dir();
+#endif
+
 #ifndef DISABLE_OPERATINGDIR
     /* Set up the operating directory.  This entails chdir()ing there,
        so that file reads and writes will be based there. */
@@ -3425,6 +3448,7 @@ int main(int argc, char *argv[])
        quotestr = mallocstrcpy(NULL, "> ");
 #endif
 #endif /* !DISABLE_JUSTIFY */
+
     if (tabsize == -1)
        tabsize = 8;
 
index d330b7d6758bac2cb48ffbf6851df871e650b445..83697ffcb3392e7e3ee89d6082c37efe2648551c 100644 (file)
@@ -50,6 +50,10 @@ extern int currslen;
 extern char *quotestr;
 #endif
 
+#ifndef NANO_SMALL
+extern char *backup_dir;
+#endif
+
 extern WINDOW *edit, *topwin, *bottomwin;
 extern char *filename;
 extern struct stat originalfilestat;
@@ -178,6 +182,9 @@ char *safe_tempnam(const char *dirname, const char *filename_prefix);
 void init_operating_dir(void);
 int check_operating_dir(const char *currpath, int allow_tabcomp);
 #endif
+#ifndef NANO_SMALL
+void init_backup_dir(void);
+#endif
 int write_file(const char *name, int tmp, int append, int nonamechange);
 #ifndef NANO_SMALL
 int write_marked(const char *name, int tmp, int append, int
@@ -192,10 +199,12 @@ char **username_tab_completion(char *buf, int *num_matches);
 char **cwd_tab_completion(char *buf, int *num_matches);
 char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list);
 #endif
+#if !defined(DISABLE_BROWSER) || !defined(NANO_SMALL)
+const char *tail(const char *foo);
+#endif
 #ifndef DISABLE_BROWSER
 int diralphasort(const void *va, const void *vb);
 void free_charptrarray(char **array, int len);
-const char *tail(const char *foo);
 void striponedir(char *foo);
 int readable_dir(const char *path);
 char **browser_init(const char *path, int *longest, int *numents);
index e15379c90d52fe9a43c821cdfd92c2f8c58dfd0b..dcfdb8c7959e24fa7e3ff2ac5eb0d5fdfe9f40aa 100644 (file)
@@ -41,6 +41,7 @@ const static rcoption rcopts[] = {
 #ifndef NANO_SMALL
     {"autoindent", AUTOINDENT},
     {"backup", BACKUP_FILE},
+    {"backupdir", 0},
 #endif
     {"const", CONSTUPDATE},
 #ifndef NANO_SMALL
@@ -145,12 +146,12 @@ char *parse_next_word(char *ptr)
     return ptr;
 }
 
-/* The keywords operatingdir, fill, tabsize, speller, and quotestr take
- * an argument when set.  Among these, operatingdir, speller, and
- * quotestr have to allow tabs and spaces in the argument.  Thus, if the
- * next word starts with a ", we say it ends with the last " of the line.
- * Otherwise, the word is interpreted as usual.  That is so the arguments
- * can contain "s too. */
+/* The keywords operatingdir, backupdir, fill, tabsize, speller, and
+ * quotestr take an argument when set.  Among these, operatingdir,
+ * backupdir, speller, and quotestr have to allow tabs and spaces in the
+ * argument.  Thus, if the next word starts with a ", we say it ends
+ * with the last " of the line.  Otherwise, the word is interpreted as
+ * usual.  That is so the arguments can contain "s too. */
 char *parse_argument(char *ptr)
 {
     const char *ptr_bak = ptr;
@@ -540,6 +541,9 @@ void parse_rcfile(FILE *rcstream)
 #ifndef DISABLE_JUSTIFY
                                || !strcasecmp(rcopts[i].name, "quotestr")
 #endif
+#ifndef NANO_SMALL
+                               || !strcasecmp(rcopts[i].name, "backupdir")
+#endif
 #ifndef DISABLE_SPELLER
                                || !strcasecmp(rcopts[i].name, "speller")
 #endif
@@ -582,6 +586,11 @@ void parse_rcfile(FILE *rcstream)
                                quotestr = mallocstrcpy(NULL, option);
                            else
 #endif
+#ifndef NANO_SMALL
+                           if (!strcasecmp(rcopts[i].name, "backupdir"))
+                               backup_dir = mallocstrcpy(NULL, option);
+                           else
+#endif
 #ifndef DISABLE_SPELLER
                            if (!strcasecmp(rcopts[i].name, "speller"))
                                alt_speller = mallocstrcpy(NULL, option);