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