1 /* retawq/resource.h - resource handling (network, cache, DNS, ...) 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 /* In the comments for data structure declarations in this file, "EXAC(thread)" 10 meant that <thread> is the only thread which may access the marked member 11 in any way ("exclusive access"). For a pointer, EXACD(thread) meant that 12 only that thread may dereference the pointer. */ 13 14 #ifndef __retawq_resource_h__ 15 #define __retawq_resource_h__ 16 17 #include "stuff.h" 18 19 extern /*@observer@*/ const char strRedirection[]; 20 21 #if CAN_HANDLE_SIGNALS 22 extern const_after_init int fd_any2main_read, fd_any2main_write; 23 #endif 24 #if CONFIG_TG == TG_XCURSES 25 extern const_after_init int fd_xcurses2main_read, fd_xcurses2main_write; 26 #endif 27 28 extern const char strCrlf[]; 29 #if CONFIG_FTP 30 extern const char strList[], strRetr[]; 31 #endif 32 33 34 /* Resource protocols */ 35 36 my_enum1 enum 37 { rpUnknown = 0, rpDisabled = 1, rpHttp = 2, __rpFtp = 3, rpLocal = 4, 38 rpAbout = 5, __rpFinger = 6, __rpLocalCgi = 7, __rpNntp = 8, __rpPop = 9, 39 __rpPops = 10, rpCvs = 11, __rpGopher = 12, rpInfo = 13, __rpMailto = 14, 40 __rpJavascript = 15, __rpHttps = 16, __rpFtps = 17, __rpExecextShell = 18 41 } my_enum2(unsigned char) tResourceProtocol; 42 #define rpMax (18) 43 #define is_rp_nice(rp) ((rp) > rpDisabled) 44 #define MAXSCHEMESTRSIZE ((100) + 1) 45 /* (just a value which is "big enough", even for _(strUnknown)) */ 46 47 #if CONFIG_FINGER 48 #define rpFinger (__rpFinger) 49 #endif 50 #if CONFIG_GOPHER 51 #define rpGopher (__rpGopher) 52 #endif 53 #if CONFIG_FTP 54 #define rpFtp (__rpFtp) 55 #endif 56 #if OPTION_LOCAL_CGI 57 #define rpLocalCgi (__rpLocalCgi) 58 #endif 59 #if OPTION_NEWS 60 #define rpNntp (__rpNntp) 61 #endif 62 #if OPTION_POP 63 #define rpPop (__rpPop) 64 #if OPTION_TLS 65 #define rpPops (__rpPops) 66 #endif 67 #endif 68 #if CONFIG_MAILTO 69 #define rpMailto (__rpMailto) 70 #endif 71 #if CONFIG_JAVASCRIPT 72 #define rpJavascript (__rpJavascript) 73 #endif 74 75 #if OPTION_TLS 76 #define rpHttps (__rpHttps) 77 #if CONFIG_FTP 78 #define rpFtps (__rpFtps) 79 #endif 80 #endif 81 82 #if OPTION_EXECEXT & EXECEXT_SHELL 83 #define rpExecextShell (__rpExecextShell) 84 #endif 85 86 my_enum1 enum 87 { rpfNone = 0, rpfIsLocallike = 0x01, rpfIsHttplike = 0x02, 88 rpfIsFtplike = 0x04, rpfIsPoplike = 0x08, rpfIsTlslike = 0x10, 89 rpfUsesAuthority = 0x20, rpfIsPathHierarchical = 0x40, rpfUiToupper = 0x80, 90 rpfUiAlternate = 0x100 91 } my_enum2(unsigned short) tRpFlags; 92 93 typedef struct 94 { const char* scheme; 95 tResourceProtocol final_rp; 96 tRpFlags flags; 97 } tRpData; 98 99 extern const tRpData rp_data[rpMax + 1]; 100 101 #define __has_rpflag(rp, rpf) (rp_data[(rp)].flags & (rpf)) 102 #define is_locallike(rp) __has_rpflag((rp), rpfIsLocallike) 103 #define is_httplike(rp) __has_rpflag((rp), rpfIsHttplike) 104 #if CONFIG_FTP 105 #define is_ftplike(rp) __has_rpflag((rp), rpfIsFtplike) 106 #endif 107 #if OPTION_POP 108 #define is_poplike(rp) __has_rpflag((rp), rpfIsPoplike) 109 #endif 110 #if OPTION_TLS 111 #define is_tlslike(rp) __has_rpflag((rp), rpfIsTlslike) 112 #endif 113 114 115 /* Resource data */ 116 117 my_enum1 enum 118 { rfNone = 0, rfFinal = 0x01, rfPost = 0x02, rfIsRedirection = 0x04, 119 rfIsEmbedded = 0x08, rfIsEnforced = 0x10, rfActivityWatched = 0x20, 120 rfActivityUnwatchable = 0x40 121 #if CONFIG_EXTRA & EXTRA_DOWNLOAD 122 , rfDownload = 0x80 123 #endif 124 #if CONFIG_ANY_MAIL 125 , rfMailbox = 0x100 126 #endif 127 #if OPTION_COOKIES 128 , rfCookieSender = 0x200, rfCookieStorer = 0x400 /* RFC2965, 6.1, *2 */ 129 #define rfCookieAnything (rfCookieSender | rfCookieStorer) 130 #endif 131 #if CONFIG_CUSTOM_CONN 132 , rfCustomConn = 0x800, rfCustomConnStopSequencer = 0x1000, 133 rfCustomConnBd1 = 0x2000, rfCustomConnBd2 = 0x4000, rfCustomConnBd3 = 0x8000, 134 rfCustomConnBd4 = 0x10000 135 #define rfCustomConnBdAny (rfCustomConnBd1 | rfCustomConnBd2 | rfCustomConnBd3 | rfCustomConnBd4) 136 /* "Bd" as in "Brain-damaged"; the FTP protocol seriously deserves it... */ 137 #endif 138 } my_enum2(unsigned int) tResourceFlags; 139 140 my_enum1 enum 141 { rsUnknown = 0, rsError = 1, rsConnecting = 2, rsMsgExchange = 3, 142 rsReading = 4, rsComplete = 5, rsStopped = 6 143 } my_enum2(unsigned char) tResourceState; 144 #define MAX_RESOURCE_STATE (6) 145 extern /*@observer@*/ const char* const 146 strResourceState[MAX_RESOURCE_STATE + 1]; 147 148 my_enum1 enum 149 { rchUnknown = 0, rchConnected = 1 150 #if CONFIG_FTP 151 , rchFtpUser = 2, rchFtpPassword = 3, rchFtpAccount = 4, rchFtpPasv = 5, 152 rchFtpRequest = 6 153 #if OPTION_TLS 154 , rchFtpTlsAuthTls = 7, rchFtpTlsAuthSsl = 8, rchFtpTlsPbsz = 9, 155 rchFtpTlsProt = 10 156 #endif 157 #if CONFIG_CUSTOM_CONN 158 , rchFtpCustom = 11 159 #endif 160 #endif 161 #if OPTION_NEWS 162 , rchNntpModeReader = 12, rchNntpGetGroups = 13, rchNntpFetchArticle = 14, 163 rchNntpFetchHeader = 15, rchNntpSelectGroup = 16 164 #endif 165 #if OPTION_POP 166 , rchPopUser = 17, rchPopPass = 18, rchPopApop = 19, rchPopStat = 20, 167 rchPopTop = 21, rchPopUidl = 22, rchPopRetr = 23 168 #if OPTION_TLS 169 , rchPopStls = 24 170 #endif 171 #endif 172 } my_enum2(unsigned char) tResourceCommandHandshake; 173 174 my_enum1 enum 175 { reFine = 0, reKind = 1, reSocket = 2, reConnect = 3, reRefused = 4, 176 reNetwork = 5, reDns = 6, reFile = 7, reUri = 8, reServerClosed = 9, 177 reHandshake = 10, rePortnumber = 11, reProtocol = 12, reTimeout = 13, 178 reResponse = 14, reLogin = 15, reRedirection = 16, reRandom = 17, reTls = 18, 179 reProxyAuth = 19, rePipe = 20, reFork = 21, reConfigForbids = 22, 180 reExec = 23, reProtDisabled = 24, reHostname = 25, reTmofd = 26, 181 reConnReset = 27 182 } my_enum2(unsigned char) tResourceError; 183 #define MAX_RESOURCE_ERROR (27) 184 extern /*@observer@*/ const char* const 185 strResourceError[MAX_RESOURCE_ERROR + 1]; 186 187 #if OPTION_TLS 188 my_enum1 enum 189 { teFine = 0, teUnknown = 1, teSessionExpired = 2, teFatalAlert = 3, 190 teFile = 4, teData = 5, teOom = 6, teCipher = 7, teCompression = 8, 191 teCrypt = 9, teSrp = 10, tePk = 11, tePacket = 12, teUnimplemented = 13, 192 teHandshake = 14, teInit = 15 193 } my_enum2(unsigned char) tTlsError; 194 #define MAX_TLS_ERROR (15) 195 extern /*@observer@*/ const char* const strTlsError[MAX_TLS_ERROR + 1]; 196 #define is_tls_error_expressive(te) ((te) > teUnknown) /* for UI */ 197 #endif 198 199 my_enum1 enum 200 { udfNone = 0, udfTryIpv6 = 0x01, udfGotExplicitPortnumber = 0x02 201 #if CONFIG_FTP 202 , udfFtpTypeA = 0x04, udfFtpTypeD = 0x08, udfFtpTypeI = 0x10 203 #endif 204 } my_enum2(unsigned char) tUriDataFlags; 205 206 typedef struct 207 { char *uri, *hostname, *path, *query, *post, *username, *password; 208 tPortnumber portnumber; /* (in network byte order) */ 209 unsigned char refcount; /* 0..2 */ 210 tResourceProtocol rp; 211 tResourceError re; 212 tUriDataFlags udf; 213 } tUriData; 214 215 typedef struct tSaveAs 216 { struct tSaveAs* next; 217 int fd; 218 } tSaveAs; 219 220 typedef unsigned short tServerStatusCode; /* 0 or roughly 100..699 */ 221 typedef signed char tTlHeaderState; /*transport-level header state (misnomer)*/ 222 223 #define UNKNOWN_CONTENTLENGTH ((size_t) (~((size_t) 0))) 224 225 #if 1 || CONFIG_FTP || OPTION_NEWS || OPTION_POP || OPTION_TRAP 226 /* (the "1 ||" is for HTTP nowadays) */ 227 #define USE_RPSD 1 228 struct tRpsdGeneric; /* resource-protocol-specific data */ 229 #else 230 #define USE_RPSD 0 231 #endif 232 233 typedef struct tTransferData 234 { struct tTransferData* next; 235 const char* name; 236 char* data; 237 size_t size; 238 tBoolean need_unmap; 239 } tTransferData; 240 241 my_enum1 enum 242 { sdfNone = 0, sdfIsDownloadFdValid = 0x01, sdfIsRestartMarkerValid = 0x02 243 } my_enum2(unsigned char) tSinkingDataFlags; 244 245 typedef struct 246 { tTransferData* transfer_data; 247 size_t restart_marker; 248 int download_fd; 249 tSinkingDataFlags flags; 250 } tSinkingData; 251 /* data which "sinks" from the high-level user interface over tResourceRequest 252 to the low-level networking code */ 253 254 struct tConnection; 255 256 typedef struct tResource 257 { struct tResource *next, *prev; /* for the RAM cache; EXAC(resource) */ 258 struct tConnection *cconn, *dconn; /* control/data; EXAC(resource) */ 259 tCantent* cantent; 260 tUriData* uri_data; 261 tDhmGenericData* dhm_data; 262 const tConfigProxy* proxy; 263 struct tHostPortProtInfo *actual_hppi, *textual_hppi; /* EXAC(resource) */ 264 /* (might differ, e.g. when proxies are used; textual_hppi always holds 265 stuff which originates from the URI) */ 266 tSinkingData* sinking_data; 267 tSaveAs* save_as; /* for saving to disk; EXAC(resource) */ 268 #if USE_RPSD 269 struct tRpsdGeneric* rpsd; /* EXAC(resource) */ 270 #endif 271 #if CONFIG_CUSTOM_CONN 272 void* custconn_handle; /* tConsoleTaskNum or tWindow* */ 273 #endif 274 size_t nominal_contentlength; 275 size_t bytecount; /* roughly "number of bytes in document" */ 276 tResourceFlags flags; 277 tServerStatusCode server_status_code; /* (FTP terminology: reply code) */ 278 tTlHeaderState tlheaderstate; /* EXAC(resource) */ 279 tResourceProtocol protocol; 280 tResourceState state; 281 tResourceCommandHandshake handshake; 282 tResourceError error; 283 #if OPTION_TLS 284 tTlsError tls_error; /* used if ->error == reTls */ 285 #endif 286 } tResource; 287 288 289 /* Resource requests */ 290 291 my_enum1 enum 292 { rraLoad = 0, rraReload = 1, rraEnforcedReload = 2 293 #if CONFIG_CUSTOM_CONN 294 , rraCustomConn = 3 295 #endif 296 } my_enum2(unsigned char) tResourceRequestAction; 297 298 #define is_loadrra(rra) \ 299 ( ((rra) == rraLoad) || ((rra) == rraReload) || ((rra) == rraEnforcedReload)) 300 301 my_enum1 enum 302 { rrsUnknown = 0, rrsError = 1, rrsPreparedByMain = 2, rrsAttachedResource = 3, 303 rrsStopped = 4 304 #if CONFIG_ASYNC_DNS 305 , rrsDnsLookup = 5 306 #endif 307 } my_enum2(unsigned char) tResourceRequestState; 308 #define MAX_RESOURCE_REQUEST_STATE (5) 309 extern /*@observer@*/ const char* const 310 strResourceRequestState[MAX_RESOURCE_REQUEST_STATE + 1]; 311 312 my_enum1 enum 313 { rrfNone = 0, rrfResourceChanged = 0x01, rrfPost = 0x02, 314 rrfIsRedirection = 0x04, rrfIsEmbedded = 0x08 315 #if CONFIG_EXTRA & EXTRA_DOWNLOAD 316 , rrfDownload = 0x10 317 #endif 318 } my_enum2(unsigned char) tResourceRequestFlags; 319 320 struct tCachedHostInformation; 321 322 typedef struct 323 { tUriData* uri_data; 324 tDhmGenericData* dhm_data; /* (non-refcounted) */ 325 const tConfigProxy* proxy; /* EXAC(resource) */ 326 tResource* resource; /* the result of the request */ 327 struct tCachedHostInformation* lookup; /* EXAC(resource) */ 328 tSinkingData* sinking_data; 329 tResourceRequestFlags flags; 330 tResourceRequestAction action; 331 tResourceRequestState state; 332 tResourceError error; 333 } tResourceRequest; 334 335 336 /* User queries */ 337 338 #if CONFIG_USER_QUERY 339 340 my_enum1 enum 341 { mifNone = 0, mifQueryFailed = 0x01, mifUserCancelled = 0x02, 342 mifObjectVanished = 0x04, mifProxyrelated = 0x08, 343 mifPriorLoginAttemptFailed = 0x10, mifUsername = 0x20, mifPassword = 0x40, 344 mifAccount = 0x80, mifSharedSecret = 0x100 345 #if CONFIG_FTP && OPTION_TLS 346 , mifFtpsDataclear = 0x200 347 #endif 348 } my_enum2(unsigned short) tMissingInformationFlags; 349 #define mifSet (mifUsername | mifPassword | mifAccount | mifSharedSecret) 350 351 struct tUserQuery; 352 typedef void (*tUserQueryCallback)(struct tUserQuery*); 353 typedef struct tUserQuery 354 { tUserQueryCallback callback; /* a function in resource.c */ 355 tResource* resource; 356 struct tHostPortProtInfo* hppi; /* EXAC(resource) */ 357 const char* hostname; /* (just a pointer copy, no strdup()ing necessary) */ 358 tPortnumber portnumber; /* (in network byte order) */ 359 tMissingInformationFlags mif; 360 } tUserQuery; 361 362 extern void user_query_queue(tUserQuery*); /* see main.c */ 363 364 #else 365 366 typedef struct { unsigned char dummy; } tUserQuery; 367 368 #endif 369 370 371 /* Execution of shell commands */ 372 373 #if OPTION_EXECEXT & EXECEXT_SHELL 374 375 my_enum1 enum 376 { esfNone = 0, esfReadStdout = 0x01, esfReadStderr = 0x02, 377 esfEnforceHtml = 0x04 378 } my_enum2(unsigned char) tExecextShellFlags; 379 380 typedef struct 381 { tResourceRequest* request; 382 const char *command, *writedata; 383 size_t writedata_size; 384 tExecextShellFlags esf; 385 } tExecextShellData; 386 387 extern void resource_start_execext_shell(tExecextShellData*); 388 389 #endif 390 391 392 /* Custom connections */ 393 394 #if CONFIG_CUSTOM_CONN 395 396 my_enum1 enum 397 { ccpkNormal = 0, ccpkError = 1, ccpkNetcmd = 2, ccpkNetresp = 3 398 } my_enum2(unsigned char) tCustomConnPrintingKind; 399 400 typedef struct 401 { const char* text; 402 size_t len; /* (only needed for ccpkNetresp) */ 403 tCustomConnPrintingKind ccpk; 404 } tCustomConnPrintingData; 405 406 extern void resource_custom_conn_start(tResource*, unsigned char, const void*); 407 408 extern void main_handle_custom_conn(tResource*, unsigned char, void*); 409 /* see main.c */ 410 411 #endif 412 413 414 /* Functions */ 415 416 extern tPortnumber rp2portnumber(tResourceProtocol); 417 extern void rp2scheme(tResourceProtocol, /*@out@*/ char*); 418 extern void resource_preplex(void); 419 extern void resource_postplex(void); 420 extern void resource_request_start(tResourceRequest*); 421 extern void resource_request_stop(tResourceRequest*); 422 extern void resource_start_saving(tResource*, const tCantent*, int); 423 extern void uri_put(tUriData*); 424 #define uri_attach(dest, u) do { (u)->refcount++; (dest) = (u); } while (0) 425 #define uri_detach(u) do { uri_put(u); (u) = NULL; } while (0) 426 extern tCantent* cantent_create(void); 427 extern void cantent_put(tCantent*); 428 #define cantent_attach(dest, c) do { (c)->refcount++; (dest) = (c); } while (0) 429 #define cantent_detach(c) do { cantent_put(c); (c) = NULL; } while (0) 430 extern void cantent_collect_str(tCantent*, const char*); 431 extern void cantent_collect_title(tCantent*, const char*); 432 extern void sinking_data_cleanup(tSinkingData*); 433 extern void sinking_data_deallocate(tSinkingData**); 434 435 extern const char* htmlify(const char*); 436 #define htmlify_cleanup(orig, htmlified) \ 437 do { if (htmlified != orig) memory_deallocate(htmlified); } while (0) 438 439 #if CONFIG_BLOAT & BLOAT_SSC 440 extern /*@observer@*/ const char* ssc2info(tResourceProtocol, 441 tServerStatusCode); 442 #else 443 #define ssc2info(rp, ssc) (strEmpty) 444 #endif 445 446 #define USE_S2U ((CONFIG_BLOAT & BLOAT_UIIP) || (CONFIG_DEBUG)) 447 #if USE_S2U 448 extern tBoolean resource_ui_conn_ip(const tResource*, /*@out@*/ char*, size_t); 449 #else 450 #define resource_ui_conn_ip(res, buf, size) (falsE) 451 #endif 452 453 #if OPTION_TLS 454 extern tBoolean resource_in_tls(const tResource*, tBoolean); 455 #endif 456 457 extern void resource_initialize(void); 458 extern void resource_quit(void); 459 460 #endif /* #ifndef __retawq_resource_h__ */ 461