If you use mg as the editor with mutt, any backup files mutt creates
are kept in /tmp. However, with backup-to-home-directory enabled all
backup files are moved to ~/.mg.d. Personally, I'd rather not move
these backups but keep them in the /tmp dir.
This modified diff allows backup files that are located in the /tmp
directory to stay there, while allowing all other backups to go to the
~/.mg.d directory. Arguably, this could just be made the default
behaviour (with backup-to-home-directory enabled), however I wrote the
diff with an added an option so am sending the diff with it in. Also,
since this option is not exactly the same as an emacs command I have
chosen a non emacs command name:
leave-tmpdir-backups
Of course, by default nothing is changed in mg. Backups are still
kept in the current directory.
Comments/ok?
-lum
Index: def.h
===================================================================
RCS file: /cvs/src/usr.bin/mg/def.h,v
retrieving revision 1.123
diff -u -p -r1.123 def.h
--- def.h 7 Jun 2012 15:15:04 -0000 1.123
+++ def.h 13 Jun 2012 12:33:06 -0000
@@ -446,6 +446,8 @@ struct list *make_file_list(char *);
int fisdir(const char *);
int fchecktime(struct buffer *);
int fupdstat(struct buffer *);
+int backuptohomedir(int, int);
+int toggleleavetmp(int, int);
/* kbd.c X */
int do_meta(int, int);
Index: fileio.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/fileio.c,v
retrieving revision 1.90
diff -u -p -r1.90 fileio.c
--- fileio.c 11 Jun 2012 18:30:03 -0000 1.90
+++ fileio.c 13 Jun 2012 12:33:06 -0000
@@ -22,6 +22,12 @@
#include "kbd.h"
+static char *bkuplocation(const char *);
+static int bkupleavetmp(const char *);
+
+static char *bkupdir;
+static int leavetmp = 0; /* 1 = leave any '~' files in tmp dir */
+
/*
* Open a file for reading.
*/
@@ -203,23 +209,28 @@ fbackupfile(const char *fn)
int from, to, serrno;
ssize_t nread;
char buf[BUFSIZ];
- char *nname, *tname;
+ char *nname, *tname, *bkpth;
if (stat(fn, &sb) == -1) {
ewprintf("Can't stat %s : %s", fn, strerror(errno));
return (FALSE);
}
- if (asprintf(&nname, "%s~", fn) == -1) {
+ if ((bkpth = bkuplocation(fn)) == NULL)
+ return (FALSE);
+
+ if (asprintf(&nname, "%s~", bkpth) == -1) {
ewprintf("Can't allocate backup file name : %s",
strerror(errno));
+ free(bkpth);
return (ABORT);
}
-
- if (asprintf(&tname, "%s.XXXXXXXXXX", fn) == -1) {
+ if (asprintf(&tname, "%s.XXXXXXXXXX", bkpth) == -1) {
ewprintf("Can't allocate temp file name : %s", strerror(errno));
+ free(bkpth);
free(nname);
return (ABORT);
}
+ free(bkpth);
if ((from = open(fn, O_RDONLY)) == -1) {
free(nname);
@@ -610,4 +621,113 @@ fchecktime(struct buffer *bp)
return (TRUE);
+}
+
+/*
+ * Location of backup file. This function creates the correct path.
+ */
+static char *
+bkuplocation(const char *fn)
+{
+ struct stat sb;
+ char *ret;
+
+ if (bkupdir != NULL && (stat(bkupdir, &sb) == 0) &&
+ S_ISDIR(sb.st_mode) && !bkupleavetmp(fn)) {
+ char fname[NFILEN];
+ const char *c;
+ int i = 0, len;
+
+ c = fn;
+ len = strlen(bkupdir);
+
+ while (*c != '\0') {
+ /* Make sure we don't go over combined:
+ * strlen(bkupdir + '/' + fname + '\0')
+ */
+ if (i >= NFILEN - len - 1)
+ return (NULL);
+ if (*c == '/') {
+ fname[i] = '!';
+ } else if (*c == '!') {
+ if (i >= NFILEN - len - 2)
+ return (NULL);
+ fname[i++] = '!';
+ fname[i] = '!';
+ } else
+ fname[i] = *c;
+ i++;
+ c++;
+ }
+ fname[i] = '\0';
+ if (asprintf(&ret, "%s/%s", bkupdir, fname) == -1)
+ return (NULL);
+
+ } else if ((ret = strndup(fn, NFILEN)) == NULL)
+ return (NULL);
+
+ return (ret);
+}
+
+int
+backuptohomedir(int f, int n)
+{
+ const char *c = "~/.mg.d";
+ char *p;
+
+ if (bkupdir == NULL) {
+ p = adjustname(c, TRUE);
+ bkupdir = strndup(p, NFILEN);
+ if (bkupdir == NULL)
+ return(FALSE);
+
+ if (mkdir(bkupdir, 0700) == -1 && errno != EEXIST) {
+ free(bkupdir);
+ bkupdir = NULL;
+ }
+ } else {
+ free(bkupdir);
+ bkupdir = NULL;
+ }
+
+ return (TRUE);
+}
+
+/*
+ * For applications that use mg as the editor and have a desire to keep
+ * '~' files in the TMPDIR, toggle the location: /tmp | ~/.mg.d
+ */
+int
+toggleleavetmp(int f, int n)
+{
+ leavetmp = !leavetmp;
+
+ return (TRUE);
+}
+
+/*
+ * Returns TRUE if fn is located in the temp directory and we want to save
+ * those backups there.
+ */
+int
+bkupleavetmp(const char *fn)
+{
+ char *tmpdir, *tmp = NULL;
+
+ if (!leavetmp)
+ return(FALSE);
+
+ if((tmpdir = getenv("TMPDIR")) != NULL && *tmpdir != '\0') {
+ tmp = strstr(fn, tmpdir);
+ if (tmp == fn)
+ return (TRUE);
+
+ return (FALSE);
+ }
+
+ tmp = strstr(fn, "/tmp");
+ if (tmp == fn)
+ return (TRUE);
+
+ return (FALSE);
}
Index: funmap.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/funmap.c,v
retrieving revision 1.39
diff -u -p -r1.39 funmap.c
--- funmap.c 7 Jun 2012 15:15:04 -0000 1.39
+++ funmap.c 13 Jun 2012 12:33:06 -0000
@@ -25,6 +25,7 @@ static struct funmap functnames[] = {
{fillmode, "auto-fill-mode",},
{indentmode, "auto-indent-mode",},
{backtoindent, "back-to-indentation",},
+ {backuptohomedir, "backup-to-home-directory",},
{backchar, "backward-char",},
{delbword, "backward-kill-word",},
{gotobop, "backward-paragraph",},
@@ -99,6 +100,7 @@ static struct funmap functnames[] = {
{killpara, "kill-paragraph",},
{killregion, "kill-region",},
{delfword, "kill-word",},
+ {toggleleavetmp, "leave-tmpdir-backups",},
{linenotoggle, "line-number-mode",},
{listbuffers, "list-buffers",},
{evalfile, "load",},
Index: mg.1
===================================================================
RCS file: /cvs/src/usr.bin/mg/mg.1,v
retrieving revision 1.61
diff -u -p -r1.61 mg.1
--- mg.1 7 Jun 2012 15:15:04 -0000 1.61
+++ mg.1 13 Jun 2012 12:33:06 -0000
@@ -350,6 +350,9 @@ to a new line.
Toggle indent mode, where indentation is preserved after a newline.
.It back-to-indentation
Move the dot to the first non-whitespace character on the current line.
+.It backup-to-home-directory
+Save backup copies to a ~/.mg.d directory instead of working directory.
+Requires make-backup-files to be on.
.It backward-char
Move cursor backwards one character.
.It backward-kill-word
@@ -635,6 +638,10 @@ at the end of buffer.
When disabled, the meta key can be used to insert extended-ascii (8-bit)
characters.
When enabled, the meta key acts as usual.
+.It leave-tmpdir-backups
+Modifies the behaviour of backup-to-home-directory.
+Backup files that would normally reside in the system TMPDIR are
+left there and not moved to the ~/.mg.d directory.
.It negative-argument
Process a negative argument for keyboard-invoked functions.
.It newline