"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.6.1/src/xface.c" (22 Dec 2021, 7690 Bytes) of package /linux/misc/tin-2.6.1.tar.xz:


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