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

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

test client script dumps output to bbftpc.log. Some debug code removed.

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