Merge branch 'view-only'

* view-only:
  Add file managers integration for qvm-open-in-dvm --view-only
  qvm-open-in-vm: mark file as read-only if opened with --view-only
  qvm-open-in-vm: implement --view-only option
  qubes-rpc: fix code style - indent with spaces
This commit is contained in:
Marek Marczykowski-Górecki 2018-05-26 22:41:05 +02:00
commit bd445742fb
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
12 changed files with 535 additions and 441 deletions

View File

@ -59,7 +59,7 @@
</action>
<action>
<icon>document-open</icon>
<name>Open in DisposableVM</name>
<name>Edit in DisposableVM</name>
<unique-id>1507455559234996-8</unique-id>
<command>/usr/lib/qubes/qvm-actions.sh opendvm %F</command>
<description></description>
@ -70,3 +70,16 @@
<text-files/>
<video-files/>
</action>
<action>
<icon>document-open</icon>
<name>View in DisposableVM</name>
<unique-id>1507455559234997-9</unique-id>
<command>/usr/lib/qubes/qvm-actions.sh viewdvm %F</command>
<description></description>
<patterns>*</patterns>
<audio-files/>
<image-files/>
<other-files/>
<text-files/>
<video-files/>
</action>

View File

@ -1,2 +1,3 @@
#define DVM_FILENAME_SIZE 256
#define DVM_SPOOL "/home/user/.dvmspool"
#define DVM_VIEW_ONLY_PREFIX "view-only-"

View File

@ -9,24 +9,30 @@
#include <stdlib.h>
#include <libqubes-rpc-filecopy.h>
#include <unistd.h>
#include <getopt.h>
#include <gui-fatal.h>
#include "dvm2.h"
void send_file(const char *fname)
void send_file(const char *fname, int view_only)
{
const char *base;
char sendbuf[DVM_FILENAME_SIZE];
char sendbuf[DVM_FILENAME_SIZE] = {0};
size_t sendbuf_size = DVM_FILENAME_SIZE;
int fd = open(fname, O_RDONLY);
if (fd < 0)
gui_fatal("open %s", fname);
if (view_only) {
strncpy(sendbuf, DVM_VIEW_ONLY_PREFIX, sendbuf_size);
sendbuf_size -= strlen(DVM_VIEW_ONLY_PREFIX);
}
base = rindex(fname, '/');
if (!base)
base = fname;
else
base++;
if (strlen(base) >= DVM_FILENAME_SIZE)
base += strlen(base) - DVM_FILENAME_SIZE + 1;
strncpy(sendbuf,base,DVM_FILENAME_SIZE - 1); /* fills out with NULs */
if (strlen(base) >= sendbuf_size)
base += strlen(base) - sendbuf_size + 1;
strncat(sendbuf,base,sendbuf_size - 1); /* fills out with NULs */
sendbuf[DVM_FILENAME_SIZE - 1] = '\0';
if (!write_all(1, sendbuf, DVM_FILENAME_SIZE))
gui_fatal("send filename to dispVM");
@ -92,17 +98,35 @@ void recv_file(const char *fname)
actually_recv_file(fname, tempfile, tmpfd);
}
void talk_to_daemon(const char *fname)
{
send_file(fname);
recv_file(fname);
}
int main(int argc, char ** argv)
{
char *fname;
int view_only = 0;
int ret;
const struct option opts[] = {
{"view-only", no_argument, &view_only, 1},
{0}
};
while ((ret=getopt_long(argc, argv, "", opts, NULL)) != -1) {
if (ret == '?') {
exit(2);
}
}
signal(SIGPIPE, SIG_IGN);
if (argc!=2)
if (optind >= argc)
gui_fatal("OpenInVM - no file given?");
talk_to_daemon(argv[1]);
fname = argv[optind];
send_file(fname, view_only);
if (!view_only) {
recv_file(fname);
} else {
/* discard received data */
int null_fd = open("/dev/null", O_WRONLY);
copy_fd_all(null_fd, 0);
close(null_fd);
}
return 0;
}

View File

@ -45,6 +45,12 @@ case "$action" in
qvm-open-in-dvm "$file" | zenity --notification --text "Opening $file in DisposableVM..." --timeout 3 &
done
;;
viewdvm)
for file in "$@"
do
qvm-open-in-dvm --view-only "$file" | zenity --notification --text "Opening $file in DisposableVM..." --timeout 3 &
done
;;
*)
echo "Unknown action. Aborting..."
exit 1

View File

@ -1,10 +1,15 @@
[Desktop Entry]
Actions=QvmDvm;
Actions=QvmDvm;QvmViewDvm
Type=Service
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,all/allfiles
[Desktop Action QvmDvm]
Exec=/usr/bin/qvm-open-in-dvm %U
Icon=kget
Name=Open In DisposableVM
Name=Edit In DisposableVM
[Desktop Action QvmViewDvm]
Exec=/usr/bin/qvm-open-in-dvm --view-only %U
Icon=kget
Name=View In DisposableVM

View File

@ -20,10 +20,10 @@
#
#
if ! [ $# = 1 ] ; then
echo "Usage: $0 filename"
if ! [ $# = 1 ] && ! [ $# = 2 ]; then
echo "Usage: $0 [--view-only] filename"
exit 1
fi
# shellcheck disable=SC2016
exec qvm-open-in-vm '$dispvm' "$1"
exec qvm-open-in-vm '$dispvm' "$@"

View File

@ -20,16 +20,37 @@
#
#
if ! [ $# = 2 ] ; then
echo "Usage: $0 vmname filename"
exit 1
usage() {
echo "Usage: $0 [--view-only] vmname filename"
exit 2
}
qopen_opts=
target=
filename=
while [ $# -gt 0 ]; do
if [ "x$1" = "x--view-only" ]; then
qopen_opts=--view-only
elif [ -z "$target" ]; then
target="$1"
elif [ -z "$filename" ]; then
filename="$1"
else
usage
fi
shift
done
if [ -z "$target" ] || [ -z "$filename" ]; then
usage
fi
case "$2" in
case "$filename" in
*://*)
exec /usr/lib/qubes/qrexec-client-vm "$1" qubes.OpenURL /bin/echo "$2"
exec /usr/lib/qubes/qrexec-client-vm "$target" qubes.OpenURL /bin/echo "$filename"
;;
*)
exec /usr/lib/qubes/qrexec-client-vm "$1" qubes.OpenInVM "/usr/lib/qubes/qopen-in-vm" "$2"
exec /usr/lib/qubes/qrexec-client-vm "$target" qubes.OpenInVM "/usr/lib/qubes/qopen-in-vm" $qopen_opts "$filename"
;;
esac

View File

@ -17,15 +17,24 @@ class OpenInDvmItemExtension(GObject.GObject, Nautilus.MenuProvider):
if not files:
return
menu_item = Nautilus.MenuItem(name='QubesMenuProvider::OpenInDvm',
label='Open In DisposableVM',
menu_item1 = Nautilus.MenuItem(name='QubesMenuProvider::OpenInDvm',
label='Edit In DisposableVM',
tip='',
icon='')
menu_item.connect('activate', self.on_menu_item_clicked, files)
return menu_item,
menu_item1.connect('activate', self.on_menu_item_clicked, files)
def on_menu_item_clicked(self, menu, files):
menu_item2 = Nautilus.MenuItem(name='QubesMenuProvider::ViewInDvm',
label='View In DisposableVM',
tip='',
icon='')
menu_item2.connect('activate',
self.on_menu_item_clicked,
files, True)
return menu_item1, menu_item2,
def on_menu_item_clicked(self, menu, files, view_only=False):
'''Called when user chooses files though Nautilus context menu.
'''
for file_obj in files:
@ -38,6 +47,11 @@ class OpenInDvmItemExtension(GObject.GObject, Nautilus.MenuProvider):
# Use subprocess.DEVNULL in python >= 3.3
devnull = open(os.devnull, 'wb')
command = ['nohup', '/usr/bin/qvm-open-in-dvm']
if view_only:
command.append('--view-only')
command.append(gio_file.get_path())
# Use Popen instead of subprocess.call to spawn the process
Popen(['nohup', '/usr/bin/qvm-open-in-dvm', gio_file.get_path()], stdout=devnull, stderr=devnull)
Popen(command, stdout=devnull, stderr=devnull)
devnull.close()

View File

@ -79,9 +79,10 @@ fail:
exit(1);
}
char *get_filename(void)
char *get_filename(int *view_only)
{
char buf[DVM_FILENAME_SIZE];
char *fname = buf;
static char *retname;
int i;
char *directory;
@ -100,13 +101,17 @@ char *get_filename(void)
if (index(" !?\"#$%^&*()[]<>;`~|", buf[i]))
buf[i]='_';
}
len = strlen(directory)+1+strlen(buf)+1;
if (strncmp(buf, DVM_VIEW_ONLY_PREFIX, strlen(DVM_VIEW_ONLY_PREFIX)) == 0) {
*view_only = 1;
fname += strlen(DVM_VIEW_ONLY_PREFIX);
}
len = strlen(directory)+1+strlen(fname)+1;
retname = malloc(len);
if (!retname) {
fprintf(stderr, "Cannot allocate memory\n");
exit(1);
}
snprintf(retname, len, "%s/%s", directory, buf);
snprintf(retname, len, "%s/%s", directory, fname);
free(directory);
return retname;
}
@ -143,11 +148,16 @@ int
main()
{
struct stat stat_pre, stat_post, session_stat;
char *filename = get_filename();
int view_only = 0;
char *filename = get_filename(&view_only);
int child, status, log_fd, null_fd;
FILE *waiter_pidfile;
copy_file_by_name(filename);
if (view_only) {
// mark file as read-only so applications will signal it to the user
chmod(filename, 0400);
}
if (stat(filename, &stat_pre)) {
perror("stat pre");
exit(1);