Annotation of libwww/Library/src/HTAccess.c, revision 1.121
1.120 eric 1: /* htaccess.c
1.61 frystyk 2: ** ACCESS MANAGER
3: **
1.75 frystyk 4: ** (c) COPYRIGHT MIT 1995.
1.61 frystyk 5: ** Please first read the full copyright statement in the file COPYRIGH.
1.121 ! frystyk 6: ** @(#) $Id: HTAccess.c,v 1.120 1996/05/15 22:33:58 eric Exp $
1.1 timbl 7: **
8: ** Authors
1.79 frystyk 9: ** TBL Tim Berners-Lee timbl@w3.org
1.4 timbl 10: ** JFG Jean-Francois Groff jfg@dxcern.cern.ch
1.1 timbl 11: ** DD Denis DeLaRoca (310) 825-4580 <CSP1DWD@mvs.oac.ucla.edu>
12: ** History
13: ** 8 Jun 92 Telnet hopping prohibited as telnet is not secure TBL
14: ** 26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. JFG
1.42 frystyk 15: ** 6 Oct 92 Moved HTClientHost and HTlogfile into here. TBL
1.1 timbl 16: ** 17 Dec 92 Tn3270 added, bug fix. DD
1.2 timbl 17: ** 4 Feb 93 Access registration, Search escapes bad chars TBL
1.9 timbl 18: ** PARAMETERS TO HTSEARCH AND HTLOADRELATIVE CHANGED
19: ** 28 May 93 WAIS gateway explicit if no WAIS library linked in.
1.19 timbl 20: ** Dec 93 Bug change around, more reentrant, etc
1.42 frystyk 21: ** 09 May 94 logfile renamed to HTlogfile to avoid clash with WAIS
1.114 frystyk 22: ** 8 Jul 94 Insulate HT_FREE();
1.88 frystyk 23: ** Sep 95 Rewritten, HFN
1.1 timbl 24: */
25:
1.68 frystyk 26: #if !defined(HT_DIRECT_WAIS) && !defined(HT_DEFAULT_WAIS_GATEWAY)
27: #define HT_DEFAULT_WAIS_GATEWAY "http://www.w3.org:8001/"
1.54 frystyk 28: #endif
1.8 timbl 29:
1.67 frystyk 30: /* Library include files */
1.88 frystyk 31: #include "WWWLib.h"
1.93 frystyk 32: #include "HTReqMan.h"
33: #include "HTAccess.h" /* Implemented here */
1.88 frystyk 34:
1.117 frystyk 35: #ifndef W3C_VERSION
36: #define W3C_VERSION "unknown"
1.99 frystyk 37: #endif
38:
1.121 ! frystyk 39: #ifndef HT_DEFAULT_USER
! 40: #define HT_DEFAULT_USER "LIBWWW_GENERIC_USER"
! 41: #endif
! 42:
1.93 frystyk 43: PRIVATE char * HTAppName = NULL; /* Application name: please supply */
44: PRIVATE char * HTAppVersion = NULL; /* Application version: please supply */
1.2 timbl 45:
1.99 frystyk 46: PRIVATE char * HTLibName = "libwww";
1.117 frystyk 47: PRIVATE char * HTLibVersion = W3C_VERSION;
1.99 frystyk 48:
49: PRIVATE BOOL HTSecure = NO; /* Can we access local file system? */
50:
1.121 ! frystyk 51: PRIVATE HTUserProfile * UserProfile = NULL; /* Default user profile */
! 52:
1.111 frystyk 53: #define PUTBLOCK(b, l) (*target->isa->put_block)(target, b, l)
54:
55: struct _HTStream {
56: HTStreamClass * isa;
57: };
58:
1.59 frystyk 59: /* --------------------------------------------------------------------------*/
1.61 frystyk 60: /* Initialization and Termination of the Library */
61: /* --------------------------------------------------------------------------*/
62:
1.99 frystyk 63: /* Information about the Application
64: ** ---------------------------------
1.93 frystyk 65: */
1.117 frystyk 66: PUBLIC const char * HTLib_appName (void)
1.93 frystyk 67: {
1.99 frystyk 68: return HTAppName ? HTAppName : "UNKNOWN";
69: }
70:
1.117 frystyk 71: PUBLIC const char * HTLib_appVersion (void)
1.99 frystyk 72: {
73: return HTAppVersion ? HTAppVersion : "0.0";
1.93 frystyk 74: }
75:
1.99 frystyk 76: /* Information about libwww
77: ** ------------------------
78: */
1.117 frystyk 79: PUBLIC const char * HTLib_name (void)
1.99 frystyk 80: {
81: return HTLibName ? HTLibName : "UNKNOWN";
82: }
83:
1.117 frystyk 84: PUBLIC const char * HTLib_version (void)
1.99 frystyk 85: {
86: return HTLibVersion ? HTLibVersion : "0.0";
87: }
88:
1.121 ! frystyk 89: /* Default User Profile
! 90: ** --------------------
! 91: */
! 92: PUBLIC HTUserProfile * HTLib_userProfile (void)
! 93: {
! 94: return UserProfile;
! 95: }
! 96:
! 97: PUBLIC BOOL HTLib_setUserProfile (HTUserProfile * up)
! 98: {
! 99: if (up) {
! 100: UserProfile = up;
! 101: return YES;
! 102: }
! 103: return NO;
! 104: }
! 105:
1.99 frystyk 106: /* Access Local File System
107: ** ------------------------
108: ** In this mode we do not tough the local file system at all
1.93 frystyk 109: */
1.99 frystyk 110: PUBLIC BOOL HTLib_secure (void)
111: {
112: return HTSecure;
113: }
114:
115: PUBLIC void HTLib_setSecure (BOOL mode)
1.93 frystyk 116: {
1.99 frystyk 117: HTSecure = mode;
1.93 frystyk 118: }
119:
1.61 frystyk 120: /* HTLibInit
121: **
122: ** This function initiates the Library and it MUST be called when
123: ** starting up an application. See also HTLibTerminate()
124: */
1.117 frystyk 125: PUBLIC BOOL HTLibInit (const char * AppName, const char * AppVersion)
1.61 frystyk 126: {
1.91 frystyk 127: if (WWWTRACE)
1.115 eric 128: HTTrace("WWWLibInit.. INITIALIZING LIBRARY OF COMMON CODE\n");
1.63 frystyk 129:
1.93 frystyk 130: /* Set the application name and version */
131: if (AppName) {
132: char *ptr;
133: StrAllocCopy(HTAppName, AppName);
134: ptr = HTAppName;
135: while (*ptr) {
136: if (WHITE(*ptr)) *ptr = '_';
137: ptr++;
138: }
139: }
140: if (AppVersion) {
141: char *ptr;
142: StrAllocCopy(HTAppVersion, AppVersion);
143: ptr = HTAppVersion;
144: while (*ptr) {
145: if (WHITE(*ptr)) *ptr = '_';
146: ptr++;
147: }
148: }
149:
1.121 ! frystyk 150: /* Create a default user profile */
! 151: UserProfile = HTUserProfile_new(HT_DEFAULT_USER, NULL);
! 152:
! 153: /* Initialize bindings */
! 154: HTBind_init();
1.61 frystyk 155:
1.62 frystyk 156: #ifdef WWWLIB_SIG
1.61 frystyk 157: /* On Solaris (and others?) we get a BROKEN PIPE signal when connecting
1.67 frystyk 158: ** to a port where we should get `connection refused'. We ignore this
1.61 frystyk 159: ** using the following function call
160: */
161: HTSetSignal(); /* Set signals in library */
1.1 timbl 162: #endif
163:
1.105 frystyk 164:
1.108 frystyk 165: #ifdef _WINSOCKAPI_
1.67 frystyk 166: /*
167: ** Initialise WinSock DLL. This must also be shut down! PMH
168: */
169: {
170: WSADATA wsadata;
171: if (WSAStartup(DESIRED_WINSOCK_VERSION, &wsadata)) {
1.91 frystyk 172: if (WWWTRACE)
1.115 eric 173: HTTrace("WWWLibInit.. Can't initialize WinSoc\n");
1.67 frystyk 174: WSACleanup();
175: return NO;
176: }
177: if (wsadata.wVersion < MINIMUM_WINSOCK_VERSION) {
1.91 frystyk 178: if (WWWTRACE)
1.115 eric 179: HTTrace("WWWLibInit.. Bad version of WinSoc\n");
1.67 frystyk 180: WSACleanup();
181: return NO;
182: }
183: }
1.108 frystyk 184: #endif /* _WINSOCKAPI_ */
1.67 frystyk 185:
1.61 frystyk 186: return YES;
187: }
188:
189:
1.90 frystyk 190: /* HTLibTerminate
191: ** --------------
1.117 frystyk 192: ** This function HT_FREEs memory kept by the Library and should be called
1.63 frystyk 193: ** before exit of an application (if you are on a PC platform)
1.61 frystyk 194: */
1.101 frystyk 195: PUBLIC BOOL HTLibTerminate (void)
1.61 frystyk 196: {
1.116 frystyk 197: if (WWWTRACE) HTTrace("WWWLibTerm.. Cleaning up LIBRARY OF COMMON CODE\n");
198:
199: HT_FREE(HTAppName); /* Freed thanks to Wade Ogden <wade@ebt.com> */
200: HT_FREE(HTAppVersion);
201:
1.101 frystyk 202: HTAtom_deleteAll(); /* Remove the atoms */
203: HTDNS_deleteAll(); /* Remove the DNS host cache */
204: HTAnchor_deleteAll(NULL); /* Delete anchors and drop hyperdocs */
1.73 frystyk 205:
1.81 frystyk 206: HTProtocol_deleteAll(); /* Remove bindings between access and protocols */
1.73 frystyk 207: HTBind_deleteAll(); /* Remove bindings between suffixes, media types */
208:
1.121 ! frystyk 209: HTUserProfile_delete(UserProfile); /* Free our default User profile */
1.67 frystyk 210:
1.108 frystyk 211: #ifdef _WINSOCKAPI_
1.67 frystyk 212: WSACleanup();
1.105 frystyk 213: #endif
214:
1.61 frystyk 215: return YES;
216: }
217:
1.59 frystyk 218: /* --------------------------------------------------------------------------*/
1.104 frystyk 219: /* Load Access functions */
1.59 frystyk 220: /* --------------------------------------------------------------------------*/
1.33 luotonen 221:
1.90 frystyk 222: /* Request a document
223: ** -----------------
224: ** Private version that requests a document from the request manager
225: ** Returns YES if request accepted, else NO
1.88 frystyk 226: */
1.101 frystyk 227: PRIVATE BOOL HTLoadDocument (HTRequest * request, BOOL recursive)
1.88 frystyk 228: {
229: if (PROT_TRACE) {
1.90 frystyk 230: HTParentAnchor *anchor = HTRequest_anchor(request);
231: char * full_address = HTAnchor_address((HTAnchor *) anchor);
1.115 eric 232: HTTrace("HTAccess.... Accessing document %s\n", full_address);
1.114 frystyk 233: HT_FREE(full_address);
1.88 frystyk 234: }
1.96 frystyk 235: return HTLoad(request, recursive);
1.58 frystyk 236: }
1.1 timbl 237:
238:
1.90 frystyk 239: /* Request a document from absolute name
240: ** -------------------------------------
241: ** Request a document referencd by an absolute URL.
242: ** Returns YES if request accepted, else NO
243: */
1.117 frystyk 244: PUBLIC BOOL HTLoadAbsolute (const char * url, HTRequest* request)
1.90 frystyk 245: {
246: if (url && request) {
247: HTAnchor * anchor = HTAnchor_findAddress(url);
248: HTRequest_setAnchor(request, anchor);
249: return HTLoadDocument(request, NO);
250: }
251: return NO;
252: }
253:
254:
255: /* Request a document from absolute name to stream
256: ** -----------------------------------------------
257: ** Request a document referencd by an absolute URL and sending the data
258: ** down a stream. This is _excactly_ the same as HTLoadAbsolute as
259: ** the ourputstream is specified using the function
260: ** HTRequest_setOutputStream(). 'filter' is ignored!
261: ** Returns YES if request accepted, else NO
262: */
1.117 frystyk 263: PUBLIC BOOL HTLoadToStream (const char * url, BOOL filter, HTRequest *request)
1.90 frystyk 264: {
265: return HTLoadAbsolute(url, request);
266: }
267:
268:
269: /* Request a document from relative name
270: ** -------------------------------------
271: ** Request a document referenced by a relative URL. The relative URL is
272: ** made absolute by resolving it relative to the address of the 'base'
273: ** anchor.
274: ** Returns YES if request accepted, else NO
275: */
1.117 frystyk 276: PUBLIC BOOL HTLoadRelative (const char * relative,
1.90 frystyk 277: HTParentAnchor * base,
278: HTRequest * request)
279: {
280: BOOL status = NO;
281: if (relative && base && request) {
282: char * rel = NULL;
283: char * full_url = NULL;
284: char * base_url = HTAnchor_address((HTAnchor *) base);
285: StrAllocCopy(rel, relative);
286: full_url = HTParse(HTStrip(rel), base_url,
287: PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION);
288: status = HTLoadAbsolute(full_url, request);
1.114 frystyk 289: HT_FREE(rel);
290: HT_FREE(full_url);
291: HT_FREE(base_url);
1.90 frystyk 292: }
293: return status;
294: }
295:
296:
297: /* Request an anchor
298: ** -----------------
299: ** Request the document referenced by the anchor
300: ** Returns YES if request accepted, else NO
301: */
302: PUBLIC BOOL HTLoadAnchor (HTAnchor * anchor, HTRequest * request)
303: {
304: if (anchor && request) {
305: HTRequest_setAnchor(request, anchor);
306: return HTLoadDocument(request, NO);
307: }
308: return NO;
309: }
310:
311:
312: /* Request an anchor
313: ** -----------------
314: ** Same as HTLoadAnchor but any information in the Error Stack in the
315: ** request object is kept, so that any error messages in one
1.52 frystyk 316: ** This function is almost identical to HTLoadAnchor, but it doesn't
317: ** clear the error stack so that the information in there is kept.
1.90 frystyk 318: ** Returns YES if request accepted, else NO
319: */
320: PUBLIC BOOL HTLoadAnchorRecursive (HTAnchor * anchor, HTRequest * request)
321: {
322: if (anchor && request) {
323: HTRequest_setAnchor(request, anchor);
324: return HTLoadDocument(request, YES);
325: }
326: return NO;
327: }
328:
329:
330: /* Search an Anchor
331: ** ----------------
332: ** Performs a keyword search on word given by the user. Adds the keyword
333: ** to the end of the current address and attempts to open the new address.
334: ** The list of keywords must be a space-separated list and spaces will
335: ** be converted to '+' before the request is issued.
336: ** Search can also be performed by HTLoadAbsolute() etc.
337: ** Returns YES if request accepted, else NO
338: */
1.117 frystyk 339: PUBLIC BOOL HTSearch (const char * keywords,
1.90 frystyk 340: HTParentAnchor * base,
341: HTRequest * request)
342: {
1.99 frystyk 343: BOOL status = NO;
1.90 frystyk 344: if (keywords && base && request) {
345: char *base_url = HTAnchor_address((HTAnchor *) base);
346: if (*keywords) {
347: char *plus;
348: StrAllocCat(base_url, "?");
349: StrAllocCat(base_url, keywords);
350: plus = strchr(base_url, '?');
351: while (*plus) {
352: if (*plus == ' ') *plus = '+';
353: plus++;
354: }
1.2 timbl 355: }
1.99 frystyk 356: status = HTLoadAbsolute(base_url, request);
1.114 frystyk 357: HT_FREE(base_url);
1.90 frystyk 358: }
1.99 frystyk 359: return status;
1.2 timbl 360: }
361:
362:
1.90 frystyk 363: /* Search a document from absolute name
364: ** ------------------------------------
365: ** Request a document referencd by an absolute URL appended with the
366: ** keywords given. The URL can NOT contain any fragment identifier!
367: ** The list of keywords must be a space-separated list and spaces will
368: ** be converted to '+' before the request is issued.
369: ** Returns YES if request accepted, else NO
370: */
1.117 frystyk 371: PUBLIC BOOL HTSearchAbsolute (const char * keywords,
372: const char * url,
1.90 frystyk 373: HTRequest * request)
374: {
375: if (url && request) {
376: HTAnchor * anchor = HTAnchor_findAddress(url);
377: return HTSearch(keywords, HTAnchor_parent(anchor), request);
378: }
379: return NO;
1.57 howcome 380: }
381:
1.70 frystyk 382: /* --------------------------------------------------------------------------*/
1.104 frystyk 383: /* Post Access Functions */
1.70 frystyk 384: /* --------------------------------------------------------------------------*/
385:
1.90 frystyk 386: /* Copy an anchor
1.70 frystyk 387: ** --------------
1.90 frystyk 388: ** Fetch the URL (possibly local file URL) and send it using either PUT
389: ** or POST to the remote destination using HTTP. The caller can decide the
390: ** exact method used and which HTTP header fields to transmit by setting
391: ** the user fields in the request structure.
1.92 frystyk 392: ** If posting to NNTP then we can't dispatch at this level but must pass
393: ** the source anchor to the news module that then takes all the refs
394: ** to NNTP and puts into the "newsgroups" header
1.90 frystyk 395: ** Returns YES if request accepted, else NO
1.70 frystyk 396: */
1.109 frystyk 397: PUBLIC BOOL HTCopyAnchor (HTAnchor * src_anchor, HTRequest * main_dest)
1.80 frystyk 398: {
1.106 frystyk 399: HTRequest * src_req;
400: HTList * cur;
1.109 frystyk 401: if (!src_anchor || !main_dest) {
1.115 eric 402: if (WWWTRACE) HTTrace("Copy........ BAD ARGUMENT\n");
1.90 frystyk 403: return NO;
1.109 frystyk 404: }
1.70 frystyk 405:
1.112 frystyk 406: /* Set the source anchor */
407: main_dest->source_anchor = HTAnchor_parent(src_anchor);
408:
1.80 frystyk 409: /* Build the POST web if not already there */
1.109 frystyk 410: if (!main_dest->source) {
411: src_req = HTRequest_dupInternal(main_dest); /* Get a duplicate */
1.80 frystyk 412: HTAnchor_clearHeader((HTParentAnchor *) src_anchor);
1.109 frystyk 413: src_req->method = METHOD_GET;
1.85 frystyk 414: src_req->reload = HT_MEM_REFRESH;
1.104 frystyk 415: src_req->output_stream = NULL;
1.80 frystyk 416: src_req->output_format = WWW_SOURCE; /* We want source (for now) */
417:
418: /* Set up the main link in the source anchor */
419: {
1.106 frystyk 420: HTLink * main_link = HTAnchor_mainLink((HTAnchor *) src_anchor);
421: HTAnchor *main_anchor = HTLink_destination(main_link);
422: HTMethod method = HTLink_method(main_link);
1.85 frystyk 423: if (!main_link || method==METHOD_INVALID) {
1.91 frystyk 424: if (WWWTRACE)
1.115 eric 425: HTTrace("Copy Anchor. No destination found or unspecified method\n");
1.80 frystyk 426: HTRequest_delete(src_req);
1.90 frystyk 427: return NO;
1.80 frystyk 428: }
1.109 frystyk 429: main_dest->GenMask |= HT_G_DATE; /* Send date header */
430: main_dest->reload = HT_CACHE_REFRESH;
431: main_dest->method = method;
432: main_dest->input_format = WWW_SOURCE;
433: HTRequest_addDestination(src_req, main_dest);
434: if (HTLoadAnchor(main_anchor, main_dest) == NO)
435: return NO;
1.80 frystyk 436: }
1.78 frystyk 437:
1.80 frystyk 438: /* For all other links in the source anchor */
1.106 frystyk 439: if ((cur = HTAnchor_subLinks(src_anchor))) {
440: HTLink * pres;
1.109 frystyk 441: while ((pres = (HTLink *) HTList_nextObject(cur))) {
1.106 frystyk 442: HTAnchor *dest = HTLink_destination(pres);
443: HTMethod method = HTLink_method(pres);
1.80 frystyk 444: HTRequest *dest_req;
445: if (!dest || method==METHOD_INVALID) {
1.91 frystyk 446: if (WWWTRACE)
1.115 eric 447: HTTrace("Copy Anchor. Bad anchor setup %p\n",
1.80 frystyk 448: dest);
1.90 frystyk 449: return NO;
1.80 frystyk 450: }
1.109 frystyk 451: dest_req = HTRequest_dupInternal(main_dest);
1.107 frystyk 452: dest_req->GenMask |= HT_G_DATE; /* Send date header */
1.85 frystyk 453: dest_req->reload = HT_CACHE_REFRESH;
1.80 frystyk 454: dest_req->method = method;
1.104 frystyk 455: dest_req->output_stream = NULL;
456: dest_req->output_format = WWW_SOURCE;
1.109 frystyk 457: HTRequest_addDestination(src_req, dest_req);
1.104 frystyk 458:
1.90 frystyk 459: if (HTLoadAnchor(dest, dest_req) == NO)
460: return NO;
1.80 frystyk 461: }
462: }
463: } else { /* Use the existing Post Web and restart it */
1.109 frystyk 464: src_req = main_dest->source;
1.80 frystyk 465: if (src_req->mainDestination)
1.109 frystyk 466: if (HTLoadDocument(main_dest, NO) == NO)
1.90 frystyk 467: return NO;
1.80 frystyk 468: if (src_req->destinations) {
1.106 frystyk 469: HTRequest * pres;
470: cur = HTAnchor_subLinks(src_anchor);
1.80 frystyk 471: while ((pres = (HTRequest *) HTList_nextObject(cur)) != NULL) {
1.90 frystyk 472: if (HTLoadDocument(pres, NO) == NO)
473: return NO;
1.80 frystyk 474: }
475: }
1.78 frystyk 476: }
477:
1.80 frystyk 478: /* Now open the source */
479: return HTLoadAnchor(src_anchor, src_req);
1.70 frystyk 480: }
481:
482:
1.90 frystyk 483: /* Upload an Anchor
1.70 frystyk 484: ** ----------------
1.111 frystyk 485: ** This function can be used to send data along with a request to a remote
486: ** server. It can for example be used to POST form data to a remote HTTP
487: ** server - or it can be used to post a newsletter to a NNTP server. In
488: ** either case, you pass a callback function which the request calls when
489: ** the remote destination is ready to accept data. In this callback
490: ** you get the current request object and a stream into where you can
491: ** write data. It is very important that you return the value returned
492: ** by this stream to the Library so that it knows what to do next. The
493: ** reason is that the outgoing stream might block or an error may
494: ** occur and in that case the Library must know about it. The source
495: ** anchor represents the data object in memory and it points to
496: ** the destination anchor by using the POSTWeb method. The source anchor
497: ** contains metainformation about the data object in memory and the
498: ** destination anchor represents the reponse from the remote server.
1.90 frystyk 499: ** Returns YES if request accepted, else NO
500: */
1.111 frystyk 501: PUBLIC BOOL HTUploadAnchor (HTAnchor * source_anchor,
502: HTRequest * request,
503: HTPostCallback * callback)
504: {
505: HTLink * link = HTAnchor_mainLink((HTAnchor *) source_anchor);
506: HTAnchor * dest_anchor = HTLink_destination(link);
507: HTMethod method = HTLink_method(link);
508: if (!link || method==METHOD_INVALID || !callback) {
509: if (WWWTRACE)
1.115 eric 510: HTTrace("Upload...... No destination found or unspecified method\n");
1.90 frystyk 511: return NO;
1.109 frystyk 512: }
1.111 frystyk 513: request->GenMask |= HT_G_DATE; /* Send date header */
514: request->reload = HT_CACHE_REFRESH;
515: request->method = method;
516: request->source_anchor = HTAnchor_parent(source_anchor);
517: request->PostCallback = callback;
518: return HTLoadAnchor(dest_anchor, request);
519: }
520:
521: /* POST Callback Handler
522: ** ---------------------
523: ** If you do not want to handle the stream interface on your own, you
524: ** can use this function which writes the source anchor hyperdoc to the
525: ** target stream for the anchor upload and also handles the return value
526: ** from the stream. If you don't want to write the source anchor hyperdoc
527: ** then you can register your own callback function that can get the data
528: ** you want.
529: */
530: PUBLIC int HTUpload_callback (HTRequest * request, HTStream * target)
531: {
1.115 eric 532: if (WWWTRACE) HTTrace("Uploading... from callback function\n");
1.111 frystyk 533: if (!request || !request->source_anchor || !target) return HT_ERROR;
534: {
535: int status;
536: HTParentAnchor * source = request->source_anchor;
537: char * document = (char *) HTAnchor_document(request->source_anchor);
538: int len = HTAnchor_length(source);
539: if (len < 0) {
540: len = strlen(document);
541: HTAnchor_setLength(source, len);
542: }
543: status = (*target->isa->put_block)(target, document, len);
544: if (status == HT_OK)
545: return (*target->isa->flush)(target);
546: if (status == HT_WOULD_BLOCK) {
1.115 eric 547: if (PROT_TRACE)HTTrace("POST Anchor. Target WOULD BLOCK\n");
1.111 frystyk 548: return HT_WOULD_BLOCK;
549: } else if (status == HT_PAUSE) {
1.115 eric 550: if (PROT_TRACE) HTTrace("POST Anchor. Target PAUSED\n");
1.111 frystyk 551: return HT_PAUSE;
552: } else if (status > 0) { /* Stream specific return code */
553: if (PROT_TRACE)
1.115 eric 554: HTTrace("POST Anchor. Target returns %d\n", status);
1.111 frystyk 555: return status;
1.120 eric 556: } else { /* we have a real error */
1.115 eric 557: if (PROT_TRACE) HTTrace("POST Anchor. Target ERROR\n");
1.111 frystyk 558: return status;
559: }
1.70 frystyk 560: }
1.1 timbl 561: }
Webmaster