1 // Copyright 2020 Google LLC
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 // https://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
15 // This file contains the main function from the original minitar example:
16 // https://github.com/libarchive/libarchive/blob/master/examples/minitar/minitar.c
17 // Most of the logic is the same, it was only simplified a bit since this is
18 // only used for the command line tool.
19 // No sandboxing takes place in this function.
20
21 #include <iostream>
22
23 #include "sapi_minitar.h" // NOLINT(build/include)
24
PrintUsage()25 static void PrintUsage() {
26 /* Many program options depend on compile options. */
27 const char* m =
28 "Usage: minitar [-"
29 "c"
30 "j"
31 "tvx"
32 "y"
33 "Z"
34 "z"
35 "] [-f file] [file]\n";
36
37 std::cout << m << std::endl;
38 exit(EXIT_FAILURE);
39 }
40
main(int unused_argc,char * argv[])41 int main(int unused_argc, char* argv[]) {
42 sapi::InitLogging(argv[0]);
43 const char* filename = nullptr;
44 int compress;
45 int flags;
46 int mode;
47 int opt;
48
49 mode = 'x';
50 int verbose = 0;
51 compress = '\0';
52 flags = ARCHIVE_EXTRACT_TIME;
53
54 while (*++argv != nullptr && **argv == '-') {
55 const char* p = *argv + 1;
56
57 while ((opt = *p++) != '\0') {
58 switch (opt) {
59 case 'c':
60 mode = opt;
61 break;
62 case 'f':
63 if (*p != '\0')
64 filename = p;
65 else
66 filename = *++argv;
67 p += strlen(p);
68 break;
69 case 'j':
70 compress = opt;
71 break;
72 case 'p':
73 flags |= ARCHIVE_EXTRACT_PERM;
74 flags |= ARCHIVE_EXTRACT_ACL;
75 flags |= ARCHIVE_EXTRACT_FFLAGS;
76 break;
77 case 't':
78 mode = opt;
79 break;
80 case 'v':
81 verbose++;
82 break;
83 case 'x':
84 mode = opt;
85 break;
86 case 'y':
87 compress = opt;
88 break;
89 case 'Z':
90 compress = opt;
91 break;
92 case 'z':
93 compress = opt;
94 break;
95 default:
96 PrintUsage();
97 }
98 }
99 }
100
101 absl::Status status;
102 switch (mode) {
103 case 'c':
104 status = CreateArchive(filename, compress,
105 sandbox2::util::CharArrPtr(argv).ToStringVector(),
106 verbose);
107 if (!status.ok()) {
108 LOG(ERROR) << "Archive creation failed with message: "
109 << status.message();
110 return EXIT_FAILURE;
111 }
112 break;
113 case 't':
114 status = ExtractArchive(filename, 0, flags, verbose);
115 if (!status.ok()) {
116 LOG(ERROR) << "Archive extraction failed with message: "
117 << status.message();
118 return EXIT_FAILURE;
119 }
120 break;
121 case 'x':
122 status = ExtractArchive(filename, 1, flags, verbose);
123 if (!status.ok()) {
124 LOG(ERROR) << "Archive extraction failed with message: "
125 << status.message();
126 return EXIT_FAILURE;
127 }
128 break;
129 }
130
131 return EXIT_SUCCESS;
132 }
133