source: TI05-delivery/trunk/src/bbftp-server-3.2.0/bbftpd/signals_routines.c @ 1328

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

I've created a bbftpd log facility to replace syslog.
At present it allows you to log messages to a file in addition
to syslog. This should help testing on other machines.

Line 
1/*
2 * bbftpd/signals_routines.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 signals_routines.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 
31*****************************************************************************/
32#include <bbftpd.h>
33
34#include <errno.h>
35#include <signal.h>
36#include <sys/wait.h>
37#include <bbftpd_log.h>
38#include <netinet/in.h>
39#include <sys/socket.h>
40#include <utime.h>
41#if HAVE_STRING_H
42# include <string.h>
43#endif
44
45#include <daemon.h>
46#include <daemon_proto.h>
47#include <status.h>
48#include <structures.h>
49
50/*#ifdef RFIO
51**#include <shift.h>
52**#endif
53*/
54/*
55** For V1 Protocol
56*/
57extern int  pid_child[MAXPORT] ;
58extern char currentfilename[MAXLENFILE];
59/*
60** For V1 and V2 Protocol
61*/
62extern int  flagsighup;
63extern int  childendinerror ;
64extern int  state ;
65extern int  killdone ;
66extern int  unlinkfile ;
67extern pid_t    fatherpid ;
68/*
69** For V2 protocol
70*/
71extern char *realfilename ;
72extern char *curfilename ;
73extern int  transferoption ;
74extern int  *mychildren ;
75extern int  nbpidchild ;
76extern char lastaccess[9] ;
77extern char lastmodif[9] ;
78extern int  filemode ;
79
80int checkendchild(status)
81    int status ;
82{
83   
84    if (WEXITSTATUS(status) == 0 ) {
85        if ( WIFSIGNALED(status) == 0 ) {
86            return(0) ;
87        } else {
88            /*
89            ** In order to differenciate signal and ernno we choose
90            ** to return ENOEXEC in case of signal
91            */
92            return(ENOEXEC) ;
93        }
94    } else {
95        return(WEXITSTATUS(status)) ;
96    }             
97}
98
99void in_sigchld_v1(sig) 
100int        sig ;
101{
102    int    pid ;
103    int    status ;
104    int    totpid ;
105    int i ;
106    char logmessage[256] ;
107    int    retcode ;
108   
109    /*
110    ** We are going to check if the process generating this
111    ** signal was not already detected as dead. This was causing
112    ** a send of a MSG_OK if all process have been dectected dead
113    ** througn the waitpid routine and the signal was pending.
114    ** If all processes have been detected dead before childendinerror
115    ** to 0, totpid also so we send a reply MSS_OK
116    */
117    totpid = 0 ;
118    for ( i=0 ; i< MAXPORT; i++) {
119        totpid = totpid + pid_child[i] ;
120    }
121    if ( totpid == 0 ) {
122        /*
123        ** All Ended
124        */
125        return ;
126    }
127    totpid = 0 ;
128/*
129** Check the status
130*/
131    for ( i=0 ; i< MAXPORT; i++) {
132        if ( pid_child[i] != 0 ) {
133            pid = waitpid(pid_child[i],&status,WNOHANG) ;
134            if ( pid == pid_child[i] ) {
135                /*
136                ** the process has ended
137                */
138                if ( (retcode = checkendchild(status)) != 0 ) {
139                    if ( childendinerror == 0 ) {
140                        childendinerror = 1 ;
141                        bbftpd_log(BBFTPD_ERR,"Child pid %d ends in error status %d",pid,retcode) ;
142                        if ( unlinkfile == 1 ) unlink(currentfilename) ;
143                        if (retcode == 255) {
144                            sprintf(logmessage,"Disk quota excedeed or No Space left on device") ;
145                            reply(MSG_BAD_NO_RETRY,logmessage) ;
146                        } else {
147                            if (retcode ==  ENOEXEC ) {
148                                sprintf(logmessage,"Interrupted by signal") ;
149                            } else {
150                                sprintf(logmessage,"%s",strerror(retcode)) ;
151                            }
152                            reply(MSG_BAD,logmessage) ;
153                        }
154                    } else {
155                        bbftpd_log(BBFTPD_ERR,"Child pid %d ends in error",pid) ;
156                    }
157                }
158                pid_child[i] = 0 ;
159            }   
160        }
161    }
162    for ( i=0 ; i< MAXPORT; i++) {
163        totpid = totpid + pid_child[i] ;
164    }
165    if ( totpid == 0 && childendinerror == 0 ) {
166        state = S_LOGGED ;
167        reply(MSG_OK,"OK") ;
168    } 
169    if ( childendinerror == 1 ) {
170        clean_child() ;
171    }
172    if (totpid == 0 ) {
173        state = S_LOGGED ;
174        unlinkfile = 0 ;
175        killdone = 0 ;
176        childendinerror = 0 ;
177    }
178}
179
180void in_sighup_v1(sig) 
181int        sig ;
182{
183    flagsighup = 1 ;
184}
185
186
187void in_sigterm_v1(sig) 
188int        sig ;
189{
190    if ( fatherpid == getpid() ) {
191        /*
192        ** We are in father
193        */
194        /*
195        ** Unlink the file if we are getting a file
196        */ 
197        if ( unlinkfile == 1 ) unlink(currentfilename) ;
198        clean_child() ;
199        exit(0) ;       /* BUG porting */
200    } else {
201        exit(EINTR) ;
202    }
203}
204
205
206int set_signals_v1() {
207    struct    sigaction    sga ;
208   
209    sga.sa_handler = SIG_IGN ;
210    sigemptyset(&(sga.sa_mask));
211    sga.sa_flags = 0   ;
212    if ( sigaction(SIGPIPE,&sga,0) < 0 ) {
213        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGPIPE : %s",strerror(errno)) ;
214        return(-1) ;
215    }
216    sga.sa_handler = in_sigchld_v1 ;
217    sigemptyset(&(sga.sa_mask));
218    sga.sa_flags = 0  ;
219    if ( sigaction(SIGCHLD,&sga,0) < 0 ) {
220        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGCHLD : %s",strerror(errno)) ;
221        return(-1) ;
222    }
223    sga.sa_handler = in_sighup_v1 ;
224    sigemptyset(&(sga.sa_mask));
225    sga.sa_flags = 0  ;
226    if ( sigaction(SIGHUP,&sga,0) < 0 ) {
227        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGHUP : %s",strerror(errno)) ;
228        return(-1) ;
229    }
230    sga.sa_handler = in_sigterm_v1 ;
231    sigemptyset(&(sga.sa_mask));
232    sga.sa_flags = 0  ;
233    if ( sigaction(SIGTERM,&sga,0) < 0 ) {
234        bbftpd_log(BBFTPD_ERR,"Error sigaction SIGTERM : %s",strerror(errno)) ;
235        return(-1) ;
236    }
237    return 0 ;
238}
239
Note: See TracBrowser for help on using the repository browser.