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

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

Client-side python embedding is being implemented but doesn't pass the
test cases yet.

I've uncovered a bug (see #343) which needs fixing before the embedded client
can be fully debugged.

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
372bbftpc_main(int argc, char **argv, char **envp) {
373#else
374main(argc, argv, envp)
375    int argc;
376    char **argv;
377    char **envp;
378{
379#endif
380    extern char *optarg;
381    extern int optind, opterr, optopt;
382/*
383** Variable set by options
384*/
385    char    *inputfile  = NULL ;
386    char    *resultfile = NULL ;
387    char    *outputfile = NULL ;
388    char    *errorfile  = NULL ;
389    char    *bbftpcmd   = NULL ;
390    int     background  = SETTOZERO ;
391/*
392** For hostname
393*/ 
394    int     hosttype = 0 ;
395    char    *calchostname ;
396/*
397** For local user
398*/
399    struct  passwd  *mypasswd ;
400    char    *bbftprcfile = NULL ;
401    int     fd ;
402    char    *carret ;
403    char    *startcmd ;
404    int     nooption ;
405   
406    struct  stat    statbuf ;
407    int     retcode ;
408    int     i, j, k ;
409    int     stderrfd ;
410    int     stdoutfd ;
411    int     infd ;
412    char    calcmaxline[1] ;
413    int     maxlen ;
414    int     lengthread ;
415    char    *buffercmd ;
416    int     alluse ;
417    char    *tmpsshremotecmd ;
418    char    logmessage[1024] ;
419    char    minbuffer[MINMESSLEN] ;
420    struct  message *msg ;
421/*
422** Get local umask
423*/
424    localumask = umask(0) ;
425/*
426** and reset it to the correct value
427*/
428    umask(localumask) ;
429/*
430** First check for timestamp in order to have a common output
431*/
432    opterr = 0 ;
433    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
434        switch (j) {
435            case 't' :{
436                timestamp = SETTOONE ;
437                break ;
438            }
439        }
440    }
441
442#ifdef PRIVATE_AUTH
443    useprivate = SETTOONE ;
444    usessh = SETTOZERO ;
445#endif
446
447/*
448** Check for -v option
449*/
450    opterr = 0 ;
451    optind = 1 ;
452    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
453        switch (j) {
454            case 'v' :{
455                printmessage(stdout,CASE_NORMAL,0,timestamp,"bbftp version %s\n",VERSION) ;
456                printmessage(stdout,CASE_NORMAL,0,timestamp,"Compiled with  :   default port %d\n",CONTROLPORT) ;
457#ifdef PORT_RANGE
458                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   data ports range = %s \n", PORT_RANGE) ;
459#endif
460#ifdef WITH_GZIP
461                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   compression with Zlib-%s\n", zlibVersion()) ;
462#endif
463#ifdef WITH_SSL
464                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   encryption with %s \n",SSLeay_version(SSLEAY_VERSION)) ;
465#endif
466#ifdef WITH_RFIO
467# ifdef CASTOR
468                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   CASTOR support (RFIO)\n") ;
469# else
470                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   HPSS support (RFIO)\n") ;
471# endif
472#endif
473#ifdef WITH_RFIO64
474# ifdef CASTOR
475                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   CASTOR support (RFIO64)\n") ;
476# else
477                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   HPSS support (RFIO64)\n") ;
478# endif
479#endif
480#ifdef AFS
481                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   AFS authentication \n") ;
482#endif
483#ifdef PRIVATE_AUTH
484                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   private authentication \n") ;
485#else
486                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   default ssh command = %s \n",SSHCMD) ;
487                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   default ssh remote command = %s \n",SSHREMOTECMD) ;
488# ifdef CERTIFICATE_AUTH
489                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   GSI authentication\n") ;
490# endif
491#endif
492#ifdef NDG_PYTHON_EMBED
493                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   Embedded in Python interpreter\n") ;
494#endif // NDG_PYTHON_EMBED
495
496                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   default number of tries = %d  \n",NBTRYMAX) ;
497                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   default sendwinsize = %d Kbytes\n",sendwinsize) ;
498                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   default recvwinsize = %d Kbytes\n",recvwinsize) ;
499                printmessage(stdout,CASE_NORMAL,0,timestamp,"                   default number of stream = %d \n",nbport) ;
500                exit(0) ;
501            }
502        }
503    }
504
505#ifndef NDG_PYTHON_EMBED
506/*
507** Check for stderr replacement
508*/
509    opterr = 0 ;
510    optind = 1 ;
511    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
512        switch (j) {
513            case 'f' :{
514                errorfile = optarg ;
515                break ;
516            }
517        }
518    }
519    if ( errorfile != NULL ) {
520#ifdef DARWIN
521                if ( (stderrfd = open(errorfile,O_CREAT|O_WRONLY|O_TRUNC,0777)) < 0 ) {
522#else
523        if ( (stderrfd = open(errorfile,O_CREAT|O_WRONLY|O_SYNC|O_TRUNC,0777)) < 0 ) {
524#endif
525                printmessage(stderr,CASE_FATAL_ERROR,10,timestamp,"Error openning error file (%s) : %s\n",errorfile,strerror(errno)) ;
526        }
527        close(STDERR_FILENO);
528        if ( fcntl(stderrfd,F_DUPFD,STDERR_FILENO) != STDERR_FILENO ) {
529            printmessage(stderr,CASE_FATAL_ERROR,11,timestamp,"Error dup on error file (%s) : %s\n",errorfile,strerror(errno)) ;
530        }
531    }
532/*
533** Check for stdout replacement
534*/
535    opterr = 0 ;
536    optind = 1 ;
537    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
538        switch (j) {
539            case 'o' :{
540                outputfile = optarg ;
541                break ;
542            }
543        }
544    }
545    if ( outputfile != NULL ) {
546#ifdef DARWIN
547                if ( (stdoutfd = open(outputfile,O_CREAT|O_WRONLY|O_TRUNC,0777)) < 0 ) {
548#else
549        if ( (stdoutfd = open(outputfile,O_CREAT|O_WRONLY|O_SYNC|O_TRUNC,0777)) < 0 ) {
550#endif
551                printmessage(stderr,CASE_FATAL_ERROR,12,timestamp,"Error openning output file (%s) : %s\n",outputfile,strerror(errno)) ;
552        }
553        close(STDOUT_FILENO);
554        if ( fcntl(stdoutfd,F_DUPFD,STDOUT_FILENO) != STDOUT_FILENO ) {
555            printmessage(stderr,CASE_FATAL_ERROR,13,timestamp,"Error dup on output file (%s) : %s\n",outputfile,strerror(errno)) ;
556        }
557    }
558
559/*
560** Block all signals , the routine will exit in case of error
561*/
562    blockallsignals() ;
563
564#endif // NDG_PYTHON_EMBED
565
566/*
567** Now all the others
568*/
569    opterr = 0 ;
570    optind = 1 ;
571    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
572        switch (j) {
573            case 'b' :{
574                background = SETTOONE ;
575                break ;
576            }
577            case 'c' :{
578#ifdef WITH_GZIP               
579                transferoption = transferoption | TROPT_GZIP ;
580#else
581                printmessage(stderr,CASE_FATAL_ERROR,7,timestamp,"option -c is not available: bbftp was built without compression utility\n") ;
582#endif               
583                break ;
584            }
585            case 'd' :{
586                debug = 1 ;
587                break ;
588            }
589            case 'D' :{         
590                if (optarg) {
591                    if ((sscanf(optarg,"%d:%d",&i, &k) == 2) && (i < k)) {
592                        pasvport_min = i; pasvport_max = k;
593                    } else {
594                        printmessage(stderr,CASE_FATAL_ERROR,4,timestamp,"Invalid port range : %s\n",optarg) ;
595                    }
596                } else {
597#ifdef PORT_RANGE
598                     sscanf(PORT_RANGE,"%d:%d",&pasvport_min, &pasvport_max) ;
599#endif
600                     if (0 == pasvport_max) {
601                         pasvport_min = 0;
602                         pasvport_max = 1;
603                     }
604                }
605                protocolmax = 2 ;
606                break ;
607            }
608            case 'e' : {
609                bbftpcmd = optarg ;
610                break ;
611            }
612            case 'E' : {
613                sshremotecmd = optarg ;
614                usessh = 1 ;
615                break ;
616            }
617            case 'f' :{
618                errorfile = optarg ;
619                break ;
620            }
621#ifdef CERTIFICATE_AUTH
622            case 'g' :{
623                service = optarg ;
624                break ;
625            }
626#endif         
627            case 'i' :{
628                inputfile = optarg ;
629                if ( stat (inputfile,&statbuf) < 0 ) {
630                    printmessage(stderr,CASE_FATAL_ERROR,7,timestamp,"Input file (%s) cannot be stated\n",inputfile) ;
631                }
632                if ( (resultfile = (char *) malloc (strlen(inputfile) + 5 )) == NULL ) {
633                    printmessage(stderr,CASE_FATAL_ERROR,1,timestamp,"Cannot malloc space for result file name\n") ;
634                }
635                strcpy(resultfile,inputfile) ;
636                strcat(resultfile,".res") ;
637                break ;
638            }
639            case 'I' :{
640                sshidentityfile = optarg ;
641                usessh = 1 ;
642                /*
643                ** Check if file exists
644                */
645                if ( stat (sshidentityfile,&statbuf) < 0 ) {
646                    printmessage(stderr,CASE_FATAL_ERROR,5,timestamp,"SSH identity file (%s) cannot be stated\n",sshidentityfile) ;
647                }
648                break ;
649            }
650            case 'L' : {
651                sshcmd = optarg ;
652                usessh = 1 ;
653                break ;
654            }
655            case 'm' :{
656                statoutput = SETTOONE ;
657                break ;
658            }
659            case 'n':{
660                simulation_mode = SETTOONE ;
661                break ;
662            }
663            case 'o' :{
664                outputfile = optarg ;
665                break ;
666            }
667            case 'P' :{
668                privatestr = optarg ;
669                break ;
670            }
671            case 'q' :{
672                transferoption = transferoption | TROPT_QBSS ;
673                                break ;
674                        }
675            case 'p' :{
676                retcode = sscanf(optarg,"%d",&alluse) ;
677                if ( retcode != 1 || alluse < 0) {
678                    printmessage(stderr,CASE_FATAL_ERROR,3,timestamp,"Number of streams must be numeric and > 0\n") ;
679                }
680                nbport = alluse ;
681                break ;
682            }
683            case 'r' :{
684                retcode = sscanf(optarg,"%d",&alluse) ;
685                if ( retcode != 1 || alluse <= 0) {
686                    printmessage(stderr,CASE_FATAL_ERROR,4,timestamp,"Number of tries must be numeric > 0\n") ;
687                }
688                globaltrymax = alluse ;
689                break ;
690            }
691            case 'R' :{
692                bbftprcfile = optarg ;
693                break ;
694            }
695            case 's' :{
696                usessh = SETTOONE ;
697                break ;
698            }
699            case 'S' :{
700                usessh = SETTOONE ;
701                sshbatchmode = SETTOONE ;
702                break ;
703            }
704            case 't' :{
705                timestamp = SETTOONE ;
706                break ;
707            }
708            case 'u' :{
709                username = optarg ;
710                break ;
711            }
712            case 'V':{
713                verbose = SETTOONE ;
714                break ;
715            }
716            case 'w' :{
717                retcode = sscanf(optarg,"%d",&alluse) ;
718                if ( retcode != 1 || alluse <= 0) {
719                    printmessage(stderr,CASE_FATAL_ERROR,4,timestamp,"Control port must be numeric\n") ;
720                }
721                newcontrolport = alluse ;
722                break ;
723            }
724            case 'W':{
725                warning = SETTOONE ;
726                break ;
727            }
728            default : {
729                Usage() ;
730                printmessage(stderr,CASE_FATAL_ERROR,6,timestamp,"Error on command line (unsupported option -%c)\n",optopt) ;
731            }
732        }
733    }
734    /*
735    ** Get 5K for castfilename in order to work with CASTOR
736    ** software (even if we are not using it)
737    */
738#ifdef CASTOR
739    if ( (castfilename = (char *) malloc (5000)) == NULL ) {
740        /*
741        ** Starting badly if we are unable to malloc 5K
742        */
743        printmessage(stderr,CASE_FATAL_ERROR,10,timestamp,"No memory for CASTOR : %s\n",strerror(errno)) ;
744    }
745#endif
746
747    /*
748    ** Reset all outputs variable if statoutput is set to one
749    */
750    if ( statoutput ) {
751        debug     = SETTOZERO ;
752        verbose   = SETTOZERO ;
753        warning   = SETTOZERO ;
754        timestamp = SETTOZERO ;
755    }
756/*
757#ifdef PRIVATE_AUTH
758    useprivate = SETTOONE ;
759    usessh = SETTOZERO ;
760#endif
761
762#ifdef CERTIFICATE_AUTH
763        usecert = SETTOONE ;
764    useprivate = SETTOZERO ;
765    usessh = SETTOZERO ;
766#endif
767*/             
768 
769/*
770** Check all ssh stuff
771*/
772    if ( usessh) {
773        if ( sshremotecmd == NULL ) {
774            /*
775            ** Malloc space and set the default
776            */
777            if ( (sshremotecmd = (char *) malloc (strlen(SSHREMOTECMD)+1) ) == NULL ) {
778                printmessage(stderr,CASE_FATAL_ERROR,8,timestamp,"Cannot malloc space for ssh remote cmd\n") ;
779            }
780            strcpy(sshremotecmd,SSHREMOTECMD) ;
781        } else {
782            /*
783            ** Verify if -s is present if not add it (in order to fit v 1.9.4-tja1
784            ** behaviour)
785            */
786            if ( strstr(sshremotecmd," -s") == NULL ) {
787                if ( ( tmpsshremotecmd = (char *) malloc (strlen(sshremotecmd) + 4) ) == NULL ) {
788                    printmessage(stderr,CASE_FATAL_ERROR,8,timestamp,"Cannot malloc space for ssh remote cmd\n") ;
789                }
790                sprintf(tmpsshremotecmd,"%s -s",sshremotecmd) ;
791                sshremotecmd = tmpsshremotecmd ;
792            }
793        }
794        if ( sshcmd == NULL ) {
795            if ( (sshcmd = (char *) malloc (strlen(SSHCMD)+1) ) == NULL ) {
796                  printmessage(stderr,CASE_FATAL_ERROR,9,timestamp,"Cannot malloc space for ssh cmd\n") ;
797            }
798            strcpy(sshcmd,SSHCMD) ;
799        }
800    }
801
802#ifndef NDG_PYTHON_EMBED
803/*
804** Check for the local user in order to find the .bbftprc file
805*/
806    if ( bbftprcfile == NULL ) {
807        /*
808        ** look for the local user in order to find the .bbftprc file
809        */
810        if ( (mypasswd = getpwuid(getuid())) == NULL ) {
811            if ( warning ) printmessage(stderr,CASE_WARNING,6,timestamp,"Unable to get passwd entry, using %s\n", BBFTP_CONF) ;
812            if ( (bbftprcfile = (char *) malloc (strlen(BBFTP_CONF)+1) ) != NULL ) {
813              strcpy(bbftprcfile,BBFTP_CONF);
814            }
815        } else if ( mypasswd->pw_dir == NULL ) {
816            if ( warning ) printmessage(stderr,CASE_WARNING,7,timestamp,"No home directory, using %s\n", BBFTP_CONF) ;
817            if ( (bbftprcfile = (char *) malloc (strlen(BBFTP_CONF)+1) ) != NULL ) {
818              strcpy(bbftprcfile,BBFTP_CONF);
819            }
820        } else if ( (bbftprcfile = (char *) malloc (strlen(mypasswd->pw_dir)+10) ) == NULL ) {
821            if ( warning ) printmessage(stderr,CASE_WARNING,8,timestamp,"Error allocationg space for bbftprc file name, .bbftprc will not be used\n") ;
822        } else {
823            strcpy(bbftprcfile,mypasswd->pw_dir) ;
824            strcat(bbftprcfile,"/.bbftprc") ;
825            if ( stat(bbftprcfile,&statbuf) < 0  ) {
826                bbftprcfile == NULL;
827                if ( (bbftprcfile = (char *) malloc (strlen(BBFTP_CONF)+1) ) != NULL ) {
828                  strcpy(bbftprcfile,BBFTP_CONF);
829                }
830            }
831        }
832    }
833    if ( bbftprcfile != NULL ) {
834        if ( strncmp(bbftprcfile,"none",4) != 0 ) {
835            /*
836            ** Stat the file in order to get the length
837            */
838            if ( stat(bbftprcfile,&statbuf) < 0  ) {
839                if ( warning ) printmessage(stderr,CASE_WARNING,9,timestamp,"Error stating bbftprc file (%s)\n",bbftprcfile) ;
840            } else if ( statbuf.st_size == 0 ) {
841                /*
842                ** do nothing
843                */
844            } else if ( (bbftprc = (char *) malloc (statbuf.st_size + 1 ) ) == NULL ) {
845                if ( warning ) printmessage(stderr,CASE_WARNING,10,timestamp,"Error allocation memory for bbftprc, .bbftprc will not be used\n") ;
846            } else if ( ( fd  = open (bbftprcfile,O_RDONLY) )  < 0 ) {
847                if ( warning ) printmessage(stderr,CASE_WARNING,11,timestamp,"Error openning .bbftprc file (%s) : %s \n",bbftprcfile,strerror(errno)) ;
848            } else if ( ( j = read( fd, bbftprc , statbuf.st_size )) != statbuf.st_size ) {
849                if ( warning ) printmessage(stderr,CASE_WARNING,12,timestamp,"Error reading .bbftprc file (%s)\n",bbftprcfile) ;
850            } else {
851                bbftprc[j] = '\0' ;
852            }
853        }
854    }
855/*
856** Analyse the bbftprc command in order to supress forbiden command
857** Allowed commands are :
858**          setbuffersize %d
859**          setlocalcos %d
860**          setremotecos %d
861**          setlocalumask %ooo
862**          setremoteumask %ooo
863**          setsendwinsize %d
864**          setrecvwinsize %d
865**          setnbstream %d
866**          setoption [ [no]createdir | [no]tmpfile | [no]remoterfio | [no]localrfio | [no]keepmode |[no]keepaccess |[no]gzip]
867**
868*/
869    if ( bbftprc != NULL ) {
870        carret = bbftprc ;
871        startcmd = bbftprc ;
872        /*
873        ** Strip starting CR
874        */
875        while (1) {
876            while ( *carret == 10 || *carret == ' ' ) carret++ ;
877            startcmd = carret ;
878            carret = (char *) strchr (carret, 10);
879            if ( carret == NULL ) break ;
880            *carret = '\0' ;
881            if ( !strncmp(startcmd,"setbuffersize",13)) {
882                retcode = sscanf(startcmd,"setbuffersize %d",&alluse) ;
883                if ( retcode != 1 || alluse < 0 ) {
884                    if ( warning ) printmessage(stderr,CASE_WARNING,5,timestamp,"Buffersize in bbftprc file must be numeric > 0\n") ;
885                } else {
886                    buffersizeperstream = alluse ;
887                }
888#if defined(WITH_RFIO) || defined(WITH_RFIO64)
889            } else if ( !strncmp(startcmd,"setlocalcos",11)) {
890                retcode = sscanf(startcmd,"setlocalcos %d",&alluse) ;
891                if ( retcode != 1 /*|| alluse < 0*/) {
892                    if ( warning ) printmessage(stderr,CASE_WARNING,14,timestamp,"Local COS in bbftprc file must be numeric\n") ;
893                } else {
894                    localcos = alluse ;
895                }
896#endif
897            } else if (!strncmp(startcmd,"setremotecos",12)) {
898                retcode = sscanf(startcmd,"setremotecos %d",&alluse) ;
899                if ( retcode != 1 /*|| alluse < 0*/) {
900                    if ( warning ) printmessage(stderr,CASE_WARNING,15,timestamp,"Remote COS in bbftprc file must be numeric\n") ;
901                }else {
902                    remotecos = alluse ;
903                }
904            } else if (!strncmp(startcmd,"setlocalumask",13)) {
905                retcode = sscanf(startcmd,"setlocalumask %o",&alluse) ;
906                if ( retcode != 1 || alluse < 0) {
907                    if ( warning ) printmessage(stderr,CASE_WARNING,16,timestamp,"Local umask in bbftprc file must be numeric\n") ;
908                } else {
909                    localumask = alluse ;
910                    umask(localumask) ;
911                }
912            } else if (!strncmp(startcmd,"setremoteumask",14)) {
913                retcode = sscanf(startcmd,"setremoteumask %o",&alluse) ;
914                if ( retcode != 1  || alluse < 0) {
915                    if ( warning ) printmessage(stderr,CASE_WARNING,17,timestamp,"Remote umask in bbftprc file must be numeric\n") ;
916                }else {
917                    remoteumask = alluse ;
918                    umask(localumask) ;
919                }
920            } else if (!strncmp(startcmd,"setsendwinsize",14)) {
921                retcode = sscanf(startcmd,"setsendwinsize %d",&alluse) ;
922                if ( retcode != 1 || alluse < 0 ) {
923                    if ( warning ) printmessage(stderr,CASE_WARNING,18,timestamp,"Send window size in bbftprc file must be numeric\n") ;
924                } else {
925                    sendwinsize = alluse ;
926                }
927            } else if (!strncmp(startcmd,"setrecvwinsize",14)) {
928                retcode = sscanf(startcmd,"setrecvwinsize %d",&alluse) ;
929                if ( retcode != 1 || alluse < 0  ) {
930                    if ( warning ) printmessage(stderr,CASE_WARNING,19,timestamp,"Receive window size in bbftprc file must be numeric\n") ;
931                }else {
932                    recvwinsize = alluse ;
933                }
934            } else if (!strncmp(startcmd,"setnbstream",11)) {
935                retcode = sscanf(startcmd,"setnbstream %d",&alluse) ;
936                if ( retcode != 1  || alluse <= 0 ) {
937                    if ( warning ) printmessage(stderr,CASE_WARNING,19,timestamp,"Number of streams in bbftprc file must be numeric and > 0\n") ;
938                } else {
939                    nbport = alluse ;
940                }
941            } else if (!strncmp(startcmd,"setackto",8)) {
942                retcode = sscanf(startcmd,"setackto %d",&alluse) ;
943                if ( retcode != 1  || alluse <= 0 ) {
944                    if ( warning ) printmessage(stderr,CASE_WARNING,19,timestamp,"Acknowledge timeout must be numeric and > 0\n") ;
945                } else {
946                    ackto = alluse ;
947                }
948            } else if (!strncmp(startcmd,"setrecvcontrolto",16)) {
949                retcode = sscanf(startcmd,"setrecvcontrolto %d",&alluse) ;
950                if ( retcode != 1  || alluse <= 0 ) {
951                    if ( warning ) printmessage(stderr,CASE_WARNING,19,timestamp,"Input control timeout must be numeric and > 0\n") ;
952                } else {
953                    recvcontrolto = alluse ;
954                }
955            } else if (!strncmp(startcmd,"setsendcontrolto",16)) {
956                retcode = sscanf(startcmd,"setsendcontrolto %d",&alluse) ;
957                if ( retcode != 1  || alluse <= 0 ) {
958                    if ( warning ) printmessage(stderr,CASE_WARNING,19,timestamp,"Output control timeout must be numeric and > 0\n") ;
959                } else {
960                    sendcontrolto = alluse ;
961                }
962            } else if (!strncmp(startcmd,"setdatato",9)) {
963                retcode = sscanf(startcmd,"setdatato %d",&alluse) ;
964                if ( retcode != 1  || alluse <= 0 ) {
965                    if ( warning ) printmessage(stderr,CASE_WARNING,19,timestamp,"Data timeout must be numeric and > 0\n") ;
966                } else {
967                    datato = alluse ;
968                }
969            } else if (!strncmp(startcmd,"setoption",9)) {
970                /*
971                ** look for the option
972                */
973                startcmd = startcmd + 9 ;
974                while (*startcmd == ' ' && *startcmd != '\0' ) startcmd++ ;
975                if ( !strncmp(startcmd,"no",2) ) {
976                    nooption = SETTOONE ;
977                    startcmd = startcmd+2 ;
978                } else {
979                    nooption = SETTOZERO ;
980                }
981                if ( !strncmp(startcmd,"createdir",9) ) {
982                    if ( nooption ) {
983                        transferoption = transferoption & ~TROPT_DIR ;
984                    } else {
985                        transferoption = transferoption | TROPT_DIR ;
986                   }
987                } else if ( !strncmp(startcmd,"tmpfile",7) ) {
988                    if ( nooption ) {
989                        transferoption = transferoption & ~TROPT_TMP ;
990                    } else {
991                        transferoption = transferoption | TROPT_TMP ;
992                   }
993                } else if ( !strncmp(startcmd,"remoterfio",10) ) {
994                    if ( nooption ) {
995                        transferoption = transferoption & ~TROPT_RFIO ;
996                    } else {
997                        transferoption = transferoption | TROPT_RFIO ;
998                        if ( remotecos == -1 ) remotecos = 0;
999                    }
1000                } else if ( !strncmp(startcmd,"localrfio",9) ) {
1001                    if ( nooption ) {
1002                        transferoption = transferoption & ~TROPT_RFIO_O ;
1003                    } else {
1004#if defined(WITH_RFIO) || defined(WITH_RFIO64)
1005                        transferoption = transferoption | TROPT_RFIO_O ;
1006#else
1007                        if (warning) printmessage(stderr,CASE_WARNING,20,timestamp,"Incorrect command : setoption localrfio (RFIO not supported)\n",buffercmd) ;
1008#endif
1009                    }
1010                } else if ( !strncmp(startcmd,"keepmode",8) ) {
1011                    if ( nooption ) {
1012                        transferoption = transferoption & ~TROPT_MODE ;
1013                    } else {
1014                        transferoption = transferoption | TROPT_MODE ;
1015                    }
1016                } else if ( !strncmp(startcmd,"keepaccess",10) ) {
1017                    if ( nooption ) {
1018                        transferoption = transferoption & ~TROPT_ACC ;
1019                    } else {
1020                        transferoption = transferoption | TROPT_ACC ;
1021                    }
1022                } else if ( !strncmp(startcmd,"gzip",4) ) {
1023                    if ( nooption ) {
1024                        transferoption = transferoption & ~TROPT_GZIP ;
1025                    } else {
1026#ifdef WITH_GZIP                       
1027                        transferoption = transferoption | TROPT_GZIP ;
1028#else
1029                        printmessage(stderr,CASE_FATAL_ERROR,7,timestamp,"gzip option is not available: bbftp was built without compression support\n") ;
1030#endif                       
1031                    }
1032                } else if ( !strncmp(startcmd,"qbss",4) ) {
1033                    if ( nooption ) {
1034                        transferoption = transferoption & ~TROPT_QBSS ;
1035                    } else {
1036                        transferoption = transferoption | TROPT_QBSS ;
1037                    }
1038                } else {
1039                    if ( warning ) printmessage(stderr,CASE_WARNING,20,timestamp,"Unkown option in .bbftprc file (%s)\n",startcmd) ;
1040                }
1041            } else {
1042                if ( warning ) printmessage(stderr,CASE_WARNING,13,timestamp,"Unkown command in .bbftprc file (%s)\n",startcmd) ;
1043            }
1044            carret++ ;
1045        }
1046    }
1047#endif // NDG_PYTHON_EMBED
1048
1049/*
1050** Check for input file or command line
1051*/
1052    if ( inputfile == NULL && bbftpcmd == NULL ) {
1053        printmessage(stderr,CASE_FATAL_ERROR,20,timestamp,"Error on command line (-i or -e option are mandatory)\n") ;
1054    }
1055/*
1056** Open the input file if needed
1057*/
1058    if ( inputfile != NULL ) {
1059        if ( (infd = open(inputfile,O_RDONLY)) < 0 ) {
1060            printmessage(stderr,CASE_FATAL_ERROR,21,timestamp,"Error opening input file (%s) : %s\n",inputfile,strerror(errno)) ;
1061        }
1062#ifdef DARWIN
1063                if ( (resfd = open(resultfile,O_CREAT|O_WRONLY|O_TRUNC,0777)) < 0 ) {
1064#else
1065        if ( (resfd = open(resultfile,O_CREAT|O_WRONLY|O_SYNC|O_TRUNC,0777)) < 0 ) {
1066#endif
1067                printmessage(stderr,CASE_FATAL_ERROR,22,timestamp,"Error opening result file (%s) : %s\n",resultfile,strerror(errno)) ;
1068        }
1069        /*
1070        ** Now calc the max line of the input file in order to malloc
1071        ** the buffer
1072        */
1073        maxlen = 0 ;
1074        j = 0 ;
1075        while ( (lengthread = read (infd,calcmaxline,1)) == 1 ) {
1076            if ( calcmaxline[0] == 10 ) {
1077                if ( j > maxlen ) {
1078                    maxlen = j  ;
1079                }
1080                j = 0 ;
1081            } else {
1082                j++ ;
1083            }
1084        }
1085        if ( lengthread < 0 ) {
1086            printmessage(stderr,CASE_FATAL_ERROR,24,timestamp,"Error reading input file (%s) : %s\n",inputfile,strerror(errno)) ;
1087        } else if ( lengthread == 0 ) {
1088            if ( j > maxlen ) {
1089                maxlen = j  ;
1090            }
1091        }
1092       /*
1093        ** Reset the file at start position
1094        */
1095        lseek(infd,0,SEEK_SET) ;
1096        if ( (buffercmd = (char *) malloc (maxlen+2) ) == NULL ) {
1097            printmessage(stderr,CASE_FATAL_ERROR,23,timestamp,"Unable to malloc memory for command : %s\n",strerror(errno)) ;
1098        }
1099    } else {
1100        if ( (buffercmd = (char *) malloc (strlen(bbftpcmd)+1)) == NULL ) {
1101             printmessage(stderr,CASE_FATAL_ERROR,23,timestamp,"Unable to malloc memory for command : %s\n",strerror(errno)) ;
1102         }
1103    }
1104     
1105/*
1106** Check hostname
1107*/         
1108    if ( optind == argc-1 ) {
1109        hostname= argv[optind] ;
1110    } else {
1111        /*
1112         * Maybe a TURL format: get hostname from command
1113         */
1114        maxlen = 0 ;
1115        retcode = 0 ;
1116        while (retcode == 0 ) {
1117            if ( inputfile != NULL ) {
1118                j = 0 ;
1119                while ( (lengthread = read (infd,&buffercmd[j],1)) == 1 ) {
1120                    if ( buffercmd[j] == 10 ) {
1121                        buffercmd[j] = 0 ;
1122                        break ;
1123                    } else {
1124                        j++ ;
1125                    }
1126                }
1127                if ( lengthread < 0 ) {
1128                    printmessage(stderr,CASE_FATAL_ERROR,24,timestamp,"Error reading input file (%s) : %s\n",inputfile,strerror(errno)) ;
1129                } else if ( lengthread == 0 ) {
1130                    if ( j == 0 ) {
1131                        retcode = 1 ;
1132                        break ;
1133                    } else {
1134                        buffercmd[j+1] = 0 ;
1135                    }
1136                }
1137            } else {
1138                /*
1139                ** the command may be under the form cmd ; cmd ; cmd....
1140                */
1141                j = 0 ;
1142                while ((maxlen < strlen(bbftpcmd)) && (bbftpcmd[maxlen] == ' ')) maxlen++ ;
1143                while ( (maxlen < strlen(bbftpcmd)) && (bbftpcmd[maxlen] != ';') ) {
1144                    buffercmd[j] =  bbftpcmd[maxlen] ;
1145                    j++ ;
1146                    maxlen++ ;
1147                }
1148                if ( maxlen == strlen(bbftpcmd) ) retcode = 1 ;
1149                maxlen++ ;
1150                buffercmd[j] = 0 ;
1151            }
1152            if ( translatecommand(buffercmd, &newcmd, &hostname, &newcontrolport, &remoterfio, &localrfio) == 0 ) {
1153                    if (localrfio == 1 && ((transferoption & TROPT_RFIO_O)!=TROPT_RFIO_O) ) {
1154                        addCommand("setoption localrfio");
1155                        transferoption = transferoption | TROPT_RFIO_O ;
1156                    } else if (localrfio == 0 && ((transferoption & TROPT_RFIO_O)==TROPT_RFIO_O) ) {
1157                        addCommand("setoption nolocalrfio");
1158                        transferoption = transferoption & ~TROPT_RFIO_O ;
1159                    }
1160                    if (remoterfio == 1 && ((transferoption & TROPT_RFIO)!=TROPT_RFIO) ) {
1161                        addCommand("setoption remoterfio");
1162                        if ( remotecos == -1 ) remotecos = 0 ;
1163                        transferoption = transferoption | TROPT_RFIO ;
1164                    } else if (remoterfio == 0 && ((transferoption & TROPT_RFIO)==TROPT_RFIO) ) {
1165                        addCommand("setoption noremoterfio");
1166                        transferoption = transferoption & ~TROPT_RFIO ;
1167                    }
1168                    addCommand(newcmd);
1169            } else {
1170                    printmessage(stderr,CASE_FATAL_ERROR,24,timestamp,"Unable to parse command  : %s\n",buffercmd) ;
1171            }
1172        }
1173        commandList = first;
1174    }
1175    if (hostname == NULL || strlen(hostname) == 0) {
1176        Usage() ;
1177        printmessage(stderr,CASE_FATAL_ERROR,14,timestamp,"No hostname on command line\n") ;
1178    }   
1179/*
1180** Check if hostname is in numeric format
1181*/
1182    for (j=0 ; j < strlen(hostname) ; j++) {
1183        if ( isalpha(hostname[j]) ) {
1184            /*
1185            ** One alpha caractere means no numeric form
1186            */
1187            hosttype = 1 ;
1188            break ;
1189        } else if ( isdigit(hostname[j]) ) {
1190        } else if ( hostname[j] == '.' ) {
1191        } else {
1192            printmessage(stderr,CASE_FATAL_ERROR,15,timestamp,"Invalid hostname (%s)\n",hostname) ;
1193        }
1194    }
1195    if ( hosttype == 0 ) {
1196       /*
1197       ** Numeric format
1198       */
1199        hisctladdr.sin_addr.s_addr = 0 ;
1200        hisctladdr.sin_addr.s_addr = inet_addr(hostname) ;
1201        if (hisctladdr.sin_addr.s_addr == -1 ) {
1202            printmessage(stderr,CASE_FATAL_ERROR,16,timestamp,"Invalid IP address (%s)\n",hostname) ;
1203        }
1204        calchostname = (char *)inet_ntoa(hisctladdr.sin_addr) ;
1205        if ( strcmp(hostname,calchostname) ) {
1206            printmessage(stderr,CASE_FATAL_ERROR,16,timestamp,"Invalid IP address (%s)\n",hostname) ;
1207        }
1208    } else {
1209       /*
1210       ** Alpha format
1211       */
1212        if ( (hp = gethostbyname((char *)hostname) ) == NULL ) {
1213            printmessage(stderr,CASE_FATAL_ERROR,17,timestamp,"Hostname no found (%s)\n",hostname) ;
1214        } else {
1215            if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {
1216                hp->h_length = sizeof(hisctladdr.sin_addr);
1217            }
1218            memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length) ;
1219        }
1220    }
1221/*
1222** Check username if not in     certificate authentication mode
1223*/         
1224    if ( username == NULL ) {
1225#ifdef CERTIFICATE_AUTH
1226        if (usessh) {
1227/*            Usage() ;
1228            printmessage(stderr,CASE_FATAL_ERROR,18,timestamp,"No username given\n") ;*/
1229        } else {
1230            usecert = SETTOONE;
1231        }
1232#else       
1233        if (!usessh) {
1234            Usage() ;
1235            printmessage(stderr,CASE_FATAL_ERROR,18,timestamp,"No username given\n") ;
1236        }
1237#endif
1238    }
1239    if ( debug ) {
1240        if (simulation_mode) {
1241            printmessage(stdout,CASE_NORMAL,0,timestamp,"** SIMULATION MODE: No data written **\n") ;
1242        }
1243        printmessage(stdout,CASE_NORMAL,0,timestamp,"Starting parameters -----------------\n") ;
1244        printmessage(stdout,CASE_NORMAL,0,timestamp,"number of tries   = %d\n",globaltrymax) ;
1245        printmessage(stdout,CASE_NORMAL,0,timestamp,"number of streams = %d\n",nbport) ;
1246        printmessage(stdout,CASE_NORMAL,0,timestamp,"localumask        = %03o\n",localumask) ;
1247        printmessage(stdout,CASE_NORMAL,0,timestamp,"remoteumask       = %03o\n",remoteumask) ;
1248#if defined(WITH_RFIO) || defined(WITH_RFIO64)
1249        printmessage(stdout,CASE_NORMAL,0,timestamp,"localcos          = %d\n",localcos) ;
1250#endif
1251        printmessage(stdout,CASE_NORMAL,0,timestamp,"remotecos         = %d\n",remotecos) ;
1252        printmessage(stdout,CASE_NORMAL,0,timestamp,"buffersize        = %d KB\n",buffersizeperstream) ;
1253        printmessage(stdout,CASE_NORMAL,0,timestamp,"sendwinsize       = %d KB\n",sendwinsize) ;
1254        printmessage(stdout,CASE_NORMAL,0,timestamp,"recvwinsize       = %d KB\n",recvwinsize) ;
1255        printmessage(stdout,CASE_NORMAL,0,timestamp,"ackto                         = %d s\n",ackto) ;
1256        printmessage(stdout,CASE_NORMAL,0,timestamp,"recvcontrolto     = %d s\n",recvcontrolto) ;
1257        printmessage(stdout,CASE_NORMAL,0,timestamp,"sendcontrolto     = %d s\n",sendcontrolto) ;
1258        printmessage(stdout,CASE_NORMAL,0,timestamp,"datato     = %d s\n",datato) ;
1259                printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_DIR ) == TROPT_DIR) ? "createdir" : "nocreatedir") ;
1260                printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_TMP ) == TROPT_TMP) ? "tmpfile" : "notmpfile") ;
1261                printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_RFIO ) == TROPT_RFIO) ? "remoterfio" : "noremoterfio") ;
1262#if defined(WITH_RFIO) || defined(WITH_RFIO64)
1263                printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_RFIO_O ) == TROPT_RFIO_O) ? "localrfio" : "nolocalrfio") ;
1264#endif
1265                printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_MODE ) == TROPT_MODE) ? "keepmode" : "nokeepmode") ;
1266                printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_ACC ) == TROPT_ACC) ? "keepaccess" : "nokeepaccess") ;
1267#ifdef WITH_GZIP
1268                printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_GZIP ) == TROPT_GZIP) ? "gzip" : "nogzip") ;
1269#endif       
1270                printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_QBSS ) == TROPT_QBSS) ? "qbss" : "noqbss") ;
1271        printmessage(stdout,CASE_NORMAL,0,timestamp,"-------------------------------------\n") ;
1272        printmessage(stdout,CASE_NORMAL,0,timestamp,"Connection mode ---------------------\n") ;
1273        if ( usecert ) {
1274/*                      if ( username == NULL ) {*/
1275                                printmessage(stdout,CASE_NORMAL,0,timestamp,"Using certificate authentication\n") ;
1276/*                      } else {
1277                                printmessage(stdout,CASE_NORMAL,0,timestamp,"Using standard bbftp mode\n") ;
1278                        }*/
1279        } else if ( useprivate ) {
1280            printmessage(stdout,CASE_NORMAL,0,timestamp,"Using private authentication\n") ;
1281        } else if ( usessh) {
1282            printmessage(stdout,CASE_NORMAL,0,timestamp,"Using ssh mode\n") ;
1283            printmessage(stdout,CASE_NORMAL,0,timestamp,"     ssh command        = %s \n",sshcmd) ;
1284            printmessage(stdout,CASE_NORMAL,0,timestamp,"     ssh remote command = %s \n",sshremotecmd) ;
1285        } else {
1286            printmessage(stdout,CASE_NORMAL,0,timestamp,"Using standard bbftp mode\n",localumask) ;
1287        }
1288        printmessage(stdout,CASE_NORMAL,0,timestamp,"-------------------------------------\n") ;
1289   }
1290
1291/*
1292** Ask for password if not in ssh mode
1293*/
1294#ifdef PRIVATE_AUTH
1295    if ( bbftp_private_getargs(logmessage) < 0 ) {
1296        printmessage(stderr,CASE_FATAL_ERROR,19,timestamp,"Error while private authentication : %s\n",logmessage) ;
1297    }     
1298#else
1299    if ((!usessh && !usecert)/* || (usecert && username)*/) {
1300# ifdef AFS
1301        char *reasonString, passwordBuffer[1024] ;
1302        long code ;
1303        if ( (code = ka_UserReadPassword("Password: ", passwordBuffer, sizeof(passwordBuffer), &reasonString)) ) {
1304            printmessage(stderr,CASE_FATAL_ERROR,19,timestamp,"Error while entering password\n") ;
1305        }
1306        if ( ( password = (char *) malloc (strlen(passwordBuffer) + 1) ) == NULL ) {
1307            printmessage(stderr,CASE_FATAL_ERROR,54,timestamp,"Unable to store password : malloc failed (%s)\n",strerror(errno)) ;
1308            return -1 ;
1309        }
1310        strcpy(password, passwordBuffer);
1311# else
1312#  ifdef USE_GETPASSPHRASE
1313        password = (char *) getpassphrase("Password: ") ;
1314        if ( strlen(password) == 0 ) {
1315            printmessage(stderr,CASE_FATAL_ERROR,19,timestamp,"Password is mandatory\n") ;
1316        }
1317#  else
1318        printmessage(stdout,CASE_NORMAL,0,0,"Password: ") ;
1319        password = (char *) getpass("") ;
1320#  endif /* USE_GETPASSPHRASE */
1321# endif /* AFS */
1322    }
1323#endif
1324/*
1325** Set in background if required
1326*/
1327    if ( background ) {
1328        retcode = fork() ; 
1329        if ( retcode < 0 ) printmessage(stderr,CASE_FATAL_ERROR,31,timestamp,"Error forking while setting in background\n") ;
1330        if ( retcode > 0 ) exit(0) ;
1331        setsid() ;
1332        if ( verbose ) printmessage(stdout,CASE_NORMAL,0,timestamp,"Starting under pid %d\n",getpid());
1333    }
1334
1335/*
1336** Set the signals
1337*/
1338    bbftp_setsignals() ;
1339
1340/*
1341 * Analyze command list or command file to populate commandList
1342 */
1343    if (commandList == NULL) {
1344      maxlen = 0 ;
1345      retcode = 0 ;
1346      while (retcode == 0 ) {
1347        if ( inputfile != NULL ) {
1348            j = 0 ;
1349            while ( (lengthread = read (infd,&buffercmd[j],1)) == 1 ) {
1350                if ( buffercmd[j] == 10 ) {
1351                    buffercmd[j] = 0 ;
1352                    break ;
1353                } else {
1354                    j++ ;
1355                }
1356            }
1357            if ( lengthread < 0 ) {
1358                printmessage(stderr,CASE_FATAL_ERROR,24,timestamp,"Error reading input file (%s) : %s\n",inputfile,strerror(errno)) ;
1359            } else if ( lengthread == 0 ) {
1360                if ( j == 0 ) {
1361                    retcode = 1 ;
1362                    break ;
1363                } else {
1364                    buffercmd[j+1] = 0 ;
1365                }
1366            }
1367        } else {
1368            /*
1369            ** the command may be under the form cmd ; cmd ; cmd....
1370            */
1371            j = 0 ;
1372            while ((maxlen < strlen(bbftpcmd)) && (bbftpcmd[maxlen] == ' ')) maxlen++ ;
1373            while ( (maxlen < strlen(bbftpcmd)) && (bbftpcmd[maxlen] != ';') ) {
1374                buffercmd[j] =  bbftpcmd[maxlen] ;
1375                j++ ;
1376                maxlen++ ;
1377            }
1378            if ( maxlen == strlen(bbftpcmd) ) retcode = 1 ;
1379            buffercmd[j] = 0 ;
1380            maxlen++ ;
1381        }
1382        addCommand(buffercmd);
1383        if ( !strncmp(buffercmd,"setoption remoterfio",20) ) {
1384            if ( remotecos == -1 ) remotecos = 0;
1385        }
1386      }
1387      commandList = first;
1388    }
1389/*
1390** Now we've got all informations to make the connection
1391*/
1392
1393    if ( debug )
1394        printmessage(stdout,CASE_NORMAL,0,timestamp,"Connecting to server ----------------\n",localumask) ;
1395    reconnecttoserver() ;
1396    if ( debug )
1397         printmessage(stdout,CASE_NORMAL,0,timestamp,"Connecting end ---------------------\n",localumask) ;
1398   
1399/*
1400** Start the infinite loop
1401*/
1402    {
1403      cmd_list *iterator;
1404      iterator = commandList;
1405      while (iterator != NULL) {
1406        if ( treatcommand(iterator->cmd) == 0 ) {
1407            if ( inputfile != NULL ) {
1408                write(resfd,iterator->cmd,strlen(iterator->cmd)) ;               
1409                write(resfd," OK\n",4) ;
1410            } else {
1411                if (!verbose && !statoutput) printmessage(stdout,CASE_NORMAL,0,timestamp,"%s OK\n",iterator->cmd);
1412            }
1413        } else {
1414            if ( inputfile != NULL ) {
1415                write(resfd,iterator->cmd,strlen(iterator->cmd)) ;               
1416                write(resfd," FAILED\n",8) ;
1417            } else {
1418                if (!verbose && !statoutput) printmessage(stdout,CASE_NORMAL,0,timestamp,"%s FAILED\n",iterator->cmd);
1419            }
1420        }
1421        iterator = iterator->next;
1422      }
1423    }
1424    if ( inputfile != NULL ) {
1425        close(infd) ;
1426        close(resfd) ;
1427    }
1428    msg = (struct message *)minbuffer ;
1429    msg->code = MSG_CLOSE_CONN ;
1430    msg->msglen = 0 ;
1431    /*
1432    ** We do not care of the result because this routine is called
1433    ** only at the end of the client
1434    */
1435    writemessage(outcontrolsock,minbuffer,MINMESSLEN,sendcontrolto,0) ;
1436    sleep(1) ;
1437    bbftp_close_control() ;
1438#ifndef NDG_PYTHON_EMBED
1439    exit(myexitcode) ;
1440#endif
1441}
Note: See TracBrowser for help on using the repository browser.