123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- #include <sys/stat.h>
- #include <sys/wait.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <ioall.h>
- #include "dvm2.h"
- #define USER_HOME "/home/user"
- #define MIMEINFO_DATABASES "/usr/share/mime:/usr/local/share:" USER_HOME "/.local/share:/usr/share/qubes/mime-override"
- char *gettime()
- {
- static char retbuf[60];
- struct timeval tv;
- gettimeofday(&tv, NULL);
- snprintf(retbuf, sizeof(retbuf), "%lld.%lld",
- (long long) tv.tv_sec, (long long) tv.tv_usec);
- return retbuf;
- }
- char *get_filename()
- {
- char buf[DVM_FILENAME_SIZE];
- static char retname[sizeof(buf) + sizeof("/tmp/")];
- int i;
- if (!read_all(0, buf, sizeof(buf)))
- exit(1);
- if (index(buf, '/')) {
- fprintf(stderr, "filename contains /");
- exit(1);
- }
- for (i=0; i < DVM_FILENAME_SIZE && buf[i]!=0; i++) {
- // replace some characters with _ (eg mimeopen have problems with some of them)
- if (index(" !?\"#$%^&*()[]<>;`~", buf[i]))
- buf[i]='_';
- }
- snprintf(retname, sizeof(retname), "/tmp/%s", buf);
- return retname;
- }
- void copy_file(char *filename)
- {
- int fd = open(filename, O_WRONLY | O_CREAT, 0600);
- if (fd < 0) {
- perror("open file");
- exit(1);
- }
- if (!copy_fd_all(fd, 0))
- exit(1);
- close(fd);
- }
- void send_file_back(char * filename)
- {
- int fd = open(filename, O_RDONLY);
- if (fd < 0) {
- perror("open file");
- exit(1);
- }
- if (!copy_fd_all(1, fd))
- exit(1);
- close(fd);
- }
- int
- main()
- {
- struct stat stat_pre, stat_post, session_stat;
- char *filename = get_filename();
- int child, status, log_fd, null_fd;
- char var[1024], val[4096];
- FILE *env_file;
- FILE *waiter_pidfile;
- copy_file(filename);
- if (stat(filename, &stat_pre)) {
- perror("stat pre");
- exit(1);
- }
- fprintf(stderr, "time=%s, waiting for qubes-session\n", gettime());
- // wait for X server to starts (especially in DispVM)
- if (stat("/tmp/qubes-session-env", &session_stat)) {
- switch (child = fork()) {
- case -1:
- perror("fork");
- exit(1);
- case 0:
- waiter_pidfile = fopen("/tmp/qubes-session-waiter", "a");
- if (waiter_pidfile == NULL) {
- perror("fopen waiter_pidfile");
- exit(1);
- }
- fprintf(waiter_pidfile, "%d\n", getpid());
- fclose(waiter_pidfile);
- // check the second time, to prevent race
- if (stat("/tmp/qubes-session-env", &session_stat)) {
- // wait for qubes-session notify
- pause();
- }
- exit(0);
- default:
- waitpid(child, &status, 0);
- if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
- //propagate exit code from child
- exit(WEXITSTATUS(status));
- }
- }
- }
- fprintf(stderr, "time=%s, starting editor\n", gettime());
- switch (child = fork()) {
- case -1:
- perror("fork");
- exit(1);
- case 0:
- null_fd = open("/dev/null", O_RDONLY);
- dup2(null_fd, 0);
- close(null_fd);
- env_file = fopen("/tmp/qubes-session-env", "r");
- while(fscanf(env_file, "%1024[^=]=%4096[^\n]\n", var, val) == 2) {
- setenv(var, val, 1);
- }
- fclose(env_file);
- log_fd = open("/tmp/mimeopen.log", O_CREAT | O_APPEND, 0666);
- if (log_fd == -1) {
- perror("open /tmp/mimeopen.log");
- exit(1);
- }
- dup2(log_fd, 1);
- close(log_fd);
- setenv("HOME", USER_HOME, 1);
- setenv("DISPLAY", ":0", 1);
- execl("/usr/bin/mimeopen", "mimeopen", "-n",
- "--database", MIMEINFO_DATABASES, filename, (char*)NULL);
- perror("execl");
- exit(1);
- default:
- waitpid(child, &status, 0);
- if (status != 0) {
- char cmd[512];
- #ifdef USE_KDIALOG
- snprintf(cmd, sizeof(cmd),
- "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);
- ("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);
- #else
- snprintf(cmd, sizeof(cmd),
- "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);
- #endif
- system(cmd);
- }
- }
- if (stat(filename, &stat_post)) {
- perror("stat post");
- exit(1);
- }
- if (stat_pre.st_mtime != stat_post.st_mtime)
- send_file_back(filename);
- return 0;
- }
|