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