home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / smartcache / src / repair.java < prev    next >
Text File  |  2001-01-26  |  15KB  |  489 lines

  1. /*
  2.  *  Smart Cache REPAIR TOOL
  3.  *  Copyright (C) 1999, 2000 Radim Kolar 
  4.  *
  5.  *    Smart Cache is Open Source Software; you may redistribute it
  6.  *  and/or modify it under the terms of the GNU General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2, or (at your option) any later version.
  9.  *
  10.  *    This program distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13.  *  General Public License for more details.
  14.  *
  15.  *    A copy of the GNU General Public License is available as
  16.  *  /usr/doc/copyright/GPL in the Debian GNU/Linux distribution or on
  17.  *  the World Wide Web at http://www.gnu.org/copyleft/gpl.html. You
  18.  *  can also obtain it by writing to the Free Software Foundation,
  19.  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20.  */
  21.  
  22. import java.util.*;
  23. import java.io.*;
  24.  
  25. public class repair
  26. {
  27.  
  28.  public static final String VERSION="0.9";
  29.  /* global vars */
  30.  public static boolean quiet=false;
  31.  public static boolean force=false;
  32.  public static boolean nosave=false;
  33.  public static boolean forcesave=false;
  34.  public static boolean compress=false;
  35.  
  36.  static regexp ignoretable[]=
  37.             {
  38.               new regexp("*.tmp",false)
  39.             };
  40.  
  41.  
  42.  static String guesstable[]=
  43.            { 
  44.              // java stuff
  45.              // ".java","application/java",
  46.              ".java","text/plain",
  47.              ".class","application/java-vm",
  48.              ".jar","application/java-archive",
  49.          
  50.          // images
  51.              ".gif","image/gif",
  52.          ".ief","image/ief",
  53.          ".tiff","image/tiff",
  54.          ".tif","image/tiff",
  55.              ".jpeg","image/jpeg",
  56.              ".jpe","image/jpeg",
  57.              ".jpg","image/jpeg",
  58.          ".png","image/png",
  59.          ".ras","image/x-cmu-raster",
  60.          ".bmp","image/x-ms-bmp",
  61.          ".pnm","image/x-portable-anymap",
  62.          ".pbm","image/x-portable-bitmap",
  63.          ".pgm","image/x-portable-graymap",
  64.          ".ppm","image/x-portable-pixmap",
  65.          ".rgb","image/x-rgb",
  66.          ".xbm","image/x-xbitmap",
  67.          ".xpm","image/x-xpixmap",
  68.          ".xwd","image/x-xwindowdump",
  69.          
  70.          // plain text
  71.              ".txt","text/plain",
  72.              ".text","text/plain",
  73.              ".doc","text/plain",
  74.              ".log","text/plain",             
  75.          ".csv","text/comma-separated-values",
  76.          ".tsv","text/tab-separated-values",
  77.  
  78.          // hypertext
  79.              "welcome",  "text/html", // cache-generated index
  80.          ".shtml", "text/html",
  81.          ".pl",  "text/html",
  82.          ".cgi",  "text/html",
  83.          ".asp",  "text/html",
  84.          ".jsp",  "text/html",
  85.              ".htm",  "text/html",
  86.              ".html",  "text/html",
  87.              ".htmli",  "text/html",
  88.              ".dchtml",  "text/html",
  89.          ".pht",   "text/html",
  90.          ".phtml", "text/html",
  91.          ".php",   "text/html",
  92.          ".php3",  "text/html",
  93.          ".php3p", "text/html",
  94.          
  95.          ".texi","application/x-texinfo",
  96.          ".texinfo","application/x-texinfo",
  97.  
  98.          // VRML
  99.          ".vrm","x-world/x-vrml",
  100.          ".vrml","x-world/x-vrml",
  101.          ".wrl" ,"x-world/x-vrml",
  102.          
  103.          // formated text
  104.          ".rtx","text/richtext",
  105.              ".pdf","application/pdf",
  106.          ".rtf","application/rtf",
  107.          ".ai","application/postscript",
  108.          ".ps","application/postscript",
  109.          ".eps","application/postscript",
  110.          ".wp5","application/wordperfect5.1",
  111.          ".wk","application/x-123",
  112.          ".dvi","application/x-dvi",
  113.          ".frm","application/x-maker",
  114.          ".maker","application/x-maker",
  115.          ".frame","application/x-maker",
  116.          ".fm"   ,"application/x-maker",
  117.          ".fb"   ,"application/x-maker",
  118.          ".book", "application/x-maker",
  119.          ".fbdoc","application/x-maker",
  120.  
  121.          // fonts
  122.          ".pfa","application/x-font",
  123.          ".pfb","application/x-font",
  124.          ".gsf","application/x-font",
  125.          ".pcf","application/x-font",
  126.          ".pcf.z","application/x-font",
  127.          ".gf","application/x-tex-gf",
  128.          ".pk","application/x-tex-pk",
  129.  
  130.          // archives
  131.              ".zip","application/zip",
  132.              ".tar","application/x-tar",
  133.          ".hqx","application/mac-binhex40",
  134.          ".bcpio","application/x-bcpio",
  135.          ".cpio","application/x-cpio",
  136.          ".deb","application/x-debian-package",
  137.              ".gtar","application/x-gtar",
  138.          ".tgz" ,"application/x-gtar",
  139.          ".tar.gz","application/x-gtar",
  140.          ".shar","application/x-shar",
  141.          ".sit","application/x-stuffit",
  142.          ".sv4cpio","application/x-sv4cpio",
  143.          ".sv4crc","application/x-sv4crc",
  144.          
  145.          //audio
  146.          ".au","audio/basic",
  147.          ".snd","audio/basic",
  148.              ".mid","audio/midi",
  149.              ".midi","audio/midi",
  150.              ".mp2","audio/mpeg",
  151.              ".mpega","audio/mpeg",
  152.              ".mpga","audio/mpeg",
  153.              ".mp3","audio/mpeg",
  154.          ".m3u","audio/mpegurl",
  155.              ".aif","audio/x-aiff",
  156.              ".aiff","audio/x-aiff",
  157.              ".aifc","audio/x-aiff",
  158.          ".wav","audio/x-wav",
  159.          ".ra" ,"audio/x-pn-realaudio",
  160.          ".rm" ,"audio/x-pn-realaudio",
  161.          ".ram","audio/x-pn-realaudio",
  162.  
  163.          //video
  164.          ".mpeg","video/mpeg",
  165.          ".mpg","video/mpeg",
  166.              ".mpe","video/mpeg",
  167.              ".qt","video/quicktime",
  168.              ".mov","video/quicktime",
  169.              ".avi","video/x-msvideo",
  170.              ".movie","video/x-sgi-movie",
  171.          ".dl","video/dl",
  172.          ".fli","video/fli",
  173.          ".gl","video/gl",
  174.          ".asf","video/x-ms-asf",
  175.          ".asx","video/x-ms-asf",
  176.  
  177.          //sources
  178.          ".tex","text/x-tex",
  179.          ".c","text/plain",
  180.          ".h","text/plain",
  181.          ".ltx","text/x-tex",
  182.          ".sty","text/x-tex",
  183.          ".cls","text/x-tex",
  184.          ".latex","application/x-latex",
  185.          ".oda","application/oda",
  186.          ".t"  ,"application/x-troff",
  187.          ".tr" ,"application/x-troff",
  188.          ".roff","application/x-troff",
  189.          ".man", "application/x-troff-man",
  190.          ".me",  "application/x-troff-me",
  191.          ".ms",  "application/x-troff-ms",
  192.          ".vcs", "text/x-vCalendar",
  193.          ".vcf", "text/x-vCard",
  194.  
  195.          // misc apps
  196.          ".csm","application/cu-seeme",
  197.          ".cu", "application/cu-seeme",
  198.          ".tsp","application/dsptype",
  199.          ".spl","application/futuresplash",
  200.          ".pgp","application/pgp-signature",
  201.              ".wz", "application/x-Wingz",
  202.          ".dcr","application/x-director",
  203.          ".dir","application/x-director",
  204.          ".dxr","application/x-director",
  205.              ".hdf","application/x-hdf",
  206.              ".mif","application/x-mif",
  207.          ".nc" ,"application/x-netcdf",
  208.          ".cdf","application/x-netcdf",
  209.          ".pac","application/x-ns-proxy-autoconfig",
  210.          ".swf","application/x-shockwave-flash",
  211.          ".swfl","application/x-shockwave-flash",         
  212.          ".ustar","application/x-ustar",
  213.          ".src","application/x-wais-source",
  214.  
  215.          // msdos
  216.          ".com","application/x-msdos-program",
  217.          ".exe","application/x-msdos-program",
  218.          ".bat","application/x-msdos-program",
  219.  
  220.          //microsoft apps
  221.          ".xls","application/excel",
  222.          ".dot","application/msword", 
  223.              ".ppt","application/powerpoint",
  224.          
  225.          //binary files
  226.          ".bin","application/octet-stream",
  227.  
  228.            };
  229.  
  230.  public final static void main(String argv[])
  231.  {
  232.   System.out.println("Repair "+VERSION+" - Smart Cache integrity checker and repairer.");
  233.   System.out.println("Utility for recreating .cacheinfo files without data loss. ");
  234.   System.out.println("Copyright (c) Radim Kolar 1999, 2000. There are NO warranty and no miracles!\n");
  235.  
  236.   if(argv.length==0)
  237.    {
  238.      usage();
  239.    } 
  240.   boolean rec;
  241.   rec=false;
  242.   if(cacheobject.defaultname==null) cacheobject.defaultname=mgr.DEFAULTNAME;
  243.   boolean anydir=false;
  244.   for(int i=0;i<argv.length;i++)
  245.   {
  246.    if(argv[i].equals("-q")) { quiet=true;continue;}
  247.    if(argv[i].equals("-f")) { force=true;continue;}
  248.    if(argv[i].equals("-n")) { nosave=true;continue;}
  249.    if(argv[i].equals("-c")) { compress=true;continue;}
  250.    if(argv[i].equals("-r")) { rec=true;continue;}
  251.    if(argv[i].equals("-w")) { forcesave=true;continue;}
  252.    if(argv[i].equals("-m"))
  253.        if (i<argv.length-1) 
  254.        {
  255.            loadMimeTypes(argv[i+1]);i++;continue;
  256.        } else continue;
  257.    if(argv[i].equals("-x"))
  258.        if (i<argv.length-1) 
  259.        {
  260.               StringTokenizer st=new StringTokenizer(argv[i+1],File.pathSeparator,false);
  261.            while(st.hasMoreTokens())
  262.            {
  263.             String token;
  264.             token=st.nextToken();
  265.             if(token.equals("!")) { ignoretable=null;continue;}
  266.             ignoretable=mgr.addRegexpToArray(token,ignoretable);i++;continue;
  267.            }
  268.        } else continue;
  269.    if(argv[i].equals("-i"))
  270.        if (i<argv.length-1) 
  271.        {
  272.            cacheobject.defaultname=argv[i+1];continue;
  273.        } else continue; 
  274.    if(argv[i].startsWith("-"))
  275.      {
  276.        System.out.println("[ERROR] Unrecognized option: "+argv[i]);
  277.        return;
  278.      }
  279.    repairDir(argv[i],rec);
  280.    anydir=true;
  281.   }
  282.   if(anydir) System.out.println("[OK] Rebuild done.\n");
  283.    else
  284.     usage();
  285.  }
  286.  
  287.  public final static cachedir repairDir(String dirname,boolean recurse)
  288.  {
  289.    if(dirname==null) return null;
  290.    File f=new File(dirname);
  291.    if(!f.exists())
  292.     {
  293.      System.out.println("[ERROR] Directory "+dirname+" doesn't exists.");
  294.      return null;
  295.     }
  296.    
  297.    if(!f.isDirectory())
  298.     {
  299.      //System.out.println("[ERROR] "+dirname+" is not a directory, no action done. ");
  300.      int sep=dirname.lastIndexOf(File.separatorChar);
  301.     if(sep==-1) dirname=".";
  302.      else
  303.     dirname=dirname.substring(0,sep);
  304.     f=new File(dirname);
  305.     // return;
  306.     }
  307.   if(!dirname.endsWith(File.separator)) dirname+=File.separatorChar;
  308.     
  309.   cachedir cd;
  310.   if(force)
  311.    {
  312.     /* try to delete old .cacheinfo */
  313.     new File(dirname,cachedir.DIRINFO).delete();
  314.    }
  315.   cd=new cachedir(dirname);
  316.   boolean msg=false;
  317.   if(!cd.checkDir())
  318.     if(!quiet) 
  319.        {
  320.          System.out.println("[START] Rebuilding directory "+dirname);
  321.      msg=true;
  322.        }
  323.  
  324.   String dirfilez[];
  325.   String local[];
  326.   Vector filez=new Vector();
  327.   
  328.   dirfilez=f.list();
  329.   local=cd.listLocalNames();
  330.   if(dirfilez==null) return null;
  331.   /* konverze dirfilez na vector */
  332.   for(int i=dirfilez.length-1;i>=0;i--)
  333.    filez.addElement(dirfilez[i]);
  334.   dirfilez=null;
  335.  
  336.   /* smazat localnames z filez, abychom je nesmazali */
  337.   for(int i=local.length-1;i>=0;i--)
  338.    filez.removeElement(local[i]);
  339.    
  340.   filez.removeElement(cachedir.DIRINFO);
  341.   // cd=null;
  342.     
  343.   local=null;
  344.   /* projedeme filez a pridame nalezene soubory */
  345.   addorphan:for(int i=filez.size()-1;i>=0;i--)
  346.    {
  347.     File df=null;
  348.     String fn=null;
  349.     try{
  350.       fn=(String)filez.elementAt(i);
  351.     }
  352.     catch (ArrayIndexOutOfBoundsException z) {continue;}
  353.     df=new File(dirname+fn);
  354.     /* scan ignoretable */
  355.     for(int j=ignoretable.length-1;j>=0;j--) 
  356.        if(ignoretable[j].matches(fn)) continue addorphan;
  357.     if(!df.isDirectory())
  358.       {
  359.        if(msg==false && !quiet)
  360.        {
  361.          System.out.println("[START] Rebuilding directory "+dirname);
  362.      msg=true;
  363.        }
  364.        String ctype;
  365.        String enc;
  366.        enc=null;
  367.        if(df.toString().endsWith(".gz"))
  368.         {
  369.       ctype=guessContentType(df.toString().substring(0,df.toString().length()-3));
  370.       enc="gzip";
  371.     } else ctype=guessContentType(df.toString());
  372.        if(!quiet) System.out.println("[INFO] Adding orphan file: "+df+" ct="+ctype);
  373.        cacheobject co;
  374.        String nm;
  375.        nm=fn;
  376.        if(nm.equals(cacheobject.defaultname)) nm="";
  377.        co=new cacheobject(nm,cd,fn,
  378.        df.lastModified(),ctype,enc,(int)df.length());
  379.        cd.putObject(co);
  380.        // filez.removeElementAt(i);       
  381.        // i++;
  382.        continue;
  383.       } else
  384.          if(recurse==true)
  385.         repairDir(df.getPath(),true);
  386.    }
  387.   if(!nosave) 
  388.          {
  389.         if(cd.countObjects()==0) { cd.cleandir();return null;}
  390.           else
  391.             {
  392.           if(forcesave==true) cd.dirty=true;
  393.           if(compress) cd.compressdir();
  394.                   cd.save();
  395.         }
  396.          }
  397.   return cd;
  398.   // if(!quiet) System.out.println("[OK] Rebuild done.\n");
  399.  }
  400.  
  401.  public final static void loadMimeTypes(String fname)
  402.  {
  403.   if(fname==null) return;
  404.   File f=new File(fname);
  405.   if(!f.isFile()) return;
  406.   try
  407.   {
  408.     BufferedReader in=new BufferedReader(new LineNumberReader(new FileReader(fname)));
  409.     String line;
  410.     StringTokenizer st;
  411.     String mimetype,ext;
  412.     // init GT
  413.     guesstable=new String[0];
  414.     while(true)
  415.     {
  416.         ext=mimetype=null;
  417.         line=in.readLine();
  418.         if(line==null) break;
  419.         st=new StringTokenizer(line);
  420.         if(!st.hasMoreTokens()) continue;
  421.         mimetype=st.nextToken();
  422.         if(mimetype.startsWith("#")) continue;
  423.         while(true)
  424.         {
  425.             
  426.             if(!st.hasMoreTokens()) break;
  427.             ext=st.nextToken();
  428.         updateGuessTable(mimetype,ext);
  429.         }
  430.     }
  431.     in.close();
  432.   }
  433.   catch (IOException grrrrrrrrrrrrr)
  434.    {
  435.     System.err.println("[ERROR] Reading mime.types from "+fname);
  436.    }
  437.  
  438.  }
  439.  
  440.  public final static String guessContentType(String fname)
  441.  {
  442.   fname=fname.toLowerCase();
  443.   for(int i=0;i<guesstable.length;i+=2)
  444.    {
  445.     if(fname.endsWith(guesstable[i])) return guesstable[i+1];
  446.    }
  447.   System.out.println("[WARNING] Can not determine MIME type for "+fname+", defaulting to text/html");
  448.   return "text/html";
  449.  }
  450.  
  451.  /* prozdejsi prepise predchozi hodnotu */
  452.  private final static void updateGuessTable(String mimetype,String ext)
  453.  {
  454.       if(mimetype==null || ext==null) return;
  455.      if(mimetype.length()==0 || ext.length()==0) return;
  456.      ext=("."+ext).toLowerCase();
  457.      for(int i=0;i<guesstable.length;i+=2)
  458.      {
  459.          if(ext.equals(guesstable[i])) 
  460.            {
  461.              guesstable[i+1]=mimetype;
  462.              return;
  463.            }
  464.      }
  465.      String tmp[];
  466.      tmp=new String[guesstable.length+2];
  467.      System.arraycopy(guesstable,0,tmp,0,guesstable.length);
  468.      tmp[guesstable.length]=ext;
  469.      tmp[guesstable.length+1]=mimetype;
  470.      guesstable=tmp;
  471. }
  472. private static final void usage()
  473. {
  474.      System.out.println("Syntax: repair [-q] [-r] [-f] [-n] [-m mime.types] < Directory ... >");
  475.  
  476.  System.out.println("  -q            quiet mode");
  477.  System.out.println("  -r            recurse into directories");
  478.  System.out.println("  -w            write new .cacheinfo files even if not changed");
  479.  System.out.println("  -f            ignore existing .cacheinfo files");
  480.  System.out.println("  -c            gzip compress directory contents");
  481.  System.out.println("  -n            do not actually make changes");
  482.  System.out.println("  -i <filename> directory index filename (default .welcome)");
  483.  System.out.println("  -x <mask>["+File.pathSeparator+"mask] ... Ignore more files (default *.tmp, ! to reset)");
  484.  System.out.println("  -m <file>     use alternate table for determining mime type");
  485.      System.exit(1);
  486.      return;
  487. }
  488.