qvm-open-in-vm: mark file as read-only if opened with --view-only
This will cause most applications to disallow changing the file and also add some visual indication about the view being read only. This will avoid making the changes that would be discarded later. QubesOS/qubes-issues#1118
This commit is contained in:
parent
ef557ca460
commit
42b1355957
@ -1,2 +1,3 @@
|
|||||||
#define DVM_FILENAME_SIZE 256
|
#define DVM_FILENAME_SIZE 256
|
||||||
#define DVM_SPOOL "/home/user/.dvmspool"
|
#define DVM_SPOOL "/home/user/.dvmspool"
|
||||||
|
#define DVM_VIEW_ONLY_PREFIX "view-only-"
|
||||||
|
@ -13,21 +13,26 @@
|
|||||||
#include <gui-fatal.h>
|
#include <gui-fatal.h>
|
||||||
#include "dvm2.h"
|
#include "dvm2.h"
|
||||||
|
|
||||||
void send_file(const char *fname)
|
void send_file(const char *fname, int view_only)
|
||||||
{
|
{
|
||||||
const char *base;
|
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);
|
int fd = open(fname, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
gui_fatal("open %s", fname);
|
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, '/');
|
base = rindex(fname, '/');
|
||||||
if (!base)
|
if (!base)
|
||||||
base = fname;
|
base = fname;
|
||||||
else
|
else
|
||||||
base++;
|
base++;
|
||||||
if (strlen(base) >= DVM_FILENAME_SIZE)
|
if (strlen(base) >= sendbuf_size)
|
||||||
base += strlen(base) - DVM_FILENAME_SIZE + 1;
|
base += strlen(base) - sendbuf_size + 1;
|
||||||
strncpy(sendbuf,base,DVM_FILENAME_SIZE - 1); /* fills out with NULs */
|
strncat(sendbuf,base,sendbuf_size - 1); /* fills out with NULs */
|
||||||
sendbuf[DVM_FILENAME_SIZE - 1] = '\0';
|
sendbuf[DVM_FILENAME_SIZE - 1] = '\0';
|
||||||
if (!write_all(1, sendbuf, DVM_FILENAME_SIZE))
|
if (!write_all(1, sendbuf, DVM_FILENAME_SIZE))
|
||||||
gui_fatal("send filename to dispVM");
|
gui_fatal("send filename to dispVM");
|
||||||
@ -114,7 +119,7 @@ int main(int argc, char ** argv)
|
|||||||
if (optind >= argc)
|
if (optind >= argc)
|
||||||
gui_fatal("OpenInVM - no file given?");
|
gui_fatal("OpenInVM - no file given?");
|
||||||
fname = argv[optind];
|
fname = argv[optind];
|
||||||
send_file(fname);
|
send_file(fname, view_only);
|
||||||
if (!view_only) {
|
if (!view_only) {
|
||||||
recv_file(fname);
|
recv_file(fname);
|
||||||
} else {
|
} else {
|
||||||
|
@ -79,9 +79,10 @@ fail:
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *get_filename(void)
|
char *get_filename(int *view_only)
|
||||||
{
|
{
|
||||||
char buf[DVM_FILENAME_SIZE];
|
char buf[DVM_FILENAME_SIZE];
|
||||||
|
char *fname = buf;
|
||||||
static char *retname;
|
static char *retname;
|
||||||
int i;
|
int i;
|
||||||
char *directory;
|
char *directory;
|
||||||
@ -100,13 +101,17 @@ char *get_filename(void)
|
|||||||
if (index(" !?\"#$%^&*()[]<>;`~|", buf[i]))
|
if (index(" !?\"#$%^&*()[]<>;`~|", buf[i]))
|
||||||
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);
|
retname = malloc(len);
|
||||||
if (!retname) {
|
if (!retname) {
|
||||||
fprintf(stderr, "Cannot allocate memory\n");
|
fprintf(stderr, "Cannot allocate memory\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
snprintf(retname, len, "%s/%s", directory, buf);
|
snprintf(retname, len, "%s/%s", directory, fname);
|
||||||
free(directory);
|
free(directory);
|
||||||
return retname;
|
return retname;
|
||||||
}
|
}
|
||||||
@ -143,11 +148,16 @@ int
|
|||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
struct stat stat_pre, stat_post, session_stat;
|
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;
|
int child, status, log_fd, null_fd;
|
||||||
FILE *waiter_pidfile;
|
FILE *waiter_pidfile;
|
||||||
|
|
||||||
copy_file_by_name(filename);
|
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)) {
|
if (stat(filename, &stat_pre)) {
|
||||||
perror("stat pre");
|
perror("stat pre");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user