[GRASS-dev] No longer able to open a mapset by symbolic link

Hi all,

I just retrieved the latest weekly CVS snapshot for GRASS and found
I'm no longer able to access mapsets that are referred to by symbolic
links in linux.

Is this intended behaviour (possibly related to the windows port)? Or a bug?

Strangely the symbolic link is displayed as being an available mapset,
but when trying to change to that mapset the mapset is said to not
exist:

----
GRASS 6.3.cvs (nzmg):~/gis_databases/nzmg > g.mapsets mapset=test2
ERROR: [test2] - no such mapset

Available mapsets:

PERMANENT gypsy_moth lhumile lhumile.old test test2
----
test2 is a copy of test, but in ~/:
----
GRASS 6.3.cvs (nzmg):~/gis_databases/nzmg > ls
gypsy_moth
lhumile -> /media/simulations/gis_databases/nzmg/lhumile
lhumile.old
PERMANENT
test
test2 -> /home/joel/test2/
----
Permission of all the files/directories look fine.

I'll submit a bug request, but wasn't sure whether this behaviour has
been discussed and decided as intended. I hope not, because I use it
to separate out simulation results (huge and stored on an external
server/HDD) and input data for the simulations (stored locally).

Thanks,
--
-Joel

"Unless you try to do something beyond what you have mastered, you
will never grow." -C.R. Lawton

After searching through the code, the problem seems to be:

if (stat (path, &info) != 0)
    return -1;

changing to:

if (G_lstat (path, &info) != 0)
    return -1;
if (!S_ISDIR(info.st_mode))
    return -1;

in lib/gis/mapset_msc.c - and S_ISDIR, from what comments say, doesn't
treat links
as directories, even if they point to one.

-J

On 4/3/07, Joel Pitt <joel.pitt@gmail.com> wrote:

Hi all,

I just retrieved the latest weekly CVS snapshot for GRASS and found
I'm no longer able to access mapsets that are referred to by symbolic
links in linux.

Is this intended behaviour (possibly related to the windows port)? Or a bug?

Strangely the symbolic link is displayed as being an available mapset,
but when trying to change to that mapset the mapset is said to not
exist:

----
GRASS 6.3.cvs (nzmg):~/gis_databases/nzmg > g.mapsets mapset=test2
ERROR: [test2] - no such mapset

Available mapsets:

PERMANENT gypsy_moth lhumile lhumile.old test test2
----
test2 is a copy of test, but in ~/:
----
GRASS 6.3.cvs (nzmg):~/gis_databases/nzmg > ls
gypsy_moth
lhumile -> /media/simulations/gis_databases/nzmg/lhumile
lhumile.old
PERMANENT
test
test2 -> /home/joel/test2/
----
Permission of all the files/directories look fine.

I'll submit a bug request, but wasn't sure whether this behaviour has
been discussed and decided as intended. I hope not, because I use it
to separate out simulation results (huge and stored on an external
server/HDD) and input data for the simulations (stored locally).

Thanks,
--
-Joel

"Unless you try to do something beyond what you have mastered, you
will never grow." -C.R. Lawton

--
-Joel

"Unless you try to do something beyond what you have mastered, you
will never grow." -C.R. Lawton

Joel Pitt wrote:

I just retrieved the latest weekly CVS snapshot for GRASS and found
I'm no longer able to access mapsets that are referred to by symbolic
links in linux.

Is this intended behaviour (possibly related to the windows port)? Or a bug?

Strangely the symbolic link is displayed as being an available mapset,
but when trying to change to that mapset the mapset is said to not
exist:

----
GRASS 6.3.cvs (nzmg):~/gis_databases/nzmg > g.mapsets mapset=test2
ERROR: [test2] - no such mapset

Available mapsets:

PERMANENT gypsy_moth lhumile lhumile.old test test2
----
test2 is a copy of test, but in ~/:
----
GRASS 6.3.cvs (nzmg):~/gis_databases/nzmg > ls
gypsy_moth
lhumile -> /media/simulations/gis_databases/nzmg/lhumile
lhumile.old
PERMANENT
test
test2 -> /home/joel/test2/
----
Permission of all the files/directories look fine.

I'll submit a bug request, but wasn't sure whether this behaviour has
been discussed and decided as intended. I hope not, because I use it
to separate out simulation results (huge and stored on an external
server/HDD) and input data for the simulations (stored locally).

AFAIK, having symlinks to mapset directories has never been
intentionally supported; it just happened to work.

--
Glynn Clements <glynn@gclements.plus.com>

On 4/3/07, Glynn Clements <glynn@gclements.plus.com> wrote:

> I'll submit a bug request, but wasn't sure whether this behaviour has
> been discussed and decided as intended. I hope not, because I use it
> to separate out simulation results (huge and stored on an external
> server/HDD) and input data for the simulations (stored locally).

AFAIK, having symlinks to mapset directories has never been
intentionally supported; it just happened to work.

I've worked out a simple solution. In lib/gis/paths.c :

int G_lstat(const char *file_name, struct stat *buf)
{
#ifdef __MINGW32__
    return stat(file_name, buf);
#else
    return lstat(file_name, buf);
#endif
}

lstat(...) stats the link itself. Is there any reason why stat(...),
which follows a link instead, can't be used for both platforms?

--
-Joel

"Unless you try to do something beyond what you have mastered, you
will never grow." -C.R. Lawton

Joel Pitt wrote:

> > I'll submit a bug request, but wasn't sure whether this behaviour has
> > been discussed and decided as intended. I hope not, because I use it
> > to separate out simulation results (huge and stored on an external
> > server/HDD) and input data for the simulations (stored locally).
>
> AFAIK, having symlinks to mapset directories has never been
> intentionally supported; it just happened to work.

I've worked out a simple solution. In lib/gis/paths.c :

int G_lstat(const char *file_name, struct stat *buf)
{
#ifdef __MINGW32__
    return stat(file_name, buf);
#else
    return lstat(file_name, buf);
#endif
}

lstat(...) stats the link itself. Is there any reason why stat(...),
which follows a link instead, can't be used for both platforms?

Some of the uses of G_lstat() require the use of lstat(); e.g.
G_remove() uses it for directory traversal, which should treat
symlinks as leaf nodes (i.e. shouldn't traverse symlinks to
directories as if they were directories).

It may be worth having a separate G_stat() function, but G_lstat()
cannot be changed.

--
Glynn Clements <glynn@gclements.plus.com>

Glynn Clements wrote on 04/03/2007 06:28 AM:

Joel Pitt wrote:

I just retrieved the latest weekly CVS snapshot for GRASS and found
I'm no longer able to access mapsets that are referred to by symbolic
links in linux.

Is this intended behaviour (possibly related to the windows port)? Or a bug?
...

AFAIK, having symlinks to mapset directories has never been
intentionally supported; it just happened to work.
  
I am long term user of such mapset links, it would be a major problem for us
to no longer have this possibility. Just to express interest in this
issue...

Markus

------------------
ITC -> dall'1 marzo 2007 Fondazione Bruno Kessler
ITC -> since 1 March 2007 Fondazione Bruno Kessler
------------------

Markus Neteler wrote:

>> I just retrieved the latest weekly CVS snapshot for GRASS and found
>> I'm no longer able to access mapsets that are referred to by symbolic
>> links in linux.
>>
>> Is this intended behaviour (possibly related to the windows port)? Or a bug?
>> ...
> AFAIK, having symlinks to mapset directories has never been
> intentionally supported; it just happened to work.

I am long term user of such mapset links, it would be a major problem for us
to no longer have this possibility. Just to express interest in this
issue...

In that case, we need to add a G_stat(), and change some uses of
G_lstat() to G_stat().

Current users of G_lstat() are:

general/manage/lib/do_copy.c
  recursive_copy(), used by do_copy(), used by g.copy

lib/gis/mapset_msc.c
  G__mapset_permissions(), G__mapset_permissions2()

lib/gis/remove.c
  recursive_remove(), used by G_remove()

lib/gis/unix_socks.c
  _get_make_sock_path(), used by G_sock_get_fname()

lib/gis/user_config.c
  _make_toplevel(), _make_sublevels(), both used by G_rc_path()

AFAICT, the problems are due to G__mapset_permissions() and/or
G__mapset_permissions2(). These can probably be safely changed to use
stat() instead.

recursive_copy() and recursive_remove() perform directory traversal,
which should only recurse into actual subdirectories, not symlinks to
directories

The other cases check whether a directory already exists prior to
creating it. It's debatable what they should do if the chosen
subdirectory name refers to an existing symlink.

--
Glynn Clements <glynn@gclements.plus.com>

Markus wrote:

I am long term user of such mapset links, it would be a major
problem for us to no longer have this possibility. Just to express
interest in this issue...

me too.

Hamish

Glynn Clements wrote:

> >> I just retrieved the latest weekly CVS snapshot for GRASS and found
> >> I'm no longer able to access mapsets that are referred to by symbolic
> >> links in linux.
> >>
> >> Is this intended behaviour (possibly related to the windows port)? Or a bug?
> >> ...
> > AFAIK, having symlinks to mapset directories has never been
> > intentionally supported; it just happened to work.
>
> I am long term user of such mapset links, it would be a major problem for us
> to no longer have this possibility. Just to express interest in this
> issue...

In that case, we need to add a G_stat(), and change some uses of
G_lstat() to G_stat().

Current users of G_lstat() are:

general/manage/lib/do_copy.c
  recursive_copy(), used by do_copy(), used by g.copy

lib/gis/mapset_msc.c
  G__mapset_permissions(), G__mapset_permissions2()

lib/gis/remove.c
  recursive_remove(), used by G_remove()

lib/gis/unix_socks.c
  _get_make_sock_path(), used by G_sock_get_fname()

lib/gis/user_config.c
  _make_toplevel(), _make_sublevels(), both used by G_rc_path()

AFAICT, the problems are due to G__mapset_permissions() and/or
G__mapset_permissions2(). These can probably be safely changed to use
stat() instead.

FWIW, I've changed these two to use G_stat(), so symlinks to mapsets
should work now.

--
Glynn Clements <glynn@gclements.plus.com>