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

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

Initial import of bbftp source

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