source: TI05-delivery/trunk/src/bbftp-server-3.2.0/bbftpd/bbftpd_signals.c @ 1392

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/trunk/src/bbftp-server-3.2.0/bbftpd/bbftpd_signals.c@1392
Revision 1392, 13.1 KB checked in by spascoe, 13 years ago (diff)

More missing #includes exposed when compiling on easterly.

Line 
1/*
2 * bbftpd/bbftpd_signals.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_signals.c   v 2.0.0 2000/12/14  - Replace files set_signals.c and
27                                          set_father_signals.c
28                    v 2.0.1 2001/04/23  - Correct indentation
29                    v 2.0.2 2001/05/04  - Correct include for RFIO
30                                        - Changes for CASTOR
31                    v 2.1.0 2001/06/01  - Change routines name
32                                        - Correct bbftpd_log level
33
34*****************************************************************************/
35#include <bbftpd.h>
36
37#include <stdio.h>
38
39#include <errno.h>
40#include <signal.h>
41#include <sys/wait.h>
42#include <bbftpd_private_log.h>
43#include <netinet/in.h>
44#include <sys/socket.h>
45#if TIME_WITH_SYS_TIME
46# include <sys/time.h>
47# include <time.h>
48#else
49# if HAVE_SYS_TIME_H
50#  include <sys/time.h>
51# else
52#  include <time.h>
53# endif
54#endif
55#include <utime.h>
56#if HAVE_STRING_H
57# include <string.h>
58#endif
59
60#include <daemon.h>
61#include <daemon_proto.h>
62#include <status.h>
63#include <structures.h>
64
65
66/*
67** For V1 and V2 Protocol
68*/
69extern int  flagsighup;
70extern int  childendinerror ;
71extern int  state ;
72extern int  killdone ;
73extern int  unlinkfile ;
74extern pid_t    fatherpid ;
75/*
76** For V2 protocol
77*/
78extern char *realfilename ;
79extern char *curfilename ;
80extern int  transferoption ;
81extern int  *mychildren ;
82extern int  nbpidchild ;
83extern char lastaccess[9] ;
84extern char lastmodif[9] ;
85extern int  filemode ;
86extern int  castfd ;
87extern struct  timeval  tstart;
88extern my64_t  filesize ;
89extern  char            currentusername[MAXLEN] ;
90
91int bbftpd_checkendchild(int status)
92{
93   
94    if (WEXITSTATUS(status) == 0 ) {
95        if ( WIFSIGNALED(status) == 0 ) {
96            return(0) ;
97        } else {
98            /*
99            ** In order to differenciate signal and ernno we choose
100            ** to return ENOEXEC in case of signal
101            */
102            return(ENOEXEC) ;
103        }
104    } else {
105        return(WEXITSTATUS(status)) ;
106    }             
107}
108
109void bbftpd_sigchld(int sig) 
110{
111    int *pidfree ;
112    int    pid ;
113    int    status ;
114    int    totpid ;
115    int i ;
116    char logmessage[1024] ;
117    int    retcode ;
118    struct utimbuf ftime ;
119    int goon ;
120    /*
121    ** We are going to check if the process generating this
122    ** signal was not already detected as dead. This was causing
123    ** a send of a MSG_OK if all process have been dectected dead
124    ** througn the waitpid routine and the signal was pending.
125    ** If all processes have been detected dead before childendinerror
126    ** to 0, totpid also so we send a reply MSS_OK
127    */
128    totpid = 0 ;
129    pidfree = mychildren ;
130    for ( i=0 ; i< nbpidchild ; i++) {
131        totpid = totpid + *pidfree ;
132        pidfree++ ;
133    }
134    if ( totpid == 0 ) {
135        /*
136        ** All Ended
137        */
138        free_all_var() ;
139        return ;
140    }
141/*
142** Check the status
143*/
144    pidfree = mychildren ;
145    for ( i=0 ; i< nbpidchild; i++) {
146        if ( *pidfree != 0 ) {
147            pid = waitpid(*pidfree,&status,WNOHANG) ;
148            if ( pid == *pidfree ) {
149                /*
150                ** the process has ended
151                */
152                if ( (retcode = bbftpd_checkendchild(status)) != 0 ) {
153                    if ( childendinerror == 0 ) {
154                        childendinerror = 1 ;
155                        bbftpd_log(BBFTPD_ERR,"Child pid %d ends in error status %d",pid,retcode) ;
156                        if ( (unlinkfile == 1) || (unlinkfile == 2) ) {
157                            bbftpd_storeunlink(realfilename) ;
158                        }
159                        if (retcode == 255) {
160                            sprintf(logmessage,"Disk quota excedeed or No Space left on device") ;
161                            reply(MSG_BAD_NO_RETRY,logmessage) ;
162                        } else {
163                            if (retcode ==  ENOEXEC ) {
164                                sprintf(logmessage,"Interrupted by signal") ;
165                            } else {
166                                sprintf(logmessage,"Error on server: %s",strerror(retcode)) ;
167                            }
168                            reply(MSG_BAD,logmessage) ;
169                        }
170                    } else {
171                        bbftpd_log(BBFTPD_ERR,"Child pid %d ends in error",pid) ;
172                    }
173                }
174                *pidfree = 0 ;
175            }
176        }
177        pidfree++ ;
178    }
179    totpid = 0 ;
180    pidfree = mychildren ;
181    for ( i=0 ; i< nbpidchild ; i++) {
182        totpid = totpid + *pidfree ;
183        pidfree++ ;
184    }
185    if ( totpid == 0 && childendinerror == 0 ) {
186        if ((unlinkfile == 1 || unlinkfile == 2 || unlinkfile == 4)) {
187            goon = 0 ;
188            if ( bbftpd_storeclosecastfile(realfilename,logmessage) < 0 ) {
189                bbftpd_log(BBFTPD_ERR,logmessage) ;
190                bbftpd_storeunlink(realfilename) ;
191                reply(MSG_BAD,logmessage) ;
192                goon = 1 ;
193            }
194            if ((goon == 0 ) &&  ((transferoption & TROPT_ACC ) == TROPT_ACC) ) {
195                sscanf(lastaccess,"%08x",&ftime.actime) ;
196                sscanf(lastmodif,"%08x",&ftime.modtime) ;
197                if ( bbftpd_storeutime(realfilename,&ftime,logmessage) < 0 ) {
198                    bbftpd_log(BBFTPD_ERR,logmessage) ;
199                    bbftpd_storeunlink(realfilename) ;
200                    reply(MSG_BAD,logmessage) ;
201                    goon = 1 ;
202                }
203           }
204           if ( (goon == 0 ) && ((transferoption & TROPT_MODE ) == TROPT_MODE) ) {
205                if ( bbftpd_storechmod(realfilename,filemode,logmessage) < 0 ) {
206                    bbftpd_log(BBFTPD_ERR,logmessage) ;
207                    bbftpd_storeunlink(realfilename) ;
208                    reply(MSG_BAD,logmessage) ;
209                    goon = 1 ;
210                }
211            }
212            if ( (goon == 0 ) && ((transferoption & TROPT_TMP ) == TROPT_TMP ) ) {
213                if ( bbftpd_storerename(realfilename,curfilename,logmessage) < 0 ) {
214                    bbftpd_log(BBFTPD_ERR,logmessage) ;
215                    bbftpd_storeunlink(realfilename) ;
216                    reply(MSG_BAD,logmessage) ;
217                    goon = 1 ;
218                }
219            }
220            state = S_LOGGED ;
221            if ( goon == 0 ) reply(MSG_OK,"OK") ;
222            if (unlinkfile == 4) {
223                bbftpd_storeunlink(curfilename) ;
224            } else if  (&tstart) {
225                /* Stats PUT user file bytes_transfered seconds kbytes/s Mbits/s*/
226                float s, bs;
227                struct  timeval tend ,tdiff;
228                (void) gettimeofday(&tend, (struct timezone *)0);
229                tdiff.tv_sec = tend.tv_sec - tstart.tv_sec ;
230                tdiff.tv_usec = tend.tv_usec - tstart.tv_usec;
231                if (tdiff.tv_usec < 0) tdiff.tv_sec--, tdiff.tv_usec += 1000000;
232                s = tdiff.tv_sec + (tdiff.tv_usec / 1000000.);
233 #define nz(x)   ((x) == 0 ? 1 : (x))
234                bs = filesize / nz(s);
235                sprintf(logmessage,"PUT %s %s %" LONG_LONG_FORMAT" %.3g %.3g %.3g", currentusername, curfilename, filesize, s, bs / 1024.0,(8.0*bs) / (1024.0 * 1024.0));
236                bbftpd_log(BBFTPD_NOTICE,logmessage);
237            }
238            free_all_var() ;
239        } else {
240            state = S_LOGGED ;
241            reply(MSG_OK,"OK") ;
242            if  (&tstart) {
243                /* Stats GET user file bytes_transfered seconds kbytes/s Mbits/s*/
244                float s, bs;
245                struct  timeval tend ,tdiff;
246                (void) gettimeofday(&tend, (struct timezone *)0);
247                tdiff.tv_sec = tend.tv_sec - tstart.tv_sec ;
248                tdiff.tv_usec = tend.tv_usec - tstart.tv_usec;
249                if (tdiff.tv_usec < 0) tdiff.tv_sec--, tdiff.tv_usec += 1000000;
250                s = tdiff.tv_sec + (tdiff.tv_usec / 1000000.);
251                bs = filesize / nz(s);
252                sprintf(logmessage,"GET %s %s %" LONG_LONG_FORMAT" %.3g %.3g %.3g", currentusername, curfilename, filesize, s, bs / 1024.0,(8.0*bs) / (1024.0 * 1024.0));
253                bbftpd_log(BBFTPD_NOTICE,logmessage);
254            }
255            free_all_var() ;
256        }
257    } 
258    if ( childendinerror == 1 ) {
259        clean_child() ;
260    }
261    if (totpid == 0 ) {
262        state = S_LOGGED ;
263        unlinkfile = 0 ;
264        killdone = 0 ;
265        childendinerror = 0 ;
266        free_all_var() ;
267    }
268}
269
270void bbftpd_sighup( int sig) 
271{
272    flagsighup = 1 ;
273}
274
275void bbftpd_sigterm(int sig) 
276{
277    if ( fatherpid == getpid() ) {
278        /*
279        ** We are in father
280        */
281        /*
282        ** Unlink the file if we are getting a file
283        */ 
284        if ( unlinkfile == 1 ) unlink(realfilename) ;
285        clean_child() ;
286        exit(0) ; /* BUG porting */
287    } else {
288        exit(EINTR) ;
289    }
290}
291
292int bbftpd_setsignals() 
293{
294    struct    sigaction    sga ;
295   
296    sga.sa_handler = SIG_IGN ;
297    sigemptyset(&(sga.sa_mask));
298    sga.sa_flags = 0   ;
299    if ( sigaction(SIGPIPE,&sga,0) < 0 ) {
300        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGPIPE : %s",strerror(errno)) ;
301        return(-1) ;
302    }
303    sga.sa_handler = bbftpd_sigchld ;
304    sigemptyset(&(sga.sa_mask));
305    sga.sa_flags = 0  ;
306    if ( sigaction(SIGCHLD,&sga,0) < 0 ) {
307        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGCHLD : %s",strerror(errno)) ;
308        return(-1) ;
309    }
310    sga.sa_handler = bbftpd_sighup ;
311    sigemptyset(&(sga.sa_mask));
312    sga.sa_flags = 0  ;
313    if ( sigaction(SIGHUP,&sga,0) < 0 ) {
314        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGHUP : %s",strerror(errno)) ;
315        return(-1) ;
316    }
317    sga.sa_handler = bbftpd_sigterm ;
318    sigemptyset(&(sga.sa_mask));
319    sga.sa_flags = 0  ;
320    if ( sigaction(SIGTERM,&sga,0) < 0 ) {
321        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGTERM : %s",strerror(errno)) ;
322        return(-1) ;
323    }
324    return 0 ;
325}
326int bbftpd_blockallsignals() {
327    struct    sigaction    sga ;
328
329    sga.sa_handler= SIG_IGN ;
330    sigemptyset(&(sga.sa_mask));
331    sga.sa_flags = 0   ;
332    if ( sigaction(SIGABRT,&sga,0) < 0 ) {
333        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGABRT : %s",strerror(errno)) ;
334        return(-1) ;
335    }
336    if ( sigaction(SIGALRM,&sga,0) < 0 ) {
337        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGALRM : %s",strerror(errno)) ;
338        return(-1) ;
339    }
340    if ( sigaction(SIGHUP,&sga,0) < 0 ) {
341        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGHUP : %s",strerror(errno)) ;
342        return(-1) ;
343    }
344    if ( sigaction(SIGINT,&sga,0) < 0 ) {
345        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGINT : %s",strerror(errno)) ;
346        return(-1) ;
347    }
348    if ( sigaction(SIGPIPE,&sga,0) < 0 ) {
349        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGPIPE : %s",strerror(errno)) ;
350        return(-1) ;
351    }
352    if ( sigaction(SIGQUIT,&sga,0) < 0 ) {
353        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGQUIT : %s",strerror(errno)) ;
354        return(-1) ;
355    }
356/*
357**    if ( sigaction(SIGTERM,&sga,0) < 0 ) {
358**        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGTERM : %s",strerror(errno)) ;
359**        return(-1) ;
360**    }
361*/
362    if ( sigaction(SIGUSR1,&sga,0) < 0 ) {
363        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGUSR1 : %s",strerror(errno)) ;
364        return(-1) ;
365    }
366    if ( sigaction(SIGUSR2,&sga,0) < 0 ) {
367        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGUSR2 : %s",strerror(errno)) ;
368        return(-1) ;
369    }
370    if ( sigaction(SIGCHLD,&sga,0) < 0 ) {
371        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGCHLD : %s",strerror(errno)) ;
372        return(-1) ;
373    }
374    if ( sigaction(SIGTSTP,&sga,0) < 0 ) {
375        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGTSTP : %s",strerror(errno)) ;
376        return(-1) ;
377    }
378#ifndef DARWIN
379    if ( sigaction(SIGPOLL,&sga,0) < 0 ) {
380        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGPOLL : %s",strerror(errno)) ;
381        return(-1) ;
382    }
383#endif
384#ifdef SIGPROF          /* BUG porting */
385    if ( sigaction(SIGPROF,&sga,0) < 0 ) {
386        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGPROF : %s",strerror(errno)) ;
387        return(-1) ;
388    }
389#endif
390    if ( sigaction(SIGURG,&sga,0) < 0 ) {
391        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGURG : %s",strerror(errno)) ;
392        return(-1) ;
393    }
394#ifdef SIGVTALRM        /* BUG porting */
395    if ( sigaction(SIGVTALRM,&sga,0) < 0 ) {
396        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGVTALRM : %s",strerror(errno)) ;
397        return(-1) ;
398    }
399#endif
400    return 0 ;
401}
Note: See TracBrowser for help on using the repository browser.