2 * Copyright (c) 2007,西安邮电学院Linux兴趣小组
6 * 摘 要:从一行数据中解析出命令和参数 并调用相应的命令处理模块
7 * 对读取的字符串做了初步分析 提高了容错能力 对参数的接收做了限制,一次只接收一个参数。
8 * 重写了接收参数模块,去掉了无用参数buf_size,_line_cmd()的返回值改成了结构体指针。
26 extern struct user_env user_env
;
27 extern struct run_env run_env
;
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
)
44 while (!isalpha(line_buf
[i
])) {
47 while (line_buf
[i
] != ' '
48 && line_buf
[i
] != '\r'
49 && line_buf
[i
] != '\n') {
51 user_cmd
->cmd
[k
++] = line_buf
[i
];
57 } /*<--接收以字母开头的字符串(命令)*/
58 while (line_buf
[i
] == ' ') {
61 while (line_buf
[i
] != '\0'
62 && line_buf
[i
] != '\r'
63 && line_buf
[i
] != '\n') {
64 user_cmd
->arg
[j
++] = line_buf
[i
];
68 for (;k
>= 0;k
--) { /*检查命令中字母的大小写,若是小写字母,则转化为大写字母*/
69 user_cmd
->cmd
[k
] = toupper(user_cmd
->cmd
[k
]);
74 printf("%s",user_cmd
->cmd
);
77 printf("%s",user_cmd
->arg
);
83 static int _cmd_num(struct parse_cmd cmd
)
86 for (i
= 0; i
< (int)(sizeof(commands
)/sizeof(commands
[0])); i
++) {
87 if (strcmp(cmd
.cmd
, commands
[i
]) == 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";
102 memset(&user_cmd
, 0, sizeof(struct parse_cmd
));
103 if (_line_cmd(p_buf
, &user_cmd
) == -1) {
104 failed(user_cmd
.cmd
);
107 if (( i
= _cmd_num(user_cmd
)) <= 4 || user_env
.login_in
== TRUE
) {
111 printf("****call user()\n");
113 do_user(user_cmd
.arg
);
117 printf("call pass()\n");
118 printf("username=%s\n", user_env
.user_name
);
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);
127 if (chdir("/") < 0) {
128 write_log("chdir error", 0);
136 const char mess
[] = "220 No username input.\r\n";
137 write(user_env
.connect_fd
, mess
, strlen(mess
));
142 debug_printf("call syst()\n");
146 debug_printf("call quit()\n");
150 debug_printf("call retr()\n");
151 do_retr(user_cmd
.arg
);
154 debug_printf("call stor()\n");
155 do_stor(user_cmd
.arg
);
158 debug_printf("call rnfr()\n");
160 strcpy(rnfr_arg
, user_cmd
.arg
);
163 debug_printf("call rnto()\n");
164 do_rnto(rnfr_arg
, user_cmd
.arg
);
165 memset(rnfr_arg
, 0, MAX_ARG
);
168 debug_printf("call abor()\n");
170 do_abor(user_cmd
.arg
);
173 debug_printf("call dele()\n");
174 do_dele(user_cmd
.arg
);
177 debug_printf("call rmd()\n");
178 do_rmd(user_cmd
.arg
);
181 debug_printf("call mkd()\n");
182 do_mkd(user_cmd
.arg
);
185 debug_printf("call pwd()\n");
189 debug_printf("call cwd()\n");
190 do_cwd(user_cmd
.arg
);
193 debug_printf("call cdup()\n");
197 debug_printf("call port()\n");
198 do_port(user_cmd
.arg
);
201 debug_printf("call noop()\n");
205 debug_printf("call pasv()\n\n");
209 debug_printf("call type()\n");
210 do_type(user_cmd
.arg
);
213 debug_printf("call mode()\n");
214 do_mode(user_cmd
.arg
);
217 debug_printf("call stat()\n");
218 do_stat(user_cmd
.arg
);
221 debug_printf("call stru()\n");
222 do_stru(user_cmd
.arg
);
225 debug_printf("call list()\n");
226 do_list(user_cmd
.arg
);
229 debug_printf("call failed()\n");
230 failed(user_cmd
.cmd
);
233 } else if (i
<= 23 && i
>= 1) {
234 write(user_env
.connect_fd
, login_error
, strlen(login_error
));
236 failed(user_cmd
.cmd
);