/*
 * bbftpc/bbftp_mget.c
 * Copyright (C) 1999, 2000, 2001, 2002 IN2P3, CNRS
 * bbftp@in2p3.fr
 * http://doc.in2p3.fr/bbftp
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */ 

/****************************************************************************

  
  
 bbftp_mget.c  v 2.0.0  2001/03/26  - Complete rewriting for version 2.0.0
               v 2.0.1  2001/04/19  - Correct indentation 


*****************************************************************************/
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

#include <bbftp.h>
#include <client.h>
#include <client_proto.h>
#include <common.h>
#include <structures.h>

extern  int     verbose ;
extern  int     timestamp ;
extern  int     transferoption  ; 
extern  char    *curfilename ;
extern  char    *realfilename;
extern  int     resfd ;
extern  int     state ;
extern  int     globaltrymax;
extern  int     myexitcode;
extern  int     connectionisbroken ;

int bbftp_mget(char *remotefile,char *localdir, int  *errcode)
{
    char    logmessage[1024] ;
    int     retcode ;
    char    *filelist ;
    int     filelistlen ;
    char    *tmpfile, *tmpchar, *slash ;
    int     nbtry ;
    
    if ( verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,">> COMMAND : mget %s %s\n",remotefile,localdir) ;
    /*
    ** First look at the local directory
    */
    if ( !strcmp(localdir,"./")) {
        /*
        ** Test if it is a local RFIO 
        */
#if defined(WITH_RFIO) || defined(WITH_RFIO64)
        if ( (transferoption & TROPT_RFIO_O) == TROPT_RFIO_O ) {
            printmessage(stderr,CASE_ERROR,26,timestamp,"Incorrect command : local rfio and localdir equal ./ are imcompatible in mget\n") ;
            *errcode = 26 ;
            return  BB_RET_FT_NR ;
        }
#endif
    } else {
        /*
        ** Check if local dir is a directory
        */
        if ( (retcode = bbftp_retrcheckdir(localdir,logmessage,errcode)) < 0 ) {
            printmessage(stderr,CASE_ERROR,*errcode,timestamp,"%s\n",logmessage) ;
            return BB_RET_FT_NR ;
        } else if ( retcode > 0 ) {
            printmessage(stderr,CASE_ERROR,*errcode,timestamp,"%s\n",logmessage) ;
            return BB_RET_ERROR ;
        }
    }
    filelist = NULL ;
    filelistlen = 0 ;
    if ( (retcode = bbftp_list(remotefile,&filelist,&filelistlen,errcode) ) != BB_RET_OK) {
        if (verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,"<< FAILED\n") ;
        return retcode ;
    }
    if ( filelistlen == 0 ) {
        if (verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,"<< OK\n") ;
        return BB_RET_OK ;
    }
    tmpfile = filelist ;
    tmpchar = NULL ;
    while (filelistlen > 0 ) {
        /*
        ** The file list is under the form : 
        **      full remote file name \0
        **      two char \0
        **          first char is 'l' if file is a link blank if not
        **          second char is  'u' if link is on a unexisting file
        **                          'd' if it is a directory
        **                          'f' if it is a regular file
        */
        tmpchar = tmpfile + strlen(tmpfile) + 1 ;
        filelistlen = filelistlen - strlen(tmpfile) - 1 - strlen(tmpchar) - 1;
        if ( tmpchar[1] == 'u' ) {
            tmpfile = tmpchar + strlen(tmpchar) + 1 ;
        } else if ( tmpchar[1] == 'd') {
            tmpfile = tmpchar + strlen(tmpchar) + 1 ;
        } else {
            /*
            ** Find the last slash in remote file
            */
            slash = tmpfile + strlen(tmpfile) ;
            while ( *slash != '/' && slash != tmpfile ) slash-- ;
            if ( *slash == '/' ) slash++ ;
            for ( nbtry = 1 ; nbtry <= globaltrymax ; nbtry++ ) {
                /*
                ** malloc space for curfilename and realfilename
                */
                if ( (curfilename = (char *) malloc (strlen(localdir)+strlen(slash)+2) ) == NULL ) {
                    printmessage(stderr,CASE_ERROR,35,timestamp,"Error allocating memory for %s : %s\n","curfilename",strerror(errno)) ;
                    *errcode = 35 ;
                    free(*filelist) ;
                    return BB_RET_ERROR ;
                }
                if ( (realfilename = (char *) malloc (strlen(localdir)+strlen(slash)+30)) == NULL ) {
                    printmessage(stderr,CASE_ERROR,35,timestamp,"Error allocating memory for %s : %s\n","realfilename",strerror(errno)) ;
                    *errcode = 35 ;
                    free(curfilename) ;
                    free(*filelist) ;
                    curfilename=NULL ;
                    return BB_RET_ERROR ;
                }
                sprintf(curfilename,"%s/%s",localdir,slash) ;
                if ( (transferoption & TROPT_TMP) == TROPT_TMP ) {
			char hostname[10 + 1];
			if (gethostname(hostname, sizeof(hostname)) < 0) {
				hostname[0] = '\0';
			} else {
				hostname[sizeof(hostname) - 1] = '\0';
			}
#ifdef CASTOR
                    if ( (transferoption & TROPT_RFIO_O) == TROPT_RFIO_O ) {
                        sprintf(realfilename,"%s",curfilename) ;
                    } else {
                        sprintf(realfilename,"%s.bbftp.tmp.%s.%d",curfilename,hostname,getpid()) ;
                    }
#else                         
                    sprintf(realfilename,"%s.bbftp.tmp.%s.%d",curfilename,hostname,getpid()) ;
#endif
                } else {
                    sprintf(realfilename,"%s",curfilename) ;
                }
                /*
                ** check if the last try was not disconnected
                */
                if ( connectionisbroken == 1 ) {
                    reconnecttoserver() ;
                    connectionisbroken = 0 ;
                }
                retcode = bbftp_get(tmpfile,errcode) ;
                state = 0 ;
                if ( retcode == BB_RET_FT_NR ) {
                    /*
                    ** Fatal error no retry and connection is not broken
                    */
                    break ;
                } else if ( retcode == BB_RET_FT_NR_CONN_BROKEN ) {
                    /*
                    ** Fatal error no retry and connection is broken
                    */
                    connectionisbroken = 1 ;
                    break ;
                } else if ( retcode == BB_RET_OK ) {
                    /*
                    ** Success , no retry
                    */                    
                    break ;
                } else if ( retcode == BB_RET_CONN_BROKEN ) {
                    /*
                    ** Retry needed with a new connection
                    */
                    if ( nbtry != globaltrymax ) {
                        sleep(WAITRETRYTIME) ;
                        reconnecttoserver() ;
                    } else {
                        /*
                        ** In case of broken connection and max retry reached
                        ** indicate to the next transfer that the connection
                        ** is broken
                        */
                        connectionisbroken = 1 ;
                    }
                } else {
                    /*
                    ** retcode > 0 means retry on this transfer
                    */
                    if ( nbtry != globaltrymax ) {
                        sleep(WAITRETRYTIME) ;
                    }
                }
            }
            if ( retcode != BB_RET_OK && nbtry == globaltrymax+1) {
                myexitcode = *errcode ;
                if ( resfd < 0 ) {
                    if (!verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,"get %s %s/%s FAILED\n",tmpfile,localdir,slash)        ;
                } else {
                    write(resfd,"get ",4) ;
                    write(resfd,tmpfile,strlen(tmpfile)) ;
                    write(resfd," ",1) ;
                    write(resfd,localdir,strlen(localdir)) ;                
                    write(resfd,"/",1) ;
                    write(resfd,slash,strlen(slash)) ;                
                    write(resfd," FAILED\n",8) ;
                }
            } else if ( retcode == BB_RET_OK) {        
                if ( resfd < 0 ) {
                    if (!verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,"get %s %s/%s OK\n",tmpfile,localdir,slash)        ;
                } else {
                    write(resfd,"get ",4) ;
                    write(resfd,tmpfile,strlen(tmpfile)) ;
                    write(resfd," ",1) ;
                    write(resfd,localdir,strlen(localdir)) ;                
                    write(resfd,"/",1) ;
                    write(resfd,slash,strlen(slash)) ;                
                    write(resfd," OK\n",4) ;
                }    
            } else {
                myexitcode = *errcode ;
                if ( resfd < 0 ) {
                    if (!verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,"get %s %s/%s FAILED\n",tmpfile,localdir,slash)        ;
                } else {
                    write(resfd,"get ",4) ;
                    write(resfd,tmpfile,strlen(tmpfile)) ;
                    write(resfd," ",1) ;
                    write(resfd,localdir,strlen(localdir)) ;                
                    write(resfd,"/",1) ;
                    write(resfd,slash,strlen(slash)) ;                
                    write(resfd," FAILED\n",8) ;
                }
            } 
            tmpfile = tmpchar + strlen(tmpchar) + 1 ;
        }
    }
    if (verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,"<< OK\n") ;
    free(filelist) ;
    return BB_RET_OK ;
    
}


syntax highlighted by Code2HTML, v. 0.9.1