"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.4/src/xface.c" (20 Nov 2019, 7753 Bytes) of package /linux/misc/tin-2.4.4.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.4.3_vs_2.4.4.

    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-2020 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 
   55 void
   56 slrnface_start(
   57     void)
   58 {
   59     char *fifo;
   60     const char *ptr;
   61     int status;
   62     pid_t pid, pidst;
   63     size_t pathlen;
   64     struct utsname u;
   65 
   66     if (tinrc.use_slrnface == FALSE)
   67         return;
   68 
   69 #ifdef HAVE_IS_XTERM
   70     if (!is_xterm()) {
   71 #   ifdef DEBUG
   72         if (debug & DEBUG_MISC)
   73             error_message(2, _("Can't run slrnface: Not running in an xterm."));
   74 #   endif /* DEBUG */
   75         return;
   76     }
   77 #endif /* HAVE_IS_XTERM */
   78 
   79     /*
   80      * $DISPLAY holds the (default) display name
   81      */
   82     if (!getenv("DISPLAY")) {
   83 #   ifdef DEBUG
   84         if (debug & DEBUG_MISC)
   85             error_message(2, _("Can't run slrnface: Environment variable %s not found."), "DISPLAY");
   86 #   endif /* DEBUG */
   87         return;
   88     }
   89 
   90     /*
   91      * $WINDOWID holds the X window id number of the xterm window
   92      */
   93     if (!getenv("WINDOWID")) {
   94 #   ifdef DEBUG
   95         if (debug & DEBUG_MISC)
   96             error_message(2, _("Can't run slrnface: Environment variable %s not found."), "WINDOWID");
   97 #   endif /* DEBUG */
   98         return;
   99     }
  100 
  101     uname(&u);
  102     ptr = get_val("XDG_RUNTIME_DIR", get_val("HOME", ""));
  103     /*
  104      * TODO:
  105      * - check if $XDG_RUNTIME_DIR is on a local filesystem and has secure permissions
  106      * <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>
  107      */
  108     if (!strlen(ptr)) { /* TODO: mention XDG_RUNTIME_DIR in error message? */
  109 #   ifdef DEBUG
  110         if (debug & DEBUG_MISC)
  111             error_message(2, _("Can't run slrnface: Environment variable %s not found."), "HOME");
  112 #   endif /* DEBUG */
  113         return;
  114     }
  115     pathlen = strlen(ptr) + strlen("/.slrnfaces/") + strlen(u.nodename) + 30;
  116     fifo = my_malloc(pathlen);
  117     snprintf(fifo, pathlen, "%s/.slrnfaces", ptr);
  118     if (my_mkdir(fifo, (mode_t) S_IRWXU)) {
  119         if (errno != EEXIST) {
  120             perror_message(_("Can't run slrnface: failed to create %s"), fifo);
  121             free(fifo);
  122             return;
  123         }
  124     } else {
  125         FILE *fp;
  126 
  127         /* We abuse fifo filename memory here. It is long enough. */
  128         snprintf(fifo, pathlen, "%s/.slrnfaces/README", ptr);
  129         if ((fp = fopen(fifo, "w")) != NULL) {
  130             fputs(_("This directory is used to create named pipes for communication between\n"
  131 "slrnface and its parent process. It should normally be empty because\n"
  132 "the pipe is deleted right after it has been opened by both processes.\n\n"
  133 "File names generated by slrnface have the form \"hostname.pid\". It is\n"
  134 "probably an error if they linger here longer than a fraction of a second.\n\n"
  135 "However, if the directory is mounted from an NFS server, you might see\n"
  136 "special files created by your NFS server while slrnface is running.\n"
  137 "Do not try to remove them.\n"), fp);
  138             fclose(fp);
  139         }
  140     }
  141 
  142     status = snprintf(fifo, pathlen, "%s/.slrnfaces/%s.%ld", ptr, u.nodename, (long) getpid());
  143     if (status <= 0 || status >= (int) pathlen) {
  144         error_message(2, _("Can't run slrnface: couldn't construct fifo name."));
  145         unlink(fifo);
  146         free(fifo);
  147         return;
  148     }
  149 
  150     unlink(fifo);
  151     if (mkfifo(fifo, (S_IRUSR|S_IWUSR)) < 0) {
  152         perror_message(_("Can't run slrnface: failed to create %s"), fifo);
  153         unlink(fifo);
  154         free(fifo);
  155         return;
  156     }
  157 
  158     switch ((pid = fork())) {
  159         case -1:
  160             break;
  161 
  162         case 0:
  163             /*
  164              * TODO: allow positioning, coloring, ...
  165              *       execl(PATH_SLRNFACE, "slrnface",
  166              *              "-xOffsetChar", tinrc.xfacex,
  167              *              "-yOffsetChar", tinrc.xfacey,
  168              *              "-ink", tinrc.xfacefg,
  169              *              "-paper", tinrc.xfacebg,
  170              *              fifo, NULL);
  171              */
  172             execlp("slrnface", "slrnface", fifo, NULL);
  173             /* This is child, exit on error. */
  174             giveup();
  175             /* NOTREACHED */
  176             break;
  177 
  178         default:
  179             do {
  180                 pidst = waitpid(pid, &status, 0);
  181             } while (pidst == -1 && errno == EINTR);
  182             if (!WIFEXITED(status))
  183                 error_message(2, _("Slrnface abnormally exited, code %d."), status);
  184             else {
  185                 const char *message;
  186 
  187                 switch (WEXITSTATUS(status)) {
  188                     case 0: /* All fine, open the pipe */
  189                         slrnface_fd = open(fifo, O_WRONLY, (S_IRUSR|S_IWUSR));
  190                         if (slrnface_fd != -1) {
  191                             write(slrnface_fd, "start\n", strlen("start\n"));
  192                             message = NULL;
  193                         } else
  194                             message = "can't open FIFO";
  195                         break;
  196 
  197                     /* TODO: warp into _()? */
  198                     case 1:
  199                         message = "couldn't connect to display";
  200                         break;
  201 
  202                     case 2:
  203                         message = "WINDOWID not found in environment";
  204                         break;
  205 
  206                     case 3:
  207                         message = "couldn't find controlling terminal";
  208                         break;
  209 
  210                     case 4:
  211                         message = "terminal doesn't export width and height";
  212                         break;
  213 
  214                     case 5:
  215                         message = "can't open FIFO";
  216                         break;
  217 
  218                     case 6:
  219                         message = "fork() failed";
  220                         break;
  221 
  222                     case 10:
  223                         message = "executable not found";
  224                         break;
  225 
  226                     default:
  227                         message = "unknown error";
  228                 }
  229                 if (message)
  230                     error_message(2, _("Slrnface failed: %s."), message);
  231             }
  232     }
  233     unlink(fifo);
  234     free(fifo);
  235 }
  236 
  237 
  238 void
  239 slrnface_stop(
  240     void)
  241 {
  242     if (slrnface_fd >= 0)
  243         close(slrnface_fd);
  244 
  245     slrnface_fd = -1;
  246     /* FIFO has been unlinked in the startup function. */
  247 }
  248 
  249 
  250 void
  251 slrnface_display_xface(
  252     char *face)
  253 {
  254     if (slrnface_fd < 0)
  255         return;
  256 
  257     if (!face || !*face)
  258         write(slrnface_fd, "clear\n", strlen("clear\n"));
  259     else {
  260         char buf[2000]; /* slrnface will ignore X-Faces larger than approx. 2000 chars. */
  261 
  262         snprintf(buf, sizeof(buf), "xface %s\n", face);
  263         write(slrnface_fd, buf, strlen(buf));
  264     }
  265 }
  266 
  267 
  268 void
  269 slrnface_clear_xface(
  270     void)
  271 {
  272     if (slrnface_fd < 0)
  273         return;
  274 
  275     write(slrnface_fd, "clear\n", strlen("clear\n"));
  276 }
  277 
  278 
  279 void
  280 slrnface_suppress_xface(
  281     void)
  282 {
  283     if (slrnface_fd < 0)
  284         return;
  285 
  286     write(slrnface_fd, "suppress\n", strlen("suppress\n"));
  287 }
  288 
  289 
  290 void
  291 slrnface_show_xface(
  292     void)
  293 {
  294     if (slrnface_fd < 0)
  295         return;
  296 
  297     write(slrnface_fd, "show\n", strlen("show\n"));
  298 }
  299 
  300 #else
  301 static void no_xface(void); /* proto-type */
  302 static void
  303 no_xface(   /* ANSI C requires non-empty source file */
  304     void)
  305 {
  306 }
  307 #endif /* XFACE_ABLE */