Removed non portable -v flag for rm command.
[uftps.git] / command_loop.c
blobd4b3a07ea1a771381db8d720fed1783cc7c6d884
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 #include <ctype.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <stdio.h>
28 * Main FTP server loop. The switch should be converted to an indexed jump
29 * because the command values are consecutive integers. Thus avoiding the
30 * multiple string comparisons.
32 * This function never returns.
34 void command_loop (void)
36 int l;
38 do {
39 switch (next_command())
42 * Straightforward implementations.
44 case FTP_NOOP:
45 reply_c("200 I'm alive, don't worry\r\n");
46 break;
48 case FTP_FEAT:
49 reply_c("211-Feature list:\r\n"
50 "211- MDTM\r\n"
51 "211- REST STREAM\r\n"
52 "211- SIZE\r\n"
53 "211- TVFS\r\n"
54 "211 End.\r\n");
55 break;
57 case FTP_SYST:
58 reply_c("215 UNIX Type: L8\r\n");
59 break;
61 case FTP_PASS:
62 case FTP_USER:
63 reply_c("230 I don't care.\r\n");
64 break;
66 case FTP_OPTS:
67 reply_c("501 Option not understood.\r\n");
68 break;
70 case FTP_ACCT:
71 case FTP_SMNT:
72 reply_c("202 Unimplemented, ignored.\r\n");
73 break;
75 case FTP_REIN:
76 reply_c("220 Nothing to REIN.\r\n");
77 break;
80 * A bit more complex commands.
82 case FTP_MODE:
83 if (toupper(SS.arg[0]) == 'S')
84 reply_c("200 MODE set to stream.\r\n");
85 else
86 reply_c("504 Mode not supported.\r\n");
87 break;
89 case FTP_STRU:
90 if (toupper(SS.arg[0]) == 'F')
91 reply_c("200 STRUcture set to file.\r\n");
92 else
93 reply_c("504 Structure not supported.\r\n");
94 break;
96 case FTP_TYPE:
97 switch (toupper(SS.arg[0]))
99 case 'I':
100 case 'A':
101 case 'L': reply_c("200 Whatever.\r\n"); break;
102 default : reply_c("504 Type not supported.\r\n");
104 break;
106 case FTP_PWD:
107 l = snprintf(SS.aux, LINE_SIZE, "257 \"%s\"\r\n", &SS.cwd[1]);
108 reply(SS.aux, l);
109 break;
111 case FTP_REST:
112 /* We don't need str_to_ll() as sscanf() does de job */
113 #ifdef __MINGW32__
114 sscanf(SS.arg, "%I64d", (__int64 *) &SS.file_offset);
115 l = snprintf(SS.aux, LINE_SIZE, "350 Got it (%I64d).\r\n",
116 (__int64) SS.file_offset);
117 #else
118 sscanf(SS.arg, "%lld", (long long *) &SS.file_offset);
119 l = snprintf(SS.aux, LINE_SIZE, "350 Got it (%lld).\r\n",
120 (long long) SS.file_offset);
121 #endif
122 reply(SS.aux, l);
123 break;
125 case FTP_QUIT:
126 reply_c("221 Goodbye.\r\n");
127 closesocket(SS.control_sk);
128 if (SS.passive_sk != -1)
129 closesocket(SS.passive_sk);
130 exit(EXIT_SUCCESS);
131 break;
134 * Complex commands implemented separately.
136 case FTP_PORT:
137 parse_port_argument();
138 break;
140 case FTP_PASV:
141 enable_passive();
142 break;
144 case FTP_CWD:
145 change_dir();
146 break;
148 case FTP_NLST:
149 list_dir(0);
150 break;
152 case FTP_LIST:
153 list_dir(1);
154 break;
156 case FTP_MDTM:
157 file_stats(0);
158 break;
160 case FTP_SIZE:
161 file_stats(1);
162 break;
164 case FTP_RETR:
165 send_file();
166 break;
169 * Unrecognized or unimplemented commands.
171 case FTP_NONE:
172 reply_c("500 Command unrecognized.\r\n");
173 break;
175 default:
176 reply_c("502 Command not implemented.\r\n");
178 } while (1);