qopen-in-vm.c 2.2 KB

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