[질문]c로 FTP client를 구현하는데.. user id전송후 패스워드 전송시 530 코드만..
글쓴이: sunnymichy / 작성시간: 화, 2006/01/24 - 6:57오후
안녕하세요.
네트워크 프로그래밍을 공부하고 있는 사람입니다..^^;
다른게 아니고.. 제가 c 언어로 ftp client를 구현하고 있는 중입니다. 그런데.. 자꾸 이상하게 동작을 해서 이렇게 조언을 구하고자 질문을 올립니다. 제가 첨부하는 소스를 보시고 혹시 틀린 부분이 있는지 조언을 부탁드립니다.
소스코드는 아래와 같습니다. 소스가 긴 관계로 현재 제가 틀린곳이 있는지 유무를 알고자하는 login()함수 부분만 적습니다.
int login() { struct termio tty; struct sockaddr_in server_addr; unsigned short saveflags; char user_id[20]; char passwd[20]; char *login_name; int receive_code = 0; cmd_response(); // 220 response code를 받기 위함. login_name = malloc(BUFSIZ); memset(user_id, '\0', 20); memset(sendbuf, '\0', sizeof(sendbuf)); if( (login_name = getenv("LOGNAME")) == NULL) { fprintf(stderr,"can't get LOGNAME."); } fprintf(stdout,"User ID[%s:%s] : ", server_ip, login_name); fgets(user_id, sizeof(user_id), stdin); if( !strcmp(user_id,"\n") ) // if input '\n', user_id is current user ID. { sprintf(sendbuf,"USER %s\r\n", login_name); write(control_fd, sendbuf, sizeof(sendbuf)); // user id를 전송. USER user_id. } else { user_id[strlen(user_id)-1] = '\0'; sprintf(sendbuf,"USER %s\r\n", user_id); write(control_fd, sendbuf, sizeof(sendbuf)); // user id를 전송. USER user_id. } bzero(sendbuf, sizeof(sendbuf)); if( ( receive_code = cmd_response()) == USER_OK ) // if login is success. { ioctl(fileno(stdout), TCGETA, &tty); // get current tty. saveflags = tty.c_lflag; // save current tty.c_lflag. tty.c_lflag &= ~ECHO; // terminal echo disable. ioctl(fileno(stdout), TCSETAF, &tty); // establish tty printf("Password: "); fgets(passwd, sizeof(passwd), stdin); passwd[strlen(passwd)-1] = '\0'; bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"PASS %s\r\n", passwd); fprintf(stdout, "\n"); write(control_fd, sendbuf, sizeof(sendbuf)); // password 전송. PASS password. tty.c_lflag = saveflags; // recovery old tty.c_lflag, terminal echo enable. ioctl(fileno(stdout), TCSETAF, &tty); fprintf(stdout, "\n"); if( (receive_code = cmd_response()) == FAILURE ) { fprintf(stderr,"Logined failed.\n"); return FAILURE_LOGIN; } return SUCCESS_LOGIN; } else { fprintf(stdout, "User ID incorect.\n"); return FAILURE_LOGIN; // if login is failed. return FAILURE_LOGIN. } } // end of login()
실행 결과는 아래와 같습니다.
220 (vsFTPd 2.0.1) user ID[(null):black422] : DEBUG_CODE: [Line: 206, Func: login()] DEBUG_CODE: sendbuf = _USER black422 _ and control_fd = _3_ of id in login(). DEBUG_CODE: sendbuf[0] = 55 DEBUG_CODE: sendbuf[1] = 53 DEBUG_CODE: sendbuf[2] = 45 DEBUG_CODE: sendbuf[3] = 52 DEBUG_CODE: sendbuf[4] = 20 DEBUG_CODE: sendbuf[5] = 62 DEBUG_CODE: sendbuf[6] = 6c DEBUG_CODE: sendbuf[7] = 61 DEBUG_CODE: sendbuf[8] = 63 DEBUG_CODE: sendbuf[9] = 6b DEBUG_CODE: sendbuf[10] = 34 DEBUG_CODE: sendbuf[11] = 32 DEBUG_CODE: sendbuf[12] = 32 DEBUG_CODE: sendbuf[13] = d DEBUG_CODE: sendbuf[14] = a DEBUG_CODE: [Line: 215, Func: login()] DEBUG_CODE: recv_buf =_331 Please specify the password. _ in cmd_response() DEBUG_CODE: response_cmd_code = _331_ 331 Please specify the password. Password: DEBUG_CODE: [Line: 570, Func: cmd_response()] DEBUG_CODE: recv_buf =_530 Please login with USER and PASS. _ in cmd_response() DEBUG_CODE: response_cmd_code = _530_ 530 Please login with USER and PASS. Logined failed.
물론 디버그코드로 헥사값으로 출력을 해보아도 제대로 버퍼에 입력이 되어집니다.
Forums:
530 이면 암호가 틀린 경우인거 같은데요..\r\n 말고 그냥
530 이면 암호가 틀린 경우인거 같은데요..
\r\n 말고 그냥 \r 만 하거나 \n만 하면 되지 않을까요? (암호 입력시와 ID입력시 모두에..)
그리고 sendbuf의 사이즈는 몇인가??
일하는 사람들의 희망 민주노동당 : http://www.kdlp.org
반공 교육의 성과로, 민주주의의 반대가 공산주의(또는 사회주의)라고 생각하는 사람이 많다.
* write(fd, buf, size)는 항상 size만큼 write
* write(fd, buf, size)는 항상 size만큼 write하는 것은 아닙니다.
정확히는, x<= size 인 x만큼을 write하게됩니다. 리턴값 검사하라는 얘기입니다.
심지어 x <= 0 인 경우에 대해서도 검사해야 합니다. 때에 따라 중단 또는 루프돌면서 전송하는 루틴이 필요합니다.
* write(fd, buf, sizeof(buf)) 스타일에서
sizeof()를 사용하는 것은 때에따라, 실제보내야 할 크기보다 더 큰 데이터를 보낼 수 있습니다. 이를 문자열의 길이로 대체하여야 할것입니다.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
mach 님 감사합니다.
지적해 주신대로 sizeof() 문제 였습니다.
다시 한번 감사드립니다..
댓글 달기