nmh-workers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: nmh 1.8RC2, xlbiff, and $HOME


From: Ralph Corderoy
Subject: Re: nmh 1.8RC2, xlbiff, and $HOME
Date: Tue, 31 Jan 2023 13:22:19 +0000

Hi az,

> "Author: Ralph Corderoy <ralph@inputplus.co.uk>
> Date:   Thu May 13 13:46:20 2021 +0100
>
> sbr/path.c: add set_mypath() to factor out repeated code."

I think it's worth expanding on that.

    commit d8ca46fabc26469be325b73a73dcc26e70681eb5
    Author: Ralph Corderoy <ralph@inputplus.co.uk>
    Date:   Thu May 13 13:46:20 2021 +0100

        sbr/path.c: add set_mypath() to factor out repeated code.
        
        set_mypath() sets the existing global ‘mypath’ which really holds
        the home-directory's path.  As getenv(3) and getpwuid(3)'s result
        can be invalidated by further library calls, a value they return is
        mh_xstrdup()'d; not all the old bits of code replaced by a call to
        set_mypath() were doing this.
        
        Also add more explicit error messages if set_mypath() has trouble
        finding the home directory's path.

And here's the current code I wrote for set_mypath() which is causing
the trouble.

    /* set_mypath sets the global mypath to the HOME environment variable if
     * it is set and not empty, or else the password entry's home-directory
     * field if it's found and not empty.  Otherwise, the program exits
     * with an error.  The value found is copied with mh_xstrdup() as later
     * library calls may invalidate returned values. */
    void
    set_mypath(void)
    {
        char *var = getenv("HOME");
        if (var) {
            if (!*var)
                die("environment variable HOME is empty");

            mypath = mh_xstrdup(var);
            return;
        }

        errno = 0;
        struct passwd *pw = getpwuid(getuid());
        if (!pw) {
            if (errno)
                adios("", "getpwuid() failed");   /* "" prints errno! */
            die("password entry not found");
        }
        if (!*pw->pw_dir)
            die("password entry has empty home directory");

        mypath = mh_xstrdup(pw->pw_dir);
    }

So an unset HOME is allowed by this function, it's an empty HOME which
isn't.

An unset HOME falls back on getpwuid() which must dish up a non-empty
pw_dir.  I think that's reasonble.

> a quick glance seems to indicate that only context_read in
> sbr/context_read.c looks at $MH for finding a home

And uip/install-mh.c in a similar manner.

> but it does (well attempts) that just a few lines AFTER set_mypath has
> bailed out on it...
>
> i think we need to fix that sequence up a little :-)

It's the long-standing arrangement going back to Git's
docs/historical/mh-6.8.5/sbr/m_getdefs.c which allows an empty HOME but
not an empty pw_dir, though it complains that the later is the lack of
a HOME ‘envariable’.  :-)

    if (mypath == NULL) {
        if (mypath = getenv ("HOME"))
            mypath = getcpy (mypath);
        else
            if ((pw = getpwuid (getuid ())) == NULL
                    || pw -> pw_dir == NULL
                    || *pw -> pw_dir == 0)
                adios (NULLCP, "no HOME envariable");
            else
                mypath = getcpy (pw -> pw_dir);
        if ((cp = mypath + strlen (mypath) - 1) > mypath && *cp == '/')
            *cp = 0;
    }

It looks to me like code assumes mypath isn't NULL, e.g. exmaildir(),
so not bothering to call set_mypath() if MH is set doesn't look a goer.
At least not without a considerably more analysis which would probably
inspire changes which would ‘disappoint’ RC-maker David.  :-)

-- 
Cheers, Ralph.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]