2 * User FTP Server, Share folders over FTP without being root.
3 * Copyright (C) 2008 Isaac Jurado
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option) any later
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 * Apply new path components to an existing working directory. The working
26 * directory is contained (full path) in "wd", which is a buffer with a capacity
27 * of LINE_SIZE bytes. Parameter "len" specifies the current length of the
30 * This function returns the length of "wd" after applying "path" on it, which
31 * means that the working directory is modified in-place. In case the working
32 * directory would exceed LINE_SIZE bytes (at any stage), -1 is returned.
34 * NOTE: Path lengths always include the terminating null byte. This means that
35 * the last useful character of the path is at length - 2.
37 static int apply_path (const char *path
, char *wd
, int len
)
43 /* Absolute path, truncate wd */
51 /* Combine delimiters */
56 /* No more components to apply */
59 /* Isolate next component */
61 while (path
[i
] != '/' && path
[i
] != '\0')
64 if (i
== 2 && path
[0] == '.' && path
[1] == '.')
66 /* Return to parent directory, found ".." */
67 while (wd
[len
] != '/')
70 len
++; /* Root reached, fix */
74 else if (i
!= 1 || path
[0] != '.')
77 if (len
+ i
>= LINE_SIZE
)
80 /* Apply component, because it is different than "." */
84 len
--; /* Skip delimiter at root */
86 memcpy(wd
+ len
, path
, i
);
91 /* Now skip to the next component */
100 * Expand the command argument to its corresponding full path. This is
101 * necessary because chdir() is never performed so the correct path needs to be
102 * resolved for each file or directory to be accessed.
104 * Returns the length of the expanded argument, including the trailing null
105 * byte (just as apply_path() does). Also note that the expanded argument is
106 * saved in the auxiliary buffer and the argument pointer is redirected
109 int expand_arg (void)
111 int len
= SS
.cwd_len
;
113 /* Even if the argument is empty, list_dir() requires the current
114 * working directory to be copied */
115 memcpy(SS
.aux
, SS
.cwd
, len
);
119 len
= apply_path(SS
.arg
, SS
.aux
, len
);
122 reply_c("552 Path overflow.\r\n");
123 fatal("Path overflow expanding argument");
128 debug("Argument expanded to %s", SS
.arg
);