links2

links 2.15+ fork
git clone git://git.codemadness.org/links2
Log | Files | Refs | README

commit 2dac222cdd430d25efd7cee0deb94435c9fa94a7
parent 5aaecf54e7d2152fe843b8831e1d48bc2ec71cb8
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Mon, 30 Apr 2018 09:37:20 +0200

remove some handlers and items from the menu

this will come back in better plumbing support later.

Diffstat:
.gitignore | 2++
Makefile | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
TODO | 15++++++++++++---
beos.h | 21---------------------
com-defs.h | 9---------
default.c | 5-----
dfb_cur.h | 98-------------------------------------------------------------------------------
directfb.c | 20--------------------
finger.c | 99-------------------------------------------------------------------------------
framebuf.c | 8--------
ftp.c | 904-------------------------------------------------------------------------------
links.h | 19-------------------
mailto.c | 56--------------------------------------------------------
menu.c | 52+---------------------------------------------------
smb.c | 2--
types.c | 9---------
url.c | 8--------
17 files changed, 93 insertions(+), 1323 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,5 +1,7 @@ links linksg +links.core +linksg.core *.o config.cache config.log diff --git a/Makefile b/Makefile @@ -1,14 +1,81 @@ -build: clean - # links terminal - cc -c -include config.h *.c -I. -I/usr/local/include -O2 - cc -o links *.o -L/usr/local/lib -levent -lssl -lz -s - # links -g - cc -c -include config.h \ - -DG=1 -DGRDRV_X \ - -DHAVE_JPEG=1 -DHAVE_LIBJPEG=1 -DHAVE_JPEGLIB_H=1 \ - -DHAVE_PNG_H=1 -DHAVE_LIBPNG=1 -DHAVE_LIBPNG_PNG_H=1 \ - *.c -I. -I/usr/local/include -I/usr/X11R6/include -O2 - cc -o linksg *.o -L/usr/X11R6/lib -L/usr/local/lib -lX11 -levent -lpng -ljpeg -lssl -lz -s +# links terminal +#CFLAGS = -include config.h -I. -I/usr/local/include -O2 #-g -O0 +#LDFLAGS = -L/usr/local/lib -levent -lssl -lz -s + +# links-g +CFLAGS = -include config.h \ + -DG=1 -DGRDRV_X \ + -DHAVE_JPEG=1 -DHAVE_LIBJPEG=1 -DHAVE_JPEGLIB_H=1 \ + -DHAVE_PNG_H=1 -DHAVE_LIBPNG=1 -DHAVE_LIBPNG_PNG_H=1 \ + -I. -I/usr/local/include -I/usr/X11R6/include -O2 #-g -O0 +LDFLAGS = -L/usr/X11R6/lib -L/usr/local/lib -lX11 -levent -lpng -ljpeg -lssl -lz -s + +OBJ = \ + af_unix.o\ + auth.o\ + bfu.o\ + block.o\ + bookmark.o\ + cache.o\ + charsets.o\ + compress.o\ + connect.o\ + cookies.o\ + data.o\ + default.o\ + dns.o\ + drivers.o\ + error.o\ + file.o\ + fn_impl.o\ + html.o\ + html_gr.o\ + html_r.o\ + html_tbl.o\ + http.o\ + https.o\ + img.o\ + jsint.o\ + kbd.o\ + language.o\ + listedit.o\ + lru.o\ + mailto.o\ + main.o\ + memory.o\ + menu.o\ + objreq.o\ + os_dep.o\ + sched.o\ + select.o\ + session.o\ + string.o\ + suffix.o\ + terminal.o\ + types.o\ + url.o\ + view.o + +# TODO +XOBJ = \ + dip.o\ + dither.o\ + font_inc.o\ + gif.o\ + imgcache.o\ + jpeg.o\ + png.o\ + view_gr.o\ + x.o + +#all: links # linksg +all: linksg + +links: $(OBJ) + cc -o links $(OBJ) $(LDFLAGS) + +linksg: $(OBJ) $(XOBJ) + cc -o links $(OBJ) $(XOBJ) $(LDFLAGS) clean: rm -f *.o links linksg diff --git a/TODO b/TODO @@ -1,6 +1,13 @@ +in menu opening telnet program settings crashes now. + +=== + +- improve Makefile/build. + - dont use all object files for normal terminal version. + - rendering: - improvement to margin rendering for <code>: see codemadness.org. - - font improvement. + - font improvement, dejavu sans mono? - add a few entities like &quot; - keep a (minimal) changelog. @@ -14,7 +21,7 @@ - improve SSL/TLS support, use libtls? - include libjpeg, libpng, zlib codebase? -- remove DNS cache. +- remove DNS caching. - remove "display:none" CSS hack. - secure/sane defaults: - referer @@ -23,10 +30,12 @@ - cookie settings - UTF-8 encoding - add gopher handler. -- add better plumbing support. + - OpenBSD pledge(2) support. - improve domain suffix matching: see suffix*.inc. - remove X11 gamma correction support. - remove brotli, lzma, lzip, bzip2 support: only support gzip/deflate. +- remove handlers for ftp, telnet, mms, etc. +- improve plumbing support. diff --git a/beos.h b/beos.h @@ -1,21 +0,0 @@ -int be_socket(int, int, int); -int be_connect(int, struct sockaddr *, int); -int be_getpeername(int, struct sockaddr *, int *); -int be_getsockname(int, struct sockaddr *, int *); -int be_listen(int, int); -int be_accept(int, struct sockaddr *, int *); -int be_bind(int, struct sockaddr *, int); -int be_pipe(int *); -int be_read(int, void *, int); -int be_write(int, void *, int); -int be_close(int); -int be_select(int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *); -int be_getsockopt(int, int, int, void *, int *); - -int start_thr(void (*fn)(void *), void *data, unsigned char *name); - -int get_input_handle(void); -void block_stdin(void); -void unblock_stdin(void); - -void fatal_exit(char *, ...); diff --git a/com-defs.h b/com-defs.h @@ -25,13 +25,4 @@ #define _FILE_OFFSET_BITS 64 #endif -#if defined(vax) && !defined(__vax) -#define __vax vax -#endif - -#ifdef __DJGPP -unsigned long __ntohl(unsigned long); -unsigned short __ntohs(unsigned short); -#endif - #endif diff --git a/default.c b/default.c @@ -2103,11 +2103,6 @@ static struct option links_options[] = { {1, NULL, term2_rd, NULL, 0, 0, NULL, "terminal2", NULL}, {1, NULL, type_rd, type_wr, 0, 0, NULL, "association", NULL}, {1, NULL, ext_rd, ext_wr, 0, 0, NULL, "extension", NULL}, - {1, NULL, prog_rd, prog_wr, 0, 0, &mailto_prog, "mailto", NULL}, - {1, NULL, prog_rd, prog_wr, 0, 0, &telnet_prog, "telnet", NULL}, - {1, NULL, prog_rd, prog_wr, 0, 0, &tn3270_prog, "tn3270", NULL}, - {1, NULL, prog_rd, prog_wr, 0, 0, &mms_prog, "mms", NULL}, - {1, NULL, prog_rd, prog_wr, 0, 0, &magnet_prog, "magnet", NULL}, {1, NULL, block_rd, block_wr, 0, 0, NULL, "imageblock", NULL}, {1, NULL, dp_rd, dp_wr, 0, 0, NULL, "video_driver", NULL}, {0, NULL, NULL, NULL, 0, 0, NULL, NULL, NULL}, diff --git a/dfb_cur.h b/dfb_cur.h @@ -1,98 +0,0 @@ -/* DirectFB surface dump created by directfb-csource 0.9.14 */ - -/* This arrow cursor surface is based on a cursor drawn by Ville Pätsi. */ -static_const unsigned char arrow_data[] = - "\0\0\0\0\0\0\0#\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0/\253\253\253\320\0\0\0N\0\0\0\3\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0H\306\306\306\363\200\200\200\320\0\0\0Y\0" - "\0\0\21\0\0\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Z\377\377\377\377\301" - "\301\301\372\223\223\223\347\0\0\0k\0\0\0\30\0\0\0\6\0\0\0\2\0\0\0\1" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0]\377\377\377\377\377\377\377\377\264\264\264\373\213\213\213" - "\352\0\0\0u\0\0\0\36\0\0\0\10\0\0\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\377\377\377\377\375\375" - "\375\377\356\356\356\377\254\254\254\374\206\206\206\354\0\0\0y\0\0\0" - "!\0\0\0\10\0\0\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0`\377\377\377\377\372\372\372\377\355\355\355\377" - "\343\343\343\377\247\247\247\374\203\203\203\354\0\0\0z\0\0\0\"\0\0\0" - "\11\0\0\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0`\377\377\377\377\365\365\365\377\351\351\351\377\341\341\341\377" - "\335\335\335\377\243\243\243\374\177\177\177\355\0\0\0{\0\0\0\"\0\0\0" - "\11\0\0\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\371" - "\371\371\377\360\360\360\377\346\346\346\377\337\337\337\377\333\333" - "\333\377\327\327\327\377\236\236\236\374{{{\355\0\0\0{\0\0\0\"\0\0\0" - "\11\0\0\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\365\365\365" - "\377\355\355\355\377\342\342\342\377\333\333\333\377\330\330\330\377" - "\325\325\325\377\317\317\317\377\227\227\227\374vvv\355\0\0\0{\0\0\0" - "\"\0\0\0\11\0\0\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\361\361\361" - "\377\350\350\350\377\335\335\335\377\326\326\326\377\324\324\324\377" - "\317\317\317\377\307\307\307\377\277\277\277\377\216\216\216\374qqq\352" - "\0\0\0r\0\0\0\33\0\0\0\11\0\0\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0`\353" - "\353\353\377\340\340\340\377\324\324\324\377\317\317\317\377\315\315" - "\315\377\307\307\307\377\274\274\274\377\257\257\257\377\212\212\212" - "\375ggg\357\\\\\\\313\0\0\0F\0\0\0\24\0\0\0\11\0\0\0\3\0\0\0\1\0\0\0" - "\0\0\0\0`\340\340\340\377\321\321\321\377\305\305\305\377\304\304\304" - "\377\307\307\307\377\302\302\302\377\242\242\242\376HHH\361\0\0\0\267" - "\0\0\0\224\0\0\0t\0\0\0?\0\0\0\"\0\0\0\22\0\0\0\7\0\0\0\2\0\0\0\0\0\0" - "\0]\321\321\321\377\277\277\277\377\207\207\207\374jjj\367\302\302\302" - "\377\301\301\301\377\263\263\263\377!!!\334\0\0\0\215\0\0\0d\0\0\0Q\0" - "\0\0>\0\0\0-\0\0\0\33\0\0\0\14\0\0\0\4\0\0\0\1\0\0\0E\230\230\230\363" - "kkk\353\0\0\0\243\0\0\0\254\200\200\200\370\304\304\304\377\271\271\271" - "\377ttt\371\0\0\0\233\0\0\0Y\0\0\0F\0\0\0<\0\0\0.\0\0\0\36\0\0\0\16\0" - "\0\0\4\0\0\0\1\0\0\0\7\0\0\0M\0\0\0]\0\0\0O\0\0\0f'''\305\304\304\304" - "\377\274\274\274\377\253\253\253\377\22\22\22\277\0\0\0e\0\0\0A\0\0\0" - "3\0\0\0%\0\0\0\27\0\0\0\13\0\0\0\4\0\0\0\1\0\0\0\0\0\0\0\3\0\0\0\24\0" - "\0\0)\0\0\0<\0\0\0\207\223\223\223\373\267\267\267\377\252\252\252\377" - "YYY\360\0\0\0\203\0\0\0@\0\0\0+\0\0\0\32\0\0\0\15\0\0\0\6\0\0\0\2\0\0" - "\0\0\0\0\0\0\0\0\0\2\0\0\0\11\0\0\0\27\0\0\0'\0\0\0N===\312\257\257\257" - "\377\242\242\242\377lll\370\0\0\0\221\0\0\0E\0\0\0)\0\0\0\26\0\0\0\11" - "\0\0\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\5\0\0\0\15\0\0\0\26\0" - "\0\0\33\0\0\0\\CCC\322ppp\366MMM\345\0\0\0\204\0\0\0I\0\0\0-\0\0\0\31" - "\0\0\0\12\0\0\0\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\5\0\0" - "\0\11\0\0\0\13\0\0\0\20\0\0\0E\0\0\0s\0\0\0w\0\0\0Z\0\0\0E\0\0\0""2\0" - "\0\0\35\0\0\0\14\0\0\0\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\1\0\0\0\2\0\0\0\3\0\0\0\4\0\0\0\12\0\0\0\36\0\0\0""4\0\0\0>\0\0\0" - "<\0\0\0""1\0\0\0\36\0\0\0\15\0\0\0\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\4\0\0\0\15\0\0\0\33\0" - "\0\0)\0\0\0.\0\0\0(\0\0\0\31\0\0\0\13\0\0\0\3\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\6\0\0" - "\0\15\0\0\0\26\0\0\0\33\0\0\0\30\0\0\0\17\0\0\0\7\0\0\0\2\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\1\0\0\0\4\0\0\0\10\0\0\0\13\0\0\0\12\0\0\0\6\0\0\0\3\0\0\0\1\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\2\0\0\0\3\0\0\0\3\0\0\0\1\0\0\0\1\0" - "\0\0\0\0\0\0\0\0\0\0\0"; - -static DFBSurfaceDescription *directfb_get_arrow_desc(void) -{ - static DFBSurfaceDescription arrow_desc; - - arrow_desc.flags = (DFBSurfaceDescriptionFlags)( - DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | - DSDESC_PREALLOCATED), - arrow_desc.width = 18, - arrow_desc.height = 25, - arrow_desc.pixelformat = DSPF_ARGB, - arrow_desc.preallocated[0].data = (void *) arrow_data, - arrow_desc.preallocated[0].pitch = 72; - - return &arrow_desc; -} - -#if 0 /* this is GNU extension, not C */ -static DFBSurfaceDescription arrow_desc = { - flags : DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | - DSDESC_PREALLOCATED, - width : 18, - height : 25, - pixelformat : DSPF_ARGB, - preallocated : {{ data : (void *) arrow_data, - pitch : 72 }} -}; -#endif - -#define arrow_hot_x 1 -#define arrow_hot_y 1 diff --git a/directfb.c b/directfb.c @@ -1,20 +0,0 @@ -/* directfb.c - * DirectFB graphics driver - * (c) 2002 Sven Neumann <sven@directfb.org> - * - * This file is a part of the Links program, released under GPL. - */ - -/* TODO: - * - Store window size as driver params (?) - * - Fix wrong colors on big-endian systems (fixed?) - * - Make everything work correctly ;-) - * - * KNOWN PROBLEMS: - * - If mouse drags don't work for you, update DirectFB - * (the upcoming 0.9.14 release fixes this). - */ - - -#include "cfg.h" - diff --git a/finger.c b/finger.c @@ -1,99 +0,0 @@ -/* finger.c - * finger:// processing - * (c) 2002 Mikulas Patocka - * This file is a part of the Links program, released under GPL. - */ - -#include "links.h" - -static void finger_send_request(struct connection *); -static void finger_sent_request(struct connection *); -static void finger_get_response(struct connection *, struct read_buffer *); -static void finger_end_request(struct connection *, int); - -void finger_func(struct connection *c) -{ - int p; - if ((p = get_port(c->url)) == -1) { - setcstate(c, S_BAD_URL); - abort_connection(c); - return; - } - c->from = 0; - make_connection(c, p, &c->sock1, finger_send_request); -} - -static void finger_send_request(struct connection *c) -{ - unsigned char *req = init_str(); - int rl = 0; - unsigned char *user; - add_to_str(&req, &rl, cast_uchar "/W"); - if ((user = get_user_name(c->url))) { - add_to_str(&req, &rl, cast_uchar " "); - add_to_str(&req, &rl, user); - mem_free(user); - } - add_to_str(&req, &rl, cast_uchar "\r\n"); - write_to_socket(c, c->sock1, req, rl, finger_sent_request); - mem_free(req); - setcstate(c, S_SENT); -} - -static void finger_sent_request(struct connection *c) -{ - struct read_buffer *rb; - set_connection_timeout(c); - if (!(rb = alloc_read_buffer(c))) return; - rb->close = 1; - read_from_socket(c, c->sock1, rb, finger_get_response); -} - -static void finger_get_response(struct connection *c, struct read_buffer *rb) -{ - int l; - int a; - set_connection_timeout(c); - if (!c->cache) { - if (get_connection_cache_entry(c)) { - setcstate(c, S_OUT_OF_MEM); - abort_connection(c); - return; - } - c->cache->refcount--; - } - if (rb->close == 2) { - finger_end_request(c, S__OK); - return; - } - l = rb->len; - if ((off_t)(0UL + c->from + l) < 0) { - setcstate(c, S_LARGE_FILE); - abort_connection(c); - return; - } - c->received += l; - a = add_fragment(c->cache, c->from, rb->data, l); - if (a < 0) { - setcstate(c, a); - abort_connection(c); - return; - } - if (a == 1) c->tries = 0; - c->from += l; - kill_buffer_data(rb, l); - read_from_socket(c, c->sock1, rb, finger_get_response); - setcstate(c, S_TRANS); -} - -static void finger_end_request(struct connection *c, int state) -{ - if (state == S__OK) { - if (c->cache) { - truncate_entry(c->cache, c->from, 1); - c->cache->incomplete = 0; - } - } - setcstate(c, state); - abort_connection(c); -} diff --git a/framebuf.c b/framebuf.c @@ -1,8 +0,0 @@ -/* framebuf.c - * Linux framebuffer code - * (c) 2002 Petr 'Brain' Kulhavy - * This file is a part of the Links program, released under GPL. - */ - -#include "cfg.h" - diff --git a/ftp.c b/ftp.c @@ -1,904 +0,0 @@ -/* ftp.c - * ftp:// processing - * (c) 2002 Mikulas Patocka - * This file is a part of the Links program, released under GPL. - */ - -#include "links.h" - -#define FTP_BUF 16384 - -struct ftp_connection_info { - int pending_commands; - int opc; - int pasv; - int eprt_epsv; - int dir; - int rest_sent; - int we_are_in_root; - int conn_st; - int d; - int dpos; - int buf_pos; - unsigned char ftp_buffer[FTP_BUF]; - unsigned char cmdbuf[1]; -}; - -static void ftp_get_banner(struct connection *); -static void ftp_got_banner(struct connection *, struct read_buffer *); -static void ftp_login(struct connection *); -static void ftp_logged(struct connection *); -static void ftp_sent_passwd(struct connection *); -static void ftp_got_info(struct connection *, struct read_buffer *); -static void ftp_got_user_info(struct connection *, struct read_buffer *); -static void ftp_dummy_info(struct connection *, struct read_buffer *); -static void ftp_pass_info(struct connection *, struct read_buffer *); -static void ftp_send_retr_req(struct connection *, int, int); -static struct ftp_connection_info *add_file_cmd_to_str(struct connection *, int); -static void ftp_retr_1(struct connection *); -static void ftp_retr_file(struct connection *, struct read_buffer *); -static void ftp_got_final_response(struct connection *, struct read_buffer *); -static void created_data_connection(struct connection *); -static void got_something_from_data_connection(void *); -static void ftp_end_request(struct connection *, int); -static int get_ftp_response(struct connection *, struct read_buffer *, int); -static int ftp_process_dirlist(struct cache_entry *, off_t *, int *, unsigned char *, int, int, int, int *); - - -static int get_ftp_response(struct connection *c, struct read_buffer *rb, int part) -{ - int l; - set_connection_timeout(c); - again: - for (l = 0; l < rb->len; l++) if (rb->data[l] == 10) { - unsigned char *e; - long k = strtoul(cast_const_char rb->data, (char **)(void *)&e, 10); - if (e != rb->data + 3 || k < 100 || k >= 1000) return -1; - if (*e == '-') { - int i; - for (i = 0; i < rb->len - 5; i++) { - if (rb->data[i] == 10 && !memcmp(rb->data+i+1, rb->data, 3) && rb->data[i+4] == ' ') { - for (i++; i < rb->len; i++) if (rb->data[i] == 10) goto ok; - return 0; - } - } - return 0; - ok: - l = i; - } - if (!part && k >= 100 && k < 200) { - kill_buffer_data(rb, l + 1); - goto again; - } - if (part == 2) return (int)k; - kill_buffer_data(rb, l + 1); - return (int)k; - } - return 0; -} - -void ftp_func(struct connection *c) -{ - int we_are_in_root; - unsigned char *de, *d; - int del, bad_url; - d = get_url_data(c->url); - de = init_str(), del = 0; - add_conv_str(&de, &del, d, (int)strcspn(cast_const_char d, POST_CHAR_STRING), -2); - bad_url = !!strchr(cast_const_char de, 10); - mem_free(de); - if (bad_url) { - setcstate(c, S_BAD_URL); - abort_connection(c); - return; - } - - if (get_keepalive_socket(c, &we_are_in_root)) { - int p; - if ((p = get_port(c->url)) == -1) { - setcstate(c, S_BAD_URL); - abort_connection(c); - return; - } - make_connection(c, p, &c->sock1, ftp_options.fast_ftp ? ftp_login : ftp_get_banner); - } else { - ftp_send_retr_req(c, S_SENT, we_are_in_root); - } -} - -static void ftp_get_banner(struct connection *c) -{ - struct read_buffer *rb; - set_connection_timeout(c); - setcstate(c, S_SENT); - if (!(rb = alloc_read_buffer(c))) return; - read_from_socket(c, c->sock1, rb, ftp_got_banner); -} - -static void ftp_got_banner(struct connection *c, struct read_buffer *rb) -{ - int g = get_ftp_response(c, rb, 0); - if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } - if (!g) { read_from_socket(c, c->sock1, rb, ftp_got_banner); return; } - if (g >= 400) { setcstate(c, S_FTP_UNAVAIL); retry_connection(c); return; } - ftp_login(c); -} - - -static unsigned char *get_ftp_password(struct connection *c) -{ - unsigned char *u; - if ((u = get_pass(c->url))) { - if (*u) return u; - mem_free(u); - } - if (SCRUB_HEADERS) - return stracpy(cast_uchar "mozilla@example.com"); - return stracpy(ftp_options.anon_pass); -} - -static void ftp_login(struct connection *c) -{ - unsigned char *login; - unsigned char *u; - int logl = 0; - set_connection_timeout(c); - login = init_str(); - add_to_str(&login, &logl, cast_uchar "USER "); - if ((u = get_user_name(c->url)) && *u) add_to_str(&login, &logl, u); - else add_to_str(&login, &logl, cast_uchar "anonymous"); - if (u) mem_free(u); - if (ftp_options.fast_ftp) { - struct ftp_connection_info *fi; - add_to_str(&login, &logl, cast_uchar "\r\nPASS "); - u = get_ftp_password(c); - add_to_str(&login, &logl, u); - mem_free(u); - add_to_str(&login, &logl, cast_uchar "\r\n"); - if (!(fi = add_file_cmd_to_str(c, 0))) { - mem_free(login); - return; - } - add_to_str(&login, &logl, fi->cmdbuf); - } else add_to_str(&login, &logl, cast_uchar "\r\n"); - write_to_socket(c, c->sock1, login, logl, ftp_logged); - mem_free(login); - setcstate(c, S_SENT); -} - -static void ftp_logged(struct connection *c) -{ - struct read_buffer *rb; - if (!(rb = alloc_read_buffer(c))) return; - if (!ftp_options.fast_ftp) { - ftp_got_user_info(c, rb); - return; - } - read_from_socket(c, c->sock1, rb, ftp_got_info); -} - -static void ftp_got_info(struct connection *c, struct read_buffer *rb) -{ - int g = get_ftp_response(c, rb, 0); - if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } - if (!g) { read_from_socket(c, c->sock1, rb, ftp_got_info); return; } - if (g >= 400) { setcstate(c, S_FTP_UNAVAIL); retry_connection(c); return; } - ftp_got_user_info(c, rb); -} - -static void ftp_got_user_info(struct connection *c, struct read_buffer *rb) -{ - int g = get_ftp_response(c, rb, 0); - if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } - if (!g) { read_from_socket(c, c->sock1, rb, ftp_got_user_info); return; } - if (g >= 530 && g < 540) { setcstate(c, S_FTP_LOGIN); retry_connection(c); return; } - if (g >= 400) { setcstate(c, S_FTP_UNAVAIL); retry_connection(c); return; } - if (g >= 200 && g < 300) { - if (ftp_options.fast_ftp) ftp_dummy_info(c, rb); - else ftp_send_retr_req(c, S_GETH, 0); - } else { - if (ftp_options.fast_ftp) ftp_pass_info(c, rb); - else { - unsigned char *login; - unsigned char *u; - int logl = 0; - login = init_str(); - add_to_str(&login, &logl, cast_uchar "PASS "); - u = get_ftp_password(c); - add_to_str(&login, &logl, u); - mem_free(u); - add_to_str(&login, &logl, cast_uchar "\r\n"); - write_to_socket(c, c->sock1, login, logl, ftp_sent_passwd); - mem_free(login); - setcstate(c, S_LOGIN); - } - } -} - -static void ftp_dummy_info(struct connection *c, struct read_buffer *rb) -{ - int g = get_ftp_response(c, rb, 0); - if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } - if (!g) { read_from_socket(c, c->sock1, rb, ftp_dummy_info); return; } - ftp_retr_file(c, rb); -} - -static void ftp_sent_passwd(struct connection *c) -{ - struct read_buffer *rb; - if (!(rb = alloc_read_buffer(c))) return; - read_from_socket(c, c->sock1, rb, ftp_pass_info); -} - -static void ftp_pass_info(struct connection *c, struct read_buffer *rb) -{ - int g = get_ftp_response(c, rb, 0); - if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } - if (!g) { read_from_socket(c, c->sock1, rb, ftp_pass_info); setcstate(c, S_LOGIN); return; } - if (g >= 530 && g < 540) { setcstate(c, S_FTP_LOGIN); abort_connection(c); return; } - if (g >= 400) { setcstate(c, S_FTP_UNAVAIL); abort_connection(c); return; } - if (ftp_options.fast_ftp) ftp_retr_file(c, rb); - else ftp_send_retr_req(c, S_GETH, 0); -} - -static void add_port_pasv(unsigned char **s, int *l, struct ftp_connection_info *inf, unsigned char *port_string) -{ - if (!inf->pasv) { - if (inf->eprt_epsv) { - add_to_str(s, l, cast_uchar "EPRT "); - add_to_str(s, l, port_string); - } else { - add_to_str(s, l, cast_uchar "PORT "); - add_to_str(s, l, port_string); - } - } else { - if (inf->eprt_epsv) { - add_to_str(s, l, cast_uchar "EPSV"); - } else { - add_to_str(s, l, cast_uchar "PASV"); - } - } - add_to_str(s, l, cast_uchar "\r\n"); -} - -static struct ftp_connection_info *add_file_cmd_to_str(struct connection *c, int we_are_in_root) -{ - unsigned char *d = get_url_data(c->url); - unsigned char *dd, *de; - int del; - unsigned char port_string[50]; - struct ftp_connection_info *inf, *inf2; - unsigned char *s; - int l; - - de = init_str(), del = 0; - add_conv_str(&de, &del, d, (int)strcspn(cast_const_char d, POST_CHAR_STRING), -2); - d = de; - inf = mem_alloc(sizeof(struct ftp_connection_info)); - memset(inf, 0, sizeof(struct ftp_connection_info)); - l = 0; - s = init_str(); - inf->we_are_in_root = we_are_in_root; - inf->pasv = ftp_options.passive_ftp; -#ifdef LINKS_2 - if (*c->socks_proxy) inf->pasv = 1; - if (ftp_options.eprt_epsv || is_ipv6(c->sock1)) inf->eprt_epsv = 1; -#endif - c->info = inf; - - if (!inf->pasv) { - int ps; - if (is_ipv6(c->sock1)) { - ps = get_pasv_socket_ipv6(c, c->sock1, &c->sock2, port_string); - if (ps) { - mem_free(d); - mem_free(s); - return NULL; - } - } else - { - unsigned char pc[6]; - ps = get_pasv_socket(c, c->sock1, &c->sock2, pc); - if (ps) { - mem_free(d); - mem_free(s); - return NULL; - } - if (inf->eprt_epsv) - sprintf(cast_char port_string, "|1|%d.%d.%d.%d|%d|", pc[0], pc[1], pc[2], pc[3], (pc[4] << 8) | pc[5]); - else - sprintf(cast_char port_string, "%d,%d,%d,%d,%d,%d", pc[0], pc[1], pc[2], pc[3], pc[4], pc[5]); - } - if (strlen(cast_const_char port_string) >= sizeof(port_string)) - internal("buffer overflow in get_pasv_socket_ipv6: %d > %d", (int)strlen(cast_const_char port_string), (int)sizeof(port_string)); - } -#ifdef HAVE_IPTOS - if (ftp_options.set_tos) { - int rx; - int on = IPTOS_THROUGHPUT; - EINTRLOOP(rx, setsockopt(c->sock2, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int))); - } -#endif - dd = d; - while (*dd == '/') dd++; - de = cast_uchar strchr(cast_const_char dd, 0); - if (dd == de || de[-1] == '/') { - inf->dir = 1; - inf->pending_commands = 3; - add_to_str(&s, &l, cast_uchar "TYPE A\r\n"); - add_port_pasv(&s, &l, inf, port_string); - if (!inf->we_are_in_root) { - add_to_str(&s, &l, cast_uchar "CWD /\r\n"); - inf->we_are_in_root = 1; - inf->pending_commands++; - } - if (dd != de) { - add_to_str(&s, &l, cast_uchar "CWD "); - add_bytes_to_str(&s, &l, dd, de - 1 - dd); - add_to_str(&s, &l, cast_uchar "\r\n"); - inf->we_are_in_root = 0; - inf->pending_commands++; - } - add_to_str(&s, &l, cast_uchar "LIST\r\n"); - c->from = 0; - } else { - inf->dir = 0; - inf->pending_commands = 3; - add_to_str(&s, &l, cast_uchar "TYPE I\r\n"); - add_port_pasv(&s, &l, inf, port_string); - if (!inf->we_are_in_root) { - add_to_str(&s, &l, cast_uchar "CWD /\r\n"); - inf->we_are_in_root = 1; - inf->pending_commands++; - } - if (c->from && c->no_cache < NC_IF_MOD) { - add_to_str(&s, &l, cast_uchar "REST "); - add_num_to_str(&s, &l, c->from); - add_to_str(&s, &l, cast_uchar "\r\n"); - inf->rest_sent = 1; - inf->pending_commands++; - } else { - c->from = 0; - } - add_to_str(&s, &l, cast_uchar "RETR "); - add_bytes_to_str(&s, &l, dd, de - dd); - add_to_str(&s, &l, cast_uchar "\r\n"); - } - inf->opc = inf->pending_commands; - if ((unsigned)l > MAXINT - sizeof(struct ftp_connection_info) - 1) overalloc(); - inf2 = mem_realloc(inf, sizeof(struct ftp_connection_info) + l + 1); - strcpy(cast_char (inf = inf2)->cmdbuf, cast_const_char s); - mem_free(s); - c->info = inf; - mem_free(d); - return inf; -} - - -static void ftp_send_retr_req(struct connection *c, int state, int we_are_in_root) -{ - struct ftp_connection_info *fi; - unsigned char *login; - int logl = 0; - set_connection_timeout(c); - login = init_str(); - if (!c->info && !(fi = add_file_cmd_to_str(c, we_are_in_root))) { - mem_free(login); - return; - } else { - fi = c->info; - } - if (ftp_options.fast_ftp) { - a:add_to_str(&login, &logl, fi->cmdbuf); - } else { - unsigned char *nl = cast_uchar strchr(cast_const_char fi->cmdbuf, '\n'); - if (!nl) goto a; - nl++; - add_bytes_to_str(&login, &logl, fi->cmdbuf, nl - fi->cmdbuf); - memmove(fi->cmdbuf, nl, strlen(cast_const_char nl) + 1); - } - write_to_socket(c, c->sock1, login, logl, ftp_retr_1); - mem_free(login); - setcstate(c, state); -} - -static void ftp_retr_1(struct connection *c) -{ - struct read_buffer *rb; - if (!(rb = alloc_read_buffer(c))) return; - read_from_socket(c, c->sock1, rb, ftp_retr_file); -} - -static void ftp_retr_file(struct connection *c, struct read_buffer *rb) -{ - int g; - struct ftp_connection_info *inf = c->info; - if (0) { - rep: - if (!ftp_options.fast_ftp) { - ftp_send_retr_req(c, S_GETH, inf->we_are_in_root); - return; - } - } - if (inf->pending_commands > 1) { - unsigned char pc[6] = { 0, 0, 0, 0, 0, 0 }; /* against warning */ - if (inf->pasv && inf->opc - (inf->pending_commands - 1) == 2) { - int i, j; - i = 3; - if (!inf->eprt_epsv) while (i < rb->len) { - if (rb->data[i] >= '0' && rb->data[i] <= '9') { - for (j = 0; j < 6; j++) { - int n = 0; - while (rb->data[i] >= '0' && rb->data[i] <= '9') { - n = n * 10 + rb->data[i] - '0'; - if (n >= 256) goto no_pasv; - if (++i >= rb->len) goto no_pasv; - } - pc[j] = (unsigned char)n; - if (j != 5) { - if (rb->data[i] != ',') goto xa; - if (++i >= rb->len) goto xa; - if (rb->data[i] < '0' || rb->data[i] > '9') { - xa: - if (j != 1) goto no_pasv; - pc[4] = pc[0]; - pc[5] = pc[1]; - pc[0] = pc[1] = pc[2] = pc[3] = 0; - goto pasv_ok; - } - } - } - goto pasv_ok; - } - i++; - } - no_pasv: - i = 3; - while (i < rb->len - 5) { - if (rb->data[i] == '(' && (rb->data[i + 1] < '0' || rb->data[i + 1] > '9') && rb->data[i + 1] == rb->data[i + 2] && rb->data[i + 2] == rb->data[i + 3]) { - unsigned char delim = rb->data[i + 1]; - int n = 0; - i += 4; - while (rb->data[i] >= '0' && rb->data[i] <= '9') { - n = n * 10 + rb->data[i] - '0'; - if (n >= 65536) goto no_epsv; - if (++i >= rb->len) goto no_epsv; - } - if (rb->data[i] != delim) goto no_epsv; - pc[4] = n >> 8; - pc[5] = n & 0xff; - pc[0] = pc[1] = pc[2] = pc[3] = 0; - goto pasv_ok; - } - i++; - } - no_epsv: - memset(pc, 0, sizeof pc); - pasv_ok:; - } - g = get_ftp_response(c, rb, 0); - if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } - if (!g) { read_from_socket(c, c->sock1, rb, ftp_retr_file); setcstate(c, S_GETH); return; } - inf->pending_commands--; - switch (inf->opc - inf->pending_commands) { - case 1: /* TYPE */ - goto rep; - case 2: /* PORT */ - if (g >= 400) { setcstate(c, S_FTP_PORT); abort_connection(c); return; } - if (inf->pasv) { - if (!pc[4] && !pc[5]) { - setcstate(c, S_FTP_ERROR); - retry_connection(c); - return; - } - make_connection(c, (pc[4] << 8) + pc[5], &c->sock2, created_data_connection); - } - goto rep; - case 3: /* REST / CWD */ - case 4: - if (g >= 400) { - if (!inf->dir && c->from && inf->pending_commands == 1) c->from = 0; - else { setcstate(c, S_FTP_NO_FILE); abort_connection(c); return; } - } - goto rep; - } - internal("WHAT???"); - } - g = get_ftp_response(c, rb, 2); - if (!g) { read_from_socket(c, c->sock1, rb, ftp_retr_file); setcstate(c, S_GETH); return; } - if (g >= 100 && g < 200) { - unsigned char *d = rb->data; - int i, p = 0; - for (i = 0; i < rb->len && d[i] != 10; i++) if (d[i] == '(') p = i; - if (!p || p == rb->len - 1) goto nol; - p++; - if (d[p] < '0' || d[p] > '9') goto nol; - for (i = p; i < rb->len; i++) if (d[i] < '0' || d[i] > '9') goto quak; - goto nol; - quak: - for (; i < rb->len; i++) if (d[i] != ' ') break; - if (i + 4 > rb->len) goto nol; - if (casecmp(&d[i], cast_uchar "byte", 4)) goto nol; - /* when resuming file transfer, some servers return total size, - others return the number of remaining bytes. So it is not - reliable to guess file size in this case */ - if (c->from) goto nol; - { - my_strtoll_t est = my_strtoll(&d[p], NULL); - if (est < 0 || (off_t)est < 0 || (off_t)est != est) est = 0; - if (est) c->est_length = est + c->from; - } - nol:; - } - if (!inf->pasv) - set_handlers(c->sock2, got_something_from_data_connection, NULL, c); - /*read_from_socket(c, c->sock1, rb, ftp_got_final_response);*/ - ftp_got_final_response(c, rb); -} - -static void ftp_got_final_response(struct connection *c, struct read_buffer *rb) -{ - struct ftp_connection_info *inf = c->info; - int g = get_ftp_response(c, rb, 0); - if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; } - if (!g) { read_from_socket(c, c->sock1, rb, ftp_got_final_response); if (c->state != S_TRANS) setcstate(c, S_GETH); return; } - if (g == 425 || g == 450 || g == 500 || g == 501 || g == 550) { - if (c->url[strlen(cast_const_char c->url) - 1] == '/') goto skip_redir; - if (!c->cache) { - if (get_connection_cache_entry(c)) { - setcstate(c, S_OUT_OF_MEM); - abort_connection(c); - return; - } - c->cache->refcount--; - } - if (c->cache->redirect) mem_free(c->cache->redirect); - c->cache->redirect = stracpy(c->url); - c->cache->redirect_get = 1; - add_to_strn(&c->cache->redirect, cast_uchar "/"); - c->cache->incomplete = 0; - /*setcstate(c, S_FTP_NO_FILE);*/ - setcstate(c, S__OK); - abort_connection(c); - return; - } - skip_redir: - if (g >= 400) { setcstate(c, S_FTP_FILE_ERROR); abort_connection(c); return; } - if (inf->conn_st == 2) { - ftp_end_request(c, S__OK); - } else { - inf->conn_st = 1; - if (c->state != S_TRANS) setcstate(c, S_GETH); - } -} - -static int is_date(unsigned char *data) /* can touch at most data[-4] --- "n 12 "<--if fed with this --- if you change it, fix the caller */ -{ - /* fix for ftp://ftp.su.se/ */ - if (*data == ' ') data--; - if (data[0] >= '0' && data[0] <= '9' && data[-1] >= '0' && data[-1] <= '9') data -= 2; - else if (data[0] >= '1' && data[0] <= '9' && data[-1] == ' ') data -= 1 + (data[-2] == ' '); - else return 0; - if (data[0] == ':') return 1; - if (data[0] != ' ') return 0; - if ((data[-1] < 'a' || data[-1] > 'z') && (data[-1] < 'A' || data[-1] > 'Z')) return 0; - return 1; -} - -#define PARSE_MODE_VMS -1 - -static int ftp_process_dirlist(struct cache_entry *ce, off_t *pos, int *d, unsigned char *bf, int ln, int fin, int root, int *tr) -{ - unsigned char *str, *buf; - int sl; - int ret = 0; - int p; - int len; - int f; - int a; - int dir; - int sp; - int ee; - again: - buf = bf + ret; - len = ln - ret; - for (p = 0; p < len; p++) if (buf[p] == '\n') goto lb; - if (p && (fin || len >= FTP_BUF)) { - ret += p; - goto pl; - } - return ret; - lb: - ret += p + 1; - if (p && buf[p - 1] == '\r') p--; - pl: - str = init_str(); - sl = 0; - /*add_to_str(&str, &sl, cast_uchar " ");*/ - - dir = 0; - if (!*d || *d == PARSE_MODE_VMS) for (ee = 0; ee + 1 < p && !WHITECHAR(buf[ee]); ee++) { - if (buf[ee] == ';' && buf[ee + 1] >= '1' && buf[ee + 1] <= '9') { - if (!ee) goto skip_vms; - if (ee >= 4 && buf[ee - 4] == '.' && buf[ee - 3] == 'D' && buf[ee - 2] == 'I' && buf[ee - 1] == 'R') { - if (ee == 4) goto raw; - dir = 1, ee -= 4; - } else { - /*if (buf[ee + 1] == '1' && (ee + 2 == p || buf[ee + 2] < '0' || buf[ee + 2] > '9')) goto no_version; - ee += 2; - while (ee < p && buf[ee] >= '0' && buf[ee] < '9') ee++; - no_version:;*/ - } - if (*d != PARSE_MODE_VMS && !root) { - add_to_str(&str, &sl, cast_uchar "<a href=\"../\">..</a>\n"); - } - sp = 0; - *d = PARSE_MODE_VMS; - goto put_entry; - } - } - skip_vms: - - if (*d < 0) goto raw; - - f = *d; - if (*d && *d < p && WHITECHAR(buf[*d - 1])) { - sp = *d; - ppp: - for (ee = sp; ee <= p - 4; ee++) - if (!memcmp(buf + ee, cast_uchar " -> ", 4)) goto syml; - ee = p; - syml: - if (!f && !root) { - if ((ee - sp != 1 || buf[sp] != '.') && - (ee - sp != 2 || buf[sp] != '.' || buf[sp + 1] != '.')) { - int i; - for (i = 0; i < sp; i++) add_chr_to_str(&str, &sl, ' '); - add_to_str(&str, &sl, cast_uchar "<a href=\"../\">..</a>\n"); - } - } - dir = buf[0] == 'd'; - if (!dir) { - unsigned char *p = memacpy(buf, sp); - if (strstr(cast_const_char p, "<DIR>")) dir = 1; - mem_free(p); - }; - put_entry: - add_conv_str(&str, &sl, buf, sp, 0); - add_to_str(&str, &sl, cast_uchar "<a href=\"./"); - add_conv_str(&str, &sl, buf + sp, ee - sp, 1); - if (dir) add_chr_to_str(&str, &sl, '/'); - add_to_str(&str, &sl, cast_uchar "\">"); - add_conv_str(&str, &sl, buf + sp, ee - sp, 0); - add_to_str(&str, &sl, cast_uchar "</a>"); - add_conv_str(&str, &sl, buf + ee, p - ee, 0); - } else { - int pp, ppos; - int bp, bn; - if (p > 5 && !casecmp(buf, cast_uchar "total", 5)) goto raw; - if (p > 10 && !memcmp(buf, cast_uchar "Directory ", 10)) goto raw; - for (pp = p - 1; pp >= 0; pp--) if (!WHITECHAR(buf[pp])) break; - if (pp < 0) goto raw; - if (pp < p - 1) pp++; - ppos = -1; - for (; pp >= 10; pp--) if (WHITECHAR(buf[pp])) { - if (is_date(&buf[pp - 6]) && - buf[pp - 5] == ' ' && - ((buf[pp - 4] == '2' && buf[pp - 3] == '0') || - (buf[pp - 4] == '1' && buf[pp - 3] == '9')) && - buf[pp - 2] >= '0' && buf[pp - 2] <= '9' && - buf[pp - 1] >= '0' && buf[pp - 1] <= '9') { - if (pp < p - 2 && buf[pp + 1] == ' ' && buf[pp + 2] != ' ') ppos = pp + 1; - else ppos = pp; - } - if (buf[pp - 6] == ' ' && - ((buf[pp - 5] >= '0' && buf[pp - 5] <= '2') || buf[pp - 5] == ' ') && - buf[pp - 4] >= '0' && buf[pp - 4] <= '9' && - buf[pp - 3] == ':' && - buf[pp - 2] >= '0' && buf[pp - 2] <= '5' && - buf[pp - 1] >= '0' && buf[pp - 1] <= '9') { - ppos = pp; - if (pp + 2 < p && buf[pp + 1] == ' ' && buf[pp + 2] != ' ') - ppos++; - } - } - if (ppos != -1) { - pp = ppos; - goto done; - } - - for (pp = 0; pp + 5 <= p; pp++) - if (!casecmp(&buf[pp], cast_uchar "<DIR>", 5)) { - pp += 4; - while (pp + 1 < p && WHITECHAR(buf[pp + 1])) pp++; - if (pp + 1 < p) goto done; - } - - bn = -1; - bp = 0; /* warning, go away */ - for (pp = 0; pp < p; ) { - if (buf[pp] >= '0' && buf[pp] <= '9') { - int i; - for (i = pp; i < p; i++) - if (buf[i] < '0' || buf[i] > '9') break; - if (i < p && WHITECHAR(buf[i])) { - if (i - pp > bn) { - bn = i - pp; - bp = pp; - } - } - pp = i; - } - while (pp < p && !WHITECHAR(buf[pp])) pp++; - while (pp < p && WHITECHAR(buf[pp])) pp++; - } - if (bn >= 0) { - pp = bp + bn; - while (pp + 1 < p && WHITECHAR(buf[pp + 1])) pp++; - if (pp + 1 < p) goto done; - } - - for (pp = p - 1; pp >= 0; pp--) if (!WHITECHAR(buf[pp])) break; - if (pp < 0) goto raw; - for (; pp >= 0; pp--) if (WHITECHAR(buf[pp]) && (pp < 3 || memcmp(buf + pp - 3, cast_uchar " -> ", 4)) && (pp > p - 4 || memcmp(buf + pp, cast_uchar " -> ", 4))) break; - done: - sp = *d = pp + 1; - goto ppp; - raw: - add_conv_str(&str, &sl, buf, p, 0); - } - add_chr_to_str(&str, &sl, '\n'); - a = add_fragment(ce, *pos, str, sl); - if (a < 0) return a; - if (a == 1) *tr = 0; - *pos += sl; - mem_free(str); - goto again; -} - -static void created_data_connection(struct connection *c) -{ - struct ftp_connection_info *inf = c->info; -#ifdef HAVE_IPTOS - if (ftp_options.set_tos) { - int rx; - int on = IPTOS_THROUGHPUT; - EINTRLOOP(rx, setsockopt(c->sock2, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int))); - } -#endif - inf->d = 1; - set_handlers(c->sock2, got_something_from_data_connection, NULL, c); -} - -static void got_something_from_data_connection(void *c_) -{ - struct connection *c = (struct connection *)c_; - struct ftp_connection_info *inf = c->info; - int l; - int m; - int rs; - set_connection_timeout(c); - if (!inf->d) { - int ns; - inf->d = 1; - set_handlers(c->sock2, NULL, NULL, NULL); - ns = c_accept(c->sock2, NULL, NULL); - if (ns == -1) goto e; - set_nonblock(ns); - EINTRLOOP(rs, close(c->sock2)); - c->sock2 = ns; - set_handlers(ns, got_something_from_data_connection, NULL, c); - return; - } - if (!c->cache) { - if (get_connection_cache_entry(c)) { - setcstate(c, S_OUT_OF_MEM); - abort_connection(c); - return; - } - c->cache->refcount--; - } - if (inf->dir && !c->from) { - unsigned char *ud; - unsigned char *s0; - int s0l; - int err = 0; - static const unsigned char ftp_head[] = "<html><head><title>/"; - static const unsigned char ftp_head2[] = "</title></head><body><h2>Directory /"; - static const unsigned char ftp_head3[] = "</h2><pre>"; -#define A(s) \ -do { \ - m = add_fragment(c->cache, c->from, s, strlen(cast_const_char s));\ - if (m < 0 && !err) err = m; \ - c->from += strlen(cast_const_char s); \ -} while (0) - A(ftp_head); - ud = stracpy(get_url_data(c->url)); - if (strchr(cast_const_char ud, POST_CHAR)) *strchr(cast_const_char ud, POST_CHAR) = 0; - s0 = init_str(); - s0l = 0; - add_conv_str(&s0, &s0l, ud, (int)strlen(cast_const_char ud), -1); - mem_free(ud); - A(s0); - A(ftp_head2); - A(s0); - A(ftp_head3); - mem_free(s0); - if (!c->cache->head) c->cache->head = stracpy(cast_uchar "\r\n"); - add_to_strn(&c->cache->head, cast_uchar "Content-Type: text/html\r\n"); - if (err) { - setcstate(c, err); - abort_connection(c); - return; - } -#undef A - } - EINTRLOOP(l, (int)read(c->sock2, inf->ftp_buffer + inf->buf_pos, FTP_BUF - inf->buf_pos)); - if (l == -1) { - e: - if (inf->conn_st != 1 && !inf->dir && !c->from) { - close_socket(&c->sock2); - inf->conn_st = 2; - return; - } - setcstate(c, get_error_from_errno(errno)); - retry_connection(c); - return; - } - if (l > 0) { - if (!inf->dir) { - if ((off_t)(0UL + c->from + l) < 0) { - setcstate(c, S_LARGE_FILE); - abort_connection(c); - return; - } - c->received += l; - m = add_fragment(c->cache, c->from, inf->ftp_buffer, l); - if (m < 0) { - setcstate(c, m); - abort_connection(c); - return; - } - if (m == 1) c->tries = 0; - c->from += l; - } else { - c->received += l; - m = ftp_process_dirlist(c->cache, &c->from, &inf->dpos, inf->ftp_buffer, l + inf->buf_pos, 0, inf->we_are_in_root, &c->tries); - if (m < 0) { - setcstate(c, m); - abort_connection(c); - return; - } - memmove(inf->ftp_buffer, inf->ftp_buffer + m, inf->buf_pos + l - m); - inf->buf_pos += l - m; - } - setcstate(c, S_TRANS); - return; - } - m = ftp_process_dirlist(c->cache, &c->from, &inf->dpos, inf->ftp_buffer, inf->buf_pos, 1, inf->we_are_in_root, &c->tries); - if (m < 0) { - setcstate(c, m); - abort_connection(c); - return; - } - close_socket(&c->sock2); - if (inf->conn_st == 1) { - ftp_end_request(c, S__OK); - } else { - inf->conn_st = 2; - } -} - -static void ftp_end_request(struct connection *c, int state) -{ - struct ftp_connection_info *inf = c->info; - if (state == S__OK) { - if (c->cache) { - truncate_entry(c->cache, c->from, 1); - c->cache->incomplete = 0; - } - } - setcstate(c, state); - add_keepalive_socket(c, FTP_KEEPALIVE_TIMEOUT, inf->we_are_in_root); -} - diff --git a/links.h b/links.h @@ -1587,29 +1587,10 @@ void data_func(struct connection *); void file_func(struct connection *); -/* finger.c */ - -void finger_func(struct connection *); - -/* ftp.c */ - -#if defined(IP_TOS) && defined(IPTOS_THROUGHPUT) -#define HAVE_IPTOS -#endif - -void ftp_func(struct connection *); - -/* smb.c */ - -void smb_func(struct connection *); - /* mailto.c */ void magnet_func(struct session *, unsigned char *); void mailto_func(struct session *, unsigned char *); -void telnet_func(struct session *, unsigned char *); -void tn3270_func(struct session *, unsigned char *); -void mms_func(struct session *, unsigned char *); /* kbd.c */ diff --git a/mailto.c b/mailto.c @@ -6,7 +6,6 @@ #include "links.h" - static void prog_func(struct terminal *term, struct list_head *list, unsigned char *param, unsigned char *name) { unsigned char *prog, *cmd; @@ -41,58 +40,3 @@ void mailto_func(struct session *ses, unsigned char *url) fail: if (f) msg_box(ses->term, NULL, TEXT_(T_BAD_URL_SYNTAX), AL_CENTER, TEXT_(T_BAD_MAILTO_URL), NULL, 1, TEXT_(T_CANCEL), NULL, B_ENTER | B_ESC); } - -static void tn_func(struct session *ses, unsigned char *url, struct list_head *prog, unsigned char *t1, unsigned char *t2) -{ - unsigned char *m; - unsigned char *h, *p; - int hl, pl; - unsigned char *hh, *pp = NULL /* against warning */; - int f = 1; - if (parse_url(url, NULL, NULL, NULL, NULL, NULL, &h, &hl, &p, &pl, NULL, NULL, NULL) || !hl) goto fail; - hh = memacpy(h, hl); - if (pl) pp = memacpy(p, pl); - check_shell_security(&hh); - if (pl) check_shell_security(&pp); - m = mem_alloc(strlen(cast_const_char hh) + (pl ? strlen(cast_const_char pp) : 0) + 2); - f = 0; - strcpy(cast_char m, cast_const_char hh); - if (pl) { - strcat(cast_char m, " "); - strcat(cast_char m, cast_const_char pp); - m[hl + 1 + pl] = 0; - } - prog_func(ses->term, prog, m, t1); - mem_free(m); - if (pl) mem_free(pp); - mem_free(hh); - fail: - if (f) msg_box(ses->term, NULL, TEXT_(T_BAD_URL_SYNTAX), AL_CENTER, t2, NULL, 1, TEXT_(T_CANCEL), NULL, B_ENTER | B_ESC); -} - - -void telnet_func(struct session *ses, unsigned char *url) -{ - tn_func(ses, url, &telnet_prog, TEXT_(T_TELNET), TEXT_(T_BAD_TELNET_URL)); -} - -void tn3270_func(struct session *ses, unsigned char *url) -{ - tn_func(ses, url, &tn3270_prog, TEXT_(T_TN3270), TEXT_(T_BAD_TN3270_URL)); -} - -void magnet_func(struct session *ses, unsigned char *url) -{ - unsigned char *escaped_url = escape_path(url); - prog_func(ses->term, &magnet_prog, escaped_url, TEXT_(T_MAGNET)); - mem_free(escaped_url); -} - -void mms_func(struct session *ses, unsigned char *url) -{ - if (check_shell_url(url)) { - msg_box(ses->term, NULL, TEXT_(T_BAD_URL_SYNTAX), AL_CENTER, TEXT_(T_MMS_URL_CONTAINS_INACCEPTABLE_CHARACTERS), NULL, 1, TEXT_(T_CANCEL), NULL, B_ENTER | B_ESC); - return; - } - prog_func(ses->term, &mms_prog, url, TEXT_(T_MMS)); -} diff --git a/menu.c b/menu.c @@ -1991,10 +1991,6 @@ static void dlg_ftp_options(struct terminal *term, void *xxx, void *yyy) static unsigned char * const prg_msg[] = { TEXT_(T_MAILTO_PROG), - TEXT_(T_TELNET_PROG), - TEXT_(T_TN3270_PROG), - TEXT_(T_MMS_PROG), - TEXT_(T_MAGNET_PROG), TEXT_(T_SHELL_PROG), cast_uchar "" }; @@ -2009,14 +2005,6 @@ static void netprog_fn(struct dialog_data *dlg) a=0; max_text_width(term, prg_msg[a], &max, AL_LEFT); min_text_width(term, prg_msg[a++], &min, AL_LEFT); - max_text_width(term, prg_msg[a], &max, AL_LEFT); - min_text_width(term, prg_msg[a++], &min, AL_LEFT); - max_text_width(term, prg_msg[a], &max, AL_LEFT); - min_text_width(term, prg_msg[a++], &min, AL_LEFT); - max_text_width(term, prg_msg[a], &max, AL_LEFT); - min_text_width(term, prg_msg[a++], &min, AL_LEFT); - max_text_width(term, prg_msg[a], &max, AL_LEFT); - min_text_width(term, prg_msg[a++], &min, AL_LEFT); #ifdef G if (have_extra_exec()) { max_text_width(term, prg_msg[a], &max, AL_LEFT); @@ -2035,19 +2023,6 @@ static void netprog_fn(struct dialog_data *dlg) if (term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); dlg_format_text_and_field(dlg, NULL, prg_msg[a], &dlg->items[a], 0, &y, w, &rw, COLOR_DIALOG_TEXT, AL_LEFT); a++; - if (!term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); - dlg_format_text_and_field(dlg, NULL, prg_msg[a], &dlg->items[a], 0, &y, w, &rw, COLOR_DIALOG_TEXT, AL_LEFT); - a++; - if (!term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); - dlg_format_text_and_field(dlg, NULL, prg_msg[a], &dlg->items[a], 0, &y, w, &rw, COLOR_DIALOG_TEXT, AL_LEFT); - a++; - if (!term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); - dlg_format_text_and_field(dlg, NULL, prg_msg[a], &dlg->items[a], 0, &y, w, &rw, COLOR_DIALOG_TEXT, AL_LEFT); - a++; - if (!term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); - dlg_format_text_and_field(dlg, NULL, prg_msg[a], &dlg->items[a], 0, &y, w, &rw, COLOR_DIALOG_TEXT, AL_LEFT); - a++; - if (!term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); #ifdef G if (have_extra_exec()) { dlg_format_text_and_field(dlg, NULL, prg_msg[a], &dlg->items[a], 0, &y, w, &rw, COLOR_DIALOG_TEXT, AL_LEFT); @@ -2067,19 +2042,6 @@ static void netprog_fn(struct dialog_data *dlg) a=0; dlg_format_text_and_field(dlg, term, prg_msg[a], &dlg->items[a], dlg->x + DIALOG_LB, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT); a++; - if (!term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); - dlg_format_text_and_field(dlg, term, prg_msg[a], &dlg->items[a], dlg->x + DIALOG_LB, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT); - a++; - if (!term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); - dlg_format_text_and_field(dlg, term, prg_msg[a], &dlg->items[a], dlg->x + DIALOG_LB, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT); - a++; - if (!term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); - dlg_format_text_and_field(dlg, term, prg_msg[a], &dlg->items[a], dlg->x + DIALOG_LB, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT); - a++; - if (!term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); - dlg_format_text_and_field(dlg, term, prg_msg[a], &dlg->items[a], dlg->x + DIALOG_LB, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT); - a++; - if (!term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE); #ifdef G if (have_extra_exec()) { dlg_format_text_and_field(dlg, term, prg_msg[a], &dlg->items[a], dlg->x + DIALOG_LB, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT); @@ -2100,25 +2062,13 @@ static void net_programs(struct terminal *term, void *xxx, void *yyy) if (have_extra_exec()) d->title = TEXT_(T_MAIL_TELNET_AND_SHELL_PROGRAMS); else #endif - d->title = TEXT_(T_MAIL_AND_TELNET_PROGRAMS); + d->title = TEXT_(T_MAIL_AND_TELNET_PROGRAMS); d->fn = netprog_fn; a=0; d->items[a].type = D_FIELD; d->items[a].dlen = MAX_STR_LEN; d->items[a++].data = get_prog(&mailto_prog); - d->items[a].type = D_FIELD; - d->items[a].dlen = MAX_STR_LEN; - d->items[a++].data = get_prog(&telnet_prog); - d->items[a].type = D_FIELD; - d->items[a].dlen = MAX_STR_LEN; - d->items[a++].data = get_prog(&tn3270_prog); - d->items[a].type = D_FIELD; - d->items[a].dlen = MAX_STR_LEN; - d->items[a++].data = get_prog(&mms_prog); - d->items[a].type = D_FIELD; - d->items[a].dlen = MAX_STR_LEN; - d->items[a++].data = get_prog(&magnet_prog); #ifdef G if (have_extra_exec()) { d->items[a].type = D_FIELD; diff --git a/smb.c b/smb.c @@ -1,2 +0,0 @@ -#include "links.h" - diff --git a/types.c b/types.c @@ -791,11 +791,6 @@ void create_initial_extensions(void) struct list_head mailto_prog = { &mailto_prog, &mailto_prog }; -struct list_head telnet_prog = { &telnet_prog, &telnet_prog }; -struct list_head tn3270_prog = { &tn3270_prog, &tn3270_prog }; -struct list_head mms_prog = { &mms_prog, &mms_prog }; -struct list_head magnet_prog = { &magnet_prog, &magnet_prog }; - static int is_in_list(unsigned char *list, unsigned char *str, int l) { @@ -1299,10 +1294,6 @@ void free_types(void) mem_free(e); } free_prog_list(&mailto_prog); - free_prog_list(&telnet_prog); - free_prog_list(&tn3270_prog); - free_prog_list(&mms_prog); - free_prog_list(&magnet_prog); free_history(ext_search_history); free_history(assoc_search_history); diff --git a/url.c b/url.c @@ -21,18 +21,10 @@ static_const struct { {"https", 443, https_func, NULL, 0, 1, 1, 1, 0}, {"http", 80, http_func, NULL, 0, 1, 1, 1, 0}, {"proxy", 3128, proxy_func, NULL, 0, 1, 1, 1, 0}, - {"ftp", 21, ftp_func, NULL, 0, 1, 1, 0, 0}, - {"finger", 79, finger_func, NULL, 0, 1, 1, 0, 0}, {"mailto", 0, NULL, mailto_func, 0, 0, 0, 0, 0}, - {"telnet", 0, NULL, telnet_func, 0, 0, 0, 0, 1}, - {"tn3270", 0, NULL, tn3270_func, 0, 0, 0, 0, 1}, - {"mms", 0, NULL, mms_func, 1, 0, 1, 0, 1}, - {"magnet", 0, NULL, magnet_func, 1, 0, 0, 0, 1}, {NULL, 0, NULL, NULL, 0, 0, 0, 0, 0} }; - - static int check_protocol(unsigned char *p, int l) { int i;