Track backup and restore progress based on the sizes of the files as they are being added to the tar backup file. Update the progress bar based on the sizes of the files. Change-Id: Idf649efa1db3e91830b4b2add86203a3f30042ff
214 lines
4.6 KiB
C
214 lines
4.6 KiB
C
/*
|
|
** Copyright 1998-2003 University of Illinois Board of Trustees
|
|
** Copyright 1998-2003 Mark D. Roth
|
|
** All rights reserved.
|
|
**
|
|
** wrapper.c - libtar high-level wrapper code
|
|
**
|
|
** Mark D. Roth <roth@uiuc.edu>
|
|
** Campus Information Technologies and Educational Services
|
|
** University of Illinois at Urbana-Champaign
|
|
*/
|
|
|
|
#define DEBUG
|
|
#include <internal.h>
|
|
|
|
#include <stdio.h>
|
|
#include <sys/param.h>
|
|
#include <dirent.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#ifdef STDC_HEADERS
|
|
# include <string.h>
|
|
#endif
|
|
|
|
int
|
|
tar_extract_glob(TAR *t, char *globname, char *prefix)
|
|
{
|
|
char *filename;
|
|
char buf[MAXPATHLEN];
|
|
int i, fd = 0;
|
|
|
|
while ((i = th_read(t)) == 0)
|
|
{
|
|
filename = th_get_pathname(t);
|
|
if (fnmatch(globname, filename, FNM_PATHNAME | FNM_PERIOD))
|
|
{
|
|
if (TH_ISREG(t) && tar_skip_regfile(t))
|
|
return -1;
|
|
continue;
|
|
}
|
|
if (t->options & TAR_VERBOSE)
|
|
th_print_long_ls(t);
|
|
if (prefix != NULL)
|
|
snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
|
|
else
|
|
strlcpy(buf, filename, sizeof(buf));
|
|
if (tar_extract_file(t, filename, prefix, &fd) != 0)
|
|
return -1;
|
|
}
|
|
|
|
return (i == 1 ? 0 : -1);
|
|
}
|
|
|
|
|
|
int
|
|
tar_extract_all(TAR *t, char *prefix, const int *progress_fd)
|
|
{
|
|
char *filename;
|
|
char buf[MAXPATHLEN];
|
|
int i;
|
|
printf("prefix: %s\n", prefix);
|
|
#ifdef DEBUG
|
|
printf("==> tar_extract_all(TAR *t, \"%s\")\n",
|
|
(prefix ? prefix : "(null)"));
|
|
#endif
|
|
while ((i = th_read(t)) == 0)
|
|
{
|
|
#ifdef DEBUG
|
|
puts(" tar_extract_all(): calling th_get_pathname()");
|
|
#endif
|
|
filename = th_get_pathname(t);
|
|
if (t->options & TAR_VERBOSE)
|
|
th_print_long_ls(t);
|
|
if (prefix != NULL)
|
|
snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
|
|
else
|
|
strlcpy(buf, filename, sizeof(buf));
|
|
#ifdef DEBUG
|
|
printf(" tar_extract_all(): calling tar_extract_file(t, "
|
|
"\"%s\")\n", buf);
|
|
#endif
|
|
printf("item name: '%s'\n", filename);
|
|
if (tar_extract_file(t, buf, prefix, progress_fd) != 0)
|
|
return -1;
|
|
}
|
|
return (i == 1 ? 0 : -1);
|
|
}
|
|
|
|
|
|
int
|
|
tar_append_tree(TAR *t, char *realdir, char *savedir, char *exclude)
|
|
{
|
|
#ifdef DEBUG
|
|
printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n",
|
|
(long unsigned int)t, realdir, (savedir ? savedir : "[NULL]"));
|
|
#endif
|
|
|
|
char temp[1024];
|
|
int skip = 0, i, n_spaces = 0;
|
|
char ** excluded = NULL;
|
|
char * p = NULL;
|
|
if (exclude) {
|
|
strcpy(temp, exclude);
|
|
p = strtok(exclude, " ");
|
|
if (p == NULL) {
|
|
excluded = realloc(excluded, sizeof(char*) * (++n_spaces));
|
|
excluded[0] = temp;
|
|
} else {
|
|
while (p) {
|
|
excluded = realloc(excluded, sizeof(char*) * (++n_spaces));
|
|
excluded[n_spaces-1] = p;
|
|
p = strtok(NULL, " ");
|
|
}
|
|
}
|
|
excluded = realloc(excluded, sizeof(char*) * (n_spaces+1));
|
|
excluded[n_spaces] = 0;
|
|
for (i = 0; i < (n_spaces+1); i++) {
|
|
if (realdir == excluded[i]) {
|
|
printf(" excluding '%s'\n", excluded[i]);
|
|
skip = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (skip == 0) {
|
|
if (tar_append_file(t, realdir, savedir) != 0)
|
|
return -1;
|
|
}
|
|
|
|
char realpath[MAXPATHLEN];
|
|
char savepath[MAXPATHLEN];
|
|
struct dirent *dent;
|
|
DIR *dp;
|
|
struct stat s;
|
|
|
|
dp = opendir(realdir);
|
|
if (dp == NULL) {
|
|
if (errno == ENOTDIR)
|
|
return 0;
|
|
return -1;
|
|
}
|
|
while ((dent = readdir(dp)) != NULL) {
|
|
if(strcmp(dent->d_name, ".") == 0
|
|
|| strcmp(dent->d_name, "..") == 0)
|
|
continue;
|
|
|
|
if (exclude) {
|
|
int omit = 0;
|
|
for (i = 0; i < (n_spaces+1); i++) {
|
|
if (excluded[i] != NULL) {
|
|
if (strcmp(dent->d_name, excluded[i]) == 0 || strcmp(excluded[i], realdir) == 0) {
|
|
printf(" excluding '%s'\n", excluded[i]);
|
|
omit = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (omit)
|
|
continue;
|
|
}
|
|
|
|
snprintf(realpath, MAXPATHLEN, "%s/%s", realdir, dent->d_name);
|
|
if (savedir)
|
|
snprintf(savepath, MAXPATHLEN, "%s/%s", savedir, dent->d_name);
|
|
|
|
if (lstat(realpath, &s) != 0)
|
|
return -1;
|
|
|
|
if (S_ISDIR(s.st_mode)) {
|
|
if (tar_append_tree(t, realpath, (savedir ? savepath : NULL), (exclude ? exclude : NULL)) != 0)
|
|
return -1;
|
|
continue;
|
|
} else {
|
|
if (tar_append_file(t, realpath, (savedir ? savepath : NULL)) != 0)
|
|
return -1;
|
|
continue;
|
|
}
|
|
}
|
|
closedir(dp);
|
|
free(excluded);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int
|
|
tar_find(TAR *t, char *searchstr)
|
|
{
|
|
if (!searchstr)
|
|
return 0;
|
|
|
|
char *filename;
|
|
int i, entryfound = 0;
|
|
#ifdef DEBUG
|
|
printf("==> tar_find(0x%lx, %s)\n", (long unsigned int)t, searchstr);
|
|
#endif
|
|
while ((i = th_read(t)) == 0) {
|
|
filename = th_get_pathname(t);
|
|
if (fnmatch(searchstr, filename, FNM_FILE_NAME | FNM_PERIOD) == 0) {
|
|
entryfound++;
|
|
#ifdef DEBUG
|
|
printf("Found matching entry: %s\n", filename);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
#ifdef DEBUG
|
|
if (!entryfound)
|
|
printf("No matching entry found.\n");
|
|
#endif
|
|
|
|
return entryfound;
|
|
}
|