qopen-in-vm.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. }
  33. int copy_and_return_nonemptiness(int tmpfd)
  34. {
  35. struct stat st;
  36. if (!copy_fd_all(tmpfd, 0))
  37. gui_fatal("receiving file from dispVM");
  38. if (fstat(tmpfd, &st))
  39. gui_fatal("fstat");
  40. close(tmpfd);
  41. return st.st_size;
  42. }
  43. void recv_file_nowrite(char *fname)
  44. {
  45. char *tempfile;
  46. char *errmsg;
  47. int tmpfd;
  48. asprintf(&tempfile, "/tmp/file_edited_in_dvm.XXXXXX");
  49. tmpfd = mkstemp(tempfile);
  50. if (tmpfd < 0)
  51. gui_fatal("unable to create any temporary file, aborting");
  52. if (!copy_and_return_nonemptiness(tmpfd)) {
  53. unlink(tempfile);
  54. return;
  55. }
  56. asprintf(&errmsg,
  57. "The file %s has been edited in Disposable VM and the modified content has been received, "
  58. "but this file is in nonwritable directory and thus cannot be modified safely. The edited file has been "
  59. "saved to %s", fname, tempfile);
  60. gui_nonfatal(errmsg);
  61. }
  62. void actually_recv_file(char *fname, char *tempfile, int tmpfd)
  63. {
  64. if (!copy_and_return_nonemptiness(tmpfd)) {
  65. unlink(tempfile);
  66. return;
  67. }
  68. if (rename(tempfile, fname))
  69. gui_fatal("rename");
  70. }
  71. void recv_file(char *fname)
  72. {
  73. int tmpfd;
  74. char *tempfile;
  75. asprintf(&tempfile, "%s.XXXXXX", fname);
  76. tmpfd = mkstemp(tempfile);
  77. if (tmpfd < 0)
  78. recv_file_nowrite(fname);
  79. else
  80. actually_recv_file(fname, tempfile, tmpfd);
  81. }
  82. void talk_to_daemon(char *fname)
  83. {
  84. send_file(fname);
  85. recv_file(fname);
  86. }
  87. int main(int argc, char ** argv)
  88. {
  89. signal(SIGPIPE, SIG_IGN);
  90. if (argc!=2)
  91. gui_fatal("OpenInVM - no file given?");
  92. talk_to_daemon(argv[1]);
  93. return 0;
  94. }