"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.3/include/tin.h" (4 Dec 2018, 72105 Bytes) of package /linux/misc/tin-2.4.3.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.4.2_vs_2.4.3.

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