6 * misc.c - Miscellaneous helper functions.
14 * Show 'msg' followed by the system error and exit badly.
16 void fatal (char *msg
)
18 fputs("FATAL ERROR: ", stderr
);
27 * Send 'msg' through socket 'sk'. Because a single send() call doesn't ensure
28 * that all data is transferred (or maybe the call is interrupted), we need to
29 * place it in a small loop to wait until all 'msg' contents, at least, gets
30 * copied onto the internal TCP/IP stack buffers.
32 void send_reply (int sk
, char *msg
)
36 debug_msg("<<< %s", msg
);
40 b
= send(sk
, msg
, msglen
, 0);
42 fatal("Could not send reply");
54 * Converts a string to its numeric value in 64 bit representation. Quote from
55 * sysutil.c file of VsFTPd:
57 * ``atoll() is C99 standard - but even modern FreeBSD, OpenBSD don't
58 * haveit, so we'll supply our own''
60 * This function is almost a literal copy of vsf_sysutil_a_to_filesize_t(),
61 * present in that file. The only difference is that the string is processed
62 * from left to right, in contrast with the original. Therefore, here, negative
63 * numbers are directly converted to 0.
65 long long str_to_ll (char *str
)
69 if (strlen(str
) <= 15) {
71 if (*str
< '0' || *str
> '9')
88 * Check if 'path' is trying to access beyond the Basedir. We shouldn't allow
89 * that because we try to emulate chroot().
91 * This implementation is basically a small DFA (Deterministic Finite Automata)
92 * which parses the path looking for any of the substrings "./" or "../" at the
93 * beginning, "/./" or "/../" within, or else "/." or "/.." at the end.
95 int path_is_secure (char *path
)
98 * Current state ____ ____ Input value
100 const static int next_state
[5][3] = {
101 /* State 0 */ { 0, 1, 4 }, /* Input values: */
102 /* State 1 */ { 3, 2, 4 }, /* */
103 /* State 2 */ { 3, 4, 4 }, /* '/' = 0 */
104 /* State 3 */ { 3, 3, 3 }, /* '.' = 1 */
105 /* State 4 */ { 0, 4, 4 } /* other = 2 */
107 int state
= 0; /* Initial state */
110 while (*path
!= '\0') {
112 case '/': input
= 0; break;
113 case '.': input
= 1; break;
116 state
= next_state
[state
][input
];
120 /* Accepting states (safe path) are: */
121 return state
== 0 || state
== 4;
129 * Only implemented when debug flags are enabled. Display an information message
130 * to the stderr. Useful to follow the progress of the command-reply exchange
131 * without the need of a debugger.
133 void debug_msg (const char *format
, ...)
137 fprintf(stderr
, "(%d) ", getpid());
138 va_start(params
, format
);
139 vfprintf(stderr
, format
, params
);