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

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

Eliminated all "implicit declaration" warnings from "python setup.py
build"

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