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

1.1       misho       1: /***************************************************************************
                      2:  *                                  _   _ ____  _
                      3:  *  Project                     ___| | | |  _ \| |
                      4:  *                             / __| | | | |_) | |
                      5:  *                            | (__| |_| |  _ <| |___
                      6:  *                             \___|\___/|_| \_\_____|
                      7:  *
                      8:  * Copyright (C) 1998 - 2019, 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: #if defined(USE_SSH)
                     26: 
                     27: #include <curl/curl.h>
                     28: #include "curl_memory.h"
                     29: #include "curl_path.h"
                     30: #include "escape.h"
                     31: #include "memdebug.h"
                     32: 
                     33: /* figure out the path to work with in this particular request */
                     34: CURLcode Curl_getworkingpath(struct connectdata *conn,
                     35:                              char *homedir,  /* when SFTP is used */
                     36:                              char **path) /* returns the  allocated
                     37:                                              real path to work with */
                     38: {
                     39:   struct Curl_easy *data = conn->data;
                     40:   char *real_path = NULL;
                     41:   char *working_path;
                     42:   size_t working_path_len;
                     43:   CURLcode result =
                     44:     Curl_urldecode(data, data->state.up.path, 0, &working_path,
                     45:                    &working_path_len, FALSE);
                     46:   if(result)
                     47:     return result;
                     48: 
                     49:   /* Check for /~/, indicating relative to the user's home directory */
                     50:   if(conn->handler->protocol & CURLPROTO_SCP) {
                     51:     real_path = malloc(working_path_len + 1);
                     52:     if(real_path == NULL) {
                     53:       free(working_path);
                     54:       return CURLE_OUT_OF_MEMORY;
                     55:     }
                     56:     if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
                     57:       /* It is referenced to the home directory, so strip the leading '/~/' */
                     58:       memcpy(real_path, working_path + 3, working_path_len - 2);
                     59:     else
                     60:       memcpy(real_path, working_path, 1 + working_path_len);
                     61:   }
                     62:   else if(conn->handler->protocol & CURLPROTO_SFTP) {
                     63:     if((working_path_len > 1) && (working_path[1] == '~')) {
                     64:       size_t homelen = strlen(homedir);
                     65:       real_path = malloc(homelen + working_path_len + 1);
                     66:       if(real_path == NULL) {
                     67:         free(working_path);
                     68:         return CURLE_OUT_OF_MEMORY;
                     69:       }
                     70:       /* It is referenced to the home directory, so strip the
                     71:          leading '/' */
                     72:       memcpy(real_path, homedir, homelen);
                     73:       real_path[homelen] = '/';
                     74:       real_path[homelen + 1] = '\0';
                     75:       if(working_path_len > 3) {
                     76:         memcpy(real_path + homelen + 1, working_path + 3,
                     77:                1 + working_path_len -3);
                     78:       }
                     79:     }
                     80:     else {
                     81:       real_path = malloc(working_path_len + 1);
                     82:       if(real_path == NULL) {
                     83:         free(working_path);
                     84:         return CURLE_OUT_OF_MEMORY;
                     85:       }
                     86:       memcpy(real_path, working_path, 1 + working_path_len);
                     87:     }
                     88:   }
                     89: 
                     90:   free(working_path);
                     91: 
                     92:   /* store the pointer for the caller to receive */
                     93:   *path = real_path;
                     94: 
                     95:   return CURLE_OK;
                     96: }
                     97: 
                     98: /* The get_pathname() function is being borrowed from OpenSSH sftp.c
                     99:    version 4.6p1. */
                    100: /*
                    101:  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
                    102:  *
                    103:  * Permission to use, copy, modify, and distribute this software for any
                    104:  * purpose with or without fee is hereby granted, provided that the above
                    105:  * copyright notice and this permission notice appear in all copies.
                    106:  *
                    107:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                    108:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                    109:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                    110:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                    111:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                    112:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                    113:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                    114:  */
                    115: CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
                    116: {
                    117:   const char *cp = *cpp, *end;
                    118:   char quot;
                    119:   unsigned int i, j;
                    120:   size_t fullPathLength, pathLength;
                    121:   bool relativePath = false;
                    122:   static const char WHITESPACE[] = " \t\r\n";
                    123: 
                    124:   if(!*cp) {
                    125:     *cpp = NULL;
                    126:     *path = NULL;
                    127:     return CURLE_QUOTE_ERROR;
                    128:   }
                    129:   /* Ignore leading whitespace */
                    130:   cp += strspn(cp, WHITESPACE);
                    131:   /* Allocate enough space for home directory and filename + separator */
                    132:   fullPathLength = strlen(cp) + strlen(homedir) + 2;
                    133:   *path = malloc(fullPathLength);
                    134:   if(*path == NULL)
                    135:     return CURLE_OUT_OF_MEMORY;
                    136: 
                    137:   /* Check for quoted filenames */
                    138:   if(*cp == '\"' || *cp == '\'') {
                    139:     quot = *cp++;
                    140: 
                    141:     /* Search for terminating quote, unescape some chars */
                    142:     for(i = j = 0; i <= strlen(cp); i++) {
                    143:       if(cp[i] == quot) {  /* Found quote */
                    144:         i++;
                    145:         (*path)[j] = '\0';
                    146:         break;
                    147:       }
                    148:       if(cp[i] == '\0') {  /* End of string */
                    149:         /*error("Unterminated quote");*/
                    150:         goto fail;
                    151:       }
                    152:       if(cp[i] == '\\') {  /* Escaped characters */
                    153:         i++;
                    154:         if(cp[i] != '\'' && cp[i] != '\"' &&
                    155:             cp[i] != '\\') {
                    156:           /*error("Bad escaped character '\\%c'",
                    157:               cp[i]);*/
                    158:           goto fail;
                    159:         }
                    160:       }
                    161:       (*path)[j++] = cp[i];
                    162:     }
                    163: 
                    164:     if(j == 0) {
                    165:       /*error("Empty quotes");*/
                    166:       goto fail;
                    167:     }
                    168:     *cpp = cp + i + strspn(cp + i, WHITESPACE);
                    169:   }
                    170:   else {
                    171:     /* Read to end of filename - either to white space or terminator */
                    172:     end = strpbrk(cp, WHITESPACE);
                    173:     if(end == NULL)
                    174:       end = strchr(cp, '\0');
                    175:     /* return pointer to second parameter if it exists */
                    176:     *cpp = end + strspn(end, WHITESPACE);
                    177:     pathLength = 0;
                    178:     relativePath = (cp[0] == '/' && cp[1] == '~' && cp[2] == '/');
                    179:     /* Handling for relative path - prepend home directory */
                    180:     if(relativePath) {
                    181:       strcpy(*path, homedir);
                    182:       pathLength = strlen(homedir);
                    183:       (*path)[pathLength++] = '/';
                    184:       (*path)[pathLength] = '\0';
                    185:       cp += 3;
                    186:     }
                    187:     /* Copy path name up until first "white space" */
                    188:     memcpy(&(*path)[pathLength], cp, (int)(end - cp));
                    189:     pathLength += (int)(end - cp);
                    190:     (*path)[pathLength] = '\0';
                    191:   }
                    192:   return CURLE_OK;
                    193: 
                    194:   fail:
                    195:   Curl_safefree(*path);
                    196:   return CURLE_QUOTE_ERROR;
                    197: }
                    198: 
                    199: #endif /* if SSH is used */

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