8 * Main program. Opens the command port until a client requests a connection.
9 * Then the server is forked the child will manage all that client's requests.
11 * Attending multiple clients is necessary to allow some clients (like lftp(1))
12 * perform multiple concurrent jops. Like moving current transfer to de
13 * background and then browse through directories.
15 * Also note that here the root directory is fixed. As we can't protect with
16 * chroot(), due to de lack of privilege, we must do a series of safety checks
17 * to simulate that behaviour. Because of this, some strong restrictions have
18 * arised; which could reduce de number of FTP clients compatible with this
27 * Reaper function. For "zombies".
29 static void child_finish (int sig
)
31 while (waitpid(-1, NULL
, WNOHANG
) > 0)
32 debug_msg("- Collecting children.\n");
39 * End. What where you expecting?
41 static void end (int sig
)
43 printf("(%d) Signal caught, exiting...\n", getpid());
49 int main (int argc
, char **argv
)
51 int bind_sk
, cmd_sk
, err
, yes
= 1;
52 unsigned short port
= 0;
53 struct sockaddr_in saddr
;
54 struct sigaction my_sa
;
60 port
= (unsigned short) atoi(argv
[1]);
62 /* Fixate root directory */
63 Basedir
= getcwd(NULL
, 0);
65 fatal("Could not retrieve working directory");
66 Basedir_len
= strlen(Basedir
);
67 debug_msg("Working directory is: %s (strlen = %d)\n", Basedir
,
71 sigfillset(&my_sa
.sa_mask
);
72 my_sa
.sa_flags
= SA_RESTART
;
73 my_sa
.sa_handler
= child_finish
;
74 sigaction(SIGCHLD
, &my_sa
, NULL
);
76 my_sa
.sa_flags
= SA_NOMASK
;
77 my_sa
.sa_handler
= end
;
78 sigaction(SIGINT
, &my_sa
, NULL
);
80 /* Connection handling */
81 saddr
.sin_family
= AF_INET
;
82 saddr
.sin_port
= htons(port
> 1024 ? port
: DEFAULT_PORT
);
83 saddr
.sin_addr
.s_addr
= INADDR_ANY
;
85 bind_sk
= socket(PF_INET
, SOCK_STREAM
, 0);
87 fatal("Could not create socket");
89 setsockopt(bind_sk
, SOL_SOCKET
, SO_REUSEADDR
, &yes
, sizeof(yes
));
90 err
= bind(bind_sk
, (struct sockaddr
*) &saddr
, sizeof(saddr
));
92 fatal("Could not bind socket");
94 err
= listen(bind_sk
, 5);
96 fatal("Could not listen at socket");
98 printf("UFTPS listening on port %d (TCP). Use CTRL+C to finish.\n\n",
99 (port
> 1024 ? port
: DEFAULT_PORT
));
100 printf("If you want to use a different port use:\n"
102 "Where port must be between 1025 and 65535.\n", argv
[0]);
105 /* It's nearly impossible, to my knowledge, debug a program that forks.
106 * First try to find the error using the debug_msg() facility. Then, if
107 * you really need to use a debugger, then replace the 0 with a 1 to
108 * compile this code. But remember you won't be able to serve multiple
111 cmd_sk
= accept(bind_sk
, (struct sockaddr
*) &saddr
,
114 fatal("could not open command connection");
116 init_session(cmd_sk
);
121 /* Main loop (accepting connections) */
123 cmd_sk
= accept(bind_sk
, (struct sockaddr
*) &saddr
,
129 fatal("Could not open command connection");
134 init_session(cmd_sk
);