diff --git a/qubes-rpc/Makefile b/qubes-rpc/Makefile index 4f153b2..314e856 100644 --- a/qubes-rpc/Makefile +++ b/qubes-rpc/Makefile @@ -1,14 +1,16 @@ CC=gcc CFLAGS=-g -Wall -I. -fPIC -pie -all: vm-file-editor qopen-in-vm qfile-agent qfile-unpacker +all: vm-file-editor qopen-in-vm qfile-unpacker tar2qfile vm-file-editor: vm-file-editor.o ioall.o $(CC) -pie -g -o $@ $^ qopen-in-vm: qopen-in-vm.o ioall.o gui-fatal.o $(CC) -pie -g -o $@ $^ -qfile-agent: qfile-agent.o gui-fatal.o +qfile-agent: qfile-agent.o gui-fatal.o qfile-utils.o $(CC) -pie -g -o $@ $^ -lqubes-rpc-filecopy qfile-unpacker: qfile-unpacker.o gui-fatal.o $(CC) -pie -g -o $@ $^ -lqubes-rpc-filecopy +tar2qfile: qfile-utils.o tar2qfile.o gui-fatal.o + $(CC) -pie -g -o $@ $^ -lqubes-rpc-filecopy clean: - rm -f qopen-in-vm qfile-agent qfile-unpacker vm-file-editor *.o *~ + rm -f qopen-in-vm qfile-agent qfile-unpacker tar2qfile vm-file-editor *.o *~ diff --git a/qubes-rpc/qfile-agent.c b/qubes-rpc/qfile-agent.c index 22712c7..f4c3586 100644 --- a/qubes-rpc/qfile-agent.c +++ b/qubes-rpc/qfile-agent.c @@ -1,186 +1,15 @@ -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -enum { - PROGRESS_FLAG_NORMAL, - PROGRESS_FLAG_INIT, - PROGRESS_FLAG_DONE -}; +#include "qfile-utils.h" -int ignore_symlinks = 0; +ignore_symlinks = 0; -unsigned long crc32_sum; -int write_all_with_crc(int fd, void *buf, int size) +char *get_abs_path(char *cwd, char *pathname) { - crc32_sum = Crc32_ComputeBuf(crc32_sum, buf, size); - return write_all(fd, buf, size); -} - -void do_notify_progress(long long total, int flag) -{ - char *du_size_env = getenv("FILECOPY_TOTAL_SIZE"); - char *progress_type_env = getenv("PROGRESS_TYPE"); - char *saved_stdout_env = getenv("SAVED_FD_1"); - if (!progress_type_env) - return; - if (!strcmp(progress_type_env, "console") && du_size_env) { - char msg[256]; - snprintf(msg, sizeof(msg), "sent %lld/%lld KB\r", - total / 1024, strtoull(du_size_env, NULL, 0)); - write(2, msg, strlen(msg)); - if (flag == PROGRESS_FLAG_DONE) - write(2, "\n", 1); - } - if (!strcmp(progress_type_env, "gui") && saved_stdout_env) { - char msg[256]; - snprintf(msg, sizeof(msg), "%lld\n", total); - write(strtoul(saved_stdout_env, NULL, 0), msg, - strlen(msg)); - } -} - -void wait_for_result() -{ - struct result_header hdr; - struct result_header_ext hdr_ext; - char last_filename[MAX_PATH_LENGTH + 1]; - char last_filename_prefix[] = "; Last file: "; - - if (!read_all(0, &hdr, sizeof(hdr))) { - if (errno == EAGAIN) { - // no result sent and stdin still open - return; - } else { - // other read error or EOF - exit(1); // hopefully remote has produced error message - } - } - if (!read_all(0, &hdr_ext, sizeof(hdr_ext))) { - // remote used old result_header struct - hdr_ext.last_namelen = 0; - } - if (hdr_ext.last_namelen > MAX_PATH_LENGTH) { - // read only at most MAX_PATH_LENGTH chars - hdr_ext.last_namelen = MAX_PATH_LENGTH; - } - if (!read_all(0, last_filename, hdr_ext.last_namelen)) { - fprintf(stderr, "Failed to get last filename\n"); - hdr_ext.last_namelen = 0; - } - last_filename[hdr_ext.last_namelen] = '\0'; - if (!hdr_ext.last_namelen) - /* set prefix to empty string */ - last_filename_prefix[0] = '\0'; - - errno = hdr.error_code; - if (hdr.error_code != 0) { - switch (hdr.error_code) { - case EEXIST: - gui_fatal("File copy: not overwriting existing file. Clean QubesIncoming dir, and retry copy%s%s", last_filename_prefix, last_filename); - break; - case EINVAL: - gui_fatal("File copy: Corrupted data from packer%s%s", last_filename_prefix, last_filename); - break; - default: - gui_fatal("File copy: %s%s%s", - strerror(hdr.error_code), last_filename_prefix, last_filename); - } - } - if (hdr.crc32 != crc32_sum) { - gui_fatal("File transfer failed: checksum mismatch"); - } -} - -void notify_progress(int size, int flag) -{ - static long long total = 0; - static long long prev_total = 0; - total += size; - if (total > prev_total + PROGRESS_NOTIFY_DELTA - || (flag != PROGRESS_FLAG_NORMAL)) { - // check for possible error from qfile-unpacker; if error occured, - // exit() will be called, so don't bother with current state - // (notify_progress can be called as callback from copy_file()) - if (flag == PROGRESS_FLAG_NORMAL) - wait_for_result(); - do_notify_progress(total, flag); - prev_total = total; - } -} - -void write_headers(struct file_header *hdr, char *filename) -{ - if (!write_all_with_crc(1, hdr, sizeof(*hdr)) - || !write_all_with_crc(1, filename, hdr->namelen)) { - set_block(0); - wait_for_result(); - exit(1); - } -} - -int single_file_processor(char *filename, struct stat *st) -{ - struct file_header hdr; - int fd; - mode_t mode = st->st_mode; - - hdr.namelen = strlen(filename) + 1; - hdr.mode = mode; - hdr.atime = st->st_atim.tv_sec; - hdr.atime_nsec = st->st_atim.tv_nsec; - hdr.mtime = st->st_mtim.tv_sec; - hdr.mtime_nsec = st->st_mtim.tv_nsec; - - if (S_ISREG(mode)) { - int ret; - fd = open(filename, O_RDONLY); - if (fd < 0) - gui_fatal("open %s", filename); - hdr.filelen = st->st_size; - write_headers(&hdr, filename); - ret = copy_file(1, fd, hdr.filelen, &crc32_sum); - if (ret != COPY_FILE_OK) { - if (ret != COPY_FILE_WRITE_ERROR) - gui_fatal("Copying file %s: %s", filename, - copy_file_status_to_str(ret)); - else { - set_block(0); - wait_for_result(); - exit(1); - } - } - close(fd); - } - if (S_ISDIR(mode)) { - hdr.filelen = 0; - write_headers(&hdr, filename); - } - if (S_ISLNK(mode) && !ignore_symlinks) { - char name[st->st_size + 1]; - if (readlink(filename, name, sizeof(name)) != st->st_size) - gui_fatal("readlink %s", filename); - hdr.filelen = st->st_size + 1; - write_headers(&hdr, filename); - if (!write_all_with_crc(1, name, st->st_size + 1)) { - set_block(0); - wait_for_result(); - exit(1); - } - } - // check for possible error from qfile-unpacker - wait_for_result(); - return 0; + char *ret; + if (pathname[0] == '/') + return strdup(pathname); + asprintf(&ret, "%s/%s", cwd, pathname); + return ret; } int do_fs_walk(char *file) @@ -213,29 +42,6 @@ int do_fs_walk(char *file) return 0; } -void notify_end_and_wait_for_result() -{ - struct file_header end_hdr; - - /* nofity end of transfer */ - memset(&end_hdr, 0, sizeof(end_hdr)); - end_hdr.namelen = 0; - end_hdr.filelen = 0; - write_all_with_crc(1, &end_hdr, sizeof(end_hdr)); - - set_block(0); - wait_for_result(); -} - -char *get_abs_path(char *cwd, char *pathname) -{ - char *ret; - if (pathname[0] == '/') - return strdup(pathname); - asprintf(&ret, "%s/%s", cwd, pathname); - return ret; -} - int main(int argc, char **argv) { int i; @@ -275,3 +81,5 @@ int main(int argc, char **argv) notify_progress(0, PROGRESS_FLAG_DONE); return 0; } + + diff --git a/qubes-rpc/tar2qfile.c b/qubes-rpc/tar2qfile.c index cb2fb4b..1965223 100644 --- a/qubes-rpc/tar2qfile.c +++ b/qubes-rpc/tar2qfile.c @@ -47,8 +47,7 @@ #include #include #include -#include - +#include /*************************************************** @@ -157,7 +156,6 @@ typedef struct { } HD_USTAR; - /* * Routines for manipulating headers, trailers: * asc_ul() @@ -343,50 +341,8 @@ ustar_id (char *blk, size_t size) } - - /* * Routines for reading tar files - */ - - - -/* -struct file_header { - unsigned int namelen; - unsigned int mode; - unsigned long long filelen; - unsigned int atime; - unsigned int atime_nsec; - unsigned int mtime; - unsigned int mtime_nsec; -}; -*/ - - - -/* - - -0000cc00 76 6d 2d 74 65 6d 70 6c 61 74 65 73 2f 61 72 63 |vm-templates/arc| -0000cc10 68 6c 69 6e 75 78 2d 78 36 34 2d 73 70 65 63 2d |hlinux-x64-spec-| -0000cc20 32 30 31 33 2e 30 30 30 00 00 00 00 00 00 00 00 |2013.000........| -0000cc30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -* -0000cc60 00 00 00 00 30 30 30 30 36 36 34 00 30 30 30 31 |....0000664.0001| -0000cc70 37 35 30 00 30 30 30 31 37 35 31 00 30 37 35 30 |750.0001751.0750| -0000cc80 32 32 30 30 30 34 30 00 31 32 32 32 31 35 32 37 |2200040.12221527| -0000cc90 31 34 34 00 30 31 37 33 30 33 00 20 30 00 00 00 |144.017303. 0...| -0000cca0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -* -0000cd00 00 75 73 74 61 72 00 30 30 6f 6d 65 00 00 00 00 |.ustar.00ome....| -0000cd10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -0000cd20 00 00 00 00 00 00 00 00 00 6f 6d 65 00 00 00 00 |.........ome....| -0000cd30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -0000cd40 00 00 00 00 00 00 00 00 00 30 30 30 30 30 30 30 |.........0000000| -0000cd50 00 30 30 30 30 30 30 30 00 00 00 00 00 00 00 00 |.0000000........| -0000cd60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -* // Source: http://www.mkssoftware.com/docs/man4/pax.4.asp struct file_header { // PAX header is similar as file_header and can be completely ignored @@ -428,7 +384,6 @@ enum { */ - enum { NEED_NOTHING, NEED_SKIP, @@ -437,7 +392,6 @@ enum { }; - /* * ustar_rd() * extract the values out of block already determined to be a ustar header. @@ -721,7 +675,6 @@ int tar_file_processor(int fd) int sync_count = 0; while (size = read(fd, &buf, BLKMULT)) { fprintf(stderr,"Read %d bytes\n",size); - ret = 0; if (current==NEED_SYNC_TRAIL) { ret = tar_trail (buf, 1, &sync_count); @@ -765,6 +718,8 @@ int main(int argc, char **argv) //signal(SIGPIPE, SIG_IGN); // this will allow checking for possible feedback packet in the middle of transfer //set_nonblock(0); + notify_progress(0, PROGRESS_FLAG_INIT); + crc32_sum = 0; cwd = getcwd(NULL, 0); for (i = 1; i < argc; i++) { @@ -787,15 +742,13 @@ int main(int argc, char **argv) if (i <= 1) { // No argument specified. Use STDIN - fprintf(stderr,"Using STDIN"); + fprintf(stderr,"Using STDIN\n"); tar_file_processor(fileno(stdin)); } + notify_end_and_wait_for_result(); + notify_progress(0, PROGRESS_FLAG_DONE); return 0; } - - - -