00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "curl_setup.h"
00024
00025 #ifndef CURL_DISABLE_GOPHER
00026
00027 #include "urldata.h"
00028 #include <curl/curl.h>
00029 #include "transfer.h"
00030 #include "sendf.h"
00031 #include "progress.h"
00032 #include "gopher.h"
00033 #include "select.h"
00034 #include "url.h"
00035 #include "escape.h"
00036 #include "warnless.h"
00037 #include "curl_memory.h"
00038
00039 #include "memdebug.h"
00040
00041
00042
00043
00044
00045 static CURLcode gopher_do(struct connectdata *conn, bool *done);
00046
00047
00048
00049
00050
00051
00052
00053 const struct Curl_handler Curl_handler_gopher = {
00054 "GOPHER",
00055 ZERO_NULL,
00056 gopher_do,
00057 ZERO_NULL,
00058 ZERO_NULL,
00059 ZERO_NULL,
00060 ZERO_NULL,
00061 ZERO_NULL,
00062 ZERO_NULL,
00063 ZERO_NULL,
00064 ZERO_NULL,
00065 ZERO_NULL,
00066 ZERO_NULL,
00067 ZERO_NULL,
00068 PORT_GOPHER,
00069 CURLPROTO_GOPHER,
00070 PROTOPT_NONE
00071 };
00072
00073 static CURLcode gopher_do(struct connectdata *conn, bool *done)
00074 {
00075 CURLcode result=CURLE_OK;
00076 struct Curl_easy *data=conn->data;
00077 curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
00078
00079 curl_off_t *bytecount = &data->req.bytecount;
00080 char *path = data->state.path;
00081 char *sel;
00082 char *sel_org = NULL;
00083 ssize_t amount, k;
00084 size_t len;
00085
00086 *done = TRUE;
00087
00088
00089 if(strlen(path) <= 2) {
00090 sel = (char *)"";
00091 len = (int)strlen(sel);
00092 }
00093 else {
00094 char *newp;
00095 size_t j, i;
00096
00097
00098 newp = path;
00099 newp+=2;
00100
00101
00102 j = strlen(newp);
00103 for(i=0; i<j; i++)
00104 if(newp[i] == '?')
00105 newp[i] = '\x09';
00106
00107
00108 result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
00109 if(!sel)
00110 return CURLE_OUT_OF_MEMORY;
00111 sel_org = sel;
00112 }
00113
00114
00115
00116 k = curlx_uztosz(len);
00117
00118 for(;;) {
00119 result = Curl_write(conn, sockfd, sel, k, &amount);
00120 if(!result) {
00121 result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
00122 if(result)
00123 break;
00124
00125 k -= amount;
00126 sel += amount;
00127 if(k < 1)
00128 break;
00129 }
00130 else
00131 break;
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 if(SOCKET_WRITABLE(sockfd, 100) < 0) {
00143 result = CURLE_SEND_ERROR;
00144 break;
00145 }
00146 }
00147
00148 free(sel_org);
00149
00150 if(!result)
00151
00152
00153 result = Curl_sendf(sockfd, conn, "\r\n");
00154 if(result) {
00155 failf(data, "Failed sending Gopher request");
00156 return result;
00157 }
00158 result = Curl_client_write(conn, CLIENTWRITE_HEADER, (char *)"\r\n", 2);
00159 if(result)
00160 return result;
00161
00162 Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
00163 -1, NULL);
00164 return CURLE_OK;
00165 }
00166 #endif