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
) {
110 debug_printf("****call user()\n");
111 do_user(user_cmd
.arg
);
114 debug_printf("call pass()\n");
115 printf("username=%s\n", user_env
.user_name
);
117 if (strlen(user_env
.user_name
) != 0) {
118 if (do_pass(user_cmd
.arg
) == 0) {
119 if (chroot(run_env
.ftp_dir
) < 0) {
120 write_log("chroot error", 0);
124 if (chdir("/") < 0) {
125 write_log("chdir error", 0);
133 const char mess
[] = "220 No username input.\r\n";
134 write(user_env
.connect_fd
, mess
, strlen(mess
));
139 debug_printf("call syst()\n");
143 debug_printf("call quit()\n");
147 debug_printf("call retr()\n");
148 do_retr(user_cmd
.arg
);
151 debug_printf("call stor()\n");
152 do_stor(user_cmd
.arg
);
155 debug_printf("call rnfr()\n");
157 strcpy(rnfr_arg
, user_cmd
.arg
);
160 debug_printf("call rnto()\n");
161 do_rnto(rnfr_arg
, user_cmd
.arg
);
162 memset(rnfr_arg
, 0, MAX_ARG
);
165 debug_printf("call abor()\n");
167 do_abor(user_cmd
.arg
);
170 debug_printf("call dele()\n");
171 do_dele(user_cmd
.arg
);
174 debug_printf("call rmd()\n");
175 do_rmd(user_cmd
.arg
);
178 debug_printf("call mkd()\n");
179 do_mkd(user_cmd
.arg
);
182 debug_printf("call pwd()\n");
186 debug_printf("call cwd()\n");
187 do_cwd(user_cmd
.arg
);
190 debug_printf("call cdup()\n");
194 debug_printf("call port()\n");
195 do_port(user_cmd
.arg
);
198 debug_printf("call noop()\n");
202 debug_printf("call pasv()\n\n");
206 debug_printf("call type()\n");
207 do_type(user_cmd
.arg
);
210 debug_printf("call mode()\n");
211 do_mode(user_cmd
.arg
);
214 debug_printf("call stat()\n");
215 do_stat(user_cmd
.arg
);
218 debug_printf("call stru()\n");
219 do_stru(user_cmd
.arg
);
222 debug_printf("call list()\n");
223 do_list(user_cmd
.arg
);
226 debug_printf("call failed()\n");
227 failed(user_cmd
.cmd
);
230 } else if (i
<= 23 && i
>= 1) {
231 write(user_env
.connect_fd
, login_error
, strlen(login_error
));
233 failed(user_cmd
.cmd
);