2011-03-11 12:44:19 +01:00
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
#include <stdlib.h>
|
2014-01-06 18:31:12 +01:00
|
|
|
#include <libqubes-rpc-filecopy.h>
|
2011-03-11 12:44:19 +01:00
|
|
|
#include <unistd.h>
|
2011-03-15 13:12:21 +01:00
|
|
|
#include <gui-fatal.h>
|
2011-03-11 12:44:19 +01:00
|
|
|
#include "dvm2.h"
|
|
|
|
|
2013-12-30 11:35:46 +01:00
|
|
|
void send_file(const char *fname)
|
2011-03-11 12:44:19 +01:00
|
|
|
{
|
2013-12-30 11:35:46 +01:00
|
|
|
const char *base;
|
2013-12-29 13:02:09 +01:00
|
|
|
char sendbuf[DVM_FILENAME_SIZE];
|
2011-03-11 12:44:19 +01:00
|
|
|
int fd = open(fname, O_RDONLY);
|
|
|
|
if (fd < 0)
|
2011-03-15 13:12:21 +01:00
|
|
|
gui_fatal("open %s", fname);
|
2011-03-11 12:44:19 +01:00
|
|
|
base = rindex(fname, '/');
|
|
|
|
if (!base)
|
|
|
|
base = fname;
|
|
|
|
else
|
|
|
|
base++;
|
|
|
|
if (strlen(base) >= DVM_FILENAME_SIZE)
|
|
|
|
base += strlen(base) - DVM_FILENAME_SIZE + 1;
|
2013-12-29 13:02:09 +01:00
|
|
|
strncpy(sendbuf,base,DVM_FILENAME_SIZE); /* fills out with NULs */
|
|
|
|
if (!write_all(1, sendbuf, DVM_FILENAME_SIZE))
|
2011-03-15 13:12:21 +01:00
|
|
|
gui_fatal("send filename to dispVM");
|
2011-03-11 12:44:19 +01:00
|
|
|
if (!copy_fd_all(1, fd))
|
2011-03-15 13:12:21 +01:00
|
|
|
gui_fatal("send file to dispVM");
|
2011-03-11 12:44:19 +01:00
|
|
|
close(1);
|
2013-12-29 13:01:45 +01:00
|
|
|
close(fd);
|
2011-03-11 12:44:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int copy_and_return_nonemptiness(int tmpfd)
|
|
|
|
{
|
|
|
|
struct stat st;
|
|
|
|
if (!copy_fd_all(tmpfd, 0))
|
2011-03-15 13:12:21 +01:00
|
|
|
gui_fatal("receiving file from dispVM");
|
2011-03-11 12:44:19 +01:00
|
|
|
if (fstat(tmpfd, &st))
|
2011-03-15 13:12:21 +01:00
|
|
|
gui_fatal("fstat");
|
2011-03-11 12:44:19 +01:00
|
|
|
close(tmpfd);
|
|
|
|
|
2013-12-29 13:04:11 +01:00
|
|
|
return st.st_size > 0;
|
2011-03-11 12:44:19 +01:00
|
|
|
}
|
|
|
|
|
2013-12-30 11:35:46 +01:00
|
|
|
void recv_file_nowrite(const char *fname)
|
2011-03-11 12:44:19 +01:00
|
|
|
{
|
|
|
|
char *tempfile;
|
|
|
|
char *errmsg;
|
2014-04-22 00:56:52 +02:00
|
|
|
int tmpfd = -1;
|
2011-03-11 12:44:19 +01:00
|
|
|
|
2014-04-22 00:56:52 +02:00
|
|
|
if (asprintf(&tempfile, "/tmp/file_edited_in_dvm.XXXXXX") != -1)
|
|
|
|
tmpfd = mkstemp(tempfile);
|
2011-03-11 12:44:19 +01:00
|
|
|
if (tmpfd < 0)
|
2011-03-15 13:12:21 +01:00
|
|
|
gui_fatal("unable to create any temporary file, aborting");
|
2011-03-11 12:44:19 +01:00
|
|
|
if (!copy_and_return_nonemptiness(tmpfd)) {
|
|
|
|
unlink(tempfile);
|
|
|
|
return;
|
|
|
|
}
|
2014-04-22 00:56:52 +02:00
|
|
|
if (asprintf(&errmsg,
|
2011-03-11 12:44:19 +01:00
|
|
|
"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 "
|
2014-04-22 00:56:52 +02:00
|
|
|
"saved to %s", fname, tempfile) != -1)
|
|
|
|
gui_nonfatal(errmsg);
|
2011-03-11 12:44:19 +01:00
|
|
|
}
|
|
|
|
|
2013-12-30 11:35:46 +01:00
|
|
|
void actually_recv_file(const char *fname, const char *tempfile, int tmpfd)
|
2011-03-11 12:44:19 +01:00
|
|
|
{
|
|
|
|
if (!copy_and_return_nonemptiness(tmpfd)) {
|
|
|
|
unlink(tempfile);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (rename(tempfile, fname))
|
2011-03-15 13:12:21 +01:00
|
|
|
gui_fatal("rename");
|
2011-03-11 12:44:19 +01:00
|
|
|
}
|
|
|
|
|
2013-12-30 11:35:46 +01:00
|
|
|
void recv_file(const char *fname)
|
2011-03-11 12:44:19 +01:00
|
|
|
{
|
2014-04-22 00:56:52 +02:00
|
|
|
int tmpfd = -1;
|
2011-03-11 12:44:19 +01:00
|
|
|
char *tempfile;
|
2014-04-22 00:56:52 +02:00
|
|
|
if (asprintf(&tempfile, "%s.XXXXXX", fname) != -1) {
|
|
|
|
tmpfd = mkstemp(tempfile);
|
|
|
|
}
|
2011-03-11 12:44:19 +01:00
|
|
|
if (tmpfd < 0)
|
|
|
|
recv_file_nowrite(fname);
|
|
|
|
else
|
|
|
|
actually_recv_file(fname, tempfile, tmpfd);
|
|
|
|
}
|
|
|
|
|
2013-12-30 11:35:46 +01:00
|
|
|
void talk_to_daemon(const char *fname)
|
2011-03-11 12:44:19 +01:00
|
|
|
{
|
|
|
|
send_file(fname);
|
|
|
|
recv_file(fname);
|
|
|
|
}
|
|
|
|
|
2011-07-06 12:32:20 +02:00
|
|
|
int main(int argc, char ** argv)
|
2011-03-11 12:44:19 +01:00
|
|
|
{
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
2015-10-15 04:34:55 +02:00
|
|
|
if (argc!=2)
|
2011-07-06 12:32:20 +02:00
|
|
|
gui_fatal("OpenInVM - no file given?");
|
|
|
|
talk_to_daemon(argv[1]);
|
2011-03-11 12:44:19 +01:00
|
|
|
return 0;
|
2015-10-15 04:34:55 +02:00
|
|
|
}
|