w3m

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/w3m.git/
Log | Files | Refs | README

commit e5ea85e0157c4c95a3f302b6bc12ebffe9d4c0dc
parent 266def362a8d116a4f69c4efbbef2cfeb1a78d77
Author: ukai <ukai>
Date:   Fri, 30 Nov 2001 09:54:22 +0000

[w3m-dev 02592] Accept: and AcceptEncoding:
From: Fumitoshi UKAI <ukai@debian.or.jp>

Diffstat:
MChangeLog | 42++++++++++++++++++++++++++++++++++++++++++
Mconfigure | 12++++++++++++
Mfile.c | 182++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Mfm.h | 10+---------
Mmailcap.c | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Mproto.h | 5+++--
Mrc.c | 67-------------------------------------------------------------------
Murl.c | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
8 files changed, 324 insertions(+), 163 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,45 @@ +2001-11-30 Fumitoshi UKAI <ukai@debian.or.jp> + + * [w3m-dev 02592] Accept: and AcceptEncoding: + * url.c (otherinfo): use acceptableEncoding() acceptableMimeTypes() + + * file.c: add compression_decoder + * file.c (check_compress): rewrite by using compression_decoder + * file.c (compress_application_type): ditto + * file.c (uncompressed_file_type): ditto + * file.c (check_command): added + * file.c (acceptableEncoding): added + * proto.h (acceptableEncoding): ditto + * file.c (uncompress_stream): renamed from gunzip_stream + * file.c (uncompress_stream): rewrite by using compression_decoder + * configure: add PATH_SEPARATOR + + * mailcap.c (extractMailcapEntry): static + * mailcap.c (loadMailcap): static + * proto.h (loadMailcap): removed + * mailcap.c (acceptableMimeTypes): added + * proto.h (acceptableMimeTypes): added + + * configure: #define USE_PATH_ENVVAR for __EMX__ + * file.c: GUNZIP_*, BUNZIP2_*, INFLATE_* removed here -> config.h + * file.c (gunzip_stream): s/(GUNZIP|BUNZIP2|INFLATE)_CMD/\1_CMDNAME/ + * configure (config.h): GUNZIP_*, BUNZIP2_*, INFLATE_* moved here + * fm.h (DirBufferCommand): use CGI_EXTENSION + * fm.h (mailcap_list): removed from global -> mailcap.c + * fm.h (UserMailcap): removed from global -> mailcap.c + * mailcap.c: static mailcap_list + * mailcap.c: static UserMailcap + * proto.h (initMimeTypes): moved + * proto.h (get_os2_dft): removed + * rc.c (loadMimeTypes): removed here -> url.c + * rc.c (initMimeTypes): removed here -> url.c + * fm.h (mimetypes_list): removed from global -> url.c + * fm.h (UserMimeTypes): removed from global -> url.c + * url.c: static mimetypes_list + * url.c: static UserMimeTypes + * url.c (loadMimeTypes): moved here + * url.c (initMimeTypes): moved here + 2001-11-30 Tsutomu Okada <okada@furuno.co.jp> * [w3m-dev 02590] diff --git a/configure b/configure @@ -2067,12 +2067,19 @@ $def_ipv6_ss_family #endif #if defined(__EMX__) /* use \$extension? */ +#define GUNZIP_CMDNAME "gzip" +#define BUNZIP2_CMDNAME "bzip2" +#define INFLATE_CMDNAME "inflate.exe" #define W3MBOOKMARK_CMDNAME "w3mbookmark.exe" #define W3MHELPERPANEL_CMDNAME "w3mhelperpanel.exe" #define DEV_NULL_PATH "nul" #define DEV_TTY_PATH "con" #define CGI_EXTENSION ".cmd" +#define USE_PATH_ENVVAR #else +#define GUNZIP_CMDNAME "gunzip" +#define BUNZIP2_CMDNAME "bunzip2" +#define INFLATE_CMDNAME "inflate" #define W3MBOOKMARK_CMDNAME "w3mbookmark" #define W3MHELPERPANEL_CMDNAME "w3mhelperpanel" #define DEV_NULL_PATH "/dev/null" @@ -2080,6 +2087,11 @@ $def_ipv6_ss_family #define CGI_EXTENSION ".cgi" #endif +#define PATH_SEPARATOR ':' +#define GUNZIP_NAME "gunzip" +#define BUNZIP2_NAME "bunzip2" +#define INFLATE_NAME "inflate" + #endif /* makefile_parameter */ #endif /* _CONFIGURED_ */ diff --git a/file.c b/file.c @@ -23,7 +23,7 @@ #define min(a,b) ((a) > (b) ? (b) : (a)) #endif /* not min */ -static void gunzip_stream(URLFile *uf); +static void uncompress_stream(URLFile *uf); static FILE *lessopen_stream(char *path); static Buffer *loadcmdout(char *cmd, Buffer *(*loadproc) (URLFile *, Buffer *), @@ -143,6 +143,26 @@ char *violations[COO_EMAX] = { }; #endif +static struct compression_decoder { + int type; + char *ext; + char *mime_type; + int libfile_p; + char *cmd; + char *name; + char *encoding; +} compression_decoders[] = { + {CMP_COMPRESS, ".gz", "application/x-gzip", + 0, GUNZIP_CMDNAME, GUNZIP_NAME, "gzip"}, + {CMP_COMPRESS, ".Z", "application/x-compress", + 0, GUNZIP_CMDNAME, GUNZIP_NAME, "compress"}, + {CMP_BZIP2, ".bz2", "application/x-bzip", + 0, BUNZIP2_CMDNAME, BUNZIP2_NAME, "bzip, bzip2"}, + {CMP_DEFLATE, NULL, "application/x-deflate", + 1, INFLATE_CMDNAME, INFLATE_NAME, "deflate"}, + {CMP_NOCOMPRESS, NULL, NULL, 0, NULL, NULL, NULL}, +}; + #define SAVE_BUF_SIZE 1536 static MySignalHandler @@ -223,41 +243,36 @@ static void check_compression(char *path, URLFile *uf) { int len; + struct compression_decoder *d; if (path == NULL) return; len = strlen(path); uf->compression = CMP_NOCOMPRESS; - if (len > 2 && strcasecmp(&path[len - 2], ".Z") == 0) { - uf->compression = CMP_COMPRESS; - uf->guess_type = "application/x-compress"; - } - else if (len > 3 && strcasecmp(&path[len - 3], ".gz") == 0) { - uf->compression = CMP_GZIP; - uf->guess_type = "application/x-gzip"; - } - else if (len > 4 && strcasecmp(&path[len - 4], ".bz2") == 0) { - uf->compression = CMP_BZIP2; - uf->guess_type = "application/x-bzip"; + for (d = compression_decoders; d->type != CMP_NOCOMPRESS; d++) { + int elen; + if (d->ext == NULL) + continue; + elen = strlen(d->ext); + if (len > elen && strcasecmp(&path[len - elen], d->ext) == 0) { + uf->compression = d->type; + uf->guess_type = d->mime_type; + break; + } } } static char * compress_application_type(int compression) { - switch (compression) { - case CMP_COMPRESS: - return "application/x-compress"; - case CMP_GZIP: - return "application/x-gzip"; - case CMP_BZIP2: - return "application/x-bzip"; - case CMP_DEFLATE: - return "application/x-deflate"; - default: - return NULL; + struct compression_decoder *d; + + for (d = compression_decoders; d->type != CMP_NOCOMPRESS; d++) { + if (d->type == compression) + return d->mime_type; } + return NULL; } static char * @@ -266,21 +281,20 @@ uncompressed_file_type(char *path, char **ext) int len, slen; Str fn; char *t0; + struct compression_decoder *d; if (path == NULL) return NULL; len = strlen(path); - if (len > 2 && strcasecmp(&path[len - 2], ".Z") == 0) { - slen = 2; - } - else if (len > 3 && strcasecmp(&path[len - 3], ".gz") == 0) { - slen = 3; - } - else if (len > 4 && strcasecmp(&path[len - 4], ".bz2") == 0) { - slen = 4; + for (d = compression_decoders; d->type != CMP_NOCOMPRESS; d++) { + if (d->ext == NULL) + continue; + slen = strlen(d->ext); + if (len > slen && strcasecmp(&path[len - slen], d->ext) == 0) + break; } - else + if (d->type == CMP_NOCOMPRESS) return NULL; fn = Strnew_charp(path); @@ -326,12 +340,71 @@ examineFile(char *path, URLFile *uf) char *t0 = uncompressed_file_type(path, &ext); uf->guess_type = t0; uf->ext = ext; - gunzip_stream(uf); + uncompress_stream(uf); return; } } } +#define S_IXANY (S_IXUSR|S_IXGRP|S_IXOTH) + +int +check_command(char *cmd, int libfile_p) +{ + static char *path = NULL; + Str dirs; + char *p, *np; + Str pathname; + struct stat st; + + if (path == NULL) + path = getenv("PATH"); + if (libfile_p) + dirs = Strnew_charp(w3m_lib_dir()); + else + dirs = Strnew_charp(path); + for (p = dirs->ptr; p != NULL; p = np) { + np = strchr(p, PATH_SEPARATOR); + if (np) + *np++ = '\0'; + pathname = Strnew(); + Strcat_charp(pathname, p); + Strcat_char(pathname, '/'); + Strcat_charp(pathname, cmd); + if (stat(pathname->ptr, &st) == 0 + && S_ISREG(st.st_mode) + && (st.st_mode & S_IXANY) != 0) + return 1; + } + return 0; +} + +char * +acceptableEncoding() +{ + static Str encodings = NULL; + struct compression_decoder *d; + TextList *l; + char *p; + + if (encodings != NULL) + return encodings->ptr; + l = newTextList(); + for (d = compression_decoders; d->type != CMP_NOCOMPRESS; d++) { + if (check_command(d->cmd, d->libfile_p)) { + pushText(l, d->encoding); + } + } + while ((p = popText(l)) != NULL) { + if (encodings == NULL) + encodings = Strnew(); + else + Strcat_charp(encodings, ", "); + Strcat_charp(encodings, p); + } + return encodings->ptr; +} + /* * convert line */ @@ -1263,7 +1336,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, if (!(w3m_dump & DUMP_SOURCE) && (w3m_dump & ~DUMP_FRAME || is_text_type(t) || searchExtViewer(t))) { - gunzip_stream(&f); + uncompress_stream(&f); uncompressed_file_type(pu.file, &f.ext); } else { @@ -5961,46 +6034,29 @@ checkOverWrite(char *path) return -1; } -#ifdef __EMX__ -#define GUNZIP_CMD "gzip" -#define BUNZIP2_CMD "bzip2" -#define INFLATE_CMD libFile("inflate.exe") -#else /* not __EMX__ */ -#define GUNZIP_CMD "gunzip" -#define BUNZIP2_CMD "bunzip2" -#define INFLATE_CMD libFile("inflate") -#endif /* not __EMX__ */ -#define GUNZIP_NAME "gunzip" -#define BUNZIP2_NAME "bunzip2" -#define INFLATE_NAME "inflate" - static void -gunzip_stream(URLFile *uf) +uncompress_stream(URLFile *uf) { int pid1; int fd1[2]; - char *expand_cmd = GUNZIP_CMD; + char *expand_cmd = GUNZIP_CMDNAME; char *expand_name = GUNZIP_NAME; char *tmpf = NULL; + struct compression_decoder *d; if (IStype(uf->stream) != IST_ENCODED) { uf->stream = newEncodedStream(uf->stream, uf->encoding); uf->encoding = ENC_7BIT; } - switch (uf->compression) { - case CMP_COMPRESS: - case CMP_GZIP: - expand_cmd = GUNZIP_CMD; - expand_name = GUNZIP_NAME; - break; - case CMP_BZIP2: - expand_cmd = BUNZIP2_CMD; - expand_name = BUNZIP2_NAME; - break; - case CMP_DEFLATE: - expand_cmd = INFLATE_CMD; - expand_name = INFLATE_NAME; - break; + for (d = compression_decoders; d->type != CMP_NOCOMPRESS; d++) { + if (uf->compression == d->type) { + if (d->libfile_p) + expand_cmd = libFile(d->cmd); + else + expand_cmd = d->cmd; + expand_name = d->name; + break; + } } uf->compression = CMP_NOCOMPRESS; diff --git a/fm.h b/fm.h @@ -744,11 +744,7 @@ global char *BookmarkFile init(NULL); global char *pauth init(NULL); global Str proxy_auth_cookie init(NULL); global int UseExternalDirBuffer init(TRUE); -#ifdef __EMX__ -global char *DirBufferCommand init("file:///$LIB/dirlist.cmd"); -#else -global char *DirBufferCommand init("file:///$LIB/dirlist.cgi"); -#endif /* __EMX__ */ +global char *DirBufferCommand init("file:///$LIB/dirlist" CGI_EXTENSION); global int ignore_null_img_alt init(TRUE); global struct auth_cookie *Auth_cookie init(NULL); @@ -757,10 +753,6 @@ global char *Local_cookie init(NULL); global struct cookie *First_cookie init(NULL); #endif /* USE_COOKIE */ -global struct mailcap **UserMailcap; -global struct table2 **UserMimeTypes; -global TextList *mailcap_list; -global TextList *mimetypes_list; global char *mailcap_files init(USER_MAILCAP ", " SYS_MAILCAP); global char *mimetypes_files init(USER_MIMETYPES ", " SYS_MIMETYPES); diff --git a/mailcap.c b/mailcap.c @@ -12,22 +12,8 @@ static struct mailcap DefaultMailcap[] = { {NULL, NULL, 0, NULL, NULL, NULL} }; -void -initMailcap() -{ - int i; - TextListItem *tl; - - if (non_null(mailcap_files)) - mailcap_list = make_domain_list(mailcap_files); - else - mailcap_list = NULL; - if (mailcap_list == NULL) - return; - UserMailcap = New_N(struct mailcap *, mailcap_list->nitem); - for (i = 0, tl = mailcap_list->first; tl; i++, tl = tl->next) - UserMailcap[i] = loadMailcap(tl->ptr); -} +static TextList *mailcap_list; +static struct mailcap **UserMailcap; int mailcapMatch(struct mailcap *mcap, char *type) @@ -124,7 +110,7 @@ matchMailcapAttr(char *p, char *attr, int len, Str *value) return 0; } -int +static int extractMailcapEntry(char *mcap_entry, struct mailcap *mcap) { int j, k; @@ -193,7 +179,7 @@ extractMailcapEntry(char *mcap_entry, struct mailcap *mcap) return 1; } -struct mailcap * +static struct mailcap * loadMailcap(char *filename) { FILE *f; @@ -233,6 +219,70 @@ loadMailcap(char *filename) return mcap; } +void +initMailcap() +{ + TextListItem *tl; + int i; + + if (non_null(mailcap_files)) + mailcap_list = make_domain_list(mailcap_files); + else + mailcap_list = NULL; + if (mailcap_list == NULL) + return; + UserMailcap = New_N(struct mailcap *, mailcap_list->nitem); + for (i = 0, tl = mailcap_list->first; tl; i++, tl = tl->next) + UserMailcap[i] = loadMailcap(tl->ptr); + +} + +char * +acceptableMimeTypes() +{ + static Str types = NULL; + TextList *l; + Hash_si *mhash; + char *p; + int i; + + if (types != NULL) + return types->ptr; + + /* generate acceptable media types */ + l = newTextList(); + mhash = newHash_si(16); /* XXX */ + pushText(l, "text"); + putHash_si(mhash, "text", 1); + pushText(l, "image"); + putHash_si(mhash, "image", 1); + for (i = 0; i < mailcap_list->nitem; i++) { + struct mailcap *mp = UserMailcap[i]; + char *mt; + if (mp == NULL) + continue; + for (; mp->type; mp++) { + p = strchr(mp->type, '/'); + if (p == NULL) + continue; + mt = allocStr(mp->type, p - mp->type); + if (getHash_si(mhash, mt, 0) == 0) { + pushText(l, mt); + putHash_si(mhash, mt, 1); + } + } + } + while ((p = popText(l)) != NULL) { + if (types == NULL) + types = Strnew(); + else + Strcat_charp(types, ", "); + Strcat_charp(types, p); + Strcat_charp(types, "/*"); + } + return types->ptr; +} + struct mailcap * searchExtViewer(char *type) { diff --git a/proto.h b/proto.h @@ -108,6 +108,7 @@ extern int currentLn(Buffer *buf); extern void tmpClearBuffer(Buffer *buf); extern char *filename_extension(char *patch, int is_url); extern void examineFile(char *path, URLFile *uf); +extern char *acceptableEncoding(); extern int dir_exist(char *path); extern Str convertLine(URLFile *uf, Str line, char *code, int mode); extern Buffer *loadFile(char *path); @@ -391,6 +392,7 @@ extern char str_to_code(char *str); extern char *code_to_str(char code); extern void put_sjis(Str os, unsigned char ub, unsigned char lb); #endif /* JP_CHARSET */ +extern void initMimeTypes(); extern void free_ssl_ctx(); extern ParsedURL *baseURL(Buffer *buf); extern int openSocket(char *hostname, char *remoteport_name, @@ -410,9 +412,9 @@ extern TextList *make_domain_list(char *domain_list); extern int check_no_proxy(char *domain); extern char *filename_extension(char *path, int is_url); extern int mailcapMatch(struct mailcap *mcap, char *type); -extern struct mailcap *loadMailcap(char *filename); extern struct mailcap *searchMailcap(struct mailcap *table, char *type); extern void initMailcap(); +extern char *acceptableMimeTypes(); extern struct mailcap *searchExtViewer(char *type); extern Str unquote_mailcap(char *qstr, char *type, char *name, char *attr, int *mc_stat); @@ -577,7 +579,6 @@ extern char *guess_save_name(Buffer *buf, char *file); extern void wrapToggle(void); extern void saveBufferInfo(void); -extern char *get_os2_dft(const char *, char *); extern void dispVer(void); diff --git a/rc.c b/rc.c @@ -1072,73 +1072,6 @@ do_mkdir(const char *dir, long mode) #define do_mkdir(dir,mode) mkdir(dir,mode) #endif /* not __EMX__ */ -struct table2 * -loadMimeTypes(char *filename) -{ - FILE *f; - char *d, *type; - int i, n; - Str tmp; - struct table2 *mtypes; - - f = fopen(expandName(filename), "r"); - if (f == NULL) - return NULL; - n = 0; - while (tmp = Strfgets(f), tmp->length > 0) { - d = tmp->ptr; - if (d[0] != '#') { - d = strtok(d, " \t\n\r"); - if (d != NULL) { - d = strtok(NULL, " \t\n\r"); - for (i = 0; d != NULL; i++) - d = strtok(NULL, " \t\n\r"); - n += i; - } - } - } - fseek(f, 0, 0); - mtypes = New_N(struct table2, n + 1); - i = 0; - while (tmp = Strfgets(f), tmp->length > 0) { - d = tmp->ptr; - if (d[0] == '#') - continue; - type = strtok(d, " \t\n\r"); - if (type == NULL) - continue; - while (1) { - d = strtok(NULL, " \t\n\r"); - if (d == NULL) - break; - mtypes[i].item1 = Strnew_charp(d)->ptr; - mtypes[i].item2 = Strnew_charp(type)->ptr; - i++; - } - } - mtypes[i].item1 = NULL; - mtypes[i].item2 = NULL; - fclose(f); - return mtypes; -} - -void -initMimeTypes() -{ - int i; - TextListItem *tl; - - if (non_null(mimetypes_files)) - mimetypes_list = make_domain_list(mimetypes_files); - else - mimetypes_list = NULL; - if (mimetypes_list == NULL) - return; - UserMimeTypes = New_N(struct table2 *, mimetypes_list->nitem); - for (i = 0, tl = mimetypes_list->first; tl; i++, tl = tl->next) - UserMimeTypes[i] = loadMimeTypes(tl->ptr); -} - void sync_with_option(void) { diff --git a/url.c b/url.c @@ -134,6 +134,76 @@ sock_log(char *message, ...) #endif +static TextList *mimetypes_list; +static struct table2 **UserMimeTypes; + +static struct table2 * +loadMimeTypes(char *filename) +{ + FILE *f; + char *d, *type; + int i, n; + Str tmp; + struct table2 *mtypes; + + f = fopen(expandName(filename), "r"); + if (f == NULL) + return NULL; + n = 0; + while (tmp = Strfgets(f), tmp->length > 0) { + d = tmp->ptr; + if (d[0] != '#') { + d = strtok(d, " \t\n\r"); + if (d != NULL) { + d = strtok(NULL, " \t\n\r"); + for (i = 0; d != NULL; i++) + d = strtok(NULL, " \t\n\r"); + n += i; + } + } + } + fseek(f, 0, 0); + mtypes = New_N(struct table2, n + 1); + i = 0; + while (tmp = Strfgets(f), tmp->length > 0) { + d = tmp->ptr; + if (d[0] == '#') + continue; + type = strtok(d, " \t\n\r"); + if (type == NULL) + continue; + while (1) { + d = strtok(NULL, " \t\n\r"); + if (d == NULL) + break; + mtypes[i].item1 = Strnew_charp(d)->ptr; + mtypes[i].item2 = Strnew_charp(type)->ptr; + i++; + } + } + mtypes[i].item1 = NULL; + mtypes[i].item2 = NULL; + fclose(f); + return mtypes; +} + +void +initMimeTypes() +{ + int i; + TextListItem *tl; + + if (non_null(mimetypes_files)) + mimetypes_list = make_domain_list(mimetypes_files); + else + mimetypes_list = NULL; + if (mimetypes_list == NULL) + return; + UserMimeTypes = New_N(struct table2 *, mimetypes_list->nitem); + for (i = 0, tl = mimetypes_list->first; tl; i++, tl = tl->next) + UserMimeTypes[i] = loadMimeTypes(tl->ptr); +} + static char * DefaultFile(int scheme) { @@ -1127,10 +1197,15 @@ otherinfo(ParsedURL *target, ParsedURL *current, char *referer) else Strcat_charp(s, UserAgent); Strcat_charp(s, "\r\n"); - Strcat_charp(s, - "Accept: text/*, image/*, audio/*, video/*, application/*\r\n"); - Strcat_charp(s, - "Accept-Encoding: gzip, compress, bzip, bzip2, deflate\r\n"); + + Strcat_charp(s, "Accept: "); + Strcat_charp(s, acceptableMimeTypes()); + Strcat_charp(s, "\r\n"); + + Strcat_charp(s, "Accept-Encoding: "); + Strcat_charp(s, acceptableEncoding()); + Strcat_charp(s, "\r\n"); + Strcat_charp(s, "Accept-Language: "); if (AcceptLang != NULL && *AcceptLang != '\0') { Strcat_charp(s, AcceptLang);