Tip: How to avoid fc-cache as root?



I've found out what's wrong (partly) with fontconfig, and why it requires running fc-cache as root.

When we call fc-list, it updates our local file "~/.fonts.cache-1" with the results of a scan of all our directories listed in "fonts.conf". For example, if "fonts.conf" contains "<dir>/usr/X11R6.6/lib/X11/fonts</dir>", then we get a list of all the fonts and directories found in it. The problem is that it doesn't run recursively, but rather just one level deep, so subdirectories found don't get scanned, rather just stored with their timestamps (this causes the trouble, see below).

One would expect that the second run of fc-list would correct the situation, but there's a single problem with that: stored "times" are the same as ctime and/or atime of listed subdirectories. So, if we have root access, we might do "su -c fc-cache", or "for i in /usr/X11R6.6/lib/X11/fonts/*; do if [ -d $i ]; then touch $i/fonts.dir; fi;done".

But if we want to follow the tradition of user-space GARNOME install, we'd have to edit all the timestamps of subdirectories in generated "~/.fonts.cache-1" (or whatever is set as <cache> in fonts.conf), but we must not change the timestamps of first-level directories (those mentioned in fonts.conf), because it would rescan that dir, and again wouldn't go any deeper.

So, here's the Python script fcfix (if you don't have Python, how did you manage to compile GARNOME?) that accepts the filename as a first argument, and all other arguments are considered directories of which no timestamp changes are wanted. No error checking, so be careful, and use at your own risk. All the timestamps that are changed are decreased for 1 (second).

WARNING: This is not a solution, this is an ugly *HACK*.


#-fcfix--CUT-HERE---------------------------------------------------
#!/usr/bin/python
import sys

if len(sys.argv)>1:
    onfile=1
    f=open(sys.argv[1],"r")
    lines=f.readlines()
    f.close()
    f=open(sys.argv[1],"w")
else:
    print "Usage: fcfix <fonts.cache file> <dir>*\n"
    sys.exit(-1)

for line in lines:
    parts=line.split(" ")
    if parts[3]=='".dir"\n' and not(parts[0][1:-1] in sys.argv[1:]):
        parts[2]=str(int(parts[2])-1)
    line=" ".join(parts)
    f.write(line)
#-fcfix---------------------------------------------------CUT-HERE--


Which directories would you put on command line depends on the settings in your fonts.conf, my example session follows:

subota u 01:24: ~ $ rm ~/.fonts.cache-1
subota u 01:24: ~ $ fc-list
subota u 01:24: ~ $ fcfix ~/.fonts.cache-1 /usr/X11R6.6/lib/X11/fonts ~/.fonts
subota u 01:24: ~ $ fc-list | wc -l
    230
subota u 01:26: ~ $

Be sure to substitute all the paths I use with paths from your fonts.conf, and (if you added <cache> directive to fonts.conf) the name .fonts.cache-1 with appropriate name.


When I get some more spare time, I'll look into fontconfig source, and try to find the real solution. Or, someone might tip the Keith Packard about this behaviour: it simply couldn't be what is desired of fc-list, so it must be a bug. As it seems after quick glance, fontconfig/src/fccache.c is the place to check, but some things are done in fcdir.c.

To summarize: fc-list works incorrectly if initially started with no cache file. Once you correct it, all's fine.

So, maybe we should generate one .fonts.cache-1 for the user with his directories and timestamps far in the past (maybe 0?)for GARNOME.


Hope this helps shed some light on the subject, so any comments? Should a bug be filed (if so, where?) or should it be first corrected, then filed :)

Danilo





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