File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / lib / curl_path.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:15 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    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>