diff --git a/qubes-rpc/gui-fatal.c b/qubes-rpc/gui-fatal.c index 5900ce5..d50db09 100644 --- a/qubes-rpc/gui-fatal.c +++ b/qubes-rpc/gui-fatal.c @@ -10,58 +10,58 @@ static void fix_display(void) { - setenv("DISPLAY", ":0", 1); + setenv("DISPLAY", ":0", 1); } static void produce_message(const char * type, const char *fmt, va_list args) { - char *dialog_msg; - char buf[1024]; - (void) vsnprintf(buf, sizeof(buf), fmt, args); - if (asprintf(&dialog_msg, "%s: %s: %s (error type: %s)", - program_invocation_short_name, type, buf, strerror(errno)) < 0) { - fprintf(stderr, "Failed to allocate memory for error message :(\n"); - return; - } - fprintf(stderr, "%s\n", dialog_msg); - switch (fork()) { - case -1: - exit(1); //what else - case 0: - if (geteuid() == 0) - if (setuid(getuid()) != 0) - perror("setuid failed, calling kdialog/zenity as root"); - fix_display(); + char *dialog_msg; + char buf[1024]; + (void) vsnprintf(buf, sizeof(buf), fmt, args); + if (asprintf(&dialog_msg, "%s: %s: %s (error type: %s)", + program_invocation_short_name, type, buf, strerror(errno)) < 0) { + fprintf(stderr, "Failed to allocate memory for error message :(\n"); + return; + } + fprintf(stderr, "%s\n", dialog_msg); + switch (fork()) { + case -1: + exit(1); //what else + case 0: + if (geteuid() == 0) + if (setuid(getuid()) != 0) + perror("setuid failed, calling kdialog/zenity as root"); + fix_display(); #ifdef USE_KDIALOG - execlp("/usr/bin/kdialog", "kdialog", "--sorry", dialog_msg, NULL); + execlp("/usr/bin/kdialog", "kdialog", "--sorry", dialog_msg, NULL); #else - execlp("/usr/bin/zenity", "zenity", "--error", "--text", dialog_msg, NULL); + execlp("/usr/bin/zenity", "zenity", "--error", "--text", dialog_msg, NULL); #endif - exit(1); - default:; - } - free(dialog_msg); + exit(1); + default:; + } + free(dialog_msg); } void gui_fatal(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - produce_message("Fatal error", fmt, args); - va_end(args); - exit(1); + va_list args; + va_start(args, fmt); + produce_message("Fatal error", fmt, args); + va_end(args); + exit(1); } void qfile_gui_fatal(const char *fmt, va_list args) { - produce_message("Fatal error", fmt, args); + produce_message("Fatal error", fmt, args); exit(1); } void gui_nonfatal(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - produce_message("Information", fmt, args); - va_end(args); + va_list args; + va_start(args, fmt); + produce_message("Information", fmt, args); + va_end(args); } diff --git a/qubes-rpc/qfile-agent.c b/qubes-rpc/qfile-agent.c index de65788..42a1dfd 100644 --- a/qubes-rpc/qfile-agent.c +++ b/qubes-rpc/qfile-agent.c @@ -13,107 +13,107 @@ #include enum { - PROGRESS_FLAG_NORMAL, - PROGRESS_FLAG_INIT, - PROGRESS_FLAG_DONE + PROGRESS_FLAG_NORMAL, + PROGRESS_FLAG_INIT, + PROGRESS_FLAG_DONE }; void do_notify_progress(long long total, int flag) { - const char *du_size_env = getenv("FILECOPY_TOTAL_SIZE"); - const char *progress_type_env = getenv("PROGRESS_TYPE"); - const char *saved_stdout_env = getenv("SAVED_FD_1"); - int ignore; - 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)); - ignore = write(2, msg, strlen(msg)); - if (flag == PROGRESS_FLAG_DONE) - ignore = write(2, "\n", 1); - } - if (!strcmp(progress_type_env, "gui") && saved_stdout_env) { - char msg[256]; - snprintf(msg, sizeof(msg), "%lld\n", total); - ignore = write(strtoul(saved_stdout_env, NULL, 0), msg, - strlen(msg)); - } - if (ignore < 0) { - /* silence gcc warning */ - } + const char *du_size_env = getenv("FILECOPY_TOTAL_SIZE"); + const char *progress_type_env = getenv("PROGRESS_TYPE"); + const char *saved_stdout_env = getenv("SAVED_FD_1"); + int ignore; + 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)); + ignore = write(2, msg, strlen(msg)); + if (flag == PROGRESS_FLAG_DONE) + ignore = write(2, "\n", 1); + } + if (!strcmp(progress_type_env, "gui") && saved_stdout_env) { + char msg[256]; + snprintf(msg, sizeof(msg), "%lld\n", total); + ignore = write(strtoul(saved_stdout_env, NULL, 0), msg, + strlen(msg)); + } + if (ignore < 0) { + /* silence gcc warning */ + } } 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; - } + 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; + } } char *get_abs_path(const char *cwd, const char *pathname) { - char *ret; - if (pathname[0] == '/') - return strdup(pathname); - if (asprintf(&ret, "%s/%s", cwd, pathname) < 0) - return NULL; - else - return ret; + char *ret; + if (pathname[0] == '/') + return strdup(pathname); + if (asprintf(&ret, "%s/%s", cwd, pathname) < 0) + return NULL; + else + return ret; } int main(int argc, char **argv) { - int i; - char *entry; - char *cwd; - char *sep; - int ignore_symlinks = 0; + int i; + char *entry; + char *cwd; + char *sep; + int ignore_symlinks = 0; - qfile_pack_init(); - register_error_handler(qfile_gui_fatal); - register_notify_progress(¬ify_progress); - notify_progress(0, PROGRESS_FLAG_INIT); - cwd = getcwd(NULL, 0); - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "--ignore-symlinks")==0) { - ignore_symlinks = 1; - continue; - } + qfile_pack_init(); + register_error_handler(qfile_gui_fatal); + register_notify_progress(¬ify_progress); + notify_progress(0, PROGRESS_FLAG_INIT); + cwd = getcwd(NULL, 0); + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--ignore-symlinks")==0) { + ignore_symlinks = 1; + continue; + } - entry = get_abs_path(cwd, argv[i]); + entry = get_abs_path(cwd, argv[i]); - do { - sep = rindex(entry, '/'); - if (!sep) - gui_fatal - ("Internal error: nonabsolute filenames not allowed"); - *sep = 0; - } while (sep[1] == 0); - if (entry[0] == 0) { - if (chdir("/") < 0) { - gui_fatal("Internal error: chdir(\"/\") failed?!"); - } - } else if (chdir(entry)) - gui_fatal("chdir to %s", entry); - do_fs_walk(sep + 1, ignore_symlinks); - free(entry); - } - notify_end_and_wait_for_result(); - notify_progress(0, PROGRESS_FLAG_DONE); - return 0; + do { + sep = rindex(entry, '/'); + if (!sep) + gui_fatal + ("Internal error: nonabsolute filenames not allowed"); + *sep = 0; + } while (sep[1] == 0); + if (entry[0] == 0) { + if (chdir("/") < 0) { + gui_fatal("Internal error: chdir(\"/\") failed?!"); + } + } else if (chdir(entry)) + gui_fatal("chdir to %s", entry); + do_fs_walk(sep + 1, ignore_symlinks); + free(entry); + } + notify_end_and_wait_for_result(); + notify_progress(0, PROGRESS_FLAG_DONE); + return 0; } diff --git a/qubes-rpc/qfile-unpacker.c b/qubes-rpc/qfile-unpacker.c index 86a9527..817277a 100644 --- a/qubes-rpc/qfile-unpacker.c +++ b/qubes-rpc/qfile-unpacker.c @@ -17,81 +17,81 @@ #define INCOMING_DIR_ROOT "/home/user/QubesIncoming" int prepare_creds_return_uid(const char *username) { - const struct passwd *pwd; - pwd = getpwnam(username); - if (!pwd) { - perror("getpwnam"); - exit(1); - } - setenv("HOME", pwd->pw_dir, 1); - setenv("USER", username, 1); - if (setgid(pwd->pw_gid) < 0) - gui_fatal("Error setting group permissions"); - if (initgroups(username, pwd->pw_gid) < 0) - gui_fatal("Error initializing groups"); - if (setfsuid(pwd->pw_uid) < 0) - gui_fatal("Error setting filesystem level permissions"); - return pwd->pw_uid; + const struct passwd *pwd; + pwd = getpwnam(username); + if (!pwd) { + perror("getpwnam"); + exit(1); + } + setenv("HOME", pwd->pw_dir, 1); + setenv("USER", username, 1); + if (setgid(pwd->pw_gid) < 0) + gui_fatal("Error setting group permissions"); + if (initgroups(username, pwd->pw_gid) < 0) + gui_fatal("Error initializing groups"); + if (setfsuid(pwd->pw_uid) < 0) + gui_fatal("Error setting filesystem level permissions"); + return pwd->pw_uid; } int main(int argc __attribute((__unused__)), char ** argv __attribute__((__unused__))) { - char *incoming_dir; - int uid, ret; - pid_t pid; - const char *remote_domain; - char *procdir_path; - int procfs_fd; + char *incoming_dir; + int uid, ret; + pid_t pid; + const char *remote_domain; + char *procdir_path; + int procfs_fd; - uid = prepare_creds_return_uid("user"); + uid = prepare_creds_return_uid("user"); - remote_domain = getenv("QREXEC_REMOTE_DOMAIN"); - if (!remote_domain) { - gui_fatal("Cannot get remote domain name"); - exit(1); - } - mkdir(INCOMING_DIR_ROOT, 0700); - if (asprintf(&incoming_dir, "%s/%s", INCOMING_DIR_ROOT, remote_domain) < 0) - gui_fatal("Error allocating memory"); - mkdir(incoming_dir, 0700); - if (chdir(incoming_dir)) - gui_fatal("Error chdir to %s", incoming_dir); + remote_domain = getenv("QREXEC_REMOTE_DOMAIN"); + if (!remote_domain) { + gui_fatal("Cannot get remote domain name"); + exit(1); + } + mkdir(INCOMING_DIR_ROOT, 0700); + if (asprintf(&incoming_dir, "%s/%s", INCOMING_DIR_ROOT, remote_domain) < 0) + gui_fatal("Error allocating memory"); + mkdir(incoming_dir, 0700); + if (chdir(incoming_dir)) + gui_fatal("Error chdir to %s", incoming_dir); - if (mount(".", ".", NULL, MS_BIND | MS_NODEV | MS_NOEXEC | MS_NOSUID, NULL) < 0) - gui_fatal("Failed to mount a directory %s", incoming_dir); + if (mount(".", ".", NULL, MS_BIND | MS_NODEV | MS_NOEXEC | MS_NOSUID, NULL) < 0) + gui_fatal("Failed to mount a directory %s", incoming_dir); - /* parse the input in unprivileged child process, parent will hold root - * access to unmount incoming dir */ - switch (pid=fork()) { - case -1: - gui_fatal("Failed to create new process"); - case 0: - if (asprintf(&procdir_path, "/proc/%d/fd", getpid()) < 0) { - gui_fatal("Error allocating memory"); - } - procfs_fd = open(procdir_path, O_DIRECTORY | O_RDONLY); - if (procfs_fd < 0) - perror("Failed to open /proc"); - else - set_procfs_fd(procfs_fd); - free(procdir_path); + /* parse the input in unprivileged child process, parent will hold root + * access to unmount incoming dir */ + switch (pid=fork()) { + case -1: + gui_fatal("Failed to create new process"); + case 0: + if (asprintf(&procdir_path, "/proc/%d/fd", getpid()) < 0) { + gui_fatal("Error allocating memory"); + } + procfs_fd = open(procdir_path, O_DIRECTORY | O_RDONLY); + if (procfs_fd < 0) + perror("Failed to open /proc"); + else + set_procfs_fd(procfs_fd); + free(procdir_path); - if (chroot(".")) - gui_fatal("Error chroot to %s", incoming_dir); - if (setuid(uid) < 0) { - /* no kdialog inside chroot */ - perror("setuid"); - exit(1); - } - return do_unpack(); - } - if (waitpid(pid, &ret, 0) < 0) { - gui_fatal("Failed to wait for child process"); - } - if (umount2(".", MNT_DETACH) < 0) - gui_fatal("Cannot umount incoming directory"); - if (!WIFEXITED(ret)) { - gui_fatal("Child process exited abnormally"); - } - return WEXITSTATUS(ret); + if (chroot(".")) + gui_fatal("Error chroot to %s", incoming_dir); + if (setuid(uid) < 0) { + /* no kdialog inside chroot */ + perror("setuid"); + exit(1); + } + return do_unpack(); + } + if (waitpid(pid, &ret, 0) < 0) { + gui_fatal("Failed to wait for child process"); + } + if (umount2(".", MNT_DETACH) < 0) + gui_fatal("Cannot umount incoming directory"); + if (!WIFEXITED(ret)) { + gui_fatal("Child process exited abnormally"); + } + return WEXITSTATUS(ret); } diff --git a/qubes-rpc/qopen-in-vm.c b/qubes-rpc/qopen-in-vm.c index 43cf854..45949df 100644 --- a/qubes-rpc/qopen-in-vm.c +++ b/qubes-rpc/qopen-in-vm.c @@ -14,95 +14,95 @@ void send_file(const char *fname) { - const char *base; - char sendbuf[DVM_FILENAME_SIZE]; - int fd = open(fname, O_RDONLY); - if (fd < 0) - gui_fatal("open %s", fname); - base = rindex(fname, '/'); - if (!base) - base = fname; - else - base++; - if (strlen(base) >= DVM_FILENAME_SIZE) - base += strlen(base) - DVM_FILENAME_SIZE + 1; + const char *base; + char sendbuf[DVM_FILENAME_SIZE]; + int fd = open(fname, O_RDONLY); + if (fd < 0) + gui_fatal("open %s", fname); + base = rindex(fname, '/'); + if (!base) + base = fname; + else + base++; + if (strlen(base) >= DVM_FILENAME_SIZE) + base += strlen(base) - DVM_FILENAME_SIZE + 1; strncpy(sendbuf,base,DVM_FILENAME_SIZE - 1); /* fills out with NULs */ sendbuf[DVM_FILENAME_SIZE - 1] = '\0'; - if (!write_all(1, sendbuf, DVM_FILENAME_SIZE)) - gui_fatal("send filename to dispVM"); - if (!copy_fd_all(1, fd)) - gui_fatal("send file to dispVM"); - close(1); - close(fd); + if (!write_all(1, sendbuf, DVM_FILENAME_SIZE)) + gui_fatal("send filename to dispVM"); + if (!copy_fd_all(1, fd)) + gui_fatal("send file to dispVM"); + close(1); + close(fd); } int copy_and_return_nonemptiness(int tmpfd) { - struct stat st; - if (!copy_fd_all(tmpfd, 0)) - gui_fatal("receiving file from dispVM"); - if (fstat(tmpfd, &st)) - gui_fatal("fstat"); - close(tmpfd); + struct stat st; + if (!copy_fd_all(tmpfd, 0)) + gui_fatal("receiving file from dispVM"); + if (fstat(tmpfd, &st)) + gui_fatal("fstat"); + close(tmpfd); - return st.st_size > 0; + return st.st_size > 0; } void recv_file_nowrite(const char *fname) { - char *tempfile; - char *errmsg; - int tmpfd = -1; + char *tempfile; + char *errmsg; + int tmpfd = -1; - if (asprintf(&tempfile, "/tmp/file_edited_in_dvm.XXXXXX") != -1) - tmpfd = mkstemp(tempfile); - if (tmpfd < 0) - gui_fatal("unable to create any temporary file, aborting"); - if (!copy_and_return_nonemptiness(tmpfd)) { - unlink(tempfile); - return; - } - if (asprintf(&errmsg, - "The file %s has been edited in Disposable VM and the modified content has been received, " - "but this file is in nonwritable directory and thus cannot be modified safely. The edited file has been " - "saved to %s", fname, tempfile) != -1) + if (asprintf(&tempfile, "/tmp/file_edited_in_dvm.XXXXXX") != -1) + tmpfd = mkstemp(tempfile); + if (tmpfd < 0) + gui_fatal("unable to create any temporary file, aborting"); + if (!copy_and_return_nonemptiness(tmpfd)) { + unlink(tempfile); + return; + } + if (asprintf(&errmsg, + "The file %s has been edited in Disposable VM and the modified content has been received, " + "but this file is in nonwritable directory and thus cannot be modified safely. The edited file has been " + "saved to %s", fname, tempfile) != -1) gui_nonfatal(errmsg); } void actually_recv_file(const char *fname, const char *tempfile, int tmpfd) { - if (!copy_and_return_nonemptiness(tmpfd)) { - unlink(tempfile); - return; - } - if (rename(tempfile, fname)) - gui_fatal("rename"); + if (!copy_and_return_nonemptiness(tmpfd)) { + unlink(tempfile); + return; + } + if (rename(tempfile, fname)) + gui_fatal("rename"); } void recv_file(const char *fname) { - int tmpfd = -1; - char *tempfile; - if (asprintf(&tempfile, "%s.XXXXXX", fname) != -1) { - tmpfd = mkstemp(tempfile); - } - if (tmpfd < 0) - recv_file_nowrite(fname); - else - actually_recv_file(fname, tempfile, tmpfd); + int tmpfd = -1; + char *tempfile; + if (asprintf(&tempfile, "%s.XXXXXX", fname) != -1) { + tmpfd = mkstemp(tempfile); + } + if (tmpfd < 0) + recv_file_nowrite(fname); + else + actually_recv_file(fname, tempfile, tmpfd); } void talk_to_daemon(const char *fname) { - send_file(fname); - recv_file(fname); + send_file(fname); + recv_file(fname); } int main(int argc, char ** argv) { - signal(SIGPIPE, SIG_IGN); - if (argc!=2) - gui_fatal("OpenInVM - no file given?"); - talk_to_daemon(argv[1]); - return 0; + signal(SIGPIPE, SIG_IGN); + if (argc!=2) + gui_fatal("OpenInVM - no file given?"); + talk_to_daemon(argv[1]); + return 0; } diff --git a/qubes-rpc/vm-file-editor.c b/qubes-rpc/vm-file-editor.c index 55594d2..054fef3 100644 --- a/qubes-rpc/vm-file-editor.c +++ b/qubes-rpc/vm-file-editor.c @@ -19,217 +19,217 @@ static const char *cleanup_dirname = NULL; static void cleanup_file(void) { - if (cleanup_filename) { - if (unlink(cleanup_filename) < 0) - fprintf(stderr, "Failed to remove file at exit\n"); - cleanup_filename = NULL; - } - if (cleanup_dirname) { - if (rmdir(cleanup_dirname) < 0) - fprintf(stderr, "Failed to remove directory at exit\n"); - cleanup_dirname = NULL; - } + if (cleanup_filename) { + if (unlink(cleanup_filename) < 0) + fprintf(stderr, "Failed to remove file at exit\n"); + cleanup_filename = NULL; + } + if (cleanup_dirname) { + if (rmdir(cleanup_dirname) < 0) + fprintf(stderr, "Failed to remove directory at exit\n"); + cleanup_dirname = NULL; + } } const char *gettime(void) { - static char retbuf[60]; - struct timeval tv; - gettimeofday(&tv, NULL); - snprintf(retbuf, sizeof(retbuf), "%lld.%06lld", - (long long) tv.tv_sec, (long long) tv.tv_usec); - return retbuf; + static char retbuf[60]; + struct timeval tv; + gettimeofday(&tv, NULL); + snprintf(retbuf, sizeof(retbuf), "%lld.%06lld", + (long long) tv.tv_sec, (long long) tv.tv_usec); + return retbuf; } static char *get_directory(void) { - const char *remote_domain; - char *dir; - size_t len; - char *ret; + const char *remote_domain; + char *dir; + size_t len; + char *ret; - remote_domain = getenv("QREXEC_REMOTE_DOMAIN"); - if (!remote_domain) { - fprintf(stderr, "Cannot get remote domain name\n"); - exit(1); - } - if (!*remote_domain || index(remote_domain, '/')) - goto fail; - if (!strcmp(remote_domain, ".") || !strcmp(remote_domain, "..")) - goto fail; + remote_domain = getenv("QREXEC_REMOTE_DOMAIN"); + if (!remote_domain) { + fprintf(stderr, "Cannot get remote domain name\n"); + exit(1); + } + if (!*remote_domain || index(remote_domain, '/')) + goto fail; + if (!strcmp(remote_domain, ".") || !strcmp(remote_domain, "..")) + goto fail; - len = strlen("/tmp/-XXXXXX")+strlen(remote_domain)+1; - dir = malloc(len); - if (!dir) { - fprintf(stderr, "Cannot allocate memory\n"); - exit(1); - } - snprintf(dir, len, "/tmp/%s-XXXXXX", remote_domain); + len = strlen("/tmp/-XXXXXX")+strlen(remote_domain)+1; + dir = malloc(len); + if (!dir) { + fprintf(stderr, "Cannot allocate memory\n"); + exit(1); + } + snprintf(dir, len, "/tmp/%s-XXXXXX", remote_domain); - ret = mkdtemp(dir); - if (ret == NULL) { - perror("mkdtemp"); - exit(1); - } - cleanup_dirname = strdup(ret); - return ret; + ret = mkdtemp(dir); + if (ret == NULL) { + perror("mkdtemp"); + exit(1); + } + cleanup_dirname = strdup(ret); + return ret; fail: - fprintf(stderr, "Invalid remote domain name: %s\n", remote_domain); - exit(1); + fprintf(stderr, "Invalid remote domain name: %s\n", remote_domain); + exit(1); } char *get_filename(void) { - char buf[DVM_FILENAME_SIZE]; - static char *retname; - int i; - char *directory; - size_t len; + char buf[DVM_FILENAME_SIZE]; + static char *retname; + int i; + char *directory; + size_t len; - directory = get_directory(); - if (!read_all(0, buf, sizeof(buf))) - exit(1); - buf[DVM_FILENAME_SIZE-1] = 0; - if (index(buf, '/')) { - fprintf(stderr, "filename contains /"); - exit(1); - } - for (i=0; buf[i]!=0; i++) { - // replace some characters with _ (eg mimeopen have problems with some of them) - if (index(" !?\"#$%^&*()[]<>;`~|", buf[i])) - buf[i]='_'; - } - len = strlen(directory)+1+strlen(buf)+1; - retname = malloc(len); - if (!retname) { - fprintf(stderr, "Cannot allocate memory\n"); - exit(1); - } - snprintf(retname, len, "%s/%s", directory, buf); - free(directory); - return retname; + directory = get_directory(); + if (!read_all(0, buf, sizeof(buf))) + exit(1); + buf[DVM_FILENAME_SIZE-1] = 0; + if (index(buf, '/')) { + fprintf(stderr, "filename contains /"); + exit(1); + } + for (i=0; buf[i]!=0; i++) { + // replace some characters with _ (eg mimeopen have problems with some of them) + if (index(" !?\"#$%^&*()[]<>;`~|", buf[i])) + buf[i]='_'; + } + len = strlen(directory)+1+strlen(buf)+1; + retname = malloc(len); + if (!retname) { + fprintf(stderr, "Cannot allocate memory\n"); + exit(1); + } + snprintf(retname, len, "%s/%s", directory, buf); + free(directory); + return retname; } void copy_file_by_name(const char *filename) { - int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0600); - if (fd < 0) { - perror("open file"); - exit(1); - } - /* we now have created a new file, ensure we delete it at the end */ - cleanup_filename = strdup(filename); - atexit(cleanup_file); - if (!copy_fd_all(fd, 0)) + int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0600); + if (fd < 0) { + perror("open file"); exit(1); - close(fd); + } + /* we now have created a new file, ensure we delete it at the end */ + cleanup_filename = strdup(filename); + atexit(cleanup_file); + if (!copy_fd_all(fd, 0)) + exit(1); + close(fd); } void send_file_back(const char * filename) { - int fd = open(filename, O_RDONLY); - if (fd < 0) { - perror("open file"); - exit(1); - } - if (!copy_fd_all(1, fd)) - exit(1); - close(fd); - close(1); + int fd = open(filename, O_RDONLY); + if (fd < 0) { + perror("open file"); + exit(1); + } + if (!copy_fd_all(1, fd)) + exit(1); + close(fd); + close(1); } int main() { - struct stat stat_pre, stat_post, session_stat; - char *filename = get_filename(); - int child, status, log_fd, null_fd; - FILE *waiter_pidfile; + struct stat stat_pre, stat_post, session_stat; + char *filename = get_filename(); + int child, status, log_fd, null_fd; + FILE *waiter_pidfile; - copy_file_by_name(filename); - if (stat(filename, &stat_pre)) { - perror("stat pre"); - exit(1); - } + copy_file_by_name(filename); + if (stat(filename, &stat_pre)) { + perror("stat pre"); + exit(1); + } #ifdef DEBUG - fprintf(stderr, "time=%s, waiting for qubes-session\n", gettime()); + fprintf(stderr, "time=%s, waiting for qubes-session\n", gettime()); #endif - // wait for X server to starts (especially in DispVM) - if (stat("/tmp/qubes-session-env", &session_stat)) { - switch (child = fork()) { - case -1: - perror("fork"); - exit(1); - case 0: - waiter_pidfile = fopen("/tmp/qubes-session-waiter", "a"); - if (waiter_pidfile == NULL) { - perror("fopen waiter_pidfile"); - exit(1); - } - fprintf(waiter_pidfile, "%d\n", getpid()); - fclose(waiter_pidfile); - // check the second time, to prevent race - if (stat("/tmp/qubes-session-env", &session_stat)) { - // wait for qubes-session notify - pause(); - } - exit(0); - default: - waitpid(child, &status, 0); - if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { - //propagate exit code from child - exit(WEXITSTATUS(status)); - } - } - } + // wait for X server to starts (especially in DispVM) + if (stat("/tmp/qubes-session-env", &session_stat)) { + switch (child = fork()) { + case -1: + perror("fork"); + exit(1); + case 0: + waiter_pidfile = fopen("/tmp/qubes-session-waiter", "a"); + if (waiter_pidfile == NULL) { + perror("fopen waiter_pidfile"); + exit(1); + } + fprintf(waiter_pidfile, "%d\n", getpid()); + fclose(waiter_pidfile); + // check the second time, to prevent race + if (stat("/tmp/qubes-session-env", &session_stat)) { + // wait for qubes-session notify + pause(); + } + exit(0); + default: + waitpid(child, &status, 0); + if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { + //propagate exit code from child + exit(WEXITSTATUS(status)); + } + } + } #ifdef DEBUG - fprintf(stderr, "time=%s, starting editor\n", gettime()); + fprintf(stderr, "time=%s, starting editor\n", gettime()); #endif - switch (child = fork()) { - case -1: - perror("fork"); - exit(1); - case 0: - null_fd = open("/dev/null", O_RDONLY); - dup2(null_fd, 0); - close(null_fd); + switch (child = fork()) { + case -1: + perror("fork"); + exit(1); + case 0: + null_fd = open("/dev/null", O_RDONLY); + dup2(null_fd, 0); + close(null_fd); - log_fd = open("/tmp/mimeopen.log", O_CREAT | O_APPEND, 0666); - if (log_fd == -1) { - perror("open /tmp/mimeopen.log"); - exit(1); - } - dup2(log_fd, 1); - close(log_fd); + log_fd = open("/tmp/mimeopen.log", O_CREAT | O_APPEND, 0666); + if (log_fd == -1) { + perror("open /tmp/mimeopen.log"); + exit(1); + } + dup2(log_fd, 1); + close(log_fd); - setenv("HOME", USER_HOME, 1); - setenv("DISPLAY", ":0", 1); - execl("/usr/bin/qubes-open", "qubes-open", filename, (char*)NULL); - perror("execl"); - exit(1); - default: - waitpid(child, &status, 0); - if (status != 0) { - char cmd[512]; + setenv("HOME", USER_HOME, 1); + setenv("DISPLAY", ":0", 1); + execl("/usr/bin/qubes-open", "qubes-open", filename, (char*)NULL); + perror("execl"); + exit(1); + default: + waitpid(child, &status, 0); + if (status != 0) { + char cmd[512]; #ifdef USE_KDIALOG - snprintf(cmd, sizeof(cmd), - "HOME=/home/user DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 /tmp/kdialog.log 2>&1 /tmp/kdialog.log 2>&1 /tmp/kdialog.log 2>&1 /tmp/kdialog.log 2>&1 /tmp/kdialog.log 2>&1