1236
*rootlen = (ftype - filename);
1228
1238
CTRACE((tfp, "HTCompressFileType(%s) returns %d:%s\n",
1229
filename, result, *suffix));
1239
filename, (int) result, filename + *rootlen));
1244
* Check if the token from "Content-Encoding" corresponds to a compression
1245
* type. RFC 2068 (and cut/paste into RFC 2616) lists these:
1249
* as well as "identity" (but that does nothing).
1251
CompressFileType HTEncodingToCompressType(const char *coding)
1253
CompressFileType result = cftNone;
1257
} else if (!strcasecomp(coding, "gzip") ||
1258
!strcasecomp(coding, "x-gzip")) {
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")) {
1266
} else if (!strcasecomp(coding, "deflate") ||
1267
!strcasecomp(coding, "x-deflate")) {
1268
result = cftDeflate;
1796
1841
StrAllocCat(tmpfilename, dirbuf->d_name);
1797
1842
data = (DIRED *) malloc(sizeof(DIRED) + strlen(dirbuf->d_name) + 4);
1798
1843
if (data == NULL) {
1844
status = HT_PARTIAL_CONTENT;
1801
1847
LYTrimPathSep(tmpfilename);
1802
if (lstat(tmpfilename, &(data->file_info)) < 0)
1803
data->file_info.st_mode = 0;
1849
actual_info = &(data->file_info);
1851
if (lstat(tmpfilename, actual_info) < 0) {
1852
actual_info->st_mode = 0;
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;
1861
if (stat(tmpfilename, actual_info) < 0)
1862
actual_info->st_mode = 0;
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';
1810
1870
data->sort_tags = 'F';
1811
1871
/* D & F to have first directories, then files */
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);
2123
#define FOPEN_MODE(bin) "r", "shr=put", "shr=upd"
2124
#define DOT_STRING "._-" /* FIXME: should we check if suffix is after ']' or ':' ? */
2126
#define FOPEN_MODE(bin) (bin ? BIN_R : "r")
2127
#define DOT_STRING "."
2130
static int decompressAndParse(HTParentAnchor *anchor,
2131
HTFormat format_out,
2133
char *nodename GCC_UNUSED,
2139
HTAtom *encoding = 0;
2144
#endif /* USE_ZLIB */
2147
#endif /* USE_ZLIB */
2148
#if defined(USE_ZLIB) || defined(USE_BZLIB)
2149
CompressFileType internal_decompress = cftNone;
2150
BOOL failed_decompress = NO;
2153
char *localname = filename;
2159
* Assume that the file is in Unix-style syntax if it contains a '/' after
2160
* the leading one. @@
2162
localname = (strchr(localname + 1, '/')
2163
? HTVMS_name(nodename, localname)
2167
bin = HTCompressFileType(filename, ".", &rootlen) != cftNone;
2168
fp = fopen(localname, FOPEN_MODE(bin));
2172
* If the file wasn't VMS syntax, then perhaps it is Ultrix.
2175
char *ultrixname = 0;
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));
2181
CTRACE((tfp, "HTLoadFile: Can't open as %s\n", ultrixname));
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);
2192
if (HTList_indexOf(methods, put) == (-1)) {
2193
HTList_addObject(methods, put);
2197
* Fake a Content-Encoding for compressed files. - FM
2199
if (!IsUnityEnc(myEncoding)) {
2201
* We already know from the call to HTFileFormat that
2202
* this is a compressed file, no need to look at the filename
2205
CompressFileType method = HTEncodingToCompressType(HTAtom_name(myEncoding));
2207
#define isDOWNLOAD(m) (strcmp(format_out->name, "www/download") && (method == m))
2209
if (isDOWNLOAD(cftGzip)) {
2211
gzfp = gzopen(localname, BIN_R);
2213
CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n",
2215
internal_decompress = cftGzip;
2216
} else if (isDOWNLOAD(cftDeflate)) {
2220
CTRACE((tfp, "HTLoadFile: zzopen of `%s' gives %p\n",
2222
internal_decompress = cftDeflate;
2224
#endif /* USE_ZLIB */
2226
if (isDOWNLOAD(cftBzip2)) {
2228
bzfp = BZ2_bzopen(localname, BIN_R);
2230
CTRACE((tfp, "HTLoadFile: bzopen of `%s' gives %p\n",
2232
internal_decompress = cftBzip2;
2234
#endif /* USE_BZLIB */
2236
StrAllocCopy(anchor->content_type, format->name);
2237
StrAllocCopy(anchor->content_encoding, HTAtom_name(myEncoding));
2238
format = HTAtom_for("www/compressed");
2241
CompressFileType cft = HTCompressFileType(localname, DOT_STRING, &rootlen);
2243
if (cft != cftNone) {
2246
StrAllocCopy(cp, localname);
2248
format = HTFileFormat(cp, &encoding, NULL);
2250
format = HTCharsetFormat(format, anchor,
2251
UCLYhndl_HTFile_for_unspec);
2252
StrAllocCopy(anchor->content_type, format->name);
2257
StrAllocCopy(anchor->content_encoding, "x-compress");
2258
format = HTAtom_for("www/compressed");
2261
StrAllocCopy(anchor->content_encoding, "x-deflate");
2263
if (strcmp(format_out->name, "www/download") != 0) {
2267
CTRACE((tfp, "HTLoadFile: zzopen of `%s' gives %p\n",
2269
internal_decompress = cftDeflate;
2271
#else /* USE_ZLIB */
2272
format = HTAtom_for("www/compressed");
2273
#endif /* USE_ZLIB */
2276
StrAllocCopy(anchor->content_encoding, "x-gzip");
2278
if (strcmp(format_out->name, "www/download") != 0) {
2280
gzfp = gzopen(localname, BIN_R);
2282
CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n",
2284
internal_decompress = cftGzip;
2286
#else /* USE_ZLIB */
2287
format = HTAtom_for("www/compressed");
2288
#endif /* USE_ZLIB */
2291
StrAllocCopy(anchor->content_encoding, "x-bzip2");
2293
if (strcmp(format_out->name, "www/download") != 0) {
2295
bzfp = BZ2_bzopen(localname, BIN_R);
2297
CTRACE((tfp, "HTLoadFile: bzopen of `%s' gives %p\n",
2299
internal_decompress = cftBzip2;
2301
#else /* USE_BZLIB */
2302
format = HTAtom_for("www/compressed");
2303
#endif /* USE_BZLIB */
2309
#if defined(USE_ZLIB) || defined(USE_BZLIB)
2310
if (internal_decompress != cftNone) {
2311
switch (internal_decompress) {
2314
failed_decompress = (zzfp == 0);
2318
failed_decompress = (gzfp == 0);
2323
failed_decompress = (bzfp == 0);
2327
failed_decompress = YES;
2330
if (failed_decompress) {
2331
*statusp = HTLoadError(NULL,
2333
FAILED_OPEN_COMPRESSED_FILE);
2335
char *sugfname = NULL;
2337
if (anchor->SugFname) {
2338
StrAllocCopy(sugfname, anchor->SugFname);
2340
char *anchor_path = HTParse(anchor->address, "",
2341
PARSE_PATH + PARSE_PUNCTUATION);
2344
HTUnEscape(anchor_path);
2345
lastslash = strrchr(anchor_path, '/');
2347
StrAllocCopy(sugfname, lastslash + 1);
2350
FREE(anchor->content_encoding);
2351
if (sugfname && *sugfname)
2352
HTCheckFnameForCompression(&sugfname, anchor,
2354
if (sugfname && *sugfname)
2355
StrAllocCopy(anchor->SugFname, sugfname);
2359
*statusp = HTParseBzFile(format, format_out,
2365
*statusp = HTParseGzFile(format, format_out,
2369
*statusp = HTParseZzFile(format, format_out,
2375
#endif /* USE_ZLIB || USE_BZLIB */
2377
*statusp = HTParseFile(format, format_out, anchor, fp, sink);
2381
} /* If successful open */
2062
2385
/* Load a document.
2063
2386
* ----------------
2215
* Assume that the file is in Unix-style syntax if it contains a '/' after
2216
* the leading one. @@
2220
char *vmsname = strchr(filename + 1, '/') ?
2221
HTVMS_name(nodename, filename) : filename + 1;
2223
fp = fopen(vmsname, "r", "shr=put", "shr=upd");
2226
* If the file wasn't VMS syntax, then perhaps it is Ultrix.
2229
char *ultrixname = 0;
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");
2235
CTRACE((tfp, "HTLoadFile: Can't open as %s\n",
2241
char *semicolon = NULL;
2243
if (HTEditable(vmsname)) {
2244
HTAtom *put = HTAtom_for("PUT");
2245
HTList *methods = HTAnchor_methods(anchor);
2247
if (HTList_indexOf(methods, put) == (-1)) {
2248
HTList_addObject(methods, put);
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
2255
if ((semicolon = strchr(vmsname, ';')) != NULL)
2258
* Fake a Content-Encoding for compressed files. - FM
2260
if (!IsUnityEnc(myEncoding)) {
2262
* We already know from the call to HTFileFormat above that
2263
* this is a compressed file, no need to look at the filename
2267
if (strcmp(format_out->name, "www/download") != 0 &&
2268
(!strcmp(HTAtom_name(myEncoding), "gzip") ||
2269
!strcmp(HTAtom_name(myEncoding), "x-gzip"))) {
2271
if (semicolon != NULL)
2273
gzfp = gzopen(vmsname, BIN_R);
2275
CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n",
2276
vmsname, (void *) gzfp));
2277
internal_decompress = cftGzip;
2279
#endif /* USE_ZLIB */
2281
if (strcmp(format_out->name, "www/download") != 0 &&
2282
(!strcmp(HTAtom_name(myEncoding), "bzip2") ||
2283
!strcmp(HTAtom_name(myEncoding), "x-bzip2"))) {
2285
if (semicolon != NULL)
2287
bzfp = BZ2_bzopen(vmsname, BIN_R);
2289
CTRACE((tfp, "HTLoadFile: bzopen of `%s' gives %p\n",
2290
vmsname, (void *) bzfp));
2293
#endif /* USE_BZLIB */
2295
StrAllocCopy(anchor->content_type, format->name);
2296
StrAllocCopy(anchor->content_encoding, HTAtom_name(myEncoding));
2297
format = HTAtom_for("www/compressed");
2300
/* FIXME: should we check if suffix is after ']' or ':' ? */
2301
CompressFileType cft = HTCompressFileType(vmsname, "._-", &dot);
2303
if (cft != cftNone) {
2306
StrAllocCopy(cp, vmsname);
2307
cp[dot - vmsname] = '\0';
2308
format = HTFileFormat(cp, &encoding, NULL);
2310
format = HTCharsetFormat(format, anchor,
2311
UCLYhndl_HTFile_for_unspec);
2312
StrAllocCopy(anchor->content_type, format->name);
2317
StrAllocCopy(anchor->content_encoding, "x-compress");
2318
format = HTAtom_for("www/compressed");
2321
StrAllocCopy(anchor->content_encoding, "x-gzip");
2323
if (strcmp(format_out->name, "www/download") != 0) {
2325
if (semicolon != NULL)
2327
gzfp = gzopen(vmsname, BIN_R);
2329
CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n",
2330
vmsname, (void *) gzfp));
2331
internal_decompress = cftGzip;
2333
#else /* USE_ZLIB */
2334
format = HTAtom_for("www/compressed");
2335
#endif /* USE_ZLIB */
2338
StrAllocCopy(anchor->content_encoding, "x-bzip2");
2340
if (strcmp(format_out->name, "www/download") != 0) {
2342
if (semicolon != NULL)
2344
bzfp = BZ2_bzopen(vmsname, BIN_R);
2346
CTRACE((tfp, "HTLoadFile: bzopen of `%s' gives %p\n",
2347
vmsname, (void *) bzfp));
2348
internal_decompress = cfgBzip2;
2350
#else /* USE_BZLIB */
2351
format = HTAtom_for("www/compressed");
2352
#endif /* USE_BZLIB */
2358
if (semicolon != NULL)
2362
#if defined(USE_ZLIB) || defined(USE_BZLIB)
2363
if (internal_decompress != cftNone) {
2364
switch (internal_decompress) {
2368
failed_decompress = (gzfp == 0);
2373
failed_decompress = (bzfp == 0);
2377
failed_decompress = YES;
2380
if (failed_decompress) {
2381
status = HTLoadError(NULL,
2383
FAILED_OPEN_COMPRESSED_FILE);
2385
char *sugfname = NULL;
2387
if (anchor->SugFname) {
2388
StrAllocCopy(sugfname, anchor->SugFname);
2390
char *anchor_path = HTParse(anchor->address, "",
2391
PARSE_PATH + PARSE_PUNCTUATION);
2394
HTUnEscape(anchor_path);
2395
lastslash = strrchr(anchor_path, '/');
2397
StrAllocCopy(sugfname, lastslash + 1);
2400
FREE(anchor->content_encoding);
2401
if (sugfname && *sugfname)
2402
HTCheckFnameForCompression(&sugfname, anchor,
2404
if (sugfname && *sugfname)
2405
StrAllocCopy(anchor->SugFname, sugfname);
2409
status = HTParseBzFile(format, format_out,
2415
status = HTParseGzFile(format, format_out,
2421
#endif /* USE_ZLIB || USE_BZLIB */
2423
status = HTParseFile(format, format_out, anchor, fp, sink);
2427
} /* If successful open */
2525
if (decompressAndParse(anchor,
2428
2534
FREE(filename);
2431
2539
#else /* not VMS: */
2658
2770
/* End of directory reading section
2660
2772
#endif /* HAVE_READDIR */
2662
int bin = HTCompressFileType(localname, ".", &dot) != cftNone;
2663
FILE *fp = fopen(localname, (bin ? BIN_R : "r"));
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);
2672
if (HTList_indexOf(methods, put) == (-1)) {
2673
HTList_addObject(methods, put);
2677
* Fake a Content-Encoding for compressed files. - FM
2679
if (!IsUnityEnc(myEncoding)) {
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
2686
if (strcmp(format_out->name, "www/download") != 0 &&
2687
(!strcmp(HTAtom_name(myEncoding), "gzip") ||
2688
!strcmp(HTAtom_name(myEncoding), "x-gzip"))) {
2690
gzfp = gzopen(localname, BIN_R);
2692
CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n",
2693
localname, (void *) gzfp));
2694
internal_decompress = cftGzip;
2696
#endif /* USE_ZLIB */
2698
if (strcmp(format_out->name, "www/download") != 0 &&
2699
(!strcmp(HTAtom_name(myEncoding), "bzip2") ||
2700
!strcmp(HTAtom_name(myEncoding), "x-bzip2"))) {
2702
bzfp = BZ2_bzopen(localname, BIN_R);
2704
CTRACE((tfp, "HTLoadFile: bzopen of `%s' gives %p\n",
2705
localname, (void *) bzfp));
2706
internal_decompress = cftBzip2;
2708
#endif /* USE_BZLIB */
2710
StrAllocCopy(anchor->content_type, format->name);
2711
StrAllocCopy(anchor->content_encoding, HTAtom_name(myEncoding));
2712
format = HTAtom_for("www/compressed");
2715
CompressFileType cft = HTCompressFileType(localname, ".", &dot);
2717
if (cft != cftNone) {
2720
StrAllocCopy(cp, localname);
2721
cp[dot - localname] = '\0';
2722
format = HTFileFormat(cp, &encoding, NULL);
2724
format = HTCharsetFormat(format, anchor,
2725
UCLYhndl_HTFile_for_unspec);
2726
StrAllocCopy(anchor->content_type, format->name);
2731
StrAllocCopy(anchor->content_encoding, "x-compress");
2732
format = HTAtom_for("www/compressed");
2735
StrAllocCopy(anchor->content_encoding, "x-gzip");
2737
if (strcmp(format_out->name, "www/download") != 0) {
2739
gzfp = gzopen(localname, BIN_R);
2742
"HTLoadFile: gzopen of `%s' gives %p\n",
2743
localname, (void *) gzfp));
2744
internal_decompress = cftGzip;
2746
#else /* USE_ZLIB */
2747
format = HTAtom_for("www/compressed");
2748
#endif /* USE_ZLIB */
2751
StrAllocCopy(anchor->content_encoding, "x-bzip2");
2753
if (strcmp(format_out->name, "www/download") != 0) {
2755
bzfp = BZ2_bzopen(localname, BIN_R);
2758
"HTLoadFile: bzopen of `%s' gives %p\n",
2759
localname, (void *) bzfp));
2760
internal_decompress = cftBzip2;
2762
#else /* USE_BZLIB */
2763
format = HTAtom_for("www/compressed");
2764
#endif /* USE_BZLIB */
2772
#if defined(USE_ZLIB) || defined(USE_BZLIB)
2773
if (internal_decompress != cftNone) {
2774
switch (internal_decompress) {
2777
failed_decompress = (gzfp == 0);
2782
failed_decompress = (bzfp == 0);
2786
failed_decompress = YES;
2789
if (failed_decompress) {
2790
status = HTLoadError(NULL,
2792
FAILED_OPEN_COMPRESSED_FILE);
2794
char *sugfname = NULL;
2796
if (anchor->SugFname) {
2797
StrAllocCopy(sugfname, anchor->SugFname);
2799
char *anchor_path = HTParse(anchor->address, "",
2800
PARSE_PATH + PARSE_PUNCTUATION);
2803
HTUnEscape(anchor_path);
2804
lastslash = strrchr(anchor_path, '/');
2806
StrAllocCopy(sugfname, lastslash + 1);
2809
FREE(anchor->content_encoding);
2810
if (sugfname && *sugfname)
2811
HTCheckFnameForCompression(&sugfname, anchor,
2813
if (sugfname && *sugfname)
2814
StrAllocCopy(anchor->SugFname, sugfname);
2818
status = HTParseBzFile(format, format_out,
2824
status = HTParseGzFile(format, format_out,
2830
#endif /* USE_ZLIB */
2832
status = HTParseFile(format, format_out, anchor, fp, sink);
2836
} /* If successful open */
2773
if (decompressAndParse(anchor,
2837
2782
FREE(localname);
2839
2786
} /* local unix file system */
2840
2787
#endif /* !NO_UNIX_IO */
2841
2788
#endif /* VMS */