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