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

Reply via email to