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
21 * Return the next command (as an integer) available in the control channel.
23 * Most of this implementation has been inspired by str_netfd_alloc() from
28 #include "command_list.h" /* Command recognizer */
29 #include <sys/types.h>
30 #include <sys/socket.h>
37 command_t
next_command (void)
39 const struct Cmd
*cmd
; /* parsed command value */
40 int keepon
; /* loop exit flag */
41 int i
; /* processed and saved information index */
42 int j
; /* unprocessed and saved information index */
43 int b
; /* read bytes from recv() (auxiliary) */
46 * First of all, try to read a whole line (consuming up to the CRLF
47 * sequence), doing a peek; that is, reading from the socket buffer
48 * without really consuming. There is a hard limit of LINE_SIZE up to
51 * If a LF character is found before reaching the end of the read chunk,
52 * only that line will be retired from the socket buffer. Otherwise,
53 * consume everything to let more network data to come.
55 * The management scheme of the 'Line' buffer is as follows:
57 * ____________ b ___________
59 * +--------------------+----------------+----------+-------+
60 * Line: | Processed data | Last call to recv() | ... |
61 * +--------------------+----------------+----------+-------+
68 b
= recv(S_cmd_sk
, LineBuf
+ i
, LINE_SIZE
- i
, MSG_PEEK
);
71 printf("(%d) * Overflow attempt, exiting.\n",
74 printf("(%d) * Close request without QUIT command, exiting.\n",
80 /* Locate LF character, j will point to it */
81 for (j
= i
; j
< (b
+ i
) && LineBuf
[j
] != '\n'; j
++)
86 /* LF not found yet, clean the socket buffer */
90 b
= recv(S_cmd_sk
, AuxBuf
, j
, 0);
94 /* LF found, consume only that line and get out */
98 b
= recv(S_cmd_sk
, AuxBuf
, i
, 0);
105 debug_msg(">>> %s\n", LineBuf
);
107 /* Check if arguments are present and set 'S_arg' pointer as needed */
108 for (; LineBuf
[i
] != ' ' && LineBuf
[i
] != '\0'; i
++)
109 LineBuf
[i
] = (char) (toupper(LineBuf
[i
]) & 0x07F);
111 if (LineBuf
[i
] != '\0')
112 S_arg
= LineBuf
+ i
+ 1;
116 cmd
= command_lookup(LineBuf
, i
);