qubes-rpc/filecopy: send last processed filename for diagnostic purposes
This will ease solving transfer problems - sender will known at which file it failed.
This commit is contained in:
parent
5131810265
commit
a73be3f126
@ -47,6 +47,12 @@ struct result_header {
|
|||||||
uint64_t crc32;
|
uint64_t crc32;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/* optional info about last processed file */
|
||||||
|
struct result_header_ext {
|
||||||
|
uint32_t last_namelen;
|
||||||
|
char last_name[0];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
COPY_FILE_OK,
|
COPY_FILE_OK,
|
||||||
COPY_FILE_READ_EOF,
|
COPY_FILE_READ_EOF,
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "libqubes-rpc-filecopy.h"
|
#include "libqubes-rpc-filecopy.h"
|
||||||
@ -31,8 +32,9 @@ int read_all_with_crc(int fd, void *buf, int size) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_status_and_crc(int code) {
|
void send_status_and_crc(int code, char *last_filename) {
|
||||||
struct result_header hdr;
|
struct result_header hdr;
|
||||||
|
struct result_header_ext hdr_ext;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
|
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
@ -40,13 +42,20 @@ void send_status_and_crc(int code) {
|
|||||||
hdr.crc32 = crc32_sum;
|
hdr.crc32 = crc32_sum;
|
||||||
if (!write_all(1, &hdr, sizeof(hdr)))
|
if (!write_all(1, &hdr, sizeof(hdr)))
|
||||||
perror("write status");
|
perror("write status");
|
||||||
|
if (last_filename) {
|
||||||
|
hdr_ext.last_namelen = strlen(last_filename);
|
||||||
|
if (!write_all(1, &hdr_ext, sizeof(hdr_ext)))
|
||||||
|
perror("write status ext");
|
||||||
|
if (!write_all(1, last_filename, hdr_ext.last_namelen))
|
||||||
|
perror("write last_filename");
|
||||||
|
}
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_exit(int code)
|
void do_exit(int code, char *last_filename)
|
||||||
{
|
{
|
||||||
close(0);
|
close(0);
|
||||||
send_status_and_crc(code);
|
send_status_and_crc(code, last_filename);
|
||||||
exit(code);
|
exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,9 +68,9 @@ void fix_times_and_perms(struct file_header *untrusted_hdr,
|
|||||||
untrusted_hdr->mtime_nsec / 1000}
|
untrusted_hdr->mtime_nsec / 1000}
|
||||||
};
|
};
|
||||||
if (chmod(untrusted_name, untrusted_hdr->mode & 07777)) /* safe because of chroot */
|
if (chmod(untrusted_name, untrusted_hdr->mode & 07777)) /* safe because of chroot */
|
||||||
do_exit(errno);
|
do_exit(errno, untrusted_name);
|
||||||
if (utimes(untrusted_name, times)) /* as above */
|
if (utimes(untrusted_name, times)) /* as above */
|
||||||
do_exit(errno);
|
do_exit(errno, untrusted_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -72,17 +81,17 @@ void process_one_file_reg(struct file_header *untrusted_hdr,
|
|||||||
int ret;
|
int ret;
|
||||||
int fdout = open(untrusted_name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0700); /* safe because of chroot */
|
int fdout = open(untrusted_name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0700); /* safe because of chroot */
|
||||||
if (fdout < 0)
|
if (fdout < 0)
|
||||||
do_exit(errno);
|
do_exit(errno, untrusted_name);
|
||||||
total_bytes += untrusted_hdr->filelen;
|
total_bytes += untrusted_hdr->filelen;
|
||||||
if (bytes_limit && total_bytes > bytes_limit)
|
if (bytes_limit && total_bytes > bytes_limit)
|
||||||
do_exit(EDQUOT);
|
do_exit(EDQUOT, untrusted_name);
|
||||||
ret = copy_file(fdout, 0, untrusted_hdr->filelen, &crc32_sum);
|
ret = copy_file(fdout, 0, untrusted_hdr->filelen, &crc32_sum);
|
||||||
if (ret != COPY_FILE_OK) {
|
if (ret != COPY_FILE_OK) {
|
||||||
if (ret == COPY_FILE_READ_EOF
|
if (ret == COPY_FILE_READ_EOF
|
||||||
|| ret == COPY_FILE_READ_ERROR)
|
|| ret == COPY_FILE_READ_ERROR)
|
||||||
do_exit(LEGAL_EOF); // hopefully remote will produce error message
|
do_exit(LEGAL_EOF, untrusted_name); // hopefully remote will produce error message
|
||||||
else
|
else
|
||||||
do_exit(errno);
|
do_exit(errno, untrusted_name);
|
||||||
}
|
}
|
||||||
close(fdout);
|
close(fdout);
|
||||||
fix_times_and_perms(untrusted_hdr, untrusted_name);
|
fix_times_and_perms(untrusted_hdr, untrusted_name);
|
||||||
@ -97,7 +106,7 @@ void process_one_file_dir(struct file_header *untrusted_hdr,
|
|||||||
if (!mkdir(untrusted_name, 0700)) /* safe because of chroot */
|
if (!mkdir(untrusted_name, 0700)) /* safe because of chroot */
|
||||||
return;
|
return;
|
||||||
if (errno != EEXIST)
|
if (errno != EEXIST)
|
||||||
do_exit(errno);
|
do_exit(errno, untrusted_name);
|
||||||
fix_times_and_perms(untrusted_hdr, untrusted_name);
|
fix_times_and_perms(untrusted_hdr, untrusted_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,13 +116,13 @@ void process_one_file_link(struct file_header *untrusted_hdr,
|
|||||||
char untrusted_content[MAX_PATH_LENGTH];
|
char untrusted_content[MAX_PATH_LENGTH];
|
||||||
unsigned int filelen;
|
unsigned int filelen;
|
||||||
if (untrusted_hdr->filelen > MAX_PATH_LENGTH - 1)
|
if (untrusted_hdr->filelen > MAX_PATH_LENGTH - 1)
|
||||||
do_exit(ENAMETOOLONG);
|
do_exit(ENAMETOOLONG, untrusted_name);
|
||||||
filelen = untrusted_hdr->filelen; /* sanitized above */
|
filelen = untrusted_hdr->filelen; /* sanitized above */
|
||||||
if (!read_all_with_crc(0, untrusted_content, filelen))
|
if (!read_all_with_crc(0, untrusted_content, filelen))
|
||||||
do_exit(LEGAL_EOF); // hopefully remote has produced error message
|
do_exit(LEGAL_EOF, untrusted_name); // hopefully remote has produced error message
|
||||||
untrusted_content[filelen] = 0;
|
untrusted_content[filelen] = 0;
|
||||||
if (symlink(untrusted_content, untrusted_name)) /* safe because of chroot */
|
if (symlink(untrusted_content, untrusted_name)) /* safe because of chroot */
|
||||||
do_exit(errno);
|
do_exit(errno, untrusted_name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,10 +130,10 @@ void process_one_file(struct file_header *untrusted_hdr)
|
|||||||
{
|
{
|
||||||
unsigned int namelen;
|
unsigned int namelen;
|
||||||
if (untrusted_hdr->namelen > MAX_PATH_LENGTH - 1)
|
if (untrusted_hdr->namelen > MAX_PATH_LENGTH - 1)
|
||||||
do_exit(ENAMETOOLONG);
|
do_exit(ENAMETOOLONG, NULL); /* filename too long so not received at all */
|
||||||
namelen = untrusted_hdr->namelen; /* sanitized above */
|
namelen = untrusted_hdr->namelen; /* sanitized above */
|
||||||
if (!read_all_with_crc(0, untrusted_namebuf, namelen))
|
if (!read_all_with_crc(0, untrusted_namebuf, namelen))
|
||||||
do_exit(LEGAL_EOF); // hopefully remote has produced error message
|
do_exit(LEGAL_EOF, NULL); // hopefully remote has produced error message
|
||||||
untrusted_namebuf[namelen] = 0;
|
untrusted_namebuf[namelen] = 0;
|
||||||
if (S_ISREG(untrusted_hdr->mode))
|
if (S_ISREG(untrusted_hdr->mode))
|
||||||
process_one_file_reg(untrusted_hdr, untrusted_namebuf);
|
process_one_file_reg(untrusted_hdr, untrusted_namebuf);
|
||||||
@ -133,7 +142,7 @@ void process_one_file(struct file_header *untrusted_hdr)
|
|||||||
else if (S_ISDIR(untrusted_hdr->mode))
|
else if (S_ISDIR(untrusted_hdr->mode))
|
||||||
process_one_file_dir(untrusted_hdr, untrusted_namebuf);
|
process_one_file_dir(untrusted_hdr, untrusted_namebuf);
|
||||||
else
|
else
|
||||||
do_exit(EINVAL);
|
do_exit(EINVAL, untrusted_namebuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_unpack()
|
int do_unpack()
|
||||||
@ -150,8 +159,8 @@ int do_unpack()
|
|||||||
process_one_file(&untrusted_hdr);
|
process_one_file(&untrusted_hdr);
|
||||||
total_files++;
|
total_files++;
|
||||||
if (files_limit && total_files > files_limit)
|
if (files_limit && total_files > files_limit)
|
||||||
do_exit(EDQUOT);
|
do_exit(EDQUOT, untrusted_namebuf);
|
||||||
}
|
}
|
||||||
send_status_and_crc(errno);
|
send_status_and_crc(errno, untrusted_namebuf);
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user