Annotation of Amaya/amaya/AHTURLTools.c, revision 1.28
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
14: *
15: */
1.7 cvs 16:
1.8 cvs 17: /* Amaya includes */
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: /* Local definitions */
25:
26: #define MAX_PRINT_URL_LENGTH 50
27:
1.28 ! cvs 28:
! 29: /*----------------------------------------------------------------------
! 30: ConvertToLowerCase
! 31: Converts a string to lowercase.
! 32: ----------------------------------------------------------------------*/
1.22 cvs 33: #ifdef __STDC__
1.28 ! cvs 34: static void ConvertToLowerCase (char *string)
! 35: #else /* __STDC__ */
! 36: static void ConvertToLowerCase (string)
! 37: char *string;
! 38:
! 39: #endif /* __STDC__ */
! 40: {
! 41: int i;
! 42:
! 43: if (!string)
! 44: return;
! 45:
! 46: for (i = 0; string[i] != EOS; i++)
! 47: string[i] = tolower (string[i]);
! 48: }
1.22 cvs 49:
1.8 cvs 50: /*----------------------------------------------------------------------
1.11 cvs 51: ExplodeURL
1.8 cvs 52: ----------------------------------------------------------------------*/
53: #ifdef __STDC__
54: void ExplodeURL (char *url, char **proto, char **host, char **dir, char **file)
55: #else
56: void ExplodeURL (url, proto, host, dir, file)
57: char *url;
58: char **proto;
59: char **host;
60: char **dir;
61: char **file;
62:
63: #endif
64: {
1.9 cvs 65: char *curr, *temp;
1.8 cvs 66:
67: if ((url == NULL) || (proto == NULL) || (host == NULL) ||
68: (dir == NULL) || (file == NULL))
69: return;
70:
71: /* initialize every pointer */
72: *proto = *host = *dir = *file = NULL;
73:
74: /* skip any leading space */
75: while ((*url == SPACE) || (*url == TAB))
76: url++;
1.9 cvs 77: curr = url;
78: if (*curr == 0)
1.8 cvs 79: goto finished;
80:
81: /* go to the end of the URL */
1.9 cvs 82: while ((*curr != 0) && (*curr != SPACE) && (*curr != '\b') &&
83: (*curr != '\r') && (*curr != EOL))
84: curr++;
1.8 cvs 85:
86: /* mark the end of the chain */
1.9 cvs 87: *curr = EOS;
88: curr--;
89: if (curr <= url)
1.8 cvs 90: goto finished;
91:
92: /* search the next DIR_SEP indicating the beginning of the file name */
93: do
1.11 cvs 94: curr--;
1.9 cvs 95: while ((curr >= url) && (*curr != DIR_SEP));
1.11 cvs 96:
1.9 cvs 97: if (curr < url)
1.8 cvs 98: goto finished;
1.9 cvs 99: *file = curr + 1;
1.8 cvs 100:
101: /* mark the end of the dir */
1.9 cvs 102: *curr = EOS;
103: curr--;
104: if (curr < url)
1.8 cvs 105: goto finished;
106:
107: /* search for the "/" indicating the host name start */
1.9 cvs 108: while ((curr > url) && ((*curr != DIR_SEP) || (*(curr + 1) != DIR_SEP)))
109: curr--;
1.8 cvs 110:
111: /* if we found it, separate the host name from the directory */
1.9 cvs 112: if ((*curr == DIR_SEP) && (*(curr + 1) == DIR_SEP))
1.8 cvs 113: {
1.9 cvs 114: *host = temp = curr + 2;
1.8 cvs 115: while ((*temp != 0) && (*temp != DIR_SEP))
116: temp++;
117: if (*temp == DIR_SEP)
118: {
119: *temp = EOS;
120: *dir = temp + 1;
121: }
122: }
123: else
1.11 cvs 124: *dir = curr;
125:
1.9 cvs 126: if (curr <= url)
1.8 cvs 127: goto finished;
128:
129: /* mark the end of the proto */
1.9 cvs 130: *curr = EOS;
131: curr--;
132: if (curr < url)
1.8 cvs 133: goto finished;
134:
1.9 cvs 135: if (*curr == ':')
1.8 cvs 136: {
1.9 cvs 137: *curr = EOS;
138: curr--;
1.8 cvs 139: }
140: else
141: goto finished;
1.11 cvs 142:
1.9 cvs 143: if (curr < url)
1.8 cvs 144: goto finished;
1.9 cvs 145: while ((curr > url) && (isalpha (*curr)))
146: curr--;
147: *proto = curr;
1.8 cvs 148:
149: finished:;
150:
151: #ifdef AMAYA_DEBUG
152: fprintf (stderr, "ExplodeURL(%s)\n\t", url);
153: if (*proto)
154: fprintf (stderr, "proto : %s, ", *proto);
155: if (*host)
156: fprintf (stderr, "host : %s, ", *host);
157: if (*dir)
158: fprintf (stderr, "dir : %s, ", *dir);
159: if (*file)
160: fprintf (stderr, "file : %s ", *file);
161: fprintf (stderr, "\n");
162: #endif
163:
164: }
1.3 cvs 165:
1.4 cvs 166: /*----------------------------------------------------------------------
1.9 cvs 167: IsHTMLName
168: returns TRUE if path points to an HTML resource.
1.4 cvs 169: ----------------------------------------------------------------------*/
1.3 cvs 170: #ifdef __STDC__
171: boolean IsHTMLName (char *path)
172: #else /* __STDC__ */
173: boolean IsHTMLName (path)
174: char *path;
175: #endif /* __STDC__ */
176: {
1.5 cvs 177: char temppath[MAX_LENGTH];
178: char suffix[MAX_LENGTH];
179: char nsuffix[MAX_LENGTH];
180: int i;
181:
182: if (!path)
1.13 cvs 183: return (FALSE);
1.5 cvs 184:
185: strcpy (temppath, path);
186: ExtractSuffix (temppath, suffix);
187:
188: /* Normalize the suffix */
189: i = 0;
190: while (suffix[i] != EOS)
1.13 cvs 191: {
1.25 cvs 192: nsuffix[i] = tolower (suffix[i]);
1.13 cvs 193: i++;
194: }
1.5 cvs 195: nsuffix[i] = EOS;
196: if ((strcmp (nsuffix, "html")) &&
197: (strcmp (nsuffix, "htm")) &&
198: (strcmp (nsuffix, "shtml")))
1.13 cvs 199: return (FALSE);
1.22 cvs 200: else if (!strcmp (nsuffix, "gz"))
1.13 cvs 201: {
202: /* take in account compressed files */
203: ExtractSuffix (temppath, suffix);
204: /* Normalize the suffix */
205: i = 0;
206: while (suffix[i] != EOS)
207: {
1.25 cvs 208: nsuffix[i] = tolower (suffix[i]);
1.13 cvs 209: i++;
210: }
211: nsuffix[i] = EOS;
212: if ((strcmp (nsuffix, "html")) &&
213: (strcmp (nsuffix, "htm")) &&
214: (strcmp (nsuffix, "shtml")))
215: return (FALSE);
216: else
217: return (TRUE);
218: }
219: else
220: return (TRUE);
1.3 cvs 221: }
222:
1.4 cvs 223: /*----------------------------------------------------------------------
1.9 cvs 224: IsImageName
225: returns TRUE if path points to an image resource.
1.4 cvs 226: ----------------------------------------------------------------------*/
1.3 cvs 227: #ifdef __STDC__
228: boolean IsImageName (char *path)
229: #else /* __STDC__ */
230: boolean IsImageName (path)
231: char *path;
232: #endif /* __STDC__ */
233: {
1.5 cvs 234: char temppath[MAX_LENGTH];
235: char suffix[MAX_LENGTH];
236: char nsuffix[MAX_LENGTH];
237: int i;
238:
239: if (!path)
1.13 cvs 240: return (FALSE);
1.5 cvs 241:
242: strcpy (temppath, path);
243: ExtractSuffix (temppath, suffix);
244:
245: /* Normalize the suffix */
246: i = 0;
247: while (suffix[i] != EOS)
1.13 cvs 248: {
1.25 cvs 249: nsuffix[i] = tolower (suffix[i]);
1.13 cvs 250: i++;
251: }
1.5 cvs 252: nsuffix[i] = EOS;
253: if ((strcmp (nsuffix, "gif")) && (strcmp (nsuffix, "xbm")) &&
254: (strcmp (nsuffix, "xpm")) && (strcmp (nsuffix, "jpg")) &&
255: (strcmp (nsuffix, "png")) && (strcmp (nsuffix, "au")))
1.13 cvs 256: return (FALSE);
257: return (TRUE);
1.3 cvs 258: }
259:
1.4 cvs 260: /*----------------------------------------------------------------------
1.9 cvs 261: IsTextName
1.4 cvs 262: ----------------------------------------------------------------------*/
1.3 cvs 263: #ifdef __STDC__
264: boolean IsTextName (char *path)
265: #else /* __STDC__ */
266: boolean IsTextName (path)
267: char *path;
268:
269: #endif /* __STDC__ */
270: {
1.5 cvs 271: char temppath[MAX_LENGTH];
272: char suffix[MAX_LENGTH];
273: char nsuffix[MAX_LENGTH];
274: int i;
275:
276: if (!path)
1.13 cvs 277: return (FALSE);
1.5 cvs 278:
279: strcpy (temppath, path);
280: ExtractSuffix (temppath, suffix);
281:
282: /* Normalize the suffix */
283: i = 0;
284: while (suffix[i] != EOS)
285: {
1.25 cvs 286: nsuffix[i] = tolower (suffix[i]);
1.5 cvs 287: i++;
288: }
289: nsuffix[i] = EOS;
290:
291: if ((strcmp (nsuffix, "gif")) && (strcmp (nsuffix, "xbm")) &&
292: (strcmp (nsuffix, "xpm")) && (strcmp (nsuffix, "jpg")) &&
293: (strcmp (nsuffix, "pdf")) && (strcmp (nsuffix, "png")) &&
1.22 cvs 294: (strcmp (nsuffix, "tgz")) && (strcmp (nsuffix, "tar")) &&
295: (strcmp (nsuffix, "xpg")) && (strcmp (nsuffix, "xpd")) &&
296: (strcmp (nsuffix, "ps")) && (strcmp (nsuffix, "au")))
1.13 cvs 297: return (TRUE);
1.22 cvs 298: else if (!strcmp (nsuffix, "gz"))
1.13 cvs 299: {
300: /* take in account compressed files */
301: ExtractSuffix (temppath, suffix);
302: /* Normalize the suffix */
303: i = 0;
304: while (suffix[i] != EOS)
305: {
1.25 cvs 306: nsuffix[i] = tolower (suffix[i]);
1.13 cvs 307: i++;
308: }
309: nsuffix[i] = EOS;
310: if ((!strcmp (nsuffix, "html")) ||
311: (!strcmp (nsuffix, "htm")) ||
312: (!strcmp (nsuffix, "shtml")))
313: return (TRUE);
314: else
315: return (FALSE);
316: }
317: else
318: return (FALSE);
1.3 cvs 319: }
320:
1.4 cvs 321: /*----------------------------------------------------------------------
1.9 cvs 322: IsHTTPPath
323: returns TRUE if path is in fact an http URL.
1.4 cvs 324: ----------------------------------------------------------------------*/
1.3 cvs 325: #ifdef __STDC__
326: boolean IsHTTPPath (char *path)
327: #else /* __STDC__ */
328: boolean IsHTTPPath (path)
329: char *path;
330: #endif /* __STDC__ */
331: {
1.5 cvs 332: if (!path)
333: return FALSE;
1.3 cvs 334:
1.5 cvs 335: if (strncmp (path, "http:", 5) != 0)
336: return FALSE;
337: return TRUE;
1.3 cvs 338: }
339:
1.4 cvs 340: /*----------------------------------------------------------------------
1.9 cvs 341: IsWithParameters
342: returns TRUE if url has a concatenated query string.
1.4 cvs 343: ----------------------------------------------------------------------*/
1.3 cvs 344: #ifdef __STDC__
1.9 cvs 345: boolean IsWithParameters (char *url)
1.3 cvs 346: #else /* __STDC__ */
1.9 cvs 347: boolean IsWithParameters (url)
348: char *url;
1.3 cvs 349: #endif /* __STDC__ */
350: {
1.5 cvs 351: int i;
1.3 cvs 352:
1.9 cvs 353: if ((!url) || (url[0] == EOS))
1.5 cvs 354: return FALSE;
1.3 cvs 355:
1.9 cvs 356: i = strlen (url) - 1;
357: while (i > 0 && url[i--] != '?')
1.5 cvs 358: if (i < 0)
359: return FALSE;
1.3 cvs 360:
1.5 cvs 361: /* There is a parameter */
362: return TRUE;
1.3 cvs 363: }
364:
1.4 cvs 365: /*----------------------------------------------------------------------
1.9 cvs 366: IsW3Path
367: returns TRUE if path is in fact a URL.
1.4 cvs 368: ----------------------------------------------------------------------*/
1.3 cvs 369: #ifdef __STDC__
370: boolean IsW3Path (char *path)
371: #else /* __STDC__ */
372: boolean IsW3Path (path)
373: char *path;
374: #endif /* __STDC__ */
375: {
1.5 cvs 376: if ((strncmp (path, "http:", 5)) && (strncmp (path, "ftp:", 4)) &&
377: (strncmp (path, "telnet:", 7)) && (strncmp (path, "wais:", 5)) &&
378: (strncmp (path, "news:", 5)) && (strncmp (path, "gopher:", 7)) &&
379: (strncmp (path, "mailto:", 7)) && (strncmp (path, "archie:", 7)))
380: return FALSE;
381: return TRUE;
1.3 cvs 382: }
383:
1.4 cvs 384: /*----------------------------------------------------------------------
1.9 cvs 385: IsValidProtocol
386: returns true if the url protocol is supported by Amaya.
1.4 cvs 387: ----------------------------------------------------------------------*/
1.3 cvs 388: #ifdef __STDC__
1.9 cvs 389: boolean IsValidProtocol (char *url)
1.3 cvs 390: #else /* __STDC__ */
1.9 cvs 391: boolean IsValidProtocol (url)
392: char *url;
1.3 cvs 393: #endif /* __STDC__ */
394: {
1.26 cvs 395: if (!strncmp (url, "http:", 5))
1.22 cvs 396: /* experimental */
1.26 cvs 397: /*** || !strncmp (url, "ftp:", 4)) ***/
1.24 cvs 398: /*** || !strncmp (path, "news:", 5)***/
1.8 cvs 399: return (TRUE);
1.5 cvs 400: else
1.8 cvs 401: return (FALSE);
1.3 cvs 402: }
403:
1.4 cvs 404: /*----------------------------------------------------------------------
1.9 cvs 405: NormalizeURL
406: normalizes orgName according to a base associated with doc, and
407: following the standard URL format rules.
408: The function returns the new complete and normalized URL
1.12 cvs 409: or file name path (newName) and the name of the document (docName).
1.9 cvs 410: N.B. If the function can't find out what's the docName, it assigns
411: the name "noname.html".
1.4 cvs 412: ----------------------------------------------------------------------*/
1.3 cvs 413: #ifdef __STDC__
414: void NormalizeURL (char *orgName, Document doc, char *newName, char *docName)
415: #else /* __STDC__ */
416: void NormalizeURL (orgName, doc, newName, docName)
417: char *orgName;
418: Document doc;
419: char *newName;
420: char *docName;
421: #endif /* __STDC__ */
422: {
1.5 cvs 423: char basename[MAX_LENGTH];
1.18 cvs 424: char tempOrgName[MAX_LENGTH];
1.5 cvs 425: char *ptr;
426: Element el;
427: ElementType elType;
428: AttributeType attrType;
1.18 cvs 429: Attribute attrHREF = NULL;
1.5 cvs 430: int length;
431:
432: if (!newName || !docName)
433: return;
1.18 cvs 434:
435: /*
436: ** First Step: Clean orgName
437: ** Make sure we have a complete orgName, without any leading or trailing
438: ** white spaces, or trailinbg new lines
439: */
440:
1.5 cvs 441: ptr = orgName;
1.18 cvs 442: /* skip leading white space and new line characters */
1.19 cvs 443: while ((*ptr == ' ' || *ptr == EOL) && *ptr++ != EOS);
1.18 cvs 444: strcpy (tempOrgName, ptr);
445: /* clean trailing white space */
446: ptr = strchr (tempOrgName, ' ');
447: if (ptr)
448: *ptr = EOS;
449: /* clean trailing new lines */
1.19 cvs 450: ptr = strchr (tempOrgName, EOL);
1.5 cvs 451: if (ptr)
452: *ptr = EOS;
453:
1.18 cvs 454: /*
455: ** Second Step: make orgName a complete URL
456: ** If the URL does not include a protocol, then
457: ** try to calculate one using the doc's base element
458: ** (if it exists),
459: */
1.21 cvs 460: if (tempOrgName[0] == EOS)
461: {
462: newName[0] = EOS;
463: return;
464: }
465: else if (IsW3Path (tempOrgName))
466: {
467: /* the name is complete, go to the Sixth Step */
468: strcpy (newName, tempOrgName);
469: /* verify if the URL has the form "protocol://server:port" */
1.25 cvs 470: ptr = AmayaParseUrl (newName, "", AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST |
471: AMAYA_PARSE_PUNCTUATION);
1.21 cvs 472: if (ptr && !strcmp (ptr, newName))
473: {
474: /* it has this form, we complete it by adding a "/" */
475: strcat (newName, "/");
476: }
477: if (ptr)
1.25 cvs 478: TtaFreeMemory (ptr);
1.21 cvs 479: }
480: else if ( doc == 0)
1.19 cvs 481: /* the name is complete, go to the Sixth Step */
1.18 cvs 482: strcpy (newName, tempOrgName);
1.5 cvs 483: else
484: {
1.18 cvs 485: /* take into account the BASE element. */
1.22 cvs 486: length = MAX_LENGTH -1;
1.18 cvs 487: /* get the root element */
488: el = TtaGetMainRoot (doc);
489:
490: /* search the BASE element */
491: elType.ElSSchema = TtaGetDocumentSSchema (doc);
492: elType.ElTypeNum = HTML_EL_BASE;
493: el = TtaSearchTypedElement (elType, SearchInTree, el);
494: if (el)
1.17 cvs 495: {
1.18 cvs 496: /*
497: ** The document has a BASE element
498: ** Get the HREF attribute of the BASE Element
499: */
500: attrType.AttrSSchema = elType.ElSSchema;
501: attrType.AttrTypeNum = HTML_ATTR_HREF_;
502: attrHREF = TtaGetAttribute (el, attrType);
503: if (attrHREF)
1.14 cvs 504: {
1.18 cvs 505: /* Use the base path of the document */
506: TtaGiveTextAttributeValue (attrHREF, basename, &length);
507: /* base and orgName have to be separated by a DIR_SEP */
1.20 cvs 508: length--;
1.28 ! cvs 509: if (basename[0] != EOS && basename[length] != DIR_SEP)
1.18 cvs 510: /* verify if the base has the form "protocol://server:port" */
1.14 cvs 511: {
1.25 cvs 512: ptr = AmayaParseUrl (basename, "", AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST |
513: AMAYA_PARSE_PUNCTUATION);
1.18 cvs 514: if (ptr && !strcmp (ptr, basename))
1.14 cvs 515: {
1.18 cvs 516: /* it has this form, we complete it by adding a "/" */
517: strcat (basename, "/");
518: length++;
1.14 cvs 519: }
1.18 cvs 520: if (ptr)
1.25 cvs 521: TtaFreeMemory (ptr);
1.14 cvs 522: }
1.19 cvs 523: /* Third Step: prepare the base
524: ** Removing anything after the
525: ** last DIR_SEP char. If no such char is found, then search for
526: ** the first ":" char, hoping that what's before that is a
527: ** protocol. If found, end the string there. If neither
528: ** char is found, then discard the whole base element.
529: */
530:
531: /* search for the last DIR_SEP char */
1.18 cvs 532: while (length >= 0 && basename[length] != DIR_SEP)
1.19 cvs 533: length--;
534: if (length >= 0)
535: /* found the last DIR_SEP char, end the string there */
536: basename[length + 1] = EOS;
537: else
538: /* search for the first ":" char */
539: {
540: for (length = 0; basename[length] != ':' &&
1.20 cvs 541: basename[length] != EOS; length++);
1.19 cvs 542: if (basename[length] == ':')
543: /* found, so end the string there */
544: basename[length + 1] = EOS;
545: else
546: /* not found, discard the base */
547: basename[0] = EOS;
548: }
1.14 cvs 549: }
550: else
551: basename[0] = EOS;
1.18 cvs 552: }
1.22 cvs 553:
1.18 cvs 554: /*
1.19 cvs 555: ** Fourth Step:
1.18 cvs 556: ** If there's no base element, and if we're following
1.19 cvs 557: ** a link, use the URL of the current document as a base.
1.18 cvs 558: */
559:
560: if (!attrHREF)
561: {
562: if (DocumentURLs[(int) doc])
1.14 cvs 563: {
1.18 cvs 564: strcpy (basename, DocumentURLs[(int) doc]);
565: /* base and orgName have to be separated by a DIR_SEP */
566: length = strlen (basename) - 1;
1.19 cvs 567: /* search for the last DIR_SEP char */
1.18 cvs 568: while (length >= 0 && basename[length] != DIR_SEP)
1.19 cvs 569: length--;
570: if (length >= 0)
571: /* found the last DIR_SEP char, end the string there */
572: basename[length + 1] = EOS;
573: else
574: /* search for the first ":" char */
575: {
576: for (length = 0; basename[length] != ':' &&
577: basename[length] != EOS; length ++);
578: if (basename[length] == ':')
579: /* found, so end the string there */
580: basename[length + 1] = EOS;
581: else
582: /* not found, discard the base */
583: basename[0] = EOS;
584: }
1.14 cvs 585: }
586: else
1.19 cvs 587: basename[0] = EOS;
1.14 cvs 588: }
1.22 cvs 589:
1.18 cvs 590: /*
1.19 cvs 591: ** Fifth Step, calculate the absolute URL, using the base
1.18 cvs 592: */
593:
1.25 cvs 594: ptr = AmayaParseUrl (tempOrgName, basename, AMAYA_PARSE_ALL);
1.16 cvs 595:
1.14 cvs 596: if (ptr)
597: {
1.28 ! cvs 598: AmayaSimplifyUrl (&ptr);
1.14 cvs 599: strcpy (newName, ptr);
1.25 cvs 600: TtaFreeMemory (ptr);
1.14 cvs 601: }
602: else
1.18 cvs 603: newName[0] = EOS;
1.5 cvs 604: }
605:
1.18 cvs 606: /*
1.19 cvs 607: ** Sixth and last Step:
1.18 cvs 608: ** Prepare the docname that will refer to this ressource in the
1.19 cvs 609: ** .amaya directory. If the new URL finishes on DIR_SEP, then use
1.18 cvs 610: ** noname.html as a default ressource name
611: */
1.19 cvs 612:
613: if (newName[0] != EOS)
1.5 cvs 614: {
1.19 cvs 615: length = strlen (newName) - 1;
1.18 cvs 616: if (newName[length] == DIR_SEP)
617: {
618: /* docname was not comprised inside the URL, so let's */
619: /* assign the default ressource name */
620: strcpy (docName, "noname.html");
621: /* remove DIR_SEP at the end of complete path */
1.23 cvs 622: /* newName[length] = EOS; */
1.18 cvs 623: }
1.14 cvs 624: else
1.18 cvs 625: {
626: /* docname is comprised inside the URL */
627: while (length >= 0 && newName[length] != DIR_SEP)
628: length--;
629: if (length < 0)
630: strcpy (docName, newName);
631: else
632: strcpy (docName, &newName[length+1]);
633: }
1.19 cvs 634:
1.5 cvs 635: }
1.18 cvs 636: else
637: docName[0] = EOS;
638: }
1.3 cvs 639:
1.4 cvs 640: /*----------------------------------------------------------------------
1.9 cvs 641: IsSameHost
1.4 cvs 642: ----------------------------------------------------------------------*/
1.3 cvs 643: #ifdef __STDC__
644: boolean IsSameHost (char *url1, char *url2)
645: #else /* __STDC__ */
646: boolean IsSameHost (url1, url2)
647: char *path;
648: #endif /* __STDC__ */
649: {
1.5 cvs 650: char *basename_ptr1, *basename_ptr2;
651: boolean result;
1.3 cvs 652:
1.25 cvs 653: basename_ptr1 = AmayaParseUrl (url1, "", AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST | AMAYA_PARSE_PUNCTUATION);
654: basename_ptr2 = AmayaParseUrl (url2, "", AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST | AMAYA_PARSE_PUNCTUATION);
1.3 cvs 655:
1.5 cvs 656: if (strcmp (basename_ptr1, basename_ptr2))
1.8 cvs 657: result = FALSE;
1.5 cvs 658: else
1.8 cvs 659: result = TRUE;
1.3 cvs 660:
1.25 cvs 661: TtaFreeMemory (basename_ptr1);
662: TtaFreeMemory (basename_ptr2);
1.3 cvs 663:
1.5 cvs 664: return (result);
1.3 cvs 665: }
666:
667:
1.4 cvs 668: /*----------------------------------------------------------------------
1.9 cvs 669: AHTMakeRelativeURL
670: converts url into a relative url to base_url.
671: If succesful, returns the new URL, otherwise, it returns NULL.
672: The caller has to free the new URL.
1.4 cvs 673: ----------------------------------------------------------------------*/
1.3 cvs 674: #ifdef __STDC__
1.28 ! cvs 675: char *AHTMakeRelativeName (char *url, char *base_url)
1.3 cvs 676: #else /* __STDC__ */
1.28 ! cvs 677: char *AHTMakeRelativeName (url, base_url)
! 678: char url;
! 679: char base_url;
1.5 cvs 680:
1.3 cvs 681: #endif /* __STDC__ */
682: {
1.28 ! cvs 683: char *base_ptr, *url_ptr;
! 684: char *result;
1.5 cvs 685:
1.28 ! cvs 686: /* verify if we are in the same host */
! 687: base_ptr = AmayaParseUrl (base_url, "", AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST | AMAYA_PARSE_PUNCTUATION);
! 688: url_ptr = AmayaParseUrl (url, "", AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST | AMAYA_PARSE_PUNCTUATION);
! 689: if (!strcmp (base_ptr, url_ptr))
! 690: {
! 691: TtaFreeMemory (base_ptr);
! 692: TtaFreeMemory (url_ptr);
! 693:
! 694: /* Normalize the URLs */
! 695: base_ptr = AmayaParseUrl (base_url, "", AMAYA_PARSE_ALL);
! 696: url_ptr = AmayaParseUrl (url, "", AMAYA_PARSE_ALL);
! 697:
! 698: /* Use libwww to make relative name */
! 699: result = AmayaRelativeUrl (url_ptr, base_ptr);
! 700: TtaFreeMemory (base_ptr);
! 701: TtaFreeMemory (url_ptr);
! 702: }
! 703: else
! 704: result = (char *) NULL;
! 705:
! 706: return (result);
1.3 cvs 707: }
1.22 cvs 708: /*----------------------------------------------------------------------
709: HasKnownFileSuffix
710: returns TRUE if path points to a file ending with a suffix.
711: ----------------------------------------------------------------------*/
712: #ifdef __STDC__
713: boolean HasKnownFileSuffix (char *path)
714: #else /* __STDC__ */
715: boolean HasKnownFileSuffix (path)
716: char *path;
717: #endif /* __STDC__ */
718: {
719: char *root;
720: char temppath[MAX_LENGTH];
721: char suffix[MAX_LENGTH];
722:
1.24 cvs 723: if (!path || path[0] == EOS || path[strlen(path)] == DIR_SEP)
1.22 cvs 724: return (FALSE);
725:
1.25 cvs 726: root = AmayaParseUrl(path, (char *) NULL, AMAYA_PARSE_PATH | AMAYA_PARSE_PUNCTUATION);
1.22 cvs 727:
728: if (root)
729: {
730: strcpy (temppath, root);
1.25 cvs 731: TtaFreeMemory (root);
1.22 cvs 732: /* Get the suffix */
733: ExtractSuffix (temppath, suffix);
734:
735: if( suffix[0] == EOS)
736: /* no suffix */
737: return (FALSE);
738:
739: /* Normalize the suffix */
740: ConvertToLowerCase (suffix);
741:
1.23 cvs 742: if (!strcmp (suffix, "gz"))
1.22 cvs 743: /* skip the compressed suffix */
744: {
745: ExtractSuffix (temppath, suffix);
746: if(suffix[0] == EOS)
747: /* no suffix */
748: return (FALSE);
749: /* Normalize the suffix */
750: ConvertToLowerCase (suffix);
751: }
752:
753: if ((strcmp (suffix, "gif")) && (strcmp (suffix, "xbm")) &&
754: (strcmp (suffix, "xpm")) && (strcmp (suffix, "jpg")) &&
755: (strcmp (suffix, "pdf")) && (strcmp (suffix, "png")) &&
756: (strcmp (suffix, "tgz")) && (strcmp (suffix, "xpg")) &&
757: (strcmp (suffix, "xpd")) && (strcmp (suffix, "ps")) &&
758: (strcmp (suffix, "au")) && (strcmp (suffix, "html")) &&
759: (strcmp (suffix, "htm")) && (strcmp (suffix, "shtml")) &&
760: (strcmp (suffix, "txt")) && (strcmp (suffix, "css")) &&
761: (strcmp (suffix, "eps")))
762: return (FALSE);
763: else
764: return (TRUE);
765: }
766: else
767: return (FALSE);
768: }
769:
770:
771: /*----------------------------------------------------------------------
1.24 cvs 772: ChopURL
773: Gives back a URL no longer than MAX_PRINT_URL_LENGTH chars (outputURL).
774: If inputURL is bigger than that size, outputURL receives
775: MAX_PRINT_URL_LENGTH / 2 chars from the beginning of inputURL, "...",
776: and MAX_PRINT_URL_LENGTH / 2 chars from the end of inputURL.
777: If inputURL is not longer than MAX_PRINT_URL_LENGTH chars, it gets
778: copied into outputURL.
779: N.B.: outputURL must point to a memory block of MAX_PRINT_URL_LENGTH
780: chars.
781: ----------------------------------------------------------------------*/
782: #ifdef __STDC__
783: void ChopURL (char *outputURL, char *inputURL)
784: #else
785: void ChopURL (outputURL, inputURL)
786: char *outputURL;
787: char *inputURL;
788: #endif
1.22 cvs 789:
1.24 cvs 790: {
791: int len;
1.9 cvs 792:
1.24 cvs 793: len = strlen (inputURL);
794: if (len <= MAX_PRINT_URL_LENGTH)
795: {
796: strcpy (outputURL, inputURL);
797: }
798: else
799: /* make a truncated urlName on the status window */
800: {
801: strncpy (outputURL, inputURL, MAX_PRINT_URL_LENGTH / 2);
802: outputURL [MAX_PRINT_URL_LENGTH / 2] = EOS;
803: strcat (outputURL, "...");
804: strcat (outputURL, &(inputURL[len - MAX_PRINT_URL_LENGTH / 2 ]));
805: }
1.25 cvs 806: }
807:
808: /************************************************************************
809: * *
1.28 ! cvs 810: * Local Adaptation of the libWWW Library/src/AmayaParseUrl.c code. *
1.25 cvs 811: * *
812: ************************************************************************/
813:
814: #define StringAllocCopy(dest,src) { \
815: if (src == NULL) dest = NULL; \
816: else { \
817: if ((dest = (char *) TtaGetMemory(strlen(src) + 1)) == NULL) \
818: exit(1); \
819: else strcpy(dest, src); }} \
820:
821: typedef struct _HTURI {
822: char * access; /* Now known as "scheme" */
823: char * host;
824: char * absolute;
825: char * relative;
826: char * fragment;
827: } HTURI;
828:
829: /*----------------------------------------------------------------------
830: scan
831: Scan a filename for its consituents
832: -----------------------------------
833:
834: On entry,
835: name points to a document name which may be incomplete.
836: On exit,
837: absolute or relative may be nonzero (but not both).
838: host, fragment and access may be nonzero if they were specified.
839: Any which are nonzero point to zero terminated strings.
840: ----------------------------------------------------------------------*/
841: #ifdef __STDC__
842: static void scan (char * name, HTURI * parts)
843: #else /* __STDC__ */
844: static void scan (name, parts)
845: char *name;
846: HTURI *parts;
847:
848: #endif /* __STDC__ */
849: {
1.28 ! cvs 850: char * p;
! 851: char * after_access = name;
1.25 cvs 852:
1.28 ! cvs 853: memset(parts, '\0', sizeof(HTURI));
! 854: /* Look for fragment identifier */
! 855: if ((p = strrchr(name, '#')) != NULL)
! 856: {
! 857: *p++ = '\0';
! 858: parts->fragment = p;
1.25 cvs 859: }
860:
1.28 ! cvs 861: for (p=name; *p; p++)
! 862: {
! 863: if (*p==DIR_SEP || *p=='#' || *p=='?')
! 864: break;
! 865: if (*p==':')
! 866: {
! 867: *p = 0;
! 868: parts->access = after_access; /* Scheme has been specified */
! 869:
! 870: /* The combination of gcc, the "-O" flag and the HP platform is
! 871: unhealthy. The following three lines is a quick & dirty fix, but is
! 872: not recommended. Rather, turn off "-O". */
! 873:
! 874: /* after_access = p;*/
! 875: /* while (*after_access == 0)*/
! 876: /* after_access++;*/
! 877: after_access = p+1;
! 878: if (0==strcasecmp("URL", parts->access))
! 879: /* Ignore IETF's URL: pre-prefix */
! 880: parts->access = NULL;
! 881: else
1.25 cvs 882: break;
883: }
884: }
885:
886: p = after_access;
1.28 ! cvs 887: if (*p==DIR_SEP)
! 888: {
! 889: if (p[1]==DIR_SEP)
! 890: {
1.25 cvs 891: parts->host = p+2; /* host has been specified */
1.28 ! cvs 892: *p = 0; /* Terminate access */
! 893: /* look for end of host name if any */
! 894: p = strchr(parts->host,DIR_SEP);
! 895: if (p)
! 896: {
1.25 cvs 897: *p=0; /* Terminate host */
898: parts->absolute = p+1; /* Root has been found */
1.28 ! cvs 899: }
! 900: }
! 901: else
! 902: /* Root found but no host */
! 903: parts->absolute = p+1;
! 904: }
! 905: else
! 906: {
1.25 cvs 907: parts->relative = (*after_access) ? after_access : 0; /* zero for "" */
1.28 ! cvs 908: }
1.25 cvs 909: }
910:
911:
912: /*----------------------------------------------------------------------
1.28 ! cvs 913: AmayaParseUrl: parse a Name relative to another name
! 914:
! 915: This returns those parts of a name which are given (and requested)
! 916: substituting bits from the related name where necessary.
1.25 cvs 917:
1.28 ! cvs 918: On entry,
1.25 cvs 919: aName A filename given
920: relatedName A name relative to which aName is to be parsed. Give
921: it an empty string if aName is absolute.
922: wanted A mask for the bits which are wanted.
923:
1.28 ! cvs 924: On exit,
1.25 cvs 925: returns A pointer to a malloc'd string which MUST BE FREED
926: ----------------------------------------------------------------------*/
927: #ifdef __STDC__
1.28 ! cvs 928: char *AmayaParseUrl (char *aName, char *relatedName, int wanted)
1.25 cvs 929: #else /* __STDC__ */
1.28 ! cvs 930: char *AmayaParseUrl (aName, relatedName, wanted)
! 931: char *aName;
! 932: char *relatedName;
! 933: int wanted;
1.25 cvs 934:
935: #endif /* __STDC__ */
936: {
937: char * result = 0;
938: char * return_value = 0;
939: int len;
940: char * name = 0;
941: char * rel = 0;
942: char * p;
943: char * access;
944: HTURI given, related;
945:
946: if (!relatedName) /* HWL 23/8/94: dont dump due to NULL */
947: relatedName = "";
948:
949: /* Make working copies of input strings to cut up: */
950: len = strlen(aName)+strlen(relatedName)+10;
951: if ((result=(char *) TtaGetMemory(len)) == NULL) /* Lots of space: more than enough */
952: exit(1);
953: StringAllocCopy(name, aName);
954: StringAllocCopy(rel, relatedName);
955:
956: scan(name, &given);
957: scan(rel, &related);
958: result[0]=0; /* Clear string */
959: access = given.access ? given.access : related.access;
960: if (wanted & AMAYA_PARSE_ACCESS)
961: if (access) {
962: strcat(result, access);
963: if(wanted & AMAYA_PARSE_PUNCTUATION) strcat(result, ":");
964: }
965:
966: if (given.access && related.access) /* If different, inherit nothing. */
967: if (strcmp(given.access, related.access)!=0) {
968: related.host=0;
969: related.absolute=0;
970: related.relative=0;
971: related.fragment=0;
972: }
973:
974: if (wanted & AMAYA_PARSE_HOST)
975: if(given.host || related.host) {
976: if(wanted & AMAYA_PARSE_PUNCTUATION) strcat(result, "//");
977: strcat(result, given.host ? given.host : related.host);
978: }
979:
980: if (given.host && related.host) /* If different hosts, inherit no path. */
981: if (strcmp(given.host, related.host)!=0) {
982: related.absolute=0;
983: related.relative=0;
984: related.fragment=0;
985: }
986:
987: if (wanted & AMAYA_PARSE_PATH) {
988: if(given.absolute) { /* All is given */
989: if(wanted & AMAYA_PARSE_PUNCTUATION) strcat(result, "/");
990: strcat(result, given.absolute);
991: } else if(related.absolute) { /* Adopt path not name */
992: strcat(result, "/");
993: strcat(result, related.absolute);
994: if (given.relative) {
995: p = strchr(result, '?'); /* Search part? */
996: if (!p) p=result+strlen(result)-1;
1.28 ! cvs 997: for (; *p!=DIR_SEP; p--); /* last / */
1.25 cvs 998: p[1]=0; /* Remove filename */
999: strcat(result, given.relative); /* Add given one */
1.28 ! cvs 1000: /*AmayaSimplifyUrl (&result);*/
1.25 cvs 1001: }
1002: } else if(given.relative) {
1003: strcat(result, given.relative); /* what we've got */
1004: } else if(related.relative) {
1005: strcat(result, related.relative);
1006: } else { /* No inheritance */
1007: strcat(result, "/");
1008: }
1009: }
1010:
1011: if (wanted & AMAYA_PARSE_ANCHOR)
1012: if(given.fragment || related.fragment) {
1013: if(given.absolute && given.fragment) { /*Fixes for relURLs...*/
1014: if(wanted & AMAYA_PARSE_PUNCTUATION) strcat(result, "#");
1015: strcat(result, given.fragment);
1016: } else if (!(given.absolute) && !(given.fragment)) {
1017: strcat(result, "");
1018: } else {
1019: if(wanted & AMAYA_PARSE_PUNCTUATION) strcat(result, "#");
1020: strcat(result, given.fragment ? given.fragment : related.fragment);
1021: }
1022: }
1023: TtaFreeMemory(rel);
1024: TtaFreeMemory(name);
1025:
1026: StringAllocCopy(return_value, result);
1027: TtaFreeMemory(result);
1028: return return_value; /* exactly the right length */
1029: }
1030:
1031: /*----------------------------------------------------------------------
1032: HTCanon
1033: Canonicalizes the URL in the following manner starting from the host
1034: pointer:
1035:
1036: 1) The host name is converted to lowercase
1037: 2) Chop off port if `:80' (http), `:70' (gopher), or `:21' (ftp)
1038:
1039: Return: OK The position of the current path part of the URL
1040: which might be the old one or a new one.
1041:
1042: ----------------------------------------------------------------------*/
1043: #ifdef __STDC__
1.28 ! cvs 1044: static char *HTCanon (char ** filename, char * host)
1.25 cvs 1045: #else /* __STDC__ */
1.28 ! cvs 1046: static char *HTCanon (filename, host)
! 1047: char **filename;
! 1048: char *host;
1.25 cvs 1049: #endif /* __STDC__ */
1050: {
1051: char *newname = NULL;
1052: char *port;
1053: char *strptr;
1054: char *path;
1055: char *access = host-3;
1056:
1.28 ! cvs 1057: while (access>*filename && *(access-1)!=DIR_SEP) /* Find access method */
1.25 cvs 1058: access--;
1.28 ! cvs 1059: if ((path = strchr(host, DIR_SEP)) == NULL) /* Find path */
1.25 cvs 1060: path = host + strlen(host);
1061: if ((strptr = strchr(host, '@')) != NULL && strptr<path) /* UserId */
1062: host = strptr;
1063: if ((port = strchr(host, ':')) != NULL && port>path) /* Port number */
1064: port = NULL;
1065:
1066: strptr = host; /* Convert to lower-case */
1067: while (strptr<path) {
1068: *strptr = tolower(*strptr);
1069: strptr++;
1070: }
1071:
1072: /* Does the URL contain a full domain name? This also works for a
1073: numerical host name. The domain name is already made lower-case
1074: and without a trailing dot. */
1075: {
1076: char *dot = port ? port : path;
1077: if (dot > *filename && *--dot=='.') {
1078: char *orig=dot, *dest=dot+1;
1079: while((*orig++ = *dest++));
1080: if (port) port--;
1081: path--;
1082: }
1083: }
1084: /* Chop off port if `:', `:80' (http), `:70' (gopher), or `:21' (ftp) */
1085: if (port) {
1.28 ! cvs 1086: if (!*(port+1) || *(port+1)==DIR_SEP) {
1.25 cvs 1087: if (!newname) {
1088: char *orig=port, *dest=port+1;
1089: while((*orig++ = *dest++));
1090: }
1091: } else if ((!strncmp(access, "http", 4) &&
1.28 ! cvs 1092: (*(port+1)=='8'&&*(port+2)=='0'&&(*(port+3)==DIR_SEP||!*(port+3)))) ||
1.25 cvs 1093: (!strncmp(access, "gopher", 6) &&
1.28 ! cvs 1094: (*(port+1)=='7'&&*(port+2)=='0'&&(*(port+3)==DIR_SEP||!*(port+3)))) ||
1.25 cvs 1095: (!strncmp(access, "ftp", 3) &&
1.28 ! cvs 1096: (*(port+1)=='2'&&*(port+2)=='1'&&(*(port+3)==DIR_SEP||!*(port+3))))) {
1.25 cvs 1097: if (!newname) {
1098: char *orig=port, *dest=port+3;
1099: while((*orig++ = *dest++));
1.28 ! cvs 1100: /* Update path position, Henry Minsky */
! 1101: path -= 3;
1.25 cvs 1102: }
1103: } else if (newname)
1104: strncat(newname, port, (int) (path-port));
1105: }
1106:
1107: if (newname) {
1108: char *newpath = newname+strlen(newname);
1109: strcat(newname, path);
1110: path = newpath;
1.28 ! cvs 1111: /* Free old copy */
! 1112: TtaFreeMemory(*filename);
1.25 cvs 1113: *filename = newname;
1114: }
1115: return path;
1116: }
1117:
1118:
1119: /*----------------------------------------------------------------------
1.28 ! cvs 1120: AmayaSimplifyUrl: simplify a URI
! 1121: A URI is allowed to contain the seqeunce xxx/../ which may be
! 1122: replaced by "" , and the seqeunce "/./" which may be replaced by "/".
! 1123: Simplification helps us recognize duplicate URIs.
1.25 cvs 1124:
1.28 ! cvs 1125: Thus, /etc/junk/../fred becomes /etc/fred
! 1126: /etc/junk/./fred becomes /etc/junk/fred
1.25 cvs 1127:
1.28 ! cvs 1128: but we should NOT change
! 1129: http://fred.xxx.edu/../..
1.25 cvs 1130:
1131: or ../../albert.html
1132:
1.28 ! cvs 1133: In order to avoid empty URLs the following URLs become:
1.25 cvs 1134:
1135: /fred/.. becomes /fred/..
1136: /fred/././.. becomes /fred/..
1137: /fred/.././junk/.././ becomes /fred/..
1138:
1.28 ! cvs 1139: If more than one set of `://' is found (several proxies in cascade) then
! 1140: only the part after the last `://' is simplified.
1.25 cvs 1141:
1.28 ! cvs 1142: Returns: A string which might be the old one or a new one.
1.25 cvs 1143: ----------------------------------------------------------------------*/
1144: #ifdef __STDC__
1.28 ! cvs 1145: void AmayaSimplifyUrl (char ** url)
1.25 cvs 1146: #else /* __STDC__ */
1.28 ! cvs 1147: void AmayaSimplifyUrl (url)
! 1148: char **url;
1.25 cvs 1149: #endif /* __STDC__ */
1150: {
1.28 ! cvs 1151: char *path, *p;
! 1152: char *newptr, *access;
! 1153: char *orig, *dest, *end;
! 1154:
! 1155: if (!url || !*url)
! 1156: return;
! 1157:
! 1158: /* Find any scheme name */
! 1159: if ((path = strstr(*url, "://")) != NULL)
! 1160: { /* Find host name */
! 1161: access = *url;
! 1162: while (access<path && (*access=tolower(*access)))
! 1163: access++;
! 1164: path += 3;
! 1165: while ((newptr = strstr(path, "://")) != NULL)
! 1166: /* For proxies */
! 1167: path = newptr+3;
! 1168: /* We have a host name */
! 1169: path = HTCanon(url, path);
1.25 cvs 1170: }
1.28 ! cvs 1171: else if ((path = strstr(*url, ":/")) != NULL)
! 1172: path += 2;
! 1173: else
! 1174: path = *url;
1.25 cvs 1175:
1.28 ! cvs 1176: if (*path == DIR_SEP && *(path+1)==DIR_SEP)
! 1177: /* Some URLs start //<foo> */
! 1178: path += 1;
! 1179: else if (!strncmp(path, "news:", 5))
! 1180: {
! 1181: newptr = strchr(path+5, '@');
! 1182: if (!newptr)
! 1183: newptr = path + 5;
! 1184: while (*newptr)
! 1185: {
! 1186: /* Make group or host lower case */
! 1187: *newptr = tolower (*newptr);
! 1188: newptr++;
1.25 cvs 1189: }
1.28 ! cvs 1190: /* Doesn't need to do any more */
! 1191: return;
1.25 cvs 1192: }
1.28 ! cvs 1193:
! 1194: if ((p = path))
! 1195: {
! 1196: if (!((end = strchr (path, ';')) || (end = strchr (path, '?')) ||
! 1197: (end = strchr (path, '#'))))
! 1198: end = path + strlen (path);
! 1199:
! 1200: /* Parse string second time to simplify */
! 1201: p = path;
! 1202: while (p < end)
! 1203: {
! 1204: if (*p==DIR_SEP)
! 1205: {
! 1206: if (p > *url && *(p+1) == '.' && (*(p+2) == DIR_SEP || !*(p+2)))
! 1207: {
! 1208: orig = p + 1;
! 1209: dest = (*(p+2)!=DIR_SEP) ? p+2 : p+3;
! 1210: while ((*orig++ = *dest++)); /* Remove a slash and a dot */
! 1211: end = orig - 1;
! 1212: }
! 1213: else if (*(p+1)=='.' && *(p+2)=='.' && (*(p+3)==DIR_SEP || !*(p+3)))
! 1214: {
! 1215: newptr = p;
! 1216: while (newptr>path && *--newptr!=DIR_SEP); /* prev slash */
! 1217: if (strncmp(newptr, "/../", 4))
! 1218: {
! 1219: orig = newptr + 1;
! 1220: dest = (*(p+3)!=DIR_SEP) ? p+3 : p+4;
! 1221: while ((*orig++ = *dest++)); /* Remove /xxx/.. */
! 1222: end = orig-1;
! 1223: /* Start again with prev slash */
! 1224: p = newptr;
1.25 cvs 1225: }
1.28 ! cvs 1226: else
1.25 cvs 1227: p++;
1.28 ! cvs 1228: }
! 1229: else if (*(p+1) == DIR_SEP)
! 1230: {
! 1231: while (*(p+1) == DIR_SEP)
! 1232: {
! 1233: orig = p;
! 1234: dest = p + 1;
! 1235: while ((*orig++ = *dest++)); /* Remove multiple /'s */
! 1236: end = orig-1;
! 1237: }
! 1238: }
! 1239: else
1.25 cvs 1240: p++;
1.28 ! cvs 1241: }
! 1242: else
! 1243: p++;
1.25 cvs 1244: }
1245: }
1.28 ! cvs 1246: return;
! 1247: }
! 1248:
! 1249:
! 1250: /*----------------------------------------------------------------------
! 1251: NormalizeFile normalizes local names.
! 1252: Return TRUE if target and src differ.
! 1253: ----------------------------------------------------------------------*/
! 1254: #ifdef __STDC__
! 1255: boolean NormalizeFile (char *src, char *target)
! 1256: #else
! 1257: boolean NormalizeFile (src, target)
! 1258: char *src;
! 1259: char *target;
! 1260:
! 1261: #endif
! 1262: {
! 1263: char *s;
! 1264: boolean change;
! 1265:
! 1266: change = FALSE;
! 1267: if (src[0] == '~')
! 1268: {
! 1269: /* replace ~ */
! 1270: s = (char *) TtaGetEnvString ("HOME");
! 1271: strcpy (target, s);
! 1272: strcat (target, &src[1]);
! 1273: change = TRUE;
! 1274: }
! 1275: else if (strncmp (src, "file:", 5) == 0)
! 1276: {
! 1277: /* remove the prefix file: */
! 1278: if (src[5] == EOS)
! 1279: strcpy (target, DIR_STR);
! 1280: else if (src[0] == '~')
! 1281: {
! 1282: /* replace ~ */
! 1283: s = (char *) TtaGetEnvString ("HOME");
! 1284: strcpy (target, s);
! 1285: strcat (target, &src[5]);
! 1286: }
! 1287: else
! 1288: strcpy (target, &src[5]);
! 1289: change = TRUE;
! 1290: }
! 1291: else
! 1292: strcpy (target, src);
! 1293:
! 1294: /* remove /../ and /./ */
! 1295: AmayaSimplifyUrl (&target);
! 1296: return (change);
1.25 cvs 1297: }
1298:
1.28 ! cvs 1299:
1.25 cvs 1300: /*----------------------------------------------------------------------
1.28 ! cvs 1301: AmayaRelativeUrl: make Relative Name
1.25 cvs 1302:
1.28 ! cvs 1303: This function creates and returns a string which gives an expression of
! 1304: one address as related to another. Where there is no relation, an absolute
! 1305: address is retured.
1.25 cvs 1306:
1.28 ! cvs 1307: On entry,
1.25 cvs 1308: Both names must be absolute, fully qualified names of nodes
1309: (no fragment bits)
1310:
1.28 ! cvs 1311: On exit,
1.25 cvs 1312: The return result points to a newly allocated name which, if
1313: parsed by AmayaParseUrl relative to relatedName, will yield aName.
1314: The caller is responsible for freeing the resulting name later.
1315: ----------------------------------------------------------------------*/
1316: #ifdef __STDC__
1.28 ! cvs 1317: char *AmayaRelativeUrl (char *aName, char *relatedName)
1.25 cvs 1318: #else /* __STDC__ */
1.28 ! cvs 1319: char *AmayaRelativeUrl (aName, relatedName)
! 1320: char *aName;
! 1321: char *relatedName;
1.25 cvs 1322: #endif /* __STDC__ */
1323: {
1.27 cvs 1324: char *result = 0;
1325: const char *p = aName;
1326: const char *q = relatedName;
1327: const char *after_access = 0;
1328: const char *last_slash = 0;
1329: int slashes = 0;
1.25 cvs 1330:
1.28 ! cvs 1331: for (;*p; p++, q++)
1.27 cvs 1332: {
1333: /* Find extent of match */
1334: if (*p != *q)
1335: break;
1336: if (*p == ':')
1337: after_access = p+1;
1.28 ! cvs 1338: if (*p == DIR_SEP)
1.27 cvs 1339: {
1340: last_slash = p;
1341: slashes++;
1.25 cvs 1342: }
1343: }
1344:
1345: /* q, p point to the first non-matching character or zero */
1.27 cvs 1346: if (!after_access)
1347: {
1348: /* Different access */
1349: StringAllocCopy (result, aName);
1350: }
1351: else if (slashes < 3)
1352: {
1353: /* Different nodes */
1.25 cvs 1354: StringAllocCopy(result, after_access);
1.27 cvs 1355: }
1356: else
1357: {
1358: /* Some path in common */
1.25 cvs 1359: int levels= 0;
1.27 cvs 1360: for (; *q && (*q!='#'); q++)
1.28 ! cvs 1361: if (*q==DIR_SEP)
1.27 cvs 1362: levels++;
1363: result = (char *) TtaGetMemory (3*levels + strlen(last_slash) + 1);
1364: if (result == NULL)
1365: exit(1);
1366: result[0] = 0;
1367: for (;levels; levels--)
1368: strcat (result, "../");
1369: strcat (result, last_slash+1);
1.25 cvs 1370: }
1371: return result;
1.24 cvs 1372: }
Webmaster