Add debug.h and clean Makefile
[xylftp.git] / server / src / parse_cmd.c
blob794027d9db9d19b58ce737f54580f565fbfc9aa2
1 /*
2 * Copyright (c) 2007,西安邮电学院Linux兴趣小组
3 * All rights reserved.
5 * 文件名称:parse_cmd.c
6 * 摘 要:从一行数据中解析出命令和参数 并调用相应的命令处理模块
7 * 对读取的字符串做了初步分析 提高了容错能力 对参数的接收做了限制,一次只接收一个参数。
8 * 重写了接收参数模块,去掉了无用参数buf_size,_line_cmd()的返回值改成了结构体指针。
9 * 当前版本:4.0
10 * 作 者:贾孟树
11 * 完成日期:2007年6月13日
12 * 取代版本:3.0
13 * 完成日期:2007年6月8日
14 * 修改者:王聪
15 * 修改日期:2007年6月15日
19 #include "xylftp.h"
20 #include "do_cmd.h"
21 #include "debug.h"
23 #define MAX_CMD 5
24 #define MAX_ARG 4096
26 extern struct user_env user_env;
27 extern struct run_env run_env;
28 struct parse_cmd{
29 char cmd[MAX_CMD];
30 char arg[MAX_ARG];
34 const char *commands[] = {"USER","PASS","SYST","QUIT","RETR","STOR","RNFR","RNTO","ABOR","DELE",
35 "RMD","MKD","PWD","CWD","CDUP","PORT","NOOP","PASV","TYPE","MODE",
36 "STAT","STRU","LIST"}; /*服务器支持的所有命令*/
38 static int _line_cmd(char *line_buf, struct parse_cmd *user_cmd)
40 int i = 0;
41 int j = 0;
42 int k = 0;
44 while (!isalpha(line_buf[i])) {
45 i++;
46 } /*<--略过不是字母的字符*/
47 while (line_buf[i] != ' '
48 && line_buf[i] != '\r'
49 && line_buf[i] != '\n') {
50 if (k < MAX_CMD-1) {
51 user_cmd->cmd[k++] = line_buf[i];
52 i++;
54 else {
55 return -1;
57 } /*<--接收以字母开头的字符串(命令)*/
58 while (line_buf[i] == ' ') {
59 i++;
60 } /*<--清除命令与参数之间的空格*/
61 while (line_buf[i] != '\0'
62 && line_buf[i] != '\r'
63 && line_buf[i] != '\n') {
64 user_cmd->arg[j++] = line_buf[i];
65 i++;
66 } /*<--只提取第一个参数*/
68 for (;k >= 0;k--) { /*检查命令中字母的大小写,若是小写字母,则转化为大写字母*/
69 user_cmd->cmd[k] = toupper(user_cmd->cmd[k]);
71 #ifdef DEBUG
72 printf("\n");
73 printf("CMD:");
74 printf("%s",user_cmd->cmd);
75 printf("\n");
76 printf("ARG:");
77 printf("%s",user_cmd->arg);
78 printf("\n");
79 #endif
80 return 0;
83 static int _cmd_num(struct parse_cmd cmd)
85 int i;
86 for (i = 0; i < (int)(sizeof(commands)/sizeof(commands[0])); i++) {
87 if (strcmp(cmd.cmd, commands[i]) == 0) {
88 return i+1;
91 return 0;
95 int parse_cmd(char *p_buf)
97 char rnfr_arg[MAX_ARG];
98 struct parse_cmd user_cmd;
99 const char login_error[] = "530 Please login with USER and PASS.\r\n";
100 int i = 0;
102 memset(&user_cmd, 0, sizeof(struct parse_cmd));
103 if (_line_cmd(p_buf, &user_cmd) == -1) {
104 failed(user_cmd.cmd);
105 return 2;
107 if (( i = _cmd_num(user_cmd)) <= 4 || user_env.login_in == TRUE) {
108 switch (i) {
109 case 1:
110 #ifdef DEBUG
111 printf("****call user()\n");
112 #endif
113 do_user(user_cmd.arg);
114 break;
115 case 2:
116 #ifdef DEBUG
117 printf("call pass()\n");
118 printf("username=%s\n", user_env.user_name);
119 #endif
120 if (strlen(user_env.user_name) != 0) {
121 if (do_pass(user_cmd.arg) == 0) {
122 if (chroot(run_env.ftp_dir) < 0) {
123 write_log("chroot error", 0);
124 do_quit();
125 break;
127 if (chdir("/") < 0) {
128 write_log("chdir error", 0);
129 do_quit();
130 break;
132 } else {
133 break;
135 } else {
136 const char mess[] = "220 No username input.\r\n";
137 write(user_env.connect_fd, mess, strlen(mess));
140 break;
141 case 3:
142 debug_printf("call syst()\n");
143 do_syst();
144 break;
145 case 4:
146 debug_printf("call quit()\n");
147 do_quit();
148 break;
149 case 5:
150 debug_printf("call retr()\n");
151 do_retr(user_cmd.arg);
152 break;
153 case 6:
154 debug_printf("call stor()\n");
155 do_stor(user_cmd.arg);
156 break;
157 case 7:
158 debug_printf("call rnfr()\n");
159 do_rnfr();
160 strcpy(rnfr_arg, user_cmd.arg);
161 break;
162 case 8:
163 debug_printf("call rnto()\n");
164 do_rnto(rnfr_arg, user_cmd.arg);
165 memset(rnfr_arg, 0, MAX_ARG);
166 break;
167 case 9:
168 debug_printf("call abor()\n");
169 fflush(stdout);
170 do_abor(user_cmd.arg);
171 break;
172 case 10:
173 debug_printf("call dele()\n");
174 do_dele(user_cmd.arg);
175 break;
176 case 11:
177 debug_printf("call rmd()\n");
178 do_rmd(user_cmd.arg);
179 break;
180 case 12:
181 debug_printf("call mkd()\n");
182 do_mkd(user_cmd.arg);
183 break;
184 case 13:
185 debug_printf("call pwd()\n");
186 do_pwd();
187 break;
188 case 14:
189 debug_printf("call cwd()\n");
190 do_cwd(user_cmd.arg);
191 break;
192 case 15:
193 debug_printf("call cdup()\n");
194 do_cdup();
195 break;
196 case 16:
197 debug_printf("call port()\n");
198 do_port(user_cmd.arg);
199 break;
200 case 17:
201 debug_printf("call noop()\n");
202 do_noop();
203 break;
204 case 18:
205 debug_printf("call pasv()\n\n");
206 do_pasv();
207 break;
208 case 19:
209 debug_printf("call type()\n");
210 do_type(user_cmd.arg);
211 break;
212 case 20:
213 debug_printf("call mode()\n");
214 do_mode(user_cmd.arg);
215 break;
216 case 21:
217 debug_printf("call stat()\n");
218 do_stat(user_cmd.arg);
219 break;
220 case 22:
221 debug_printf("call stru()\n");
222 do_stru(user_cmd.arg);
223 break;
224 case 23:
225 debug_printf("call list()\n");
226 do_list(user_cmd.arg);
227 break;
228 default:
229 debug_printf("call failed()\n");
230 failed(user_cmd.cmd);
231 break;
233 } else if (i <= 23 && i >= 1) {
234 write(user_env.connect_fd, login_error, strlen(login_error));
235 } else {
236 failed(user_cmd.cmd);
238 return 1;