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