+void
+clean_tape_list(
+ EXTRACT_LIST *tape_list)
+{
+ EXTRACT_LIST_ITEM *fn1, *pfn1, *ofn1;
+ EXTRACT_LIST_ITEM *fn2, *pfn2, *ofn2;
+ int remove_fn1;
+ int remove_fn2;
+
+ pfn1 = NULL;
+ fn1 = tape_list->files;
+ while (fn1 != NULL) {
+ remove_fn1 = 0;
+
+ pfn2 = fn1;
+ fn2 = fn1->next;
+ while (fn2 != NULL && remove_fn1 == 0) {
+ remove_fn2 = 0;
+ if(strcmp(fn1->path, fn2->path) == 0) {
+ remove_fn2 = 1;
+ } else if (strncmp(fn1->path, fn2->path, strlen(fn1->path)) == 0 &&
+ ((strlen(fn2->path) > strlen(fn1->path) &&
+ fn2->path[strlen(fn1->path)] == '/') ||
+ (fn1->path[strlen(fn1->path)-1] == '/'))) {
+ remove_fn2 = 1;
+ } else if (strncmp(fn2->path, fn1->path, strlen(fn2->path)) == 0 &&
+ ((strlen(fn1->path) > strlen(fn2->path) &&
+ fn1->path[strlen(fn2->path)] == '/') ||
+ (fn2->path[strlen(fn2->path)-1] == '/'))) {
+ remove_fn1 = 1;
+ break;
+ }
+
+ if (remove_fn2) {
+ dbprintf(("removing path %s, it is included in %s\n",
+ fn2->path, fn1->path));
+ ofn2 = fn2;
+ fn2 = fn2->next;
+ amfree(ofn2->path);
+ amfree(ofn2);
+ pfn2->next = fn2;
+ } else if (remove_fn1 == 0) {
+ pfn2 = fn2;
+ fn2 = fn2->next;
+ }
+ }
+
+ if(remove_fn1 != 0) {
+ /* fn2->path is always valid */
+ /*@i@*/ dbprintf(("removing path %s, it is included in %s\n",
+ /*@i@*/ fn1->path, fn2->path));
+ ofn1 = fn1;
+ fn1 = fn1->next;
+ amfree(ofn1->path);
+ if(pfn1 == NULL) {
+ amfree(tape_list->files);
+ tape_list->files = fn1;
+ } else {
+ amfree(pfn1->next);
+ pfn1->next = fn1;
+ }
+ } else {
+ pfn1 = fn1;
+ fn1 = fn1->next;
+ }
+ }
+}
+
+
+void
+clean_extract_list(void)
+{
+ EXTRACT_LIST *this;
+
+ for (this = extract_list; this != NULL; this = this->next)
+ clean_tape_list(this);
+}
+
+
+int add_to_unlink_list(char *path);
+int do_unlink_list(void);
+void free_unlink_list(void);
+
+typedef struct s_unlink_list {
+ char *path;
+ struct s_unlink_list *next;
+} t_unlink_list;
+t_unlink_list *unlink_list = NULL;
+
+int
+add_to_unlink_list(
+ char *path)
+{
+ t_unlink_list *ul;
+
+ if (!unlink_list) {
+ unlink_list = alloc(SIZEOF(*unlink_list));
+ unlink_list->path = stralloc(path);
+ unlink_list->next = NULL;
+ } else {
+ for (ul = unlink_list; ul != NULL; ul = ul->next) {
+ if (strcmp(ul->path, path) == 0)
+ return 0;
+ }
+ ul = alloc(SIZEOF(*ul));
+ ul->path = stralloc(path);
+ ul->next = unlink_list;
+ unlink_list = ul;
+ }
+ return 1;
+}
+
+int
+do_unlink_list(void)
+{
+ t_unlink_list *ul;
+ int ret = 1;
+
+ for (ul = unlink_list; ul != NULL; ul = ul->next) {
+ if (unlink(ul->path) < 0) {
+ fprintf(stderr,"Can't unlink %s: %s\n", ul->path, strerror(errno));
+ ret = 0;
+ }
+ }
+ return ret;
+}
+
+
+void
+free_unlink_list(void)
+{
+ t_unlink_list *ul, *ul1;
+
+ for (ul = unlink_list; ul != NULL; ul = ul1) {
+ amfree(ul->path);
+ ul1 = ul->next;
+ amfree(ul);
+ }
+
+ unlink_list = NULL;
+}
+
+
+
+void
+check_file_overwrite(
+ char *dir)
+{
+ EXTRACT_LIST *this;
+ EXTRACT_LIST_ITEM *fn;
+ struct stat stat_buf;
+ char *filename;
+ char *path, *s;
+
+ for (this = extract_list; this != NULL; this = this->next) {
+ for (fn = this->files; fn != NULL ; fn = fn->next) {
+
+ /* Check path component of fn->path */
+
+ path = stralloc2(dir, fn->path);
+ if (path[strlen(path)-1] == '/') {
+ path[strlen(path)-1] = '\0';
+ }
+
+ s = path + strlen(dir) + 1;
+ while((s = strchr(s, '/'))) {
+ *s = '\0';
+ if (lstat(path, &stat_buf) == 0) {
+ if(!S_ISDIR(stat_buf.st_mode)) {
+ if (add_to_unlink_list(path)) {
+ printf("WARNING: %s is not a directory, "
+ "it will be deleted.\n",
+ path);
+ }
+ }
+ }
+ else if (errno != ENOENT) {
+ printf("Can't stat %s: %s\n", path, strerror(errno));
+ }
+ *s = '/';
+ s++;
+ }
+ amfree(path);
+
+ /* Check fn->path */
+
+ filename = stralloc2(dir, fn->path);
+ if (filename[strlen(filename)-1] == '/') {
+ filename[strlen(filename)-1] = '\0';
+ }
+
+ if (lstat(filename, &stat_buf) == 0) {
+ if(S_ISDIR(stat_buf.st_mode)) {
+ if(!is_empty_dir(filename)) {
+ printf("WARNING: All existing files in %s "
+ "will be deleted.\n", filename);
+ }
+ } else if(S_ISREG(stat_buf.st_mode)) {
+ printf("WARNING: Existing file %s will be overwritten\n",
+ filename);
+ } else {
+ if (add_to_unlink_list(filename)) {
+ printf("WARNING: Existing entry %s will be deleted\n",
+ filename);
+ }
+ }
+ } else if (errno != ENOENT) {
+ printf("Can't stat %s: %s\n", filename, strerror(errno));
+ }
+ amfree(filename);
+ }
+ }
+}
+
+