Currently, in mg, if you try to open a file that doesn't exist and has
a name longer than LOGIN_NAME_MAX and also has a tilde at the front
e.g. 

  $ mg ~01234567890123456789012345678901

you will receive a msg:

    Login name too long

Since the filename cannot be a user name (it is too long), mg should
open up a new buffer with the file name as the buffer name. This diff
makes mg behave like that which also mimics the behaviour of emacs. 

As you can see I have put all the relevant code in a function, the
fix concerns the lines following:

+       if (ulen >= sizeof(user)) {

ok?

-lum

Index: fileio.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/fileio.c,v
retrieving revision 1.91
diff -u -p -r1.91 fileio.c
--- fileio.c    14 Jun 2012 17:21:22 -0000      1.91
+++ fileio.c    14 Jun 2012 17:56:42 -0000
@@ -24,6 +24,7 @@
 
 static char *bkuplocation(const char *);
 static int   bkupleavetmp(const char *);
+char       *expandtilde(const char *);
 
 static char *bkupdir;
 static int   leavetmp = 0;     /* 1 = leave any '~' files in tmp dir */  
@@ -281,13 +282,9 @@ fbackupfile(const char *fn)
 char *
 adjustname(const char *fn, int slashslash)
 {
-       struct stat      statbuf; 
        static char      fnb[MAXPATHLEN];
        const char      *cp, *ep = NULL;
-       char             user[LOGIN_NAME_MAX], path[MAXPATHLEN];
-       size_t           ulen, plen;
-
-       path[0] = '\0';
+       char            *path;
 
        if (slashslash == TRUE) {
                cp = fn + strlen(fn) - 1;
@@ -302,50 +299,8 @@ adjustname(const char *fn, int slashslas
                                ep = NULL;
                }
        }
-
-       /* 
-        * Next, expand file names beginning with '~', if appropriate:
-        *   1, if ./~fn exists, continue without expanding tilde.
-        *   2, otherwise, if username 'fn' exists, expand tilde with home
-        *      directory path.
-        *   3, otherwise, continue and create new buffer called ~fn.
-        */
-       if (fn[0] == '~' && stat(fn, &statbuf) != 0) {
-               struct passwd *pw;
-
-               cp = strchr(fn, '/');
-               if (cp == NULL)
-                       cp = fn + strlen(fn); /* point to the NUL byte */
-               ulen = cp - &fn[1];
-               if (ulen >= sizeof(user)) {
-                       ewprintf("Login name too long");
-                       return (NULL);
-               }
-               if (ulen == 0) /* ~/ or ~ */
-                       (void)strlcpy(user, getlogin(), sizeof(user));
-               else { /* ~user/ or ~user */
-                       memcpy(user, &fn[1], ulen);
-                       user[ulen] = '\0';
-               }
-               pw = getpwnam(user);
-               if (pw != NULL) {
-                       plen = strlcpy(path, pw->pw_dir, sizeof(path));
-                       if (plen == 0 || path[plen - 1] != '/') {
-                               if (strlcat(path, "/", sizeof(path)) >=
-                                   sizeof(path)) {
-                                       ewprintf("Path too long");
-                                       return (NULL);
-                               }
-                       }
-                       fn = cp;
-                       if (*fn == '/')
-                               fn++;
-               }
-       }
-       if (strlcat(path, fn, sizeof(path)) >= sizeof(path)) {
-               ewprintf("Path too long");
+       if ((path = expandtilde(fn)) == NULL)
                return (NULL);
-       }
 
        if (realpath(path, fnb) == NULL)
                (void)strlcpy(fnb, path, sizeof(fnb));
@@ -730,4 +685,64 @@ bkupleavetmp(const char *fn)
                return (TRUE);
 
        return (FALSE);
+}
+
+/* 
+ * Expand file names beginning with '~' if appropriate:
+ *   1, if ./~fn exists, continue without expanding tilde.
+ *   2, else, if username 'fn' exists, expand tilde with home directory path.
+ *   3, otherwise, continue and create new buffer called ~fn.
+ */
+char *
+expandtilde(const char *fn)
+{
+       struct passwd   *pw;
+       struct stat      statbuf;
+       const char      *cp;
+       char             user[LOGIN_NAME_MAX], path[NFILEN], *ret;
+       size_t           ulen, plen;
+
+       path[0] = '\0';
+
+        if (fn[0] != '~' || stat(fn, &statbuf) == 0) {
+               if ((ret = strndup(fn, NFILEN)) == NULL)
+                       return (NULL);
+               return(ret);
+       }
+       cp = strchr(fn, '/');
+       if (cp == NULL)
+               cp = fn + strlen(fn); /* point to the NUL byte */
+       ulen = cp - &fn[1];
+       if (ulen >= sizeof(user)) {
+               if ((ret = strndup(fn, NFILEN)) == NULL)
+                       return (NULL);
+               return(ret);
+       }
+       if (ulen == 0) /* ~/ or ~ */
+               (void)strlcpy(user, getlogin(), sizeof(user));
+       else { /* ~user/ or ~user */
+               memcpy(user, &fn[1], ulen);
+               user[ulen] = '\0';
+        }
+       pw = getpwnam(user);
+       if (pw != NULL) {
+               plen = strlcpy(path, pw->pw_dir, sizeof(path));
+               if (plen == 0 || path[plen - 1] != '/') {
+                       if (strlcat(path, "/", sizeof(path)) >= sizeof(path)) {
+                               ewprintf("Path too long");
+                               return (NULL);
+                       }
+                }
+               fn = cp;
+               if (*fn == '/')
+                       fn++;
+        }
+        if (strlcat(path, fn, sizeof(path)) >= sizeof(path)) {
+                ewprintf("Path too long");
+                return (NULL);
+        }
+       if ((ret = strndup(path, NFILEN)) == NULL)
+               return (NULL);
+
+       return (ret);
 }

Reply via email to