1 | /* |
---|
2 | * bbftpd/bbftpd_daemon.c |
---|
3 | * Copyright (C) 1999, 2000, 2001, 2002 IN2P3, CNRS |
---|
4 | * bbftp@in2p3.fr |
---|
5 | * http://doc.in2p3.fr/bbftp |
---|
6 | * |
---|
7 | * This program is free software; you can redistribute it and/or |
---|
8 | * modify it under the terms of the GNU General Public License |
---|
9 | * as published by the Free Software Foundation; either version 2 |
---|
10 | * of the License, or any later version. |
---|
11 | * |
---|
12 | * This program is distributed in the hope that it will be useful, |
---|
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
15 | * GNU General Public License for more details. |
---|
16 | * |
---|
17 | * You should have received a copy of the GNU General Public License |
---|
18 | * along with this program; if not, write to the Free Software |
---|
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
---|
20 | */ |
---|
21 | |
---|
22 | /**************************************************************************** |
---|
23 | |
---|
24 | |
---|
25 | |
---|
26 | bbftpd_daemon.c v 0.0.0 1999/11/24 |
---|
27 | v 1.3.0 2000/03/16 |
---|
28 | v 1.6.1 2000/03/30 - Use sysconf instead of OPEN_MAX |
---|
29 | v 1.8.4 2000/04/21 - Seed the randoma generator |
---|
30 | v 1.8.7 2000/05/24 - Include version.h |
---|
31 | v 1.8.10 2000/08/11 - Portage to Linux |
---|
32 | v 1.9.3 2000/10/12 - Define the socket first to be able |
---|
33 | to give information to the user |
---|
34 | v 1.9.4 2000/10/16 - Supress %m |
---|
35 | v 2.0.0 2000/12/13 - Supress be_daemon and controlsock |
---|
36 | as global parameters |
---|
37 | - Add parameters incontrolsock and |
---|
38 | outcontrolsock for bbftp v2 |
---|
39 | v 2.0.1 2001/04/23 - Correct indentation |
---|
40 | v 2.0.2 2001/05/04 - Correct include for RFIO |
---|
41 | v 2.1.0 2001/06/11 - Change file name |
---|
42 | |
---|
43 | *****************************************************************************/ |
---|
44 | #include <bbftpd.h> |
---|
45 | |
---|
46 | #include <netdb.h> |
---|
47 | #include <netinet/in.h> |
---|
48 | #include <netinet/tcp.h> |
---|
49 | #include <stdio.h> |
---|
50 | #include <syslog.h> |
---|
51 | #include <sys/socket.h> |
---|
52 | #if TIME_WITH_SYS_TIME |
---|
53 | # include <sys/time.h> |
---|
54 | # include <time.h> |
---|
55 | #else |
---|
56 | # if HAVE_SYS_TIME_H |
---|
57 | # include <sys/time.h> |
---|
58 | # else |
---|
59 | # include <time.h> |
---|
60 | # endif |
---|
61 | #endif |
---|
62 | #include <unistd.h> |
---|
63 | #include <utime.h> |
---|
64 | #if HAVE_STRING_H |
---|
65 | # include <string.h> |
---|
66 | #endif |
---|
67 | |
---|
68 | #include <common.h> |
---|
69 | #include <daemon.h> |
---|
70 | #include <daemon_proto.h> |
---|
71 | #include <version.h> |
---|
72 | #include <openssl/err.h> |
---|
73 | #include <openssl/rand.h> |
---|
74 | /* |
---|
75 | ** Common variables for BBFTP protocole version 1 and 2 |
---|
76 | */ |
---|
77 | extern int newcontrolport ; |
---|
78 | extern char daemonchar[50] ; |
---|
79 | /* |
---|
80 | ** Variables for BBFTP protocole version 1 |
---|
81 | */ |
---|
82 | extern int msgsock ; |
---|
83 | /* |
---|
84 | ** Variables for BBFTP protocole version 2 |
---|
85 | */ |
---|
86 | extern int incontrolsock ; |
---|
87 | extern int outcontrolsock ; |
---|
88 | |
---|
89 | #ifdef NDG_PYTHON_EMBED |
---|
90 | int do_daemon(int argc, char **argv, char **envp) |
---|
91 | #else |
---|
92 | void do_daemon(int argc,char **argv,char **envp) |
---|
93 | #endif |
---|
94 | { |
---|
95 | |
---|
96 | int prpg ; |
---|
97 | int i ; |
---|
98 | int retcode ; |
---|
99 | int controlsock ; |
---|
100 | struct sockaddr_in server; |
---|
101 | int on = 1; |
---|
102 | int nfds ; |
---|
103 | int pid; |
---|
104 | |
---|
105 | char buffrand[NBITSINKEY] ; |
---|
106 | struct timeval tp ; |
---|
107 | unsigned int seed ; |
---|
108 | |
---|
109 | controlsock = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ; |
---|
110 | if ( controlsock < 0 ) { |
---|
111 | syslog(BBFTPD_ERR, "Cannot create socket to listen on: %s",strerror(errno)); |
---|
112 | fprintf(stderr,"Cannot create socket to listen on: %s\n",strerror(errno)) ; |
---|
113 | exit(1) ; |
---|
114 | } |
---|
115 | if ( setsockopt(controlsock,SOL_SOCKET, SO_REUSEADDR,(char *)&on,sizeof(on)) < 0 ) { |
---|
116 | syslog(BBFTPD_ERR,"Cannot set SO_REUSEADDR on control socket : %s",strerror(errno)) ; |
---|
117 | fprintf(stderr,"Cannot set SO_REUSEADDR on control socket : %s\n ",strerror(errno)) ; |
---|
118 | exit(1) ; |
---|
119 | } |
---|
120 | server.sin_family = AF_INET ; |
---|
121 | server.sin_addr.s_addr = INADDR_ANY ; |
---|
122 | server.sin_port = htons(newcontrolport); |
---|
123 | if ( bind (controlsock,(struct sockaddr *) &server, sizeof(server) ) < 0 ) { |
---|
124 | syslog(BBFTPD_ERR,"Error binding control socket : %s",strerror(errno)) ; |
---|
125 | fprintf(stderr,"Error binding control socket : %s\n ",strerror(errno)) ; |
---|
126 | exit(1) ; |
---|
127 | } |
---|
128 | if ( listen(controlsock,100) < 0 ) { |
---|
129 | syslog(BBFTPD_ERR,"Error listening control socket : %s",strerror(errno)) ; |
---|
130 | fprintf(stderr,"Error listening control socket : %s\n ",strerror(errno)) ; |
---|
131 | exit(1) ; |
---|
132 | } |
---|
133 | /* Fork - so I'm not the owner of the process group any more */ |
---|
134 | retcode = fork(); |
---|
135 | if (retcode < 0) { |
---|
136 | syslog(BBFTPD_ERR, "Cannot fork %s",strerror(errno)); |
---|
137 | exit(1); |
---|
138 | } |
---|
139 | #ifdef NDG_PYTHON_EMBED |
---|
140 | /* Return the daemon's PID */ |
---|
141 | if (retcode > 0) return retcode; |
---|
142 | #else |
---|
143 | /* No need for the parent any more */ |
---|
144 | if (retcode > 0) _exit(0); |
---|
145 | #endif |
---|
146 | prpg = 0 ; |
---|
147 | prpg = setsid () ; /* disassoiciate from control terminal */ |
---|
148 | if ( prpg < 0 ) { |
---|
149 | syslog(BBFTPD_ERR,"Cannot daemonise: %s",strerror(errno)) ; |
---|
150 | exit(1) ; |
---|
151 | } |
---|
152 | /* Close off all file descriptors and reopen syslog */ |
---|
153 | |
---|
154 | nfds = sysconf(_SC_OPEN_MAX) ; |
---|
155 | |
---|
156 | closelog(); |
---|
157 | for (i = 0; i <= nfds; i++) { |
---|
158 | if ( i != controlsock) close(i); |
---|
159 | } |
---|
160 | openlog(daemonchar, LOG_PID | LOG_NDELAY, BBFTPD_FACILITY); |
---|
161 | |
---|
162 | /* log PID in /var/run/bbftpd.pid */ |
---|
163 | { |
---|
164 | FILE *f; |
---|
165 | if ((f = fopen("/var/run/bbftpd.pid", "w")) != NULL) { |
---|
166 | fprintf(f, "%d", getpid()); |
---|
167 | fclose(f); |
---|
168 | } |
---|
169 | } |
---|
170 | |
---|
171 | /* junk stderr */ |
---|
172 | (void) freopen("/dev/null", "w", stderr); |
---|
173 | |
---|
174 | syslog(BBFTPD_DEBUG,"Starting bbftpd in background mode") ; |
---|
175 | if ( bbftpd_blockallsignals() < 0 ) { |
---|
176 | exit(1) ; |
---|
177 | } |
---|
178 | /* |
---|
179 | ** Load the error message from the crypto lib |
---|
180 | */ |
---|
181 | ERR_load_crypto_strings() ; |
---|
182 | /* |
---|
183 | ** Initialize the buffrand buffer which is giong to be used to initialize the |
---|
184 | ** random generator |
---|
185 | */ |
---|
186 | /* |
---|
187 | ** Take the usec to initialize the random session |
---|
188 | */ |
---|
189 | gettimeofday(&tp,NULL) ; |
---|
190 | seed = tp.tv_usec ; |
---|
191 | srandom(seed) ; |
---|
192 | for (i=0; i < sizeof(buffrand) ; i++) { |
---|
193 | buffrand[i] = random() ; |
---|
194 | } |
---|
195 | /* |
---|
196 | ** Initialize the random generator |
---|
197 | */ |
---|
198 | RAND_seed(buffrand,NBITSINKEY) ; |
---|
199 | while (1) { |
---|
200 | |
---|
201 | msgsock = accept(controlsock, 0, 0); |
---|
202 | if (msgsock < 0) { |
---|
203 | syslog(BBFTPD_ERR, "Accept failed: %s",strerror(errno)); |
---|
204 | sleep(1); |
---|
205 | continue; |
---|
206 | } |
---|
207 | /* Fork off a handler */ |
---|
208 | pid = fork(); |
---|
209 | if (pid < 0) { |
---|
210 | syslog(BBFTPD_ERR, "failed to fork: %s",strerror(errno)); |
---|
211 | sleep(1); |
---|
212 | continue; |
---|
213 | } |
---|
214 | if (pid == 0) { |
---|
215 | /* I am that forked off child */ |
---|
216 | closelog(); |
---|
217 | /* Make sure that stdin/stdout are the new socket */ |
---|
218 | /* Only parent needs controlsock */ |
---|
219 | if (controlsock != 0 && controlsock != 1) |
---|
220 | close(controlsock); |
---|
221 | openlog(daemonchar, LOG_PID | LOG_NDELAY, BBFTPD_FACILITY); |
---|
222 | incontrolsock = msgsock ; |
---|
223 | outcontrolsock = msgsock ; |
---|
224 | #ifdef NDG_PYTHON_EMBED |
---|
225 | return 0; |
---|
226 | #else |
---|
227 | return; |
---|
228 | #endif |
---|
229 | |
---|
230 | } |
---|
231 | |
---|
232 | /* I am the parent */ |
---|
233 | close(msgsock); |
---|
234 | |
---|
235 | } |
---|
236 | } |
---|
237 | |
---|