Annotation of Amaya/amaya/AHTURLTools.c, revision 1.89
1.7 cvs 1: /*
2: *
3: * (c) COPYRIGHT MIT and INRIA, 1996.
4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
1.9 cvs 7:
1.10 cvs 8: /*
9: * AHTURLTools.c: contains all the functions for testing, manipulating,
1.25 cvs 10: * and normalizing URLs. It also contains a local copy of the libWWW
11: * URL parsing functions.
1.10 cvs 12: *
13: * Authors: J. Kahan, I. Vatton
1.87 cvs 14: * R. Guetari: Windows & Unicode.
1.10 cvs 15: *
16: */
1.7 cvs 17:
1.15 cvs 18: #define THOT_EXPORT extern
1.3 cvs 19: #include "amaya.h"
20:
1.8 cvs 21: #include "init_f.h"
22: #include "AHTURLTools_f.h"
23:
1.24 cvs 24: #define MAX_PRINT_URL_LENGTH 50
1.29 cvs 25: typedef struct _HTURI {
1.67 cvs 26: STRING access; /* Now known as "scheme" */
27: STRING host;
28: STRING absolute;
29: STRING relative;
30: STRING fragment;
1.29 cvs 31: } HTURI;
1.24 cvs 32:
1.28 cvs 33:
34: /*----------------------------------------------------------------------
35: ConvertToLowerCase
36: Converts a string to lowercase.
37: ----------------------------------------------------------------------*/
1.22 cvs 38: #ifdef __STDC__
1.67 cvs 39: void ConvertToLowerCase (STRING string)
1.28 cvs 40: #else /* __STDC__ */
1.38 cvs 41: void ConvertToLowerCase (string)
1.67 cvs 42: STRING string;
1.28 cvs 43:
44: #endif /* __STDC__ */
45: {
46: int i;
47:
48: if (!string)
49: return;
50:
1.87 cvs 51: for (i = 0; string[i] != WC_EOS; i++)
1.67 cvs 52: string[i] = utolower (string[i]);
1.28 cvs 53: }
1.22 cvs 54:
1.8 cvs 55: /*----------------------------------------------------------------------
1.75 cvs 56: EscapeChar
57: writes the equivalent escape code of a char in a string
58: ----------------------------------------------------------------------*/
59: #ifdef __STDC__
60: void EscapeChar (STRING string, UCHAR_T c)
61: #else
62: void EscapeChar (string, c)
63: STRING string;
64: UCHAR_T c;
65:
66: #endif
67: {
68: c &= 0xFF; /* strange behavior under solaris? */
69: usprintf (string, TEXT("%02x"), (unsigned int) c);
70: }
71:
72: /*----------------------------------------------------------------------
73: EscapeURL
74: Takes a URL and escapes all protected chars into
75: %xx sequences. Also, removes any leading white spaces
76: Returns either NULL or a new buffer, which must be freed by the caller
77: ----------------------------------------------------------------------*/
78: #ifdef __STDC__
79: STRING EscapeURL (const STRING url)
80: #else
81: STRING EscapeURL (url)
82: STRING url;
83: #endif /* __STDC__ */
84: {
85: STRING buffer;
86: int buffer_len;
87: int buffer_free_mem;
88: PCHAR_T ptr;
89: int new_chars;
90: void *status;
91:
92: if (url && *url)
93: {
1.76 cvs 94: buffer_free_mem = ustrlen (url) + 20;
95: buffer = TtaAllocString (buffer_free_mem + 1);
1.75 cvs 96: ptr = url;
97: buffer_len = 0;
98:
99: while (*ptr)
100: {
101: switch (*ptr)
102: {
103: /* put here below all the chars that need to
104: be escaped into %xx */
1.81 cvs 105: case 0x27: /* & */
106: case 0x20: /* space */
1.75 cvs 107: new_chars = 3;
108: break;
109:
110: default:
111: new_chars = 1;
112: break;
113: }
114:
115: /* see if we need extra room in the buffer */
116: if (new_chars > buffer_free_mem)
117: {
1.76 cvs 118: buffer_free_mem = 20;
1.75 cvs 119: status = TtaRealloc (buffer, sizeof (CHAR_T)
120: * (buffer_len + buffer_free_mem + 1));
121: if (status)
122: buffer = (STRING) status;
123: else {
124: /* @@ maybe we should do some other behavior here, like
125: freeing the buffer and return a void thing */
1.87 cvs 126: buffer[buffer_len] = WC_EOS;
1.75 cvs 127: break;
128: }
129: }
130: /* escape the char */
131: if (new_chars == 3)
132: {
133: buffer[buffer_len] = TEXT('%');
134: EscapeChar (&buffer[buffer_len+1], *ptr);
135: }
136: else
137: buffer[buffer_len] = *ptr;
138:
139: /* update the status */
140: buffer_len += new_chars;
141: buffer_free_mem -= new_chars;
142: /* examine the next char */
143: ptr++;
144: }
1.87 cvs 145: buffer[buffer_len] = WC_EOS;
1.75 cvs 146: }
1.76 cvs 147: else
148: buffer = NULL;
149:
1.75 cvs 150: return (buffer);
151: }
152:
153:
154: /*----------------------------------------------------------------------
1.11 cvs 155: ExplodeURL
1.8 cvs 156: ----------------------------------------------------------------------*/
157: #ifdef __STDC__
158: void ExplodeURL (char *url, char **proto, char **host, char **dir, char **file)
159: #else
160: void ExplodeURL (url, proto, host, dir, file)
161: char *url;
162: char **proto;
163: char **host;
164: char **dir;
165: char **file;
166:
167: #endif
168: {
1.33 cvs 169: char *curr, *temp;
170: char used_sep;
1.32 cvs 171:
1.33 cvs 172: if (url && strchr (url, URL_SEP))
173: used_sep = URL_SEP;
174: else
175: used_sep = DIR_SEP;
1.8 cvs 176:
177: if ((url == NULL) || (proto == NULL) || (host == NULL) ||
178: (dir == NULL) || (file == NULL))
179: return;
180:
181: /* initialize every pointer */
182: *proto = *host = *dir = *file = NULL;
183:
184: /* skip any leading space */
185: while ((*url == SPACE) || (*url == TAB))
186: url++;
1.9 cvs 187: curr = url;
188: if (*curr == 0)
1.8 cvs 189: goto finished;
190:
191: /* go to the end of the URL */
1.68 cvs 192: while ((*curr != EOS) && (*curr != SPACE) && (*curr != BSPACE) &&
193: (*curr != __CR__) && (*curr != EOL))
1.9 cvs 194: curr++;
1.8 cvs 195:
196: /* mark the end of the chain */
1.9 cvs 197: *curr = EOS;
198: curr--;
199: if (curr <= url)
1.8 cvs 200: goto finished;
201:
202: /* search the next DIR_SEP indicating the beginning of the file name */
203: do
1.11 cvs 204: curr--;
1.33 cvs 205: while ((curr >= url) && (*curr != used_sep));
1.11 cvs 206:
1.9 cvs 207: if (curr < url)
1.8 cvs 208: goto finished;
1.9 cvs 209: *file = curr + 1;
1.8 cvs 210:
211: /* mark the end of the dir */
1.9 cvs 212: *curr = EOS;
213: curr--;
214: if (curr < url)
1.8 cvs 215: goto finished;
216:
1.29 cvs 217: /* search for the DIR_STR indicating the host name start */
1.33 cvs 218: while ((curr > url) && ((*curr != used_sep) || (*(curr + 1) != used_sep)))
1.9 cvs 219: curr--;
1.8 cvs 220:
221: /* if we found it, separate the host name from the directory */
1.33 cvs 222: if ((*curr == DIR_SEP) && (*(curr + 1) == used_sep))
1.8 cvs 223: {
1.9 cvs 224: *host = temp = curr + 2;
1.33 cvs 225: while ((*temp != 0) && (*temp != used_sep))
1.8 cvs 226: temp++;
1.33 cvs 227: if (*temp == used_sep)
1.8 cvs 228: {
229: *temp = EOS;
230: *dir = temp + 1;
231: }
232: }
233: else
1.11 cvs 234: *dir = curr;
235:
1.9 cvs 236: if (curr <= url)
1.8 cvs 237: goto finished;
238:
239: /* mark the end of the proto */
1.9 cvs 240: *curr = EOS;
241: curr--;
242: if (curr < url)
1.8 cvs 243: goto finished;
244:
1.67 cvs 245: if (*curr == TEXT(':'))
1.8 cvs 246: {
1.9 cvs 247: *curr = EOS;
248: curr--;
1.8 cvs 249: }
250: else
251: goto finished;
1.11 cvs 252:
1.9 cvs 253: if (curr < url)
1.8 cvs 254: goto finished;
1.9 cvs 255: while ((curr > url) && (isalpha (*curr)))
256: curr--;
257: *proto = curr;
1.8 cvs 258:
259: finished:;
260:
261: #ifdef AMAYA_DEBUG
262: fprintf (stderr, "ExplodeURL(%s)\n\t", url);
263: if (*proto)
264: fprintf (stderr, "proto : %s, ", *proto);
265: if (*host)
266: fprintf (stderr, "host : %s, ", *host);
267: if (*dir)
268: fprintf (stderr, "dir : %s, ", *dir);
269: if (*file)
270: fprintf (stderr, "file : %s ", *file);
271: fprintf (stderr, "\n");
272: #endif
273:
274: }
1.3 cvs 275:
1.61 cvs 276:
277: /*----------------------------------------------------------------------
278: ExtractSuffix extract suffix from document nane.
279: ----------------------------------------------------------------------*/
280: #ifdef __STDC__
281: void ExtractSuffix (STRING aName, STRING aSuffix)
282: #else
283: void ExtractSuffix (aName, aSuffix)
284: STRING aName;
285: STRING aSuffix;
286:
287: #endif
288: {
289: int lg, i;
290: STRING ptr, oldptr;
291:
292: if (!aSuffix || !aName)
293: /* bad suffix */
294: return;
295:
1.87 cvs 296: aSuffix[0] = WC_EOS;
1.61 cvs 297: lg = ustrlen (aName);
298: if (lg)
299: {
300: /* the name is not empty */
301: oldptr = ptr = &aName[0];
302: do
303: {
1.67 cvs 304: ptr = ustrrchr (oldptr, TEXT('.'));
1.61 cvs 305: if (ptr)
306: oldptr = &ptr[1];
307: }
308: while (ptr);
309:
310: i = (int) (oldptr) - (int) (aName); /* name length */
311: if (i > 1)
312: {
1.87 cvs 313: aName[i - 1] = WC_EOS;
1.61 cvs 314: if (i != lg)
315: ustrcpy (aSuffix, oldptr);
316: }
317: }
318: }
319:
1.4 cvs 320: /*----------------------------------------------------------------------
1.9 cvs 321: IsHTMLName
322: returns TRUE if path points to an HTML resource.
1.4 cvs 323: ----------------------------------------------------------------------*/
1.3 cvs 324: #ifdef __STDC__
1.84 cvs 325: ThotBool IsHTMLName (const CHAR_T* path)
1.3 cvs 326: #else /* __STDC__ */
1.67 cvs 327: ThotBool IsHTMLName (path)
1.84 cvs 328: const CHAR_T* path;
1.3 cvs 329: #endif /* __STDC__ */
330: {
1.84 cvs 331: CHAR_T temppath[MAX_LENGTH];
332: CHAR_T suffix[MAX_LENGTH];
333: CHAR_T nsuffix[MAX_LENGTH];
334: int i;
1.5 cvs 335:
336: if (!path)
1.37 cvs 337: return (FALSE);
1.5 cvs 338:
1.84 cvs 339: ustrcpy (temppath, path);
1.5 cvs 340: ExtractSuffix (temppath, suffix);
1.88 cvs 341: while (suffix[0] != WC_EOS)
1.13 cvs 342: {
343: /* Normalize the suffix */
344: i = 0;
1.84 cvs 345: while (suffix[i] != WC_EOS && i < MAX_LENGTH -1)
1.13 cvs 346: {
1.84 cvs 347: nsuffix[i] = utolower (suffix[i]);
1.13 cvs 348: i++;
349: }
1.84 cvs 350: nsuffix[i] = WC_EOS;
351: if (!ustrcmp (nsuffix, TEXT("html")) ||
1.88 cvs 352: !ustrcmp (nsuffix, TEXT("htm")) ||
353: !ustrcmp (nsuffix, TEXT("shtml")) ||
354: !ustrcmp (nsuffix, TEXT("jsp")) ||
355: !ustrcmp (nsuffix, TEXT("xht")) ||
356: !ustrcmp (nsuffix, TEXT("xhtm")) ||
357: !ustrcmp (nsuffix, TEXT("xhtml")))
1.39 cvs 358: return (TRUE);
1.88 cvs 359: else if (!ustrcmp (nsuffix, TEXT("gz")))
360: {
361: /* take into account compressed files */
362: ExtractSuffix (temppath, suffix);
363: /* Normalize the suffix */
364: i = 0;
365: while (suffix[i] != WC_EOS && i < MAX_LENGTH -1)
366: {
367: nsuffix[i] = utolower (suffix[i]);
368: i++;
369: }
370: nsuffix[i] = WC_EOS;
371: if (!ustrcmp (nsuffix, TEXT("html")) ||
372: !ustrcmp (nsuffix, TEXT("htm")) ||
373: !ustrcmp (nsuffix, TEXT("shtml")) ||
374: !ustrcmp (nsuffix, TEXT("jsp")) ||
375: !ustrcmp (nsuffix, TEXT("xht")) ||
376: !ustrcmp (nsuffix, TEXT("xhtm")) ||
377: !ustrcmp (nsuffix, TEXT("xhtml")))
378: return (TRUE);
379: else
380: return (FALSE);
381: }
1.39 cvs 382: else
1.88 cvs 383: /* check if there is another suffix */
384: ExtractSuffix (temppath, suffix);
1.13 cvs 385: }
1.88 cvs 386:
387: return (FALSE);
1.3 cvs 388: }
389:
1.4 cvs 390: /*----------------------------------------------------------------------
1.56 cvs 391: IsXMLName
392: returns TRUE if path points to an XML resource.
393: ----------------------------------------------------------------------*/
394: #ifdef __STDC__
1.67 cvs 395: ThotBool IsXMLName (const STRING path)
1.56 cvs 396: #else /* __STDC__ */
1.67 cvs 397: ThotBool IsXMLName (path)
398: const STRING path;
1.56 cvs 399: #endif /* __STDC__ */
400: {
1.67 cvs 401: CHAR_T temppath[MAX_LENGTH];
402: CHAR_T suffix[MAX_LENGTH];
1.56 cvs 403:
404: if (!path)
405: return (FALSE);
406:
1.67 cvs 407: ustrcpy (temppath, path);
1.56 cvs 408: ExtractSuffix (temppath, suffix);
409:
1.67 cvs 410: if (!ustrcasecmp (suffix, TEXT("xml")) ||
411: !ustrcasecmp (suffix, TEXT("xht")) ||
412: !ustrcmp (suffix, TEXT("xhtm")) ||
413: !ustrcmp (suffix, TEXT("xhtml")))
1.56 cvs 414: return (TRUE);
1.67 cvs 415: else if (!ustrcmp (suffix, TEXT("gz")))
1.56 cvs 416: {
417: /* take into account compressed files */
418: ExtractSuffix (temppath, suffix);
1.67 cvs 419: if (!ustrcasecmp (suffix, TEXT("xml")) ||
420: !ustrcasecmp (suffix, TEXT("xht")) ||
421: !ustrcmp (suffix, TEXT("xhtm")) ||
422: !ustrcmp (suffix, TEXT("xhtml")))
1.60 cvs 423: return (TRUE);
424: else
425: return (FALSE);
426: }
427: else
428: return (FALSE);
429: }
430:
431: /*----------------------------------------------------------------------
432: IsCSSName
433: returns TRUE if path points to an XML resource.
434: ----------------------------------------------------------------------*/
435: #ifdef __STDC__
1.67 cvs 436: ThotBool IsCSSName (const STRING path)
1.60 cvs 437: #else /* __STDC__ */
1.67 cvs 438: ThotBool IsCSSName (path)
439: const STRING path;
1.60 cvs 440: #endif /* __STDC__ */
441: {
1.67 cvs 442: CHAR_T temppath[MAX_LENGTH];
443: CHAR_T suffix[MAX_LENGTH];
1.60 cvs 444:
445: if (!path)
446: return (FALSE);
447:
1.67 cvs 448: ustrcpy (temppath, path);
1.60 cvs 449: ExtractSuffix (temppath, suffix);
450:
1.67 cvs 451: if (!ustrcasecmp (suffix, TEXT("css")))
1.60 cvs 452: return (TRUE);
1.67 cvs 453: else if (!ustrcmp (suffix, TEXT("gz")))
1.60 cvs 454: {
455: /* take into account compressed files */
456: ExtractSuffix (temppath, suffix);
1.67 cvs 457: if (!ustrcasecmp (suffix, TEXT("css")))
1.56 cvs 458: return (TRUE);
459: else
460: return (FALSE);
461: }
462: else
463: return (FALSE);
464: }
465:
466: /*----------------------------------------------------------------------
1.9 cvs 467: IsImageName
468: returns TRUE if path points to an image resource.
1.4 cvs 469: ----------------------------------------------------------------------*/
1.3 cvs 470: #ifdef __STDC__
1.67 cvs 471: ThotBool IsImageName (const STRING path)
1.3 cvs 472: #else /* __STDC__ */
1.67 cvs 473: ThotBool IsImageName (path)
474: const STRING path;
1.3 cvs 475: #endif /* __STDC__ */
476: {
1.67 cvs 477: CHAR_T temppath[MAX_LENGTH];
478: CHAR_T suffix[MAX_LENGTH];
479: CHAR_T nsuffix[MAX_LENGTH];
1.5 cvs 480: int i;
481:
482: if (!path)
1.13 cvs 483: return (FALSE);
1.5 cvs 484:
1.67 cvs 485: ustrcpy (temppath, path);
1.5 cvs 486: ExtractSuffix (temppath, suffix);
487:
488: /* Normalize the suffix */
489: i = 0;
1.87 cvs 490: while (suffix[i] != WC_EOS && i < MAX_LENGTH -1)
1.13 cvs 491: {
1.67 cvs 492: nsuffix[i] = utolower (suffix[i]);
1.13 cvs 493: i++;
494: }
1.87 cvs 495: nsuffix[i] = WC_EOS;
1.67 cvs 496: if ((!ustrcmp (nsuffix, TEXT("gif"))) || (!ustrcmp (nsuffix, TEXT("xbm"))) ||
497: (!ustrcmp (nsuffix, TEXT("xpm"))) || (!ustrcmp (nsuffix, TEXT("jpg"))) ||
498: (!ustrcmp (nsuffix, TEXT("png"))) || (!ustrcmp (nsuffix, TEXT("au"))))
1.39 cvs 499: return (TRUE);
500: return (FALSE);
1.3 cvs 501: }
502:
1.4 cvs 503: /*----------------------------------------------------------------------
1.58 cvs 504: IsImageType
505: returns TRUE if type points to an image resource.
506: ----------------------------------------------------------------------*/
507: #ifdef __STDC__
1.67 cvs 508: ThotBool IsImageType (const STRING type)
1.58 cvs 509: #else /* __STDC__ */
1.67 cvs 510: ThotBool IsImageType (type)
511: const STRING type;
1.58 cvs 512: #endif /* __STDC__ */
513: {
1.67 cvs 514: CHAR_T temptype[MAX_LENGTH];
1.58 cvs 515: int i;
516:
517: if (!type)
518: return (FALSE);
519:
1.67 cvs 520: ustrcpy (temptype, type);
1.58 cvs 521: /* Normalize the type */
522: i = 0;
1.87 cvs 523: while (temptype[i] != WC_EOS)
1.58 cvs 524: {
525: temptype[i] = tolower (temptype[i]);
526: i++;
527: }
1.67 cvs 528: if ((!ustrcmp (temptype, TEXT("gif"))) || (!ustrcmp (temptype, TEXT("x-xbitmap"))) ||
529: (!ustrcmp (temptype, TEXT("x-xpixmap"))) || (!ustrcmp (temptype, TEXT("jpeg"))) ||
530: (!ustrcmp (temptype, TEXT("png"))))
1.58 cvs 531: return (TRUE);
532: return (FALSE);
533: }
534:
535: /*----------------------------------------------------------------------
1.9 cvs 536: IsTextName
1.4 cvs 537: ----------------------------------------------------------------------*/
1.3 cvs 538: #ifdef __STDC__
1.67 cvs 539: ThotBool IsTextName (const STRING path)
1.3 cvs 540: #else /* __STDC__ */
1.67 cvs 541: ThotBool IsTextName (path)
542: const STRING path;
1.3 cvs 543:
544: #endif /* __STDC__ */
545: {
1.67 cvs 546: CHAR_T temppath[MAX_LENGTH];
547: CHAR_T suffix[MAX_LENGTH];
548: CHAR_T nsuffix[MAX_LENGTH];
1.5 cvs 549: int i;
550:
551: if (!path)
1.13 cvs 552: return (FALSE);
1.5 cvs 553:
1.67 cvs 554: ustrcpy (temppath, path);
1.5 cvs 555: ExtractSuffix (temppath, suffix);
556:
557: /* Normalize the suffix */
558: i = 0;
1.87 cvs 559: while (suffix[i] != WC_EOS && i < MAX_LENGTH -1)
1.5 cvs 560: {
1.25 cvs 561: nsuffix[i] = tolower (suffix[i]);
1.5 cvs 562: i++;
563: }
1.87 cvs 564: nsuffix[i] = WC_EOS;
1.5 cvs 565:
1.67 cvs 566: if ((!ustrcmp (nsuffix, TEXT("txt"))) || (!ustrcmp (nsuffix, TEXT("dtd"))))
1.13 cvs 567: return (TRUE);
1.67 cvs 568: else if (!ustrcmp (nsuffix, TEXT("gz")))
1.13 cvs 569: {
1.39 cvs 570: /* take into account compressed files */
1.13 cvs 571: ExtractSuffix (temppath, suffix);
572: /* Normalize the suffix */
573: i = 0;
1.87 cvs 574: while (suffix[i] != WC_EOS && i < MAX_LENGTH -1)
1.13 cvs 575: {
1.25 cvs 576: nsuffix[i] = tolower (suffix[i]);
1.13 cvs 577: i++;
578: }
1.87 cvs 579: nsuffix[i] = WC_EOS;
1.67 cvs 580: if ((!ustrcmp (nsuffix, TEXT("txt"))) || (!ustrcmp (nsuffix, TEXT("dtd"))))
1.13 cvs 581: return (TRUE);
582: else
583: return (FALSE);
584: }
585: else
586: return (FALSE);
1.3 cvs 587: }
588:
1.4 cvs 589: /*----------------------------------------------------------------------
1.9 cvs 590: IsHTTPPath
591: returns TRUE if path is in fact an http URL.
1.4 cvs 592: ----------------------------------------------------------------------*/
1.3 cvs 593: #ifdef __STDC__
1.67 cvs 594: ThotBool IsHTTPPath (const STRING path)
1.3 cvs 595: #else /* __STDC__ */
1.67 cvs 596: ThotBool IsHTTPPath (path)
597: const STRING path;
1.3 cvs 598: #endif /* __STDC__ */
599: {
1.5 cvs 600: if (!path)
601: return FALSE;
1.3 cvs 602:
1.67 cvs 603: if ((!ustrncmp (path, TEXT("http:"), 5) != 0)
604: || !ustrncmp (path, TEXT("internal:"), 9))
1.58 cvs 605: return TRUE;
606: return FALSE;
1.3 cvs 607: }
608:
1.4 cvs 609: /*----------------------------------------------------------------------
1.9 cvs 610: IsWithParameters
611: returns TRUE if url has a concatenated query string.
1.4 cvs 612: ----------------------------------------------------------------------*/
1.3 cvs 613: #ifdef __STDC__
1.66 cvs 614: ThotBool IsWithParameters (const char *url)
1.3 cvs 615: #else /* __STDC__ */
1.66 cvs 616: ThotBool IsWithParameters (url)
1.34 cvs 617: const char *url;
1.3 cvs 618: #endif /* __STDC__ */
619: {
1.5 cvs 620: int i;
1.3 cvs 621:
1.9 cvs 622: if ((!url) || (url[0] == EOS))
1.5 cvs 623: return FALSE;
1.3 cvs 624:
1.9 cvs 625: i = strlen (url) - 1;
626: while (i > 0 && url[i--] != '?')
1.5 cvs 627: if (i < 0)
628: return FALSE;
1.3 cvs 629:
1.5 cvs 630: /* There is a parameter */
631: return TRUE;
1.3 cvs 632: }
633:
1.4 cvs 634: /*----------------------------------------------------------------------
1.9 cvs 635: IsW3Path
636: returns TRUE if path is in fact a URL.
1.4 cvs 637: ----------------------------------------------------------------------*/
1.3 cvs 638: #ifdef __STDC__
1.84 cvs 639: ThotBool IsW3Path (const CHAR_T* path)
1.3 cvs 640: #else /* __STDC__ */
1.67 cvs 641: ThotBool IsW3Path (path)
1.84 cvs 642: const CHAR_T* path;
1.3 cvs 643: #endif /* __STDC__ */
644: {
1.84 cvs 645: if (ustrncmp (path, TEXT("http:"), 5) &&
646: ustrncmp (path, TEXT("ftp:"), 4) &&
647: ustrncmp (path, TEXT("telnet:"), 7) &&
648: ustrncmp (path, TEXT("wais:"), 5) &&
649: ustrncmp (path, TEXT("news:"), 5) &&
650: ustrncmp (path, TEXT("gopher:"), 7) &&
651: ustrncmp (path, TEXT("mailto:"), 7) &&
652: ustrncmp (path, TEXT("archie:"), 7))
1.72 cvs 653: return FALSE;
654: return TRUE;
1.3 cvs 655: }
656:
1.4 cvs 657: /*----------------------------------------------------------------------
1.9 cvs 658: IsValidProtocol
659: returns true if the url protocol is supported by Amaya.
1.4 cvs 660: ----------------------------------------------------------------------*/
1.3 cvs 661: #ifdef __STDC__
1.67 cvs 662: ThotBool IsValidProtocol (const STRING url)
1.3 cvs 663: #else /* __STDC__ */
1.67 cvs 664: ThotBool IsValidProtocol (url)
665: const STRING url;
1.3 cvs 666: #endif /* __STDC__ */
667: {
1.67 cvs 668: if (!ustrncmp (url, TEXT("http:"), 5)
1.69 cvs 669: || !ustrncmp (url, TEXT("internal:"), 9)
1.70 cvs 670: || !ustrncmp (url, TEXT("ftp:"), 4))
1.22 cvs 671: /* experimental */
1.58 cvs 672: /*** || !strncmp (url, "ftp:", 4) ***/
1.24 cvs 673: /*** || !strncmp (path, "news:", 5)***/
1.8 cvs 674: return (TRUE);
1.5 cvs 675: else
1.8 cvs 676: return (FALSE);
1.3 cvs 677: }
678:
1.31 cvs 679:
680: /*----------------------------------------------------------------------
681: GetBaseURL
682: normalizes orgName according to a base associated with doc, and
683: following the standard URL format rules.
684: The function returns the base used to solve relative URL and SRC:
685: - the base of the document,
686: - or the document path (without document name).
687: ----------------------------------------------------------------------*/
688: #ifdef __STDC__
1.84 cvs 689: CHAR_T* GetBaseURL (Document doc)
1.31 cvs 690: #else /* __STDC__ */
1.84 cvs 691: CHAR_T* GetBaseURL (doc)
1.31 cvs 692: Document doc;
693: #endif /* __STDC__ */
694: {
695: Element el;
696: ElementType elType;
697: AttributeType attrType;
698: Attribute attr;
1.84 cvs 699: CHAR_T *ptr, *basename;
1.31 cvs 700: int length;
701:
1.57 cvs 702: /* @@@ irene */
703: if (!DocumentURLs[doc])
704: return NULL;
1.67 cvs 705: basename = TtaAllocString (MAX_LENGTH);
706: ustrncpy (basename, DocumentURLs[doc], MAX_LENGTH-1);
1.84 cvs 707: basename[MAX_LENGTH-1] = WC_EOS;
1.31 cvs 708: length = MAX_LENGTH -1;
709: /* get the root element */
710: el = TtaGetMainRoot (doc);
711: /* search the BASE element */
712: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.65 cvs 713: elType.ElTypeNum = HTML_EL_HEAD;
714: el = TtaSearchTypedElement (elType, SearchForward, el);
715: if (el)
716: {
717: elType.ElTypeNum = HTML_EL_BASE;
718: el = TtaSearchTypedElement (elType, SearchInTree, el);
719: }
1.31 cvs 720: if (el)
721: {
722: /* The document has a BASE element -> Get the HREF attribute */
723: attrType.AttrSSchema = elType.ElSSchema;
724: attrType.AttrTypeNum = HTML_ATTR_HREF_;
725: attr = TtaGetAttribute (el, attrType);
726: if (attr)
727: {
728: /* Use the base path of the document */
729: TtaGiveTextAttributeValue (attr, basename, &length);
730: /* base and orgName have to be separated by a DIR_SEP */
731: length--;
1.84 cvs 732: if (basename[0] != WC_EOS && basename[length] != WC_URL_SEP && basename[length] != WC_DIR_SEP)
1.31 cvs 733: /* verify if the base has the form "protocol://server:port" */
734: {
1.84 cvs 735: ptr = AmayaParseUrl (basename, TEXT(""), AMAYA_PARSE_ACCESS |
1.33 cvs 736: AMAYA_PARSE_HOST |
737: AMAYA_PARSE_PUNCTUATION);
1.67 cvs 738: if (ptr && !ustrcmp (ptr, basename))
1.31 cvs 739: {
1.43 cvs 740: /* it has this form, we complete it by adding a URL_STR */
1.84 cvs 741: if (ustrchr (basename, WC_DIR_SEP))
742: ustrcat (basename, WC_DIR_STR);
1.43 cvs 743: else
1.84 cvs 744: ustrcat (basename, WC_URL_STR);
1.31 cvs 745: length++;
746: }
747: if (ptr)
748: TtaFreeMemory (ptr);
749: }
750: }
1.33 cvs 751: }
752:
1.31 cvs 753: /* Remove anything after the last DIR_SEP char. If no such char is found,
754: * then search for the first ":" char, hoping that what's before that is a
755: * protocol. If found, end the string there. If neither char is found,
756: * then discard the whole base element.
757: */
1.67 cvs 758: length = ustrlen (basename) - 1;
1.31 cvs 759: /* search for the last DIR_SEP char */
1.84 cvs 760: while (length >= 0 && basename[length] != WC_URL_SEP && basename[length] != WC_DIR_SEP)
1.31 cvs 761: length--;
762: if (length >= 0)
763: /* found the last DIR_SEP char, end the string there */
1.84 cvs 764: basename[length + 1] = WC_EOS;
1.31 cvs 765: else
766: /* search for the first PATH_STR char */
767: {
1.67 cvs 768: for (length = 0; basename[length] != TEXT(':') &&
1.84 cvs 769: basename[length] != WC_EOS; length ++);
1.67 cvs 770: if (basename[length] == TEXT(':'))
1.31 cvs 771: /* found, so end the string there */
1.84 cvs 772: basename[length + 1] = WC_EOS;
1.31 cvs 773: else
774: /* not found, discard the base */
1.84 cvs 775: basename[0] = WC_EOS;
1.31 cvs 776: }
777: return (basename);
778: }
779:
780:
1.4 cvs 781: /*----------------------------------------------------------------------
1.40 cvs 782: GetLocalPath
783: Allocate and return the local document path associated to the url
784: ----------------------------------------------------------------------*/
785: #ifdef __STDC__
1.84 cvs 786: CHAR_T* GetLocalPath (Document doc, CHAR_T* url)
1.40 cvs 787: #else /* __STDC__ */
1.84 cvs 788: CHAR_T* GetLocalPath (doc, url)
1.40 cvs 789: Document doc;
1.84 cvs 790: CHAR_T* url;
1.40 cvs 791: #endif /* __STDC__ */
792: {
1.84 cvs 793: CHAR_T* ptr;
794: CHAR_T* n;
795: CHAR_T* documentname;
796: CHAR_T url_sep;
1.83 cvs 797: int len;
1.67 cvs 798: ThotBool noFile;
1.40 cvs 799:
800: if (url != NULL)
801: {
802: /* check whether the file name exists */
1.84 cvs 803: len = ustrlen (url) - 1;
1.71 cvs 804: if (IsW3Path (url))
1.84 cvs 805: url_sep = TEXT('/');
1.41 cvs 806: else
1.84 cvs 807: url_sep = WC_DIR_SEP;
1.41 cvs 808: noFile = (url[len] == url_sep);
1.40 cvs 809: if (noFile)
1.84 cvs 810: url[len] = WC_EOS;
811: ptr = TtaAllocString (MAX_LENGTH);
812: documentname = TtaAllocString (MAX_LENGTH);
1.78 cvs 813: TtaExtractName (url, ptr, documentname);
1.84 cvs 814: usprintf (ptr, TEXT("%s%s%d%s"), TempFileDirectory, WC_DIR_STR, doc, WC_DIR_STR);
1.40 cvs 815: if (!TtaCheckDirectory (ptr))
816: /* directory did not exist */
1.72 cvs 817: TtaMakeDirectory (ptr);
1.47 cvs 818:
819: /* don't include the query string within document name */
1.84 cvs 820: n = ustrrchr (documentname, TEXT('?'));
1.47 cvs 821: if (n != NULL)
1.84 cvs 822: *n = WC_EOS;
1.46 cvs 823: /* don't include ':' within document name */
1.84 cvs 824: n = ustrchr (documentname, TEXT(':'));
1.46 cvs 825: if (n != NULL)
1.84 cvs 826: *n = WC_EOS;
1.69 cvs 827: /* if after all this operations document name
828: is empty, let's use noname.html instead */
1.84 cvs 829: if (documentname[0] == WC_EOS)
830: ustrcat (ptr, TEXT("noname.html"));
1.69 cvs 831: else
1.84 cvs 832: ustrcat (ptr, documentname);
1.40 cvs 833: TtaFreeMemory (documentname);
834: /* restore the url */
835: if (noFile)
1.41 cvs 836: url[len] = url_sep;
1.40 cvs 837: return (ptr);
838: }
839: else
840: return (NULL);
841: }
842:
1.73 cvs 843: /*----------------------------------------------------------------------
1.79 cvs 844: ExtractTarget extract the target name from document nane.
845: ----------------------------------------------------------------------*/
846: #ifdef __STDC__
1.84 cvs 847: void ExtractTarget (CHAR_T* aName, CHAR_T* target)
1.79 cvs 848: #else
849: void ExtractTarget (aName, target)
1.84 cvs 850: CHAR_T* aName;
851: CHAR_T* target;
1.79 cvs 852: #endif
853: {
1.82 cvs 854: int lg, i;
1.84 cvs 855: CHAR_T* ptr;
856: CHAR_T* oldptr;
1.79 cvs 857:
858: if (!target || !aName)
859: /* bad target */
860: return;
861:
1.84 cvs 862: target[0] = WC_EOS;
863: lg = ustrlen (aName);
1.79 cvs 864: if (lg)
865: {
866: /* the name is not empty */
867: oldptr = ptr = &aName[0];
868: do
869: {
1.84 cvs 870: ptr = ustrrchr (oldptr, TEXT('#'));
1.79 cvs 871: if (ptr)
872: oldptr = &ptr[1];
873: }
874: while (ptr);
875:
876: i = (int) (oldptr) - (int) (aName); /* name length */
877: if (i > 1)
878: {
1.84 cvs 879: aName[i - 1] = WC_EOS;
1.79 cvs 880: if (i != lg)
1.84 cvs 881: ustrcpy (target, oldptr);
1.79 cvs 882: }
883: }
884: }
885:
886: /*----------------------------------------------------------------------
1.73 cvs 887: ConvertFileURL
888: If the URL starts with file: prefix, it removes the protocol so that we
1.89 ! cvs 889: can use it as a local filename. It also changes the URL_SEP into
! 890: DIR_SEPs if they are not the same character.
1.73 cvs 891: ----------------------------------------------------------------------*/
892: #ifdef __STDC__
1.84 cvs 893: void ConvertFileURL (CHAR_T* url)
1.73 cvs 894: #else
895: void ConvertFileURL (url)
1.84 cvs 896: CHAR_T* url
1.73 cvs 897: #endif /* __STDC__ */
898: {
1.89 ! cvs 899: CHAR_T *src, *dest;
! 900:
1.84 cvs 901: if (!ustrncasecmp (url, TEXT("file:"), 5))
1.89 ! cvs 902: {
! 903: /* skip the file prefix */
! 904: dest = url;
! 905: src = url + 5;
! 906: while (*src)
! 907: {
! 908: #ifdef _WINDOWS
! 909: if (*dest == URL_SEP)
! 910: /* make the transformation */
! 911: *dest = DIR_SEP;
! 912: else
! 913: #endif /* _WINDOWS */
! 914: *dest = *src;
! 915: src++;
! 916: dest++;
! 917: }
! 918: *src = WC_EOS;
! 919: }
1.73 cvs 920: }
1.40 cvs 921:
922: /*----------------------------------------------------------------------
1.9 cvs 923: NormalizeURL
924: normalizes orgName according to a base associated with doc, and
925: following the standard URL format rules.
1.53 cvs 926: if doc is 0 and otherPath not NULL, normalizes orgName according to this
927: other path.
1.9 cvs 928: The function returns the new complete and normalized URL
1.12 cvs 929: or file name path (newName) and the name of the document (docName).
1.9 cvs 930: N.B. If the function can't find out what's the docName, it assigns
931: the name "noname.html".
1.4 cvs 932: ----------------------------------------------------------------------*/
1.3 cvs 933: #ifdef __STDC__
1.84 cvs 934: void NormalizeURL (CHAR_T* orgName, Document doc, CHAR_T* newName, CHAR_T* docName, CHAR_T* otherPath)
1.3 cvs 935: #else /* __STDC__ */
1.53 cvs 936: void NormalizeURL (orgName, doc, newName, docName, otherPath)
1.84 cvs 937: CHAR_T* orgName;
1.3 cvs 938: Document doc;
1.84 cvs 939: CHAR_T* newName;
940: CHAR_T* docName;
941: CHAR_T* otherPath;
1.3 cvs 942: #endif /* __STDC__ */
943: {
1.84 cvs 944: CHAR_T* basename;
945: CHAR_T tempOrgName[MAX_LENGTH];
946: CHAR_T* ptr;
947: CHAR_T used_sep;
948: int length;
949: ThotBool check;
1.5 cvs 950:
1.44 cvs 951: # ifdef _WINDOWS
952: int ndx;
953: # endif /* _WINDOWS */
954:
1.5 cvs 955: if (!newName || !docName)
956: return;
1.18 cvs 957:
1.32 cvs 958: if (doc != 0)
1.53 cvs 959: basename = GetBaseURL (doc);
960: else if (otherPath != NULL)
1.84 cvs 961: basename = TtaWCSdup (otherPath);
1.32 cvs 962: else
1.53 cvs 963: basename = NULL;
1.32 cvs 964:
1.18 cvs 965: /*
1.31 cvs 966: * Clean orgName
967: * Make sure we have a complete orgName, without any leading or trailing
968: * white spaces, or trailinbg new lines
969: */
1.5 cvs 970: ptr = orgName;
1.18 cvs 971: /* skip leading white space and new line characters */
1.84 cvs 972: while ((*ptr == WC_SPACE || *ptr == WC_EOL) && *ptr++ != WC_EOS);
973: ustrncpy (tempOrgName, ptr, MAX_LENGTH -1);
974: tempOrgName[MAX_LENGTH -1] = WC_EOS;
1.18 cvs 975: /*
1.31 cvs 976: * Make orgName a complete URL
977: * If the URL does not include a protocol, then try to calculate
978: * one using the doc's base element (if it exists),
979: */
1.84 cvs 980: if (tempOrgName[0] == WC_EOS)
1.53 cvs 981: {
1.84 cvs 982: newName[0] = WC_EOS;
1.53 cvs 983: TtaFreeMemory (basename);
984: return;
985: }
1.49 cvs 986:
987: /* clean trailing white space */
1.84 cvs 988: length = ustrlen (tempOrgName) - 1;
989: while (tempOrgName[length] == WC_SPACE && tempOrgName[length] == WC_EOL)
1.53 cvs 990: {
1.84 cvs 991: tempOrgName[length] = WC_EOS;
1.53 cvs 992: length--;
993: }
1.50 cvs 994:
1.55 cvs 995: /* remove extra dot (which dot???) */
996: /* ugly, but faster than a strcmp */
1.84 cvs 997: if (tempOrgName[length] == TEXT('.')
998: && (length == 0 || tempOrgName[length-1] != TEXT('.')))
999: tempOrgName[length] = WC_EOS;
1.50 cvs 1000:
1.53 cvs 1001: if (IsW3Path (tempOrgName))
1002: {
1003: /* the name is complete, go to the Sixth Step */
1.84 cvs 1004: ustrcpy (newName, tempOrgName);
1.53 cvs 1005: SimplifyUrl (&newName);
1006: /* verify if the URL has the form "protocol://server:port" */
1.84 cvs 1007: ptr = AmayaParseUrl (newName, TEXT(""), AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST | AMAYA_PARSE_PUNCTUATION);
1008: if (ptr && !ustrcmp (ptr, newName)) /* it has this form, we complete it by adding a DIR_STR */
1009: ustrcat (newName, WC_URL_STR);
1.49 cvs 1010:
1.53 cvs 1011: if (ptr)
1.50 cvs 1012: TtaFreeMemory (ptr);
1.53 cvs 1013: }
1014: else if ( basename == NULL)
1015: /* the name is complete, go to the Sixth Step */
1.84 cvs 1016: ustrcpy (newName, tempOrgName);
1.53 cvs 1017: else
1018: {
1.31 cvs 1019: /* Calculate the absolute URL, using the base or document URL */
1.44 cvs 1020: # ifdef _WINDOWS
1.53 cvs 1021: if (!IsW3Path (basename))
1022: {
1.67 cvs 1023: length = ustrlen (tempOrgName);
1.53 cvs 1024: for (ndx = 0; ndx < length; ndx++)
1.67 cvs 1025: if (tempOrgName [ndx] == TEXT('/'))
1026: tempOrgName [ndx] = TEXT('\\');
1.53 cvs 1027: }
1.44 cvs 1028: # endif /* _WINDOWS */
1.25 cvs 1029: ptr = AmayaParseUrl (tempOrgName, basename, AMAYA_PARSE_ALL);
1.53 cvs 1030: if (ptr)
1031: {
1032: SimplifyUrl (&ptr);
1.84 cvs 1033: ustrcpy (newName, ptr);
1.53 cvs 1034: TtaFreeMemory (ptr);
1035: }
1036: else
1.84 cvs 1037: newName[0] = WC_EOS;
1.53 cvs 1038: }
1.36 cvs 1039:
1040: TtaFreeMemory (basename);
1.18 cvs 1041: /*
1.31 cvs 1042: * Prepare the docname that will refer to this ressource in the
1043: * .amaya directory. If the new URL finishes on DIR_SEP, then use
1044: * noname.html as a default ressource name
1.18 cvs 1045: */
1.84 cvs 1046: if (newName[0] != WC_EOS)
1.53 cvs 1047: {
1.84 cvs 1048: length = ustrlen (newName) - 1;
1049: if (newName[length] == WC_URL_SEP || newName[length] == WC_DIR_SEP)
1.53 cvs 1050: {
1051: used_sep = newName[length];
1052: check = TRUE;
1053: while (check)
1054: {
1.50 cvs 1055: length--;
1056: while (length >= 0 && newName[length] != used_sep)
1.53 cvs 1057: length--;
1.84 cvs 1058: if (!ustrncmp (&newName[length+1], TEXT(".."), 2))
1.53 cvs 1059: {
1.84 cvs 1060: newName[length+1] = WC_EOS;
1.53 cvs 1061: /* remove also previous directory */
1062: length--;
1063: while (length >= 0 && newName[length] != used_sep)
1064: length--;
1.84 cvs 1065: if (ustrncmp (&newName[length+1], TEXT("//"), 2))
1.53 cvs 1066: /* don't remove server name */
1.84 cvs 1067: newName[length+1] = WC_EOS;
1.53 cvs 1068: }
1.84 cvs 1069: else if (!ustrncmp (&newName[length+1], TEXT("."), 1))
1070: newName[length+1] = WC_EOS;
1.50 cvs 1071: else
1.53 cvs 1072: check = FALSE;
1073: }
1.84 cvs 1074: ustrcpy (docName, TEXT("noname.html"));
1.53 cvs 1075: /* docname was not comprised inside the URL, so let's */
1076: /* assign the default ressource name */
1.84 cvs 1077: ustrcpy (docName, TEXT("noname.html"));
1.53 cvs 1078: }
1079: else
1080: { /* docname is comprised inside the URL */
1.84 cvs 1081: while (length >= 0 && newName[length] != WC_URL_SEP && newName[length] != WC_DIR_SEP)
1.53 cvs 1082: length--;
1083: if (length < 0)
1.84 cvs 1084: ustrcpy (docName, newName);
1.53 cvs 1085: else
1.84 cvs 1086: ustrcpy (docName, &newName[length+1]);
1.53 cvs 1087: }
1088: }
1089: else
1.84 cvs 1090: docName[0] = WC_EOS;
1.18 cvs 1091: }
1.3 cvs 1092:
1.4 cvs 1093: /*----------------------------------------------------------------------
1.9 cvs 1094: IsSameHost
1.4 cvs 1095: ----------------------------------------------------------------------*/
1.3 cvs 1096: #ifdef __STDC__
1.67 cvs 1097: ThotBool IsSameHost (const STRING url1, const STRING url2)
1.3 cvs 1098: #else /* __STDC__ */
1.67 cvs 1099: ThotBool IsSameHost (url1, url2)
1100: const STRING url1;
1101: const STRING url2;
1.3 cvs 1102: #endif /* __STDC__ */
1103: {
1.67 cvs 1104: STRING basename_ptr1, basename_ptr2;
1105: ThotBool result;
1.3 cvs 1106:
1.84 cvs 1107: basename_ptr1 = AmayaParseUrl (url1, TEXT(""), AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST | AMAYA_PARSE_PUNCTUATION);
1.86 cvs 1108: basename_ptr2 = AmayaParseUrl (url2, TEXT(""), AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST | AMAYA_PARSE_PUNCTUATION);
1.3 cvs 1109:
1.67 cvs 1110: if (ustrcmp (basename_ptr1, basename_ptr2))
1.8 cvs 1111: result = FALSE;
1.5 cvs 1112: else
1.8 cvs 1113: result = TRUE;
1.3 cvs 1114:
1.25 cvs 1115: TtaFreeMemory (basename_ptr1);
1116: TtaFreeMemory (basename_ptr2);
1.5 cvs 1117: return (result);
1.3 cvs 1118: }
1119:
1120:
1.4 cvs 1121: /*----------------------------------------------------------------------
1.22 cvs 1122: HasKnownFileSuffix
1123: returns TRUE if path points to a file ending with a suffix.
1124: ----------------------------------------------------------------------*/
1125: #ifdef __STDC__
1.67 cvs 1126: ThotBool HasKnownFileSuffix (const STRING path)
1.22 cvs 1127: #else /* __STDC__ */
1.67 cvs 1128: ThotBool HasKnownFileSuffix (path)
1129: const STRING path;
1.22 cvs 1130: #endif /* __STDC__ */
1131: {
1.67 cvs 1132: STRING root;
1133: CHAR_T temppath[MAX_LENGTH];
1134: CHAR_T suffix[MAX_LENGTH];
1.22 cvs 1135:
1.87 cvs 1136: if (!path || path[0] == WC_EOS || path[ustrlen(path)] == WC_DIR_SEP)
1.22 cvs 1137: return (FALSE);
1138:
1.84 cvs 1139: root = AmayaParseUrl(path, TEXT(""), AMAYA_PARSE_PATH | AMAYA_PARSE_PUNCTUATION);
1.22 cvs 1140:
1141: if (root)
1142: {
1.67 cvs 1143: ustrcpy (temppath, root);
1.25 cvs 1144: TtaFreeMemory (root);
1.22 cvs 1145: /* Get the suffix */
1146: ExtractSuffix (temppath, suffix);
1147:
1.87 cvs 1148: if( suffix[0] == WC_EOS)
1.22 cvs 1149: /* no suffix */
1150: return (FALSE);
1151:
1152: /* Normalize the suffix */
1153: ConvertToLowerCase (suffix);
1154:
1.67 cvs 1155: if (!ustrcmp (suffix, TEXT("gz")))
1.22 cvs 1156: /* skip the compressed suffix */
1157: {
1158: ExtractSuffix (temppath, suffix);
1.87 cvs 1159: if(suffix[0] == WC_EOS)
1.22 cvs 1160: /* no suffix */
1161: return (FALSE);
1162: /* Normalize the suffix */
1163: ConvertToLowerCase (suffix);
1164: }
1165:
1.67 cvs 1166: if (ustrcmp (suffix, TEXT("gif")) &&
1167: ustrcmp (suffix, TEXT("xbm")) &&
1168: ustrcmp (suffix, TEXT("xpm")) &&
1169: ustrcmp (suffix, TEXT("jpg")) &&
1170: ustrcmp (suffix, TEXT("pdf")) &&
1171: ustrcmp (suffix, TEXT("png")) &&
1172: ustrcmp (suffix, TEXT("tgz")) &&
1173: ustrcmp (suffix, TEXT("xpg")) &&
1174: ustrcmp (suffix, TEXT("xpd")) &&
1175: ustrcmp (suffix, TEXT("ps")) &&
1176: ustrcmp (suffix, TEXT("au")) &&
1177: ustrcmp (suffix, TEXT("html")) &&
1178: ustrcmp (suffix, TEXT("htm")) &&
1179: ustrcmp (suffix, TEXT("shtml")) &&
1180: ustrcmp (suffix, TEXT("xht")) &&
1181: ustrcmp (suffix, TEXT("xhtm")) &&
1182: ustrcmp (suffix, TEXT("xhtml")) &&
1183: ustrcmp (suffix, TEXT("txt")) &&
1184: ustrcmp (suffix, TEXT("css")) &&
1185: ustrcmp (suffix, TEXT("eps")))
1.22 cvs 1186: return (FALSE);
1187: else
1188: return (TRUE);
1189: }
1190: else
1191: return (FALSE);
1192: }
1193:
1194:
1195: /*----------------------------------------------------------------------
1.24 cvs 1196: ChopURL
1197: Gives back a URL no longer than MAX_PRINT_URL_LENGTH chars (outputURL).
1198: If inputURL is bigger than that size, outputURL receives
1199: MAX_PRINT_URL_LENGTH / 2 chars from the beginning of inputURL, "...",
1200: and MAX_PRINT_URL_LENGTH / 2 chars from the end of inputURL.
1201: If inputURL is not longer than MAX_PRINT_URL_LENGTH chars, it gets
1202: copied into outputURL.
1203: N.B.: outputURL must point to a memory block of MAX_PRINT_URL_LENGTH
1204: chars.
1205: ----------------------------------------------------------------------*/
1206: #ifdef __STDC__
1.86 cvs 1207: void ChopURL (CHAR_T* outputURL, const CHAR_T* inputURL)
1.24 cvs 1208: #else
1209: void ChopURL (outputURL, inputURL)
1.86 cvs 1210: CHAR_T* outputURL;
1211: const CHAR_T* inputURL;
1.24 cvs 1212: #endif
1.22 cvs 1213:
1.24 cvs 1214: {
1215: int len;
1.9 cvs 1216:
1.86 cvs 1217: len = ustrlen (inputURL);
1.24 cvs 1218: if (len <= MAX_PRINT_URL_LENGTH)
1.86 cvs 1219: ustrcpy (outputURL, inputURL);
1.24 cvs 1220: else
1221: /* make a truncated urlName on the status window */
1222: {
1.86 cvs 1223: ustrncpy (outputURL, inputURL, MAX_PRINT_URL_LENGTH / 2);
1224: outputURL [MAX_PRINT_URL_LENGTH / 2] = WC_EOS;
1225: ustrcat (outputURL, TEXT("..."));
1226: ustrcat (outputURL, &(inputURL[len - MAX_PRINT_URL_LENGTH / 2 ]));
1.24 cvs 1227: }
1.25 cvs 1228: }
1229:
1230:
1231: /*----------------------------------------------------------------------
1232: scan
1.47 cvs 1233: Scan a filename for its constituents
1.25 cvs 1234: -----------------------------------
1235:
1236: On entry,
1237: name points to a document name which may be incomplete.
1238: On exit,
1239: absolute or relative may be nonzero (but not both).
1240: host, fragment and access may be nonzero if they were specified.
1241: Any which are nonzero point to zero terminated strings.
1242: ----------------------------------------------------------------------*/
1243: #ifdef __STDC__
1.67 cvs 1244: static void scan (STRING name, HTURI * parts)
1.25 cvs 1245: #else /* __STDC__ */
1246: static void scan (name, parts)
1.67 cvs 1247: STRING name;
1248: HTURI *parts;
1.25 cvs 1249:
1250: #endif /* __STDC__ */
1251: {
1.67 cvs 1252: STRING p;
1253: STRING after_access = name;
1.32 cvs 1254:
1.43 cvs 1255: memset (parts, '\0', sizeof (HTURI));
1.28 cvs 1256: /* Look for fragment identifier */
1.67 cvs 1257: if ((p = ustrchr(name, TEXT('#'))) != NULL)
1.28 cvs 1258: {
1.67 cvs 1259: *p++ = TEXT('\0');
1.28 cvs 1260: parts->fragment = p;
1.25 cvs 1261: }
1262:
1.28 cvs 1263: for (p=name; *p; p++)
1264: {
1.67 cvs 1265: if (*p == URL_SEP || *p == DIR_SEP || *p == TEXT('#') || *p == TEXT('?'))
1.28 cvs 1266: break;
1.67 cvs 1267: if (*p == TEXT(':'))
1.28 cvs 1268: {
1269: *p = 0;
1270: parts->access = after_access; /* Scheme has been specified */
1271:
1272: /* The combination of gcc, the "-O" flag and the HP platform is
1273: unhealthy. The following three lines is a quick & dirty fix, but is
1274: not recommended. Rather, turn off "-O". */
1275:
1276: /* after_access = p;*/
1277: /* while (*after_access == 0)*/
1278: /* after_access++;*/
1279: after_access = p+1;
1.67 cvs 1280: if (!ustrcasecmp(TEXT("URL"), parts->access))
1.28 cvs 1281: /* Ignore IETF's URL: pre-prefix */
1282: parts->access = NULL;
1283: else
1.25 cvs 1284: break;
1285: }
1286: }
1287:
1288: p = after_access;
1.43 cvs 1289: if (*p == URL_SEP || *p == DIR_SEP)
1.28 cvs 1290: {
1.43 cvs 1291: if (p[1] == URL_SEP)
1.28 cvs 1292: {
1.25 cvs 1293: parts->host = p+2; /* host has been specified */
1.28 cvs 1294: *p = 0; /* Terminate access */
1295: /* look for end of host name if any */
1.67 cvs 1296: p = ustrchr (parts->host, URL_SEP);
1.28 cvs 1297: if (p)
1298: {
1.87 cvs 1299: *p = WC_EOS; /* Terminate host */
1.25 cvs 1300: parts->absolute = p+1; /* Root has been found */
1.28 cvs 1301: }
1302: }
1303: else
1304: /* Root found but no host */
1305: parts->absolute = p+1;
1306: }
1307: else
1308: {
1.25 cvs 1309: parts->relative = (*after_access) ? after_access : 0; /* zero for "" */
1.28 cvs 1310: }
1.25 cvs 1311: }
1312:
1313:
1314: /*----------------------------------------------------------------------
1.28 cvs 1315: AmayaParseUrl: parse a Name relative to another name
1316:
1317: This returns those parts of a name which are given (and requested)
1318: substituting bits from the related name where necessary.
1.25 cvs 1319:
1.28 cvs 1320: On entry,
1.25 cvs 1321: aName A filename given
1322: relatedName A name relative to which aName is to be parsed. Give
1323: it an empty string if aName is absolute.
1324: wanted A mask for the bits which are wanted.
1325:
1.28 cvs 1326: On exit,
1.25 cvs 1327: returns A pointer to a malloc'd string which MUST BE FREED
1328: ----------------------------------------------------------------------*/
1329: #ifdef __STDC__
1.84 cvs 1330: CHAR_T* AmayaParseUrl (const CHAR_T* aName, CHAR_T* relatedName, int wanted)
1.25 cvs 1331: #else /* __STDC__ */
1.84 cvs 1332: CHAR_T* AmayaParseUrl (aName, relatedName, wanted)
1333: const CHAR_T* aName;
1334: CHAR_T* relatedName;
1.28 cvs 1335: int wanted;
1.25 cvs 1336:
1337: #endif /* __STDC__ */
1338: {
1.84 cvs 1339: CHAR_T* return_value;
1.67 cvs 1340: CHAR_T result[MAX_LENGTH];
1341: CHAR_T name[MAX_LENGTH];
1342: CHAR_T rel[MAX_LENGTH];
1.84 cvs 1343: CHAR_T *p, *access;
1.29 cvs 1344: HTURI given, related;
1345: int len;
1.67 cvs 1346: CHAR_T used_sep;
1.84 cvs 1347: CHAR_T* used_str;
1.32 cvs 1348:
1.84 cvs 1349: if (ustrchr (aName, WC_DIR_SEP) || ustrchr (relatedName, WC_DIR_SEP))
1.33 cvs 1350: {
1.84 cvs 1351: used_str = WC_DIR_STR;
1352: used_sep = WC_DIR_SEP;
1.33 cvs 1353: }
1.32 cvs 1354: else
1.33 cvs 1355: {
1.84 cvs 1356: used_str = WC_URL_STR;
1357: used_sep = WC_URL_SEP;
1.33 cvs 1358: }
1.32 cvs 1359:
1.29 cvs 1360: /* Make working copies of input strings to cut up: */
1361: return_value = NULL;
1362: result[0] = 0; /* Clear string */
1.67 cvs 1363: ustrcpy (name, aName);
1.29 cvs 1364: if (relatedName != NULL)
1.67 cvs 1365: ustrcpy (rel, relatedName);
1.29 cvs 1366: else
1.84 cvs 1367: relatedName[0] = WC_EOS;
1.29 cvs 1368:
1369: scan (name, &given);
1370: scan (rel, &related);
1371: access = given.access ? given.access : related.access;
1372: if (wanted & AMAYA_PARSE_ACCESS)
1373: if (access)
1374: {
1.67 cvs 1375: ustrcat (result, access);
1.29 cvs 1376: if(wanted & AMAYA_PARSE_PUNCTUATION)
1.67 cvs 1377: ustrcat (result, TEXT(":"));
1.29 cvs 1378: }
1379:
1380: if (given.access && related.access)
1381: /* If different, inherit nothing. */
1.67 cvs 1382: if (ustrcmp (given.access, related.access) != 0)
1.29 cvs 1383: {
1384: related.host = 0;
1385: related.absolute = 0;
1386: related.relative = 0;
1387: related.fragment = 0;
1388: }
1389:
1390: if (wanted & AMAYA_PARSE_HOST)
1391: if(given.host || related.host)
1392: {
1393: if(wanted & AMAYA_PARSE_PUNCTUATION)
1.67 cvs 1394: ustrcat (result, TEXT("//"));
1395: ustrcat (result, given.host ? given.host : related.host);
1.29 cvs 1396: }
1397:
1398: if (given.host && related.host)
1399: /* If different hosts, inherit no path. */
1.67 cvs 1400: if (ustrcmp (given.host, related.host) != 0)
1.29 cvs 1401: {
1402: related.absolute = 0;
1403: related.relative = 0;
1404: related.fragment = 0;
1405: }
1406:
1407: if (wanted & AMAYA_PARSE_PATH)
1408: {
1409: if (given.absolute)
1410: {
1411: /* All is given */
1412: if (wanted & AMAYA_PARSE_PUNCTUATION)
1.67 cvs 1413: ustrcat (result, used_str);
1414: ustrcat (result, given.absolute);
1.25 cvs 1415: }
1.29 cvs 1416: else if (related.absolute)
1417: {
1418: /* Adopt path not name */
1.67 cvs 1419: ustrcat (result, used_str);
1420: ustrcat (result, related.absolute);
1.29 cvs 1421: if (given.relative)
1422: {
1423: /* Search part? */
1.67 cvs 1424: p = ustrchr (result, TEXT('?'));
1.29 cvs 1425: if (!p)
1.67 cvs 1426: p=result+ustrlen(result)-1;
1.33 cvs 1427: for (; *p!=used_sep; p--); /* last / */
1.29 cvs 1428: /* Remove filename */
1429: p[1]=0;
1430: /* Add given one */
1.67 cvs 1431: ustrcat (result, given.relative);
1.25 cvs 1432: }
1433: }
1.29 cvs 1434: else if (given.relative)
1435: /* what we've got */
1.67 cvs 1436: ustrcat (result, given.relative);
1.29 cvs 1437: else if (related.relative)
1.67 cvs 1438: ustrcat (result, related.relative);
1.29 cvs 1439: else
1440: /* No inheritance */
1.67 cvs 1441: ustrcat (result, used_str);
1.25 cvs 1442: }
1.29 cvs 1443:
1444: if (wanted & AMAYA_PARSE_ANCHOR)
1445: if (given.fragment || related.fragment)
1446: {
1447: if (given.absolute && given.fragment)
1448: {
1449: /*Fixes for relURLs...*/
1450: if (wanted & AMAYA_PARSE_PUNCTUATION)
1.67 cvs 1451: ustrcat (result, TEXT("#"));
1452: ustrcat (result, given.fragment);
1.29 cvs 1453: }
1454: else if (!(given.absolute) && !(given.fragment))
1.84 cvs 1455: ustrcat (result, TEXT(""));
1.29 cvs 1456: else
1457: {
1458: if (wanted & AMAYA_PARSE_PUNCTUATION)
1.67 cvs 1459: ustrcat (result, TEXT("#"));
1460: ustrcat (result, given.fragment ? given.fragment : related.fragment);
1.29 cvs 1461: }
1462: }
1.67 cvs 1463: len = ustrlen (result);
1464: if ((return_value = TtaAllocString (len + 1)) != NULL)
1465: ustrcpy (return_value, result);
1.29 cvs 1466: return (return_value); /* exactly the right length */
1.25 cvs 1467: }
1468:
1469: /*----------------------------------------------------------------------
1470: HTCanon
1471: Canonicalizes the URL in the following manner starting from the host
1472: pointer:
1473:
1474: 1) The host name is converted to lowercase
1475: 2) Chop off port if `:80' (http), `:70' (gopher), or `:21' (ftp)
1476:
1477: Return: OK The position of the current path part of the URL
1478: which might be the old one or a new one.
1479:
1480: ----------------------------------------------------------------------*/
1481: #ifdef __STDC__
1.84 cvs 1482: static CHAR_T* HTCanon (CHAR_T** filename, CHAR_T* host)
1.25 cvs 1483: #else /* __STDC__ */
1.67 cvs 1484: static STRING HTCanon (filename, host)
1.84 cvs 1485: CHAR_T** filename;
1486: CHAR_T* host;
1.25 cvs 1487: #endif /* __STDC__ */
1488: {
1.84 cvs 1489: CHAR_T* newname = NULL;
1490: CHAR_T used_sep;
1491: CHAR_T* path;
1492: CHAR_T* strptr;
1493: CHAR_T* port;
1494: CHAR_T* access = host-3;
1.32 cvs 1495:
1496:
1.84 cvs 1497: if (*filename && ustrchr (*filename, WC_URL_SEP))
1.33 cvs 1498: {
1.84 cvs 1499: used_sep = WC_URL_SEP;
1.33 cvs 1500: }
1501: else
1502: {
1.84 cvs 1503: used_sep = WC_DIR_SEP;
1.33 cvs 1504: }
1.32 cvs 1505:
1.82 cvs 1506: while (access > *filename && *(access - 1) != used_sep) /* Find access method */
1.25 cvs 1507: access--;
1.84 cvs 1508: if ((path = ustrchr (host, used_sep)) == NULL) /* Find path */
1509: path = host + ustrlen (host);
1510: if ((strptr = ustrchr (host, TEXT('@'))) != NULL && strptr < path) /* UserId */
1.82 cvs 1511: host = strptr;
1.84 cvs 1512: if ((port = ustrchr (host, TEXT(':'))) != NULL && port > path) /* Port number */
1.82 cvs 1513: port = NULL;
1.25 cvs 1514:
1515: strptr = host; /* Convert to lower-case */
1.82 cvs 1516: while (strptr < path)
1.33 cvs 1517: {
1.84 cvs 1518: *strptr = utolower (*strptr);
1.82 cvs 1519: strptr++;
1.33 cvs 1520: }
1.25 cvs 1521:
1522: /* Does the URL contain a full domain name? This also works for a
1523: numerical host name. The domain name is already made lower-case
1524: and without a trailing dot. */
1525: {
1.84 cvs 1526: CHAR_T* dot = port ? port : path;
1527: if (dot > *filename && *--dot == TEXT('.'))
1.33 cvs 1528: {
1.84 cvs 1529: CHAR_T* orig = dot;
1530: CHAR_T* dest = dot + 1;
1.82 cvs 1531: while ((*orig++ = *dest++));
1532: if (port) port--;
1.33 cvs 1533: path--;
1.25 cvs 1534: }
1535: }
1536: /* Chop off port if `:', `:80' (http), `:70' (gopher), or `:21' (ftp) */
1.33 cvs 1537: if (port)
1538: {
1.82 cvs 1539: if (!*(port+1) || *(port+1) == used_sep)
1.33 cvs 1540: {
1541: if (!newname)
1542: {
1.84 cvs 1543: CHAR_T* orig = port;
1544: CHAR_T* dest = port + 1;
1.82 cvs 1545: while ((*orig++ = *dest++));
1.33 cvs 1546: }
1547: }
1.84 cvs 1548: else if ((!ustrncmp (access, TEXT("http"), 4) &&
1549: (*(port + 1) == TEXT('8') &&
1550: *(port+2) == TEXT('0') &&
1.82 cvs 1551: (*(port+3) == used_sep || !*(port + 3)))) ||
1.84 cvs 1552: (!ustrncmp (access, TEXT("gopher"), 6) &&
1553: (*(port+1) == TEXT('7') &&
1554: *(port+2) == TEXT('0') &&
1.82 cvs 1555: (*(port+3) == used_sep || !*(port+3)))) ||
1.84 cvs 1556: (!ustrncmp (access, TEXT("ftp"), 3) &&
1557: (*(port+1) == TEXT('2') &&
1558: *(port + 2) == TEXT('1') &&
1.82 cvs 1559: (*(port+3) == used_sep || !*(port+3))))) {
1.33 cvs 1560: if (!newname)
1561: {
1.84 cvs 1562: CHAR_T* orig = port;
1563: CHAR_T* dest = port + 3;
1.33 cvs 1564: while((*orig++ = *dest++));
1565: /* Update path position, Henry Minsky */
1566: path -= 3;
1.25 cvs 1567: }
1.33 cvs 1568: }
1569: else if (newname)
1.84 cvs 1570: ustrncat (newname, port, (int) (path - port));
1.33 cvs 1571: }
1.25 cvs 1572:
1.33 cvs 1573: if (newname)
1574: {
1.84 cvs 1575: CHAR_T* newpath = newname + ustrlen (newname);
1576: ustrcat (newname, path);
1.25 cvs 1577: path = newpath;
1.28 cvs 1578: /* Free old copy */
1579: TtaFreeMemory(*filename);
1.25 cvs 1580: *filename = newname;
1.33 cvs 1581: }
1.25 cvs 1582: return path;
1583: }
1584:
1585:
1586: /*----------------------------------------------------------------------
1.29 cvs 1587: SimplifyUrl: simplify a URI
1.32 cvs 1588: A URI is allowed to contain the sequence xxx/../ which may be
1589: replaced by "" , and the sequence "/./" which may be replaced by DIR_STR.
1.28 cvs 1590: Simplification helps us recognize duplicate URIs.
1.25 cvs 1591:
1.28 cvs 1592: Thus, /etc/junk/../fred becomes /etc/fred
1593: /etc/junk/./fred becomes /etc/junk/fred
1.25 cvs 1594:
1.28 cvs 1595: but we should NOT change
1596: http://fred.xxx.edu/../..
1.25 cvs 1597:
1598: or ../../albert.html
1599:
1.28 cvs 1600: In order to avoid empty URLs the following URLs become:
1.25 cvs 1601:
1602: /fred/.. becomes /fred/..
1603: /fred/././.. becomes /fred/..
1604: /fred/.././junk/.././ becomes /fred/..
1605:
1.28 cvs 1606: If more than one set of `://' is found (several proxies in cascade) then
1607: only the part after the last `://' is simplified.
1.25 cvs 1608:
1.28 cvs 1609: Returns: A string which might be the old one or a new one.
1.25 cvs 1610: ----------------------------------------------------------------------*/
1611: #ifdef __STDC__
1.84 cvs 1612: void SimplifyUrl (CHAR_T** url)
1.25 cvs 1613: #else /* __STDC__ */
1.29 cvs 1614: void SimplifyUrl (url)
1.84 cvs 1615: CHAR_T** url;
1.25 cvs 1616: #endif /* __STDC__ */
1617: {
1.84 cvs 1618: CHAR_T* path;
1619: CHAR_T* access;
1620: CHAR_T* newptr;
1621: CHAR_T* p;
1622: CHAR_T *orig, *dest, *end;
1.28 cvs 1623:
1.85 cvs 1624: CHAR_T used_sep;
1.77 cvs 1625: ThotBool ddot_simplify; /* used to desactivate the double dot simplifcation:
1626: something/../ simplification in relative URLs when they start with a ../ */
1.32 cvs 1627:
1628:
1.28 cvs 1629: if (!url || !*url)
1630: return;
1631:
1.84 cvs 1632: if (ustrchr (*url, WC_URL_SEP))
1.33 cvs 1633: {
1.84 cvs 1634: used_sep = WC_URL_SEP;
1.33 cvs 1635: }
1.32 cvs 1636: else
1.33 cvs 1637: {
1.84 cvs 1638: used_sep = WC_DIR_SEP;
1.33 cvs 1639: }
1.32 cvs 1640:
1.77 cvs 1641: /* should we simplify double dot? */
1642: path = *url;
1.84 cvs 1643: if (*path == TEXT('.') && *(path + 1) == TEXT('.'))
1.77 cvs 1644: ddot_simplify = FALSE;
1645: else
1646: ddot_simplify = TRUE;
1647:
1.28 cvs 1648: /* Find any scheme name */
1.84 cvs 1649: if ((path = ustrstr (*url, TEXT("://"))) != NULL)
1.33 cvs 1650: {
1651: /* Find host name */
1.28 cvs 1652: access = *url;
1.84 cvs 1653: while (access < path && (*access = utolower (*access)))
1.82 cvs 1654: access++;
1.28 cvs 1655: path += 3;
1.84 cvs 1656: while ((newptr = ustrstr (path, TEXT ("://"))) != NULL)
1.82 cvs 1657: /* For proxies */
1658: path = newptr+3;
1659: /* We have a host name */
1.84 cvs 1660: path = HTCanon (url, path);
1.25 cvs 1661: }
1.84 cvs 1662: else if ((path = ustrstr (*url, TEXT(":/"))) != NULL)
1.28 cvs 1663: path += 2;
1664: else
1665: path = *url;
1.25 cvs 1666:
1.84 cvs 1667: if (*path == used_sep && *(path+1) == used_sep)
1.28 cvs 1668: /* Some URLs start //<foo> */
1669: path += 1;
1.84 cvs 1670: else if (!ustrncmp (path, TEXT("news:"), 5))
1.28 cvs 1671: {
1.84 cvs 1672: newptr = ustrchr (path+5, TEXT('@'));
1.28 cvs 1673: if (!newptr)
1674: newptr = path + 5;
1675: while (*newptr)
1676: {
1677: /* Make group or host lower case */
1.84 cvs 1678: *newptr = utolower (*newptr);
1.28 cvs 1679: newptr++;
1.25 cvs 1680: }
1.28 cvs 1681: /* Doesn't need to do any more */
1682: return;
1.25 cvs 1683: }
1.28 cvs 1684:
1685: if ((p = path))
1686: {
1.67 cvs 1687: if (!((end = ustrchr (path, TEXT(';'))) || (end = ustrchr (path, TEXT('?'))) ||
1688: (end = ustrchr (path, TEXT('#')))))
1689: end = path + ustrlen (path);
1.28 cvs 1690:
1691: /* Parse string second time to simplify */
1692: p = path;
1693: while (p < end)
1694: {
1.77 cvs 1695: /* if we're pointing to a char, it's safe to reactivate the ../ convertion */
1696: if (!ddot_simplify && *p != TEXT('.') && *p != used_sep)
1697: ddot_simplify = TRUE;
1698:
1.33 cvs 1699: if (*p==used_sep)
1.28 cvs 1700: {
1.67 cvs 1701: if (p > *url && *(p+1) == TEXT('.') && (*(p+2) == used_sep || !*(p+2)))
1.28 cvs 1702: {
1703: orig = p + 1;
1.84 cvs 1704: dest = (*(p+2) != used_sep) ? p+2 : p+3;
1.52 cvs 1705: while ((*orig++ = *dest++)); /* Remove a used_sep and a dot*/
1.28 cvs 1706: end = orig - 1;
1707: }
1.77 cvs 1708: else if (ddot_simplify && *(p+1) == TEXT('.') && *(p+2) == TEXT('.')
1709: && (*(p+3) == used_sep || !*(p+3)))
1.28 cvs 1710: {
1711: newptr = p;
1.52 cvs 1712: while (newptr>path && *--newptr!=used_sep); /* prev used_sep */
1713: if (*newptr == used_sep)
1714: orig = newptr + 1;
1.28 cvs 1715: else
1.52 cvs 1716: orig = newptr;
1717:
1718: dest = (*(p+3) != used_sep) ? p+3 : p+4;
1719: while ((*orig++ = *dest++)); /* Remove /xxx/.. */
1720: end = orig-1;
1721: /* Start again with prev slash */
1722: p = newptr;
1.28 cvs 1723: }
1.33 cvs 1724: else if (*(p+1) == used_sep)
1.28 cvs 1725: {
1.33 cvs 1726: while (*(p+1) == used_sep)
1.28 cvs 1727: {
1728: orig = p;
1729: dest = p + 1;
1730: while ((*orig++ = *dest++)); /* Remove multiple /'s */
1731: end = orig-1;
1732: }
1733: }
1734: else
1.25 cvs 1735: p++;
1.28 cvs 1736: }
1737: else
1738: p++;
1.25 cvs 1739: }
1740: }
1.51 cvs 1741:
1742: /*
1743: ** Check for host/../.. kind of things
1744: */
1.77 cvs 1745: if (*path == used_sep && *(path+1) == TEXT('.') && *(path+2) == TEXT('.')
1746: && (!*(path+3) || *(path+3) == used_sep))
1.87 cvs 1747: *(path+1) = WC_EOS;
1.51 cvs 1748:
1.28 cvs 1749: return;
1750: }
1751:
1752:
1753: /*----------------------------------------------------------------------
1754: NormalizeFile normalizes local names.
1755: Return TRUE if target and src differ.
1756: ----------------------------------------------------------------------*/
1757: #ifdef __STDC__
1.84 cvs 1758: ThotBool NormalizeFile (CHAR_T* src, CHAR_T* target)
1.28 cvs 1759: #else
1.67 cvs 1760: ThotBool NormalizeFile (src, target)
1.84 cvs 1761: CHAR_T* src;
1762: CHAR_T* target;
1.28 cvs 1763:
1764: #endif
1765: {
1.84 cvs 1766: CHAR_T* s;
1.82 cvs 1767: ThotBool change;
1.28 cvs 1768:
1.54 cvs 1769: change = FALSE;
1.84 cvs 1770: if (ustrncmp (src, TEXT("file:"), 5) == 0)
1.28 cvs 1771: {
1772: /* remove the prefix file: */
1.84 cvs 1773: if (src[5] == WC_EOS)
1774: ustrcpy (target, WC_DIR_STR);
1775: else if (src[0] == TEXT('~'))
1.28 cvs 1776: {
1777: /* replace ~ */
1.74 cvs 1778: s = TtaGetEnvString ("HOME");
1.84 cvs 1779: ustrcpy (target, s);
1780: ustrcat (target, &src[5]);
1.28 cvs 1781: }
1782: else
1.84 cvs 1783: ustrcpy (target, &src[5]);
1.54 cvs 1784: change = TRUE;
1.28 cvs 1785: }
1.53 cvs 1786: # ifndef _WINDOWS
1.84 cvs 1787: else if (src[0] == TEXT('~'))
1.53 cvs 1788: {
1789: /* replace ~ */
1.82 cvs 1790: s = TtaGetEnvString ("HOME");
1.84 cvs 1791: ustrcpy (target, s);
1792: if (src[1] != WC_DIR_SEP)
1793: ustrcat (target, WC_DIR_STR);
1794: ustrcat (target, &src[1]);
1.54 cvs 1795: change = TRUE;
1.53 cvs 1796: }
1797: # endif /* _WINDOWS */
1.28 cvs 1798: else
1.84 cvs 1799: ustrcpy (target, src);
1.28 cvs 1800:
1801: /* remove /../ and /./ */
1.29 cvs 1802: SimplifyUrl (&target);
1.54 cvs 1803: if (!change)
1.84 cvs 1804: change = ustrcmp (src, target);
1.28 cvs 1805: return (change);
1.25 cvs 1806: }
1807:
1.28 cvs 1808:
1.25 cvs 1809: /*----------------------------------------------------------------------
1.31 cvs 1810: MakeRelativeURL: make relative name
1.25 cvs 1811:
1.28 cvs 1812: This function creates and returns a string which gives an expression of
1813: one address as related to another. Where there is no relation, an absolute
1814: address is retured.
1.25 cvs 1815:
1.28 cvs 1816: On entry,
1.25 cvs 1817: Both names must be absolute, fully qualified names of nodes
1818: (no fragment bits)
1819:
1.28 cvs 1820: On exit,
1.25 cvs 1821: The return result points to a newly allocated name which, if
1822: parsed by AmayaParseUrl relative to relatedName, will yield aName.
1823: The caller is responsible for freeing the resulting name later.
1824: ----------------------------------------------------------------------*/
1825: #ifdef __STDC__
1.67 cvs 1826: STRING MakeRelativeURL (STRING aName, STRING relatedName)
1.25 cvs 1827: #else /* __STDC__ */
1.67 cvs 1828: STRING MakeRelativeURL (aName, relatedName)
1829: STRING aName;
1830: STRING relatedName;
1.25 cvs 1831: #endif /* __STDC__ */
1832: {
1.87 cvs 1833: CHAR_T* return_value;
1.67 cvs 1834: CHAR_T result[MAX_LENGTH];
1.87 cvs 1835: CHAR_T* p;
1836: CHAR_T* q;
1837: CHAR_T* after_access;
1838: CHAR_T* last_slash = NULL;
1.29 cvs 1839: int slashes, levels, len;
1840:
1.44 cvs 1841: # ifdef _WINDOWS
1842: int ndx;
1843: # endif /* _WINDOWS */
1844:
1.29 cvs 1845: if (aName == NULL || relatedName == NULL)
1846: return (NULL);
1847:
1848: slashes = 0;
1849: after_access = NULL;
1850: p = aName;
1851: q = relatedName;
1852: for (; *p && (*p == *q); p++, q++)
1.27 cvs 1853: {
1854: /* Find extent of match */
1.67 cvs 1855: if (*p == TEXT(':'))
1.29 cvs 1856: after_access = p + 1;
1.28 cvs 1857: if (*p == DIR_SEP)
1.27 cvs 1858: {
1.29 cvs 1859: /* memorize the last slash position and count them */
1.27 cvs 1860: last_slash = p;
1861: slashes++;
1.25 cvs 1862: }
1863: }
1864:
1.31 cvs 1865: /* q, p point to the first non-matching character or zero */
1.87 cvs 1866: if (*q == WC_EOS)
1.31 cvs 1867: {
1868: /* New name is a subset of the related name */
1869: /* exactly the right length */
1.67 cvs 1870: len = ustrlen (p);
1871: if ((return_value = TtaAllocString (len + 1)) != NULL)
1872: ustrcpy (return_value, p);
1.31 cvs 1873: }
1874: else if ((slashes < 2 && after_access == NULL)
1875: || (slashes < 3 && after_access != NULL))
1876: {
1877: /* Two names whitout common path */
1878: /* exactly the right length */
1.67 cvs 1879: len = ustrlen (aName);
1880: if ((return_value = TtaAllocString (len + 1)) != NULL)
1881: ustrcpy (return_value, aName);
1.31 cvs 1882: }
1883: else
1884: {
1885: /* Some path in common */
1.67 cvs 1886: if (slashes == 3 && ustrncmp (aName, TEXT("http:"), 5) == 0)
1.31 cvs 1887: /* just the same server */
1.67 cvs 1888: ustrcpy (result, last_slash);
1.31 cvs 1889: else
1890: {
1891: levels= 0;
1.67 cvs 1892: for (; *q && *q != TEXT('#') && *q != TEXT(';') && *q != TEXT('?'); q++)
1.31 cvs 1893: if (*q == DIR_SEP)
1894: levels++;
1895:
1.87 cvs 1896: result[0] = WC_EOS;
1.31 cvs 1897: for (;levels; levels--)
1.67 cvs 1898: ustrcat (result, TEXT("../"));
1899: ustrcat (result, last_slash+1);
1.31 cvs 1900: }
1.52 cvs 1901:
1902: if (!*result)
1.67 cvs 1903: ustrcat (result, TEXT("./"));
1.52 cvs 1904:
1.31 cvs 1905: /* exactly the right length */
1.67 cvs 1906: len = ustrlen (result);
1907: if ((return_value = TtaAllocString (len + 1)) != NULL)
1908: ustrcpy (return_value, result);
1.52 cvs 1909:
1.25 cvs 1910: }
1.44 cvs 1911: # ifdef _WINDOWS
1.67 cvs 1912: len = ustrlen (return_value);
1.44 cvs 1913: for (ndx = 0; ndx < len; ndx ++)
1.67 cvs 1914: if (return_value[ndx] == TEXT('\\'))
1915: return_value[ndx] = TEXT('/') ;
1.44 cvs 1916: # endif /* _WINDOWS */
1.29 cvs 1917: return (return_value);
1.24 cvs 1918: }
1.35 cvs 1919:
1920:
Webmaster