source: TI05-delivery/trunk/src/bbftp-client-3.2.0/bbftpc/bbftp.c @ 1390

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/trunk/src/bbftp-client-3.2.0/bbftpc/bbftp.c@1390
Revision 1390, 51.6 KB checked in by spascoe, 14 years ago (diff)

Eliminated many socket related compile time warnings. These
were due to missing #include statements in the bbftp source.

MOST test cases now succeed on callisto! cross-platform stability
is looking more optimistic :-)

Line 
1/*
2 * bbftpc/bbftp.c
3 * Copyright (C) 1999, 2000, 2001, 2002 IN2P3, CNRS
4 * bbftp@in2p3.fr
5 * http://doc.in2p3.fr/bbftp
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */ 
21
22/****************************************************************************
23
24
25 
26 
27 bbftp.c  v 2.0.0  2001/03/01   - Complete rewriting for version 2.0.0
28          v 2.0.1  2001/04/19   - Correct indentation
29                                - Verify if -s is present on shhremotecmd
30                                  and add it if not (in order to fit v 1.9.4-tja1
31                                  behaviour)
32          v 2.1.0 2001/05/21    - Add debug
33                                - Add -m option to have special output
34                                - Set -v before all options
35                                - Correct case where the last line in control
36                                  file has no CR
37          v 2.1.2 2001/11/19    - Fix COS 0 case
38          v 2.2.0 2001/10/03    - Add certificate authentication mode
39
40*****************************************************************************/
41#include <bbftp.h>
42
43#include <stdlib.h>
44
45#include <errno.h>
46#include <fcntl.h>
47#include <netdb.h>
48#include <sys/socket.h>
49#include <netinet/in.h>
50#include <arpa/inet.h>
51#include <pwd.h>
52#include <stdio.h>
53#include <sys/stat.h>
54#include <sys/types.h>
55#include <unistd.h>
56#if TIME_WITH_SYS_TIME
57# include <sys/time.h>
58# include <time.h>
59#else
60# if HAVE_SYS_TIME_H
61#  include <sys/time.h>
62# else
63#  include <time.h>
64# endif
65#endif
66#if HAVE_STRING_H
67# include <string.h>
68#endif
69
70#include <client.h>
71#include <client_proto.h>
72#include <common.h>
73#include <config.h>
74#include <structures.h>
75#include <version.h>
76
77#ifdef WITH_SSL
78#include <openssl/rsa.h>
79#endif
80
81#ifdef WITH_GZIP
82# include <zlib.h>
83#endif
84
85#define SETTOZERO    0
86#define SETTOONE     1
87
88#define SSHREMOTECMD "bbftpd -s"
89#define SSHCMD "ssh -q"
90
91#ifdef PRIVATE_AUTH
92#define OPTIONS "qbcde:f:i:l:mno:p:P:r:R:tu:vVw:WD::"
93#else
94#define OPTIONS "qbcde:E:f:g:i:I:l:L:mno:p:r:R:sStu:vVw:WD::"
95#endif
96/*
97#endif
98*/
99
100int     state   = SETTOZERO ;
101/*
102** timestamp:
103**      Every message on standart error and standart output are
104**      timestamped
105*/
106int     timestamp = SETTOZERO ;
107/*
108** protocolmin:
109**      Minimum protocol supportted
110*/
111int     protocolmin = 2 ; 
112int     protocolmax = 3 ; 
113int     protocol ;
114/*
115** debug:
116**      Set to one to print more debugging information
117*/
118int     debug = SETTOZERO ;
119/*
120** verbose:
121**      Set to one to print  information
122*/
123int     verbose = SETTOZERO ;
124/*
125** warning:
126**      Set to one to print warning to stderr
127*/
128int     warning = SETTOZERO ;
129/*
130** statoutput:
131**      Set to one for special output
132*/
133int     statoutput = SETTOZERO ;
134/*
135** globaltrymax:
136**      Number of try in case or recoverable error
137*/
138int     globaltrymax = NBTRYMAX ;
139/*
140** newcontrolport:
141**      Control port to be used
142*/
143int     newcontrolport = CONTROLPORT ;
144/*
145** usessh:
146**      Set to one when using ssh to start the remote daemon
147*/
148int     usessh = SETTOZERO ;
149/*
150** sshbatchmode:
151**      This is set to non-zero if running in batch mode (that is, password
152**      and passphrase queries are not allowed).
153*/
154int     sshbatchmode  = SETTOZERO ;
155/*
156** sshchildpid:
157**      To keep the ssh child pid
158*/
159int     sshchildpid   = SETTOZERO ;
160/*
161** For ssh
162*/
163char    *sshidentityfile = NULL ;
164char    *sshremotecmd = NULL ;
165char    *sshcmd = NULL ;
166/*
167** usecert:
168**              Set to one if using certificate authentifaction
169*/
170int             usecert = SETTOZERO ;
171/*
172** useprivate:
173**      Set to one if using private authentication
174*/
175int     useprivate = SETTOZERO ;
176/*
177** privatestr:
178**      Pointer to a private string used for private authentication
179**
180*/
181char    *privatestr = NULL ;
182/*
183** hisctladdr:
184**      the remote address
185*/
186struct sockaddr_in hisctladdr ;
187/*
188** myctladdr:
189**      the local address
190*/
191struct sockaddr_in myctladdr ;
192/*
193** bbftprc:
194**      Where to store the bbftprc file
195*/
196char    *bbftprc = NULL ;
197/*
198** Variable defining the local options :
199**
200** localcos:
201**      Value of the local class of service (in case of RFIO ability)
202**
203** localumask:
204**      Local umask taken by the umask command at start and
205**      modified by the setlocalumask command
206**
207** localrfio:
208**      set to one when using rfio for local files
209**
210*/
211int     localumask ;
212#if defined(WITH_RFIO) || defined(WITH_RFIO64)
213int     localcos  = SETTOZERO ;
214#endif
215
216char *newcmd = NULL;
217int remoterfio;
218int localrfio;
219/*
220** Variables defining both side options :
221**
222** usetmpfile:
223**      Set to one when using tmpname for file creation
224**
225** usegzipcompress:
226**      Set to one when using tmpname for file creation
227**
228** keepaccess:
229**      Set to one when keeping access time and modification
230**
231** keepmode:
232**      Set to one when keeping file mode
233**
234** creatdir:
235**      Set to one when automatic directory creation is needed
236*/
237int     sendwinsize     = 256 ;
238int     recvwinsize     = 256 ;
239int     nbport = 1 ;
240int             ackto                   = ACKTO;
241int             recvcontrolto   = CONTROLSOCKTO;
242int             sendcontrolto   = SENDCONTROLTO;
243int             datato                  = DATASOCKTO;
244
245/*
246** Variables remote side options :
247**
248** remoterfio:
249**      Set to one when rfio for remote file
250**
251** remoteumask:
252**      if set to zero do not set remote umask
253**
254** remotecos:
255**      if not set to zero do set remote cos
256**
257** remotedir :
258**      if not set to NULL change dir after connection
259**
260*/
261int     remoteumask = SETTOZERO ;
262int     remotecos   = -1 ;
263char    *remotedir = NULL ;
264/*
265** incontrolsock :
266**      Define the control socket for reading
267** outcontrolsock :
268**      Define the control socket for writing
269**
270**      For normal use : incontrolsock = outcontrolsock
271*/
272int     incontrolsock ;
273int     outcontrolsock ;
274/*
275** myexitcode :
276**      Contains the first error code that has to be return when program
277**      is ended
278*/
279int     myexitcode = SETTOZERO ;
280char    *hostname   = NULL ;
281struct hostent  *hp = NULL ;
282char    *username   = NULL ;
283char    *password   = NULL ;
284#ifdef CERTIFICATE_AUTH
285char    *service    = NULL ;
286#endif
287/*
288** mychildren :
289**      Pointer to the first pid of children
290*/
291int     *mychildren = NULL ;
292/*
293** nbpidchid :
294**      Number of pid pointed by mychildren
295*/
296int     nbpidchild ;
297/*
298** castfd:
299**      CASTOR file descriptor
300*/
301#ifdef CASTOR
302int     castfd = -1 ;
303char    *castfilename = NULL ;
304#endif
305
306/*
307** Parameters describing the transfer ********************
308*/
309int     transferoption = TROPT_TMP | TROPT_DIR | TROPT_MODE | TROPT_ACC; 
310int     filemode ;
311char    lastaccess[9] ;
312char    lastmodif[9] ;
313int     buffersizeperstream = 256 ;
314int     requestedstreamnumber ;
315my64_t  filesize ;
316/*
317** curfilename :
318**      Define the pointer to the current file
319*/
320char    *curfilename = NULL ;
321/*
322** realfilename :
323**      Define the pointer to the real file (= curfilename if TROPT_TMP not
324**      set)
325*/
326char    *realfilename   = NULL ;
327int     *myports        = NULL ;
328int     *mysockets      = NULL ;
329char    *readbuffer     = NULL ;
330char    *compbuffer     = NULL ; 
331int     resfd = -1 ;
332/*
333** Simulation mode (option -n)
334*/
335int             simulation_mode = SETTOZERO;
336/*
337**
338*/
339int connectionisbroken = SETTOZERO ;
340
341/*
342 * Range for the ephemeral ports for data connections
343 */
344int     pasvport_min = 0 ;
345int     pasvport_max = 0 ;
346
347typedef struct cmd_list_st {
348        char *cmd;
349        struct cmd_list_st *next;
350} cmd_list;
351cmd_list *commandList = NULL;
352cmd_list *first = NULL;
353cmd_list *iterator = NULL;
354
355int addCommand(char *newcmd) {
356    cmd_list *newCommand = NULL;
357    if ((newCommand  = (cmd_list *)malloc(sizeof(cmd_list))) == NULL) {
358           PRINTMESSAGE(stderr,CASE_FATAL_ERROR,23,timestamp,"Unable to malloc memory for command list : %s\n",strerror(errno)) ;
359    }
360    if ((newCommand->cmd = (char *) malloc( strlen(newcmd) + 1)) == NULL) {
361           PRINTMESSAGE(stderr,CASE_FATAL_ERROR,23,timestamp,"Unable to malloc memory for command : %s\n",strerror(errno)) ;
362    }
363    strcpy(newCommand->cmd, newcmd);
364    newCommand->next = NULL;
365    if (iterator == NULL) {
366            iterator = newCommand;
367            first = newCommand;
368    } else {
369            iterator->next = newCommand;
370            iterator = iterator->next;
371    }
372}
373
374
375#ifdef NDG_PYTHON_EMBED
376/** Reset all global variables to how they were first initialised.
377 */
378void bbftpc_reset_globals(void) {
379
380  state   = SETTOZERO ;
381  timestamp = SETTOZERO ;
382 
383  protocolmin = 2 ; 
384  protocolmax = 3 ; 
385  //int     protocol ;
386  debug = SETTOZERO ;
387  verbose = SETTOZERO ;
388  warning = SETTOZERO ;
389  statoutput = SETTOZERO ;
390  globaltrymax = NBTRYMAX ;
391  newcontrolport = CONTROLPORT ;
392  usessh = SETTOZERO ;
393  sshbatchmode  = SETTOZERO ;
394  sshchildpid   = SETTOZERO ;
395  sshidentityfile = NULL ;
396  sshremotecmd = NULL ;
397  sshcmd = NULL ;
398 
399  usecert = SETTOZERO ;
400  useprivate = SETTOZERO ;
401  privatestr = NULL ;
402 
403  //struct sockaddr_in hisctladdr ;
404  //struct sockaddr_in myctladdr ;
405  bbftprc = NULL ;
406  //int     localumask ;
407#if defined(WITH_RFIO) || defined(WITH_RFIO64)
408  localcos  = SETTOZERO ;
409#endif
410 
411  newcmd = NULL;
412  //int remoterfio;
413  //int localrfio;
414  sendwinsize     = 256 ;
415  recvwinsize     = 256 ;
416  nbport = 1 ;
417  ackto                 = ACKTO;
418  recvcontrolto = CONTROLSOCKTO;
419  sendcontrolto = SENDCONTROLTO;
420  datato                        = DATASOCKTO;
421 
422  remoteumask = SETTOZERO ;
423  remotecos   = -1 ;
424  remotedir = NULL ;
425  //int     incontrolsock ;
426  //int     outcontrolsock ;
427  myexitcode = SETTOZERO ;
428  hostname   = NULL ;
429  hp = NULL ;
430  username   = NULL ;
431  password   = NULL ;
432#ifdef CERTIFICATE_AUTH
433  service    = NULL ;
434#endif
435  mychildren = NULL ;
436  //int     nbpidchild ;
437#ifdef CASTOR
438  castfd = -1 ;
439  castfilename = NULL ;
440#endif
441  transferoption = TROPT_TMP | TROPT_DIR | TROPT_MODE | TROPT_ACC; 
442  filemode ;
443  lastaccess[9] ;
444  lastmodif[9] ;
445  buffersizeperstream = 256 ;
446  //int     requestedstreamnumber ;
447  //my64_t  filesize ;
448  curfilename = NULL ;
449  realfilename   = NULL ;
450  myports        = NULL ;
451  mysockets      = NULL ;
452  readbuffer     = NULL ;
453  compbuffer     = NULL ; 
454  resfd = -1 ;
455  simulation_mode = SETTOZERO;
456 
457  connectionisbroken = SETTOZERO ;
458 
459  pasvport_min = 0 ;
460  pasvport_max = 0 ;
461 
462  commandList = NULL;
463  first = NULL;
464  iterator = NULL;
465}
466
467#endif // NDG_PYTHON_EMBED
468
469
470#ifdef NDG_PYTHON_EMBED
471bbftpc_main(int argc, char **argv, char **envp) {
472  bbftpc_reset_globals();
473 
474#else
475main(argc, argv, envp)
476    int argc;
477    char **argv;
478    char **envp;
479{
480#endif
481    extern char *optarg;
482    extern int optind, opterr, optopt;
483/*
484** Variable set by options
485*/
486    char    *inputfile  = NULL ;
487    char    *resultfile = NULL ;
488    char    *outputfile = NULL ;
489    char    *errorfile  = NULL ;
490    char    *bbftpcmd   = NULL ;
491    int     background  = SETTOZERO ;
492/*
493** For hostname
494*/ 
495    int     hosttype = 0 ;
496    char    *calchostname ;
497/*
498** For local user
499*/
500    struct  passwd  *mypasswd ;
501    char    *bbftprcfile = NULL ;
502    int     fd ;
503    char    *carret ;
504    char    *startcmd ;
505    int     nooption ;
506   
507    struct  stat    statbuf ;
508    int     retcode ;
509    int     i, j, k ;
510    int     stderrfd ;
511    int     stdoutfd ;
512    int     infd ;
513    char    calcmaxline[1] ;
514    int     maxlen ;
515    int     lengthread ;
516    char    *buffercmd ;
517    int     alluse ;
518    char    *tmpsshremotecmd ;
519    char    logmessage[1024] ;
520    char    minbuffer[MINMESSLEN] ;
521    struct  message *msg ;
522/*
523** Get local umask
524*/
525    localumask = umask(0) ;
526/*
527** and reset it to the correct value
528*/
529    umask(localumask) ;
530/*
531** First check for timestamp in order to have a common output
532*/
533    opterr = 0 ;
534    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
535        switch (j) {
536            case 't' :{
537                timestamp = SETTOONE ;
538                break ;
539            }
540        }
541    }
542
543#ifdef PRIVATE_AUTH
544    useprivate = SETTOONE ;
545    usessh = SETTOZERO ;
546#endif
547
548/*
549** Check for -v option
550*/
551    opterr = 0 ;
552    optind = 1 ;
553    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
554        switch (j) {
555            case 'v' :{
556                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"bbftp version %s\n",VERSION) ;
557                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Compiled with  :   default port %d\n",CONTROLPORT) ;
558#ifdef PORT_RANGE
559                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   data ports range = %s \n", PORT_RANGE) ;
560#endif
561#ifdef WITH_GZIP
562                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   compression with Zlib-%s\n", zlibVersion()) ;
563#endif
564#ifdef WITH_SSL
565                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   encryption with %s \n",SSLeay_version(SSLEAY_VERSION)) ;
566#endif
567#ifdef WITH_RFIO
568# ifdef CASTOR
569                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   CASTOR support (RFIO)\n") ;
570# else
571                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   HPSS support (RFIO)\n") ;
572# endif
573#endif
574#ifdef WITH_RFIO64
575# ifdef CASTOR
576                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   CASTOR support (RFIO64)\n") ;
577# else
578                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   HPSS support (RFIO64)\n") ;
579# endif
580#endif
581#ifdef AFS
582                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   AFS authentication \n") ;
583#endif
584#ifdef PRIVATE_AUTH
585                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   private authentication \n") ;
586#else
587                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   default ssh command = %s \n",SSHCMD) ;
588                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   default ssh remote command = %s \n",SSHREMOTECMD) ;
589# ifdef CERTIFICATE_AUTH
590                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   GSI authentication\n") ;
591# endif
592#endif
593#ifdef NDG_PYTHON_EMBED
594                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   Embedded in Python interpreter\n") ;
595#endif // NDG_PYTHON_EMBED
596
597                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   default number of tries = %d  \n",NBTRYMAX) ;
598                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   default sendwinsize = %d Kbytes\n",sendwinsize) ;
599                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   default recvwinsize = %d Kbytes\n",recvwinsize) ;
600                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"                   default number of stream = %d \n",nbport) ;
601                exit(0) ;
602            }
603        }
604    }
605
606#ifndef NDG_PYTHON_EMBED
607/*
608** Check for stderr replacement
609*/
610    opterr = 0 ;
611    optind = 1 ;
612    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
613        switch (j) {
614            case 'f' :{
615                errorfile = optarg ;
616                break ;
617            }
618        }
619    }
620    if ( errorfile != NULL ) {
621#ifdef DARWIN
622                if ( (stderrfd = open(errorfile,O_CREAT|O_WRONLY|O_TRUNC,0777)) < 0 ) {
623#else
624        if ( (stderrfd = open(errorfile,O_CREAT|O_WRONLY|O_SYNC|O_TRUNC,0777)) < 0 ) {
625#endif
626                PRINTMESSAGE(stderr,CASE_FATAL_ERROR,10,timestamp,"Error openning error file (%s) : %s\n",errorfile,strerror(errno)) ;
627        }
628        close(STDERR_FILENO);
629        if ( fcntl(stderrfd,F_DUPFD,STDERR_FILENO) != STDERR_FILENO ) {
630            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,11,timestamp,"Error dup on error file (%s) : %s\n",errorfile,strerror(errno)) ;
631        }
632    }
633/*
634** Check for stdout replacement
635*/
636    opterr = 0 ;
637    optind = 1 ;
638    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
639        switch (j) {
640            case 'o' :{
641                outputfile = optarg ;
642                break ;
643            }
644        }
645    }
646    if ( outputfile != NULL ) {
647#ifdef DARWIN
648                if ( (stdoutfd = open(outputfile,O_CREAT|O_WRONLY|O_TRUNC,0777)) < 0 ) {
649#else
650        if ( (stdoutfd = open(outputfile,O_CREAT|O_WRONLY|O_SYNC|O_TRUNC,0777)) < 0 ) {
651#endif
652                PRINTMESSAGE(stderr,CASE_FATAL_ERROR,12,timestamp,"Error openning output file (%s) : %s\n",outputfile,strerror(errno)) ;
653        }
654        close(STDOUT_FILENO);
655        if ( fcntl(stdoutfd,F_DUPFD,STDOUT_FILENO) != STDOUT_FILENO ) {
656            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,13,timestamp,"Error dup on output file (%s) : %s\n",outputfile,strerror(errno)) ;
657        }
658    }
659
660/*
661** Block all signals , the routine will exit in case of error
662*/
663    blockallsignals() ;
664
665#endif // NDG_PYTHON_EMBED
666
667/*
668** Now all the others
669*/
670    opterr = 0 ;
671    optind = 1 ;
672    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
673        switch (j) {
674            case 'b' :{
675                background = SETTOONE ;
676                break ;
677            }
678            case 'c' :{
679#ifdef WITH_GZIP               
680                transferoption = transferoption | TROPT_GZIP ;
681#else
682                PRINTMESSAGE(stderr,CASE_FATAL_ERROR,7,timestamp,"option -c is not available: bbftp was built without compression utility\n") ;
683#endif               
684                break ;
685            }
686            case 'd' :{
687                debug = 1 ;
688                break ;
689            }
690            case 'D' :{         
691                if (optarg) {
692                    if ((sscanf(optarg,"%d:%d",&i, &k) == 2) && (i < k)) {
693                        pasvport_min = i; pasvport_max = k;
694                    } else {
695                        PRINTMESSAGE(stderr,CASE_FATAL_ERROR,4,timestamp,"Invalid port range : %s\n",optarg) ;
696                    }
697                } else {
698#ifdef PORT_RANGE
699                     sscanf(PORT_RANGE,"%d:%d",&pasvport_min, &pasvport_max) ;
700#endif
701                     if (0 == pasvport_max) {
702                         pasvport_min = 0;
703                         pasvport_max = 1;
704                     }
705                }
706                protocolmax = 2 ;
707                break ;
708            }
709            case 'e' : {
710                bbftpcmd = optarg ;
711                break ;
712            }
713            case 'E' : {
714                sshremotecmd = optarg ;
715                usessh = 1 ;
716                break ;
717            }
718            case 'f' :{
719                errorfile = optarg ;
720                break ;
721            }
722#ifdef CERTIFICATE_AUTH
723            case 'g' :{
724                service = optarg ;
725                break ;
726            }
727#endif         
728            case 'i' :{
729                inputfile = optarg ;
730                if ( stat (inputfile,&statbuf) < 0 ) {
731                    PRINTMESSAGE(stderr,CASE_FATAL_ERROR,7,timestamp,"Input file (%s) cannot be stated\n",inputfile) ;
732                }
733                if ( (resultfile = (char *) malloc (strlen(inputfile) + 5 )) == NULL ) {
734                    PRINTMESSAGE(stderr,CASE_FATAL_ERROR,1,timestamp,"Cannot malloc space for result file name\n") ;
735                }
736                strcpy(resultfile,inputfile) ;
737                strcat(resultfile,".res") ;
738                break ;
739            }
740            case 'I' :{
741                sshidentityfile = optarg ;
742                usessh = 1 ;
743                /*
744                ** Check if file exists
745                */
746                if ( stat (sshidentityfile,&statbuf) < 0 ) {
747                    PRINTMESSAGE(stderr,CASE_FATAL_ERROR,5,timestamp,"SSH identity file (%s) cannot be stated\n",sshidentityfile) ;
748                }
749                break ;
750            }
751            case 'L' : {
752                sshcmd = optarg ;
753                usessh = 1 ;
754                break ;
755            }
756            case 'm' :{
757                statoutput = SETTOONE ;
758                break ;
759            }
760            case 'n':{
761                simulation_mode = SETTOONE ;
762                break ;
763            }
764            case 'o' :{
765                outputfile = optarg ;
766                break ;
767            }
768            case 'P' :{
769                privatestr = optarg ;
770                break ;
771            }
772            case 'q' :{
773                transferoption = transferoption | TROPT_QBSS ;
774                                break ;
775                        }
776            case 'p' :{
777                retcode = sscanf(optarg,"%d",&alluse) ;
778                if ( retcode != 1 || alluse < 0) {
779                    PRINTMESSAGE(stderr,CASE_FATAL_ERROR,3,timestamp,"Number of streams must be numeric and > 0\n") ;
780                }
781                nbport = alluse ;
782                break ;
783            }
784            case 'r' :{
785                retcode = sscanf(optarg,"%d",&alluse) ;
786                if ( retcode != 1 || alluse <= 0) {
787                    PRINTMESSAGE(stderr,CASE_FATAL_ERROR,4,timestamp,"Number of tries must be numeric > 0\n") ;
788                }
789                globaltrymax = alluse ;
790                break ;
791            }
792            case 'R' :{
793                bbftprcfile = optarg ;
794                break ;
795            }
796            case 's' :{
797                usessh = SETTOONE ;
798                break ;
799            }
800            case 'S' :{
801                usessh = SETTOONE ;
802                sshbatchmode = SETTOONE ;
803                break ;
804            }
805            case 't' :{
806                timestamp = SETTOONE ;
807                break ;
808            }
809            case 'u' :{
810                username = optarg ;
811                break ;
812            }
813            case 'V':{
814                verbose = SETTOONE ;
815                break ;
816            }
817            case 'w' :{
818                retcode = sscanf(optarg,"%d",&alluse) ;
819                if ( retcode != 1 || alluse <= 0) {
820                    PRINTMESSAGE(stderr,CASE_FATAL_ERROR,4,timestamp,"Control port must be numeric\n") ;
821                }
822                newcontrolport = alluse ;
823                break ;
824            }
825            case 'W':{
826                warning = SETTOONE ;
827                break ;
828            }
829            default : {
830                Usage() ;
831                PRINTMESSAGE(stderr,CASE_FATAL_ERROR,6,timestamp,"Error on command line (unsupported option -%c)\n",optopt) ;
832            }
833        }
834    }
835    /*
836    ** Get 5K for castfilename in order to work with CASTOR
837    ** software (even if we are not using it)
838    */
839#ifdef CASTOR
840    if ( (castfilename = (char *) malloc (5000)) == NULL ) {
841        /*
842        ** Starting badly if we are unable to malloc 5K
843        */
844        PRINTMESSAGE(stderr,CASE_FATAL_ERROR,10,timestamp,"No memory for CASTOR : %s\n",strerror(errno)) ;
845    }
846#endif
847
848    /*
849    ** Reset all outputs variable if statoutput is set to one
850    */
851    if ( statoutput ) {
852        debug     = SETTOZERO ;
853        verbose   = SETTOZERO ;
854        warning   = SETTOZERO ;
855        timestamp = SETTOZERO ;
856    }
857/*
858#ifdef PRIVATE_AUTH
859    useprivate = SETTOONE ;
860    usessh = SETTOZERO ;
861#endif
862
863#ifdef CERTIFICATE_AUTH
864        usecert = SETTOONE ;
865    useprivate = SETTOZERO ;
866    usessh = SETTOZERO ;
867#endif
868*/             
869 
870/*
871** Check all ssh stuff
872*/
873    if ( usessh) {
874        if ( sshremotecmd == NULL ) {
875            /*
876            ** Malloc space and set the default
877            */
878            if ( (sshremotecmd = (char *) malloc (strlen(SSHREMOTECMD)+1) ) == NULL ) {
879                PRINTMESSAGE(stderr,CASE_FATAL_ERROR,8,timestamp,"Cannot malloc space for ssh remote cmd\n") ;
880            }
881            strcpy(sshremotecmd,SSHREMOTECMD) ;
882        } else {
883            /*
884            ** Verify if -s is present if not add it (in order to fit v 1.9.4-tja1
885            ** behaviour)
886            */
887            if ( strstr(sshremotecmd," -s") == NULL ) {
888                if ( ( tmpsshremotecmd = (char *) malloc (strlen(sshremotecmd) + 4) ) == NULL ) {
889                    PRINTMESSAGE(stderr,CASE_FATAL_ERROR,8,timestamp,"Cannot malloc space for ssh remote cmd\n") ;
890                }
891                sprintf(tmpsshremotecmd,"%s -s",sshremotecmd) ;
892                sshremotecmd = tmpsshremotecmd ;
893            }
894        }
895        if ( sshcmd == NULL ) {
896            if ( (sshcmd = (char *) malloc (strlen(SSHCMD)+1) ) == NULL ) {
897                  PRINTMESSAGE(stderr,CASE_FATAL_ERROR,9,timestamp,"Cannot malloc space for ssh cmd\n") ;
898            }
899            strcpy(sshcmd,SSHCMD) ;
900        }
901    }
902
903#ifndef NDG_PYTHON_EMBED
904/*
905** Check for the local user in order to find the .bbftprc file
906*/
907    if ( bbftprcfile == NULL ) {
908        /*
909        ** look for the local user in order to find the .bbftprc file
910        */
911        if ( (mypasswd = getpwuid(getuid())) == NULL ) {
912            if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,6,timestamp,"Unable to get passwd entry, using %s\n", BBFTP_CONF) ;
913            if ( (bbftprcfile = (char *) malloc (strlen(BBFTP_CONF)+1) ) != NULL ) {
914              strcpy(bbftprcfile,BBFTP_CONF);
915            }
916        } else if ( mypasswd->pw_dir == NULL ) {
917            if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,7,timestamp,"No home directory, using %s\n", BBFTP_CONF) ;
918            if ( (bbftprcfile = (char *) malloc (strlen(BBFTP_CONF)+1) ) != NULL ) {
919              strcpy(bbftprcfile,BBFTP_CONF);
920            }
921        } else if ( (bbftprcfile = (char *) malloc (strlen(mypasswd->pw_dir)+10) ) == NULL ) {
922            if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,8,timestamp,"Error allocationg space for bbftprc file name, .bbftprc will not be used\n") ;
923        } else {
924            strcpy(bbftprcfile,mypasswd->pw_dir) ;
925            strcat(bbftprcfile,"/.bbftprc") ;
926            if ( stat(bbftprcfile,&statbuf) < 0  ) {
927                bbftprcfile == NULL;
928                if ( (bbftprcfile = (char *) malloc (strlen(BBFTP_CONF)+1) ) != NULL ) {
929                  strcpy(bbftprcfile,BBFTP_CONF);
930                }
931            }
932        }
933    }
934    if ( bbftprcfile != NULL ) {
935        if ( strncmp(bbftprcfile,"none",4) != 0 ) {
936            /*
937            ** Stat the file in order to get the length
938            */
939            if ( stat(bbftprcfile,&statbuf) < 0  ) {
940                if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,9,timestamp,"Error stating bbftprc file (%s)\n",bbftprcfile) ;
941            } else if ( statbuf.st_size == 0 ) {
942                /*
943                ** do nothing
944                */
945            } else if ( (bbftprc = (char *) malloc (statbuf.st_size + 1 ) ) == NULL ) {
946                if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,10,timestamp,"Error allocation memory for bbftprc, .bbftprc will not be used\n") ;
947            } else if ( ( fd  = open (bbftprcfile,O_RDONLY) )  < 0 ) {
948                if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,11,timestamp,"Error openning .bbftprc file (%s) : %s \n",bbftprcfile,strerror(errno)) ;
949            } else if ( ( j = read( fd, bbftprc , statbuf.st_size )) != statbuf.st_size ) {
950                if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,12,timestamp,"Error reading .bbftprc file (%s)\n",bbftprcfile) ;
951            } else {
952                bbftprc[j] = '\0' ;
953            }
954        }
955    }
956/*
957** Analyse the bbftprc command in order to supress forbiden command
958** Allowed commands are :
959**          setbuffersize %d
960**          setlocalcos %d
961**          setremotecos %d
962**          setlocalumask %ooo
963**          setremoteumask %ooo
964**          setsendwinsize %d
965**          setrecvwinsize %d
966**          setnbstream %d
967**          setoption [ [no]createdir | [no]tmpfile | [no]remoterfio | [no]localrfio | [no]keepmode |[no]keepaccess |[no]gzip]
968**
969*/
970    if ( bbftprc != NULL ) {
971        carret = bbftprc ;
972        startcmd = bbftprc ;
973        /*
974        ** Strip starting CR
975        */
976        while (1) {
977            while ( *carret == 10 || *carret == ' ' ) carret++ ;
978            startcmd = carret ;
979            carret = (char *) strchr (carret, 10);
980            if ( carret == NULL ) break ;
981            *carret = '\0' ;
982            if ( !strncmp(startcmd,"setbuffersize",13)) {
983                retcode = sscanf(startcmd,"setbuffersize %d",&alluse) ;
984                if ( retcode != 1 || alluse < 0 ) {
985                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,5,timestamp,"Buffersize in bbftprc file must be numeric > 0\n") ;
986                } else {
987                    buffersizeperstream = alluse ;
988                }
989#if defined(WITH_RFIO) || defined(WITH_RFIO64)
990            } else if ( !strncmp(startcmd,"setlocalcos",11)) {
991                retcode = sscanf(startcmd,"setlocalcos %d",&alluse) ;
992                if ( retcode != 1 /*|| alluse < 0*/) {
993                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,14,timestamp,"Local COS in bbftprc file must be numeric\n") ;
994                } else {
995                    localcos = alluse ;
996                }
997#endif
998            } else if (!strncmp(startcmd,"setremotecos",12)) {
999                retcode = sscanf(startcmd,"setremotecos %d",&alluse) ;
1000                if ( retcode != 1 /*|| alluse < 0*/) {
1001                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,15,timestamp,"Remote COS in bbftprc file must be numeric\n") ;
1002                }else {
1003                    remotecos = alluse ;
1004                }
1005            } else if (!strncmp(startcmd,"setlocalumask",13)) {
1006                retcode = sscanf(startcmd,"setlocalumask %o",&alluse) ;
1007                if ( retcode != 1 || alluse < 0) {
1008                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,16,timestamp,"Local umask in bbftprc file must be numeric\n") ;
1009                } else {
1010                    localumask = alluse ;
1011                    umask(localumask) ;
1012                }
1013            } else if (!strncmp(startcmd,"setremoteumask",14)) {
1014                retcode = sscanf(startcmd,"setremoteumask %o",&alluse) ;
1015                if ( retcode != 1  || alluse < 0) {
1016                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,17,timestamp,"Remote umask in bbftprc file must be numeric\n") ;
1017                }else {
1018                    remoteumask = alluse ;
1019                    umask(localumask) ;
1020                }
1021            } else if (!strncmp(startcmd,"setsendwinsize",14)) {
1022                retcode = sscanf(startcmd,"setsendwinsize %d",&alluse) ;
1023                if ( retcode != 1 || alluse < 0 ) {
1024                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,18,timestamp,"Send window size in bbftprc file must be numeric\n") ;
1025                } else {
1026                    sendwinsize = alluse ;
1027                }
1028            } else if (!strncmp(startcmd,"setrecvwinsize",14)) {
1029                retcode = sscanf(startcmd,"setrecvwinsize %d",&alluse) ;
1030                if ( retcode != 1 || alluse < 0  ) {
1031                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,19,timestamp,"Receive window size in bbftprc file must be numeric\n") ;
1032                }else {
1033                    recvwinsize = alluse ;
1034                }
1035            } else if (!strncmp(startcmd,"setnbstream",11)) {
1036                retcode = sscanf(startcmd,"setnbstream %d",&alluse) ;
1037                if ( retcode != 1  || alluse <= 0 ) {
1038                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,19,timestamp,"Number of streams in bbftprc file must be numeric and > 0\n") ;
1039                } else {
1040                    nbport = alluse ;
1041                }
1042            } else if (!strncmp(startcmd,"setackto",8)) {
1043                retcode = sscanf(startcmd,"setackto %d",&alluse) ;
1044                if ( retcode != 1  || alluse <= 0 ) {
1045                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,19,timestamp,"Acknowledge timeout must be numeric and > 0\n") ;
1046                } else {
1047                    ackto = alluse ;
1048                }
1049            } else if (!strncmp(startcmd,"setrecvcontrolto",16)) {
1050                retcode = sscanf(startcmd,"setrecvcontrolto %d",&alluse) ;
1051                if ( retcode != 1  || alluse <= 0 ) {
1052                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,19,timestamp,"Input control timeout must be numeric and > 0\n") ;
1053                } else {
1054                    recvcontrolto = alluse ;
1055                }
1056            } else if (!strncmp(startcmd,"setsendcontrolto",16)) {
1057                retcode = sscanf(startcmd,"setsendcontrolto %d",&alluse) ;
1058                if ( retcode != 1  || alluse <= 0 ) {
1059                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,19,timestamp,"Output control timeout must be numeric and > 0\n") ;
1060                } else {
1061                    sendcontrolto = alluse ;
1062                }
1063            } else if (!strncmp(startcmd,"setdatato",9)) {
1064                retcode = sscanf(startcmd,"setdatato %d",&alluse) ;
1065                if ( retcode != 1  || alluse <= 0 ) {
1066                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,19,timestamp,"Data timeout must be numeric and > 0\n") ;
1067                } else {
1068                    datato = alluse ;
1069                }
1070            } else if (!strncmp(startcmd,"setoption",9)) {
1071                /*
1072                ** look for the option
1073                */
1074                startcmd = startcmd + 9 ;
1075                while (*startcmd == ' ' && *startcmd != '\0' ) startcmd++ ;
1076                if ( !strncmp(startcmd,"no",2) ) {
1077                    nooption = SETTOONE ;
1078                    startcmd = startcmd+2 ;
1079                } else {
1080                    nooption = SETTOZERO ;
1081                }
1082                if ( !strncmp(startcmd,"createdir",9) ) {
1083                    if ( nooption ) {
1084                        transferoption = transferoption & ~TROPT_DIR ;
1085                    } else {
1086                        transferoption = transferoption | TROPT_DIR ;
1087                   }
1088                } else if ( !strncmp(startcmd,"tmpfile",7) ) {
1089                    if ( nooption ) {
1090                        transferoption = transferoption & ~TROPT_TMP ;
1091                    } else {
1092                        transferoption = transferoption | TROPT_TMP ;
1093                   }
1094                } else if ( !strncmp(startcmd,"remoterfio",10) ) {
1095                    if ( nooption ) {
1096                        transferoption = transferoption & ~TROPT_RFIO ;
1097                    } else {
1098                        transferoption = transferoption | TROPT_RFIO ;
1099                        if ( remotecos == -1 ) remotecos = 0;
1100                    }
1101                } else if ( !strncmp(startcmd,"localrfio",9) ) {
1102                    if ( nooption ) {
1103                        transferoption = transferoption & ~TROPT_RFIO_O ;
1104                    } else {
1105#if defined(WITH_RFIO) || defined(WITH_RFIO64)
1106                        transferoption = transferoption | TROPT_RFIO_O ;
1107#else
1108                        if (warning) PRINTMESSAGE(stderr,CASE_WARNING,20,timestamp,"Incorrect command : setoption localrfio (RFIO not supported)\n",buffercmd) ;
1109#endif
1110                    }
1111                } else if ( !strncmp(startcmd,"keepmode",8) ) {
1112                    if ( nooption ) {
1113                        transferoption = transferoption & ~TROPT_MODE ;
1114                    } else {
1115                        transferoption = transferoption | TROPT_MODE ;
1116                    }
1117                } else if ( !strncmp(startcmd,"keepaccess",10) ) {
1118                    if ( nooption ) {
1119                        transferoption = transferoption & ~TROPT_ACC ;
1120                    } else {
1121                        transferoption = transferoption | TROPT_ACC ;
1122                    }
1123                } else if ( !strncmp(startcmd,"gzip",4) ) {
1124                    if ( nooption ) {
1125                        transferoption = transferoption & ~TROPT_GZIP ;
1126                    } else {
1127#ifdef WITH_GZIP                       
1128                        transferoption = transferoption | TROPT_GZIP ;
1129#else
1130                        PRINTMESSAGE(stderr,CASE_FATAL_ERROR,7,timestamp,"gzip option is not available: bbftp was built without compression support\n") ;
1131#endif                       
1132                    }
1133                } else if ( !strncmp(startcmd,"qbss",4) ) {
1134                    if ( nooption ) {
1135                        transferoption = transferoption & ~TROPT_QBSS ;
1136                    } else {
1137                        transferoption = transferoption | TROPT_QBSS ;
1138                    }
1139                } else {
1140                    if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,20,timestamp,"Unkown option in .bbftprc file (%s)\n",startcmd) ;
1141                }
1142            } else {
1143                if ( warning ) PRINTMESSAGE(stderr,CASE_WARNING,13,timestamp,"Unkown command in .bbftprc file (%s)\n",startcmd) ;
1144            }
1145            carret++ ;
1146        }
1147    }
1148#endif // NDG_PYTHON_EMBED
1149
1150/*
1151** Check for input file or command line
1152*/
1153    if ( inputfile == NULL && bbftpcmd == NULL ) {
1154        PRINTMESSAGE(stderr,CASE_FATAL_ERROR,20,timestamp,"Error on command line (-i or -e option are mandatory)\n") ;
1155    }
1156/*
1157** Open the input file if needed
1158*/
1159    if ( inputfile != NULL ) {
1160        if ( (infd = open(inputfile,O_RDONLY)) < 0 ) {
1161            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,21,timestamp,"Error opening input file (%s) : %s\n",inputfile,strerror(errno)) ;
1162        }
1163#ifdef DARWIN
1164                if ( (resfd = open(resultfile,O_CREAT|O_WRONLY|O_TRUNC,0777)) < 0 ) {
1165#else
1166        if ( (resfd = open(resultfile,O_CREAT|O_WRONLY|O_SYNC|O_TRUNC,0777)) < 0 ) {
1167#endif
1168                PRINTMESSAGE(stderr,CASE_FATAL_ERROR,22,timestamp,"Error opening result file (%s) : %s\n",resultfile,strerror(errno)) ;
1169        }
1170        /*
1171        ** Now calc the max line of the input file in order to malloc
1172        ** the buffer
1173        */
1174        maxlen = 0 ;
1175        j = 0 ;
1176        while ( (lengthread = read (infd,calcmaxline,1)) == 1 ) {
1177            if ( calcmaxline[0] == 10 ) {
1178                if ( j > maxlen ) {
1179                    maxlen = j  ;
1180                }
1181                j = 0 ;
1182            } else {
1183                j++ ;
1184            }
1185        }
1186        if ( lengthread < 0 ) {
1187            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,24,timestamp,"Error reading input file (%s) : %s\n",inputfile,strerror(errno)) ;
1188        } else if ( lengthread == 0 ) {
1189            if ( j > maxlen ) {
1190                maxlen = j  ;
1191            }
1192        }
1193       /*
1194        ** Reset the file at start position
1195        */
1196        lseek(infd,0,SEEK_SET) ;
1197        if ( (buffercmd = (char *) malloc (maxlen+2) ) == NULL ) {
1198            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,23,timestamp,"Unable to malloc memory for command : %s\n",strerror(errno)) ;
1199        }
1200    } else {
1201        if ( (buffercmd = (char *) malloc (strlen(bbftpcmd)+1)) == NULL ) {
1202             PRINTMESSAGE(stderr,CASE_FATAL_ERROR,23,timestamp,"Unable to malloc memory for command : %s\n",strerror(errno)) ;
1203         }
1204    }
1205     
1206/*
1207** Check hostname
1208*/         
1209    if ( optind == argc-1 ) {
1210        hostname= argv[optind] ;
1211    } else {
1212        /*
1213         * Maybe a TURL format: get hostname from command
1214         */
1215        maxlen = 0 ;
1216        retcode = 0 ;
1217        while (retcode == 0 ) {
1218            if ( inputfile != NULL ) {
1219                j = 0 ;
1220                while ( (lengthread = read (infd,&buffercmd[j],1)) == 1 ) {
1221                    if ( buffercmd[j] == 10 ) {
1222                        buffercmd[j] = 0 ;
1223                        break ;
1224                    } else {
1225                        j++ ;
1226                    }
1227                }
1228                if ( lengthread < 0 ) {
1229                    PRINTMESSAGE(stderr,CASE_FATAL_ERROR,24,timestamp,"Error reading input file (%s) : %s\n",inputfile,strerror(errno)) ;
1230                } else if ( lengthread == 0 ) {
1231                    if ( j == 0 ) {
1232                        retcode = 1 ;
1233                        break ;
1234                    } else {
1235                        buffercmd[j+1] = 0 ;
1236                    }
1237                }
1238            } else {
1239                /*
1240                ** the command may be under the form cmd ; cmd ; cmd....
1241                */
1242                j = 0 ;
1243                while ((maxlen < strlen(bbftpcmd)) && (bbftpcmd[maxlen] == ' ')) maxlen++ ;
1244                while ( (maxlen < strlen(bbftpcmd)) && (bbftpcmd[maxlen] != ';') ) {
1245                    buffercmd[j] =  bbftpcmd[maxlen] ;
1246                    j++ ;
1247                    maxlen++ ;
1248                }
1249                if ( maxlen == strlen(bbftpcmd) ) retcode = 1 ;
1250                maxlen++ ;
1251                buffercmd[j] = 0 ;
1252            }
1253            if ( translatecommand(buffercmd, &newcmd, &hostname, &newcontrolport, &remoterfio, &localrfio) == 0 ) {
1254                    if (localrfio == 1 && ((transferoption & TROPT_RFIO_O)!=TROPT_RFIO_O) ) {
1255                        addCommand("setoption localrfio");
1256                        transferoption = transferoption | TROPT_RFIO_O ;
1257                    } else if (localrfio == 0 && ((transferoption & TROPT_RFIO_O)==TROPT_RFIO_O) ) {
1258                        addCommand("setoption nolocalrfio");
1259                        transferoption = transferoption & ~TROPT_RFIO_O ;
1260                    }
1261                    if (remoterfio == 1 && ((transferoption & TROPT_RFIO)!=TROPT_RFIO) ) {
1262                        addCommand("setoption remoterfio");
1263                        if ( remotecos == -1 ) remotecos = 0 ;
1264                        transferoption = transferoption | TROPT_RFIO ;
1265                    } else if (remoterfio == 0 && ((transferoption & TROPT_RFIO)==TROPT_RFIO) ) {
1266                        addCommand("setoption noremoterfio");
1267                        transferoption = transferoption & ~TROPT_RFIO ;
1268                    }
1269                    addCommand(newcmd);
1270            } else {
1271                    PRINTMESSAGE(stderr,CASE_FATAL_ERROR,24,timestamp,"Unable to parse command  : %s\n",buffercmd) ;
1272            }
1273        }
1274        commandList = first;
1275    }
1276    if (hostname == NULL || strlen(hostname) == 0) {
1277        Usage() ;
1278        PRINTMESSAGE(stderr,CASE_FATAL_ERROR,14,timestamp,"No hostname on command line\n") ;
1279    }   
1280/*
1281** Check if hostname is in numeric format
1282*/
1283    for (j=0 ; j < strlen(hostname) ; j++) {
1284        if ( isalpha(hostname[j]) ) {
1285            /*
1286            ** One alpha caractere means no numeric form
1287            */
1288            hosttype = 1 ;
1289            break ;
1290        } else if ( isdigit(hostname[j]) ) {
1291        } else if ( hostname[j] == '.' ) {
1292        } else {
1293            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,15,timestamp,"Invalid hostname (%s)\n",hostname) ;
1294        }
1295    }
1296    if ( hosttype == 0 ) {
1297       /*
1298       ** Numeric format
1299       */
1300        hisctladdr.sin_addr.s_addr = 0 ;
1301        hisctladdr.sin_addr.s_addr = inet_addr(hostname) ;
1302        if (hisctladdr.sin_addr.s_addr == -1 ) {
1303            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,16,timestamp,"Invalid IP address (%s)\n",hostname) ;
1304        }
1305        calchostname = (char *)inet_ntoa(hisctladdr.sin_addr) ;
1306        if ( strcmp(hostname,calchostname) ) {
1307            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,16,timestamp,"Invalid IP address (%s)\n",hostname) ;
1308        }
1309    } else {
1310       /*
1311       ** Alpha format
1312       */
1313        if ( (hp = gethostbyname((char *)hostname) ) == NULL ) {
1314            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,17,timestamp,"Hostname no found (%s)\n",hostname) ;
1315        } else {
1316            if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {
1317                hp->h_length = sizeof(hisctladdr.sin_addr);
1318            }
1319            memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length) ;
1320        }
1321    }
1322/*
1323** Check username if not in     certificate authentication mode
1324*/         
1325    if ( username == NULL ) {
1326#ifdef CERTIFICATE_AUTH
1327        if (usessh) {
1328/*            Usage() ;
1329            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,18,timestamp,"No username given\n") ;*/
1330        } else {
1331            usecert = SETTOONE;
1332        }
1333#else       
1334        if (!usessh) {
1335            Usage() ;
1336            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,18,timestamp,"No username given\n") ;
1337        }
1338#endif
1339    }
1340    if ( debug ) {
1341        if (simulation_mode) {
1342            PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"** SIMULATION MODE: No data written **\n") ;
1343        }
1344        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Starting parameters -----------------\n") ;
1345        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"number of tries   = %d\n",globaltrymax) ;
1346        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"number of streams = %d\n",nbport) ;
1347        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"localumask        = %03o\n",localumask) ;
1348        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"remoteumask       = %03o\n",remoteumask) ;
1349#if defined(WITH_RFIO) || defined(WITH_RFIO64)
1350        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"localcos          = %d\n",localcos) ;
1351#endif
1352        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"remotecos         = %d\n",remotecos) ;
1353        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"buffersize        = %d KB\n",buffersizeperstream) ;
1354        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"sendwinsize       = %d KB\n",sendwinsize) ;
1355        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"recvwinsize       = %d KB\n",recvwinsize) ;
1356        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"ackto                         = %d s\n",ackto) ;
1357        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"recvcontrolto     = %d s\n",recvcontrolto) ;
1358        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"sendcontrolto     = %d s\n",sendcontrolto) ;
1359        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"datato     = %d s\n",datato) ;
1360                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_DIR ) == TROPT_DIR) ? "createdir" : "nocreatedir") ;
1361                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_TMP ) == TROPT_TMP) ? "tmpfile" : "notmpfile") ;
1362                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_RFIO ) == TROPT_RFIO) ? "remoterfio" : "noremoterfio") ;
1363#if defined(WITH_RFIO) || defined(WITH_RFIO64)
1364                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_RFIO_O ) == TROPT_RFIO_O) ? "localrfio" : "nolocalrfio") ;
1365#endif
1366                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_MODE ) == TROPT_MODE) ? "keepmode" : "nokeepmode") ;
1367                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_ACC ) == TROPT_ACC) ? "keepaccess" : "nokeepaccess") ;
1368#ifdef WITH_GZIP
1369                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_GZIP ) == TROPT_GZIP) ? "gzip" : "nogzip") ;
1370#endif       
1371                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_QBSS ) == TROPT_QBSS) ? "qbss" : "noqbss") ;
1372        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"-------------------------------------\n") ;
1373        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Connection mode ---------------------\n") ;
1374        if ( usecert ) {
1375/*                      if ( username == NULL ) {*/
1376                                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Using certificate authentication\n") ;
1377/*                      } else {
1378                                PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Using standard bbftp mode\n") ;
1379                        }*/
1380        } else if ( useprivate ) {
1381            PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Using private authentication\n") ;
1382        } else if ( usessh) {
1383            PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Using ssh mode\n") ;
1384            PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"     ssh command        = %s \n",sshcmd) ;
1385            PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"     ssh remote command = %s \n",sshremotecmd) ;
1386        } else {
1387            PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Using standard bbftp mode\n",localumask) ;
1388        }
1389        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"-------------------------------------\n") ;
1390   }
1391
1392/*
1393** Ask for password if not in ssh mode
1394*/
1395#ifdef PRIVATE_AUTH
1396    if ( bbftp_private_getargs(logmessage) < 0 ) {
1397        PRINTMESSAGE(stderr,CASE_FATAL_ERROR,19,timestamp,"Error while private authentication : %s\n",logmessage) ;
1398    }     
1399#else
1400    if ((!usessh && !usecert)/* || (usecert && username)*/) {
1401# ifdef AFS
1402        char *reasonString, passwordBuffer[1024] ;
1403        long code ;
1404        if ( (code = ka_UserReadPassword("Password: ", passwordBuffer, sizeof(passwordBuffer), &reasonString)) ) {
1405            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,19,timestamp,"Error while entering password\n") ;
1406        }
1407        if ( ( password = (char *) malloc (strlen(passwordBuffer) + 1) ) == NULL ) {
1408            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,54,timestamp,"Unable to store password : malloc failed (%s)\n",strerror(errno)) ;
1409            return -1 ;
1410        }
1411        strcpy(password, passwordBuffer);
1412# else
1413#  ifdef USE_GETPASSPHRASE
1414        password = (char *) getpassphrase("Password: ") ;
1415        if ( strlen(password) == 0 ) {
1416            PRINTMESSAGE(stderr,CASE_FATAL_ERROR,19,timestamp,"Password is mandatory\n") ;
1417        }
1418#  else
1419        PRINTMESSAGE(stdout,CASE_NORMAL,0,0,"Password: ") ;
1420        password = (char *) getpass("") ;
1421#  endif /* USE_GETPASSPHRASE */
1422# endif /* AFS */
1423    }
1424#endif
1425/*
1426** Set in background if required
1427*/
1428    if ( background ) {
1429        retcode = fork() ; 
1430        if ( retcode < 0 ) PRINTMESSAGE(stderr,CASE_FATAL_ERROR,31,timestamp,"Error forking while setting in background\n") ;
1431        if ( retcode > 0 ) exit(0) ;
1432        setsid() ;
1433        if ( verbose ) PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Starting under pid %d\n",getpid());
1434    }
1435
1436/*
1437** Set the signals
1438*/
1439    bbftp_setsignals() ;
1440
1441/*
1442 * Analyze command list or command file to populate commandList
1443 */
1444    if (commandList == NULL) {
1445      maxlen = 0 ;
1446      retcode = 0 ;
1447      while (retcode == 0 ) {
1448        if ( inputfile != NULL ) {
1449            j = 0 ;
1450            while ( (lengthread = read (infd,&buffercmd[j],1)) == 1 ) {
1451                if ( buffercmd[j] == 10 ) {
1452                    buffercmd[j] = 0 ;
1453                    break ;
1454                } else {
1455                    j++ ;
1456                }
1457            }
1458            if ( lengthread < 0 ) {
1459                PRINTMESSAGE(stderr,CASE_FATAL_ERROR,24,timestamp,"Error reading input file (%s) : %s\n",inputfile,strerror(errno)) ;
1460            } else if ( lengthread == 0 ) {
1461                if ( j == 0 ) {
1462                    retcode = 1 ;
1463                    break ;
1464                } else {
1465                    buffercmd[j+1] = 0 ;
1466                }
1467            }
1468        } else {
1469            /*
1470            ** the command may be under the form cmd ; cmd ; cmd....
1471            */
1472            j = 0 ;
1473            while ((maxlen < strlen(bbftpcmd)) && (bbftpcmd[maxlen] == ' ')) maxlen++ ;
1474            while ( (maxlen < strlen(bbftpcmd)) && (bbftpcmd[maxlen] != ';') ) {
1475                buffercmd[j] =  bbftpcmd[maxlen] ;
1476                j++ ;
1477                maxlen++ ;
1478            }
1479            if ( maxlen == strlen(bbftpcmd) ) retcode = 1 ;
1480            buffercmd[j] = 0 ;
1481            maxlen++ ;
1482        }
1483        addCommand(buffercmd);
1484        if ( !strncmp(buffercmd,"setoption remoterfio",20) ) {
1485            if ( remotecos == -1 ) remotecos = 0;
1486        }
1487      }
1488      commandList = first;
1489    }
1490/*
1491** Now we've got all informations to make the connection
1492*/
1493
1494    if ( debug )
1495        PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Connecting to server ----------------\n",localumask) ;
1496    reconnecttoserver() ;
1497    if ( debug )
1498         PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Connecting end ---------------------\n",localumask) ;
1499   
1500/*
1501** Start the infinite loop
1502*/
1503    {
1504      cmd_list *iterator;
1505      iterator = commandList;
1506      while (iterator != NULL) {
1507        if ( treatcommand(iterator->cmd) == 0 ) {
1508            if ( inputfile != NULL ) {
1509                write(resfd,iterator->cmd,strlen(iterator->cmd)) ;               
1510                write(resfd," OK\n",4) ;
1511            } else {
1512                if (!verbose && !statoutput) PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"%s OK\n",iterator->cmd);
1513            }
1514        } else {
1515            if ( inputfile != NULL ) {
1516                write(resfd,iterator->cmd,strlen(iterator->cmd)) ;               
1517                write(resfd," FAILED\n",8) ;
1518            } else {
1519                if (!verbose && !statoutput) PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"%s FAILED\n",iterator->cmd);
1520            }
1521        }
1522        iterator = iterator->next;
1523      }
1524    }
1525    if ( inputfile != NULL ) {
1526        close(infd) ;
1527        close(resfd) ;
1528    }
1529    msg = (struct message *)minbuffer ;
1530    msg->code = MSG_CLOSE_CONN ;
1531    msg->msglen = 0 ;
1532    /*
1533    ** We do not care of the result because this routine is called
1534    ** only at the end of the client
1535    */
1536    writemessage(outcontrolsock,minbuffer,MINMESSLEN,sendcontrolto,0) ;
1537    sleep(1) ;
1538    bbftp_close_control() ;
1539#ifndef NDG_PYTHON_EMBED
1540    exit(myexitcode) ;
1541#endif
1542}
Note: See TracBrowser for help on using the repository browser.