1 /* retawq/stuff.h - general stuff
2    This file is part of retawq (<http://retawq.sourceforge.net/>), a network
3    client created by Arne Thomassen; retawq is basically released under certain
4    versions of the GNU General Public License and WITHOUT ANY WARRANTY.
5    Read the file COPYING for license details, README for program information.
6    Copyright (C) 2001-2005 Arne Thomassen <arne@arne-thomassen.de>
7 */
8 
9 #ifndef __retawq_stuff_h__
10 #define __retawq_stuff_h__
11 
12 /* Compile-time configuration */
13 
14 #include ".config"
15 
16 #undef OPTION_TG /* make sure it won't be used anywhere accidentally... */
17 
18 #if OPTION_BUILTIN_DNS
19 #undef OPTION_THREADING
20 #define OPTION_THREADING 0 /* no need for threading */
21 #endif
22 
23 #define CONFIG_ASYNC_DNS (OPTION_THREADING || OPTION_BUILTIN_DNS)
24 #define CONFIG_ANY_MAIL (OPTION_POP || OPTION_IMAP)
25 
26 /* flags in OPTION_EXECEXT */
27 #define EXECEXT_SHELL (1)
28 #define EXECEXT_ALL (EXECEXT_SHELL)
29 
30 /* flags in OPTION_EXECINT */
31 #define EXECINT_RELIAWFUL (1)
32 
33 /* flags in CONFIG_BLOAT */
34 #define BLOAT_SSC (1)
35 #define BLOAT_UIIP (2)
36 #define BLOAT_HELP (4)
37 #define BLOAT_HELPARG (8)
38 #define BLOAT_COLORHL (16)
39 #define BLOAT_SCROLL_BARS (32)
40 #define BLOAT_TERMWINTITLE (64)
41 #define BLOAT_ICONLOGO (128)
42 #define BLOAT_COLORS (256)
43 
44 /* flags in CONFIG_HTTP */
45 #define HTTP_11 (1)
46 #define HTTP_PUT (2)
47 #define HTTP_AUTH_BASIC (4)
48 #define HTTP_AUTH_DIGEST (8)
49 #define HTTP_AUTH_ANY (HTTP_AUTH_BASIC | HTTP_AUTH_DIGEST) /* any non-proxy */
50 #define HTTP_PROXYAUTH (16)
51 
52 /* flags in CONFIG_HTML */
53 #define CONFIG_HTML_COLORNAMES 0 /* (CONFIG_HTML & 3) */
54 #define HTML_TABLES (4)
55 #define HTML_FRAMES (8)
56 #define HTML_FORM_FILE_UPLOAD (16)
57 
58 /* flags in CONFIG_MENUS */
59 #define MENUS_CONTEXT (1)
60 #define MENUS_UHIST (2)
61 #define MENUS_WLIST (4)
62 #define MENUS_HTML (8)
63 #define MENUS_BAR (16)
64 #define MENUS_ALL (31) /* (sum of all the above) */
65 
66 /* flags in CONFIG_EXTRA */
67 #define EXTRA_DOWNLOAD (1)
68 #define EXTRA_DUMP (2)
69 #define EXTRA_PAGER (4)
70 
71 #define DO_PAGER ( (CONFIG_DEBUG) && (CONFIG_EXTRA & EXTRA_PAGER) )
72 
73 #if CONFIG_PLATFORM == 1
74 #undef const
75 #define const
76 #endif
77 
78 
79 /* Text/graphics configuration I: numerical values for CONFIG_TG */
80 
81 #define TG_INVALID 0
82 #define TG_BACKGROUND 1
83 #define TG_CONSOLE 2
84 #define TG_CURSES 3
85 #define TG_NCURSES 4
86 #define TG_XCURSES 5
87 #define TG_BICURSES 6
88 #define TG_FLEXCURSES 7
89 #define TG_X 8
90 #define TG_GTK 9
91 #define TG_SVGA 10
92 #define TG_FRAMEBUFFER 11
93 
94 /* text/graphics classes, for convenience */
95 #define TGC_IS_CURSES ( (CONFIG_TG == TG_CURSES) || (CONFIG_TG == TG_NCURSES) || (CONFIG_TG == TG_XCURSES) || (CONFIG_TG == TG_BICURSES) || (CONFIG_TG == TG_FLEXCURSES) )
96 #define TGC_IS_GRAPHICS ( (CONFIG_TG == TG_X) || (CONFIG_TG == TG_GTK) )
97 #define TGC_IS_PIXELING ( (TGC_IS_GRAPHICS) || (CONFIG_TG == TG_SVGA) || (CONFIG_TG == TG_FRAMEBUFFER) )
98 #define TGC_IS_WINDOWING (CONFIG_TG > TG_CONSOLE) /* virtual or real windows */
99 
100 #if CONFIG_TG == TG_CONSOLE /* default runmode is console, so enable console */
101 #undef CONFIG_CONSOLE
102 #define CONFIG_CONSOLE 1
103 #endif
104 
105 /* window kinds */
106 #define DO_WK_INFO    ((CONFIG_WK & 1) && (TGC_IS_CURSES))
107 #define DO_WK_CUSTOM_CONN (CONFIG_DEBUG && (CONFIG_WK & 2) && (TGC_IS_CURSES) && (CONFIG_FTP))
108 #define DO_WK_EDITOR  (CONFIG_DEBUG && (CONFIG_WK & 4) && (TGC_IS_CURSES))
109 #define DO_WK_FILEMGR (CONFIG_DEBUG && (CONFIG_WK & 8) && (TGC_IS_CURSES))
110 #define DO_WK_MAILMGR (CONFIG_DEBUG && (CONFIG_WK & 16) && (TGC_IS_CURSES) && (CONFIG_ANY_MAIL))
111 
112 #define CONFIG_MAILTO ( (DO_WK_EDITOR) /* && (OPTION_SMTP) */ )
113 #define CONFIG_CUSTOM_CONN ((CONFIG_CONSOLE) || (DO_WK_CUSTOM_CONN))
114 
115 #if CONFIG_CUSTOM_CONN
116 #if (!CONFIG_FTP)
117 #error "You enabled custom connections (CONFIG_CONSOLE) but disabled CONFIG_FTP. This cannot work."
118 #endif
119 #if (!(CONFIG_EXTRA & EXTRA_DOWNLOAD))
120 #error "You enabled custom connections (CONFIG_CONSOLE) but disabled downloads in CONFIG_EXTRA. This cannot work."
121 #endif
122 #endif
123 
124 #define OFWAX 0
125 
126 #define MIGHT_USE_SCROLL_BARS ( (CONFIG_TG == TG_XCURSES) && (CONFIG_BLOAT & BLOAT_SCROLL_BARS) )
127 
128 
129 /* Standard header file includes */
130 
131 #include <stdio.h>
132 
133 #if HAVE_SYS_TYPES_H
134 #include <sys/types.h>
135 #endif
136 
137 #if STDC_HEADERS
138 #include <stdlib.h>
139 #include <stddef.h>
140 #else
141 #if HAVE_STDLIB_H
142 #include <stdlib.h>
143 #endif
144 #endif
145 
146 #if HAVE_STRING_H
147 #if (!STDC_HEADERS) && HAVE_MEMORY_H
148 #include <memory.h>
149 #endif
150 #include <string.h>
151 #endif
152 
153 #if HAVE_STRINGS_H
154 #include <strings.h>
155 #endif
156 
157 #if HAVE_UNISTD_H
158 #include <unistd.h>
159 #endif
160 
161 #if HAVE_ERRNO_H
162 #include <errno.h>
163 #endif
164 
165 #if HAVE_LIMITS_H
166 #include <limits.h>
167 #endif
168 
169 #if HAVE_FCNTL_H
170 #include <fcntl.h>
171 #endif
172 
173 #if HAVE_SYS_STAT_H
174 #include <sys/stat.h>
175 #endif
176 
177 #if HAVE_TERMIOS_H && ( (CONFIG_CONSOLE) || (CONFIG_TG == TG_BICURSES) )
178 #include <termios.h>
179 #define MIGHT_DO_TERMIOS 1
180 #else
181 #define MIGHT_DO_TERMIOS 0
182 #endif
183 
184 typedef unsigned char tUint8;
185 typedef unsigned int tUint32;
186 typedef signed short tSint16;
187 
188 
189 /* Strings */
190 
191 #define STRBUF_SIZE (4096)
192 extern const char strCopyright[], strProgramLegalese[], strRetawq[],
193   strOptHelp[], strOptVersion[], strProgramVersion[], strText[], strGraphics[];
194 extern /*@observer@*/ const char strEmpty[], strNewline[];
195 extern const char strMinus[], strSlash[], strAsterisk[], strLt[], strGt[],
196   strHm[], strQm[], strDoubleQuote[], strSpacedDash[], strDoubleDot[],
197   str1dot0[], str1dot1[];
198 extern const char strPercsPercs[], strPercd[], strBracedNumstr[];
199 extern const char strHexnum[];
200 extern const char strA[], strShtml[], strReset[], strSelect[], strSubmit[],
201   strOn[], strClose[], strQuit[], strGet[], strPost[], strLocalhost[];
202 extern const char strUnknown[], strBracedDisabled[], strImage[], strCheckbox[],
203   strButton[], strYes[], strNo[], strFileUc[], strDirectoryUc[], strLink[],
204   strLoginFailed[], strFwdact[], strByte[], strBytes[], strOff[],strBadValue[],
205   strErrorTrail[];
206 #if !CONFIG_SESSIONS
207 extern const char strFsessions[];
208 #endif
209 #if !CONFIG_JUMPS
210 extern const char strFjumps[];
211 #endif
212 #if OPTION_EXECEXT != EXECEXT_ALL
213 extern const char strFexecext[];
214 #endif
215 #if CONFIG_CONSOLE
216 extern const char strConsoleDiscard[];
217 #endif
218 #if (CONFIG_TG == TG_X) || (CONFIG_TG == TG_XCURSES)
219 extern const char strCantOpenXws[];
220 #endif
221 #if OPTION_LOCAL_CGI || OPTION_TRAP || (OPTION_EXECEXT & EXECEXT_SHELL)
222 extern const char strSoftwareId[];
223 #endif
224 
225 /* ugly :-) */
226 #define strHelp    (strOptHelp + 2)
227 #define strVersion (strOptVersion + 2)
228 #define strSpace   (strSpacedDash + 2)
229 #define strPercs   (strPercsPercs + 2)
230 #define strHtml    (strShtml + 1)
231 
232 /* scheme strings: */
233 extern const char strHttp[], strFtp[], strLocal[], strFile[], strAbout[],
234   strFinger[], strLocalCgi[], strNntp[], strNews[], strCvs[], strGopher[],
235   strInfo[], strMailto[], strJavascript[], strHttps[], strFtps[], strPop[],
236   strPops[], strExecextShell[];
237 
238 
239 /* Helper macros */
240 
241 #define CONFIG_EXDEBUG 0
242 
243 #ifndef NULL
244 #define NULL ((void*) 0)
245 #endif
246 
247 #ifndef MIN
248 #define MIN(a,b) (((a)<(b)) ? (a) : (b))
249 #endif
250 
251 #ifndef MAX
252 #define MAX(a,b) (((a)>(b)) ? (a) : (b))
253 #endif
254 
255 #ifdef INT_MAX
256 #define MY_ATOI_INT_MAX (INT_MAX / 11)
257   /* (avoids overflows in my_atoi() and is still big enough for any "real-life"
258       case) */
259 #else
260 #define MY_ATOI_INT_MAX (99999999)
261 #endif
262 
263 /* compare two numbers; in Perl we'd use the "<=>" operator... */
264 #define my_numcmp(num1, num2) \
265   ( ((num1) > (num2)) ? (+1) : ( ((num1) < (num2)) ? (-1) : (0) ) )
266 
267 #ifdef S_SPLINT_S
268 
269 /* make splint happy; __sunused and __sallocator are splint-specific variants
270    of __cunused and __callocator; this rubbish is necessary because splint and
271    gcc expect such annotations in different places within a declaration... */
272 
273 #define __sunused /*@unused@*/
274 #define __dnr /*@noreturn@*/
275 #define __sallocator /*@only@*/
276 #define my_enum1 typedef
277 #define my_enum2(ctype)
278 
279 #else
280 
281 /* make _me_ happy :-) */
282 
283 #define __sunused
284 #define __dnr
285 #define __sallocator
286 #define my_enum1
287 #define my_enum2(ctype) ; typedef ctype
288 
289 #endif
290 
291 #if USING_CONFIGURE
292 #define __my_inline inline
293 #elif defined(__GNUC__)
294 #define __my_inline inline
295 #else
296 #define __my_inline /* nothing (we don't know for _sure_ how to do it) */
297 #endif
298 
299 #ifdef DO_NOT_INLINE
300 #define my_inline /* nothing (to make the program smaller) */
301 #else
302 #define my_inline __my_inline
303 #endif
304 
305 #if defined(__GNUC__) && ( (__GNUC__ > 2) || ( (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5) ) )
306 #define __cunused __attribute__((__unused__))
307 #define my_spf_attr __attribute__((__format__(printf, 4, 5))) /* shows bugs */
308 #define does_not_return __attribute__((__noreturn__))
309 #if CONFIG_EXDEBUG
310 #define __init __attribute__((__section__ ("textinit")))
311 #endif
312 /* #define __callocator __attribute__((__malloc__)) */
313 #else
314 #define __cunused
315 #define my_spf_attr
316 #endif
317 
318 #ifndef __init
319 #define __init
320 #endif
321 #ifndef __initdata
322 #define __initdata
323 #endif
324 #ifndef __callocator
325 #define __callocator
326 #endif
327 #ifndef does_not_return
328 #define does_not_return __dnr
329 #endif
330 #define const_after_init
331 #if CONFIG_DEBUG
332 #define one_caller /* nothing (gcc/gdb and line numbers...) */
333 #else
334 #define one_caller __my_inline /* (function is called from only one place) */
335 #endif
336 
337 /* Mark that we checked that the library function won't overflow the buffer: */
338 #define sprint_safe sprintf
339 
340 /* Some snprintf() implementations in C libraries are rubbish. Just one example
341    from a Linux manual page: "Linux libc4.[45] does not have a snprintf, but
342    provides a libbsd that contains an snprintf equivalent to sprintf, i.e.,
343    one that ignores the size argument. Thus, the use of snprintf with early
344    libc4 leads to serious security problems." Congratulations... */
345 #define snprint_safe DOES_NOT_EXIST__DO_NOT_USE_SNPRINTF /* clear? :-) */
346 
347 /* Some sscanf() implementations in C libraries are rubbish: they try to write
348    into the <format> parameter, causing a crash if operating on read-only
349    string constants. (Information found in "info gcc".) Thus: */
350 #if 1
351 #define PREPARE_SSCANF_FORMAT(bufvar, bufsize, formatstr) \
352   char bufvar[bufsize]; strcpy(bufvar, formatstr); /* for buggy libraries */
353 #else
354 #define PREPARE_SSCANF_FORMAT(bufvar, bufsize, formatstr) \
355   static const char bufvar[] = formatstr; /* for non-buggy libraries */
356 #endif
357 
358 #define zero2one(x) ( ((x) == 0) ? (1) : (x) )
359 #define bytebytes(x) ( ((x) == 1) ? _(strByte) : _(strBytes) )
360 #define null2empty(str) ( (str == NULL) ? (strEmpty) : (str) )
361 #define __unconstify(_t, _v) ( (_t) (_v) ) /* discard "const", avoid warning */
362 #define unconstify(str) __unconstify(char*, str)
363 
364 #define is_control_char(unsigned_char) \
365   ( ((unsigned_char) < ' ') || ((unsigned_char) == 127) )
366 #define TO_EOS(str) do { while (*str != '\0') str++; } while (0)
367   /* go to end of string */
368 
369 #define ARRAY_ELEMNUM(arr) (sizeof(arr) / sizeof(arr[0]))
370 
371 /* We need library function variants which are _guaranteed_ to be
372    locale-independent, even if i18n is enabled. */
373 #define my_isdigit(ch) ( ((ch) >= '0') && ((ch) <= '9') )
374 #define my_islower(ch) ( ((ch) >= 'a') && ((ch) <= 'z') )
375 #define my_isupper(ch) ( ((ch) >= 'A') && ((ch) <= 'Z') )
376 #define my_isalpha(ch) (my_islower(ch) || my_isupper(ch))
377 #define my_isalnum(ch) (my_isalpha(ch) || my_isdigit(ch))
378 #define my_tolower(ch) ( my_isupper(ch) ? ((ch) + ('a' - 'A')) : (ch) )
379 #define my_toupper(ch) ( my_islower(ch) ? ((ch) - ('a' - 'A')) : (ch) )
380 
381 
382 /* Boolean */
383 
384 /* It seems that "false", "False" and "FALSE" are already used by compilers and
385    libraries; it can't be true... :-) Let's hope that our choice is safe. */
386 /*@-booltype tBoolean@*/ /*@-booltrue truE@*/ /*@-boolfalse falsE@*/
387 my_enum1 enum { falsE = 0, truE = 1 } my_enum2(unsigned char) tBoolean;
388 #define flip_boolean(var) \
389   do { var = ( (var == falsE) ? (truE) : (falsE) ); } while (0)
390 #define boolean2bool(x) ( ((x) == falsE) ? (0) : (1) )
391 #define cond2boolean(condition) ( (condition) ? (truE) : (falsE) )
392 #define cond2bool(condition) ( (condition) ? (1) : (0) )
393 
394 
395 /* Text/graphics configuration II */
396 
397 #define MIGHT_USE_COLORS (CONFIG_BLOAT & BLOAT_COLORS)
398 
399 #include "tgmode.inc"
400 
401 #if MIGHT_DO_TERMIOS
402 extern tBoolean do_restore_termios;
403 extern struct termios saved_termios;
404 #endif
405 
406 #if TGC_IS_GRAPHICS
407 
408 /* We are Pixels of Borg - curses is irrelevant. */
409 #undef OPTION_CED
410 #define OPTION_CED 1
411 
412 #define strTG strGraphics
413 
414 #if CONFIG_TG == TG_X
415 #include <X11/Xlib.h>
416 extern Display* xws_display;
417 typedef unsigned int tKey;
418 typedef int tCoordinate;
419 #else
420 #include <gtk/gtk.h>
421 typedef guint tKey; /*struct _GdkEventKey->keyval,/usr/include/gdk/gdktypes.h*/
422 typedef gint16 tCoordinate; /* struct _GdkPoint, gtk/gdk/gdktypes.h */
423 #endif
424 
425 #else /* #if TGC_IS_GRAPHICS */
426 
427 #define strTG strText
428 
429 typedef int tKey;
430 typedef signed short tCoordinate;
431 
432 #endif /* #if TGC_IS_GRAPHICS */
433 
434 #if CONFIG_TG == TG_XCURSES
435 #undef OPTION_CED
436 #define OPTION_CED 1
437 #endif
438 
439 #if (OPTION_TEXTMODEMOUSE) && ( ( (TGC_IS_CURSES) && (defined(NCURSES_MOUSE_VERSION)) ) || (CONFIG_TG == TG_XCURSES) )
440 /* "user wants" && "library can" */
441 #define CONFIG_DO_TEXTMODEMOUSE 1
442 #define TEXTMODEMOUSE_MASK (BUTTON1_CLICKED | BUTTON2_CLICKED |BUTTON3_CLICKED)
443 #else
444 #define CONFIG_DO_TEXTMODEMOUSE 0
445 #endif
446 
447 extern tBoolean need_tglib_cleanup;
448 extern const_after_init unsigned char __lfdmbs;
449 #define lfdmbs(x) (__lfdmbs & (1 << (x)))
450 
451 
452 /* i18n configuration; this must be done _after_ OPTION_CED (re-)definition */
453 
454 #if (OPTION_I18N) && (OPTION_CED == 0)
455 /* We need special code to make translated texts seven-bit clean: */
456 
457 #define NEED_SPECIAL_GETTEXT 1
458 extern char* my_do_gettext(char** buffer, const char* str);
459 #define declare_local_i18n_buffer static char* local_i18n_buffer = NULL;
460 #define my_gettext(str) my_do_gettext(&local_i18n_buffer, str)
461 #define i18n_strdup(str) my_strdup(str) /* orig destroyed by i18n_cleanup */
462 #define i18n_cleanup \
463   if (local_i18n_buffer != NULL) (void) my_do_gettext(&local_i18n_buffer,NULL);
464 
465 #else
466 
467 #define NEED_SPECIAL_GETTEXT 0
468 #define declare_local_i18n_buffer /* nothing */
469 #define my_gettext(str) gettext(str)
470 #define i18n_strdup(str) (str) /* no need to copy */
471 #define i18n_cleanup
472 
473 #endif
474 
475 #if OPTION_I18N
476 
477 #if HAVE_LIBINTL_H
478 #include <libintl.h>
479 #endif
480 
481 #undef _
482 #ifndef _
483 #define _(str) my_gettext(str)
484 #endif
485 
486 #ifndef N_
487 #ifdef gettext_noop
488 #define N_(str) gettext_noop(str)
489 #else
490 #define N_(str) (str)
491 #endif
492 #endif
493 #define unconstify_or_(str) _(str)
494 
495 #else /* #if OPTION_I18N */
496 
497 #define _(str) (str)
498 #define N_(str) (str)
499 #define unconstify_or_(str) unconstify(str)
500 
501 #endif /* #if OPTION_I18N */
502 
503 #define localized_size(size) (size) /* IMPLEMENTME! */
504 
505 
506 /* Curses */
507 
508 #if MIGHT_USE_COLORS
509 extern tBoolean use_colors;
510 #endif
511 
512 #if TGC_IS_CURSES
513 
514 #define CURSES_MINCOLS (30)
515 #define CURSES_MINLINES (10)
516 #define CURSES_MAXCOLS (250)
517 #define CURSES_MAXLINES (250)
518 /* (All values must fit into an "unsigned char".) */
519 
520 #if MIGHT_USE_COLORS
521 
522 my_enum1 enum
523 { ccBlack = 0, ccRed = 1, ccGreen = 2, ccYellow = 3, ccBlue = 4, ccMagenta = 5,
524   ccCyan = 6, ccWhite = 7
525 } my_enum2(unsigned char) tColorCode;
526 
527 my_enum1 enum
528 { /* cpnHardwired = 0, -- not usable for us */ cpnDefault = 1, cpnRed = 2,
529   cpnGreen = 3, cpnYellow = 4, cpnBlue = 5
530 } my_enum2(short) tColorPairNumber;
531 #define cpnMax (5)
532 
533 typedef chtype tColorBitmask;
534 extern tColorBitmask color_bitmask[cpnMax + 1];
535 
536 #define my_color_attr(cpn) (color_bitmask[cpn]) /*only do this if use_colors!*/
537 #define my_set_color(cpn) \
538   do { if (use_colors) { (void) attron(my_color_attr(cpn)); } } while (0)
539 
540 #else /* colors */
541 
542 #define my_set_color(cpn) do { } while (0)
543 
544 #endif /* colors */
545 
546 #endif /* curses */
547 
548 
549 /* HTML forms; active elements; content */
550 
551 typedef unsigned int tHtmlInputLength;
552 #define MAX_HTML_INPUT_LENGTH (STRBUF_SIZE / 2)
553 
554 enum
555 { aekUnknown = 0, aekLink = 1, aekFormText = 2, aekFormPassword = 3,
556   aekFormCheckbox = 4, aekFormRadio = 5, aekFormSubmit = 6, aekFormReset = 7,
557   aekFormFile = 8, aekFormTextarea = 9, aekFormSelect = 10, aekFormButton = 11,
558   aekFormImage = 12, aekFormHidden = 13
559 };
560 #define MAX_AEK (13) /* associated UI strings in main.c */
561 typedef unsigned char tActiveElementKind;
562 #define is_form_aek(kind) \
563   ( ((kind) >= aekFormText) && ((kind) <= aekFormHidden) )
564 #define has_input_length(kind) \
565   ( ((kind) == aekFormText) || ((kind) == aekFormPassword) )
566 
567 enum
568 { aefNone = 0, aefCheckedSelected = 0x01, aefDisabled = 0x02,
569   aefReadonly = 0x04, aefMultiple = 0x08, aefButtonTag = 0x10
570 };
571 typedef unsigned char tActiveElementFlags;
572 #define aefChangeable (aefCheckedSelected)
573 
574 typedef signed int tActiveElementNumber;
575 #define INVALID_AE (-1)
576 
577 typedef signed int tHtmlFormNumber;
578 #define INVALID_HTML_FORM_NUMBER (-1)
579 
580 #if CONFIG_JAVASCRIPT
581 struct tJavascriptEventHandler;
582 #endif
583 
584 typedef struct
585 { const char *data, /* an attribute value - href for links, name otherwise */
586     *render; /* e.g. text to be rendered for this active element */
587 #if CONFIG_JAVASCRIPT
588   const struct tJavascriptEventHandler* eh;
589 #endif
590   tHtmlInputLength size, maxlength;
591   tActiveElementKind kind;
592   tActiveElementFlags flags;
593 } tActiveElementBase;
594 /* tActiveElementBase contains "constant" information which only depends on the
595    parsed resource (HTML source code), e.g. the target of a link or the maximum
596    length of a text-input element, while tActiveElement (in main.c) contains
597    view-dependent information like layout coordinates and current contents of
598    text-input elements. */
599 /* For aekFormSelect kind, <render> points to the list of options, and
600    <maxlength> is the number of options. */
601 
602 enum { hffNone = 0, hffMethodPost = 0x01, hffEncodingMultipart = 0x02 };
603 typedef unsigned char tHtmlFormFlags;
604 
605 typedef struct
606 { const char* action_uri;
607   tActiveElementNumber first_ae, last_ae;
608   tHtmlFormFlags flags;
609 } tHtmlForm;
610 
611 typedef struct tContentblock
612 { struct tContentblock* next;
613   char* data;
614   size_t usable, used;
615 } tContentblock;
616 
617 my_enum1 enum
618 { rckUnknown = 0, rckPlainText = 1, rckHtml = 2
619 } my_enum2(unsigned char) tResourceContentKind; /* CHECKME: rename! */
620 
621 my_enum1 enum
622 { cafNone = 0, cafNeedUnmap = 0x01, cafHtmlRedirection = 0x02
623 } my_enum2(unsigned char) tCantentFlags;
624 
625 /* a can/tent for con-tent; or maybe an abbr. for "can't entice"? :-) */
626 typedef struct
627 { tContentblock *content, *lastcontent, *lhpp_content;
628   void* tree; /* built from <content> (e.g. tree of HTML tags) */
629   tActiveElementBase* aebase;
630   tHtmlForm* form;
631   const char *redirection, *major_html_title;
632   size_t lhpp_byte; /* last HTML parser position: byte within content block */
633   size_t refcount;
634   tActiveElementNumber aenum, aemax;
635   tHtmlFormNumber hfnum, hfmax;
636   tResourceContentKind kind;
637   tCantentFlags caf;
638 } tCantent;
639 
640 
641 /* To have or not to have, that is the question! :-) */
642 
643 #if HAVE_MEMCPY
644 #define my_memcpy(dest, src, cnt) (void) memcpy(dest, src, cnt)
645 #elif HAVE_BCOPY
646 #define my_memcpy(dest, src, cnt) bcopy(src, dest, cnt)
647 #else
648 #define my_memcpy(dest, src, cnt) \
649   do \
650   { char* _d = (char*) (dest); \
651     const char* _s = (const char*) (src); \
652     size_t _c = (cnt); \
653     while (_c-- > 0) *_d++ = *_s++; \
654   } while (0)
655 #endif
656 
657 #if HAVE_MEMSET
658 #define my_memset(start, value, length) memset(start, value, length)
659 #else
660 #define my_memset(start, value, length) \
661   do \
662   { char* _s = (char*) (start); \
663     const char _v = (char) (value); \
664     size_t count = (length); \
665     while (count-- > 0) *_s++ = _v; \
666   } while (0)
667 #endif
668 
669 #if (!HAVE_MEMSET) && (HAVE_BZERO)
670   /* Use bzero() because it might be much faster than our stupid byte-by-byte
671      cleaning fallback; but use it only in this case -- it's marked "legacy",
672      SUSv3 says: "The memset() function is preferred over this function." */
673 #define my_memclr(start, length) bzero(start, length)
674 #else
675 #define my_memclr(start, length) my_memset(start, 0, length)
676 #endif
677 
678 #define my_memclr_var(var) my_memclr(&(var), sizeof(var))
679 #define my_memclr_arr(arr) my_memclr((arr), sizeof(arr))
680 
681 #if HAVE_MMAP
682 
683 #include <sys/mman.h>
684 #define my_mmap(len, fd) mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0)
685 #define my_munmap(start, len) (void) munmap(start, len)
686 
687 #else /* #if HAVE_MMAP */
688 
689 #ifndef MAP_FAILED
690 #define MAP_FAILED ((void*) (-1))
691 #endif
692 
693 extern void* nonbroken_mmap(size_t, int);
694 #define my_mmap(len, fd) nonbroken_mmap(len, fd)
695 #define my_munmap(start, len) memory_deallocate(start)
696 
697 #endif /* #if HAVE_MMAP */
698 
699 #if defined(MADV_SEQUENTIAL)
700 #define my_madvise_sequential(ptr, size) \
701   (void) madvise(ptr, size, MADV_SEQUENTIAL)
702 #elif defined(POSIX_MADV_SEQUENTIAL)
703 #define my_madvise_sequential(ptr, size) \
704   (void) posix_madvise(ptr, size, POSIX_MADV_SEQUENTIAL)
705 #else
706 #define my_madvise_sequential(ptr, size) do { } while (0)
707 #endif
708 
709 #if HAVE_STRCASECMP
710 #define my_strcasecmp(s1, s2) strcasecmp(s1, s2)
711 #else
712 extern int nonbroken_strcasecmp(const char*, const char*);
713 #define my_strcasecmp(s1, s2) nonbroken_strcasecmp(s1, s2)
714 #endif
715 
716 #if 0
717 #if HAVE_STRNCASECMP
718 #define my_strncasecmp(s1, s2, n) strncasecmp(s1, s2, n)
719 #else
720 extern int nonbroken_strncasecmp(const char*, const char*, size_t);
721 #define my_strncasecmp(s1, s2, n) nonbroken_strncasecmp(s1, s2, n)
722 #endif
723 #endif
724 
725 #if HAVE_STRCHR
726 #define my_strchr(str, ch) strchr(str, ch)
727 #else
728 extern char* nonbroken_strchr(const char*, int);
729 #define my_strchr(str, ch) nonbroken_strchr(str, ch)
730 #endif
731 
732 #if HAVE_STRERROR
733 #define my_strerror(errnum) strerror(errnum) /* CHECKME: use strerror_r()? */
734 #define __my_strerror(errnum) my_strerror(errnum)
735 #else
736 #define my_strerror(errnum) _(strUnknown) /* CHECKME! */
737 #define __my_strerror(errnum) strUnknown /* CHECKME! */
738 #endif
739 
740 #if HAVE_STRRCHR
741 #define my_strrchr(str, ch) strrchr(str, ch)
742 #else
743 extern char* nonbroken_strrchr(const char*, int);
744 #define my_strrchr(str, ch) nonbroken_strrchr(str, ch)
745 #endif
746 
747 #if HAVE_STRSTR
748 #define my_strstr(haystack, needle) strstr(haystack, needle)
749 #else
750 extern char* nonbroken_strstr(const char*, const char*);
751 #define my_strstr(haystack, needle) nonbroken_strstr(haystack, needle)
752 #endif
753 
754 
755 /* Miscellaneous */
756 
757 /* platform-specific settings */
758 #define USE_LWIP (CONFIG_PLATFORM == 1)
759 #define NEED_FD_REGISTER ( (USE_LWIP) /* || (....) */ )
760 #define CAN_HANDLE_SIGNALS (CONFIG_PLATFORM != 1)
761 #define CAN_ISSUE_WARNINGS (CONFIG_PLATFORM != 1)
762 #if CONFIG_PLATFORM == 1
763 #define chDirsep ('_')
764 #define strDirsep "_"
765 #else
766 #define chDirsep ('/')
767 #define strDirsep strSlash
768 #endif
769 
770 #if OPTION_LOCAL_CGI || OPTION_EXECEXT || OFWAX
771 #define MIGHT_FORK_EXEC 1
772 #define __initfe /* function not only used at initialization time */
773 #else
774 #define MIGHT_FORK_EXEC 0
775 #define __initfe __init /* function only used at initialization time */
776 #endif
777 
778 #if MIGHT_FORK_EXEC && defined(FD_CLOEXEC)
779 extern void make_fd_cloexec(int);
780 #else
781 #define make_fd_cloexec(fd) do { } while (0)
782 #endif
783 
784 #define TLS_GNUTLS  (1)
785 #define TLS_OPENSSL (2)
786 #define TLS_MATRIX  (3)
787 #define TLS_BUILTIN (4)
788 
789 #if OPTION_TLS
790 #define strTls ", tls"
791 #else
792 #define strTls ""
793 #endif
794 
795 #if OPTION_TLS == TLS_GNUTLS
796 #define strTLS "TLS (GnuTLS)"
797 #elif OPTION_TLS == TLS_OPENSSL
798 #define strTLS "TLS (OpenSSL)"
799 #elif OPTION_TLS == TLS_MATRIX
800 #define strTLS "TLS (MatrixSSL)"
801 #elif OPTION_TLS
802 #define strTLS "TLS"
803 #endif
804 
805 my_enum1 enum
806 { pmEnvironed = 0
807 #if CONFIG_EXTRA & EXTRA_DOWNLOAD
808   , pmDownload = 1
809 #endif
810 #if CONFIG_EXTRA & EXTRA_DUMP
811   , pmDump = 2
812 #endif
813 #if CONFIG_CONSOLE
814   , pmConsole = 3
815 #endif
816 #if DO_PAGER
817   , pmPager = 4
818 #endif
819 } my_enum2(unsigned char) tProgramMode;
820 extern const_after_init tProgramMode program_mode;
821 #define is_environed (program_mode == pmEnvironed) /* using curses/GTK/... */
822 
823 #if CONFIG_CONSOLE
824 #define is_promptable ( (is_environed) || (program_mode == pmConsole) )
825 #else
826 #define is_promptable (is_environed)
827 #endif
828 
829 extern /*@null@*/ const char* initial_messages;
830 #if CONFIG_CONSOLE
831 extern /*@null@*/ const char* initial_console_msgs;
832 #endif
833 extern unsigned char launch_uri_count;
834 extern const char* launch_uri[2];
835 
836 my_enum1 enum
837 { ftUnknown = 0, ftDontOverwrite = 1, ftMayOverwrite = 2, ftAppend = 3
838 } my_enum2(unsigned char) tFileTreatment;
839 
840 typedef unsigned char tRgbPart;
841 
842 /* A fast, flexible binary search algorithm; the standard library function
843    bsearch() only returns a useless _member_ of the array, while we want to get
844    an array _index_ by which we can access key, value, member, neighbor member
845    or whatever else we just need. */
846 typedef signed short tMbsIndex;
847 #define INVALID_INDEX ((tMbsIndex) (-1))
848 #define my_binary_search(_min_index, _max_index, comparison, action) \
849   { tMbsIndex min = _min_index, max = _max_index, idx; \
850     do \
851     { int res; \
852       idx = (min + max) / 2; \
853       res = comparison; /* depends on <idx> */ \
854       if (res < 0) max = idx - 1; \
855       else if (res > 0) min = idx + 1; \
856       else { perform_action: action; } \
857     } while (min <= max); \
858     idx = INVALID_INDEX; goto perform_action; /* not found */ \
859   }
860 
861 /* Simple bit manipulation helpers; <address> is the start address of a
862    bitfield, <bit> is the number of the desired bit within the field. */
863 #define __my_byte(address, bit) (*((unsigned char*) ((address) + ((bit) / 8))))
864 #define __my_bit(bit) (1 << ((bit) % 8))
865 #define my_bit_set(address, bit) __my_byte(address, bit) |= __my_bit(bit)
866 #define my_bit_clear(address, bit) __my_byte(address, bit) &= ~__my_bit(bit)
867 #define my_bit_flip(address, bit) __my_byte(address, bit) ^= __my_bit(bit)
868 #define my_bit_test(address, bit) (__my_byte(address, bit) & __my_bit(bit))
869 
870 #define list_reverse(_head, _type) \
871   do \
872   { _type *head = NULL, *temp = _head; \
873     while (temp != NULL) \
874     { _type* next = temp->next; \
875       temp->next = head; \
876       head = temp; \
877       temp = next; \
878     } \
879     _head = head; \
880   } while (0)
881 
882 #define list_extract(_headaddr0, _entry, _type) \
883   do \
884   { _type **headaddr0 = _headaddr0, *head0 = *headaddr0, *entry = _entry; \
885     if ( (head0 == NULL) || (entry == NULL) ) { /* "should not happen" */ } \
886     else if (head0 == entry) *headaddr0 = head0->next; \
887     else \
888     { while (head0->next != NULL) \
889       { if (head0->next == entry) { head0->next = entry->next; break; } \
890         head0 = head0->next; \
891       } \
892     } \
893   } while (0)
894 
895 /* CHECKME: use a sizeof() test with configure to avoid (_bogus_!) compiler
896    warnings on 64-bit machines! */
897 #define MY_INT_TO_POINTER(x) ( (void*) ((int) (x)) )
898 #define MY_POINTER_TO_INT(x) ((int) (x))
899 
900 /* Suppress _bogus_ compiler warnings about uninitialized variables (in order
901    to make all "real" warnings more visible): */
902 #if 1
903 #define SHUT_UP_COMPILER(value) = (value)
904 #else
905 #define SHUT_UP_COMPILER(value) /* nothing */
906 #endif
907 
908 #if CONFIG_DEBUG
909 extern const_after_init int debugfd;
910 #define __debugmsg(msg, len) (void) my_write(debugfd, msg, len)
911 #define debugmsg(_dbgmsg) \
912   do \
913   { const char* dbgmsg = (_dbgmsg); /* (evaluate it only once) */ \
914     __debugmsg(dbgmsg, strlen(dbgmsg)); \
915   } while (0)
916 #else
917 #define __debugmsg(msg, len) do { } while (0)
918 #define debugmsg(msg) do { } while (0)
919 #endif
920 
921 #define __exdebugmsg(msg, len) do { } while (0)
922 #define exdebugmsg(msg) do { } while (0)
923 
924 extern const_after_init int fd_stdin, fd_stdout, fd_stderr, fd_keyboard_input;
925 
926 typedef unsigned short tPortnumber;
927 /* (The correct formal type would be in_port_t, but this seems to be
928     not-so-portable; e.g. glibc before 2000-04-01 doesn't have it.) */
929 
930 #define __dealloc(ptr) do { if (ptr != NULL) memory_deallocate(ptr); } while(0)
931 #define dealloc(ptr) \
932   do { if (ptr != NULL) { memory_deallocate(ptr); ptr = NULL; } } while (0)
933 #define my_strdedup(dest, src) /* deallocate and duplicate */ \
934   do { __dealloc(dest); (dest) = my_strdup(src); } while (0)
935 
936 /* some dumb library headers define what we need as variable identifiers... */
937 #undef min
938 #undef max
939 #undef _min
940 #undef _max
941 
942 
943 /* Data handling mechanism */
944 
945 my_enum1 enum
946 { dhmcInit = 0, dhmcGet = 1, dhmcPut = 2, dhmcNotificationSetup = 3,
947   dhmcNotify = 4, dhmcControl = 5
948 } my_enum2(unsigned char) tDhmCommand;
949 
950 my_enum1 enum
951 { dhmnfNone = 0, dhmnfRemoval = 0x01, dhmnfOnce = 0x02, dhmnfDataChange = 0x04,
952   dhmnfMetadataChange = 0x08, dhmnfAttachery = 0x10
953 } my_enum2(unsigned char) tDhmNotificationFlags;
954 #define dhmnfGotData (dhmnfDataChange)
955 #define dhmnfAll ((dhmnfMetadataChange << 1) - 1)
956 /* dhmnfOnce is semantically a simplified, fast combination of dhmnfGotData,
957    dhm_notification_off() and dhmnfRemoval. */
958 
959 typedef void (*tDhmNotificationCallback)(void*, tDhmNotificationFlags);
960 
961 typedef struct tDhmNotificationEntry
962 { struct tDhmNotificationEntry* next;
963   tDhmNotificationCallback callback;
964   void* callback_data;
965   tDhmNotificationFlags flags;
966 } tDhmNotificationEntry;
967 
968 my_enum1 enum
969 { dhmccRefcount0 = 0, dhmccFirstUnused = 1
970 } my_enum2(unsigned char) tDhmControlCode;
971 
972 typedef void (*tDhmControlHandler)(void* /*obj*/, void* /*ctrldata*/,
973   tDhmControlCode);
974 
975 typedef struct
976 { void* data;
977   tDhmControlCode code;
978 } tDhmControlData;
979 
980 typedef struct
981 { void* object;
982   tDhmControlHandler control_handler;
983   tDhmNotificationEntry* notifications;
984 #if CONFIG_DEBUG
985   const char* debugstr;
986 #endif
987   size_t refcount;
988 } tDhmGenericData;
989 
990 my_enum1 enum
991 { dhmnSet = 0, dhmnOr = 1, dhmnAndnot = 2, dhmnXor = 3
992 } my_enum2(unsigned char) tDhmNotimode;
993 
994 typedef struct
995 { tDhmNotificationCallback callback;
996   void* callback_data;
997   tDhmNotificationFlags flags;
998   tDhmNotimode mode;
999 } tDhmNotificationSetup;
1000 
1001 #if 0
1002 typedef void (*tDhmHandler)(tDhmGenericData**, const void*, tDhmCommand);
1003 extern tDhmHandler dhm_generic_handler;
1004 #else
1005 extern void dhm_generic_handler(tDhmGenericData**, const void*, tDhmCommand);
1006 #endif
1007 
1008 #define __dhm_handler(obj) (dhm_generic_handler)
1009   /* (might become e.g. ((obj)->dhm_handler) in a later version?) */
1010 
1011 #define dhm_handle_command(obj, cmddata, cmd) \
1012   (__dhm_handler(obj))(&((obj)->dhm_data), (cmddata), (cmd))
1013 
1014 #if CONFIG_DEBUG
1015 #define dhm_set_debugstr(obj, dbgstr) \
1016   do \
1017   { (((obj)->dhm_data)->debugstr) = dbgstr; \
1018     debugmsg("dhm_init(): "); debugmsg(dbgstr); debugmsg(strNewline); \
1019   } while (0)
1020 #else
1021 #define dhm_set_debugstr(obj, dbgstr) do { } while (0)
1022 #endif
1023 
1024 #define dhm_init(obj, _control_handler, dbgstr) \
1025   do \
1026   { dhm_handle_command((obj), (obj), dhmcInit); \
1027     dhm_set_debugstr((obj), (dbgstr)); \
1028     (obj)->dhm_data->control_handler = (_control_handler); \
1029   } while (0)
1030 
1031 #define dhm_get(obj) dhm_handle_command((obj), NULL, dhmcGet)
1032 
1033 #define dhm_put(obj) dhm_handle_command((obj), NULL, dhmcPut) /*lost interest*/
1034 
1035 #define dhm_attach(dest, obj) do { dhm_get(obj); (dest) = (obj); } while (0)
1036 
1037 #define dhm_detach(obj) do { dhm_put(obj); (obj) = NULL; } while (0)
1038 
1039 #define dhm_notification_setup(obj, callback, cbdata, flags, mode) \
1040   do \
1041   { const tDhmNotificationSetup _dns = { callback, cbdata, flags, mode }; \
1042     dhm_handle_command((obj), &_dns, dhmcNotificationSetup); \
1043   } while (0)
1044 
1045 #define dhm_notification_off(obj, callback, cbdata) /* lost interest */ \
1046   dhm_notification_setup((obj), (callback), (cbdata), dhmnfAll, dhmnAndnot)
1047 
1048 #define dhm_notify(obj, flags) \
1049   do \
1050   { const tDhmNotificationFlags _df = (flags); \
1051     dhm_handle_command((obj), &_df, dhmcNotify); \
1052   } while (0)
1053 
1054 #define dhm_control(obj, ctrldata, ctrlcode) \
1055   do \
1056   { const tDhmControlData _cd = { (ctrldata), (ctrlcode) }; \
1057     dhm_handle_command((obj), &_cd, dhmcControl); \
1058   } while (0)
1059 
1060 /* General usage of the data handling mechanism:
1061    - dhm_init() is called by the "owner" of an object, usually right after the
1062      object has been allocated
1063    - dhm_get() and dhm_put() are called by "users" of the object, normally via
1064      dhm_attach() and dhm_detach()
1065    - dhm_notification_setup() and dhm_notification_off() are called by "users"
1066      of the object if 1. the object is completely non-refcounted or 2. get/put
1067      isn't appropriate for a specific "user"
1068    - dhm_notify() is called by the "owner" to inform the "users" about
1069      something, esp. dhmnfRemoval
1070    - dhm_control() can be called by the dhm itself (esp. for dhmccRefcount0) or
1071      by "users" of the object to set/query information or to start/stop actions
1072 */
1073 
1074 
1075 /* Run-time Configuration */
1076 
1077 typedef struct tConfigProxy
1078 { struct tConfigProxy* next;
1079   char *hosts_pattern, *proxy_hostname;
1080 #if CONFIG_HTTP & HTTP_PROXYAUTH
1081   char *auth_user, *auth_pass;
1082 #endif
1083   tPortnumber hosts_portnumber, proxy_portnumber; /* (in network byte order) */
1084 } tConfigProxy;
1085 
1086 typedef struct tConfigProtocolVersion
1087 { struct tConfigProtocolVersion* next;
1088   char *hosts_pattern, *protstr;
1089   tPortnumber hosts_portnumber;
1090 } tConfigProtocolVersion;
1091 
1092 #if OPTION_COOKIES
1093 enum { ccfNone = 0, ccfAllowed = 0x01 };
1094 typedef unsigned char tConfigCookieFlags;
1095 
1096 typedef struct tConfigCookie
1097 { struct tConfigCookie* next;
1098   const char* hosts_pattern;
1099   tConfigCookieFlags flags;
1100 } tConfigCookie;
1101 #endif /* #if OPTION_COOKIES */
1102 
1103 #if OPTION_LOCAL_CGI
1104 enum { clcfNone = 0, clcfAllowed = 0x01 };
1105 typedef unsigned char tConfigLocalCgiFlags;
1106 
1107 typedef struct tConfigLocalCgi
1108 { struct tConfigLocalCgi* next;
1109   const char* path_pattern;
1110   tConfigLocalCgiFlags flags;
1111 } tConfigLocalCgi;
1112 #endif /* #if OPTION_LOCAL_CGI */
1113 
1114 typedef struct tConfigLogin
1115 { struct tConfigLogin* next;
1116   char *user, *password, *hosts_pattern;
1117   tPortnumber hosts_portnumber; /* (in network byte order) */
1118 } tConfigLogin;
1119 
1120 #if CONFIG_JUMPS
1121 typedef struct tConfigJump
1122 { struct tConfigJump* next;
1123   const char* name; /* "name" is a shortcut for "shortcut" :-) */
1124   char *uri, **arg;
1125   unsigned short argcount, maxargcount;
1126 } tConfigJump;
1127 #endif
1128 
1129 #if CONFIG_LOCALDIR > 1
1130 typedef struct tConfigLocaldirsort
1131 { struct tConfigLocaldirsort* next;
1132   const char* path_pattern;
1133   const_after_init char* sorting;
1134 } tConfigLocaldirsort;
1135 typedef struct tConfigLocaldirformat
1136 { struct tConfigLocaldirformat* next;
1137   const char *path_pattern, *format;
1138 } tConfigLocaldirformat;
1139 #endif /* #if CONFIG_LOCALDIR > 1 */
1140 
1141 #if CONFIG_FTP && OPTION_TLS
1142 my_enum1 enum
1143 { ftmAutodetect = 0, ftmAuthTls = 1, ftmAuthTlsDataclear = 2, ftmAuthSsl = 3,
1144   ftmTls = 4
1145 } my_enum2(unsigned char) tFtpTlsMethod;
1146 typedef struct tConfigFtpTlsMethod
1147 { struct tConfigFtpTlsMethod* next;
1148   char* hosts_pattern;
1149   tPortnumber hosts_portnumber; /* (in network byte order) */
1150   tFtpTlsMethod ftm;
1151 } tConfigFtpTlsMethod;
1152 #endif
1153 
1154 #if OPTION_EXECEXT
1155 typedef struct tExecextParam
1156 { struct tExecextParam* next;
1157   char* param;
1158 } tExecextParam;
1159 #endif
1160 
1161 #if CONFIG_RTCONFIG && OPTION_BIRTCFG
1162 extern const char strBirtcfg[]; /* see auto-generated birtcfg.inc */
1163 #endif
1164 
1165 my_enum1 enum
1166 { cfNone = 0, cfColorsOff = 0x01, cfColorsReverse = 0x02,
1167   cfUserDefinedConfigPath = 0x04, cfTermwintitle = 0x08,
1168   cfDontConfirmQuit = 0x10, cfDontConfirmClose = 0x20,
1169   cfDontConfirmOverwrite = 0x40, cfDontConfirmSubmit = 0x80,
1170   cfDontConfirmReset = 0x100, cfDontConfirmRepost = 0x200,
1171   cfDontConfirmHtml = 0x400, cfDontConfirmEnable = 0x800
1172 #if CONFIG_DISK_CACHE
1173   , cfUseDiskCache = 0x1000, cfMayWriteDiskCache = 0x2000
1174 #endif
1175 #if OPTION_EXECEXT & EXECEXT_SHELL
1176   , cfExecextShellCustom = 0x4000
1177 #endif
1178 #if CONFIG_HTML & HTML_FRAMES
1179   , cfHtmlFramesSimple = 0x8000
1180 #endif
1181 #if MIGHT_USE_SCROLL_BARS
1182   , cfUseScrollBars = 0x10000
1183 #endif
1184 #if CONFIG_RTCONFIG
1185   , cfRtExternal = 0x20000
1186 #if OPTION_BIRTCFG
1187   , cfRtBuiltin = 0x40000
1188 #define cfRtAll (cfRtExternal | cfRtBuiltin)
1189 #else
1190 #define cfRtAll (cfRtExternal)
1191 #endif
1192 #endif
1193 } my_enum2(tUint32) tConfigurationFlags;
1194 
1195 typedef struct
1196 { const char* path; /* path to the directory which contains config file etc. */
1197 #if CONFIG_DISK_CACHE
1198   const char* cachepath; /* path to the disk cache directory */
1199 #endif
1200   const char* user_agent; /* for HTTP header "User-Agent" */
1201   const char* languages; /* for HTTP header "Accept-Language" */
1202   const char *home_uri, *search_engine, *bookmarks; /* special URIs */
1203 #if CONFIG_EXTRA & (EXTRA_DOWNLOAD | EXTRA_DUMP)
1204   const char* pm_uri; /* for pmDownload/pmDump */
1205 #endif
1206   const_after_init tConfigProtocolVersion* http_version;
1207   const_after_init tConfigProxy* http_proxies;
1208 #if OPTION_TLS
1209   const_after_init tConfigProxy* https_proxies;
1210 #endif
1211 #if CONFIG_FTP
1212   const_after_init tConfigLogin* ftp_login;
1213 #if OPTION_TLS
1214   const_after_init tConfigFtpTlsMethod* ftp_tls_method;
1215 #endif
1216 #endif
1217 #if CONFIG_JUMPS
1218   const_after_init tConfigJump* jumps;
1219 #endif
1220 #if CONFIG_LOCALDIR > 1
1221   const_after_init tConfigLocaldirsort* lds;
1222   const_after_init tConfigLocaldirformat* ldf;
1223 #endif
1224 #if OPTION_COOKIES
1225   const_after_init tConfigCookie* http_cookies;
1226 #endif
1227 #if OPTION_TLS && OPTION_COOKIES
1228   const_after_init tConfigCookie* https_cookies;
1229 #endif
1230 #if OPTION_LOCAL_CGI
1231   const_after_init tConfigLocalCgi* local_cgi;
1232 #endif
1233 #if OPTION_EXECEXT & EXECEXT_SHELL
1234   const_after_init tExecextParam* execext_shell;
1235 #endif
1236 #if CONFIG_SESSIONS
1237   const char *session_default, *session_resume;
1238 #endif
1239 #if OPTION_NEWS
1240   const char* news_server;
1241 #endif
1242   size_t ramcachesize;
1243 #if CONFIG_DISK_CACHE
1244   size_t diskcachesize;
1245 #endif
1246 #if TGC_IS_GRAPHICS
1247   tCoordinate width, height; /* default window-contents width/height */
1248 #endif
1249   tConfigurationFlags flags;
1250 #if TGC_IS_CURSES
1251   char char_yes, char_no; /* (mostly for i18n) */
1252 #endif
1253 #if CONFIG_CONSOLE
1254   char console_backspace;
1255 #endif
1256   char char_file, char_dir, char_link; /* (mostly for i18n) */
1257   unsigned char redirections; /* maximum number of automatic redirections */
1258 } tConfiguration;
1259 
1260 extern tConfiguration config;
1261 
1262 
1263 /* Functions */
1264 
1265 extern int streqcase3(const char*, const char*);
1266 #define streqcase(str1, str2) (streqcase3(str1, str2) == 0)
1267 extern int strneqcase3(const char*, const char*, size_t);
1268 #define strneqcase(str1, str2, maxlen) (strneqcase3(str1, str2, maxlen) == 0)
1269 extern void my_atoi(const char*, /*@reldef@*/ int*, /*@reldef@*/ const char**,
1270   int);
1271 extern char* my_strnchr(const char*, int, int);
1272 extern char* my_strncasestr(const char*, const char*, const size_t);
1273 extern tBoolean is_suffix(const char* /*string*/, const char* /*suffix*/);
1274 extern tBoolean my_pattern_matcher(const char*, const char*);
1275 extern void does_not_return do_quit(void);
1276 extern void does_not_return do_quit_sig(void);
1277 extern void does_not_return fatal_error(int, const char*);
1278 extern __sallocator /*@notnull@*/ /*@out@*/ void* __callocator
1279   __memory_allocate_ll(size_t);
1280 extern __sallocator /*@notnull@*/ void* __callocator
1281   memory_allocate_ll(size_t);
1282 extern __sallocator /*@notnull@*/ void* memory_reallocate_ll(/*@only@*/ void*,
1283   size_t);
1284 extern void memory_deallocate_ll(/*@only@*/ /*@notnull@*/ const void*);
1285 extern __sallocator char* __callocator my_strdup(const char*);
1286 extern __sallocator char* __callocator my_strndup(const char*, size_t);
1287 extern __sallocator char* __callocator my_strdup_tolower(const char*);
1288 extern __sallocator char* __callocator my_strndup_tolower(const char*, size_t);
1289 
1290 my_enum1 enum
1291 { /* low-level */
1292   mapUnknown = 0, mapOther = 1, mapPermanent = 2, mapString = 3,
1293   mapScripting = 4,
1294   /* networking */
1295   mapResource = 5, mapResourceRequest = 6, mapContentblock = 7,
1296   mapConnection = 8, mapUriData = 9, mapSinkingData = 10, mapWritedata = 11,
1297   mapRpsd = 12,
1298   /* user interface */
1299   mapWindow = 13, mapWksd = 14, mapWindowView = 15, mapCantent = 16,
1300   mapLineInput = 17, mapUserQuery = 18, mapGtk = 19, mapKeymap = 20,
1301   mapRendering = 21, mapHtmlNode = 22
1302 } my_enum2(unsigned char) tMemoryAllocationPool; /* (mostly for debugging) */
1303 
1304 #ifndef memory_allocate
1305 #define __memory_allocate(s, m) __memory_allocate_ll(s)
1306 #define memory_allocate(s, m) memory_allocate_ll(s)
1307 #define memory_reallocate(p, s, m) memory_reallocate_ll(p, s)
1308 #define memory_deallocate(p) memory_deallocate_ll(p)
1309 #endif
1310 
1311 extern tBoolean is_time_valid;
1312 extern time_t my_time(void);
1313 extern tBoolean my_memdiff(const void*, const void*, size_t);
1314 extern const char* get_homepath(void);
1315 #if CONFIG_LOCALDIR > 1
1316 extern void check_localdirsort(char*);
1317 #endif
1318 
1319 #define MIGHT_NEED_TIMEOUTS ( (CONFIG_TG == TG_BICURSES) || ( (CONFIG_TG == TG_XCURSES) && (MIGHT_USE_SCROLL_BARS) ) || (OPTION_EXECINT & EXECINT_RELIAWFUL) || (USE_LWIP) )
1320 
1321 #if MIGHT_NEED_TIMEOUTS
1322 typedef tBoolean (*tTimeoutHandler)(int*);
1323 extern void timeout_register(tTimeoutHandler);
1324 extern void timeout_unregister(tTimeoutHandler);
1325 #endif
1326 
1327 #if NEED_FD_REGISTER
1328 my_enum1 enum
1329 { fdkNone = 0, fdkFile = 0x01, fdkPipe = 0x02, fdkSocket = 0x04,
1330   fdkOther = 0x08 /* ..., fdkStdin, fdkStdout, fdkStderr, fdkTerminal, ...? */
1331 } my_enum2(unsigned char) tFdKind;
1332 extern void fd_register_init(void);
1333 extern void fd_register(int*, tFdKind);
1334 extern tFdKind fd_register_lookup(int*);
1335 #if CONFIG_TG == TG_XCURSES
1336 extern tBoolean fd_register_rlookup(int*, tFdKind);
1337 #endif
1338 extern int my_pipe(/*@out@*/ int*);
1339 extern int my_isatty(int);
1340 #define my_write_str_unregistried(fd, str) write(fd, str, strlen(str))/*FIXME*/
1341 #define my_close_unregistried close /* FIXME! */
1342 #define my_fstat_unregistried fstat /* FIXME! */
1343 #else
1344 #define fd_register(fdptr, kind) do { } while (0)
1345 #define my_write_str_unregistried my_write_str
1346 #define my_close_unregistried my_close
1347 #define my_fstat_unregistried my_fstat
1348 #define my_pipe(f) pipe(f)
1349 #define my_isatty(x) isatty(x)
1350 #endif
1351 
1352 my_enum1 enum
1353 { fdofNone = 0, fdofRead = 0x01, fdofWrite = 0x02
1354 } my_enum2(unsigned char) tFdObservationFlags;
1355 
1356 typedef void (*tFdObservationHandler)(void*, tFdObservationFlags);
1357 
1358 #if OPTION_POLL
1359 #define fd_is_observable(fd) (truE) /* never a problem */
1360 #else
1361 extern tBoolean fd_is_observable(int);
1362 #endif
1363 
1364 extern void fd_observe_init(void);
1365 extern void fd_observe(int, tFdObservationHandler, void*, tFdObservationFlags);
1366 extern void fd_observe_change_handler(int, tFdObservationHandler);
1367 extern void fd_unobserve(int);
1368 extern void fd_multiplex(void);
1369 extern void does_not_return fatal_tmofd(int);
1370 
1371 extern int my_create(const char*, int, mode_t);
1372 extern int my_open(const char*, int);
1373 extern void my_close(int);
1374 extern ssize_t my_read(int, /*@out@*/ void*, size_t);
1375 extern ssize_t __my_write(int, const void*, size_t);
1376 extern ssize_t my_write(int, const void*, size_t);
1377 #define my_write_str(fd, str) \
1378   do { const char* _x = (str); (void) my_write(fd, _x, strlen(_x)); } while (0)
1379 extern void my_write_crucial(int, const void*, size_t);
1380 extern unsigned char my_mmap_file_readonly(const char*, /*@out@*/ void**,
1381   /*@out@*/ size_t*);
1382 extern int my_stat(const char*, /*@out@*/ struct stat*);
1383 extern int my_fstat(int, /*@out@*/ struct stat*);
1384 
1385 /* confus^Wclarification for sockets */
1386 #define my_read_sock my_read
1387 #define my_write_sock my_write
1388 #define my_close_sock my_close
1389 
1390 /* clarification for pipes */
1391 #define my_read_pipe my_read
1392 #define my_write_pipe my_write
1393 #define my_close_pipe my_close
1394 
1395 /* clarification for sockets/pipes */
1396 #define my_read_sopi my_read
1397 #define my_write_sopi my_write
1398 #define my_close_sopi my_close
1399 
1400 #define my_strcpy_conv(__dest, __src, __func) \
1401   do \
1402   { const char* _src = (__src); char ch, *_dest = (__dest); /* eval once */ \
1403     do { ch = *_src++; *_dest++ = (__func); } while (ch != '\0'); \
1404   } while (0)
1405 #define my_strcpy_tolower(_dest, _src) \
1406   my_strcpy_conv(_dest, _src, my_tolower(ch))
1407 #define my_strcpy_toupper(_dest, _src) \
1408   my_strcpy_conv(_dest, _src, my_toupper(ch))
1409 
1410 extern void my_spf_attr my_spf(char*, size_t, /*@out@*/ char**,
1411   const char*, ...);
1412 #define my_spf_cleanup(staticbuf, spfbuf) \
1413   do { if (staticbuf != spfbuf) memory_deallocate(spfbuf); } while (0)
1414 #define my_spf_use(spfbuf) (spfbuf) /* (just to clarify the code) */
1415 
1416 #if (CONFIG_TG == TG_BICURSES) || (CONFIG_TG == TG_XCURSES)
1417 extern tBoolean env_termsize(/*@out@*/ int*, /*@out@*/ int*); /* see init.c */
1418 #endif
1419 
1420 #define MIGHT_WANT_TERMSIZE ( ( (TGC_IS_CURSES) && (CONFIG_TG != TG_XCURSES) ) /* || (CONFIG_CONSOLE) */ )
1421 #if MIGHT_WANT_TERMSIZE
1422 extern tBoolean calc_termsize(/*@out@*/ int*, /*@out@*/ int*); /* see init.c */
1423 #endif
1424 
1425 #if MIGHT_FORK_EXEC
1426 #if CAN_HANDLE_SIGNALS
1427 extern void reset_signals(void); /* see init.c */
1428 #else
reset_signals(void)1429 static __my_inline void reset_signals(void) { }
1430 #endif
1431 #endif
1432 
1433 #if CONFIG_KEYMAPS /* see main.c */
1434 extern unsigned char keymap_command_key_register(const char*, const char*);
1435 extern unsigned char keymap_lineinput_key_register(const char*, const char*);
1436 #endif
1437 
1438 #endif /* #ifndef __retawq_stuff_h__ */
1439