home *** CD-ROM | disk | FTP | other *** search
Java Source | 1997-12-11 | 4.2 KB | 178 lines |
-
- /*
- * Unpack -- a completely non-object oriented utility...
- *
- */
-
- import java.io.*;
-
- class Unpack {
- static final int IDPAKHEADER = (('K'<<24)+('C'<<16)+('A'<<8)+'P');
-
- static int intSwap(int i) {
- int a, b, c, d;
-
- a = i & 255;
- b = (i >> 8) & 255;
- c = (i >> 16) & 255;
- d = (i >> 24) & 255;
-
- return (a << 24) + (b << 16) + (c << 8) + d;
- }
-
- static boolean patternMatch (String pattern, String s) {
- int index;
- int remaining;
-
- if (pattern.equals(s)) {
- return true;
- }
-
- // fairly lame single wildcard matching
- index = pattern.indexOf('*');
- if (index == -1) {
- return false;
- }
- if (!pattern.regionMatches(0, s, 0, index)) {
- return false;
- }
-
- index += 1; // skip the *
- remaining = pattern.length() - index;
- if (s.length() < remaining) {
- return false;
- }
-
- if (!pattern.regionMatches(index, s, s.length()-remaining, remaining)) {
- return false;
- }
-
- return true;
- }
-
- static void usage() {
- System.out.println ("Usage: unpack <packfile> <match> <basedir>");
- System.out.println (" or: unpack -list <packfile>");
- System.out.println ("<match> may contain a single * wildcard");
- System.exit (1);
- }
-
- public static void main (String[] args) {
- int ident;
- int dirofs;
- int dirlen;
- int i;
- int numLumps;
- byte[] name = new byte[56];
- String nameString;
- int filepos;
- int filelen;
- RandomAccessFile readLump;
- DataInputStream directory;
- String pakName;
- String pattern;
-
- if (args.length == 2) {
- if (!args[0].equals("-list")) {
- usage();
- }
- pakName = args[1];
- pattern = null;
- } else if (args.length == 3) {
- pakName = args[0];
- pattern = args[1];
- } else {
- pakName = null;
- pattern = null;
- usage ();
- }
-
- try {
- // one stream to read the directory
- directory = new DataInputStream(new FileInputStream(pakName));
-
- // another to read lumps
- readLump = new RandomAccessFile(pakName, "r");
-
- // read the header
- ident = intSwap(directory.readInt());
- dirofs = intSwap(directory.readInt());
- dirlen = intSwap(directory.readInt());
-
- if (ident != IDPAKHEADER) {
- System.out.println ( pakName + " is not a pakfile.");
- System.exit (1);
- }
-
- // read the directory
- directory.skipBytes (dirofs - 12);
- numLumps = dirlen / 64;
-
- System.out.println (numLumps + " lumps in " + pakName);
-
- for (i = 0 ; i < numLumps ; i++) {
- directory.readFully(name);
- filepos = intSwap(directory.readInt());
- filelen = intSwap(directory.readInt());
-
- nameString = new String (name, 0);
- // chop to the first 0 byte
- nameString = nameString.substring (0, nameString.indexOf(0));
-
- if (pattern == null) {
- // listing mode
- System.out.println (nameString + " : " + filelen + "bytes");
- } else if (patternMatch (pattern, nameString) ) {
- File writeFile;
- DataOutputStream writeLump;
- byte[] buffer = new byte[filelen];
- StringBuffer fixedString;
- String finalName;
- int index;
-
- System.out.println ("Unpaking " + nameString + " " + filelen
- + " bytes");
-
- // load the lump
- readLump.seek(filepos);
- readLump.readFully(buffer);
-
- // quake uses forward slashes, but java requires
- // they only by the host's seperator, which
- // varies from win to unix
- fixedString = new StringBuffer (args[2] + File.separator + nameString);
- for (index = 0 ; index < fixedString.length() ; index++) {
- if (fixedString.charAt(index) == '/') {
- fixedString.setCharAt(index, File.separatorChar);
- }
- }
- finalName = fixedString.toString ();
-
- index = finalName.lastIndexOf(File.separatorChar);
- if (index != -1) {
- String finalPath;
- File writePath;
-
- finalPath = finalName.substring(0, index);
- writePath = new File (finalPath);
- writePath.mkdirs();
- }
-
- writeFile = new File (finalName);
- writeLump = new DataOutputStream ( new FileOutputStream(writeFile) );
- writeLump.write(buffer);
- writeLump.close();
-
- }
- }
-
- readLump.close();
- directory.close();
-
- } catch (IOException e) {
- System.out.println ( e.toString() );
- }
- }
-
- }
-