Annotation of libwww/Library/src/HTAccess.c, revision 1.88
1.61 frystyk 1: /* HTAccess.c
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.1 timbl 6: **
7: ** Authors
1.79 frystyk 8: ** TBL Tim Berners-Lee timbl@w3.org
1.4 timbl 9: ** JFG Jean-Francois Groff jfg@dxcern.cern.ch
1.1 timbl 10: ** DD Denis DeLaRoca (310) 825-4580 <CSP1DWD@mvs.oac.ucla.edu>
11: ** History
12: ** 8 Jun 92 Telnet hopping prohibited as telnet is not secure TBL
13: ** 26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. JFG
1.42 frystyk 14: ** 6 Oct 92 Moved HTClientHost and HTlogfile into here. TBL
1.1 timbl 15: ** 17 Dec 92 Tn3270 added, bug fix. DD
1.2 timbl 16: ** 4 Feb 93 Access registration, Search escapes bad chars TBL
1.9 timbl 17: ** PARAMETERS TO HTSEARCH AND HTLOADRELATIVE CHANGED
18: ** 28 May 93 WAIS gateway explicit if no WAIS library linked in.
1.19 timbl 19: ** Dec 93 Bug change around, more reentrant, etc
1.42 frystyk 20: ** 09 May 94 logfile renamed to HTlogfile to avoid clash with WAIS
1.53 duns 21: ** 8 Jul 94 Insulate free() from _free structure element.
1.88 ! frystyk 22: ** Sep 95 Rewritten, HFN
1.1 timbl 23: */
24:
1.68 frystyk 25: #if !defined(HT_DIRECT_WAIS) && !defined(HT_DEFAULT_WAIS_GATEWAY)
26: #define HT_DEFAULT_WAIS_GATEWAY "http://www.w3.org:8001/"
1.54 frystyk 27: #endif
1.8 timbl 28:
1.67 frystyk 29: /* Library include files */
1.88 ! frystyk 30: #include "WWWLib.h"
! 31: #include "HTReqMan.h" /* @@@@@@@@@@@@@@@@@@@@@@@@ */
! 32:
1.70 frystyk 33: #include "HTInit.h"
1.67 frystyk 34: #include "HTAccess.h" /* Implemented here */
1.2 timbl 35:
1.59 frystyk 36: /* --------------------------------------------------------------------------*/
1.61 frystyk 37: /* Initialization and Termination of the Library */
38: /* --------------------------------------------------------------------------*/
39:
40: /* HTLibInit
41: **
42: ** This function initiates the Library and it MUST be called when
43: ** starting up an application. See also HTLibTerminate()
44: */
45: PUBLIC BOOL HTLibInit NOARGS
46: {
1.67 frystyk 47: #ifdef NO_STDIO /* Open trace file */
48: if ((TDEST = fopen(TRACE_FILE, "a")) != NULL) {
49: if (setvbuf(TDEST, NULL, _IOLBF, 0) < 0) { /* Change to line buffer */
1.70 frystyk 50: printf("WWWLibInit.. Can't initialize TRACE buffer - no TRACE\n");
1.67 frystyk 51: fclose(TDEST);
52: TDEST = NULL;
53: WWW_TraceFlag = 0;
54: }
55: } else
56: WWW_TraceFlag = 0;
57: #endif
58:
1.61 frystyk 59: if (TRACE)
1.67 frystyk 60: fprintf(TDEST, "WWWLibInit.. INITIALIZING LIBRARY OF COMMON CODE\n");
1.63 frystyk 61:
1.77 frystyk 62: /* Set up User preferences, but leave initialization to the application */
1.73 frystyk 63: if (!HTConversions)
64: HTConversions = HTList_new();
1.77 frystyk 65: if (!HTEncodings)
66: HTEncodings = HTList_new();
67: if (!HTLanguages)
68: HTLanguages = HTList_new();
69: if (!HTCharsets)
70: HTCharsets = HTList_new();
71:
72: /* Set up bindings to the local file system */
73: HTBind_init();
1.73 frystyk 74:
1.70 frystyk 75: #ifndef HT_NO_INIT
76: HTAccessInit(); /* Bind access schemes and protocol modules */
77: HTFileInit(); /* Bind file extensions and media types */
1.63 frystyk 78: #endif
1.61 frystyk 79:
1.77 frystyk 80: #ifndef HT_DIRECT_WAIS
81: HTProxy_setGateway("wais", HT_DEFAULT_WAIS_GATEWAY);
82: #endif
83:
1.88 ! frystyk 84: /* Register a call back function for the Net Manager */
! 85: HTNet_register (HTLoad_terminate, HT_ALL);
! 86:
1.62 frystyk 87: #ifdef WWWLIB_SIG
1.61 frystyk 88: /* On Solaris (and others?) we get a BROKEN PIPE signal when connecting
1.67 frystyk 89: ** to a port where we should get `connection refused'. We ignore this
1.61 frystyk 90: ** using the following function call
91: */
92: HTSetSignal(); /* Set signals in library */
1.1 timbl 93: #endif
94:
1.67 frystyk 95: #ifdef _WINDOWS
96: /*
97: ** Initialise WinSock DLL. This must also be shut down! PMH
98: */
99: {
100: WSADATA wsadata;
101: if (WSAStartup(DESIRED_WINSOCK_VERSION, &wsadata)) {
102: if (TRACE)
103: fprintf(TDEST, "WWWLibInit.. Can't initialize WinSoc\n");
104: WSACleanup();
105: return NO;
106: }
107: if (wsadata.wVersion < MINIMUM_WINSOCK_VERSION) {
108: if (TRACE)
109: fprintf(TDEST, "WWWLibInit.. Bad version of WinSoc\n");
110: WSACleanup();
111: return NO;
112: }
113: }
114: #endif /* _WINDOWS */
115:
1.71 frystyk 116: #ifndef NO_TIMEGM
117: HTGetTimeZoneOffset(); /* Find offset from GMT if using mktime() */
118: #endif
1.70 frystyk 119: HTTmp_setRoot(NULL); /* Set up default tmp directory */
1.61 frystyk 120: return YES;
121: }
122:
123:
124: /* HTLibTerminate
125: **
126: ** This function frees memory kept by the Library and should be called
1.63 frystyk 127: ** before exit of an application (if you are on a PC platform)
1.61 frystyk 128: */
129: PUBLIC BOOL HTLibTerminate NOARGS
130: {
131: if (TRACE)
1.67 frystyk 132: fprintf(TDEST, "WWWLibTerm.. Cleaning up LIBRARY OF COMMON CODE\n");
1.88 ! frystyk 133: #if 0
! 134: HTNet_deleteAll(); /* Remove all remaining requests */
! 135: #endif
1.63 frystyk 136: HTAtom_deleteAll();
137: HTDisposeConversions();
138: HTTCPCacheRemoveAll();
1.73 frystyk 139:
140: #ifndef HT_NO_INIT
1.81 frystyk 141: HTProtocol_deleteAll(); /* Remove bindings between access and protocols */
1.73 frystyk 142: HTBind_deleteAll(); /* Remove bindings between suffixes, media types */
143: #endif
144:
1.77 frystyk 145: HTProxy_deleteProxy(); /* Clean up lists of proxies and gateways */
146: HTProxy_deleteNoProxy();
147: HTProxy_deleteGateway();
148:
149: HTFreeHostName(); /* Free up some internal strings */
1.63 frystyk 150: HTFreeMailAddress();
1.70 frystyk 151: HTCache_freeRoot();
1.84 frystyk 152: HTCache_clearMem(); /* Keep the disk versions! */
1.70 frystyk 153: HTTmp_freeRoot();
1.67 frystyk 154:
155: #ifdef _WINDOWS
156: WSACleanup();
157: #endif
158:
159: #ifdef NO_STDIO /* Close trace file */
160: if (TDEST) {
161: fclose(TDEST);
162: TDEST = NULL;
163: WWW_TraceFlag = 0;
164: }
165: #endif
1.61 frystyk 166: return YES;
167: }
168:
1.59 frystyk 169: /* --------------------------------------------------------------------------*/
1.88 ! frystyk 170: /* Access functions */
1.59 frystyk 171: /* --------------------------------------------------------------------------*/
1.33 luotonen 172:
1.88 ! frystyk 173: /* Load a document
! 174: ** ---------------
1.2 timbl 175: **
176: ** - Checks or documents already loaded
177: ** - Logs the access
178: ** - Trace ouput and error messages
179: **
1.1 timbl 180: ** On Entry,
1.19 timbl 181: ** request->anchor valid for of the document to be accessed.
182: ** request->childAnchor optional anchor within doc to be selected
183: **
1.15 timbl 184: ** request->anchor is the node_anchor for the document
185: ** request->output_format is valid
186: **
1.88 ! frystyk 187: ** returns
! 188: ** YES if request has been registered (success)
! 189: ** NO an error occured
! 190: */
! 191: PRIVATE int HTLoadDocument ARGS2(HTRequest *, request, BOOL, recursive)
! 192: {
! 193: if (PROT_TRACE) {
! 194: char * full_address = HTAnchor_address((HTAnchor *) request->anchor);
! 195: fprintf (TDEST, "HTAccess.... Accessing document %s\n", full_address);
! 196: free(full_address);
! 197: }
! 198: if (!request->output_format)
! 199: request->output_format = WWW_PRESENT;
! 200: return HTLoad(request, recursive, 0); /* @@@@ PRIORITY @@@@ */
1.58 frystyk 201: }
1.1 timbl 202:
203:
204: /* Load a document from absolute name
205: ** ---------------
206: **
1.59 frystyk 207: ** On Entry,
1.1 timbl 208: ** addr The absolute address of the document to be accessed.
209: **
1.59 frystyk 210: ** On exit,
211: ** returns HT_WOULD_BLOCK An I/O operation would block
212: ** HT_ERROR Error has occured
213: ** HT_LOADED Success
214: ** HT_NO_DATA Success, but no document loaded.
215: ** (telnet sesssion started etc)
1.72 frystyk 216: ** HT_RETRY if service isn't available before
217: ** request->retry_after
1.1 timbl 218: */
1.59 frystyk 219: PUBLIC int HTLoadAbsolute ARGS2(CONST char *,addr, HTRequest*, request)
1.2 timbl 220: {
1.19 timbl 221: HTAnchor * anchor = HTAnchor_findAddress(addr);
222: request->anchor = HTAnchor_parent(anchor);
223: request->childAnchor = ((HTAnchor*)request->anchor == anchor) ?
224: NULL : (HTChildAnchor*) anchor;
1.52 frystyk 225: return HTLoadDocument(request, NO);
1.2 timbl 226: }
227:
228:
229: /* Load a document from absolute name to stream
230: ** --------------------------------------------
231: **
1.59 frystyk 232: ** On Entry,
1.2 timbl 233: ** addr The absolute address of the document to be accessed.
1.15 timbl 234: ** request->output_stream if non-NULL, send data down this stream
1.2 timbl 235: **
1.59 frystyk 236: ** On exit,
237: ** returns HT_WOULD_BLOCK An I/O operation would block
238: ** HT_ERROR Error has occured
239: ** HT_LOADED Success
240: ** HT_NO_DATA Success, but no document loaded.
241: ** (telnet sesssion started etc)
1.72 frystyk 242: ** HT_RETRY if service isn't available before
243: ** request->retry_after
1.2 timbl 244: */
1.59 frystyk 245: PUBLIC int HTLoadToStream ARGS3(CONST char *, addr,
246: BOOL, filter,
247: HTRequest*, request)
1.1 timbl 248: {
1.63 frystyk 249: HTAnchor * anchor = HTAnchor_findAddress(addr);
250: request->anchor = HTAnchor_parent(anchor);
251: request->childAnchor = ((HTAnchor*)request->anchor == anchor) ? NULL :
1.19 timbl 252: (HTChildAnchor*) anchor;
1.15 timbl 253: request->output_stream = request->output_stream;
1.52 frystyk 254: return HTLoadDocument(request, NO);
1.1 timbl 255: }
256:
257:
258: /* Load a document from relative name
259: ** ---------------
260: **
1.59 frystyk 261: ** On Entry,
1.2 timbl 262: ** relative_name The relative address of the document
263: ** to be accessed.
1.1 timbl 264: **
1.59 frystyk 265: ** On exit,
266: ** returns HT_WOULD_BLOCK An I/O operation would block
267: ** HT_ERROR Error has occured
268: ** HT_LOADED Success
269: ** HT_NO_DATA Success, but no document loaded.
270: ** (telnet sesssion started etc)
1.72 frystyk 271: ** HT_RETRY if service isn't available before
272: ** request->retry_after
1.1 timbl 273: */
1.59 frystyk 274: PUBLIC int HTLoadRelative ARGS3(CONST char *, relative_name,
275: HTParentAnchor *, here,
276: HTRequest *, request)
1.1 timbl 277: {
278: char * full_address = 0;
1.65 frystyk 279: int result;
1.1 timbl 280: char * mycopy = 0;
281: char * stripped = 0;
282: char * current_address =
1.2 timbl 283: HTAnchor_address((HTAnchor*)here);
1.1 timbl 284:
285: StrAllocCopy(mycopy, relative_name);
286:
287: stripped = HTStrip(mycopy);
288: full_address = HTParse(stripped,
289: current_address,
290: PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION);
1.15 timbl 291: result = HTLoadAbsolute(full_address, request);
1.1 timbl 292: free(full_address);
293: free(current_address);
294: free(mycopy); /* Memory leak fixed 10/7/92 -- JFG */
295: return result;
296: }
297:
298:
299: /* Load if necessary, and select an anchor
300: ** --------------------------------------
301: **
1.59 frystyk 302: ** On Entry,
1.1 timbl 303: ** destination The child or parenet anchor to be loaded.
304: **
1.59 frystyk 305: ** On exit,
306: ** returns HT_WOULD_BLOCK An I/O operation would block
307: ** HT_ERROR Error has occured
308: ** HT_LOADED Success
309: ** HT_NO_DATA Success, but no document loaded.
310: ** (telnet sesssion started etc)
1.72 frystyk 311: ** HT_RETRY if service isn't available before
312: ** request->retry_after
1.1 timbl 313: */
1.59 frystyk 314: PUBLIC int HTLoadAnchor ARGS2(HTAnchor*, anchor, HTRequest *, request)
1.1 timbl 315: {
1.70 frystyk 316: if (!anchor || !request)
317: return HT_ERROR;
318: request->anchor = HTAnchor_parent(anchor);
1.59 frystyk 319: request->childAnchor = ((HTAnchor *) request->anchor == anchor) ?
320: NULL : (HTChildAnchor*) anchor;
321: return HTLoadDocument(request, NO);
322: }
1.52 frystyk 323:
324:
325: /* Load if necessary, and select an anchor
326: ** --------------------------------------
327: **
328: ** This function is almost identical to HTLoadAnchor, but it doesn't
329: ** clear the error stack so that the information in there is kept.
330: **
1.59 frystyk 331: ** On Entry,
1.52 frystyk 332: ** destination The child or parenet anchor to be loaded.
333: **
1.59 frystyk 334: ** On exit,
335: ** returns HT_WOULD_BLOCK An I/O operation would block
336: ** HT_ERROR Error has occured
337: ** HT_LOADED Success
338: ** HT_NO_DATA Success, but no document loaded.
339: ** (telnet sesssion started etc)
1.72 frystyk 340: ** HT_RETRY if service isn't available before
341: ** request->retry_after
1.52 frystyk 342: */
1.59 frystyk 343: PUBLIC int HTLoadAnchorRecursive ARGS2(HTAnchor*, anchor,
344: HTRequest *, request)
1.52 frystyk 345: {
1.59 frystyk 346: if (!anchor) return HT_ERROR; /* No link */
1.52 frystyk 347:
348: request->anchor = HTAnchor_parent(anchor);
1.59 frystyk 349: request->childAnchor = ((HTAnchor *) request->anchor == anchor) ?
350: NULL : (HTChildAnchor*) anchor;
1.52 frystyk 351:
1.59 frystyk 352: return HTLoadDocument(request, YES);
353: }
1.1 timbl 354:
355:
356: /* Search
357: ** ------
358: ** Performs a keyword search on word given by the user. Adds the keyword to
359: ** the end of the current address and attempts to open the new address.
360: **
361: ** On Entry,
362: ** *keywords space-separated keyword list or similar search list
1.2 timbl 363: ** here is anchor search is to be done on.
1.59 frystyk 364: **
365: ** On exit,
366: ** returns HT_WOULD_BLOCK An I/O operation would block
367: ** HT_ERROR Error has occured
368: ** HT_LOADED Success
369: ** HT_NO_DATA Success, but no document loaded.
370: ** (telnet sesssion started etc)
1.72 frystyk 371: ** HT_RETRY if service isn't available before
372: ** request->retry_after
1.1 timbl 373: */
1.56 frystyk 374: PRIVATE char hex ARGS1(int, i)
1.2 timbl 375: {
1.13 timbl 376: char * hexchars = "0123456789ABCDEF";
377: return hexchars[i];
1.2 timbl 378: }
1.1 timbl 379:
1.59 frystyk 380: PUBLIC int HTSearch ARGS3(CONST char *, keywords,
381: HTParentAnchor *, here,
382: HTRequest *, request)
1.1 timbl 383: {
1.2 timbl 384:
385: #define acceptable \
386: "1234567890abcdefghijlkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_"
387:
388: char *q, *u;
389: CONST char * p, *s, *e; /* Pointers into keywords */
390: char * address = HTAnchor_address((HTAnchor*)here);
1.65 frystyk 391: int result;
1.56 frystyk 392: char * escaped = (char *) malloc(strlen(keywords)*3+1);
1.2 timbl 393:
1.29 frystyk 394: /* static CONST BOOL isAcceptable[96] = */
395: /* static AND const is not good for a gnu compiler! Frystyk 25/02-94 */
1.30 luotonen 396: static BOOL isAcceptable[96] =
1.2 timbl 397: /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
398: { 0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0, /* 2x !"#$%&'()*+,-./ */
399: 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */
400: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4x @ABCDEFGHIJKLMNO */
401: 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, /* 5X PQRSTUVWXYZ[\]^_ */
402: 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6x `abcdefghijklmno */
403: 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0 }; /* 7X pqrstuvwxyz{\}~ DEL */
404:
405: if (escaped == NULL) outofmem(__FILE__, "HTSearch");
406:
1.29 frystyk 407: /* Convert spaces to + and hex escape unacceptable characters */
1.2 timbl 408:
1.29 frystyk 409: for(s=keywords; *s && WHITE(*s); s++); /*scan */ /* Skip white space */
410: for(e = s + strlen(s); e>s && WHITE(*(e-1)) ; e--); /* Skip trailers */
411: for(q=escaped, p=s; p<e; p++) { /* scan stripped field */
1.2 timbl 412: int c = (int)TOASCII(*p);
413: if (WHITE(*p)) {
414: *q++ = '+';
1.29 frystyk 415: } else if (c>=32 && c<=127 && isAcceptable[c-32] != 0) {
1.13 timbl 416: *q++ = *p; /* 930706 TBL for MVS bug */
1.2 timbl 417: } else {
418: *q++ = '%';
419: *q++ = hex(c / 16);
420: *q++ = hex(c % 16);
421: }
422: } /* Loop over string */
1.1 timbl 423:
1.2 timbl 424: *q=0;
425: /* terminate escaped sctring */
426: u=strchr(address, '?'); /* Find old search string */
427: if (u) *u = 0; /* Chop old search off */
1.1 timbl 428:
429: StrAllocCat(address, "?");
1.2 timbl 430: StrAllocCat(address, escaped);
431: free(escaped);
1.15 timbl 432: result = HTLoadRelative(address, here, request);
1.1 timbl 433: free(address);
1.2 timbl 434:
1.1 timbl 435: return result;
1.2 timbl 436: }
437:
438:
439: /* Search Given Indexname
440: ** ------
441: ** Performs a keyword search on word given by the user. Adds the keyword to
442: ** the end of the current address and attempts to open the new address.
443: **
1.59 frystyk 444: ** On Entry,
1.2 timbl 445: ** *keywords space-separated keyword list or similar search list
446: ** *addres is name of object search is to be done on.
1.59 frystyk 447: ** On exit,
448: ** returns HT_WOULD_BLOCK An I/O operation would block
449: ** HT_ERROR Error has occured
450: ** HT_LOADED Success
451: ** HT_NO_DATA Success, but no document loaded.
452: ** (telnet sesssion started etc)
1.72 frystyk 453: ** HT_RETRY if service isn't available before
454: ** request->retry_after
1.2 timbl 455: */
1.59 frystyk 456: PUBLIC int HTSearchAbsolute ARGS3(CONST char *, keywords,
457: CONST char *, indexname,
458: HTRequest *, request)
1.2 timbl 459: {
460: HTParentAnchor * anchor =
461: (HTParentAnchor*) HTAnchor_findAddress(indexname);
1.15 timbl 462: return HTSearch(keywords, anchor, request);
1.57 howcome 463: }
464:
1.70 frystyk 465: /* --------------------------------------------------------------------------*/
466: /* Document Poster */
467: /* --------------------------------------------------------------------------*/
468:
1.88 ! frystyk 469: #if 0
1.70 frystyk 470: /* Get a save stream for a document
471: ** --------------------------------
472: */
473: PUBLIC HTStream *HTSaveStream ARGS1(HTRequest *, request)
474: {
475: HTProtocol * p;
476: int status;
477: request->method = METHOD_PUT;
478: status = get_physical(request);
479: if (status == HT_FORBIDDEN) {
480: char *url = HTAnchor_address((HTAnchor *) request->anchor);
481: if (url) {
482: HTUnEscape(url);
483: HTErrorAdd(request, ERR_FATAL, NO, HTERR_FORBIDDEN,
1.88 ! frystyk 484: (void *) url, (int) strlen(url), "HTSaveStream");
1.70 frystyk 485: free(url);
486: } else {
487: HTErrorAdd(request, ERR_FATAL, NO, HTERR_FORBIDDEN,
1.88 ! frystyk 488: NULL, 0, "HTSaveStream");
1.70 frystyk 489: }
490: return NULL; /* should return error status? */
491: }
492: if (status < 0) return NULL; /* @@ error. Can't resolve or forbidden */
493:
494: p = (HTProtocol *) HTAnchor_protocol(request->anchor);
495: if (!p) return NULL;
496:
497: return (*p->saveStream)(request);
498:
499: }
1.88 ! frystyk 500: #endif
1.70 frystyk 501:
502: /* COPY AN ANCHOR
503: ** --------------
504: ** Fetch the URL (possibly local file URL) and send it using either PUT
505: ** or POST to the remote destination using HTTP. The caller can decide the
506: ** exact method used and which HTTP header fields to transmit by setting the
507: ** user fields in the request structure.
508: **
1.80 frystyk 509: ** BUGS: Should take ALL links in the destination anchor and PUT/POST to
510: ** all of them!
511: **
1.70 frystyk 512: ** returns HT_WOULD_BLOCK An I/O operation would block
513: ** HT_ERROR Error has occured
514: ** HT_LOADED Success
515: ** HT_NO_DATA Success, but no document loaded.
1.72 frystyk 516: ** HT_RETRY if service isn't available before
517: ** request->retry_after
1.70 frystyk 518: */
1.80 frystyk 519: PUBLIC int HTCopyAnchor ARGS2(HTAnchor *, src_anchor,
1.85 frystyk 520: HTRequest *, main_req)
1.80 frystyk 521: {
1.78 frystyk 522: HTRequest *src_req;
1.85 frystyk 523: if (!src_anchor || !main_req)
1.70 frystyk 524: return HT_ERROR;
525:
1.80 frystyk 526: /* Build the POST web if not already there */
1.85 frystyk 527: if (!main_req->source) {
1.80 frystyk 528: src_req = HTRequest_new(); /* First set up the source */
529: HTAnchor_clearHeader((HTParentAnchor *) src_anchor);
1.85 frystyk 530: src_req->reload = HT_MEM_REFRESH;
1.80 frystyk 531: src_req->source = src_req; /* Point to myself */
532: src_req->output_format = WWW_SOURCE; /* We want source (for now) */
533:
534: /* Set up the main link in the source anchor */
535: {
1.85 frystyk 536: HTLink *main_link = HTAnchor_findMainLink(src_anchor);
537: HTAnchor *main_anchor = HTAnchor_linkDest(main_link);
538: HTMethod method = HTAnchor_linkMethod(main_link);
539: if (!main_link || method==METHOD_INVALID) {
1.80 frystyk 540: if (TRACE)
541: fprintf(TDEST, "Copy Anchor. No destination found or unspecified method");
542: HTRequest_delete(src_req);
543: return HT_ERROR;
544: }
1.85 frystyk 545: if (HTAnchor_linkResult(main_link) == HT_LINK_NONE) {
546: main_req->GenMask |= HT_DATE; /* Send date header */
547: main_req->source = src_req;
548: main_req->reload = HT_CACHE_REFRESH;
549: main_req->method = method;
550: HTRequest_addDestination(src_req, main_req);
551: main_req->input_format = WWW_SOURCE; /* for now :-( @@@ */
552: if (HTLoadAnchor(main_anchor, main_req) == HT_ERROR)
553: return HT_ERROR;
554: }
1.80 frystyk 555: }
1.78 frystyk 556:
1.80 frystyk 557: /* For all other links in the source anchor */
558: if (src_anchor->links) {
559: HTList *cur = src_anchor->links;
560: HTLink *pres;
1.85 frystyk 561: while ((pres = (HTLink *) HTList_nextObject(cur)) &&
562: HTAnchor_linkResult(pres) == HT_LINK_NONE) {
563: HTAnchor *dest = HTAnchor_linkDest(pres);
564: HTMethod method = HTAnchor_linkMethod(pres);
1.80 frystyk 565: HTRequest *dest_req;
566: if (!dest || method==METHOD_INVALID) {
567: if (TRACE)
568: fprintf(TDEST, "Copy Anchor. Bad anchor setup %p\n",
569: dest);
570: return HT_ERROR;
571: }
572: dest_req = HTRequest_new();
1.85 frystyk 573: dest_req->GenMask |= HT_DATE; /* Send date header */
1.80 frystyk 574: dest_req->source = src_req;
1.85 frystyk 575: dest_req->reload = HT_CACHE_REFRESH;
1.80 frystyk 576: dest_req->method = method;
577: HTRequest_addDestination(src_req, dest_req);
578: dest_req->input_format = WWW_SOURCE; /* for now :-( @@@ */
579: if (HTLoadAnchor(dest, dest_req) == HT_ERROR)
580: return HT_ERROR;
581: }
582: }
583: } else { /* Use the existing Post Web and restart it */
1.85 frystyk 584: src_req = main_req->source;
1.80 frystyk 585: if (src_req->mainDestination)
1.85 frystyk 586: if (HTLoadDocument(main_req, NO) == HT_ERROR)
1.80 frystyk 587: return HT_ERROR;
588: if (src_req->destinations) {
589: HTList *cur = src_anchor->links;
590: HTRequest *pres;
591: while ((pres = (HTRequest *) HTList_nextObject(cur)) != NULL) {
592: if (HTLoadDocument(pres, NO) == HT_ERROR)
593: return HT_ERROR;
594: }
595: }
1.78 frystyk 596: }
597:
1.80 frystyk 598: /* Now open the source */
599: return HTLoadAnchor(src_anchor, src_req);
1.70 frystyk 600: }
601:
602:
603: /* UPLOAD AN ANCHOR
604: ** ----------------
605: ** Send the contents (in hyperdoc) of the source anchor using either PUT
606: ** or POST to the remote destination using HTTP. The caller can decide the
607: ** exact method used and which HTTP header fields to transmit by setting the
608: ** user fields in the request structure.
609: **
610: ** returns HT_WOULD_BLOCK An I/O operation would block
611: ** HT_ERROR Error has occured
612: ** HT_LOADED Success
613: ** HT_NO_DATA Success, but no document loaded.
1.72 frystyk 614: ** HT_RETRY if service isn't available before
615: ** request->retry_after
1.70 frystyk 616: */
617: PUBLIC int HTUploadAnchor ARGS3(HTAnchor *, src_anchor,
618: HTParentAnchor *, dest_anchor,
619: HTRequest *, dest_req)
620: {
621: if (!(src_anchor && dest_anchor && dest_req))
622: return HT_ERROR;
623:
624: if (!(dest_anchor->methods & dest_req->method)) {
625: char buf[80];
626: sprintf(buf, "It might not be allowed to %s to this destination, continue?", HTMethod_name(dest_req->method));
1.86 frystyk 627: if (!HTConfirm(dest_req, buf))
1.70 frystyk 628: return HT_ERROR;
629: }
1.77 frystyk 630:
631: /* @@@ NOT FINISHED @@@ */
1.70 frystyk 632:
633: return HT_ERROR;
634: }
635:
636: /* --------------------------------------------------------------------------*/
637: /* Anchor help routines */
638: /* --------------------------------------------------------------------------*/
1.57 howcome 639:
640: /*
641: ** Find Related Name
642: **
643: ** Creates a string that can be used as a related name when
644: ** calling HTParse initially.
645: **
646: ** The code for this routine originates from the Linemode
1.79 frystyk 647: ** browser and was moved here by howcome@w3.org
1.57 howcome 648: ** in order for all clients to take advantage.
649: **
1.59 frystyk 650: ** The string returned must be freed by the caller
1.57 howcome 651: */
652: PUBLIC char * HTFindRelatedName NOARGS
653: {
1.59 frystyk 654: char* default_default = NULL; /* Parse home relative to this */
655: CONST char *host = HTGetHostName();
1.57 howcome 656: StrAllocCopy(default_default, "file://");
1.59 frystyk 657: if (host)
658: StrAllocCat(default_default, host);
659: else
660: StrAllocCat(default_default, "localhost");
661: {
662: char wd[HT_MAX_PATH+1];
1.67 frystyk 663:
664: #ifdef NO_GETWD
665: #ifdef HAS_GETCWD /* System V variant SIGN CHANGED TBL 921006 !! */
666: char *result = (char *) getcwd(wd, sizeof(wd));
667: #else
668: char *result = NULL;
669: HTAlert("This platform does not support neither getwd nor getcwd\n");
670: #endif
671: #else
672: char *result = (char *) getwd(wd);
673: #endif
1.59 frystyk 674: *(wd+HT_MAX_PATH) = '\0';
1.57 howcome 675: if (result) {
676: #ifdef VMS
677: /* convert directory name to Unix-style syntax */
678: char * disk = strchr (wd, ':');
679: char * dir = strchr (wd, '[');
680: if (disk) {
681: *disk = '\0';
682: StrAllocCat (default_default, "/"); /* needs delimiter */
683: StrAllocCat (default_default, wd);
684: }
685: if (dir) {
686: char *p;
687: *dir = '/'; /* Convert leading '[' */
688: for (p = dir ; *p != ']'; ++p)
689: if (*p == '.') *p = '/';
690: *p = '\0'; /* Cut on final ']' */
691: StrAllocCat (default_default, dir);
692: }
1.74 frystyk 693: #else /* not VMS */
1.70 frystyk 694: #ifdef WIN32
695: char * p = wd ; /* a colon */
696: StrAllocCat(default_default, "/");
697: while( *p != 0 ) {
698: if (*p == '\\') /* change to one true slash */
699: *p = '/' ;
700: p++;
701: }
1.74 frystyk 702: StrAllocCat( default_default, wd);
703: #else /* not WIN32 */
1.57 howcome 704: StrAllocCat (default_default, wd);
1.70 frystyk 705: #endif /* not WIN32 */
1.67 frystyk 706: #endif /* not VMS */
1.57 howcome 707: }
1.67 frystyk 708: }
1.57 howcome 709: StrAllocCat(default_default, "/default.html");
710: return default_default;
1.2 timbl 711: }
712:
713:
714: /* Generate the anchor for the home page
715: ** -------------------------------------
716: **
717: ** As it involves file access, this should only be done once
718: ** when the program first runs.
1.10 timbl 719: ** This is a default algorithm -- browser don't HAVE to use this.
720: ** But consistency betwen browsers is STRONGLY recommended!
1.2 timbl 721: **
1.10 timbl 722: ** Priority order is:
723: **
724: ** 1 WWW_HOME environment variable (logical name, etc)
725: ** 2 ~/WWW/default.html
726: ** 3 /usr/local/bin/default.html
1.70 frystyk 727: ** 4 http://www.w3.org/default.html
1.10 timbl 728: **
1.2 timbl 729: */
730: PUBLIC HTParentAnchor * HTHomeAnchor NOARGS
731: {
1.12 timbl 732: char * my_home_document = NULL;
1.70 frystyk 733: char * home = (char *) getenv(LOGICAL_DEFAULT);
1.2 timbl 734: char * ref;
735: HTParentAnchor * anchor;
1.1 timbl 736:
1.70 frystyk 737: /* Someone telnets in, they get a special home */
1.12 timbl 738: if (home) {
739: StrAllocCopy(my_home_document, home);
1.70 frystyk 740: } else if (HTClientHost) { /* Telnet server */
1.12 timbl 741: FILE * fp = fopen(REMOTE_POINTER, "r");
742: char * status;
743: if (fp) {
1.59 frystyk 744: my_home_document = (char*) malloc(HT_MAX_PATH);
745: status = fgets(my_home_document, HT_MAX_PATH, fp);
1.12 timbl 746: if (!status) {
747: free(my_home_document);
748: my_home_document = NULL;
749: }
750: fclose(fp);
751: }
752: if (!my_home_document) StrAllocCopy(my_home_document, REMOTE_ADDRESS);
753: }
754:
1.67 frystyk 755: #ifdef unix
1.10 timbl 756: if (!my_home_document) {
757: FILE * fp = NULL;
1.70 frystyk 758: char * home = (char *) getenv("HOME");
1.10 timbl 759: if (home) {
760: my_home_document = (char *)malloc(
761: strlen(home)+1+ strlen(PERSONAL_DEFAULT)+1);
762: if (my_home_document == NULL) outofmem(__FILE__, "HTLocalName");
763: sprintf(my_home_document, "%s/%s", home, PERSONAL_DEFAULT);
764: fp = fopen(my_home_document, "r");
765: }
766:
767: if (!fp) {
768: StrAllocCopy(my_home_document, LOCAL_DEFAULT_FILE);
769: fp = fopen(my_home_document, "r");
770: }
1.2 timbl 771: if (fp) {
772: fclose(fp);
773: } else {
1.62 frystyk 774: if (TRACE)
1.67 frystyk 775: fprintf(TDEST,
1.62 frystyk 776: "HTBrowse: No local home document ~/%s or %s\n",
777: PERSONAL_DEFAULT, LOCAL_DEFAULT_FILE);
1.11 timbl 778: free(my_home_document);
779: my_home_document = NULL;
1.2 timbl 780: }
781: }
1.67 frystyk 782: #endif
1.70 frystyk 783: ref = HTParse(my_home_document ? my_home_document :
784: HTClientHost ? REMOTE_ADDRESS : LAST_RESORT, "file:",
785: PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION);
1.10 timbl 786: if (my_home_document) {
1.62 frystyk 787: if (TRACE)
1.67 frystyk 788: fprintf(TDEST,
1.62 frystyk 789: "HTAccess.... `%s\' used for custom home page as\n`%s\'\n",
790: my_home_document, ref);
1.10 timbl 791: free(my_home_document);
1.2 timbl 792: }
793: anchor = (HTParentAnchor*) HTAnchor_findAddress(ref);
794: free(ref);
795: return anchor;
1.1 timbl 796: }
1.26 frystyk 797:
Webmaster