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