aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorMarin Ivanov <[email protected]>2024-03-29 01:21:52 +0200
committerMarin Ivanov <[email protected]>2024-03-29 01:21:52 +0200
commit2865c2a71f4bba4a2214e07ca8a3af52d9ae245d (patch)
treee8b37f529b5a22cefe05008bac841bdbeddbc3f6 /main.go
parentff2fff5a72217aaaa8ceea20f4732bea97cc382e (diff)
update command line parameters
Diffstat (limited to 'main.go')
-rw-r--r--main.go58
1 files changed, 36 insertions, 22 deletions
diff --git a/main.go b/main.go
index 9389c65..fa391cc 100644
--- a/main.go
+++ b/main.go
@@ -18,9 +18,11 @@ import (
func main() {
var zipFilename string
- var output string
+ var extract string
+ var verbose int
flag.StringVarP(&zipFilename, "filename", "f", "", "filename")
- flag.StringVarP(&output, "output", "o", "./out/", "output directory")
+ flag.StringVarP(&extract, "extract", "e", "", "extraction output directory")
+ flag.CountVarP(&verbose, "verbose", "v", "-v verbose, -vv more verbose")
flag.Parse()
f, err := os.Open(zipFilename)
@@ -49,21 +51,29 @@ func main() {
log.Fatalf("failed to read file header at 0x%x: %s", pos, err)
}
hdr.Offset, _ = f.Seek(0, io.SeekCurrent)
- j, _ := json.MarshalIndent(hdr, "", " ")
- log.Printf("File at 0x%x: %s", hdr.Offset, string(j))
+ if verbose >= 2 {
+ j, _ := json.MarshalIndent(hdr, "", " ")
+ log.Printf("File at 0x%x: %s", hdr.Offset, string(j))
+ }
hasDD := false
if hdr.Flags&0x08 > 0 {
if hdr.CompressedSize == 0 {
- log.Printf("Searching for file's end...")
- if err = findAndUseDataDescriptor(&hdr, f); err != nil {
+ if verbose >= 2 {
+ log.Printf("Searching for file's end...")
+ }
+ if err = findAndUseDataDescriptor(&hdr, f, verbose); err != nil {
log.Fatalf("failed to udpate using data descriptor at 0x%x: %s", hdr.Offset, err)
}
}
hasDD = true
}
- err := extract(f, &hdr, output)
- if err != nil {
- log.Fatalf("failed to extract file: %s", err)
+ if extract != "" {
+ if verbose >= 1 {
+ log.Printf("Extracting '%s'...", hdr.Name)
+ }
+ if err := extractFile(f, &hdr, extract); err != nil {
+ log.Fatalf("failed to extract file: %s", err)
+ }
}
size := int64(hdr.CompressedSize)
if size == 0xFFFFFFFF {
@@ -82,7 +92,9 @@ func main() {
if signature != dataDescriptorSignature {
log.Fatalf("unexpected signature at 0x%x: got %08x", pos, signature)
}
- log.Printf("Skipping data descriptor at 0x%x, zip64=%t...", pos, hdr.zip64)
+ if verbose >= 2 {
+ log.Printf("Skipping data descriptor at 0x%x, zip64=%t...", pos, hdr.zip64)
+ }
if hdr.zip64 {
io.CopyN(io.Discard, f, 20)
} else {
@@ -95,16 +107,20 @@ func main() {
pos, _ := f.Seek(0, io.SeekCurrent)
log.Fatalf("failed to read directory header at 0x%x: %s", pos, err)
}
- j, _ := json.MarshalIndent(hdr, "", " ")
- log.Printf("Directory: %s", string(j))
+ if verbose >= 2 {
+ j, _ := json.MarshalIndent(hdr, "", " ")
+ log.Printf("Directory: %s", string(j))
+ }
case directoryEndSignature:
var hdr directoryEnd
if err := parseDirectoryEnd(&hdr, f); err != nil {
pos, _ := f.Seek(0, io.SeekCurrent)
log.Fatalf("failed to read directory end at 0x%x: %s", pos, err)
}
- j, _ := json.MarshalIndent(hdr, "", " ")
- log.Printf("Directory End: %s", string(j))
+ if verbose >= 2 {
+ j, _ := json.MarshalIndent(hdr, "", " ")
+ log.Printf("Directory End: %s", string(j))
+ }
default:
pos, _ := f.Seek(0, io.SeekCurrent)
log.Fatalf("invalid header signature at 0x%x: got %08x", pos, signature)
@@ -307,14 +323,12 @@ func parseDataDescriptor(f *File, r io.Reader) error {
f.DescriptorCompressedSize = b.uint32()
f.DescriptorUncompressedSize = b.uint32()
- log.Printf("compsize=%d, size=%d", f.DescriptorCompressedSize, f.DescriptorUncompressedSize)
-
return nil
}
var dataDescriptorSignatureBytes = []byte{'P', 'K', 0x07, 0x08}
-func findAndUseDataDescriptor(f *File, r io.ReadSeeker) error {
+func findAndUseDataDescriptor(f *File, r io.ReadSeeker, verbose int) error {
pos, err := r.Seek(0, io.SeekCurrent)
if err != nil {
return err
@@ -324,7 +338,9 @@ func findAndUseDataDescriptor(f *File, r io.ReadSeeker) error {
if err != nil {
return fmt.Errorf("failed to find descriptor maxed at 0x%x: %s", descriptorPos, err)
}
- log.Printf("found descriptor at offset 0x%x", descriptorPos)
+ if verbose >= 2 {
+ log.Printf("found descriptor at offset 0x%x", descriptorPos)
+ }
if pos, err = r.Seek(descriptorPos, io.SeekStart); err != nil {
return fmt.Errorf("failed to seek to descriptor at 0x%x: %s", pos, err)
}
@@ -333,14 +349,12 @@ func findAndUseDataDescriptor(f *File, r io.ReadSeeker) error {
}
if descriptorPos-int64(f.DescriptorCompressedSize) == f.Offset+4 {
break
- } else {
+ } else if verbose >= 2 {
log.Printf("invalid size: expected offset %x (hex) != %x (hex), compsize=%d, size=%d",
f.Offset+4, descriptorPos-int64(f.DescriptorCompressedSize), f.DescriptorCompressedSize, f.DescriptorUncompressedSize)
}
if pos, err = r.Seek(descriptorPos+4, io.SeekStart); err != nil {
return fmt.Errorf("failed to seek to descriptor at 0x%x: %s", pos, err)
- } else {
- // log.Printf("resetted to offset %d", pos)
}
}
@@ -364,7 +378,7 @@ func findAndUseDataDescriptor(f *File, r io.ReadSeeker) error {
return nil
}
-func extract(r io.ReadSeeker, f *File, outputDirectory string) error {
+func extractFile(r io.ReadSeeker, f *File, outputDirectory string) error {
dir, base := path.Split(path.Clean(f.Name))
directory := path.Join(outputDirectory, dir)
err := os.MkdirAll(directory, 0o755)