"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.6.2/include/tin.h" (20 Dec 2022, 76264 Bytes) of package /linux/misc/tin-2.6.2.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 "tin.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.6.1_vs_2.6.2.

A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.


    1 /*
    2  *  Project   : tin - a Usenet reader
    3  *  Module    : tin.h
    4  *  Author    : I. Lea & R. Skrenta
    5  *  Created   : 1991-04-01
    6  *  Updated   : 2022-09-20
    7  *  Notes     : #include files, #defines & struct's
    8  *
    9  * Copyright (c) 1997-2023 Iain Lea <iain@bricbrac.de>, Rich Skrenta <skrenta@pbm.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  * OS specific doda's
   43  */
   44 
   45 #ifndef TIN_H
   46 #define TIN_H 1
   47 
   48 #ifdef HAVE_CONFIG_H
   49 #   ifndef TIN_AUTOCONF_H
   50 #       include <autoconf.h>    /* FIXME: normally we use 'config.h' */
   51 #   endif /* !TIN_AUTOCONF_H */
   52 #else
   53 #   ifndef HAVE_CONFDEFS_H
   54 #       error "configure run missing"
   55 #   endif /* !HAVE_CONFDEFS_H */
   56 #endif /* HAVE_CONFIG_H */
   57 
   58 
   59 /*
   60  * this causes trouble on Linux (forces nameserver lookups even for local
   61  * connections - this is an (unwanted) feature of getaddrinfo) see also
   62  * nntplib.c
   63  */
   64 /* IPv6 support */
   65 #if defined(HAVE_GETADDRINFO) && defined(HAVE_GAI_STRERROR) && defined(ENABLE_IPV6)
   66 #   define INET6
   67 #endif /* HAVE_GETADDRINFO && HAVE_GAI_STRERROR && ENABLE_IPV6 */
   68 
   69 
   70 /*
   71  * Native Language Support.
   72  */
   73 #ifndef NO_LOCALE
   74 #   ifdef HAVE_LOCALE_H
   75 #       include <locale.h>
   76 #   endif /* HAVE_LOCALE_H */
   77 #   ifndef HAVE_SETLOCALE
   78 #       define setlocale(Category, Locale) /* empty */
   79 #   endif /* !HAVE_SETLOCALE */
   80 #endif /* !NO_LOCALE */
   81 
   82 #define N_(Str) Str
   83 
   84 #if defined(ENABLE_NLS) && !defined(__BUILD__)
   85 #   ifdef HAVE_LIBINTL_H
   86 #       include <libintl.h>
   87 #   endif /* HAVE_LIBINTL_H */
   88 #   define _(Text)  gettext(Text)
   89 #else
   90 #   undef bindtextdomain
   91 #   define bindtextdomain(Domain, Directory) /* empty */
   92 #   undef textdomain
   93 #   define textdomain(Domain) /* empty */
   94 #   define _(Text) Text
   95 #endif /* ENABLE_NLS && !__BUILD__ */
   96 
   97 #ifndef LOCALEDIR
   98 #   define LOCALEDIR "/usr/share/locale"
   99 #endif /* !LOCALEDIR */
  100 
  101 #if defined(__amiga__) || defined(__amiga)
  102 #   define SMALL_MEMORY_MACHINE
  103 #endif /* __amiga__ || __amiga */
  104 
  105 #include <signal.h>
  106 
  107 enum context { cMain, cArt, cAttachment, cAttrib, cConfig, cFilter, cGroup, cInfopager, cPage, cPOSTED, cPost, cPostCancel, cPostFup, cReconnect, cScope, cSelect, cThread, cURL };
  108 enum icontext { cNone, cGetline, cPromptCONT, cPromptSLK, cPromptYN };
  109 enum resizer { cNo, cYes, cRedraw };
  110 enum rc_state { RC_IGNORE, RC_UPGRADE, RC_DOWNGRADE, RC_ERROR };
  111 
  112 #include <stdio.h>
  113 #ifdef HAVE_ERRNO_H
  114 #   include <errno.h>
  115 #else
  116 #   ifdef HAVE_SYS_ERRNO_H
  117 #       include <sys/errno.h>
  118 /*
  119     #   else
  120     #       error "No errno.h or sys/errno.h found"
  121 */
  122 #   endif /* HAVE_SYS_ERRNO_H */
  123 #endif /* HAVE_ERRNO_H */
  124 #if !defined(errno)
  125 #   ifdef DECL_ERRNO
  126         extern int errno;
  127 #   endif /* DECL_ERRNO */
  128 #endif /* !errno */
  129 #if !defined(EHOSTUNREACH)
  130 #   define EHOSTUNREACH 113
  131 #endif /* !EHOSTUNREACH */
  132 
  133 #ifdef HAVE_STDDEF_H
  134 #   include <stddef.h>
  135 #endif /* HAVE_STDDEF_H */
  136 #ifdef HAVE_SYS_TYPES_H
  137 #   include <sys/types.h>
  138 #endif /* HAVE_SYS_TYPES_H */
  139 
  140 #ifdef HAVE_SYS_STAT_H
  141 #   include <sys/stat.h>
  142 #endif /* HAVE_SYS_STAT_H */
  143 
  144 #ifdef TIME_WITH_SYS_TIME
  145 #   include <sys/time.h>
  146 #   include <time.h>
  147 #else
  148 #   ifdef HAVE_SYS_TIME_H
  149 #       include <sys/time.h>
  150 #   else
  151 #       include <time.h>
  152 #   endif /* HAVE_SYS_TIME_H */
  153 #endif /* TIME_WITH_SYS_TIME */
  154 
  155 #ifdef HAVE_SYS_TIMES_H
  156 #   include <sys/times.h>
  157 #endif /* HAVE_SYS_TIMES_H */
  158 
  159 #if defined(HAVE_LIBC_H) && defined(__NeXT__)
  160 #   include <libc.h>
  161 #endif /* HAVE_LIBC_H && __NeXT__ */
  162 
  163 #ifdef HAVE_UNISTD_H
  164 #   include <unistd.h>
  165 #endif /* HAVE_UNISTD_H */
  166 
  167 #ifdef HAVE_PWD_H
  168 #   include <pwd.h>
  169 #endif /* HAVE_PWD_H */
  170 
  171 #ifdef HAVE_SYS_PARAM_H
  172 #   include <sys/param.h>
  173 #endif /* HAVE_SYS_PARAM_H */
  174 
  175 #include <ctype.h>
  176 
  177 #ifdef HAVE_STDLIB_H
  178 #   include <stdlib.h>
  179 #endif /* HAVE_STDLIB_H */
  180 
  181 #include <stdarg.h>
  182 
  183 #ifdef HAVE_GETOPT_H
  184 #   include <getopt.h>
  185 #endif /* HAVE_GETOPT_H */
  186 
  187 #if defined(ENABLE_LONG_ARTICLE_NUMBERS) && !defined(SMALL_MEMORY_MACHINE)
  188 /*
  189  * defines and typedefs for 64 bit article numbers
  190  *
  191  * TODO: what if !CPP_DOES_CONCAT
  192  *       add configure check for PRIdLEAST64
  193  *       add configure check for SCNdLEAST64
  194  *       add configure check for INT64_MAX, LLONG_MAX, LONG_MAX
  195  */
  196 #   if defined(HAVE_INT_LEAST64_T) && !defined(HAVE_INTTYPES_H)
  197 #       undef HAVE_INT_LEAST64_T
  198 #   endif /* HAVE_INT_LEAST64_T && !HAVE_INTTYPES_H */
  199 #   if defined(HAVE_INT_LEAST64_T) || defined(HAVE_LONG_LONG) || defined(quad_t)
  200 #       if defined(HAVE_ATOLL) || defined(HAVE_ATOQ)
  201 #           ifdef HAVE_STRTOLL
  202 #               define USE_LONG_ARTICLE_NUMBERS 1
  203 #           endif /* HAVE_STRTOLL */
  204 #       endif /* HAVE_ATOLL || HAVE_ATOQ */
  205 #   endif /* HAVE_INT_LEAST64_T || HAVE_LONG_LONG || quad_t */
  206 #   ifdef HAVE_STDINT_H
  207 #       include <stdint.h>
  208 #   endif   /* HAVE_STDINT_H */
  209 #endif /* ENABLE_LONG_ARTICLE_NUMBERS && !SMALL_MEMORY_MACHINE */
  210 #ifdef USE_LONG_ARTICLE_NUMBERS
  211 #   if defined(HAVE_INT_LEAST64_T) && defined(HAVE_INT64_C)
  212 #       include <inttypes.h>
  213         typedef int_least64_t t_artnum;
  214 #       define T_ARTNUM_PFMT PRIdLEAST64
  215 #       define T_ARTNUM_SFMT SCNdLEAST64
  216 #       define T_ARTNUM_CONST(v) INT64_C(v)
  217 #       define ARTNUM_MAX INT64_MAX
  218 #   else
  219         typedef long long t_artnum;
  220 #       define T_ARTNUM_PFMT "lld"
  221 #       define T_ARTNUM_SFMT "lld"
  222 #       define T_ARTNUM_CONST(v) v ## LL
  223 #       define ARTNUM_MAX LLONG_MAX
  224 #   endif /* HAVE_INT_LEAST64_T && HAVE_INT64_C */
  225 #   ifdef HAVE_ATOLL
  226 #       define atoartnum atoll
  227 #   else
  228 #       define atoartnum atoq
  229 #   endif /* HAVE_ATOLL */
  230 #   define strtoartnum strtoll
  231 #else
  232     typedef long t_artnum;
  233 #   define T_ARTNUM_PFMT "ld"
  234 #   define T_ARTNUM_SFMT "ld"
  235 #   define T_ARTNUM_CONST(v) v ## L
  236 #   define ARTNUM_MAX LONG_MAX
  237 #   define atoartnum atol
  238 #   define strtoartnum strtol
  239 #endif /* USE_LONG_ARTICLE_NUMBERS */
  240 
  241 /*
  242  * FIXME: make this autoconf
  243  */
  244 #ifndef __QNX__
  245 #   ifdef HAVE_STRING_H
  246 #       include <string.h>
  247 #   else
  248 #       ifdef HAVE_STRINGS_H
  249 #           include <strings.h>
  250 #       endif /* HAVE_STRINGS_H */
  251 #   endif /* HAVE_STRING_H */
  252 #else
  253 #   ifdef HAVE_STRING_H
  254 #       include <string.h>
  255 #   endif /* HAVE_STRING_H */
  256 #   ifdef HAVE_STRINGS_H
  257 #       include <strings.h>
  258 #   endif /* HAVE_STRINGS_H */
  259 #endif /* !__QNX__ */
  260 
  261 /*
  262  * FIXME: make this autoconf
  263  */
  264 #ifdef SEIUX
  265 #   include <bsd/sys/time.h>
  266 #   include <bsd/sys/signal.h>
  267 #   include <bsd/sys/types.h>
  268 #   include <posix/unistd.h>
  269 #   include <bsd/netinet/in.h>
  270 #endif /* SEIUX */
  271 /* *-next-nextstep3 && *-next-openstep4 */
  272 #ifdef __NeXT__
  273 #   undef HAVE_SYS_UTSNAME_H
  274 #   undef HAVE_UNAME
  275 #   undef WEXITSTATUS
  276 #   undef WIFEXITED
  277 #   define IGNORE_SYSTEM_STATUS 1
  278 #   define HAVE_SYS_WAIT_H 1
  279 #   define NO_LOCKING 1
  280 #endif /* __NeXT__ */
  281 /* m68k-sun-sunos3.5 */
  282 #if defined(sun) || defined(__sun) && (!defined(__SVR4) || !defined(__svr4__)) && defined(BSD) && BSD < 199306
  283 #   define IGNORE_SYSTEM_STATUS 1
  284 #endif /* sun|| __sun && (!__SVR4 || __svr4__) && BSD && BSD < 199306 */
  285 
  286 #ifdef HAVE_FCNTL_H
  287 #   include <fcntl.h>
  288 #endif /* HAVE_FCNTL_H */
  289 
  290 #ifdef HAVE_SYS_IOCTL_H
  291 #   include <sys/ioctl.h>
  292 /* We don't need/use these, and they cause redefinition errors with SunOS 4.x
  293  * when we include termio.h or termios.h
  294  */
  295 #   if defined(sun) && !defined(__svr4)
  296 #       undef NL0
  297 #       undef NL1
  298 #       undef CR0
  299 #       undef CR1
  300 #       undef CR2
  301 #       undef CR3
  302 #       undef TAB0
  303 #       undef TAB1
  304 #       undef TAB2
  305 #       undef XTABS
  306 #       undef BS0
  307 #       undef BS1
  308 #       undef FF0
  309 #       undef FF1
  310 #       undef ECHO
  311 #       undef NOFLSH
  312 #       undef TOSTOP
  313 #       undef FLUSHO
  314 #       undef PENDIN
  315 #   endif /* sun && !__svr4 */
  316 #endif /* HAVE_SYS_IOCTL_H */
  317 
  318 #ifdef HAVE_PROTOTYPES_H
  319 #   include <prototypes.h>
  320 #endif /* HAVE_PROTOTYPES_H */
  321 
  322 #ifdef HAVE_SYS_UTSNAME_H
  323 #   include <sys/utsname.h>
  324 #endif /* HAVE_SYS_UTSNAME_H */
  325 
  326 /*
  327  * Needed for catching child processes
  328  */
  329 #ifdef HAVE_SYS_WAIT_H
  330 #   include <sys/wait.h>
  331 #endif /* HAVE_SYS_WAIT_H */
  332 
  333 #ifndef WEXITSTATUS
  334 #   define WEXITSTATUS(status)  ((int) (((status) >> 8) & 0xFF))
  335 #endif /* !WEXITSTATUS */
  336 
  337 #ifndef WIFEXITED
  338 #   define WIFEXITED(status)    ((int) (((status) & 0xFF) == 0))
  339 #endif /* !WIFEXITED */
  340 
  341 /*
  342  * Needed for timeout in user abort of indexing a group (BSD & SYSV variaties)
  343  */
  344 #ifdef HAVE_SYS_SELECT_H
  345 #   ifdef NEED_TIMEVAL_FIX
  346 #       define timeval fake_timeval
  347 #       include <sys/select.h>
  348 #       undef timeval
  349 #   else
  350 #       include <sys/select.h>
  351 #   endif /* NEED_TIMEVAL_FIX */
  352 #endif /* HAVE_SYS_SELECT_H */
  353 
  354 #if defined(HAVE_STROPTS_H) && !defined(__dietlibc__)
  355 #   include <stropts.h>
  356 #endif /* HAVE_STROPTS_H && !__dietlibc__ */
  357 
  358 #ifdef HAVE_POLL_H
  359 #   include <poll.h>
  360 #else
  361 #   ifdef HAVE_SYS_POLL_H
  362 #       include <sys/poll.h>
  363 #   endif /* HAVE_SYS_POLL_H */
  364 #endif /* HAVE_POLL_H */
  365 
  366 /*
  367  * Directory handling code
  368  */
  369 #ifdef HAVE_DIRENT_H
  370 #   include <dirent.h>
  371 /* #    define NAMLEN(dirent) strlen((dirent)->d_name) */
  372 #else
  373 #   define dirent direct
  374 /* #    define NAMLEN(dirent) (dirent)->d_namlen */
  375 #   ifdef HAVE_SYS_NDIR_H
  376 #       include <sys/ndir.h>
  377 #   endif /* HAVE_SYS_NDIR_H */
  378 #   ifdef HAVE_SYS_DIR_H
  379 #       include <sys/dir.h>
  380 #   endif /* HAVE_SYS_DIR_H */
  381 #   ifdef HAVE_NDIR_H
  382 #       include <ndir.h>
  383 #   endif /* HAVE_NDIR_H */
  384 #endif /* HAVE_DIRENT_H */
  385 
  386 #ifndef DIR_BUF
  387 #   define DIR_BUF struct dirent
  388 #endif /* !DIR_BUF */
  389 
  390 #ifndef HAVE_UNLINK
  391 #   define unlink(file) remove(file)
  392 #endif /* !HAVE_UNLINK */
  393 
  394 /*
  395  * If native OS hasn't defined STDIN_FILENO be a smartass and do it
  396  */
  397 #if !defined(STDIN_FILENO)
  398 #   define STDIN_FILENO 0
  399 #endif /* !STDIN_FILENO */
  400 
  401 /*
  402  * include <paths.h> if available to define _PATH_TMP
  403  */
  404 #ifdef HAVE_PATHS_H
  405 #   include <paths.h>
  406 #endif /* HAVE_PATHS_H */
  407 #ifndef _PATH_TMP
  408 #   define _PATH_TMP    "/tmp/"
  409 #endif /* _PATH_TMP */
  410 
  411 /*
  412  * If OS misses the isascii() function
  413  */
  414 #if !defined(HAVE_ISASCII) && !defined(isascii)
  415 #   define isascii(c) (!((c) & ~0177))
  416 #endif /* !HAVE_ISASCII && !isascii */
  417 
  418 
  419 /*
  420  * any pgp/gpp support possible and wanted
  421  * sort out possible conflicts: gpg is preferred over pgp5 over pgp
  422  */
  423 #if defined(HAVE_PGP) || defined(HAVE_PGPK) || defined(HAVE_GPG)
  424 #   define HAVE_PGP_GPG 1
  425 #   if defined(HAVE_PGP) && defined(HAVE_PGPK)
  426 #       undef HAVE_PGP
  427 #   endif /* HAVE_PGP && HAVE_PGPK */
  428 #   if defined(HAVE_PGPK) && defined(HAVE_GPG)
  429 #       undef HAVE_PGPK
  430 #   endif /* HAVE_PGPK && HAVE_GPG */
  431 #   if defined(HAVE_PGP) && defined(HAVE_GPG)
  432 #       undef HAVE_PGP
  433 #   endif /* HAVE_PGP && HAVE_GPG */
  434 #endif /* HAVE_PGP || HAVE_PGPK || HAVE_GPG */
  435 
  436 /*
  437  * slrnface requires some things
  438  */
  439 #if defined(HAVE_SLRNFACE) && defined(HAVE_MKFIFO) && defined(HAVE_FORK) && defined(HAVE_EXECLP) && defined(HAVE_WAITPID) && !defined(DONT_HAVE_PIPING) && !defined(X_DISPLAY_MISSING)
  440 #   define XFACE_ABLE
  441 #endif /* HAVE_SLRNFACE && HAVE_MKFIFO && HAVE_FORK && HAVE_EXECLP && HAVE_WAITPID && !DONT_HAVE_PIPING && !X_DISPLAY_MISSING */
  442 
  443 /*
  444  * Setup support for reading from NNTP
  445  */
  446 #if defined(NNTP_ABLE) || defined(NNTP_ONLY)
  447 #   ifndef NNTP_ABLE
  448 #       define NNTP_ABLE    1
  449 #   endif /* !NNTP_ABLE */
  450 #   ifndef NNTP_INEWS
  451 #       define NNTP_INEWS   1
  452 #   endif /* !NNTP_INEWS */
  453 #else
  454 #   ifdef XHDR_XREF
  455 #       undef XHDR_XREF
  456 #   endif /* XHDR_XREF */
  457 #   ifdef BROKEN_LISTGROUP
  458 #       undef BROKEN_LISTGROUP
  459 #   endif /* BROKEN_LISTGROUP */
  460 #endif /* NNTP_ABLE || NNTP_ONLY */
  461 
  462 #define FAKE_NNTP_FP        (FILE *) 9999
  463 
  464 /*
  465  * Max time between the first character of a VT terminal escape sequence
  466  * for special keys and the following characters to arrive (msec)
  467  */
  468 #define SECOND_CHARACTER_DELAY  200
  469 
  470 /*
  471  * Maximum time (seconds) for a VT terminal escape sequence
  472  */
  473 #define VT_ESCAPE_TIMEOUT   1
  474 
  475 /*
  476  * Determine machine configuration for external programs & directories
  477  */
  478 #if defined(BSD)
  479 /*
  480  * To catch 4.3 Net2 code base or newer
  481  * (e.g. FreeBSD 1.x, 4.3/Reno, NetBSD 0.9, 386BSD, BSD/386 1.1 and below).
  482  * use
  483  * #if (defined(BSD) && (BSD >= 199103))
  484  *
  485  * To detect if the code is being compiled on a 4.4 code base or newer
  486  * (e.g. FreeBSD 2.x, 4.4, NetBSD 1.0, BSD/386 2.0 or above).
  487  * use
  488  * #if (defined(BSD) && (BSD >= 199306))
  489  *
  490  * (defined in <sys/param.h>)
  491  */
  492 #   ifndef HAVE_MEMCMP
  493 #       define memcmp(s1, s2, n)    bcmp(s2, s1, n)
  494 #   endif /* !HAVE_MEMCMP */
  495 #   ifndef HAVE_MEMCPY
  496 #       define memcpy(s1, s2, n)    bcopy(s2, s1, n)
  497 #   endif /* !HAVE_MEMCPY */
  498 #   ifndef HAVE_MEMSET
  499 #       define memset(s1, s2, n)    bfill(s1, n, s2)
  500 #   endif /* !HAVE_MEMSET */
  501 #   ifndef HAVE_STRCHR
  502 #       define strchr(str, ch)  index(str, ch)
  503 #   endif /* !HAVE_STRCHR */
  504 #   ifndef HAVE_STRRCHR
  505 #       define strrchr(str, ch) rindex(str, ch)
  506 #   endif /* !HAVE_STRRCHR */
  507 #   if defined(__386BSD__) || defined(__bsdi__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
  508 #       define DEFAULT_PRINTER  "/usr/bin/lpr"
  509 #       define DEFAULT_SUM  "/usr/bin/cksum -o 1 <" /* use tailing <, otherwise get filename output too */
  510 #   else
  511 #       define DEFAULT_PRINTER  "/usr/ucb/lpr"
  512 #       define DEFAULT_SUM  "sum"
  513 #   endif /* __386BSD__ || __bsdi__ || __NetBSD__ || __FreeBSD__ || __OpenBSD__ */
  514 #   ifdef DGUX
  515 #       define USE_INVERSE_HACK
  516 #   endif /* DGUX */
  517 #   ifdef pyr
  518 #       define DEFAULT_MAILER   "/usr/.ucbucb/mail"
  519 #   endif /* pyr */
  520 #else /* !BSD */
  521 #   ifdef linux
  522 #       define DEFAULT_PRINTER  "/usr/bin/lpr"
  523 #   endif /* linux */
  524 #   ifdef QNX42
  525 #       ifndef DEFAULT_EDITOR
  526 #           define DEFAULT_EDITOR   "/bin/vedit"
  527 #       endif /* !DEFAULT_EDITOR */
  528 #   endif /* QNX42 */
  529 #   ifdef _AIX
  530 #       define DEFAULT_PRINTER  "/bin/lp"
  531 #       define READ_CHAR_HACK
  532 #   endif /* _AIX */
  533 #   ifdef sinix
  534 #       define DEFAULT_PRINTER  "/bin/lpr"
  535 #   endif /* sinix */
  536 #   ifdef sysV68
  537 #       define DEFAULT_MAILER   "/bin/rmail"
  538 #   endif /* sysV68 */
  539 #   ifdef UNIXPC
  540 #       define DEFAULT_MAILER   "/bin/rmail"
  541 #   endif /* UNIXPC */
  542 
  543 #   ifndef DEFAULT_PRINTER
  544 #       define DEFAULT_PRINTER  "/usr/bin/lp"
  545 #   endif /* !DEFAULT_PRINTER */
  546 #   ifndef PATH_SUM
  547 #       define DEFAULT_SUM  "sum -r"
  548 #   endif /* !PATH_SUM */
  549 #endif /* BSD */
  550 
  551 /*
  552  * fallback values
  553  */
  554 #ifndef DEFAULT_EDITOR
  555 #   define DEFAULT_EDITOR   "/usr/bin/vi"
  556 #endif /* !DEFAULT_EDITOR */
  557 #ifndef DEFAULT_MAILER
  558 #   define DEFAULT_MAILER   "/usr/lib/sendmail"
  559 #endif /* !DEFAULT_MAILER */
  560 #ifndef DEFAULT_MAILBOX
  561 #   define DEFAULT_MAILBOX  "/usr/spool/mail"
  562 #endif /* !DEFAULT_MAILBOX */
  563 
  564 
  565 /* FIXME: remove absolute-paths! */
  566 /*
  567  * Miscellaneous program-paths
  568  */
  569 #ifndef PATH_ISPELL
  570 #   define PATH_ISPELL  "ispell"
  571 #endif /* !PATH_ISPELL */
  572 
  573 #ifndef PATH_METAMAIL   /* only unset if !HAVE_METAMAIL */
  574 #   define PATH_METAMAIL    "metamail"
  575 #endif /* !PATH_METAMAIL */
  576 #define METAMAIL_CMD        PATH_METAMAIL" -e -p -m \"tin\""
  577 
  578 #define INTERNAL_CMD    "--internal"
  579 
  580 /*
  581  * Fix up the 'sum' path and parameter for './configure'd systems
  582  */
  583 #ifdef PATH_SUM
  584 #   ifdef DEFAULT_SUM
  585 #       undef DEFAULT_SUM
  586 #   endif /* DEFAULT_SUM */
  587 #   ifdef SUM_TAKES_DASH_R
  588 #       define DEFAULT_SUM PATH_SUM_R
  589 #   else
  590 #       define DEFAULT_SUM PATH_SUM
  591 #   endif /* SUM_TAKES_DASH_R */
  592 #endif /* PATH_SUM */
  593 
  594 #ifdef HAVE_LONG_FILE_NAMES
  595 #   define PATH_PART    "part"
  596 #   define PATH_PATCH   "patch"
  597 #   define INDEX_LOCK   "tin.%s.LCK"
  598 #else
  599 #   define PATH_PART    ""
  600 #   define PATH_PATCH   "p"
  601 #   define INDEX_LOCK   "%s.LCK"
  602 #endif /* HAVE_LONG_FILE_NAMES */
  603 
  604 /* inews.c:submit_inews() and save.c:save_and_process_art() */
  605 #define PATHMASTER  "not-for-mail"
  606 
  607 /*
  608  * How often should the active file be reread for new news
  609  */
  610 #ifndef REREAD_ACTIVE_FILE_SECS
  611 #   define REREAD_ACTIVE_FILE_SECS 1200 /* seconds (20 mins) */
  612 #endif /* !REREAD_ACTIVE_FILE_SECS */
  613 
  614 /*
  615  * Initial sizes of internal arrays for small (<4MB) & large memory machines
  616  */
  617 #ifdef SMALL_MEMORY_MACHINE
  618 #   define DEFAULT_ARTICLE_NUM  600
  619 #   define DEFAULT_SAVE_NUM 10
  620 #else
  621 #   define DEFAULT_ARTICLE_NUM  1200
  622 #   define DEFAULT_SAVE_NUM 30
  623 #endif /* SMALL_MEMORY_MACHINE */
  624 #define DEFAULT_ACTIVE_NUM  1800
  625 #define DEFAULT_NEWNEWS_NUM 5
  626 #define DEFAULT_MAPKEYS_NUM 100 /* ~remappable keys per level (avoid massiv reallocs) */
  627 #define DEFAULT_SCOPE_NUM   8
  628 
  629 #define RCDIR   ".tin"
  630 #define INDEX_MAILDIR   ".mail"
  631 #define INDEX_NEWSDIR   ".news"
  632 #define INDEX_SAVEDIR   ".save"
  633 
  634 #define ACTIVE_FILE "active"
  635 #define ACTIVE_MAIL_FILE    "active.mail"
  636 #define ACTIVE_SAVE_FILE    "active.save"
  637 #define ACTIVE_TIMES_FILE   "active.times"
  638 #define ATTRIBUTES_FILE "attributes"
  639 #define CONFIG_FILE "tinrc"
  640 #define SERVERCONFIG_FILE   "serverrc"
  641 #define DEFAULT_MAILDIR "Mail"
  642 #define DEFAULT_SAVEDIR "News"
  643 #define DEFAULT_URL_HANDLER "url_handler.pl"
  644 /* Prefixes saved attachments with no set filename */
  645 #define SAVEFILE_PREFIX     "unknown"
  646 
  647 
  648 /* MMDF-mailbox separator */
  649 #ifndef MMDFHDRTXT
  650 #   define MMDFHDRTXT "\01\01\01\01\n"
  651 #endif /* MMDFHDRTXT */
  652 
  653 
  654 /*
  655  * all regexps are extended -> # must be quoted!
  656  */
  657 #ifdef HAVE_COLOR
  658 /* case insensitive */
  659 #   define DEFAULT_QUOTE_REGEX  "^\\s{0,3}(?:[\\]{}>|:)]|\\w{1,3}[>|])(?!-)"
  660 #   define DEFAULT_QUOTE_REGEX2 "^\\s{0,3}(?:(?:[\\]{}>|:)]|\\w{1,3}[>|])\\s*){2}(?!-[})>])"
  661 #   define DEFAULT_QUOTE_REGEX3 "^\\s{0,3}(?:(?:[\\]{}>|:)]|\\w{1,3}[>|])\\s*){3}"
  662 #endif /* HAVE_COLOR */
  663 
  664 /* case insensitive */
  665 #if 0 /* single words only */
  666 #   define DEFAULT_SLASHES_REGEX    "(?:^|(?<=\\s))/[^\\s/]+/(?:(?=[,.!?;]?\\s)|$)"
  667 #   define DEFAULT_STARS_REGEX  "(?:^|(?<=\\s))\\*[^\\s*]+\\*(?:(?=[,.!?;]?\\s)|$)"
  668 #   define DEFAULT_UNDERSCORES_REGEX    "(?:^|(?<=\\s))_[^\\s_]+_(?:(?=[,.!?;]?\\s)|$)"
  669 #   define DEFAULT_STROKES_REGEX    "(?:^|(?<=\\s))-[^-\\s]+-(?:(?=[,.!?;]?\\s)|$)"
  670 #else /* multiple words */
  671 #   define DEFAULT_SLASHES_REGEX    "(?:^|(?<=\\s))/(?(?=[^-*/_\\s][^/\\s])[^-*/_\\s][^/]*[^-*/_\\s]|[^/\\s])/(?:(?=[,.!?;]?\\s)|$)"
  672 #   define DEFAULT_STARS_REGEX  "(?:^|(?<=\\s))\\*(?(?=[^-*/_\\s][^*\\s])[^-*/_\\s][^*]*[^-*/_\\s]|[^*\\s])\\*(?:(?=[,.!?;]?\\s)|$)"
  673 #   define DEFAULT_UNDERSCORES_REGEX    "(?:^|(?<=\\s))_(?(?=[^-*/_\\s][^_\\s])[^-*/_\\s][^_]*[^-*/_\\s]|[^_\\s])_(?:(?=[,.!?;]?\\s)|$)"
  674 #   define DEFAULT_STROKES_REGEX    "(?:^|(?<=\\s))-(?(?=[^-*/_\\s][^-\\s])[^-*/_\\s][^-]*[^-*/_\\s]|[^-\\s])-(?:(?=[,.!?;]?\\s)|$)"
  675 #endif /* 0 */
  676 
  677 /* case sensitive && ^-anchored */
  678 #define DEFAULT_STRIP_RE_REGEX  "(?:R[eE](?:\\^\\d+|\\[\\d+\\])?|A[wW]|Odp|Sv):\\s"
  679 /* case sensitive */
  680 #define DEFAULT_STRIP_WAS_REGEX "(?:(?<=\\S)|\\s)\\((?:[Ww]a[rs]|[Bb]y[l\\xb3]o):.*\\)\\s*$"
  681 #define DEFAULT_U8_STRIP_WAS_REGEX  "(?:(?<=\\S)|\\s)\\((?:[Ww]a[rs]|[Bb]y[l\\x{0142}]o):.*\\)\\s*$"
  682 /*
  683  * overkill regexp for balanced '()':
  684  * #define DEFAULT_STRIP_WAS_REGEX  "(?:(?<=\\S)|\\s)\\((?:[Ww]a[rs]|[Bb]y[l\xb3]o):(?:(?:[^)(])*(?:\\([^)(]*\\))*)+\\)\\s*$"
  685  */
  686 
  687 /* case sensitive & ^-anchored */
  688 #define UUBEGIN_REGEX   "begin\\s\\s?[0-7]{3,4}\\s+"
  689 /* case sensitive & ^-anchored */
  690 #define UUBODY_REGEX    "(?:`|.[\\x20-\\x60]{1,61})$"
  691 
  692 /* case sensitive & ^-anchored */
  693 #define SHAR_REGEX  "\\#(?:!\\s?(?:/usr)?/bin/sh|\\s?(?i)this\\sis\\sa\\sshell\\sarchive)"
  694 
  695 /* slrn verbatim marks, case sensitive & ^-anchored */
  696 #define DEFAULT_VERBATIM_BEGIN_REGEX    "#v\\+\\s$"
  697 #define DEFAULT_VERBATIM_END_REGEX  "#v-\\s$"
  698 
  699 /* quoted text from external sources */
  700 #define DEFAULT_EXTQUOTE_REGEX "^\\|\\s"
  701 
  702 /*
  703  * URL related regexs:
  704  * add TELNET (RFC 4248), WAIS (RFC 4156), IMAP (RFC 2192), NFS (RFC 2224)
  705  *     LDAP (RFC 2255), POP (RFC 2384), ...
  706  * add IPv6 (RFC 3986) support
  707  */
  708 /*
  709  * case insensitive
  710  * TODO: - split out ftp (only ftp allows username:passwd@, RFC 1738)?
  711  *       - test IDNA (RFC 3490) case
  712  *       - adjust to follow RFC 3986 (section 2.3)
  713  */
  714 #define URL_REGEX   "\\b(?:https?|ftp|gopher)://(?:[^:@/\\s]*(?::[^:@/\\s]*)?@)?(?:(?:(?:[^\\W_](?:(?:-|[^\\W_]){0,61}(?<!---)[^\\W_])?|xn--[^\\W_](?:-(?!-)|[^\\W_]){1,57}[^\\W_])\\.)+[a-z]{2,18}\\.?|localhost|(?:(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?)|\\[(?:(?:[0-9A-F]{0,4}:){1,7}[0-9A-F]{1,4}|(?:[0-9A-F]{0,4}:){1,3}(?:(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?))\\])(?::\\d+)?(?:[-a-zA-Z0-9()@:%_\\+.~#?&\\/=\\$,]*)"
  715 /*
  716  * case insensitive
  717  * TOFO: check against RFC 6068
  718  */
  719 #define MAIL_REGEX  "\\b(?:mailto:(?:[-\\w$.+!*'(),;/?:@&=]|%[\\da-f]{2})+)(?<!\\))"
  720 /*
  721  * case insensitive
  722  * TODO: check against RFC 5538
  723  */
  724 #define NEWS_REGEX "\\b(?:s?news|nntp):(?:(?:(?://(?:(?:[^\\W_](?:(?:-|[^\\W_]){0,61}(?<!---)[^\\W_])?|xn--[^\\W_](?:-(?!-)|[^\\W_]){1,57}[^\\W_])\\.)+[a-z]{2,14}\\.?|localhost|(?:(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?))(?::\\d+)?(?(?=[/])[^()\\^\\[\\]{}\\|\\x00-\\x1f\\x7f\\s\"<>'\\\\:,;]+|$))|[^\\^\\[\\]{}\\|\\x00-\\x1f\\x7f\\s<>\"():,;\\\\'/]+)\\b"
  725 
  726 #if 0 /* not implemented */
  727 /*
  728  * case insensitive
  729  */
  730 #   define TELNET_REGEX "\\btelnet://(?:[^:@/]*(?::[^:@/]*)?@)?(?:(?:[^\\W_](?:(?:-|[^\\W_]){0,61}(?<!---)[^\\W_])?\\.)+[a-z]{2,14}\\.?||localhost|(?:(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?))(?::\\d+)?/?"
  731 #endif /* 0 */
  732 
  733 
  734 #define FILTER_FILE "filter"
  735 #define INPUT_HISTORY_FILE  ".inputhistory"
  736 #ifdef HAVE_MH_MAIL_HANDLING
  737 #   define MAILGROUPS_FILE  "mailgroups"
  738 #endif /* HAVE_MH_MAIL_HANDLING */
  739 #define NEWSRC_FILE ".newsrc"
  740 #define NEWSRCTABLE_FILE    "newsrctable"
  741 /* ifdef APPEND_PID (default) NEWNEWSRC_FILE will be .newnewsrc<pid> */
  742 #define NEWNEWSRC_FILE  ".newnewsrc"
  743 #define OLDNEWSRC_FILE  ".oldnewsrc"
  744 #ifndef OVERVIEW_FILE
  745 #   define OVERVIEW_FILE    ".overview"
  746 #endif /* !OVERVIEW_FILE */
  747 #define OVERVIEW_FMT    "overview.fmt"
  748 #define POSTED_FILE "posted"
  749 #define POSTPONED_FILE  "postponed.articles"
  750 #define SUBSCRIPTIONS_FILE  "subscriptions"
  751 #define NEWSGROUPS_FILE "newsgroups"
  752 #define KEYMAP_FILE "keymap"
  753 
  754 #define SIGDASHES "-- \n"
  755 
  756 #ifndef BOOL_H
  757 #   include "bool.h"
  758 #endif /* BOOL_H */
  759 
  760 /* Philip Hazel's Perl regular expressions library */
  761 #ifdef HAVE_LIB_PCRE2
  762 
  763 #define PCRE2_CODE_UNIT_WIDTH 0
  764 #include <pcre2.h>
  765 
  766 #define REGEX_CASELESS PCRE2_CASELESS
  767 #define REGEX_ANCHORED PCRE2_ANCHORED
  768 #define REGEX_NOTEMPTY PCRE2_NOTEMPTY
  769 
  770 #define REGEX_ERROR_NOMATCH PCRE2_ERROR_NOMATCH
  771 
  772 #define REGEX_OPTIONS uint32_t
  773 #define REGEX_NOFFSET uint32_t
  774 #define REGEX_SIZE size_t
  775 
  776 #else /* HAVE_LIB_PCRE2 */
  777 
  778 #include <pcre.h>
  779 
  780 #define REGEX_CASELESS PCRE_CASELESS
  781 #define REGEX_ANCHORED PCRE_ANCHORED
  782 #define REGEX_NOTEMPTY PCRE_NOTEMPTY
  783 
  784 #define REGEX_ERROR_NOMATCH PCRE_ERROR_NOMATCH
  785 
  786 #define REGEX_OPTIONS int
  787 #define REGEX_NOFFSET int
  788 #define REGEX_SIZE int
  789 
  790 #endif /* HAVE_LIB_PCRE2 */
  791 
  792 #ifdef HAVE_ICONV
  793 #   define CHARSET_CONVERSION 1
  794 #   ifdef HAVE_ICONV_H
  795 #       include <iconv.h>
  796 #   endif /* HAVE_ICONV_H */
  797 #endif /* HAVE_ICONV */
  798 
  799 #ifdef HAVE_LANGINFO_H
  800 #   include <langinfo.h>
  801 #else
  802 #   ifdef HAVE_NL_TYPES_H
  803 #       include <nl_types.h>
  804 #   endif /* HAVE_NL_TYPES_H */
  805 #endif /* HAVE_LANGINFO_H */
  806 #ifndef HAVE_NL_ITEM
  807     typedef int nl_item;
  808 #endif /* HAVE_NL_ITEM */
  809 #ifndef CODESET
  810 #   define CODESET ((nl_item) 1)
  811 #endif /* CODESET */
  812 
  813 #ifdef CHARSET_CONVERSION
  814 #   define IS_LOCAL_CHARSET(c)  (!strncasecmp(tinrc.mm_local_charset, c, strlen(c)))
  815 #else
  816 #   define IS_LOCAL_CHARSET(c)  (!strncasecmp(tinrc.mm_charset, c, strlen(c)))
  817 #endif /* CHARSET_CONVERSION */
  818 
  819 /* TODO: move up to the 'right' place */
  820 #ifdef HAVE_SYS_FILE_H
  821 #   include <sys/file.h>
  822 #endif /* HAVE_SYS_FILE_H */
  823 
  824 #ifdef HAVE_LIBUTF8_H
  825 #   include <libutf8.h>
  826 #else
  827 /*
  828  * order is important here:
  829  * - Solaris 2.5.1 requires wchar.h before wctype.h
  830  * - Tru64 with Desktop Toolkit C requires stdio.h before wchar.h
  831  * - BSD/OS 4.0.1 requires stddef.h, stdio.h and time.h before wchar.h
  832  */
  833 #   ifdef HAVE_WCHAR_H
  834 #       include <wchar.h>
  835 #   endif /* HAVE_WCHAR_H */
  836 #   ifdef HAVE_WCTYPE_H
  837 #       include <wctype.h>
  838 #   endif /* HAVE_WCTYPE_H */
  839 #endif /* HAVE_LIBUTF8_H */
  840 
  841 #ifndef MAX
  842 #   define MAX(a,b) (((a) > (b)) ? (a) : (b))
  843 #endif /* !MAX */
  844 #ifndef MIN
  845 #   define MIN(a,b) (((a) > (b)) ? (b) : (a))
  846 #endif /* !MIN */
  847 
  848 #ifndef forever
  849 /*@notfunction@*/
  850 #   define forever  for(;;)
  851 #endif /* !forever */
  852 
  853 /*
  854  * safe strcpy into fixed-legth buffer
  855  */
  856 #if 1
  857 #   define STRCPY(dst, src) (strncpy(dst, src, sizeof(dst) - 1), dst[sizeof(dst) - 1] = '\0')
  858 #else
  859 #   define STRCPY(dst, src) (*(dst) = '\0', strncat(dst, src, sizeof(dst) - 1))
  860 #endif /* 1 */
  861 
  862 #define STRCMPEQ(s1, s2)    (strcmp((s1), (s2)) == 0)
  863 #define STRNCMPEQ(s1, s2, n)    (strncmp((s1), (s2), n) == 0)
  864 #define STRNCASECMPEQ(s1, s2, n)    (strncasecmp((s1), (s2), n) == 0)
  865 
  866 /*
  867  * PATH_LEN    = max. path length (incl. terminating '\0')
  868  * NAME_LEN    = max. filename length (not incl. terminating '\0')
  869  * LEN         =
  870  * HEADER_LEN  = max. size of a news/mail header-line
  871  * NEWSRC_LINE =
  872  */
  873 
  874 #ifdef PATH_MAX
  875 #   define PATH_LEN PATH_MAX
  876 #else
  877 #   ifdef MAXPATHLEN
  878 #       define PATH_LEN MAXPATHLEN
  879 #   else
  880 #       ifdef _POSIX_PATH_MAX
  881 #           define PATH_LEN _POSIX_PATH_MAX
  882 #       else
  883 #           define PATH_LEN 255
  884 #       endif /* _POSIX_PATH_MAX */
  885 #   endif /* MAXPATHLEN */
  886 #endif /* PATH_MAX */
  887 #ifdef HAVE_LONG_FILE_NAMES
  888 #   ifdef NAME_MAX
  889 #       define NAME_LEN NAME_MAX
  890 #   else
  891 #       ifdef _POSIX_NAME_MAX
  892 #           define NAME_LEN _POSIX_NAME_MAX
  893 #       else
  894 #           define NAME_LEN 14
  895 #       endif /* _POSIX_NAME_MAX */
  896 #   endif /* NAME_MAX */
  897 #else
  898 #   define NAME_LEN 14
  899 #endif /* HAVE_LONG_FILE_NAMES */
  900 #define LEN 1024
  901 
  902 #define NEWSRC_LINE 8192
  903 #define HEADER_LEN  1024
  904 #define IMF_LINE_LEN 998 /* RFC 5322 2.1.1 */
  905 
  906 #define TABLE_SIZE  1409
  907 
  908 #define MODULO_COUNT_NUM    50
  909 
  910 #define DAY (60*60*24)      /* Seconds in a day */
  911 
  912 #define ctrl(c) ((c) & 0x1F)
  913 
  914 #ifndef DEFAULT_ISO2ASC
  915 #   define DEFAULT_ISO2ASC  "-1 "   /* ISO -> ASCII charset conversion */
  916 #endif /* !DEFAULT_ISO2ASC */
  917 
  918 #ifndef DEFAULT_COMMENT
  919 #   define DEFAULT_COMMENT  "> "    /* used when by follow-ups & replies */
  920 #endif /* !DEFAULT_COMMENT */
  921 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
  922 #   define T_CHAR_FMT "lc"
  923 #else
  924 #   define T_CHAR_FMT "c"
  925 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
  926 #ifndef ART_MARK_UNREAD
  927 #   define ART_MARK_UNREAD  '+' /* used to show that an art is unread */
  928 #endif /* !ART_MARK_UNREAD */
  929 #ifndef ART_MARK_RETURN
  930 #   define ART_MARK_RETURN  '-' /* used to show that an art will return */
  931 #endif /* !ART_MARK_RETURN */
  932 #ifndef ART_MARK_SELECTED
  933 #   define ART_MARK_SELECTED    '*' /* used to show that an art was auto selected */
  934 #endif /* !ART_MARK_SELECTED */
  935 #ifndef ART_MARK_RECENT
  936 #   define ART_MARK_RECENT  'o' /* used to show that an art is fresh */
  937 #endif /* !ART_MARK_RECENT */
  938 #ifndef ART_MARK_READ
  939 #   define ART_MARK_READ    ' ' /* used to show that an art was not read or seen */
  940 #endif /* !ART_MARK_READ */
  941 #ifndef ART_MARK_READ_SELECTED
  942 #   define ART_MARK_READ_SELECTED ':'   /* used to show that a read art is hot (kill_level >0) */
  943 #endif /* !ART_MARK_READ_SELECTED */
  944 #ifndef ART_MARK_KILLED
  945 #   define ART_MARK_KILLED 'K'      /* art has been killed (kill_level >0) */
  946 #endif /* !ART_MARK_KILLED */
  947 #ifndef ART_MARK_DELETED
  948 #   define ART_MARK_DELETED 'D' /* art has been marked for deletion (mailgroup) */
  949 #endif /* !ART_MARK_DELETED */
  950 #ifndef MARK_INRANGE
  951 #   define MARK_INRANGE '#' /* group/art within a range (# command) */
  952 #endif /* !MARK_INRANGE */
  953 
  954 
  955 /*
  956  * Unicode chars for thread and attachment tree and cursor (instead of "|+`->")
  957  * only available when IS_LOCAL_CHARSET("UTF-8")
  958  */
  959 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
  960     /*
  961      * For CURSOR_ARROW and CURSOR_HORIZ tinrc.utf8_graphics ? :
  962      * is handled inside screen.c:draw_arrow_mark().
  963      */
  964 #   define CURSOR_ARROW     (wint_t) 0x25B6
  965 #   define CURSOR_HORIZ     (wint_t) 0x2500
  966 #   define TREE_ARROW       (wchar_t) (tinrc.utf8_graphics ? 0x25B6 : '>')
  967 #   define TREE_ARROW_WRAP  (wchar_t) (tinrc.utf8_graphics ? 0x25B7 : '>')
  968 #   define TREE_BLANK       (wchar_t) ' '
  969 #   define TREE_HORIZ       (wchar_t) (tinrc.utf8_graphics ? 0x2500 : '-')
  970 #   define TREE_UP_RIGHT    (wchar_t) (tinrc.utf8_graphics ? 0x2514 : '`')
  971 #   define TREE_VERT        (wchar_t) (tinrc.utf8_graphics ? 0x2502 : '|')
  972 #   define TREE_VERT_RIGHT  (wchar_t) (tinrc.utf8_graphics ? 0x251C : '+')
  973 #else
  974     /*
  975      * No need for CURSOR_ARROW and CURSOR_HORIZ here. This is handled inside
  976      * screen.c:draw_arrow_mark().
  977      */
  978 #   define TREE_ARROW       '>'
  979 #   define TREE_ARROW_WRAP  '>'
  980 #   define TREE_BLANK       ' '
  981 #   define TREE_HORIZ       '-'
  982 #   define TREE_UP_RIGHT    '`'
  983 #   define TREE_VERT        '|'
  984 #   define TREE_VERT_RIGHT  '+'
  985 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
  986 
  987 #ifdef USE_INVERSE_HACK
  988 #   define BLANK_PAGE_COLS  2
  989 #else
  990 #   define BLANK_PAGE_COLS  0
  991 #endif /* USE_INVERSE_HACK */
  992 
  993 /*
  994  * Return values for tin_errno
  995  */
  996 #define TIN_ABORT       1           /* User requested abort or timeout */
  997 
  998 #define TINRC_CONFIRM_ACTION    (tinrc.confirm_choice == 1 || tinrc.confirm_choice == 4 || tinrc.confirm_choice == 5 || tinrc.confirm_choice == 7)
  999 #define TINRC_CONFIRM_TO_QUIT   (tinrc.confirm_choice == 3 || tinrc.confirm_choice == 4 || tinrc.confirm_choice == 6 || tinrc.confirm_choice == 7)
 1000 #define TINRC_CONFIRM_SELECT    (tinrc.confirm_choice == 2 || tinrc.confirm_choice == 5 || tinrc.confirm_choice == 6 || tinrc.confirm_choice == 7)
 1001 #define TINRC_CONFIRM_MAX   7
 1002 
 1003 /*
 1004  * defines for tinrc.auto_cc_bcc
 1005  */
 1006 #define AUTO_CC                 1
 1007 #define AUTO_BCC                2
 1008 #define AUTO_CC_BCC             3
 1009 
 1010 /*
 1011  * defines for tinrc.goto_next_unread
 1012  */
 1013 #define NUM_GOTO_NEXT_UNREAD    4
 1014 #define GOTO_NEXT_UNREAD_PGDN   1
 1015 #define GOTO_NEXT_UNREAD_TAB    2
 1016 
 1017 /*
 1018  * defines for tinrc.trim_article_body
 1019  */
 1020 #define NUM_TRIM_ARTICLE_BODY   8
 1021 #define SKIP_LEADING            1
 1022 #define SKIP_TRAILING           2
 1023 #define COMPACT_MULTIPLE        4
 1024 
 1025 /*
 1026  * defines for tinrc.show_help_mail_sign
 1027  */
 1028 enum {
 1029     SHOW_SIGN_NONE = 0,
 1030     SHOW_SIGN_HELP,
 1031     SHOW_SIGN_MAIL,
 1032     SHOW_SIGN_BOTH
 1033 };
 1034 
 1035 /*
 1036  * MIME Encodings
 1037  */
 1038 enum {
 1039     MIME_ENCODING_8BIT = 0,
 1040     MIME_ENCODING_BASE64,
 1041     MIME_ENCODING_QP,
 1042     MIME_ENCODING_7BIT
 1043 };
 1044 
 1045 /*
 1046  * Number of charset-traslation tables (iso2asci)
 1047  */
 1048 #define NUM_ISO_TABLES  7
 1049 
 1050 /*
 1051  * Maximum permissible colour number
 1052  */
 1053 #define MAX_COLOR   15
 1054 #define MAX_BACKCOLOR   7
 1055 
 1056 /*
 1057  * Count of available attributes for highlighting
 1058  */
 1059 #define MAX_ATTR    6
 1060 
 1061 /*
 1062  * Maximal permissible word mark type
 1063  * 0 = nothing, 1 = mark, 2 = space
 1064  */
 1065 #define MAX_MARK    2
 1066 
 1067 /* Line number (starting at 0) of 1st non-header data on the screen */
 1068 /* ie, size of header */
 1069 #define INDEX_TOP   2
 1070 #define INDEX2LNUM(i)   (INDEX_TOP + (i) - currmenu->first)
 1071 #ifndef USE_CURSES
 1072 #   define INDEX2SNUM(i)    ((i) - currmenu->first)
 1073 #endif /* !USE_CURSES */
 1074 
 1075 #define GROUP_MATCH(s1, pat, case_s)        (wildmat(s1, pat, case_s))
 1076 
 1077 #define REGEX_FMT (tinrc.wildcard ? "%s" : "*%s*")
 1078 
 1079 #define IGNORE_ART(i)   ((tinrc.kill_level != KILL_THREAD && arts[i].killed) || (arts[i].thread == ART_EXPIRED))
 1080 /* only used for threading */
 1081 #define IGNORE_ART_THREAD(i)    (arts[i].thread != ART_UNTHREADED || (tinrc.kill_level == KILL_NOTHREAD && arts[i].killed))
 1082 
 1083 /*
 1084  * Is this part text/plain?
 1085  */
 1086 #define IS_PLAINTEXT(x) \
 1087             (x->type == TYPE_TEXT && strcasecmp("plain", x->subtype) == 0)
 1088 
 1089 /* TRUE if basenote has responses */
 1090 #define HAS_FOLLOWUPS(i)    (arts[base[i]].thread >= 0)
 1091 
 1092 /*
 1093  * Only close off our stream when reading on local spool
 1094  */
 1095 #ifdef NNTP_ABLE
 1096 #   define TIN_FCLOSE(x)    if (x != FAKE_NNTP_FP) fclose(x)
 1097 #else
 1098 #   define TIN_FCLOSE(x)    fclose(x)
 1099 #endif /* NNTP_ABLE */
 1100 
 1101 /*
 1102  * Often used macro to point to the group we are currently in
 1103  */
 1104 #define CURR_GROUP  (active[my_group[selmenu.curr]])
 1105 
 1106 /*
 1107  * Defines an unread group
 1108  */
 1109 #define UNREAD_GROUP(i)     (!active[my_group[i]].bogus && active[my_group[i]].newsrc.num_unread > 0)
 1110 
 1111 /*
 1112  * Expands to singular/plural version of string
 1113  */
 1114 #define PLURAL(x,y)         ((x == 1) ? _(y##_singular) : _(y##_plural))
 1115 
 1116 /*
 1117  * News/Mail group types
 1118  */
 1119 #define GROUP_TYPE_MAIL 0
 1120 #define GROUP_TYPE_NEWS 1
 1121 #define GROUP_TYPE_SAVE 2   /* saved news, read with tin -R */
 1122 
 1123 /*
 1124  * used by get_arrow_key()
 1125  */
 1126 #   define KEYMAP_UNKNOWN       0
 1127 #   define KEYMAP_UP        1
 1128 #   define KEYMAP_DOWN      2
 1129 #   define KEYMAP_LEFT      3
 1130 #   define KEYMAP_RIGHT     4
 1131 #   define KEYMAP_PAGE_UP       5
 1132 #   define KEYMAP_PAGE_DOWN 6
 1133 #   define KEYMAP_HOME      7
 1134 #   define KEYMAP_END       8
 1135 #   define KEYMAP_DEL       9
 1136 #   define KEYMAP_INS       10
 1137 #   define KEYMAP_MOUSE     11
 1138 
 1139 
 1140 /*
 1141  * used in main.c, curses.c and signal.c
 1142  * it's useless trying to run tin interactively below these sizes
 1143  * (values acquired by testing ;-) )
 1144  */
 1145 #define MIN_LINES_ON_TERMINAL        8
 1146 #define MIN_COLUMNS_ON_TERMINAL     40
 1147 
 1148 
 1149 /*
 1150  * indicate given cmd-line options
 1151  */
 1152 #define CMDLINE_GETART_LIMIT    1
 1153 #define CMDLINE_MAILDIR         2
 1154 #define CMDLINE_NNTPSERVER      4
 1155 #define CMDLINE_SAVEDIR         8
 1156 #define CMDLINE_USE_COLOR       16
 1157 
 1158 
 1159 /*
 1160  * used by feed_articles() & show_mini_help() & quick_filter & add_filter_rule
 1161  */
 1162 #define SELECT_LEVEL    1
 1163 #define GROUP_LEVEL 2
 1164 #define THREAD_LEVEL    3
 1165 #define PAGE_LEVEL  4
 1166 #define INFO_PAGER  5
 1167 #define SCOPE_LEVEL 6
 1168 #define CONFIG_LEVEL    7
 1169 #define ATTRIB_LEVEL    8
 1170 #define ATTACHMENT_LEVEL    9
 1171 #define URL_LEVEL   10
 1172 #define POSTED_LEVEL    11
 1173 
 1174 #define MINI_HELP_LINES     5
 1175 
 1176 #define FEED_MAIL       1
 1177 #define FEED_PIPE       2
 1178 #define FEED_PRINT      3
 1179 #define FEED_SAVE       4
 1180 #define FEED_AUTOSAVE   5
 1181 #define FEED_REPOST     6
 1182 #define FEED_MARK_READ      7
 1183 #define FEED_MARK_UNREAD    8
 1184 
 1185 
 1186 /*
 1187  * Threading strategies available
 1188  */
 1189 #define THREAD_NONE     0
 1190 #define THREAD_SUBJ     1
 1191 #define THREAD_REFS     2
 1192 #define THREAD_BOTH     3
 1193 #define THREAD_MULTI        4
 1194 #define THREAD_PERC     5
 1195 
 1196 #define THREAD_MAX      THREAD_PERC
 1197 
 1198 #define THREAD_PERC_DEFAULT 75
 1199 
 1200 /*
 1201  * Values for show_author
 1202  */
 1203 #define SHOW_FROM_NONE      0
 1204 #define SHOW_FROM_ADDR      1
 1205 #define SHOW_FROM_NAME      2
 1206 #define SHOW_FROM_BOTH      3
 1207 
 1208 /*
 1209  * Values for thread_score
 1210  */
 1211 #define THREAD_SCORE_MAX    0
 1212 #define THREAD_SCORE_SUM    1
 1213 #define THREAD_SCORE_WEIGHT 2
 1214 
 1215 /*
 1216  * Values for interactive_mailer
 1217  */
 1218 enum {
 1219     INTERACTIVE_NONE = 0,
 1220     INTERACTIVE_WITH_HEADERS,
 1221     INTERACTIVE_WITHOUT_HEADERS
 1222 };
 1223 
 1224 /*
 1225  * used in feed.c & save.c
 1226  */
 1227 #define POST_PROC_NO        0
 1228 #define POST_PROC_SHAR      1
 1229 #define POST_PROC_YES       2
 1230 
 1231 /*
 1232  * used in art.c
 1233  * sort types on arts[] array
 1234  */
 1235 #define SORT_ARTICLES_BY_NOTHING        0
 1236 #define SORT_ARTICLES_BY_SUBJ_DESCEND   1
 1237 #define SORT_ARTICLES_BY_SUBJ_ASCEND    2
 1238 #define SORT_ARTICLES_BY_FROM_DESCEND   3
 1239 #define SORT_ARTICLES_BY_FROM_ASCEND    4
 1240 #define SORT_ARTICLES_BY_DATE_DESCEND   5
 1241 #define SORT_ARTICLES_BY_DATE_ASCEND    6
 1242 #define SORT_ARTICLES_BY_SCORE_DESCEND  7
 1243 #define SORT_ARTICLES_BY_SCORE_ASCEND   8
 1244 #define SORT_ARTICLES_BY_LINES_DESCEND  9
 1245 #define SORT_ARTICLES_BY_LINES_ASCEND   10
 1246 
 1247 /*
 1248  * used in art.c
 1249  * sort types on base[] array
 1250  */
 1251 #define SORT_THREADS_BY_NOTHING         0
 1252 #define SORT_THREADS_BY_SCORE_DESCEND   1
 1253 #define SORT_THREADS_BY_SCORE_ASCEND    2
 1254 #define SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND   3
 1255 #define SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND    4
 1256 
 1257 /*
 1258  * Different values of strip_bogus - the ways to handle bogus groups
 1259  */
 1260 #define BOGUS_KEEP      0   /* not used */
 1261 #define BOGUS_REMOVE        1
 1262 #define BOGUS_SHOW      2
 1263 
 1264 /*
 1265  * Different extents to which we can hide killed articles
 1266  */
 1267 #define KILL_UNREAD     0       /* Kill only unread articles */
 1268 #define KILL_THREAD     1       /* Kill all articles and show as K */
 1269 #define KILL_NOTHREAD   2       /* Kill all articles, never show them */
 1270 
 1271 /*
 1272  * Various types of quoting behaviour
 1273  */
 1274 #define QUOTE_COMPRESS  1       /* Compress quotes */
 1275 #define QUOTE_SIGS      2       /* Quote signatures */
 1276 #define QUOTE_EMPTY     4       /* Quote empty lines */
 1277 
 1278 
 1279 /*
 1280  * used in save.c/main.c
 1281  */
 1282 #define CHECK_ANY_NEWS      0
 1283 #define START_ANY_NEWS      1
 1284 #define MAIL_ANY_NEWS       2
 1285 #define SAVE_ANY_NEWS       3
 1286 
 1287 
 1288 /*
 1289  * used in post.c
 1290  */
 1291 #define POSTED_NONE     0           /* Article wasn't posted */
 1292 #define POSTED_REDRAW       1           /* redraw needed in any case */
 1293 #define POSTED_OK       2           /* posted normally */
 1294 
 1295 
 1296 /*
 1297  * used in pager
 1298  */
 1299 #define UUE_NO          0       /* Don't hide uue data */
 1300 #define UUE_YES         1       /* Hide uue data */
 1301 #define UUE_ALL         2       /* Hide uue data harder */
 1302 
 1303 /*
 1304  * used in misc.c/rfc1524.c
 1305  */
 1306 enum quote_enum {
 1307     no_quote = 0,
 1308     dbl_quote,
 1309     sgl_quote
 1310 };
 1311 
 1312 
 1313 /*
 1314  * Values used in show_article_by_msid
 1315  */
 1316 enum {
 1317     LOOKUP_OK           = 0,
 1318     LOOKUP_FAILED       = -1,
 1319     LOOKUP_QUIT         = -2,
 1320     LOOKUP_UNAVAIL      = -3,
 1321     LOOKUP_REPLY        = -4,
 1322     LOOKUP_ART_UNAVAIL  = -5,
 1323     LOOKUP_NO_LAST      = -6
 1324 };
 1325 
 1326 /*
 1327  * index_point variable values used throughout tin
 1328  */
 1329 
 1330 /*
 1331  * -1 is kind of overloaded as an error from which_thread() and other functions
 1332  * where we wish to return to the next level up
 1333  */
 1334 enum {
 1335     GRP_RETSELECT   = -1,   /* Pager 'T' command only -> return to selection screen */
 1336     GRP_QUIT        = -2,   /* Set by 'Q' when coming all the way out */
 1337     GRP_NEXTUNREAD  = -3,   /* (After catchup) goto next unread item */
 1338     GRP_NEXT        = -4,   /* (After catchup) move to next item */
 1339     GRP_ARTUNAVAIL  = -5,   /* show_page() Article is unavailable */
 1340     GRP_ARTABORT    = -6,   /* show_page() User aborted article read */
 1341     GRP_KILLED      = -7,   /* ?? Thread was killed at pager level */
 1342     GRP_GOTOTHREAD  = -8,   /* show_page() only. Goto thread menu */
 1343     GRP_ENTER       = -9,   /* New group is set, spin in read_groups() */
 1344     GRP_EXIT        = -10   /* Normal return to higher level */
 1345 };
 1346 
 1347 #ifndef EXIT_SUCCESS
 1348 #   define EXIT_SUCCESS 0   /* Successful exit status */
 1349 #endif /* !EXIT_SUCCESS */
 1350 
 1351 #ifndef EXIT_FAILURE
 1352 #   define EXIT_FAILURE 1   /* Failing exit status */
 1353 #endif /* !EXIT_FAILURE */
 1354 
 1355 #define NEWS_AVAIL_EXIT 2
 1356 #define NNTP_ERROR_EXIT 3
 1357 
 1358 /*
 1359  * Assertion verifier
 1360  */
 1361 #ifdef assert
 1362 #   undef assert
 1363 #endif /* assert */
 1364 #ifdef NDEBUG
 1365 #   define assert(p)        ((void) 0)
 1366 #else
 1367 #   ifdef CPP_DOES_EXPAND
 1368 #       define assert(p)    if(!(p)) asfail(__FILE__, __LINE__, #p); else (void) 0;
 1369 #   else
 1370 #       define assert(p)    if(!(p)) asfail(__FILE__, __LINE__, "p"); else (void) 0;
 1371 #   endif /* CPP_DOES_EXPAND */
 1372 #endif /* NDEBUG */
 1373 
 1374 #define ESC 27
 1375 
 1376 /*
 1377  * filter entries expire after DEFAULT_FILTER_DAYS
 1378  */
 1379 #define DEFAULT_FILTER_DAYS     28
 1380 
 1381 /*
 1382  * art.thread
 1383  */
 1384 #define ART_UNTHREADED  -1
 1385 #define ART_EXPIRED     -2
 1386 
 1387 /*
 1388  * Where does this belong?? It is overloaded
 1389  */
 1390 #define ART_NORMAL      -1
 1391 
 1392 /*
 1393  * art.status
 1394  */
 1395 #define ART_READ        0
 1396 #define ART_UNREAD      1
 1397 #define ART_WILL_RETURN     2
 1398 #define ART_UNAVAILABLE     -1 /* Also used by msgid.article */
 1399 
 1400 /*
 1401  * art.killed
 1402  */
 1403 #define ART_NOTKILLED       0
 1404 #define ART_KILLED      1
 1405 #define ART_KILLED_UNREAD   2
 1406 
 1407 /*
 1408  * Additionally used for user aborts in art_open()
 1409  */
 1410 #define ART_ABORT       -2
 1411 
 1412 /*
 1413  * used by t_group & my_group[]
 1414  */
 1415 #define UNSUBSCRIBED    '!'
 1416 #define SUBSCRIBED  ':'
 1417 
 1418 /* Converts subscription status to char for .newsrc */
 1419 #define SUB_CHAR(x) (x ? SUBSCRIBED : UNSUBSCRIBED)
 1420 /* Converts .newsrc subscription char to boolean */
 1421 #define SUB_BOOL(x) (x == SUBSCRIBED)
 1422 
 1423 /*
 1424  * filter_type used in struct t_filter
 1425  */
 1426 #define SCORE_MAX       10000
 1427 
 1428 #define FILTER_SUBJ_CASE_SENSITIVE      0
 1429 #define FILTER_SUBJ_CASE_IGNORE     1
 1430 #define FILTER_FROM_CASE_SENSITIVE      2
 1431 #define FILTER_FROM_CASE_IGNORE     3
 1432 #define FILTER_MSGID        4
 1433 #define FILTER_MSGID_LAST   5
 1434 #define FILTER_MSGID_ONLY   6
 1435 #define FILTER_REFS_ONLY    7
 1436 #define FILTER_LINES        8
 1437 
 1438 #define FILTER_LINES_NO     0
 1439 #define FILTER_LINES_EQ     1
 1440 #define FILTER_LINES_LT     2
 1441 #define FILTER_LINES_GT     3
 1442 
 1443 /*
 1444  * default format strings for selection, group, thread level
 1445  * and the date display in the page header.
 1446  * Don't change without adjusting rc_update() and the like accordingly!
 1447  */
 1448 #define DEFAULT_SELECT_FORMAT   "%f %n %U  %G  %d"
 1449 #define DEFAULT_GROUP_FORMAT    "%n %m %R %L  %s  %F"
 1450 #define DEFAULT_THREAD_FORMAT   "%n %m  [%L]  %T  %F"
 1451 #define DEFAULT_DATE_FORMAT     "%a, %d %b %Y %H:%M:%S"
 1452 
 1453 /*
 1454  * unicode normalization
 1455  */
 1456 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
 1457 #   ifdef HAVE_LIBICUUC
 1458 #       define HAVE_UNICODE_NORMALIZATION 3
 1459 #   else
 1460 #       ifdef HAVE_LIBUNISTRING
 1461 #           define HAVE_UNICODE_NORMALIZATION 2
 1462 #       else
 1463 #           if defined(HAVE_LIBIDN) && defined(HAVE_STRINGPREP_H)
 1464 #               define HAVE_UNICODE_NORMALIZATION 1
 1465 #           endif /* HAVE_LIBIDN && HAVE_STRINGPREP_H */
 1466 #       endif /* HAVE_LIBUNISTRING */
 1467 #   endif /* HAVE_LIBICUUC */
 1468 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
 1469 
 1470 /*
 1471  * normalization forms, we prefer NFC (see RFC 6532) if possible
 1472  */
 1473 #ifdef HAVE_UNICODE_NORMALIZATION
 1474 enum {
 1475     NORMALIZE_NONE = 0,
 1476     NORMALIZE_NFKC = 1,
 1477 #   if (HAVE_UNICODE_NORMALIZATION >= 2)
 1478     NORMALIZE_NFKD = 2,
 1479     NORMALIZE_NFC = 3,
 1480     NORMALIZE_NFD = 4
 1481 #       ifdef HAVE_UNICODE_UNORM2_H
 1482     , NORMALIZE_NFKC_CF = 5
 1483 #       endif /* HAVE_UNICODE_UNORM2_H */
 1484 #   endif /* HAVE_UNICODE_NORMALIZATION >= 2 */
 1485 };
 1486 #   if (HAVE_UNICODE_NORMALIZATION >= 2)
 1487 #       ifdef HAVE_UNICODE_UNORM2_H
 1488 #           define NORMALIZE_MAX NORMALIZE_NFKC_CF
 1489 #       else
 1490 #           define NORMALIZE_MAX NORMALIZE_NFD
 1491 #       endif /* HAVE_UNICODE_UNORM2_H */
 1492 #       define DEFAULT_NORMALIZE NORMALIZE_NFC
 1493 #   else
 1494 #       define NORMALIZE_MAX NORMALIZE_NFKC
 1495 #       define DEFAULT_NORMALIZE NORMALIZE_NFKC
 1496 #   endif /* HAVE_UNICODE_NORMALIZATION >= 2 */
 1497 #endif /* HAVE_UNICODE_NORMALIZATION */
 1498 
 1499 #ifdef HAVE_LIBICUUC
 1500 #   ifdef HAVE_UNICODE_USTRING_H
 1501 #       include <unicode/ustring.h>
 1502 #   endif /* HAVE_UNICODE_USTRING_H */
 1503 #   ifdef HAVE_UNICODE_UNORM2_H
 1504 #       include <unicode/unorm2.h>
 1505 #   else
 1506 #       ifdef HAVE_UNICODE_UNORM_H
 1507 #           include <unicode/unorm.h>
 1508 #       endif /* HAVE_UNICODE_UNORM_H */
 1509 #   endif /* HAVE_UNICODE_UNORM2_H */
 1510 #   ifdef HAVE_UNICODE_UIDNA_H
 1511 #       include <unicode/uidna.h>
 1512 #   endif /* HAVE_UNICODE_UIDNA_H */
 1513 #   ifdef HAVE_UNICODE_UBIDI_H
 1514 #       include <unicode/ubidi.h>
 1515 #   endif /* HAVE_UNICODE_UBIDI_H */
 1516 #endif /* HAVE_LIBICUUC */
 1517 
 1518 
 1519 /*
 1520  * used in checking article header before posting
 1521  */
 1522 #define MAX_COL     78  /* Max. line length before issuing a warning */
 1523 #define MAX_SIG_LINES   4   /* Max. num. of signature lines before warning */
 1524 
 1525 typedef unsigned char   t_bitmap;
 1526 
 1527 /*
 1528  * Keys for add_msgid()
 1529  */
 1530 #define REF_REF             1       /* Add a ref->ref entry */
 1531 #define MSGID_REF           2       /* Add a msgid->ref entry */
 1532 
 1533 /*
 1534  * Size of hash tables for hash_str() and hash_msgid()
 1535  * Make sure it's prime!
 1536  */
 1537 #ifdef SMALL_MEMORY_MACHINE
 1538 #   define HASHNODE_TABLE_SIZE 2411
 1539 #   define MSGID_HASH_SIZE  2609
 1540 #else
 1541 #   define HASHNODE_TABLE_SIZE 222199
 1542 #   define MSGID_HASH_SIZE  222199
 1543 #endif /* MSGID_HASH_SIZE */
 1544 
 1545 /*
 1546  * cmd-line options
 1547  */
 1548 struct t_cmdlineopts {
 1549     int getart_limit;           /* getart_limit */
 1550     char maildir[PATH_LEN];     /* maildir */
 1551     char nntpserver[PATH_LEN];  /* nntpserver */
 1552     char savedir[PATH_LEN];     /* savedir */
 1553     unsigned int args:5;        /* given options */
 1554 };
 1555 
 1556 /*
 1557  * struct t_msgid - message id
 1558  */
 1559 struct t_msgid {
 1560     struct t_msgid *next;       /* Next in hash chain */
 1561     struct t_msgid *parent;     /* Message-id followed up to */
 1562     struct t_msgid *sibling;    /* Next followup to parent */
 1563     struct t_msgid *child;      /* First followup to this article */
 1564     int article;            /* index in arts[] or ART_NORMAL */
 1565     char txt[1];            /* The actual msgid */
 1566 };
 1567 
 1568 /*
 1569  * struct t_article - article header
 1570  *
 1571  * article.thread:
 1572  * the next article in thread
 1573  *  -1  (ART_UNTHREADED) article exists but is not (yet) threaded
 1574  *  -2  (ART_EXPIRED) article has expired (wasn't found in search of spool
 1575  *      directory for the group)
 1576  *  >=0 points to another arts[] (struct t_article)
 1577  *
 1578  * article.prev:
 1579  *  the previous article in thread
 1580  *  -1  (ART_NORMAL) initial default, first (no previous) article in thread
 1581  *  >=0 points to the previous arts[] (struct t_article)
 1582  */
 1583 struct t_article {
 1584     t_artnum artnum;        /* Article number in spool directory for group */
 1585     char *subject;          /* Subject: line from mail header */
 1586     char *from;         /* From: line from mail header (address) */
 1587     char *name;         /* From: line from mail header (full name) */
 1588     char *xref;         /* Xref: cross posted article reference line */
 1589     char *path;         /* Path: line */
 1590     /* NB: The msgid and refs are only retained until the reference tree is built */
 1591     char *msgid;            /* Message-ID: unique message identifier */
 1592     char *refs;         /* References: article reference id's */
 1593     struct t_msgid *refptr;     /* Pointer to us in the reference tree */
 1594     time_t date;            /* Date: line from header in seconds */
 1595     int line_count;         /* Lines: number of lines in article */
 1596     int gnksa_code;         /* From: line from mail header (GNKSA error code) */
 1597     int tagged;         /* 0 = not tagged, >0 = tagged */
 1598     int thread;
 1599     int prev;
 1600     int score;          /* score article has reached after filtering */
 1601     unsigned int status:2;  /* 0 = read, 1 = unread, 2 = will return */
 1602     unsigned int killed:2;  /* 0 = not killed, 1 = killed, 2 = killed unread */
 1603     t_bool zombie:1;    /* 1 = was alive (unread) before 'X' command */
 1604     t_bool delete_it:1; /* 1 = delete art when leaving group [mail group] */
 1605     t_bool selected:1;  /* FALSE = not selected, TRUE = selected */
 1606     t_bool inrange:1;   /* TRUE = article selected via # range command */
 1607     t_bool matched:1;   /* TRUE = article matched regex in feed.c */
 1608     t_bool keep_in_base:1;  /* TRUE = keep (read) article in base[] (show_only_unread_arts) */
 1609     t_bool multipart_subj:1;    /* TRUE = subject looks like multipart subject */
 1610 };
 1611 
 1612 
 1613 #ifdef NNTP_ABLE
 1614 /*
 1615  * struct t_article_range - holds ranges of article numbers to perform actions on parts of arts[]
 1616  */
 1617 struct t_article_range {
 1618     t_artnum start;
 1619     t_artnum end;
 1620     t_artnum cnt;
 1621     struct t_article_range *next;
 1622 };
 1623 #endif /* NNTP_ABLE */
 1624 
 1625 
 1626 /*
 1627  * struct t_newsheader - holds an array of which news headers to [not] display
 1628  */
 1629 struct t_newsheader {
 1630     char **header;  /* array of which headers to [not] display */
 1631     int num;        /* number of headers in array header */
 1632 };
 1633 
 1634 /*
 1635  * Use these macros to quiet gcc warnings when assigning into a bitfield.
 1636  */
 1637 #define CAST_MASK(value,bits)   (((1U << (bits)) - 1) & (unsigned) (value))
 1638 #define CAST_BOOL(value)    CAST_MASK(value, 1)
 1639 #define CAST_BITS(value,bits)   CAST_MASK(value, BITS_OF(bits))
 1640 #define BITS_OF(bits)       BITS_OF_ ## bits
 1641 
 1642 #define BoolField(value)    unsigned value:1
 1643 #define IntField(value) unsigned value:BITS_OF(value)
 1644 
 1645 #define BITS_OF_auto_cc_bcc     2
 1646 #define BITS_OF_mail_mime_encoding  2
 1647 #define BITS_OF_mm_network_charset  6
 1648 #define BITS_OF_post_mime_encoding  2
 1649 #define BITS_OF_post_process_type   2
 1650 #define BITS_OF_quick_kill_header   3
 1651 #define BITS_OF_quick_select_header 3
 1652 #define BITS_OF_show_author     2
 1653 #define BITS_OF_sort_article_type   4
 1654 #define BITS_OF_sort_threads_type   3
 1655 #define BITS_OF_thread_articles 3
 1656 #define BITS_OF_thread_perc     7
 1657 #define BITS_OF_trim_article_body   3
 1658 
 1659 /*
 1660  * struct t_attribute - configurable attributes on a per group basis
 1661  */
 1662 struct t_attribute {
 1663     char *maildir;              /* mail dir if other than ~/Mail */
 1664     char *savedir;              /* save dir if other than ~/News */
 1665     char *savefile;             /* save articles to specified file */
 1666     char *sigfile;              /* sig file if other than ~/.Sig */
 1667     char *group_format;         /* format string for group level */
 1668     char *thread_format;        /* format string for thread level */
 1669     char *date_format;          /* format string for the date display */
 1670     char *editor_format;        /* editor + parameters  %E +%N %F */
 1671     char *organization;         /* organization name */
 1672     char *fcc;                  /* Fcc folder for mail */
 1673     char *followup_to;          /* where posts should be redirected */
 1674     char *quick_kill_scope;     /* quick filter kill scope */
 1675     char *quick_select_scope;   /* quick filter select scope */
 1676     char *mailing_list;         /* mail list email address */
 1677     char *news_headers_to_display;  /* which headers to display */
 1678     char *news_headers_to_not_display;  /* which headers to not display */
 1679     char *x_headers;            /* extra headers for message header */
 1680     char *x_body;               /* boilerplate text for message body */
 1681     char *from;                 /* from line */
 1682     char *news_quote_format;    /* another way to begin a posting format */
 1683     char *quote_chars;          /* string to precede quoted text on each line */
 1684     char *mime_types_to_save;   /* MIME content major/minors we want to save */
 1685 #ifdef HAVE_ISPELL
 1686     char *ispell;               /* path to ispell and options */
 1687 #endif /* HAVE_ISPELL */
 1688 #ifdef CHARSET_CONVERSION
 1689     char *undeclared_charset;       /* charset of articles without MIME charset declaration */
 1690     IntField(mm_network_charset);       /* network charset */
 1691 #endif /* CHARSET_CONVERSION */
 1692     struct t_newsheader *headers_to_display;    /* array of which headers to display */
 1693     struct t_newsheader *headers_to_not_display;    /* array of which headers to not display */
 1694     BoolField(global);          /* global/group specific */
 1695     IntField(quick_kill_header);    /* quick filter kill header */
 1696     BoolField(quick_kill_expire);   /* quick filter kill limited/unlimited time */
 1697     BoolField(quick_kill_case);     /* quick filter kill case sensitive? */
 1698     IntField(quick_select_header);  /* quick filter select header */
 1699     BoolField(quick_select_expire); /* quick filter select limited/unlimited time */
 1700     BoolField(quick_select_case);   /* quick filter select case sensitive? */
 1701     BoolField(add_posted_to_filter);    /* add posted articles to filter */
 1702     BoolField(advertising);         /* add User-Agent: -header */
 1703     BoolField(alternative_handling);    /* skip multipart/alternative parts */
 1704     BoolField(ask_for_metamail);    /* ask before using MIME viewer */
 1705     IntField(auto_cc_bcc);          /* add your name to cc/bcc automatically */
 1706     BoolField(auto_list_thread);    /* list thread when entering it using right arrow */
 1707     BoolField(auto_select);         /* 0=show all unread, 1='X' just hot arts */
 1708     BoolField(batch_save);          /* 0=none, 1=save -S/mail -M */
 1709     BoolField(delete_tmp_files);    /* 0=leave, 1=delete */
 1710     BoolField(group_catchup_on_exit);   /* ask if read groups are to be marked read */
 1711     BoolField(mail_8bit_header);    /* allow 8bit chars. in header of mail message */
 1712     IntField(mail_mime_encoding);
 1713     BoolField(mark_ignore_tags);    /* Ignore tags for GROUP_MARK_THREAD_READ/THREAD_MARK_ARTICLE_READ */
 1714     BoolField(mark_saved_read);     /* mark saved article/thread as read */
 1715     BoolField(pos_first_unread);    /* position cursor at first/last unread article */
 1716     BoolField(post_8bit_header);    /* allow 8bit chars. in header when posting to newsgroup */
 1717     IntField(post_mime_encoding);
 1718     BoolField(post_process_view);   /* set TRUE to invoke mailcap viewer app */
 1719 #ifndef DISABLE_PRINTING
 1720     BoolField(print_header);        /* print all of mail header or just Subject: & From lines */
 1721 #endif /* !DISABLE_PRINTING */
 1722     BoolField(process_only_unread); /* save/print//mail/pipe unread/all articles */
 1723     BoolField(prompt_followupto);   /* display empty Followup-To header in editor */
 1724     BoolField(show_only_unread_arts);   /* 0=all, 1=only unread */
 1725     BoolField(sigdashes);           /* set TRUE to prepend every signature with dashes */
 1726     BoolField(signature_repost);    /* set TRUE to add signature when reposting articles */
 1727     IntField(thread_articles);          /* 0=unthread, 1=subject, 2=refs, 3=both, 4=multipart, 5=percentage */
 1728     BoolField(thread_catchup_on_exit);  /* catchup thread with left arrow key or not */
 1729     IntField(thread_perc);          /* percentage threading threshold */
 1730     IntField(show_author);          /* 0=none, 1=name, 2=addr, 3=both */
 1731     BoolField(show_signatures);     /* 0=none, 1=show signatures */
 1732 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
 1733     BoolField(suppress_soft_hyphens);   /* set TRUE to remove soft hyphens (U+00AD) from articles */
 1734 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
 1735     IntField(trim_article_body);    /* 0=Don't trim article body, 1=Skip leading blank lines,
 1736                         2=Skip trailing blank lines, 3=Skip leading and trailing blank lines,
 1737                         4=Compact multiple blank lines between textblocks,
 1738                         5=Compact multiple blank lines between textblocks and skip leading blank lines,
 1739                         6=Compact multiple blank lines between textblocks and skip trailing blank lines,
 1740                         7=Compact multiple blank lines between textblocks and skip leading and trailing
 1741                           blank lines */
 1742     BoolField(verbatim_handling);   /* 0=none, 1=detect verbatim blocks */
 1743 #ifdef HAVE_COLOR
 1744     BoolField(extquote_handling);       /* 0=none, 1=detect quoted text from external sources */
 1745 #endif /* HAVE_COLOR */
 1746     BoolField(wrap_on_next_unread); /* Wrap around threads when searching next unread article */
 1747     IntField(sort_article_type);        /* 0=none, 1=subj descend, 2=subj ascend,
 1748                            3=from descend, 4=from ascend,
 1749                            5=date descend, 6=date ascend,
 1750                            7=score descend, 8=score ascend */
 1751     IntField(sort_threads_type);    /* 0=none, 1=score descend, 2=score ascend,
 1752                            3=last posting date descend, 4=last posting date ascend */
 1753     IntField(post_process_type);    /* 0=none, 1=shar, 2=uudecode */
 1754     BoolField(x_comment_to);    /* insert X-Comment-To: in Followup */
 1755     BoolField(tex2iso_conv);    /* Convert TeX2ISO */
 1756     BoolField(mime_forward);    /* forward articles as attachment or inline */
 1757 };
 1758 
 1759 /*
 1760  * struct t_attribute_state - holds additional information
 1761  * about numeric attributes within a scope
 1762  */
 1763 struct t_attribute_state {
 1764     BoolField(add_posted_to_filter);
 1765     BoolField(advertising);
 1766     BoolField(alternative_handling);
 1767     BoolField(ask_for_metamail);
 1768     BoolField(auto_cc_bcc);
 1769     BoolField(auto_list_thread);
 1770     BoolField(auto_select);
 1771     BoolField(batch_save);
 1772     BoolField(date_format);
 1773     BoolField(delete_tmp_files);
 1774     BoolField(editor_format);
 1775     BoolField(fcc);
 1776     BoolField(followup_to);
 1777     BoolField(from);
 1778     BoolField(group_catchup_on_exit);
 1779     BoolField(group_format);
 1780 #ifdef HAVE_ISPELL
 1781     BoolField(ispell);
 1782 #endif /* HAVE_ISPELL */
 1783     BoolField(mail_8bit_header);
 1784     BoolField(mail_mime_encoding);
 1785     BoolField(maildir);
 1786     BoolField(mailing_list);
 1787     BoolField(mark_ignore_tags);
 1788     BoolField(mark_saved_read);
 1789     BoolField(mime_forward);
 1790     BoolField(mime_types_to_save);
 1791     BoolField(news_headers_to_display);
 1792     BoolField(news_headers_to_not_display);
 1793     BoolField(news_quote_format);
 1794     BoolField(organization);
 1795     BoolField(pos_first_unread);
 1796     BoolField(post_8bit_header);
 1797     BoolField(post_mime_encoding);
 1798     BoolField(post_process_view);
 1799     BoolField(post_process_type);
 1800 #ifndef DISABLE_PRINTING
 1801     BoolField(print_header);
 1802 #endif /* !DISABLE_PRINTING */
 1803     BoolField(process_only_unread);
 1804     BoolField(prompt_followupto);
 1805     BoolField(quick_kill_case);
 1806     BoolField(quick_kill_expire);
 1807     BoolField(quick_kill_header);
 1808     BoolField(quick_kill_scope);
 1809     BoolField(quick_select_case);
 1810     BoolField(quick_select_expire);
 1811     BoolField(quick_select_header);
 1812     BoolField(quick_select_scope);
 1813     BoolField(quote_chars);
 1814     BoolField(savedir);
 1815     BoolField(savefile);
 1816     BoolField(show_author);
 1817     BoolField(show_only_unread_arts);
 1818     BoolField(show_signatures);
 1819     BoolField(sigdashes);
 1820     BoolField(sigfile);
 1821     BoolField(signature_repost);
 1822     BoolField(sort_article_type);
 1823     BoolField(sort_threads_type);
 1824 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
 1825     BoolField(suppress_soft_hyphens);
 1826 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
 1827     BoolField(tex2iso_conv);
 1828     BoolField(thread_articles);
 1829     BoolField(thread_catchup_on_exit);
 1830     BoolField(thread_format);
 1831     BoolField(thread_perc);
 1832     BoolField(trim_article_body);
 1833 #ifdef CHARSET_CONVERSION
 1834     BoolField(undeclared_charset);
 1835     BoolField(mm_network_charset);
 1836 #endif /* CHARSET_CONVERSION */
 1837     BoolField(verbatim_handling);
 1838 #ifdef HAVE_COLOR
 1839     BoolField(extquote_handling);
 1840 #endif /* HAVE_COLOR */
 1841     BoolField(wrap_on_next_unread);
 1842     BoolField(x_body);
 1843     BoolField(x_comment_to);
 1844     BoolField(x_headers);
 1845 };
 1846 
 1847 /*
 1848  * struct t_scope
 1849  */
 1850 struct t_scope {
 1851     char *scope;                /* scope for these group attributes */
 1852     struct t_attribute *attribute;  /* the attributes itself */
 1853     struct t_attribute_state *state;    /* additional information about numeric attributes */
 1854     BoolField(global);          /* TRUE for scopes from global_attributes_file */
 1855 };
 1856 
 1857 /*
 1858  * struct t_newsrc - newsrc related info.
 1859  */
 1860 struct t_newsrc {
 1861     t_bool present:1;       /* update newsrc? */
 1862     t_artnum num_unread;        /* unread articles in group */
 1863     t_artnum xmax;          /* newsrc max */
 1864     t_artnum xmin;          /* newsrc min */
 1865     t_artnum xbitlen;           /* bitmap length (max-min+1) */
 1866     t_bitmap *xbitmap;  /* bitmap read/unread (max-min+1+7)/8 */
 1867 };
 1868 
 1869 /*
 1870  * struct t_group - newsgroup info from active file
 1871  */
 1872 struct t_group {
 1873     char *name;         /* newsgroup/mailbox name */
 1874     char *aliasedto;        /* =new.group in active file, NULL if not */
 1875     char *description;  /* text from NEWSLIBDIR/newsgroups file */
 1876     char *spooldir;     /* groups spool directory */
 1877     char moderated;     /* state of group moderation */
 1878     t_artnum count;     /* article number count */
 1879     t_artnum xmax;      /* max. article number */
 1880     t_artnum xmin;      /* min. article number */
 1881     unsigned int type:4;        /* grouptype - newsgroup/mailbox/savebox */
 1882     t_bool inrange:1;       /* TRUE if group selected via # range command */
 1883     t_bool read_during_session:1;   /* TRUE if group entered during session */
 1884     t_bool art_was_posted:1;    /* TRUE if art was posted to group */
 1885     t_bool subscribed:1;        /* TRUE if subscribed to group */
 1886     t_bool newgroup:1;      /* TRUE if group was new this session */
 1887     t_bool bogus:1;         /* TRUE if group is not in active list */
 1888     int next;           /* next active entry in hash chain */
 1889     struct t_newsrc newsrc;     /* newsrc bitmap specific info. */
 1890     struct t_attribute *attribute;  /* group specific attributes */
 1891     struct t_filters *glob_filter;  /* points to filter array */
 1892 };
 1893 
 1894 /*
 1895  * used in hashstr.c
 1896  */
 1897 struct t_hashnode {
 1898     struct t_hashnode *next;    /* chain for spillover */
 1899     int aptr;           /* used in subject threading */
 1900     char txt[1];            /* stub for the string data, \0 terminated */
 1901 };
 1902 
 1903 /*
 1904  * used for variable screen layout
 1905  *
 1906  * holds a preparsed format string, a date format string and some
 1907  * precalculated length
 1908  */
 1909 struct t_fmt {
 1910     char str[LEN];
 1911     char date_str[LEN];
 1912     size_t len_date;        /* %D Date */
 1913     size_t len_date_max;
 1914     size_t len_grpdesc;     /* %d newsgroup description */
 1915     size_t len_from;        /* %F From */
 1916     size_t len_grpname;     /* %G groupname */
 1917     size_t len_grpname_dsc;
 1918     size_t len_grpname_max;
 1919     size_t len_initials;    /* %I initials */
 1920     size_t len_linenumber;  /* %n linenumber on screen */
 1921     size_t len_linecnt;     /* %L line count (article) */
 1922     size_t len_msgid;       /* %M message-id */
 1923     size_t len_respcnt;     /* %R count, number of responses */
 1924     size_t len_score;       /* %S score */
 1925     size_t len_subj;        /* %s subject */
 1926     size_t len_ucnt;        /* %U unread count */
 1927     size_t flags_offset;
 1928     size_t mark_offset;
 1929     size_t ucnt_offset;
 1930     t_bool show_grpdesc;
 1931     t_bool d_before_f;
 1932     t_bool g_before_f;
 1933     t_bool d_before_u;
 1934     t_bool g_before_u;
 1935 };
 1936 
 1937 /*
 1938  * used in filter.c
 1939  *
 1940  * Create 2 filter arrays - global & local. Local will be part of group_t
 1941  * structure and will have priority over global filter. Should help to
 1942  * speed kill/selecting within a group. The long value number that is in
 1943  * ~/.tin/kill will be replaced by group name so that it is more human
 1944  * readable and that if hash routine is changed it will still work.
 1945  *
 1946  * Add time period to filter_t struct to allow timed kills & auto-selection
 1947  * Default kill & select time 28 days. Store as a long and compare when
 1948  * loading against present time. If time secs is passed set flag to save
 1949  * filter file and don't load expired entry. Renamed to filter because of
 1950  * future directions in adding other retrieval methods to present kill &
 1951  * auto selection.
 1952  *
 1953  * Also separate kill/select screen to allow ^K=kill ^A=auto-select
 1954  */
 1955 struct t_filters {
 1956     int max;
 1957     int num;
 1958     struct t_filter *filter;
 1959 };
 1960 
 1961 /*
 1962  * struct t_filter_comment: allow multiple comment-lines in filter-file.
 1963  */
 1964 struct t_filter_comment {
 1965     char *text;         /* One line of comment. */
 1966     struct t_filter_comment *next;  /* points to next comment-entry */
 1967 };
 1968 
 1969 /*
 1970  * struct t_filter - local & global filtering (ie. kill & auto-selection)
 1971  */
 1972 struct t_filter {
 1973     struct t_filter_comment *comment;
 1974     char *scope;            /* NULL='*' (all groups) or 'comp.os.*' */
 1975     char *subj;         /* Subject: line */
 1976     char *from;         /* From: line */
 1977     char *msgid;            /* Message-ID: line */
 1978     char *xref;         /* groups in xref line */
 1979     char *path;         /* server in path line */
 1980     struct t_filter *next;      /* next rule valid in group */
 1981     time_t time;            /* expire time in seconds */
 1982     int lines_num;          /* Lines: line */
 1983     int gnksa_num;          /* GNKSA code */
 1984     int score;          /* score to give if rule matches */
 1985     char lines_cmp;         /* Lines compare <> */
 1986     char gnksa_cmp;         /* GNKSA compare <> */
 1987     unsigned int inscope:4;     /* if group matches scope e.g. 'comp.os.*' */
 1988     unsigned int icase:2;       /* Case sensitive filtering */
 1989     unsigned int fullref:4;     /* use full references or last entry only */
 1990 };
 1991 
 1992 /*
 1993  * struct t_filter_rule - provides parameters to build filter rule from
 1994  */
 1995 struct t_filter_rule {
 1996     struct t_filter_comment *comment;
 1997     char text[PATH_LEN];
 1998     char scope[PATH_LEN];
 1999     int counter;
 2000     int icase;
 2001     int fullref;
 2002     int lines_cmp;
 2003     int lines_num;
 2004     int score;
 2005     int expire_time;
 2006     t_bool from_ok:1;
 2007     t_bool lines_ok:1;
 2008     t_bool msgid_ok:1;
 2009     t_bool subj_ok:1;
 2010     t_bool check_string:1;
 2011 };
 2012 
 2013 /*
 2014  * Filter cache structure using Philip Hazel's Perl regular expression
 2015  * library (see pcre/pcre.[ch] for details)
 2016  */
 2017 #ifdef HAVE_LIB_PCRE2
 2018 
 2019 struct regex_cache {
 2020     pcre2_code_8 *re;
 2021     pcre2_match_data_8 *match;
 2022 };
 2023 
 2024 #define REGEX_CACHE_INITIALIZER { NULL, NULL }
 2025 
 2026 #else /* HAVE_LIB_PCRE2 */
 2027 
 2028 struct regex_cache {
 2029     pcre *re;
 2030     pcre_extra *extra;
 2031     int *ovector;
 2032     int ovecalloc;  /* number of allocated integers */
 2033     int ovecmax;    /* max valid pairs in ovector, i.e. max capturecount */
 2034     int oveccount;  /* valid capture count from last regex_exec */
 2035 };
 2036 
 2037 #define REGEX_CACHE_INITIALIZER { NULL, NULL, NULL, 0, 0, 0 }
 2038 
 2039 #endif /* HAVE_LIB_PCRE2 */
 2040 
 2041 struct t_save {
 2042     char *path;
 2043     char *file;                 /* ptr to file part of *path */
 2044     t_bool mailbox:1;           /* Set if path is a mailbox */
 2045 };
 2046 
 2047 #ifndef USE_CURSES
 2048 struct t_screen {
 2049     char *col;
 2050 };
 2051 #endif /* !USE_CURSES */
 2052 
 2053 typedef struct posted {
 2054     char date[10];
 2055     char group[80];
 2056     char action;
 2057     char subj[120];
 2058     char mid[256];
 2059     struct posted *next;
 2060 } t_posted;
 2061 
 2062 struct t_art_stat {
 2063 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
 2064     wchar_t art_mark;       /* mark to use for this thread - not used for groups */
 2065 #else
 2066     char art_mark;      /* mark to use for this thread - not used for groups */
 2067 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
 2068     int total;      /* total article count */
 2069     int unread;     /* number of unread articles (does not include seen) arts */
 2070     int seen;       /* number of seen articles (ART_WILL_RETURN) */
 2071     int deleted;        /* number of articles marked for deletion (mailgroups) */
 2072     int inrange;        /* number of articles marked in a range */
 2073     int selected_total; /* total selected count */
 2074     int selected_unread;    /* selected and unread */
 2075     int selected_seen;  /* selected and seen */
 2076     int killed;     /* killed */
 2077     int score;      /* maximum score */
 2078     int multipart_total; /* 0=not multipart, >0 = number of articles in the multipart */
 2079     int multipart_have; /* number of articles we actually have found */
 2080     int multipart_compare_len; /* length of subject which contains non-specific multipart info */
 2081     time_t time;        /* latest time */
 2082 };
 2083 
 2084 
 2085 /*
 2086  * Used for detecting changes in active file size on different news servers
 2087  */
 2088 struct t_newnews {
 2089     char *host;
 2090     time_t time;
 2091 };
 2092 
 2093 typedef const char constext;
 2094 
 2095 /*
 2096  * Defines text strings used by a tinrc variable
 2097  */
 2098 struct opttxt {
 2099     constext *help;                 /* Helptext on Option Menu */
 2100     constext *opt;                  /* Text on body of Option Menu screen */
 2101     constext *tinrc;                /* (optional) Text written with variable to tinrc file */
 2102 };
 2103 
 2104 /*
 2105  * Used for building option menu
 2106  */
 2107 struct t_option {
 2108     int var_type;       /* type of variable (see tincfg.h) */
 2109     int var_index;      /* index in corresponding table */
 2110     int *variable;      /* ptr to variable to change */
 2111     constext **opt_list;    /* ptr to list entries if OPT_LIST */
 2112     struct opttxt *txt; /* ptr to information/help on option */
 2113 };
 2114 
 2115 /*
 2116  * Multipart article detection
 2117  */
 2118 typedef struct {
 2119     char *subject;
 2120     int subject_compare_len;
 2121     int part_number;
 2122     int total;
 2123     int arts_index;
 2124 } MultiPartInfo;
 2125 
 2126 
 2127 /*
 2128  * Key information about current menu screen
 2129  */
 2130 typedef struct {
 2131     int curr;                   /* Current cursor pos (cur_groupnum, index_point, thread_index_point) */
 2132     int max;                    /* Max # on current menu (group_top, top_base, top_thread) */
 2133     int first;                  /* First # on current menu */
 2134     void (*redraw) (void);      /* Redraw function */
 2135     void (*draw_arrow) (void);  /* Arrow draw */
 2136     void (*draw_item) (int item);   /* draw the specified item */
 2137 } t_menu;
 2138 
 2139 
 2140 /*
 2141  * Packet of data needed to enter pager
 2142  */
 2143 typedef struct {
 2144     int art;
 2145     t_bool ignore_unavail:1;
 2146 } t_pagerinfo;
 2147 
 2148 
 2149 /*
 2150  * Time functions.
 2151  */
 2152 typedef struct _TIMEINFO {
 2153     time_t time;
 2154     long usec;
 2155     long tzone;
 2156 } TIMEINFO;
 2157 
 2158 
 2159 struct t_tintime {
 2160     time_t tv_sec; /* seconds */
 2161     long tv_nsec; /* nanoseconds */
 2162 };
 2163 
 2164 
 2165 /*
 2166  * mailcap fields
 2167  * the x-token field is missing, we would need something like
 2168  * struct t_xtoken { char *xtoken; t_xtoken *next; } for that ...
 2169  */
 2170 typedef struct {
 2171     char *type;     /* content-type, mandatory */
 2172     char *command;  /* view-command, mandatory */
 2173     char *compose;
 2174     char *composetyped;
 2175     char *description;
 2176     char *edit;
 2177     char *nametemplate;
 2178     char *print;
 2179     char *test;
 2180     char *x11bitmap;
 2181     int textualnewlines;
 2182     t_bool needsterminal:1;
 2183     t_bool copiousoutput:1;
 2184 } t_mailcap;
 2185 
 2186 
 2187 typedef struct urllist {
 2188     char *url;
 2189     struct urllist *next;
 2190 } t_url;
 2191 
 2192 
 2193 /*
 2194  * Determine signal return type
 2195  */
 2196 #ifndef RETSIGTYPE
 2197 #   define RETSIGTYPE void
 2198 #endif /* !RETSIGTYPE */
 2199 
 2200 /*
 2201  * Determine qsort compare type
 2202  */
 2203 #ifdef HAVE_COMPTYPE_VOID
 2204 #   ifdef __STDC__
 2205         typedef const void *t_comptype;
 2206 #   else
 2207         typedef void *t_comptype;
 2208 #   endif /* __STDC__ */
 2209 #else
 2210 #   ifdef HAVE_COMPTYPE_CHAR
 2211         typedef char *t_comptype;
 2212 #   endif /* HAVE_COMPTYPE_CHAR */
 2213 #endif /* HAVE_COMPTYPE_VOID */
 2214 
 2215 /* Define a matching function pointer type */
 2216 typedef int (*t_compfunc)(t_comptype, t_comptype);
 2217 typedef void (*t_sortfunc)(void *, size_t, size_t, t_compfunc);
 2218 
 2219 #define _CDECL
 2220 
 2221 /* set to (void)heapsort or qsort */
 2222 #ifndef USE_HEAPSORT
 2223 #   define tin_sort qsort
 2224 #else
 2225 #   define MAX_SORT_FUNCS 1
 2226 #endif /* !USE_HEAPSORT */
 2227 
 2228 /* Separator between dir part of path & the filename */
 2229 #define DIRSEP  '/'
 2230 
 2231 /*
 2232  * mouse buttons for use in xterm
 2233  */
 2234 #define MOUSE_BUTTON_1      0
 2235 #define MOUSE_BUTTON_2      1
 2236 #define MOUSE_BUTTON_3      2
 2237 
 2238 
 2239 #define REDIRECT_OUTPUT     "> /dev/null 2>&1"
 2240 #define REDIRECT_PGP_OUTPUT     "> /dev/null"
 2241 #define ENV_VAR_MAILER      "MAILER"
 2242 #define ENV_VAR_SHELL       "SHELL"
 2243 #define TIN_EDITOR_FMT      "%E +%N %F"
 2244 #define MAILER_FORMAT       "%M -oi -t < %F"
 2245 #ifdef HAVE_KEY_PREFIX
 2246 #   define KEY_PREFIX       0x8f: case 0x9b
 2247 #endif /* HAVE_KEY_PREFIX */
 2248 
 2249 #if !defined(S_ISDIR)
 2250 #   define S_ISDIR(m)   (((m) & S_IFMT) == S_IFDIR)
 2251 #endif /* !S_ISDIR */
 2252 
 2253 #if !defined(S_ISREG)
 2254 #   define S_ISREG(m)   (((m) & S_IFMT) == S_IFREG)
 2255 #endif /* !S_ISREG */
 2256 
 2257 #ifndef S_IRWXU /* should be defined in <sys/stat.h> */
 2258 #   define S_IRWXU  0000700 /* read, write, execute permission (owner) */
 2259 #   define S_IRUSR  0000400 /* read permission (owner) */
 2260 #   define S_IWUSR  0000200 /* write permission (owner) */
 2261 #   define S_IXUSR  0000100 /* execute permission (owner) */
 2262 
 2263 #   define S_IRWXG  0000070 /* read, write, execute permission (group) */
 2264 #   define S_IRGRP  0000040 /* read permission (group) */
 2265 #   define S_IWGRP  0000020 /* write permission (group) */
 2266 #   define S_IXGRP  0000010 /* execute permission (group) */
 2267 
 2268 #   define S_IRWXO  0000007 /* read, write, execute permission (other) */
 2269 #   define S_IROTH  0000004 /* read permission (other) */
 2270 #   define S_IWOTH  0000002 /* write permission (other) */
 2271 #   define S_IXOTH  0000001 /* execute permission (other) */
 2272 #endif /* !S_IRWXU */
 2273 
 2274 /* the next two are needed for fcc 1.0 on linux */
 2275 #ifndef S_IFMT
 2276 #   define S_IFMT   0xF000  /* type of file */
 2277 #endif /* S_IFMT */
 2278 #ifndef S_IFREG
 2279 #   define S_IFREG  0x8000  /* regular */
 2280 #endif /* S_IFREG */
 2281 
 2282 #ifndef S_IRWXUGO
 2283 #   define S_IRWXUGO    (S_IRWXU|S_IRWXG|S_IRWXO)   /* read, write, execute permission (all) */
 2284 #   define S_IRUGO  (S_IRUSR|S_IRGRP|S_IROTH)   /* read permission (all) */
 2285 #   define S_IWUGO  (S_IWUSR|S_IWGRP|S_IWOTH)   /* write permission (all) */
 2286 #   define S_IXUGO  (S_IXUSR|S_IXGRP|S_IXOTH)   /* execute permission (all) */
 2287 #endif /* !S_IRWXUGO */
 2288 
 2289 #ifndef S_ISVTX
 2290 #   define S_ISVTX 0
 2291 #endif /* !S_ISVTX */
 2292 
 2293 #ifdef DONT_HAVE_PIPING
 2294 #   define TIN_PRINTFILE "tinprint%d.tmp"
 2295 #endif /* DONT_HAVE_PIPING */
 2296 
 2297 /*
 2298  * Defines for access()
 2299  */
 2300 #ifndef R_OK
 2301 #   define R_OK 4   /* Test for Read permission */
 2302 #endif /* !R_OK */
 2303 #ifndef W_OK
 2304 #   define W_OK 2   /* Test for Write permission */
 2305 #endif /* !W_OK */
 2306 #ifndef X_OK
 2307 #   define X_OK 1   /* Test for eXecute permission */
 2308 #endif /* !X_OK */
 2309 #ifndef F_OK
 2310 #   define F_OK 0   /* Test for existence of File */
 2311 #endif /* !F_OK */
 2312 
 2313 /* Various function redefinitions */
 2314 #if defined(USE_DBMALLOC) || defined(USE_DMALLOC)
 2315 #   define my_malloc(size)  malloc((size_t) (size))
 2316 #   define my_calloc(nmemb, size)   calloc((nmemb), (size_t) (size))
 2317 #   define my_realloc(ptr, size)    realloc((ptr), (size_t) (size))
 2318 #else
 2319 #   define my_malloc(size)  my_malloc1(__FILE__, __LINE__, (size_t) (size))
 2320 #   define my_calloc(nmemb, size)   my_calloc1(__FILE__, __LINE__, (nmemb), (size_t) (size))
 2321 #   define my_realloc(ptr, size)    my_realloc1(__FILE__, __LINE__, (ptr), (size_t) (size))
 2322 #endif /* USE_DBMALLOC || USE_DMALLOC */
 2323 
 2324 #define ARRAY_SIZE(array)   ((int) (sizeof(array) / sizeof(array[0])))
 2325 
 2326 #define FreeIfNeeded(p) if (p != NULL) free((void *) p)
 2327 #define FreeAndNull(p)  if (p != NULL) { free((void *) p); p = NULL; }
 2328 
 2329 #define BlankIfNull(p)  ((p) ? (p) : "")
 2330 
 2331 #define my_group_find(x)    add_my_group(x, FALSE, FALSE)
 2332 #define my_group_add(x, y)  add_my_group(x, TRUE, y)
 2333 #define for_each_group(x)   for (x = 0; x < num_active; x++)
 2334 #define for_each_art(x)     for (x = 0; x < top_art; x++)
 2335 #define for_each_art_in_thread(x, y)    for (x = (int) base[y]; x >= 0; x = arts[x].thread)
 2336 
 2337 /*
 2338  * Cast for the (few!) places where we need to examine 8-bit characters w/o
 2339  * sign-extension, and a corresponding test-macro.
 2340  */
 2341 #define EIGHT_BIT(ptr)  (unsigned char *)ptr
 2342 #define is_EIGHT_BIT(p) ((*EIGHT_BIT(p) < 32 && !isspace((int)*p)) || *EIGHT_BIT(p) > 127)
 2343 
 2344 /*
 2345  * function prototypes & extern definitions
 2346  */
 2347 
 2348 #ifndef SIG_ARGS
 2349 #   if defined(__STDC__)
 2350 #       define SIG_ARGS int sig
 2351 #   endif /* __STDC__ */
 2352 #endif /* !SIG_ARGS */
 2353 
 2354 #ifndef __LCLINT__ /* lclint doesn't like it */
 2355 /* stifle complaints about not-a-prototype from gcc */
 2356 #   ifdef DECL_SIG_CONST
 2357 #       undef   SIG_DFL
 2358 #       define SIG_DFL  (void (*)(SIG_ARGS))0
 2359 #       undef   SIG_IGN
 2360 #       define SIG_IGN  (void (*)(SIG_ARGS))1
 2361 #       undef   SIG_ERR
 2362 #       define SIG_ERR  (void (*)(SIG_ARGS))-1
 2363 #   endif /* DECL_SIG_CONST */
 2364 #endif /* !__LCLINT__ */
 2365 
 2366 /*
 2367  * tputs() function-param
 2368  */
 2369 #ifdef OUTC_RETURN
 2370 #   define OUTC_RETTYPE int
 2371 #else
 2372 #   define OUTC_RETTYPE void
 2373 #endif /* OUTC_RETURN */
 2374 
 2375 #ifndef OUTC_ARGS
 2376 #   define OUTC_ARGS    int c
 2377 #endif /* !OUTC_ARGS */
 2378 
 2379 #if __STDC__ || defined(__cplusplus)
 2380 #   define OUTC_FUNCTION(func)  OUTC_RETTYPE func (OUTC_ARGS)
 2381 #else
 2382 #   define OUTC_FUNCTION(func)  OUTC_RETTYPE func (c) int c;
 2383 #endif /* __STDC__ || __cplusplus */
 2384 
 2385 typedef OUTC_RETTYPE (*OutcPtr) (OUTC_ARGS);
 2386 typedef FILE TCP;
 2387 
 2388 #ifndef EXTERN_H
 2389 #   include "extern.h"
 2390 #endif /* !EXTERN_H */
 2391 #ifndef TINRC_H
 2392 #   include "tinrc.h"
 2393 #endif /* !TINRC_H */
 2394 #ifndef NNTPLIB_H
 2395 #   include "nntplib.h"
 2396 #endif /* !NNTPLIB_H */
 2397 
 2398 /*
 2399  * rfc1521/rfc1522 interface
 2400  */
 2401 typedef void (*BodyPtr) (char *, FILE *, int);
 2402 
 2403 #ifdef USE_DBMALLOC
 2404 #   undef strchr
 2405 #   undef strrchr
 2406 #   include <dbmalloc.h> /* dbmalloc 1.4 */
 2407 #endif /* USE_DBMALLOC */
 2408 
 2409 #ifdef USE_DMALLOC
 2410 #   include <dmalloc.h>
 2411 #   define DMALLOC_FUNC_CHECK
 2412 #   ifdef HAVE_STRDUP
 2413 #       define my_strdup(s) strdup((s))
 2414 #   endif /* HAVE_STRDUP */
 2415 #endif /* USE_DMALLOC */
 2416 
 2417 #ifdef DOALLOC
 2418     extern char *doalloc(char *, size_t);
 2419     extern char *docalloc(size_t, size_t);
 2420     extern void dofree(char *);
 2421 #   undef malloc
 2422 #   undef realloc
 2423 #   undef calloc
 2424 #   undef free
 2425 #   define malloc(n)    doalloc((char *) 0, n)
 2426 #   define realloc      doalloc
 2427 #   define calloc       docalloc
 2428 #   define free     dofree
 2429     extern void fail_alloc(char *, char *);
 2430     extern void Trace(char *, ...);
 2431     extern void Elapsed(char *);
 2432     extern void WalkBack(void);
 2433     extern void show_alloc(void);
 2434     extern void no_leaks(void);
 2435 #endif /* DOALLOC */
 2436 
 2437 /* define some standard places to look for a tin.defaults file */
 2438 #define TIN_DEFAULTS_BUILTIN "/etc/opt/tin","/etc/tin","/etc","/usr/local/lib/tin","/usr/local/lib","/usr/local/etc/tin","/usr/local/etc","/usr/lib/tin","/usr/lib",NULL
 2439 #ifdef TIN_DEFAULTS_DIR
 2440 #   define TIN_DEFAULTS TIN_DEFAULTS_DIR,TIN_DEFAULTS_BUILTIN
 2441 #else
 2442 #   define TIN_DEFAULTS TIN_DEFAULTS_BUILTIN
 2443 #endif /* TIN_DEFAULTS_DIR */
 2444 
 2445 /*
 2446  * We force this include-ordering since socks.h contains redefinitions of
 2447  * functions that probably are prototyped via other includes. The socks.h
 2448  * definitions have to be included everywhere, since they're making wrappers
 2449  * for the stdio functions as well as the network functions.
 2450  */
 2451 #ifdef USE_SOCKS5
 2452 #   define SOCKS
 2453 #   include <socks.h>
 2454 /* socks.h doesn't define prototypes for use */
 2455 extern size_t read(int, char *, size_t);
 2456 extern int dup(int);
 2457 extern int close(int);
 2458 extern int fprintf(FILE *, const char *, ...);
 2459 extern int fclose(FILE *);
 2460 extern struct tm *localtime(time_t *);
 2461 #endif /* USE_SOCKS5 */
 2462 
 2463 #ifdef SETVBUF_REVERSED
 2464 #   define SETVBUF(stream, buf, mode, size) setvbuf(stream, mode, buf, size)
 2465 #else
 2466 #   define SETVBUF(stream, buf, mode, size) setvbuf(stream, buf, mode, size)
 2467 #endif /* SETVBUF_REVERSED */
 2468 
 2469 #ifdef CLOSEDIR_VOID
 2470 #   define CLOSEDIR(DIR)    closedir(DIR)
 2471 #else
 2472 #   define CLOSEDIR(DIR)    if (closedir(DIR)) error_message(2, "closedir() failed: %s %d", __FILE__, __LINE__)
 2473 #endif /* CLOSEDIR_VOID */
 2474 
 2475 #ifdef HAVE_GETTIMEOFDAY
 2476 #   ifndef GETTIMEOFDAY_2ARGS
 2477 #       define gettimeofday(a,b) gettimeofday(a)
 2478 #   endif /* GETTIMEOFDAY_2ARGS */
 2479 #endif /* HAVE_GETTIMEOFDAY */
 2480 
 2481 /* libmss */
 2482 #ifdef MSS
 2483 #   ifdef strdup
 2484 #       undef strdup
 2485 #   endif /* strdup */
 2486 #   include <mss.h>
 2487 #   undef my_malloc
 2488 #   undef my_realloc
 2489 #   undef my_calloc
 2490 #   define my_malloc(size)  malloc((size_t)(size))
 2491 #   define my_realloc(ptr, size)    realloc((ptr), (size_t) (size))
 2492 #   define my_calloc(nmemb, size) calloc((nmemb), (size_t) (size))
 2493 #endif /* MSS */
 2494 
 2495 /* libcanlock */
 2496 #ifdef USE_CANLOCK
 2497 #   ifdef HAVE_LIBCANLOCK_3_CANLOCK_H
 2498 #       include <libcanlock-3/canlock.h>
 2499 #   else
 2500 #       include <canlock.h>
 2501 #   endif /* HAVE_LIBCANLOCK_3_CANLOCK_H */
 2502 #endif /* USE_CANLOCK */
 2503 
 2504 /* gsasl */
 2505 #ifdef USE_SASL
 2506 #   include <gsasl.h>
 2507 #endif /* USE_SASL */
 2508 
 2509 /*
 2510  * adapted from ncurses curses.priv.h:
 2511  * If we have va_copy(), use it for assigning va_list's.
 2512  */
 2513 #if defined(HAVE___VA_COPY)
 2514 #   define begin_va_copy(dst,src)   __va_copy(dst, src)
 2515 #   define end_va_copy(dst) va_end(dst)
 2516 #else
 2517 #   if defined(va_copy) || defined(HAVE_VA_COPY)
 2518 #       define begin_va_copy(dst,src)   va_copy(dst, src)
 2519 #       define end_va_copy(dst) va_end(dst)
 2520 #   else
 2521 #       if defined(HAVE___BUILTIN_VA_COPY)
 2522 #           define begin_va_copy(dst,src)   __builtin_va_copy(dst, src)
 2523 #           define end_va_copy(dst) va_end(dst)
 2524 #       else
 2525 #           if defined(ARRAY_VA_LIST)
 2526 #               define begin_va_copy(dst,src)   *(dst) = *(src)
 2527 #               define end_va_copy(dst) /* nothing */
 2528 #           else
 2529 #               define begin_va_copy(dst,src)   (dst) = (src)
 2530 #               define end_va_copy(dst) /* nothing */
 2531 #           endif /* ARRAY_VA_LIST */
 2532 #       endif /* HAVE___BUILTIN_VA_COPY */
 2533 #   endif /* va_copy || HAVE_VA_COPY */
 2534 #endif /* HAVE___VA_COPY */
 2535 
 2536 /* snprintf(), vsnprintf() */
 2537 #ifndef HAVE_SNPRINTF
 2538 #   define snprintf plp_snprintf
 2539 #endif /* HAVE_SNPRINTF */
 2540 #ifndef HAVE_VSNPRINTF
 2541 #   define vsnprintf    plp_vsnprintf
 2542 #endif /* HAVE_VSNPRINTF */
 2543 
 2544 /* gcc-specific attributes */
 2545 #if defined(__GNUC__) && !defined(__cplusplus) && !defined(__APPLE_CC__) && !defined(__NeXT__)
 2546 #   if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6)
 2547 #       define UNUSED(x) x __attribute__((unused))
 2548 #   else
 2549 #       define UNUSED(x) x
 2550 #   endif /* __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6) */
 2551 #else
 2552 #   define UNUSED(x) x
 2553 #endif /* __GNUC__ && !__cplusplus && !__APPLE_CC__ && !__NeXT__ */
 2554 
 2555 /* #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L */
 2556 #ifdef STDC_NORETURN
 2557 #   ifdef HAVE_STDNORETURN_H
 2558 #       include <stdnoreturn.h>
 2559 #   endif /* HAVE_STDNORETURN_H */
 2560 #else
 2561 #   undef _Noreturn
 2562     /*
 2563      * gcc says "The attribute noreturn is not implemented in GCC
 2564      * versions earlier than 2.5" but gcc 2.7.2.3 on m68k-sony-newsos
 2565      * or mips-dec-osf1 still doesn't know __attribute__((noreturn)).
 2566      * __GNUC__ > 2 should be fine
 2567      */
 2568 #   if defined(__GNUC__) && !defined(__cplusplus) && !defined(__APPLE_CC__) && !defined(__NeXT__)
 2569 #       if __GNUC__ > 2
 2570 #           define _Noreturn __attribute__((noreturn))
 2571 #       else
 2572 #           define _Noreturn /**/
 2573 #       endif /* __GNUC__ > 2 */
 2574 #   else
 2575 #       define _Noreturn /**/
 2576 #   endif /* __GNUC__ && !__cplusplus && !__APPLE_CC__ && !__NeXT__ */
 2577 #endif /* STDC_NORETURN */
 2578 
 2579 #ifndef __CPROTO__
 2580 #   ifndef PROTO_H
 2581 #       include "proto.h"
 2582 #   endif /* !PROTO_H */
 2583 #endif /* !__CPROTO__ */
 2584 
 2585 /* init_selfinfo() needs MM_CHARSET */
 2586 #ifndef MM_CHARSET
 2587 #   define MM_CHARSET "US-ASCII"
 2588 #endif /* !MM_CHARSET */
 2589 
 2590 
 2591 #if !defined(SEEK_SET)
 2592 #   define SEEK_SET 0L
 2593 #endif /* !SEEK_SET */
 2594 
 2595 #if !defined(EOF)
 2596 #   define EOF -1
 2597 #endif /* !EOF */
 2598 
 2599 /* various filenames used by tin */
 2600 #define TIN_ARTICLE_NAME    ".article"
 2601 #define TIN_CANCEL_NAME ".cancel"
 2602 #define TIN_LETTER_NAME ".letter"
 2603 #define TIN_BUGREPORT_NAME  ".bugreport"
 2604 
 2605 /* read_news_active_file() / open_newsgroups_fp() */
 2606 #ifndef DISABLE_PIPELINING
 2607 #   define PIPELINE_LIMIT 45
 2608 #else
 2609 #   define PIPELINE_LIMIT 1
 2610 #endif /* DISABLE_PIPELINING */
 2611 
 2612 #ifndef DEBUG_H
 2613 #   include "debug.h"
 2614 #endif /* !DEBUG_H */
 2615 
 2616 struct t_overview_fmt {
 2617     char *name;
 2618     enum f_type type;
 2619 };
 2620 
 2621 struct t_version {
 2622     enum rc_state state;
 2623     int file_version;       /* rc_majorv * 10000 + rc_minorv * 100 + rc_subv */
 2624 /*  int current_version;*/  /* c_majorv * 10000 + c_minorv * 100 + c_subv */
 2625 };
 2626 
 2627 #endif /* !TIN_H */