From 201637d4682973bcc4a1fd0f4e8d4159300bd0b8 Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Thu, 12 Aug 2010 07:55:48 -0700 Subject: [PATCH] Gopher protocol support (initial release) --- configure.ac | 19 ++++++ include/curl/curl.h | 1 + lib/Makefile.inc | 3 +- lib/gopher.c | 162 ++++++++++++++++++++++++++++++++++++++++++++ lib/gopher.h | 29 ++++++++ lib/url.c | 8 +++ lib/urldata.h | 9 ++- lib/version.c | 3 + src/main.c | 1 + 9 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 lib/gopher.c create mode 100644 lib/gopher.h diff --git a/configure.ac b/configure.ac index a389cfd85..76c151efd 100644 --- a/configure.ac +++ b/configure.ac @@ -570,6 +570,22 @@ AC_HELP_STRING([--disable-smtp],[Disable SMTP support]), AC_MSG_RESULT(yes) ) +AC_MSG_CHECKING([whether to support gopher]) +AC_ARG_ENABLE(gopher, +AC_HELP_STRING([--enable-gopher],[Enable Gopher support]) +AC_HELP_STRING([--disable-gopher],[Disable Gopher support]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable Gopher]) + AC_SUBST(CURL_DISABLE_GOPHER, [1]) + ;; + *) AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + dnl ********************************************************************** dnl Check for built-in manual @@ -2738,6 +2754,9 @@ fi if test "x$CURL_DISABLE_TFTP" != "x1"; then SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS TFTP" fi +if test "x$CURL_DISABLE_GOPHER" != "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS GOPHER" +fi if test "x$CURL_DISABLE_POP3" != "x1"; then SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS POP3" if test "x$SSL_ENABLED" = "x1"; then diff --git a/include/curl/curl.h b/include/curl/curl.h index b19828f58..cb9d0fbfb 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -722,6 +722,7 @@ typedef enum { #define CURLPROTO_RTMPTE (1<<22) #define CURLPROTO_RTMPS (1<<23) #define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) #define CURLPROTO_ALL (~0) /* enable everything */ /* long may be 32 or 64 bits, but we should never depend on anything else diff --git a/lib/Makefile.inc b/lib/Makefile.inc index bfd3abedc..33b576520 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -20,7 +20,8 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c \ socks_gssapi.c socks_sspi.c curl_sspi.c slist.c nonblock.c \ curl_memrchr.c imap.c pop3.c smtp.c pingpong.c rtsp.c curl_threads.c \ - warnless.c hmac.c polarssl.c curl_rtmp.c openldap.c curl_gethostname.c + warnless.c hmac.c polarssl.c curl_rtmp.c openldap.c curl_gethostname.c\ + gopher.c HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \ progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \ diff --git a/lib/gopher.c b/lib/gopher.c new file mode 100644 index 000000000..d1ca440e5 --- /dev/null +++ b/lib/gopher.c @@ -0,0 +1,162 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "setup.h" + +#ifndef CURL_DISABLE_GOPHER + +/* -- WIN32 approved -- */ +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#include +#else +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + + +#endif + +#include "urldata.h" +#include +#include "transfer.h" +#include "sendf.h" + +#include "progress.h" +#include "strequal.h" +#include "gopher.h" +#include "rawstr.h" + +#define _MPRINTF_REPLACE /* use our functions only */ +#include + +/* The last #include file should be: */ +#include "memdebug.h" + + +/* + * Forward declarations. + */ + +static CURLcode gopher_do(struct connectdata *conn, bool *done); + +/* + * Gopher protocol handler. + * This is also a nice simple template to build off for simple + * connect-command-download protocols. + */ + +const struct Curl_handler Curl_handler_gopher = { + "GOPHER", /* scheme */ + ZERO_NULL, /* setup_connection */ + gopher_do, /* do_it */ + ZERO_NULL, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + PORT_GOPHER, /* defport */ + PROT_GOPHER /* protocol */ +}; + +static CURLcode gopher_do(struct connectdata *conn, bool *done) +{ + CURLcode result=CURLE_OK; + struct SessionHandle *data=conn->data; + curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; + + curl_off_t *bytecount = &data->req.bytecount; + char *path = data->state.path; + + char *sel; + + *done = TRUE; /* unconditionally */ + + /* Create selector. Degenerate cases: / and /1 => convert to "" */ + if (strlen(path) <= 2) + sel = (char *)""; + else { + char *newp; + int i, j, len; + + /* Otherwise, drop / and the first character (i.e., item type) ... */ + newp = path; + newp+=2; + + /* ... then turn ? into TAB for search servers, Veronica, etc. ... */ + j = strlen(newp); + if (j) + for(i=0; i, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifndef CURL_DISABLE_GOPHER +extern const struct Curl_handler Curl_handler_gopher; +#endif + +#endif /* HEADER_CURL_GOPHER_H */ diff --git a/lib/url.c b/lib/url.c index 3ae797532..6b312eb11 100644 --- a/lib/url.c +++ b/lib/url.c @@ -138,6 +138,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "socks.h" #include "rtsp.h" #include "curl_rtmp.h" +#include "gopher.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -227,6 +228,10 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_rtsp, #endif +#ifndef CURL_DISABLE_GOPHER + &Curl_handler_gopher, +#endif + #ifdef USE_LIBRTMP &Curl_handler_rtmp, &Curl_handler_rtmpt, @@ -3482,8 +3487,11 @@ static CURLcode findprotocol(struct SessionHandle *data, if(Curl_raw_equal(p->scheme, protostr)) { /* Protocol found in table. Check if allowed */ if(!(data->set.allowed_protocols & p->protocol)) +{ /* nope, get out */ + fprintf(stderr, "well, shit\n"); break; +} /* it is allowed for "normal" request, now do an extra check if this is the result of a redirect */ diff --git a/lib/urldata.h b/lib/urldata.h index 940cb3551..9369dd853 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -46,6 +46,7 @@ #define PORT_RTMP 1935 #define PORT_RTMPT PORT_HTTP #define PORT_RTMPS PORT_HTTPS +#define PORT_GOPHER 70 #define DICT_MATCH "/MATCH:" #define DICT_MATCH2 "/M:" @@ -712,11 +713,13 @@ struct connectdata { #define PROT_RTMPTE CURLPROTO_RTMPTE #define PROT_RTMPS CURLPROTO_RTMPS #define PROT_RTMPTS CURLPROTO_RTMPTS +#define PROT_GOPHER CURLPROTO_GOPHER -/* (1<<24) is currently the highest used bit in the public bitmask. We make - sure we use "private bits" above the public ones to make things easier. */ +/* (1<<25) is currently the highest used bit in the public bitmask. We make + sure we use "private bits" above the public ones to make things easier; + Gopher will not conflict with the current bit 25. */ -#define PROT_EXTMASK 0xffffff +#define PROT_EXTMASK 0x03ffffff #define PROT_SSL (1<<29) /* protocol requires SSL */ diff --git a/lib/version.c b/lib/version.c index 9a336a32d..9ba2e33c1 100644 --- a/lib/version.c +++ b/lib/version.c @@ -158,6 +158,9 @@ static const char * const protocols[] = { #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) "ftps", #endif +#ifndef CURL_DISABLE_GOPHER + "gopher", +#endif #ifndef CURL_DISABLE_HTTP "http", #endif diff --git a/src/main.c b/src/main.c index 3734c94fd..d428a7850 100644 --- a/src/main.c +++ b/src/main.c @@ -1552,6 +1552,7 @@ static long proto2num(struct Configurable *config, long *val, const char *str) { "smtp", CURLPROTO_SMTP }, { "smtps", CURLPROTO_SMTPS }, { "rtsp", CURLPROTO_RTSP }, + { "gopher", CURLPROTO_GOPHER }, { NULL, 0 } };