Annotation of embedaddon/curl/lib/dict.c, revision 1.1.1.1

1.1       misho       1: /***************************************************************************
                      2:  *                                  _   _ ____  _
                      3:  *  Project                     ___| | | |  _ \| |
                      4:  *                             / __| | | | |_) | |
                      5:  *                            | (__| |_| |  _ <| |___
                      6:  *                             \___|\___/|_| \_\_____|
                      7:  *
                      8:  * Copyright (C) 1998 - 2020, 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 https://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:  ***************************************************************************/
                     22: 
                     23: #include "curl_setup.h"
                     24: 
                     25: #ifndef CURL_DISABLE_DICT
                     26: 
                     27: #ifdef HAVE_NETINET_IN_H
                     28: #include <netinet/in.h>
                     29: #endif
                     30: #ifdef HAVE_NETDB_H
                     31: #include <netdb.h>
                     32: #endif
                     33: #ifdef HAVE_ARPA_INET_H
                     34: #include <arpa/inet.h>
                     35: #endif
                     36: #ifdef HAVE_NET_IF_H
                     37: #include <net/if.h>
                     38: #endif
                     39: #ifdef HAVE_SYS_IOCTL_H
                     40: #include <sys/ioctl.h>
                     41: #endif
                     42: 
                     43: #ifdef HAVE_SYS_PARAM_H
                     44: #include <sys/param.h>
                     45: #endif
                     46: 
                     47: #ifdef HAVE_SYS_SELECT_H
                     48: #include <sys/select.h>
                     49: #elif defined(HAVE_UNISTD_H)
                     50: #include <unistd.h>
                     51: #endif
                     52: 
                     53: #include "urldata.h"
                     54: #include <curl/curl.h>
                     55: #include "transfer.h"
                     56: #include "sendf.h"
                     57: #include "escape.h"
                     58: #include "progress.h"
                     59: #include "dict.h"
                     60: #include "strcase.h"
                     61: #include "curl_memory.h"
                     62: /* The last #include file should be: */
                     63: #include "memdebug.h"
                     64: 
                     65: /*
                     66:  * Forward declarations.
                     67:  */
                     68: 
                     69: static CURLcode dict_do(struct connectdata *conn, bool *done);
                     70: 
                     71: /*
                     72:  * DICT protocol handler.
                     73:  */
                     74: 
                     75: const struct Curl_handler Curl_handler_dict = {
                     76:   "DICT",                               /* scheme */
                     77:   ZERO_NULL,                            /* setup_connection */
                     78:   dict_do,                              /* do_it */
                     79:   ZERO_NULL,                            /* done */
                     80:   ZERO_NULL,                            /* do_more */
                     81:   ZERO_NULL,                            /* connect_it */
                     82:   ZERO_NULL,                            /* connecting */
                     83:   ZERO_NULL,                            /* doing */
                     84:   ZERO_NULL,                            /* proto_getsock */
                     85:   ZERO_NULL,                            /* doing_getsock */
                     86:   ZERO_NULL,                            /* domore_getsock */
                     87:   ZERO_NULL,                            /* perform_getsock */
                     88:   ZERO_NULL,                            /* disconnect */
                     89:   ZERO_NULL,                            /* readwrite */
                     90:   ZERO_NULL,                            /* connection_check */
                     91:   PORT_DICT,                            /* defport */
                     92:   CURLPROTO_DICT,                       /* protocol */
                     93:   PROTOPT_NONE | PROTOPT_NOURLQUERY      /* flags */
                     94: };
                     95: 
                     96: static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
                     97: {
                     98:   char *newp = NULL;
                     99:   char *dictp;
                    100:   size_t len;
                    101: 
                    102:   CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
                    103:   if(!newp || result)
                    104:     return NULL;
                    105: 
                    106:   dictp = malloc(len*2 + 1); /* add one for terminating zero */
                    107:   if(dictp) {
                    108:     char *ptr;
                    109:     char ch;
                    110:     int olen = 0;
                    111:     /* According to RFC2229 section 2.2, these letters need to be escaped with
                    112:        \[letter] */
                    113:     for(ptr = newp;
                    114:         (ch = *ptr) != 0;
                    115:         ptr++) {
                    116:       if((ch <= 32) || (ch == 127) ||
                    117:           (ch == '\'') || (ch == '\"') || (ch == '\\')) {
                    118:         dictp[olen++] = '\\';
                    119:       }
                    120:       dictp[olen++] = ch;
                    121:     }
                    122:     dictp[olen] = 0;
                    123:   }
                    124:   free(newp);
                    125:   return dictp;
                    126: }
                    127: 
                    128: static CURLcode dict_do(struct connectdata *conn, bool *done)
                    129: {
                    130:   char *word;
                    131:   char *eword;
                    132:   char *ppath;
                    133:   char *database = NULL;
                    134:   char *strategy = NULL;
                    135:   char *nthdef = NULL; /* This is not part of the protocol, but required
                    136:                           by RFC 2229 */
                    137:   CURLcode result = CURLE_OK;
                    138:   struct Curl_easy *data = conn->data;
                    139:   curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
                    140: 
                    141:   char *path = data->state.up.path;
                    142: 
                    143:   *done = TRUE; /* unconditionally */
                    144: 
                    145:   if(conn->bits.user_passwd) {
                    146:     /* AUTH is missing */
                    147:   }
                    148: 
                    149:   if(strncasecompare(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
                    150:      strncasecompare(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
                    151:      strncasecompare(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
                    152: 
                    153:     word = strchr(path, ':');
                    154:     if(word) {
                    155:       word++;
                    156:       database = strchr(word, ':');
                    157:       if(database) {
                    158:         *database++ = (char)0;
                    159:         strategy = strchr(database, ':');
                    160:         if(strategy) {
                    161:           *strategy++ = (char)0;
                    162:           nthdef = strchr(strategy, ':');
                    163:           if(nthdef) {
                    164:             *nthdef = (char)0;
                    165:           }
                    166:         }
                    167:       }
                    168:     }
                    169: 
                    170:     if((word == NULL) || (*word == (char)0)) {
                    171:       infof(data, "lookup word is missing\n");
                    172:       word = (char *)"default";
                    173:     }
                    174:     if((database == NULL) || (*database == (char)0)) {
                    175:       database = (char *)"!";
                    176:     }
                    177:     if((strategy == NULL) || (*strategy == (char)0)) {
                    178:       strategy = (char *)".";
                    179:     }
                    180: 
                    181:     eword = unescape_word(data, word);
                    182:     if(!eword)
                    183:       return CURLE_OUT_OF_MEMORY;
                    184: 
                    185:     result = Curl_sendf(sockfd, conn,
                    186:                         "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
                    187:                         "MATCH "
                    188:                         "%s "    /* database */
                    189:                         "%s "    /* strategy */
                    190:                         "%s\r\n" /* word */
                    191:                         "QUIT\r\n",
                    192: 
                    193:                         database,
                    194:                         strategy,
                    195:                         eword
                    196:                         );
                    197: 
                    198:     free(eword);
                    199: 
                    200:     if(result) {
                    201:       failf(data, "Failed sending DICT request");
                    202:       return result;
                    203:     }
                    204:     Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); /* no upload */
                    205:   }
                    206:   else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
                    207:           strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
                    208:           strncasecompare(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
                    209: 
                    210:     word = strchr(path, ':');
                    211:     if(word) {
                    212:       word++;
                    213:       database = strchr(word, ':');
                    214:       if(database) {
                    215:         *database++ = (char)0;
                    216:         nthdef = strchr(database, ':');
                    217:         if(nthdef) {
                    218:           *nthdef = (char)0;
                    219:         }
                    220:       }
                    221:     }
                    222: 
                    223:     if((word == NULL) || (*word == (char)0)) {
                    224:       infof(data, "lookup word is missing\n");
                    225:       word = (char *)"default";
                    226:     }
                    227:     if((database == NULL) || (*database == (char)0)) {
                    228:       database = (char *)"!";
                    229:     }
                    230: 
                    231:     eword = unescape_word(data, word);
                    232:     if(!eword)
                    233:       return CURLE_OUT_OF_MEMORY;
                    234: 
                    235:     result = Curl_sendf(sockfd, conn,
                    236:                         "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
                    237:                         "DEFINE "
                    238:                         "%s "     /* database */
                    239:                         "%s\r\n"  /* word */
                    240:                         "QUIT\r\n",
                    241:                         database,
                    242:                         eword);
                    243: 
                    244:     free(eword);
                    245: 
                    246:     if(result) {
                    247:       failf(data, "Failed sending DICT request");
                    248:       return result;
                    249:     }
                    250:     Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
                    251:   }
                    252:   else {
                    253: 
                    254:     ppath = strchr(path, '/');
                    255:     if(ppath) {
                    256:       int i;
                    257: 
                    258:       ppath++;
                    259:       for(i = 0; ppath[i]; i++) {
                    260:         if(ppath[i] == ':')
                    261:           ppath[i] = ' ';
                    262:       }
                    263:       result = Curl_sendf(sockfd, conn,
                    264:                           "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
                    265:                           "%s\r\n"
                    266:                           "QUIT\r\n", ppath);
                    267:       if(result) {
                    268:         failf(data, "Failed sending DICT request");
                    269:         return result;
                    270:       }
                    271: 
                    272:       Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
                    273:     }
                    274:   }
                    275: 
                    276:   return CURLE_OK;
                    277: }
                    278: #endif /*CURL_DISABLE_DICT*/

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>