Remove the error message on interrupted accept().
[uftps.git] / main-unix.c
blobd99de266852ce8892d6816b4b3ebb51b3a645475
1 /*
2 * User FTP Server, Share folders over FTP without being root.
3 * Copyright (C) 2008 Isaac Jurado
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option) any later
8 * version.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 * details.
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "uftps.h"
21 #include <sys/socket.h>
22 #include <sys/wait.h>
23 #include <signal.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <stdio.h>
29 struct _SessionScope SS; /* SS --> Session State*/
33 * clid_finish
35 * Reaper function. For "zombies".
37 static void child_finish (int sig)
39 while (waitpid(-1, NULL, WNOHANG) > 0)
40 debug("Collecting children");
45 * end
47 * End. What where you expecting?
49 static void end (int sig)
51 notice("Signal caught, exiting");
52 exit(EXIT_SUCCESS);
57 * Main program.
59 int main (int argc, char **argv)
61 int bind_sk, cmd_sk, e, yes;
62 int port = DEFAULT_PORT;
63 struct sigaction my_sa;
64 struct sockaddr_in sai;
65 socklen_t sai_len = sizeof(struct sockaddr_in);
67 if (argc > 1)
69 port = atoi(argv[1]) & 0x00FFFF;
70 if (port <= 1024)
72 errno = 0;
73 fatal("Invalid port number");
77 /* Signal handling */
78 sigfillset(&my_sa.sa_mask);
79 my_sa.sa_flags = SA_RESTART;
80 my_sa.sa_handler = child_finish;
81 sigaction(SIGCHLD, &my_sa, NULL);
83 sigemptyset(&my_sa.sa_mask);
84 my_sa.sa_flags = 0;
85 my_sa.sa_handler = end;
86 sigaction(SIGINT, &my_sa, NULL);
87 sigaction(SIGTERM, &my_sa, NULL);
89 /* Connection handling, preparing to serve */
90 sai.sin_family = AF_INET;
91 sai.sin_port = htons(port);
92 sai.sin_addr.s_addr = INADDR_ANY;
94 bind_sk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
95 if (bind_sk == -1)
96 fatal("Creating main server socket");
98 yes = 1;
99 setsockopt(bind_sk, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
100 e = bind(bind_sk, (struct sockaddr *) &sai, sai_len);
101 if (e == -1)
102 fatal("Binding main server socket");
104 e = listen(bind_sk, 5);
105 if (e == -1)
106 fatal("Listening at main server socket");
108 notice("UFTPS listening on port %d (TCP)", port);
109 notice("Use CTRL + C to finish");
110 notice("If you want to use a different port, specify it as the only argument in the command line");
112 /* Main server loop (accepting connections) */
113 do {
114 sai_len = sizeof(struct sockaddr_in);
115 cmd_sk = accept(bind_sk, (struct sockaddr *) &sai, &sai_len);
116 if (cmd_sk == -1)
118 if (errno != EINTR)
119 error("Accepting incoming connection");
120 continue;
123 e = fork();
124 if (e == 0)
126 /*** CHILD ***/
127 close(bind_sk);
128 init_session(cmd_sk);
129 command_loop();
131 else
133 /*** PARENT ***/
134 if (e == -1)
135 error("Could not create a child process");
136 close(cmd_sk);
138 } while (1);
140 return EXIT_SUCCESS;