FACEPATH problem - finding the best match

Dirk Craeynest (dirk.craeynest@cs.kuleuven.ac.be)
Tue, 15 Oct 91 16:14:45 MET

[ Rich Burridge suggested to post this problem on the faces mailing list
so that hopefully somebody will be able to verify one way or the other
whether this is a bug or not. -- dc ]

The `faces' manual entry claims (faces version 1.5.6):

----------------------------------------
To access the face for the mail name machine.dom.ain!uid take the
result of the first successful open from the following list of files
(where $DIR represents iteration over the list of directories in
FACEPATH):
$DIR/machine.dom.ain/uid/iconname
$DIR/dom.ain/uid/iconname
$DIR/ain/uid/iconname
$DIR/misc./uid/iconname
$DIR/machine.dom.ain/unknown/iconname
$DIR/dom.ain/unknown/iconname
$DIR/ain/unknown/iconname
$DIR/misc./unknown/iconname
----------------------------------------

This means that all directories in the FACEPATH are first searched for
the directory machine.dom.ain/uid. If no match is found, then the
search is repeated for the directory dom.ain/uid, again in all
directories in the FACEPATH; and so on, until misc./unknown.

That's the expected behavior: the `best' match is used, regardless of
the face directory (at least that's what we expect, after reading the
documentation ;-) ).

Unfortunately, the code doesn't implement that! In the file main.c, in
procedure make_iconname, the main loop [1] iterates over the directories
in the FACEPATH. Each iteration step looks for a match [2] as described
above.

---main.c---line 609--------------------
enum min_type
make_iconname(facepath, community, user) /* Construct the icon name.*/
char *facepath[MAXPATHS+1], *community, *user ;
{

/* Sets up community and user based on the first successful
* open from the following list of files:
*
* $(FACEDIR)/community/user/[face.ps, sun.icon, 48x48x1, face.xbm]
* $(FACEDIR)/misc./user/[face.ps, sun.icon, 48x48x1, face.xbm]
* $(FACEDIR)/community/unknown/[face.ps, sun.icon, 48x48x1, face.xbm]
* $(FACEDIR)/misc./unknown/[face.ps, sun.icon, 48x48x1, face.xbm]
[...]
*/
[...]

[1] for (id = 0; facepath[id] != NULL; id++) {

/* Chdir temporarily to the current facedir for faster namei accesses,
* if possible.
*/

path = (chdir(facepath[id])) ? facepath[id] : "." ;

[2] for (iu = 0; iuser[iu] != NULL; iu++)
[2] for (ic = 0; icomm[ic] != NULL; ic++)
[2] for (cptr = icomm[ic]; cptr != NULL; cptr = index(cptr, '.'))
{
[...]
----------------------------------------

We find this a rather serious problem.

If, for example, in one facedir we have
$DIR1/cs.kuleuven.ac.be/dirk/face.xbm
and in another facedir we have
$DIR2/kuleuven.ac.be/unknown/face.xbm

Depending upon the order of $DIR1 and $DIR2 in the FACEPATH
dirk@cs.kuleuven.ac.be
will be matched with the first or the second face.xbm.
Thus, if $DIR2 precedes $DIR1, the `incomplete match'
$DIR2/kuleuven.ac.be/unknown/face.xbm
takes precedence over the `complete match'
$DIR1/cs.kuleuven.ac.be/dirk/face.xbm...

Solution:
turn the loops [1] and [2] inside out, i.e. iterate in loop [2] over
all directories in the FACEPATH.

Comments?

Dirk Craeynest | domain: dirk@cs.kuleuven.ac.be
The Absynt project: Semantics | bitnet: dirk@blekul60.bitnet
Directed Compiler Construction | uucp: dirk@kulcs.uucp
Katholieke Universiteit Leuven | ...!mcsun!ub4b!kulcs!dirk
Department of Computer Science | phone: ++32(0)16-201015 x3555
Celestijnenlaan 200 A | fax: ++32(0)16-205308
B-3001 Leuven (Heverlee), Belgium | telex: 23674 kuleuv b