X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=init.c;h=d566add3f711c81eb326487737707280879c96b8;hp=cbc9645aa5b1e5c2133086116420991178df6148;hb=047342c2a0526885217e03d06e9b7a715f55b92f;hpb=cf3b7c1d74544527da3f894bc732d696731a5cde diff --git a/init.c b/init.c index cbc9645..d566add 100644 --- a/init.c +++ b/init.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include void toggle_quadoption (int opt) @@ -2175,3 +2177,131 @@ int mutt_get_hook_type (const char *name) return c->data; return 0; } + +void mutt_start_slrnface(void) +{ + char *fifo; + int pathlen, status; + pid_t pid, pidst; + struct utsname u; + + if (!option(OPTXFACE)) + return; + + /* + * If we don't have display, there's no point. The user probably knows, + * so fail silently. + */ + if (!getenv("DISPLAY")) + return; + /* If there is no WINDOWID, complain. */ + if (!getenv ("WINDOWID")) + { + mutt_error (_("Cannot run slrnface: WINDOWID not found in environment.")); + return; + } + + uname (&u); + pathlen = strlen (Homedir) + sizeof("/.slrnfaces/") + + strlen (u.nodename) + 30; + fifo = safe_malloc (pathlen); + sprintf (fifo, "%s/.slrnfaces", Homedir); + if (mkdir (fifo, 0700)) + { + if (errno != EEXIST) + { + mutt_error (_("Cannot run slrnface: failed to create %s: %s."), + fifo, strerror(errno)); + return; + } + } + else + { + FILE *fp; + + /* We'll abuse fifo filename memory here. It's long enough. */ + sprintf (fifo, "%s/.slrnfaces/README", Homedir); + if ((fp = fopen (fifo, "w")) != NULL) + { + fputs (_( +"This directory is used to create named pipes for communication between\n" +"slrnface and its parent process. It should normally be empty because\n" +"the pipe is deleted right after it has been opened by both processes.\n\n" +"File names generated by slrnface have the form \"hostname.pid\". It is\n" +"probably an error if they linger here longer than a fraction of a second.\n\n" +"However, if the directory is mounted from an NFS server, you might see\n" +"special files created by your NFS server while slrnface is running.\n" +"Do not try to remove them.\n"), fp); + fclose (fp); + } + } + + status = snprintf (fifo, pathlen, "%s/.slrnfaces/%s.%ld", Homedir, + u.nodename, (long)getpid()); + if (status < 0) + goto clean_face; + + unlink (fifo); + if (mkfifo (fifo, 0600) < 0) + { + mutt_error (_("Cannot run slrnface, failed to create %s: %s."), fifo, + strerror(errno)); + goto clean_face; + } + + pid = fork(); + switch (pid) + { + case -1: break; + case 0: execlp ("slrnface", "slrnface", fifo, (char *)0); + /* This is child, exit on error. */ + _exit (10); + default: do { + pidst = waitpid (pid, &status, 0); + } while (pidst == -1 && errno == EINTR); + + if (!WIFEXITED (status)) + mutt_error (_("Slrnface abnormaly exited, code %d."), status); + else + { + char *message; + + switch (WEXITSTATUS (status)) + { + case 0: /* All fine, open the pipe */ + slrnface_fd = open (fifo, O_WRONLY, 0600); + write (slrnface_fd, "start\n", sizeof "start"); + goto clean_face; + case 1: message = "couldn't connect to display"; + break; + case 2: message = "WINDOWID not found in environment"; + break; + case 3: message = "couldn't find controlling terminal"; + break; + case 4: message = "terminal doesn't export width and height"; + break; + case 5: message = "cannot open FIFO"; + break; + case 6: message = "fork() failed"; + break; + case 10: message = "executable not found"; + break; + default: message = "unknown error"; + } + mutt_error (_("Slrnface failed: %s."), message); + } + } + +clean_face: + unlink (fifo); + free (fifo); +} + +void mutt_stop_slrnface(void) +{ + if (slrnface_fd >= 0) + close(slrnface_fd); + slrnface_fd = -1; + + /* FIFO has been unlinked in the startup function. */ +}