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

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

Initial import of bbftp source

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