6
6
"debug/macho"
7
7
"debug/pe"
8
8
"errors"
9
+ "flag"
9
10
"fmt"
10
11
"io"
11
12
"os"
@@ -21,9 +22,33 @@ const (
21
22
opUnTar
22
23
)
23
24
25
+ var (
26
+ help = flag .Bool ("help" , false , "Display help" )
27
+ untarFlag = flag .Bool ("untar" , true , "Untar tar files if specified at creation" )
28
+ forceUntar = flag .Bool ("force-untar" , false , "Always untar file" )
29
+ quiet = flag .Bool ("q" , false , "Don't write any output to terminal, except errors" )
30
+ )
31
+
24
32
func main () {
33
+ flag .Parse ()
25
34
me , err := os .Executable ()
26
35
exitErr (err )
36
+ args := flag .Args ()
37
+ invalidArgs := len (args ) > 1
38
+ if * help || invalidArgs {
39
+ _ , _ = fmt .Fprintf (os .Stderr , "s2sx Self Extracting Archive\n \n " )
40
+ _ , _ = fmt .Fprintf (os .Stderr , "Usage: %s [options] [output-file/dir]\n \n " , os .Args [0 ])
41
+ _ , _ = fmt .Fprintf (os .Stderr , "Use - as file name to extract to stdout when not untarring.\n \n " )
42
+ _ , _ = fmt .Fprintln (os .Stderr , `Options:` )
43
+ flag .PrintDefaults ()
44
+ if invalidArgs {
45
+ os .Exit (1 )
46
+ }
47
+ os .Exit (0 )
48
+ }
49
+ stdout := len (args ) > 0 && args [0 ] == "-"
50
+ * quiet = * quiet || stdout
51
+
27
52
f , err := os .Open (me )
28
53
exitErr (err )
29
54
defer f .Close ()
@@ -35,16 +60,35 @@ func main() {
35
60
_ , err = io .ReadFull (rd , tmp [:])
36
61
exitErr (err )
37
62
dec := s2 .NewReader (rd )
63
+ if ! * untarFlag {
64
+ tmp [0 ] = opUnpack
65
+ }
66
+ if * forceUntar {
67
+ tmp [0 ] = opUnTar
68
+ }
38
69
switch tmp [0 ] {
39
70
case opUnpack :
40
71
outname := me + "-extracted"
41
72
if idx := strings .Index (me , ".s2sfx" ); idx > 0 {
42
73
// Trim from '.s2sfx'
43
74
outname = me [:idx ]
44
75
}
45
- fmt .Printf ("Extracting to %q..." , outname )
46
- out , err := os .Create (outname )
47
- exitErr (err )
76
+ var out io.Writer
77
+ if stdout {
78
+ out = os .Stdout
79
+ } else {
80
+ if len (args ) > 0 {
81
+ outname , err = filepath .Abs (args [0 ])
82
+ exitErr (err )
83
+ }
84
+ if ! * quiet {
85
+ fmt .Printf ("Extracting to \" %s\" ..." , outname )
86
+ }
87
+ f , err := os .Create (outname )
88
+ exitErr (err )
89
+ defer f .Close ()
90
+ out = f
91
+ }
48
92
_ , err = io .Copy (out , dec )
49
93
exitErr (err )
50
94
@@ -53,12 +97,26 @@ func main() {
53
97
if err != nil {
54
98
dir = filepath .Dir (me )
55
99
}
56
- fmt .Printf ("Extracting TAR file to %s...\n " , dir )
100
+ if len (args ) > 0 {
101
+ if args [0 ] == "-" {
102
+ exitErr (errors .New ("cannot untar files to stdout. Use -untar=false to skip untar operation" ))
103
+ }
104
+ if filepath .IsAbs (args [0 ]) {
105
+ dir = args [0 ]
106
+ } else {
107
+ dir = filepath .Join (dir , args [0 ])
108
+ }
109
+ }
110
+ if ! * quiet {
111
+ fmt .Printf ("Extracting TAR file to %s...\n " , dir )
112
+ }
57
113
exitErr (untar (dir , dec ))
58
114
default :
59
115
exitErr (fmt .Errorf ("unknown operation: %d" , tmp [0 ]))
60
116
}
61
- fmt .Println ("\n Done." )
117
+ if ! * quiet {
118
+ fmt .Println ("\n Done." )
119
+ }
62
120
}
63
121
64
122
func exitErr (err error ) {
@@ -191,7 +249,9 @@ func untar(dst string, r io.Reader) error {
191
249
192
250
// if its a dir and it doesn't exist create it
193
251
case tar .TypeDir :
194
- fmt .Println (target )
252
+ if ! * quiet {
253
+ fmt .Println (target )
254
+ }
195
255
if _ , err := os .Stat (target ); err != nil {
196
256
if err := os .MkdirAll (target , 0755 ); err != nil {
197
257
return err
@@ -201,7 +261,9 @@ func untar(dst string, r io.Reader) error {
201
261
// if it's a file create it
202
262
case tar .TypeReg , tar .TypeChar , tar .TypeBlock , tar .TypeFifo , tar .TypeGNUSparse :
203
263
target = path .Clean (target )
204
- fmt .Println (target )
264
+ if ! * quiet {
265
+ fmt .Println (target )
266
+ }
205
267
206
268
f , err := os .OpenFile (target , os .O_CREATE | os .O_RDWR , os .FileMode (header .Mode ))
207
269
if err != nil {
@@ -224,15 +286,19 @@ func untar(dst string, r io.Reader) error {
224
286
f .Close ()
225
287
case tar .TypeSymlink :
226
288
target = path .Clean (target )
227
- fmt .Println (target )
289
+ if ! * quiet {
290
+ fmt .Println (target )
291
+ }
228
292
229
293
err := writeNewSymbolicLink (target , header .Linkname )
230
294
if err != nil {
231
295
return err
232
296
}
233
297
case tar .TypeLink :
234
298
target = path .Clean (target )
235
- fmt .Println (target )
299
+ if ! * quiet {
300
+ fmt .Println (target )
301
+ }
236
302
237
303
err := writeNewHardLink (target , filepath .Join (dst , header .Linkname ))
238
304
if err != nil {
0 commit comments