diff options
Diffstat (limited to '')
-rw-r--r-- | .#file.c.1.243 | 8188 |
1 files changed, 0 insertions, 8188 deletions
diff --git a/.#file.c.1.243 b/.#file.c.1.243 deleted file mode 100644 index 411aa7a..0000000 --- a/.#file.c.1.243 +++ /dev/null @@ -1,8188 +0,0 @@ -/* $Id: file.c,v 1.243 2006/05/29 12:54:26 inu Exp $ */ -#include "fm.h" -#include <sys/types.h> -#include "myctype.h" -#include <signal.h> -#include <setjmp.h> -#if defined(HAVE_WAITPID) || defined(HAVE_WAIT3) -#include <sys/wait.h> -#endif -#include <stdio.h> -#include <time.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <utime.h> -/* foo */ - -#include "html.h" -#include "parsetagx.h" -#include "local.h" -#include "regex.h" - -#ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) -#endif /* not max */ -#ifndef min -#define min(a,b) ((a) > (b) ? (b) : (a)) -#endif /* not min */ - -static int frame_source = 0; - -static char *guess_filename(char *file); -static int _MoveFile(char *path1, char *path2); -static void uncompress_stream(URLFile *uf, char **src); -static FILE *lessopen_stream(char *path); -static Buffer *loadcmdout(char *cmd, - Buffer *(*loadproc) (URLFile *, Buffer *), - Buffer *defaultbuf); -#ifndef USE_ANSI_COLOR -#define addnewline(a,b,c,d,e,f,g) _addnewline(a,b,c,e,f,g) -#endif -static void addnewline(Buffer *buf, char *line, Lineprop *prop, - Linecolor *color, int pos, int width, int nlines); -static void addLink(Buffer *buf, struct parsed_tag *tag); - -static JMP_BUF AbortLoading; - -static struct table *tables[MAX_TABLE]; -static struct table_mode table_mode[MAX_TABLE]; - -#ifdef USE_IMAGE -static ParsedURL *cur_baseURL = NULL; -#ifdef USE_M17N -static char cur_document_charset; -#endif -#endif - -static Str cur_title; -static Str cur_select; -static Str select_str; -static int select_is_multiple; -static int n_selectitem; -static Str cur_option; -static Str cur_option_value; -static Str cur_option_label; -static int cur_option_selected; -static int cur_status; -#ifdef MENU_SELECT -/* menu based <select> */ -FormSelectOption *select_option; -static int max_select = MAX_SELECT; -static int n_select; -static int cur_option_maxwidth; -#endif /* MENU_SELECT */ - -static Str cur_textarea; -Str *textarea_str; -static int cur_textarea_size; -static int cur_textarea_rows; -static int cur_textarea_readonly; -static int n_textarea; -static int ignore_nl_textarea; -static int max_textarea = MAX_TEXTAREA; - -static int http_response_code; - -#ifdef USE_M17N -static wc_ces content_charset = 0; -static wc_ces meta_charset = 0; -static char *check_charset(char *p); -static char *check_accept_charset(char *p); -#endif - -#define set_prevchar(x,y,n) Strcopy_charp_n((x),(y),(n)) -#define set_space_to_prevchar(x) Strcopy_charp_n((x)," ",1) - -struct link_stack { - int cmd; - short offset; - short pos; - struct link_stack *next; -}; - -static struct link_stack *link_stack = NULL; - -#define FORMSTACK_SIZE 10 -#define FRAMESTACK_SIZE 10 - -#ifdef USE_NNTP -#define Str_news_endline(s) ((s)->ptr[0]=='.'&&((s)->ptr[1]=='\n'||(s)->ptr[1]=='\r'||(s)->ptr[1]=='\0')) -#endif /* USE_NNTP */ - -#define INITIAL_FORM_SIZE 10 -static FormList **forms; -static int *form_stack; -static int form_max = -1; -static int forms_size = 0; -#define cur_form_id ((form_sp >= 0)? form_stack[form_sp] : -1) -static int form_sp = 0; - -static clen_t current_content_length; - -static int cur_hseq; -#ifdef USE_IMAGE -static int cur_iseq; -#endif - -#define MAX_UL_LEVEL 9 -#define UL_SYMBOL(x) (N_GRAPH_SYMBOL + (x)) -#define UL_SYMBOL_DISC UL_SYMBOL(9) -#define UL_SYMBOL_CIRCLE UL_SYMBOL(10) -#define UL_SYMBOL_SQUARE UL_SYMBOL(11) -#define IMG_SYMBOL UL_SYMBOL(12) -#define HR_SYMBOL 26 - -#ifdef USE_COOKIE -/* This array should be somewhere else */ -/* FIXME: gettextize? */ -char *violations[COO_EMAX] = { - "internal error", - "tail match failed", - "wrong number of dots", - "RFC 2109 4.3.2 rule 1", - "RFC 2109 4.3.2 rule 2.1", - "RFC 2109 4.3.2 rule 2.2", - "RFC 2109 4.3.2 rule 3", - "RFC 2109 4.3.2 rule 4", - "RFC XXXX 4.3.2 rule 5" -}; -#endif - -/* *INDENT-OFF* */ -static struct compression_decoder { - int type; - char *ext; - char *mime_type; - int auxbin_p; - char *cmd; - char *name; - char *encoding; - char *encodings[4]; -} compression_decoders[] = { - { CMP_COMPRESS, ".gz", "application/x-gzip", - 0, GUNZIP_CMDNAME, GUNZIP_NAME, "gzip", - {"gzip", "x-gzip", NULL} }, - { CMP_COMPRESS, ".Z", "application/x-compress", - 0, GUNZIP_CMDNAME, GUNZIP_NAME, "compress", - {"compress", "x-compress", NULL} }, - { CMP_BZIP2, ".bz2", "application/x-bzip", - 0, BUNZIP2_CMDNAME, BUNZIP2_NAME, "bzip, bzip2", - {"x-bzip", "bzip", "bzip2", NULL} }, - { CMP_DEFLATE, ".deflate", "application/x-deflate", - 1, INFLATE_CMDNAME, INFLATE_NAME, "deflate", - {"deflate", "x-deflate", NULL} }, - { CMP_NOCOMPRESS, NULL, NULL, 0, NULL, NULL, NULL, {NULL}}, -}; -/* *INDENT-ON* */ - -#define SAVE_BUF_SIZE 1536 - -static MySignalHandler -KeyAbort(SIGNAL_ARG) -{ - LONGJMP(AbortLoading, 1); - SIGNAL_RETURN; -} - -static void -UFhalfclose(URLFile *f) -{ - switch (f->scheme) { - case SCM_FTP: - closeFTP(); - break; -#ifdef USE_NNTP - case SCM_NEWS: - case SCM_NNTP: - closeNews(); - break; -#endif - default: - UFclose(f); - break; - } -} - -int -currentLn(Buffer *buf) -{ - if (buf->currentLine) - /* return buf->currentLine->real_linenumber + 1; */ - return buf->currentLine->linenumber + 1; - else - return 1; -} - -static Buffer * -loadSomething(URLFile *f, - char *path, - Buffer *(*loadproc) (URLFile *, Buffer *), Buffer *defaultbuf) -{ - Buffer *buf; - - if ((buf = loadproc(f, defaultbuf)) == NULL) - return NULL; - - buf->filename = path; - if (buf->buffername == NULL || buf->buffername[0] == '\0') { - buf->buffername = checkHeader(buf, "Subject:"); - if (buf->buffername == NULL) - buf->buffername = conv_from_system(lastFileName(path)); - } - if (buf->currentURL.scheme == SCM_UNKNOWN) - buf->currentURL.scheme = f->scheme; - buf->real_scheme = f->scheme; - if (f->scheme == SCM_LOCAL && buf->sourcefile == NULL) - buf->sourcefile = path; - return buf; -} - -int -dir_exist(char *path) -{ - struct stat stbuf; - - if (path == NULL || *path == '\0') - return 0; - if (stat(path, &stbuf) == -1) - return 0; - return IS_DIRECTORY(stbuf.st_mode); -} - -static int -is_dump_text_type(char *type) -{ - struct mailcap *mcap; - return (type && (mcap = searchExtViewer(type)) && - (mcap->flags & (MAILCAP_HTMLOUTPUT | MAILCAP_COPIOUSOUTPUT))); -} - -static int -is_text_type(char *type) -{ - return (type == NULL || type[0] == '\0' || - strncasecmp(type, "text/", 5) == 0 || - strncasecmp(type, "message/", sizeof("message/") - 1) == 0); -} - -static int -is_plain_text_type(char *type) -{ - return ((type && strcasecmp(type, "text/plain") == 0) || - (is_text_type(type) && !is_dump_text_type(type))); -} - -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; - 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) -{ - 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 * -uncompressed_file_type(char *path, char **ext) -{ - int len, slen; - Str fn; - char *t0; - struct compression_decoder *d; - - if (path == NULL) - return NULL; - - slen = 0; - len = strlen(path); - 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; - } - if (d->type == CMP_NOCOMPRESS) - return NULL; - - fn = Strnew_charp(path); - Strshrink(fn, slen); - if (ext) - *ext = filename_extension(fn->ptr, 0); - t0 = guessContentType(fn->ptr); - if (t0 == NULL) - t0 = "text/plain"; - return t0; -} - -static int -setModtime(char *path, time_t modtime) -{ - struct utimbuf t; - struct stat st; - - if (stat(path, &st) == 0) - t.actime = st.st_atime; - else - t.actime = time(NULL); - t.modtime = modtime; - return utime(path, &t); -} - -void -examineFile(char *path, URLFile *uf) -{ - struct stat stbuf; - - uf->guess_type = NULL; - if (path == NULL || *path == '\0' || - stat(path, &stbuf) == -1 || NOT_REGULAR(stbuf.st_mode)) { - uf->stream = NULL; - return; - } - uf->stream = openIS(path); - if (!do_download) { - if (use_lessopen && getenv("LESSOPEN") != NULL) { - FILE *fp; - uf->guess_type = guessContentType(path); - if (uf->guess_type == NULL) - uf->guess_type = "text/plain"; - if (strcasecmp(uf->guess_type, "text/html") == 0) - return; - if ((fp = lessopen_stream(path))) { - UFclose(uf); - uf->stream = newFileStream(fp, (void (*)())pclose); - uf->guess_type = "text/plain"; - return; - } - } - check_compression(path, uf); - if (uf->compression != CMP_NOCOMPRESS) { - char *ext = uf->ext; - char *t0 = uncompressed_file_type(path, &ext); - uf->guess_type = t0; - uf->ext = ext; - uncompress_stream(uf, NULL); - return; - } - } -} - -#define S_IXANY (S_IXUSR|S_IXGRP|S_IXOTH) - -int -check_command(char *cmd, int auxbin_p) -{ - static char *path = NULL; - Str dirs; - char *p, *np; - Str pathname; - struct stat st; - - if (path == NULL) - path = getenv("PATH"); - if (auxbin_p) - dirs = Strnew_charp(w3m_auxbin_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->auxbin_p)) { - pushText(l, d->encoding); - } - } - encodings = Strnew(); - while ((p = popText(l)) != NULL) { - if (encodings->length) - Strcat_charp(encodings, ", "); - Strcat_charp(encodings, p); - } - return encodings->ptr; -} - -/* - * convert line - */ -#ifdef USE_M17N -Str -convertLine(URLFile *uf, Str line, int mode, wc_ces * charset, - wc_ces doc_charset) -#else -Str -convertLine0(URLFile *uf, Str line, int mode) -#endif -{ -#ifdef USE_M17N - line = wc_Str_conv_with_detect(line, charset, doc_charset, InnerCharset); -#endif - if (mode != RAW_MODE) - cleanup_line(line, mode); -#ifdef USE_NNTP - if (uf && uf->scheme == SCM_NEWS) - Strchop(line); -#endif /* USE_NNTP */ - return line; -} - -/* - * loadFile: load file to buffer - */ -Buffer * -loadFile(char *path) -{ - Buffer *buf; - URLFile uf; - init_stream(&uf, SCM_LOCAL, NULL); - examineFile(path, &uf); - if (uf.stream == NULL) - return NULL; - buf = newBuffer(INIT_BUFFER_WIDTH); - current_content_length = 0; -#ifdef USE_M17N - content_charset = 0; -#endif - buf = loadSomething(&uf, path, loadBuffer, buf); - UFclose(&uf); - return buf; -} - -int -matchattr(char *p, char *attr, int len, Str *value) -{ - int quoted; - char *q = NULL; - - if (strncasecmp(p, attr, len) == 0) { - p += len; - SKIP_BLANKS(p); - if (value) { - *value = Strnew(); - if (*p == '=') { - p++; - SKIP_BLANKS(p); - quoted = 0; - while (!IS_ENDL(*p) && (quoted || *p != ';')) { - if (!IS_SPACE(*p)) - q = p; - if (*p == '"') - quoted = (quoted) ? 0 : 1; - else - Strcat_char(*value, *p); - p++; - } - if (q) - Strshrink(*value, p - q - 1); - } - return 1; - } - else { - if (IS_ENDT(*p)) { - return 1; - } - } - } - return 0; -} - -#ifdef USE_IMAGE -#ifdef USE_XFACE -static char * -xface2xpm(char *xface) -{ - Image image; - ImageCache *cache; - FILE *f; - struct stat st; - - SKIP_BLANKS(xface); - image.url = xface; - image.ext = ".xpm"; - image.width = 48; - image.height = 48; - image.cache = NULL; - cache = getImage(&image, NULL, IMG_FLAG_AUTO); - if (cache->loaded & IMG_FLAG_LOADED && !stat(cache->file, &st)) - return cache->file; - cache->loaded = IMG_FLAG_ERROR; - - f = popen(Sprintf("%s > %s", shell_quote(auxbinFile(XFACE2XPM)), - shell_quote(cache->file))->ptr, "w"); - if (!f) - return NULL; - fputs(xface, f); - pclose(f); - if (stat(cache->file, &st) || !st.st_size) - return NULL; - cache->loaded = IMG_FLAG_LOADED | IMG_FLAG_DONT_REMOVE; - cache->index = 0; - return cache->file; -} -#endif -#endif - -void -readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu) -{ - char *p, *q; -#ifdef USE_COOKIE - char *emsg; -#endif - char c; - Str lineBuf2 = NULL; - Str tmp; - TextList *headerlist; -#ifdef USE_M17N - wc_ces charset = WC_CES_US_ASCII, mime_charset; -#endif - char *tmpf; - FILE *src = NULL; - Lineprop *propBuffer; - - headerlist = newBuf->document_header = newTextList(); - if (uf->scheme == SCM_HTTP -#ifdef USE_SSL - || uf->scheme == SCM_HTTPS -#endif /* USE_SSL */ - ) - http_response_code = -1; - else - http_response_code = 0; - - if (thru && !newBuf->header_source -#ifdef USE_IMAGE - && !image_source -#endif - ) { - tmpf = tmpfname(TMPF_DFL, NULL)->ptr; - src = fopen(tmpf, "w"); - if (src) - newBuf->header_source = tmpf; - } - while ((tmp = StrmyUFgets(uf))->length) { -#ifdef USE_NNTP - if (uf->scheme == SCM_NEWS && tmp->ptr[0] == '.') - Strshrinkfirst(tmp, 1); -#endif -#ifdef HTTP_DEBUG - { - FILE *ff; - ff = fopen("zzrequest", "a"); - Strfputs(tmp, ff); - fclose(ff); - } -#endif /* HTTP_DEBUG */ - if (src) - Strfputs(tmp, src); - cleanup_line(tmp, HEADER_MODE); - if (tmp->ptr[0] == '\n' || tmp->ptr[0] == '\r' || tmp->ptr[0] == '\0') { - if (!lineBuf2) - /* there is no header */ - break; - /* last header */ - } - else if (!(w3m_dump & DUMP_HEAD)) { - if (lineBuf2) { - Strcat(lineBuf2, tmp); - } - else { - lineBuf2 = tmp; - } - c = UFgetc(uf); - UFundogetc(uf); - if (c == ' ' || c == '\t') - /* header line is continued */ - continue; - lineBuf2 = decodeMIME(lineBuf2, &mime_charset); - lineBuf2 = convertLine(NULL, lineBuf2, RAW_MODE, - mime_charset ? &mime_charset : &charset, - mime_charset ? mime_charset - : DocumentCharset); - /* separated with line and stored */ - tmp = Strnew_size(lineBuf2->length); - for (p = lineBuf2->ptr; *p; p = q) { - for (q = p; *q && *q != '\r' && *q != '\n'; q++) ; - lineBuf2 = checkType(Strnew_charp_n(p, q - p), &propBuffer, - NULL); - Strcat(tmp, lineBuf2); - if (thru) - addnewline(newBuf, lineBuf2->ptr, propBuffer, NULL, - lineBuf2->length, FOLD_BUFFER_WIDTH, -1); - for (; *q && (*q == '\r' || *q == '\n'); q++) ; - } -#ifdef USE_IMAGE - if (thru && activeImage && displayImage) { - Str src = NULL; - if (!strncasecmp(tmp->ptr, "X-Image-URL:", 12)) { - tmpf = &tmp->ptr[12]; - SKIP_BLANKS(tmpf); - src = Strnew_m_charp("<img src=\"", html_quote(tmpf), - "\" alt=\"X-Image-URL\">", NULL); - } -#ifdef USE_XFACE - else if (!strncasecmp(tmp->ptr, "X-Face:", 7)) { - tmpf = xface2xpm(&tmp->ptr[7]); - if (tmpf) - src = Strnew_m_charp("<img src=\"file:", - html_quote(tmpf), - "\" alt=\"X-Face\"", - " width=48 height=48>", NULL); - } -#endif - if (src) { - URLFile f; - Line *l; -#ifdef USE_M17N - wc_ces old_charset = newBuf->document_charset; -#endif - init_stream(&f, SCM_LOCAL, newStrStream(src)); - loadHTMLstream(&f, newBuf, NULL, TRUE); - for (l = newBuf->lastLine; l && l->real_linenumber; - l = l->prev) - l->real_linenumber = 0; -#ifdef USE_M17N - newBuf->document_charset = old_charset; -#endif - } - } -#endif - lineBuf2 = tmp; - } - else { - lineBuf2 = tmp; - } - if ((uf->scheme == SCM_HTTP -#ifdef USE_SSL - || uf->scheme == SCM_HTTPS -#endif /* USE_SSL */ - ) && http_response_code == -1) { - p = lineBuf2->ptr; - while (*p && !IS_SPACE(*p)) - p++; - while (*p && IS_SPACE(*p)) - p++; - http_response_code = atoi(p); - if (fmInitialized) { - message(lineBuf2->ptr, 0, 0); - refresh(); - } - } - if (!strncasecmp(lineBuf2->ptr, "content-transfer-encoding:", 26)) { - p = lineBuf2->ptr + 26; - while (IS_SPACE(*p)) - p++; - if (!strncasecmp(p, "base64", 6)) - uf->encoding = ENC_BASE64; - else if (!strncasecmp(p, "quoted-printable", 16)) - uf->encoding = ENC_QUOTE; - else if (!strncasecmp(p, "uuencode", 8) || - !strncasecmp(p, "x-uuencode", 10)) - uf->encoding = ENC_UUENCODE; - else - uf->encoding = ENC_7BIT; - } - else if (!strncasecmp(lineBuf2->ptr, "content-encoding:", 17)) { - struct compression_decoder *d; - p = lineBuf2->ptr + 17; - while (IS_SPACE(*p)) - p++; - uf->compression = CMP_NOCOMPRESS; - for (d = compression_decoders; d->type != CMP_NOCOMPRESS; d++) { - char **e; - for (e = d->encodings; *e != NULL; e++) { - if (strncasecmp(p, *e, strlen(*e)) == 0) { - uf->compression = d->type; - break; - } - } - if (uf->compression != CMP_NOCOMPRESS) - break; - } - uf->content_encoding = uf->compression; - } -#ifdef USE_COOKIE - else if (use_cookie && accept_cookie && - pu && check_cookie_accept_domain(pu->host) && - (!strncasecmp(lineBuf2->ptr, "Set-Cookie:", 11) || - !strncasecmp(lineBuf2->ptr, "Set-Cookie2:", 12))) { - Str name = Strnew(), value = Strnew(), domain = NULL, path = NULL, - comment = NULL, commentURL = NULL, port = NULL, tmp2; - int version, quoted, flag = 0; - time_t expires = (time_t) - 1; - - q = NULL; - if (lineBuf2->ptr[10] == '2') { - p = lineBuf2->ptr + 12; - version = 1; - } - else { - p = lineBuf2->ptr + 11; - version = 0; - } -#ifdef DEBUG - fprintf(stderr, "Set-Cookie: [%s]\n", p); -#endif /* DEBUG */ - SKIP_BLANKS(p); - while (*p != '=' && !IS_ENDT(*p)) - Strcat_char(name, *(p++)); - Strremovetrailingspaces(name); - if (*p == '=') { - p++; - SKIP_BLANKS(p); - quoted = 0; - while (!IS_ENDL(*p) && (quoted || *p != ';')) { - if (!IS_SPACE(*p)) - q = p; - if (*p == '"') - quoted = (quoted) ? 0 : 1; - Strcat_char(value, *(p++)); - } - if (q) - Strshrink(value, p - q - 1); - } - while (*p == ';') { - p++; - SKIP_BLANKS(p); - if (matchattr(p, "expires", 7, &tmp2)) { - /* version 0 */ - expires = mymktime(tmp2->ptr); - } - else if (matchattr(p, "max-age", 7, &tmp2)) { - /* XXX Is there any problem with max-age=0? (RFC 2109 ss. 4.2.1, 4.2.2 */ - expires = time(NULL) + atol(tmp2->ptr); - } - else if (matchattr(p, "domain", 6, &tmp2)) { - domain = tmp2; - } - else if (matchattr(p, "path", 4, &tmp2)) { - path = tmp2; - } - else if (matchattr(p, "secure", 6, NULL)) { - flag |= COO_SECURE; - } - else if (matchattr(p, "comment", 7, &tmp2)) { - comment = tmp2; - } - else if (matchattr(p, "version", 7, &tmp2)) { - version = atoi(tmp2->ptr); - } - else if (matchattr(p, "port", 4, &tmp2)) { - /* version 1, Set-Cookie2 */ - port = tmp2; - } - else if (matchattr(p, "commentURL", 10, &tmp2)) { - /* version 1, Set-Cookie2 */ - commentURL = tmp2; - } - else if (matchattr(p, "discard", 7, NULL)) { - /* version 1, Set-Cookie2 */ - flag |= COO_DISCARD; - } - quoted = 0; - while (!IS_ENDL(*p) && (quoted || *p != ';')) { - if (*p == '"') - quoted = (quoted) ? 0 : 1; - p++; - } - } - if (pu && name->length > 0) { - int err; - if (show_cookie) { - if (flag & COO_SECURE) - disp_message_nsec("Received a secured cookie", FALSE, 1, - TRUE, FALSE); - else - disp_message_nsec(Sprintf("Received cookie: %s=%s", - name->ptr, value->ptr)->ptr, - FALSE, 1, TRUE, FALSE); - } - err = - add_cookie(pu, name, value, expires, domain, path, flag, - comment, version, port, commentURL); - if (err) { - char *ans = (accept_bad_cookie == ACCEPT_BAD_COOKIE_ACCEPT) - ? "y" : NULL; - if (fmInitialized && (err & COO_OVERRIDE_OK) && - accept_bad_cookie == ACCEPT_BAD_COOKIE_ASK) { - Str msg = Sprintf("Accept bad cookie from %s for %s?", - pu->host, - ((domain && domain->ptr) - ? domain->ptr : "<localdomain>")); - if (msg->length > COLS - 10) - Strshrink(msg, msg->length - (COLS - 10)); - Strcat_charp(msg, " (y/n)"); - ans = inputAnswer(msg->ptr); - } - if (ans == NULL || TOLOWER(*ans) != 'y' || - (err = - add_cookie(pu, name, value, expires, domain, path, - flag | COO_OVERRIDE, comment, version, - port, commentURL))) { - err = (err & ~COO_OVERRIDE_OK) - 1; - if (err >= 0 && err < COO_EMAX) - emsg = Sprintf("This cookie was rejected " - "to prevent security violation. [%s]", - violations[err])->ptr; - else - emsg = - "This cookie was rejected to prevent security violation."; - record_err_message(emsg); - if (show_cookie) - disp_message_nsec(emsg, FALSE, 1, TRUE, FALSE); - } - else - if (show_cookie) - disp_message_nsec(Sprintf - ("Accepting invalid cookie: %s=%s", - name->ptr, value->ptr)->ptr, FALSE, - 1, TRUE, FALSE); - } - } - } -#endif /* USE_COOKIE */ - else if (!strncasecmp(lineBuf2->ptr, "w3m-control:", 12) && - uf->scheme == SCM_LOCAL_CGI) { - Str funcname = Strnew(); - int f; - - p = lineBuf2->ptr + 12; - SKIP_BLANKS(p); - while (*p && !IS_SPACE(*p)) - Strcat_char(funcname, *(p++)); - SKIP_BLANKS(p); - f = getFuncList(funcname->ptr); - if (f >= 0) { - tmp = Strnew_charp(p); - Strchop(tmp); - pushEvent(f, tmp->ptr); - } - } - if (headerlist) - pushText(headerlist, lineBuf2->ptr); - Strfree(lineBuf2); - lineBuf2 = NULL; - } - if (thru) - addnewline(newBuf, "", propBuffer, NULL, 0, -1, -1); - if (src) - fclose(src); -} - -char * -checkHeader(Buffer *buf, char *field) -{ - int len; - TextListItem *i; - char *p; - - if (buf == NULL || field == NULL || buf->document_header == NULL) - return NULL; - len = strlen(field); - for (i = buf->document_header->first; i != NULL; i = i->next) { - if (!strncasecmp(i->ptr, field, len)) { - p = i->ptr + len; - return remove_space(p); - } - } - return NULL; -} - -char * -checkContentType(Buffer *buf) -{ - char *p; - Str r; - p = checkHeader(buf, "Content-Type:"); - if (p == NULL) - return NULL; - r = Strnew(); - while (*p && *p != ';' && !IS_SPACE(*p)) - Strcat_char(r, *p++); -#ifdef USE_M17N - if ((p = strcasestr(p, "charset")) != NULL) { - p += 7; - SKIP_BLANKS(p); - if (*p == '=') { - p++; - SKIP_BLANKS(p); - if (*p == '"') - p++; - content_charset = wc_guess_charset(p, 0); - } - } -#endif - return r->ptr; -} - -struct auth_param { - char *name; - Str val; -}; - -struct http_auth { - int pri; - char *scheme; - struct auth_param *param; - Str (*cred) (struct http_auth * ha, Str uname, Str pw, ParsedURL *pu, - HRequest *hr, FormList *request); -}; - -enum { - AUTHCHR_NUL, - AUTHCHR_SEP, - AUTHCHR_TOKEN, -}; - -static int -skip_auth_token(char **pp) -{ - char *p; - int first = AUTHCHR_NUL, typ; - - for (p = *pp ;; ++p) { - switch (*p) { - case '\0': - goto endoftoken; - default: - if ((unsigned char)*p > 037) { - typ = AUTHCHR_TOKEN; - break; - } - /* thru */ - case '\177': - case '[': - case ']': - case '(': - case ')': - case '<': - case '>': - case '@': - case ';': - case ':': - case '\\': - case '"': - case '/': - case '?': - case '=': - case ' ': - case '\t': - case ',': - typ = AUTHCHR_SEP; - break; - } - - if (!first) - first = typ; - else if (first != typ) - break; - } -endoftoken: - *pp = p; - return first; -} - -static Str -extract_auth_val(char **q) -{ - unsigned char *qq = *(unsigned char **)q; - int quoted = 0; - Str val = Strnew(); - - SKIP_BLANKS(qq); - if (*qq == '"') { - quoted = TRUE; - Strcat_char(val, *qq++); - } - while (*qq != '\0') { - if (quoted && *qq == '"') { - Strcat_char(val, *qq++); - break; - } - if (!quoted) { - switch (*qq) { - case '[': - case ']': - case '(': - case ')': - case '<': - case '>': - case '@': - case ';': - case ':': - case '\\': - case '"': - case '/': - case '?': - case '=': - case ' ': - case '\t': - qq++; - case ',': - goto end_token; - default: - if (*qq <= 037 || *qq == 0177) { - qq++; - goto end_token; - } - } - } - else if (quoted && *qq == '\\') - Strcat_char(val, *qq++); - Strcat_char(val, *qq++); - } - end_token: - *q = (char *)qq; - return val; -} - -static Str -qstr_unquote(Str s) -{ - char *p; - - if (s == NULL) - return NULL; - p = s->ptr; - if (*p == '"') { - Str tmp = Strnew(); - for (p++; *p != '\0'; p++) { - if (*p == '\\') - p++; - Strcat_char(tmp, *p); - } - if (Strlastchar(tmp) == '"') - Strshrink(tmp, 1); - return tmp; - } - else - return s; -} - -static char * -extract_auth_param(char *q, struct auth_param *auth) -{ - struct auth_param *ap; - char *p; - - for (ap = auth; ap->name != NULL; ap++) { - ap->val = NULL; - } - - while (*q != '\0') { - SKIP_BLANKS(q); - for (ap = auth; ap->name != NULL; ap++) { - size_t len; - - len = strlen(ap->name); - if (strncasecmp(q, ap->name, len) == 0 && - (IS_SPACE(q[len]) || q[len] == '=')) { - p = q + len; - SKIP_BLANKS(p); - if (*p != '=') - return q; - q = p + 1; - ap->val = extract_auth_val(&q); - break; - } - } - if (ap->name == NULL) { - /* skip unknown param */ - int token_type; - p = q; - if ((token_type = skip_auth_token(&q)) == AUTHCHR_TOKEN && - (IS_SPACE(*q) || *q == '=')) { - SKIP_BLANKS(q); - if (*q != '=') - return p; - q++; - extract_auth_val(&q); - } - else - return p; - } - if (*q != '\0') { - SKIP_BLANKS(q); - if (*q == ',') - q++; - else - break; - } - } - return q; -} - -static Str -get_auth_param(struct auth_param *auth, char *name) -{ - struct auth_param *ap; - for (ap = auth; ap->name != NULL; ap++) { - if (strcasecmp(name, ap->name) == 0) - return ap->val; - } - return NULL; -} - -static Str -AuthBasicCred(struct http_auth *ha, Str uname, Str pw, ParsedURL *pu, - HRequest *hr, FormList *request) -{ - Str s = Strdup(uname); - Strcat_char(s, ':'); - Strcat(s, pw); - return Strnew_m_charp("Basic ", encodeB(s->ptr)->ptr, NULL); -} - -#ifdef USE_DIGEST_AUTH -#include <openssl/md5.h> - -/* RFC2617: 3.2.2 The Authorization Request Header - * - * credentials = "Digest" digest-response - * digest-response = 1#( username | realm | nonce | digest-uri - * | response | [ algorithm ] | [cnonce] | - * [opaque] | [message-qop] | - * [nonce-count] | [auth-param] ) - * - * username = "username" "=" username-value - * username-value = quoted-string - * digest-uri = "uri" "=" digest-uri-value - * digest-uri-value = request-uri ; As specified by HTTP/1.1 - * message-qop = "qop" "=" qop-value - * cnonce = "cnonce" "=" cnonce-value - * cnonce-value = nonce-value - * nonce-count = "nc" "=" nc-value - * nc-value = 8LHEX - * response = "response" "=" request-digest - * request-digest = <"> 32LHEX <"> - * LHEX = "0" | "1" | "2" | "3" | - * "4" | "5" | "6" | "7" | - * "8" | "9" | "a" | "b" | - * "c" | "d" | "e" | "f" - */ - -static Str -digest_hex(char *p) -{ - char *h = "0123456789abcdef"; - Str tmp = Strnew_size(MD5_DIGEST_LENGTH * 2 + 1); - int i; - for (i = 0; i < MD5_DIGEST_LENGTH; i++, p++) { - Strcat_char(tmp, h[(*p >> 4) & 0x0f]); - Strcat_char(tmp, h[*p & 0x0f]); - } - return tmp; -} - -enum { - QOP_NONE, - QOP_AUTH, - QOP_AUTH_INT, -}; - -static Str -AuthDigestCred(struct http_auth *ha, Str uname, Str pw, ParsedURL *pu, - HRequest *hr, FormList *request) -{ - Str tmp, a1buf, a2buf, rd, s; - char md5[MD5_DIGEST_LENGTH + 1]; - Str uri = HTTPrequestURI(pu, hr); - char nc[] = "00000001"; - - Str algorithm = qstr_unquote(get_auth_param(ha->param, "algorithm")); - Str nonce = qstr_unquote(get_auth_param(ha->param, "nonce")); - Str cnonce /* = qstr_unquote(get_auth_param(ha->param, "cnonce")) */; - /* cnonce is what client should generate. */ - Str qop = qstr_unquote(get_auth_param(ha->param, "qop")); - - static union { - int r[4]; - char s[sizeof(int) * 4]; - } cnonce_seed; - int qop_i = QOP_NONE; - - cnonce_seed.r[0] = rand(); - cnonce_seed.r[1] = rand(); - cnonce_seed.r[2] = rand(); - MD5(cnonce_seed.s, sizeof(cnonce_seed.s), md5); - cnonce = digest_hex(md5); - cnonce_seed.r[3]++; - - if (qop) { - char *p; - size_t i; - - p = qop->ptr; - SKIP_BLANKS(p); - - for (;;) { - if ((i = strcspn(p, " \t,")) > 0) { - if (i == sizeof("auth-int") - sizeof("") && !strncasecmp(p, "auth-int", i)) { - if (qop_i < QOP_AUTH_INT) - qop_i = QOP_AUTH_INT; - } - else if (i == sizeof("auth") - sizeof("") && !strncasecmp(p, "auth", i)) { - if (qop_i < QOP_AUTH) - qop_i = QOP_AUTH; - } - } - - if (p[i]) { - p += i + 1; - SKIP_BLANKS(p); - } - else - break; - } - } - - /* A1 = unq(username-value) ":" unq(realm-value) ":" passwd */ - tmp = Strnew_m_charp(uname->ptr, ":", - qstr_unquote(get_auth_param(ha->param, "realm"))->ptr, - ":", pw->ptr, NULL); - MD5(tmp->ptr, strlen(tmp->ptr), md5); - a1buf = digest_hex(md5); - - if (algorithm) { - if (strcasecmp(algorithm->ptr, "MD5-sess") == 0) { - /* A1 = H(unq(username-value) ":" unq(realm-value) ":" passwd) - * ":" unq(nonce-value) ":" unq(cnonce-value) - */ - if (nonce == NULL) - return NULL; - tmp = Strnew_m_charp(a1buf->ptr, ":", - qstr_unquote(nonce)->ptr, - ":", qstr_unquote(cnonce)->ptr, NULL); - MD5(tmp->ptr, strlen(tmp->ptr), md5); - a1buf = digest_hex(md5); - } - else if (strcasecmp(algorithm->ptr, "MD5") == 0) - /* ok default */ - ; - else - /* unknown algorithm */ - return NULL; - } - - /* A2 = Method ":" digest-uri-value */ - tmp = Strnew_m_charp(HTTPrequestMethod(hr)->ptr, ":", uri->ptr, NULL); - if (qop_i == QOP_AUTH_INT) { - /* A2 = Method ":" digest-uri-value ":" H(entity-body) */ - if (request && request->body) { - if (request->method == FORM_METHOD_POST && request->enctype == FORM_ENCTYPE_MULTIPART) { - FILE *fp = fopen(request->body, "r"); - if (fp != NULL) { - Str ebody; - ebody = Strfgetall(fp); - MD5(ebody->ptr, strlen(ebody->ptr), md5); - } - else { - MD5("", 0, md5); - } - } - else { - MD5(request->body, request->length, md5); - } - } - else { - MD5("", 0, md5); - } - Strcat_char(tmp, ':'); - Strcat(tmp, digest_hex(md5)); - } - MD5(tmp->ptr, strlen(tmp->ptr), md5); - a2buf = digest_hex(md5); - - if (qop_i >= QOP_AUTH) { - /* request-digest = <"> < KD ( H(A1), unq(nonce-value) - * ":" nc-value - * ":" unq(cnonce-value) - * ":" unq(qop-value) - * ":" H(A2) - * ) <"> - */ - if (nonce == NULL) - return NULL; - tmp = Strnew_m_charp(a1buf->ptr, ":", qstr_unquote(nonce)->ptr, - ":", nc, - ":", qstr_unquote(cnonce)->ptr, - ":", qop_i == QOP_AUTH ? "auth" : "auth-int", - ":", a2buf->ptr, NULL); - MD5(tmp->ptr, strlen(tmp->ptr), md5); - rd = digest_hex(md5); - } - else { - /* compatibility with RFC 2069 - * request_digest = KD(H(A1), unq(nonce), H(A2)) - */ - tmp = Strnew_m_charp(a1buf->ptr, ":", - qstr_unquote(get_auth_param(ha->param, "nonce"))-> - ptr, ":", a2buf->ptr, NULL); - MD5(tmp->ptr, strlen(tmp->ptr), md5); - rd = digest_hex(md5); - } - - /* - * digest-response = 1#( username | realm | nonce | digest-uri - * | response | [ algorithm ] | [cnonce] | - * [opaque] | [message-qop] | - * [nonce-count] | [auth-param] ) - */ - - tmp = Strnew_m_charp("Digest username=\"", uname->ptr, "\"", NULL); - Strcat_m_charp(tmp, ", realm=", - get_auth_param(ha->param, "realm")->ptr, NULL); - Strcat_m_charp(tmp, ", nonce=", - get_auth_param(ha->param, "nonce")->ptr, NULL); - Strcat_m_charp(tmp, ", uri=\"", uri->ptr, "\"", NULL); - Strcat_m_charp(tmp, ", response=\"", rd->ptr, "\"", NULL); - - if (algorithm) - Strcat_m_charp(tmp, ", algorithm=", - get_auth_param(ha->param, "algorithm")->ptr, NULL); - - if (cnonce) - Strcat_m_charp(tmp, ", cnonce=\"", cnonce->ptr, "\"", NULL); - - if ((s = get_auth_param(ha->param, "opaque")) != NULL) - Strcat_m_charp(tmp, ", opaque=", s->ptr, NULL); - - if (qop_i >= QOP_AUTH) { - Strcat_m_charp(tmp, ", qop=", - qop_i == QOP_AUTH ? "auth" : "auth-int", - NULL); - /* XXX how to count? */ - /* Since nonce is unique up to each *-Authenticate and w3m does not re-use *-Authenticate: headers, - nonce-count should be always "00000001". */ - Strcat_m_charp(tmp, ", nc=", nc, NULL); - } - - return tmp; -} -#endif - -/* *INDENT-OFF* */ -struct auth_param none_auth_param[] = { - {NULL, NULL} -}; - -struct auth_param basic_auth_param[] = { - {"realm", NULL}, - {NULL, NULL} -}; - -#ifdef USE_DIGEST_AUTH -/* RFC2617: 3.2.1 The WWW-Authenticate Response Header - * challenge = "Digest" digest-challenge - * - * digest-challenge = 1#( realm | [ domain ] | nonce | - * [ opaque ] |[ stale ] | [ algorithm ] | - * [ qop-options ] | [auth-param] ) - * - * domain = "domain" "=" <"> URI ( 1*SP URI ) <"> - * URI = absoluteURI | abs_path - * nonce = "nonce" "=" nonce-value - * nonce-value = quoted-string - * opaque = "opaque" "=" quoted-string - * stale = "stale" "=" ( "true" | "false" ) - * algorithm = "algorithm" "=" ( "MD5" | "MD5-sess" | - * token ) - * qop-options = "qop" "=" <"> 1#qop-value <"> - * qop-value = "auth" | "auth-int" | token - */ -struct auth_param digest_auth_param[] = { - {"realm", NULL}, - {"domain", NULL}, - {"nonce", NULL}, - {"opaque", NULL}, - {"stale", NULL}, - {"algorithm", NULL}, - {"qop", NULL}, - {NULL, NULL} -}; -#endif -/* for RFC2617: HTTP Authentication */ -struct http_auth www_auth[] = { - { 1, "Basic ", basic_auth_param, AuthBasicCred }, -#ifdef USE_DIGEST_AUTH - { 10, "Digest ", digest_auth_param, AuthDigestCred }, -#endif - { 0, NULL, NULL, NULL,} -}; -/* *INDENT-ON* */ - -static struct http_auth * -findAuthentication(struct http_auth *hauth, Buffer *buf, char *auth_field) -{ - struct http_auth *ha; - int len = strlen(auth_field), slen; - TextListItem *i; - char *p0, *p; - - bzero(hauth, sizeof(struct http_auth)); - for (i = buf->document_header->first; i != NULL; i = i->next) { - if (strncasecmp(i->ptr, auth_field, len) == 0) { - for (p = i->ptr + len; p != NULL && *p != '\0';) { - SKIP_BLANKS(p); - p0 = p; - for (ha = &www_auth[0]; ha->scheme != NULL; ha++) { - slen = strlen(ha->scheme); - if (strncasecmp(p, ha->scheme, slen) == 0) { - p += slen; - SKIP_BLANKS(p); - if (hauth->pri < ha->pri) { - *hauth = *ha; - p = extract_auth_param(p, hauth->param); - break; - } - else { - /* weak auth */ - p = extract_auth_param(p, none_auth_param); - } - } - } - if (p0 == p) { - /* all unknown auth failed */ - int token_type; - if ((token_type = skip_auth_token(&p)) == AUTHCHR_TOKEN && IS_SPACE(*p)) { - SKIP_BLANKS(p); - p = extract_auth_param(p, none_auth_param); - } - else - break; - } - } - } - } - return hauth->scheme ? hauth : NULL; -} - -static void -getAuthCookie(struct http_auth *hauth, char *auth_header, - TextList *extra_header, ParsedURL *pu, HRequest *hr, - FormList *request, - volatile Str *uname, volatile Str *pwd) -{ - Str ss = NULL; - Str tmp; - TextListItem *i; - int a_found; - int auth_header_len = strlen(auth_header); - char *realm = NULL; - int proxy; - - if (hauth) - realm = qstr_unquote(get_auth_param(hauth->param, "realm"))->ptr; - - if (!realm) - return; - - a_found = FALSE; - for (i = extra_header->first; i != NULL; i = i->next) { - if (!strncasecmp(i->ptr, auth_header, auth_header_len)) { - a_found = TRUE; - break; - } - } - proxy = !strncasecmp("Proxy-Authorization:", auth_header, - auth_header_len); - if (a_found) { - /* This means that *-Authenticate: header is received after - * Authorization: header is sent to the server. - */ - if (fmInitialized) { - message("Wrong username or password", 0, 0); - refresh(); - } - else - fprintf(stderr, "Wrong username or password\n"); - sleep(1); - /* delete Authenticate: header from extra_header */ - delText(extra_header, i); - invalidate_auth_user_passwd(pu, realm, *uname, *pwd, proxy); - } - *uname = NULL; - *pwd = NULL; - - if (!a_found && find_auth_user_passwd(pu, realm, (Str*)uname, (Str*)pwd, - proxy)) { - /* found username & password in passwd file */ ; - } - else { - if (QuietMessage) - return; - /* input username and password */ - sleep(2); - if (fmInitialized) { - char *pp; - term_raw(); - /* FIXME: gettextize? */ - if ((pp = inputStr(Sprintf("Username for %s: ", realm)->ptr, - NULL)) == NULL) - return; - *uname = Str_conv_to_system(Strnew_charp(pp)); - if ((pp = inputLine(Sprintf("Password for %s: ", realm)->ptr, NULL, - IN_PASSWORD)) == NULL) { - *uname = NULL; - return; - } - *pwd = Str_conv_to_system(Strnew_charp(pp)); - term_cbreak(); - } - else { - /* - * If post file is specified as '-', stdin is closed at this - * point. - * In this case, w3m cannot read username from stdin. - * So exit with error message. - * (This is same behavior as lwp-request.) - */ - if (feof(stdin) || ferror(stdin)) { - /* FIXME: gettextize? */ - fprintf(stderr, "w3m: Authorization required for %s\n", - realm); - exit(1); - } - - /* FIXME: gettextize? */ - printf(proxy ? "Proxy Username for %s: " : "Username for %s: ", - realm); - fflush(stdout); - *uname = Strfgets(stdin); - Strchop(*uname); -#ifdef HAVE_GETPASSPHRASE - *pwd = Strnew_charp((char *) - getpassphrase(proxy ? "Proxy Password: " : - "Password: ")); -#else - *pwd = Strnew_charp((char *) - getpass(proxy ? "Proxy Password: " : - "Password: ")); -#endif - } - } - ss = hauth->cred(hauth, *uname, *pwd, pu, hr, request); - if (ss) { - tmp = Strnew_charp(auth_header); - Strcat_m_charp(tmp, " ", ss->ptr, "\r\n", NULL); - pushText(extra_header, tmp->ptr); - } - else { - *uname = NULL; - *pwd = NULL; - } - return; -} - -static int -same_url_p(ParsedURL *pu1, ParsedURL *pu2) -{ - return (pu1->scheme == pu2->scheme && pu1->port == pu2->port && - (pu1->host ? pu2->host ? !strcasecmp(pu1->host, pu2->host) : 0 : 1) - && (pu1->file ? pu2-> - file ? !strcmp(pu1->file, pu2->file) : 0 : 1)); -} - -static int -checkRedirection(ParsedURL *pu) -{ - static ParsedURL *puv = NULL; - static int nredir = 0; - static int nredir_size = 0; - Str tmp; - - if (pu == NULL) { - nredir = 0; - nredir_size = 0; - puv = NULL; - return TRUE; - } - if (nredir >= FollowRedirection) { - /* FIXME: gettextize? */ - tmp = Sprintf("Number of redirections exceeded %d at %s", - FollowRedirection, parsedURL2Str(pu)->ptr); - disp_err_message(tmp->ptr, FALSE); - return FALSE; - } - else if (nredir_size > 0 && - (same_url_p(pu, &puv[(nredir - 1) % nredir_size]) || - (!(nredir % 2) - && same_url_p(pu, &puv[(nredir / 2) % nredir_size])))) { - /* FIXME: gettextize? */ - tmp = Sprintf("Redirection loop detected (%s)", - parsedURL2Str(pu)->ptr); - disp_err_message(tmp->ptr, FALSE); - return FALSE; - } - if (!puv) { - nredir_size = FollowRedirection / 2 + 1; - puv = New_N(ParsedURL, nredir_size); - memset(puv, 0, sizeof(ParsedURL) * nredir_size); - } - copyParsedURL(&puv[nredir % nredir_size], pu); - nredir++; - return TRUE; -} - -/* - * loadGeneralFile: load file to buffer - */ -Buffer * -loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, - int flag, FormList *volatile request) -{ - URLFile f, *volatile of = NULL; - ParsedURL pu; - Buffer *b = NULL, *(*volatile proc)() = loadBuffer; - char *volatile tpath; - char *volatile t = "text/plain", *p, *volatile real_type = NULL; - Buffer *volatile t_buf = NULL; - int volatile searchHeader = SearchHeader; - int volatile searchHeader_through = TRUE; - MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; - TextList *extra_header = newTextList(); - volatile Str uname = NULL; - volatile Str pwd = NULL; - volatile Str realm = NULL; - int volatile add_auth_cookie_flag; - unsigned char status = HTST_NORMAL; - URLOption url_option; - Str tmp; - Str volatile page = NULL; -#ifdef USE_M17N - wc_ces charset = WC_CES_US_ASCII; -#endif - HRequest hr; - ParsedURL *volatile auth_pu; - - tpath = path; - prevtrap = NULL; - add_auth_cookie_flag = 0; - - checkRedirection(NULL); - load_doc: - TRAP_OFF; - url_option.referer = referer; - url_option.flag = flag; - f = openURL(tpath, &pu, current, &url_option, request, extra_header, of, - &hr, &status); - of = NULL; -#ifdef USE_M17N - content_charset = 0; -#endif - if (f.stream == NULL) { - switch (f.scheme) { - case SCM_LOCAL: - { - struct stat st; - if (stat(pu.real_file, &st) < 0) - return NULL; - if (S_ISDIR(st.st_mode)) { - if (UseExternalDirBuffer) { - Str cmd = Sprintf("%s?dir=%s#current", - DirBufferCommand, pu.file); - b = loadGeneralFile(cmd->ptr, NULL, NO_REFERER, 0, - NULL); - if (b != NULL && b != NO_BUFFER) { - copyParsedURL(&b->currentURL, &pu); - b->filename = b->currentURL.real_file; - } - return b; - } - else { - page = loadLocalDir(pu.real_file); - t = "local:directory"; -#ifdef USE_M17N - charset = SystemCharset; -#endif - } - } - } - break; - case SCM_FTPDIR: - page = loadFTPDir(&pu, &charset); - t = "ftp:directory"; - break; -#ifdef USE_NNTP - case SCM_NEWS_GROUP: - page = loadNewsgroup(&pu, &charset); - t = "news:group"; - break; -#endif - case SCM_UNKNOWN: -#ifdef USE_EXTERNAL_URI_LOADER - tmp = searchURIMethods(&pu); - if (tmp != NULL) { - b = loadGeneralFile(tmp->ptr, current, referer, flag, request); - if (b != NULL && b != NO_BUFFER) - copyParsedURL(&b->currentURL, &pu); - return b; - } -#endif - /* FIXME: gettextize? */ - disp_err_message(Sprintf("Unknown URI: %s", - parsedURL2Str(&pu)->ptr)->ptr, FALSE); - break; - } - if (page && page->length > 0) - goto page_loaded; - return NULL; - } - - if (status == HTST_MISSING) { - TRAP_OFF; - UFclose(&f); - return NULL; - } - - /* openURL() succeeded */ - if (SETJMP(AbortLoading) != 0) { - /* transfer interrupted */ - TRAP_OFF; - if (b) - discardBuffer(b); - UFclose(&f); - return NULL; - } - - b = NULL; - if (f.is_cgi) { - /* local CGI */ - searchHeader = TRUE; - searchHeader_through = FALSE; - } - if (header_string) - header_string = NULL; - TRAP_ON; - if (pu.scheme == SCM_HTTP || -#ifdef USE_SSL - pu.scheme == SCM_HTTPS || -#endif /* USE_SSL */ - (( -#ifdef USE_GOPHER - (pu.scheme == SCM_GOPHER && non_null(GOPHER_proxy)) || -#endif /* USE_GOPHER */ - (pu.scheme == SCM_FTP && non_null(FTP_proxy)) - ) && !Do_not_use_proxy && !check_no_proxy(pu.host))) { - - if (fmInitialized) { - term_cbreak(); - /* FIXME: gettextize? */ - message(Sprintf("%s contacted. Waiting for reply...", pu.host)-> - ptr, 0, 0); - refresh(); - } - if (t_buf == NULL) - t_buf = newBuffer(INIT_BUFFER_WIDTH); -#if 0 /* USE_SSL */ - if (IStype(f.stream) == IST_SSL) { - Str s = ssl_get_certificate(f.stream, pu.host); - if (s == NULL) - return NULL; - else - t_buf->ssl_certificate = s->ptr; - } -#endif - readHeader(&f, t_buf, FALSE, &pu); - if (((http_response_code >= 301 && http_response_code <= 303) - || http_response_code == 307) - && (p = checkHeader(t_buf, "Location:")) != NULL - && checkRedirection(&pu)) { - /* document moved */ - /* 301: Moved Permanently */ - /* 302: Found */ - /* 303: See Other */ - /* 307: Temporary Redirect (HTTP/1.1) */ - tpath = url_quote_conv(p, DocumentCharset); - request = NULL; - UFclose(&f); - current = New(ParsedURL); - copyParsedURL(current, &pu); - t_buf = newBuffer(INIT_BUFFER_WIDTH); - t_buf->bufferprop |= BP_REDIRECTED; - status = HTST_NORMAL; - goto load_doc; - } - t = checkContentType(t_buf); - if (t == NULL && pu.file != NULL) { - if (!((http_response_code >= 400 && http_response_code <= 407) || - (http_response_code >= 500 && http_response_code <= 505))) - t = guessContentType(pu.file); - } - if (t == NULL) - t = "text/plain"; - if (add_auth_cookie_flag && realm && uname && pwd) { - /* If authorization is required and passed */ - add_auth_user_passwd(&pu, qstr_unquote(realm)->ptr, uname, pwd, - 0); - add_auth_cookie_flag = 0; - } - if ((p = checkHeader(t_buf, "WWW-Authenticate:")) != NULL && - http_response_code == 401) { - /* Authentication needed */ - struct http_auth hauth; - if (findAuthentication(&hauth, t_buf, "WWW-Authenticate:") != NULL - && (realm = get_auth_param(hauth.param, "realm")) != NULL) { - auth_pu = &pu; - getAuthCookie(&hauth, "Authorization:", extra_header, - auth_pu, &hr, request, &uname, &pwd); - if (uname == NULL) { - /* abort */ - TRAP_OFF; - goto page_loaded; - } - UFclose(&f); - add_auth_cookie_flag = 1; - status = HTST_NORMAL; - goto load_doc; - } - } - if ((p = checkHeader(t_buf, "Proxy-Authenticate:")) != NULL && - http_response_code == 407) { - /* Authentication needed */ - struct http_auth hauth; - if (findAuthentication(&hauth, t_buf, "Proxy-Authenticate:") - != NULL - && (realm = get_auth_param(hauth.param, "realm")) != NULL) { - auth_pu = schemeToProxy(pu.scheme); - getAuthCookie(&hauth, "Proxy-Authorization:", - extra_header, auth_pu, &hr, request, - &uname, &pwd); - if (uname == NULL) { - /* abort */ - TRAP_OFF; - goto page_loaded; - } - UFclose(&f); - add_auth_cookie_flag = 1; - status = HTST_NORMAL; - goto load_doc; - } - } - /* XXX: RFC2617 3.2.3 Authentication-Info: ? */ - - if (status == HTST_CONNECT) { - of = &f; - goto load_doc; - } - - f.modtime = mymktime(checkHeader(t_buf, "Last-Modified:")); - } -#ifdef USE_NNTP - else if (pu.scheme == SCM_NEWS || pu.scheme == SCM_NNTP) { - if (t_buf == NULL) - t_buf = newBuffer(INIT_BUFFER_WIDTH); - readHeader(&f, t_buf, TRUE, &pu); - t = checkContentType(t_buf); - if (t == NULL) - t = "text/plain"; - } -#endif /* USE_NNTP */ -#ifdef USE_GOPHER - else if (pu.scheme == SCM_GOPHER) { - switch (*pu.file) { - case '0': - t = "text/plain"; - break; - case '1': - case 'm': - page = loadGopherDir(&f, &pu, &charset); - t = "gopher:directory"; - TRAP_OFF; - goto page_loaded; - case 's': - t = "audio/basic"; - break; - case 'g': - t = "image/gif"; - break; - case 'h': - t = "text/html"; - break; - } - } -#endif /* USE_GOPHER */ - else if (pu.scheme == SCM_FTP) { - check_compression(path, &f); - if (f.compression != CMP_NOCOMPRESS) { - char *t1 = uncompressed_file_type(pu.file, NULL); - real_type = f.guess_type; -#if 0 - if (t1 && strncasecmp(t1, "application/", 12) == 0) { - f.compression = CMP_NOCOMPRESS; - t = real_type; - } - else -#endif - if (t1) - t = t1; - else - t = real_type; - } - else { - real_type = guessContentType(pu.file); - if (real_type == NULL) - real_type = "text/plain"; - t = real_type; - } -#if 0 - if (!strncasecmp(t, "application/", 12)) { - char *tmpf = tmpfname(TMPF_DFL, NULL)->ptr; - current_content_length = 0; - if (save2tmp(f, tmpf) < 0) - UFclose(&f); - else { - UFclose(&f); - TRAP_OFF; - doFileMove(tmpf, guess_save_name(t_buf, pu.file)); - } - return NO_BUFFER; - } -#endif - } - else if (pu.scheme == SCM_DATA) { - t = f.guess_type; - } - else if (searchHeader) { - searchHeader = SearchHeader = FALSE; - if (t_buf == NULL) - t_buf = newBuffer(INIT_BUFFER_WIDTH); - readHeader(&f, t_buf, searchHeader_through, &pu); - if (f.is_cgi && (p = checkHeader(t_buf, "Location:")) != NULL && - checkRedirection(&pu)) { - /* document moved */ - tpath = url_quote_conv(remove_space(p), DocumentCharset); - request = NULL; - UFclose(&f); - add_auth_cookie_flag = 0; - current = New(ParsedURL); - copyParsedURL(current, &pu); - t_buf = newBuffer(INIT_BUFFER_WIDTH); - t_buf->bufferprop |= BP_REDIRECTED; - status = HTST_NORMAL; - goto load_doc; - } -#ifdef AUTH_DEBUG - if ((p = checkHeader(t_buf, "WWW-Authenticate:")) != NULL) { - /* Authentication needed */ - struct http_auth hauth; - if (findAuthentication(&hauth, t_buf, "WWW-Authenticate:") != NULL - && (realm = get_auth_param(hauth.param, "realm")) != NULL) { - auth_pu = &pu; - getAuthCookie(&hauth, "Authorization:", extra_header, - auth_pu, &hr, request, &uname, &pwd); - if (uname == NULL) { - /* abort */ - TRAP_OFF; - goto page_loaded; - } - UFclose(&f); - add_auth_cookie_flag = 1; - status = HTST_NORMAL; - goto load_doc; - } - } -#endif /* defined(AUTH_DEBUG) */ - t = checkContentType(t_buf); - if (t == NULL) - t = "text/plain"; - } - else if (DefaultType) { - t = DefaultType; - DefaultType = NULL; - } - else { - t = guessContentType(pu.file); - if (t == NULL) - t = "text/plain"; - real_type = t; - if (f.guess_type) - t = f.guess_type; - } - - page_loaded: - if (page) { - FILE *src; -#ifdef USE_IMAGE - if (image_source) - return NULL; -#endif - tmp = tmpfname(TMPF_SRC, ".html"); - src = fopen(tmp->ptr, "w"); - if (src) { - Str s; - s = wc_Str_conv_strict(page, InnerCharset, charset); - Strfputs(s, src); - fclose(src); - } - if (do_download) { - char *file; - if (!src) - return NULL; - file = guess_filename(pu.file); -#ifdef USE_GOPHER - if (f.scheme == SCM_GOPHER) - file = Sprintf("%s.html", file)->ptr; -#endif -#ifdef USE_NNTP - if (f.scheme == SCM_NEWS_GROUP) - file = Sprintf("%s.html", file)->ptr; -#endif - doFileMove(tmp->ptr, file); - return NO_BUFFER; - } - b = loadHTMLString(page); - if (b) { - copyParsedURL(&b->currentURL, &pu); - b->real_scheme = pu.scheme; - b->real_type = t; - if (src) - b->sourcefile = tmp->ptr; -#ifdef USE_M17N - b->document_charset = charset; -#endif - } - return b; - } - - if (real_type == NULL) - real_type = t; - proc = loadBuffer; -#ifdef USE_IMAGE - cur_baseURL = New(ParsedURL); - copyParsedURL(cur_baseURL, &pu); -#endif - - current_content_length = 0; - if ((p = checkHeader(t_buf, "Content-Length:")) != NULL) - current_content_length = strtoclen(p); - if (do_download) { - /* download only */ - char *file; - TRAP_OFF; - if (DecodeCTE && IStype(f.stream) != IST_ENCODED) - f.stream = newEncodedStream(f.stream, f.encoding); - if (pu.scheme == SCM_LOCAL) { - struct stat st; - if (PreserveTimestamp && !stat(pu.real_file, &st)) - f.modtime = st.st_mtime; - file = conv_from_system(guess_save_name(NULL, pu.real_file)); - } - else - file = guess_save_name(t_buf, pu.file); - if (doFileSave(f, file) == 0) - UFhalfclose(&f); - else - UFclose(&f); - return NO_BUFFER; - } - - if (f.content_encoding != CMP_NOCOMPRESS) { - uncompress_stream(&f, &pu.real_file); - } - else if (f.compression != CMP_NOCOMPRESS) { - if (!(w3m_dump & DUMP_SOURCE) && - (w3m_dump & ~DUMP_FRAME || is_text_type(t) - || searchExtViewer(t))) { - if (t_buf == NULL) - t_buf = newBuffer(INIT_BUFFER_WIDTH); - uncompress_stream(&f, &t_buf->sourcefile); - uncompressed_file_type(pu.file, &f.ext); - } - else { - t = compress_application_type(f.compression); - f.compression = CMP_NOCOMPRESS; - } - } -#ifdef USE_IMAGE - if (image_source) { - Buffer *b = NULL; - if (IStype(f.stream) != IST_ENCODED) - f.stream = newEncodedStream(f.stream, f.encoding); - if (save2tmp(f, image_source) == 0) { - b = newBuffer(INIT_BUFFER_WIDTH); - b->sourcefile = image_source; - b->real_type = t; - } - UFclose(&f); - TRAP_OFF; - return b; - } -#endif - - if (!strcasecmp(t, "text/html")) - proc = loadHTMLBuffer; - else if (is_plain_text_type(t)) - proc = loadBuffer; -#ifdef USE_IMAGE - else if (activeImage && displayImage && !useExtImageViewer && - !(w3m_dump & ~DUMP_FRAME) && !strncasecmp(t, "image/", 6)) - proc = loadImageBuffer; -#endif - else if (w3m_backend) ; - else if (!(w3m_dump & ~DUMP_FRAME) || is_dump_text_type(t)) { - if (!do_download && doExternal(f, - pu.real_file ? pu.real_file : pu.file, - t, &b, t_buf)) { - if (b && b != NO_BUFFER) { - b->real_scheme = f.scheme; - b->real_type = real_type; - if (b->currentURL.host == NULL && b->currentURL.file == NULL) - copyParsedURL(&b->currentURL, &pu); - } - UFclose(&f); - TRAP_OFF; - return b; - } - else { - TRAP_OFF; - if (pu.scheme == SCM_LOCAL) { - UFclose(&f); - _doFileCopy(pu.real_file, - conv_from_system(guess_save_name - (NULL, pu.real_file)), TRUE); - } - else { - if (DecodeCTE && IStype(f.stream) != IST_ENCODED) - f.stream = newEncodedStream(f.stream, f.encoding); - if (doFileSave(f, guess_save_name(t_buf, pu.file)) == 0) - UFhalfclose(&f); - else - UFclose(&f); - } - return NO_BUFFER; - } - } - else if (w3m_dump & DUMP_FRAME) - return NULL; - - if (flag & RG_FRAME) { - if (t_buf == NULL) - t_buf = newBuffer(INIT_BUFFER_WIDTH); - t_buf->bufferprop |= BP_FRAME; - } -#ifdef USE_SSL - if (t_buf) - t_buf->ssl_certificate = f.ssl_certificate; -#endif - frame_source = flag & RG_FRAME_SRC; - b = loadSomething(&f, pu.real_file ? pu.real_file : pu.file, proc, t_buf); - UFclose(&f); - frame_source = 0; - if (b) { - b->real_scheme = f.scheme; - b->real_type = real_type; - if (b->currentURL.host == NULL && b->currentURL.file == NULL) - copyParsedURL(&b->currentURL, &pu); - if (!strcasecmp(t, "text/html")) - b->type = "text/html"; - else if (w3m_backend) { - Str s = Strnew_charp(t); - b->type = s->ptr; - } -#ifdef USE_IMAGE - else if (proc == loadImageBuffer) - b->type = "text/html"; -#endif - else - b->type = "text/plain"; - if (pu.label) { - if (proc == loadHTMLBuffer) { - Anchor *a; - a = searchURLLabel(b, pu.label); - if (a != NULL) { - gotoLine(b, a->start.line); - if (label_topline) - b->topLine = lineSkip(b, b->topLine, - b->currentLine->linenumber - - b->topLine->linenumber, FALSE); - b->pos = a->start.pos; - arrangeCursor(b); - } - } - else { /* plain text */ - int l = atoi(pu.label); - gotoLine(b, l); - b->pos = 0; - arrangeCursor(b); - } - } - } - if (header_string) - header_string = NULL; -#ifdef USE_NNTP - if (f.scheme == SCM_NNTP || f.scheme == SCM_NEWS) - reAnchorNewsheader(b); -#endif - preFormUpdateBuffer(b); - TRAP_OFF; - return b; -} - -#define TAG_IS(s,tag,len)\ - (strncasecmp(s,tag,len)==0&&(s[len] == '>' || IS_SPACE((int)s[len]))) - -static char * -has_hidden_link(struct readbuffer *obuf, int cmd) -{ - Str line = obuf->line; - struct link_stack *p; - - if (Strlastchar(line) != '>') - return NULL; - - for (p = link_stack; p; p = p->next) - if (p->cmd == cmd) - break; - if (!p) - return NULL; - - if (obuf->pos == p->pos) - return line->ptr + p->offset; - - return NULL; -} - -static void -push_link(int cmd, int offset, int pos) -{ - struct link_stack *p; - p = New(struct link_stack); - p->cmd = cmd; - p->offset = offset; - p->pos = pos; - p->next = link_stack; - link_stack = p; -} - -static int -is_period_char(unsigned char *ch) -{ - switch (*ch) { - case ',': - case '.': - case ':': - case ';': - case '?': - case '!': - case ')': - case ']': - case '}': - case '>': - return 1; - default: - return 0; - } -} - -static int -is_beginning_char(unsigned char *ch) -{ - switch (*ch) { - case '(': - case '[': - case '{': - case '`': - case '<': - return 1; - default: - return 0; - } -} - -static int -is_word_char(unsigned char *ch) -{ - Lineprop ctype = get_mctype(ch); - -#ifdef USE_M17N - if (ctype & (PC_CTRL | PC_KANJI | PC_UNKNOWN)) - return 0; - if (ctype & (PC_WCHAR1 | PC_WCHAR2)) - return 1; -#else - if (ctype == PC_CTRL) - return 0; -#endif - - if (IS_ALNUM(*ch)) - return 1; - - switch (*ch) { - case ',': - case '.': - case ':': - case '\"': /* " */ - case '\'': - case '$': - case '%': - case '*': - case '+': - case '-': - case '@': - case '~': - case '_': - return 1; - } -#ifdef USE_M17N - if (*ch == NBSP_CODE) - return 1; -#else - if (*ch == TIMES_CODE || *ch == DIVIDE_CODE || *ch == ANSP_CODE) - return 0; - if (*ch >= AGRAVE_CODE || *ch == NBSP_CODE) - return 1; -#endif - return 0; -} - -#ifdef USE_M17N -static int -is_combining_char(unsigned char *ch) -{ - Lineprop ctype = get_mctype(ch); - - if (ctype & PC_WCHAR2) - return 1; - return 0; -} -#endif - -int -is_boundary(unsigned char *ch1, unsigned char *ch2) -{ - if (!*ch1 || !*ch2) - return 1; - - if (*ch1 == ' ' && *ch2 == ' ') - return 0; - - if (*ch1 != ' ' && is_period_char(ch2)) - return 0; - - if (*ch2 != ' ' && is_beginning_char(ch1)) - return 0; - -#ifdef USE_M17N - if (is_combining_char(ch2)) - return 0; -#endif - if (is_word_char(ch1) && is_word_char(ch2)) - return 0; - - return 1; -} - - -static void -set_breakpoint(struct readbuffer *obuf, int tag_length) -{ - obuf->bp.len = obuf->line->length; - obuf->bp.pos = obuf->pos; - obuf->bp.tlen = tag_length; - obuf->bp.flag = obuf->flag; -#ifdef FORMAT_NICE - obuf->bp.flag &= ~RB_FILL; -#endif /* FORMAT_NICE */ - obuf->bp.top_margin = obuf->top_margin; - obuf->bp.bottom_margin = obuf->bottom_margin; - - if (!obuf->bp.init_flag) - return; - - bcopy((void *)&obuf->anchor, (void *)&obuf->bp.anchor, - sizeof(obuf->anchor)); - obuf->bp.img_alt = obuf->img_alt; - obuf->bp.in_bold = obuf->in_bold; - obuf->bp.in_under = obuf->in_under; - obuf->bp.nobr_level = obuf->nobr_level; - obuf->bp.prev_ctype = obuf->prev_ctype; - obuf->bp.init_flag = 0; -} - -static void -back_to_breakpoint(struct readbuffer *obuf) -{ - obuf->flag = obuf->bp.flag; - bcopy((void *)&obuf->bp.anchor, (void *)&obuf->anchor, - sizeof(obuf->anchor)); - obuf->img_alt = obuf->bp.img_alt; - obuf->in_bold = obuf->bp.in_bold; - obuf->in_under = obuf->bp.in_under; - obuf->prev_ctype = obuf->bp.prev_ctype; - obuf->pos = obuf->bp.pos; - obuf->top_margin = obuf->bp.top_margin; - obuf->bottom_margin = obuf->bp.bottom_margin; - if (obuf->flag & RB_NOBR) - obuf->nobr_level = obuf->bp.nobr_level; -} - -static void -append_tags(struct readbuffer *obuf) -{ - int i; - int len = obuf->line->length; - int set_bp = 0; - - for (i = 0; i < obuf->tag_sp; i++) { - switch (obuf->tag_stack[i]->cmd) { - case HTML_A: - case HTML_IMG_ALT: - case HTML_B: - case HTML_U: - push_link(obuf->tag_stack[i]->cmd, obuf->line->length, obuf->pos); - break; - } - Strcat_charp(obuf->line, obuf->tag_stack[i]->cmdname); - switch (obuf->tag_stack[i]->cmd) { - case HTML_NOBR: - if (obuf->nobr_level > 1) - break; - case HTML_WBR: - set_bp = 1; - break; - } - } - obuf->tag_sp = 0; - if (set_bp) - set_breakpoint(obuf, obuf->line->length - len); -} - -static void -push_tag(struct readbuffer *obuf, char *cmdname, int cmd) -{ - obuf->tag_stack[obuf->tag_sp] = New(struct cmdtable); - obuf->tag_stack[obuf->tag_sp]->cmdname = allocStr(cmdname, -1); - obuf->tag_stack[obuf->tag_sp]->cmd = cmd; - obuf->tag_sp++; - if (obuf->tag_sp >= TAG_STACK_SIZE || obuf->flag & (RB_SPECIAL & ~RB_NOBR)) - append_tags(obuf); -} - -static void -push_nchars(struct readbuffer *obuf, int width, - char *str, int len, Lineprop mode) -{ - append_tags(obuf); - Strcat_charp_n(obuf->line, str, len); - obuf->pos += width; - if (width > 0) { - set_prevchar(obuf->prevchar, str, len); - obuf->prev_ctype = mode; - } - obuf->flag |= RB_NFLUSHED; -} - -#define push_charp(obuf, width, str, mode)\ -push_nchars(obuf, width, str, strlen(str), mode) - -#define push_str(obuf, width, str, mode)\ -push_nchars(obuf, width, str->ptr, str->length, mode) - -static void -check_breakpoint(struct readbuffer *obuf, int pre_mode, char *ch) -{ - int tlen, len = obuf->line->length; - - append_tags(obuf); - if (pre_mode) - return; - tlen = obuf->line->length - len; - if (tlen > 0 - || is_boundary((unsigned char *)obuf->prevchar->ptr, - (unsigned char *)ch)) - set_breakpoint(obuf, tlen); -} - -static void -push_char(struct readbuffer *obuf, int pre_mode, char ch) -{ - check_breakpoint(obuf, pre_mode, &ch); - Strcat_char(obuf->line, ch); - obuf->pos++; - set_prevchar(obuf->prevchar, &ch, 1); - if (ch != ' ') - obuf->prev_ctype = PC_ASCII; - obuf->flag |= RB_NFLUSHED; -} - -#define PUSH(c) push_char(obuf, obuf->flag & RB_SPECIAL, c) - -static void -push_spaces(struct readbuffer *obuf, int pre_mode, int width) -{ - int i; - - if (width <= 0) - return; - check_breakpoint(obuf, pre_mode, " "); - for (i = 0; i < width; i++) - Strcat_char(obuf->line, ' '); - obuf->pos += width; - set_space_to_prevchar(obuf->prevchar); - obuf->flag |= RB_NFLUSHED; -} - -static void -proc_mchar(struct readbuffer *obuf, int pre_mode, - int width, char **str, Lineprop mode) -{ - check_breakpoint(obuf, pre_mode, *str); - obuf->pos += width; - Strcat_charp_n(obuf->line, *str, get_mclen(*str)); - if (width > 0) { - set_prevchar(obuf->prevchar, *str, 1); - if (**str != ' ') - obuf->prev_ctype = mode; - } - (*str) += get_mclen(*str); - obuf->flag |= RB_NFLUSHED; -} - -void -push_render_image(Str str, int width, int limit, - struct html_feed_environ *h_env) -{ - struct readbuffer *obuf = h_env->obuf; - int indent = h_env->envs[h_env->envc].indent; - - push_spaces(obuf, 1, (limit - width) / 2); - push_str(obuf, width, str, PC_ASCII); - push_spaces(obuf, 1, (limit - width + 1) / 2); - if (width > 0) - flushline(h_env, obuf, indent, 0, h_env->limit); -} - -static int -sloppy_parse_line(char **str) -{ - if (**str == '<') { - while (**str && **str != '>') - (*str)++; - if (**str == '>') - (*str)++; - return 1; - } - else { - while (**str && **str != '<') - (*str)++; - return 0; - } -} - -static void -passthrough(struct readbuffer *obuf, char *str, int back) -{ - int cmd; - Str tok = Strnew(); - char *str_bak; - - if (back) { - Str str_save = Strnew_charp(str); - Strshrink(obuf->line, obuf->line->ptr + obuf->line->length - str); - str = str_save->ptr; - } - while (*str) { - str_bak = str; - if (sloppy_parse_line(&str)) { - char *q = str_bak; - cmd = gethtmlcmd(&q); - if (back) { - struct link_stack *p; - for (p = link_stack; p; p = p->next) { - if (p->cmd == cmd) { - link_stack = p->next; - break; - } - } - back = 0; - } - else { - Strcat_charp_n(tok, str_bak, str - str_bak); - push_tag(obuf, tok->ptr, cmd); - Strclear(tok); - } - } - else { - push_nchars(obuf, 0, str_bak, str - str_bak, obuf->prev_ctype); - } - } -} - -#if 0 -int -is_blank_line(char *line, int indent) -{ - int i, is_blank = 0; - - for (i = 0; i < indent; i++) { - if (line[i] == '\0') { - is_blank = 1; - } - else if (line[i] != ' ') { - break; - } - } - if (i == indent && line[i] == '\0') - is_blank = 1; - return is_blank; -} -#endif - -void -fillline(struct readbuffer *obuf, int indent) -{ - push_spaces(obuf, 1, indent - obuf->pos); - obuf->flag &= ~RB_NFLUSHED; -} - -void -flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, - int force, int width) -{ - TextLineList *buf = h_env->buf; - FILE *f = h_env->f; - Str line = obuf->line, pass = NULL; - char *hidden_anchor = NULL, *hidden_img = NULL, *hidden_bold = NULL, - *hidden_under = NULL, *hidden = NULL; - -#ifdef DEBUG - if (w3m_debug) { - FILE *df = fopen("zzzproc1", "a"); - fprintf(df, "flushline(%s,%d,%d,%d)\n", obuf->line->ptr, indent, force, - width); - if (buf) { - TextLineListItem *p; - for (p = buf->first; p; p = p->next) { - fprintf(df, "buf=\"%s\"\n", p->ptr->line->ptr); - } - } - fclose(df); - } -#endif - - if (!(obuf->flag & (RB_SPECIAL & ~RB_NOBR)) && Strlastchar(line) == ' ') { - Strshrink(line, 1); - obuf->pos--; - } - - append_tags(obuf); - - if (obuf->anchor.url) - hidden = hidden_anchor = has_hidden_link(obuf, HTML_A); - if (obuf->img_alt) { - if ((hidden_img = has_hidden_link(obuf, HTML_IMG_ALT)) != NULL) { - if (!hidden || hidden_img < hidden) - hidden = hidden_img; - } - } - if (obuf->in_bold) { - if ((hidden_bold = has_hidden_link(obuf, HTML_B)) != NULL) { - if (!hidden || hidden_bold < hidden) - hidden = hidden_bold; - } - } - if (obuf->in_under) { - if ((hidden_under = has_hidden_link(obuf, HTML_U)) != NULL) { - if (!hidden || hidden_under < hidden) - hidden = hidden_under; - } - } - if (hidden) { - pass = Strnew_charp(hidden); - Strshrink(line, line->ptr + line->length - hidden); - } - - if (!(obuf->flag & (RB_SPECIAL & ~RB_NOBR)) && obuf->pos > width) { - char *tp = &line->ptr[obuf->bp.len - obuf->bp.tlen]; - char *ep = &line->ptr[line->length]; - - if (obuf->bp.pos == obuf->pos && tp <= ep && - tp > line->ptr && tp[-1] == ' ') { - bcopy(tp, tp - 1, ep - tp + 1); - line->length--; - obuf->pos--; - } - } - - if (obuf->anchor.url && !hidden_anchor) - Strcat_charp(line, "</a>"); - if (obuf->img_alt && !hidden_img) - Strcat_charp(line, "</img_alt>"); - if (obuf->in_bold && !hidden_bold) - Strcat_charp(line, "</b>"); - if (obuf->in_under && !hidden_under) - Strcat_charp(line, "</u>"); - - if (obuf->top_margin > 0) { - int i; - struct html_feed_environ h; - struct readbuffer o; - struct environment e[1]; - - init_henv(&h, &o, e, 1, NULL, width, indent); - o.line = Strnew_size(width + 20); - o.pos = obuf->pos; - o.flag = obuf->flag; - o.top_margin = -1; - o.bottom_margin = -1; - Strcat_charp(o.line, "<pre_int>"); - for (i = 0; i < o.pos; i++) - Strcat_char(o.line, ' '); - Strcat_charp(o.line, "</pre_int>"); - for (i = 0; i < obuf->top_margin; i++) - flushline(h_env, &o, indent, force, width); - } - - if (force == 1 || obuf->flag & RB_NFLUSHED) { - TextLine *lbuf = newTextLine(line, obuf->pos); - if (RB_GET_ALIGN(obuf) == RB_CENTER) { - align(lbuf, width, ALIGN_CENTER); - } - else if (RB_GET_ALIGN(obuf) == RB_RIGHT) { - align(lbuf, width, ALIGN_RIGHT); - } - else if (RB_GET_ALIGN(obuf) == RB_LEFT && obuf->flag & RB_INTABLE) { - align(lbuf, width, ALIGN_LEFT); - } -#ifdef FORMAT_NICE - else if (obuf->flag & RB_FILL) { - char *p; - int rest, rrest; - int nspace, d, i; - - rest = width - get_Str_strwidth(line); - if (rest > 1) { - nspace = 0; - for (p = line->ptr + indent; *p; p++) { - if (*p == ' ') - nspace++; - } - if (nspace > 0) { - int indent_here = 0; - d = rest / nspace; - p = line->ptr; - while (IS_SPACE(*p)) { - p++; - indent_here++; - } - rrest = rest - d * nspace; - line = Strnew_size(width + 1); - for (i = 0; i < indent_here; i++) - Strcat_char(line, ' '); - for (; *p; p++) { - Strcat_char(line, *p); - if (*p == ' ') { - for (i = 0; i < d; i++) - Strcat_char(line, ' '); - if (rrest > 0) { - Strcat_char(line, ' '); - rrest--; - } - } - } - lbuf = newTextLine(line, width); - } - } - } -#endif /* FORMAT_NICE */ -#ifdef TABLE_DEBUG - if (w3m_debug) { - FILE *f = fopen("zzzproc1", "a"); - fprintf(f, "pos=%d,%d, maxlimit=%d\n", - visible_length(lbuf->line->ptr), lbuf->pos, - h_env->maxlimit); - fclose(f); - } -#endif - if (lbuf->pos > h_env->maxlimit) - h_env->maxlimit = lbuf->pos; - if (buf) - pushTextLine(buf, lbuf); - else if (f) { - Strfputs(Str_conv_to_halfdump(lbuf->line), f); - fputc('\n', f); - } - if (obuf->flag & RB_SPECIAL || obuf->flag & RB_NFLUSHED) - h_env->blank_lines = 0; - else - h_env->blank_lines++; - } - else { - char *p = line->ptr, *q; - Str tmp = Strnew(), tmp2 = Strnew(); - -#define APPEND(str) \ - if (buf) \ - appendTextLine(buf,(str),0); \ - else if (f) \ - Strfputs((str),f) - - while (*p) { - q = p; - if (sloppy_parse_line(&p)) { - Strcat_charp_n(tmp, q, p - q); - if (force == 2) { - APPEND(tmp); - } - else - Strcat(tmp2, tmp); - Strclear(tmp); - } - } - if (force == 2) { - if (pass) { - APPEND(pass); - } - pass = NULL; - } - else { - if (pass) - Strcat(tmp2, pass); - pass = tmp2; - } - } - - if (obuf->bottom_margin > 0) { - int i; - struct html_feed_environ h; - struct readbuffer o; - struct environment e[1]; - - init_henv(&h, &o, e, 1, NULL, width, indent); - o.line = Strnew_size(width + 20); - o.pos = obuf->pos; - o.flag = obuf->flag; - o.top_margin = -1; - o.bottom_margin = -1; - Strcat_charp(o.line, "<pre_int>"); - for (i = 0; i < o.pos; i++) - Strcat_char(o.line, ' '); - Strcat_charp(o.line, "</pre_int>"); - for (i = 0; i < obuf->bottom_margin; i++) - flushline(h_env, &o, indent, force, width); - } - if (obuf->top_margin < 0 || obuf->bottom_margin < 0) - return; - - obuf->line = Strnew_size(256); - obuf->pos = 0; - obuf->top_margin = 0; - obuf->bottom_margin = 0; - set_space_to_prevchar(obuf->prevchar); - obuf->bp.init_flag = 1; - obuf->flag &= ~RB_NFLUSHED; - set_breakpoint(obuf, 0); - obuf->prev_ctype = PC_ASCII; - link_stack = NULL; - fillline(obuf, indent); - if (pass) - passthrough(obuf, pass->ptr, 0); - if (!hidden_anchor && obuf->anchor.url) { - Str tmp; - if (obuf->anchor.hseq > 0) - obuf->anchor.hseq = -obuf->anchor.hseq; - tmp = Sprintf("<A HSEQ=\"%d\" HREF=\"", obuf->anchor.hseq); - Strcat_charp(tmp, html_quote(obuf->anchor.url)); - if (obuf->anchor.target) { - Strcat_charp(tmp, "\" TARGET=\""); - Strcat_charp(tmp, html_quote(obuf->anchor.target)); - } - if (obuf->anchor.referer) { - Strcat_charp(tmp, "\" REFERER=\""); - Strcat_charp(tmp, html_quote(obuf->anchor.referer)); - } - if (obuf->anchor.title) { - Strcat_charp(tmp, "\" TITLE=\""); - Strcat_charp(tmp, html_quote(obuf->anchor.title)); - } - if (obuf->anchor.accesskey) { - char *c = html_quote_char(obuf->anchor.accesskey); - Strcat_charp(tmp, "\" ACCESSKEY=\""); - if (c) - Strcat_charp(tmp, c); - else - Strcat_char(tmp, obuf->anchor.accesskey); - } - Strcat_charp(tmp, "\">"); - push_tag(obuf, tmp->ptr, HTML_A); - } - if (!hidden_img && obuf->img_alt) { - Str tmp = Strnew_charp("<IMG_ALT SRC=\""); - Strcat_charp(tmp, html_quote(obuf->img_alt->ptr)); - Strcat_charp(tmp, "\">"); - push_tag(obuf, tmp->ptr, HTML_IMG_ALT); - } - if (!hidden_bold && obuf->in_bold) - push_tag(obuf, "<B>", HTML_B); - if (!hidden_under && obuf->in_under) - push_tag(obuf, "<U>", HTML_U); -} - -void -do_blankline(struct html_feed_environ *h_env, struct readbuffer *obuf, - int indent, int indent_incr, int width) -{ - if (h_env->blank_lines == 0) - flushline(h_env, obuf, indent, 1, width); -} - -void -purgeline(struct html_feed_environ *h_env) -{ - char *p, *q; - Str tmp; - - if (h_env->buf == NULL || h_env->blank_lines == 0) - return; - - p = rpopTextLine(h_env->buf)->line->ptr; - tmp = Strnew(); - while (*p) { - q = p; - if (sloppy_parse_line(&p)) { - Strcat_charp_n(tmp, q, p - q); - } - } - appendTextLine(h_env->buf, tmp, 0); - h_env->blank_lines--; -} - -static int -close_effect0(struct readbuffer *obuf, int cmd) -{ - int i; - char *p; - - for (i = obuf->tag_sp - 1; i >= 0; i--) { - if (obuf->tag_stack[i]->cmd == cmd) - break; - } - if (i >= 0) { - obuf->tag_sp--; - bcopy(&obuf->tag_stack[i + 1], &obuf->tag_stack[i], - (obuf->tag_sp - i) * sizeof(struct cmdtable *)); - return 1; - } - else if ((p = has_hidden_link(obuf, cmd)) != NULL) { - passthrough(obuf, p, 1); - return 1; - } - return 0; -} - -static void -close_anchor(struct html_feed_environ *h_env, struct readbuffer *obuf) -{ - if (obuf->anchor.url) { - int i; - char *p = NULL; - int is_erased = 0; - - for (i = obuf->tag_sp - 1; i >= 0; i--) { - if (obuf->tag_stack[i]->cmd == HTML_A) - break; - } - if (i < 0 && obuf->anchor.hseq > 0 && Strlastchar(obuf->line) == ' ') { - Strshrink(obuf->line, 1); - obuf->pos--; - is_erased = 1; - } - - if (i >= 0 || (p = has_hidden_link(obuf, HTML_A))) { - if (obuf->anchor.hseq > 0) { - HTMLlineproc1(ANSP, h_env); - set_space_to_prevchar(obuf->prevchar); - } - else { - if (i >= 0) { - obuf->tag_sp--; - bcopy(&obuf->tag_stack[i + 1], &obuf->tag_stack[i], - (obuf->tag_sp - i) * sizeof(struct cmdtable *)); - } - else { - passthrough(obuf, p, 1); - } - bzero((void *)&obuf->anchor, sizeof(obuf->anchor)); - return; - } - is_erased = 0; - } - if (is_erased) { - Strcat_char(obuf->line, ' '); - obuf->pos++; - } - - push_tag(obuf, "</a>", HTML_N_A); - } - bzero((void *)&obuf->anchor, sizeof(obuf->anchor)); -} - -void -save_fonteffect(struct html_feed_environ *h_env, struct readbuffer *obuf) -{ - if (obuf->fontstat_sp < FONT_STACK_SIZE) - bcopy(obuf->fontstat, obuf->fontstat_stack[obuf->fontstat_sp], - FONTSTAT_SIZE); - obuf->fontstat_sp++; - if (obuf->in_bold) - push_tag(obuf, "</b>", HTML_N_B); - if (obuf->in_under) - push_tag(obuf, "</u>", HTML_N_U); - bzero(obuf->fontstat, FONTSTAT_SIZE); -} - -void -restore_fonteffect(struct html_feed_environ *h_env, struct readbuffer *obuf) -{ - if (obuf->fontstat_sp > 0) - obuf->fontstat_sp--; - if (obuf->fontstat_sp < FONT_STACK_SIZE) - bcopy(obuf->fontstat_stack[obuf->fontstat_sp], obuf->fontstat, - FONTSTAT_SIZE); - if (obuf->in_bold) - push_tag(obuf, "<b>", HTML_B); - if (obuf->in_under) - push_tag(obuf, "<u>", HTML_U); -} - -static Str -process_title(struct parsed_tag *tag) -{ - cur_title = Strnew(); - return NULL; -} - -static Str -process_n_title(struct parsed_tag *tag) -{ - Str tmp; - - if (!cur_title) - return NULL; - Strremovefirstspaces(cur_title); - Strremovetrailingspaces(cur_title); - tmp = Strnew_m_charp("<title_alt title=\"", - html_quote(cur_title->ptr), "\">", NULL); - cur_title = NULL; - return tmp; -} - -static void -feed_title(char *str) -{ - if (!cur_title) - return; - while (*str) { - if (*str == '&') - Strcat_charp(cur_title, getescapecmd(&str)); - else if (*str == '\n' || *str == '\r') { - Strcat_char(cur_title, ' '); - str++; - } - else - Strcat_char(cur_title, *(str++)); - } -} - -Str -process_img(struct parsed_tag *tag, int width) -{ - char *p, *q, *r, *r2 = NULL, *s, *t; -#ifdef USE_IMAGE - int w, i, nw, ni = 1, n, w0 = -1, i0 = -1; - int align, xoffset, yoffset, top, bottom, ismap = 0; - int use_image = activeImage && displayImage; -#else - int w, i, nw, n; -#endif - int pre_int = FALSE; - Str tmp = Strnew(); - - if (!parsedtag_get_value(tag, ATTR_SRC, &p)) - return tmp; - p = remove_space(p); - q = NULL; - parsedtag_get_value(tag, ATTR_ALT, &q); - t = q; - parsedtag_get_value(tag, ATTR_TITLE, &t); - w = -1; - if (parsedtag_get_value(tag, ATTR_WIDTH, &w)) { - if (w < 0) { - if (width > 0) - w = (int)(-width * pixel_per_char * w / 100 + 0.5); - else - w = -1; - } -#ifdef USE_IMAGE - if (use_image) { - if (w > 0) { - w = (int)(w * image_scale / 100 + 0.5); - if (w == 0) - w = 1; - else if (w > MAX_IMAGE_SIZE) - w = MAX_IMAGE_SIZE; - } - } -#endif - } -#ifdef USE_IMAGE - if (use_image) { - i = -1; - if (parsedtag_get_value(tag, ATTR_HEIGHT, &i)) { - if (i > 0) { - i = (int)(i * image_scale / 100 + 0.5); - if (i == 0) - i = 1; - else if (i > MAX_IMAGE_SIZE) - i = MAX_IMAGE_SIZE; - } - else { - i = -1; - } - } - align = -1; - parsedtag_get_value(tag, ATTR_ALIGN, &align); - ismap = 0; - if (parsedtag_exists(tag, ATTR_ISMAP)) - ismap = 1; - } - else -#endif - parsedtag_get_value(tag, ATTR_HEIGHT, &i); - r = NULL; - parsedtag_get_value(tag, ATTR_USEMAP, &r); - - tmp = Strnew_size(128); -#ifdef USE_IMAGE - if (use_image) { - switch (align) { - case ALIGN_LEFT: - Strcat_charp(tmp, "<div_int align=left>"); - break; - case ALIGN_CENTER: - Strcat_charp(tmp, "<div_int align=center>"); - break; - case ALIGN_RIGHT: - Strcat_charp(tmp, "<div_int align=right>"); - break; - } - } -#endif - if (r) { - Str tmp2; - r2 = strchr(r, '#'); - s = "<form_int method=internal action=map>"; - tmp2 = process_form(parse_tag(&s, TRUE)); - if (tmp2) - Strcat(tmp, tmp2); - Strcat(tmp, Sprintf("<input_alt fid=\"%d\" " - "type=hidden name=link value=\"", cur_form_id)); - Strcat_charp(tmp, html_quote((r2) ? r2 + 1 : r)); - Strcat(tmp, Sprintf("\"><input_alt hseq=\"%d\" fid=\"%d\" " - "type=submit no_effect=true>", - cur_hseq++, cur_form_id)); - } -#ifdef USE_IMAGE - if (use_image) { - w0 = w; - i0 = i; - if (w < 0 || i < 0) { - Image image; - ParsedURL u; - -#ifdef USE_M17N - parseURL2(wc_conv(p, InnerCharset, cur_document_charset)->ptr, &u, - cur_baseURL); -#else - parseURL2(p, &u, cur_baseURL); -#endif - image.url = parsedURL2Str(&u)->ptr; - if (!uncompressed_file_type(u.file, &image.ext)) - image.ext = filename_extension(u.file, TRUE); - image.cache = NULL; - image.width = w; - image.height = i; - - image.cache = getImage(&image, cur_baseURL, IMG_FLAG_SKIP); - if (image.cache && image.cache->width > 0 && - image.cache->height > 0) { - w = w0 = image.cache->width; - i = i0 = image.cache->height; - } - if (w < 0) - w = 8 * pixel_per_char; - if (i < 0) - i = pixel_per_line; - } - nw = (w > 3) ? (int)((w - 3) / pixel_per_char + 1) : 1; - ni = (i > 3) ? (int)((i - 3) / pixel_per_line + 1) : 1; - Strcat(tmp, - Sprintf("<pre_int><img_alt hseq=\"%d\" src=\"", cur_iseq++)); - pre_int = TRUE; - } - else -#endif - { - if (w < 0) - w = 12 * pixel_per_char; - nw = w ? (int)((w - 1) / pixel_per_char + 1) : 1; - if (r) { - Strcat_charp(tmp, "<pre_int>"); - pre_int = TRUE; - } - Strcat_charp(tmp, "<img_alt src=\""); - } - Strcat_charp(tmp, html_quote(p)); - Strcat_charp(tmp, "\""); - if (t) { - Strcat_charp(tmp, " title=\""); - Strcat_charp(tmp, html_quote(t)); - Strcat_charp(tmp, "\""); - } -#ifdef USE_IMAGE - if (use_image) { - if (w0 >= 0) - Strcat(tmp, Sprintf(" width=%d", w0)); - if (i0 >= 0) - Strcat(tmp, Sprintf(" height=%d", i0)); - switch (align) { - case ALIGN_TOP: - top = 0; - bottom = ni - 1; - yoffset = 0; - break; - case ALIGN_MIDDLE: - top = ni / 2; - bottom = top; - if (top * 2 == ni) - yoffset = (int)(((ni + 1) * pixel_per_line - i) / 2); - else - yoffset = (int)((ni * pixel_per_line - i) / 2); - break; - case ALIGN_BOTTOM: - top = ni - 1; - bottom = 0; - yoffset = (int)(ni * pixel_per_line - i); - break; - default: - top = ni - 1; - bottom = 0; - if (ni == 1 && ni * pixel_per_line > i) - yoffset = 0; - else { - yoffset = (int)(ni * pixel_per_line - i); - if (yoffset <= -2) - yoffset++; - } - break; - } - xoffset = (int)((nw * pixel_per_char - w) / 2); - if (xoffset) - Strcat(tmp, Sprintf(" xoffset=%d", xoffset)); - if (yoffset) - Strcat(tmp, Sprintf(" yoffset=%d", yoffset)); - if (top) - Strcat(tmp, Sprintf(" top_margin=%d", top)); - if (bottom) - Strcat(tmp, Sprintf(" bottom_margin=%d", bottom)); - if (r) { - Strcat_charp(tmp, " usemap=\""); - Strcat_charp(tmp, html_quote((r2) ? r2 + 1 : r)); - Strcat_charp(tmp, "\""); - } - if (ismap) - Strcat_charp(tmp, " ismap"); - } -#endif - Strcat_charp(tmp, ">"); - if (q != NULL && *q == '\0' && ignore_null_img_alt) - q = NULL; - if (q != NULL) { - n = get_strwidth(q); -#ifdef USE_IMAGE - if (use_image) { - if (n > nw) { - char *r; - for (r = q, n = 0; r; r += get_mclen(r), n += get_mcwidth(r)) { - if (n + get_mcwidth(r) > nw) - break; - } - Strcat_charp(tmp, html_quote(Strnew_charp_n(q, r - q)->ptr)); - } - else - Strcat_charp(tmp, html_quote(q)); - } - else -#endif - Strcat_charp(tmp, html_quote(q)); - goto img_end; - } - if (w > 0 && i > 0) { - /* guess what the image is! */ - if (w < 32 && i < 48) { - /* must be an icon or space */ - n = 1; - if (strcasestr(p, "space") || strcasestr(p, "blank")) - Strcat_charp(tmp, "_"); - else { - if (w * i < 8 * 16) - Strcat_charp(tmp, "*"); - else { - if (!pre_int) { - Strcat_charp(tmp, "<pre_int>"); - pre_int = TRUE; - } - push_symbol(tmp, IMG_SYMBOL, symbol_width, 1); - n = symbol_width; - } - } - goto img_end; - } - if (w > 200 && i < 13) { - /* must be a horizontal line */ - if (!pre_int) { - Strcat_charp(tmp, "<pre_int>"); - pre_int = TRUE; - } - w = w / pixel_per_char / symbol_width; - if (w <= 0) - w = 1; - push_symbol(tmp, HR_SYMBOL, symbol_width, w); - n = w * symbol_width; - goto img_end; - } - } - for (q = p; *q; q++) ; - while (q > p && *q != '/') - q--; - if (*q == '/') - q++; - Strcat_char(tmp, '['); - n = 1; - p = q; - for (; *q; q++) { - if (!IS_ALNUM(*q) && *q != '_' && *q != '-') { - break; - } - Strcat_char(tmp, *q); - n++; - if (n + 1 >= nw) - break; - } - Strcat_char(tmp, ']'); - n++; - img_end: -#ifdef USE_IMAGE - if (use_image) { - for (; n < nw; n++) - Strcat_char(tmp, ' '); - } -#endif - Strcat_charp(tmp, "</img_alt>"); - if (pre_int) - Strcat_charp(tmp, "</pre_int>"); - if (r) { - Strcat_charp(tmp, "</input_alt>"); - process_n_form(); - } -#ifdef USE_IMAGE - if (use_image) { - switch (align) { - case ALIGN_RIGHT: - case ALIGN_CENTER: - case ALIGN_LEFT: - Strcat_charp(tmp, "</div_int>"); - break; - } - } -#endif - return tmp; -} - -Str -process_anchor(struct parsed_tag *tag, char *tagbuf) -{ - if (parsedtag_need_reconstruct(tag)) { - parsedtag_set_value(tag, ATTR_HSEQ, Sprintf("%d", cur_hseq++)->ptr); - return parsedtag2str(tag); - } - else { - Str tmp = Sprintf("<a hseq=\"%d\"", cur_hseq++); - Strcat_charp(tmp, tagbuf + 2); - return tmp; - } -} - -Str -process_input(struct parsed_tag *tag) -{ - int i, w, v, x, y, z, iw, ih; - char *q, *p, *r, *p2, *s; - Str tmp = NULL; - char *qq = ""; - int qlen = 0; - - if (cur_form_id < 0) { - char *s = "<form_int method=internal action=none>"; - tmp = process_form(parse_tag(&s, TRUE)); - } - if (tmp == NULL) - tmp = Strnew(); - - p = "text"; - parsedtag_get_value(tag, ATTR_TYPE, &p); - q = NULL; - parsedtag_get_value(tag, ATTR_VALUE, &q); - r = ""; - parsedtag_get_value(tag, ATTR_NAME, &r); - w = 20; - parsedtag_get_value(tag, ATTR_SIZE, &w); - i = 20; - parsedtag_get_value(tag, ATTR_MAXLENGTH, &i); - p2 = NULL; - parsedtag_get_value(tag, ATTR_ALT, &p2); - x = parsedtag_exists(tag, ATTR_CHECKED); - y = parsedtag_exists(tag, ATTR_ACCEPT); - z = parsedtag_exists(tag, ATTR_READONLY); - - v = formtype(p); - if (v == FORM_UNKNOWN) - return NULL; - - if (!q) { - switch (v) { - case FORM_INPUT_IMAGE: - case FORM_INPUT_SUBMIT: - case FORM_INPUT_BUTTON: - q = "SUBMIT"; - break; - case FORM_INPUT_RESET: - q = "RESET"; - break; - /* if no VALUE attribute is specified in - * <INPUT TYPE=CHECKBOX> tag, then the value "on" is used - * as a default value. It is not a part of HTML4.0 - * specification, but an imitation of Netscape behaviour. - */ - case FORM_INPUT_CHECKBOX: - q = "on"; - } - } - /* VALUE attribute is not allowed in <INPUT TYPE=FILE> tag. */ - if (v == FORM_INPUT_FILE) - q = NULL; - if (q) { - qq = html_quote(q); - qlen = get_strwidth(q); - } - - Strcat_charp(tmp, "<pre_int>"); - switch (v) { - case FORM_INPUT_PASSWORD: - case FORM_INPUT_TEXT: - case FORM_INPUT_FILE: - case FORM_INPUT_CHECKBOX: - Strcat_char(tmp, '['); - break; - case FORM_INPUT_RADIO: - Strcat_char(tmp, '('); - } - Strcat(tmp, Sprintf("<input_alt hseq=\"%d\" fid=\"%d\" type=%s " - "name=\"%s\" width=%d maxlength=%d value=\"%s\"", - cur_hseq++, cur_form_id, p, html_quote(r), w, i, qq)); - if (x) - Strcat_charp(tmp, " checked"); - if (y) - Strcat_charp(tmp, " accept"); - if (z) - Strcat_charp(tmp, " readonly"); - Strcat_char(tmp, '>'); - - if (v == FORM_INPUT_HIDDEN) - Strcat_charp(tmp, "</input_alt></pre_int>"); - else { - switch (v) { - case FORM_INPUT_PASSWORD: - case FORM_INPUT_TEXT: - case FORM_INPUT_FILE: - Strcat_charp(tmp, "<u>"); - break; - case FORM_INPUT_IMAGE: - s = NULL; - parsedtag_get_value(tag, ATTR_SRC, &s); - if (s) { - Strcat(tmp, Sprintf("<img src=\"%s\"", html_quote(s))); - if (p2) - Strcat(tmp, Sprintf(" alt=\"%s\"", html_quote(p2))); - if (parsedtag_get_value(tag, ATTR_WIDTH, &iw)) - Strcat(tmp, Sprintf(" width=\"%d\"", iw)); - if (parsedtag_get_value(tag, ATTR_HEIGHT, &ih)) - Strcat(tmp, Sprintf(" height=\"%d\"", ih)); - Strcat_charp(tmp, ">"); - Strcat_charp(tmp, "</input_alt></pre_int>"); - return tmp; - } - case FORM_INPUT_SUBMIT: - case FORM_INPUT_BUTTON: - case FORM_INPUT_RESET: - Strcat_charp(tmp, "["); - break; - } - switch (v) { - case FORM_INPUT_PASSWORD: - i = 0; - if (q) { - for (; i < qlen && i < w; i++) - Strcat_char(tmp, '*'); - } - for (; i < w; i++) - Strcat_char(tmp, ' '); - break; - case FORM_INPUT_TEXT: - case FORM_INPUT_FILE: - if (q) - Strcat(tmp, textfieldrep(Strnew_charp(q), w)); - else { - for (i = 0; i < w; i++) - Strcat_char(tmp, ' '); - } - break; - case FORM_INPUT_SUBMIT: - case FORM_INPUT_BUTTON: - if (p2) - Strcat_charp(tmp, html_quote(p2)); - else - Strcat_charp(tmp, qq); - break; - case FORM_INPUT_RESET: - Strcat_charp(tmp, qq); - break; - case FORM_INPUT_RADIO: - case FORM_INPUT_CHECKBOX: - if (x) - Strcat_char(tmp, '*'); - else - Strcat_char(tmp, ' '); - break; - } - switch (v) { - case FORM_INPUT_PASSWORD: - case FORM_INPUT_TEXT: - case FORM_INPUT_FILE: - Strcat_charp(tmp, "</u>"); - break; - case FORM_INPUT_IMAGE: - case FORM_INPUT_SUBMIT: - case FORM_INPUT_BUTTON: - case FORM_INPUT_RESET: - Strcat_charp(tmp, "]"); - } - Strcat_charp(tmp, "</input_alt>"); - switch (v) { - case FORM_INPUT_PASSWORD: - case FORM_INPUT_TEXT: - case FORM_INPUT_FILE: - case FORM_INPUT_CHECKBOX: - Strcat_char(tmp, ']'); - break; - case FORM_INPUT_RADIO: - Strcat_char(tmp, ')'); - } - Strcat_charp(tmp, "</pre_int>"); - } - return tmp; -} - -Str -process_select(struct parsed_tag *tag) -{ - Str tmp = NULL; - char *p; - - if (cur_form_id < 0) { - char *s = "<form_int method=internal action=none>"; - tmp = process_form(parse_tag(&s, TRUE)); - } - - p = ""; - parsedtag_get_value(tag, ATTR_NAME, &p); - cur_select = Strnew_charp(p); - select_is_multiple = parsedtag_exists(tag, ATTR_MULTIPLE); - -#ifdef MENU_SELECT - if (!select_is_multiple) { - select_str = Sprintf("<pre_int>[<input_alt hseq=\"%d\" " - "fid=\"%d\" type=select name=\"%s\" selectnumber=%d", - cur_hseq++, cur_form_id, html_quote(p), n_select); - Strcat_charp(select_str, ">"); - if (n_select == max_select) { - max_select *= 2; - select_option = - New_Reuse(FormSelectOption, select_option, max_select); - } - select_option[n_select].first = NULL; - select_option[n_select].last = NULL; - cur_option_maxwidth = 0; - } - else -#endif /* MENU_SELECT */ - select_str = Strnew(); - cur_option = NULL; - cur_status = R_ST_NORMAL; - n_selectitem = 0; - return tmp; -} - -Str -process_n_select(void) -{ - if (cur_select == NULL) - return NULL; - process_option(); -#ifdef MENU_SELECT - if (!select_is_multiple) { - if (select_option[n_select].first) { - FormItemList sitem; - chooseSelectOption(&sitem, select_option[n_select].first); - Strcat(select_str, textfieldrep(sitem.label, cur_option_maxwidth)); - } - Strcat_charp(select_str, "</input_alt>]</pre_int>"); - n_select++; - } - else -#endif /* MENU_SELECT */ - Strcat_charp(select_str, "<br>"); - cur_select = NULL; - n_selectitem = 0; - return select_str; -} - -void -feed_select(char *str) -{ - Str tmp = Strnew(); - int prev_status = cur_status; - static int prev_spaces = -1; - char *p; - - if (cur_select == NULL) - return; - while (read_token(tmp, &str, &cur_status, 0, 0)) { - if (cur_status != R_ST_NORMAL || prev_status != R_ST_NORMAL) - continue; - p = tmp->ptr; - if (tmp->ptr[0] == '<' && Strlastchar(tmp) == '>') { - struct parsed_tag *tag; - char *q; - if (!(tag = parse_tag(&p, FALSE))) - continue; - switch (tag->tagid) { - case HTML_OPTION: - process_option(); - cur_option = Strnew(); - if (parsedtag_get_value(tag, ATTR_VALUE, &q)) - cur_option_value = Strnew_charp(q); - else - cur_option_value = NULL; - if (parsedtag_get_value(tag, ATTR_LABEL, &q)) - cur_option_label = Strnew_charp(q); - else - cur_option_label = NULL; - cur_option_selected = parsedtag_exists(tag, ATTR_SELECTED); - prev_spaces = -1; - break; - case HTML_N_OPTION: - /* do nothing */ - break; - default: - /* never happen */ - break; - } - } - else if (cur_option) { - while (*p) { - if (IS_SPACE(*p) && prev_spaces != 0) { - p++; - if (prev_spaces > 0) - prev_spaces++; - } - else { - if (IS_SPACE(*p)) - prev_spaces = 1; - else - prev_spaces = 0; - if (*p == '&') - Strcat_charp(cur_option, getescapecmd(&p)); - else - Strcat_char(cur_option, *(p++)); - } - } - } - } -} - -void -process_option(void) -{ - char begin_char = '[', end_char = ']'; - int len; - - if (cur_select == NULL || cur_option == NULL) - return; - while (cur_option->length > 0 && IS_SPACE(Strlastchar(cur_option))) - Strshrink(cur_option, 1); - if (cur_option_value == NULL) - cur_option_value = cur_option; - if (cur_option_label == NULL) - cur_option_label = cur_option; -#ifdef MENU_SELECT - if (!select_is_multiple) { - len = get_Str_strwidth(cur_option_label); - if (len > cur_option_maxwidth) - cur_option_maxwidth = len; - addSelectOption(&select_option[n_select], - cur_option_value, - cur_option_label, cur_option_selected); - return; - } -#endif /* MENU_SELECT */ - if (!select_is_multiple) { - begin_char = '('; - end_char = ')'; - } - Strcat(select_str, Sprintf("<br><pre_int>%c<input_alt hseq=\"%d\" " - "fid=\"%d\" type=%s name=\"%s\" value=\"%s\"", - begin_char, cur_hseq++, cur_form_id, - select_is_multiple ? "checkbox" : "radio", - html_quote(cur_select->ptr), - html_quote(cur_option_value->ptr))); - if (cur_option_selected) - Strcat_charp(select_str, " checked>*</input_alt>"); - else - Strcat_charp(select_str, "> </input_alt>"); - Strcat_char(select_str, end_char); - Strcat_charp(select_str, html_quote(cur_option_label->ptr)); - Strcat_charp(select_str, "</pre_int>"); - n_selectitem++; -} - -Str -process_textarea(struct parsed_tag *tag, int width) -{ - Str tmp = NULL; - char *p; - - if (cur_form_id < 0) { - char *s = "<form_int method=internal action=none>"; - tmp = process_form(parse_tag(&s, TRUE)); - } - - p = ""; - parsedtag_get_value(tag, ATTR_NAME, &p); - cur_textarea = Strnew_charp(p); - cur_textarea_size = 20; - if (parsedtag_get_value(tag, ATTR_COLS, &p)) { - cur_textarea_size = atoi(p); - if (p[strlen(p) - 1] == '%') - cur_textarea_size = width * cur_textarea_size / 100 - 2; - if (cur_textarea_size <= 0) - cur_textarea_size = 20; - } - cur_textarea_rows = 1; - if (parsedtag_get_value(tag, ATTR_ROWS, &p)) { - cur_textarea_rows = atoi(p); - if (cur_textarea_rows <= 0) - cur_textarea_rows = 1; - } - cur_textarea_readonly = parsedtag_exists(tag, ATTR_READONLY); - if (n_textarea >= max_textarea) { - max_textarea *= 2; - textarea_str = New_Reuse(Str, textarea_str, max_textarea); - } - textarea_str[n_textarea] = Strnew(); - ignore_nl_textarea = TRUE; - - return tmp; -} - -Str -process_n_textarea(void) -{ - Str tmp; - int i; - - if (cur_textarea == NULL) - return NULL; - - tmp = Strnew(); - Strcat(tmp, Sprintf("<pre_int>[<input_alt hseq=\"%d\" fid=\"%d\" " - "type=textarea name=\"%s\" size=%d rows=%d " - "top_margin=%d textareanumber=%d", - cur_hseq, cur_form_id, - html_quote(cur_textarea->ptr), - cur_textarea_size, cur_textarea_rows, - cur_textarea_rows - 1, n_textarea)); - if (cur_textarea_readonly) - Strcat_charp(tmp, " readonly"); - Strcat_charp(tmp, "><u>"); - for (i = 0; i < cur_textarea_size; i++) - Strcat_char(tmp, ' '); - Strcat_charp(tmp, "</u></input_alt>]</pre_int>\n"); - cur_hseq++; - n_textarea++; - cur_textarea = NULL; - - return tmp; -} - -void -feed_textarea(char *str) -{ - if (cur_textarea == NULL) - return; - if (ignore_nl_textarea) { - if (*str == '\r') - str++; - if (*str == '\n') - str++; - } - ignore_nl_textarea = FALSE; - while (*str) { - if (*str == '&') - Strcat_charp(textarea_str[n_textarea], getescapecmd(&str)); - else if (*str == '\n') { - Strcat_charp(textarea_str[n_textarea], "\r\n"); - str++; - } - else if (*str != '\r') - Strcat_char(textarea_str[n_textarea], *(str++)); - } -} - -Str -process_hr(struct parsed_tag *tag, int width, int indent_width) -{ - Str tmp = Strnew_charp("<nobr>"); - int w = 0; - int x = ALIGN_CENTER; - - if (width > indent_width) - width -= indent_width; - if (parsedtag_get_value(tag, ATTR_WIDTH, &w)) - w = REAL_WIDTH(w, width); - else - w = width; - - parsedtag_get_value(tag, ATTR_ALIGN, &x); - switch (x) { - case ALIGN_CENTER: - Strcat_charp(tmp, "<div_int align=center>"); - break; - case ALIGN_RIGHT: - Strcat_charp(tmp, "<div_int align=right>"); - break; - case ALIGN_LEFT: - Strcat_charp(tmp, "<div_int align=left>"); - break; - } - w /= symbol_width; - if (w <= 0) - w = 1; - push_symbol(tmp, HR_SYMBOL, symbol_width, w); - Strcat_charp(tmp, "</div_int></nobr>"); - return tmp; -} - -#ifdef USE_M17N -static char * -check_charset(char *p) -{ - return wc_guess_charset(p, 0) ? p : NULL; -} - -static char * -check_accept_charset(char *ac) -{ - char *s = ac, *e; - - while (*s) { - while (*s && (IS_SPACE(*s) || *s == ',')) - s++; - if (!*s) - break; - e = s; - while (*e && !(IS_SPACE(*e) || *e == ',')) - e++; - if (wc_guess_charset(Strnew_charp_n(s, e - s)->ptr, 0)) - return ac; - s = e; - } - return NULL; -} -#endif - -static Str -process_form_int(struct parsed_tag *tag, int fid) -{ - char *p, *q, *r, *s, *tg, *n; - - p = "get"; - parsedtag_get_value(tag, ATTR_METHOD, &p); - q = "!CURRENT_URL!"; - parsedtag_get_value(tag, ATTR_ACTION, &q); - r = NULL; -#ifdef USE_M17N - if (parsedtag_get_value(tag, ATTR_ACCEPT_CHARSET, &r)) - r = check_accept_charset(r); - if (!r && parsedtag_get_value(tag, ATTR_CHARSET, &r)) - r = check_charset(r); -#endif - s = NULL; - parsedtag_get_value(tag, ATTR_ENCTYPE, &s); - tg = NULL; - parsedtag_get_value(tag, ATTR_TARGET, &tg); - n = NULL; - parsedtag_get_value(tag, ATTR_NAME, &n); - - if (fid < 0) { - form_max++; - form_sp++; - fid = form_max; - } - else { /* <form_int> */ - if (form_max < fid) - form_max = fid; - form_sp = fid; - } - if (forms_size == 0) { - forms_size = INITIAL_FORM_SIZE; - forms = New_N(FormList *, forms_size); - form_stack = NewAtom_N(int, forms_size); - } - else if (forms_size <= form_max) { - forms_size += form_max; - forms = New_Reuse(FormList *, forms, forms_size); - form_stack = New_Reuse(int, form_stack, forms_size); - } - form_stack[form_sp] = fid; - - if (w3m_halfdump) { - Str tmp = Sprintf("<form_int fid=\"%d\" action=\"%s\" method=\"%s\"", - fid, html_quote(q), html_quote(p)); - if (s) - Strcat(tmp, Sprintf(" enctype=\"%s\"", html_quote(s))); - if (tg) - Strcat(tmp, Sprintf(" target=\"%s\"", html_quote(tg))); - if (n) - Strcat(tmp, Sprintf(" name=\"%s\"", html_quote(n))); -#ifdef USE_M17N - if (r) - Strcat(tmp, Sprintf(" accept-charset=\"%s\"", html_quote(r))); -#endif - Strcat_charp(tmp, ">"); - return tmp; - } - - forms[fid] = newFormList(q, p, r, s, tg, n, NULL); - return NULL; -} - -Str -process_form(struct parsed_tag *tag) -{ - return process_form_int(tag, -1); -} - -Str -process_n_form(void) -{ - if (form_sp >= 0) - form_sp--; - return NULL; -} - -static void -clear_ignore_p_flag(int cmd, struct readbuffer *obuf) -{ - static int clear_flag_cmd[] = { - HTML_HR, HTML_UNKNOWN - }; - int i; - - for (i = 0; clear_flag_cmd[i] != HTML_UNKNOWN; i++) { - if (cmd == clear_flag_cmd[i]) { - obuf->flag &= ~RB_IGNORE_P; - return; - } - } -} - -static void -set_alignment(struct readbuffer *obuf, struct parsed_tag *tag) -{ - long flag = -1; - int align; - - if (parsedtag_get_value(tag, ATTR_ALIGN, &align)) { - switch (align) { - case ALIGN_CENTER: - flag = RB_CENTER; - break; - case ALIGN_RIGHT: - flag = RB_RIGHT; - break; - case ALIGN_LEFT: - flag = RB_LEFT; - } - } - RB_SAVE_FLAG(obuf); - if (flag != -1) { - RB_SET_ALIGN(obuf, flag); - } -} - -#ifdef ID_EXT -static void -process_idattr(struct readbuffer *obuf, int cmd, struct parsed_tag *tag) -{ - char *id = NULL, *framename = NULL; - Str idtag = NULL; - - /* - * HTML_TABLE is handled by the other process. - */ - if (cmd == HTML_TABLE) - return; - - parsedtag_get_value(tag, ATTR_ID, &id); - parsedtag_get_value(tag, ATTR_FRAMENAME, &framename); - if (id == NULL) - return; - if (framename) - idtag = Sprintf("<_id id=\"%s\" framename=\"%s\">", - html_quote(id), html_quote(framename)); - else - idtag = Sprintf("<_id id=\"%s\">", html_quote(id)); - push_tag(obuf, idtag->ptr, HTML_NOP); -} -#endif /* ID_EXT */ - -#define CLOSE_P if (obuf->flag & RB_P) { \ - flushline(h_env, obuf, envs[h_env->envc].indent,0,h_env->limit);\ - RB_RESTORE_FLAG(obuf);\ - obuf->flag &= ~RB_P;\ - } - -#define CLOSE_A \ - CLOSE_P; \ - close_anchor(h_env, obuf); - -#define CLOSE_DT \ - if (obuf->flag & RB_IN_DT) { \ - obuf->flag &= ~RB_IN_DT; \ - HTMLlineproc1("</b>", h_env); \ - } - -#define PUSH_ENV(cmd) \ - if (++h_env->envc_real < h_env->nenv) { \ - ++h_env->envc; \ - envs[h_env->envc].env = cmd; \ - envs[h_env->envc].count = 0; \ - if (h_env->envc <= MAX_INDENT_LEVEL) \ - envs[h_env->envc].indent = envs[h_env->envc - 1].indent + INDENT_INCR; \ - else \ - envs[h_env->envc].indent = envs[h_env->envc - 1].indent; \ - } - -#define POP_ENV \ - if (h_env->envc_real-- < h_env->nenv) \ - h_env->envc--; - -static int -ul_type(struct parsed_tag *tag, int default_type) -{ - char *p; - if (parsedtag_get_value(tag, ATTR_TYPE, &p)) { - if (!strcasecmp(p, "disc")) - return (int)'d'; - else if (!strcasecmp(p, "circle")) - return (int)'c'; - else if (!strcasecmp(p, "square")) - return (int)'s'; - } - return default_type; -} - -int -getMetaRefreshParam(char *q, Str *refresh_uri) -{ - int refresh_interval; - char *r; - Str s_tmp = NULL; - - if (q == NULL || refresh_uri == NULL) - return 0; - - refresh_interval = atoi(q); - if (refresh_interval < 0) - return 0; - - while (*q) { - if (!strncasecmp(q, "url=", 4)) { - q += 4; - if (*q == '\"') /* " */ - q++; - r = q; - while (*r && !IS_SPACE(*r) && *r != ';') - r++; - s_tmp = Strnew_charp_n(q, r - q); - - if (s_tmp->ptr[s_tmp->length - 1] == '\"') { /* " - */ - s_tmp->length--; - s_tmp->ptr[s_tmp->length] = '\0'; - } - q = r; - } - while (*q && *q != ';') - q++; - if (*q == ';') - q++; - while (*q && *q == ' ') - q++; - } - *refresh_uri = s_tmp; - return refresh_interval; -} - -int -HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) -{ - char *p, *q, *r; - int i, w, x, y, z, count, width; - struct readbuffer *obuf = h_env->obuf; - struct environment *envs = h_env->envs; - Str tmp; - int hseq; - int cmd; -#ifdef ID_EXT - char *id = NULL; -#endif /* ID_EXT */ - - cmd = tag->tagid; - - if (obuf->flag & RB_PRE) { - switch (cmd) { - case HTML_NOBR: - case HTML_N_NOBR: - case HTML_PRE_INT: - case HTML_N_PRE_INT: - return 1; - } - } - - switch (cmd) { - case HTML_B: - obuf->in_bold++; - if (obuf->in_bold > 1) - return 1; - return 0; - case HTML_N_B: - if (obuf->in_bold == 1 && close_effect0(obuf, HTML_B)) - obuf->in_bold = 0; - if (obuf->in_bold > 0) { - obuf->in_bold--; - if (obuf->in_bold == 0) - return 0; - } - return 1; - case HTML_U: - obuf->in_under++; - if (obuf->in_under > 1) - return 1; - return 0; - case HTML_N_U: - if (obuf->in_under == 1 && close_effect0(obuf, HTML_U)) - obuf->in_under = 0; - if (obuf->in_under > 0) { - obuf->in_under--; - if (obuf->in_under == 0) - return 0; - } - return 1; - case HTML_EM: - HTMLlineproc1("<b>", h_env); - return 1; - case HTML_N_EM: - HTMLlineproc1("</b>", h_env); - return 1; - case HTML_Q: - HTMLlineproc1("`", h_env); - return 1; - case HTML_N_Q: - HTMLlineproc1("'", h_env); - return 1; - case HTML_P: - case HTML_N_P: - CLOSE_A; - if (!(obuf->flag & RB_IGNORE_P)) { - flushline(h_env, obuf, envs[h_env->envc].indent, 1, h_env->limit); - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - } - obuf->flag |= RB_IGNORE_P; - if (cmd == HTML_P) { - set_alignment(obuf, tag); - obuf->flag |= RB_P; - } - return 1; - case HTML_BR: - flushline(h_env, obuf, envs[h_env->envc].indent, 1, h_env->limit); - h_env->blank_lines = 0; - return 1; - case HTML_H: - if (!(obuf->flag & (RB_PREMODE | RB_IGNORE_P))) { - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - } - HTMLlineproc1("<b>", h_env); - set_alignment(obuf, tag); - return 1; - case HTML_N_H: - HTMLlineproc1("</b>", h_env); - if (!(obuf->flag & RB_PREMODE)) { - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - } - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - RB_RESTORE_FLAG(obuf); - close_anchor(h_env, obuf); - obuf->flag |= RB_IGNORE_P; - return 1; - case HTML_UL: - case HTML_OL: - case HTML_BLQ: - CLOSE_A; - if (!(obuf->flag & RB_IGNORE_P)) { - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - if (!(obuf->flag & RB_PREMODE) && - (h_env->envc == 0 || cmd == HTML_BLQ)) - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - } - PUSH_ENV(cmd); - if (cmd == HTML_UL || cmd == HTML_OL) { - if (parsedtag_get_value(tag, ATTR_START, &count)) { - envs[h_env->envc].count = count - 1; - } - } - if (cmd == HTML_OL) { - envs[h_env->envc].type = '1'; - if (parsedtag_get_value(tag, ATTR_TYPE, &p)) { - envs[h_env->envc].type = (int)*p; - } - } - if (cmd == HTML_UL) - envs[h_env->envc].type = ul_type(tag, 0); - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - return 1; - case HTML_N_UL: - case HTML_N_OL: - case HTML_N_DL: - case HTML_N_BLQ: - CLOSE_DT; - CLOSE_A; - if (h_env->envc > 0) { - flushline(h_env, obuf, envs[h_env->envc - 1].indent, 0, - h_env->limit); - POP_ENV; - if (!(obuf->flag & RB_PREMODE) && - (h_env->envc == 0 || cmd == HTML_N_DL || cmd == HTML_N_BLQ)) { - do_blankline(h_env, obuf, - envs[h_env->envc].indent, - INDENT_INCR, h_env->limit); - obuf->flag |= RB_IGNORE_P; - } - } - close_anchor(h_env, obuf); - return 1; - case HTML_DL: - CLOSE_A; - if (!(obuf->flag & RB_IGNORE_P)) { - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - if (!(obuf->flag & RB_PREMODE)) - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - } - PUSH_ENV(cmd); - if (parsedtag_exists(tag, ATTR_COMPACT)) - envs[h_env->envc].env = HTML_DL_COMPACT; - obuf->flag |= RB_IGNORE_P; - return 1; - case HTML_LI: - CLOSE_A; - CLOSE_DT; - if (h_env->envc > 0) { - Str num; - flushline(h_env, obuf, - envs[h_env->envc - 1].indent, 0, h_env->limit); - envs[h_env->envc].count++; - if (parsedtag_get_value(tag, ATTR_VALUE, &p)) { - count = atoi(p); - if (count > 0) - envs[h_env->envc].count = count; - else - envs[h_env->envc].count = 0; - } - switch (envs[h_env->envc].env) { - case HTML_UL: - envs[h_env->envc].type = ul_type(tag, envs[h_env->envc].type); - for (i = 0; i < INDENT_INCR - 3; i++) - push_charp(obuf, 1, NBSP, PC_ASCII); - tmp = Strnew(); - switch (envs[h_env->envc].type) { - case 'd': - push_symbol(tmp, UL_SYMBOL_DISC, symbol_width, 1); - break; - case 'c': - push_symbol(tmp, UL_SYMBOL_CIRCLE, symbol_width, 1); - break; - case 's': - push_symbol(tmp, UL_SYMBOL_SQUARE, symbol_width, 1); - break; - default: - push_symbol(tmp, - UL_SYMBOL((h_env->envc_real - - 1) % MAX_UL_LEVEL), symbol_width, - 1); - break; - } - if (symbol_width == 1) - push_charp(obuf, 1, NBSP, PC_ASCII); - push_str(obuf, symbol_width, tmp, PC_ASCII); - push_charp(obuf, 1, NBSP, PC_ASCII); - set_space_to_prevchar(obuf->prevchar); - break; - case HTML_OL: - if (parsedtag_get_value(tag, ATTR_TYPE, &p)) - envs[h_env->envc].type = (int)*p; - switch ((envs[h_env->envc].count > 0)? envs[h_env->envc].type: '1') { - case 'i': - num = romanNumeral(envs[h_env->envc].count); - break; - case 'I': - num = romanNumeral(envs[h_env->envc].count); - Strupper(num); - break; - case 'a': - num = romanAlphabet(envs[h_env->envc].count); - break; - case 'A': - num = romanAlphabet(envs[h_env->envc].count); - Strupper(num); - break; - default: - num = Sprintf("%d", envs[h_env->envc].count); - break; - } - if (INDENT_INCR >= 4) - Strcat_charp(num, ". "); - else - Strcat_char(num, '.'); - push_spaces(obuf, 1, INDENT_INCR - num->length); - push_str(obuf, num->length, num, PC_ASCII); - if (INDENT_INCR >= 4) - set_space_to_prevchar(obuf->prevchar); - break; - default: - push_spaces(obuf, 1, INDENT_INCR); - break; - } - } - else { - flushline(h_env, obuf, 0, 0, h_env->limit); - } - obuf->flag |= RB_IGNORE_P; - return 1; - case HTML_DT: - CLOSE_A; - if (h_env->envc == 0 || - (h_env->envc_real < h_env->nenv && - envs[h_env->envc].env != HTML_DL && - envs[h_env->envc].env != HTML_DL_COMPACT)) { - PUSH_ENV(HTML_DL); - } - if (h_env->envc > 0) { - flushline(h_env, obuf, - envs[h_env->envc - 1].indent, 0, h_env->limit); - } - if (!(obuf->flag & RB_IN_DT)) { - HTMLlineproc1("<b>", h_env); - obuf->flag |= RB_IN_DT; - } - obuf->flag |= RB_IGNORE_P; - return 1; - case HTML_DD: - CLOSE_A; - CLOSE_DT; - if (envs[h_env->envc].env == HTML_DL_COMPACT) { - if (obuf->pos > envs[h_env->envc].indent) - flushline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - else - push_spaces(obuf, 1, envs[h_env->envc].indent - obuf->pos); - } - else - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - /* obuf->flag |= RB_IGNORE_P; */ - return 1; - case HTML_TITLE: - close_anchor(h_env, obuf); - process_title(tag); - obuf->flag |= RB_TITLE; - obuf->end_tag = HTML_N_TITLE; - return 1; - case HTML_N_TITLE: - if (!(obuf->flag & RB_TITLE)) - return 1; - obuf->flag &= ~RB_TITLE; - obuf->end_tag = 0; - tmp = process_n_title(tag); - if (tmp) - HTMLlineproc1(tmp->ptr, h_env); - return 1; - case HTML_TITLE_ALT: - if (parsedtag_get_value(tag, ATTR_TITLE, &p)) - h_env->title = html_unquote(p); - return 0; - case HTML_FRAMESET: - PUSH_ENV(cmd); - push_charp(obuf, 9, "--FRAME--", PC_ASCII); - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - return 0; - case HTML_N_FRAMESET: - if (h_env->envc > 0) { - POP_ENV; - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - } - return 0; - case HTML_NOFRAMES: - CLOSE_A; - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - obuf->flag |= (RB_NOFRAMES | RB_IGNORE_P); - /* istr = str; */ - return 1; - case HTML_N_NOFRAMES: - CLOSE_A; - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - obuf->flag &= ~RB_NOFRAMES; - return 1; - case HTML_FRAME: - q = r = NULL; - parsedtag_get_value(tag, ATTR_SRC, &q); - parsedtag_get_value(tag, ATTR_NAME, &r); - if (q) { - q = html_quote(q); - push_tag(obuf, Sprintf("<a hseq=\"%d\" href=\"%s\">", - cur_hseq++, q)->ptr, HTML_A); - if (r) - q = html_quote(r); - push_charp(obuf, get_strwidth(q), q, PC_ASCII); - push_tag(obuf, "</a>", HTML_N_A); - } - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - return 0; - case HTML_HR: - close_anchor(h_env, obuf); - tmp = process_hr(tag, h_env->limit, envs[h_env->envc].indent); - HTMLlineproc1(tmp->ptr, h_env); - set_space_to_prevchar(obuf->prevchar); - return 1; - case HTML_PRE: - x = parsedtag_exists(tag, ATTR_FOR_TABLE); - CLOSE_A; - if (!(obuf->flag & RB_IGNORE_P)) { - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - if (!x) - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - } - else - fillline(obuf, envs[h_env->envc].indent); - obuf->flag |= (RB_PRE | RB_IGNORE_P); - /* istr = str; */ - return 1; - case HTML_N_PRE: - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - if (!(obuf->flag & RB_IGNORE_P)) { - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - obuf->flag |= RB_IGNORE_P; - } - obuf->flag &= ~RB_PRE; - close_anchor(h_env, obuf); - return 1; - case HTML_PRE_INT: - i = obuf->line->length; - append_tags(obuf); - if (!(obuf->flag & RB_SPECIAL)) { - set_breakpoint(obuf, obuf->line->length - i); - } - obuf->flag |= RB_PRE_INT; - return 0; - case HTML_N_PRE_INT: - push_tag(obuf, "</pre_int>", HTML_N_PRE_INT); - obuf->flag &= ~RB_PRE_INT; - if (!(obuf->flag & RB_SPECIAL) && obuf->pos > obuf->bp.pos) { - set_prevchar(obuf->prevchar, "", 0); - obuf->prev_ctype = PC_CTRL; - } - return 1; - case HTML_NOBR: - obuf->flag |= RB_NOBR; - obuf->nobr_level++; - return 0; - case HTML_N_NOBR: - if (obuf->nobr_level > 0) - obuf->nobr_level--; - if (obuf->nobr_level == 0) - obuf->flag &= ~RB_NOBR; - return 0; - case HTML_PRE_PLAIN: - CLOSE_A; - if (!(obuf->flag & RB_IGNORE_P)) { - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - } - obuf->flag |= (RB_PRE | RB_IGNORE_P); - return 1; - case HTML_N_PRE_PLAIN: - CLOSE_A; - if (!(obuf->flag & RB_IGNORE_P)) { - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - obuf->flag |= RB_IGNORE_P; - } - obuf->flag &= ~RB_PRE; - return 1; - case HTML_LISTING: - case HTML_XMP: - case HTML_PLAINTEXT: - CLOSE_A; - if (!(obuf->flag & RB_IGNORE_P)) { - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - } - obuf->flag |= (RB_PLAIN | RB_IGNORE_P); - switch (cmd) { - case HTML_LISTING: - obuf->end_tag = HTML_N_LISTING; - break; - case HTML_XMP: - obuf->end_tag = HTML_N_XMP; - break; - case HTML_PLAINTEXT: - obuf->end_tag = MAX_HTMLTAG; - break; - } - return 1; - case HTML_N_LISTING: - case HTML_N_XMP: - CLOSE_A; - if (!(obuf->flag & RB_IGNORE_P)) { - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - obuf->flag |= RB_IGNORE_P; - } - obuf->flag &= ~RB_PLAIN; - obuf->end_tag = 0; - return 1; - case HTML_SCRIPT: - obuf->flag |= RB_SCRIPT; - obuf->end_tag = HTML_N_SCRIPT; - return 1; - case HTML_STYLE: - obuf->flag |= RB_STYLE; - obuf->end_tag = HTML_N_STYLE; - return 1; - case HTML_N_SCRIPT: - obuf->flag &= ~RB_SCRIPT; - obuf->end_tag = 0; - return 1; - case HTML_N_STYLE: - obuf->flag &= ~RB_STYLE; - obuf->end_tag = 0; - return 1; - case HTML_A: - if (obuf->anchor.url) - close_anchor(h_env, obuf); - - hseq = 0; - - if (parsedtag_get_value(tag, ATTR_HREF, &p)) - obuf->anchor.url = Strnew_charp(p)->ptr; - if (parsedtag_get_value(tag, ATTR_TARGET, &p)) - obuf->anchor.target = Strnew_charp(p)->ptr; - if (parsedtag_get_value(tag, ATTR_REFERER, &p)) - obuf->anchor.referer = Strnew_charp(p)->ptr; - if (parsedtag_get_value(tag, ATTR_TITLE, &p)) - obuf->anchor.title = Strnew_charp(p)->ptr; - if (parsedtag_get_value(tag, ATTR_ACCESSKEY, &p)) - obuf->anchor.accesskey = (unsigned char)*p; - if (parsedtag_get_value(tag, ATTR_HSEQ, &hseq)) - obuf->anchor.hseq = hseq; - - if (hseq == 0 && obuf->anchor.url) { - obuf->anchor.hseq = cur_hseq; - tmp = process_anchor(tag, h_env->tagbuf->ptr); - push_tag(obuf, tmp->ptr, HTML_A); - return 1; - } - return 0; - case HTML_N_A: - close_anchor(h_env, obuf); - return 1; - case HTML_IMG: - tmp = process_img(tag, h_env->limit); - HTMLlineproc1(tmp->ptr, h_env); - return 1; - case HTML_IMG_ALT: - if (parsedtag_get_value(tag, ATTR_SRC, &p)) - obuf->img_alt = Strnew_charp(p); -#ifdef USE_IMAGE - i = 0; - if (parsedtag_get_value(tag, ATTR_TOP_MARGIN, &i)) { - if (i > obuf->top_margin) - obuf->top_margin = i; - } - i = 0; - if (parsedtag_get_value(tag, ATTR_BOTTOM_MARGIN, &i)) { - if (i > obuf->bottom_margin) - obuf->bottom_margin = i; - } -#endif - return 0; - case HTML_N_IMG_ALT: - if (obuf->img_alt) { - if (!close_effect0(obuf, HTML_IMG_ALT)) - push_tag(obuf, "</img_alt>", HTML_N_IMG_ALT); - obuf->img_alt = NULL; - } - return 1; - case HTML_INPUT_ALT: - i = 0; - if (parsedtag_get_value(tag, ATTR_TOP_MARGIN, &i)) { - if (i > obuf->top_margin) - obuf->top_margin = i; - } - i = 0; - if (parsedtag_get_value(tag, ATTR_BOTTOM_MARGIN, &i)) { - if (i > obuf->bottom_margin) - obuf->bottom_margin = i; - } - return 0; - case HTML_TABLE: - close_anchor(h_env, obuf); - obuf->table_level++; - if (obuf->table_level >= MAX_TABLE) - break; - w = BORDER_NONE; - /* x: cellspacing, y: cellpadding */ - x = 2; - y = 1; - z = 0; - width = 0; - if (parsedtag_exists(tag, ATTR_BORDER)) { - if (parsedtag_get_value(tag, ATTR_BORDER, &w)) { - if (w > 2) - w = BORDER_THICK; - else if (w < 0) { /* weird */ - w = BORDER_THIN; - } - } - else - w = BORDER_THIN; - } - if (parsedtag_get_value(tag, ATTR_WIDTH, &i)) { - if (obuf->table_level == 0) - width = REAL_WIDTH(i, h_env->limit - envs[h_env->envc].indent); - else - width = RELATIVE_WIDTH(i); - } - if (parsedtag_exists(tag, ATTR_HBORDER)) - w = BORDER_NOWIN; - parsedtag_get_value(tag, ATTR_CELLSPACING, &x); - parsedtag_get_value(tag, ATTR_CELLPADDING, &y); - parsedtag_get_value(tag, ATTR_VSPACE, &z); -#ifdef ID_EXT - parsedtag_get_value(tag, ATTR_ID, &id); -#endif /* ID_EXT */ - tables[obuf->table_level] = begin_table(w, x, y, z); -#ifdef ID_EXT - if (id != NULL) - tables[obuf->table_level]->id = Strnew_charp(id); -#endif /* ID_EXT */ - table_mode[obuf->table_level].pre_mode = 0; - table_mode[obuf->table_level].indent_level = 0; - table_mode[obuf->table_level].nobr_level = 0; - table_mode[obuf->table_level].caption = 0; - table_mode[obuf->table_level].end_tag = 0; /* HTML_UNKNOWN */ -#ifndef TABLE_EXPAND - tables[obuf->table_level]->total_width = width; -#else - tables[obuf->table_level]->real_width = width; - tables[obuf->table_level]->total_width = 0; -#endif - return 1; - case HTML_N_TABLE: - /* should be processed in HTMLlineproc() */ - return 1; - case HTML_CENTER: - CLOSE_A; - if (!(obuf->flag & (RB_PREMODE | RB_IGNORE_P))) - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - RB_SAVE_FLAG(obuf); - RB_SET_ALIGN(obuf, RB_CENTER); - return 1; - case HTML_N_CENTER: - CLOSE_A; - if (!(obuf->flag & RB_PREMODE)) - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - RB_RESTORE_FLAG(obuf); - return 1; - case HTML_DIV: - CLOSE_A; - if (!(obuf->flag & RB_IGNORE_P)) - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - set_alignment(obuf, tag); - return 1; - case HTML_N_DIV: - CLOSE_A; - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - RB_RESTORE_FLAG(obuf); - return 1; - case HTML_DIV_INT: - CLOSE_P; - if (!(obuf->flag & RB_IGNORE_P)) - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - set_alignment(obuf, tag); - return 1; - case HTML_N_DIV_INT: - CLOSE_P; - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - RB_RESTORE_FLAG(obuf); - return 1; - case HTML_FORM: - CLOSE_A; - if (!(obuf->flag & RB_IGNORE_P)) - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - tmp = process_form(tag); - if (tmp) - HTMLlineproc1(tmp->ptr, h_env); - return 1; - case HTML_N_FORM: - CLOSE_A; - flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); - obuf->flag |= RB_IGNORE_P; - process_n_form(); - return 1; - case HTML_INPUT: - close_anchor(h_env, obuf); - tmp = process_input(tag); - if (tmp) - HTMLlineproc1(tmp->ptr, h_env); - return 1; - case HTML_SELECT: - close_anchor(h_env, obuf); - tmp = process_select(tag); - if (tmp) - HTMLlineproc1(tmp->ptr, h_env); - obuf->flag |= RB_INSELECT; - obuf->end_tag = HTML_N_SELECT; - return 1; - case HTML_N_SELECT: - obuf->flag &= ~RB_INSELECT; - obuf->end_tag = 0; - tmp = process_n_select(); - if (tmp) - HTMLlineproc1(tmp->ptr, h_env); - return 1; - case HTML_OPTION: - /* nothing */ - return 1; - case HTML_TEXTAREA: - close_anchor(h_env, obuf); - tmp = process_textarea(tag, h_env->limit); - if (tmp) - HTMLlineproc1(tmp->ptr, h_env); - obuf->flag |= RB_INTXTA; - obuf->end_tag = HTML_N_TEXTAREA; - return 1; - case HTML_N_TEXTAREA: - obuf->flag &= ~RB_INTXTA; - obuf->end_tag = 0; - tmp = process_n_textarea(); - if (tmp) - HTMLlineproc1(tmp->ptr, h_env); - return 1; - case HTML_ISINDEX: - p = ""; - q = "!CURRENT_URL!"; - parsedtag_get_value(tag, ATTR_PROMPT, &p); - parsedtag_get_value(tag, ATTR_ACTION, &q); - tmp = Strnew_m_charp("<form method=get action=\"", - html_quote(q), - "\">", - html_quote(p), - "<input type=text name=\"\" accept></form>", - NULL); - HTMLlineproc1(tmp->ptr, h_env); - return 1; - case HTML_META: - p = q = NULL; - parsedtag_get_value(tag, ATTR_HTTP_EQUIV, &p); - parsedtag_get_value(tag, ATTR_CONTENT, &q); -#ifdef USE_M17N - if (p && q && !strcasecmp(p, "Content-Type") && - (q = strcasestr(q, "charset")) != NULL) { - q += 7; - SKIP_BLANKS(q); - if (*q == '=') { - q++; - SKIP_BLANKS(q); - meta_charset = wc_guess_charset(q, 0); - } - } - else -#endif - if (p && q && !strcasecmp(p, "refresh")) { - int refresh_interval; - tmp = NULL; - refresh_interval = getMetaRefreshParam(q, &tmp); - if (tmp) { - q = html_quote(tmp->ptr); - tmp = Sprintf("Refresh (%d sec) <a href=\"%s\">%s</a>", - refresh_interval, q, q); - } - else if (refresh_interval > 0) - tmp = Sprintf("Refresh (%d sec)", refresh_interval); - if (tmp) { - HTMLlineproc1(tmp->ptr, h_env); - do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, - h_env->limit); - if (!is_redisplay && - !((obuf->flag & RB_NOFRAMES) && RenderFrame)) { - tag->need_reconstruct = TRUE; - return 0; - } - } - } - return 1; - case HTML_BASE: -#ifdef USE_IMAGE - p = NULL; - if (parsedtag_get_value(tag, ATTR_HREF, &p)) { - if (!cur_baseURL) - cur_baseURL = New(ParsedURL); - parseURL(p, cur_baseURL, NULL); - } -#endif - case HTML_MAP: - case HTML_N_MAP: - case HTML_AREA: - return 0; - case HTML_DEL: - if (displayInsDel) - HTMLlineproc1("<U>[DEL:</U>", h_env); - else - obuf->flag |= RB_DEL; - return 1; - case HTML_N_DEL: - if (displayInsDel) - HTMLlineproc1("<U>:DEL]</U>", h_env); - else - obuf->flag &= ~RB_DEL; - return 1; - case HTML_S: - if (displayInsDel) - HTMLlineproc1("<U>[S:</U>", h_env); - else - obuf->flag |= RB_S; - return 1; - case HTML_N_S: - if (displayInsDel) - HTMLlineproc1("<U>:S]</U>", h_env); - else - obuf->flag &= ~RB_S; - return 1; - case HTML_INS: - if (displayInsDel) - HTMLlineproc1("<U>[INS:</U>", h_env); - return 1; - case HTML_N_INS: - if (displayInsDel) - HTMLlineproc1("<U>:INS]</U>", h_env); - return 1; - case HTML_SUP: - if (!(obuf->flag & (RB_DEL | RB_S))) - HTMLlineproc1("^", h_env); - return 1; - case HTML_N_SUP: - return 1; - case HTML_SUB: - if (!(obuf->flag & (RB_DEL | RB_S))) - HTMLlineproc1("[", h_env); - return 1; - case HTML_N_SUB: - if (!(obuf->flag & (RB_DEL | RB_S))) - HTMLlineproc1("]", h_env); - return 1; - case HTML_FONT: - case HTML_N_FONT: - case HTML_NOP: - return 1; - case HTML_BGSOUND: - if (view_unseenobject) { - if (parsedtag_get_value(tag, ATTR_SRC, &p)) { - Str s; - q = html_quote(p); - s = Sprintf("<A HREF=\"%s\">bgsound(%s)</A>", q, q); - HTMLlineproc1(s->ptr, h_env); - } - } - return 1; - case HTML_EMBED: - if (view_unseenobject) { - if (parsedtag_get_value(tag, ATTR_SRC, &p)) { - Str s; - q = html_quote(p); - s = Sprintf("<A HREF=\"%s\">embed(%s)</A>", q, q); - HTMLlineproc1(s->ptr, h_env); - } - } - return 1; - case HTML_APPLET: - if (view_unseenobject) { - if (parsedtag_get_value(tag, ATTR_ARCHIVE, &p)) { - Str s; - q = html_quote(p); - s = Sprintf("<A HREF=\"%s\">applet archive(%s)</A>", q, q); - HTMLlineproc1(s->ptr, h_env); - } - } - return 1; - case HTML_BODY: - if (view_unseenobject) { - if (parsedtag_get_value(tag, ATTR_BACKGROUND, &p)) { - Str s; - q = html_quote(p); - s = Sprintf("<IMG SRC=\"%s\" ALT=\"bg image(%s)\"><BR>", q, q); - HTMLlineproc1(s->ptr, h_env); - } - } - case HTML_N_HEAD: - if (obuf->flag & RB_TITLE) - HTMLlineproc1("</title>", h_env); - case HTML_HEAD: - case HTML_N_BODY: - return 1; - default: - /* obuf->prevchar = '\0'; */ - return 0; - } - /* not reached */ - return 0; -} - -#define PPUSH(p,c) {outp[pos]=(p);outc[pos]=(c);pos++;} -#define PSIZE \ - if (out_size <= pos + 1) { \ - out_size = pos * 3 / 2; \ - outc = New_Reuse(char, outc, out_size); \ - outp = New_Reuse(Lineprop, outp, out_size); \ - } - -static TextLineListItem *_tl_lp2; - -static Str -textlist_feed() -{ - TextLine *p; - if (_tl_lp2 != NULL) { - p = _tl_lp2->ptr; - _tl_lp2 = _tl_lp2->next; - return p->line; - } - return NULL; -} - -static void -HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) -{ - static char *outc = NULL; - static Lineprop *outp = NULL; - static int out_size = 0; - Anchor *a_href = NULL, *a_img = NULL, *a_form = NULL; - char *p, *q, *r, *s, *t, *str; - Lineprop mode, effect; - int pos; - int nlines; -#ifdef DEBUG - FILE *debug = NULL; -#endif - struct frameset *frameset_s[FRAMESTACK_SIZE]; - int frameset_sp = -1; - union frameset_element *idFrame = NULL; - char *id = NULL; - int hseq, form_id; - Str line; - char *endp; - char symbol = '\0'; - int internal = 0; - Anchor **a_textarea = NULL; -#ifdef MENU_SELECT - Anchor **a_select = NULL; -#endif - - if (out_size == 0) { - out_size = LINELEN; - outc = NewAtom_N(char, out_size); - outp = NewAtom_N(Lineprop, out_size); - } - - n_textarea = -1; - if (!max_textarea) { /* halfload */ - max_textarea = MAX_TEXTAREA; - textarea_str = New_N(Str, max_textarea); - a_textarea = New_N(Anchor *, max_textarea); - } -#ifdef MENU_SELECT - n_select = -1; - if (!max_select) { /* halfload */ - max_select = MAX_SELECT; - select_option = New_N(FormSelectOption, max_select); - a_select = New_N(Anchor *, max_select); - } -#endif - -#ifdef DEBUG - if (w3m_debug) - debug = fopen("zzzerr", "a"); -#endif - - effect = 0; - nlines = 0; - while ((line = feed()) != NULL) { -#ifdef DEBUG - if (w3m_debug) { - Strfputs(line, debug); - fputc('\n', debug); - } -#endif - if (n_textarea >= 0 && *(line->ptr) != '<') { /* halfload */ - Strcat(textarea_str[n_textarea], line); - continue; - } - proc_again: - if (++nlines == llimit) - break; - pos = 0; -#ifdef ENABLE_REMOVE_TRAILINGSPACES - Strremovetrailingspaces(line); -#endif - str = line->ptr; - endp = str + line->length; - while (str < endp) { - PSIZE; - mode = get_mctype(str); - if (effect & PC_SYMBOL && *str != '<') { -#ifdef USE_M17N - char **buf = set_symbol(symbol_width0); - int len; - - p = buf[(int)symbol]; - len = get_mclen(p); - mode = get_mctype(p); - PPUSH(mode | effect, *(p++)); - if (--len) { - mode = (mode & ~PC_WCHAR1) | PC_WCHAR2; - while (len--) { - PSIZE; - PPUSH(mode | effect, *(p++)); - } - } -#else - PPUSH(PC_ASCII | effect, SYMBOL_BASE + symbol); -#endif - str += symbol_width; - } -#ifdef USE_M17N - else if (mode == PC_CTRL || mode == PC_UNDEF) { -#else - else if (mode == PC_CTRL || IS_INTSPACE(*str)) { -#endif - PPUSH(PC_ASCII | effect, ' '); - str++; - } -#ifdef USE_M17N - else if (mode & PC_UNKNOWN) { - PPUSH(PC_ASCII | effect, ' '); - str += get_mclen(str); - } -#endif - else if (*str != '<' && *str != '&') { -#ifdef USE_M17N - int len = get_mclen(str); -#endif - PPUSH(mode | effect, *(str++)); -#ifdef USE_M17N - if (--len) { - mode = (mode & ~PC_WCHAR1) | PC_WCHAR2; - while (len--) { - PSIZE; - PPUSH(mode | effect, *(str++)); - } - } -#endif - } - else if (*str == '&') { - /* - * & escape processing - */ - p = getescapecmd(&str); - while (*p) { - PSIZE; - mode = get_mctype((unsigned char *)p); -#ifdef USE_M17N - if (mode == PC_CTRL || mode == PC_UNDEF) { -#else - if (mode == PC_CTRL || IS_INTSPACE(*str)) { -#endif - PPUSH(PC_ASCII | effect, ' '); - p++; - } -#ifdef USE_M17N - else if (mode & PC_UNKNOWN) { - PPUSH(PC_ASCII | effect, ' '); - p += get_mclen(p); - } -#endif - else { -#ifdef USE_M17N - int len = get_mclen(p); -#endif - PPUSH(mode | effect, *(p++)); -#ifdef USE_M17N - if (--len) { - mode = (mode & ~PC_WCHAR1) | PC_WCHAR2; - while (len--) { - PSIZE; - PPUSH(mode | effect, *(p++)); - } - } -#endif - } - } - } - else { - /* tag processing */ - struct parsed_tag *tag; - if (!(tag = parse_tag(&str, TRUE))) - continue; - switch (tag->tagid) { - case HTML_B: - effect |= PE_BOLD; - break; - case HTML_N_B: - effect &= ~PE_BOLD; - break; - case HTML_U: - effect |= PE_UNDER; - break; - case HTML_N_U: - effect &= ~PE_UNDER; - break; - case HTML_A: - if (renderFrameSet && - parsedtag_get_value(tag, ATTR_FRAMENAME, &p)) { - p = url_quote_conv(p, buf->document_charset); - if (!idFrame || strcmp(idFrame->body->name, p)) { - idFrame = search_frame(renderFrameSet, p); - if (idFrame && idFrame->body->attr != F_BODY) - idFrame = NULL; - } - } - p = r = s = NULL; - q = buf->baseTarget; - t = ""; - hseq = 0; - id = NULL; - if (parsedtag_get_value(tag, ATTR_NAME, &id)) { - id = url_quote_conv(id, buf->document_charset); - registerName(buf, id, currentLn(buf), pos); - } - if (parsedtag_get_value(tag, ATTR_HREF, &p)) - p = url_quote_conv(remove_space(p), - buf->document_charset); - if (parsedtag_get_value(tag, ATTR_TARGET, &q)) - q = url_quote_conv(q, buf->document_charset); - if (parsedtag_get_value(tag, ATTR_REFERER, &r)) - r = url_quote_conv(r, buf->document_charset); - parsedtag_get_value(tag, ATTR_TITLE, &s); - parsedtag_get_value(tag, ATTR_ACCESSKEY, &t); - parsedtag_get_value(tag, ATTR_HSEQ, &hseq); - if (hseq > 0) - buf->hmarklist = - putHmarker(buf->hmarklist, currentLn(buf), - pos, hseq - 1); - else if (hseq < 0) { - int h = -hseq - 1; - if (buf->hmarklist && - h < buf->hmarklist->nmark && - buf->hmarklist->marks[h].invalid) { - buf->hmarklist->marks[h].pos = pos; - buf->hmarklist->marks[h].line = currentLn(buf); - buf->hmarklist->marks[h].invalid = 0; - hseq = -hseq; - } - } - if (id && idFrame) - idFrame->body->nameList = - putAnchor(idFrame->body->nameList, id, NULL, - (Anchor **)NULL, NULL, NULL, '\0', - currentLn(buf), pos); - if (p) { - effect |= PE_ANCHOR; - a_href = registerHref(buf, p, q, r, s, - *t, currentLn(buf), pos); - a_href->hseq = ((hseq > 0) ? hseq : -hseq) - 1; - a_href->slave = (hseq > 0) ? FALSE : TRUE; - } - break; - case HTML_N_A: - effect &= ~PE_ANCHOR; - if (a_href) { - a_href->end.line = currentLn(buf); - a_href->end.pos = pos; - if (a_href->start.line == a_href->end.line && - a_href->start.pos == a_href->end.pos) { - if (buf->hmarklist && - a_href->hseq < buf->hmarklist->nmark) - buf->hmarklist->marks[a_href->hseq].invalid = 1; - a_href->hseq = -1; - } - a_href = NULL; - } - break; - - case HTML_LINK: - addLink(buf, tag); - break; - - case HTML_IMG_ALT: - if (parsedtag_get_value(tag, ATTR_SRC, &p)) { -#ifdef USE_IMAGE - int w = -1, h = -1, iseq = 0, ismap = 0; - int xoffset = 0, yoffset = 0, top = 0, bottom = 0; - parsedtag_get_value(tag, ATTR_HSEQ, &iseq); - parsedtag_get_value(tag, ATTR_WIDTH, &w); - parsedtag_get_value(tag, ATTR_HEIGHT, &h); - parsedtag_get_value(tag, ATTR_XOFFSET, &xoffset); - parsedtag_get_value(tag, ATTR_YOFFSET, &yoffset); - parsedtag_get_value(tag, ATTR_TOP_MARGIN, &top); - parsedtag_get_value(tag, ATTR_BOTTOM_MARGIN, &bottom); - if (parsedtag_exists(tag, ATTR_ISMAP)) - ismap = 1; - q = NULL; - parsedtag_get_value(tag, ATTR_USEMAP, &q); - if (iseq > 0) { - buf->imarklist = putHmarker(buf->imarklist, - currentLn(buf), pos, - iseq - 1); - } -#endif - s = NULL; - parsedtag_get_value(tag, ATTR_TITLE, &s); - p = url_quote_conv(remove_space(p), - buf->document_charset); - a_img = registerImg(buf, p, s, currentLn(buf), pos); -#ifdef USE_IMAGE - a_img->hseq = iseq; - a_img->image = NULL; - if (iseq > 0) { - ParsedURL u; - Image *image; - - parseURL2(a_img->url, &u, cur_baseURL); - a_img->image = image = New(Image); - image->url = parsedURL2Str(&u)->ptr; - if (!uncompressed_file_type(u.file, &image->ext)) - image->ext = filename_extension(u.file, TRUE); - image->cache = NULL; - image->width = - (w > MAX_IMAGE_SIZE) ? MAX_IMAGE_SIZE : w; - image->height = - (h > MAX_IMAGE_SIZE) ? MAX_IMAGE_SIZE : h; - image->xoffset = xoffset; - image->yoffset = yoffset; - image->y = currentLn(buf) - top; - if (image->xoffset < 0 && pos == 0) - image->xoffset = 0; - if (image->yoffset < 0 && image->y == 1) - image->yoffset = 0; - image->rows = 1 + top + bottom; - image->map = q; - image->ismap = ismap; - image->touch = 0; - image->cache = getImage(image, cur_baseURL, - IMG_FLAG_SKIP); - } - else if (iseq < 0) { - BufferPoint *po = buf->imarklist->marks - iseq - 1; - Anchor *a = retrieveAnchor(buf->img, - po->line, po->pos); - if (a) { - a_img->url = a->url; - a_img->image = a->image; - } - } -#endif - } - effect |= PE_IMAGE; - break; - case HTML_N_IMG_ALT: - effect &= ~PE_IMAGE; - if (a_img) { - a_img->end.line = currentLn(buf); - a_img->end.pos = pos; - } - a_img = NULL; - break; - case HTML_INPUT_ALT: - { - FormList *form; - int top = 0, bottom = 0; - int textareanumber = -1; -#ifdef MENU_SELECT - int selectnumber = -1; -#endif - hseq = 0; - form_id = -1; - - parsedtag_get_value(tag, ATTR_HSEQ, &hseq); - parsedtag_get_value(tag, ATTR_FID, &form_id); - parsedtag_get_value(tag, ATTR_TOP_MARGIN, &top); - parsedtag_get_value(tag, ATTR_BOTTOM_MARGIN, &bottom); - if (form_id < 0 || form_id > form_max || forms == NULL) - break; /* outside of <form>..</form> */ - form = forms[form_id]; - if (hseq > 0) { - int hpos = pos; - if (*str == '[') - hpos++; - buf->hmarklist = - putHmarker(buf->hmarklist, currentLn(buf), - hpos, hseq - 1); - } - if (!form->target) - form->target = buf->baseTarget; - if (a_textarea && - parsedtag_get_value(tag, ATTR_TEXTAREANUMBER, - &textareanumber)) { - if (textareanumber >= max_textarea) { - max_textarea = 2 * textareanumber; - textarea_str = New_Reuse(Str, textarea_str, - max_textarea); - a_textarea = New_Reuse(Anchor *, a_textarea, - max_textarea); - } - } -#ifdef MENU_SELECT - if (a_select && - parsedtag_get_value(tag, ATTR_SELECTNUMBER, - &selectnumber)) { - if (selectnumber >= max_select) { - max_select = 2 * selectnumber; - select_option = New_Reuse(FormSelectOption, - select_option, - max_select); - a_select = New_Reuse(Anchor *, a_select, - max_select); - } - } -#endif - a_form = - registerForm(buf, form, tag, currentLn(buf), pos); - if (a_textarea && textareanumber >= 0) - a_textarea[textareanumber] = a_form; -#ifdef MENU_SELECT - if (a_select && selectnumber >= 0) - a_select[selectnumber] = a_form; -#endif - if (a_form) { - a_form->hseq = hseq - 1; - a_form->y = currentLn(buf) - top; - a_form->rows = 1 + top + bottom; - if (!parsedtag_exists(tag, ATTR_NO_EFFECT)) - effect |= PE_FORM; - break; - } - } - case HTML_N_INPUT_ALT: - effect &= ~PE_FORM; - if (a_form) { - a_form->end.line = currentLn(buf); - a_form->end.pos = pos; - if (a_form->start.line == a_form->end.line && - a_form->start.pos == a_form->end.pos) - a_form->hseq = -1; - } - a_form = NULL; - break; - case HTML_MAP: - if (parsedtag_get_value(tag, ATTR_NAME, &p)) { - MapList *m = New(MapList); - m->name = Strnew_charp(p); - m->area = newGeneralList(); - m->next = buf->maplist; - buf->maplist = m; - } - break; - case HTML_N_MAP: - /* nothing to do */ - break; - case HTML_AREA: - if (buf->maplist == NULL) /* outside of <map>..</map> */ - break; - if (parsedtag_get_value(tag, ATTR_HREF, &p)) { - MapArea *a; - p = url_quote_conv(remove_space(p), - buf->document_charset); - t = NULL; - parsedtag_get_value(tag, ATTR_TARGET, &t); - q = ""; - parsedtag_get_value(tag, ATTR_ALT, &q); - r = NULL; - s = NULL; -#ifdef USE_IMAGE - parsedtag_get_value(tag, ATTR_SHAPE, &r); - parsedtag_get_value(tag, ATTR_COORDS, &s); -#endif - a = newMapArea(p, t, q, r, s); - pushValue(buf->maplist->area, (void *)a); - } - break; - case HTML_FRAMESET: - frameset_sp++; - if (frameset_sp >= FRAMESTACK_SIZE) - break; - frameset_s[frameset_sp] = newFrameSet(tag); - if (frameset_s[frameset_sp] == NULL) - break; - if (frameset_sp == 0) { - if (buf->frameset == NULL) { - buf->frameset = frameset_s[frameset_sp]; - } - else - pushFrameTree(&(buf->frameQ), - frameset_s[frameset_sp], NULL); - } - else - addFrameSetElement(frameset_s[frameset_sp - 1], - *(union frameset_element *) - &frameset_s[frameset_sp]); - break; - case HTML_N_FRAMESET: - if (frameset_sp >= 0) - frameset_sp--; - break; - case HTML_FRAME: - if (frameset_sp >= 0 && frameset_sp < FRAMESTACK_SIZE) { - union frameset_element element; - - element.body = newFrame(tag, buf); - addFrameSetElement(frameset_s[frameset_sp], element); - } - break; - case HTML_BASE: - if (parsedtag_get_value(tag, ATTR_HREF, &p)) { - p = url_quote_conv(remove_space(p), - buf->document_charset); - if (!buf->baseURL) - buf->baseURL = New(ParsedURL); - parseURL(p, buf->baseURL, NULL); - } - if (parsedtag_get_value(tag, ATTR_TARGET, &p)) - buf->baseTarget = - url_quote_conv(p, buf->document_charset); - break; - case HTML_META: - p = q = NULL; - parsedtag_get_value(tag, ATTR_HTTP_EQUIV, &p); - parsedtag_get_value(tag, ATTR_CONTENT, &q); - if (p && q && !strcasecmp(p, "refresh") && MetaRefresh) { - Str tmp = NULL; - int refresh_interval = getMetaRefreshParam(q, &tmp); -#ifdef USE_ALARM - if (tmp) { - p = url_quote_conv(remove_space(tmp->ptr), - buf->document_charset); - buf->event = setAlarmEvent(buf->event, - refresh_interval, - AL_IMPLICIT_ONCE, - FUNCNAME_gorURL, p); - } - else if (refresh_interval > 0) - buf->event = setAlarmEvent(buf->event, - refresh_interval, - AL_IMPLICIT, - FUNCNAME_reload, NULL); -#else - if (tmp && refresh_interval == 0) { - p = url_quote_conv(remove_space(tmp->ptr), - buf->document_charset); - pushEvent(FUNCNAME_gorURL, p); - } -#endif - } - break; - case HTML_INTERNAL: - internal = HTML_INTERNAL; - break; - case HTML_N_INTERNAL: - internal = HTML_N_INTERNAL; - break; - case HTML_FORM_INT: - if (parsedtag_get_value(tag, ATTR_FID, &form_id)) - process_form_int(tag, form_id); - break; - case HTML_TEXTAREA_INT: - if (parsedtag_get_value(tag, ATTR_TEXTAREANUMBER, - &n_textarea) - && n_textarea < max_textarea) { - textarea_str[n_textarea] = Strnew(); - } - else - n_textarea = -1; - break; - case HTML_N_TEXTAREA_INT: - if (n_textarea >= 0) { - FormItemList *item = - (FormItemList *)a_textarea[n_textarea]->url; - item->init_value = item->value = - textarea_str[n_textarea]; - } - break; -#ifdef MENU_SELECT - case HTML_SELECT_INT: - if (parsedtag_get_value(tag, ATTR_SELECTNUMBER, &n_select) - && n_select < max_select) { - select_option[n_select].first = NULL; - select_option[n_select].last = NULL; - } - else - n_select = -1; - break; - case HTML_N_SELECT_INT: - if (n_select >= 0) { - FormItemList *item = - (FormItemList *)a_select[n_select]->url; - item->select_option = select_option[n_select].first; - chooseSelectOption(item, item->select_option); - item->init_selected = item->selected; - item->init_value = item->value; - item->init_label = item->label; - } - break; - case HTML_OPTION_INT: - if (n_select >= 0) { - int selected; - q = ""; - parsedtag_get_value(tag, ATTR_LABEL, &q); - p = q; - parsedtag_get_value(tag, ATTR_VALUE, &p); - selected = parsedtag_exists(tag, ATTR_SELECTED); - addSelectOption(&select_option[n_select], - Strnew_charp(p), Strnew_charp(q), - selected); - } - break; -#endif - case HTML_TITLE_ALT: - if (parsedtag_get_value(tag, ATTR_TITLE, &p)) - buf->buffername = html_unquote(p); - break; - case HTML_SYMBOL: - effect |= PC_SYMBOL; - if (parsedtag_get_value(tag, ATTR_TYPE, &p)) - symbol = (char)atoi(p); - break; - case HTML_N_SYMBOL: - effect &= ~PC_SYMBOL; - break; - } -#ifdef ID_EXT - id = NULL; - if (parsedtag_get_value(tag, ATTR_ID, &id)) { - id = url_quote_conv(id, buf->document_charset); - registerName(buf, id, currentLn(buf), pos); - } - if (renderFrameSet && - parsedtag_get_value(tag, ATTR_FRAMENAME, &p)) { - p = url_quote_conv(p, buf->document_charset); - if (!idFrame || strcmp(idFrame->body->name, p)) { - idFrame = search_frame(renderFrameSet, p); - if (idFrame && idFrame->body->attr != F_BODY) - idFrame = NULL; - } - } - if (id && idFrame) - idFrame->body->nameList = - putAnchor(idFrame->body->nameList, id, NULL, - (Anchor **)NULL, NULL, NULL, '\0', - currentLn(buf), pos); -#endif /* ID_EXT */ - } - } - /* end of processing for one line */ - if (!internal) - addnewline(buf, outc, outp, NULL, pos, -1, nlines); - if (internal == HTML_N_INTERNAL) - internal = 0; - if (str != endp) { - line = Strsubstr(line, str - line->ptr, endp - str); - goto proc_again; - } - } -#ifdef DEBUG - if (w3m_debug) - fclose(debug); -#endif - for (form_id = 1; form_id <= form_max; form_id++) - forms[form_id]->next = forms[form_id - 1]; - buf->formlist = (form_max >= 0) ? forms[form_max] : NULL; - if (n_textarea) - addMultirowsForm(buf, buf->formitem); -#ifdef USE_IMAGE - addMultirowsImg(buf, buf->img); -#endif -} - -static void -addLink(Buffer *buf, struct parsed_tag *tag) -{ - char *href = NULL, *title = NULL, *ctype = NULL, *rel = NULL, *rev = NULL; - char type = LINK_TYPE_NONE; - LinkList *l; - - parsedtag_get_value(tag, ATTR_HREF, &href); - if (href) - href = url_quote_conv(remove_space(href), buf->document_charset); - parsedtag_get_value(tag, ATTR_TITLE, &title); - parsedtag_get_value(tag, ATTR_TYPE, &ctype); - parsedtag_get_value(tag, ATTR_REL, &rel); - if (rel != NULL) { - /* forward link type */ - type = LINK_TYPE_REL; - if (title == NULL) - title = rel; - } - parsedtag_get_value(tag, ATTR_REV, &rev); - if (rev != NULL) { - /* reverse link type */ - type = LINK_TYPE_REV; - if (title == NULL) - title = rev; - } - - l = New(LinkList); - l->url = href; - l->title = title; - l->ctype = ctype; - l->type = type; - l->next = NULL; - if (buf->linklist) { - LinkList *i; - for (i = buf->linklist; i->next; i = i->next) ; - i->next = l; - } - else - buf->linklist = l; -} - -void -HTMLlineproc2(Buffer *buf, TextLineList *tl) -{ - _tl_lp2 = tl->first; - HTMLlineproc2body(buf, textlist_feed, -1); -} - -static InputStream _file_lp2; - -static Str -file_feed() -{ - Str s; - s = StrISgets(_file_lp2); - if (s->length == 0) { - ISclose(_file_lp2); - return NULL; - } - return s; -} - -void -HTMLlineproc3(Buffer *buf, InputStream stream) -{ - _file_lp2 = stream; - HTMLlineproc2body(buf, file_feed, -1); -} - -static void -proc_escape(struct readbuffer *obuf, char **str_return) -{ - char *str = *str_return, *estr; - int ech = getescapechar(str_return); - int width, n_add = *str_return - str; - Lineprop mode = PC_ASCII; - - if (ech < 0) { - *str_return = str; - proc_mchar(obuf, obuf->flag & RB_SPECIAL, 1, str_return, PC_ASCII); - return; - } - mode = IS_CNTRL(ech) ? PC_CTRL : PC_ASCII; - - estr = conv_entity(ech); - check_breakpoint(obuf, obuf->flag & RB_SPECIAL, estr); - width = get_strwidth(estr); - if (width == 1 && ech == (unsigned char)*estr && - ech != '&' && ech != '<' && ech != '>') { - if (IS_CNTRL(ech)) - mode = PC_CTRL; - push_charp(obuf, width, estr, mode); - } - else - push_nchars(obuf, width, str, n_add, mode); - set_prevchar(obuf->prevchar, estr, strlen(estr)); - obuf->prev_ctype = mode; -} - - -static int -need_flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, - Lineprop mode) -{ - char ch; - - if (obuf->flag & RB_PRE_INT) { - if (obuf->pos > h_env->limit) - return 1; - else - return 0; - } - - ch = Strlastchar(obuf->line); - /* if (ch == ' ' && obuf->tag_sp > 0) */ - if (ch == ' ') - return 0; - - if (obuf->pos > h_env->limit) - return 1; - - return 0; -} - -static int -table_width(struct html_feed_environ *h_env, int table_level) -{ - int width; - if (table_level < 0) - return 0; - width = tables[table_level]->total_width; - if (table_level > 0 || width > 0) - return width; - return h_env->limit - h_env->envs[h_env->envc].indent; -} - -/* HTML processing first pass */ -void -HTMLlineproc0(char *line, struct html_feed_environ *h_env, int internal) -{ - Lineprop mode; - int cmd; - struct readbuffer *obuf = h_env->obuf; - int indent, delta; - struct parsed_tag *tag; - Str tokbuf; - struct table *tbl = NULL; - struct table_mode *tbl_mode = NULL; - int tbl_width = 0; -#ifdef USE_M17N - int is_hangul, prev_is_hangul = 0; -#endif - -#ifdef DEBUG - if (w3m_debug) { - FILE *f = fopen("zzzproc1", "a"); - fprintf(f, "%c%c%c%c", - (obuf->flag & RB_PREMODE) ? 'P' : ' ', - (obuf->table_level >= 0) ? 'T' : ' ', - (obuf->flag & RB_INTXTA) ? 'X' : ' ', - (obuf->flag & (RB_SCRIPT | RB_STYLE)) ? 'S' : ' '); - fprintf(f, "HTMLlineproc1(\"%s\",%d,%lx)\n", line, h_env->limit, - (unsigned long)h_env); - fclose(f); - } -#endif - - tokbuf = Strnew(); - - table_start: - if (obuf->table_level >= 0) { - int level = min(obuf->table_level, MAX_TABLE - 1); - tbl = tables[level]; - tbl_mode = &table_mode[level]; - tbl_width = table_width(h_env, level); - } - - while (*line != '\0') { - char *str, *p; - int is_tag = FALSE; - int pre_mode = (obuf->table_level >= 0) ? tbl_mode->pre_mode : - obuf->flag; - int end_tag = (obuf->table_level >= 0) ? tbl_mode->end_tag : - obuf->end_tag; - - if (*line == '<' || obuf->status != R_ST_NORMAL) { - /* - * Tag processing - */ - if (obuf->status == R_ST_EOL) - obuf->status = R_ST_NORMAL; - else { - read_token(h_env->tagbuf, &line, &obuf->status, - pre_mode & RB_PREMODE, obuf->status != R_ST_NORMAL); - if (obuf->status != R_ST_NORMAL) - return; - } - if (h_env->tagbuf->length == 0) - continue; - str = h_env->tagbuf->ptr; - if (*str == '<') { - if (str[1] && REALLY_THE_BEGINNING_OF_A_TAG(str)) - is_tag = TRUE; - else if (!(pre_mode & (RB_PLAIN | RB_INTXTA | RB_INSELECT | - RB_SCRIPT | RB_STYLE | RB_TITLE))) { - line = Strnew_m_charp(str + 1, line, NULL)->ptr; - str = "<"; - } - } - } - else { - read_token(tokbuf, &line, &obuf->status, pre_mode & RB_PREMODE, 0); - if (obuf->status != R_ST_NORMAL) /* R_ST_AMP ? */ - obuf->status = R_ST_NORMAL; - str = tokbuf->ptr; - } - - if (pre_mode & (RB_PLAIN | RB_INTXTA | RB_INSELECT | RB_SCRIPT | - RB_STYLE | RB_TITLE)) { - if (is_tag) { - p = str; - if ((tag = parse_tag(&p, internal))) { - if (tag->tagid == end_tag || - (pre_mode & RB_INSELECT && tag->tagid == HTML_N_FORM) - || (pre_mode & RB_TITLE - && (tag->tagid == HTML_N_HEAD - || tag->tagid == HTML_BODY))) - goto proc_normal; - } - } - /* title */ - if (pre_mode & RB_TITLE) { - feed_title(str); - continue; - } - /* select */ - if (pre_mode & RB_INSELECT) { - if (obuf->table_level >= 0) - goto proc_normal; - feed_select(str); - continue; - } - if (is_tag) { - if (strncmp(str, "<!--", 4) && (p = strchr(str + 1, '<'))) { - str = Strnew_charp_n(str, p - str)->ptr; - line = Strnew_m_charp(p, line, NULL)->ptr; - } - is_tag = FALSE; - } - if (obuf->table_level >= 0) - goto proc_normal; - /* textarea */ - if (pre_mode & RB_INTXTA) { - feed_textarea(str); - continue; - } - /* script */ - if (pre_mode & RB_SCRIPT) - continue; - /* style */ - if (pre_mode & RB_STYLE) - continue; - } - - proc_normal: - if (obuf->table_level >= 0) { - /* - * within table: in <table>..</table>, all input tokens - * are fed to the table renderer, and then the renderer - * makes HTML output. - */ - switch (feed_table(tbl, str, tbl_mode, tbl_width, internal)) { - case 0: - /* </table> tag */ - obuf->table_level--; - if (obuf->table_level >= MAX_TABLE - 1) - continue; - end_table(tbl); - if (obuf->table_level >= 0) { - struct table *tbl0 = tables[obuf->table_level]; - str = Sprintf("<table_alt tid=%d>", tbl0->ntable)->ptr; - pushTable(tbl0, tbl); - tbl = tbl0; - tbl_mode = &table_mode[obuf->table_level]; - tbl_width = table_width(h_env, obuf->table_level); - feed_table(tbl, str, tbl_mode, tbl_width, TRUE); - continue; - /* continue to the next */ - } - if (obuf->flag & RB_DEL) - continue; - /* all tables have been read */ - if (tbl->vspace > 0 && !(obuf->flag & RB_IGNORE_P)) { - int indent = h_env->envs[h_env->envc].indent; - flushline(h_env, obuf, indent, 0, h_env->limit); - do_blankline(h_env, obuf, indent, 0, h_env->limit); - } - save_fonteffect(h_env, obuf); - renderTable(tbl, tbl_width, h_env); - restore_fonteffect(h_env, obuf); - obuf->flag &= ~RB_IGNORE_P; - if (tbl->vspace > 0) { - int indent = h_env->envs[h_env->envc].indent; - do_blankline(h_env, obuf, indent, 0, h_env->limit); - obuf->flag |= RB_IGNORE_P; - } - set_space_to_prevchar(obuf->prevchar); - continue; - case 1: - /* <table> tag */ - break; - default: - continue; - } - } - - if (is_tag) { -/*** Beginning of a new tag ***/ - if ((tag = parse_tag(&str, internal))) - cmd = tag->tagid; - else - continue; - /* process tags */ - if (HTMLtagproc1(tag, h_env) == 0) { - /* preserve the tag for second-stage processing */ - if (parsedtag_need_reconstruct(tag)) - h_env->tagbuf = parsedtag2str(tag); - push_tag(obuf, h_env->tagbuf->ptr, cmd); - } -#ifdef ID_EXT - else { - process_idattr(obuf, cmd, tag); - } -#endif /* ID_EXT */ - obuf->bp.init_flag = 1; - clear_ignore_p_flag(cmd, obuf); - if (cmd == HTML_TABLE) - goto table_start; - else - continue; - } - - if (obuf->flag & (RB_DEL | RB_S)) - continue; - while (*str) { - mode = get_mctype(str); - delta = get_mcwidth(str); - if (obuf->flag & (RB_SPECIAL & ~RB_NOBR)) { - char ch = *str; - if (!(obuf->flag & RB_PLAIN) && (*str == '&')) { - char *p = str; - int ech = getescapechar(&p); - if (ech == '\n' || ech == '\r') { - ch = '\n'; - str = p - 1; - } - else if (ech == '\t') { - ch = '\t'; - str = p - 1; - } - } - if (ch != '\n') - obuf->flag &= ~RB_IGNORE_P; - if (ch == '\n') { - str++; - if (obuf->flag & RB_IGNORE_P) { - obuf->flag &= ~RB_IGNORE_P; - continue; - } - if (obuf->flag & RB_PRE_INT) - PUSH(' '); - else - flushline(h_env, obuf, h_env->envs[h_env->envc].indent, - 1, h_env->limit); - } - else if (ch == '\t') { - do { - PUSH(' '); - } while ((h_env->envs[h_env->envc].indent + obuf->pos) - % Tabstop != 0); - str++; - } - else if (obuf->flag & RB_PLAIN) { - char *p = html_quote_char(*str); - if (p) { - push_charp(obuf, 1, p, PC_ASCII); - str++; - } - else { - proc_mchar(obuf, 1, delta, &str, mode); - } - } - else { - if (*str == '&') - proc_escape(obuf, &str); - else - proc_mchar(obuf, 1, delta, &str, mode); - } - if (obuf->flag & (RB_SPECIAL & ~RB_PRE_INT)) - continue; - } - else { - if (!IS_SPACE(*str)) - obuf->flag &= ~RB_IGNORE_P; - if ((mode == PC_ASCII || mode == PC_CTRL) && IS_SPACE(*str)) { - if (*obuf->prevchar->ptr != ' ') { - PUSH(' '); - } - str++; - } - else { -#ifdef USE_M17N - if (mode == PC_KANJI1) - is_hangul = wtf_is_hangul((wc_uchar *) str); - else - is_hangul = 0; - if (mode == PC_KANJI1 && - !is_hangul && !prev_is_hangul && - obuf->pos > h_env->envs[h_env->envc].indent && - Strlastchar(obuf->line) == ' ') { - while (obuf->line->length >= 2 && - !strncmp(obuf->line->ptr + obuf->line->length - - 2, " ", 2) - && obuf->pos >= h_env->envs[h_env->envc].indent) { - Strshrink(obuf->line, 1); - obuf->pos--; - } - if (obuf->line->length >= 3 && - obuf->prev_ctype == PC_KANJI1 && - Strlastchar(obuf->line) == ' ' && - obuf->pos >= h_env->envs[h_env->envc].indent) { - Strshrink(obuf->line, 1); - obuf->pos--; - } - } - prev_is_hangul = is_hangul; -#endif - if (*str == '&') - proc_escape(obuf, &str); - else - proc_mchar(obuf, obuf->flag & RB_SPECIAL, delta, &str, - mode); - } - } - if (need_flushline(h_env, obuf, mode)) { - char *bp = obuf->line->ptr + obuf->bp.len; - char *tp = bp - obuf->bp.tlen; - int i = 0; - - if (tp > obuf->line->ptr && tp[-1] == ' ') - i = 1; - - indent = h_env->envs[h_env->envc].indent; - if (obuf->bp.pos - i > indent) { - Str line; - append_tags(obuf); - line = Strnew_charp(bp); - Strshrink(obuf->line, obuf->line->length - obuf->bp.len); -#ifdef FORMAT_NICE - if (obuf->pos - i > h_env->limit) - obuf->flag |= RB_FILL; -#endif /* FORMAT_NICE */ - back_to_breakpoint(obuf); - flushline(h_env, obuf, indent, 0, h_env->limit); -#ifdef FORMAT_NICE - obuf->flag &= ~RB_FILL; -#endif /* FORMAT_NICE */ - HTMLlineproc1(line->ptr, h_env); - } - } - } - } - if (!(obuf->flag & (RB_SPECIAL | RB_INTXTA | RB_INSELECT))) { - char *tp; - int i = 0; - - if (obuf->bp.pos == obuf->pos) { - tp = &obuf->line->ptr[obuf->bp.len - obuf->bp.tlen]; - } - else { - tp = &obuf->line->ptr[obuf->line->length]; - } - - if (tp > obuf->line->ptr && tp[-1] == ' ') - i = 1; - indent = h_env->envs[h_env->envc].indent; - if (obuf->pos - i > h_env->limit) { -#ifdef FORMAT_NICE - obuf->flag |= RB_FILL; -#endif /* FORMAT_NICE */ - flushline(h_env, obuf, indent, 0, h_env->limit); -#ifdef FORMAT_NICE - obuf->flag &= ~RB_FILL; -#endif /* FORMAT_NICE */ - } - } -} - -extern char *NullLine; -extern Lineprop NullProp[]; - -#ifndef USE_ANSI_COLOR -#define addnewline2(a,b,c,d,e,f) _addnewline2(a,b,c,e,f) -#endif -static void -addnewline2(Buffer *buf, char *line, Lineprop *prop, Linecolor *color, int pos, - int nlines) -{ - Line *l; - l = New(Line); - l->next = NULL; - l->lineBuf = line; - l->propBuf = prop; -#ifdef USE_ANSI_COLOR - l->colorBuf = color; -#endif - l->len = pos; - l->width = -1; - l->size = pos; - l->bpos = 0; - l->bwidth = 0; - l->prev = buf->currentLine; - if (buf->currentLine) { - l->next = buf->currentLine->next; - buf->currentLine->next = l; - } - else - l->next = NULL; - if (buf->lastLine == NULL || buf->lastLine == buf->currentLine) - buf->lastLine = l; - buf->currentLine = l; - if (buf->firstLine == NULL) - buf->firstLine = l; - l->linenumber = ++buf->allLine; - if (nlines < 0) { - /* l->real_linenumber = l->linenumber; */ - l->real_linenumber = 0; - } - else { - l->real_linenumber = nlines; - } - l = NULL; -} - -static void -addnewline(Buffer *buf, char *line, Lineprop *prop, Linecolor *color, int pos, - int width, int nlines) -{ - char *s; - Lineprop *p; -#ifdef USE_ANSI_COLOR - Linecolor *c; -#endif - Line *l; - int i, bpos, bwidth; - - if (pos > 0) { - s = allocStr(line, pos); - p = NewAtom_N(Lineprop, pos); - bcopy((void *)prop, (void *)p, pos * sizeof(Lineprop)); - } - else { - s = NullLine; - p = NullProp; - } -#ifdef USE_ANSI_COLOR - if (pos > 0 && color) { - c = NewAtom_N(Linecolor, pos); - bcopy((void *)color, (void *)c, pos * sizeof(Linecolor)); - } - else { - c = NULL; - } -#endif - addnewline2(buf, s, p, c, pos, nlines); - if (pos <= 0 || width <= 0) - return; - bpos = 0; - bwidth = 0; - while (1) { - l = buf->currentLine; - l->bpos = bpos; - l->bwidth = bwidth; - i = columnLen(l, width); - if (i == 0) { - i++; -#ifdef USE_M17N - while (i < l->len && p[i] & PC_WCHAR2) - i++; -#endif - } - l->len = i; - l->width = COLPOS(l, l->len); - if (pos <= i) - return; - bpos += l->len; - bwidth += l->width; - s += i; - p += i; -#ifdef USE_ANSI_COLOR - if (c) - c += i; -#endif - pos -= i; - addnewline2(buf, s, p, c, pos, nlines); - } -} - -/* - * loadHTMLBuffer: read file and make new buffer - */ -Buffer * -loadHTMLBuffer(URLFile *f, Buffer *newBuf) -{ - FILE *src = NULL; - Str tmp; - - if (newBuf == NULL) - newBuf = newBuffer(INIT_BUFFER_WIDTH); - if (newBuf->sourcefile == NULL && - (f->scheme != SCM_LOCAL || newBuf->mailcap)) { - tmp = tmpfname(TMPF_SRC, ".html"); - src = fopen(tmp->ptr, "w"); - if (src) - newBuf->sourcefile = tmp->ptr; - } - - loadHTMLstream(f, newBuf, src, newBuf->bufferprop & BP_FRAME); - - newBuf->topLine = newBuf->firstLine; - newBuf->lastLine = newBuf->currentLine; - newBuf->currentLine = newBuf->firstLine; - if (n_textarea) - formResetBuffer(newBuf, newBuf->formitem); - if (src) - fclose(src); - - return newBuf; -} - -static char *_size_unit[] = { "b", "kb", "Mb", "Gb", "Tb", - "Pb", "Eb", "Zb", "Bb", "Yb", NULL -}; - -char * -convert_size(clen_t size, int usefloat) -{ - float csize; - int sizepos = 0; - char **sizes = _size_unit; - - csize = (float)size; - while (csize >= 999.495 && sizes[sizepos + 1]) { - csize = csize / 1024.0; - sizepos++; - } - return Sprintf(usefloat ? "%.3g%s" : "%.0f%s", - floor(csize * 100.0 + 0.5) / 100.0, sizes[sizepos])->ptr; -} - -char * -convert_size2(clen_t size1, clen_t size2, int usefloat) -{ - char **sizes = _size_unit; - float csize, factor = 1; - int sizepos = 0; - - csize = (float)((size1 > size2) ? size1 : size2); - while (csize / factor >= 999.495 && sizes[sizepos + 1]) { - factor *= 1024.0; - sizepos++; - } - return Sprintf(usefloat ? "%.3g/%.3g%s" : "%.0f/%.0f%s", - floor(size1 / factor * 100.0 + 0.5) / 100.0, - floor(size2 / factor * 100.0 + 0.5) / 100.0, - sizes[sizepos])->ptr; -} - -void -showProgress(clen_t * linelen, clen_t * trbyte) -{ - int i, j, rate, duration, eta, pos; - static time_t last_time, start_time; - time_t cur_time; - Str messages; - char *fmtrbyte, *fmrate; - - if (!fmInitialized) - return; - - if (*linelen < 1024) - return; - if (current_content_length > 0) { - double ratio; - cur_time = time(0); - if (*trbyte == 0) { - move(LASTLINE, 0); - clrtoeolx(); - start_time = cur_time; - } - *trbyte += *linelen; - *linelen = 0; - if (cur_time == last_time) - return; - last_time = cur_time; - move(LASTLINE, 0); - ratio = 100.0 * (*trbyte) / current_content_length; - fmtrbyte = convert_size2(*trbyte, current_content_length, 1); - duration = cur_time - start_time; - if (duration) { - rate = *trbyte / duration; - fmrate = convert_size(rate, 1); - eta = rate ? (current_content_length - *trbyte) / rate : -1; - messages = Sprintf("%11s %3.0f%% " - "%7s/s " - "eta %02d:%02d:%02d ", - fmtrbyte, ratio, - fmrate, - eta / (60 * 60), (eta / 60) % 60, eta % 60); - } - else { - messages = Sprintf("%11s %3.0f%% ", - fmtrbyte, ratio); - } - addstr(messages->ptr); - pos = 42; - i = pos + (COLS - pos - 1) * (*trbyte) / current_content_length; - move(LASTLINE, pos); - standout(); - addch(' '); - for (j = pos + 1; j <= i; j++) - addch('|'); - standend(); - /* no_clrtoeol(); */ - refresh(); - } - else { - cur_time = time(0); - if (*trbyte == 0) { - move(LASTLINE, 0); - clrtoeolx(); - start_time = cur_time; - } - *trbyte += *linelen; - *linelen = 0; - if (cur_time == last_time) - return; - last_time = cur_time; - move(LASTLINE, 0); - fmtrbyte = convert_size(*trbyte, 1); - duration = cur_time - start_time; - if (duration) { - fmrate = convert_size(*trbyte / duration, 1); - messages = Sprintf("%7s loaded %7s/s", fmtrbyte, fmrate); - } - else { - messages = Sprintf("%7s loaded", fmtrbyte); - } - message(messages->ptr, 0, 0); - refresh(); - } -} - -void -init_henv(struct html_feed_environ *h_env, struct readbuffer *obuf, - struct environment *envs, int nenv, TextLineList *buf, - int limit, int indent) -{ - envs[0].indent = indent; - - obuf->line = Strnew(); - obuf->cprop = 0; - obuf->pos = 0; - obuf->prevchar = Strnew_size(8); - set_space_to_prevchar(obuf->prevchar); - obuf->flag = RB_IGNORE_P; - obuf->flag_sp = 0; - obuf->status = R_ST_NORMAL; - obuf->table_level = -1; - obuf->nobr_level = 0; - bzero((void *)&obuf->anchor, sizeof(obuf->anchor)); - obuf->img_alt = 0; - obuf->in_bold = 0; - obuf->in_under = 0; - obuf->prev_ctype = PC_ASCII; - obuf->tag_sp = 0; - obuf->fontstat_sp = 0; - obuf->top_margin = 0; - obuf->bottom_margin = 0; - obuf->bp.init_flag = 1; - set_breakpoint(obuf, 0); - - h_env->buf = buf; - h_env->f = NULL; - h_env->obuf = obuf; - h_env->tagbuf = Strnew(); - h_env->limit = limit; - h_env->maxlimit = 0; - h_env->envs = envs; - h_env->nenv = nenv; - h_env->envc = 0; - h_env->envc_real = 0; - h_env->title = NULL; - h_env->blank_lines = 0; -} - -void -completeHTMLstream(struct html_feed_environ *h_env, struct readbuffer *obuf) -{ - close_anchor(h_env, obuf); - if (obuf->img_alt) { - push_tag(obuf, "</img_alt>", HTML_N_IMG_ALT); - obuf->img_alt = NULL; - } - if (obuf->in_bold) { - push_tag(obuf, "</b>", HTML_N_B); - obuf->in_bold = 0; - } - if (obuf->in_under) { - push_tag(obuf, "</u>", HTML_N_U); - obuf->in_under = 0; - } - if (obuf->flag & RB_INTXTA) - HTMLlineproc1("</textarea>", h_env); - /* for unbalanced select tag */ - if (obuf->flag & RB_INSELECT) - HTMLlineproc1("</select>", h_env); - if (obuf->flag & RB_TITLE) - HTMLlineproc1("</title>", h_env); - - /* for unbalanced table tag */ - if (obuf->table_level >= MAX_TABLE) - obuf->table_level = MAX_TABLE - 1; - - while (obuf->table_level >= 0) { - table_mode[obuf->table_level].pre_mode - &= ~(TBLM_SCRIPT | TBLM_STYLE | TBLM_PLAIN); - HTMLlineproc1("</table>", h_env); - } -} - -static void -print_internal_information(struct html_feed_environ *henv) -{ - int i; - Str s; - TextLineList *tl = newTextLineList(); - - s = Strnew_charp("<internal>"); - pushTextLine(tl, newTextLine(s, 0)); - if (henv->title) { - s = Strnew_m_charp("<title_alt title=\"", - html_quote(henv->title), "\">", NULL); - pushTextLine(tl, newTextLine(s, 0)); - } -#if 0 - if (form_max >= 0) { - FormList *fp; - for (i = 0; i <= form_max; i++) { - fp = forms[i]; - s = Sprintf("<form_int fid=\"%d\" action=\"%s\" method=\"%s\"", - i, html_quote(fp->action->ptr), - (fp->method == FORM_METHOD_POST) ? "post" - : ((fp->method == - FORM_METHOD_INTERNAL) ? "internal" : "get")); - if (fp->target) - Strcat(s, Sprintf(" target=\"%s\"", html_quote(fp->target))); - if (fp->enctype == FORM_ENCTYPE_MULTIPART) - Strcat_charp(s, " enctype=\"multipart/form-data\""); -#ifdef USE_M17N - if (fp->charset) - Strcat(s, Sprintf(" accept-charset=\"%s\"", - html_quote(fp->charset))); -#endif - Strcat_charp(s, ">"); - pushTextLine(tl, newTextLine(s, 0)); - } - } -#endif -#ifdef MENU_SELECT - if (n_select > 0) { - FormSelectOptionItem *ip; - for (i = 0; i < n_select; i++) { - s = Sprintf("<select_int selectnumber=%d>", i); - pushTextLine(tl, newTextLine(s, 0)); - for (ip = select_option[i].first; ip; ip = ip->next) { - s = Sprintf("<option_int value=\"%s\" label=\"%s\"%s>", - html_quote(ip->value ? ip->value->ptr : - ip->label->ptr), - html_quote(ip->label->ptr), - ip->checked ? " selected" : ""); - pushTextLine(tl, newTextLine(s, 0)); - } - s = Strnew_charp("</select_int>"); - pushTextLine(tl, newTextLine(s, 0)); - } - } -#endif /* MENU_SELECT */ - if (n_textarea > 0) { - for (i = 0; i < n_textarea; i++) { - s = Sprintf("<textarea_int textareanumber=%d>", i); - pushTextLine(tl, newTextLine(s, 0)); - s = Strnew_charp(html_quote(textarea_str[i]->ptr)); - Strcat_charp(s, "</textarea_int>"); - pushTextLine(tl, newTextLine(s, 0)); - } - } - s = Strnew_charp("</internal>"); - pushTextLine(tl, newTextLine(s, 0)); - - if (henv->buf) - appendTextLineList(henv->buf, tl); - else if (henv->f) { - TextLineListItem *p; - for (p = tl->first; p; p = p->next) - fprintf(henv->f, "%s\n", Str_conv_to_halfdump(p->ptr->line)->ptr); - } -} - -void -loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal) -{ - struct environment envs[MAX_ENV_LEVEL]; - clen_t linelen = 0; - clen_t trbyte = 0; - Str lineBuf2 = Strnew(); -#ifdef USE_M17N - wc_ces charset = WC_CES_US_ASCII; - wc_ces volatile doc_charset = DocumentCharset; -#endif - struct html_feed_environ htmlenv1; - struct readbuffer obuf; -#ifdef USE_IMAGE - int volatile image_flag; -#endif - MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; - -#ifdef USE_M17N - if (fmInitialized && graph_ok()) { - symbol_width = symbol_width0 = 1; - } - else { - symbol_width0 = 0; - get_symbol(DisplayCharset, &symbol_width0); - symbol_width = WcOption.use_wide ? symbol_width0 : 1; - } -#else - symbol_width = symbol_width0 = 1; -#endif - - cur_title = NULL; - n_textarea = 0; - cur_textarea = NULL; - max_textarea = MAX_TEXTAREA; - textarea_str = New_N(Str, max_textarea); -#ifdef MENU_SELECT - n_select = 0; - max_select = MAX_SELECT; - select_option = New_N(FormSelectOption, max_select); -#endif /* MENU_SELECT */ - cur_select = NULL; - form_sp = -1; - form_max = -1; - forms_size = 0; - forms = NULL; - cur_hseq = 1; -#ifdef USE_IMAGE - cur_iseq = 1; - if (newBuf->image_flag) - image_flag = newBuf->image_flag; - else if (activeImage && displayImage && autoImage) - image_flag = IMG_FLAG_AUTO; - else - image_flag = IMG_FLAG_SKIP; - if (newBuf->currentURL.file) - cur_baseURL = baseURL(newBuf); -#endif - - if (w3m_halfload) { - newBuf->buffername = "---"; -#ifdef USE_M17N - newBuf->document_charset = InnerCharset; -#endif - max_textarea = 0; -#ifdef MENU_SELECT - max_select = 0; -#endif - HTMLlineproc3(newBuf, f->stream); - w3m_halfload = FALSE; - return; - } - - init_henv(&htmlenv1, &obuf, envs, MAX_ENV_LEVEL, NULL, newBuf->width, 0); - - if (w3m_halfdump) - htmlenv1.f = stdout; - else - htmlenv1.buf = newTextLineList(); - - if (SETJMP(AbortLoading) != 0) { - HTMLlineproc1("<br>Transfer Interrupted!<br>", &htmlenv1); - goto phase2; - } - TRAP_ON; - -#ifdef USE_M17N - if (newBuf != NULL) { - if (newBuf->bufferprop & BP_FRAME) - charset = InnerCharset; - else if (newBuf->document_charset) - charset = doc_charset = newBuf->document_charset; - } - if (content_charset && UseContentCharset) - doc_charset = content_charset; - meta_charset = 0; -#endif -#if 0 - do_blankline(&htmlenv1, &obuf, 0, 0, htmlenv1.limit); - obuf.flag = RB_IGNORE_P; -#endif - if (IStype(f->stream) != IST_ENCODED) - f->stream = newEncodedStream(f->stream, f->encoding); - while ((lineBuf2 = StrmyUFgets(f))->length) { -#ifdef USE_NNTP - if (f->scheme == SCM_NEWS && lineBuf2->ptr[0] == '.') { - Strshrinkfirst(lineBuf2, 1); - if (lineBuf2->ptr[0] == '\n' || lineBuf2->ptr[0] == '\r' || - lineBuf2->ptr[0] == '\0') { - /* - * iseos(f->stream) = TRUE; - */ - break; - } - } -#endif /* USE_NNTP */ - if (src) - Strfputs(lineBuf2, src); - linelen += lineBuf2->length; - if (w3m_dump & DUMP_EXTRA) - printf("W3m-in-progress: %s?n", convert_size2(linelen, current_content_length, TRUE)); - if (w3m_dump & DUMP_SOURCE) - continue; - showProgress(&linelen, &trbyte); - /* - * if (frame_source) - * continue; - */ -#ifdef USE_M17N - if (meta_charset) { /* <META> */ - if (content_charset == 0 && UseContentCharset) { - doc_charset = meta_charset; - charset = WC_CES_US_ASCII; - } - meta_charset = 0; - } -#endif - lineBuf2 = convertLine(f, lineBuf2, HTML_MODE, &charset, doc_charset); -#if defined(USE_M17N) && defined(USE_IMAGE) - cur_document_charset = charset; -#endif - HTMLlineproc0(lineBuf2->ptr, &htmlenv1, internal); - } - if (obuf.status != R_ST_NORMAL) { - obuf.status = R_ST_EOL; - HTMLlineproc0("\n", &htmlenv1, internal); - } - obuf.status = R_ST_NORMAL; - completeHTMLstream(&htmlenv1, &obuf); - flushline(&htmlenv1, &obuf, 0, 2, htmlenv1.limit); - if (htmlenv1.title) - newBuf->buffername = htmlenv1.title; - if (w3m_halfdump) { - TRAP_OFF; - print_internal_information(&htmlenv1); - return; - } - if (w3m_backend) { - TRAP_OFF; - print_internal_information(&htmlenv1); - backend_halfdump_buf = htmlenv1.buf; - return; - } - phase2: - newBuf->trbyte = trbyte + linelen; - TRAP_OFF; -#ifdef USE_M17N - if (!(newBuf->bufferprop & BP_FRAME)) - newBuf->document_charset = charset; -#endif -#ifdef USE_IMAGE - newBuf->image_flag = image_flag; -#endif - HTMLlineproc2(newBuf, htmlenv1.buf); -} - -/* - * loadHTMLString: read string and make new buffer - */ -Buffer * -loadHTMLString(Str page) -{ - URLFile f; - MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; - Buffer *newBuf; - - newBuf = newBuffer(INIT_BUFFER_WIDTH); - if (SETJMP(AbortLoading) != 0) { - TRAP_OFF; - discardBuffer(newBuf); - return NULL; - } - TRAP_ON; - - init_stream(&f, SCM_LOCAL, newStrStream(page)); - -#ifdef USE_M17N - newBuf->document_charset = InnerCharset; -#endif - loadHTMLstream(&f, newBuf, NULL, TRUE); -#ifdef USE_M17N - newBuf->document_charset = WC_CES_US_ASCII; -#endif - - TRAP_OFF; - newBuf->topLine = newBuf->firstLine; - newBuf->lastLine = newBuf->currentLine; - newBuf->currentLine = newBuf->firstLine; - newBuf->type = "text/html"; - newBuf->real_type = newBuf->type; - if (n_textarea) - formResetBuffer(newBuf, newBuf->formitem); - return newBuf; -} - -#ifdef USE_GOPHER - -/* - * loadGopherDir: get gopher directory - */ -Str -loadGopherDir(URLFile *uf, ParsedURL *pu, wc_ces * charset) -{ - Str volatile tmp; - Str lbuf, name, file, host, port; - char *volatile p, *volatile q; - MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; -#ifdef USE_M17N - wc_ces doc_charset = DocumentCharset; -#endif - - tmp = parsedURL2Str(pu); - p = html_quote(tmp->ptr); - tmp = - convertLine(NULL, Strnew_charp(file_unquote(tmp->ptr)), RAW_MODE, - charset, doc_charset); - q = html_quote(tmp->ptr); - tmp = Strnew_m_charp("<html>\n<head>\n<base href=\"", p, "\">\n<title>", q, - "</title>\n</head>\n<body>\n<h1>Index of ", q, - "</h1>\n<table>\n", NULL); - - if (SETJMP(AbortLoading) != 0) - goto gopher_end; - TRAP_ON; - - while (1) { - if (lbuf = StrUFgets(uf), lbuf->length == 0) - break; - if (lbuf->ptr[0] == '.' && - (lbuf->ptr[1] == '\n' || lbuf->ptr[1] == '\r')) - break; - lbuf = convertLine(uf, lbuf, HTML_MODE, charset, doc_charset); - p = lbuf->ptr; - for (q = p; *q && *q != '\t'; q++) ; - name = Strnew_charp_n(p, q - p); - if (!*q) - continue; - p = q + 1; - for (q = p; *q && *q != '\t'; q++) ; - file = Strnew_charp_n(p, q - p); - if (!*q) - continue; - p = q + 1; - for (q = p; *q && *q != '\t'; q++) ; - host = Strnew_charp_n(p, q - p); - if (!*q) - continue; - p = q + 1; - for (q = p; *q && *q != '\t' && *q != '\r' && *q != '\n'; q++) ; - port = Strnew_charp_n(p, q - p); - - switch (name->ptr[0]) { - case '0': - p = "[text file]"; - break; - case '1': - p = "[directory]"; - break; - case 'm': - p = "[message]"; - break; - case 's': - p = "[sound]"; - break; - case 'g': - p = "[gif]"; - break; - case 'h': - p = "[HTML]"; - break; - default: - p = "[unsupported]"; - break; - } - q = Strnew_m_charp("gopher://", host->ptr, ":", port->ptr, - "/", file->ptr, NULL)->ptr; - Strcat_m_charp(tmp, "<a href=\"", - html_quote(url_quote_conv(q, *charset)), - "\">", p, html_quote(name->ptr + 1), "</a>\n", NULL); - } - - gopher_end: - TRAP_OFF; - - Strcat_charp(tmp, "</table>\n</body>\n</html>\n"); - return tmp; -} -#endif /* USE_GOPHER */ - -/* - * loadBuffer: read file and make new buffer - */ -Buffer * -loadBuffer(URLFile *uf, Buffer *volatile newBuf) -{ - FILE *volatile src = NULL; -#ifdef USE_M17N - wc_ces charset = WC_CES_US_ASCII; - wc_ces volatile doc_charset = DocumentCharset; -#endif - Str lineBuf2; - volatile char pre_lbuf = '\0'; - int nlines; - Str tmpf; - clen_t linelen = 0, trbyte = 0; - Lineprop *propBuffer = NULL; -#ifdef USE_ANSI_COLOR - Linecolor *colorBuffer = NULL; -#endif - MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; - - if (newBuf == NULL) - newBuf = newBuffer(INIT_BUFFER_WIDTH); - lineBuf2 = Strnew(); - - if (SETJMP(AbortLoading) != 0) { - goto _end; - } - TRAP_ON; - - if (newBuf->sourcefile == NULL && - (uf->scheme != SCM_LOCAL || newBuf->mailcap)) { - tmpf = tmpfname(TMPF_SRC, NULL); - src = fopen(tmpf->ptr, "w"); - if (src) - newBuf->sourcefile = tmpf->ptr; - } -#ifdef USE_M17N - if (newBuf->document_charset) - charset = doc_charset = newBuf->document_charset; - if (content_charset && UseContentCharset) - doc_charset = content_charset; -#endif - - nlines = 0; - if (IStype(uf->stream) != IST_ENCODED) - uf->stream = newEncodedStream(uf->stream, uf->encoding); - while ((lineBuf2 = StrmyISgets(uf->stream))->length) { -#ifdef USE_NNTP - if (uf->scheme == SCM_NEWS && lineBuf2->ptr[0] == '.') { - Strshrinkfirst(lineBuf2, 1); - if (lineBuf2->ptr[0] == '\n' || lineBuf2->ptr[0] == '\r' || - lineBuf2->ptr[0] == '\0') { - /* - * iseos(uf->stream) = TRUE; - */ - break; - } - } -#endif /* USE_NNTP */ - if (src) - Strfputs(lineBuf2, src); - linelen += lineBuf2->length; - if (w3m_dump & DUMP_SOURCE) - continue; - showProgress(&linelen, &trbyte); - if (frame_source) - continue; - lineBuf2 = - convertLine(uf, lineBuf2, PAGER_MODE, &charset, doc_charset); - if (squeezeBlankLine) { - if (lineBuf2->ptr[0] == '\n' && pre_lbuf == '\n') { - ++nlines; - continue; - } - pre_lbuf = lineBuf2->ptr[0]; - } - ++nlines; - Strchop(lineBuf2); - lineBuf2 = checkType(lineBuf2, &propBuffer, NULL); - addnewline(newBuf, lineBuf2->ptr, propBuffer, colorBuffer, - lineBuf2->length, FOLD_BUFFER_WIDTH, nlines); - } - _end: - TRAP_OFF; - newBuf->topLine = newBuf->firstLine; - newBuf->lastLine = newBuf->currentLine; - newBuf->currentLine = newBuf->firstLine; - newBuf->trbyte = trbyte + linelen; -#ifdef USE_M17N - newBuf->document_charset = charset; -#endif - if (src) - fclose(src); - - return newBuf; -} - -#ifdef USE_IMAGE -Buffer * -loadImageBuffer(URLFile *uf, Buffer *newBuf) -{ - Image image; - ImageCache *cache; - Str tmp, tmpf; - FILE *src = NULL; - URLFile f; - MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; - struct stat st; - - loadImage(newBuf, IMG_FLAG_STOP); - image.url = uf->url; - image.ext = uf->ext; - image.width = -1; - image.height = -1; - image.cache = NULL; - cache = getImage(&image, cur_baseURL, IMG_FLAG_AUTO); - if (!cur_baseURL->is_nocache && cache->loaded & IMG_FLAG_LOADED && - !stat(cache->file, &st)) - goto image_buffer; - - TRAP_ON; - if (IStype(uf->stream) != IST_ENCODED) - uf->stream = newEncodedStream(uf->stream, uf->encoding); - if (save2tmp(*uf, cache->file) < 0) { - UFclose(uf); - TRAP_OFF; - return NULL; - } - UFclose(uf); - TRAP_OFF; - - cache->loaded = IMG_FLAG_LOADED; - cache->index = 0; - - image_buffer: - if (newBuf == NULL) - newBuf = newBuffer(INIT_BUFFER_WIDTH); - cache->loaded |= IMG_FLAG_DONT_REMOVE; - if (newBuf->sourcefile == NULL && uf->scheme != SCM_LOCAL) - newBuf->sourcefile = cache->file; - - tmp = Sprintf("<img src=\"%s\"><br><br>", html_quote(image.url)); - tmpf = tmpfname(TMPF_SRC, ".html"); - src = fopen(tmpf->ptr, "w"); - newBuf->mailcap_source = tmpf->ptr; - - init_stream(&f, SCM_LOCAL, newStrStream(tmp)); - loadHTMLstream(&f, newBuf, src, TRUE); - if (src) - fclose(src); - - newBuf->topLine = newBuf->firstLine; - newBuf->lastLine = newBuf->currentLine; - newBuf->currentLine = newBuf->firstLine; - newBuf->image_flag = IMG_FLAG_AUTO; - return newBuf; -} -#endif - -static Str -conv_symbol(Line *l) -{ - Str tmp = NULL; - char *p = l->lineBuf, *ep = p + l->len; - Lineprop *pr = l->propBuf; -#ifdef USE_M17N - int w; - char **symbol = NULL; -#else - char **symbol = get_symbol(); -#endif - - for (; p < ep; p++, pr++) { - if (*pr & PC_SYMBOL) { -#ifdef USE_M17N - char c = ((char)wtf_get_code((wc_uchar *) p) & 0x7f) - SYMBOL_BASE; - int len = get_mclen(p); -#else - char c = *p - SYMBOL_BASE; -#endif - if (tmp == NULL) { - tmp = Strnew_size(l->len); - Strcopy_charp_n(tmp, l->lineBuf, p - l->lineBuf); -#ifdef USE_M17N - w = (*pr & PC_KANJI) ? 2 : 1; - symbol = get_symbol(DisplayCharset, &w); -#endif - } - Strcat_charp(tmp, symbol[(int)c]); -#ifdef USE_M17N - p += len - 1; - pr += len - 1; -#endif - } - else if (tmp != NULL) - Strcat_char(tmp, *p); - } - if (tmp) - return tmp; - else - return Strnew_charp_n(l->lineBuf, l->len); -} - -/* - * saveBuffer: write buffer to file - */ -static void -_saveBuffer(Buffer *buf, Line *l, FILE * f, int cont) -{ - Str tmp; - int is_html = FALSE; -#ifdef USE_M17N - int set_charset = !DisplayCharset; - wc_ces charset = DisplayCharset ? DisplayCharset : WC_CES_US_ASCII; -#endif - - if (buf->type && !strcasecmp(buf->type, "text/html")) - is_html = TRUE; - - pager_next: - for (; l != NULL; l = l->next) { - if (is_html) - tmp = conv_symbol(l); - else - tmp = Strnew_charp_n(l->lineBuf, l->len); - tmp = wc_Str_conv(tmp, InnerCharset, charset); - Strfputs(tmp, f); - if (Strlastchar(tmp) != '\n' && !(cont && l->next && l->next->bpos)) - putc('\n', f); - } - if (buf->pagerSource && !(buf->bufferprop & BP_CLOSE)) { - l = getNextPage(buf, PagerMax); -#ifdef USE_M17N - if (set_charset) - charset = buf->document_charset; -#endif - goto pager_next; - } -} - -void -saveBuffer(Buffer *buf, FILE * f, int cont) -{ - _saveBuffer(buf, buf->firstLine, f, cont); -} - -void -saveBufferBody(Buffer *buf, FILE * f, int cont) -{ - Line *l = buf->firstLine; - - while (l != NULL && l->real_linenumber == 0) - l = l->next; - _saveBuffer(buf, l, f, cont); -} - -static Buffer * -loadcmdout(char *cmd, - Buffer *(*loadproc) (URLFile *, Buffer *), Buffer *defaultbuf) -{ - FILE *f, *popen(const char *, const char *); - Buffer *buf; - URLFile uf; - - if (cmd == NULL || *cmd == '\0') - return NULL; - f = popen(cmd, "r"); - if (f == NULL) - return NULL; - init_stream(&uf, SCM_UNKNOWN, newFileStream(f, (void (*)())pclose)); - buf = loadproc(&uf, defaultbuf); - UFclose(&uf); - return buf; -} - -/* - * getshell: execute shell command and get the result into a buffer - */ -Buffer * -getshell(char *cmd) -{ - Buffer *buf; - - buf = loadcmdout(cmd, loadBuffer, NULL); - if (buf == NULL) - return NULL; - buf->filename = cmd; - buf->buffername = Sprintf("%s %s", SHELLBUFFERNAME, - conv_from_system(cmd))->ptr; - return buf; -} - -/* - * getpipe: execute shell command and connect pipe to the buffer - */ -Buffer * -getpipe(char *cmd) -{ - FILE *f, *popen(const char *, const char *); - Buffer *buf; - - if (cmd == NULL || *cmd == '\0') - return NULL; - f = popen(cmd, "r"); - if (f == NULL) - return NULL; - buf = newBuffer(INIT_BUFFER_WIDTH); - buf->pagerSource = newFileStream(f, (void (*)())pclose); - buf->filename = cmd; - buf->buffername = Sprintf("%s %s", PIPEBUFFERNAME, - conv_from_system(cmd))->ptr; - buf->bufferprop |= BP_PIPE; -#ifdef USE_M17N - buf->document_charset = WC_CES_US_ASCII; -#endif - return buf; -} - -/* - * Open pager buffer - */ -Buffer * -openPagerBuffer(InputStream stream, Buffer *buf) -{ - - if (buf == NULL) - buf = newBuffer(INIT_BUFFER_WIDTH); - buf->pagerSource = stream; - buf->buffername = getenv("MAN_PN"); - if (buf->buffername == NULL) - buf->buffername = PIPEBUFFERNAME; - else - buf->buffername = conv_from_system(buf->buffername); - buf->bufferprop |= BP_PIPE; -#ifdef USE_M17N - if (content_charset && UseContentCharset) - buf->document_charset = content_charset; - else - buf->document_charset = WC_CES_US_ASCII; -#endif - buf->currentLine = buf->firstLine; - - return buf; -} - -Buffer * -openGeneralPagerBuffer(InputStream stream) -{ - Buffer *buf; - char *t = "text/plain"; - Buffer *t_buf = NULL; - URLFile uf; - - init_stream(&uf, SCM_UNKNOWN, stream); - -#ifdef USE_M17N - content_charset = 0; -#endif - if (SearchHeader) { - t_buf = newBuffer(INIT_BUFFER_WIDTH); - readHeader(&uf, t_buf, TRUE, NULL); - t = checkContentType(t_buf); - if (t == NULL) - t = "text/plain"; - if (t_buf) { - t_buf->topLine = t_buf->firstLine; - t_buf->currentLine = t_buf->lastLine; - } - SearchHeader = FALSE; - } - else if (DefaultType) { - t = DefaultType; - DefaultType = NULL; - } - if (!strcasecmp(t, "text/html")) { - buf = loadHTMLBuffer(&uf, t_buf); - buf->type = "text/html"; - } - else if (is_plain_text_type(t)) { - if (IStype(stream) != IST_ENCODED) - stream = newEncodedStream(stream, uf.encoding); - buf = openPagerBuffer(stream, t_buf); - buf->type = "text/plain"; - } -#ifdef USE_IMAGE - else if (activeImage && displayImage && !useExtImageViewer && - !(w3m_dump & ~DUMP_FRAME) && !strncasecmp(t, "image/", 6)) { - cur_baseURL = New(ParsedURL); - parseURL("-", cur_baseURL, NULL); - buf = loadImageBuffer(&uf, t_buf); - buf->type = "text/html"; - } -#endif - else { - if (doExternal(uf, "-", t, &buf, t_buf)) { - UFclose(&uf); - if (buf == NULL || buf == NO_BUFFER) - return buf; - } - else { /* unknown type is regarded as text/plain */ - if (IStype(stream) != IST_ENCODED) - stream = newEncodedStream(stream, uf.encoding); - buf = openPagerBuffer(stream, t_buf); - buf->type = "text/plain"; - } - } - buf->real_type = t; - buf->currentURL.scheme = SCM_LOCAL; - buf->currentURL.file = "-"; - return buf; -} - -Line * -getNextPage(Buffer *buf, int plen) -{ - Line *volatile top = buf->topLine, *volatile last = buf->lastLine, - *volatile cur = buf->currentLine; - int i; - int volatile nlines = 0; - clen_t linelen = 0, trbyte = buf->trbyte; - Str lineBuf2; - char volatile pre_lbuf = '\0'; - URLFile uf; -#ifdef USE_M17N - wc_ces charset; - wc_ces volatile doc_charset = DocumentCharset; - wc_uint8 old_auto_detect = WcOption.auto_detect; -#endif - int volatile squeeze_flag = FALSE; - Lineprop *propBuffer = NULL; - -#ifdef USE_ANSI_COLOR - Linecolor *colorBuffer = NULL; -#endif - MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; - - if (buf->pagerSource == NULL) - return NULL; - - if (last != NULL) { - nlines = last->real_linenumber; - pre_lbuf = *(last->lineBuf); - if (pre_lbuf == '\0') - pre_lbuf = '\n'; - buf->currentLine = last; - } - -#ifdef USE_M17N - charset = buf->document_charset; - if (buf->document_charset != WC_CES_US_ASCII) - doc_charset = buf->document_charset; - else if (UseContentCharset) { - content_charset = 0; - checkContentType(buf); - if (content_charset) - doc_charset = content_charset; - } - WcOption.auto_detect = buf->auto_detect; -#endif - - if (SETJMP(AbortLoading) != 0) { - goto pager_end; - } - TRAP_ON; - - init_stream(&uf, SCM_UNKNOWN, NULL); - for (i = 0; i < plen; i++) { - lineBuf2 = StrmyISgets(buf->pagerSource); - if (lineBuf2->length == 0) { - /* Assume that `cmd == buf->filename' */ - if (buf->filename) - buf->buffername = Sprintf("%s %s", - CPIPEBUFFERNAME, - conv_from_system(buf->filename))-> - ptr; - else if (getenv("MAN_PN") == NULL) - buf->buffername = CPIPEBUFFERNAME; - buf->bufferprop |= BP_CLOSE; - break; - } - linelen += lineBuf2->length; - showProgress(&linelen, &trbyte); - lineBuf2 = - convertLine(&uf, lineBuf2, PAGER_MODE, &charset, doc_charset); - if (squeezeBlankLine) { - squeeze_flag = FALSE; - if (lineBuf2->ptr[0] == '\n' && pre_lbuf == '\n') { - ++nlines; - --i; - squeeze_flag = TRUE; - continue; - } - pre_lbuf = lineBuf2->ptr[0]; - } - ++nlines; - Strchop(lineBuf2); - lineBuf2 = checkType(lineBuf2, &propBuffer, &colorBuffer); - addnewline(buf, lineBuf2->ptr, propBuffer, colorBuffer, - lineBuf2->length, FOLD_BUFFER_WIDTH, nlines); - if (!top) { - top = buf->firstLine; - cur = top; - } - if (buf->lastLine->real_linenumber - buf->firstLine->real_linenumber - >= PagerMax) { - Line *l = buf->firstLine; - do { - if (top == l) - top = l->next; - if (cur == l) - cur = l->next; - if (last == l) - last = NULL; - l = l->next; - } while (l && l->bpos); - buf->firstLine = l; - buf->firstLine->prev = NULL; - } - } - pager_end: - TRAP_OFF; - - buf->trbyte = trbyte + linelen; -#ifdef USE_M17N - buf->document_charset = charset; - WcOption.auto_detect = old_auto_detect; -#endif - buf->topLine = top; - buf->currentLine = cur; - if (!last) - last = buf->firstLine; - else if (last && (last->next || !squeeze_flag)) - last = last->next; - return last; -} - -int -save2tmp(URLFile uf, char *tmpf) -{ - FILE *ff; - int check; - clen_t linelen = 0, trbyte = 0; - MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; - static JMP_BUF env_bak; - - ff = fopen(tmpf, "wb"); - if (ff == NULL) { - /* fclose(f); */ - return -1; - } - bcopy(AbortLoading, env_bak, sizeof(JMP_BUF)); - if (SETJMP(AbortLoading) != 0) { - goto _end; - } - TRAP_ON; - check = 0; -#ifdef USE_NNTP - if (uf.scheme == SCM_NEWS) { - char c; - while (c = UFgetc(&uf), !iseos(uf.stream)) { - if (c == '\n') { - if (check == 0) - check++; - else if (check == 3) - break; - } - else if (c == '.' && check == 1) - check++; - else if (c == '\r' && check == 2) - check++; - else - check = 0; - putc(c, ff); - linelen += sizeof(c); - showProgress(&linelen, &trbyte); - } - } - else -#endif /* USE_NNTP */ - { - Str buf = Strnew_size(SAVE_BUF_SIZE); - while (UFread(&uf, buf, SAVE_BUF_SIZE)) { - Strfputs(buf, ff); - linelen += buf->length; - showProgress(&linelen, &trbyte); - } - } - _end: - bcopy(env_bak, AbortLoading, sizeof(JMP_BUF)); - TRAP_OFF; - fclose(ff); - current_content_length = 0; - return 0; -} - -int -doExternal(URLFile uf, char *path, char *type, Buffer **bufp, - Buffer *defaultbuf) -{ - Str tmpf, command; - struct mailcap *mcap; - int mc_stat; - Buffer *buf = NULL; - char *header, *src = NULL, *ext = uf.ext; - - if (!(mcap = searchExtViewer(type))) - return 0; - - if (mcap->nametemplate) { - tmpf = unquote_mailcap(mcap->nametemplate, NULL, "", NULL, NULL); - if (tmpf->ptr[0] == '.') - ext = tmpf->ptr; - } - tmpf = tmpfname(TMPF_DFL, (ext && *ext) ? ext : NULL); - - if (IStype(uf.stream) != IST_ENCODED) - uf.stream = newEncodedStream(uf.stream, uf.encoding); - header = checkHeader(defaultbuf, "Content-Type:"); - if (header) - header = conv_to_system(header); - command = unquote_mailcap(mcap->viewer, type, tmpf->ptr, header, &mc_stat); -#ifndef __EMX__ - if (!(mc_stat & MCSTAT_REPNAME)) { - Str tmp = Sprintf("(%s) < %s", command->ptr, shell_quote(tmpf->ptr)); - command = tmp; - } -#endif - -#ifdef HAVE_SETPGRP - if (!(mcap->flags & (MAILCAP_HTMLOUTPUT | MAILCAP_COPIOUSOUTPUT)) && - !(mcap->flags & MAILCAP_NEEDSTERMINAL) && BackgroundExtViewer) { - flush_tty(); - if (!fork()) { - setup_child(FALSE, 0, UFfileno(&uf)); - if (save2tmp(uf, tmpf->ptr) < 0) - exit(1); - UFclose(&uf); - myExec(command->ptr); - } - *bufp = NO_BUFFER; - return 1; - } - else -#endif - { - if (save2tmp(uf, tmpf->ptr) < 0) { - *bufp = NULL; - return 1; - } - } - if (mcap->flags & (MAILCAP_HTMLOUTPUT | MAILCAP_COPIOUSOUTPUT)) { - if (defaultbuf == NULL) - defaultbuf = newBuffer(INIT_BUFFER_WIDTH); - if (defaultbuf->sourcefile) - src = defaultbuf->sourcefile; - else - src = tmpf->ptr; - defaultbuf->sourcefile = NULL; - defaultbuf->mailcap = mcap; - } - if (mcap->flags & MAILCAP_HTMLOUTPUT) { - buf = loadcmdout(command->ptr, loadHTMLBuffer, defaultbuf); - if (buf && buf != NO_BUFFER) { - buf->type = "text/html"; - buf->mailcap_source = buf->sourcefile; - buf->sourcefile = src; - } - } - else if (mcap->flags & MAILCAP_COPIOUSOUTPUT) { - buf = loadcmdout(command->ptr, loadBuffer, defaultbuf); - if (buf && buf != NO_BUFFER) { - buf->type = "text/plain"; - buf->mailcap_source = buf->sourcefile; - buf->sourcefile = src; - } - } - else { - if (mcap->flags & MAILCAP_NEEDSTERMINAL || !BackgroundExtViewer) { - fmTerm(); - mySystem(command->ptr, 0); - fmInit(); - if (CurrentTab && Currentbuf) - displayBuffer(Currentbuf, B_FORCE_REDRAW); - } - else { - mySystem(command->ptr, 1); - } - buf = NO_BUFFER; - } - if (buf && buf != NO_BUFFER) { - buf->filename = path; - if (buf->buffername == NULL || buf->buffername[0] == '\0') - buf->buffername = conv_from_system(lastFileName(path)); - buf->edit = mcap->edit; - buf->mailcap = mcap; - } - *bufp = buf; - return 1; -} - -static int -_MoveFile(char *path1, char *path2) -{ - InputStream f1; - FILE *f2; - int is_pipe; - clen_t linelen = 0, trbyte = 0; - Str buf; - - f1 = openIS(path1); - if (f1 == NULL) - return -1; - if (*path2 == '|' && PermitSaveToPipe) { - is_pipe = TRUE; - f2 = popen(path2 + 1, "w"); - } - else { - is_pipe = FALSE; - f2 = fopen(path2, "wb"); - } - if (f2 == NULL) { - ISclose(f1); - return -1; - } - current_content_length = 0; - buf = Strnew_size(SAVE_BUF_SIZE); - while (ISread(f1, buf, SAVE_BUF_SIZE)) { - Strfputs(buf, f2); - linelen += buf->length; - showProgress(&linelen, &trbyte); - } - ISclose(f1); - if (is_pipe) - pclose(f2); - else - fclose(f2); - return 0; -} - -int -_doFileCopy(char *tmpf, char *defstr, int download) -{ - Str msg; - Str filen; - char *p, *q = NULL; - pid_t pid; - char *lock; -#if !(defined(HAVE_SYMLINK) && defined(HAVE_LSTAT)) - FILE *f; -#endif - struct stat st; - clen_t size = 0; - int is_pipe = FALSE; - - if (fmInitialized) { - p = searchKeyData(); - if (p == NULL || *p == '\0') { - /* FIXME: gettextize? */ - q = inputLineHist("(Download)Save file to: ", - defstr, IN_COMMAND, SaveHist); - if (q == NULL || *q == '\0') - return FALSE; - p = conv_to_system(q); - } - if (*p == '|' && PermitSaveToPipe) - is_pipe = TRUE; - else { - if (q) { - p = unescape_spaces(Strnew_charp(q))->ptr; - p = conv_to_system(q); - } - p = expandPath(p); - if (checkOverWrite(p) < 0) - return -1; - } - if (checkCopyFile(tmpf, p) < 0) { - /* FIXME: gettextize? */ - msg = Sprintf("Can't copy. %s and %s are identical.", - conv_from_system(tmpf), conv_from_system(p)); - disp_err_message(msg->ptr, FALSE); - return -1; - } - if (!download) { - if (_MoveFile(tmpf, p) < 0) { - /* FIXME: gettextize? */ - msg = Sprintf("Can't save to %s", conv_from_system(p)); - disp_err_message(msg->ptr, FALSE); - } - return -1; - } - lock = tmpfname(TMPF_DFL, ".lock")->ptr; -#if defined(HAVE_SYMLINK) && defined(HAVE_LSTAT) - symlink(p, lock); -#else - f = fopen(lock, "w"); - if (f) - fclose(f); -#endif - flush_tty(); - pid = fork(); - if (!pid) { - setup_child(FALSE, 0, -1); - if (!_MoveFile(tmpf, p) && PreserveTimestamp && !is_pipe && - !stat(tmpf, &st)) - setModtime(p, st.st_mtime); - unlink(lock); - exit(0); - } - if (!stat(tmpf, &st)) - size = st.st_size; - addDownloadList(pid, conv_from_system(tmpf), p, lock, size); - } - else { - q = searchKeyData(); - if (q == NULL || *q == '\0') { - /* FIXME: gettextize? */ - printf("(Download)Save file to: "); - fflush(stdout); - filen = Strfgets(stdin); - if (filen->length == 0) - return -1; - q = filen->ptr; - } - for (p = q + strlen(q) - 1; IS_SPACE(*p); p--) ; - *(p + 1) = '\0'; - if (*q == '\0') - return -1; - p = q; - if (*p == '|' && PermitSaveToPipe) - is_pipe = TRUE; - else { - p = expandPath(p); - if (checkOverWrite(p) < 0) - return -1; - } - if (checkCopyFile(tmpf, p) < 0) { - /* FIXME: gettextize? */ - printf("Can't copy. %s and %s are identical.", tmpf, p); - return -1; - } - if (_MoveFile(tmpf, p) < 0) { - /* FIXME: gettextize? */ - printf("Can't save to %s\n", p); - return -1; - } - if (PreserveTimestamp && !is_pipe && !stat(tmpf, &st)) - setModtime(p, st.st_mtime); - } - return 0; -} - -int -doFileMove(char *tmpf, char *defstr) -{ - int ret = doFileCopy(tmpf, defstr); - unlink(tmpf); - return ret; -} - -int -doFileSave(URLFile uf, char *defstr) -{ - Str msg; - Str filen; - char *p, *q; - pid_t pid; - char *lock; - char *tmpf = NULL; -#if !(defined(HAVE_SYMLINK) && defined(HAVE_LSTAT)) - FILE *f; -#endif - - if (fmInitialized) { - p = searchKeyData(); - if (p == NULL || *p == '\0') { - /* FIXME: gettextize? */ - p = inputLineHist("(Download)Save file to: ", - defstr, IN_FILENAME, SaveHist); - if (p == NULL || *p == '\0') - return -1; - p = conv_to_system(p); - } - if (checkOverWrite(p) < 0) - return -1; - if (checkSaveFile(uf.stream, p) < 0) { - /* FIXME: gettextize? */ - msg = Sprintf("Can't save. Load file and %s are identical.", - conv_from_system(p)); - disp_err_message(msg->ptr, FALSE); - return -1; - } - /* - * if (save2tmp(uf, p) < 0) { - * msg = Sprintf("Can't save to %s", conv_from_system(p)); - * disp_err_message(msg->ptr, FALSE); - * } - */ - lock = tmpfname(TMPF_DFL, ".lock")->ptr; -#if defined(HAVE_SYMLINK) && defined(HAVE_LSTAT) - symlink(p, lock); -#else - f = fopen(lock, "w"); - if (f) - fclose(f); -#endif - flush_tty(); - pid = fork(); - if (!pid) { - if (uf.content_encoding != CMP_NOCOMPRESS) { - uncompress_stream(&uf, &tmpf); - if (tmpf) - unlink(tmpf); - } - setup_child(FALSE, 0, UFfileno(&uf)); - if (!save2tmp(uf, p) && PreserveTimestamp && uf.modtime != -1) - setModtime(p, uf.modtime); - UFclose(&uf); - unlink(lock); - exit(0); - } - addDownloadList(pid, uf.url, p, lock, current_content_length); - } - else { - q = searchKeyData(); - if (q == NULL || *q == '\0') { - /* FIXME: gettextize? */ - printf("(Download)Save file to: "); - fflush(stdout); - filen = Strfgets(stdin); - if (filen->length == 0) - return -1; - q = filen->ptr; - } - for (p = q + strlen(q) - 1; IS_SPACE(*p); p--) ; - *(p + 1) = '\0'; - if (*q == '\0') - return -1; - p = expandPath(q); - if (checkOverWrite(p) < 0) - return -1; - if (checkSaveFile(uf.stream, p) < 0) { - /* FIXME: gettextize? */ - printf("Can't save. Load file and %s are identical.", p); - return -1; - } - if (uf.content_encoding != CMP_NOCOMPRESS) { - uncompress_stream(&uf, &tmpf); - if (tmpf) - unlink(tmpf); - } - if (save2tmp(uf, p) < 0) { - /* FIXME: gettextize? */ - printf("Can't save to %s\n", p); - return -1; - } - if (PreserveTimestamp && uf.modtime != -1) - setModtime(p, uf.modtime); - } - return 0; -} - -int -checkCopyFile(char *path1, char *path2) -{ - struct stat st1, st2; - - if (*path2 == '|' && PermitSaveToPipe) - return 0; - if ((stat(path1, &st1) == 0) && (stat(path2, &st2) == 0)) - if (st1.st_ino == st2.st_ino) - return -1; - return 0; -} - -int -checkSaveFile(InputStream stream, char *path2) -{ - struct stat st1, st2; - int des = ISfileno(stream); - - if (des < 0) - return 0; - if (*path2 == '|' && PermitSaveToPipe) - return 0; - if ((fstat(des, &st1) == 0) && (stat(path2, &st2) == 0)) - if (st1.st_ino == st2.st_ino) - return -1; - return 0; -} - -int -checkOverWrite(char *path) -{ - struct stat st; - char *ans; - - if (stat(path, &st) < 0) - return 0; - /* FIXME: gettextize? */ - ans = inputAnswer("File exists. Overwrite? (y/n)"); - if (ans && TOLOWER(*ans) == 'y') - return 0; - else - return -1; -} - -char * -inputAnswer(char *prompt) -{ - char *ans; - - if (QuietMessage) - return "n"; - if (fmInitialized) { - term_raw(); - ans = inputChar(prompt); - } - else { - printf(prompt); - fflush(stdout); - ans = Strfgets(stdin)->ptr; - } - return ans; -} - -static void -uncompress_stream(URLFile *uf, char **src) -{ - pid_t pid1; - FILE *f1; - char *expand_cmd = GUNZIP_CMDNAME; - char *expand_name = GUNZIP_NAME; - char *tmpf = NULL; - char *ext = NULL; - struct compression_decoder *d; - - if (IStype(uf->stream) != IST_ENCODED) { - uf->stream = newEncodedStream(uf->stream, uf->encoding); - uf->encoding = ENC_7BIT; - } - for (d = compression_decoders; d->type != CMP_NOCOMPRESS; d++) { - if (uf->compression == d->type) { - if (d->auxbin_p) - expand_cmd = auxbinFile(d->cmd); - else - expand_cmd = d->cmd; - expand_name = d->name; - ext = d->ext; - break; - } - } - uf->compression = CMP_NOCOMPRESS; - - if (uf->scheme != SCM_LOCAL -#ifdef USE_IMAGE - && !image_source -#endif - ) { - tmpf = tmpfname(TMPF_DFL, ext)->ptr; - } - - /* child1 -- stdout|f1=uf -> parent */ - pid1 = open_pipe_rw(&f1, NULL); - if (pid1 < 0) { - UFclose(uf); - return; - } - if (pid1 == 0) { - /* child */ - pid_t pid2; - FILE *f2 = stdin; - - /* uf -> child2 -- stdout|stdin -> child1 */ - pid2 = open_pipe_rw(&f2, NULL); - if (pid2 < 0) { - UFclose(uf); - exit(1); - } - if (pid2 == 0) { - /* child2 */ - Str buf = Strnew_size(SAVE_BUF_SIZE); - FILE *f = NULL; - - setup_child(TRUE, 2, UFfileno(uf)); - if (tmpf) - f = fopen(tmpf, "wb"); - while (UFread(uf, buf, SAVE_BUF_SIZE)) { - if (Strfputs(buf, stdout) < 0) - break; - if (f) - Strfputs(buf, f); - } - UFclose(uf); - if (f) - fclose(f); - exit(0); - } - /* child1 */ - dup2(1, 2); /* stderr>&stdout */ - setup_child(TRUE, -1, -1); - execlp(expand_cmd, expand_name, NULL); - exit(1); - } - if (tmpf) { - if (src) - *src = tmpf; - else - uf->scheme = SCM_LOCAL; - } - UFhalfclose(uf); - uf->stream = newFileStream(f1, (void (*)())fclose); -} - -static FILE * -lessopen_stream(char *path) -{ - char *lessopen; - FILE *fp; - - lessopen = getenv("LESSOPEN"); - if (lessopen == NULL) { - return NULL; - } - if (lessopen[0] == '\0') { - return NULL; - } - - if (lessopen[0] == '|') { - /* pipe mode */ - Str tmpf; - int c; - - ++lessopen; - tmpf = Sprintf(lessopen, shell_quote(path)); - fp = popen(tmpf->ptr, "r"); - if (fp == NULL) { - return NULL; - } - c = getc(fp); - if (c == EOF) { - fclose(fp); - return NULL; - } - ungetc(c, fp); - } - else { - /* filename mode */ - /* not supported m(__)m */ - fp = NULL; - } - return fp; -} - -#if 0 -void -reloadBuffer(Buffer *buf) -{ - URLFile uf; - - if (buf->sourcefile == NULL || buf->pagerSource != NULL) - return; - init_stream(&uf, SCM_UNKNOWN, NULL); - examineFile(buf->mailcap_source ? buf->mailcap_source : buf->sourcefile, - &uf); - if (uf.stream == NULL) - return; - is_redisplay = TRUE; - buf->allLine = 0; - buf->href = NULL; - buf->name = NULL; - buf->img = NULL; - buf->formitem = NULL; - buf->linklist = NULL; - buf->maplist = NULL; - if (buf->hmarklist) - buf->hmarklist->nmark = 0; - if (buf->imarklist) - buf->imarklist->nmark = 0; - if (!strcasecmp(buf->type, "text/html")) - loadHTMLBuffer(&uf, buf); - else - loadBuffer(&uf, buf); - UFclose(&uf); - is_redisplay = FALSE; -} -#endif - -static char * -guess_filename(char *file) -{ - char *p = NULL, *s; - - if (file != NULL) - p = mybasename(file); - if (p == NULL || *p == '\0') - return DEF_SAVE_FILE; - s = p; - if (*p == '#') - p++; - while (*p != '\0') { - if ((*p == '#' && *(p + 1) != '\0') || *p == '?') { - *p = '\0'; - break; - } - p++; - } - return s; -} - -char * -guess_save_name(Buffer *buf, char *path) -{ - if (buf && buf->document_header) { - Str name = NULL; - char *p, *q; - if ((p = checkHeader(buf, "Content-Disposition:")) != NULL && - (q = strcasestr(p, "filename")) != NULL && - (q == p || IS_SPACE(*(q - 1)) || *(q - 1) == ';') && - matchattr(q, "filename", 8, &name)) - path = name->ptr; - else if ((p = checkHeader(buf, "Content-Type:")) != NULL && - (q = strcasestr(p, "name")) != NULL && - (q == p || IS_SPACE(*(q - 1)) || *(q - 1) == ';') && - matchattr(q, "name", 4, &name)) - path = name->ptr; - } - return guess_filename(path); -} - -/* Local Variables: */ -/* c-basic-offset: 4 */ -/* tab-width: 8 */ -/* End: */ |