vm-file-editor.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include <sys/stat.h>
  2. #include <sys/wait.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>
  8. #include <ioall.h>
  9. #include "dvm2.h"
  10. char *get_filename()
  11. {
  12. char buf[DVM_FILENAME_SIZE];
  13. static char retname[sizeof(buf) + sizeof("/tmp/")];
  14. int i;
  15. if (!read_all(0, buf, sizeof(buf)))
  16. exit(1);
  17. if (index(buf, '/')) {
  18. fprintf(stderr, "filename contains /");
  19. exit(1);
  20. }
  21. for (i=0; i < DVM_FILENAME_SIZE && buf[i]!=0; i++) {
  22. // replace some characters with _ (eg mimeopen have problems with some of them)
  23. if (index(" !?\"#$%^&*()[]<>;`~", buf[i]))
  24. buf[i]='_';
  25. }
  26. snprintf(retname, sizeof(retname), "/tmp/%s", buf);
  27. return retname;
  28. }
  29. void copy_file(char *filename)
  30. {
  31. int fd = open(filename, O_WRONLY | O_CREAT, 0600);
  32. if (fd < 0) {
  33. perror("open file");
  34. exit(1);
  35. }
  36. if (!copy_fd_all(fd, 0))
  37. exit(1);
  38. close(fd);
  39. }
  40. void send_file_back(char * filename)
  41. {
  42. int fd = open(filename, O_RDONLY);
  43. if (fd < 0) {
  44. perror("open file");
  45. exit(1);
  46. }
  47. if (!copy_fd_all(1, fd))
  48. exit(1);
  49. close(fd);
  50. }
  51. int
  52. main()
  53. {
  54. struct stat stat_pre, stat_post, session_stat;
  55. char *filename = get_filename();
  56. int child, status, log_fd;
  57. FILE *waiter_pidfile;
  58. copy_file(filename);
  59. if (stat(filename, &stat_pre)) {
  60. perror("stat pre");
  61. exit(1);
  62. }
  63. // wait for X server to starts (especially in DispVM)
  64. if (stat("/tmp/qubes-session-env", &session_stat)) {
  65. switch (child = fork()) {
  66. case -1:
  67. perror("fork");
  68. exit(1);
  69. case 0:
  70. waiter_pidfile = fopen("/tmp/qubes-session-waiter", "a");
  71. if (waiter_pidfile == NULL) {
  72. perror("fopen waiter_pidfile");
  73. exit(1);
  74. }
  75. fprintf(waiter_pidfile, "%d\n", getpid());
  76. fclose(waiter_pidfile);
  77. // check the second time, to prevent race
  78. if (stat("/tmp/qubes-session-env", &session_stat)) {
  79. // wait for qubes-session notify
  80. pause();
  81. }
  82. exit(0);
  83. default:
  84. waitpid(child, &status, 0);
  85. if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
  86. //propagate exit code from child
  87. exit(WEXITSTATUS(status));
  88. }
  89. }
  90. }
  91. switch (child = fork()) {
  92. case -1:
  93. perror("fork");
  94. exit(1);
  95. case 0:
  96. close(0);
  97. log_fd = open("/tmp/mimeopen.log", O_CREAT | O_APPEND, 0666);
  98. if (log_fd == -1) {
  99. perror("open /tmp/mimeopen.log");
  100. exit(1);
  101. }
  102. dup2(log_fd, 1);
  103. dup2(log_fd, 2);
  104. close(log_fd);
  105. setenv("HOME", "/home/user", 1);
  106. setenv("DISPLAY", ":0", 1);
  107. execl("/usr/bin/mimeopen", "mimeopen", "-n", "-M", filename, (char*)NULL);
  108. perror("execl");
  109. exit(1);
  110. default:
  111. waitpid(child, &status, 0);
  112. if (status != 0) {
  113. char cmd[512];
  114. #ifdef USE_KDIALOG
  115. snprintf(cmd, sizeof(cmd),
  116. "HOME=/home/user DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
  117. ("HOME=/home/user DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
  118. #else
  119. snprintf(cmd, sizeof(cmd),
  120. "HOME=/home/user DISPLAY=:0 /usr/bin/zenity --error --text 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
  121. #endif
  122. system(cmd);
  123. }
  124. }
  125. if (stat(filename, &stat_post)) {
  126. perror("stat post");
  127. exit(1);
  128. }
  129. if (stat_pre.st_mtime != stat_post.st_mtime)
  130. send_file_back(filename);
  131. return 0;
  132. }