#include "setup.h"
#ifndef CURL_DISABLE_GOPHER
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef WIN32
#include <time.h>
#include <io.h>
#else
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <netinet/in.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <netdb.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#endif
#include "urldata.h"
#include <curl/curl.h>
#include "transfer.h"
#include "sendf.h"
#include "progress.h"
#include "strequal.h"
#include "gopher.h"
#include "rawstr.h"
#include "select.h"
#include "url.h"
#include "warnless.h"
#define _MPRINTF_REPLACE
#include <curl/mprintf.h>
#include "memdebug.h"
static CURLcode gopher_do(struct connectdata *conn, bool *done);
const struct Curl_handler Curl_handler_gopher = {
"GOPHER",
ZERO_NULL,
gopher_do,
ZERO_NULL,
ZERO_NULL,
ZERO_NULL,
ZERO_NULL,
ZERO_NULL,
ZERO_NULL,
ZERO_NULL,
ZERO_NULL,
ZERO_NULL,
PORT_GOPHER,
PROT_GOPHER
};
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;
char *sel_org = NULL;
ssize_t amount, k;
*done = TRUE;
if (strlen(path) <= 2)
sel = (char *)"";
else {
char *newp;
size_t j, i;
int len;
newp = path;
newp+=2;
j = strlen(newp);
for(i=0; i<j; i++)
if(newp[i] == '?')
newp[i] = '\x09';
sel = curl_easy_unescape(data, newp, 0, &len);
if (!sel)
return CURLE_OUT_OF_MEMORY;
sel_org = sel;
}
k = curlx_uztosz(strlen(sel));
for(;;) {
result = Curl_write(conn, sockfd, sel, k, &amount);
if (CURLE_OK == result) {
result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
if(result) {
Curl_safefree(sel_org);
return result;
}
k -= amount;
sel += amount;
if (k < 1)
break;
}
else {
failf(data, "Failed sending Gopher request");
Curl_safefree(sel_org);
return result;
}
Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
}
Curl_safefree(sel_org);
result = Curl_sendf(sockfd, conn, "\r\n");
if (result != CURLE_OK) {
failf(data, "Failed sending Gopher request");
return result;
}
result = Curl_client_write(conn, CLIENTWRITE_HEADER, (char *)"\r\n", 2);
if(result)
return result;
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-1, NULL);
return CURLE_OK;
}
#endif