blob: dab7e007635ce9bc7703f2d77addbbb657cfb15d [file] [log] [blame]
bigbiff bigbiff9c754052013-01-09 09:09:08 -05001/*
2** Copyright 1998-2003 University of Illinois Board of Trustees
3** Copyright 1998-2003 Mark D. Roth
4** All rights reserved.
5**
6** wrapper.c - libtar high-level wrapper code
7**
8** Mark D. Roth <roth@uiuc.edu>
9** Campus Information Technologies and Educational Services
10** University of Illinois at Urbana-Champaign
11*/
12
13#define DEBUG
14#include <internal.h>
15
16#include <stdio.h>
17#include <sys/param.h>
18#include <dirent.h>
19#include <errno.h>
Dees_Troy83bd4832013-05-04 12:39:56 +000020#include <stdlib.h>
bigbiff bigbiff9c754052013-01-09 09:09:08 -050021#ifdef STDC_HEADERS
22# include <string.h>
23#endif
24
25int
26tar_extract_glob(TAR *t, char *globname, char *prefix)
27{
28 char *filename;
29 char buf[MAXPATHLEN];
30 int i;
31
32 while ((i = th_read(t)) == 0)
33 {
34 filename = th_get_pathname(t);
35 if (fnmatch(globname, filename, FNM_PATHNAME | FNM_PERIOD))
36 {
37 if (TH_ISREG(t) && tar_skip_regfile(t))
38 return -1;
39 continue;
40 }
41 if (t->options & TAR_VERBOSE)
42 th_print_long_ls(t);
43 if (prefix != NULL)
44 snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
45 else
46 strlcpy(buf, filename, sizeof(buf));
Dees_Troyee6632c2013-02-27 18:07:32 +000047 if (tar_extract_file(t, filename, prefix) != 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -050048 return -1;
49 }
50
51 return (i == 1 ? 0 : -1);
52}
53
54
55int
56tar_extract_all(TAR *t, char *prefix)
57{
58 char *filename;
59 char buf[MAXPATHLEN];
60 int i;
61 printf("prefix: %s\n", prefix);
62#ifdef DEBUG
63 printf("==> tar_extract_all(TAR *t, \"%s\")\n",
64 (prefix ? prefix : "(null)"));
65#endif
66 while ((i = th_read(t)) == 0)
67 {
68#ifdef DEBUG
69 puts(" tar_extract_all(): calling th_get_pathname()");
70#endif
71 filename = th_get_pathname(t);
72 if (t->options & TAR_VERBOSE)
73 th_print_long_ls(t);
74 if (prefix != NULL)
75 snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
76 else
77 strlcpy(buf, filename, sizeof(buf));
78#ifdef DEBUG
79 printf(" tar_extract_all(): calling tar_extract_file(t, "
80 "\"%s\")\n", buf);
81#endif
Dees_Troy71796592013-03-14 20:16:29 +000082 printf("item name: '%s'\n", filename);
bigbiff bigbiff9c754052013-01-09 09:09:08 -050083 /*
84 if (strcmp(filename, "/") == 0) {
85 printf("skipping /\n");
86 continue;
87 }
88 */
Dees_Troyee6632c2013-02-27 18:07:32 +000089 if (tar_extract_file(t, buf, prefix) != 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -050090 return -1;
91 }
92 return (i == 1 ? 0 : -1);
93}
94
95
96int
Dees_Troy83bd4832013-05-04 12:39:56 +000097tar_append_tree(TAR *t, char *realdir, char *savedir, char *exclude)
bigbiff bigbiff9c754052013-01-09 09:09:08 -050098{
Dees_Troy83bd4832013-05-04 12:39:56 +000099#ifdef DEBUG
100 printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n",
101 (long unsigned int)t, realdir, (savedir ? savedir : "[NULL]"));
102#endif
103
104 char temp[1024];
105 int skip = 0, i, n_spaces = 0;
106 char ** excluded = NULL;
107 char * p = NULL;
108 if (exclude) {
109 strcpy(temp, exclude);
110 p = strtok(exclude, " ");
111 if (p == NULL) {
112 excluded = realloc(excluded, sizeof(char*) * (++n_spaces));
113 excluded[0] = temp;
114 } else {
115 while (p) {
116 excluded = realloc(excluded, sizeof(char*) * (++n_spaces));
117 excluded[n_spaces-1] = p;
118 p = strtok(NULL, " ");
119 }
120 }
121 excluded = realloc(excluded, sizeof(char*) * (n_spaces+1));
122 excluded[n_spaces] = 0;
123 for (i = 0; i < (n_spaces+1); i++) {
124 if (realdir == excluded[i]) {
125 printf(" excluding '%s'\n", excluded[i]);
126 skip = 1;
127 break;
128 }
129 }
130 }
131 if (skip == 0) {
132 if (tar_append_file(t, realdir, savedir) != 0)
133 return -1;
134 }
135
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500136 char realpath[MAXPATHLEN];
137 char savepath[MAXPATHLEN];
138 struct dirent *dent;
139 DIR *dp;
140 struct stat s;
141
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500142 dp = opendir(realdir);
Dees_Troy83bd4832013-05-04 12:39:56 +0000143 if (dp == NULL) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500144 if (errno == ENOTDIR)
145 return 0;
146 return -1;
147 }
Dees_Troy83bd4832013-05-04 12:39:56 +0000148 while ((dent = readdir(dp)) != NULL) {
149 if(strcmp(dent->d_name, ".") == 0
150 || strcmp(dent->d_name, "..") == 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500151 continue;
152
Dees_Troy83bd4832013-05-04 12:39:56 +0000153 if (exclude) {
154 int omit = 0;
155 for (i = 0; i < (n_spaces+1); i++) {
bigbiff bigbiff86e77bc2013-08-26 21:36:23 -0400156 if (excluded[i] != NULL) {
157 if (strcmp(dent->d_name, excluded[i]) == 0 || strcmp(excluded[i], realdir) == 0) {
158 printf(" excluding '%s'\n", excluded[i]);
159 omit = 1;
160 break;
161 }
Dees_Troy83bd4832013-05-04 12:39:56 +0000162 }
163 }
164 if (omit)
165 continue;
166 }
167
168 snprintf(realpath, MAXPATHLEN, "%s/%s", realdir, dent->d_name);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500169 if (savedir)
Dees_Troy83bd4832013-05-04 12:39:56 +0000170 snprintf(savepath, MAXPATHLEN, "%s/%s", savedir, dent->d_name);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500171
172 if (lstat(realpath, &s) != 0)
173 return -1;
174
Dees_Troy83bd4832013-05-04 12:39:56 +0000175 if (S_ISDIR(s.st_mode)) {
176 if (tar_append_tree(t, realpath, (savedir ? savepath : NULL), (exclude ? exclude : NULL)) != 0)
177 return -1;
178 continue;
179 } else {
180 if (tar_append_file(t, realpath, (savedir ? savepath : NULL)) != 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500181 return -1;
182 continue;
183 }
bigbiff bigbiff86e77bc2013-08-26 21:36:23 -0400184 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500185 closedir(dp);
Dees_Troy83bd4832013-05-04 12:39:56 +0000186 free(excluded);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500187
188 return 0;
189}
n0d33b511632013-03-06 21:14:15 +0200190
191
192int
193tar_find(TAR *t, char *searchstr)
194{
195 if (!searchstr)
196 return 0;
197
198 char *filename;
199 int i, entryfound = 0;
200#ifdef DEBUG
201 printf("==> tar_find(0x%lx, %s)\n", (long unsigned int)t, searchstr);
202#endif
203 while ((i = th_read(t)) == 0) {
204 filename = th_get_pathname(t);
205 if (fnmatch(searchstr, filename, FNM_FILE_NAME | FNM_PERIOD) == 0) {
206 entryfound++;
207#ifdef DEBUG
208 printf("Found matching entry: %s\n", filename);
209#endif
210 break;
211 }
212 }
213#ifdef DEBUG
214 if (!entryfound)
215 printf("No matching entry found.\n");
216#endif
217
218 return entryfound;
219}