source: TI05-delivery/trunk/src/bbftp-server-3.2.0/bbftpd/bbftpd_store_rfio.c @ 1448

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

Implemented two hooks in the bbftpd source that allow
python code to be executed before and afer a fork(). This is needed
to reset python logging and will probably be usefull for other things
in the future.

Line 
1/*
2 * bbftpd/bbftpd_store_rfio.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 bbftpd_store_rfio.c    v 2.0.0 2000/12/19  - Routines creation
26                        v 2.0.1 2001/04/17 - Realy wait STARTCHILDTO
27                                            - Correct indentation
28                                            - Port to IRIX
29                        v 2.0.2 2001/05/04  - Correct include for RFIO
30                                            - Get serrno instead of errno
31                                            - Add debug
32                                            - Support CASTOR
33                        v 2.1.0 2001/05/30  - Correct bbftpd_log level
34                                            - Reorganise routines as in bbftp_
35                        v 2.1.2 2001/11/19  - Fix COS 0 case
36             
37*****************************************************************************/
38#include <bbftpd.h>
39
40#include <errno.h>
41#include <fcntl.h>
42#include <netinet/in.h>
43#include <signal.h>
44#include <bbftpd_private_log.h>
45#include <bbftpd_private_fork.h>
46#include <sys/stat.h>
47#if TIME_WITH_SYS_TIME
48# include <sys/time.h>
49# include <time.h>
50#else
51# if HAVE_SYS_TIME_H
52#  include <sys/time.h>
53# else
54#  include <time.h>
55# endif
56#endif
57#include <sys/types.h>
58#include <unistd.h>
59#include <utime.h>
60#if HAVE_STRING_H
61# include <string.h>
62#endif
63
64#include <common.h>
65#include <daemon.h>
66#include <daemon_proto.h>
67#include <status.h>
68#include <structures.h>
69
70#ifdef WITH_GZIP
71#include <zlib.h>
72#endif
73
74#ifdef WITH_RFIO64
75#include <shift/rfio_api.h>
76#include <shift/serrno.h>
77#else
78#include <shift.h>
79#endif
80
81#ifdef CASTOR
82#include <shift/stage_api.h>
83#endif
84
85extern int  transferoption ;
86extern my64_t  filesize ;
87extern int  requestedstreamnumber ;
88extern int  buffersizeperstream ;
89extern int  maxstreams ;
90extern int  *myports ;
91extern int  *mysockets ;
92extern char *readbuffer ;
93extern char *compbuffer ;
94extern int  *mychildren ;
95extern int  nbpidchild ;
96extern int  unlinkfile ;
97extern int  incontrolsock ;
98extern int  outcontrolsock ;
99extern  int     datato ;
100extern  int     sendcontrolto ;
101extern int  state ;
102extern int childendinerror ;
103extern int flagsighup ;
104extern int mycos ;
105extern int  debug ;
106extern int  castfd ;
107extern char *castfilename ;
108extern struct  timeval  tstart ;
109extern int  protocolversion ;
110extern  char            currentusername[MAXLEN] ;
111
112/*******************************************************************************
113** bbftpd_storeclosecastfile_rfio :                                            *
114**                                                                             *
115**      Routine to chage access time a file                                    *
116**                                                                             *
117**      OUPUT variable :                                                       *
118**          logmessage :  to write the error message in case of error          *
119**                                                                             *
120**      GLOBAL VARIABLE USED :                                                 *                                                                      *
121**                                                                             *
122**      RETURN:                                                                *
123**          -1  Failed                                                         *
124**           0  OK                                                             *
125**                                                                             *
126*******************************************************************************/
127
128int bbftpd_storeclosecastfile_rfio(char *filename,char *logmessage)
129{
130    int     retcode ;
131   
132    if ( castfd > 0 ) {
133        if ( debug ) {
134            fprintf(stdout,"In storeclosecastfile_rfio : rfio_close(castfd) (%d)\n",castfd) ;
135        }
136        if ( ( retcode = rfio_close(castfd) ) < 0 ){
137            sprintf(logmessage,"Error rfio_close on %s : %s",filename,rfio_serror()) ;
138            castfd = -1 ;
139            return -1 ;
140        }
141        castfd = -1 ;
142    }
143    return 0 ;
144}
145/*******************************************************************************
146** bbftpd_storechmod_rfio :                                                    *
147**                                                                             *
148**      Routine to chmod a file                                                *
149**                                                                             *
150**      OUPUT variable :                                                       *
151**          logmessage :  to write the error message in case of error          *
152**                                                                             *
153**      GLOBAL VARIABLE USED :                                                 *                                                                      *
154**          transferoption                   NOT MODIFIED                      *
155**                                                                             *
156**      RETURN:                                                                *
157**          -1  Failed                                                         *
158**           0  OK                                                             *
159**                                                                             *
160*******************************************************************************/
161
162int bbftpd_storechmod_rfio(char *filename,int mode,char *logmessage)
163{
164    int     retcode ;
165   
166    if ( debug ) {
167        fprintf(stdout,"In storechmod_rfio : rfio_chmod(filename,mode) (%s,%d)\n",filename,mode) ;
168    }
169    retcode = rfio_chmod(filename,mode) ;
170    if ( retcode < 0 ) {
171        sprintf(logmessage,"Error chmod on file %s : %s",filename,rfio_serror()) ;
172        return retcode ;
173    }
174    return 0 ;
175}
176
177/*******************************************************************************
178** bbftpd_storerename :                                                        *
179**                                                                             *
180**      Routine to rename a file                                               *
181**                                                                             *
182**      OUPUT variable :                                                       *
183**          logmessage :  to write the error message in case of error          *
184**                                                                             *
185**      GLOBAL VARIABLE USED :                                                 *                                                                      *
186**          transferoption                   NOT MODIFIED                      *
187**                                                                             *
188**      RETURN:                                                                *
189**          -1  Failed                                                         *
190**           0  OK                                                             *
191**                                                                             *
192*******************************************************************************/
193
194int bbftpd_storerename_rfio(char *newfilename,char *oldfilename,char *logmessage)
195{
196   
197    int     retcode ;
198   
199    if ( debug ) {
200        fprintf(stdout,"**In storerename_rfio : rfio_rename(newfilename,oldfilename) (%s,%s)\n",newfilename,oldfilename) ;
201    }
202    retcode = rfio_rename(newfilename,oldfilename) ;
203    if ( retcode < 0 ) {
204        sprintf(logmessage,"Error renaming %s to %s : %s",newfilename,oldfilename,rfio_serror()) ;
205        return retcode ;
206    }
207    return 0 ;
208}
209/*******************************************************************************
210** bbftpd_storeunlink_rfio :                                                   *
211**                                                                             *
212**      Routine to unlink a file                                               *
213**                                                                             *
214**      OUPUT variable :                                                       *
215**          logmessage :  to write the error message in case of error          *
216**                                                                             *
217**      GLOBAL VARIABLE USED :                                                 *                                                                      *
218**                                                                             *
219**      RETURN:                                                                *
220**          -1  Failed                                                         *
221**           0  OK                                                             *
222**                                                                             *
223*******************************************************************************/
224
225int bbftpd_storeunlink_rfio(char *filename)
226{
227#if defined (WITH_RFIO64) && !defined(STANDART_FILE_CALL)
228    struct  stat64    statbuf ;
229#else
230    struct  stat    statbuf ;
231#endif
232
233#ifdef WITH_RFIO64
234    if ( rfio_stat64(filename,&statbuf ) == 0) {
235#else
236    if ( rfio_stat(filename,&statbuf ) == 0 ) {
237#endif
238
239#ifdef CASTOR
240    /*
241    ** We are suppose to fill the castfilename after an open
242    ** and to call this function only when needed
243    */
244    if ( castfd > 0 ) {
245        rfio_close(castfd) ;
246        castfd = -1 ;
247    }
248# ifdef HAVE_STAGECLR_PATH
249    if ( strncmp(filename,"/castor/",8) == 0 ) {
250        if ( debug ) {
251            fprintf(stdout,"**In storeunlink_rfio : stageclr_Path(castfilename) (%s)\n",castfilename) ;
252        }
253        stageclr_Path((u_signed64) STAGE_REMOVEHSM,NULL,castfilename) ;
254    } else {
255        if ( debug ) {
256            fprintf(stdout,"**In storeunlink_rfio (CASTOR case) : rfio_unlink(filename) (%s)\n",filename) ;
257        }
258        rfio_unlink(filename) ;
259    }
260# else
261    if ( debug ) {
262        fprintf(stdout,"**In storeunlink_rfio (CASTOR case) : rfio_unlink(filename) (%s)\n",filename) ;
263    }
264    rfio_unlink(filename) ;
265# endif
266#else
267    if ( debug ) {
268        fprintf(stdout,"**In storeunlink_rfio : rfio_unlink(filename) (%s)\n",filename) ;
269    }
270    rfio_unlink(filename) ;
271#endif
272    }
273    return 0 ;
274}
275/*******************************************************************************
276** bbftpd_storecheckoptions_rfio :                                             *
277**                                                                             *
278**      Routine to check the options parameters                                *
279**                                                                             *
280**      RETURN:                                                                *
281**          -1  Incorrect options                                              *
282**           0  OK                                                             *
283**                                                                             *
284*******************************************************************************/
285
286int bbftpd_storecheckoptions_rfio(char *logmessage)
287{
288    int tmpoptions ;
289   
290    /*
291    ** Check the compatibility with other options
292    */
293    if ((transferoption & TROPT_ACC) == TROPT_ACC) {
294        /*
295        ** RFIO has no fonction to change access and modif time
296        ** till now to have the same behaviour in deamon and client
297        ** do not care
298        */
299    }
300   /*
301    ** Check all known options
302    */
303#ifdef CASTOR
304    /*
305    ** As CASTOR in unable to support a rename discard the TROPT_TMP option
306    */
307    tmpoptions = TROPT_ACC | TROPT_MODE | TROPT_DIR | TROPT_GZIP | TROPT_RFIO | TROPT_RFIO_O ;
308#else
309    tmpoptions = TROPT_TMP | TROPT_ACC | TROPT_MODE | TROPT_DIR | TROPT_GZIP | TROPT_RFIO | TROPT_RFIO_O  ;
310#endif
311    transferoption = transferoption & tmpoptions ;
312    /*
313    ** Check the maxstreams
314    */
315    if ( requestedstreamnumber > maxstreams ) requestedstreamnumber = maxstreams ;
316    return 0 ;
317}       
318/*******************************************************************************
319** bbftpd_storemkdir_rfio :                                                    *
320**                                                                             *
321**      Routine to create a bunch of directory                                 *
322**                                                                             *
323**      INPUT variable :                                                       *
324**          dirname    :  directory to create    NOT MODIFIED                  *
325**          recursif   :  1 recursif             NOT MODIFIED                  *
326**                        0 non recursif                                       *
327**                                                                             *
328**      OUPUT variable :                                                       *
329**          logmessage :  to write the error message in case of error          *
330**                                                                             *
331**      TO FREE before any return : dirpath                                    *
332**                                                                             *
333**      RETURN:                                                                *
334**          -1   Creation failed unrecoverable error                           *
335**           0   OK                                                            *
336**           >0  Creation failed recoverable error                             *
337**                                                                             *
338*******************************************************************************/
339int bbftpd_storemkdir_rfio(char *dirname,char *logmessage,int recursif)
340{
341    char    *dirpath;
342    char    *basedir ;
343    char    *slash ;
344    int     savederrno ;
345#if defined (WITH_RFIO64) && !defined(STANDART_FILE_CALL)
346    struct  stat64    statbuf ;
347#else
348    struct  stat    statbuf ;
349#endif
350    int     k ;
351   
352    /*
353    ** make a copy of dirname for security
354    */
355    if ( (dirpath = (char *) malloc (strlen(dirname)+1) ) == NULL ) {
356        sprintf(logmessage,"Error allocating memory for dirpath : %s",strerror(errno)) ;
357        return 1 ;
358    }
359    strcpy (dirpath, dirname);
360    /*
361    ** Strip trailing slash
362    */
363    strip_trailing_slashes(dirpath) ;
364    slash = dirpath ;
365    if ( recursif == 1 ) {
366        /*
367        ** Recursif, we are going to create all directory
368        */
369        /*
370        ** This is an absolut path, but look if it is a syntax like :
371        **      host:/.....
372        **      /.....
373        */
374        if ( *dirpath == '/' ) {
375            while (*slash == '/') slash++;
376        } else {
377            /*
378            ** find the :
379            */
380            k = 0 ;
381            while (*slash != ':' && k < strlen(dirpath) ) {
382                slash++;
383                k++ ;
384            }
385            if ( k == strlen(dirpath) ) {
386                sprintf(logmessage,"Incorrect directory name : %s",dirpath) ;
387                FREE(dirpath) ;
388                return -1 ;
389            } else {
390                slash++ ;
391                slash++ ;
392            }
393        }
394        while (1) {
395            slash = (char *) strchr (slash, '/');
396            if ( slash == NULL ) break ;
397            basedir = dirpath ;
398            /*
399            ** The mkdir and stat calls below appear to be reversed.
400            ** They are not.  It is important to call mkdir first and then to
401            ** call stat (to distinguish the three cases) only if mkdir fails.
402            ** The alternative to this approach is to `stat' each directory,
403            ** then to call mkdir if it doesn't exist.  But if some other process
404            ** were to create the directory between the stat & mkdir, the mkdir
405            ** would fail with EEXIST.
406            ** We create it with mode = 777 because the umask is set by bbftpd
407            */
408             *slash = '\0';
409            if ( debug ) {
410                fprintf(stdout,"**In storemkdir_rfio : rfio_mkdir(basedir,0777) (%s)\n",basedir) ;
411            }
412            if ( rfio_mkdir (basedir, 0777) ) {
413                if ( serrno != 0 ) {
414                    savederrno = serrno ;
415                } else if ( rfio_errno != 0 ) {
416                    savederrno = rfio_errno ;
417                } else if ( errno != 0 ){
418                    savederrno = errno ;
419                } else {
420                    /*
421                    ** We use EBFONT in case of undescribed error
422                    */
423                    savederrno = 57 ;
424                }
425                if ( debug ) {
426                    fprintf(stdout,"**In storemkdir_rfio : rfio_stat(basedir,&statbuf) (%s)\n",basedir) ;
427                }
428#ifdef WITH_RFIO64
429                if ( rfio_stat64(basedir,&statbuf ) ) {
430#else
431                if ( rfio_stat(basedir,&statbuf ) ) {
432#endif
433                    sprintf(logmessage,"Error creation directory %s (%s)",basedir,rfio_serror()) ; 
434                    /*
435                    ** We tell the client not to retry in the following case (even in waiting
436                    ** WAITRETRYTIME the problem will not be solved) :
437                    **        EACCES        : Search permission denied
438                    **        EDQUOT        : No more quota
439                    **        ENOSPC        : No more space
440                    **        ELOOP        : To many symbolic links on path
441                    **        ENAMETOOLONG: Path argument too long
442                    **        ENOTDIR        : A component in path is not a directory
443                    **        EROFS        : The path prefix resides on a read-only file system.
444                    **        ENOENT      : A component of the path prefix does not exist or is a null pathname.
445                    **        EEXIST      : The named file already exists.
446                    */
447                     if ( savederrno == EACCES ||
448                            savederrno == EDQUOT ||
449                            savederrno == ENOSPC ||
450                            savederrno == ELOOP ||
451                            savederrno == ENAMETOOLONG ||
452                            savederrno == ENOTDIR ||
453                            savederrno == EROFS ||
454                            savederrno == ENOENT ||
455                            savederrno == EEXIST ) {
456                        FREE(dirpath) ;
457                        return -1 ;
458                    } else {
459                        FREE(dirpath) ;
460                        return 1 ;
461                    }
462                } else if ( (statbuf.st_mode & S_IFDIR) != S_IFDIR) {
463                    sprintf(logmessage,"%s exists but is not a directory",basedir) ; 
464                    FREE(dirpath) ;
465                    return -1 ;
466                } else {
467                     /*
468                    ** dirpath already exists and is a directory.
469                    */
470                }               
471            }
472            *slash++ = '/';
473
474            /*
475            ** Avoid unnecessary calls to `stat' when given
476            ** pathnames containing multiple adjacent slashes. 
477            */
478            while (*slash == '/') slash++;
479       }
480    }
481    /*
482    ** We have created all leading directories so let see the last one
483    */
484    basedir = dirpath ;
485    if ( debug ) {
486        fprintf(stdout,"**In storemkdir_rfio : rfio_mkdir(basedir,0777) (%s)\n",basedir) ;
487    }
488    if ( rfio_mkdir (basedir, 0777) ) {
489        if ( serrno != 0 ) {
490            savederrno = serrno ;
491        } else if ( rfio_errno != 0 ) {
492            savederrno = rfio_errno ;
493        } else if ( errno != 0 ){
494            savederrno = errno ;
495        } else {
496            /*
497            ** We use EBFONT in case of undescribed error
498            */
499            savederrno = 57 ;
500        }
501        if ( debug ) {
502            fprintf(stdout,"**In storemkdir_rfio : rfio_stat(basedir,&statbuf) (%s)\n",basedir) ;
503        }
504#ifdef WITH_RFIO64
505        if ( rfio_stat64(basedir,&statbuf ) ) {
506#else
507        if ( rfio_stat(basedir,&statbuf ) ) {
508#endif
509            sprintf(logmessage,"Error creation directory %s (%s)",basedir,rfio_serror()) ; 
510            /*
511            ** We tell the client not to retry in the following case (even in waiting
512            ** WAITRETRYTIME the problem will not be solved) :
513            **        EACCES        : Search permission denied
514            **        EDQUOT        : No more quota
515            **        ENOSPC        : No more space
516            **        ELOOP        : To many symbolic links on path
517            **        ENAMETOOLONG: Path argument too long
518            **        ENOTDIR        : A component in path is not a directory
519            **        EROFS        : The path prefix resides on a read-only file system.
520            **        ENOENT      : A component of the path prefix does not exist or is a null pathname.
521            **        EEXIST      : The named file already exists.
522            */
523             if ( savederrno == EACCES ||
524                    savederrno == EDQUOT ||
525                    savederrno == ENOSPC ||
526                    savederrno == ELOOP ||
527                    savederrno == ENAMETOOLONG ||
528                    savederrno == ENOTDIR ||
529                    savederrno == EROFS ||
530                    savederrno == ENOENT ||
531                    savederrno == EEXIST ) {
532                FREE(dirpath) ;
533                return -1 ;
534            } else {
535                FREE(dirpath) ;
536                return 1 ;
537            }
538        } else if ( (statbuf.st_mode & S_IFDIR) != S_IFDIR) {
539            sprintf(logmessage,"%s exists but is not a directory",basedir) ; 
540            FREE(dirpath) ;
541            return -1 ;
542        } else {
543             /*
544            ** dirpath already exists and is a directory.
545            */
546            FREE(dirpath) ;
547            return 0 ;
548        }
549    }
550    FREE(dirpath) ;
551    return 0 ;
552}
553/*******************************************************************************
554** bbftpd_storecreatefile_rfio :                                               *
555**                                                                             *
556**      Routine to create a file                                               *
557**                                                                             *
558**      OUTPUT variable :                                                      *
559**          logmessage :  to write the error message in case of error          *
560**                                                                             *
561**      GLOBAL VARIABLE USED :                                                 *                                                                      *
562**          transferoption                   NOT MODIFIED                      *
563**          filesize                         NOT MODIFIED                      *
564**                                                                             *
565**      TO FREE before any return : filepath                                   *
566**                                                                             *
567**      RETURN:                                                                *
568**          -1  Transfer failed calling has to close the connection            *
569**           0  OK  (Does not mean the transfer is successfull                 *
570**                                                                             *
571*******************************************************************************/
572
573int bbftpd_storecreatefile_rfio(char *filename, char *logmessage) 
574{
575    char    *filepath ;
576    int     fd ;
577    int     lastslash ;
578    int     savederrno ;
579    int     retcode ;
580#if defined (WITH_RFIO64) && !defined(STANDART_FILE_CALL)
581    off64_t   toseek ;
582    struct  stat64    statbuf ;
583#else
584    off_t   toseek ;
585    struct  stat    statbuf ;
586#endif
587    int         hpss_file = 0;
588   
589    /*
590    ** make a copy of filename for security
591    */
592    if ( (filepath = (char *) malloc (strlen(filename)+1) ) == NULL ) {
593        sprintf(logmessage,"Error allocating memory for filepath : %s",strerror(errno)) ;
594        return 1 ;
595    }
596    strcpy (filepath, filename);
597    /*
598    ** Check if the file exist
599    **      We are going to first see if the directory exist
600    **      and then look at the options
601    **      and then look if the file exist
602    */
603    lastslash = strlen(filepath) - 1 ;
604    while ( lastslash >= 0 && filepath[lastslash] != '/') lastslash-- ;
605    if ( lastslash == -1 ) {
606        /*
607        ** No slash in the path, that means that we have done a chdir
608        ** before so do not care for the directory problem
609        */
610    } else if ( lastslash == 0 ) {
611        /*
612        ** A slash in first position so we suppose the "/" directory
613        ** exist ... nothing to do
614        */
615    } else if ( lastslash == strlen(filepath) - 1 ) {
616        /*
617        ** The filename end with a slash ..... error
618        */
619        sprintf(logmessage,"Filename %s ends with a /",filepath) ;
620        FREE(filepath) ;
621        return -1 ;
622    } else {
623        filepath[lastslash] = '\0';
624        /*
625        ** Check the existence of the directory
626        */
627        if ( debug ) {
628            fprintf(stdout,"**In storecreatefile_rfio : rfio_stat(filepath,&statbuf) (%s)\n",filepath) ;
629        }
630#ifdef WITH_RFIO64
631        if ( rfio_stat64(filepath,&statbuf ) ) {
632#else
633        if ( rfio_stat(filepath,&statbuf ) ) {
634#endif
635            if ( serrno != 0 ) {
636                savederrno = serrno ;
637            } else if ( rfio_errno != 0 ) {
638                savederrno = rfio_errno ;
639            } else if ( errno != 0 ){
640                savederrno = errno ;
641            } else {
642                /*
643                ** We use EBFONT in case of undescribed error
644                */
645                savederrno = 57 ;
646            }
647            /*
648            ** It may be normal to get an error if the directory
649            ** does not exist but some error code must lead
650            ** to the interruption of the transfer:
651            **        EACCES        : Search permission denied
652            **        ELOOP        : To many symbolic links on path
653            **        ENAMETOOLONG: Path argument too long
654            **        ENOTDIR        : A component in path is not a directory
655            */
656            if ( savederrno == EACCES ||
657                savederrno == ELOOP ||
658                savederrno == ENAMETOOLONG ||
659                savederrno == ENOTDIR ) {
660                sprintf(logmessage,"Error stating directory %s : %s ",filepath,rfio_serror()) ;
661                FREE(filepath) ;
662                return -1 ;
663            } else if (savederrno == ENOENT) {
664                /*
665                ** The directory does not exist so check for the TROPT_DIR
666                ** option
667                */
668                if ( (transferoption & TROPT_DIR ) != TROPT_DIR ) {
669                    sprintf(logmessage,"Directory (%s) creation needed but TROPT_DIR not set",filepath) ;
670                    FREE(filepath) ;
671                    return -1 ;
672                } else {
673                    if ( (retcode = bbftpd_storemkdir_rfio(filepath,logmessage,1)) != 0 ) {
674                        FREE(filepath) ;
675                        return retcode ;
676                    }
677                    /* Now check if the new dir is in HPSS */
678#ifdef WITH_RFIO64
679                    if ( rfio_stat64(filepath,&statbuf ) ) {
680#else
681                    if ( rfio_stat(filepath,&statbuf ) ) {
682#endif
683                        sprintf(logmessage,"Error stating directory %s : %s ",filepath,rfio_serror()) ;
684                        FREE(filepath) ;
685                        return -1 ;
686                    }
687                    if (statbuf.st_dev == 0 && statbuf.st_ino == 1) {
688                        hpss_file = 1;
689                        if ( debug ) {
690                                fprintf(stdout,"**In storecreatefile_rfio : HPSS file\n") ;
691                        }
692                    }
693                    filepath[lastslash] = '/';
694                }
695            } else {
696                sprintf(logmessage,"Error stating directory %s : %s ",filepath,rfio_serror()) ;
697                FREE(filepath) ;
698                return 1 ;
699            }
700        } else {
701            /*
702            ** The directory exist, check if it is a directory
703            */
704            if ( (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
705                /*
706                ** OK correct
707                */
708                filepath[lastslash] = '/';
709                                /*
710                                **      check if it is a hpss file
711                                */
712                                if (statbuf.st_dev == 0 && statbuf.st_ino == 1) {
713                                        hpss_file = 1;
714                                        if ( debug ) {
715                                                fprintf(stdout,"**In storecreatefile_rfio : HPSS file\n") ;
716                                        }
717                                }
718            } else {
719                sprintf(logmessage,"%s is a not a directory",filepath) ;
720                FREE(filepath) ;
721                return -1 ;
722            }
723        }
724    }
725    /*
726    ** At this stage all directory exists so check for the file
727    */
728    if ( debug ) {
729        fprintf(stdout,"**In storecreatefile_rfio : rfio_stat(filepath,&statbuf) (%s)\n",filepath) ;
730    }
731#ifdef WITH_RFIO64
732    if ( rfio_stat64(filepath,&statbuf ) < 0 ) {
733#else
734    if ( rfio_stat(filepath,&statbuf ) < 0 ) {
735#endif
736        /*
737        ** It may be normal to get an error if the file
738        ** does not exist but some error code must lead
739        ** to the interruption of the transfer:
740        **        EACCES        : Search permission denied
741        **        ELOOP        : To many symbolic links on path
742        **        ENAMETOOLONG: Path argument too long
743        **        ENOTDIR        : A component in path is not a directory
744        */
745        if ( serrno != 0 ) {
746            savederrno = serrno ;
747        } else if ( rfio_errno != 0 ) {
748            savederrno = rfio_errno ;
749        } else if ( errno != 0 ){
750            savederrno = errno ;
751        } else {
752            /*
753            ** We use EBFONT in case of undescribed error
754            */
755            savederrno = 57 ;
756        }
757        if ( savederrno == EACCES ||
758            savederrno == ELOOP ||
759            savederrno == ENAMETOOLONG ||
760            savederrno == ENOTDIR ) {
761            sprintf(logmessage,"Error stating file %s : %s ",filepath,rfio_serror()) ;
762            FREE(filepath) ;
763            return -1 ;
764        } else if (savederrno == ENOENT) {
765            /*
766            ** That is normal the file does not exist
767            */
768        } else {
769            sprintf(logmessage,"Error stating file %s : %s ",filepath,rfio_serror()) ;
770            FREE(filepath) ;
771            return 1 ;
772        }
773    } else {
774        /*
775        ** The file exists so check if it is a directory
776        */
777        if ( (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
778            sprintf(logmessage,"File %s is a directory",filepath) ;
779            FREE(filepath) ;
780            return -1 ;
781        }
782        /*
783        ** check if it is writable
784        */
785        if ( (statbuf.st_mode & S_IWUSR) != S_IWUSR) {
786            sprintf(logmessage,"File %s is not writable",filepath) ;
787            FREE(filepath) ;
788            return -1 ;
789        }
790        /*
791        ** In order to set correctly the user and group id we
792        ** erase the file first excetp if it is CASTOR
793        */
794#ifndef CASTOR
795        bbftpd_storeunlink_rfio(filepath) ;
796#endif
797    }
798#ifdef CASTOR
799    /*
800    ** Do nothing except if the file length is null
801    */
802    if ( filesize == 0 ) {
803#ifdef WITH_RFIO64
804        if ((fd = rfio_open64(filepath,O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0 ) {
805#else
806        if ((fd = rfio_open(filepath,O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0 ) {
807#endif
808            /*
809            ** Depending on errno we are going to tell the client to
810            ** retry or not
811            */
812            if ( serrno != 0 ) {
813                savederrno = serrno ;
814            } else if ( rfio_errno != 0 ) {
815                savederrno = rfio_errno ;
816            } else if ( errno != 0 ){
817                savederrno = errno ;
818            } else {
819                /*
820                ** We use EBFONT in case of undescribed error
821                */
822                savederrno = 57 ;
823            }
824            sprintf(logmessage,"Error creation file %s : %s ",filepath,rfio_serror()) ;
825            /*
826            ** We tell the client not to retry in the following case (even in waiting
827            ** WAITRETRYTIME the problem will not be solved) :
828            **        EACCES        : Search permission denied
829            **        EDQUOT        : No more quota
830            **        ENOSPC        : No more space
831            **        ELOOP        : To many symbolic links on path
832            **        ENAMETOOLONG: Path argument too long
833            **        ENOTDIR        : A component in path is not a directory
834            */
835            if ( savederrno == EACCES ||
836                    savederrno == EDQUOT ||
837                    savederrno == ENOSPC ||
838                    savederrno == ELOOP ||
839                    savederrno == ENAMETOOLONG ||
840                    savederrno == ENOTDIR ) {
841                    FREE(filepath) ;
842                    return -1 ;
843            } else {
844                FREE(filepath) ;
845                return 1 ;
846            }
847        }
848        if ( debug ) {
849            fprintf(stdout,"**In storecreatefile_rfio : rfio_close(fd) (%d)\n",fd) ;
850        }
851        rfio_close(fd) ;
852        FREE(filepath) ;
853        return 0 ;
854    } else {
855        if ( debug ) {
856            fprintf(stdout,"**In storecreatefile_rfio : I do nothing with Castor (%s)\n",filepath) ;
857        }
858        FREE(filepath) ;
859        return 0 ;
860    }
861#else
862    /*
863    ** We create the file
864    */
865    if ( debug ) {
866        fprintf(stdout,"**In storecreatefile_rfio : rfio_open(filepath) (%s)\n",filepath) ;
867    }
868#ifdef WITH_RFIO64
869    if ((fd = rfio_open64(filepath,O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0 ) {
870#else
871    if ((fd = rfio_open(filepath,O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0 ) {
872#endif
873        /*
874        ** Depending on errno we are going to tell the client to
875        ** retry or not
876        */
877        if ( serrno != 0 ) {
878            savederrno = serrno ;
879        } else if ( rfio_errno != 0 ) {
880            savederrno = rfio_errno ;
881        } else if ( errno != 0 ){
882            savederrno = errno ;
883        } else {
884            /*
885            ** We use EBFONT in case of undescribed error
886            */
887            savederrno = 57 ;
888        }
889        sprintf(logmessage,"Error creation file %s : %s ",filepath,rfio_serror()) ;
890        /*
891        ** We tell the client not to retry in the following case (even in waiting
892        ** WAITRETRYTIME the problem will not be solved) :
893        **        EACCES        : Search permission denied
894        **        EDQUOT        : No more quota
895        **        ENOSPC        : No more space
896        **        ELOOP        : To many symbolic links on path
897        **        ENAMETOOLONG: Path argument too long
898        **        ENOTDIR        : A component in path is not a directory
899        */
900        if ( savederrno == EACCES ||
901                savederrno == EDQUOT ||
902                savederrno == ENOSPC ||
903                savederrno == ELOOP ||
904                savederrno == ENAMETOOLONG ||
905                savederrno == ENOTDIR ) {
906                FREE(filepath) ;
907                return -1 ;
908        } else {
909            FREE(filepath) ;
910            return 1 ;
911        }
912    }
913    if ( mycos >= 0 && hpss_file) {
914        if ( debug ) {
915           fprintf(stdout,"**In storecreatefile_rfio : rfio_setcos(%d,%" LONG_LONG_FORMAT ",%d)\n", fd, filesize, mycos) ;
916        }
917#ifdef WITH_RFIO64
918        rfio_setcos64(fd,filesize,mycos) ;
919#else
920        rfio_setcos(fd,(int)filesize,mycos) ;
921#endif
922    }
923    if ( filesize == 0 ) {
924        char statmessage[1024];
925        if ( debug ) {
926            fprintf(stdout,"**In storecreatefile_rfio : rfio_close(fd) (%d)\n",fd) ;
927        }
928        rfio_close(fd) ;
929        sprintf(statmessage,"PUT %s %s 0 0 0.0 0.0", currentusername, filepath);
930        bbftpd_log(BBFTPD_NOTICE,statmessage);
931        FREE(filepath) ;
932        return 0 ;
933    }
934    /*
935    ** Lseek to set it to the correct size
936    ** We use toseek because filesize is of type my64t and
937    ** call to lseek can be done with off_t which may be
938    ** of length 64 bits or 32 bits
939    */
940/*    toseek = filesize-1 ;
941*    if ( debug ) {
942*        fprintf(stdout,"**In storecreatefile_rfio : rfio_lseek(fd,toseek,SEEK_SET) (%d,%d)\n",fd,toseek) ;
943*    }
944*    if ( rfio_lseek(fd,toseek,SEEK_SET) < 0 ) {
945*        sprintf(logmessage,"Error seeking file %s : %s ",filepath,rfio_serror()) ;
946*        if ( debug ) {
947*            fprintf(stdout,"**In storecreatefile_rfio : rfio_close(fd) (%d)\n",fd) ;
948*        }
949*        rfio_close(fd) ;
950*        bbftpd_storeunlink_rfio(filepath) ;
951*        free(filepath) ;
952*        return 1 ;
953*    }
954*/
955    /*
956    ** Write one byte
957    */
958/*    if ( debug ) {
959*        fprintf(stdout,"**In storecreatefile_rfio : rfio_write(fd,) (%d)\n",fd) ;
960*    }
961*    if ( rfio_write(fd,"\0",1) != 1) {
962*        if ( serrno != 0 ) {
963*            savederrno = serrno ;
964*        } else if ( rfio_errno != 0 ) {
965*            savederrno = rfio_errno ;
966*        } else if ( errno != 0 ){
967*            savederrno = errno ;
968*        } else {
969*/
970            /*
971            ** We use EBFONT in case of undescribed error
972            */
973/*            savederrno = 57 ;
974*        }
975*        sprintf(logmessage,"Error writing file %s : %s ",filepath,rfio_serror()) ;
976*        if ( debug ) {
977*            fprintf(stdout,"**In storecreatefile_rfio : rfio_close(fd) (%d)\n",fd) ;
978*        }
979*        rfio_close(fd) ;
980*        bbftpd_storeunlink_rfio(filepath) ;
981*/
982        /*
983        ** We tell the client not to retry in the following case (even in waiting
984        ** WAITRETRYTIME the problem will not be solved) :
985        **        EDQUOT        : No more quota
986        **        ENOSPC        : No space on device
987        */
988/*        if ( savederrno == EDQUOT ||
989*                savederrno == ENOSPC ) {
990*            free(filepath) ;
991*            return -1 ;
992*        } else {
993*            free(filepath) ;
994*            return 1 ;
995*        }
996*    }
997*/
998    /*
999    ** And close the file
1000    */
1001    if ( debug ) {
1002        fprintf(stdout,"**In storecreatefile_rfio : rfio_close(fd) (%d)\n",fd) ;
1003    }
1004    if ( rfio_close(fd) < 0 ) {
1005        if ( serrno != 0 ) {
1006            savederrno = serrno ;
1007        } else if ( rfio_errno != 0 ) {
1008            savederrno = rfio_errno ;
1009        } else if ( errno != 0 ){
1010            savederrno = errno ;
1011        } else {
1012            /*
1013            ** We use EBFONT in case of undescribed error
1014            */
1015            savederrno = 57 ;
1016        }
1017        sprintf(logmessage,"Error closing file %s : %s ",filepath,rfio_serror()) ;
1018        bbftpd_storeunlink_rfio(filepath) ;
1019        if ( savederrno == ENOSPC ) {
1020            FREE(filepath) ;
1021            return -1 ;
1022        } else {
1023            FREE(filepath) ;
1024            return 1 ;
1025        }
1026    }
1027    FREE(filepath) ;
1028    return 0 ;
1029#endif
1030}
1031/*******************************************************************************
1032** bbftpd_storetransferfile_rfio :                                             *
1033**                                                                             *
1034**      Routine to transfer a file                                             *
1035**                                                                             *
1036**      INPUT variable :                                                       *
1037**          filename    :  file to create    NOT MODIFIED                      *
1038**                                                                             *
1039**      OUTPUT variable :                                                      *
1040**          logmessage :  to write the error message in case of error          *
1041**                                                                             *
1042**      GLOBAL VARIABLE USED :                                                 *                                                                      *
1043**                                                                             *
1044**      RETURN:                                                                *
1045**          -1  transfer failed unrecoverable error                            *
1046**           0  Keep the connection open (does not mean that the file has been *
1047**                successfully transfered)                                     *
1048**          >0  Recoverable error but calling has the cleaning to do           *
1049**                                                                             *
1050*******************************************************************************/
1051 
1052int bbftpd_storetransferfile_rfio(char *filename,int simulation,char *logmessage) 
1053{
1054#if defined (WITH_RFIO64) && !defined(STANDART_FILE_CALL)
1055    off64_t   nbperchild ;
1056    off64_t   nbtoget;
1057    off64_t   startpoint ;
1058    off64_t   nbget ;
1059    off64_t   toseek ;
1060    struct stat64 statbuf ;
1061#else
1062    off_t   nbperchild ;
1063    off_t   nbtoget;
1064    off_t   startpoint ;
1065    off_t   nbget ;
1066    off_t   toseek ;
1067    struct stat statbuf ;
1068#endif
1069#ifdef WITH_GZIP
1070    uLong    buflen ;
1071    uLong    bufcomplen ;
1072#endif
1073    int     lentowrite;
1074    int     lenwrited;
1075    int     datatoreceive;
1076    int     dataonone;
1077
1078    int     *pidfree ;
1079    int     *sockfree ; /* for PASV mode only */
1080    int     *portnumber ;
1081    int     i ;
1082    int     recsock ;
1083    int        retcode ;
1084    int        compressionon ;
1085    int     nfds ; 
1086    fd_set    selectmask ;
1087    struct timeval    wait_timer;
1088    int     fd ;
1089    my64_t    toprint64 ;
1090    struct mess_compress *msg_compress ;
1091    struct message *msg ;
1092    int     waitedtime ;
1093
1094    /*
1095    ** Set castfd to -1 to differentiate case
1096    */
1097    castfd = -1 ;
1098    if ( protocolversion <= 2 ) { /* Active mode */
1099      portnumber = myports ;
1100    } else {
1101      sockfree = mysockets ;
1102    }
1103    nbperchild = filesize/requestedstreamnumber ;
1104    pidfree = mychildren ;
1105    nbpidchild = 0 ;
1106    /*
1107    ** unlike is set to one in case of death of a children by a kill -9
1108    ** In this case the child is unable to unlink the file so that
1109    ** has to be done by the father
1110    */
1111    childendinerror = 0 ; /* No child so no error */
1112#ifdef CASTOR
1113    /*
1114    ** CASTOR has a very strange behaviour, you cannot open twice the
1115    ** same file with the castor name in write mode !!!. So if the
1116    ** name starts by /castor the father is going to open the file
1117    ** in write mode, look at the real file name and children will
1118    ** use this real file name. The close will be done by the
1119    ** father
1120    ** CARE HAS TO BE TAKEN FOR THIS CLOSE BECAUSE THIS MAY LEAD
1121    ** TO OPEN DESCRIPTOR IN FATHER
1122    */
1123    if ( debug ) {
1124        fprintf(stdout,"**In bbftpd_storetransferfile_rfio : rfio_open(filename) (%s)\n",filename) ;
1125    }
1126#ifdef WITH_RFIO64
1127    if ((castfd = rfio_open64(filename,O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0 ) {
1128#else
1129    if ((castfd = rfio_open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0 ) {
1130#endif
1131        /*
1132        ** Depending on errno we are going to tell the client to
1133        ** retry or not
1134        */
1135        if ( serrno != 0 ) {
1136            i = serrno ;
1137        } else if ( rfio_errno != 0 ) {
1138            i = rfio_errno ;
1139        } else if ( errno != 0 ){
1140            i = errno ;
1141        } else {
1142            /*
1143            ** We use EBFONT in case of undescribed error
1144            */
1145            i = 57 ;
1146        }
1147        sprintf(logmessage,"Error creation file %s : %s ",filename,rfio_serror()) ;
1148        bbftpd_log(BBFTPD_ERR,"Error creation file %s : %s ",filename,rfio_serror()) ;
1149        /*
1150        ** We tell the client not to retry in the following case (even in waiting
1151        ** WAITRETRYTIME the problem will not be solved) :
1152        **        EACCES        : Search permission denied
1153        **        EDQUOT        : No more quota
1154        **        ENOSPC        : No more space
1155        **        ELOOP        : To many symbolic links on path
1156        **        ENAMETOOLONG: Path argument too long
1157        **        ENOTDIR        : A component in path is not a directory
1158        */
1159        if ( i == EACCES ||
1160                i == EDQUOT ||
1161                i == ENOSPC ||
1162                i == ELOOP ||
1163                i == ENAMETOOLONG ||
1164                i == ENOTDIR ) {
1165            reply(MSG_BAD_NO_RETRY,logmessage) ;
1166            return -1 ;
1167        } else {
1168            reply(MSG_BAD,logmessage) ;
1169            return 1 ;
1170        }
1171    }
1172    if ( mycos >= 0 ) {
1173#ifdef WITH_RFIO64
1174        if ( rfio_stat64(filename,&statbuf) < 0 ) {
1175#else
1176        if ( rfio_stat(filename,&statbuf) < 0 ) {
1177#endif                 
1178            /*
1179            ** If the file does not exist that means that another
1180            ** child has detroyed it
1181            */ 
1182            if ( serrno != 0 ) {
1183                i = serrno ;
1184            } else if ( rfio_errno != 0 ) {
1185                i = rfio_errno ;
1186            } else if ( errno != 0 ){
1187                i = errno ;
1188            } else {
1189                /*
1190                ** We use EBFONT in case of undescribed error
1191                */
1192                i = 57 ;
1193            }
1194            bbftpd_log(BBFTPD_ERR,"Error stating file %s : %s ",filename,rfio_serror()) ;
1195            close(recsock) ;
1196            exit(i) ;
1197        }
1198    }
1199    if ( strncmp(filename,"/castor/",8) == 0 ) {
1200        if ( debug ) {
1201            fprintf(stdout,"**In storetransferile_rfio : Case of a /castor/ file\n") ;
1202            fprintf(stdout,"**In storetransferfile_rfio : HsmIf_FindPhysicalPath(filename,&castfilename) (%s)\n",filename) ;
1203        }
1204        if (  rfio_HsmIf_FindPhysicalPath(filename,&castfilename) == 0 ) {
1205            bbftpd_log(BBFTPD_ERR,"Error finding castor physical path %s : %s ",filename,rfio_serror()) ;
1206            sprintf(logmessage,"Error finding castor physical path %s : %s ",filename,rfio_serror()) ;
1207            if ( debug ) {
1208                fprintf(stdout,"**In storecreatefile_rfio : rfio_close(castfd) (%s)\n",fd) ;
1209            }
1210            rfio_close(castfd) ;
1211            castfd = -1 ;
1212            /*
1213            ** Within the actual state of CASTOR I am unable to unlink the file
1214            ** if I have not the physical name
1215            */
1216            reply(MSG_BAD,logmessage) ;
1217            return 1 ;
1218        }
1219    } else {
1220        strcpy(castfilename,filename) ;
1221    }
1222    /*
1223    ** Write one byte
1224    */
1225    if ( debug ) {
1226        fprintf(stdout,"**In storetransferfile_rfio : rfio_write(castfd,) (%d)\n",castfd) ;
1227    }
1228    if ( rfio_write(castfd,"\0",1) != 1) {
1229        if ( serrno != 0 ) {
1230            i = serrno ;
1231        } else if ( rfio_errno != 0 ) {
1232            i = rfio_errno ;
1233        } else if ( errno != 0 ){
1234            i = errno ;
1235        } else {
1236            /*
1237            ** We use EBFONT in case of undescribed error
1238            */
1239            i = 57 ;
1240        }
1241        sprintf(logmessage,"Error writing file %s : %s ",filename,rfio_serror()) ;
1242        bbftpd_log(BBFTPD_ERR,"Error writing file %s : %s ",filename,rfio_serror()) ;
1243        if ( debug ) {
1244            fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%d)\n",fd) ;
1245        }
1246        bbftpd_storeunlink_rfio(filename) ;
1247        /*
1248        ** We tell the client not to retry in the following case (even in waiting
1249        ** WAITRETRYTIME the problem will not be solved) :
1250        **        EDQUOT        : No more quota
1251        **        ENOSPC        : No space on device
1252        */
1253        if ( i == EDQUOT ||
1254                i == ENOSPC ) {
1255            reply(MSG_BAD_NO_RETRY,logmessage) ;
1256            return -1 ;
1257        } else {
1258            reply(MSG_BAD,logmessage) ;
1259            return 1 ;
1260        }
1261    }
1262    /*
1263    ** We do not need to look at the PhysicalPath, that
1264    ** has already been done by storecreatefile
1265    */
1266    if ( debug ) {
1267        fprintf(stdout,"**In storetransferfile_rfio : Real castor file name : %s\n",castfilename) ;
1268        fflush(stdout) ;
1269    }
1270#endif
1271    unlinkfile = 2 ;
1272    for (i = 1 ; i <= requestedstreamnumber ; i++) {
1273        if ( i == requestedstreamnumber ) {
1274            startpoint = (i-1)*nbperchild;
1275            nbtoget = filesize-(nbperchild*(requestedstreamnumber-1)) ;
1276        } else {
1277            startpoint = (i-1)*nbperchild;
1278            nbtoget = nbperchild ;
1279        }
1280        if (protocolversion <= 2) { /* ACTIVE MODE */
1281          /*
1282          ** Now create the socket to send
1283          */
1284          recsock = 0 ;
1285          while (recsock == 0 ) {
1286            recsock = bbftpd_createreceivesocket(*portnumber,logmessage) ;
1287          }
1288          if ( recsock < 0 ) {
1289            /*
1290            ** We set childendinerror to 1 in order to prevent the father
1291            ** to send a BAD message which can desynchronize the client and the
1292            ** server (We need only one error message)
1293            ** Bug discovered by amlutz on 2000/03/11
1294            */
1295            if ( childendinerror == 0 ) {
1296                childendinerror = 1 ;
1297                reply(MSG_BAD,logmessage) ;
1298            }
1299            clean_child() ;
1300            return 1 ;
1301          }
1302          portnumber++ ;
1303        } else { /* PASSIVE MODE */
1304          recsock = *sockfree ;
1305          sockfree++ ;
1306        }
1307        /*
1308        ** Set flagsighup to zero in order to be able in child
1309        ** not to wait STARTCHILDTO if signal was sent before
1310        ** entering select. (Seen on Linux with one child)
1311        */
1312        flagsighup = 0 ;
1313        if ( ( retcode = bbftpd_fork() ) == 0 ) {
1314            int     ns ;
1315            /*
1316            ** We are in child
1317            */
1318            /*
1319            ** Pause until father send a SIGHUP in order to prevent
1320            ** child to die before father has started all children
1321            */
1322            waitedtime = 0 ;
1323            while (flagsighup == 0 && waitedtime < STARTCHILDTO) {
1324                int nfds2 ;
1325                                wait_timer.tv_sec  = 1 ;
1326                wait_timer.tv_usec = 0 ;
1327                nfds2 = sysconf(_SC_OPEN_MAX) ;
1328                select(nfds2,0,0,0,&wait_timer) ;
1329                waitedtime = waitedtime + 1 ;
1330            }
1331            bbftpd_log(BBFTPD_DEBUG,"Child %d starting",getpid()) ;
1332            /*
1333            ** Close all unnecessary stuff
1334            */
1335            close(incontrolsock) ;
1336            close(outcontrolsock) ;
1337            if ( debug != 0 ) {
1338                sprintf(logmessage,"/tmp/bbftp.rfio.trace.level.%d.%d",debug,getpid()) ;
1339                (void) freopen(logmessage,"w",stdout) ;
1340                fprintf(stdout,"**Starting rfio trace for child number %d (pid=%d)\n",i,getpid()) ;
1341            }
1342            /*
1343            ** Check if file exist
1344            */
1345            if ( debug ) {
1346#ifdef CASTOR
1347                fprintf(stdout,"**In storetransferfile_rfio : rfio_stat(castfilename,&statbuf) (%s)\n",castfilename) ;
1348#else
1349                fprintf(stdout,"**In storetransferfile_rfio : rfio_stat(filename,&statbuf) (%s)\n",filename) ;
1350#endif
1351            }
1352#ifdef CASTOR
1353# ifdef WITH_RFIO64
1354            if ( rfio_stat64(castfilename,&statbuf) < 0 ) {
1355# else
1356            if ( rfio_stat(castfilename,&statbuf) < 0 ) {
1357# endif
1358#else
1359# ifdef WITH_RFIO64
1360            if ( rfio_stat64(filename,&statbuf) < 0 ) {
1361# else
1362            if ( rfio_stat(filename,&statbuf) < 0 ) {
1363# endif
1364#endif
1365                /*
1366                ** If the file does not exist that means that another
1367                ** child has detroyed it
1368                */ 
1369                if ( serrno != 0 ) {
1370                    i = serrno ;
1371                } else if ( rfio_errno != 0 ) {
1372                    i = rfio_errno ;
1373                } else if ( errno != 0 ){
1374                    i = errno ;
1375                } else {
1376                    /*
1377                    ** We use EBFONT in case of undescribed error
1378                    */
1379                    i = 57 ;
1380                }
1381#ifdef CASTOR
1382                bbftpd_log(BBFTPD_ERR,"Error stating file %s : %s ",castfilename,rfio_serror()) ;
1383#else
1384                bbftpd_log(BBFTPD_ERR,"Error stating file %s : %s ",filename,rfio_serror()) ;
1385#endif
1386                close(recsock) ;
1387                exit(i) ;
1388            }
1389            /*
1390            ** Open and seek to position
1391            */
1392            if ( debug ) {
1393#ifdef CASTOR
1394                fprintf(stdout,"**In storetransferfile_rfio : rfio_open(castfilename,O_RDWR) (%s)\n",castfilename) ;
1395#else
1396                fprintf(stdout,"**In storetransferfile_rfio : rfio_open(filename,O_RDWR) (%s)\n",filename) ;
1397#endif
1398            }
1399#ifdef CASTOR
1400# ifdef WITH_RFIO64
1401            if ((fd = rfio_open64(castfilename,O_RDWR)) < 0 ) {
1402# else
1403            if ((fd = rfio_open(castfilename,O_RDWR)) < 0 ) {
1404# endif
1405#else
1406# ifdef WITH_RFIO64
1407            if ((fd = rfio_open64(filename,O_RDWR)) < 0 ) {
1408# else
1409            if ((fd = rfio_open(filename,O_RDWR)) < 0 ) {
1410# endif
1411#endif
1412                if ( serrno != 0 ) {
1413                    i = serrno ;
1414                } else if ( rfio_errno != 0 ) {
1415                    i = rfio_errno ;
1416                } else if ( errno != 0 ){
1417                    i = errno ;
1418                } else {
1419                    /*
1420                    ** We use EBFONT in case of undescribed error
1421                    */
1422                    i = 57 ;
1423                }
1424#ifdef CASTOR
1425                bbftpd_log(BBFTPD_ERR,"Error opening file %s : %s ",castfilename,rfio_serror()) ;
1426#else
1427                bbftpd_log(BBFTPD_ERR,"Error opening file %s : %s ",filename,rfio_serror()) ;
1428#endif
1429                /*
1430                ** At this point a non recoverable error is
1431                **        EDQUOT        : No more quota
1432                **        ENOSPC        : No more space
1433                */
1434                if ( i == EDQUOT ||
1435                        i == ENOSPC ) {
1436                    close(recsock) ;
1437                    exit(255) ;
1438                } else {
1439                    close(recsock) ;
1440                    exit(i) ;
1441                }
1442            }
1443            if ( debug ) {
1444                fprintf(stdout,"**In storetransferfile_rfio : rfio_lseek(fd,startpoint,SEEK_SET) (%d,%d)\n",fd,startpoint) ;
1445            }
1446#ifdef WITH_RFIO64
1447            if ( rfio_lseek64(fd,startpoint,SEEK_SET) < 0 ) {
1448#else
1449            if ( rfio_lseek(fd,startpoint,SEEK_SET) < 0 ) {
1450#endif
1451                if ( serrno != 0 ) {
1452                    i = serrno ;
1453                } else if ( rfio_errno != 0 ) {
1454                    i = rfio_errno ;
1455                } else if ( errno != 0 ){
1456                    i = errno ;
1457                } else {
1458                    /*
1459                    ** We use EBFONT in case of undescribed error
1460                    */
1461                    i = 57 ;
1462                }
1463                bbftpd_log(BBFTPD_ERR,"error seeking file : %s",rfio_serror()) ;
1464                if ( debug ) {
1465                    fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%s)\n",fd) ;
1466                }
1467                rfio_close(fd) ;
1468                close(recsock) ;
1469                exit(i)  ;
1470            }
1471            if ( protocolversion >= 3 ) {
1472              if ( (ns = accept(recsock,0,0) ) < 0 ) {
1473                i = errno ;
1474                rfio_close(fd) ;
1475                bbftpd_log(BBFTPD_ERR,"Error accept socket : %s",strerror(errno)) ;
1476                close(recsock) ;
1477                exit(i)  ;
1478              }
1479                          close(recsock) ;
1480                        } else {
1481                          ns = recsock ;
1482                        }
1483             /*
1484            ** start the reading loop
1485            ** Handle the simulation mode
1486            */
1487            if (!simulation) {
1488              nbget = 0 ;
1489              while ( nbget < nbtoget) {
1490                if ( (transferoption & TROPT_GZIP ) == TROPT_GZIP ) {
1491                    /*
1492                    ** Receive the header first
1493                    */
1494                    if (readmessage(ns,readbuffer,COMPMESSLEN,datato) < 0 ) {
1495                        bbftpd_log(BBFTPD_ERR,"Error reading compression header") ;
1496                        if ( debug ) {
1497                            fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%s)\n",fd) ;
1498                        }
1499                        rfio_close(fd) ;
1500                        i = ETIMEDOUT ;
1501                        exit(i) ;
1502                    }
1503                    msg_compress = ( struct mess_compress *) readbuffer ;
1504#ifndef WORDS_BIGENDIAN
1505                    msg_compress->datalen = ntohl(msg_compress->datalen) ;
1506#endif
1507                    if ( msg_compress->code == DATA_COMPRESS) {
1508                        compressionon = 1 ;
1509                    } else {
1510                        compressionon = 0 ;
1511                    }
1512                    datatoreceive = msg_compress->datalen ;
1513                } else {
1514                    /*
1515                    ** No compression just adjust the length to receive
1516                    */
1517                    if (buffersizeperstream*1024  <= nbtoget-nbget ) {
1518                        datatoreceive =  buffersizeperstream*1024 ;
1519                    } else {
1520                        datatoreceive = nbtoget-nbget ;
1521                    }
1522                }
1523                /*
1524                ** Start the data collection
1525                */
1526                dataonone = 0 ;
1527                while ( dataonone < datatoreceive ) {
1528                    nfds = sysconf(_SC_OPEN_MAX) ;
1529                    FD_ZERO(&selectmask) ;
1530                    FD_SET(ns,&selectmask) ;
1531                    wait_timer.tv_sec  = datato ;
1532                    wait_timer.tv_usec = 0 ;
1533                    if ( (retcode = select(nfds,&selectmask,0,0,&wait_timer) ) == -1 ) {
1534                        /*
1535                        ** Select error
1536                        */
1537                        i = errno ;
1538                        bbftpd_log(BBFTPD_ERR,"Error select while receiving : %s",strerror(errno)) ;
1539                        if ( debug ) {
1540                            fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%s)\n",fd) ;
1541                        }
1542                        rfio_close(fd) ;
1543                        close(ns) ;
1544                        exit(i) ;
1545                    } else if ( retcode == 0 ) {
1546                        bbftpd_log(BBFTPD_ERR,"Time out while receiving") ;
1547                        if ( debug ) {
1548                            fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%s)\n",fd) ;
1549                        }
1550                        rfio_close(fd) ;
1551                        i=ETIMEDOUT ;
1552                        close(ns) ;
1553                        exit(i) ;
1554                    } else {
1555                        retcode = recv(ns,&readbuffer[dataonone],datatoreceive-dataonone,0) ;
1556                        if ( retcode < 0 ) {
1557                            i = errno ;
1558                            bbftpd_log(BBFTPD_ERR,"Error while receiving : %s",strerror(errno)) ;
1559                            if ( debug ) {
1560                                fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%s)\n",fd) ;
1561                            }
1562                            rfio_close(fd) ;
1563                            close(ns) ;
1564                            exit(i) ;
1565                        } else if ( retcode == 0 ) {
1566                            i = ECONNRESET ;
1567                            bbftpd_log(BBFTPD_ERR,"Connexion breaks") ;
1568                            if ( debug ) {
1569                                fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%s)\n",fd) ;
1570                            }
1571                            rfio_close(fd) ;
1572                            close(ns) ;
1573                            exit(i) ;
1574                        } else {
1575                            dataonone = dataonone + retcode ;
1576                        }
1577                    }
1578                }
1579                /*
1580                ** We have received all data needed
1581                */
1582#ifdef WITH_GZIP
1583                if ( (transferoption & TROPT_GZIP ) == TROPT_GZIP ) {
1584                    if ( compressionon == 1 ) {
1585                        bufcomplen = buffersizeperstream*1024 ;
1586                        buflen = dataonone ;
1587                        retcode = uncompress((Bytef *) compbuffer, &bufcomplen, (Bytef *) readbuffer, buflen) ;
1588                        if ( retcode != 0 ) {
1589                            i = EILSEQ ;
1590                            bbftpd_log(BBFTPD_ERR,"Error while decompressing %d ",retcode) ;
1591                            if ( debug ) {
1592                                fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%s)\n",fd) ;
1593                            }
1594                            rfio_close(fd) ;
1595                            close(ns) ;
1596                            exit(i) ;
1597                        }
1598                        memcpy(readbuffer,compbuffer,buffersizeperstream*1024) ;
1599                        lentowrite = bufcomplen ;
1600                    } else {
1601                        lentowrite = dataonone ;
1602                    }
1603                } else {
1604                    lentowrite = dataonone ;
1605                }
1606#else
1607                lentowrite = dataonone ;
1608#endif
1609                /*
1610                ** Write it to the file
1611                */
1612                lenwrited = 0 ;
1613                while ( lenwrited < lentowrite ) {
1614                    if ( debug ) {
1615                        fprintf(stdout,"**In storetransferfile_rfio : rfio_write(fd,&readbuffer[lenwrited],lentowrite-lenwrited) (%d,add,%d)\n",fd,lentowrite-lenwrited) ;
1616                    }
1617                    if ( (retcode = rfio_write(fd,&readbuffer[lenwrited],lentowrite-lenwrited)) < 0 ) {
1618                        if ( serrno != 0 ) {
1619                            i = serrno ;
1620                        } else if ( rfio_errno != 0 ) {
1621                            i = rfio_errno ;
1622                        } else if ( errno != 0 ){
1623                            i = errno ;
1624                        } else {
1625                            /*
1626                            ** We use EBFONT in case of undescribed error
1627                            */
1628                            i = 57 ;
1629                        }
1630                        bbftpd_log(BBFTPD_ERR,"error writing file : %s",rfio_serror()) ;
1631                        if ( debug ) {
1632                            fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%s)\n",fd) ;
1633                        }
1634                        rfio_close(fd) ;
1635                        if ( i == EDQUOT ||
1636                                i == ENOSPC ) {
1637                            close(ns) ;
1638                            exit(255) ;
1639                        } else {
1640                            close(ns) ;
1641                            exit(i) ;
1642                        }
1643                    } 
1644                    lenwrited = lenwrited + retcode ;
1645                }
1646                nbget = nbget+lenwrited ;
1647              }
1648              /*
1649              ** All data have been received so send the ACK message
1650              */
1651              msg = (struct message *) readbuffer ;
1652              msg->code = MSG_ACK ;
1653              msg->msglen = 0 ;
1654              if ( writemessage(ns,readbuffer,MINMESSLEN,sendcontrolto) < 0 ) {
1655                if ( debug ) {
1656                    fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%s)\n",fd) ;
1657                }
1658                rfio_close(fd) ;
1659                bbftpd_log(BBFTPD_ERR,"Error sending ACK ") ;
1660                close(ns) ;
1661                exit(ETIMEDOUT) ;
1662              }
1663              toprint64 = nbget ;
1664              bbftpd_log(BBFTPD_DEBUG,"Child received %" LONG_LONG_FORMAT " bytes ; end correct ",toprint64) ;
1665              if ( debug ) {
1666                fprintf(stdout,"**In storetransferfile_rfio : rfio_close(fd) (%s)\n",fd) ;
1667              }
1668            }
1669            rfio_close(fd) ;
1670            close(ns) ;
1671            exit(0) ;
1672        } else {
1673            /*
1674            ** We are in father
1675            */
1676            if ( retcode == -1 ) {
1677                /*
1678                ** Fork failed ...
1679                */
1680                bbftpd_log(BBFTPD_ERR,"fork failed : %s",strerror(errno)) ;
1681                bbftpd_storeunlink_rfio(filename) ;
1682                sprintf(logmessage,"fork failed : %s ",strerror(errno)) ;
1683                if ( childendinerror == 0 ) {
1684                    childendinerror = 1 ;
1685                    reply(MSG_BAD,logmessage) ;
1686                }
1687                clean_child() ;
1688                return 1 ;
1689            } else {
1690                *pidfree++ = retcode ;
1691                nbpidchild++ ;
1692                close(recsock) ;
1693            }
1694        }
1695    }
1696    /*
1697    ** Set the state before starting children because if the file was
1698    ** small the child has ended before state was setup to correct value
1699    */
1700    state = S_RECEIVING ;
1701    /*
1702    ** Start all children
1703    */
1704    pidfree = mychildren ;
1705    for (i = 0 ; i<nbpidchild ; i++) {
1706        if ( *pidfree != 0 ) {
1707            kill(*pidfree,SIGHUP) ;
1708        }
1709       pidfree++ ;
1710    }
1711    if (simulation) {
1712       /*
1713       ** set unlinkfile = 4 in order to delete the file after
1714       ** the simulated transfer
1715       */
1716       unlinkfile = 4 ;
1717    }
1718    (void) gettimeofday(&tstart, (struct timezone *)0);
1719    return 0 ;
1720}
Note: See TracBrowser for help on using the repository browser.