blob: 82f045f7d32a53973cd6ac691cd419c36334d097 [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];
Ethan Yonker1b7a31b2014-07-03 15:09:22 -050030 int i, fd = 0;
bigbiff bigbiff9c754052013-01-09 09:09:08 -050031
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));
Ethan Yonker1b7a31b2014-07-03 15:09:22 -050047 if (tar_extract_file(t, filename, prefix, &fd) != 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -050048 return -1;
49 }
50
51 return (i == 1 ? 0 : -1);
52}
53
54
55int
Ethan Yonker1b7a31b2014-07-03 15:09:22 -050056tar_extract_all(TAR *t, char *prefix, const int *progress_fd)
bigbiff bigbiff9c754052013-01-09 09:09:08 -050057{
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);
Ethan Yonker1b7a31b2014-07-03 15:09:22 -050083 if (tar_extract_file(t, buf, prefix, progress_fd) != 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -050084 return -1;
85 }
86 return (i == 1 ? 0 : -1);
87}
88
89
90int
Dees_Troy83bd4832013-05-04 12:39:56 +000091tar_append_tree(TAR *t, char *realdir, char *savedir, char *exclude)
bigbiff bigbiff9c754052013-01-09 09:09:08 -050092{
Dees_Troy83bd4832013-05-04 12:39:56 +000093#ifdef DEBUG
94 printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n",
95 (long unsigned int)t, realdir, (savedir ? savedir : "[NULL]"));
96#endif
97
98 char temp[1024];
99 int skip = 0, i, n_spaces = 0;
100 char ** excluded = NULL;
101 char * p = NULL;
102 if (exclude) {
103 strcpy(temp, exclude);
104 p = strtok(exclude, " ");
105 if (p == NULL) {
106 excluded = realloc(excluded, sizeof(char*) * (++n_spaces));
107 excluded[0] = temp;
108 } else {
109 while (p) {
110 excluded = realloc(excluded, sizeof(char*) * (++n_spaces));
111 excluded[n_spaces-1] = p;
112 p = strtok(NULL, " ");
113 }
114 }
115 excluded = realloc(excluded, sizeof(char*) * (n_spaces+1));
116 excluded[n_spaces] = 0;
117 for (i = 0; i < (n_spaces+1); i++) {
118 if (realdir == excluded[i]) {
119 printf(" excluding '%s'\n", excluded[i]);
120 skip = 1;
121 break;
122 }
123 }
124 }
125 if (skip == 0) {
126 if (tar_append_file(t, realdir, savedir) != 0)
127 return -1;
128 }
129
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500130 char realpath[MAXPATHLEN];
131 char savepath[MAXPATHLEN];
132 struct dirent *dent;
133 DIR *dp;
134 struct stat s;
135
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500136 dp = opendir(realdir);
Dees_Troy83bd4832013-05-04 12:39:56 +0000137 if (dp == NULL) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500138 if (errno == ENOTDIR)
139 return 0;
140 return -1;
141 }
Dees_Troy83bd4832013-05-04 12:39:56 +0000142 while ((dent = readdir(dp)) != NULL) {
143 if(strcmp(dent->d_name, ".") == 0
144 || strcmp(dent->d_name, "..") == 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500145 continue;
146
Dees_Troy83bd4832013-05-04 12:39:56 +0000147 if (exclude) {
148 int omit = 0;
149 for (i = 0; i < (n_spaces+1); i++) {
bigbiff bigbiff86e77bc2013-08-26 21:36:23 -0400150 if (excluded[i] != NULL) {
151 if (strcmp(dent->d_name, excluded[i]) == 0 || strcmp(excluded[i], realdir) == 0) {
152 printf(" excluding '%s'\n", excluded[i]);
153 omit = 1;
154 break;
155 }
Dees_Troy83bd4832013-05-04 12:39:56 +0000156 }
157 }
158 if (omit)
159 continue;
160 }
161
162 snprintf(realpath, MAXPATHLEN, "%s/%s", realdir, dent->d_name);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500163 if (savedir)
Dees_Troy83bd4832013-05-04 12:39:56 +0000164 snprintf(savepath, MAXPATHLEN, "%s/%s", savedir, dent->d_name);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500165
166 if (lstat(realpath, &s) != 0)
167 return -1;
168
Dees_Troy83bd4832013-05-04 12:39:56 +0000169 if (S_ISDIR(s.st_mode)) {
170 if (tar_append_tree(t, realpath, (savedir ? savepath : NULL), (exclude ? exclude : NULL)) != 0)
171 return -1;
172 continue;
173 } else {
174 if (tar_append_file(t, realpath, (savedir ? savepath : NULL)) != 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500175 return -1;
176 continue;
177 }
bigbiff bigbiff86e77bc2013-08-26 21:36:23 -0400178 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500179 closedir(dp);
Dees_Troy83bd4832013-05-04 12:39:56 +0000180 free(excluded);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500181
182 return 0;
183}
n0d33b511632013-03-06 21:14:15 +0200184
185
186int
187tar_find(TAR *t, char *searchstr)
188{
189 if (!searchstr)
190 return 0;
191
192 char *filename;
193 int i, entryfound = 0;
194#ifdef DEBUG
195 printf("==> tar_find(0x%lx, %s)\n", (long unsigned int)t, searchstr);
196#endif
197 while ((i = th_read(t)) == 0) {
198 filename = th_get_pathname(t);
199 if (fnmatch(searchstr, filename, FNM_FILE_NAME | FNM_PERIOD) == 0) {
200 entryfound++;
201#ifdef DEBUG
202 printf("Found matching entry: %s\n", filename);
203#endif
204 break;
205 }
206 }
207#ifdef DEBUG
208 if (!entryfound)
209 printf("No matching entry found.\n");
210#endif
211
212 return entryfound;
213}