1
1

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
Этот коммит содержится в:
David Lawrence Ramsey 2004-02-28 16:24:31 +00:00
родитель 6a2877d399
Коммит 04e42a6bcc
10 изменённых файлов: 160 добавлений и 27 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);