NetBSD Problem Report #47577
From www@NetBSD.org Mon Feb 18 14:22:33 2013
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
by www.NetBSD.org (Postfix) with ESMTP id 3423563E500
for <gnats-bugs@gnats.NetBSD.org>; Mon, 18 Feb 2013 14:22:33 +0000 (UTC)
Message-Id: <20130218142231.41CE363E500@www.NetBSD.org>
Date: Mon, 18 Feb 2013 14:22:31 +0000 (UTC)
From: sdaoden@gmail.com
Reply-To: sdaoden@gmail.com
To: gnats-bugs@NetBSD.org
Subject: Mail(1)/mail(1)/mailx(1) gets stuck when current folder becomes accessible
X-Send-Pr-Version: www-1.0
>Number: 47577
>Category: bin
>Synopsis: Mail(1)/mail(1)/mailx(1) gets stuck when current folder becomes accessible
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Feb 18 14:25:00 +0000 2013
>Last-Modified: Mon Feb 25 19:20:04 +0000 2013
>Originator: Steffen Nurpmeso
>Release: 6.99.16
>Organization:
>Environment:
NetBSD nhead 6.99.16 NetBSD 6.99.16 (GENERIC) #0: Mon Feb 11 21:12:26 UTC 2013 builds@b6.netbsd.org:/home/builds/ab/HEAD/amd64/201302111840Z-obj/home/builds/ab/HEAD/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
Yes, and i forgot this one.
If you open a folder with a relative path, use the cd command to change the current working directory, then any action that needs to update the opened folder (as opposed to the temporary MBOX; e.g., switching to a different folder) will fail and claim that the opened folder is not accessible.
You need to cd to a path which turns the relative folder path accessible again to be able to continue.
This is just one facet of a basic architectural problem of Berkeley Mail, i.e., concurrent deletion of the current folder etc. still bails, but for this particular aspect the solution is easy.
>How-To-Repeat:
See desc.
>Fix:
--- cmd3.c.orig 2013-02-18 13:36:32.000000000 +0100
+++ cmd3.c 2013-02-18 13:35:36.000000000 +0100
@@ -201,7 +201,7 @@ help(void *v __unused)
PUBLIC int
schdir(void *v)
{
- char **arglist;
+ char rpath[PATHSIZE], **arglist;
const char *cp;
arglist = v;
@@ -210,6 +210,15 @@ schdir(void *v)
else
if ((cp = expand(*arglist)) == NULL)
return 1;
+
+ if (mailname[0] != '/') {
+ if (realpath(mailname, rpath) == NULL) {
+ perror("Cannot canonicalize path of current folder");
+ return 1;
+ }
+ (void)stpcpy(mailname, rpath);
+ }
+
if (chdir(cp) < 0) {
warn("%s", cp);
return 1;
>Audit-Trail:
From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@NetBSD.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Cc:
Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current folder becomes accessible
Date: Mon, 18 Feb 2013 10:49:26 -0500
On Feb 18, 2:25pm, sdaoden@gmail.com (sdaoden@gmail.com) wrote:
-- Subject: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current folde
| If you open a folder with a relative path, use the cd command to change the current working directory, then any action that needs to update the opened folder (as opposed to the temporary MBOX; e.g., switching to a different folder) will fail and claim that the opened folder is not accessible.
| You need to cd to a path which turns the relative folder path accessible again to be able to continue.
| This is just one facet of a basic architectural problem of Berkeley Mail, i.e., concurrent deletion of the current folder etc. still bails, but for this particular aspect the solution is easy.
I think it is better to canonicalize the name when the name is set? No?
christos
From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, sdaoden@gmail.com
Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current
folder becomes accessible
Date: Mon, 18 Feb 2013 19:19:07 +0100
christos@zoulas.com (Christos Zoulas) wrote:
| On Feb 18, 2:25pm, sdaoden@gmail.com (sdaoden@gmail.com) wrote:
| -- Subject: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current =
\
|folde
|=20
|| If you open a folder with a relative path, use the cd command to change=
\
| the current working directory, then any action that needs to update the=
\
| opened folder (as opposed to the temporary MBOX; e.g., switching to a \
| different folder) will fail and claim that the opened folder is not \
| accessible.
|| You need to cd to a path which turns the relative folder path accessibl=
e \
| again to be able to continue.
|| This is just one facet of a basic architectural problem of Berkeley Mai=
l, \
| i.e., concurrent deletion of the current folder etc. still bails, but f=
or \
| this particular aspect the solution is easy.
|=20
| I think it is better to canonicalize the name when the name is set? No?
Sure; "fi" etc. then always show an absolute path, which is often
annoying imho, especially on 80 column terminals, though.
I as a user would then really like to see some
"/path1/[...]/folder" instead of "p1/p2/p3/p4/folder". I, e.g.,
often have problems with mksh(1) because that radically cuts job
paths at 40 (or so) characters, so that i sometimes have to check
ps(1) to know which job relates to what command.
So then i would possibly consider a basename(3)/realpath(3) tuple
(or, better, a path and an offset) from the begin on, the one for
display and the other for file operations.
Possibly overkill; I think even then i would delay the realpath(3)
until this very command is used, because (1) it is very expensive
(not that expensive with a getcwd() syscall, but still), and (2)
it is completely useless unless the cd command is used. I've just
encountered the problem that the Berkeley codebase stucks
completely unless the open folder comes into sight again, and that
was an at-a-glance solution for this particular problem, which
works automatically and without user interaction.
I haven't considered yet the basename(3)/realpath(3) solution;
hmmm; i think i look into that tomorrow, and come back with an
alternative patch if it's easy to implement -- i couldn't tell how
many places would need to be changed right now.
| christos
--steffen
From: christos@zoulas.com (Christos Zoulas)
To: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>, gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current folder becomes accessible
Date: Mon, 18 Feb 2013 13:51:03 -0500
On Feb 18, 7:19pm, sdaoden@gmail.com (Steffen "Daode" Nurpmeso) wrote:
-- Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current f
| Sure; "fi" etc. then always show an absolute path, which is often
| annoying imho, especially on 80 column terminals, though.
So keep a "displayname" and a "resolvedname" so you always show the
displayname. It is strange that the name will change when the user cds?
Don't you agree?
christos
From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: christos@zoulas.com (Christos Zoulas)
Cc: gnats-admin@netbsd.org, gnats-bugs@NetBSD.org,
netbsd-bugs@netbsd.org
Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current
folder becomes accessible
Date: Mon, 18 Feb 2013 20:07:55 +0100
christos@zoulas.com (Christos Zoulas) wrote:
|On Feb 18, 7:19pm, sdaoden@gmail.com (Steffen "Daode" Nurpmeso) wrote:
|-- Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current \
|f
|
|| Sure; "fi" etc. then always show an absolute path, which is often
|| annoying imho, especially on 80 column terminals, though.
|
|So keep a "displayname" and a "resolvedname" so you always show the
|displayname. It is strange that the name will change when the user cds?
|Don't you agree?
Sound good to me.
I'll take a look tomorrow.
|christos
--steffen
From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current
folder becomes accessible
Date: Mon, 18 Feb 2013 21:54:39 +0100
christos@zoulas.com (Christos Zoulas) wrote:
|| Sure; "fi" etc. then always show an absolute path, which is often
|| annoying imho, especially on 80 column terminals, though.
|=20
| So keep a "displayname" and a "resolvedname" so you always show the
| displayname. It is strange that the name will change when the user cds?
| Don't you agree?
I took a quick look, and i think it'll be more complicated.
I also think that my solution is too simple minded, for the
Berkeley codebase as such, at least because lex.c:newfileinfo()
tries to abbreviate folders which have the same path prefix as the
value of the *folder* option to "+BOX"; all this is thus
inherently broken ... so to say.
I'll continue tomorrow, but append a diff that fixes usage of an
inner-scope buffer that is used outside the scope.
| christos
--steffen
--- lex.c.orig 2013-02-18 17:38:31.000000000 +0100
+++ lex.c 2013-02-18 18:05:47.000000000 +0100
@@ -974,7 +974,7 @@ newfileinfo(int omsgCount)
{
struct message *mp;
int d, n, s, t, u, mdot;
- char fname[PATHSIZE];
+ char fname[PATHSIZE], zname[PATHSIZE];
char *ename;
=20
/*
@@ -1021,7 +1021,6 @@ newfileinfo(int omsgCount)
}
ename =3D mailname;
if (getfold(fname, sizeof(fname)) >=3D 0) {
- char zname[PATHSIZE];
size_t l;
l =3D strlen(fname);
if (l < sizeof(fname) - 1)
From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current
folder becomes accessible
Date: Tue, 19 Feb 2013 18:10:12 +0100
|The following reply was made to PR bin/47577; it has been noted by GNATS.
|
|From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
|To: christos@zoulas.com (Christos Zoulas)
|Cc: gnats-admin@netbsd.org, gnats-bugs@NetBSD.org,
| netbsd-bugs@netbsd.org
|Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current
| folder becomes accessible
|Date: Mon, 18 Feb 2013 20:07:55 +0100
|
| christos@zoulas.com (Christos Zoulas) wrote:
||On Feb 18, 7:19pm, sdaoden@gmail.com (Steffen "Daode" Nurpmeso) wrote:
||-- Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when \
| current \
||f
||
||| Sure; "fi" etc. then always show an absolute path, which is often
||| annoying imho, especially on 80 column terminals, though.
||
||So keep a "displayname" and a "resolvedname" so you always show the
||displayname. It is strange that the name will change when the user cds?
||Don't you agree?
This seems to work after some testing; the actual display length
can be controlled by adjusting sizeof(displayname).
Forgive if i f..d up something, but don't think so.
Ciao,
--steffen
--- fio.c.orig 2013-02-19 01:06:53.000000000 +0100
+++ fio.c 2013-02-19 03:00:56.000000000 +0100
@@ -392,14 +392,18 @@ fsize(FILE *iob)
PUBLIC int
getfold(char *name, size_t namesize)
{
+ char unres[PATHSIZE], res[PATHSIZE];
char *folder;
=20
if ((folder =3D value(ENAME_FOLDER)) =3D=3D NULL)
return -1;
if (*folder =3D=3D '/')
- (void)strlcpy(name, folder, namesize);
+ (void)strlcpy(unres, folder, sizeof unres);
else
- (void)snprintf(name, namesize, "%s/%s", homedir, folder);
+ (void)snprintf(unres, sizeof unres, "%s/%s", homedir, folder);
+ if (realpath(unres, res) =3D=3D NULL)
+ err(EXIT_FAILURE, "Can't canonicalize *folder* `%s'", unres);
+ (void)strlcpy(name, res, namesize);
return 0;
}
=20
--- glob.h.orig 2013-02-18 17:39:46.000000000 +0100
+++ glob.h 2013-02-19 03:02:37.000000000 +0100
@@ -59,6 +59,7 @@ EXTERN FILE *otf; /* Output temp file
EXTERN int image; /* File descriptor for image of msg */
EXTERN FILE *input; /* Current command input file */
EXTERN char mailname[PATHSIZE]; /* Name of current file */
+EXTERN char displayname[80]; /* Prettyfied for display */
EXTERN char prevfile[PATHSIZE]; /* Name of previous file */
EXTERN char *tmpdir; /* Path name of temp directory */
EXTERN char *homedir; /* Path name of home directory */
--- lex.c.orig 2013-02-18 17:38:31.000000000 +0100
+++ lex.c 2013-02-19 03:05:58.000000000 +0100
@@ -141,6 +141,45 @@ file_leak_check(void)
}
#endif /* DEBUG_FILE_LEAK */
=20
+static void
+_update_mailname(char const *name)
+{
+ char tbuf[PATHSIZE];
+ size_t l;
+
+ if (realpath(name, mailname) =3D=3D NULL)
+ err(EXIT_FAILURE, "Can't canonicalize `%s'", name);
+
+ if (getfold(tbuf, sizeof tbuf) >=3D 0) {
+ l =3D strlen(tbuf);
+ if (l < sizeof(tbuf) - 1)
+ tbuf[l++] =3D '/';
+ if (strncmp(tbuf, mailname, l) =3D=3D 0) {
+ char const *sep =3D "", *cp =3D mailname + l;
+
+ l =3D strlen(cp);
+ if (l >=3D sizeof displayname) {
+ cp +=3D l;
+ cp -=3D sizeof(displayname) - 5;
+ sep =3D "...";
+ }
+ (void)snprintf(displayname, sizeof displayname,
+ "+%s%s", sep, cp);
+ goto jleave;
+ }
+ }
+
+ l =3D strlen(mailname);
+ if (l < sizeof displayname)
+ strcpy(displayname, mailname);
+ else {
+ l -=3D sizeof(displayname) - 4 - sizeof(displayname) / 3;
+ (void)snprintf(displayname, sizeof displayname, "%.*s...%s",
+ (int)sizeof(displayname) / 3, mailname, mailname + l);
+ }
+jleave: ;
+}
+
/*
* Set the size of the message vector used to construct argument
* lists to message list functions.
@@ -232,11 +271,8 @@ setfile(const char *name)
shudclob =3D 1;
edit =3D isedit;
(void)strcpy(prevfile, mailname);
- if (name !=3D mailname) {
- (void)strcpy(mailname, name);
-
- (void)strcpy(mailname, name);
- }
+ if (name !=3D mailname)
+ _update_mailname(name);
mailsize =3D fsize(ibuf);
(void)snprintf(tempname, sizeof(tempname),
"%s/mail.RxXXXXXXXXXX", tmpdir);
@@ -975,7 +1011,6 @@ newfileinfo(int omsgCount)
struct message *mp;
int d, n, s, t, u, mdot;
char fname[PATHSIZE];
- char *ename;
=20
/*
* Figure out where to set the 'dot'. Use the first new or
@@ -1019,23 +1054,10 @@ newfileinfo(int omsgCount)
if (mp->m_flag & MTAGGED)
t++;
}
- ename =3D mailname;
- if (getfold(fname, sizeof(fname)) >=3D 0) {
- char zname[PATHSIZE];
- size_t l;
- l =3D strlen(fname);
- if (l < sizeof(fname) - 1)
- fname[l++] =3D '/';
- if (strncmp(fname, mailname, l) =3D=3D 0) {
- (void)snprintf(zname, sizeof(zname), "+%s",
- mailname + l);
- ename =3D zname;
- }
- }
/*
* Display the statistics.
*/
- (void)printf("\"%s\": ", ename);
+ (void)printf("\"%s\": ", displayname);
{
int cnt =3D get_abs_msgCount();
(void)printf("%d message%s", cnt, cnt =3D=3D 1 ? "" : "s");
From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/47577: Mail(1)/mail(1)/mailx(1) gets stuck when current
folder becomes accessible
Date: Tue, 19 Feb 2013 18:26:49 +0100
aaah, i get grazy, wrong lex.c.orig.
--- fio.c.orig 2013-02-19 01:06:53.000000000 +0100
+++ fio.c 2013-02-19 03:00:56.000000000 +0100
@@ -392,14 +392,18 @@ fsize(FILE *iob)
PUBLIC int
getfold(char *name, size_t namesize)
{
+ char unres[PATHSIZE], res[PATHSIZE];
char *folder;
=20
if ((folder =3D value(ENAME_FOLDER)) =3D=3D NULL)
return -1;
if (*folder =3D=3D '/')
- (void)strlcpy(name, folder, namesize);
+ (void)strlcpy(unres, folder, sizeof unres);
else
- (void)snprintf(name, namesize, "%s/%s", homedir, folder);
+ (void)snprintf(unres, sizeof unres, "%s/%s", homedir, folder);
+ if (realpath(unres, res) =3D=3D NULL)
+ err(EXIT_FAILURE, "Can't canonicalize *folder* `%s'", unres);
+ (void)strlcpy(name, res, namesize);
return 0;
}
=20
--- glob.h.orig 2013-02-18 17:39:46.000000000 +0100
+++ glob.h 2013-02-19 03:02:37.000000000 +0100
@@ -59,6 +59,7 @@ EXTERN FILE *otf; /* Output temp file
EXTERN int image; /* File descriptor for image of msg */
EXTERN FILE *input; /* Current command input file */
EXTERN char mailname[PATHSIZE]; /* Name of current file */
+EXTERN char displayname[80]; /* Prettyfied for display */
EXTERN char prevfile[PATHSIZE]; /* Name of previous file */
EXTERN char *tmpdir; /* Path name of temp directory */
EXTERN char *homedir; /* Path name of home directory */
--- lex.c.orig 2013-02-19 03:23:22.000000000 +0100
+++ lex.c 2013-02-19 03:05:58.000000000 +0100
@@ -141,6 +141,45 @@ file_leak_check(void)
}
#endif /* DEBUG_FILE_LEAK */
=20
+static void
+_update_mailname(char const *name)
+{
+ char tbuf[PATHSIZE];
+ size_t l;
+
+ if (realpath(name, mailname) =3D=3D NULL)
+ err(EXIT_FAILURE, "Can't canonicalize `%s'", name);
+
+ if (getfold(tbuf, sizeof tbuf) >=3D 0) {
+ l =3D strlen(tbuf);
+ if (l < sizeof(tbuf) - 1)
+ tbuf[l++] =3D '/';
+ if (strncmp(tbuf, mailname, l) =3D=3D 0) {
+ char const *sep =3D "", *cp =3D mailname + l;
+
+ l =3D strlen(cp);
+ if (l >=3D sizeof displayname) {
+ cp +=3D l;
+ cp -=3D sizeof(displayname) - 5;
+ sep =3D "...";
+ }
+ (void)snprintf(displayname, sizeof displayname,
+ "+%s%s", sep, cp);
+ goto jleave;
+ }
+ }
+
+ l =3D strlen(mailname);
+ if (l < sizeof displayname)
+ strcpy(displayname, mailname);
+ else {
+ l -=3D sizeof(displayname) - 4 - sizeof(displayname) / 3;
+ (void)snprintf(displayname, sizeof displayname, "%.*s...%s",
+ (int)sizeof(displayname) / 3, mailname, mailname + l);
+ }
+jleave: ;
+}
+
/*
* Set the size of the message vector used to construct argument
* lists to message list functions.
@@ -233,7 +272,7 @@ setfile(const char *name)
edit =3D isedit;
(void)strcpy(prevfile, mailname);
if (name !=3D mailname)
- (void)strcpy(mailname, name);
+ _update_mailname(name);
mailsize =3D fsize(ibuf);
(void)snprintf(tempname, sizeof(tempname),
"%s/mail.RxXXXXXXXXXX", tmpdir);
@@ -972,7 +1011,6 @@ newfileinfo(int omsgCount)
struct message *mp;
int d, n, s, t, u, mdot;
char fname[PATHSIZE];
- char *ename;
=20
/*
* Figure out where to set the 'dot'. Use the first new or
@@ -1016,23 +1054,10 @@ newfileinfo(int omsgCount)
if (mp->m_flag & MTAGGED)
t++;
}
- ename =3D mailname;
- if (getfold(fname, sizeof(fname)) >=3D 0) {
- char zname[PATHSIZE];
- size_t l;
- l =3D strlen(fname);
- if (l < sizeof(fname) - 1)
- fname[l++] =3D '/';
- if (strncmp(fname, mailname, l) =3D=3D 0) {
- (void)snprintf(zname, sizeof(zname), "+%s",
- mailname + l);
- ename =3D zname;
- }
- }
/*
* Display the statistics.
*/
- (void)printf("\"%s\": ", ename);
+ (void)printf("\"%s\": ", displayname);
{
int cnt =3D get_abs_msgCount();
(void)printf("%d message%s", cnt, cnt =3D=3D 1 ? "" : "s");
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/47577 CVS commit: src/usr.bin/mail
Date: Tue, 19 Feb 2013 12:43:33 -0500
Module Name: src
Committed By: christos
Date: Tue Feb 19 17:43:33 UTC 2013
Modified Files:
src/usr.bin/mail: fio.c glob.h lex.c
Log Message:
PR/47577: Steffen "Daode" Nurpmeso: Keep a resolved folder name together
with a display name in order to keep track of current state when the directory
is changed.
To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/usr.bin/mail/fio.c
cvs rdiff -u -r1.12 -r1.13 src/usr.bin/mail/glob.h
cvs rdiff -u -r1.41 -r1.42 src/usr.bin/mail/lex.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: PR/47577 CVS commit: src/usr.bin/mail
Date: Wed, 20 Feb 2013 13:44:50 +0100
Hello,
| Committed By: christos
| Date: Tue Feb 19 17:43:33 UTC 2013
|=20
| Modified Files:
| src/usr.bin/mail: fio.c glob.h lex.c
|=20
| Log Message:
| PR/47577: Steffen "Daode" Nurpmeso: Keep a resolved folder name together
| with a display name in order to keep track of current state when the \
|directory
| is changed.
I'm not happy with the code after all -- it doesn't recognize
concurrent changes of the *folder* option (and assign() and
unset() do not check for special variables to perform necessary
updates).
So here is a refinement which is of smaller code size and prints
correct results even if *folder* is modified on the fly.
Thanks
--steffen
--- fio.c.orig 2013-02-19 06:58:25.000000000 +0100
+++ fio.c 2013-02-19 07:09:47.000000000 +0100
@@ -397,15 +397,15 @@ getfold(char *name, size_t namesize)
=20
if ((folder =3D value(ENAME_FOLDER)) =3D=3D NULL)
return -1;
- if (*folder =3D=3D '/')
- (void)strlcpy(unres, folder, sizeof(unres));
- else
+ if (*folder !=3D '/') {
(void)snprintf(unres, sizeof(unres), "%s/%s", homedir, folder);
- if (realpath(unres, res) =3D=3D NULL) {
- warn("Can't canonicalize folder `%s'", unres);
- (void)strlcpy(name, unres, namesize);
- } else
- (void)strlcpy(name, res, namesize);
+ folder =3D unres;
+ }
+ if (realpath(folder, res) =3D=3D NULL)
+ warn("Can't canonicalize folder `%s'", folder);
+ else
+ folder =3D res;
+ (void)strlcpy(name, folder, namesize);
return 0;
}
=20
--- lex.c.orig 2013-02-19 06:58:25.000000000 +0100
+++ lex.c 2013-02-19 07:09:47.000000000 +0100
@@ -147,7 +147,8 @@ update_mailname(const char *name)
char tbuf[PATHSIZE];
size_t l;
=20
- if (realpath(name, mailname) =3D=3D NULL) {
+ /* Don't realpath(3) if it's only an update request */
+ if (name !=3D NULL && realpath(name, mailname) =3D=3D NULL) {
warn("Can't canonicalize `%s'", name);
return;
}
@@ -272,8 +273,7 @@ setfile(const char *name)
shudclob =3D 1;
edit =3D isedit;
(void)strcpy(prevfile, mailname);
- if (name !=3D mailname)
- update_mailname(name);
+ update_mailname(name !=3D mailname ? name : NULL);
mailsize =3D fsize(ibuf);
(void)snprintf(tempname, sizeof(tempname),
"%s/mail.RxXXXXXXXXXX", tmpdir);
@@ -1057,6 +1057,7 @@ newfileinfo(int omsgCount)
/*
* Display the statistics.
*/
+ update_mailname(NULL);
(void)printf("\"%s\": ", displayname);
{
int cnt =3D get_abs_msgCount();
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/47577 CVS commit: src/usr.bin/mail
Date: Wed, 20 Feb 2013 09:38:14 -0500
Module Name: src
Committed By: christos
Date: Wed Feb 20 14:38:13 UTC 2013
Modified Files:
src/usr.bin/mail: fio.c lex.c
Log Message:
PR/47577: Steffen "Daode" Nurpmeso: Refinement to previous to keep always
keep track of the folder when it is updated.
To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/usr.bin/mail/fio.c
cvs rdiff -u -r1.42 -r1.43 src/usr.bin/mail/lex.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: PR/47577 CVS commit: src/usr.bin/mail
Date: Mon, 25 Feb 2013 19:58:24 +0100
ach, it's a mess!
No thought of multibyte awareness until saturday, when doing
something completely different..
So this should make it multibyte aware (i hope).
--steffen
diff -Napru mail.orig/Makefile mail/Makefile
--- mail.orig/Makefile 2013-02-25 14:58:37.000000000 +0100
+++ mail/Makefile 2013-02-25 16:02:01.000000000 +0100
@@ -8,6 +8,7 @@ USE_FORT?=3D yes # data-driven bugs?
USE_EDITLINE?=3Dyes
MIME_SUPPORT?=3Dyes # currently requires USE_EDITLINE
CHARSET_SUPPORT?=3Dyes # requires MIME_SUPPORT
+WIDECHAR?=3Dyes # avoid multibyte sequence -hickups- disruptions
THREAD_SUPPORT?=3Dyes # EXPERIMENTAL
=20
# Work around some problems in -current.
@@ -52,6 +53,10 @@ CPPFLAGS+=3D -DMIME_SUPPORT
CPPFLAGS+=3D -DCHARSET_SUPPORT
.endif
=20
+.if ${WIDECHAR:Uno} =3D=3D "yes"
+CPPFLAGS+=3D -DWIDECHAR
+.endif
+
LDADD+=3D -lmagic -lz
DPADD+=3D ${LIBMAGIC} ${LIBZ}
.endif
diff -Napru mail.orig/lex.c mail/lex.c
--- mail.orig/lex.c 2013-02-25 14:58:37.000000000 +0100
+++ mail/lex.c 2013-02-25 18:47:19.000000000 +0100
@@ -40,6 +40,9 @@ __RCSID("$NetBSD: lex.c,v 1.43 2013/02/2
=20
#include <assert.h>
#include <util.h>
+#ifdef WIDECHAR
+# include <wchar.h>
+#endif
=20
#include "rcv.h"
#include "extern.h"
@@ -144,8 +147,8 @@ file_leak_check(void)
static void
update_mailname(const char *name)
{
- char tbuf[PATHSIZE];
- size_t l;
+ char tbuf[PATHSIZE], *mailp, *dispp;
+ size_t i, j;
=20
/* Don't realpath(3) if it's only an update request */
if (name !=3D NULL && realpath(name, mailname) =3D=3D NULL) {
@@ -153,32 +156,41 @@ update_mailname(const char *name)
return;
}
=20
+ mailp =3D mailname;
+ dispp =3D displayname;
+
+ /* Don't display an absolute path but "+FOLDER" if under *folder* */
if (getfold(tbuf, sizeof(tbuf)) >=3D 0) {
- l =3D strlen(tbuf);
- if (l < sizeof(tbuf) - 1)
- tbuf[l++] =3D '/';
- if (strncmp(tbuf, mailname, l) =3D=3D 0) {
- char const *sep =3D "", *cp =3D mailname + l;
-
- l =3D strlen(cp);
- if (l >=3D sizeof(displayname)) {
- cp +=3D l;
- cp -=3D sizeof(displayname) - 5;
- sep =3D "...";
- }
- (void)snprintf(displayname, sizeof(displayname),
- "+%s%s", sep, cp);
- return;
+ i =3D strlen(tbuf);
+ if (i < sizeof(tbuf) - 1)
+ tbuf[i++] =3D '/';
+ if (strncmp(tbuf, mailp, i) =3D=3D 0) {
+ mailp +=3D i;
+ *dispp++ =3D '+';
}
}
=20
- l =3D strlen(mailname);
- if (l < sizeof(displayname))
- strcpy(displayname, mailname);
+ /* We want to see the name of the folder .. on the screen */
+ i =3D strlen(mailp);
+ if (i < sizeof(displayname) - 1)
+ memcpy(dispp, mailp, i + 1);
else {
- l -=3D sizeof(displayname) - 4 - sizeof(displayname) / 3;
- (void)snprintf(displayname, sizeof(displayname), "%.*s...%s",
- (int)sizeof(displayname) / 3, mailname, mailname + l);
+#ifdef WIDECHAR
+ size_t si =3D i;
+#endif
+ j =3D sizeof(displayname) / 3;
+ i -=3D sizeof(displayname) - (1 /* "+" */ + 4) - j;
+ /* Avoid disrupting multibyte sequences */
+#ifdef WIDECHAR
+ goto jmblen;
+ while (i < si && mblen(mailp + i, si - i) < 0) {
+ ++i;
+jmblen:
+ mblen(NULL, 0);
+ }
+#endif
+ (void)snprintf(dispp, sizeof(displayname) - 1, "%.*s...%s",
+ (int)j, mailp, mailp + i);
}
}
=20
From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-admin@netbsd.org, gnats-bugs@NetBSD.org,
netbsd-bugs@netbsd.org
Cc:
Subject: Re: PR/47577 CVS commit: src/usr.bin/mail
Date: Mon, 25 Feb 2013 20:06:08 +0100
..This may also be sufficient.
(Just scream, i'll stop, then ...)
--steffen
diff -Napru mail.orig/lex.c mail/lex.c
--- mail.orig/lex.c 2013-02-25 14:58:37.000000000 +0100
+++ mail/lex.c 2013-02-25 20:04:28.000000000 +0100
@@ -144,8 +144,8 @@ file_leak_check(void)
static void
update_mailname(const char *name)
{
- char tbuf[PATHSIZE];
- size_t l;
+ char tbuf[PATHSIZE], *mailp, *dispp;
+ size_t si, i, j;
=20
/* Don't realpath(3) if it's only an update request */
if (name !=3D NULL && realpath(name, mailname) =3D=3D NULL) {
@@ -153,32 +153,37 @@ update_mailname(const char *name)
return;
}
=20
+ mailp =3D mailname;
+ dispp =3D displayname;
+
+ /* Don't display an absolute path but "+FOLDER" if under *folder* */
if (getfold(tbuf, sizeof(tbuf)) >=3D 0) {
- l =3D strlen(tbuf);
- if (l < sizeof(tbuf) - 1)
- tbuf[l++] =3D '/';
- if (strncmp(tbuf, mailname, l) =3D=3D 0) {
- char const *sep =3D "", *cp =3D mailname + l;
-
- l =3D strlen(cp);
- if (l >=3D sizeof(displayname)) {
- cp +=3D l;
- cp -=3D sizeof(displayname) - 5;
- sep =3D "...";
- }
- (void)snprintf(displayname, sizeof(displayname),
- "+%s%s", sep, cp);
- return;
+ i =3D strlen(tbuf);
+ if (i < sizeof(tbuf) - 1)
+ tbuf[i++] =3D '/';
+ if (strncmp(tbuf, mailp, i) =3D=3D 0) {
+ mailp +=3D i;
+ *dispp++ =3D '+';
}
}
=20
- l =3D strlen(mailname);
- if (l < sizeof(displayname))
- strcpy(displayname, mailname);
+ /* We want to see the name of the folder .. on the screen */
+ i =3D strlen(mailp);
+ if (i < sizeof(displayname) - 1)
+ memcpy(dispp, mailp, i + 1);
else {
- l -=3D sizeof(displayname) - 4 - sizeof(displayname) / 3;
- (void)snprintf(displayname, sizeof(displayname), "%.*s...%s",
- (int)sizeof(displayname) / 3, mailname, mailname + l);
+ j =3D sizeof(displayname) / 3;
+ si =3D i;
+ i -=3D sizeof(displayname) - (1 /* "+" */ + 4) - j;
+ /* Avoid disrupting multibyte sequences */
+ goto jmblen;
+ while (i < si && mblen(mailp + i, si - i) < 0) {
+ ++i;
+jmblen:
+ mblen(NULL, 0);
+ }
+ (void)snprintf(dispp, sizeof(displayname) - 1, "%.*s...%s",
+ (int)j, mailp, mailp + i);
}
}
=20
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.