blob: 8e7523ffc45a381f228b1a875a1e252a4c01a3ed [file] [log] [blame]
Dan Willemsen3bf1a082016-08-03 00:35:25 -07001// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package main
16
17import (
18 "flag"
19 "fmt"
20 "os"
21 "path/filepath"
22 "strings"
23
24 "android/soong/third_party/zip"
25)
26
27var (
28 input = flag.String("i", "", "zip file to read from")
29 output = flag.String("o", "", "output file")
30)
31
32func usage() {
33 fmt.Fprintln(os.Stderr, "usage: zip2zip -i zipfile -o zipfile [filespec]...")
34 flag.PrintDefaults()
35 fmt.Fprintln(os.Stderr, " filespec:")
36 fmt.Fprintln(os.Stderr, " <name>")
37 fmt.Fprintln(os.Stderr, " <in_name>:<out_name>")
38 fmt.Fprintln(os.Stderr, " <glob>:<out_dir>/")
39 fmt.Fprintln(os.Stderr, "")
40 fmt.Fprintln(os.Stderr, "Files will be copied with their existing compression from the input zipfile to")
41 fmt.Fprintln(os.Stderr, "the output zipfile, in the order of filespec arguments")
42 os.Exit(2)
43}
44
45func main() {
46 flag.Parse()
47
48 if flag.NArg() == 0 || *input == "" || *output == "" {
49 usage()
50 }
51
52 reader, err := zip.OpenReader(*input)
53 if err != nil {
54 fmt.Fprintln(os.Stderr, err)
55 os.Exit(3)
56 }
57 defer reader.Close()
58
59 output, err := os.Create(*output)
60 if err != nil {
61 fmt.Fprintln(os.Stderr, err)
62 os.Exit(4)
63 }
64 defer output.Close()
65
66 writer := zip.NewWriter(output)
67 defer func() {
68 err := writer.Close()
69 if err != nil {
70 fmt.Fprintln(os.Stderr, err)
71 os.Exit(5)
72 }
73 }()
74
75 for _, arg := range flag.Args() {
76 var input string
77 var output string
78
79 // Reserve escaping for future implementation, so make sure no
80 // one is using \ and expecting a certain behavior.
81 if strings.Contains(arg, "\\") {
82 fmt.Fprintln(os.Stderr, "\\ characters are not currently supported")
83 os.Exit(6)
84 }
85
86 args := strings.SplitN(arg, ":", 2)
87 input = args[0]
88 if len(args) == 2 {
89 output = args[1]
90 }
91
92 if strings.IndexAny(input, "*?[") >= 0 {
93 for _, file := range reader.File {
94 if match, err := filepath.Match(input, file.Name); err != nil {
95 fmt.Fprintln(os.Stderr, err)
96 os.Exit(7)
97 } else if match {
98 var newFileName string
99 if output == "" {
100 newFileName = file.Name
101 } else {
102 _, name := filepath.Split(file.Name)
103 newFileName = filepath.Join(output, name)
104 }
105 err = writer.CopyFrom(file, newFileName)
106 if err != nil {
107 fmt.Fprintln(os.Stderr, err)
108 os.Exit(8)
109 }
110 }
111 }
112 } else {
113 if output == "" {
114 output = input
115 }
116 for _, file := range reader.File {
117 if input == file.Name {
118 err = writer.CopyFrom(file, output)
119 if err != nil {
120 fmt.Fprintln(os.Stderr, err)
121 os.Exit(8)
122 }
123 break
124 }
125 }
126 }
127 }
128}