WvStreams
unifstreegen.cc
00001 #include "uniconfgen.h"
00002 #include "unimountgen.h"
00003 #include "wvmoniker.h"
00004 #include "wvlinkerhack.h"
00005 #include "wvlog.h"
00006 
00007 #include "unifiltergen.h"
00008 
00009 class UniAutoMountGen : public UniFilterGen
00010 {
00011     WvString dir;
00012     UniMountGen *mount;
00013     IUniConfGen *treegen;
00014     WvLog log;
00015     
00016 public:
00017     UniAutoMountGen(WvStringParm _dir)
00018         : UniFilterGen(mount = new UniMountGen), dir(_dir),
00019           log(WvString("AutoMount '%s'", dir), WvLog::Info)
00020     {
00021         log("Starting.\n");
00022         mount->mount("/", WvString("readonly:fs:%s", dir), true);
00023         treegen = mount->whichmount("/", NULL);
00024     }
00025     
00026     virtual ~UniAutoMountGen()
00027     {
00028         log("Stopping.\n");
00029     }
00030     
00031     virtual bool keymap(const UniConfKey &key, UniConfKey &mapped_key)
00032     {
00033         automount(key);
00034         return UniFilterGen::keymap(key, mapped_key);
00035     }
00036     
00037     void automount(const UniConfKey &key)
00038     {
00039         IUniConfGen *parent = mount->whichmount(key, NULL);
00040         if (parent && parent != treegen && parent->haschildren("/"))
00041             return; // don't bother; already mounted a parent
00042         
00043         log("Automount for '%s'\n", key);
00044         
00045         for (int count = key.numsegments(); count >= 0; count--)
00046         {
00047             UniConfKey k(key.first(count));
00048             if (mount->ismountpoint(k))
00049             {
00050                 log("Key '%s' already mounted.\n", k);
00051                 return; // already mounted
00052             }
00053             
00054             WvString filename("%s/%s", dir, k);
00055             log("Filename is '%s'\n", filename);
00056             mount->mount(k, WvString("ini:%s", filename), true);
00057             log("Key '%s' newly mounted.\n", k);
00058             return; // newly mounted
00059         }
00060         
00061         // just plain not found
00062         log("Key '%s' not found.\n", key);
00063     }
00064     
00065     virtual Iter *recursiveiterator(const UniConfKey &key)
00066     {
00067         // don't try to optimize this like UniMountGen does, because we're
00068         // going to mount things *as* we iterate through them, not sooner.
00069         // Use the default UniConfGen implementation, which just recursively
00070         // calls iterator().
00071         return UniConfGen::recursiveiterator(key);
00072     }
00073 };
00074 
00075 
00076 WV_LINK(UniFsTreeGen);
00077 
00078 
00079 static IUniConfGen *creator(WvStringParm s, IObject *)
00080 {
00081     return new UniAutoMountGen(s);
00082 }
00083 
00084 WvMoniker<IUniConfGen> UniFsTreeGenMoniker("fstree", creator);
00085 
00086