qopen-in-vm.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #define _GNU_SOURCE
  2. #include <dirent.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <sys/stat.h>
  6. #include <signal.h>
  7. #include <fcntl.h>
  8. #include <malloc.h>
  9. #include <stdlib.h>
  10. #include <libqubes-rpc-filecopy.h>
  11. #include <unistd.h>
  12. #include <gui-fatal.h>
  13. #include "dvm2.h"
  14. void send_file(const char *fname)
  15. {
  16. const char *base;
  17. char sendbuf[DVM_FILENAME_SIZE];
  18. int fd = open(fname, O_RDONLY);
  19. if (fd < 0)
  20. gui_fatal("open %s", fname);
  21. base = rindex(fname, '/');
  22. if (!base)
  23. base = fname;
  24. else
  25. base++;
  26. if (strlen(base) >= DVM_FILENAME_SIZE)
  27. base += strlen(base) - DVM_FILENAME_SIZE + 1;
  28. strncpy(sendbuf,base,DVM_FILENAME_SIZE); /* fills out with NULs */
  29. if (!write_all(1, sendbuf, DVM_FILENAME_SIZE))
  30. gui_fatal("send filename to dispVM");
  31. if (!copy_fd_all(1, fd))
  32. gui_fatal("send file to dispVM");
  33. close(1);
  34. close(fd);
  35. }
  36. int copy_and_return_nonemptiness(int tmpfd)
  37. {
  38. struct stat st;
  39. if (!copy_fd_all(tmpfd, 0))
  40. gui_fatal("receiving file from dispVM");
  41. if (fstat(tmpfd, &st))
  42. gui_fatal("fstat");
  43. close(tmpfd);
  44. return st.st_size > 0;
  45. }
  46. void recv_file_nowrite(const char *fname)
  47. {
  48. char *tempfile;
  49. char *errmsg;
  50. int tmpfd;
  51. asprintf(&tempfile, "/tmp/file_edited_in_dvm.XXXXXX");
  52. tmpfd = mkstemp(tempfile);
  53. if (tmpfd < 0)
  54. gui_fatal("unable to create any temporary file, aborting");
  55. if (!copy_and_return_nonemptiness(tmpfd)) {
  56. unlink(tempfile);
  57. return;
  58. }
  59. asprintf(&errmsg,
  60. "The file %s has been edited in Disposable VM and the modified content has been received, "
  61. "but this file is in nonwritable directory and thus cannot be modified safely. The edited file has been "
  62. "saved to %s", fname, tempfile);
  63. gui_nonfatal(errmsg);
  64. }
  65. void actually_recv_file(const char *fname, const char *tempfile, int tmpfd)
  66. {
  67. if (!copy_and_return_nonemptiness(tmpfd)) {
  68. unlink(tempfile);
  69. return;
  70. }
  71. if (rename(tempfile, fname))
  72. gui_fatal("rename");
  73. }
  74. void recv_file(const char *fname)
  75. {
  76. int tmpfd;
  77. char *tempfile;
  78. asprintf(&tempfile, "%s.XXXXXX", fname);
  79. tmpfd = mkstemp(tempfile);
  80. if (tmpfd < 0)
  81. recv_file_nowrite(fname);
  82. else
  83. actually_recv_file(fname, tempfile, tmpfd);
  84. }
  85. void talk_to_daemon(const char *fname)
  86. {
  87. send_file(fname);
  88. recv_file(fname);
  89. }
  90. int main(int argc, char ** argv)
  91. {
  92. signal(SIGPIPE, SIG_IGN);
  93. if (argc!=2)
  94. gui_fatal("OpenInVM - no file given?");
  95. talk_to_daemon(argv[1]);
  96. return 0;
  97. }