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
00085 #include <sys/version.h>
00086
00087 #include <sys/socket.h>
00088 #include <netinet/tcp.h>
00089
00090 #include <string.h>
00091 #include <stdio.h>
00092 #include <stdlib.h>
00093 #include <io.h>
00094 #include <fcntl.h>
00095 #include <sys/stat.h>
00096 #include <dirent.h>
00097 #include <unistd.h>
00098 #include <memdebug.h>
00099
00100 #include <pro/ftpd.h>
00101
00102 #ifdef FTPD_DEBUG
00103 #include <sys/heap.h>
00104 #endif
00105
00112
00119
00125 #ifndef FTP_ROOTPATH
00126 #define FTP_ROOTPATH "PNUT:"
00127 #endif
00128
00134 #ifndef FTP_DATA_PORT
00135 #define FTP_DATA_PORT 20
00136 #endif
00137
00140 static char *ftp_root;
00141 static char *ftp_user;
00142 static char *ftp_pass;
00143
00144
00145
00146
00147
00148 static prog_char cmd_cwd_P[] = "CWD";
00149 static prog_char cmd_dele_P[] = "DELE";
00150 static prog_char cmd_list_P[] = "LIST";
00151 static prog_char cmd_mkd_P[] = "MKD";
00152 static prog_char cmd_xmkd_P[] = "XMKD";
00153 static prog_char cmd_nlst_P[] = "NLST";
00154 static prog_char cmd_noop_P[] = "NOOP";
00155 static prog_char cmd_pass_P[] = "PASS";
00156 static prog_char cmd_pasv_P[] = "PASV";
00157 static prog_char cmd_port_P[] = "PORT";
00158 static prog_char cmd_pwd_P[] = "PWD";
00159 static prog_char cmd_xpwd_P[] = "XPWD";
00160 static prog_char cmd_quit_P[] = "QUIT";
00161 static prog_char cmd_retr_P[] = "RETR";
00162 static prog_char cmd_rmd_P[] = "RMD";
00163 static prog_char cmd_xrmd_P[] = "XRMD";
00164 static prog_char cmd_stor_P[] = "STOR";
00165 static prog_char cmd_syst_P[] = "SYST";
00166 static prog_char cmd_type_P[] = "TYPE";
00167 static prog_char cmd_user_P[] = "USER";
00168
00169 static char *mon_name = "JanFebMarAprMayJunJulAugSepOctNovDec";
00170
00171 static prog_char rep_banner[] = "220 Nut/OS FTP %s ready at %.3s%3d %02d:%02d:%02d\r\n";
00172
00185 static void SplitCmdArg(char * line, char ** cmd, char ** args)
00186 {
00187
00188 while (*line && *line <= ' ') {
00189 line++;
00190 }
00191
00192
00193 *cmd = line;
00194 while (*line > ' ') {
00195 if (*line >= (uint8_t) 'a' && *line <= (uint8_t) 'z') {
00196 *line -= (uint8_t) 'a' - 'A';
00197 }
00198 line++;
00199 }
00200
00201
00202 if (*line) {
00203 *line++ = '\0';
00204 }
00205
00206
00207 while (*line && *line <= ' ') {
00208 ++line;
00209 }
00210
00211
00212 *args = line;
00213 while (*line && *line != '\r' && *line != '\n') {
00214 line++;
00215 }
00216
00217
00218 *line = 0;
00219 }
00220
00236 static int ParseIpPort(CONST char * arg, uint32_t * ip, uint16_t * port)
00237 {
00238 int rc;
00239
00240 *ip = 0;
00241 *port = 0;
00242 for (rc = 0; rc < 6; rc++) {
00243 if (*arg < '0' || *arg > '9') {
00244 break;
00245 }
00246 if (rc < 4) {
00247 *ip >>= 8;
00248 *ip += atol(arg) << 24;
00249 } else {
00250 *port <<= 8;
00251 *port += atoi(arg);
00252 }
00253 while (*arg && *arg != ',') {
00254 arg++;
00255 }
00256 if (*arg == ',') {
00257 arg++;
00258 }
00259 }
00260 return rc;
00261 }
00262
00272 int NutFtpRespondOk(FTPSESSION * session, int code)
00273 {
00274 static prog_char fmt_P[] = "%d OK\r\n";
00275
00276 #ifdef FTPD_DEBUG
00277 printf("\n<'%d OK' ", code);
00278 #endif
00279 fprintf_P(session->ftp_stream, fmt_P, code);
00280 fflush(session->ftp_stream);
00281
00282 return 0;
00283 }
00284
00294 int NutFtpRespondBad(FTPSESSION * session, int code)
00295 {
00296 static prog_char fmt_P[] = "%d Failed\r\n";
00297
00298 #ifdef FTPD_DEBUG
00299 printf("\n<'%d Failed' ", code);
00300 #endif
00301 fprintf_P(session->ftp_stream, fmt_P, code);
00302 fflush(session->ftp_stream);
00303
00304 return 0;
00305 }
00306
00316 int NutFtpSendMode(FTPSESSION * session, int binary)
00317 {
00318 static prog_char intro_P[] = "150 Opening ";
00319 static prog_char amode_P[] = "ASCII.\r\n";
00320 static prog_char bmode_P[] = "BINARY.\r\n";
00321
00322 #ifdef FTPD_DEBUG
00323 printf("\n<'150 Opening %s' ", binary ? "BINARY" : "ASCII");
00324 #endif
00325 fputs_P(intro_P, session->ftp_stream);
00326 fputs_P(binary ? bmode_P : amode_P, session->ftp_stream);
00327 fflush(session->ftp_stream);
00328
00329 return 0;
00330 }
00331
00352 char *CreateFullPathName(char *root, char *work, char *path)
00353 {
00354 char *full;
00355 char *cp;
00356 size_t rl = root ? strlen(root) : 0;
00357 size_t wl = work ? strlen(work) : 0;
00358 size_t pl = path ? strlen(path) : 0;
00359
00360
00361 if (rl && *(root + rl - 1) == '/') {
00362 rl--;
00363 }
00364 if (wl && *(work + wl - 1) == '/') {
00365 wl--;
00366 }
00367
00368 if ((full = malloc(rl + wl + pl + 3)) != NULL) {
00369
00370 cp = full;
00371 if (rl) {
00372 cp = strcpy(full, root) + rl;
00373 }
00374
00375
00376 if(pl == 0 || *path != '/') {
00377 if (wl) {
00378 if (*work != '/') {
00379 *cp++ = '/';
00380 }
00381 cp = strcpy(cp, work) + wl;
00382 }
00383 *cp++ = '/';
00384 rl++;
00385 }
00386
00387 if (pl) {
00388 *cp = 0;
00389 work = full + rl;
00390
00391 while (*path) {
00392
00393 if (*path == '/') {
00394 *cp++ = *path++;
00395 while (*path == '/') {
00396 path++;
00397 }
00398 }
00399
00400 if (*path == '.') {
00401 path++;
00402 if (*path == '/') {
00403 path++;
00404 continue;
00405 }
00406 if (*path == 0) {
00407 break;
00408 }
00409 if (*path == '.') {
00410 path++;
00411 if (*path == '/' || *path == 0) {
00412 if (cp != work) {
00413 cp--;
00414 while (cp != work) {
00415 cp--;
00416 if (*cp == '/') {
00417 break;
00418 }
00419 }
00420 }
00421 continue;
00422 }
00423 path--;
00424 }
00425 path--;
00426 }
00427
00428 while (*path && *path != '/') {
00429 *cp++ = *path++;
00430 }
00431 }
00432 }
00433 *cp = 0;
00434 }
00435 return full;
00436 }
00437
00447 TCPSOCKET *NutFtpDataConnect(FTPSESSION * session)
00448 {
00449 TCPSOCKET *sock;
00450 int rc;
00451
00452 if ((sock = NutTcpCreateSocket()) != 0) {
00453
00454 if (session->ftp_maxseg) {
00455 NutTcpSetSockOpt(sock, TCP_MAXSEG, &session->ftp_maxseg, sizeof(session->ftp_maxseg));
00456 }
00457 if (session->ftp_passive) {
00458 rc = NutTcpAccept(sock, session->ftp_data_port);
00459 } else {
00460 rc = NutTcpConnect(sock, session->ftp_data_ip, session->ftp_data_port);
00461 }
00462 if (rc) {
00463 NutTcpCloseSocket(sock);
00464 sock = 0;
00465 }
00466 }
00467 return sock;
00468 }
00469
00483 int NutRegisterFtpRoot(CONST char *path)
00484 {
00485
00486 if (path == NULL || *path == 0) {
00487
00488 if (ftp_root) {
00489 free(ftp_root);
00490 }
00491 if ((ftp_root = malloc(sizeof(FTP_ROOTPATH))) == 0) {
00492 return -1;
00493 }
00494 strcpy(ftp_root, FTP_ROOTPATH);
00495 }
00496
00497
00498 else {
00499 char *cp = strchr(path, ':');
00500 int len = strlen(path);
00501
00502
00503 if (len < 2 || cp == 0 || (*++cp && *cp != '/')) {
00504 return -1;
00505 }
00506
00507
00508 if ((cp = malloc(len + 1)) == 0) {
00509 return -1;
00510 }
00511
00512
00513 strcpy(cp, path);
00514 if (ftp_root) {
00515 free(ftp_root);
00516 }
00517 ftp_root = cp;
00518
00519
00520 cp = cp + strlen(cp) - 1;
00521 if (*cp == '/') {
00522 *cp = 0;
00523 }
00524 }
00525 return 0;
00526 }
00527
00543 int NutRegisterFtpUser(CONST char *user, CONST char *pass)
00544 {
00545 if (ftp_user) {
00546 free(ftp_user);
00547 ftp_user = NULL;
00548 }
00549 if (user && *user) {
00550 if ((ftp_user = strdup(user)) == NULL) {
00551 return -1;
00552 }
00553 }
00554 if (ftp_pass) {
00555 free(ftp_pass);
00556 ftp_pass = NULL;
00557 }
00558 if (pass && *pass) {
00559 if ((ftp_pass = strdup(pass)) == NULL) {
00560 return -1;
00561 }
00562 }
00563 return 0;
00564 }
00565
00566
00576 FTPSESSION *NutFtpOpenSession(TCPSOCKET * sock)
00577 {
00578 FTPSESSION *session;
00579
00580 session = malloc(sizeof(FTPSESSION));
00581
00582 if (session) {
00583 memset(session, 0, sizeof(FTPSESSION));
00584 session->ftp_data_port = FTP_DATA_PORT;
00585 session->ftp_maxseg = sock->so_mss;
00586 session->ftp_sock = sock;
00587
00588
00589 if ((session->ftp_cwd = malloc(2)) == 0) {
00590 free(session);
00591 session = 0;
00592 } else {
00593 session->ftp_cwd[0] = '/';
00594 session->ftp_cwd[1] = 0;
00595
00596
00597
00598
00599
00600
00601 if ((session->ftp_stream = _fdopen((int) sock, "r+b")) == 0) {
00602 free(session->ftp_cwd);
00603 free(session);
00604 session = 0;
00605 }
00606 }
00607 }
00608 return session;
00609 }
00610
00617 void NutFtpCloseSession(FTPSESSION * session)
00618 {
00619 if (session) {
00620
00621 fclose(session->ftp_stream);
00622 if (session->ftp_cwd) {
00623 free(session->ftp_cwd);
00624 }
00625 free(session);
00626 }
00627 }
00628
00639 int NutFtpProcessCwd(FTPSESSION * session, char *path)
00640 {
00641 struct stat st;
00642 char *cp = path + strlen(ftp_root);
00643
00644 if (*cp && strcmp(cp, "/")) {
00645
00646
00647
00648 if (stat(path, &st) || !S_ISDIR(st.st_mode)) {
00649 return NutFtpRespondBad(session, 550);
00650 }
00651 }
00652
00653
00654
00655
00656 if (*cp == 0) {
00657 cp = "/";
00658 }
00659 if (session->ftp_cwd) {
00660 free(session->ftp_cwd);
00661 }
00662 if ((session->ftp_cwd = strdup(cp)) == NULL) {
00663 return NutFtpRespondBad(session, 550);
00664 }
00665 return NutFtpRespondOk(session, 250);
00666 }
00667
00680 int NutFtpProcessDelete(FTPSESSION * session, char *path)
00681 {
00682 if (unlink(path)) {
00683 return NutFtpRespondBad(session, 550);
00684 }
00685 return NutFtpRespondOk(session, 250);
00686 }
00687
00705 int NutFtpTransferFile(FTPSESSION * session, char *path, int mode)
00706 {
00707 TCPSOCKET *sock;
00708 int ec = 550;
00709 int fh;
00710
00711
00712 if (mode) {
00713 fh = _open(path, _O_BINARY | _O_RDONLY);
00714 }
00715
00716 else {
00717 fh = _open(path, _O_CREAT | _O_TRUNC);
00718 }
00719
00720 if (fh != -1) {
00721
00722 NutFtpSendMode(session, session->ftp_tran_mode);
00723 if ((sock = NutFtpDataConnect(session)) != 0) {
00724 uint16_t mss = sock->so_mss;
00725 uint8_t *buf;
00726
00727 if (mss < 256) {
00728 mss = 256;
00729 }
00730 if ((buf = malloc(mss)) != 0) {
00731 int got;
00732
00733 ec = 0;
00734
00735
00736 if (mode) {
00737 while ((got = _read(fh, buf, mss)) > 0) {
00738 if (NutTcpSend(sock, buf, got) != got) {
00739 ec = 551;
00740 break;
00741 }
00742 }
00743 }
00744
00745
00746 else {
00747 while ((got = NutTcpReceive(sock, buf, mss)) > 0) {
00748 int x;
00749 if ((x = _write(fh, buf, got)) != got) {
00750 ec = 552;
00751 break;
00752 }
00753 }
00754 }
00755 free(buf);
00756 }
00757 NutTcpCloseSocket(sock);
00758 }
00759 _close(fh);
00760
00761
00762 if (mode == 0 && ec) {
00763 unlink(path);
00764 }
00765 }
00766 if (ec) {
00767 return NutFtpRespondBad(session, ec);
00768 }
00769 return NutFtpRespondOk(session, 226);
00770 }
00771
00784 int NutFtpTransferDirectory(FTPSESSION * session, char *path)
00785 {
00786 TCPSOCKET *sock;
00787 FILE *fp;
00788
00789 struct stat st;
00790 DIR *dir;
00791 struct dirent *d_ent;
00792 tm *gmt;
00793 uint32_t size;
00794 int ec = 550;
00795 char *name;
00796
00797 dir = opendir(path);
00798 if (dir) {
00799 NutFtpSendMode(session, 0);
00800 if ((sock = NutFtpDataConnect(session)) != 0) {
00801 if ((fp = _fdopen((int) sock, "r+b")) != 0) {
00802 ec = 0;
00803 while ((d_ent = readdir(dir)) != 0) {
00804 if (d_ent->d_name[0] == '.') {
00805 continue;
00806 }
00807
00808 if ((name = malloc(strlen(path) + strlen(d_ent->d_name) + 2)) != 0) {
00809 sprintf(name, "%s/%s", path, d_ent->d_name);
00810 if (stat(name, &st) == 0) {
00811 if (S_ISDIR(st.st_mode)) {
00812 fputc('d', fp);
00813 size = 0;
00814 } else {
00815 fputc('-', fp);
00816 size = st.st_size;
00817 }
00818 fprintf(fp, "rw-rw-rw- 1 0 0 %6lu ", size);
00819 gmt = gmtime(&st.st_mtime);
00820
00821 fprintf(fp, "%.3s %u ", mon_name + gmt->tm_mon * 3, gmt->tm_mday);
00822
00823 fprintf(fp, "%02u:%02u ", gmt->tm_hour, gmt->tm_min);
00824 fputs(d_ent->d_name, fp);
00825 fputs("\r\n", fp);
00826 }
00827 free(name);
00828 }
00829 }
00830 fclose(fp);
00831 }
00832 NutTcpCloseSocket(sock);
00833 }
00834 closedir(dir);
00835 }
00836 if (ec) {
00837 return NutFtpRespondBad(session, ec);
00838 }
00839 return NutFtpRespondOk(session, 226);
00840 }
00841
00854 int NutFtpProcessMkd(FTPSESSION * session, char *path)
00855 {
00856 if (mkdir(path, 0777)) {
00857 return NutFtpRespondBad(session, 550);
00858 }
00859 return NutFtpRespondOk(session, 257);
00860 }
00861
00874 int NutFtpProcessPass(FTPSESSION * session, char *pass)
00875 {
00876 if (ftp_pass && *ftp_pass) {
00877 if (session->ftp_login != 1 || strcmp(ftp_pass, pass)) {
00878 session->ftp_login = 0;
00879 return NutFtpRespondBad(session, 550);
00880 }
00881 }
00882 session->ftp_login = 2;
00883 return NutFtpRespondOk(session, 230);
00884 }
00885
00899 int NutFtpProcessPassiv(FTPSESSION * session)
00900 {
00901 uint32_t ip = session->ftp_sock->so_local_addr;
00902 uint16_t port = 20;
00903
00904 fprintf(session->ftp_stream, "227 Passive (%u,%u,%u,%u,%u,%u).\r\n",
00905 (uint8_t) ip, (uint8_t) (ip >> 8), (uint8_t) (ip >> 16), (uint8_t) (ip >> 24),
00906 (uint8_t) (port >> 8), (uint8_t) port);
00907 fflush(session->ftp_stream);
00908 session->ftp_passive = 1;
00909
00910 return 0;
00911 }
00912
00927 int NutFtpProcessPort(FTPSESSION * session, char *args)
00928 {
00929 if (ParseIpPort(args, &session->ftp_data_ip, &session->ftp_data_port) == 6) {
00930 if (session->ftp_sock->so_remote_addr == session->ftp_data_ip) {
00931 return NutFtpRespondOk(session, 200);
00932 }
00933 return NutFtpRespondBad(session, 425);
00934 }
00935 return NutFtpRespondBad(session, 501);;
00936 }
00937
00950 int NutFtpProcessPwd(FTPSESSION * session)
00951 {
00952 #ifdef FTPD_DEBUG
00953 printf("\n<'257 \"%s\"' ", session->ftp_cwd);
00954 #endif
00955 fprintf(session->ftp_stream, "257 \"%s\"\r\n", session->ftp_cwd);
00956 return 0;
00957 }
00958
00971 int NutFtpProcessRmd(FTPSESSION * session, char *path)
00972 {
00973 if (rmdir(path)) {
00974 return NutFtpRespondBad(session, 451);
00975 }
00976 return NutFtpRespondOk(session, 257);
00977 }
00978
00988 int NutFtpProcessSystem(FTPSESSION * session)
00989 {
00990 #ifdef FTPD_DEBUG
00991 printf("\n<'215 UNIX Type: L8' ");
00992 #endif
00993 fputs("215 UNIX Type: L8\r\n", session->ftp_stream);
00994 return 0;
00995 }
00996
01011 int NutFtpProcessType(FTPSESSION * session, char *typecode)
01012 {
01013 session->ftp_tran_mode = (*typecode != 'A') && (*typecode != 'a');
01014 return NutFtpRespondOk(session, 200);
01015 }
01016
01029 int NutFtpProcessUser(FTPSESSION * session, char *user)
01030 {
01031 if (ftp_user && *ftp_user) {
01032 if (session->ftp_login && strcmp(ftp_user, user)) {
01033 session->ftp_login = 0;
01034 return NutFtpRespondBad(session, 550);
01035 }
01036 }
01037
01038
01039 if (ftp_pass && *ftp_pass) {
01040 session->ftp_login = 1;
01041 return NutFtpRespondOk(session, 331);
01042 }
01043
01044
01045 session->ftp_login = 2;
01046 return NutFtpRespondOk(session, 230);
01047 }
01048
01060 int NutFtpProcessRequest(FTPSESSION * session, char *request)
01061 {
01062 int rc = 0;
01063 char *cmd;
01064 char *args;
01065
01066
01067 SplitCmdArg(request, &cmd, &args);
01068 #ifdef FTPD_DEBUG
01069 printf("\n>'%s %s' ", cmd, args);
01070 #endif
01071
01072
01073 if (strcmp_P(cmd, cmd_quit_P) == 0) {
01074 NutFtpRespondOk(session, 221);
01075 rc = -1;
01076 }
01077
01078
01079 else if (strcmp_P(cmd, cmd_user_P) == 0) {
01080 rc = NutFtpProcessUser(session, args);
01081 }
01082
01083
01084 else if (strcmp_P(cmd, cmd_pass_P) == 0) {
01085 rc = NutFtpProcessPass(session, args);
01086 } else if (strcmp_P(cmd, cmd_noop_P) == 0) {
01087 NutFtpRespondOk(session, 200);
01088 }
01089
01090 else if (session->ftp_login < 2) {
01091 rc = NutFtpRespondBad(session, 530);
01092 }
01093
01094
01095 else {
01096
01097
01098 if (strcmp_P(cmd, cmd_pasv_P) == 0) {
01099 rc = NutFtpProcessPassiv(session);
01100 }
01101
01102
01103 else if (strcmp_P(cmd, cmd_port_P) == 0) {
01104 rc = NutFtpProcessPort(session, args);
01105 }
01106
01107
01108 else if (strcmp_P(cmd, cmd_pwd_P) == 0 || strcmp_P(cmd, cmd_xpwd_P) == 0) {
01109 rc = NutFtpProcessPwd(session);
01110 }
01111
01112
01113 else if (strcmp_P(cmd, cmd_syst_P) == 0) {
01114 rc = NutFtpProcessSystem(session);
01115 }
01116
01117
01118 else if (strcmp_P(cmd, cmd_type_P) == 0) {
01119 rc = NutFtpProcessType(session, args);
01120 }
01121
01122
01123 else {
01124 char *path;
01125
01126 if ((path = CreateFullPathName(ftp_root, session->ftp_cwd, args)) == 0) {
01127 rc = NutFtpRespondBad(session, 451);
01128 }
01129
01130
01131 else if (strcmp_P(cmd, cmd_cwd_P) == 0) {
01132 rc = NutFtpProcessCwd(session, path);
01133 }
01134
01135
01136 else if (strcmp_P(cmd, cmd_dele_P) == 0) {
01137 rc = NutFtpProcessDelete(session, path);
01138 }
01139
01140
01141 else if (strcmp_P(cmd, cmd_list_P) == 0 || strcmp_P(cmd, cmd_nlst_P) == 0) {
01142 rc = NutFtpTransferDirectory(session, path);
01143 }
01144
01145
01146 else if (strcmp_P(cmd, cmd_mkd_P) == 0 || strcmp_P(cmd, cmd_xmkd_P) == 0) {
01147 rc = NutFtpProcessMkd(session, path);
01148 }
01149
01150
01151 else if (strcmp_P(cmd, cmd_retr_P) == 0) {
01152 rc = NutFtpTransferFile(session, path, 1);
01153 }
01154
01155
01156 else if (strcmp_P(cmd, cmd_rmd_P) == 0 || strcmp_P(cmd, cmd_xrmd_P) == 0) {
01157 rc = NutFtpProcessRmd(session, path);
01158 }
01159
01160
01161 else if (strcmp_P(cmd, cmd_stor_P) == 0) {
01162 rc = NutFtpTransferFile(session, path, 0);
01163 }
01164
01165
01166 else {
01167 rc = NutFtpRespondBad(session, 502);
01168 }
01169
01170 if (path) {
01171 free(path);
01172 }
01173 }
01174 }
01175 return rc;
01176 }
01177
01193 int NutFtpServerSession(TCPSOCKET * sock)
01194 {
01195 int rc = 0;
01196 FTPSESSION *session;
01197 char *buff;
01198 time_t now;
01199 struct _tm *tip;
01200 char ch;
01201
01202
01203 if (NutRegisterFtpRoot(ftp_root)) {
01204 return -1;
01205 }
01206
01207
01208 if ((buff = malloc(FTP_MAX_CMDBUF)) == 0) {
01209 return -1;
01210 }
01211
01212
01213 if ((session = NutFtpOpenSession(sock)) == 0) {
01214 free(buff);
01215 return -1;
01216 }
01217
01218
01219 time(&now);
01220 tip = localtime(&now);
01221 #ifdef FTPD_DEBUG
01222 printf("\n<'");
01223 printf_P(rep_banner, NutVersionString(), &mon_name[tip->tm_mon * 3],
01224 tip->tm_mday, tip->tm_hour, tip->tm_min, tip->tm_sec);
01225 #endif
01226 fprintf_P(session->ftp_stream, rep_banner, NutVersionString(),
01227 &mon_name[tip->tm_mon * 3],
01228 tip->tm_mday, tip->tm_hour, tip->tm_min, tip->tm_sec);
01229
01230
01231
01232
01233 while (rc == 0) {
01234
01235
01236 fflush(session->ftp_stream);
01237 if (fgets(buff, FTP_MAX_CMDBUF, session->ftp_stream) == 0) {
01238 rc = -1;
01239 break;
01240 }
01241
01242
01243 if ((ch = *(buff + strlen(buff) - 1)) != '\n' && ch != '\r') {
01244 do {
01245 if (fgets(buff, FTP_MAX_CMDBUF, session->ftp_stream) == 0) {
01246 rc = -1;
01247 break;
01248 }
01249 } while ((ch = *(buff + strlen(buff) - 1)) != '\n' && ch != '\r');
01250 if (rc == 0) {
01251 rc = NutFtpRespondBad(session, 500);
01252 }
01253 }
01254
01255
01256 else {
01257 rc = NutFtpProcessRequest(session, buff);
01258 }
01259 }
01260
01261
01262 NutFtpCloseSession(session);
01263 free(buff);
01264 return rc;
01265 }
01266