~ubuntu-branches/ubuntu/hoary/lynx-cur/hoary

« back to all changes in this revision

Viewing changes to WWW/Library/Implementation/HTFile.c

  • Committer: Bazaar Package Importer
  • Author(s): Atsuhito KOHDA
  • Date: 2005-01-03 11:05:58 UTC
  • Revision ID: james.westby@ubuntu.com-20050103110558-76sra39x20blifda
Tags: 2.8.6-8
* This is of 2.8.6dev.10
- syslog'ing of URLs was now an option in lynx.cfg or in command line.
  (Closes:  #282739)
- fixed gap in title from newline. (Closes: #284679)
- fixed can't climb to the root directory.  (Closes: #285140)

Show diffs side-by-side

added added

removed removed

Lines of Context:
130
130
int HTDirReadme = HT_DIR_README_TOP;
131
131
#endif /* DIRED_SUPPORT */
132
132
 
133
 
static char *HTMountRoot = "/Net/";     /* Where to find mounts */
 
133
static const char *HTMountRoot = "/Net/";       /* Where to find mounts */
134
134
 
135
135
#ifdef VMS
136
 
static char *HTCacheRoot = "/WWW$SCRATCH";      /* Where to cache things */
 
136
static const char *HTCacheRoot = "/WWW$SCRATCH";        /* Where to cache things */
137
137
 
138
138
#else
139
 
static char *HTCacheRoot = "/tmp/W3_Cache_";    /* Where to cache things */
 
139
static const char *HTCacheRoot = "/tmp/W3_Cache_";      /* Where to cache things */
140
140
#endif /* VMS */
141
141
 
142
142
/*
189
189
    return *bufp;
190
190
}
191
191
 
192
 
static void LYListFmtParse(char *fmtstr,
 
192
static void LYListFmtParse(const char *fmtstr,
193
193
                           DIRED * data,
194
194
                           char *file,
195
195
                           HTStructured * target,
205
205
    char type;
206
206
 
207
207
#ifndef NOUSERS
208
 
    char *name;
 
208
    const char *name;
209
209
#endif
210
210
    time_t now;
211
211
    char *datestr;
216
216
#define SEC_PER_YEAR    (60 * 60 * 24 * 365)
217
217
 
218
218
#ifdef _WINDOWS                 /* 1998/01/06 (Tue) 21:20:53 */
219
 
    static char *pbits[] =
 
219
    static const char *pbits[] =
220
220
    {
221
221
        "---", "--x", "-w-", "-wx",
222
222
        "r--", "r-x", "rw-", "rwx",
225
225
#define PBIT(a, n, s)  pbits[((a) >> (n)) & 0x7]
226
226
 
227
227
#else
228
 
    static char *pbits[] =
 
228
    static const char *pbits[] =
229
229
    {"---", "--x", "-w-", "-wx",
230
230
     "r--", "r-x", "rw-", "rwx", 0};
231
 
    static char *psbits[] =
 
231
    static const char *psbits[] =
232
232
    {"--S", "--s", "-wS", "-ws",
233
233
     "r-S", "r-s", "rwS", "rws", 0};
234
234
 
236
236
        pbits[((a) >> (n)) & 0x7]
237
237
#endif
238
238
#ifdef S_ISVTX
239
 
    static char *ptbits[] =
 
239
    static const char *ptbits[] =
240
240
    {"--T", "--t", "-wT", "-wt",
241
241
     "r-T", "r-t", "rwT", "rwt", 0};
242
242
 
669
669
    char *acc_method = HTParse(name, "", PARSE_ACCESS);
670
670
    char *host = HTParse(name, "", PARSE_HOST);
671
671
    char *path = HTParse(name, "", PARSE_PATH + PARSE_PUNCTUATION);
672
 
    char *home;
 
672
    const char *home;
673
673
    char *result = NULL;
674
674
 
675
675
    if (expand_all) {
697
697
            home = HTVMS_wwwName(home);
698
698
#else
699
699
#if defined(_WINDOWS)           /* 1997/10/16 (Thu) 20:42:51 */
700
 
        home = (char *) Home_Dir();
 
700
        home = Home_Dir();
701
701
#else
702
702
        home = LYGetEnv("HOME");
703
703
#endif
812
812
    return "";                  /* Dunno */
813
813
}
814
814
 
 
815
/*
 
816
 * Trim version from VMS filenames to avoid confusing comparisons.
 
817
 */
 
818
#ifdef VMS
 
819
static const char *VMS_trim_version(const char *filename)
 
820
{
 
821
    const char *result = filename;
 
822
    const char *version = strchr(filename, ';');
 
823
 
 
824
    if (version != 0) {
 
825
        static char *stripped;
 
826
 
 
827
        StrAllocCopy(stripped, filename);
 
828
        stripped[version - filename] = '\0';
 
829
        result = (const char *) stripped;
 
830
    }
 
831
    return result;
 
832
}
 
833
#define VMS_DEL_VERSION(name) name = VMS_trim_version(name)
 
834
#else
 
835
#define VMS_DEL_VERSION(name)   /* nothing */
 
836
#endif
 
837
 
815
838
/*      Determine file format from file name.
816
839
 *      -------------------------------------
817
840
 *
832
855
    int i;
833
856
    int lf;
834
857
 
835
 
#ifdef VMS
836
 
    char *semicolon = NULL;
837
 
#endif /* VMS */
 
858
    VMS_DEL_VERSION(filename);
838
859
 
839
860
    if (pencoding)
840
861
        *pencoding = NULL;
845
866
            *pencoding = WWW_ENC_8BIT;
846
867
        return WWW_HTML;
847
868
    }
848
 
#ifdef VMS
849
 
    /*
850
 
     * Trim at semicolon if a version number was included, so it doesn't
851
 
     * interfere with the code for getting the MIME type.  - FM
852
 
     */
853
 
    if ((semicolon = strchr(filename, ';')) != NULL)
854
 
        *semicolon = '\0';
855
 
#endif /* VMS */
856
 
 
857
869
#ifndef NO_INIT
858
870
    if (!HTSuffixes)
859
871
        HTFileInit();
873
885
            if (pdesc)
874
886
                *pdesc = suff->desc;
875
887
            if (suff->rep) {
876
 
#ifdef VMS
877
 
                if (semicolon != NULL)
878
 
                    *semicolon = ';';
879
 
#endif /* VMS */
880
888
                return suff->rep;       /* OK -- found */
881
889
            }
882
890
            for (j = 0; j < n; j++) {   /* Got encoding, need representation */
894
902
                            *pencoding != WWW_ENC_7BIT &&
895
903
                            !IsUnityEnc(suff->encoding))
896
904
                            *pencoding = suff->encoding;
897
 
#ifdef VMS
898
 
                        if (semicolon != NULL)
899
 
                            *semicolon = ';';
900
 
#endif /* VMS */
901
905
                        return suff->rep;
902
906
                    }
903
907
                }
915
919
    /*
916
920
     * Set default encoding unless found with suffix already.
917
921
     */
918
 
    if (pencoding && !*pencoding)
919
 
        *pencoding = suff->encoding ? suff->encoding
920
 
            : HTAtom_for("binary");
921
 
#ifdef VMS
922
 
    if (semicolon != NULL)
923
 
        *semicolon = ';';
924
 
#endif /* VMS */
 
922
    if (pencoding && !*pencoding) {
 
923
        *pencoding = (suff->encoding
 
924
                      ? suff->encoding
 
925
                      : HTAtom_for("binary"));
 
926
    }
925
927
    return suff->rep ? suff->rep : WWW_BINARY;
926
928
}
927
929
 
1199
1201
 *  Determine compression type from file name, by looking at its suffix.
1200
1202
 *  Sets as side-effect a pointer to the "dot" that begins the suffix.
1201
1203
 */
1202
 
CompressFileType HTCompressFileType(char *filename,
1203
 
                                    char *dots,
1204
 
                                    char **suffix)
 
1204
CompressFileType HTCompressFileType(const char *filename,
 
1205
                                    const char *dots,
 
1206
                                    int *rootlen)
1205
1207
{
1206
1208
    CompressFileType result = cftNone;
1207
1209
    size_t len = strlen(filename);
1208
 
    char *ftype = filename + len;
 
1210
    const char *ftype = filename + len;
 
1211
 
 
1212
    VMS_DEL_VERSION(filename);
1209
1213
 
1210
1214
    if ((len > 4)
1211
1215
        && !strcasecomp((ftype - 3), "bz2")
1217
1221
               && strchr(dots, ftype[-3]) != 0) {
1218
1222
        result = cftGzip;
1219
1223
        ftype -= 3;
 
1224
    } else if ((len > 3)
 
1225
               && !strcasecomp((ftype - 2), "zz")
 
1226
               && strchr(dots, ftype[-3]) != 0) {
 
1227
        result = cftDeflate;
 
1228
        ftype -= 3;
1220
1229
    } else if ((len > 2)
1221
1230
               && !strcmp((ftype - 1), "Z")
1222
1231
               && strchr(dots, ftype[-2]) != 0) {
1224
1233
        ftype -= 2;
1225
1234
    }
1226
1235
 
1227
 
    *suffix = ftype;
 
1236
    *rootlen = (ftype - filename);
 
1237
 
1228
1238
    CTRACE((tfp, "HTCompressFileType(%s) returns %d:%s\n",
1229
 
            filename, result, *suffix));
 
1239
            filename, (int) result, filename + *rootlen));
 
1240
    return result;
 
1241
}
 
1242
 
 
1243
/*
 
1244
 * Check if the token from "Content-Encoding" corresponds to a compression
 
1245
 * type.  RFC 2068 (and cut/paste into RFC 2616) lists these:
 
1246
 *      gzip
 
1247
 *      compress
 
1248
 *      deflate
 
1249
 * as well as "identity" (but that does nothing).
 
1250
 */
 
1251
CompressFileType HTEncodingToCompressType(const char *coding)
 
1252
{
 
1253
    CompressFileType result = cftNone;
 
1254
 
 
1255
    if (coding == 0) {
 
1256
        result = cftNone;
 
1257
    } else if (!strcasecomp(coding, "gzip") ||
 
1258
               !strcasecomp(coding, "x-gzip")) {
 
1259
        result = cftGzip;
 
1260
    } else if (!strcasecomp(coding, "compress") ||
 
1261
               !strcasecomp(coding, "x-compress")) {
 
1262
        result = cftCompress;
 
1263
    } else if (!strcasecomp(coding, "bzip2") ||
 
1264
               !strcasecomp(coding, "x-bzip2")) {
 
1265
        result = cftBzip2;
 
1266
    } else if (!strcasecomp(coding, "deflate") ||
 
1267
               !strcasecomp(coding, "x-deflate")) {
 
1268
        result = cftDeflate;
 
1269
    }
1230
1270
    return result;
1231
1271
}
1232
1272
 
1623
1663
#define NM_cmp(a,b) ((a) < (b) ? -1 : ((a) > (b) ? 1 : 0))
1624
1664
 
1625
1665
#if defined(LONG_LIST) && defined(DIRED_SUPPORT)
1626
 
static char *file_type(char *path)
 
1666
static const char *file_type(const char *path)
1627
1667
{
1628
 
    char *type;
 
1668
    const char *type;
1629
1669
 
1630
1670
    while (*path == '.')
1631
1671
        ++path;
1696
1736
    BOOL need_parent_link = FALSE;
1697
1737
    int status;
1698
1738
    int i;
 
1739
    struct stat *actual_info;
 
1740
 
 
1741
#ifdef S_IFLNK
 
1742
    struct stat link_info;
 
1743
#endif
1699
1744
 
1700
1745
    CTRACE((tfp, "print_local_dir() started\n"));
1701
1746
 
1796
1841
            StrAllocCat(tmpfilename, dirbuf->d_name);
1797
1842
            data = (DIRED *) malloc(sizeof(DIRED) + strlen(dirbuf->d_name) + 4);
1798
1843
            if (data == NULL) {
1799
 
                /* FIXME */
 
1844
                status = HT_PARTIAL_CONTENT;
 
1845
                break;
1800
1846
            }
1801
1847
            LYTrimPathSep(tmpfilename);
1802
 
            if (lstat(tmpfilename, &(data->file_info)) < 0)
1803
 
                data->file_info.st_mode = 0;
 
1848
 
 
1849
            actual_info = &(data->file_info);
 
1850
#ifdef S_IFLNK
 
1851
            if (lstat(tmpfilename, actual_info) < 0) {
 
1852
                actual_info->st_mode = 0;
 
1853
            } else {
 
1854
                if (S_ISLNK(actual_info->st_mode)) {
 
1855
                    actual_info = &link_info;
 
1856
                    if (stat(tmpfilename, actual_info) < 0)
 
1857
                        actual_info->st_mode = 0;
 
1858
                }
 
1859
            }
 
1860
#else
 
1861
            if (stat(tmpfilename, actual_info) < 0)
 
1862
                actual_info->st_mode = 0;
 
1863
#endif
1804
1864
 
1805
1865
            strcpy(data->file_name, dirbuf->d_name);
1806
1866
#ifndef DIRED_SUPPORT
1807
 
            if (S_ISDIR(data->file_info.st_mode)) {
 
1867
            if (S_ISDIR(actual_info->st_mode)) {
1808
1868
                data->sort_tags = 'D';
1809
1869
            } else {
1810
1870
                data->sort_tags = 'F';
1811
1871
                /* D & F to have first directories, then files */
1812
1872
            }
1813
1873
#else
1814
 
            if (S_ISDIR(data->file_info.st_mode)) {
 
1874
            if (S_ISDIR(actual_info->st_mode)) {
1815
1875
                if (dir_list_style == MIXED_STYLE) {
1816
1876
                    data->sort_tags = ' ';
1817
1877
                    LYAddPathSep0(data->file_name);
2059
2119
}
2060
2120
#endif
2061
2121
 
 
2122
#ifdef VMS
 
2123
#define FOPEN_MODE(bin) "r", "shr=put", "shr=upd"
 
2124
#define DOT_STRING "._-"        /* FIXME: should we check if suffix is after ']' or ':' ? */
 
2125
#else
 
2126
#define FOPEN_MODE(bin) (bin ? BIN_R : "r")
 
2127
#define DOT_STRING "."
 
2128
#endif
 
2129
 
 
2130
static int decompressAndParse(HTParentAnchor *anchor,
 
2131
                              HTFormat format_out,
 
2132
                              HTStream *sink,
 
2133
                              char *nodename GCC_UNUSED,
 
2134
                              char *filename,
 
2135
                              HTAtom *myEncoding,
 
2136
                              HTFormat format,
 
2137
                              int *statusp)
 
2138
{
 
2139
    HTAtom *encoding = 0;
 
2140
 
 
2141
#ifdef USE_ZLIB
 
2142
    FILE *zzfp = 0;
 
2143
    gzFile gzfp = 0;
 
2144
#endif /* USE_ZLIB */
 
2145
#ifdef USE_BZLIB
 
2146
    BZFILE *bzfp = 0;
 
2147
#endif /* USE_ZLIB */
 
2148
#if defined(USE_ZLIB) || defined(USE_BZLIB)
 
2149
    CompressFileType internal_decompress = cftNone;
 
2150
    BOOL failed_decompress = NO;
 
2151
#endif
 
2152
    int rootlen = 0;
 
2153
    char *localname = filename;
 
2154
    int bin;
 
2155
    FILE *fp;
 
2156
 
 
2157
#ifdef VMS
 
2158
    /*
 
2159
     * Assume that the file is in Unix-style syntax if it contains a '/' after
 
2160
     * the leading one.  @@
 
2161
     */
 
2162
    localname = (strchr(localname + 1, '/')
 
2163
                 ? HTVMS_name(nodename, localname)
 
2164
                 : localname + 1);
 
2165
#endif /* VMS */
 
2166
 
 
2167
    bin = HTCompressFileType(filename, ".", &rootlen) != cftNone;
 
2168
    fp = fopen(localname, FOPEN_MODE(bin));
 
2169
 
 
2170
#ifdef VMS
 
2171
    /*
 
2172
     * If the file wasn't VMS syntax, then perhaps it is Ultrix.
 
2173
     */
 
2174
    if (!fp) {
 
2175
        char *ultrixname = 0;
 
2176
 
 
2177
        CTRACE((tfp, "HTLoadFile: Can't open as %s\n", localname));
 
2178
        HTSprintf0(&ultrixname, "%s::\"%s\"", nodename, filename);
 
2179
        fp = fopen(ultrixname, FOPEN_MODE(bin));
 
2180
        if (!fp) {
 
2181
            CTRACE((tfp, "HTLoadFile: Can't open as %s\n", ultrixname));
 
2182
        }
 
2183
        FREE(ultrixname);
 
2184
    }
 
2185
#endif /* VMS */
 
2186
    CTRACE((tfp, "HTLoadFile: Opening `%s' gives %p\n", localname, fp));
 
2187
    if (fp) {                   /* Good! */
 
2188
        if (HTEditable(localname)) {
 
2189
            HTAtom *put = HTAtom_for("PUT");
 
2190
            HTList *methods = HTAnchor_methods(anchor);
 
2191
 
 
2192
            if (HTList_indexOf(methods, put) == (-1)) {
 
2193
                HTList_addObject(methods, put);
 
2194
            }
 
2195
        }
 
2196
        /*
 
2197
         * Fake a Content-Encoding for compressed files.  - FM
 
2198
         */
 
2199
        if (!IsUnityEnc(myEncoding)) {
 
2200
            /*
 
2201
             * We already know from the call to HTFileFormat that
 
2202
             * this is a compressed file, no need to look at the filename
 
2203
             * again.  - kw
 
2204
             */
 
2205
            CompressFileType method = HTEncodingToCompressType(HTAtom_name(myEncoding));
 
2206
 
 
2207
#define isDOWNLOAD(m) (strcmp(format_out->name, "www/download") && (method == m))
 
2208
#ifdef USE_ZLIB
 
2209
            if (isDOWNLOAD(cftGzip)) {
 
2210
                fclose(fp);
 
2211
                gzfp = gzopen(localname, BIN_R);
 
2212
 
 
2213
                CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n",
 
2214
                        localname, gzfp));
 
2215
                internal_decompress = cftGzip;
 
2216
            } else if (isDOWNLOAD(cftDeflate)) {
 
2217
                zzfp = fp;
 
2218
                fp = 0;
 
2219
 
 
2220
                CTRACE((tfp, "HTLoadFile: zzopen of `%s' gives %p\n",
 
2221
                        localname, zzfp));
 
2222
                internal_decompress = cftDeflate;
 
2223
            } else
 
2224
#endif /* USE_ZLIB */
 
2225
#ifdef USE_BZLIB
 
2226
            if (isDOWNLOAD(cftBzip2)) {
 
2227
                fclose(fp);
 
2228
                bzfp = BZ2_bzopen(localname, BIN_R);
 
2229
 
 
2230
                CTRACE((tfp, "HTLoadFile: bzopen of `%s' gives %p\n",
 
2231
                        localname, bzfp));
 
2232
                internal_decompress = cftBzip2;
 
2233
            } else
 
2234
#endif /* USE_BZLIB */
 
2235
            {
 
2236
                StrAllocCopy(anchor->content_type, format->name);
 
2237
                StrAllocCopy(anchor->content_encoding, HTAtom_name(myEncoding));
 
2238
                format = HTAtom_for("www/compressed");
 
2239
            }
 
2240
        } else {
 
2241
            CompressFileType cft = HTCompressFileType(localname, DOT_STRING, &rootlen);
 
2242
 
 
2243
            if (cft != cftNone) {
 
2244
                char *cp = NULL;
 
2245
 
 
2246
                StrAllocCopy(cp, localname);
 
2247
                cp[rootlen] = '\0';
 
2248
                format = HTFileFormat(cp, &encoding, NULL);
 
2249
                FREE(cp);
 
2250
                format = HTCharsetFormat(format, anchor,
 
2251
                                         UCLYhndl_HTFile_for_unspec);
 
2252
                StrAllocCopy(anchor->content_type, format->name);
 
2253
            }
 
2254
 
 
2255
            switch (cft) {
 
2256
            case cftCompress:
 
2257
                StrAllocCopy(anchor->content_encoding, "x-compress");
 
2258
                format = HTAtom_for("www/compressed");
 
2259
                break;
 
2260
            case cftDeflate:
 
2261
                StrAllocCopy(anchor->content_encoding, "x-deflate");
 
2262
#ifdef USE_ZLIB
 
2263
                if (strcmp(format_out->name, "www/download") != 0) {
 
2264
                    zzfp = fp;
 
2265
                    fp = 0;
 
2266
 
 
2267
                    CTRACE((tfp, "HTLoadFile: zzopen of `%s' gives %p\n",
 
2268
                            localname, zzfp));
 
2269
                    internal_decompress = cftDeflate;
 
2270
                }
 
2271
#else /* USE_ZLIB */
 
2272
                format = HTAtom_for("www/compressed");
 
2273
#endif /* USE_ZLIB */
 
2274
                break;
 
2275
            case cftGzip:
 
2276
                StrAllocCopy(anchor->content_encoding, "x-gzip");
 
2277
#ifdef USE_ZLIB
 
2278
                if (strcmp(format_out->name, "www/download") != 0) {
 
2279
                    fclose(fp);
 
2280
                    gzfp = gzopen(localname, BIN_R);
 
2281
 
 
2282
                    CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n",
 
2283
                            localname, gzfp));
 
2284
                    internal_decompress = cftGzip;
 
2285
                }
 
2286
#else /* USE_ZLIB */
 
2287
                format = HTAtom_for("www/compressed");
 
2288
#endif /* USE_ZLIB */
 
2289
                break;
 
2290
            case cftBzip2:
 
2291
                StrAllocCopy(anchor->content_encoding, "x-bzip2");
 
2292
#ifdef USE_BZLIB
 
2293
                if (strcmp(format_out->name, "www/download") != 0) {
 
2294
                    fclose(fp);
 
2295
                    bzfp = BZ2_bzopen(localname, BIN_R);
 
2296
 
 
2297
                    CTRACE((tfp, "HTLoadFile: bzopen of `%s' gives %p\n",
 
2298
                            localname, bzfp));
 
2299
                    internal_decompress = cftBzip2;
 
2300
                }
 
2301
#else /* USE_BZLIB */
 
2302
                format = HTAtom_for("www/compressed");
 
2303
#endif /* USE_BZLIB */
 
2304
                break;
 
2305
            case cftNone:
 
2306
                break;
 
2307
            }
 
2308
        }
 
2309
#if defined(USE_ZLIB) || defined(USE_BZLIB)
 
2310
        if (internal_decompress != cftNone) {
 
2311
            switch (internal_decompress) {
 
2312
#ifdef USE_ZLIB
 
2313
            case cftDeflate:
 
2314
                failed_decompress = (zzfp == 0);
 
2315
                break;
 
2316
            case cftCompress:
 
2317
            case cftGzip:
 
2318
                failed_decompress = (gzfp == 0);
 
2319
                break;
 
2320
#endif
 
2321
#ifdef USE_BZLIB
 
2322
            case cftBzip2:
 
2323
                failed_decompress = (bzfp == 0);
 
2324
                break;
 
2325
#endif
 
2326
            default:
 
2327
                failed_decompress = YES;
 
2328
                break;
 
2329
            }
 
2330
            if (failed_decompress) {
 
2331
                *statusp = HTLoadError(NULL,
 
2332
                                       -(HT_ERROR),
 
2333
                                       FAILED_OPEN_COMPRESSED_FILE);
 
2334
            } else {
 
2335
                char *sugfname = NULL;
 
2336
 
 
2337
                if (anchor->SugFname) {
 
2338
                    StrAllocCopy(sugfname, anchor->SugFname);
 
2339
                } else {
 
2340
                    char *anchor_path = HTParse(anchor->address, "",
 
2341
                                                PARSE_PATH + PARSE_PUNCTUATION);
 
2342
                    char *lastslash;
 
2343
 
 
2344
                    HTUnEscape(anchor_path);
 
2345
                    lastslash = strrchr(anchor_path, '/');
 
2346
                    if (lastslash)
 
2347
                        StrAllocCopy(sugfname, lastslash + 1);
 
2348
                    FREE(anchor_path);
 
2349
                }
 
2350
                FREE(anchor->content_encoding);
 
2351
                if (sugfname && *sugfname)
 
2352
                    HTCheckFnameForCompression(&sugfname, anchor,
 
2353
                                               TRUE);
 
2354
                if (sugfname && *sugfname)
 
2355
                    StrAllocCopy(anchor->SugFname, sugfname);
 
2356
                FREE(sugfname);
 
2357
#ifdef USE_BZLIB
 
2358
                if (bzfp)
 
2359
                    *statusp = HTParseBzFile(format, format_out,
 
2360
                                             anchor,
 
2361
                                             bzfp, sink);
 
2362
#endif
 
2363
#ifdef USE_ZLIB
 
2364
                if (gzfp)
 
2365
                    *statusp = HTParseGzFile(format, format_out,
 
2366
                                             anchor,
 
2367
                                             gzfp, sink);
 
2368
                else if (zzfp)
 
2369
                    *statusp = HTParseZzFile(format, format_out,
 
2370
                                             anchor,
 
2371
                                             zzfp, sink);
 
2372
#endif
 
2373
            }
 
2374
        } else
 
2375
#endif /* USE_ZLIB || USE_BZLIB */
 
2376
        {
 
2377
            *statusp = HTParseFile(format, format_out, anchor, fp, sink);
 
2378
            fclose(fp);
 
2379
        }
 
2380
        return TRUE;
 
2381
    }                           /* If successful open */
 
2382
    return FALSE;
 
2383
}
 
2384
 
2062
2385
/*      Load a document.
2063
2386
 *      ----------------
2064
2387
 *
2082
2405
    HTFormat format;
2083
2406
    char *nodename = NULL;
2084
2407
    char *newname = NULL;       /* Simplified name of file */
2085
 
    HTAtom *encoding;           /* @@ not used yet */
2086
2408
    HTAtom *myEncoding = NULL;  /* enc of this file, may be gzip etc. */
2087
2409
    int status = -1;
2088
 
    char *dot;
2089
2410
 
2090
2411
#ifdef VMS
2091
2412
    struct stat stat_info;
2092
2413
#endif /* VMS */
2093
 
#ifdef USE_ZLIB
2094
 
    gzFile gzfp = 0;
2095
 
#endif /* USE_ZLIB */
2096
 
#ifdef USE_BZLIB
2097
 
    BZFILE *bzfp = 0;
2098
 
#endif /* USE_ZLIB */
2099
 
#if defined(USE_ZLIB) || defined(USE_BZLIB)
2100
 
    CompressFileType internal_decompress = cftNone;
2101
 
    BOOL failed_decompress = NO;
2102
 
#endif
2103
2414
 
2104
2415
    /*
2105
2416
     * Reduce the filename to a basic form (hopefully unique!).
2211
2522
        }
2212
2523
    }
2213
2524
 
2214
 
    /*
2215
 
     * Assume that the file is in Unix-style syntax if it contains a '/' after
2216
 
     * the leading one.  @@
2217
 
     */
2218
 
    {
2219
 
        FILE *fp;
2220
 
        char *vmsname = strchr(filename + 1, '/') ?
2221
 
        HTVMS_name(nodename, filename) : filename + 1;
2222
 
 
2223
 
        fp = fopen(vmsname, "r", "shr=put", "shr=upd");
2224
 
 
2225
 
        /*
2226
 
         * If the file wasn't VMS syntax, then perhaps it is Ultrix.
2227
 
         */
2228
 
        if (!fp) {
2229
 
            char *ultrixname = 0;
2230
 
 
2231
 
            CTRACE((tfp, "HTLoadFile: Can't open as %s\n", vmsname));
2232
 
            HTSprintf0(&ultrixname, "%s::\"%s\"", nodename, filename);
2233
 
            fp = fopen(ultrixname, "r", "shr=put", "shr=upd");
2234
 
            if (!fp) {
2235
 
                CTRACE((tfp, "HTLoadFile: Can't open as %s\n",
2236
 
                        ultrixname));
2237
 
            }
2238
 
            FREE(ultrixname);
2239
 
        }
2240
 
        if (fp) {
2241
 
            char *semicolon = NULL;
2242
 
 
2243
 
            if (HTEditable(vmsname)) {
2244
 
                HTAtom *put = HTAtom_for("PUT");
2245
 
                HTList *methods = HTAnchor_methods(anchor);
2246
 
 
2247
 
                if (HTList_indexOf(methods, put) == (-1)) {
2248
 
                    HTList_addObject(methods, put);
2249
 
                }
2250
 
            }
2251
 
            /*
2252
 
             * Trim vmsname at semicolon if a version number was included, so
2253
 
             * it doesn't interfere with the check for a compressed file.  - FM
2254
 
             */
2255
 
            if ((semicolon = strchr(vmsname, ';')) != NULL)
2256
 
                *semicolon = '\0';
2257
 
            /*
2258
 
             * Fake a Content-Encoding for compressed files.  - FM
2259
 
             */
2260
 
            if (!IsUnityEnc(myEncoding)) {
2261
 
                /*
2262
 
                 * We already know from the call to HTFileFormat above that
2263
 
                 * this is a compressed file, no need to look at the filename
2264
 
                 * again.  - kw
2265
 
                 */
2266
 
#ifdef USE_ZLIB
2267
 
                if (strcmp(format_out->name, "www/download") != 0 &&
2268
 
                    (!strcmp(HTAtom_name(myEncoding), "gzip") ||
2269
 
                     !strcmp(HTAtom_name(myEncoding), "x-gzip"))) {
2270
 
                    fclose(fp);
2271
 
                    if (semicolon != NULL)
2272
 
                        *semicolon = ';';
2273
 
                    gzfp = gzopen(vmsname, BIN_R);
2274
 
 
2275
 
                    CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n",
2276
 
                            vmsname, (void *) gzfp));
2277
 
                    internal_decompress = cftGzip;
2278
 
                } else
2279
 
#endif /* USE_ZLIB */
2280
 
#ifdef USE_BZLIB
2281
 
                    if (strcmp(format_out->name, "www/download") != 0 &&
2282
 
                        (!strcmp(HTAtom_name(myEncoding), "bzip2") ||
2283
 
                         !strcmp(HTAtom_name(myEncoding), "x-bzip2"))) {
2284
 
                    fclose(fp);
2285
 
                    if (semicolon != NULL)
2286
 
                        *semicolon = ';';
2287
 
                    bzfp = BZ2_bzopen(vmsname, BIN_R);
2288
 
 
2289
 
                    CTRACE((tfp, "HTLoadFile: bzopen of `%s' gives %p\n",
2290
 
                            vmsname, (void *) bzfp));
2291
 
                    use_zread = YES;
2292
 
                } else
2293
 
#endif /* USE_BZLIB */
2294
 
                {
2295
 
                    StrAllocCopy(anchor->content_type, format->name);
2296
 
                    StrAllocCopy(anchor->content_encoding, HTAtom_name(myEncoding));
2297
 
                    format = HTAtom_for("www/compressed");
2298
 
                }
2299
 
            } else {
2300
 
                /* FIXME: should we check if suffix is after ']' or ':' ? */
2301
 
                CompressFileType cft = HTCompressFileType(vmsname, "._-", &dot);
2302
 
 
2303
 
                if (cft != cftNone) {
2304
 
                    char *cp = NULL;
2305
 
 
2306
 
                    StrAllocCopy(cp, vmsname);
2307
 
                    cp[dot - vmsname] = '\0';
2308
 
                    format = HTFileFormat(cp, &encoding, NULL);
2309
 
                    FREE(cp);
2310
 
                    format = HTCharsetFormat(format, anchor,
2311
 
                                             UCLYhndl_HTFile_for_unspec);
2312
 
                    StrAllocCopy(anchor->content_type, format->name);
2313
 
                }
2314
 
 
2315
 
                switch (cft) {
2316
 
                case cftCompress:
2317
 
                    StrAllocCopy(anchor->content_encoding, "x-compress");
2318
 
                    format = HTAtom_for("www/compressed");
2319
 
                    break;
2320
 
                case cftGzip:
2321
 
                    StrAllocCopy(anchor->content_encoding, "x-gzip");
2322
 
#ifdef USE_ZLIB
2323
 
                    if (strcmp(format_out->name, "www/download") != 0) {
2324
 
                        fclose(fp);
2325
 
                        if (semicolon != NULL)
2326
 
                            *semicolon = ';';
2327
 
                        gzfp = gzopen(vmsname, BIN_R);
2328
 
 
2329
 
                        CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n",
2330
 
                                vmsname, (void *) gzfp));
2331
 
                        internal_decompress = cftGzip;
2332
 
                    }
2333
 
#else /* USE_ZLIB */
2334
 
                    format = HTAtom_for("www/compressed");
2335
 
#endif /* USE_ZLIB */
2336
 
                    break;
2337
 
                case cftBzip2:
2338
 
                    StrAllocCopy(anchor->content_encoding, "x-bzip2");
2339
 
#ifdef USE_BZLIB
2340
 
                    if (strcmp(format_out->name, "www/download") != 0) {
2341
 
                        fclose(fp);
2342
 
                        if (semicolon != NULL)
2343
 
                            *semicolon = ';';
2344
 
                        bzfp = BZ2_bzopen(vmsname, BIN_R);
2345
 
 
2346
 
                        CTRACE((tfp, "HTLoadFile: bzopen of `%s' gives %p\n",
2347
 
                                vmsname, (void *) bzfp));
2348
 
                        internal_decompress = cfgBzip2;
2349
 
                    }
2350
 
#else /* USE_BZLIB */
2351
 
                    format = HTAtom_for("www/compressed");
2352
 
#endif /* USE_BZLIB */
2353
 
                    break;
2354
 
                case cftNone:
2355
 
                    break;
2356
 
                }
2357
 
            }
2358
 
            if (semicolon != NULL)
2359
 
                *semicolon = ';';
2360
 
            FREE(filename);
2361
 
            FREE(nodename);
2362
 
#if defined(USE_ZLIB) || defined(USE_BZLIB)
2363
 
            if (internal_decompress != cftNone) {
2364
 
                switch (internal_decompress) {
2365
 
#ifdef USE_ZLIB
2366
 
                case cftCompress:
2367
 
                case cftGzip:
2368
 
                    failed_decompress = (gzfp == 0);
2369
 
                    break;
2370
 
#endif
2371
 
#ifdef USE_BZLIB
2372
 
                case cftBzip2:
2373
 
                    failed_decompress = (bzfp == 0);
2374
 
                    break;
2375
 
#endif
2376
 
                default:
2377
 
                    failed_decompress = YES;
2378
 
                    break;
2379
 
                }
2380
 
                if (failed_decompress) {
2381
 
                    status = HTLoadError(NULL,
2382
 
                                         -(HT_ERROR),
2383
 
                                         FAILED_OPEN_COMPRESSED_FILE);
2384
 
                } else {
2385
 
                    char *sugfname = NULL;
2386
 
 
2387
 
                    if (anchor->SugFname) {
2388
 
                        StrAllocCopy(sugfname, anchor->SugFname);
2389
 
                    } else {
2390
 
                        char *anchor_path = HTParse(anchor->address, "",
2391
 
                                                    PARSE_PATH + PARSE_PUNCTUATION);
2392
 
                        char *lastslash;
2393
 
 
2394
 
                        HTUnEscape(anchor_path);
2395
 
                        lastslash = strrchr(anchor_path, '/');
2396
 
                        if (lastslash)
2397
 
                            StrAllocCopy(sugfname, lastslash + 1);
2398
 
                        FREE(anchor_path);
2399
 
                    }
2400
 
                    FREE(anchor->content_encoding);
2401
 
                    if (sugfname && *sugfname)
2402
 
                        HTCheckFnameForCompression(&sugfname, anchor,
2403
 
                                                   TRUE);
2404
 
                    if (sugfname && *sugfname)
2405
 
                        StrAllocCopy(anchor->SugFname, sugfname);
2406
 
                    FREE(sugfname);
2407
 
#ifdef USE_BZLIB
2408
 
                    if (bzfp)
2409
 
                        status = HTParseBzFile(format, format_out,
2410
 
                                               anchor,
2411
 
                                               bzfp, sink);
2412
 
#endif
2413
 
#ifdef USE_ZLIB
2414
 
                    if (gzfp)
2415
 
                        status = HTParseGzFile(format, format_out,
2416
 
                                               anchor,
2417
 
                                               gzfp, sink);
2418
 
#endif
2419
 
                }
2420
 
            } else
2421
 
#endif /* USE_ZLIB || USE_BZLIB */
2422
 
            {
2423
 
                status = HTParseFile(format, format_out, anchor, fp, sink);
2424
 
                fclose(fp);
2425
 
            }
2426
 
            return status;
2427
 
        }                       /* If successful open */
 
2525
    if (decompressAndParse(anchor,
 
2526
                           format_out,
 
2527
                           sink,
 
2528
                           nodename,
 
2529
                           filename,
 
2530
                           myEncoding,
 
2531
                           format,
 
2532
                           &status)) {
 
2533
        FREE(nodename);
2428
2534
        FREE(filename);
 
2535
        return status;
2429
2536
    }
 
2537
    FREE(filename);
2430
2538
 
2431
2539
#else /* not VMS: */
2432
2540
 
2500
2608
                                               0L /* @@@@@@ */ );
2501
2609
 
2502
2610
                    if (value <= 0.0) {
2503
 
                        char *atomname = NULL;
 
2611
                        int rootlen = 0;
 
2612
                        const char *atomname = NULL;
2504
2613
                        CompressFileType cft =
2505
 
                        HTCompressFileType(dirbuf->d_name, ".", &dot);
 
2614
                        HTCompressFileType(dirbuf->d_name, ".", &rootlen);
2506
2615
                        char *cp = NULL;
2507
2616
 
2508
2617
                        enc = NULL;
2509
2618
                        if (cft != cftNone) {
2510
2619
                            StrAllocCopy(cp, dirbuf->d_name);
2511
 
                            cp[dot - dirbuf->d_name] = '\0';
 
2620
                            cp[rootlen] = '\0';
2512
2621
                            format = HTFileFormat(cp, NULL, NULL);
2513
2622
                            FREE(cp);
2514
2623
                            value = HTStackValue(format, format_out,
2520
2629
                            case cftGzip:
2521
2630
                                atomname = "application/x-gzip";
2522
2631
                                break;
 
2632
                            case cftDeflate:
 
2633
                                atomname = "application/x-deflate";
 
2634
                                break;
2523
2635
                            case cftBzip2:
2524
2636
                                atomname = "application/x-bzip2";
2525
2637
                                break;
2658
2770
/* End of directory reading section
2659
2771
*/
2660
2772
#endif /* HAVE_READDIR */
2661
 
        {
2662
 
            int bin = HTCompressFileType(localname, ".", &dot) != cftNone;
2663
 
            FILE *fp = fopen(localname, (bin ? BIN_R : "r"));
2664
 
 
2665
 
            CTRACE((tfp, "HTLoadFile: Opening `%s' gives %p\n",
2666
 
                    localname, (void *) fp));
2667
 
            if (fp) {           /* Good! */
2668
 
                if (HTEditable(localname)) {
2669
 
                    HTAtom *put = HTAtom_for("PUT");
2670
 
                    HTList *methods = HTAnchor_methods(anchor);
2671
 
 
2672
 
                    if (HTList_indexOf(methods, put) == (-1)) {
2673
 
                        HTList_addObject(methods, put);
2674
 
                    }
2675
 
                }
2676
 
                /*
2677
 
                 * Fake a Content-Encoding for compressed files.  - FM
2678
 
                 */
2679
 
                if (!IsUnityEnc(myEncoding)) {
2680
 
                    /*
2681
 
                     * We already know from the call to HTFileFormat above that
2682
 
                     * this is a compressed file, no need to look at the
2683
 
                     * filename again.  - kw
2684
 
                     */
2685
 
#ifdef USE_ZLIB
2686
 
                    if (strcmp(format_out->name, "www/download") != 0 &&
2687
 
                        (!strcmp(HTAtom_name(myEncoding), "gzip") ||
2688
 
                         !strcmp(HTAtom_name(myEncoding), "x-gzip"))) {
2689
 
                        fclose(fp);
2690
 
                        gzfp = gzopen(localname, BIN_R);
2691
 
 
2692
 
                        CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n",
2693
 
                                localname, (void *) gzfp));
2694
 
                        internal_decompress = cftGzip;
2695
 
                    } else
2696
 
#endif /* USE_ZLIB */
2697
 
#ifdef USE_BZLIB
2698
 
                        if (strcmp(format_out->name, "www/download") != 0 &&
2699
 
                            (!strcmp(HTAtom_name(myEncoding), "bzip2") ||
2700
 
                             !strcmp(HTAtom_name(myEncoding), "x-bzip2"))) {
2701
 
                        fclose(fp);
2702
 
                        bzfp = BZ2_bzopen(localname, BIN_R);
2703
 
 
2704
 
                        CTRACE((tfp, "HTLoadFile: bzopen of `%s' gives %p\n",
2705
 
                                localname, (void *) bzfp));
2706
 
                        internal_decompress = cftBzip2;
2707
 
                    } else
2708
 
#endif /* USE_BZLIB */
2709
 
                    {
2710
 
                        StrAllocCopy(anchor->content_type, format->name);
2711
 
                        StrAllocCopy(anchor->content_encoding, HTAtom_name(myEncoding));
2712
 
                        format = HTAtom_for("www/compressed");
2713
 
                    }
2714
 
                } else {
2715
 
                    CompressFileType cft = HTCompressFileType(localname, ".", &dot);
2716
 
 
2717
 
                    if (cft != cftNone) {
2718
 
                        char *cp = NULL;
2719
 
 
2720
 
                        StrAllocCopy(cp, localname);
2721
 
                        cp[dot - localname] = '\0';
2722
 
                        format = HTFileFormat(cp, &encoding, NULL);
2723
 
                        FREE(cp);
2724
 
                        format = HTCharsetFormat(format, anchor,
2725
 
                                                 UCLYhndl_HTFile_for_unspec);
2726
 
                        StrAllocCopy(anchor->content_type, format->name);
2727
 
                    }
2728
 
 
2729
 
                    switch (cft) {
2730
 
                    case cftCompress:
2731
 
                        StrAllocCopy(anchor->content_encoding, "x-compress");
2732
 
                        format = HTAtom_for("www/compressed");
2733
 
                        break;
2734
 
                    case cftGzip:
2735
 
                        StrAllocCopy(anchor->content_encoding, "x-gzip");
2736
 
#ifdef USE_ZLIB
2737
 
                        if (strcmp(format_out->name, "www/download") != 0) {
2738
 
                            fclose(fp);
2739
 
                            gzfp = gzopen(localname, BIN_R);
2740
 
 
2741
 
                            CTRACE((tfp,
2742
 
                                    "HTLoadFile: gzopen of `%s' gives %p\n",
2743
 
                                    localname, (void *) gzfp));
2744
 
                            internal_decompress = cftGzip;
2745
 
                        }
2746
 
#else /* USE_ZLIB */
2747
 
                        format = HTAtom_for("www/compressed");
2748
 
#endif /* USE_ZLIB */
2749
 
                        break;
2750
 
                    case cftBzip2:
2751
 
                        StrAllocCopy(anchor->content_encoding, "x-bzip2");
2752
 
#ifdef USE_BZLIB
2753
 
                        if (strcmp(format_out->name, "www/download") != 0) {
2754
 
                            fclose(fp);
2755
 
                            bzfp = BZ2_bzopen(localname, BIN_R);
2756
 
 
2757
 
                            CTRACE((tfp,
2758
 
                                    "HTLoadFile: bzopen of `%s' gives %p\n",
2759
 
                                    localname, (void *) bzfp));
2760
 
                            internal_decompress = cftBzip2;
2761
 
                        }
2762
 
#else /* USE_BZLIB */
2763
 
                        format = HTAtom_for("www/compressed");
2764
 
#endif /* USE_BZLIB */
2765
 
                        break;
2766
 
                    case cftNone:
2767
 
                        break;
2768
 
                    }
2769
 
                }
2770
 
                FREE(localname);
2771
 
                FREE(nodename);
2772
 
#if defined(USE_ZLIB) || defined(USE_BZLIB)
2773
 
                if (internal_decompress != cftNone) {
2774
 
                    switch (internal_decompress) {
2775
 
#ifdef USE_ZLIB
2776
 
                    case cftGzip:
2777
 
                        failed_decompress = (gzfp == 0);
2778
 
                        break;
2779
 
#endif
2780
 
#ifdef USE_BZLIB
2781
 
                    case cftBzip2:
2782
 
                        failed_decompress = (bzfp == 0);
2783
 
                        break;
2784
 
#endif
2785
 
                    default:
2786
 
                        failed_decompress = YES;
2787
 
                        break;
2788
 
                    }
2789
 
                    if (failed_decompress) {
2790
 
                        status = HTLoadError(NULL,
2791
 
                                             -(HT_ERROR),
2792
 
                                             FAILED_OPEN_COMPRESSED_FILE);
2793
 
                    } else {
2794
 
                        char *sugfname = NULL;
2795
 
 
2796
 
                        if (anchor->SugFname) {
2797
 
                            StrAllocCopy(sugfname, anchor->SugFname);
2798
 
                        } else {
2799
 
                            char *anchor_path = HTParse(anchor->address, "",
2800
 
                                                        PARSE_PATH + PARSE_PUNCTUATION);
2801
 
                            char *lastslash;
2802
 
 
2803
 
                            HTUnEscape(anchor_path);
2804
 
                            lastslash = strrchr(anchor_path, '/');
2805
 
                            if (lastslash)
2806
 
                                StrAllocCopy(sugfname, lastslash + 1);
2807
 
                            FREE(anchor_path);
2808
 
                        }
2809
 
                        FREE(anchor->content_encoding);
2810
 
                        if (sugfname && *sugfname)
2811
 
                            HTCheckFnameForCompression(&sugfname, anchor,
2812
 
                                                       TRUE);
2813
 
                        if (sugfname && *sugfname)
2814
 
                            StrAllocCopy(anchor->SugFname, sugfname);
2815
 
                        FREE(sugfname);
2816
 
#ifdef USE_BZLIB
2817
 
                        if (bzfp)
2818
 
                            status = HTParseBzFile(format, format_out,
2819
 
                                                   anchor,
2820
 
                                                   bzfp, sink);
2821
 
#endif
2822
 
#ifdef USE_ZLIB
2823
 
                        if (gzfp)
2824
 
                            status = HTParseGzFile(format, format_out,
2825
 
                                                   anchor,
2826
 
                                                   gzfp, sink);
2827
 
#endif
2828
 
                    }
2829
 
                } else
2830
 
#endif /* USE_ZLIB */
2831
 
                {
2832
 
                    status = HTParseFile(format, format_out, anchor, fp, sink);
2833
 
                    fclose(fp);
2834
 
                }
2835
 
                return status;
2836
 
            }                   /* If successful open */
 
2773
        if (decompressAndParse(anchor,
 
2774
                               format_out,
 
2775
                               sink,
 
2776
                               nodename,
 
2777
                               localname,
 
2778
                               myEncoding,
 
2779
                               format,
 
2780
                               &status)) {
 
2781
            FREE(nodename);
2837
2782
            FREE(localname);
2838
 
        }                       /* scope of fp */
 
2783
            return status;
 
2784
        }
 
2785
        FREE(localname);
2839
2786
    }                           /* local unix file system */
2840
2787
#endif /* !NO_UNIX_IO */
2841
2788
#endif /* VMS */
2910
2857
 */
2911
2858
void HTInitProgramPaths(void)
2912
2859
{
2913
 
    int code;
 
2860
    ProgramPaths code;
 
2861
    int n;
2914
2862
    const char *path;
2915
2863
    const char *test;
2916
2864
 
2917
 
    for (code = (int) ppUnknown + 1; code < (int) pp_Last; ++code) {
2918
 
        switch (code) {
 
2865
    for (n = (int) ppUnknown + 1; n < (int) pp_Last; ++n) {
 
2866
        switch (code = (ProgramPaths) n) {
2919
2867
#ifdef BZIP2_PATH
2920
2868
        case ppBZIP2:
2921
2869
            path = BZIP2_PATH;
2946
2894
            path = GZIP_PATH;
2947
2895
            break;
2948
2896
#endif
 
2897
#ifdef INFLATE_PATH
 
2898
        case ppINFLATE:
 
2899
            path = INFLATE_PATH;
 
2900
            break;
 
2901
#endif
2949
2902
#ifdef INSTALL_PATH
2950
2903
        case ppINSTALL:
2951
2904
            path = INSTALL_PATH;