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>