@@ -2194,6 +2194,97 @@ int wolfSSH_ChannelGetEof(WOLFSSH_CHANNEL* channel)
21942194}
21952195
21962196
2197+ #if (defined(WOLFSSH_SFTP ) || defined(WOLFSSH_SCP )) && \
2198+ !defined(NO_WOLFSSH_SERVER )
2199+ /*
2200+ * Paths starting with a slash are absolute, rooted at root. Any path that
2201+ * doesn't have a starting slash is assumed to be relative to the current
2202+ * path. If the path is empty, return the default path.
2203+ *
2204+ * The path "/." is stripped out. The path "/.." strips out the previous
2205+ * path value. The root path, "/", is always present.
2206+ *
2207+ * Example: "/home/fred/frob/frizz/../../../barney/bar/baz/./././../.."
2208+ * will return "/home/barney". "/../.." will return "/". "." will return
2209+ * currentPath.
2210+ *
2211+ * Note, this function does not care about OS and filesystem issues. The
2212+ * SFTP protocol describes how paths are handled in SFTP. Specialized
2213+ * behaviors are handled when actually calling the OS functions. Paths
2214+ * are further massaged there. For example, the C: drive is treated as
2215+ * the path "/C:", and is a directory like any other.
2216+ *
2217+ * @param currentPath RealPath of the current working directory
2218+ * @param defaultPath RealPath of the default directory, usually user's
2219+ * @param in requested new path
2220+ * @param out output of real path cleanup
2221+ * @param outSz size in bytes of buffer 'out'
2222+ * @return WS_SUCCESS, WS_BAD_ARGUMENT, or WS_INVALID_PATH_E
2223+ */
2224+ int wolfSSH_RealPath (const char * currentPath , const char * defaultPath ,
2225+ char * in , char * out , word32 outSz )
2226+ {
2227+ char * tail = NULL ;
2228+ char * seg ;
2229+ word32 inSz , segSz , curSz ;
2230+
2231+ if (currentPath == NULL || defaultPath == NULL ||
2232+ in == NULL || out == NULL || outSz == 0 )
2233+ return WS_BAD_ARGUMENT ;
2234+
2235+ WMEMSET (out , 0 , outSz );
2236+ inSz = (word32 )WSTRLEN (in );
2237+ if (inSz == 0 ) {
2238+ WSTRNCPY (out , defaultPath , outSz );
2239+ }
2240+ else if (in [0 ] == '/' ) {
2241+ out [0 ] = '/' ;
2242+ }
2243+ else {
2244+ WSTRNCPY (out , currentPath , outSz );
2245+ }
2246+ out [outSz - 1 ] = 0 ;
2247+ curSz = (word32 )WSTRLEN (out );
2248+
2249+ for (seg = WSTRTOK (in , "/" , & tail ); seg ; seg = WSTRTOK (NULL , "/" , & tail )) {
2250+ segSz = (word32 )WSTRLEN (seg );
2251+
2252+ /* Try to match "." */
2253+ if (segSz == 1 && seg [0 ] == '.' ) {
2254+ /* Do nothing. Keep current directory. */
2255+ }
2256+ /* Try to match ".." */
2257+ else if (segSz == 2 && seg [0 ] == '.' && seg [1 ] == '.' ) {
2258+ char * prev = strrchr (out , '/' );
2259+
2260+ if (prev != NULL ) {
2261+ if (prev != out ) {
2262+ prev [0 ] = 0 ;
2263+ curSz = (word32 )WSTRLEN (out );
2264+ }
2265+ else {
2266+ /* preserve the root / */
2267+ prev [1 ] = 0 ;
2268+ curSz = 1 ;
2269+ }
2270+ }
2271+ }
2272+ /* Everything else is copied */
2273+ else {
2274+ if (curSz != 1 ) {
2275+ WSTRNCAT (out , "/" , outSz - curSz );
2276+ curSz ++ ;
2277+ }
2278+ WSTRNCAT (out , seg , outSz - curSz );
2279+ curSz += segSz ;
2280+ }
2281+ }
2282+
2283+ return WS_SUCCESS ;
2284+ }
2285+ #endif /* WOLFSSH_SFTP || WOLFSSH_SCP */
2286+
2287+
21972288#ifdef WOLFSSH_SHOW_SIZES
21982289
21992290void wolfSSH_ShowSizes (void )
0 commit comments