vm+dom0/filecopy-unpacker: send errors to qfile-agent istead of local message (#239)

Because unpacker no longer require GUI access, there is no need for separate
process for error reporting. Which greatly simplify the code.
This commit is contained in:
Marek Marczykowski 2012-08-25 02:09:45 +02:00
parent 2903de54ae
commit 13e973a591
2 changed files with 21 additions and 63 deletions

View File

@ -29,32 +29,14 @@ int prepare_creds_return_uid(char *username)
return pwd->pw_uid;
}
void wait_for_child(int statusfd)
{
int status;
if (read(statusfd, &status, sizeof status)!=sizeof status)
gui_fatal("File copy error: Internal error reading status from unpacker");
errno = status;
switch (status) {
case LEGAL_EOF: break;
case 0: gui_fatal("File copy: Connection terminated unexpectedly"); break;
case EINVAL: gui_fatal("File copy: Corrupted data from packer"); break;
case EEXIST: gui_fatal("File copy: not overwriting existing file. Clean ~/incoming, and retry copy"); break;
default: gui_fatal("File copy");
}
}
extern void do_unpack(int);
extern int do_unpack(void);
int main(int argc, char ** argv)
{
char *incoming_dir;
int pipefds[2];
int uid;
char *remote_domain;
pipe(pipefds);
uid = prepare_creds_return_uid("user");
remote_domain = getenv("QREXEC_REMOTE_DOMAIN");
@ -67,25 +49,8 @@ int main(int argc, char ** argv)
mkdir(incoming_dir, 0700);
if (chdir(incoming_dir))
gui_fatal("Error chdir to %s", incoming_dir);
switch (fork()) {
case -1:
perror("fork");
exit(1);
case 0:
if (chroot(incoming_dir)) //impossible
gui_fatal("Error chroot to %s", incoming_dir);
setuid(uid);
close(pipefds[0]);
do_unpack(pipefds[1]);
exit(0);
default:;
}
close(0);
close(1);
if (chroot(incoming_dir)) //impossible
gui_fatal("Error chroot to %s", incoming_dir);
setuid(uid);
close(pipefds[1]);
wait_for_child(pipefds[0]);
return 0;
return do_unpack();
}

View File

@ -35,14 +35,22 @@ int read_all_with_crc(int fd, void *buf, int size) {
return ret;
}
int global_status_fd;
void do_exit(int code)
{
int codebuf = code;
write(global_status_fd, &codebuf, sizeof codebuf);
exit(0);
void send_status_and_crc(int code) {
struct result_header hdr;
int saved_errno;
saved_errno = errno;
hdr.error_code = code;
hdr.crc32 = crc32_sum;
write_all(1, &hdr, sizeof(hdr));
errno = saved_errno;
}
void do_exit(int code)
{
send_status_and_crc(code);
exit(code);
}
void fix_times_and_perms(struct file_header *untrusted_hdr,
char *untrusted_name)
@ -130,20 +138,8 @@ void process_one_file(struct file_header *untrusted_hdr)
do_exit(EINVAL);
}
void send_status_and_crc() {
struct result_header hdr;
int saved_errno;
saved_errno = errno;
hdr.error_code = errno;
hdr.crc32 = crc32_sum;
write_all(1, &hdr, sizeof(hdr));
errno = saved_errno;
}
void do_unpack(int fd)
int do_unpack()
{
global_status_fd = fd;
struct file_header untrusted_hdr;
/* initialize checksum */
crc32_sum = 0;
@ -158,9 +154,6 @@ void do_unpack(int fd)
if (files_limit && total_files > files_limit)
do_exit(EDQUOT);
}
send_status_and_crc();
if (errno)
do_exit(errno);
else
do_exit(LEGAL_EOF);
send_status_and_crc(errno);
return errno;
}