Merge branch 'spring-merge' of ssh://git.qubes-os.org/var/lib/qubes/git/rafal/core

This commit is contained in:
Marek Marczykowski 2011-03-24 16:43:13 -04:00
commit 6c2a6d4d4d
11 changed files with 5 additions and 682 deletions

View File

@ -1,6 +1,6 @@
CC=gcc
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
all: 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
@ -9,13 +9,6 @@ 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
$(CC) -o qubes_add_pendrive_script qubes_add_pendrive_script.o -lxenstore
qvm-open-in-dvm: qvm-open-in-dvm.o
$(CC) -o qvm-open-in-dvm qvm-open-in-dvm.o -lxenstore
clean:
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
rm -f qfile-agent-dvm qfile-agent qfile-unpacker dvm_file_editor *.o *~

View File

@ -1,6 +0,0 @@
#define DBDIR "/home/user/.dvm"
struct dvm_header {
unsigned long long file_size;
char name[1024-sizeof(unsigned long long)];
};

View File

@ -58,11 +58,11 @@ main()
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",
"HOME=/home/user DISPLAY=:0 /usr/bin/mimeopen -n -M '%s' > /tmp/kde-open.log 2>&1 </dev/null",
filename);
if (system(cmdbuf))
system
("HOME=/home/user DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file!'");
("HOME=/home/user DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file!' > /tmp/kdialog.log 2>&1 </dev/null");
if (stat(filename, &stat_post)) {
perror("stat post");
exit(1);

View File

@ -1 +0,0 @@
SUBSYSTEM=="block", KERNEL=="xvdh", ACTION=="add", RUN+="/usr/lib/qubes/qubes_add_pendrive_script"

View File

@ -1,284 +0,0 @@
/*
* 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 <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/inotify.h>
#include <fcntl.h>
#include <stdlib.h>
#include <xs.h>
#include <syslog.h>
#include <sys/stat.h>
#include <string.h>
#include "dvm.h"
int parse_events(char *buf, int len)
{
int i = 0;
while (i < len) {
struct inotify_event *ev =
(struct inotify_event *) (buf + i);
if ((ev->mask & IN_UNMOUNT) || (ev->mask & IN_IGNORED))
return 1;
i += sizeof(struct inotify_event) + ev->len;
}
return 0;
}
#define BUFLEN 1024
void wait_for_umount(char *name)
{
char buf[BUFLEN];
int fd = inotify_init();
int len;
int ret = inotify_add_watch(fd, name, IN_ATTRIB);
if (ret < 0) {
perror("inotify_add_watch");
return;
}
for (;;) {
len = read(fd, buf, BUFLEN - 1);
if (len <= 0) {
perror("read inotify");
return;
}
if (parse_events(buf, len))
return;
}
}
void background()
{
int i, fd;
for (i = 0; i < 256; i++)
close(i);
fd = open("/dev/null", O_RDWR);
for (i = 0; i <= 2; i++)
dup2(fd, i);
switch (fork()) {
case -1:
exit(1);
case 0:
break;
default:
exit(0);
}
}
int check_legal_filename(char *name)
{
if (index(name, '/')) {
syslog(LOG_DAEMON | LOG_ERR,
"the received filename contains /");
return 0;
}
return 1;
}
void drop_to_user()
{
struct passwd *pw = getpwnam("user");
if (pw)
setuid(pw->pw_uid);
}
int copy_from_xvdh(int destfd, int srcfd, unsigned long long count)
{
int n, size;
char buf[4096];
unsigned long long total = 0;
while (total < count) {
if (count - total > sizeof(buf))
size = sizeof(buf);
else
size = count - total;
n = read(srcfd, buf, size);
if (n != size) {
syslog(LOG_DAEMON | LOG_ERR, "reading xvdh");
return 0;
}
if (write(destfd, buf, size) != size) {
syslog(LOG_DAEMON | LOG_ERR, "writing file");
return 0;
}
total += size;
}
return 1;
}
void redirect_stderr()
{
int fd =
open("/var/log/dvm.log", O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (fd < 0) {
syslog(LOG_DAEMON | LOG_ERR, "open dvm.log");
exit(1);
}
dup2(fd, 2);
}
void suicide(struct xs_handle *xs)
{
xs_write(xs, XBT_NULL, "device/qpen", "killme", 6);
xs_daemon_close(xs);
exit(1);
}
// we are DVM, AppVM sends us a document to work on
// /dev/xvdh contains the dvm_header and document data
void dvm_transaction_request(char *seq, struct xs_handle *xs)
{
char filename[1024], cmdbuf[1024];
struct dvm_header header;
int xvdh_fd, file_fd;
char *src_vm;
unsigned int len;
struct stat stat_pre, stat_post;
xvdh_fd = open("/dev/xvdh", O_RDONLY);
if (read(xvdh_fd, &header, sizeof(header)) != sizeof(header)) {
syslog(LOG_DAEMON | LOG_ERR, "read dvm_header");
suicide(xs);
}
header.name[sizeof(header.name) - 1] = 0;
if (!check_legal_filename(header.name))
suicide(xs);
snprintf(filename, sizeof(filename), "/tmp/%s", header.name);
drop_to_user();
file_fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (file_fd < 0) {
syslog(LOG_DAEMON | LOG_ERR, "open file");
suicide(xs);
}
if (!copy_from_xvdh(file_fd, xvdh_fd, header.file_size))
suicide(xs);
close(xvdh_fd);
close(file_fd);
if (stat(filename, &stat_pre)) {
syslog(LOG_DAEMON | LOG_ERR, "stat pre");
suicide(xs);
}
snprintf(cmdbuf, sizeof(cmdbuf),
"HOME=/home/user DISPLAY=:0 /usr/bin/mimeopen -n -M '/tmp/%s' 2>&1 > /tmp/kde-open.log", header.name);
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)) {
syslog(LOG_DAEMON | LOG_ERR, "stat post");
suicide(xs);
}
src_vm = xs_read(xs, XBT_NULL, "qubes_blocksrc", &len);
xs_write(xs, XBT_NULL, "device/qpen", "umount", 6);
if (stat_pre.st_mtime == stat_post.st_mtime)
suicide(xs);
xs_daemon_close(xs);
// if the modify timestamp of the document file has changed, write back the
// modified content to the requestor AppVM
execl("/usr/lib/qubes/qvm-dvm-transfer", "qvm-dvm-transfer", src_vm,
filename, seq, NULL);
syslog(LOG_DAEMON | LOG_ERR, "execl qvm-dvm-transfer");
suicide(xs);
}
// we are AppVM, DVM sends us a modified document
// /dev/xvdh contains the dvm_header and document data
void dvm_transaction_return(char *seq_string, struct xs_handle *xs)
{
int seq = strtoul(seq_string, 0, 10);
char db_name[1024];
char file_name[1024];
int db_fd, file_fd, xvdh_fd;
struct dvm_header header;
xvdh_fd = open("/dev/xvdh", O_RDONLY);
if (xvdh_fd < 0) {
syslog(LOG_DAEMON | LOG_ERR, "open xvdh");
goto out_err;
}
if (read(xvdh_fd, &header, sizeof(header)) != sizeof(header)) {
syslog(LOG_DAEMON | LOG_ERR, "read dvm_header");
goto out_err;
}
drop_to_user();
// read the file name for which the open-in-dvm with transaction=="seq" was started
snprintf(db_name, sizeof(db_name), DBDIR "/%d", seq);
db_fd = open(db_name, O_RDONLY);
if (!db_fd) {
syslog(LOG_DAEMON | LOG_ERR, "open db");
goto out_err;
}
if (read(db_fd, file_name, sizeof(file_name)) < 0) {
syslog(LOG_DAEMON | LOG_ERR, "read db");
goto out_err;
}
close(db_fd);
file_fd = open(file_name, O_WRONLY | O_TRUNC);
if (file_fd < 0) {
syslog(LOG_DAEMON | LOG_ERR, "open filename");
goto out_err;
}
copy_from_xvdh(file_fd, xvdh_fd, header.file_size);
close(xvdh_fd);
close(file_fd);
out_err:
xs_write(xs, XBT_NULL, "device/qpen", "umount", 6);
xs_daemon_close(xs);
}
void dvm_transaction(char *seq, struct xs_handle *xs)
{
struct stat st;
redirect_stderr();
if (stat("/etc/this_is_dvm", &st))
dvm_transaction_return(seq, xs);
else
dvm_transaction_request(seq, xs);
}
#define MOUNTDIR "/mnt/incoming"
int main()
{
struct xs_handle *xs;
char *seq;
unsigned int len;
background();
openlog("qubes_add_pendrive_script", LOG_CONS | LOG_PID,
LOG_DAEMON);
xs = xs_domain_open();
if (!xs) {
syslog(LOG_DAEMON | LOG_ERR, "xs_domain_open");
exit(1);
}
seq = xs_read(xs, XBT_NULL, "qubes_transaction_seq", &len);
if (seq && len > 0 && strcmp(seq, "0")) {
dvm_transaction(seq, xs);
exit(0);
}
if (!system("su - user -c 'mount " MOUNTDIR "'"))
wait_for_umount(MOUNTDIR "/.");
xs_write(xs, XBT_NULL, "device/qpen", "umount", 6);
xs_daemon_close(xs);
return 0;
}

View File

@ -1,94 +0,0 @@
/*
* 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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <xs.h>
void check_name(unsigned char *s)
{
int c;
for (; *s; s++) {
c = *s;
if (c >= 'a' && c <= 'z')
continue;
if (c >= 'A' && c <= 'Z')
continue;
if (c == '_' || c == '-')
continue;
if (c >= '0' && c <= '9')
continue;
fprintf(stderr, "invalid string %s\n", s);
exit(1);
}
}
/*
A tool to request action from qfileexchgd by writing to device/qpen xenstore key.
new - please attach a vfat-formatted block device at /dev/xvdg; I will either write some files to it and
then request sending it to other AppVM, or I will place dvm_header+some file on it and send it to DVM
send vmname - detach my /dev/xvdg and attach it to vmname at /dev/xvdh
umount - I am done with my /dev/xvdh, please detach it
*/
void usage(char *argv0)
{
fprintf(stderr, "usage: %s [new|umount]\n"
"%s send vmname [seq]\n", argv0, argv0);
exit(1);
}
int main(int argc, char **argv)
{
char buf[256];
struct xs_handle *xs;
xs = xs_domain_open();
setuid(getuid());
if (!xs) {
perror("xs_domain_open");
exit(1);
}
switch (argc) {
case 2:
if (!strcmp(argv[1], "umount"))
strcpy(buf, "umount");
else
strcpy(buf, "new");
break;
case 3:
check_name((unsigned char *) argv[2]);
snprintf(buf, sizeof(buf), "send %s", argv[2]);
break;
case 4:
check_name((unsigned char *) argv[2]);
check_name((unsigned char *) argv[3]);
snprintf(buf, sizeof(buf), "send %s %s", argv[2], argv[3]);
default:
usage(argv[0]);
}
if (!xs_write(xs, 0, "device/qpen", buf, strlen(buf))) {
perror("xs_write");
exit(1);
}
xs_daemon_close(xs);
return 0;
}

View File

@ -1,40 +0,0 @@
#!/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
/usr/lib/qubes/qubes_penctl new || exit 1
echo -n Waiting for the Qubes virtual pendrive
while ! [ -e /dev/xvdg ] ; do
echo -n .
sleep 1
done
echo " received"
mount /mnt/outgoing
VMNAME=$1
shift
cp -v -a "$@" /mnt/outgoing
#sometimes Dolphin lags a bit
umount /mnt/outgoing || (sleep 1; umount /mnt/outgoing) || exit 1
/usr/lib/qubes/qubes_penctl send $VMNAME || exit 1

View File

@ -1,41 +0,0 @@
#!/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
DEST=/mnt/outgoing
SIZE=$(du -c "$@" | tail -1 | cut -f 1)
REF=$(kdialog --progressbar "Copy progress")
qdbus $REF org.freedesktop.DBus.Properties.Set "" maximum $SIZE
FLAG=$(mktemp)
(qvm-copy-to-vm $VM "$@" ; rm $FLAG) &
while ! grep -q $DEST /proc/mounts && [ -f $FLAG ] ; do
sleep 0.1
done
while grep -q $DEST /proc/mounts ; do
CURRSIZE=$(du -c $DEST | tail -1 | cut -f 1)
qdbus $REF org.freedesktop.DBus.Properties.Set "" value $CURRSIZE
sleep 1
done
qdbus $REF close

View File

@ -1,187 +0,0 @@
/*
* 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.
*
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <xs.h>
#include "dvm.h"
void check_name(unsigned char *s)
{
int c;
for (; *s; s++) {
c = *s;
if (c >= 'a' && c <= 'z')
continue;
if (c >= 'A' && c <= 'Z')
continue;
if (c == '_' || c == '-')
continue;
fprintf(stderr, "invalid string %s\n", s);
exit(1);
}
}
int get_and_set_seq()
{
int seq_fd, seq, n;
mkdir(DBDIR, 0700);
seq_fd = open(DBDIR "/seq", O_CREAT | O_RDWR, 0600);
if (seq_fd < 0) {
perror("open seq_fd");
exit(1);
}
n = read(seq_fd, &seq, sizeof(seq));
if (n < sizeof(seq))
seq = 0;
seq++;
lseek(seq_fd, 0, SEEK_SET);
write(seq_fd, &seq, sizeof(seq));
close(seq_fd);
return seq;
}
/*
Write the filename we are sending to DVM to DBDIR/transaction_seq
When DVM sends us a modified document via transaction with transaction_seq,
we will know that we are supposed to update the document with the
filename at DBDIR/transaction_seq
*/
void write_db(char *name, int seq)
{
int db_fd;
char dbname[256];
struct stat st;
if (!stat("/etc/this_is_dvm", &st))
return;
snprintf(dbname, sizeof(dbname), DBDIR "/%d", seq);
db_fd = open(dbname, O_CREAT | O_WRONLY | O_TRUNC, 0600);
if (db_fd < 0) {
perror("open dbfile");
exit(1);
}
if (write(db_fd, name, strlen(name) + 1) != strlen(name) + 1) {
perror("write db");
exit(1);
}
close(db_fd);
}
void copy_file(int xvdg_fd, int file_fd)
{
int n;
char buf[4096];
for (;;) {
n = read(file_fd, buf, sizeof(buf));
if (n < 0) {
perror("read file");
exit(1);
}
if (n == 0)
break;
if (write(xvdg_fd, buf, n) != n) {
perror("write file");
exit(1);
}
}
}
int main(int argc, char **argv)
{
struct dvm_header header = { 0, };
struct stat st;
struct xs_handle *xs;
int seq;
int xvdg_fd, file_fd;
char *abs_filename;
char buf[4096];
if (argc != 3 && argc != 4) {
fprintf(stderr, "usage: %s vmname file\n", argv[0]);
exit(1);
}
check_name((unsigned char *) argv[1]);
if (argv[2][0] == '/')
abs_filename = argv[2];
else {
char cwd[4096];
getcwd(cwd, sizeof(cwd));
asprintf(&abs_filename, "%s/%s", cwd, argv[2]);
}
if (stat(abs_filename, &st)) {
perror("stat file");
exit(1);
}
header.file_size = st.st_size;
strncpy(header.name, rindex(abs_filename, '/') + 1,
sizeof(header.name) - 1);
xs = xs_domain_open();
if (!xs) {
perror("xs_domain_open");
exit(1);
}
// request a new block device at /dev/xvdg from qfileexchgd
if (!xs_write(xs, 0, "device/qpen", "new", 3)) {
perror("xs_write");
exit(1);
}
while (stat("/dev/xvdg", &st))
usleep(100000);
xvdg_fd = open("/dev/xvdg", O_WRONLY);
if (xvdg_fd < 0) {
perror("open xvdg");
exit(1);
}
setuid(getuid());
if (argc == 3)
// we are AppVM; get new seq
seq = get_and_set_seq();
else
// we are DVM; use the cmdline transaction_seq
seq = strtoul(argv[3], 0, 0);
file_fd = open(abs_filename, O_RDONLY);
if (file_fd < 0) {
perror("open file");
exit(1);
}
if (write(xvdg_fd, &header, sizeof(header)) != sizeof(header)) {
perror("write filesize");
exit(1);
}
copy_file(xvdg_fd, file_fd);
close(file_fd);
close(xvdg_fd);
// request qfileexchgd to send our /dev/xvdg to its destination
// either "disposable", which means "create DVM for me"
// or vmname, meaning this is a reply to originator AppVM
snprintf(buf, sizeof(buf), "send %s %d", argv[1], seq);
if (!xs_write(xs, 0, "device/qpen", buf, strlen(buf))) {
perror("xs_write");
exit(1);
}
write_db(abs_filename, seq);
xs_daemon_close(xs);
return 0;
}

View File

@ -13,6 +13,4 @@ tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/xvdg /mnt/outgoing vfat noauto,user,rw 0 0
/dev/xvdh /mnt/incoming vfat noauto,user,rw 0 0
/dev/xvdi /mnt/removable auto noauto,user,rw 0 0

View File

@ -70,21 +70,15 @@ 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 qvm-open-in-dvm2 $RPM_BUILD_ROOT/usr/bin
cp qubes_timestamp 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}
cp qvm-copy.desktop qvm-dvm.desktop $RPM_BUILD_ROOT/%{kde_service_dir}
mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d
cp qubes.rules $RPM_BUILD_ROOT/etc/udev/rules.d
mkdir -p $RPM_BUILD_ROOT/mnt/incoming
mkdir -p $RPM_BUILD_ROOT/mnt/outgoing
mkdir -p $RPM_BUILD_ROOT/mnt/removable
mkdir -p $RPM_BUILD_ROOT/etc/X11
@ -129,26 +123,17 @@ rm -rf $RPM_BUILD_ROOT
%files
%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
%dir /mnt/removable
/usr/bin/qubes_timestamp
%dir /home_volatile