"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.1/src/xface.c" (12 Oct 2016, 7647 Bytes) of archive /linux/misc/tin-2.4.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "xface.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.4.0_vs_2.4.1.

    1 /*
    2  *  Project   : tin - a Usenet reader
    3  *  Module    : xface.c
    4  *  Author    : Joshua Crawford & Drazen Kacar
    5  *  Created   : 2003-04-27
    6  *  Updated   : 2013-11-06
    7  *  Notes     :
    8  *
    9  * Copyright (c) 2003-2017 Joshua Crawford <mortarn@softhome.net> & Drazen Kacar <dave@willfork.com>
   10  * All rights reserved.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. The name of the author may not be used to endorse or promote
   21  *    products derived from this software without specific prior written
   22  *    permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
   25  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
   28  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   30  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   32  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   33  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   34  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35  */
   36 
   37 
   38 /*
   39  * TODO: - document the used vars/files/dir in the mapage
   40  *       - move strings to lang.c
   41  */
   42 
   43 #ifndef TIN_H
   44 #   include "tin.h"
   45 #endif /* !TIN_H */
   46 
   47 #ifdef XFACE_ABLE
   48 
   49 static int slrnface_fd = -1;
   50 
   51 
   52 void
   53 slrnface_start(
   54     void)
   55 {
   56     char *fifo;
   57     const char *ptr;
   58     int status;
   59     pid_t pid, pidst;
   60     size_t pathlen;
   61     struct utsname u;
   62 
   63     if (tinrc.use_slrnface == FALSE)
   64         return;
   65 
   66 #ifdef HAVE_IS_XTERM
   67     if (!is_xterm()) {
   68 #   ifdef DEBUG
   69         if (debug & DEBUG_MISC)
   70             error_message(2, _("Can't run slrnface: Not running in a xterm."));
   71 #   endif /* DEBUG */
   72         return;
   73     }
   74 #endif /* HAVE_IS_XTERM */
   75 
   76     /*
   77      * $DISPLAY holds the (default) display name
   78      */
   79     if (!getenv("DISPLAY")) {
   80 #   ifdef DEBUG
   81         if (debug & DEBUG_MISC)
   82             error_message(2, _("Can't run slrnface: Environment variable %s not found."), "DISPLAY");
   83 #   endif /* DEBUG */
   84         return;
   85     }
   86 
   87     /*
   88      * $WINDOWID holds the X window id number of the xterm window
   89      */
   90     if (!getenv("WINDOWID")) {
   91 #   ifdef DEBUG
   92         if (debug & DEBUG_MISC)
   93             error_message(2, _("Can't run slrnface: Environment variable %s not found."), "WINDOWID");
   94 #   endif /* DEBUG */
   95         return;
   96     }
   97 
   98     uname(&u);
   99     ptr = get_val("XDG_RUNTIME_DIR", get_val("HOME", ""));
  100     /*
  101      * TODO:
  102      * - check if $XDG_RUNTIME_DIR is on a local filesystem and has secure permissions
  103      * <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>
  104      */
  105     if (!strlen(ptr)) { /* TODO: mention XDG_RUNTIME_DIR in error message? */
  106 #   ifdef DEBUG
  107         if (debug & DEBUG_MISC)
  108             error_message(2, _("Can't run slrnface: Environment variable %s not found."), "HOME");
  109 #   endif /* DEBUG */
  110         return;
  111     }
  112     pathlen = strlen(ptr) + strlen("/.slrnfaces/") + strlen(u.nodename) + 30;
  113     fifo = my_malloc(pathlen);
  114     snprintf(fifo, pathlen, "%s/.slrnfaces", ptr);
  115     if (my_mkdir(fifo, (mode_t) S_IRWXU)) {
  116         if (errno != EEXIST) {
  117             perror_message(_("Can't run slrnface: failed to create %s"), fifo);
  118             free(fifo);
  119             return;
  120         }
  121     } else {
  122         FILE *fp;
  123 
  124         /* We abuse fifo filename memory here. It is long enough. */
  125         snprintf(fifo, pathlen, "%s/.slrnfaces/README", ptr);
  126         if ((fp = fopen(fifo, "w")) != NULL) {
  127             fputs(_("This directory is used to create named pipes for communication between\n"
  128 "slrnface and its parent process. It should normally be empty because\n"
  129 "the pipe is deleted right after it has been opened by both processes.\n\n"
  130 "File names generated by slrnface have the form \"hostname.pid\". It is\n"
  131 "probably an error if they linger here longer than a fraction of a second.\n\n"
  132 "However, if the directory is mounted from an NFS server, you might see\n"
  133 "special files created by your NFS server while slrnface is running.\n"
  134 "Do not try to remove them.\n"), fp);
  135             fclose(fp);
  136         }
  137     }
  138 
  139     status = snprintf(fifo, pathlen, "%s/.slrnfaces/%s.%ld", ptr, u.nodename, (long) getpid());
  140     if (status <= 0 || status >= (int) pathlen) {
  141         error_message(2, _("Can't run slrnface: couldn't construct fifo name."));
  142         unlink(fifo);
  143         free(fifo);
  144         return;
  145     }
  146 
  147     unlink(fifo);
  148     if (mkfifo(fifo, (S_IRUSR|S_IWUSR)) < 0) {
  149         perror_message(_("Can't run slrnface: failed to create %s"), fifo);
  150         unlink(fifo);
  151         free(fifo);
  152         return;
  153     }
  154 
  155     switch ((pid = fork())) {
  156         case -1:
  157             break;
  158 
  159         case 0:
  160             /*
  161              * TODO: allow positioning, coloring, ...
  162              *       execlp("slrnface", "slrnface",
  163              *              "-xOffsetChar", tinrc.xfacex,
  164              *              "-yOffsetChar", tinrc.xfacey,
  165              *              "-ink", tinrc.xfacefg,
  166              *              "-paper", tinrc.xfacebg,
  167              *              fifo, NULL);
  168              */
  169             execlp("slrnface", "slrnface", fifo, NULL);
  170             /* This is child, exit on error. */
  171             giveup();
  172             /* NOTREACHED */
  173             break;
  174 
  175         default:
  176             do {
  177                 pidst = waitpid(pid, &status, 0);
  178             } while (pidst == -1 && errno == EINTR);
  179             if (!WIFEXITED(status))
  180                 error_message(2, _("Slrnface abnormally exited, code %d."), status);
  181             else {
  182                 const char *message;
  183 
  184                 switch (WEXITSTATUS(status)) {
  185                     case 0: /* All fine, open the pipe */
  186                         slrnface_fd = open(fifo, O_WRONLY, (S_IRUSR|S_IWUSR));
  187                         if (slrnface_fd != -1) {
  188                             write(slrnface_fd, "start\n", strlen("start\n"));
  189                             message = NULL;
  190                         } else
  191                             message = "can't open FIFO";
  192                         break;
  193 
  194                     /* TODO: warp into _()? */
  195                     case 1:
  196                         message = "couldn't connect to display";
  197                         break;
  198 
  199                     case 2:
  200                         message = "WINDOWID not found in environment";
  201                         break;
  202 
  203                     case 3:
  204                         message = "couldn't find controlling terminal";
  205                         break;
  206 
  207                     case 4:
  208                         message = "terminal doesn't export width and height";
  209                         break;
  210 
  211                     case 5:
  212                         message = "can't open FIFO";
  213                         break;
  214 
  215                     case 6:
  216                         message = "fork() failed";
  217                         break;
  218 
  219                     case 10:
  220                         message = "executable not found";
  221                         break;
  222 
  223                     default:
  224                         message = "unknown error";
  225                 }
  226                 if (message)
  227                     error_message(2, _("Slrnface failed: %s."), message);
  228             }
  229     }
  230     unlink(fifo);
  231     free(fifo);
  232 }
  233 
  234 
  235 void
  236 slrnface_stop(
  237     void)
  238 {
  239     if (slrnface_fd >= 0)
  240         close(slrnface_fd);
  241 
  242     slrnface_fd = -1;
  243     /* FIFO has been unlinked in the startup function. */
  244 }
  245 
  246 
  247 void
  248 slrnface_display_xface(
  249     char *face)
  250 {
  251     if (slrnface_fd < 0)
  252         return;
  253 
  254     if (!face || !*face)
  255         write(slrnface_fd, "clear\n", strlen("clear\n"));
  256     else {
  257         char buf[2000]; /* slrnface will ignore X-Faces larger than approx. 2000 chars. */
  258 
  259         snprintf(buf, sizeof(buf), "xface %s\n", face);
  260         write(slrnface_fd, buf, strlen(buf));
  261     }
  262 }
  263 
  264 
  265 void
  266 slrnface_clear_xface(
  267     void)
  268 {
  269     if (slrnface_fd < 0)
  270         return;
  271 
  272     write(slrnface_fd, "clear\n", strlen("clear\n"));
  273 }
  274 
  275 
  276 void
  277 slrnface_suppress_xface(
  278     void)
  279 {
  280     if (slrnface_fd < 0)
  281         return;
  282 
  283     write(slrnface_fd, "suppress\n", strlen("suppress\n"));
  284 }
  285 
  286 
  287 void
  288 slrnface_show_xface(
  289     void)
  290 {
  291     if (slrnface_fd < 0)
  292         return;
  293 
  294     write(slrnface_fd, "show\n", strlen("show\n"));
  295 }
  296 
  297 #else
  298 static void no_xface(void); /* proto-type */
  299 static void
  300 no_xface(   /* ANSI C requires non-empty source file */
  301     void)
  302 {
  303 }
  304 #endif /* XFACE_ABLE */