// Copyright (c) 1999-2001 David Muse // See the file COPYING for more information #include #include #include #include #include #include #include #include #ifdef RUDIMENTS_NAMESPACE using namespace rudiments; #endif #include #include dirnode::dirnode(const char *dirname) { this->dirname=charstring::duplicate(dirname); next=NULL; } dirnode::dirnode(const char *start, const char *end) { dirname=charstring::duplicate(start,end-start); next=NULL; } dirnode::~dirnode() { delete[] dirname; } cachemanager::cachemanager(int argc, const char **argv) { cmdl=new cmdline(argc,argv); tmpdir=new tempdir(cmdl); pidfile=NULL; // get the scaninterval const char *scanint=cmdl->getValue("-scaninterval"); if (scanint && scanint[0]) { scaninterval=charstring::toInteger(scanint); } else { scaninterval=DEFAULT_INTERVAL; } // get the directories to scan const char *cachedirs=cmdl->getValue("-cachedirs"); parseCacheDirs(cachedirs); } cachemanager::~cachemanager() { // delete the list of dirnames currentdir=firstdir; while (currentdir) { firstdir=currentdir; currentdir=currentdir->next; delete firstdir; } delete cmdl; delete tmpdir; if (pidfile) { file::remove(pidfile); delete[] pidfile; } } void cachemanager::scan() { // detach from the controlling tty detach(); // create pid file pid_t pid=process::getProcessId(); size_t pidfilelen=tmpdir->getLength()+24+ charstring::integerLength((uint64_t)pid)+1; pidfile=new char[pidfilelen]; snprintf(pidfile,pidfilelen,"%s/pids/sqlr-cachemanager.%d", tmpdir->getString(),pid); createPidFile(pidfile,permissions::ownerReadWrite()); // scan... directory dir; for (;;) { // start with the first dir in the list currentdir=firstdir; while (currentdir) { // open directory if (dir.open(currentdir->dirname)) { // loop through directory, erasing uint32_t index=0; for (;;) { char *name=dir.getChildName(index); if (!name) { break; } if (charstring::compare( name,".") && charstring::compare( name,"..")) { erase(currentdir->dirname,name); } delete[] name; index++; } // close the directory dir.close(); } // move to the next dir in the list currentdir=currentdir->next; } // wait... snooze::macrosnooze(scaninterval); } } void cachemanager::erase(const char *dirname, const char *filename) { // derive the full pathname size_t fullpathnamelen=charstring::length(dirname)+1+ charstring::length(filename)+1; char *fullpathname=new char[fullpathnamelen]; snprintf(fullpathname,fullpathnamelen,"%s/%s",dirname,filename); // open the file file fl; if (fl.open(fullpathname,O_RDONLY)) { // get the "magic" identifier char magicid[13]; fl.read(magicid,13); if (!charstring::compare(magicid,"SQLRELAYCACHE",13)) { // get the ttl int32_t ttl; fl.read(&ttl); fl.close(); // delete the file if the ttl has expired datetime dt; dt.getSystemDateAndTime(); if (ttlnext=new dirnode(ptr1,ptr2); currentdir=currentdir->next; } else { firstdir=new dirnode(ptr1,ptr2); currentdir=firstdir; } if (*ptr2==':') { ptr1=ptr2+1; } } if (!(*ptr2)) { return; } ptr2++; } } else { // in the event that there is no dirnames // string then use the default CACHE_DIR firstdir=new dirnode(CACHE_DIR); currentdir=firstdir; } }