/*
* 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