Merge branch 'spring-merge' of git.qubes-os.org:/var/lib/qubes/git/rafal/core
This commit is contained in:
commit
452cb48b1f
2
Makefile
2
Makefile
@ -33,3 +33,5 @@ clean:
|
||||
(cd dom0/restore && make clean)
|
||||
(cd dom0/qmemman && make clean)
|
||||
(cd common && make clean)
|
||||
make -C qrexec clean
|
||||
make -C vchan clean
|
||||
|
@ -1,6 +1,14 @@
|
||||
CC=gcc
|
||||
CFLAGS=-Wall
|
||||
all: qubes_penctl qubes_add_pendrive_script qvm-open-in-dvm
|
||||
CFLAGS=-g -Wall -I../common
|
||||
all: qubes_penctl qubes_add_pendrive_script qvm-open-in-dvm dvm_file_editor qfile-agent-dvm qfile-agent qfile-unpacker
|
||||
dvm_file_editor: dvm_file_editor.o ../common/ioall.o
|
||||
$(CC) -g -o dvm_file_editor dvm_file_editor.o ../common/ioall.o
|
||||
qfile-agent-dvm: qfile-agent-dvm.o ../common/ioall.o ../common/gui-fatal.o
|
||||
$(CC) -g -o qfile-agent-dvm qfile-agent-dvm.o ../common/ioall.o ../common/gui-fatal.o
|
||||
qfile-agent: qfile-agent.o ../common/ioall.o ../common/gui-fatal.o copy_file.o
|
||||
$(CC) -g -o qfile-agent qfile-agent.o ../common/ioall.o ../common/gui-fatal.o copy_file.o
|
||||
qfile-unpacker: qfile-unpacker.o ../common/ioall.o ../common/gui-fatal.o copy_file.o unpack.o
|
||||
$(CC) -g -o qfile-unpacker qfile-unpacker.o ../common/ioall.o ../common/gui-fatal.o copy_file.o unpack.o
|
||||
qubes_penctl: qubes_penctl.o
|
||||
$(CC) -o qubes_penctl qubes_penctl.o -lxenstore
|
||||
qubes_add_pendrive_script: qubes_add_pendrive_script.o
|
||||
@ -9,4 +17,5 @@ qvm-open-in-dvm: qvm-open-in-dvm.o
|
||||
$(CC) -o qvm-open-in-dvm qvm-open-in-dvm.o -lxenstore
|
||||
|
||||
clean:
|
||||
rm -f qubes_penctl qubes_add_pendrive_script qvm-open-in-dvm xenstore-watch *.o *~
|
||||
rm -f qfile-agent-dvm qfile-agent qfile-unpacker dvm_file_editor qubes_penctl qubes_add_pendrive_script qvm-open-in-dvm *.o *~
|
||||
rm -f xenstore-watch
|
||||
|
28
appvm/copy_file.c
Normal file
28
appvm/copy_file.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include <unistd.h>
|
||||
#include <ioall.h>
|
||||
extern void notify_progress(int, int);
|
||||
|
||||
char * copy_file(int outfd, int infd, long long size)
|
||||
{
|
||||
char buf[4096];
|
||||
long long written = 0;
|
||||
int ret;
|
||||
int count;
|
||||
while (written < size) {
|
||||
if (size - written > sizeof(buf))
|
||||
count = sizeof buf;
|
||||
else
|
||||
count = size - written;
|
||||
ret = read(infd, buf, count);
|
||||
if (!ret)
|
||||
return("EOF while reading file");
|
||||
if (ret < 0)
|
||||
return("error reading file");
|
||||
if (!write_all(outfd, buf, ret))
|
||||
return("error writing file content");
|
||||
notify_progress(ret, 0);
|
||||
written += ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
2
appvm/dvm2.h
Normal file
2
appvm/dvm2.h
Normal file
@ -0,0 +1,2 @@
|
||||
#define DVM_FILENAME_SIZE 256
|
||||
#define DVM_SPOOL "/home/user/.dvmspool"
|
73
appvm/dvm_file_editor.c
Normal file
73
appvm/dvm_file_editor.c
Normal file
@ -0,0 +1,73 @@
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <ioall.h>
|
||||
#include "dvm2.h"
|
||||
|
||||
char *get_filename()
|
||||
{
|
||||
char buf[DVM_FILENAME_SIZE];
|
||||
static char retname[sizeof(buf) + sizeof("/tmp/")];
|
||||
if (!read_all(0, buf, sizeof(buf)))
|
||||
exit(1);
|
||||
if (index(buf, '/')) {
|
||||
fprintf(stderr, "filename contains /");
|
||||
exit(1);
|
||||
}
|
||||
snprintf(retname, sizeof(retname), "/tmp/%s", buf);
|
||||
return retname;
|
||||
}
|
||||
|
||||
void copy_file(char *filename)
|
||||
{
|
||||
int fd = open(filename, O_WRONLY | O_CREAT, 0600);
|
||||
if (fd < 0) {
|
||||
perror("open file");
|
||||
exit(1);
|
||||
}
|
||||
if (!copy_fd_all(fd, 0))
|
||||
exit(1);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void send_file_back(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);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
char cmdbuf[512];
|
||||
struct stat stat_pre, stat_post;
|
||||
char *filename = get_filename();
|
||||
|
||||
copy_file(filename);
|
||||
if (stat(filename, &stat_pre)) {
|
||||
perror("stat pre");
|
||||
exit(1);
|
||||
}
|
||||
snprintf(cmdbuf, sizeof(cmdbuf),
|
||||
"HOME=/home/user DISPLAY=:0 /usr/bin/mimeopen -n -M '%s' 2>&1 > /tmp/kde-open.log </dev/null",
|
||||
filename);
|
||||
if (system(cmdbuf))
|
||||
system
|
||||
("HOME=/home/user DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file!'");
|
||||
if (stat(filename, &stat_post)) {
|
||||
perror("stat post");
|
||||
exit(1);
|
||||
}
|
||||
if (stat_pre.st_mtime != stat_post.st_mtime)
|
||||
send_file_back(filename);
|
||||
return 0;
|
||||
}
|
18
appvm/filecopy.h
Normal file
18
appvm/filecopy.h
Normal file
@ -0,0 +1,18 @@
|
||||
#define FILECOPY_SPOOL "/home/user/.filecopyspool"
|
||||
#define FILECOPY_VMNAME_SIZE 32
|
||||
#define PROGRESS_NOTIFY_DELTA (15*1000*1000)
|
||||
#define MAX_PATH_LENGTH 16384
|
||||
|
||||
#define LEGAL_EOF 31415926
|
||||
|
||||
struct file_header {
|
||||
unsigned int namelen;
|
||||
unsigned int mode;
|
||||
unsigned long long filelen;
|
||||
unsigned int atime;
|
||||
unsigned int atime_nsec;
|
||||
unsigned int mtime;
|
||||
unsigned int mtime_nsec;
|
||||
};
|
||||
|
||||
char * copy_file(int outfd, int infd, long long size);
|
139
appvm/qfile-agent-dvm.c
Normal file
139
appvm/qfile-agent-dvm.c
Normal file
@ -0,0 +1,139 @@
|
||||
#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>
|
||||
#include <ioall.h>
|
||||
#include <unistd.h>
|
||||
#include <gui-fatal.h>
|
||||
#include "dvm2.h"
|
||||
|
||||
void send_file(char *fname)
|
||||
{
|
||||
char *base;
|
||||
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;
|
||||
if (!write_all(1, base, DVM_FILENAME_SIZE))
|
||||
gui_fatal("send filename to dispVM");
|
||||
if (!copy_fd_all(1, fd))
|
||||
gui_fatal("send file to dispVM");
|
||||
close(1);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
void recv_file_nowrite(char *fname)
|
||||
{
|
||||
char *tempfile;
|
||||
char *errmsg;
|
||||
int tmpfd;
|
||||
|
||||
asprintf(&tempfile, "/tmp/file_edited_in_dvm.XXXXXX");
|
||||
tmpfd = mkstemp(tempfile);
|
||||
if (tmpfd < 0)
|
||||
gui_fatal("unable to create any temporary file, aborting");
|
||||
if (!copy_and_return_nonemptiness(tmpfd)) {
|
||||
unlink(tempfile);
|
||||
return;
|
||||
}
|
||||
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);
|
||||
gui_nonfatal(errmsg);
|
||||
}
|
||||
|
||||
void actually_recv_file(char *fname, char *tempfile, int tmpfd)
|
||||
{
|
||||
if (!copy_and_return_nonemptiness(tmpfd)) {
|
||||
unlink(tempfile);
|
||||
return;
|
||||
}
|
||||
if (rename(tempfile, fname))
|
||||
gui_fatal("rename");
|
||||
}
|
||||
|
||||
void recv_file(char *fname)
|
||||
{
|
||||
int tmpfd;
|
||||
char *tempfile;
|
||||
asprintf(&tempfile, "%s.XXXXXX", fname);
|
||||
tmpfd = mkstemp(tempfile);
|
||||
if (tmpfd < 0)
|
||||
recv_file_nowrite(fname);
|
||||
else
|
||||
actually_recv_file(fname, tempfile, tmpfd);
|
||||
}
|
||||
|
||||
void talk_to_daemon(char *fname)
|
||||
{
|
||||
send_file(fname);
|
||||
recv_file(fname);
|
||||
}
|
||||
|
||||
void process_spoolentry(char *entry_name)
|
||||
{
|
||||
char *abs_spool_entry_name;
|
||||
int entry_fd;
|
||||
struct stat st;
|
||||
char *filename;
|
||||
int entry_size;
|
||||
asprintf(&abs_spool_entry_name, "%s/%s", DVM_SPOOL, entry_name);
|
||||
entry_fd = open(abs_spool_entry_name, O_RDONLY);
|
||||
unlink(abs_spool_entry_name);
|
||||
if (entry_fd < 0 || fstat(entry_fd, &st))
|
||||
gui_fatal("bad dvm_entry");
|
||||
entry_size = st.st_size;
|
||||
filename = calloc(1, entry_size + DVM_FILENAME_SIZE);
|
||||
if (!filename)
|
||||
gui_fatal("malloc");
|
||||
if (!read_all(entry_fd, filename, entry_size))
|
||||
gui_fatal("read dvm entry %s", abs_spool_entry_name);
|
||||
close(entry_fd);
|
||||
talk_to_daemon(filename);
|
||||
}
|
||||
|
||||
void scan_spool(char *name)
|
||||
{
|
||||
struct dirent *ent;
|
||||
DIR *dir = opendir(name);
|
||||
if (!dir)
|
||||
gui_fatal("opendir %s", name);
|
||||
while ((ent = readdir(dir))) {
|
||||
char *fname = ent->d_name;
|
||||
if (!strcmp(fname, ".") || !strcmp(fname, ".."))
|
||||
continue;
|
||||
process_spoolentry(fname);
|
||||
break;
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
scan_spool(DVM_SPOOL);
|
||||
return 0;
|
||||
}
|
215
appvm/qfile-agent.c
Normal file
215
appvm/qfile-agent.c
Normal file
@ -0,0 +1,215 @@
|
||||
#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>
|
||||
#include <ioall.h>
|
||||
#include <unistd.h>
|
||||
#include <gui-fatal.h>
|
||||
#include "filecopy.h"
|
||||
|
||||
enum {
|
||||
PROGRESS_FLAG_NORMAL,
|
||||
PROGRESS_FLAG_INIT,
|
||||
PROGRESS_FLAG_DONE
|
||||
};
|
||||
|
||||
|
||||
|
||||
char *client_flags;
|
||||
void do_notify_progress(long long total, int flag)
|
||||
{
|
||||
FILE *progress;
|
||||
if (!client_flags[0])
|
||||
return;
|
||||
progress = fopen(client_flags, "w");
|
||||
if (!progress)
|
||||
return;
|
||||
fprintf(progress, "%d %lld %s", getpid(), total,
|
||||
flag == PROGRESS_FLAG_DONE ? "DONE" : "BUSY");
|
||||
fclose(progress);
|
||||
}
|
||||
|
||||
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)) {
|
||||
do_notify_progress(total, flag);
|
||||
prev_total = total;
|
||||
}
|
||||
}
|
||||
|
||||
void write_headers(struct file_header *hdr, char *filename)
|
||||
{
|
||||
if (!write_all(1, hdr, sizeof(*hdr))
|
||||
|| !write_all(1, filename, hdr->namelen))
|
||||
gui_fatal("writing file headers to remove AppVM");
|
||||
}
|
||||
|
||||
int single_file_processor(char *filename, struct stat *st)
|
||||
{
|
||||
struct file_header hdr;
|
||||
int fd;
|
||||
mode_t mode = st->st_mode;
|
||||
|
||||
hdr.namelen = strlen(filename) + 1;
|
||||
hdr.mode = mode;
|
||||
hdr.atime = st->st_atim.tv_sec;
|
||||
hdr.atime_nsec = st->st_atim.tv_nsec;
|
||||
hdr.mtime = st->st_mtim.tv_sec;
|
||||
hdr.mtime_nsec = st->st_mtim.tv_nsec;
|
||||
|
||||
if (S_ISREG(mode)) {
|
||||
char *ret;
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (!fd)
|
||||
gui_fatal("open %s", filename);
|
||||
hdr.filelen = st->st_size;
|
||||
write_headers(&hdr, filename);
|
||||
ret = copy_file(1, fd, hdr.filelen);
|
||||
if (ret)
|
||||
gui_fatal("Copying file %s: %s", filename, ret);
|
||||
close(fd);
|
||||
}
|
||||
if (S_ISDIR(mode)) {
|
||||
hdr.filelen = 0;
|
||||
write_headers(&hdr, filename);
|
||||
}
|
||||
if (S_ISLNK(mode)) {
|
||||
char name[st->st_size + 1];
|
||||
if (readlink(filename, name, sizeof(name)) != st->st_size)
|
||||
gui_fatal("readlink %s", filename);
|
||||
hdr.filelen = st->st_size + 1;
|
||||
write_headers(&hdr, filename);
|
||||
if (!write_all(1, name, st->st_size + 1))
|
||||
gui_fatal("write to remote VM");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_fs_walk(char *file)
|
||||
{
|
||||
char *newfile;
|
||||
struct stat st;
|
||||
struct dirent *ent;
|
||||
DIR *dir;
|
||||
|
||||
if (lstat(file, &st))
|
||||
gui_fatal("stat %s", file);
|
||||
single_file_processor(file, &st);
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
return 0;
|
||||
dir = opendir(file);
|
||||
if (!dir)
|
||||
gui_fatal("opendir %s", file);
|
||||
while ((ent = readdir(dir))) {
|
||||
char *fname = ent->d_name;
|
||||
if (!strcmp(fname, ".") || !strcmp(fname, ".."))
|
||||
continue;
|
||||
asprintf(&newfile, "%s/%s", file, fname);
|
||||
do_fs_walk(newfile);
|
||||
free(newfile);
|
||||
}
|
||||
closedir(dir);
|
||||
// directory metadata is resent; this makes the code simple,
|
||||
// and the atime/mtime is set correctly at the second time
|
||||
single_file_processor(file, &st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void send_vmname(char *vmname)
|
||||
{
|
||||
char buf[FILECOPY_VMNAME_SIZE];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
strncat(buf, vmname, sizeof(buf) - 1);
|
||||
if (!write_all(1, buf, sizeof buf))
|
||||
gui_fatal("writing vmname to remote VM");
|
||||
}
|
||||
|
||||
char *get_item(char *data, char **current, int size)
|
||||
{
|
||||
char *ret;
|
||||
if ((unsigned long) *current >= (unsigned long) data + size)
|
||||
return NULL;
|
||||
ret = *current;
|
||||
*current += strlen(ret) + 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void parse_entry(char *data, int datasize)
|
||||
{
|
||||
char *current = data;
|
||||
char *vmname, *entry, *sep;
|
||||
vmname = get_item(data, ¤t, datasize);
|
||||
client_flags = get_item(data, ¤t, datasize);
|
||||
notify_progress(0, PROGRESS_FLAG_INIT);
|
||||
send_vmname(vmname);
|
||||
while ((entry = get_item(data, ¤t, datasize))) {
|
||||
do {
|
||||
sep = rindex(entry, '/');
|
||||
if (!sep)
|
||||
gui_fatal
|
||||
("Internal error: nonabsolute filenames not allowed");
|
||||
*sep = 0;
|
||||
} while (sep[1] == 0);
|
||||
if (entry[0] == 0)
|
||||
chdir("/");
|
||||
else if (chdir(entry))
|
||||
gui_fatal("chdir to %s", entry);
|
||||
do_fs_walk(sep + 1);
|
||||
}
|
||||
notify_progress(0, PROGRESS_FLAG_DONE);
|
||||
}
|
||||
|
||||
void process_spoolentry(char *entry_name)
|
||||
{
|
||||
char *abs_spool_entry_name;
|
||||
int entry_fd;
|
||||
struct stat st;
|
||||
char *entry;
|
||||
int entry_size;
|
||||
asprintf(&abs_spool_entry_name, "%s/%s", FILECOPY_SPOOL,
|
||||
entry_name);
|
||||
entry_fd = open(abs_spool_entry_name, O_RDONLY);
|
||||
unlink(abs_spool_entry_name);
|
||||
if (entry_fd < 0 || fstat(entry_fd, &st))
|
||||
gui_fatal("bad file copy spool entry");
|
||||
entry_size = st.st_size;
|
||||
entry = calloc(1, entry_size + 1);
|
||||
if (!entry)
|
||||
gui_fatal("malloc");
|
||||
if (!read_all(entry_fd, entry, entry_size))
|
||||
gui_fatal("read filecopy entry");
|
||||
close(entry_fd);
|
||||
parse_entry(entry, entry_size);
|
||||
}
|
||||
|
||||
void scan_spool(char *name)
|
||||
{
|
||||
struct dirent *ent;
|
||||
DIR *dir = opendir(name);
|
||||
if (!dir)
|
||||
gui_fatal("opendir %s", name);
|
||||
while ((ent = readdir(dir))) {
|
||||
char *fname = ent->d_name;
|
||||
if (fname[0] != '.') {
|
||||
process_spoolentry(fname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
scan_spool(FILECOPY_SPOOL);
|
||||
return 0;
|
||||
}
|
83
appvm/qfile-unpacker.c
Normal file
83
appvm/qfile-unpacker.c
Normal file
@ -0,0 +1,83 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <ioall.h>
|
||||
#include <grp.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/fsuid.h>
|
||||
#include <gui-fatal.h>
|
||||
#include <errno.h>
|
||||
#include "filecopy.h"
|
||||
#define INCOMING_DIR_ROOT "/home/user/incoming"
|
||||
int prepare_creds_return_uid(char *username)
|
||||
{
|
||||
struct passwd *pwd;
|
||||
pwd = getpwnam(username);
|
||||
if (!pwd) {
|
||||
perror("getpwnam");
|
||||
exit(1);
|
||||
}
|
||||
setenv("HOME", pwd->pw_dir, 1);
|
||||
setenv("USER", username, 1);
|
||||
setgid(pwd->pw_gid);
|
||||
initgroups(username, pwd->pw_gid);
|
||||
setfsuid(pwd->pw_uid);
|
||||
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);
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
char *incoming_dir;
|
||||
int pipefds[2];
|
||||
int uid;
|
||||
|
||||
pipe(pipefds);
|
||||
|
||||
uid = prepare_creds_return_uid("user");
|
||||
|
||||
mkdir(INCOMING_DIR_ROOT, 0700);
|
||||
asprintf(&incoming_dir, "%s/from-%s", INCOMING_DIR_ROOT, argv[1]);
|
||||
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:;
|
||||
}
|
||||
|
||||
setuid(uid);
|
||||
close(pipefds[1]);
|
||||
wait_for_child(pipefds[0]);
|
||||
|
||||
return 0;
|
||||
}
|
46
appvm/qvm-copy-to-vm2
Executable file
46
appvm/qvm-copy-to-vm2
Executable file
@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
if [ $# -lt 2 ] ; then
|
||||
echo usage: $0 'vmname file [file]*'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FILECOPY_SPOOL=/home/user/.filecopyspool
|
||||
if ! [ -e $FILECOPY_SPOOL ] ; then
|
||||
mkdir $FILECOPY_SPOOL
|
||||
fi
|
||||
|
||||
REQ_FILE_TMP=$FILECOPY_SPOOL/.req.$$
|
||||
echo -ne "$1""\x00" > $REQ_FILE_TMP
|
||||
echo -ne "$PROGRESS_FILE""\x00" >> $REQ_FILE_TMP
|
||||
|
||||
shift
|
||||
for FILE in "$@" ; do
|
||||
if ! [ "X""${FILE:0:1}" = X/ ] ; then
|
||||
FILE="$PWD"/"$FILE"
|
||||
fi
|
||||
echo -ne "$FILE""\x00" >> $REQ_FILE_TMP
|
||||
done
|
||||
|
||||
mv $REQ_FILE_TMP $FILECOPY_SPOOL/req.$$
|
||||
echo -n FCPR > /var/run/qubes/qrexec_agent
|
48
appvm/qvm-copy-to-vm2.kde
Executable file
48
appvm/qvm-copy-to-vm2.kde
Executable file
@ -0,0 +1,48 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
VM=$(kdialog -inputbox "Enter the VM name to send files to:")
|
||||
if [ X$VM = X ] ; then exit 0 ; fi
|
||||
|
||||
SIZE=$(du -c "$@" | tail -1 | cut -f 1)
|
||||
REF=$(kdialog --progressbar "Copy progress")
|
||||
qdbus $REF org.freedesktop.DBus.Properties.Set "" maximum $SIZE
|
||||
|
||||
export PROGRESS_FILE=$(mktemp)
|
||||
qvm-copy-to-vm2 $VM "$@"
|
||||
while ! [ -s $PROGRESS_FILE ] ; do
|
||||
sleep 0.1
|
||||
done
|
||||
while true ; do
|
||||
read agentpid sentsize agentstatus < $PROGRESS_FILE
|
||||
if ! [ -e /proc/$agentpid ] ; then break ; fi
|
||||
if [ "x"$agentstatus = xdone ] ; then break ; fi
|
||||
CURRSIZE=$(($sentsize/1024))
|
||||
qdbus $REF org.freedesktop.DBus.Properties.Set "" value $CURRSIZE
|
||||
sleep 0.4
|
||||
done
|
||||
|
||||
qdbus $REF close
|
||||
rm -f $PROGRESS_FILE
|
||||
if ! [ "x"$agentstatus = xDONE ] ; then
|
||||
kdialog --sorry 'Abnormal file copy termination; see /var/log/qubes/qrexec.xid.log in dom0 for more details'
|
||||
fi
|
@ -4,7 +4,7 @@ Type=Service
|
||||
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,inode/directory,all/allfiles
|
||||
|
||||
[Desktop Action QvmCopy]
|
||||
Exec=/usr/lib/qubes/qvm-copy-to-vm.kde %U
|
||||
Exec=/usr/lib/qubes/qvm-copy-to-vm2.kde %U
|
||||
Icon=kget
|
||||
Name=Send To VM
|
||||
|
||||
|
@ -4,7 +4,7 @@ Type=Service
|
||||
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,all/allfiles
|
||||
|
||||
[Desktop Action QvmDvm]
|
||||
Exec=/usr/bin/qvm-open-in-dvm disposable %U
|
||||
Exec=/usr/bin/qvm-open-in-dvm2 %U
|
||||
Icon=kget
|
||||
Name=Open In DisposableVM
|
||||
|
||||
|
40
appvm/qvm-open-in-dvm2
Executable file
40
appvm/qvm-open-in-dvm2
Executable file
@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
if ! [ $# = 1 ] ; then
|
||||
echo "Usage: $0 filename"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FILE="$1"
|
||||
if ! [ "X""${FILE:0:1}" = X/ ] ; then
|
||||
FILE="$PWD"/"$1"
|
||||
fi
|
||||
|
||||
DVMSPOOL=/home/user/.dvmspool
|
||||
if ! [ -e $DVMSPOOL ] ; then
|
||||
mkdir $DVMSPOOL || exit 1
|
||||
fi
|
||||
|
||||
echo -n "$FILE" > $DVMSPOOL/req.$$
|
||||
echo -n DVMR > /var/run/qubes/qrexec_agent
|
||||
|
105
appvm/unpack.c
Normal file
105
appvm/unpack.c
Normal file
@ -0,0 +1,105 @@
|
||||
#include <errno.h>
|
||||
#include <ioall.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include "filecopy.h"
|
||||
|
||||
char namebuf[MAX_PATH_LENGTH];
|
||||
void notify_progress(int p1, int p2)
|
||||
{
|
||||
}
|
||||
|
||||
int global_status_fd;
|
||||
void do_exit(int code)
|
||||
{
|
||||
int codebuf = code;
|
||||
write(global_status_fd, &codebuf, sizeof codebuf);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void fix_times_and_perms(struct file_header *hdr, char *name)
|
||||
{
|
||||
struct timeval times[2] =
|
||||
{ {hdr->atime, hdr->atime_nsec / 1000}, {hdr->mtime,
|
||||
hdr->mtime_nsec / 1000}
|
||||
};
|
||||
if (chmod(name, hdr->mode & 07777))
|
||||
do_exit(errno);
|
||||
if (utimes(name, times))
|
||||
do_exit(errno);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void process_one_file_reg(struct file_header *hdr, char *name)
|
||||
{
|
||||
char *ret;
|
||||
int fdout =
|
||||
open(name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0700);
|
||||
if (fdout < 0)
|
||||
do_exit(errno);
|
||||
ret = copy_file(fdout, 0, hdr->filelen);
|
||||
if (ret)
|
||||
do_exit(errno);
|
||||
close(fdout);
|
||||
fix_times_and_perms(hdr, name);
|
||||
}
|
||||
|
||||
|
||||
void process_one_file_dir(struct file_header *hdr, char *name)
|
||||
{
|
||||
// fix perms only when the directory is sent for the second time
|
||||
// it allows to transfer r.x directory contents, as we create it rwx initially
|
||||
if (!mkdir(name, 0700))
|
||||
return;
|
||||
if (errno != EEXIST)
|
||||
do_exit(errno);
|
||||
fix_times_and_perms(hdr, name);
|
||||
}
|
||||
|
||||
void process_one_file_link(struct file_header *hdr, char *name)
|
||||
{
|
||||
char content[MAX_PATH_LENGTH];
|
||||
if (hdr->filelen > MAX_PATH_LENGTH - 1)
|
||||
do_exit(ENAMETOOLONG);
|
||||
if (!read_all(0, content, hdr->filelen))
|
||||
do_exit(errno);
|
||||
content[hdr->filelen] = 0;
|
||||
if (symlink(content, name))
|
||||
do_exit(errno);
|
||||
|
||||
}
|
||||
|
||||
void process_one_file(struct file_header *hdr)
|
||||
{
|
||||
if (hdr->namelen > MAX_PATH_LENGTH - 1)
|
||||
do_exit(ENAMETOOLONG);
|
||||
if (!read_all(0, namebuf, hdr->namelen))
|
||||
do_exit(errno);
|
||||
namebuf[hdr->namelen] = 0;
|
||||
if (S_ISREG(hdr->mode))
|
||||
process_one_file_reg(hdr, namebuf);
|
||||
else if (S_ISLNK(hdr->mode))
|
||||
process_one_file_link(hdr, namebuf);
|
||||
else if (S_ISDIR(hdr->mode))
|
||||
process_one_file_dir(hdr, namebuf);
|
||||
else
|
||||
do_exit(EINVAL);
|
||||
}
|
||||
|
||||
void do_unpack(int fd)
|
||||
{
|
||||
global_status_fd = fd;
|
||||
struct file_header hdr;
|
||||
while (read_all(0, &hdr, sizeof hdr))
|
||||
process_one_file(&hdr);
|
||||
if (errno)
|
||||
do_exit(errno);
|
||||
else
|
||||
do_exit(LEGAL_EOF);
|
||||
}
|
@ -174,12 +174,18 @@ case "$command" in
|
||||
dmsetup remove $snap
|
||||
fi
|
||||
done
|
||||
# Commit template changes
|
||||
domain=$(xenstore_read "$XENBUS_PATH/domain")
|
||||
if [ "$domain" ]; then
|
||||
# Dont stop on errors
|
||||
/usr/bin/qvm-template-commit "$domain" || true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -e $node ]; then
|
||||
if [ -e $node ]; then
|
||||
log debug "Removing $node"
|
||||
dmsetup remove $node
|
||||
fi
|
||||
fi
|
||||
|
||||
# try to free loop devices
|
||||
for dev in $deps; do
|
||||
|
@ -7,8 +7,8 @@
|
||||
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
|
||||
#
|
||||
/dev/mapper/dmroot / ext4 defaults,noatime 1 1
|
||||
/dev/mapper/dmswap swap swap defaults 0 0
|
||||
/dev/xvdb /rw ext4 noauto,defaults 0 0
|
||||
/dev/xvdc1 swap swap defaults 0 0
|
||||
tmpfs /dev/shm tmpfs defaults 0 0
|
||||
devpts /dev/pts devpts gid=5,mode=620 0 0
|
||||
sysfs /sys sysfs defaults 0 0
|
||||
|
50
common/gui-fatal.c
Normal file
50
common/gui-fatal.c
Normal file
@ -0,0 +1,50 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static void fix_display()
|
||||
{
|
||||
setenv("DISPLAY", ":0", 1);
|
||||
}
|
||||
|
||||
static void produce_message(char * type, const char *fmt, va_list args)
|
||||
{
|
||||
char *kdialog_msg;
|
||||
char buf[1024];
|
||||
(void) vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
asprintf(&kdialog_msg, "%s: %s: %s (error type: %s)",
|
||||
program_invocation_short_name, type, buf, strerror(errno));
|
||||
fprintf(stderr, "%s", kdialog_msg);
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
exit(1); //what else
|
||||
case 0:
|
||||
fix_display();
|
||||
execlp("kdialog", "kdialog", "--sorry", kdialog_msg, NULL);
|
||||
exit(1);
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
void gui_fatal(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
produce_message("Fatal error", fmt, args);
|
||||
va_end(args);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void gui_nonfatal(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
produce_message("Information", fmt, args);
|
||||
va_end(args);
|
||||
}
|
2
common/gui-fatal.h
Normal file
2
common/gui-fatal.h
Normal file
@ -0,0 +1,2 @@
|
||||
void gui_fatal(const char *fmt, ...);
|
||||
void gui_nonfatal(const char *fmt, ...);
|
97
common/ioall.c
Normal file
97
common/ioall.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
void perror_wrapper(char * msg)
|
||||
{
|
||||
int prev=errno;
|
||||
perror(msg);
|
||||
errno=prev;
|
||||
}
|
||||
|
||||
|
||||
int write_all(int fd, void *buf, int size)
|
||||
{
|
||||
int written = 0;
|
||||
int ret;
|
||||
while (written < size) {
|
||||
ret = write(fd, (char *) buf + written, size - written);
|
||||
if (ret == -1 && errno == EINTR)
|
||||
continue;
|
||||
if (ret <= 0) {
|
||||
perror_wrapper("write");
|
||||
return 0;
|
||||
}
|
||||
written += ret;
|
||||
}
|
||||
// fprintf(stderr, "sent %d bytes\n", size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int read_all(int fd, void *buf, int size)
|
||||
{
|
||||
int got_read = 0;
|
||||
int ret;
|
||||
while (got_read < size) {
|
||||
ret = read(fd, (char *) buf + got_read, size - got_read);
|
||||
if (ret == -1 && errno == EINTR)
|
||||
continue;
|
||||
if (ret == 0) {
|
||||
errno = 0;
|
||||
fprintf(stderr, "EOF\n");
|
||||
return 0;
|
||||
}
|
||||
if (ret < 0) {
|
||||
perror_wrapper("read");
|
||||
return 0;
|
||||
}
|
||||
got_read += ret;
|
||||
}
|
||||
// fprintf(stderr, "read %d bytes\n", size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int copy_fd_all(int fdout, int fdin)
|
||||
{
|
||||
int ret;
|
||||
char buf[4096];
|
||||
for (;;) {
|
||||
ret = read(fdin, buf, sizeof(buf));
|
||||
if (ret == -1 && errno == EINTR)
|
||||
continue;
|
||||
if (!ret)
|
||||
break;
|
||||
if (ret < 0) {
|
||||
perror_wrapper("read");
|
||||
return 0;
|
||||
}
|
||||
if (!write_all(fdout, buf, ret)) {
|
||||
perror_wrapper("write");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
3
common/ioall.h
Normal file
3
common/ioall.h
Normal file
@ -0,0 +1,3 @@
|
||||
int write_all(int fd, void *buf, int size);
|
||||
int read_all(int fd, void *buf, int size);
|
||||
int copy_fd_all(int fdout, int fdin);
|
@ -54,6 +54,8 @@ start()
|
||||
fi
|
||||
fi
|
||||
|
||||
/usr/lib/qubes/qrexec_agent 2>/var/log/qubes/qrexec_agent.log &
|
||||
|
||||
[ -x /rw/config/rc.local ] && /rw/config/rc.local
|
||||
success
|
||||
echo ""
|
||||
|
@ -32,6 +32,7 @@ start()
|
||||
/usr/lib/qubes/qubes_setup_dnat_to_ns
|
||||
echo "1" > /proc/sys/net/ipv4/ip_forward
|
||||
fi
|
||||
|
||||
success
|
||||
echo ""
|
||||
return 0
|
||||
|
@ -32,7 +32,7 @@ Vendor: Invisible Things Lab
|
||||
License: GPL
|
||||
URL: http://www.qubes-os.org
|
||||
Requires: /usr/bin/xenstore-read
|
||||
Requires: fedora-release = 13
|
||||
Requires: fedora-release
|
||||
Requires: /usr/bin/mimeopen
|
||||
Requires: qubes-core-commonvm
|
||||
BuildRequires: gcc
|
||||
@ -60,6 +60,9 @@ mkdir -p $RPM_BUILD_ROOT/var/lib/qubes
|
||||
%build
|
||||
make clean all
|
||||
make -C ../common
|
||||
make -C ../qrexec
|
||||
make -C ../vchan
|
||||
make -C ../u2mfn
|
||||
|
||||
%install
|
||||
|
||||
@ -67,9 +70,13 @@ mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
||||
cp qubes_core_appvm $RPM_BUILD_ROOT/etc/init.d/
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/qubes
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/bin
|
||||
cp qubes_timestamp qvm-copy-to-vm qvm-open-in-dvm $RPM_BUILD_ROOT/usr/bin
|
||||
cp qubes_timestamp qvm-copy-to-vm qvm-open-in-dvm qvm-open-in-dvm2 $RPM_BUILD_ROOT/usr/bin
|
||||
cp qvm-copy-to-vm2 $RPM_BUILD_ROOT/usr/bin
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp qubes_add_pendrive_script qubes_penctl qvm-copy-to-vm.kde $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp qvm-copy-to-vm2.kde $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp ../qrexec/qrexec_agent $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
cp dvm_file_editor qfile-agent qfile-agent-dvm qfile-unpacker $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
ln -s /usr/bin/qvm-open-in-dvm $RPM_BUILD_ROOT/usr/lib/qubes/qvm-dvm-transfer
|
||||
cp ../common/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes
|
||||
mkdir -p $RPM_BUILD_ROOT/%{kde_service_dir}
|
||||
@ -86,6 +93,18 @@ cp xorg-preload-apps.conf $RPM_BUILD_ROOT/etc/X11
|
||||
mkdir -p $RPM_BUILD_ROOT/home_volatile/user
|
||||
chown 500:500 $RPM_BUILD_ROOT/home_volatile/user
|
||||
|
||||
install -D ../vchan/libvchan.h $RPM_BUILD_ROOT/usr/include/libvchan.h
|
||||
install -D ../u2mfn/u2mfnlib.h $RPM_BUILD_ROOT/usr/include/u2mfnlib.h
|
||||
install -D ../u2mfn/u2mfn-kernel.h $RPM_BUILD_ROOT/usr/include/u2mfn-kernel.h
|
||||
|
||||
install -D ../vchan/libvchan.so $RPM_BUILD_ROOT/%{_libdir}/libvchan.so
|
||||
install -D ../u2mfn/libu2mfn.so $RPM_BUILD_ROOT/%{_libdir}/libu2mfn.so
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/var/run/qubes
|
||||
|
||||
%triggerin -- initscripts
|
||||
cp /var/lib/qubes/serial.conf /etc/init/serial.conf
|
||||
|
||||
%post
|
||||
|
||||
chkconfig --add qubes_core_appvm || echo "WARNING: Cannot add service qubes_core!"
|
||||
@ -111,14 +130,22 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%defattr(-,root,root,-)
|
||||
/etc/init.d/qubes_core_appvm
|
||||
/usr/bin/qvm-copy-to-vm
|
||||
/usr/bin/qvm-copy-to-vm2
|
||||
/usr/lib/qubes/qvm-copy-to-vm.kde
|
||||
/usr/lib/qubes/qvm-copy-to-vm2.kde
|
||||
%attr(4755,root,root) /usr/bin/qvm-open-in-dvm
|
||||
/usr/bin/qvm-open-in-dvm2
|
||||
/usr/lib/qubes/qvm-dvm-transfer
|
||||
/usr/lib/qubes/meminfo-writer
|
||||
/usr/lib/qubes/dvm_file_editor
|
||||
%{kde_service_dir}/qvm-copy.desktop
|
||||
%{kde_service_dir}/qvm-dvm.desktop
|
||||
%attr(4755,root,root) /usr/lib/qubes/qubes_penctl
|
||||
/usr/lib/qubes/qubes_add_pendrive_script
|
||||
/usr/lib/qubes/qrexec_agent
|
||||
/usr/lib/qubes/qfile-agent
|
||||
/usr/lib/qubes/qfile-agent-dvm
|
||||
/usr/lib/qubes/qfile-unpacker
|
||||
/etc/udev/rules.d/qubes.rules
|
||||
%dir /mnt/incoming
|
||||
%dir /mnt/outgoing
|
||||
@ -127,3 +154,20 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%dir /home_volatile
|
||||
%attr(700,user,user) /home_volatile/user
|
||||
/etc/X11/xorg-preload-apps.conf
|
||||
/usr/include/libvchan.h
|
||||
%{_libdir}/libvchan.so
|
||||
%{_libdir}/libu2mfn.so
|
||||
%dir /var/run/qubes
|
||||
|
||||
|
||||
%package devel
|
||||
Summary: Include files for qubes core libraries
|
||||
License: GPL v2 only
|
||||
Group: Development/Sources
|
||||
|
||||
%description devel
|
||||
|
||||
%files devel
|
||||
/usr/include/libvchan.h
|
||||
/usr/include/u2mfnlib.h
|
||||
/usr/include/u2mfn-kernel.h
|
||||
|
@ -32,7 +32,7 @@ Vendor: Invisible Things Lab
|
||||
License: GPL
|
||||
URL: http://www.qubes-os.org
|
||||
Requires: /usr/bin/xenstore-read
|
||||
Requires: fedora-release = 13
|
||||
Requires: fedora-release
|
||||
|
||||
%define _builddir %(pwd)/common
|
||||
|
||||
@ -101,6 +101,7 @@ do
|
||||
[ $srv = 'killall' ] && continue
|
||||
[ $srv = 'halt' ] && continue
|
||||
[ $srv = 'single' ] && continue
|
||||
[ $srv = 'reboot' ] && continue
|
||||
[ $srv = 'qubes_gui' ] && continue
|
||||
chkconfig $srv off
|
||||
done
|
||||
|
@ -32,7 +32,7 @@ Vendor: Invisible Things Lab
|
||||
License: GPL
|
||||
URL: http://www.qubes-os.org
|
||||
Requires: /usr/bin/xenstore-read
|
||||
Requires: fedora-release = 13
|
||||
Requires: fedora-release
|
||||
Requires: NetworkManager >= 0.8.1-1
|
||||
Requires: qubes-core-commonvm
|
||||
Provides: qubes-core-vm
|
||||
@ -45,6 +45,8 @@ The Qubes core files for installation inside a Qubes NetVM.
|
||||
%pre
|
||||
|
||||
%build
|
||||
make -C ../vchan
|
||||
make -C ../u2mfn
|
||||
|
||||
%install
|
||||
|
||||
@ -89,4 +91,3 @@ rm -rf $RPM_BUILD_ROOT
|
||||
/etc/NetworkManager/dispatcher.d/qubes_nmhook
|
||||
/etc/NetworkManager/dispatcher.d/30-qubes_external_ip
|
||||
/etc/xen/scripts/vif-route-qubes
|
||||
%dir /var/run/qubes
|
||||
|
@ -33,7 +33,7 @@ License: GPL
|
||||
URL: http://www.qubes-os.org
|
||||
Requires: /usr/bin/xenstore-read
|
||||
Requires: /sbin/ethtool
|
||||
Requires: fedora-release = 13
|
||||
Requires: fedora-release
|
||||
Requires: qubes-core-netvm
|
||||
|
||||
%define _builddir %(pwd)/proxyvm
|
||||
|
Loading…
Reference in New Issue
Block a user