Add NLST by Liu Yang.
[xylftp.git] / server / src / xylsocket.c
blobd87a0d129a4c4b93c70526cd24cec7a2907e4ddc
1 /* All rights reserved.
3 * 文件名称:xylsocket.c
4 * 摘 要:对socket函数进行封装
5 * 当前版本:1.0
6 * 作 者:董溥
7 * 完成日期:2007年5月13日
9 *修改人员:林峰
10 *修改日期:2007年6月6日
11 *修改:王聪
12 *修改日期:2007.8.4
15 #include "xylftp.h"
16 #include "debug.h"
18 extern struct user_env user_env;
19 extern struct run_env run_env;
21 extern void telnet(void);
23 int r_close(int fd)
25 int state;
26 while ((state = close(fd)) == -1 && errno == EINTR) {
27 continue;
29 return state;
31 void listen_connect(void)
33 int socket_fd;
34 int connect_fd;
35 pid_t child_pid;
36 #ifdef DEBUG
37 run_env.ftp_port = 1986;
38 #endif
39 if ((socket_fd = xyl_listen(run_env.ftp_port)) == -1) {
40 exit(1);
42 while (1) {
43 if ((connect_fd = xyl_accept(socket_fd)) == -1) {
44 if (r_close(socket_fd) == -1) {
45 LOG_IT("close error.");
47 exit(1);
49 user_env.connect_fd = connect_fd;
51 debug_printf("run to fork.\n");
53 signal(SIGCLD,SIG_IGN); /*to avoid zombie process*/
55 if ((child_pid = fork()) == -1) {
56 LOG_IT("fork error.");
58 else if (child_pid) { /*parent*/
59 if (r_close(user_env.connect_fd) == -1) {
60 LOG_IT("close error.");
62 continue;
64 else if (child_pid == 0) {
65 if (r_close(socket_fd) == -1) {
66 LOG_IT("close error.");
69 telnet();
71 if (r_close(user_env.connect_fd) == -1) {
72 LOG_IT("close connect_fd error.");
74 exit(0);
78 int xyl_listen(short port)
80 int socket_fd;
81 struct sockaddr_in server_addr;
82 bzero(&server_addr, sizeof(server_addr)); /*initial socket address to zero*/
83 server_addr.sin_family = AF_INET; /*use IPv4*/
84 server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*use localhost IP*/
85 server_addr.sin_port = htons(port); /*convert from host byte order to network byte order*/
87 if ((socket_fd = socket(AF_INET,SOCK_STREAM,0)) == -1) {
88 LOG_IT("socket error.");
89 if (errno == ENFILE){
90 LOG_IT("The system limit on the total number of open files has been reached.");
92 else if (errno == EPROTONOSUPPORT) {
93 LOG_IT("The protocol type or the specified protocol is not supported within this domain.");
95 else if (errno == EACCES) {
96 LOG_IT("Permission to create a socket of the specified type and/or protocol is denied.");
97 return -1;
101 if ((bind(socket_fd,(struct sockaddr *) &server_addr,sizeof(server_addr)) == -1)) {
102 LOG_IT("bind error.");
103 if (errno == EADDRINUSE) {
104 LOG_IT("The given address is already in use.");
106 else if (errno == EBADF) {
107 LOG_IT("sock_fd is not a valid descriptor.");
109 else if (errno == EACCES) {
110 LOG_IT("The address is protected.");
112 if (r_close(socket_fd) == -1) {
113 LOG_IT("close socket_fd error.");
115 return -1;
118 if (listen(socket_fd,LISTENQ) == -1) {
119 LOG_IT("listen error.");
120 if (errno == EADDRINUSE) {
121 LOG_IT("Another socket is already listening on the same port.");
122 return -1;
126 return socket_fd;
130 int xyl_accept(int socket_fd)
132 int connect_fd;
133 socklen_t len;
134 struct sockaddr_in client_addr;
135 while (1) {
136 len = sizeof(client_addr);
137 if ((connect_fd = accept(socket_fd, (struct sockaddr *)&client_addr,&len)) == -1
138 && errno == EINTR) {
139 continue;
141 if (connect_fd == -1) {
142 LOG_IT("accept error.");
143 if (errno == ECONNABORTED) {
144 LOG_IT("A connection has been aborted.");
146 else if (errno == EPERM) {
147 LOG_IT("Firewall rules forbid connection.");
149 else if (errno == ENFILE) {
150 LOG_IT("The system limit on the total number of open files has been reached.");
152 else if (errno == EINTR) {
153 LOG_IT("The system call was interrupted by a signal that was"
154 "caught before a valid connection arrived.");
157 break;
159 strcpy(user_env.client_ip, inet_ntoa(client_addr.sin_addr));
160 return connect_fd;
164 int xyl_connect(char *hostname,short port)
166 int socket_fd;
167 int ret;
168 struct sockaddr_in server_addr;
169 socklen_t len;
171 server_addr.sin_port = htons(port);
172 server_addr.sin_family = AF_INET;
173 if ((inet_aton(hostname, &server_addr.sin_addr)) == 0) {
174 LOG_IT("invalid address.");
175 return -1;
177 /*bzero(&(server_addr.sin_zero),8);*/
179 if ((socket_fd = socket(AF_INET,SOCK_STREAM,0)) == -1) {
180 LOG_IT("socket error.");
181 if (errno == ENFILE){
182 LOG_IT("The system limit on the total number of open files has been reached.");
184 else if (errno == EPROTONOSUPPORT) {
185 LOG_IT("The protocol type or the specified protocol is not supported within this domain.");
187 else if (errno == EACCES) {
188 LOG_IT("Permission to create a socket of the specified type and/or protocol is denied.");
190 return -1;
194 while (1) {
195 len = sizeof(server_addr);
196 if (((ret = connect(socket_fd, (struct sockaddr *)&server_addr, len)) == -1
197 && errno == EINTR) || errno == EALREADY) {
198 continue;
200 if (ret == -1) {
201 LOG_IT("connect error.");
202 if (errno == ENETUNREACH) {
203 LOG_IT("Network is unreachable.");
205 else if (errno == ETIMEDOUT) {
206 LOG_IT("Timeout while attempting connection.");
208 else if (errno == EISCONN) {
209 LOG_IT("The socket is already connected.");
211 else if (errno == ECONNREFUSED) {
212 LOG_IT("No one listening on the remote address.");
214 if (r_close(socket_fd) == -1) {
215 LOG_IT("close socket_fd error.");
217 return -1;
219 break;
221 return socket_fd;