Run through indent, fix comments
[oweals/busybox.git] / archival / libunarchive / unarchive.c
index ff9b5876fd714de419dab7046ea2e185493c1ec3..03e3c3ec2934abb8eadb065679a7bf5519fd51d2 100644 (file)
 #include <string.h>
 #include <unistd.h>
 #include <utime.h>
+#include <sys/wait.h>
+#include <signal.h>
 #include "unarchive.h"
-#include "libbb.h"
+#include "busybox.h"
 
 /* Extract the data postioned at src_stream to either filesystem, stdout or 
  * buffer depending on the value of 'function' which is defined in libbb.h 
@@ -56,9 +58,7 @@ char *extract_archive(FILE *src_stream, FILE *out_stream, const file_header_t *f
                                return(NULL);
                        }
                }
-               full_name = xmalloc(strlen(prefix) + strlen(path) + 1);
-               strcpy(full_name, prefix);
-               strcat(full_name, path);
+               bb_asprintf(&full_name, "%s%s", prefix, path);
        } else {
                full_name = file_entry->name;
        }
@@ -120,7 +120,8 @@ char *extract_archive(FILE *src_stream, FILE *out_stream, const file_header_t *f
                                                return NULL;
                                        }
                                        archive_offset += file_entry->size;
-                                       copy_file_chunk(src_stream, dst_stream, file_entry->size);                      
+                                       if (file_entry->extract_func) file_entry->extract_func(src_stream, dst_stream);
+                                       else copy_file_chunk(src_stream, dst_stream, file_entry->size);                 
                                        fclose(dst_stream);
                                }
                                break;
@@ -189,7 +190,9 @@ char *extract_archive(FILE *src_stream, FILE *out_stream, const file_header_t *f
                fprintf(out_stream, "%s\n", full_name);
        }
 
-       free(full_name);
+       if (prefix != NULL) {
+         free(full_name);
+       }
 
        return(NULL); /* Maybe we should say if failed */
 }
@@ -201,7 +204,22 @@ char *unarchive(FILE *src_stream, FILE *out_stream, file_header_t *(*get_headers
        int extract_flag = TRUE;
        int i;
        char *buffer = NULL;
+#ifdef CONFIG_FEATURE_UNARCHIVE_TAPE
+       int pid, tape_pipe[2];
 
+       if (pipe(tape_pipe) != 0) error_msg_and_die("Can't create pipe\n");
+       if ((pid = fork()) == -1) error_msg_and_die("Fork failed\n");
+       if (pid==0) { /* child process */
+           close(tape_pipe[0]); /* We don't wan't to read from the pipe */
+           copyfd(fileno(src_stream), tape_pipe[1]);
+           close(tape_pipe[1]); /* Send EOF */
+           exit(0);
+           /* notreached */
+       }
+       close(tape_pipe[1]); /* Don't want to write down the pipe */
+       fclose(src_stream);
+       src_stream = fdopen(tape_pipe[0], "r");
+#endif
        archive_offset = 0;
        while ((file_entry = get_headers(src_stream)) != NULL) {
 
@@ -237,5 +255,9 @@ char *unarchive(FILE *src_stream, FILE *out_stream, file_header_t *(*get_headers
                free(file_entry->link_name);
                free(file_entry);
        }
+#ifdef CONFIG_FEATURE_UNARCHIVE_TAPE
+       kill(pid, SIGTERM);
+       waitpid(pid, NULL, 0);
+#endif
        return(buffer);
 }