Return to AHTURLTools.c CVS log | Up to [Public] / Amaya / amaya |
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.90 ! cvs 658: IsFilePath ! 659: returns TRUE if path is in fact a URL. ! 660: ----------------------------------------------------------------------*/ ! 661: #ifdef __STDC__ ! 662: static ThotBool IsFilePath (const CHAR_T* path) ! 663: #else /* __STDC__ */ ! 664: static ThotBool IsFilePath (path) ! 665: const CHAR_T* path; ! 666: #endif /* __STDC__ */ ! 667: { ! 668: if (ustrncmp (path, TEXT("file:"), 5)) ! 669: return FALSE; ! 670: return TRUE; ! 671: } ! 672: ! 673: /*---------------------------------------------------------------------- 1.9 cvs 674: IsValidProtocol 675: returns true if the url protocol is supported by Amaya. 1.4 cvs 676: ----------------------------------------------------------------------*/ 1.3 cvs 677: #ifdef __STDC__ 1.67 cvs 678: ThotBool IsValidProtocol (const STRING url) 1.3 cvs 679: #else /* __STDC__ */ 1.67 cvs 680: ThotBool IsValidProtocol (url) 681: const STRING url; 1.3 cvs 682: #endif /* __STDC__ */ 683: { 1.67 cvs 684: if (!ustrncmp (url, TEXT("http:"), 5) 1.69 cvs 685: || !ustrncmp (url, TEXT("internal:"), 9) 1.70 cvs 686: || !ustrncmp (url, TEXT("ftp:"), 4)) 1.22 cvs 687: /* experimental */ 1.58 cvs 688: /*** || !strncmp (url, "ftp:", 4) ***/ 1.24 cvs 689: /*** || !strncmp (path, "news:", 5)***/ 1.8 cvs 690: return (TRUE); 1.5 cvs 691: else 1.8 cvs 692: return (FALSE); 1.3 cvs 693: } 694: 1.31 cvs 695: 696: /*---------------------------------------------------------------------- 697: GetBaseURL 698: normalizes orgName according to a base associated with doc, and 699: following the standard URL format rules. 700: The function returns the base used to solve relative URL and SRC: 701: - the base of the document, 702: - or the document path (without document name). 703: ----------------------------------------------------------------------*/ 704: #ifdef __STDC__ 1.84 cvs 705: CHAR_T* GetBaseURL (Document doc) 1.31 cvs 706: #else /* __STDC__ */ 1.84 cvs 707: CHAR_T* GetBaseURL (doc) 1.31 cvs 708: Document doc; 709: #endif /* __STDC__ */ 710: { 711: Element el; 712: ElementType elType; 713: AttributeType attrType; 714: Attribute attr; 1.84 cvs 715: CHAR_T *ptr, *basename; 1.31 cvs 716: int length; 717: 1.57 cvs 718: /* @@@ irene */ 719: if (!DocumentURLs[doc]) 720: return NULL; 1.67 cvs 721: basename = TtaAllocString (MAX_LENGTH); 722: ustrncpy (basename, DocumentURLs[doc], MAX_LENGTH-1); 1.84 cvs 723: basename[MAX_LENGTH-1] = WC_EOS; 1.31 cvs 724: length = MAX_LENGTH -1; 725: /* get the root element */ 726: el = TtaGetMainRoot (doc); 727: /* search the BASE element */ 728: elType.ElSSchema = TtaGetDocumentSSchema (doc); 1.65 cvs 729: elType.ElTypeNum = HTML_EL_HEAD; 730: el = TtaSearchTypedElement (elType, SearchForward, el); 731: if (el) 732: { 733: elType.ElTypeNum = HTML_EL_BASE; 734: el = TtaSearchTypedElement (elType, SearchInTree, el); 735: } 1.31 cvs 736: if (el) 737: { 738: /* The document has a BASE element -> Get the HREF attribute */ 739: attrType.AttrSSchema = elType.ElSSchema; 740: attrType.AttrTypeNum = HTML_ATTR_HREF_; 741: attr = TtaGetAttribute (el, attrType); 742: if (attr) 743: { 744: /* Use the base path of the document */ 745: TtaGiveTextAttributeValue (attr, basename, &length); 746: /* base and orgName have to be separated by a DIR_SEP */ 747: length--; 1.84 cvs 748: if (basename[0] != WC_EOS && basename[length] != WC_URL_SEP && basename[length] != WC_DIR_SEP) 1.31 cvs 749: /* verify if the base has the form "protocol://server:port" */ 750: { 1.84 cvs 751: ptr = AmayaParseUrl (basename, TEXT(""), AMAYA_PARSE_ACCESS | 1.33 cvs 752: AMAYA_PARSE_HOST | 753: AMAYA_PARSE_PUNCTUATION); 1.67 cvs 754: if (ptr && !ustrcmp (ptr, basename)) 1.31 cvs 755: { 1.43 cvs 756: /* it has this form, we complete it by adding a URL_STR */ 1.84 cvs 757: if (ustrchr (basename, WC_DIR_SEP)) 758: ustrcat (basename, WC_DIR_STR); 1.43 cvs 759: else 1.84 cvs 760: ustrcat (basename, WC_URL_STR); 1.31 cvs 761: length++; 762: } 763: if (ptr) 764: TtaFreeMemory (ptr); 765: } 766: } 1.33 cvs 767: } 768: 1.31 cvs 769: /* Remove anything after the last DIR_SEP char. If no such char is found, 770: * then search for the first ":" char, hoping that what's before that is a 771: * protocol. If found, end the string there. If neither char is found, 772: * then discard the whole base element. 773: */ 1.67 cvs 774: length = ustrlen (basename) - 1; 1.31 cvs 775: /* search for the last DIR_SEP char */ 1.84 cvs 776: while (length >= 0 && basename[length] != WC_URL_SEP && basename[length] != WC_DIR_SEP) 1.31 cvs 777: length--; 778: if (length >= 0) 779: /* found the last DIR_SEP char, end the string there */ 1.84 cvs 780: basename[length + 1] = WC_EOS; 1.31 cvs 781: else 782: /* search for the first PATH_STR char */ 783: { 1.67 cvs 784: for (length = 0; basename[length] != TEXT(':') && 1.84 cvs 785: basename[length] != WC_EOS; length ++); 1.67 cvs 786: if (basename[length] == TEXT(':')) 1.31 cvs 787: /* found, so end the string there */ 1.84 cvs 788: basename[length + 1] = WC_EOS; 1.31 cvs 789: else 790: /* not found, discard the base */ 1.84 cvs 791: basename[0] = WC_EOS; 1.31 cvs 792: } 793: return (basename); 794: } 795: 796: 1.4 cvs 797: /*---------------------------------------------------------------------- 1.40 cvs 798: GetLocalPath 799: Allocate and return the local document path associated to the url 800: ----------------------------------------------------------------------*/ 801: #ifdef __STDC__ 1.84 cvs 802: CHAR_T* GetLocalPath (Document doc, CHAR_T* url) 1.40 cvs 803: #else /* __STDC__ */ 1.84 cvs 804: CHAR_T* GetLocalPath (doc, url) 1.40 cvs 805: Document doc; 1.84 cvs 806: CHAR_T* url; 1.40 cvs 807: #endif /* __STDC__ */ 808: { 1.84 cvs 809: CHAR_T* ptr; 810: CHAR_T* n; 811: CHAR_T* documentname; 812: CHAR_T url_sep; 1.83 cvs 813: int len; 1.67 cvs 814: ThotBool noFile; 1.40 cvs 815: 816: if (url != NULL) 817: { 818: /* check whether the file name exists */ 1.84 cvs 819: len = ustrlen (url) - 1; 1.71 cvs 820: if (IsW3Path (url)) 1.84 cvs 821: url_sep = TEXT('/'); 1.41 cvs 822: else 1.84 cvs 823: url_sep = WC_DIR_SEP; 1.41 cvs 824: noFile = (url[len] == url_sep); 1.40 cvs 825: if (noFile) 1.84 cvs 826: url[len] = WC_EOS; 827: ptr = TtaAllocString (MAX_LENGTH); 828: documentname = TtaAllocString (MAX_LENGTH); 1.78 cvs 829: TtaExtractName (url, ptr, documentname); 1.84 cvs 830: usprintf (ptr, TEXT("%s%s%d%s"), TempFileDirectory, WC_DIR_STR, doc, WC_DIR_STR); 1.40 cvs 831: if (!TtaCheckDirectory (ptr)) 832: /* directory did not exist */ 1.72 cvs 833: TtaMakeDirectory (ptr); 1.47 cvs 834: 835: /* don't include the query string within document name */ 1.84 cvs 836: n = ustrrchr (documentname, TEXT('?')); 1.47 cvs 837: if (n != NULL) 1.84 cvs 838: *n = WC_EOS; 1.46 cvs 839: /* don't include ':' within document name */ 1.84 cvs 840: n = ustrchr (documentname, TEXT(':')); 1.46 cvs 841: if (n != NULL) 1.84 cvs 842: *n = WC_EOS; 1.69 cvs 843: /* if after all this operations document name 844: is empty, let's use noname.html instead */ 1.84 cvs 845: if (documentname[0] == WC_EOS) 846: ustrcat (ptr, TEXT("noname.html")); 1.69 cvs 847: else 1.84 cvs 848: ustrcat (ptr, documentname); 1.40 cvs 849: TtaFreeMemory (documentname); 850: /* restore the url */ 851: if (noFile) 1.41 cvs 852: url[len] = url_sep; 1.40 cvs 853: return (ptr); 854: } 855: else 856: return (NULL); 857: } 858: 1.73 cvs 859: /*---------------------------------------------------------------------- 1.79 cvs 860: ExtractTarget extract the target name from document nane. 861: ----------------------------------------------------------------------*/ 862: #ifdef __STDC__ 1.84 cvs 863: void ExtractTarget (CHAR_T* aName, CHAR_T* target) 1.79 cvs 864: #else 865: void ExtractTarget (aName, target) 1.84 cvs 866: CHAR_T* aName; 867: CHAR_T* target; 1.79 cvs 868: #endif 869: { 1.82 cvs 870: int lg, i; 1.84 cvs 871: CHAR_T* ptr; 872: CHAR_T* oldptr; 1.79 cvs 873: 874: if (!target || !aName) 875: /* bad target */ 876: return; 877: 1.84 cvs 878: target[0] = WC_EOS; 879: lg = ustrlen (aName); 1.79 cvs 880: if (lg) 881: { 882: /* the name is not empty */ 883: oldptr = ptr = &aName[0]; 884: do 885: { 1.84 cvs 886: ptr = ustrrchr (oldptr, TEXT('#')); 1.79 cvs 887: if (ptr) 888: oldptr = &ptr[1]; 889: } 890: while (ptr); 891: 892: i = (int) (oldptr) - (int) (aName); /* name length */ 893: if (i > 1) 894: { 1.84 cvs 895: aName[i - 1] = WC_EOS; 1.79 cvs 896: if (i != lg) 1.84 cvs 897: ustrcpy (target, oldptr); 1.79 cvs 898: } 899: } 900: } 901: 902: /*---------------------------------------------------------------------- 1.90 ! cvs 903: RemoveNewLines (text) ! 904: Removes any '\n' chars that are found in text. ! 905: Returns TRUE if it did the operation, FALSE otherwise. 1.73 cvs 906: ----------------------------------------------------------------------*/ 907: #ifdef __STDC__ 1.90 ! cvs 908: ThotBool RemoveNewLines (CHAR_T *text) 1.73 cvs 909: #else 1.90 ! cvs 910: ThotBool RemoveNewLines (text) ! 911: CHAR_T *text; ! 912: 1.73 cvs 913: #endif /* __STDC__ */ 914: { 1.90 ! cvs 915: ThotBool change = FALSE; ! 916: CHAR_T *src; ! 917: CHAR_T *dest; ! 918: ! 919: src = text; ! 920: dest = text; ! 921: ! 922: while (*src) ! 923: { ! 924: switch (*src) ! 925: { ! 926: case TEXT('\n'): ! 927: /* don't copy the newline */ ! 928: change = 1; ! 929: break; ! 930: default: ! 931: *dest = *src; ! 932: dest++; ! 933: break; ! 934: } ! 935: src++; ! 936: } ! 937: /* copy the last EOS char */ ! 938: *dest = *src; ! 939: ! 940: return (change); ! 941: } ! 942: ! 943: /*---------------------------------------------------------------------- ! 944: CleanCopyFileURL ! 945: Copies a file url from a src string to destination string. ! 946: It changes the URL_SEP into DIR_SEPs if they are not the same ! 947: character. ! 948: ----------------------------------------------------------------------*/ ! 949: #ifdef __STDC__ ! 950: static void CleanCopyFileURL (CHAR_T *dest, CHAR_T *src) ! 951: #else ! 952: static void CleanCopyFileURL (dest, src) ! 953: CHAR_T* dest; ! 954: CHAR_T* src; 1.89 cvs 955: 1.90 ! cvs 956: #endif /* __STDC__ */ ! 957: { ! 958: while (*src) 1.89 cvs 959: { 1.90 ! cvs 960: switch (*src) 1.89 cvs 961: { 962: #ifdef _WINDOWS 1.90 ! cvs 963: case WC_URL_SEP: ! 964: /* make the transformation */ ! 965: *dest = WC_DIR_SEP; ! 966: dest++; ! 967: break; 1.89 cvs 968: #endif /* _WINDOWS */ 1.90 ! cvs 969: default: ! 970: *dest = *src; 1.89 cvs 971: dest++; 1.90 ! cvs 972: break; 1.89 cvs 973: } 1.90 ! cvs 974: src++; 1.89 cvs 975: } 1.90 ! cvs 976: /* copy the EOS char */ ! 977: *dest = *src; 1.73 cvs 978: } 1.40 cvs 979: 980: /*---------------------------------------------------------------------- 1.9 cvs 981: NormalizeURL 982: normalizes orgName according to a base associated with doc, and 983: following the standard URL format rules. 1.53 cvs 984: if doc is 0 and otherPath not NULL, normalizes orgName according to this 985: other path. 1.9 cvs 986: The function returns the new complete and normalized URL 1.12 cvs 987: or file name path (newName) and the name of the document (docName). 1.9 cvs 988: N.B. If the function can't find out what's the docName, it assigns 989: the name "noname.html". 1.4 cvs 990: ----------------------------------------------------------------------*/ 1.3 cvs 991: #ifdef __STDC__ 1.84 cvs 992: void NormalizeURL (CHAR_T* orgName, Document doc, CHAR_T* newName, CHAR_T* docName, CHAR_T* otherPath) 1.3 cvs 993: #else /* __STDC__ */ 1.53 cvs 994: void NormalizeURL (orgName, doc, newName, docName, otherPath) 1.84 cvs 995: CHAR_T* orgName; 1.3 cvs 996: Document doc; 1.84 cvs 997: CHAR_T* newName; 998: CHAR_T* docName; 999: CHAR_T* otherPath; 1.3 cvs 1000: #endif /* __STDC__ */ 1001: { 1.84 cvs 1002: CHAR_T* basename; 1003: CHAR_T tempOrgName[MAX_LENGTH]; 1004: CHAR_T* ptr; 1005: CHAR_T used_sep; 1006: int length; 1007: ThotBool check; 1.5 cvs 1008: 1.44 cvs 1009: # ifdef _WINDOWS 1010: int ndx; 1011: # endif /* _WINDOWS */ 1012: 1.5 cvs 1013: if (!newName || !docName) 1014: return; 1.18 cvs 1015: 1.32 cvs 1016: if (doc != 0) 1.53 cvs 1017: basename = GetBaseURL (doc); 1018: else if (otherPath != NULL) 1.84 cvs 1019: basename = TtaWCSdup (otherPath); 1.32 cvs 1020: else 1.53 cvs 1021: basename = NULL; 1.32 cvs 1022: 1.18 cvs 1023: /* 1.31 cvs 1024: * Clean orgName 1025: * Make sure we have a complete orgName, without any leading or trailing 1026: * white spaces, or trailinbg new lines 1027: */ 1.5 cvs 1028: ptr = orgName; 1.18 cvs 1029: /* skip leading white space and new line characters */ 1.84 cvs 1030: while ((*ptr == WC_SPACE || *ptr == WC_EOL) && *ptr++ != WC_EOS); 1031: ustrncpy (tempOrgName, ptr, MAX_LENGTH -1); 1032: tempOrgName[MAX_LENGTH -1] = WC_EOS; 1.18 cvs 1033: /* 1.31 cvs 1034: * Make orgName a complete URL 1035: * If the URL does not include a protocol, then try to calculate 1036: * one using the doc's base element (if it exists), 1037: */ 1.84 cvs 1038: if (tempOrgName[0] == WC_EOS) 1.53 cvs 1039: { 1.84 cvs 1040: newName[0] = WC_EOS; 1.53 cvs 1041: TtaFreeMemory (basename); 1042: return; 1043: } 1.49 cvs 1044: 1045: /* clean trailing white space */ 1.84 cvs 1046: length = ustrlen (tempOrgName) - 1; 1047: while (tempOrgName[length] == WC_SPACE && tempOrgName[length] == WC_EOL) 1.53 cvs 1048: { 1.84 cvs 1049: tempOrgName[length] = WC_EOS; 1.53 cvs 1050: length--; 1051: } 1.50 cvs 1052: 1.55 cvs 1053: /* remove extra dot (which dot???) */ 1054: /* ugly, but faster than a strcmp */ 1.84 cvs 1055: if (tempOrgName[length] == TEXT('.') 1056: && (length == 0 || tempOrgName[length-1] != TEXT('.'))) 1057: tempOrgName[length] = WC_EOS; 1.50 cvs 1058: 1.90 ! cvs 1059: if (IsW3Path (tempOrgName) || IsFilePath (tempOrgName)) 1.53 cvs 1060: { 1061: /* the name is complete, go to the Sixth Step */ 1.84 cvs 1062: ustrcpy (newName, tempOrgName); 1.53 cvs 1063: SimplifyUrl (&newName); 1064: /* verify if the URL has the form "protocol://server:port" */ 1.84 cvs 1065: ptr = AmayaParseUrl (newName, TEXT(""), AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST | AMAYA_PARSE_PUNCTUATION); 1066: if (ptr && !ustrcmp (ptr, newName)) /* it has this form, we complete it by adding a DIR_STR */ 1067: ustrcat (newName, WC_URL_STR); 1.49 cvs 1068: 1.53 cvs 1069: if (ptr) 1.50 cvs 1070: TtaFreeMemory (ptr); 1.53 cvs 1071: } 1072: else if ( basename == NULL) 1073: /* the name is complete, go to the Sixth Step */ 1.84 cvs 1074: ustrcpy (newName, tempOrgName); 1.53 cvs 1075: else 1076: { 1.31 cvs 1077: /* Calculate the absolute URL, using the base or document URL */ 1.44 cvs 1078: # ifdef _WINDOWS 1.53 cvs 1079: if (!IsW3Path (basename)) 1080: { 1.67 cvs 1081: length = ustrlen (tempOrgName); 1.53 cvs 1082: for (ndx = 0; ndx < length; ndx++) 1.67 cvs 1083: if (tempOrgName [ndx] == TEXT('/')) 1084: tempOrgName [ndx] = TEXT('\\'); 1.53 cvs 1085: } 1.44 cvs 1086: # endif /* _WINDOWS */ 1.25 cvs 1087: ptr = AmayaParseUrl (tempOrgName, basename, AMAYA_PARSE_ALL); 1.53 cvs 1088: if (ptr) 1089: { 1090: SimplifyUrl (&ptr); 1.84 cvs 1091: ustrcpy (newName, ptr); 1.53 cvs 1092: TtaFreeMemory (ptr); 1093: } 1094: else 1.84 cvs 1095: newName[0] = WC_EOS; 1.53 cvs 1096: } 1.36 cvs 1097: 1098: TtaFreeMemory (basename); 1.18 cvs 1099: /* 1.31 cvs 1100: * Prepare the docname that will refer to this ressource in the 1101: * .amaya directory. If the new URL finishes on DIR_SEP, then use 1102: * noname.html as a default ressource name 1.18 cvs 1103: */ 1.84 cvs 1104: if (newName[0] != WC_EOS) 1.53 cvs 1105: { 1.84 cvs 1106: length = ustrlen (newName) - 1; 1107: if (newName[length] == WC_URL_SEP || newName[length] == WC_DIR_SEP) 1.53 cvs 1108: { 1109: used_sep = newName[length]; 1110: check = TRUE; 1111: while (check) 1112: { 1.50 cvs 1113: length--; 1114: while (length >= 0 && newName[length] != used_sep) 1.53 cvs 1115: length--; 1.84 cvs 1116: if (!ustrncmp (&newName[length+1], TEXT(".."), 2)) 1.53 cvs 1117: { 1.84 cvs 1118: newName[length+1] = WC_EOS; 1.53 cvs 1119: /* remove also previous directory */ 1120: length--; 1121: while (length >= 0 && newName[length] != used_sep) 1122: length--; 1.84 cvs 1123: if (ustrncmp (&newName[length+1], TEXT("//"), 2)) 1.53 cvs 1124: /* don't remove server name */ 1.84 cvs 1125: newName[length+1] = WC_EOS; 1.53 cvs 1126: } 1.84 cvs 1127: else if (!ustrncmp (&newName[length+1], TEXT("."), 1)) 1128: newName[length+1] = WC_EOS; 1.50 cvs 1129: else 1.53 cvs 1130: check = FALSE; 1131: } 1.84 cvs 1132: ustrcpy (docName, TEXT("noname.html")); 1.53 cvs 1133: /* docname was not comprised inside the URL, so let's */ 1134: /* assign the default ressource name */ 1.84 cvs 1135: ustrcpy (docName, TEXT("noname.html")); 1.53 cvs 1136: } 1137: else 1138: { /* docname is comprised inside the URL */ 1.84 cvs 1139: while (length >= 0 && newName[length] != WC_URL_SEP && newName[length] != WC_DIR_SEP) 1.53 cvs 1140: length--; 1141: if (length < 0) 1.84 cvs 1142: ustrcpy (docName, newName); 1.53 cvs 1143: else 1.84 cvs 1144: ustrcpy (docName, &newName[length+1]); 1.53 cvs 1145: } 1146: } 1147: else 1.84 cvs 1148: docName[0] = WC_EOS; 1.18 cvs 1149: } 1.3 cvs 1150: 1.4 cvs 1151: /*---------------------------------------------------------------------- 1.9 cvs 1152: IsSameHost 1.4 cvs 1153: ----------------------------------------------------------------------*/ 1.3 cvs 1154: #ifdef __STDC__ 1.67 cvs 1155: ThotBool IsSameHost (const STRING url1, const STRING url2) 1.3 cvs 1156: #else /* __STDC__ */ 1.67 cvs 1157: ThotBool IsSameHost (url1, url2) 1158: const STRING url1; 1159: const STRING url2; 1.3 cvs 1160: #endif /* __STDC__ */ 1161: { 1.67 cvs 1162: STRING basename_ptr1, basename_ptr2; 1163: ThotBool result; 1.3 cvs 1164: 1.84 cvs 1165: basename_ptr1 = AmayaParseUrl (url1, TEXT(""), AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST | AMAYA_PARSE_PUNCTUATION); 1.86 cvs 1166: basename_ptr2 = AmayaParseUrl (url2, TEXT(""), AMAYA_PARSE_ACCESS | AMAYA_PARSE_HOST | AMAYA_PARSE_PUNCTUATION); 1.3 cvs 1167: 1.67 cvs 1168: if (ustrcmp (basename_ptr1, basename_ptr2)) 1.8 cvs 1169: result = FALSE; 1.5 cvs 1170: else 1.8 cvs 1171: result = TRUE; 1.3 cvs 1172: 1.25 cvs 1173: TtaFreeMemory (basename_ptr1); 1174: TtaFreeMemory (basename_ptr2); 1.5 cvs 1175: return (result); 1.3 cvs 1176: } 1177: 1178: 1.4 cvs 1179: /*---------------------------------------------------------------------- 1.22 cvs 1180: HasKnownFileSuffix 1181: returns TRUE if path points to a file ending with a suffix. 1182: ----------------------------------------------------------------------*/ 1183: #ifdef __STDC__ 1.67 cvs 1184: ThotBool HasKnownFileSuffix (const STRING path) 1.22 cvs 1185: #else /* __STDC__ */ 1.67 cvs 1186: ThotBool HasKnownFileSuffix (path) 1187: const STRING path; 1.22 cvs 1188: #endif /* __STDC__ */ 1189: { 1.67 cvs 1190: STRING root; 1191: CHAR_T temppath[MAX_LENGTH]; 1192: CHAR_T suffix[MAX_LENGTH]; 1.22 cvs 1193: 1.87 cvs 1194: if (!path || path[0] == WC_EOS || path[ustrlen(path)] == WC_DIR_SEP) 1.22 cvs 1195: return (FALSE); 1196: 1.84 cvs 1197: root = AmayaParseUrl(path, TEXT(""), AMAYA_PARSE_PATH | AMAYA_PARSE_PUNCTUATION); 1.22 cvs 1198: 1199: if (root) 1200: { 1.67 cvs 1201: ustrcpy (temppath, root); 1.25 cvs 1202: TtaFreeMemory (root); 1.22 cvs 1203: /* Get the suffix */ 1204: ExtractSuffix (temppath, suffix); 1205: 1.87 cvs 1206: if( suffix[0] == WC_EOS) 1.22 cvs 1207: /* no suffix */ 1208: return (FALSE); 1209: 1210: /* Normalize the suffix */ 1211: ConvertToLowerCase (suffix); 1212: 1.67 cvs 1213: if (!ustrcmp (suffix, TEXT("gz"))) 1.22 cvs 1214: /* skip the compressed suffix */ 1215: { 1216: ExtractSuffix (temppath, suffix); 1.87 cvs 1217: if(suffix[0] == WC_EOS) 1.22 cvs 1218: /* no suffix */ 1219: return (FALSE); 1220: /* Normalize the suffix */ 1221: ConvertToLowerCase (suffix); 1222: } 1223: 1.67 cvs 1224: if (ustrcmp (suffix, TEXT("gif")) && 1225: ustrcmp (suffix, TEXT("xbm")) && 1226: ustrcmp (suffix, TEXT("xpm")) && 1227: ustrcmp (suffix, TEXT("jpg")) && 1228: ustrcmp (suffix, TEXT("pdf")) && 1229: ustrcmp (suffix, TEXT("png")) && 1230: ustrcmp (suffix, TEXT("tgz")) && 1231: ustrcmp (suffix, TEXT("xpg")) && 1232: ustrcmp (suffix, TEXT("xpd")) && 1233: ustrcmp (suffix, TEXT("ps")) && 1234: ustrcmp (suffix, TEXT("au")) && 1235: ustrcmp (suffix, TEXT("html")) && 1236: ustrcmp (suffix, TEXT("htm")) && 1237: ustrcmp (suffix, TEXT("shtml")) && 1238: ustrcmp (suffix, TEXT("xht")) && 1239: ustrcmp (suffix, TEXT("xhtm")) && 1240: ustrcmp (suffix, TEXT("xhtml")) && 1241: ustrcmp (suffix, TEXT("txt")) && 1242: ustrcmp (suffix, TEXT("css")) && 1243: ustrcmp (suffix, TEXT("eps"))) 1.22 cvs 1244: return (FALSE); 1245: else 1246: return (TRUE); 1247: } 1248: else 1249: return (FALSE); 1250: } 1251: 1252: 1253: /*---------------------------------------------------------------------- 1.24 cvs 1254: ChopURL 1255: Gives back a URL no longer than MAX_PRINT_URL_LENGTH chars (outputURL). 1256: If inputURL is bigger than that size, outputURL receives 1257: MAX_PRINT_URL_LENGTH / 2 chars from the beginning of inputURL, "...", 1258: and MAX_PRINT_URL_LENGTH / 2 chars from the end of inputURL. 1259: If inputURL is not longer than MAX_PRINT_URL_LENGTH chars, it gets 1260: copied into outputURL. 1261: N.B.: outputURL must point to a memory block of MAX_PRINT_URL_LENGTH 1262: chars. 1263: ----------------------------------------------------------------------*/ 1264: #ifdef __STDC__ 1.86 cvs 1265: void ChopURL (CHAR_T* outputURL, const CHAR_T* inputURL) 1.24 cvs 1266: #else 1267: void ChopURL (outputURL, inputURL) 1.86 cvs 1268: CHAR_T* outputURL; 1269: const CHAR_T* inputURL; 1.24 cvs 1270: #endif 1.22 cvs 1271: 1.24 cvs 1272: { 1273: int len; 1.9 cvs 1274: 1.86 cvs 1275: len = ustrlen (inputURL); 1.24 cvs 1276: if (len <= MAX_PRINT_URL_LENGTH) 1.86 cvs 1277: ustrcpy (outputURL, inputURL); 1.24 cvs 1278: else 1279: /* make a truncated urlName on the status window */ 1280: { 1.86 cvs 1281: ustrncpy (outputURL, inputURL, MAX_PRINT_URL_LENGTH / 2); 1282: outputURL [MAX_PRINT_URL_LENGTH / 2] = WC_EOS; 1283: ustrcat (outputURL, TEXT("...")); 1284: ustrcat (outputURL, &(inputURL[len - MAX_PRINT_URL_LENGTH / 2 ])); 1.24 cvs 1285: } 1.25 cvs 1286: } 1287: 1288: 1289: /*---------------------------------------------------------------------- 1290: scan 1.47 cvs 1291: Scan a filename for its constituents 1.25 cvs 1292: ----------------------------------- 1293: 1294: On entry, 1295: name points to a document name which may be incomplete. 1296: On exit, 1297: absolute or relative may be nonzero (but not both). 1298: host, fragment and access may be nonzero if they were specified. 1299: Any which are nonzero point to zero terminated strings. 1300: ----------------------------------------------------------------------*/ 1301: #ifdef __STDC__ 1.67 cvs 1302: static void scan (STRING name, HTURI * parts) 1.25 cvs 1303: #else /* __STDC__ */ 1304: static void scan (name, parts) 1.67 cvs 1305: STRING name; 1306: HTURI *parts; 1.25 cvs 1307: 1308: #endif /* __STDC__ */ 1309: { 1.67 cvs 1310: STRING p; 1311: STRING after_access = name; 1.32 cvs 1312: 1.43 cvs 1313: memset (parts, '\0', sizeof (HTURI)); 1.28 cvs 1314: /* Look for fragment identifier */ 1.67 cvs 1315: if ((p = ustrchr(name, TEXT('#'))) != NULL) 1.28 cvs 1316: { 1.67 cvs 1317: *p++ = TEXT('\0'); 1.28 cvs 1318: parts->fragment = p; 1.25 cvs 1319: } 1320: 1.28 cvs 1321: for (p=name; *p; p++) 1322: { 1.67 cvs 1323: if (*p == URL_SEP || *p == DIR_SEP || *p == TEXT('#') || *p == TEXT('?')) 1.28 cvs 1324: break; 1.67 cvs 1325: if (*p == TEXT(':')) 1.28 cvs 1326: { 1327: *p = 0; 1328: parts->access = after_access; /* Scheme has been specified */ 1329: 1330: /* The combination of gcc, the "-O" flag and the HP platform is 1331: unhealthy. The following three lines is a quick & dirty fix, but is 1332: not recommended. Rather, turn off "-O". */ 1333: 1334: /* after_access = p;*/ 1335: /* while (*after_access == 0)*/ 1336: /* after_access++;*/ 1337: after_access = p+1; 1.67 cvs 1338: if (!ustrcasecmp(TEXT("URL"), parts->access)) 1.28 cvs 1339: /* Ignore IETF's URL: pre-prefix */ 1340: parts->access = NULL; 1341: else 1.25 cvs 1342: break; 1343: } 1344: } 1345: 1346: p = after_access; 1.43 cvs 1347: if (*p == URL_SEP || *p == DIR_SEP) 1.28 cvs 1348: { 1.43 cvs 1349: if (p[1] == URL_SEP) 1.28 cvs 1350: { 1.25 cvs 1351: parts->host = p+2; /* host has been specified */ 1.28 cvs 1352: *p = 0; /* Terminate access */ 1353: /* look for end of host name if any */ 1.67 cvs 1354: p = ustrchr (parts->host, URL_SEP); 1.28 cvs 1355: if (p) 1356: { 1.87 cvs 1357: *p = WC_EOS; /* Terminate host */ 1.25 cvs 1358: parts->absolute = p+1; /* Root has been found */ 1.28 cvs 1359: } 1360: } 1361: else 1362: /* Root found but no host */ 1363: parts->absolute = p+1; 1364: } 1365: else 1366: { 1.25 cvs 1367: parts->relative = (*after_access) ? after_access : 0; /* zero for "" */ 1.28 cvs 1368: } 1.25 cvs 1369: } 1370: 1371: 1372: /*---------------------------------------------------------------------- 1.28 cvs 1373: AmayaParseUrl: parse a Name relative to another name 1374: 1375: This returns those parts of a name which are given (and requested) 1376: substituting bits from the related name where necessary. 1.25 cvs 1377: 1.28 cvs 1378: On entry, 1.25 cvs 1379: aName A filename given 1380: relatedName A name relative to which aName is to be parsed. Give 1381: it an empty string if aName is absolute. 1382: wanted A mask for the bits which are wanted. 1383: 1.28 cvs 1384: On exit, 1.25 cvs 1385: returns A pointer to a malloc'd string which MUST BE FREED 1386: ----------------------------------------------------------------------*/ 1387: #ifdef __STDC__ 1.84 cvs 1388: CHAR_T* AmayaParseUrl (const CHAR_T* aName, CHAR_T* relatedName, int wanted) 1.25 cvs 1389: #else /* __STDC__ */ 1.84 cvs 1390: CHAR_T* AmayaParseUrl (aName, relatedName, wanted) 1391: const CHAR_T* aName; 1392: CHAR_T* relatedName; 1.28 cvs 1393: int wanted; 1.25 cvs 1394: 1395: #endif /* __STDC__ */ 1396: { 1.84 cvs 1397: CHAR_T* return_value; 1.67 cvs 1398: CHAR_T result[MAX_LENGTH]; 1399: CHAR_T name[MAX_LENGTH]; 1400: CHAR_T rel[MAX_LENGTH]; 1.84 cvs 1401: CHAR_T *p, *access; 1.29 cvs 1402: HTURI given, related; 1403: int len; 1.67 cvs 1404: CHAR_T used_sep; 1.84 cvs 1405: CHAR_T* used_str; 1.32 cvs 1406: 1.84 cvs 1407: if (ustrchr (aName, WC_DIR_SEP) || ustrchr (relatedName, WC_DIR_SEP)) 1.33 cvs 1408: { 1.84 cvs 1409: used_str = WC_DIR_STR; 1410: used_sep = WC_DIR_SEP; 1.33 cvs 1411: } 1.32 cvs 1412: else 1.33 cvs 1413: { 1.84 cvs 1414: used_str = WC_URL_STR; 1415: used_sep = WC_URL_SEP; 1.33 cvs 1416: } 1.32 cvs 1417: 1.29 cvs 1418: /* Make working copies of input strings to cut up: */ 1419: return_value = NULL; 1420: result[0] = 0; /* Clear string */ 1.67 cvs 1421: ustrcpy (name, aName); 1.29 cvs 1422: if (relatedName != NULL) 1.67 cvs 1423: ustrcpy (rel, relatedName); 1.29 cvs 1424: else 1.84 cvs 1425: relatedName[0] = WC_EOS; 1.29 cvs 1426: 1427: scan (name, &given); 1428: scan (rel, &related); 1429: access = given.access ? given.access : related.access; 1430: if (wanted & AMAYA_PARSE_ACCESS) 1431: if (access) 1432: { 1.67 cvs 1433: ustrcat (result, access); 1.29 cvs 1434: if(wanted & AMAYA_PARSE_PUNCTUATION) 1.67 cvs 1435: ustrcat (result, TEXT(":")); 1.29 cvs 1436: } 1437: 1438: if (given.access && related.access) 1439: /* If different, inherit nothing. */ 1.67 cvs 1440: if (ustrcmp (given.access, related.access) != 0) 1.29 cvs 1441: { 1442: related.host = 0; 1443: related.absolute = 0; 1444: related.relative = 0; 1445: related.fragment = 0; 1446: } 1447: 1448: if (wanted & AMAYA_PARSE_HOST) 1449: if(given.host || related.host) 1450: { 1451: if(wanted & AMAYA_PARSE_PUNCTUATION) 1.67 cvs 1452: ustrcat (result, TEXT("//")); 1453: ustrcat (result, given.host ? given.host : related.host); 1.29 cvs 1454: } 1455: 1456: if (given.host && related.host) 1457: /* If different hosts, inherit no path. */ 1.67 cvs 1458: if (ustrcmp (given.host, related.host) != 0) 1.29 cvs 1459: { 1460: related.absolute = 0; 1461: related.relative = 0; 1462: related.fragment = 0; 1463: } 1464: 1465: if (wanted & AMAYA_PARSE_PATH) 1466: { 1467: if (given.absolute) 1468: { 1469: /* All is given */ 1470: if (wanted & AMAYA_PARSE_PUNCTUATION) 1.67 cvs 1471: ustrcat (result, used_str); 1472: ustrcat (result, given.absolute); 1.25 cvs 1473: } 1.29 cvs 1474: else if (related.absolute) 1475: { 1476: /* Adopt path not name */ 1.67 cvs 1477: ustrcat (result, used_str); 1478: ustrcat (result, related.absolute); 1.29 cvs 1479: if (given.relative) 1480: { 1481: /* Search part? */ 1.67 cvs 1482: p = ustrchr (result, TEXT('?')); 1.29 cvs 1483: if (!p) 1.67 cvs 1484: p=result+ustrlen(result)-1; 1.33 cvs 1485: for (; *p!=used_sep; p--); /* last / */ 1.29 cvs 1486: /* Remove filename */ 1487: p[1]=0; 1488: /* Add given one */ 1.67 cvs 1489: ustrcat (result, given.relative); 1.25 cvs 1490: } 1491: } 1.29 cvs 1492: else if (given.relative) 1493: /* what we've got */ 1.67 cvs 1494: ustrcat (result, given.relative); 1.29 cvs 1495: else if (related.relative) 1.67 cvs 1496: ustrcat (result, related.relative); 1.29 cvs 1497: else 1498: /* No inheritance */ 1.67 cvs 1499: ustrcat (result, used_str); 1.25 cvs 1500: } 1.29 cvs 1501: 1502: if (wanted & AMAYA_PARSE_ANCHOR) 1503: if (given.fragment || related.fragment) 1504: { 1505: if (given.absolute && given.fragment) 1506: { 1507: /*Fixes for relURLs...*/ 1508: if (wanted & AMAYA_PARSE_PUNCTUATION) 1.67 cvs 1509: ustrcat (result, TEXT("#")); 1510: ustrcat (result, given.fragment); 1.29 cvs 1511: } 1512: else if (!(given.absolute) && !(given.fragment)) 1.84 cvs 1513: ustrcat (result, TEXT("")); 1.29 cvs 1514: else 1515: { 1516: if (wanted & AMAYA_PARSE_PUNCTUATION) 1.67 cvs 1517: ustrcat (result, TEXT("#")); 1518: ustrcat (result, given.fragment ? given.fragment : related.fragment); 1.29 cvs 1519: } 1520: } 1.67 cvs 1521: len = ustrlen (result); 1522: if ((return_value = TtaAllocString (len + 1)) != NULL) 1523: ustrcpy (return_value, result); 1.29 cvs 1524: return (return_value); /* exactly the right length */ 1.25 cvs 1525: } 1526: 1527: /*---------------------------------------------------------------------- 1528: HTCanon 1529: Canonicalizes the URL in the following manner starting from the host 1530: pointer: 1531: 1532: 1) The host name is converted to lowercase 1533: 2) Chop off port if `:80' (http), `:70' (gopher), or `:21' (ftp) 1534: 1535: Return: OK The position of the current path part of the URL 1536: which might be the old one or a new one. 1537: 1538: ----------------------------------------------------------------------*/ 1539: #ifdef __STDC__ 1.84 cvs 1540: static CHAR_T* HTCanon (CHAR_T** filename, CHAR_T* host) 1.25 cvs 1541: #else /* __STDC__ */ 1.67 cvs 1542: static STRING HTCanon (filename, host) 1.84 cvs 1543: CHAR_T** filename; 1544: CHAR_T* host; 1.25 cvs 1545: #endif /* __STDC__ */ 1546: { 1.84 cvs 1547: CHAR_T* newname = NULL; 1548: CHAR_T used_sep; 1549: CHAR_T* path; 1550: CHAR_T* strptr; 1551: CHAR_T* port; 1552: CHAR_T* access = host-3; 1.32 cvs 1553: 1554: 1.84 cvs 1555: if (*filename && ustrchr (*filename, WC_URL_SEP)) 1.33 cvs 1556: { 1.84 cvs 1557: used_sep = WC_URL_SEP; 1.33 cvs 1558: } 1559: else 1560: { 1.84 cvs 1561: used_sep = WC_DIR_SEP; 1.33 cvs 1562: } 1.32 cvs 1563: 1.82 cvs 1564: while (access > *filename && *(access - 1) != used_sep) /* Find access method */ 1.25 cvs 1565: access--; 1.84 cvs 1566: if ((path = ustrchr (host, used_sep)) == NULL) /* Find path */ 1567: path = host + ustrlen (host); 1568: if ((strptr = ustrchr (host, TEXT('@'))) != NULL && strptr < path) /* UserId */ 1.82 cvs 1569: host = strptr; 1.84 cvs 1570: if ((port = ustrchr (host, TEXT(':'))) != NULL && port > path) /* Port number */ 1.82 cvs 1571: port = NULL; 1.25 cvs 1572: 1573: strptr = host; /* Convert to lower-case */ 1.82 cvs 1574: while (strptr < path) 1.33 cvs 1575: { 1.84 cvs 1576: *strptr = utolower (*strptr); 1.82 cvs 1577: strptr++; 1.33 cvs 1578: } 1.25 cvs 1579: 1580: /* Does the URL contain a full domain name? This also works for a 1581: numerical host name. The domain name is already made lower-case 1582: and without a trailing dot. */ 1583: { 1.84 cvs 1584: CHAR_T* dot = port ? port : path; 1585: if (dot > *filename && *--dot == TEXT('.')) 1.33 cvs 1586: { 1.84 cvs 1587: CHAR_T* orig = dot; 1588: CHAR_T* dest = dot + 1; 1.82 cvs 1589: while ((*orig++ = *dest++)); 1590: if (port) port--; 1.33 cvs 1591: path--; 1.25 cvs 1592: } 1593: } 1594: /* Chop off port if `:', `:80' (http), `:70' (gopher), or `:21' (ftp) */ 1.33 cvs 1595: if (port) 1596: { 1.82 cvs 1597: if (!*(port+1) || *(port+1) == used_sep) 1.33 cvs 1598: { 1599: if (!newname) 1600: { 1.84 cvs 1601: CHAR_T* orig = port; 1602: CHAR_T* dest = port + 1; 1.82 cvs 1603: while ((*orig++ = *dest++)); 1.33 cvs 1604: } 1605: } 1.84 cvs 1606: else if ((!ustrncmp (access, TEXT("http"), 4) && 1607: (*(port + 1) == TEXT('8') && 1608: *(port+2) == TEXT('0') && 1.82 cvs 1609: (*(port+3) == used_sep || !*(port + 3)))) || 1.84 cvs 1610: (!ustrncmp (access, TEXT("gopher"), 6) && 1611: (*(port+1) == TEXT('7') && 1612: *(port+2) == TEXT('0') && 1.82 cvs 1613: (*(port+3) == used_sep || !*(port+3)))) || 1.84 cvs 1614: (!ustrncmp (access, TEXT("ftp"), 3) && 1615: (*(port+1) == TEXT('2') && 1616: *(port + 2) == TEXT('1') && 1.82 cvs 1617: (*(port+3) == used_sep || !*(port+3))))) { 1.33 cvs 1618: if (!newname) 1619: { 1.84 cvs 1620: CHAR_T* orig = port; 1621: CHAR_T* dest = port + 3; 1.33 cvs 1622: while((*orig++ = *dest++)); 1623: /* Update path position, Henry Minsky */ 1624: path -= 3; 1.25 cvs 1625: } 1.33 cvs 1626: } 1627: else if (newname) 1.84 cvs 1628: ustrncat (newname, port, (int) (path - port)); 1.33 cvs 1629: } 1.25 cvs 1630: 1.33 cvs 1631: if (newname) 1632: { 1.84 cvs 1633: CHAR_T* newpath = newname + ustrlen (newname); 1634: ustrcat (newname, path); 1.25 cvs 1635: path = newpath; 1.28 cvs 1636: /* Free old copy */ 1637: TtaFreeMemory(*filename); 1.25 cvs 1638: *filename = newname; 1.33 cvs 1639: } 1.25 cvs 1640: return path; 1641: } 1642: 1643: 1644: /*---------------------------------------------------------------------- 1.29 cvs 1645: SimplifyUrl: simplify a URI 1.32 cvs 1646: A URI is allowed to contain the sequence xxx/../ which may be 1647: replaced by "" , and the sequence "/./" which may be replaced by DIR_STR. 1.28 cvs 1648: Simplification helps us recognize duplicate URIs. 1.25 cvs 1649: 1.28 cvs 1650: Thus, /etc/junk/../fred becomes /etc/fred 1651: /etc/junk/./fred becomes /etc/junk/fred 1.25 cvs 1652: 1.28 cvs 1653: but we should NOT change 1654: http://fred.xxx.edu/../.. 1.25 cvs 1655: 1656: or ../../albert.html 1657: 1.28 cvs 1658: In order to avoid empty URLs the following URLs become: 1.25 cvs 1659: 1660: /fred/.. becomes /fred/.. 1661: /fred/././.. becomes /fred/.. 1662: /fred/.././junk/.././ becomes /fred/.. 1663: 1.28 cvs 1664: If more than one set of `://' is found (several proxies in cascade) then 1665: only the part after the last `://' is simplified. 1.25 cvs 1666: 1.28 cvs 1667: Returns: A string which might be the old one or a new one. 1.25 cvs 1668: ----------------------------------------------------------------------*/ 1669: #ifdef __STDC__ 1.84 cvs 1670: void SimplifyUrl (CHAR_T** url) 1.25 cvs 1671: #else /* __STDC__ */ 1.29 cvs 1672: void SimplifyUrl (url) 1.84 cvs 1673: CHAR_T** url; 1.25 cvs 1674: #endif /* __STDC__ */ 1675: { 1.84 cvs 1676: CHAR_T* path; 1677: CHAR_T* access; 1678: CHAR_T* newptr; 1679: CHAR_T* p; 1680: CHAR_T *orig, *dest, *end; 1.28 cvs 1681: 1.85 cvs 1682: CHAR_T used_sep; 1.77 cvs 1683: ThotBool ddot_simplify; /* used to desactivate the double dot simplifcation: 1684: something/../ simplification in relative URLs when they start with a ../ */ 1.32 cvs 1685: 1686: 1.28 cvs 1687: if (!url || !*url) 1688: return; 1689: 1.84 cvs 1690: if (ustrchr (*url, WC_URL_SEP)) 1.33 cvs 1691: { 1.84 cvs 1692: used_sep = WC_URL_SEP; 1.33 cvs 1693: } 1.32 cvs 1694: else 1.33 cvs 1695: { 1.84 cvs 1696: used_sep = WC_DIR_SEP; 1.33 cvs 1697: } 1.32 cvs 1698: 1.77 cvs 1699: /* should we simplify double dot? */ 1700: path = *url; 1.84 cvs 1701: if (*path == TEXT('.') && *(path + 1) == TEXT('.')) 1.77 cvs 1702: ddot_simplify = FALSE; 1703: else 1704: ddot_simplify = TRUE; 1705: 1.28 cvs 1706: /* Find any scheme name */ 1.84 cvs 1707: if ((path = ustrstr (*url, TEXT("://"))) != NULL) 1.33 cvs 1708: { 1709: /* Find host name */ 1.28 cvs 1710: access = *url; 1.84 cvs 1711: while (access < path && (*access = utolower (*access))) 1.82 cvs 1712: access++; 1.28 cvs 1713: path += 3; 1.84 cvs 1714: while ((newptr = ustrstr (path, TEXT ("://"))) != NULL) 1.82 cvs 1715: /* For proxies */ 1716: path = newptr+3; 1717: /* We have a host name */ 1.84 cvs 1718: path = HTCanon (url, path); 1.25 cvs 1719: } 1.84 cvs 1720: else if ((path = ustrstr (*url, TEXT(":/"))) != NULL) 1.28 cvs 1721: path += 2; 1722: else 1723: path = *url; 1.25 cvs 1724: 1.84 cvs 1725: if (*path == used_sep && *(path+1) == used_sep) 1.28 cvs 1726: /* Some URLs start //<foo> */ 1727: path += 1; 1.84 cvs 1728: else if (!ustrncmp (path, TEXT("news:"), 5)) 1.28 cvs 1729: { 1.84 cvs 1730: newptr = ustrchr (path+5, TEXT('@')); 1.28 cvs 1731: if (!newptr) 1732: newptr = path + 5; 1733: while (*newptr) 1734: { 1735: /* Make group or host lower case */ 1.84 cvs 1736: *newptr = utolower (*newptr); 1.28 cvs 1737: newptr++; 1.25 cvs 1738: } 1.28 cvs 1739: /* Doesn't need to do any more */ 1740: return; 1.25 cvs 1741: } 1.28 cvs 1742: 1743: if ((p = path)) 1744: { 1.67 cvs 1745: if (!((end = ustrchr (path, TEXT(';'))) || (end = ustrchr (path, TEXT('?'))) || 1746: (end = ustrchr (path, TEXT('#'))))) 1747: end = path + ustrlen (path); 1.28 cvs 1748: 1749: /* Parse string second time to simplify */ 1750: p = path; 1751: while (p < end) 1752: { 1.77 cvs 1753: /* if we're pointing to a char, it's safe to reactivate the ../ convertion */ 1754: if (!ddot_simplify && *p != TEXT('.') && *p != used_sep) 1755: ddot_simplify = TRUE; 1756: 1.33 cvs 1757: if (*p==used_sep) 1.28 cvs 1758: { 1.67 cvs 1759: if (p > *url && *(p+1) == TEXT('.') && (*(p+2) == used_sep || !*(p+2))) 1.28 cvs 1760: { 1761: orig = p + 1; 1.84 cvs 1762: dest = (*(p+2) != used_sep) ? p+2 : p+3; 1.52 cvs 1763: while ((*orig++ = *dest++)); /* Remove a used_sep and a dot*/ 1.28 cvs 1764: end = orig - 1; 1765: } 1.77 cvs 1766: else if (ddot_simplify && *(p+1) == TEXT('.') && *(p+2) == TEXT('.') 1767: && (*(p+3) == used_sep || !*(p+3))) 1.28 cvs 1768: { 1769: newptr = p; 1.52 cvs 1770: while (newptr>path && *--newptr!=used_sep); /* prev used_sep */ 1771: if (*newptr == used_sep) 1772: orig = newptr + 1; 1.28 cvs 1773: else 1.52 cvs 1774: orig = newptr; 1775: 1776: dest = (*(p+3) != used_sep) ? p+3 : p+4; 1777: while ((*orig++ = *dest++)); /* Remove /xxx/.. */ 1778: end = orig-1; 1779: /* Start again with prev slash */ 1780: p = newptr; 1.28 cvs 1781: } 1.33 cvs 1782: else if (*(p+1) == used_sep) 1.28 cvs 1783: { 1.33 cvs 1784: while (*(p+1) == used_sep) 1.28 cvs 1785: { 1786: orig = p; 1787: dest = p + 1; 1788: while ((*orig++ = *dest++)); /* Remove multiple /'s */ 1789: end = orig-1; 1790: } 1791: } 1792: else 1.25 cvs 1793: p++; 1.28 cvs 1794: } 1795: else 1796: p++; 1.25 cvs 1797: } 1798: } 1.51 cvs 1799: 1800: /* 1801: ** Check for host/../.. kind of things 1802: */ 1.77 cvs 1803: if (*path == used_sep && *(path+1) == TEXT('.') && *(path+2) == TEXT('.') 1804: && (!*(path+3) || *(path+3) == used_sep)) 1.87 cvs 1805: *(path+1) = WC_EOS; 1.51 cvs 1806: 1.28 cvs 1807: return; 1808: } 1809: 1810: 1811: /*---------------------------------------------------------------------- 1812: NormalizeFile normalizes local names. 1813: Return TRUE if target and src differ. 1814: ----------------------------------------------------------------------*/ 1815: #ifdef __STDC__ 1.90 ! cvs 1816: ThotBool NormalizeFile (CHAR_T* src, CHAR_T* target) 1.28 cvs 1817: #else 1.90 ! cvs 1818: ThotBool NormalizeFile (src, target) 1.84 cvs 1819: CHAR_T* src; 1820: CHAR_T* target; 1.28 cvs 1821: 1822: #endif 1823: { 1.90 ! cvs 1824: CHAR_T *s; 1.82 cvs 1825: ThotBool change; 1.90 ! cvs 1826: int i; ! 1827: int start_index; /* the first char that we'll copy */ 1.28 cvs 1828: 1.54 cvs 1829: change = FALSE; 1.90 ! cvs 1830: start_index = 0; ! 1831: ! 1832: if (!src || src[0] == WC_EOS) ! 1833: return FALSE; ! 1834: ! 1835: /* @@ do I need file: or file:/ here? */ 1.84 cvs 1836: if (ustrncmp (src, TEXT("file:"), 5) == 0) 1.28 cvs 1837: { 1.90 ! cvs 1838: /* remove the prefix file: */ ! 1839: start_index += 5; ! 1840: ! 1841: if (ustrncmp (&src[start_index], TEXT("/localhost"), 10) == 0) ! 1842: /* remove the localhost prefix */ ! 1843: start_index += 10; ! 1844: ! 1845: if (src[start_index] == WC_EOS) ! 1846: /* if there's nothing afterwards, add a DIR_STR */ ! 1847: ustrcpy (target, WC_DIR_STR); ! 1848: #ifndef _WINDOWS ! 1849: else if (src[start_index] == TEXT('~')) ! 1850: { ! 1851: /* replace ~ */ ! 1852: s = TtaGetEnvString ("HOME"); ! 1853: ustrcpy (target, s); ! 1854: start_index++; ! 1855: i = ustrlen (target); ! 1856: ustrcat (&target[i], &src[start_index]); ! 1857: } ! 1858: #endif /* _WINDOWS */ ! 1859: else ! 1860: { ! 1861: CleanCopyFileURL (target, &src[start_index]); ! 1862: change = TRUE; ! 1863: } 1.28 cvs 1864: } 1.90 ! cvs 1865: #ifndef _WINDOWS 1.84 cvs 1866: else if (src[0] == TEXT('~')) 1.53 cvs 1867: { 1868: /* replace ~ */ 1.82 cvs 1869: s = TtaGetEnvString ("HOME"); 1.84 cvs 1870: ustrcpy (target, s); 1.90 ! cvs 1871: #if 0 1.84 cvs 1872: if (src[1] != WC_DIR_SEP) 1873: ustrcat (target, WC_DIR_STR); 1.90 ! cvs 1874: #endif ! 1875: i = ustrlen (target); ! 1876: CleanCopyFileURL (&target[i], &src[1]); 1.54 cvs 1877: change = TRUE; 1.53 cvs 1878: } 1.90 ! cvs 1879: #endif /* _WINDOWS */ ! 1880: 1.28 cvs 1881: else 1.90 ! cvs 1882: CleanCopyFileURL (target, src); 1.28 cvs 1883: 1884: /* remove /../ and /./ */ 1.29 cvs 1885: SimplifyUrl (&target); 1.54 cvs 1886: if (!change) 1.84 cvs 1887: change = ustrcmp (src, target); 1.28 cvs 1888: return (change); 1.25 cvs 1889: } 1890: 1.28 cvs 1891: 1.25 cvs 1892: /*---------------------------------------------------------------------- 1.31 cvs 1893: MakeRelativeURL: make relative name 1.25 cvs 1894: 1.28 cvs 1895: This function creates and returns a string which gives an expression of 1896: one address as related to another. Where there is no relation, an absolute 1897: address is retured. 1.25 cvs 1898: 1.28 cvs 1899: On entry, 1.25 cvs 1900: Both names must be absolute, fully qualified names of nodes 1901: (no fragment bits) 1902: 1.28 cvs 1903: On exit, 1.25 cvs 1904: The return result points to a newly allocated name which, if 1905: parsed by AmayaParseUrl relative to relatedName, will yield aName. 1906: The caller is responsible for freeing the resulting name later. 1907: ----------------------------------------------------------------------*/ 1908: #ifdef __STDC__ 1.67 cvs 1909: STRING MakeRelativeURL (STRING aName, STRING relatedName) 1.25 cvs 1910: #else /* __STDC__ */ 1.67 cvs 1911: STRING MakeRelativeURL (aName, relatedName) 1912: STRING aName; 1913: STRING relatedName; 1.25 cvs 1914: #endif /* __STDC__ */ 1915: { 1.87 cvs 1916: CHAR_T* return_value; 1.67 cvs 1917: CHAR_T result[MAX_LENGTH]; 1.87 cvs 1918: CHAR_T* p; 1919: CHAR_T* q; 1920: CHAR_T* after_access; 1921: CHAR_T* last_slash = NULL; 1.29 cvs 1922: int slashes, levels, len; 1923: 1.44 cvs 1924: # ifdef _WINDOWS 1925: int ndx; 1926: # endif /* _WINDOWS */ 1927: 1.29 cvs 1928: if (aName == NULL || relatedName == NULL) 1929: return (NULL); 1930: 1931: slashes = 0; 1932: after_access = NULL; 1933: p = aName; 1934: q = relatedName; 1935: for (; *p && (*p == *q); p++, q++) 1.27 cvs 1936: { 1937: /* Find extent of match */ 1.67 cvs 1938: if (*p == TEXT(':')) 1.29 cvs 1939: after_access = p + 1; 1.28 cvs 1940: if (*p == DIR_SEP) 1.27 cvs 1941: { 1.29 cvs 1942: /* memorize the last slash position and count them */ 1.27 cvs 1943: last_slash = p; 1944: slashes++; 1.25 cvs 1945: } 1946: } 1947: 1.31 cvs 1948: /* q, p point to the first non-matching character or zero */ 1.87 cvs 1949: if (*q == WC_EOS) 1.31 cvs 1950: { 1951: /* New name is a subset of the related name */ 1952: /* exactly the right length */ 1.67 cvs 1953: len = ustrlen (p); 1954: if ((return_value = TtaAllocString (len + 1)) != NULL) 1955: ustrcpy (return_value, p); 1.31 cvs 1956: } 1957: else if ((slashes < 2 && after_access == NULL) 1958: || (slashes < 3 && after_access != NULL)) 1959: { 1960: /* Two names whitout common path */ 1961: /* exactly the right length */ 1.67 cvs 1962: len = ustrlen (aName); 1963: if ((return_value = TtaAllocString (len + 1)) != NULL) 1964: ustrcpy (return_value, aName); 1.31 cvs 1965: } 1966: else 1967: { 1968: /* Some path in common */ 1.67 cvs 1969: if (slashes == 3 && ustrncmp (aName, TEXT("http:"), 5) == 0) 1.31 cvs 1970: /* just the same server */ 1.67 cvs 1971: ustrcpy (result, last_slash); 1.31 cvs 1972: else 1973: { 1974: levels= 0; 1.67 cvs 1975: for (; *q && *q != TEXT('#') && *q != TEXT(';') && *q != TEXT('?'); q++) 1.31 cvs 1976: if (*q == DIR_SEP) 1977: levels++; 1978: 1.87 cvs 1979: result[0] = WC_EOS; 1.31 cvs 1980: for (;levels; levels--) 1.67 cvs 1981: ustrcat (result, TEXT("../")); 1982: ustrcat (result, last_slash+1); 1.31 cvs 1983: } 1.52 cvs 1984: 1985: if (!*result) 1.67 cvs 1986: ustrcat (result, TEXT("./")); 1.52 cvs 1987: 1.31 cvs 1988: /* exactly the right length */ 1.67 cvs 1989: len = ustrlen (result); 1990: if ((return_value = TtaAllocString (len + 1)) != NULL) 1991: ustrcpy (return_value, result); 1.52 cvs 1992: 1.25 cvs 1993: } 1.44 cvs 1994: # ifdef _WINDOWS 1.67 cvs 1995: len = ustrlen (return_value); 1.44 cvs 1996: for (ndx = 0; ndx < len; ndx ++) 1.67 cvs 1997: if (return_value[ndx] == TEXT('\\')) 1998: return_value[ndx] = TEXT('/') ; 1.44 cvs 1999: # endif /* _WINDOWS */ 1.29 cvs 2000: return (return_value); 1.24 cvs 2001: } 1.35 cvs 2002: 2003: