- 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
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)
.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
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
## 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
@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.
}
#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,
}
#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. */
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
}
#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. */
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)
{
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 */
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);
#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"));
#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'},
#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) {
case 'D':
SET(DOS_FILE);
break;
+ case 'E':
+ backup_dir = mallocstrcpy(backup_dir, optarg);
+ break;
#endif
#ifdef ENABLE_MULTIBUFFER
case 'F':
#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
#ifndef DISABLE_OPERATINGDIR
operating_dir = NULL;
#endif
+#ifndef NANO_SMALL
+ backup_dir = NULL;
+#endif
#ifndef DISABLE_JUSTIFY
quotestr = NULL;
#endif
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);
#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. */
quotestr = mallocstrcpy(NULL, "> ");
#endif
#endif /* !DISABLE_JUSTIFY */
+
if (tabsize == -1)
tabsize = 8;
extern char *quotestr;
#endif
+#ifndef NANO_SMALL
+extern char *backup_dir;
+#endif
+
extern WINDOW *edit, *topwin, *bottomwin;
extern char *filename;
extern struct stat originalfilestat;
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
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);
#ifndef NANO_SMALL
{"autoindent", AUTOINDENT},
{"backup", BACKUP_FILE},
+ {"backupdir", 0},
#endif
{"const", CONSTUPDATE},
#ifndef NANO_SMALL
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;
#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
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);