Martin Ehmsen's backup directory patch, with a few minor changes
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1674 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Этот коммит содержится в:
родитель
6a2877d399
Коммит
04e42a6bcc
12
ChangeLog
12
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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
92
src/files.c
92
src/files.c
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
28
src/nano.c
28
src/nano.c
@ -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;
|
||||
|
||||
|
11
src/proto.h
11
src/proto.h
@ -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);
|
||||
|
21
src/rcfile.c
21
src/rcfile.c
@ -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);
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user