Branch: Tag:

1996-11-11

1996-11-11 23:31:54 by Per Hedbor <ph@opera.com>

Ny version... HATA CVS ibland

Rev: .cvsignore:1.1.1.1
Rev: BUGS:1.1.1.1
Rev: CHANGES:1.1.1.1
Rev: COPYING:1.1.1.1
Rev: INSTALLING:1.1.1.1
Rev: Makefile.in:1.1.1.1
Rev: README:1.1.1.1
Rev: TODO:1.1.1.1
Rev: configure.in:1.1.1.1
Rev: extern/.cvsignore:1.1.1.1
Rev: extern/Makefile.in:1.1.1.1
Rev: extern/README:1.1.1.1
Rev: extern/cgi.c:1.1.1.1
Rev: extern/configure.in:1.1.1.1
Rev: extern/fast_cgi/LICENSE.TERMS:1.1.1.1
Rev: extern/fast_cgi/Makefile.in:1.1.1.1
Rev: extern/fast_cgi/README:1.1.1.1
Rev: extern/fast_cgi/acconfig.h:1.1.1.1
Rev: extern/fast_cgi/cgi-fcgi/Makefile.in:1.1.1.1
Rev: extern/fast_cgi/cgi-fcgi/cgi-fcgi.c:1.1.1.1
Rev: extern/fast_cgi/configure.in:1.1.1.1
Rev: extern/fast_cgi/include/fastcgi.h:1.1.1.1
Rev: extern/fast_cgi/include/fcgi_stdio.h:1.1.1.1
Rev: extern/fast_cgi/include/fcgiapp.h:1.1.1.1
Rev: extern/fast_cgi/include/fcgiappmisc.h:1.1.1.1
Rev: extern/fast_cgi/include/fcgimisc.h:1.1.1.1
Rev: extern/fast_cgi/libfcgi/Makefile.in:1.1.1.1
Rev: extern/fast_cgi/libfcgi/fcgi_stdio.c:1.1.1.1
Rev: extern/fast_cgi/libfcgi/fcgiapp.c:1.1.1.1
Rev: extern/fast_cgi/libfcgi/strerror.c:1.1.1.1
Rev: extern/roxen_hostname.c:1.1.1.1
Rev: extern/shuffle.c:1.1.1.1
Rev: extern/ssl.c:1.1.1.1
Rev: install-sh:1.1.1.1
Rev: mkdir:1.1.1.1
Rev: pike/.cvsignore:1.1.1.1
Rev: pike/Makefile.in:1.1.1.1
Rev: pike/README:1.1.1.1
Rev: pike/ROXEN_PIKE_BASE:1.1.1.1
Rev: pike/configure.in:1.1.1.1
Rev: server/base_server/cache.pike:1.1.1.1
Rev: server/base_server/config/builders.pike:1.1.1.1
Rev: server/base_server/config/describers.pike:1.1.1.1
Rev: server/base_server/config/low_describers.pike:1.1.1.1
Rev: server/base_server/config/savers.pike:1.1.1.1
Rev: server/base_server/configuration.pike:1.1.1.1
Rev: server/base_server/db.pike:1.1.1.1
Rev: server/base_server/disk_cache.pike:1.1.1.1
Rev: server/base_server/dummy_hosts.pike:1.1.1.1
Rev: server/base_server/hosts.pike:1.1.1.1
Rev: server/base_server/html.pike:1.1.1.1
Rev: server/base_server/http.pike:1.1.1.1
Rev: server/base_server/language.pike:1.1.1.1
Rev: server/base_server/lock.pike:1.1.1.1
Rev: server/base_server/mainconfig.pike:1.1.1.1
Rev: server/base_server/module.pike:1.1.1.1
Rev: server/base_server/module_support.pike:1.1.1.1
Rev: server/base_server/newdecode.pike:1.1.1.1
Rev: server/base_server/persistent.pike:1.1.1.1
Rev: server/base_server/proxyauth.pike:1.1.1.1
Rev: server/base_server/read_config.pike:1.1.1.1
Rev: server/base_server/roxen.pike:1.1.1.1
Rev: server/base_server/roxenlib.pike:1.1.1.1
Rev: server/base_server/roxenloader.pike:1.1.1.1
Rev: server/base_server/socket.pike:1.1.1.1
Rev: server/base_server/spinnerlib.pike:1.1.1.1
Rev: server/base_server/struct/ftp_gateway_request.pike:1.1.1.1
Rev: server/base_server/struct/node.pike:1.1.1.1
Rev: server/bin/.cvsignore:1.1.1.1
Rev: server/bin/garbagecollector.pike:1.1.1.1
Rev: server/bin/install.pike:1.1.1.1
Rev: server/configvar:1.1.1.1
Rev: server/etc/config.html:1.1.1.1
Rev: server/etc/extensions:1.1.1.1
Rev: server/etc/include/array.h:1.1.1.1
Rev: server/etc/include/array.pre.pike:1.1.1.1
Rev: server/etc/include/config.h:1.1.1.1
Rev: server/etc/include/confignode.h:1.1.1.1
Rev: server/etc/include/fifo.h:1.1.1.1
Rev: server/etc/include/fifo.pre.pike:1.1.1.1
Rev: server/etc/include/getopt.h:1.1.1.1
Rev: server/etc/include/getopt.pre.pike:1.1.1.1
Rev: server/etc/include/module.h:1.1.1.1
Rev: server/etc/include/process.h:1.1.1.1
Rev: server/etc/include/process.pre.pike:1.1.1.1
Rev: server/etc/include/roxen.h:1.1.1.1
Rev: server/etc/include/simulate.h:1.1.1.1
Rev: server/etc/include/simulate.pre.pike:1.1.1.1
Rev: server/etc/include/stat.h:1.1.1.1
Rev: server/etc/include/stdio.h:1.1.1.1
Rev: server/etc/include/stdio.pre.pike:1.1.1.1
Rev: server/etc/include/string.h:1.1.1.1
Rev: server/etc/include/string.pre.pike:1.1.1.1
Rev: server/etc/include/syslog.h:1.1.1.1
Rev: server/etc/include/variables.h:1.1.1.1
Rev: server/etc/newconfig.html:1.1.1.1
Rev: server/etc/restart.html:1.1.1.1
Rev: server/etc/roxen_master.pike:1.1.1.1
Rev: server/etc/shutdown.html:1.1.1.1
Rev: server/etc/supports:1.1.1.1
Rev: server/etc/welcome.html:1.1.1.1
Rev: server/install:1.1.1.1
Rev: server/languages/catala.pike:1.1.1.1
Rev: server/languages/dutch.pike:1.1.1.1
Rev: server/languages/english.pike:1.1.1.1
Rev: server/languages/finnish.pike:1.1.1.1
Rev: server/languages/french.pike:1.1.1.1
Rev: server/languages/german.pike:1.1.1.1
Rev: server/languages/japanese.pike:1.1.1.1
Rev: server/languages/norwegian.pike:1.1.1.1
Rev: server/languages/spanish.pike:1.1.1.1
Rev: server/languages/swedish.pike:1.1.1.1
Rev: server/mkdir:1.1.1.1
Rev: server/modules/cgi.pike:1.1.1.1
Rev: server/modules/client_logger.pike:1.1.1.1
Rev: server/modules/connect.pike:1.1.1.1
Rev: server/modules/contenttypes.pike:1.1.1.1
Rev: server/modules/directories.pike:1.1.1.1
Rev: server/modules/fastdir.pike:1.1.1.1
Rev: server/modules/fcgi.pike:1.1.1.1
Rev: server/modules/filesystem.pike:1.1.1.1
Rev: server/modules/ftpgateway.pike:1.1.1.1
Rev: server/modules/gopher.pike:1.1.1.1
Rev: server/modules/header.pike:1.1.1.1
Rev: server/modules/home_logger.pike:1.1.1.1
Rev: server/modules/hostredirect.pike:1.1.1.1
Rev: server/modules/htaccess.pike:1.1.1.1
Rev: server/modules/htmlparse.pike:1.1.1.1
Rev: server/modules/indexfiles.pike:1.1.1.1
Rev: server/modules/indirect_href.pike:1.1.1.1
Rev: server/modules/ismap.pike:1.1.1.1
Rev: server/modules/language.pike:1.1.1.1
Rev: server/modules/lpcscript.pike:1.1.1.1
Rev: server/modules/lpctag.pike:1.1.1.1
Rev: server/modules/nologging.pike:1.1.1.1
Rev: server/modules/proxy.pike:1.1.1.1
Rev: server/modules/redirect.pike:1.1.1.1
Rev: server/modules/relay.pike:1.1.1.1
Rev: server/modules/secure_fs.pike:1.1.1.1
Rev: server/modules/tablist.pike:1.1.1.1
Rev: server/modules/userdb.pike:1.1.1.1
Rev: server/modules/userfs.pike:1.1.1.1
Rev: server/modules/variable.pike:1.1.1.1
Rev: server/modules/wais.pike:1.1.1.1
Rev: server/more_modules/bofh.pike:1.1.1.1
Rev: server/more_modules/clock.pike:1.1.1.1
Rev: server/more_modules/configure.pike:1.1.1.1
Rev: server/more_modules/lysator.pike:1.1.1.1
Rev: server/more_modules/tablify.pike:1.1.1.1
Rev: server/protocols/ftp.pike:1.1.1.1
Rev: server/protocols/gopher.pike:1.1.1.1
Rev: server/protocols/http.pike:1.1.1.1
Rev: server/protocols/ssl.pike:1.1.1.1
Rev: server/roxen-images/back.gif:1.1.1.1
Rev: server/roxen-images/background.jpg:1.1.1.1
Rev: server/roxen-images/changed.gif:1.1.1.1
Rev: server/roxen-images/delconf.gif:1.1.1.1
Rev: server/roxen-images/delmod.gif:1.1.1.1
Rev: server/roxen-images/delmodcop.gif:1.1.1.1
Rev: server/roxen-images/dir/binary.gif:1.1.1.1
Rev: server/roxen-images/dir/image.gif:1.1.1.1
Rev: server/roxen-images/dir/menu.gif:1.1.1.1
Rev: server/roxen-images/dir/sound.gif:1.1.1.1
Rev: server/roxen-images/dir/text.gif:1.1.1.1
Rev: server/roxen-images/dir/unknown.gif:1.1.1.1
Rev: server/roxen-images/fold.gif:1.1.1.1
Rev: server/roxen-images/fold2.gif:1.1.1.1
Rev: server/roxen-images/foldall.gif:1.1.1.1
Rev: server/roxen-images/infovav.gif:1.1.1.1
Rev: server/roxen-images/left.gif:1.1.1.1
Rev: server/roxen-images/newconf.gif:1.1.1.1
Rev: server/roxen-images/newmod.gif:1.1.1.1
Rev: server/roxen-images/off.gif:1.1.1.1
Rev: server/roxen-images/on.gif:1.1.1.1
Rev: server/roxen-images/power.gif:1.1.1.1
Rev: server/roxen-images/power_anim.gif:1.1.1.1
Rev: server/roxen-images/refresh.gif:1.1.1.1
Rev: server/roxen-images/restart.gif:1.1.1.1
Rev: server/roxen-images/right.gif:1.1.1.1
Rev: server/roxen-images/roxen.gif:1.1.1.1
Rev: server/roxen-images/save.gif:1.1.1.1
Rev: server/roxen-images/shutdown.gif:1.1.1.1
Rev: server/roxen-images/tablists/1.gif:1.1.1.1
Rev: server/roxen-images/tablists/10.gif:1.1.1.1
Rev: server/roxen-images/tablists/11.gif:1.1.1.1
Rev: server/roxen-images/tablists/12.gif:1.1.1.1
Rev: server/roxen-images/tablists/13.gif:1.1.1.1
Rev: server/roxen-images/tablists/14.gif:1.1.1.1
Rev: server/roxen-images/tablists/15.gif:1.1.1.1
Rev: server/roxen-images/tablists/16.gif:1.1.1.1
Rev: server/roxen-images/tablists/2.gif:1.1.1.1
Rev: server/roxen-images/tablists/3.gif:1.1.1.1
Rev: server/roxen-images/tablists/4.gif:1.1.1.1
Rev: server/roxen-images/tablists/5.gif:1.1.1.1
Rev: server/roxen-images/tablists/6.gif:1.1.1.1
Rev: server/roxen-images/tablists/7.gif:1.1.1.1
Rev: server/roxen-images/tablists/8.gif:1.1.1.1
Rev: server/roxen-images/tablists/9.gif:1.1.1.1
Rev: server/roxen-images/top.gif:1.1.1.1
Rev: server/roxen-images/unfold.gif:1.1.1.1
Rev: server/roxen-images/unfold2.gif:1.1.1.1
Rev: server/roxen-images/unmod.gif:1.1.1.1
Rev: server/roxen-images/up.gif:1.1.1.1
Rev: server/roxen-images/zap.gif:1.1.1.1
Rev: server/start:1.1.1.1
Rev: server/unfinishedmodules/deepthought.pike:1.1.1.1
Rev: server/unfinishedmodules/extended_logger.pike:1.1.1.1
Rev: server/unfinishedmodules/fastcgi.pike:1.1.1.1
Rev: server/unfinishedmodules/hedbor.pike:1.1.1.1
Rev: server/unfinishedmodules/httpc.lpc.gz:1.1.1.1
Rev: server/unfinishedmodules/javascript.pike:1.1.1.1
Rev: server/unfinishedmodules/mirror.lpc.gz:1.1.1.1
Rev: server/unfinishedmodules/mountserver.pike:1.1.1.1
Rev: server/unfinishedmodules/tree.pike:1.1.1.1
Rev: server/unfinishedmodules/whois++.pike:1.1.1.1
Rev: tools/Makefile:1.1.1.1
Rev: tools/accessed.lpc:1.1.1.1
Rev: tools/backlog-bumper:1.1.1.1
Rev: tools/htpasswd.c:1.1.1.1
Rev: tools/init.d_roxen:1.1.1.1
Rev: tools/xdumpfont/Makefile:1.1.1.1
Rev: tools/xdumpfont/README:1.1.1.1
Rev: tools/xdumpfont/banner.c:1.1.1.1
Rev: tools/xdumpfont/fontdemo.c:1.1.1.1
Rev: tools/xdumpfont/makefonts.lpc:1.1.1.1
Rev: tools/xdumpfont/readfont.c:1.1.1.1
Rev: tools/xdumpfont/readfont.h:1.1.1.1
Rev: tools/xdumpfont/xdumpfont.c:1.1.1.1

1: + /* There is some bug in this I haven't had time to find. */    -  + //#define DEBUG +  + #define MAX_LOG_SIZE 512 +  + string lp; + int last_log, first_log=0x7fffffff; +  + mapping log = ([]); +  + string _order(int from) + { +  return sprintf("%08x", from); + } +  + int _num(string from) + { +  return (int)("0x"+from[strlen(from)-8..]); + } +  +  + int rm_log(int num) + { +  rm(lp+"cachelog"+_order(num)); + } +  + mapping parse_log(int num) + { +  string s; +  string file; +  mapping log; +  +  mkdir(lp); +  file = lp+"cachelog"+_order(num); +  if(!(s=read_bytes(file))) +  { +  log = ([]); +  return 0; +  } else { +  if(catch(log = decode_value( s ))) +  return 0; +  return log; +  } + } +  + void create_cache(string logprefix) + { +  lp = logprefix; +  int i; +  string file; +  array (string) files; +  +  mkdir(lp); + #if 0 +  files = map_array(get_dir(lp), lambda(string s) { +  if(!search(s, "cachelog")) return s; +  return 0; +  }) - ({ 0 }); +  +  foreach(files, file) +  { +  if((i=_num(file)) > last_log) +  last_log = i; +  if(i < first_log) +  first_log = i; +  } +  +  if(!last_log) { +  first_log = 0; +  return; // Ok, no old log. +  } +  +  while(!((log=parse_log(last_log)) && last_log>=0)) +  last_log--; +  if(!log) +  log = ([]); +  +  if(last_log < 0) +  perror("CACHE: Failed to read existing logfile.\n"); + #endif + } +  + void write_log() + { +  string file; +  last_log++; +  mkdir(lp); +  file = lp+"cachelog"+_order(last_log); +  rm(file); +  write_bytes(file, encode_value(log)); +  log = ([]); + } +  + void update(string file, int tim, int|void score) + { + //perror(file+" "+(time(1)-tim)+" seconds old, "+score+" \"bonus\" seconds.\n"); +  log[file] = ({ tim, score }); +  if(sizeof(log) > MAX_LOG_SIZE) +  write_log(); + } +  + void accessed(string filename, int extra) + { +  update(filename, time(), extra); + } +  + int do_collect(int amnt, function cb, mapping log) + { +  array a, b; +  +  a = values(log); +  b = indices(log); +  sort(map_array(a,lambda(array a){`-(@a);}), b); +  +  int i; +  for(i=0; i<sizeof(b); i++) +  { +  m_delete(log, b[i]); +  amnt -= cb(b[i], a[i][0]); +  if(amnt <= 0) throw("Done"); +  } +  return amnt; + } +  + #define BLOCK_SIZE 2048 +  + #define FILE_SIZE_TO_BLOCK(X) (((X)+(BLOCK_SIZE-1))/BLOCK_SIZE) + #define BLOCK_TO_KB(X) (((X)*BLOCK_SIZE)/1024) +  + int max_cache_size; + int cache_normal_garb; + int cache_size; + int num_files; // Only used for informative output +  + void find_all_files_in(string dir, function|void cb) + { +  string path; +  foreach(get_dir(dir)||({}), path) +  { +  array st = file_stat(dir+path); +  if(st) +  { +  if(st[1] == -2) +  { +  if((path != "..") && (path!=".")) +  find_all_files_in(dir+path+"/", cb); +  } else { +  if(!cb) +  { +  cache_size += FILE_SIZE_TO_BLOCK(st[1]); +  num_files++; +  update(dir+path, st[2], st[1]/20); +  } else +  cb(dir+path); +  } +  } +  } + } +  + void find_all_files_and_log_it() + { +  array dirs = get_dir("."); +  string dir; +  +  perror("Rechecking cache ... "); +  +  num_files = cache_size = 0; +  rm("size"); +  find_all_files_in("logs/", rm); // Remove all logs +  log=([]); +  first_log = last_log = 0; // Well, lets start again then. +  +  foreach(dirs, dir) +  if(file_size(dir)<-1 && dir!="logs") +  find_all_files_in(dir+"/"); +  +  perror(sprintf("Found %d files, in total %.2fMb data\n", +  num_files, (float)BLOCK_TO_KB(cache_size)/1024.0)); +  remove_call_out(find_all_files_and_log_it); +  call_out(find_all_files_and_log_it, cache_size/2+3000); + } +  +  + void collect(int amnt, function callback, int|void norec) + { +  int i, t_last_log = last_log+(last_log-first_log); +  mixed r; +  write_log(); + // perror("Collect. first_log="+first_log+"; last_log="+last_log+"\n"); +  r = catch { +  for(i=first_log; i<=t_last_log; i++) +  { +  mapping rl; + // perror("Collecting log "+i+"\n"); + // perror("Collect. first_log="+first_log+"; last_log="+last_log+"\n"); +  if(rl = parse_log(i)) +  { +  rm_log(i); +  if(i != last_log) +  first_log = i+1; +  amnt = do_collect(amnt, callback, rl); +  } +  } +  }; +  if(!r) +  { + #ifdef DEBUG +  perror("All files removed?\n"); + #endif +  if(norec) +  { +  perror("All files removed, but still data to collect.\n"); +  return; +  } +  find_all_files_and_log_it(); +  if(amnt >= 0) +  return collect(amnt, callback, 1); +  } +  if(r && (r!= "Done")) +  perror("Error while garbagecollecting: "+r[0]+"\n" +  +describe_backtrace(r[1])); + } +  + void gc(int); +  + // All sizes are in BLOCK_SIZE b blocks, except for + // howmuch, which is in bytes. + int check(int howmuch) + { +  howmuch = FILE_SIZE_TO_BLOCK(howmuch); +  cache_size += howmuch; +  +  // len is in units of BLOCK_SIZE bytes. +  if(((int)((float)cache_size)) > max_cache_size) +  gc(cache_size); +  + #ifdef DEBUG +  perror(sprintf("data in cache: %d Kb\n", +  (int)((float)BLOCK_TO_KB(cache_size)))); + #endif +  return cache_size; + } +  + void cache_stream_closed() + { +  perror("garbagecollector: cache command stream closed. Exiting\n"); + #ifdef LPC_GARB +  write_log(); + #endif +  exit(0); + } +  + static mixed do_command(array what) + { +  mixed res; +  if(!arrayp(what)) +  { +  perror(sprintf("Got strange command (%O)\n", what)); +  return 0; +  } +  + #ifdef DEBUG + // perror(sprintf("Got command %O\n", what)); + #endif +  +  return this_object()[what[0]](@what[1..]); + } +  + private string _cache = ""; + static void got_command(object o, string cmd) + { +  cmd = _cache+cmd; +  + // perror("Got some data: '"+cmd+"'\n"); +  +  while(strlen(cmd)) +  { +  int l; +  +  if(strlen(cmd) < 8) break; // More needed. +  +  l = (int)("0x"+(cmd[..7]-" ")); +  +  if(strlen(cmd) < l+8) break; // More needed +  +  cmd=cmd[8..]; // Remove the 'length' field of this command. +  +  array err; +  if(err=catch(do_command( decode_value( cmd[..l-1] ) ))) +  stderr->write(describe_backtrace( err )); +  +  cmd=cmd[l..]; // Remove the 'command' field of this command +  } + // perror("data parsed ("+strlen(cmd)+" bytes in cache).\n"); +  +  _cache=cmd; + } +  + int removed, lastgc; +  + #define MAX(x,y) ((x)<(y)?(y):(x)) +  + mapping stat_cache = ([]); +  +  +  + void cleandirs() + { +  object null = new(File); +  null->open("/dev/null", "rw"); +  spawn("find . -type d | xargs rmdir", null, null, null); +  remove_call_out(cleandirs); +  call_out(cleandirs, cache_size+3600); + } +  +  + int remove_one_file(string fname, int last_access) + { +  array s; + #ifdef DEBUG + // perror("remove one file? "+fname+" --- "); + #endif +  s=stat_cache[fname]; +  if(!s) +  if(!(s = file_stat( fname ))) +  s = stat_cache[fname] = ({0,-1,0,0,0,0}); +  else +  stat_cache[fname]=s; +  +  if(s[1] != -1) +  { +  int i; +  +  if((search(fname, ".done")!=-1) && (s[2]-10 > last_access)) +  { + #ifdef DEBUG + // perror("Nope.\n"); + #endif +  update(fname, s[2], s[1]/20); +  return 0; /* File has been accessed since the cache checked */ +  } +  i=FILE_SIZE_TO_BLOCK(s[1]); + #ifdef DEBUG + // perror("Yep. "+(int)BLOCK_TO_KB(i)+"Kb removed\n"); + #endif +  s[1]=-1; +  removed += i; +  cache_size-=i; +  rm( fname ); +  return i; /* Ok, removed */ +  } + #ifdef DEBUG + // perror("Already.\n"); + #endif +  return 0; /* No such file */ + } +  + /* Do _not_ call check() from this function. It might cause infinite +  * recursion +  */ +  + void gc(int cs) + { +  int amnt; +  +  stat_cache = ([]); +  removed = 0; +  lastgc = time(); +  amnt = MAX(cache_normal_garb, cs-max_cache_size); +  +  catch { + #ifdef DEBUG +  perror("really_gc ("+(int)BLOCK_TO_KB(amnt)+" Kb)\n"); + #endif +  collect(amnt, remove_one_file); + #ifdef DEBUG +  perror("--------- ("+(int)BLOCK_TO_KB(removed)+" Kb really removed)\n"); + #endif +  }; + // cleandirs(); +  stat_cache = ([]); + } +  + string statistics() + { +  string last_garb; +  +  if(!removed) +  last_garb=""; +  else +  last_garb=sprintf("%2.2f Mb was removed in the last garbage collection " +  "%d minutes ago", +  (float)removed/(1048576.0/BLOCK_SIZE), +  (time()-lastgc)/60); +  rm("statistics"); +  write_file("statistics", +  sprintf("%2.2f Mb data in the cache\n%s", +  ((float)BLOCK_TO_KB(cache_size))/(1024.0), +  last_garb)); + } +  +  + private string lf; +  + void do_write_log() + { +  write_log(); +  exit(0); + } +  + void create(string cdir, string logfiles, int cng, int mcs) + { +  int i; +  for(i = 1; i < 3; i++) +  signal(i,do_write_log); +  signal(signum("SIGINT"), 0); +  +  if(cdir) +  { + #ifdef DEBUG +  perror("Initalizing cache, cache-dir is "+cdir+"\n"); + #endif +  cd(cdir); +  cache_normal_garb = cng*(1048576/BLOCK_SIZE); +  max_cache_size = mcs*(1048576/BLOCK_SIZE); +  if(lf != logfiles) // This function might be called more than once. +  { +  lf = logfiles; +  cleandirs(); +  create_cache(logfiles); +  find_all_files_and_log_it(); +  } +  check(0); // Open the 'size' file and, perhaps, do a garbage collect. +  perror("Garbage collector on-line, waiting for commands.\n"); +  perror("Current cache size: " +  +((float)BLOCK_TO_KB(cache_size)/(1024.0))+" MB\n"); +  } + } +  + int main() + { +  stdin->set_nonblocking( got_command, 0, cache_stream_closed ); +  stdin->set_id(stdin); +  return -1; + }   Newline at end of file added.