diff options
Diffstat (limited to 'cmd/zip2zip/zip2zip.go')
-rw-r--r-- | cmd/zip2zip/zip2zip.go | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/cmd/zip2zip/zip2zip.go b/cmd/zip2zip/zip2zip.go new file mode 100644 index 000000000..8e7523ffc --- /dev/null +++ b/cmd/zip2zip/zip2zip.go @@ -0,0 +1,128 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "flag" + "fmt" + "os" + "path/filepath" + "strings" + + "android/soong/third_party/zip" +) + +var ( + input = flag.String("i", "", "zip file to read from") + output = flag.String("o", "", "output file") +) + +func usage() { + fmt.Fprintln(os.Stderr, "usage: zip2zip -i zipfile -o zipfile [filespec]...") + flag.PrintDefaults() + fmt.Fprintln(os.Stderr, " filespec:") + fmt.Fprintln(os.Stderr, " <name>") + fmt.Fprintln(os.Stderr, " <in_name>:<out_name>") + fmt.Fprintln(os.Stderr, " <glob>:<out_dir>/") + fmt.Fprintln(os.Stderr, "") + fmt.Fprintln(os.Stderr, "Files will be copied with their existing compression from the input zipfile to") + fmt.Fprintln(os.Stderr, "the output zipfile, in the order of filespec arguments") + os.Exit(2) +} + +func main() { + flag.Parse() + + if flag.NArg() == 0 || *input == "" || *output == "" { + usage() + } + + reader, err := zip.OpenReader(*input) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(3) + } + defer reader.Close() + + output, err := os.Create(*output) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(4) + } + defer output.Close() + + writer := zip.NewWriter(output) + defer func() { + err := writer.Close() + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(5) + } + }() + + for _, arg := range flag.Args() { + var input string + var output string + + // Reserve escaping for future implementation, so make sure no + // one is using \ and expecting a certain behavior. + if strings.Contains(arg, "\\") { + fmt.Fprintln(os.Stderr, "\\ characters are not currently supported") + os.Exit(6) + } + + args := strings.SplitN(arg, ":", 2) + input = args[0] + if len(args) == 2 { + output = args[1] + } + + if strings.IndexAny(input, "*?[") >= 0 { + for _, file := range reader.File { + if match, err := filepath.Match(input, file.Name); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(7) + } else if match { + var newFileName string + if output == "" { + newFileName = file.Name + } else { + _, name := filepath.Split(file.Name) + newFileName = filepath.Join(output, name) + } + err = writer.CopyFrom(file, newFileName) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(8) + } + } + } + } else { + if output == "" { + output = input + } + for _, file := range reader.File { + if input == file.Name { + err = writer.CopyFrom(file, output) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(8) + } + break + } + } + } + } +} |