dict.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at http://curl.haxx.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. * $Id$
  22. ***************************************************************************/
  23. #include "setup.h"
  24. #ifndef CURL_DISABLE_DICT
  25. /* -- WIN32 approved -- */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <stdarg.h>
  29. #include <stdlib.h>
  30. #include <ctype.h>
  31. #ifdef WIN32
  32. #include <time.h>
  33. #include <io.h>
  34. #else
  35. #ifdef HAVE_SYS_SOCKET_H
  36. #include <sys/socket.h>
  37. #endif
  38. #include <netinet/in.h>
  39. #ifdef HAVE_SYS_TIME_H
  40. #include <sys/time.h>
  41. #endif
  42. #ifdef HAVE_UNISTD_H
  43. #include <unistd.h>
  44. #endif
  45. #include <netdb.h>
  46. #ifdef HAVE_ARPA_INET_H
  47. #include <arpa/inet.h>
  48. #endif
  49. #ifdef HAVE_NET_IF_H
  50. #include <net/if.h>
  51. #endif
  52. #ifdef HAVE_SYS_IOCTL_H
  53. #include <sys/ioctl.h>
  54. #endif
  55. #ifdef HAVE_SYS_PARAM_H
  56. #include <sys/param.h>
  57. #endif
  58. #ifdef HAVE_SYS_SELECT_H
  59. #include <sys/select.h>
  60. #endif
  61. #endif
  62. #include "urldata.h"
  63. #include <curl/curl.h>
  64. #include "transfer.h"
  65. #include "sendf.h"
  66. #include "progress.h"
  67. #include "strequal.h"
  68. #include "dict.h"
  69. #include "rawstr.h"
  70. #define _MPRINTF_REPLACE /* use our functions only */
  71. #include <curl/mprintf.h>
  72. /* The last #include file should be: */
  73. #include "memdebug.h"
  74. /*
  75. * Forward declarations.
  76. */
  77. static CURLcode dict_do(struct connectdata *conn, bool *done);
  78. /*
  79. * DICT protocol handler.
  80. */
  81. const struct Curl_handler Curl_handler_dict = {
  82. "DICT", /* scheme */
  83. ZERO_NULL, /* setup_connection */
  84. dict_do, /* do_it */
  85. ZERO_NULL, /* done */
  86. ZERO_NULL, /* do_more */
  87. ZERO_NULL, /* connect_it */
  88. ZERO_NULL, /* connecting */
  89. ZERO_NULL, /* doing */
  90. ZERO_NULL, /* proto_getsock */
  91. ZERO_NULL, /* doing_getsock */
  92. ZERO_NULL, /* perform_getsock */
  93. ZERO_NULL, /* disconnect */
  94. PORT_DICT, /* defport */
  95. PROT_DICT /* protocol */
  96. };
  97. static char *unescape_word(struct SessionHandle *data, const char *inp)
  98. {
  99. char *newp;
  100. char *dictp;
  101. char *ptr;
  102. int len;
  103. char byte;
  104. int olen=0;
  105. newp = curl_easy_unescape(data, inp, 0, &len);
  106. if(!newp)
  107. return NULL;
  108. dictp = malloc(len*2 + 1); /* add one for terminating zero */
  109. if(dictp) {
  110. /* According to RFC2229 section 2.2, these letters need to be escaped with
  111. \[letter] */
  112. for(ptr = newp;
  113. (byte = *ptr) != 0;
  114. ptr++) {
  115. if((byte <= 32) || (byte == 127) ||
  116. (byte == '\'') || (byte == '\"') || (byte == '\\')) {
  117. dictp[olen++] = '\\';
  118. }
  119. dictp[olen++] = byte;
  120. }
  121. dictp[olen]=0;
  122. free(newp);
  123. }
  124. return dictp;
  125. }
  126. static CURLcode dict_do(struct connectdata *conn, bool *done)
  127. {
  128. char *word;
  129. char *eword;
  130. char *ppath;
  131. char *database = NULL;
  132. char *strategy = NULL;
  133. char *nthdef = NULL; /* This is not part of the protocol, but required
  134. by RFC 2229 */
  135. CURLcode result=CURLE_OK;
  136. struct SessionHandle *data=conn->data;
  137. curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
  138. char *path = data->state.path;
  139. curl_off_t *bytecount = &data->req.bytecount;
  140. *done = TRUE; /* unconditionally */
  141. if(conn->bits.user_passwd) {
  142. /* AUTH is missing */
  143. }
  144. if(Curl_raw_nequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
  145. Curl_raw_nequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
  146. Curl_raw_nequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
  147. word = strchr(path, ':');
  148. if(word) {
  149. word++;
  150. database = strchr(word, ':');
  151. if(database) {
  152. *database++ = (char)0;
  153. strategy = strchr(database, ':');
  154. if(strategy) {
  155. *strategy++ = (char)0;
  156. nthdef = strchr(strategy, ':');
  157. if(nthdef) {
  158. *nthdef++ = (char)0;
  159. }
  160. }
  161. }
  162. }
  163. if((word == NULL) || (*word == (char)0)) {
  164. infof(data, "lookup word is missing");
  165. word=(char *)"default";
  166. }
  167. if((database == NULL) || (*database == (char)0)) {
  168. database = (char *)"!";
  169. }
  170. if((strategy == NULL) || (*strategy == (char)0)) {
  171. strategy = (char *)".";
  172. }
  173. eword = unescape_word(data, word);
  174. if(!eword)
  175. return CURLE_OUT_OF_MEMORY;
  176. result = Curl_sendf(sockfd, conn,
  177. "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
  178. "MATCH "
  179. "%s " /* database */
  180. "%s " /* strategy */
  181. "%s\r\n" /* word */
  182. "QUIT\r\n",
  183. database,
  184. strategy,
  185. eword
  186. );
  187. free(eword);
  188. if(result)
  189. failf(data, "Failed sending DICT request");
  190. else
  191. result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
  192. -1, NULL); /* no upload */
  193. if(result)
  194. return result;
  195. }
  196. else if(Curl_raw_nequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
  197. Curl_raw_nequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
  198. Curl_raw_nequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
  199. word = strchr(path, ':');
  200. if(word) {
  201. word++;
  202. database = strchr(word, ':');
  203. if(database) {
  204. *database++ = (char)0;
  205. nthdef = strchr(database, ':');
  206. if(nthdef) {
  207. *nthdef++ = (char)0;
  208. }
  209. }
  210. }
  211. if((word == NULL) || (*word == (char)0)) {
  212. infof(data, "lookup word is missing");
  213. word=(char *)"default";
  214. }
  215. if((database == NULL) || (*database == (char)0)) {
  216. database = (char *)"!";
  217. }
  218. eword = unescape_word(data, word);
  219. if(!eword)
  220. return CURLE_OUT_OF_MEMORY;
  221. result = Curl_sendf(sockfd, conn,
  222. "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
  223. "DEFINE "
  224. "%s " /* database */
  225. "%s\r\n" /* word */
  226. "QUIT\r\n",
  227. database,
  228. eword);
  229. free(eword);
  230. if(result)
  231. failf(data, "Failed sending DICT request");
  232. else
  233. result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
  234. -1, NULL); /* no upload */
  235. if(result)
  236. return result;
  237. }
  238. else {
  239. ppath = strchr(path, '/');
  240. if(ppath) {
  241. int i;
  242. ppath++;
  243. for (i = 0; ppath[i]; i++) {
  244. if(ppath[i] == ':')
  245. ppath[i] = ' ';
  246. }
  247. result = Curl_sendf(sockfd, conn,
  248. "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
  249. "%s\r\n"
  250. "QUIT\r\n", ppath);
  251. if(result)
  252. failf(data, "Failed sending DICT request");
  253. else
  254. result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
  255. -1, NULL);
  256. if(result)
  257. return result;
  258. }
  259. }
  260. return CURLE_OK;
  261. }
  262. #endif /*CURL_DISABLE_DICT*/