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

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

Messages from the client that were previously printed to stdout/stderr are now returned
in a list from python functions bbftpc.connect() and bbftpc.docommand().

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