aboutsummaryrefslogtreecommitdiffstats
path: root/.#file.c.1.243
diff options
context:
space:
mode:
Diffstat (limited to '.#file.c.1.243')
-rw-r--r--.#file.c.1.2438188
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 = "&lt;";
- }
- }
- }
- 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: */