home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2001 April
/
PCWorld_2001-04_cd.bin
/
Software
/
TemaCD
/
smartcache
/
src
/
mgr.java
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
Macintosh to JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
Java Source
|
2001-01-26
|
66.8 KB
|
1,829 lines
/*
* Smart Cache, http proxy cache server
* Copyright (C) 1998, 1999 Radim Kolar
*
* Smart Cache is Open Source Software; you may redistribute it
* and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2, or (at your option) any later version.
*
* This program distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* A copy of the GNU General Public License is available as
* /usr/doc/copyright/GPL in the Debian GNU/Linux distribution or on
* the World Wide Web at http://www.gnu.org/copyleft/gpl.html. You
* can also obtain it by writing to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
import java.io.*;
import java.util.*;
import java.text.*;
import java.util.zip.*;
import java.net.*;
public final class mgr implements Runnable{
public static final String DEFAULTNAME=".welcome";
/* cache manager */
public static InetAddress parentproxy;
public static String parentauth; /* auth header */
public static int port; // parentproxyport
public static int ourport;
private static InetAddress ouraddress;
private static final long SAVETIMER=1000L*60*3; /* 3 min. */
public static String cache_dir;
private static String custom403;
public static int swap_level1_dirs= 4;
public static int swap_level2_dirs= 4;
public static String[] no_proxy;
public static String[] allow_cookies_to;
public static boolean case_sensitive;
/* ad Busters */
private static AdBuster ad;
private static String AdID,AdAuth;
/* access rulez */
private static boolean cacheonly;
private static regexp[] fail;
private static regexp[] nocache;
private static regexp[] pass;
private static int allowconnect[];
private static boolean fail_trace;
/* time stamps */
private static long pass_timestamp;
private static long fail_timestamp;
private static long cookie_timestamp;
private static String cookie_filename;
private static String pass_filename;
private static String fail_filename;
/* refresh strategy - multiple */
private static regexp[] refresh;
private static long minage[];
private static long maxage[];
private static long reloadage[];
private static float lastmodf[];
private static long expireage[];
private static long redirage[];
/* simple refresh p. */
private static long min_age;
public static long max_age;
private static long reload_age;
private static long expire_age;
private static long redir_age;
private static float lmfactor;
/* redirects */
private static String[] redirfrom;
private static String[] redirto;
private static Hashtable dircache;
/* flags */
private static String shutdownflag,immediate_shutdownflag;
public static boolean clear_flags_on_start=true;
private static int flag_check_interval;
/* log for statistic */
private static String stat_log;
mgr()
{
dircache=new Hashtable(25);
/* init to some defaults */
/* static intit */
request.formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
httpreq.formatter.setTimeZone(TimeZone.getDefault());
/* compute timezone in apache log style format */
int ofs=TimeZone.getDefault().getRawOffset();
if(TimeZone.getDefault().inDaylightTime(new Date())) ofs+=60*60*1000;
httpreq.timezone=(ofs<0?" -":" +");
ofs=Math.abs(ofs);
httpreq.timezone=httpreq.timezone+
(ofs/(60*60*1000)<10 ? "0"+ofs/(60*60*1000): ""+ofs/(60*60*1000));
ofs-=(ofs/(60*60*1000))*60*60*1000;
ofs/=60*1000;
httpreq.timezone=httpreq.timezone+(ofs<10? "0"+ofs : ""+ofs)+"] \"";
/* defaults */
cacheonly=false;
cache_dir="store";
port=3128; /* default squid parent proxy port */
ourport=8080; /* well known webcache port */
request.default_forward_for="127.0.0.1";
swap_level1_dirs= swap_level2_dirs=4;
lmfactor=0.2f;
min_age=15*60*1000L; /* 15 minut */
max_age=4*24*60*60*1000L; /* 4 dny */
expire_age=1000L*60*5; /* 5 minutes */
redir_age=15*1000L; /* 15 seconds */
request.qa_minlen=-1; /* quick abort disable */
request.qa_maxtime=3*60*60*1000L; /* max luxovaci cas 3 minuty */
httpreq.client_timeout=30*1000; /* 30 sec. read from cl. timeout */
request.read_timeout=5*60*1000; /* 5 min. read from net timeout */
cacheobject.keep_deleted=false;
cacheobject.generate_lastmod=0;
cacheobject.hide_errors=false;
cacheobject.defaultname=DEFAULTNAME; // UGLY CERN standard
request.remove_pragma_no_cache=false;
request.referer_hack=0;
request.fake_referer=null;
request.fake_user_agent=null;
request.append_via=true;
request.full_referer_log=true;
request.cache_protected=false;
case_sensitive=false;
httpreq.visible_hostname="smart.cache.lan";
httpreq.visible_link=null;
cachedir.readonly=false;
clear_flags_on_start=true;
fail_trace=false;
stat_log=null;
flag_check_interval=45;
cacheobject.auto_compress=false;
cacheobject.auto_decompress=false;
/* for safety */
cacheobject.end_dot=false;
cacheobject.escape_backslash=true;
}
public final void check_filesystem()
{
System.err.println("Checking filesystem ("+cache_dir+")");
if(!cachedir.readonly)
cacheobject.end_dot=endDotFilesystem();
if(!new File(cache_dir).isDirectory())
{
System.out.println("[SMARTCACHE] Fatal Error: Directory "+cache_dir+" can not be created.");
return;
}
if(cachedir.readonly)
System.err.println(" Using cache directory in READ-ONLY mode.");
else
{
System.err.println(" Host OS allows ending dot in filename: "+cacheobject.end_dot);
cacheobject.escape_backslash=!(filesystemCanUseBackslash());
System.err.println(" Host OS allows backslash in filename : "+!(cacheobject.escape_backslash));
garbage.realdirsize=filesystemHasRealDirsize();
System.err.println(" Host OS reports real directory size : "+garbage.realdirsize);
}
System.err.println("");
}
public void go() throws IOException
{
scache daemon=new scache(ourport,ouraddress);
new Thread(this).start(); /* start background directory saver... */
// TODO: REMOVE ALL ADBUSTERS CODE ??
scache.faststart=true;
// NO BUSTERS AND LASTVERCHECK. NO SERVER FOR HOSTING :(
// SOME1 WANTS TO HOST IT?
if(scache.faststart==false)
{
System.err.println("Checking for latest Smart Cache version");
String lv=getLatestVersion();
if (lv==null) lv="(Error connecting to server)";
else if (!lv.equals(scache.CACHEVER)) lv+="\007 ... its time for update!";
else
lv+=" ... up to date";
System.err.println(" Latest version is "+lv);
}
initAdBusters();
/* refresh pattern hack */
if(refresh!=null && !isInRegexpArray("*",refresh))
{
refresh=addRegexpToArray("*",refresh);
/* natahnout ! */
reloadage=incLongArraySize(reloadage);
minage=incLongArraySize(minage);
maxage=incLongArraySize(maxage);
lastmodf=incFloatArraySize(lastmodf);
expireage=incLongArraySize(expireage);
redirage=incLongArraySize(redirage);
/* nastavit hodnoty */
reloadage[reloadage.length-1]=reload_age;
minage[minage.length-1]=min_age;
maxage[maxage.length-1]=max_age;
lastmodf[lastmodf.length-1]=lmfactor;
expireage[expireage.length-1]=expire_age;
redirage[redirage.length-1]=redir_age;
}
System.out.println(new Date()+" "+scache.VERSION+" ready.");
// on port "+ourport+"/"+(ouraddress==null ? "*" : ouraddress.getHostAddress())+".");
ouraddress=null; // GC IT!
httpreq.mgr=this;
if(clear_flags_on_start)
{
checkFlag(shutdownflag); // delete pending shutdown flag on start
checkFlag(immediate_shutdownflag); // delete pending shutdown flag on start
}
daemon.httpdloop(); // enter main loop
}
private final static boolean filesystemCanUseBackslash()
{
if(cachedir.readonly) return false;
File test=new File(cache_dir,"test\\slash");
try{
new FileOutputStream(test).close();
}
catch (IOException e1) {
return false;
}
test.delete();
return true;
}
private final static boolean filesystemHasRealDirsize()
{
try
{
if(new File(".").length()>0) return true;
else return false;
}
catch (Exception grrrrrrrrrrrrrrrr)
{
return false;
}
// return false; /* Uncomment to keep some stupid JAVAC compilers happy */
}
private final static String getLatestVersion()
{
URL u=null;
try
{
u=new URL("http://adbusters.netmag.cz:8001/cachever");
// u=new URL("http://localhost:8001/cachever");
}
catch (MalformedURLException e)
{ return null;}
String ver=null;
try
{
ver=new DataInputStream(u.openStream()).readLine();
return ver;
}
catch (IOException e)
{ return null;}
}
private final void initAdBusters()
{
if(AdID==null || AdAuth==null) return;
System.err.println("Initializing cache in AdBusters mode");
try
{
URL u;
if(scache.faststart==true)
u=new URL("http://127.0.0.1:8001/AdBuster?id="+AdID+"&auth="+AdAuth+"&e");
else
u=new URL("http://adbusters.netmag.cz:8001/AdBuster?id="+AdID+"&auth="+AdAuth+"&e");
// u=new URL("http://localhost:8001/AdBuster?id="+AdID+"&auth="+AdAuth+"&e");
ObjectInputStream ois=null;
try{
ois =
new ObjectInputStream(u.openStream());
ad = (AdBuster)ois.readObject();
}
catch (Throwable e) {
System.err.println(" *ERR "+e);
}
finally
{
if(ois!=null) try{ois.close();}
catch(IOException e) {};
ois=null;
}
if(ad!=null) { System.err.println(" Refreshed rules list from server");
mergeBusters();
ad=null;
return;}
/* ze souboru */
try{
ois =
new ObjectInputStream(new FileInputStream("AdBuster.ser"));
ad = (AdBuster)ois.readObject();
}
catch (Throwable e) {
System.err.println(" *ERR "+e);
}
finally
{
if(ois!=null) try{ois.close();}
catch(IOException e) {};
ois=null;
}
if(ad!=null) { System.err.println(" Rules list loaded from local backup copy");mergeBusters(); ad=null; return;}
}
catch (MalformedURLException e)
{}
}
private final void mergeBusters()
{
if(ad==null) return;
/* save! */
try {
BufferedOutputStream bos = new BufferedOutputStream
(new FileOutputStream("AdBuster.tmp"));
ObjectOutputStream oos =
new ObjectOutputStream(bos);
oos.writeObject(ad);
oos.close();
bos.close();
/* prejmenovat na .ser */
File f=new File("AdBuster.tmp");
File f2=new File("AdBuster.ser");
if(!f2.delete()) { System.err.println(" Delete old savefile failed.");}
if(false==f.renameTo(f2)) { System.err.println(" Rename to new savefile failed");}
}
catch (Throwable e) {
System.err.println("error when saving: "+e);
}
for(int i=0;i<ad.allow.length;i++)
pass=addRegexpToArray(ad.allow[i],pass);
for(int i=0;i<ad.fail.length;i++)
fail=addRegexpToArray(ad.fail[i],fail);
System.err.println(" Ad Busters mode init done.");
scache.VERSION=scache.CACHENAME+" "+scache.CACHEVER+" in Ad Busters mode";
}
/*
private final boolean caseSensitiveFilesystem()
{
(new File(cache_dir)).mkdirs();
try{
new FileOutputStream(cache_dir+File.separator+"casecheck").close();
}
catch (IOException e1) {return false;}
boolean r=!new File(cache_dir+File.separator+"cAsEcHeCk").exists();
new File(cache_dir,"casecheck").delete();
return r;
}
*/
private final boolean endDotFilesystem()
{
(new File(cache_dir)).mkdirs();
try{
new FileOutputStream(cache_dir+File.separator+"dot.").close();
}
catch (IOException e1) {
cachedir.readonly=true;
return false;
}
File d=new File(cache_dir);
String names[];
names=d.list();
new File(cache_dir,"dot.").delete();
if(names==null) return false;
for(int i=0;i<names.length;i++)
{
if(names[i].toLowerCase().equals("dot.")) return true;
}
return false;
}
public final void read_config(String cfgfile)
{
try{
String line,token;
StringTokenizer st;
int lineno=0;
if(! new File(cfgfile).isAbsolute()) cfgfile=scache.cfgdir+File.separator+cfgfile;
DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputStream(cfgfile)));
while ( (line = dis.readLine()) != null)
{
lineno++;
if(line.startsWith("#")) continue;
st=new StringTokenizer(line);
if(st.hasMoreTokens()==false) continue;
token=st.nextToken();
try
{
if(token.equalsIgnoreCase("visible_link")) {httpreq.visible_link=st.nextToken();
continue;
}
if(token.equalsIgnoreCase("stat_log")) {stat_log=st.nextToken();
continue;
}
if(token.equalsIgnoreCase("visible_hostname")) {httpreq.visible_hostname=st.nextToken();
continue;
}
if(token.equalsIgnoreCase("default_forward_for")) {request.default_forward_for=st.nextToken();
continue;
}
if(token.equalsIgnoreCase("adbustersid")) {AdID=st.nextToken();
continue;
}
if(token.equalsIgnoreCase("adbustersauth")) {AdAuth=st.nextToken();
continue;
}
if(token.equalsIgnoreCase("defaultname")) {cacheobject.defaultname=st.nextToken();
continue;
}
if(token.equalsIgnoreCase("allow_cookies_to"))
{
while(st.hasMoreTokens())
{
String z;
z=st.nextToken().toLowerCase();
if(z.equals("all")) { allow_cookies_to=null;break;}
allow_cookies_to=addStringToArray(z,allow_cookies_to);
}
continue;
}
if(token.equalsIgnoreCase("bindaddress")) {
String ip=st.nextToken();
if(ip.equals("*")) { ouraddress=null;continue;}
try{
ouraddress=InetAddress.getByName(ip);
}
catch (IOException e) { System.err.println("Can not resolve my BindAddress: "+ip);}
continue;
}
if(token.equalsIgnoreCase("shutdown_flag")) {shutdownflag=st.nextToken();
continue;
}
if(token.equalsIgnoreCase("mime_types")) {repair.loadMimeTypes(st.nextToken());
continue;
}
if(token.equalsIgnoreCase("immediate_shutdown_flag")) {immediate_shutdownflag=st.nextToken();
continue;
}
if(token.equals("case_sensitive_matching")) {
char c=(char)Integer.valueOf(st.nextToken()).intValue();
if(c!=0) case_sensitive=true; else case_sensitive=false;
continue;
}
if(token.equals("auto_compress")) {
char c=(char)Integer.valueOf(st.nextToken()).intValue();
if(c!=0) cacheobject.auto_compress=true; else cacheobject.auto_compress=false;
continue;
}
if(token.equals("auto_decompress")) {
char c=(char)Integer.valueOf(st.nextToken()).intValue();
if(c!=0) cacheobject.auto_decompress=true; else cacheobject.auto_decompress=false;
continue;
}
if(token.equals("allowconnect")) {
while(st.hasMoreTokens())
{
int c;
c=Integer.valueOf(st.nextToken()).intValue();
allowconnect=incIntegerArraySize(allowconnect);
allowconnect[allowconnect.length-1]=c;
}
continue;
}
if(token.equalsIgnoreCase("cacheroot")) {
cache_dir=st.nextToken();
if(cache_dir.endsWith(File.separator))
cache_dir=cache_dir.substring(0,cache_dir.length()-File.separator.length());
if(cache_dir.length()==2 && cache_dir.charAt(1)==':') throw new IllegalArgumentException("Smart Cache will not use root directory '"+cache_dir+"' as data storage. Use some subdirectory instead.");
continue;
}
if(token.equalsIgnoreCase("port")) {ourport=Integer.valueOf(st.nextToken()).intValue();
continue;
}
if(token.equalsIgnoreCase("referer_hack")) {
String rh=st.nextToken();
try
{
request.referer_hack=(char)Integer.valueOf(rh).intValue();
}
catch (NumberFormatException e)
{
System.out.println("[ERROR] Referer_hack do not longer accept non-numeric agument `"+rh+"`.\nUse fake_referer instead.");
}
continue;
}
if(token.equalsIgnoreCase("fake_user_agent")) {request.fake_user_agent="User-Agent:"+st.nextToken("\n");
continue;
}
if(token.equalsIgnoreCase("fake_referer")) {request.fake_referer="Referer:"+st.nextToken("\n");
request.referer_hack=98;
continue;
}
if(token.equalsIgnoreCase("swap_level1_dirs")) {swap_level1_dirs=Integer.valueOf(st.nextToken()).intValue();
continue;
}
if(token.equalsIgnoreCase("swap_level2_dirs")) {swap_level2_dirs=Integer.valueOf(st.nextToken()).intValue();
continue;
}
if(token.equalsIgnoreCase("http_proxy")) {
if (st.countTokens()>2)
setproxy(st.nextToken(),Integer.valueOf(st.nextToken()).intValue(),st.nextToken());
else
setproxy(st.nextToken(),Integer.valueOf(st.nextToken()).intValue(),null);
continue;
}
if(token.equalsIgnoreCase("access_log")) {
String mask=st.nextToken();
if(mask.equals("*")) mask=null;
httpreq.logpatterns=addStringToArray(mask,httpreq.logpatterns);
httpreq.logfilenames=addStringToArray(st.nextToken(),httpreq.logfilenames);
continue;
}
if(token.equalsIgnoreCase("agent_log")) {
String mask=st.nextToken();
if(mask.equals("*")) mask=null;
request.alogpatterns=addStringToArray(mask,request.alogpatterns);
request.alogfilenames=addStringToArray(st.nextToken(),request.alogfilenames);
continue;
}
if(token.equalsIgnoreCase("referer_log")) {
String mask=st.nextToken();
if(mask.equals("*")) mask=null;
request.rlogpatterns=addStringToArray(mask,request.rlogpatterns);
request.rlogfilenames=addStringToArray(st.nextToken(),request.rlogfilenames);
continue;
}
if(token.equalsIgnoreCase("no_proxy")) {
while(st.hasMoreTokens())
no_proxy=addStringToArray(st.nextToken().toLowerCase(),no_proxy);
continue;
}
if(token.equalsIgnoreCase("serialnumber")) {
/* Look at my very secure registration keys checker */
// if(st.nextToken().startsWith("HTTP")) registered=true;
// else
//System.out.println("\t\007WARNING: Invalid serial number entered!");
// registered=true;
continue;
}
if(token.equalsIgnoreCase("fail")) { while(st.hasMoreTokens())
fail=addRegexpToArray(st.nextToken(),fail);
continue;
}
if(token.equalsIgnoreCase("fail_file")) {
String fn=st.nextToken();
fail=parseRegexpFile(fn,fail);
fail_timestamp=new File(fn).lastModified();
fail_filename=fn;
continue;
}
if(token.equalsIgnoreCase("allow_cookies_to_file")) {
String fn=st.nextToken();
allow_cookies_to=parseCookieFile(fn,allow_cookies_to);
cookie_timestamp=new File(fn).lastModified();
cookie_filename=fn;
continue;
}
if(token.equalsIgnoreCase("pass_file")) {
String fn=st.nextToken();
pass=parseRegexpFile(fn,pass);
pass_timestamp=new File(fn).lastModified();
pass_filename=fn;
continue;
}
if(token.equalsIgnoreCase("nocaching")) { while(st.hasMoreTokens())
nocache=addRegexpToArray(st.nextToken(),nocache);
cacheonly=false;
continue;
}
if(token.equalsIgnoreCase("wafer")
|| token.equalsIgnoreCase("fake_cookie")
) {request.wafer="Cookie:"+st.nextToken("\n");
continue;
}
if(token.equalsIgnoreCase("pass")) {while(st.hasMoreTokens())
pass=addRegexpToArray(st.nextToken(),pass);
continue;
}
if(token.equalsIgnoreCase("cacheonly")) {while(st.hasMoreTokens())
nocache=addRegexpToArray(st.nextToken(),nocache);
cacheonly=true;
continue;
}
if(token.equalsIgnoreCase("redirect")) { redirfrom=addStringToArray(st.nextToken(),redirfrom);
redirto=addStringToArray(st.nextToken(),redirto);
continue;
}
if(token.equalsIgnoreCase("quick_abort")) {
request.qa_minlen=Integer.valueOf(st.nextToken()).intValue();
request.qa_percent=Float.valueOf(st.nextToken()).floatValue();
request.qa_maxlen=Integer.valueOf(st.nextToken()).intValue();
continue;
}
if(token.equalsIgnoreCase("errordocument")) {
int code=Integer.valueOf(st.nextToken()).intValue();
if(code==403) custom403=st.nextToken();
else if(code==400 || code==500) cacheobject.custom500=st.nextToken();
else
System.err.println("[CONFIG_ERROR] "+cfgfile+":"+lineno+" Error code "+code+" is not customizable.");
continue;
}
if(token.equalsIgnoreCase("max_aborted_transfer_time")) {
request.qa_maxtime=Integer.valueOf(st.nextToken()).intValue()*1000L*60L;
continue;
}
if(token.equalsIgnoreCase("max_clients")) {
scache.MAXHTTPCLIENTS=Integer.valueOf(st.nextToken()).intValue();
continue;
}
if(token.equalsIgnoreCase("inputtimeout")) {
httpreq.client_timeout=Integer.valueOf(st.nextToken()).intValue()*1000;
continue;
}
if(token.equalsIgnoreCase("proxyreadtimeout")) {
request.read_timeout=Integer.valueOf(st.nextToken()).intValue()*1000;
continue;
}
if(token.equalsIgnoreCase("pragma_no_cache")) {
request.pnocache=(char)Integer.valueOf(st.nextToken()).intValue();
continue;
}
if(token.equalsIgnoreCase("append_via" )) {
int z=Integer.valueOf(st.nextToken()).intValue();
if(z!=0) request.append_via=true; else
request.append_via=false;
continue;
}
if(token.equalsIgnoreCase("keep_deleted")) {
int z=Integer.valueOf(st.nextToken()).intValue();
if(z!=0) cacheobject.keep_deleted=true; else
cacheobject.keep_deleted=false;
continue;
}
if(token.equalsIgnoreCase("cache_password_protected")) {
int z=Integer.valueOf(st.nextToken()).intValue();
if(z!=0) request.cache_protected=true; else
request.cache_protected=false;
continue;
}
if(token.equalsIgnoreCase("remove_pragma_no_cache")) {
int z=Integer.valueOf(st.nextToken()).intValue();
if(z!=0) request.remove_pragma_no_cache=true; else
request.remove_pragma_no_cache=false;
continue;
}
if(token.equalsIgnoreCase("fail_trace")) {
int z=Integer.valueOf(st.nextToken()).intValue();
if(z!=0) fail_trace=true; else
fail_trace=false;
continue;
}
if(token.equalsIgnoreCase("clear_flags_on_start")) {
int z=Integer.valueOf(st.nextToken()).intValue();
if(z!=0) clear_flags_on_start=true; else
clear_flags_on_start=false;
continue;
}
if(token.equalsIgnoreCase("flag_check_interval")) {
int z=Integer.valueOf(st.nextToken()).intValue();
flag_check_interval=z;
continue;
}
if(token.equalsIgnoreCase("reload_block_files")) {
// ABSOLETE: now always enabled
continue;
}
if(token.equalsIgnoreCase("generate_lastmod")) {
int z=Integer.valueOf(st.nextToken()).intValue();
cacheobject.generate_lastmod=z;
continue;
}
if(token.equalsIgnoreCase("hide_errors")) {
int z=Integer.valueOf(st.nextToken()).intValue();
if(z!=0) cacheobject.hide_errors=true; else
cacheobject.hide_errors=false;
continue;
}
if(token.equalsIgnoreCase("full_referer_log")) {
int z=Integer.valueOf(st.nextToken()).intValue();
if(z!=0) request.full_referer_log=true; else
request.full_referer_log=false;
continue;
}
if(token.equalsIgnoreCase("allow")) {
while(st.hasMoreElements())
{
String adr;
adr=st.nextToken();
if(adr.equals("*")) httpreq.allowed=null;
else
httpreq.allowed=addInetAdrToArray(InetAddress.getByName(adr),httpreq.allowed);
}
continue;
}
if(token.equalsIgnoreCase("default_refresh_pattern"))
{
reload_age=(long)(Float.valueOf(st.nextToken()).floatValue()*1000L*60L);
min_age=(long)(Float.valueOf(st.nextToken()).floatValue()*1000L*60L);
lmfactor=Float.valueOf(st.nextToken()).floatValue();
max_age=(long)(Float.valueOf(st.nextToken()).floatValue()*1000L*60L);
if(reload_age>min_age) reload_age=min_age/2;
if(max_age<=min_age) max_age=min_age+1000L*60L*60L*48L;
if(st.countTokens()>0)
{
expire_age=(long)(Float.valueOf(st.nextToken()).floatValue()*1000L*60L);
redir_age=(long)(Float.valueOf(st.nextToken()).floatValue()*1000L*60L);
} else
System.out.println("[WARNING] default_refresh_pattern can have additional arguments.");
if(expire_age>max_age) expire_age=max_age;
if(redir_age>min_age) redir_age=min_age;
continue;
}
if(token.equalsIgnoreCase("refresh_pattern"))
{
String url=st.nextToken();
if(isInRegexpArray(url,refresh)) continue;
long xreload_age=(long)Float.valueOf(st.nextToken()).floatValue()*1000L*60L;
long xmin_age=(long)Float.valueOf(st.nextToken()).floatValue()*1000L*60L;
float xlmfactor=Float.valueOf(st.nextToken()).floatValue();
long xmax_age=(long)Float.valueOf(st.nextToken()).floatValue()*1000L*60L;
if(xreload_age>xmin_age) xreload_age=xmin_age/4;
if(xmax_age<=xmin_age) xmax_age=xmin_age+1000L*60L*60L*48L;
long xexpire_age,xredir_age;
if(st.countTokens()>0)
{
xexpire_age=(long)(Float.valueOf(st.nextToken()).floatValue()*1000L*60L);
xredir_age=(long)(Float.valueOf(st.nextToken()).floatValue()*1000L*60L);
} else
{
System.out.println("[WARNING] refresh_pattern can have additional arguments.");
xexpire_age=5*60*1000L;
xredir_age=10*1000L;
}
if(xexpire_age>xmax_age) xexpire_age=xmax_age;
if(xredir_age>xmin_age) xredir_age=xmin_age;
/* pridat do pole */
refresh=addRegexpToArray(url,refresh);
/* natahnout ! */
reloadage=incLongArraySize(reloadage);
minage=incLongArraySize(minage);
maxage=incLongArraySize(maxage);
expireage=incLongArraySize(expireage);
redirage=incLongArraySize(redirage);
lastmodf=incFloatArraySize(lastmodf);
/* nastavit hodnoty */
reloadage[reloadage.length-1]=xreload_age;
minage[minage.length-1]=xmin_age;
maxage[maxage.length-1]=xmax_age;
lastmodf[lastmodf.length-1]=xlmfactor;
expireage[expireage.length-1]=xexpire_age;
redirage[redirage.length-1]=xredir_age;
continue;
}
System.out.println("[CONFIG_ERROR] Unknown keyword "+token+" in "+cfgfile+":"+lineno);
}
catch (NoSuchElementException nse)
{ System.out.println("[CONFIG_ERROR] "+cfgfile+":"+lineno+" Missing arguent(s).");
continue;}
catch (NumberFormatException nse)
{ System.out.println("[CONFIG_ERROR] "+cfgfile+":"+lineno+" Invalid Number Format.");
continue;}
}/* while */
dis.close();
}
catch(FileNotFoundException kiss)
{ System.out.println("[WARNING] No config file ("+cfgfile+") found, using defaults.");}
catch(IOException e)
{ System.out.println("I/O Error reading config file "+cfgfile);}
// init access log filez
if(httpreq.logpatterns!=null) httpreq.logfilez=new DataOutputStream[httpreq.logpatterns.length];
// init agent log filez
if(request.alogpatterns!=null) request.alogfilez=new DataOutputStream[request.alogpatterns.length];
// init referer log filez
if(request.rlogpatterns!=null) request.rlogfilez=new DataOutputStream[request.rlogpatterns.length];
if(swap_level1_dirs<1) swap_level1_dirs=1;
if(swap_level2_dirs<1) swap_level2_dirs=1;
}
public final void setproxy(String hostname,int port,String auth)
{
if (auth!=null) parentauth="Proxy-authorization: Basic "+HTUU.encode_string(auth); else parentauth=null;
try{
parentproxy=InetAddress.getByName(hostname);
this.port=port;
// System.out.println("My parent proxy is "+hostname+" port "+port);
}
catch (UnknownHostException e)
{
System.err.println("[WARNING] Can not resolve parent proxy hostname: "+hostname+" - running without it.");
parentproxy=null;
no_proxy=null;
parentauth=null;
this.port=0;
}
}
final public void process_request(request req) throws MalformedURLException, IOException
{
boolean allowed;
allowed=false;
String requested=req.getURL();
/* HANDLE REWRITE ! */
if(redirfrom!=null)
{
String fragment;
int j=redirfrom.length;
for(int i=0;i<j;i++)
{
fragment=simpleWildMatch(redirfrom[i], requested);
if(fragment==null) continue;
if(is_wild(redirto[i]))
//req.make_headers(301,"text/html",redirto[i].substring(0,redirto[i].length()-1)+fragment,0,0,0);
req.rewriteURL(redirto[i].substring(0,redirto[i].length()-1)+fragment);
else
// req.make_headers(301,"text/html",redirto[i],0,0,0);
req.rewriteURL(redirto[i]);
requested=req.getURL(); // reread URL
break;
}
} /* redir handler end */
try
{
/* is URL in allowed list ? */
if(pass!=null)
{
int j=pass.length;
for(int i=0;i<j;i++)
if(pass[i].matches(requested))
{ allowed=true;break;}
}
}
catch (IndexOutOfBoundsException ignore) {}
try
{
/* is URL blocked ? */
if(fail!=null && allowed==false)
{
int j=fail.length;
for(int i=0;i<j;i++)
{
if(fail[i].matches(requested))
{
cacheobject.c_block++; //STAT
if(fail_trace)
{
System.out.println("Blocked: " +requested+"\n\tby rule: \""+fail[i]+"\"");
}
if(custom403==null) req.send_error(403,"Forbidden by rule");
else
if(custom403.charAt(0)=='0') {
req.make_headers(200,"image/gif",null,null,43,886828316241L,0);
req.send_headers();
req.sendBytes(req.GIF);
}
else
if(custom403.charAt(0)=='-') {
req.send_error(204,"No Content");
}
else if(custom403.charAt(0)=='!')
{
req.make_headers(200,"text/html",null,null,0,new Date().getTime(),0);
req.send_headers();
req.sendString("<HTML></HTML>");
}
else
{ req.make_headers(301,null,null,custom403,0,new Date().getTime(),0);
req.send_headers();
}
req.close();
return;
}
}
}
}
catch (IndexOutOfBoundsException ignore) {}
/* NO-CACHE HANDLER */
if(nocache!=null)
{ // if(cacheonly) req.nocache();
int j=nocache.length;
int i;
toploop:while(true)
{
for(i=0;i<j;i++)
{
if(nocache[i].matches(requested))
{
if(!cacheonly) req.nocache();
break toploop;
}
} /* for */
if(cacheonly) req.nocache();
break;
} /* toploop */
}
String[] parsed;
parsed=parseURL(requested,req.getProtocol());
String host=parsed[0];
try
{
/* C00KIES FILTER */
if(allow_cookies_to!=null)
{
cookieloop:while(true)
{
for(int i=allow_cookies_to.length-1;i>=0;i--)
if(host.endsWith(allow_cookies_to[i])) { break cookieloop;}
req.removeCookies();
break;
}
}
}
catch (IndexOutOfBoundsException ignore) {}
/* USE PARENT PROXY SERVER ?? */
boolean direct;
if(parentproxy==null) direct=true;
else
{
direct=false;
if(no_proxy!=null) {
int j=no_proxy.length;
for(int i=0;i<j;i++) {
if(host.endsWith(no_proxy[i])) {
direct=true;
break;
}
}
} /* if No_proxy */
}
if(direct)
{
/* DIREKT REZIM - klidek */
try{
req.setTarget(InetAddress.getByName(host),parsed[1]==null? 80: Integer.valueOf(parsed[1]).intValue());
}
catch (UnknownHostException e) { req.setTarget(null,80); }
catch (NumberFormatException e) { req.send_error(400,"Port is not a numeric constant: "+parsed[1]); }
/* premenime request na normal */
if(parsed[4]!=null) req.send_error(501,"Protocol "+parsed[4]+" is not directly supported, configure http_proxy.");
req.setRequestTo(parsed[2]+parsed[3]);
}
else
{
req.setTarget(parentproxy,port);
if (parentauth!=null) req.add_header(parentauth);
}
/* testneme na non HEAD/GET methods */
switch(req.getMethod())
{
case httpreq.REQUEST_POST:
case httpreq.REQUEST_PUT:
req.addHost(host,parsed[1]);
req.direct_request(true);
return;
case httpreq.REQUEST_TRACE:
req.handle_trace();
return;
case httpreq.REQUEST_OPTIONS:
req.addHost(host,parsed[1]);
req.handle_options();
return;
case httpreq.REQUEST_DELETE:
req.addHost(host,parsed[1]);
req.direct_request(false);
return;
case httpreq.REQUEST_CONNECT:
{
int port=80;
if(parsed[1]!=null)
try
{ port=Integer.valueOf(parsed[1]).intValue();}
catch (NumberFormatException e) { req.send_error(400,"Port is not a numeric constant:"+parsed[1]); }
if(allowconnect==null) req.send_error(501,"CONNECCT method is disabled by configuration.");
/* Always go direct! */
try
{
req.setTarget(InetAddress.getByName(host),port);}
catch (UnknownHostException e)
{ req.send_error(500,"CONNECT failed: "+host+" Host unknown.");}
for(int i=allowconnect.length-1;i>=0;i--)
{
if(allowconnect[i]==port)
{
req.handle_connect();
return;
}
}
req.send_error(403,"Direct connecting to port "+parsed[1]+" is forbidden by rule.");
}
}
req.addHost(host,parsed[1]); /* pridat Host: hlavicku */
/* konverze na local dir */
String locdir=getLocalDir(host,parsed[1],parsed[2],parsed[4]);
cachedir dir=null;
try{
dir=getDir(locdir);
}
catch(Exception e) { e.printStackTrace();
System.out.println("Hostname:"+host);
System.out.println("Port:"+parsed[1]);
System.out.println("Dir:"+parsed[2]);
req.close();
return;
}
cacheobject cobj;
cobj=dir.getObject(parsed[3]);
/* HANDLE REFRESH PATTERNS MIN_AGE, PERCENT, MAX_AGE */
if(refresh!=null)
{
int refreshcache=refresh.length;
for(int i=0;i<refreshcache;i++)
if(refresh[i].matches(requested))
{
cobj.make_request(req,reloadage[i],minage[i],maxage[i],lastmodf[i],expireage[i],redirage[i]);
break;
}
}
else
cobj.make_request(req,reload_age,min_age,max_age, lmfactor,expire_age,redir_age);
req.close();
}
final private synchronized cachedir getDir(String locdir)
{
cachedir dir=(cachedir)dircache.get(locdir);
if(dir!=null) return dir;
dir=new cachedir(locdir);
dircache.put(locdir,dir);
return dir;
}
final public void run()
{
int ticks;
if(immediate_shutdownflag==null || flag_check_interval<=0)
flag_check_interval=(int)(SAVETIMER/1000);
/* normalize fci */
ticks=(int)(SAVETIMER/1000/flag_check_interval);
if(ticks==0) ticks=1;
flag_check_interval=(int)(SAVETIMER/1000/ticks);
long sleeptime=flag_check_interval*1000L;
int i=0;
// System.out.println("[debug] ticks="+ticks+" sleeptime="+sleeptime/1000);
while(true)
{
try{
Thread.sleep(sleeptime);
}
catch (InterruptedException e)
{
System.out.println("[Smart Cache] Background saver Interrupted, exiting.");
save();save();break;
}
i++;
if(i>=ticks) { save();i=0;}
/* check 4 IMM shutdownflag */
if(checkFlag(immediate_shutdownflag))
{
Enumeration e2=dircache.elements();
while(e2.hasMoreElements())
{
cachedir d;
d=(cachedir) e2.nextElement();
d.save();
d.cleandir(); /* if needed */
}
httpreq.flush(httpreq.logfilez);
httpreq.flush(request.alogfilez);
httpreq.flush(request.rlogfilez);
System.out.println(new Date()+" Server stoped by Immediate shutdown flag.");System.exit(0);
}
// reloading block files
if(pass_filename!=null)
{
if(new File(pass_filename).lastModified()!=pass_timestamp)
{
System.out.println(new Date()+" Reloading Pass_file "+pass_filename);
pass=parseRegexpFile(pass_filename,null);
pass_timestamp=new File(pass_filename).lastModified();
}
}
if(fail_filename!=null)
{
if(new File(fail_filename).lastModified()!=fail_timestamp)
{
System.out.println(new Date()+" Reloading fail_file "+fail_filename);
fail=parseRegexpFile(fail_filename,null);
fail_timestamp=new File(fail_filename).lastModified();
}
}
if(cookie_filename!=null)
{
if(new File(cookie_filename).lastModified()!=cookie_timestamp)
{
System.out.println(new Date()+" Reloading allow_cookies_to_file "+cookie_filename);
allow_cookies_to=parseCookieFile(cookie_filename,null);
cookie_timestamp=new File(cookie_filename).lastModified();
}
}
}
}
/* Ulozi hashtabulku na disk */
final private void save()
{
int saved=0;
int cleaned=0;
Enumeration e1=dircache.keys();
Enumeration e2=dircache.elements();
while(e1.hasMoreElements())
{
cachedir d;
d=(cachedir) e2.nextElement();
String key;
key=(String) e1.nextElement();
if(d.dirty==true) { d.save(); saved++;}
else
{ dircache.remove(key);
d.cleandir(); /* if needed */
// System.err.println("[DIRGC] "+key);
cleaned++;}
}
httpreq.flush(httpreq.logfilez);
httpreq.flush(request.alogfilez);
httpreq.flush(request.rlogfilez);
/* STATs */
DataOutputStream dos=null;
if(stat_log!=null)
try
{
dos=new DataOutputStream(new BufferedOutputStream(
new FileOutputStream(stat_log,true),4096));
}
catch (IOException ee1)
{
System.err.println("Problem creating stat_log file "+stat_log+" - turning it off.");
stat_log=null;
}
if(saved>0)
{
StringBuffer sb=new StringBuffer(100);
sb.append(new Date().toString());
sb.append(" - ");
sb.append(
(int)(
100.0f*(cacheobject.c_hit+cacheobject.c_block) /
((float)cacheobject.c_hit+cacheobject.c_block
+cacheobject.c_miss+cacheobject.c_refresh)
) );
sb.append("% REQS: ");
sb.append(cacheobject.c_hit);
sb.append(" Hit, ");
sb.append(cacheobject.c_refresh);
sb.append(" Refresh, ");
sb.append(cacheobject.c_miss);
sb.append(" Miss, ");
sb.append(cacheobject.c_block);
sb.append(" Block.");
System.out.println(sb);
if(dos!=null)
try
{
dos.writeBytes(sb.toString());
dos.writeBytes("\n");
}
catch (IOException ignore) {}
// clear the stats
cacheobject.c_hit=cacheobject.c_miss=cacheobject.c_refresh=cacheobject.c_block
=0;
}
if(cacheobject.b_miss+cacheobject.b_hit>0)
{
StringBuffer sb=new StringBuffer(100);
sb.append(new Date());
sb.append(" - ");
sb.append(
(int)(
100.0f*cacheobject.b_hit/((float)cacheobject.b_miss+cacheobject.b_hit)
) );
sb.append("% BYTES: ");
sb.append(cacheobject.b_miss);
sb.append(" B in, ");
sb.append(cacheobject.b_miss+cacheobject.b_hit);
sb.append(" B out.");
System.out.println(sb);
if(dos!=null)
try
{
dos.writeBytes(sb.toString());
dos.writeBytes("\n");
}
catch (IOException ignore) {}
// clear the stats
cacheobject.b_hit=cacheobject.b_miss=0;
}
/* close stat_logfile */
if(dos!=null)
try
{ dos.close();}
catch (IOException err)
{
stat_log=null;
}
if(saved>0 || cleaned> 0)
{
System.out.println(new Date().toString()+" - DIRS: "+saved+" saved, "+cleaned+" garbage collected.");
}
if(saved==0)
{
httpreq.close(httpreq.logfilez);
httpreq.close(request.alogfilez);
httpreq.close(request.rlogfilez);
if(checkFlag(shutdownflag))
{ System.out.println(new Date()+" Server stoped by shutdown flag.");System.exit(0);}
}
} /* save end */
/* prechrousta URL a vrati
0 - hostname
1 - port (if any) jinak null
2 - directory
3 - file including query string ("" if empty)
4 - protocol (null if http)
*/
final public static String[] parseURL(String url,String proto)
{
String[] res=new String[5];
res[3]=""; /* HashTable do not likes NULL */
int i,j,seven;
if(proto!=null)
{
/* protocol check */
res[4]=proto;
seven=proto.length()+3; /* '://' */
if(seven==7)
{
char c;
c=proto.charAt(0);
if(c=='h' || c=='H') res[4]=null;
}
}else { res[4]=null;seven=0;}
i=url.indexOf('/',seven);
if(i==-1) { url+='/'; i=url.length()-1;}
j=url.indexOf(':',seven);
/* http://zero.dsd:434/ */
if(j!=-1 && j<i) /* mame tu portname */
{
res[0]=url.substring(seven,j).toLowerCase();
res[1]=url.substring(j+1,i);
if(res[1].equals("80")) res[1]=null;
}
else
{
res[0]=url.substring(seven,i).toLowerCase();
}
/* parse adr */
/* najdeme nejvice vlevo z moznych debilnich znaku */
j=url.length()-1;
byte v[];
v=new byte[j+1];
url.getBytes(i,j+1,v,i);
// getChars(i,j,v,0);
loop1:for(int zz=i;zz<=j;zz++)
{
switch(v[zz])
{
case 0x3b: // ;
case 0x3a: // :
case 0x3d: // =
case 0x3f: // ?
j=zz;break loop1;
case 0x23: // #
url=url.substring(0,zz);break loop1;
}
}
j=url.lastIndexOf('/',j);
String adr=url.substring(i,j+1); // adresar
/* Normalize URL - remove /../ */
/* NOTE: /./ should be also removed, but it do not hurt anything? */
while( (i=adr.indexOf("/../")) >= 0 )
{
/* DEBUG:
*/
int l;
if( (l=adr.lastIndexOf('/',i-1)) >=0 )
adr= adr.substring(0,l)+ adr.substring(i+3);
else
adr=adr.substring(i+3);
}
res[2]=adr;
if(j+1!=url.length()) res[3]=url.substring(j+1);
return res;
}
final public String getLocalDir(String host,String port,String urldir,String proto)
{
/***
Host - zero.vole.cz:3333
urldir = /ddfgfds/rerew/ - musi koncit s /
*/
StringBuffer result=new StringBuffer(80);
result.append(cache_dir);
int i;
/* 1. spocitat hash z host stringu */
CRC32 crc=new CRC32();
// host=host.toLowerCase();
crc.update(host.getBytes());
/* mame hash - rozdelime ho na adresar */
// System.out.println("value="+i);
/* zacneme budovat cestu */
i=(int)(crc.getValue()/(0x100000000L/(swap_level1_dirs*swap_level2_dirs)));
result.append(File.separator+(i/swap_level2_dirs)+File.separator+(i % swap_level2_dirs)+File.separator+host);
/* pridame port */
if(port!=null)
{result.append('_');
result.append(port);
}
/* add protocol */
if(proto!=null)
{
result.append('^');
result.append(proto);
}
/* pridame adresar */
if(File.separatorChar!='/') urldir=urldir.replace('/',File.separatorChar);
/* *************************************************** */
/* ALERT: Synchronize by hand with garbage.encodechars */
/* *************************************************** */
/* nahrazujeme nepratelske znaky */
// urldir=urldir.replace(':','_');
// zde to neni nutne, neb muze byt jen v portu
// urldir=urldir.replace('*','@');
// urldir=urldir.replace('?','#');
// urldir=urldir.replace('~','-');
// these two are not needed. Browsers sends < >
// urldir=urldir.replace('>','}');
// urldir=urldir.replace('<','{');
urldir=urldir.replace('|','!');
result.append(urldir);
return result.toString();
}
/* U T I L I T Y */
final static String[] addStringToArray(String what,String[] array)
{
//if(what==null) return array;
if(array==null) { array=new String[1];array[0]=what;return array;}
String[] tmp;
int ar=array.length;
tmp=new String[ar+1];
System.arraycopy(array,0,tmp,0,ar);
tmp[ar]=what;
return tmp;
}
final static String[] reverseStringArray(String[] what)
{
String res[];
if(what==null) return null;
res=new String[what.length];
for(int i=0;i<what.length;i++)
res[what.length-1-i]=what[i];
return res;
}
final static regexp[] reverseRegexpArray(regexp[] what)
{
regexp res[];
if(what==null) return null;
res=new regexp[what.length];
for(int i=0;i<what.length;i++)
res[what.length-1-i]=what[i];
return res;
}
final static regexp[] addRegexpToArray(String what,regexp[] array)
{
if(what==null) return array;
if(array==null) { array=new regexp[1];array[0]=new regexp(what,true);return array;}
/* test zda tam uz nejsme */
for(int i=0;i<array.length;i++)
if(array[i].matches(what)) { System.err.println("[INFO] Rule \""+what+"\" ignored, already matched by \""+array[i]+"\"");return array;}
regexp[] tmp;
tmp=new regexp[array.length+1];
System.arraycopy(array,0,tmp,0,array.length);
tmp[array.length]=new regexp(what,!case_sensitive);
return tmp;
}
final static boolean isInRegexpArray(String what,regexp[] array)
{
if(array==null) return false;
for(int i=0;i<array.length;i++)
if(array[i].matches(what)) { return true;}
return false;
}
final public static int [] incIntegerArraySize(int[] array)
{
if(array==null) { array=new int[1];return array;}
int[] tmp;
tmp=new int[array.length+1];
System.arraycopy(array,0,tmp,0,array.length);
return tmp;
}
final public static long[] incLongArraySize(long[] array)
{
if(array==null) { array=new long[1];return array;}
long[] tmp;
tmp=new long[array.length+1];
System.arraycopy(array,0,tmp,0,array.length);
return tmp;
}
final public static float[] incFloatArraySize(float[] array)
{
if(array==null) { array=new float[1];return array;}
float[] tmp;
tmp=new float[array.length+1];
System.arraycopy(array,0,tmp,0,array.length);
return tmp;
}
/* SIMPLE WILD CARD REGEXP */
/* hvezdicka muze byt jen na konci retezce */
/* TODO: predelat na regionmatches */
final public static String simpleWildMatch(String mask, String test)
{
String lastmatch;
if(mask==null) return test;
int i=mask.indexOf('*',0);
if(i==-1) {
if(test.equals(mask)) return test;
else
return null;
}
int tl=test.length();
int ml=mask.length();
if(i!=ml-1) throw new IllegalArgumentException("* is not at end of string "+mask);
//if(test.startsWith(mask.substring(0,ml-1)))
if(test.regionMatches(0,mask,0,ml-1))
if (tl>=ml) return test.substring(ml-1);
else
return "";
return null;
}
final public void garbage_collection()
{
System.out.println(new Date()+" running garbage collection");
garbage g=new garbage(cache_dir);
g.garbage_collection();
System.out.println(new Date()+" operation ended");
}
final public void rebalance()
{
System.out.println(new Date()+" rebalancing directories to "+swap_level1_dirs+"/"+swap_level2_dirs+" levels.");
garbage g=new garbage(cache_dir);
g.rebalance();
System.out.println(new Date()+" operation ended");
}
final public void cacheimport(String d)
{
repair.quiet=true;
repair.nosave=true;
repair.force=false;
System.out.println(new Date()+" importing from cache on "+d);
garbage g=new garbage(cache_dir);
g.cacheimport(d);
System.out.println(new Date()+" operation ended");
}
final public void cacheexport(String d,int type,long diff)
{
repair.quiet=true;
repair.nosave=true;
repair.force=false;
System.out.println(new Date()+" exporting cache to "+d);
garbage g=new garbage(cache_dir);
g.export(d,type,diff);
System.out.println(new Date()+" operation ended");
}
final public void dirimport(String d)
{
repair.quiet=true;
repair.nosave=true;
repair.force=false;
System.out.println(new Date()+" importing "+d);
garbage g=new garbage(cache_dir);
g.dirimport(d);
System.out.println(new Date()+" operation ended");
}
final public void fake_garbage_collection()
{
System.out.println(new Date()+" [FAKE] running garbage collection.");
garbage g=new garbage(cache_dir);
g.fake_garbage_collection();
System.out.println(new Date()+" [FAKE] garbage collection ended.");
}
final public void kill_unref()
{
System.out.println(new Date()+" killing unreferenced files.");
garbage g=new garbage(cache_dir);
g.cleanup();
System.out.println(new Date()+" unreferenced files removed.");
}
final public void converto020()
{
System.out.println(new Date()+" converting cache control files to version 0.20");
garbage g=new garbage(cache_dir);
g.converto020();
System.out.println(new Date()+" operation ended\nDO *** NOT *** RUN THIS OPERATION AGAIN OR YOUR DATA IN CACHE WILL BE DESTROYED!");
}
final public void converto030()
{
System.out.println(new Date()+" converting cache control files to version 0.30.");
garbage g=new garbage(cache_dir);
g.converto030();
System.out.println(new Date()+" operation ended.");
}
final static private boolean is_wild(String r)
{
if(r.indexOf('*',0)==-1) return false;
else
return true;
}
final static private boolean checkFlag(String f)
{
if(f==null) return false;
File fl=new File(f);
if(fl.canRead())
{fl.delete();return true;}
return false;
}
final static regexp[] parseRegexpFile(String fname,regexp fail[])
{
try
{
String line,token;
StringTokenizer st;
if(! new File(fname).isAbsolute()) fname=scache.cfgdir+File.separator+fname;
DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputStream(fname)));
while ( (line = dis.readLine()) != null)
{
if(line.startsWith("#")) continue;
st=new StringTokenizer(line);
if(st.hasMoreTokens()==false) continue;
token=st.nextToken();
if(token.equalsIgnoreCase("fail")||token.equalsIgnoreCase("pass"))
{
System.out.println(new Date()+" [WARNING] Stop using Fail/Pass keyword in fail/pass file.");
if(st.hasMoreTokens()==false) continue;
token=st.nextToken();
}
if(token.indexOf('*')==-1) token+="*";
fail=addRegexpToArray(token,fail);
}
dis.close();
}
catch (IOException ioe)
{
System.out.println(new Date()+" I/O Error reading file "+fname);
}
return fail;
}
/* load block c00kie */
final static String[] parseCookieFile(String fname,String fail[])
{
try
{
String line,token;
StringTokenizer st;
if(! new File(fname).isAbsolute()) fname=scache.cfgdir+File.separator+fname;
DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputStream(fname)));
while ( (line = dis.readLine()) != null)
{
if(line.startsWith("#")) continue;
st=new StringTokenizer(line);
while(st.hasMoreTokens())
{
token=st.nextToken().toLowerCase();
if(token.indexOf('*')>-1)
{
System.out.println(new Date()+" [ERROR] Wildcards records are not supported in cookie_file");
continue;
}
else
if(token.equalsIgnoreCase("all")) { return null;}
fail=addStringToArray(token,fail);
}
}
dis.close();
}
catch (IOException ioe)
{
System.out.println(new Date()+" I/O Error reading file "+fname);
}
return fail;
}
final static InetAddress[] addInetAdrToArray(InetAddress what,InetAddress[] array)
{
if(array==null) { array=new InetAddress[1];array[0]=what;return array;}
InetAddress[] tmp;
int ar=array.length;
tmp=new InetAddress[ar+1];
System.arraycopy(array,0,tmp,0,ar);
tmp[ar]=what;
return tmp;
}
} /* class */