Removed non portable -v flag for rm command.
[uftps.git] / next_command.c
blob0c7f994d031fdff3b32dd714e8d600caeeedc706
1 /*
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
8 * version.
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
13 * details.
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
20 #include "uftps.h"
21 #ifdef __MINGW32__
22 # include "hase.h"
23 #else
24 # include <sys/socket.h>
25 # include <unistd.h>
26 #endif
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <ctype.h>
32 #include "command_parser.h"
36 * Read data from the control channel until a complete request (delimited by
37 * CRLF) is found.
39 * Control channel processing is implemented in a pipelined fashion. Trailing
40 * bytes belonging to the following request are left in the buffer; to be read
41 * in the next call to this function.
43 static void read_request (void)
45 int l, i, b;
47 i = 0;
48 l = SS.input_len;
49 /* Shift trailing data from previous call */
50 if (SS.input_offset > 0)
51 memmove(SS.input, SS.input + SS.input_offset, l);
53 do {
54 while (i < l && SS.input[i] != '\n')
55 i++;
56 if (SS.input[i] == '\n')
58 if (i > 0 && SS.input[i - 1] == '\r')
59 break;
60 else
61 continue;
64 /* Buffer data exhausted, get more from the network */
65 b = recv(SS.control_sk, SS.input + l, LINE_SIZE - l, 0);
66 if (b <= 0)
68 if (b == -1)
69 fatal("Control channel input");
70 else if (l == LINE_SIZE)
72 errno = 0;
73 fatal("Input buffer overflow");
75 else
77 notice("Peer closed control connection");
78 closesocket(SS.control_sk);
79 exit(EXIT_SUCCESS);
83 l += b;
84 } while (1);
86 /* Mark residual (trailing) bytes for the next call */
87 SS.input[i - 1] = '\0';
88 SS.input[i] = '\0';
89 i++;
90 SS.input_len = l - i;
91 SS.input_offset = (l - i > 0 ? i : 0);
93 debug("Request : %s", SS.input);
98 * Parse the current request from the control channel and return the
99 * corresponding command number. The command argument (SS.arg) is filled
100 * accordingly.
102 enum command next_command (void)
104 const struct Cmd *cmd;
105 int i;
107 read_request();
109 i = 0;
110 while (SS.input[i] != ' ' && SS.input[i] != '\0')
112 SS.input[i] = toupper(SS.input[i] & 0x07F);
113 i++;
116 SS.arg = (SS.input[i] == ' ' ? &SS.input[i + 1] : NULL);
117 SS.input[i] = '\0';
119 cmd = parse_command(SS.input, i);
120 if (cmd == NULL)
121 return FTP_NONE;
122 return cmd->value;