qubes-rpc: fix code style - indent with spaces
This commit is contained in:
parent
6a088a3992
commit
5deac1802f
@ -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);
|
||||
}
|
||||
|
@ -13,107 +13,107 @@
|
||||
#include <libqubes-rpc-filecopy.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 </dev/null", status);
|
||||
("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 </dev/null", status);
|
||||
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 </dev/null", status);
|
||||
("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 </dev/null", status);
|
||||
#else
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
"HOME=/home/user DISPLAY=:0 /usr/bin/zenity --error --text 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
"HOME=/home/user DISPLAY=:0 /usr/bin/zenity --error --text 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
|
||||
#endif
|
||||
status = system(cmd);
|
||||
}
|
||||
}
|
||||
status = system(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
if (stat(filename, &stat_post)) {
|
||||
perror("stat post");
|
||||
exit(1);
|
||||
}
|
||||
if (stat_pre.st_mtime != stat_post.st_mtime)
|
||||
send_file_back(filename);
|
||||
free(filename);
|
||||
return 0;
|
||||
if (stat(filename, &stat_post)) {
|
||||
perror("stat post");
|
||||
exit(1);
|
||||
}
|
||||
if (stat_pre.st_mtime != stat_post.st_mtime)
|
||||
send_file_back(filename);
|
||||
free(filename);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user