00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00074 #include <sys/version.h>
00075
00076 #include <sys/socket.h>
00077 #include <netinet/tcp.h>
00078
00079 #include <string.h>
00080 #include <stdio.h>
00081 #include <stdlib.h>
00082 #include <io.h>
00083 #include <fcntl.h>
00084 #include <sys/stat.h>
00085 #include <dirent.h>
00086 #include <unistd.h>
00087
00088 #include <pro/ftpd.h>
00089
00090 #ifdef FTPD_DEBUG
00091 #include <sys/heap.h>
00092 #endif
00093
00100
00107
00113 #ifndef FTP_ROOTPATH
00114 #define FTP_ROOTPATH "PNUT:"
00115 #endif
00116
00122 #ifndef FTP_DATA_PORT
00123 #define FTP_DATA_PORT 20
00124 #endif
00125
00128 static char *ftp_root;
00129 static char *ftp_user;
00130 static char *ftp_pass;
00131
00132
00133
00134
00135
00136 static prog_char cmd_cwd_P[] = "CWD";
00137 static prog_char cmd_dele_P[] = "DELE";
00138 static prog_char cmd_list_P[] = "LIST";
00139 static prog_char cmd_mkd_P[] = "MKD";
00140 static prog_char cmd_xmkd_P[] = "XMKD";
00141 static prog_char cmd_nlst_P[] = "NLST";
00142 static prog_char cmd_noop_P[] = "NOOP";
00143 static prog_char cmd_pass_P[] = "PASS";
00144 static prog_char cmd_pasv_P[] = "PASV";
00145 static prog_char cmd_port_P[] = "PORT";
00146 static prog_char cmd_pwd_P[] = "PWD";
00147 static prog_char cmd_xpwd_P[] = "XPWD";
00148 static prog_char cmd_quit_P[] = "QUIT";
00149 static prog_char cmd_retr_P[] = "RETR";
00150 static prog_char cmd_rmd_P[] = "RMD";
00151 static prog_char cmd_xrmd_P[] = "XRMD";
00152 static prog_char cmd_stor_P[] = "STOR";
00153 static prog_char cmd_syst_P[] = "SYST";
00154 static prog_char cmd_type_P[] = "TYPE";
00155 static prog_char cmd_user_P[] = "USER";
00156
00157 static char *mon_name = "JanFebMarAprMayJunJulAugSepOctNovDec";
00158
00159 static prog_char rep_banner[] = "220 Nut/OS FTP %s ready at %.3s%3d %02d:%02d:%02d\r\n";
00160
00173 static void SplitCmdArg(char * line, char ** cmd, char ** args)
00174 {
00175
00176 while (*line && *line <= ' ') {
00177 line++;
00178 }
00179
00180
00181 *cmd = line;
00182 while (*line > ' ') {
00183 if (*line >= (u_char) 'a' && *line <= (u_char) 'z') {
00184 *line -= (u_char) 'a' - 'A';
00185 }
00186 line++;
00187 }
00188
00189
00190 if (*line) {
00191 *line++ = '\0';
00192 }
00193
00194
00195 while (*line && *line <= ' ') {
00196 ++line;
00197 }
00198
00199
00200 *args = line;
00201 while (*line && *line != '\r' && *line != '\n') {
00202 line++;
00203 }
00204
00205
00206 *line = 0;
00207 }
00208
00224 static int ParseIpPort(CONST char * arg, u_long * ip, u_short * port)
00225 {
00226 int rc;
00227
00228 *ip = 0;
00229 *port = 0;
00230 for (rc = 0; rc < 6; rc++) {
00231 if (*arg < '0' || *arg > '9') {
00232 break;
00233 }
00234 if (rc < 4) {
00235 *ip >>= 8;
00236 *ip += atol(arg) << 24;
00237 } else {
00238 *port <<= 8;
00239 *port += atoi(arg);
00240 }
00241 while (*arg && *arg != ',') {
00242 arg++;
00243 }
00244 if (*arg == ',') {
00245 arg++;
00246 }
00247 }
00248 return rc;
00249 }
00250
00260 int NutFtpRespondOk(FTPSESSION * session, int code)
00261 {
00262 static prog_char fmt_P[] = "%d OK\r\n";
00263
00264 #ifdef FTPD_DEBUG
00265 printf("\n<'%d OK' ", code);
00266 #endif
00267 fprintf_P(session->ftp_stream, fmt_P, code);
00268 fflush(session->ftp_stream);
00269
00270 return 0;
00271 }
00272
00282 int NutFtpRespondBad(FTPSESSION * session, int code)
00283 {
00284 static prog_char fmt_P[] = "%d Failed\r\n";
00285
00286 #ifdef FTPD_DEBUG
00287 printf("\n<'%d Failed' ", code);
00288 #endif
00289 fprintf_P(session->ftp_stream, fmt_P, code);
00290 fflush(session->ftp_stream);
00291
00292 return 0;
00293 }
00294
00304 int NutFtpSendMode(FTPSESSION * session, int binary)
00305 {
00306 static prog_char intro_P[] = "150 Opening ";
00307 static prog_char amode_P[] = "ASCII.\r\n";
00308 static prog_char bmode_P[] = "BINARY.\r\n";
00309
00310 #ifdef FTPD_DEBUG
00311 printf("\n<'150 Opening %s' ", binary ? "BINARY" : "ASCII");
00312 #endif
00313 fputs_P(intro_P, session->ftp_stream);
00314 fputs_P(binary ? bmode_P : amode_P, session->ftp_stream);
00315 fflush(session->ftp_stream);
00316
00317 return 0;
00318 }
00319
00340 char *CreateFullPathName(char *root, char *work, char *path)
00341 {
00342 char *full;
00343 char *cp;
00344 size_t rl = root ? strlen(root) : 0;
00345 size_t wl = work ? strlen(work) : 0;
00346 size_t pl = path ? strlen(path) : 0;
00347
00348
00349 if (rl && *(root + rl - 1) == '/') {
00350 rl--;
00351 }
00352 if (wl && *(work + wl - 1) == '/') {
00353 wl--;
00354 }
00355
00356 if ((full = malloc(rl + wl + pl + 3)) != NULL) {
00357
00358 cp = full;
00359 if (rl) {
00360 cp = strcpy(full, root) + rl;
00361 }
00362
00363
00364 if(pl == 0 || *path != '/') {
00365 if (wl) {
00366 if (*work != '/') {
00367 *cp++ = '/';
00368 }
00369 cp = strcpy(cp, work) + wl;
00370 }
00371 *cp++ = '/';
00372 rl++;
00373 }
00374
00375 if (pl) {
00376 *cp = 0;
00377 work = full + rl;
00378
00379 while (*path) {
00380
00381 if (*path == '/') {
00382 *cp++ = *path++;
00383 while (*path == '/') {
00384 path++;
00385 }
00386 }
00387
00388 if (*path == '.') {
00389 path++;
00390 if (*path == '/') {
00391 path++;
00392 continue;
00393 }
00394 if (*path == 0) {
00395 break;
00396 }
00397 if (*path == '.') {
00398 path++;
00399 if (*path == '/' || *path == 0) {
00400 if (cp != work) {
00401 cp--;
00402 while (cp != work) {
00403 cp--;
00404 if (*cp == '/') {
00405 break;
00406 }
00407 }
00408 }
00409 continue;
00410 }
00411 path--;
00412 }
00413 path--;
00414 }
00415
00416 while (*path && *path != '/') {
00417 *cp++ = *path++;
00418 }
00419 }
00420 }
00421 *cp = 0;
00422 }
00423 return full;
00424 }
00425
00435 TCPSOCKET *NutFtpDataConnect(FTPSESSION * session)
00436 {
00437 TCPSOCKET *sock;
00438 int rc;
00439
00440 if ((sock = NutTcpCreateSocket()) != 0) {
00441
00442 if (session->ftp_maxseg) {
00443 NutTcpSetSockOpt(sock, TCP_MAXSEG, &session->ftp_maxseg, sizeof(session->ftp_maxseg));
00444 }
00445 if (session->ftp_passive) {
00446 rc = NutTcpAccept(sock, session->ftp_data_port);
00447 } else {
00448 rc = NutTcpConnect(sock, session->ftp_data_ip, session->ftp_data_port);
00449 }
00450 if (rc) {
00451 NutTcpCloseSocket(sock);
00452 sock = 0;
00453 }
00454 }
00455 return sock;
00456 }
00457
00471 int NutRegisterFtpRoot(CONST char *path)
00472 {
00473
00474 if (path == NULL || *path == 0) {
00475
00476 if (ftp_root) {
00477 free(ftp_root);
00478 }
00479 if ((ftp_root = malloc(sizeof(FTP_ROOTPATH))) == 0) {
00480 return -1;
00481 }
00482 strcpy(ftp_root, FTP_ROOTPATH);
00483 }
00484
00485
00486 else {
00487 char *cp = strchr(path, ':');
00488 int len = strlen(path);
00489
00490
00491 if (len < 2 || cp == 0 || (*++cp && *cp != '/')) {
00492 return -1;
00493 }
00494
00495
00496 if ((cp = malloc(len + 1)) == 0) {
00497 return -1;
00498 }
00499
00500
00501 strcpy(cp, path);
00502 if (ftp_root) {
00503 free(ftp_root);
00504 }
00505 ftp_root = cp;
00506
00507
00508 cp = cp + strlen(cp) - 1;
00509 if (*cp == '/') {
00510 *cp = 0;
00511 }
00512 }
00513 return 0;
00514 }
00515
00531 int NutRegisterFtpUser(CONST char *user, CONST char *pass)
00532 {
00533 if (ftp_user) {
00534 free(ftp_user);
00535 ftp_user = 0;
00536 }
00537 if (user && *user) {
00538 if ((ftp_user = malloc(strlen(user) + 1)) == 0) {
00539 return -1;
00540 }
00541 strcpy(ftp_user, user);
00542 }
00543 if (ftp_pass) {
00544 free(ftp_pass);
00545 ftp_pass = 0;
00546 }
00547 if (pass && *pass) {
00548 if ((ftp_pass = malloc(strlen(pass) + 1)) == 0) {
00549 return -1;
00550 }
00551 strcpy(ftp_pass, pass);
00552 }
00553 return 0;
00554 }
00555
00556
00566 FTPSESSION *NutFtpOpenSession(TCPSOCKET * sock)
00567 {
00568 FTPSESSION *session;
00569
00570 session = malloc(sizeof(FTPSESSION));
00571
00572 if (session) {
00573 memset(session, 0, sizeof(FTPSESSION));
00574 session->ftp_data_port = FTP_DATA_PORT;
00575 session->ftp_maxseg = sock->so_mss;
00576 session->ftp_sock = sock;
00577
00578
00579 if ((session->ftp_cwd = malloc(2)) == 0) {
00580 free(session);
00581 session = 0;
00582 } else {
00583 session->ftp_cwd[0] = '/';
00584 session->ftp_cwd[1] = 0;
00585
00586
00587
00588
00589
00590
00591 if ((session->ftp_stream = _fdopen((int) sock, "r+b")) == 0) {
00592 free(session->ftp_cwd);
00593 free(session);
00594 session = 0;
00595 }
00596 }
00597 }
00598 return session;
00599 }
00600
00607 void NutFtpCloseSession(FTPSESSION * session)
00608 {
00609 if (session) {
00610
00611 fclose(session->ftp_stream);
00612 if (session->ftp_cwd) {
00613 free(session->ftp_cwd);
00614 }
00615 free(session);
00616 }
00617 }
00618
00629 int NutFtpProcessCwd(FTPSESSION * session, char *path)
00630 {
00631 struct stat st;
00632 char *cp = path + strlen(ftp_root);
00633
00634 if (*cp && strcmp(cp, "/")) {
00635
00636
00637
00638 if (stat(path, &st) || !S_ISDIR(st.st_mode)) {
00639 return NutFtpRespondBad(session, 550);
00640 }
00641 }
00642
00643
00644
00645
00646 if (*cp == 0) {
00647 cp = "/";
00648 }
00649 if (session->ftp_cwd) {
00650 free(session->ftp_cwd);
00651 }
00652 if ((session->ftp_cwd = malloc(strlen(cp) + 1)) == 0) {
00653 return NutFtpRespondBad(session, 550);
00654 }
00655 strcpy(session->ftp_cwd, cp);
00656
00657 return NutFtpRespondOk(session, 250);
00658 }
00659
00672 int NutFtpProcessDelete(FTPSESSION * session, char *path)
00673 {
00674 if (unlink(path)) {
00675 return NutFtpRespondBad(session, 550);
00676 }
00677 return NutFtpRespondOk(session, 250);
00678 }
00679
00697 int NutFtpTransferFile(FTPSESSION * session, char *path, int mode)
00698 {
00699 TCPSOCKET *sock;
00700 int ec = 550;
00701 int fh;
00702
00703
00704 if (mode) {
00705 fh = _open(path, _O_BINARY | _O_RDONLY);
00706 }
00707
00708 else {
00709 fh = _open(path, _O_CREAT | _O_TRUNC);
00710 }
00711
00712 if (fh != -1) {
00713
00714 NutFtpSendMode(session, session->ftp_tran_mode);
00715 if ((sock = NutFtpDataConnect(session)) != 0) {
00716 u_short mss = sock->so_mss;
00717 u_char *buf;
00718
00719 if (mss < 256) {
00720 mss = 256;
00721 }
00722 if ((buf = malloc(mss)) != 0) {
00723 int got;
00724
00725 ec = 0;
00726
00727
00728 if (mode) {
00729 while ((got = _read(fh, buf, mss)) > 0) {
00730 if (NutTcpSend(sock, buf, got) != got) {
00731 ec = 551;
00732 break;
00733 }
00734 }
00735 }
00736
00737
00738 else {
00739 while ((got = NutTcpReceive(sock, buf, mss)) > 0) {
00740 int x;
00741 if ((x = _write(fh, buf, got)) != got) {
00742 ec = 552;
00743 break;
00744 }
00745 }
00746 }
00747 free(buf);
00748 }
00749 NutTcpCloseSocket(sock);
00750 }
00751 _close(fh);
00752
00753
00754 if (mode == 0 && ec) {
00755 unlink(path);
00756 }
00757 }
00758 if (ec) {
00759 return NutFtpRespondBad(session, ec);
00760 }
00761 return NutFtpRespondOk(session, 226);
00762 }
00763
00776 int NutFtpTransferDirectory(FTPSESSION * session, char *path)
00777 {
00778 TCPSOCKET *sock;
00779 FILE *fp;
00780
00781 struct stat st;
00782 DIR *dir;
00783 struct dirent *d_ent;
00784 tm *gmt;
00785 u_long size;
00786 int ec = 550;
00787 char *name;
00788
00789 dir = opendir(path);
00790 if (dir) {
00791 NutFtpSendMode(session, 0);
00792 if ((sock = NutFtpDataConnect(session)) != 0) {
00793 if ((fp = _fdopen((int) sock, "r+b")) != 0) {
00794 ec = 0;
00795 while ((d_ent = readdir(dir)) != 0) {
00796 if (d_ent->d_name[0] == '.') {
00797 continue;
00798 }
00799
00800 if ((name = malloc(strlen(path) + strlen(d_ent->d_name) + 2)) != 0) {
00801 sprintf(name, "%s/%s", path, d_ent->d_name);
00802 if (stat(name, &st) == 0) {
00803 if (S_ISDIR(st.st_mode)) {
00804 fputc('d', fp);
00805 size = 0;
00806 } else {
00807 fputc('-', fp);
00808 size = st.st_size;
00809 }
00810 fprintf(fp, "rw-rw-rw- 1 0 0 %6lu ", size);
00811 gmt = gmtime(&st.st_mtime);
00812
00813 fprintf(fp, "%.3s %u ", mon_name + gmt->tm_mon * 3, gmt->tm_mday);
00814
00815 fprintf(fp, "%02u:%02u ", gmt->tm_hour, gmt->tm_min);
00816 fputs(d_ent->d_name, fp);
00817 fputs("\r\n", fp);
00818 }
00819 free(name);
00820 }
00821 }
00822 fclose(fp);
00823 }
00824 NutTcpCloseSocket(sock);
00825 }
00826 closedir(dir);
00827 }
00828 if (ec) {
00829 return NutFtpRespondBad(session, ec);
00830 }
00831 return NutFtpRespondOk(session, 226);
00832 }
00833
00846 int NutFtpProcessMkd(FTPSESSION * session, char *path)
00847 {
00848 if (mkdir(path, 0777)) {
00849 return NutFtpRespondBad(session, 550);
00850 }
00851 return NutFtpRespondOk(session, 257);
00852 }
00853
00866 int NutFtpProcessPass(FTPSESSION * session, char *pass)
00867 {
00868 if (ftp_pass && *ftp_pass) {
00869 if (session->ftp_login != 1 || strcmp(ftp_pass, pass)) {
00870 session->ftp_login = 0;
00871 return NutFtpRespondBad(session, 550);
00872 }
00873 }
00874 session->ftp_login = 2;
00875 return NutFtpRespondOk(session, 230);
00876 }
00877
00891 int NutFtpProcessPassiv(FTPSESSION * session)
00892 {
00893 u_long ip = session->ftp_sock->so_local_addr;
00894 u_short port = 20;
00895
00896 fprintf(session->ftp_stream, "227 Passive (%u,%u,%u,%u,%u,%u).\r\n",
00897 (u_char) ip, (u_char) (ip >> 8), (u_char) (ip >> 16), (u_char) (ip >> 24),
00898 (u_char) (port >> 8), (u_char) port);
00899 fflush(session->ftp_stream);
00900 session->ftp_passive = 1;
00901
00902 return 0;
00903 }
00904
00919 int NutFtpProcessPort(FTPSESSION * session, char *args)
00920 {
00921 if (ParseIpPort(args, &session->ftp_data_ip, &session->ftp_data_port) == 6) {
00922 if (session->ftp_sock->so_remote_addr == session->ftp_data_ip) {
00923 return NutFtpRespondOk(session, 200);
00924 }
00925 return NutFtpRespondBad(session, 425);
00926 }
00927 return NutFtpRespondBad(session, 501);;
00928 }
00929
00942 int NutFtpProcessPwd(FTPSESSION * session)
00943 {
00944 #ifdef FTPD_DEBUG
00945 printf("\n<'257 \"%s\"' ", session->ftp_cwd);
00946 #endif
00947 fprintf(session->ftp_stream, "257 \"%s\"\r\n", session->ftp_cwd);
00948 return 0;
00949 }
00950
00963 int NutFtpProcessRmd(FTPSESSION * session, char *path)
00964 {
00965 if (rmdir(path)) {
00966 return NutFtpRespondBad(session, 451);
00967 }
00968 return NutFtpRespondOk(session, 257);
00969 }
00970
00980 int NutFtpProcessSystem(FTPSESSION * session)
00981 {
00982 #ifdef FTPD_DEBUG
00983 printf("\n<'215 UNIX Type: L8' ");
00984 #endif
00985 fputs("215 UNIX Type: L8\r\n", session->ftp_stream);
00986 return 0;
00987 }
00988
01003 int NutFtpProcessType(FTPSESSION * session, char *typecode)
01004 {
01005 session->ftp_tran_mode = (*typecode != 'A') && (*typecode != 'a');
01006 return NutFtpRespondOk(session, 200);
01007 }
01008
01021 int NutFtpProcessUser(FTPSESSION * session, char *user)
01022 {
01023 if (ftp_user && *ftp_user) {
01024 if (session->ftp_login && strcmp(ftp_user, user)) {
01025 session->ftp_login = 0;
01026 return NutFtpRespondBad(session, 550);
01027 }
01028 }
01029
01030
01031 if (ftp_pass && *ftp_pass) {
01032 session->ftp_login = 1;
01033 return NutFtpRespondOk(session, 331);
01034 }
01035
01036
01037 session->ftp_login = 2;
01038 return NutFtpRespondOk(session, 230);
01039 }
01040
01052 int NutFtpProcessRequest(FTPSESSION * session, char *request)
01053 {
01054 int rc = 0;
01055 char *cmd;
01056 char *args;
01057
01058
01059 SplitCmdArg(request, &cmd, &args);
01060 #ifdef FTPD_DEBUG
01061 printf("\n>'%s %s' ", cmd, args);
01062 #endif
01063
01064
01065 if (strcmp_P(cmd, cmd_quit_P) == 0) {
01066 NutFtpRespondOk(session, 221);
01067 rc = -1;
01068 }
01069
01070
01071 else if (strcmp_P(cmd, cmd_user_P) == 0) {
01072 rc = NutFtpProcessUser(session, args);
01073 }
01074
01075
01076 else if (strcmp_P(cmd, cmd_pass_P) == 0) {
01077 rc = NutFtpProcessPass(session, args);
01078 } else if (strcmp_P(cmd, cmd_noop_P) == 0) {
01079 NutFtpRespondOk(session, 200);
01080 }
01081
01082 else if (session->ftp_login < 2) {
01083 rc = NutFtpRespondBad(session, 530);
01084 }
01085
01086
01087 else {
01088
01089
01090 if (strcmp_P(cmd, cmd_pasv_P) == 0) {
01091 rc = NutFtpProcessPassiv(session);
01092 }
01093
01094
01095 else if (strcmp_P(cmd, cmd_port_P) == 0) {
01096 rc = NutFtpProcessPort(session, args);
01097 }
01098
01099
01100 else if (strcmp_P(cmd, cmd_pwd_P) == 0 || strcmp_P(cmd, cmd_xpwd_P) == 0) {
01101 rc = NutFtpProcessPwd(session);
01102 }
01103
01104
01105 else if (strcmp_P(cmd, cmd_syst_P) == 0) {
01106 rc = NutFtpProcessSystem(session);
01107 }
01108
01109
01110 else if (strcmp_P(cmd, cmd_type_P) == 0) {
01111 rc = NutFtpProcessType(session, args);
01112 }
01113
01114
01115 else {
01116 char *path;
01117
01118 if ((path = CreateFullPathName(ftp_root, session->ftp_cwd, args)) == 0) {
01119 rc = NutFtpRespondBad(session, 451);
01120 }
01121
01122
01123 else if (strcmp_P(cmd, cmd_cwd_P) == 0) {
01124 rc = NutFtpProcessCwd(session, path);
01125 }
01126
01127
01128 else if (strcmp_P(cmd, cmd_dele_P) == 0) {
01129 rc = NutFtpProcessDelete(session, path);
01130 }
01131
01132
01133 else if (strcmp_P(cmd, cmd_list_P) == 0 || strcmp_P(cmd, cmd_nlst_P) == 0) {
01134 rc = NutFtpTransferDirectory(session, path);
01135 }
01136
01137
01138 else if (strcmp_P(cmd, cmd_mkd_P) == 0 || strcmp_P(cmd, cmd_xmkd_P) == 0) {
01139 rc = NutFtpProcessMkd(session, path);
01140 }
01141
01142
01143 else if (strcmp_P(cmd, cmd_retr_P) == 0) {
01144 rc = NutFtpTransferFile(session, path, 1);
01145 }
01146
01147
01148 else if (strcmp_P(cmd, cmd_rmd_P) == 0 || strcmp_P(cmd, cmd_xrmd_P) == 0) {
01149 rc = NutFtpProcessRmd(session, path);
01150 }
01151
01152
01153 else if (strcmp_P(cmd, cmd_stor_P) == 0) {
01154 rc = NutFtpTransferFile(session, path, 0);
01155 }
01156
01157
01158 else {
01159 rc = NutFtpRespondBad(session, 502);
01160 }
01161
01162 if (path) {
01163 free(path);
01164 }
01165 }
01166 }
01167 return rc;
01168 }
01169
01185 int NutFtpServerSession(TCPSOCKET * sock)
01186 {
01187 int rc = 0;
01188 FTPSESSION *session;
01189 char *buff;
01190 time_t now;
01191 struct _tm *tip;
01192 char ch;
01193
01194
01195 if (NutRegisterFtpRoot(ftp_root)) {
01196 return -1;
01197 }
01198
01199
01200 if ((buff = malloc(FTP_MAX_CMDBUF)) == 0) {
01201 return -1;
01202 }
01203
01204
01205 if ((session = NutFtpOpenSession(sock)) == 0) {
01206 free(buff);
01207 return -1;
01208 }
01209
01210
01211 time(&now);
01212 tip = localtime(&now);
01213 #ifdef FTPD_DEBUG
01214 printf("\n<'");
01215 printf_P(rep_banner, NutVersionString(), &mon_name[tip->tm_mon * 3],
01216 tip->tm_mday, tip->tm_hour, tip->tm_min, tip->tm_sec);
01217 #endif
01218 fprintf_P(session->ftp_stream, rep_banner, NutVersionString(),
01219 &mon_name[tip->tm_mon * 3],
01220 tip->tm_mday, tip->tm_hour, tip->tm_min, tip->tm_sec);
01221
01222
01223
01224
01225 while (rc == 0) {
01226
01227
01228 fflush(session->ftp_stream);
01229 if (fgets(buff, FTP_MAX_CMDBUF, session->ftp_stream) == 0) {
01230 rc = -1;
01231 break;
01232 }
01233
01234
01235 if ((ch = *(buff + strlen(buff) - 1)) != '\n' && ch != '\r') {
01236 do {
01237 if (fgets(buff, FTP_MAX_CMDBUF, session->ftp_stream) == 0) {
01238 rc = -1;
01239 break;
01240 }
01241 } while ((ch = *(buff + strlen(buff) - 1)) != '\n' && ch != '\r');
01242 if (rc == 0) {
01243 rc = NutFtpRespondBad(session, 500);
01244 }
01245 }
01246
01247
01248 else {
01249 rc = NutFtpProcessRequest(session, buff);
01250 }
01251 }
01252
01253
01254 NutFtpCloseSession(session);
01255 free(buff);
01256 return rc;
01257 }
01258