source: TI05-delivery/trunk/src/python_ext/bbftpc_main.c @ 1242

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/trunk/src/python_ext/bbftpc_main.c@1242
Revision 1242, 14.1 KB checked in by spascoe, 15 years ago (diff)

bbftpc_main.c has been cut down further and split into static functions.
The client test cases now pass using this file instead of bbftp.c.

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 * This is a drop-in replacment for bbftp.c for use with NDG python
24 * embedding.  Together with bbftpc.h and bbftpc_globals.h it contains
25 * all code originally in bbftp.c that is required for the embedded
26 * client.  Since it is largely based on the original bbftp code I
27 * have retained the original copyright.  Most sections from bbftp.c
28 * are not relevent when embedding in python and have been removed.
29 * Support for ssh, CASTOR and RFIO has been removed.  The defines
30 * PRIVATE_AUTH and NDG_PYTHON_EMBED are assumed in this file.
31 *
32 * @author Stephen Pascoe
33 */
34
35#include "bbftpc.h"
36#include "bbftpc_globals.h"
37
38/**
39 * Reset all global variables to how they were first initialised.
40 */
41static void bbftpc_reset_globals(void) {
42
43  state   = SETTOZERO ;
44  timestamp = SETTOZERO ;
45 
46  protocolmin = 2 ; 
47  protocolmax = 3 ; 
48  //int     protocol ;
49  debug = SETTOZERO ;
50  verbose = SETTOZERO ;
51  warning = SETTOZERO ;
52  statoutput = SETTOZERO ;
53  globaltrymax = NBTRYMAX ;
54  newcontrolport = CONTROLPORT ;
55  usessh = SETTOZERO ;
56  sshbatchmode  = SETTOZERO ;
57  sshchildpid   = SETTOZERO ;
58  sshidentityfile = NULL ;
59  sshremotecmd = NULL ;
60  sshcmd = NULL ;
61 
62  usecert = SETTOZERO ;
63  useprivate = SETTOZERO ;
64  privatestr = NULL ;
65 
66  //struct sockaddr_in hisctladdr ;
67  //struct sockaddr_in myctladdr ;
68  bbftprc = NULL ;
69  //int     localumask ;
70 
71  newcmd = NULL;
72  //int remoterfio;
73  //int localrfio;
74  sendwinsize     = 256 ;
75  recvwinsize     = 256 ;
76  nbport = 1 ;
77  ackto                 = ACKTO;
78  recvcontrolto = CONTROLSOCKTO;
79  sendcontrolto = SENDCONTROLTO;
80  datato                        = DATASOCKTO;
81 
82  remoteumask = SETTOZERO ;
83  remotecos   = -1 ;
84  remotedir = NULL ;
85  //int     incontrolsock ;
86  //int     outcontrolsock ;
87  myexitcode = SETTOZERO ;
88  hostname   = NULL ;
89  hp = NULL ;
90  username   = NULL ;
91  password   = NULL ;
92  mychildren = NULL ;
93  //int     nbpidchild ;
94  transferoption = TROPT_TMP | TROPT_DIR | TROPT_MODE | TROPT_ACC; 
95  //int filemode ;
96  //char lastaccess[9] ;
97  //char lastmodif[9] ;
98  buffersizeperstream = 256 ;
99  //int     requestedstreamnumber ;
100  //my64_t  filesize ;
101  curfilename = NULL ;
102  realfilename   = NULL ;
103  myports        = NULL ;
104  mysockets      = NULL ;
105  readbuffer     = NULL ;
106  compbuffer     = NULL ; 
107  resfd = -1 ;
108  simulation_mode = SETTOZERO;
109 
110  connectionisbroken = SETTOZERO ;
111 
112  pasvport_min = 0 ;
113  pasvport_max = 0 ;
114 
115}
116
117
118static void print_version(void) {
119  printmessage(stdout,CASE_NORMAL,0,timestamp,"bbftp version %s\n",VERSION) ;
120  printmessage(stdout,CASE_NORMAL,0,timestamp,"Compiled with  :   default port %d\n",CONTROLPORT) ;
121#ifdef PORT_RANGE
122  printmessage(stdout,CASE_NORMAL,0,timestamp,"                   data ports range = %s \n", PORT_RANGE) ;
123#endif
124#ifdef WITH_GZIP
125  printmessage(stdout,CASE_NORMAL,0,timestamp,"                   compression with Zlib-%s\n", zlibVersion()) ;
126#endif
127#ifdef WITH_SSL
128  printmessage(stdout,CASE_NORMAL,0,timestamp,"                   encryption with %s \n",SSLeay_version(SSLEAY_VERSION)) ;
129#endif
130#ifdef AFS
131  printmessage(stdout,CASE_NORMAL,0,timestamp,"                   AFS authentication \n") ;
132#endif
133  printmessage(stdout,CASE_NORMAL,0,timestamp,"                   private authentication \n") ;
134  printmessage(stdout,CASE_NORMAL,0,timestamp,"                   Embedded in Python interpreter\n") ;
135 
136  printmessage(stdout,CASE_NORMAL,0,timestamp,"                   default number of tries = %d  \n",NBTRYMAX) ;
137  printmessage(stdout,CASE_NORMAL,0,timestamp,"                   default sendwinsize = %d Kbytes\n",sendwinsize) ;
138  printmessage(stdout,CASE_NORMAL,0,timestamp,"                   default recvwinsize = %d Kbytes\n",recvwinsize) ;
139  printmessage(stdout,CASE_NORMAL,0,timestamp,"                   default number of stream = %d \n",nbport) ;
140}
141
142
143static void print_debug(void) {
144  if (simulation_mode) {
145    printmessage(stdout,CASE_NORMAL,0,timestamp,"** SIMULATION MODE: No data written **\n") ;
146  }
147  printmessage(stdout,CASE_NORMAL,0,timestamp,"Starting parameters -----------------\n") ;
148  printmessage(stdout,CASE_NORMAL,0,timestamp,"number of tries   = %d\n",globaltrymax) ;
149  printmessage(stdout,CASE_NORMAL,0,timestamp,"number of streams = %d\n",nbport) ;
150  printmessage(stdout,CASE_NORMAL,0,timestamp,"localumask        = %03o\n",localumask) ;
151  printmessage(stdout,CASE_NORMAL,0,timestamp,"remoteumask       = %03o\n",remoteumask) ;
152  printmessage(stdout,CASE_NORMAL,0,timestamp,"remotecos         = %d\n",remotecos) ;
153  printmessage(stdout,CASE_NORMAL,0,timestamp,"buffersize        = %d KB\n",buffersizeperstream) ;
154  printmessage(stdout,CASE_NORMAL,0,timestamp,"sendwinsize       = %d KB\n",sendwinsize) ;
155  printmessage(stdout,CASE_NORMAL,0,timestamp,"recvwinsize       = %d KB\n",recvwinsize) ;
156  printmessage(stdout,CASE_NORMAL,0,timestamp,"ackto                       = %d s\n",ackto) ;
157  printmessage(stdout,CASE_NORMAL,0,timestamp,"recvcontrolto     = %d s\n",recvcontrolto) ;
158  printmessage(stdout,CASE_NORMAL,0,timestamp,"sendcontrolto     = %d s\n",sendcontrolto) ;
159  printmessage(stdout,CASE_NORMAL,0,timestamp,"datato     = %d s\n",datato) ;
160  printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_DIR ) == TROPT_DIR) ? "createdir" : "nocreatedir") ;
161  printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_TMP ) == TROPT_TMP) ? "tmpfile" : "notmpfile") ;
162  printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_RFIO ) == TROPT_RFIO) ? "remoterfio" : "noremoterfio") ;
163  printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_MODE ) == TROPT_MODE) ? "keepmode" : "nokeepmode") ;
164  printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_ACC ) == TROPT_ACC) ? "keepaccess" : "nokeepaccess") ;
165#ifdef WITH_GZIP
166  printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_GZIP ) == TROPT_GZIP) ? "gzip" : "nogzip") ;
167#endif       
168  printmessage(stdout,CASE_NORMAL,0,timestamp,"option %s\n", ((transferoption & TROPT_QBSS ) == TROPT_QBSS) ? "qbss" : "noqbss") ;
169  printmessage(stdout,CASE_NORMAL,0,timestamp,"-------------------------------------\n") ;
170  printmessage(stdout,CASE_NORMAL,0,timestamp,"Connection mode ---------------------\n") ;
171  printmessage(stdout,CASE_NORMAL,0,timestamp,"Using standard bbftp mode\n",localumask) ;
172  printmessage(stdout,CASE_NORMAL,0,timestamp,"-------------------------------------\n") ;
173}
174
175
176static void close_connection(void) {
177  char    minbuffer[MINMESSLEN] ;
178  struct  message *msg ;
179 
180  msg = (struct message *)minbuffer ;
181  msg->code = MSG_CLOSE_CONN ;
182  msg->msglen = 0 ;
183  /*
184  ** We do not care of the result because this routine is called
185  ** only at the end of the client
186  */
187  writemessage(outcontrolsock,minbuffer,MINMESSLEN,sendcontrolto,0) ;
188  sleep(1) ;
189  bbftp_close_control() ;
190}
191
192
193int bbftpc_main(int argc, char **argv, char **envp) {
194  bbftpc_reset_globals();
195 
196  extern char *optarg;
197  extern int optind, opterr, optopt;
198  /*
199  ** Variable set by options
200  */
201  char    *outputfile = NULL ;
202  char    *bbftpcmd   = NULL ;
203  /*
204  ** For hostname
205  */ 
206  int     hosttype = 0 ;
207  char    *calchostname ;
208  /*
209  ** For local user
210  */
211  char    *bbftprcfile = NULL ;
212 
213  int     retcode ;
214  int     i, j, k ;
215  int     alluse ;
216  char    logmessage[1024] ;
217  /*
218  ** Get local umask
219  */
220  localumask = umask(0) ;
221  /*
222  ** and reset it to the correct value
223  */
224  umask(localumask) ;
225  /*
226  ** First check for timestamp in order to have a common output
227  */
228  opterr = 0 ;
229  while ((j = getopt(argc, argv, OPTIONS)) != -1) {
230    switch (j) {
231    case 't' :
232      timestamp = SETTOONE ;
233      break ; 
234    }
235  }
236 
237  useprivate = SETTOONE ;
238  usessh = SETTOZERO ;
239   
240  /*
241  ** Check for -v option
242  */
243  opterr = 0 ;
244  optind = 1 ;
245  while ((j = getopt(argc, argv, OPTIONS)) != -1) {
246    switch (j) {
247    case 'v' :
248      print_version();
249      exit(0) ; 
250    }
251  }
252   
253  /**
254   * @todo replace getopt arguments with python calls.
255   */
256 
257  /*
258  ** Now all the others
259  */
260  opterr = 0 ;
261  optind = 1 ;
262  while ((j = getopt(argc, argv, OPTIONS)) != -1) {
263    switch (j) {
264    case 'c' :
265#ifdef WITH_GZIP               
266      transferoption = transferoption | TROPT_GZIP ;
267#else
268      printmessage(stderr,CASE_FATAL_ERROR,7,timestamp,"option -c is not available: bbftp was built without compression utility\n") ;
269#endif               
270      break ;
271     
272    case 'd' :
273      debug = 1 ;
274      break ;
275     
276    case 'D' :
277      if (optarg) {
278        if ((sscanf(optarg,"%d:%d",&i, &k) == 2) && (i < k)) {
279          pasvport_min = i; pasvport_max = k;
280        } else {
281          printmessage(stderr,CASE_FATAL_ERROR,4,timestamp,"Invalid port range : %s\n",optarg) ;
282        }
283      } else {
284#ifdef PORT_RANGE
285        sscanf(PORT_RANGE,"%d:%d",&pasvport_min, &pasvport_max) ;
286#endif
287        if (0 == pasvport_max) {
288          pasvport_min = 0;
289          pasvport_max = 1;
290        }
291      }
292      protocolmax = 2 ;
293      break ;
294     
295    case 'e' :
296      bbftpcmd = optarg ;
297      break ;
298           
299    case 'm' :
300      statoutput = SETTOONE ;
301      break ;
302     
303    case 'n':
304      simulation_mode = SETTOONE ;
305      break ;
306     
307    case 'o' :
308      outputfile = optarg ;
309      break ;
310     
311    case 'P' :
312      privatestr = optarg ;
313      break ;
314     
315    case 'q' :
316      transferoption = transferoption | TROPT_QBSS ;
317      break ;
318     
319    case 'p' :
320      retcode = sscanf(optarg,"%d",&alluse) ;
321      if ( retcode != 1 || alluse < 0) {
322        printmessage(stderr,CASE_FATAL_ERROR,3,timestamp,"Number of streams must be numeric and > 0\n") ;
323      }
324      nbport = alluse ;
325      break ;
326     
327    case 'r' :
328      retcode = sscanf(optarg,"%d",&alluse) ;
329      if ( retcode != 1 || alluse <= 0) {
330        printmessage(stderr,CASE_FATAL_ERROR,4,timestamp,"Number of tries must be numeric > 0\n") ;
331      }
332      globaltrymax = alluse ;
333      break ;
334     
335    case 'R' :
336      bbftprcfile = optarg ;
337      break ;
338     
339    case 't' :
340      timestamp = SETTOONE ;
341      break ;
342     
343    case 'u' :
344      username = optarg ;
345      break ;
346     
347    case 'V':
348      verbose = SETTOONE ;
349      break ;
350     
351    case 'w' :
352      retcode = sscanf(optarg,"%d",&alluse) ;
353      if ( retcode != 1 || alluse <= 0) {
354        printmessage(stderr,CASE_FATAL_ERROR,4,timestamp,"Control port must be numeric\n") ;
355      }
356      newcontrolport = alluse ;
357      break ;
358     
359    case 'W':
360      warning = SETTOONE ;
361      break ;
362     
363    default :
364      Usage() ;
365      printmessage(stderr,CASE_FATAL_ERROR,6,timestamp,"Error on command line (unsupported option -%c)\n",optopt) ;
366     
367    }
368  }
369 
370  /*
371  ** Reset all outputs variable if statoutput is set to one
372  */
373  if ( statoutput ) {
374    debug     = SETTOZERO ;
375    verbose   = SETTOZERO ;
376    warning   = SETTOZERO ;
377    timestamp = SETTOZERO ;
378  }
379 
380
381 
382  /**
383   * @todo replace hostname code with something better.
384   */
385 
386  /*
387  ** Check hostname
388  */         
389  if ( optind == argc-1 ) {
390    hostname= argv[optind] ;
391  }
392  else {
393    printmessage(stderr,CASE_FATAL_ERROR,24,timestamp,"Unable to find hostname\n");
394  }
395  if (hostname == NULL || strlen(hostname) == 0) {
396    Usage() ;
397    printmessage(stderr,CASE_FATAL_ERROR,14,timestamp,"No hostname on command line\n") ;
398  }   
399  /*
400  ** Check if hostname is in numeric format
401  */
402  for (j=0 ; j < strlen(hostname) ; j++) {
403    if ( isalpha(hostname[j]) ) {
404      /*
405      ** One alpha caractere means no numeric form
406      */
407      hosttype = 1 ;
408      break ;
409    } else if ( isdigit(hostname[j]) ) {
410    } else if ( hostname[j] == '.' ) {
411    } else {
412      printmessage(stderr,CASE_FATAL_ERROR,15,timestamp,"Invalid hostname (%s)\n",hostname) ;
413    }
414  }
415  if ( hosttype == 0 ) {
416    /*
417    ** Numeric format
418    */
419    hisctladdr.sin_addr.s_addr = 0 ;
420    hisctladdr.sin_addr.s_addr = inet_addr(hostname) ;
421    if (hisctladdr.sin_addr.s_addr == -1 ) {
422      printmessage(stderr,CASE_FATAL_ERROR,16,timestamp,"Invalid IP address (%s)\n",hostname) ;
423    }
424    calchostname = (char *)inet_ntoa(hisctladdr.sin_addr) ;
425    if ( strcmp(hostname,calchostname) ) {
426      printmessage(stderr,CASE_FATAL_ERROR,16,timestamp,"Invalid IP address (%s)\n",hostname) ;
427    }
428  } else {
429    /*
430    ** Alpha format
431    */
432    if ( (hp = gethostbyname((char *)hostname) ) == NULL ) {
433      printmessage(stderr,CASE_FATAL_ERROR,17,timestamp,"Hostname no found (%s)\n",hostname) ;
434    } else {
435      if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {
436        hp->h_length = sizeof(hisctladdr.sin_addr);
437      }
438      memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length) ;
439    }
440  }
441  /*
442  ** Check username if not in   certificate authentication mode
443  */         
444  if ( username == NULL ) {
445    Usage() ;
446    printmessage(stderr,CASE_FATAL_ERROR,18,timestamp,"No username given\n") ;
447  }
448  if ( debug ) {
449    print_debug();
450  }
451 
452  if ( bbftp_private_getargs(logmessage) < 0 ) {
453    printmessage(stderr,CASE_FATAL_ERROR,19,timestamp,"Error while private authentication : %s\n",logmessage) ;
454  }     
455   
456  /*
457  ** Set the signals
458  */
459  bbftp_setsignals() ;
460 
461 
462  if ( debug )
463    printmessage(stdout,CASE_NORMAL,0,timestamp,"Connecting to server ----------------\n",localumask) ;
464  reconnecttoserver() ;
465  if ( debug )
466    printmessage(stdout,CASE_NORMAL,0,timestamp,"Connecting end ---------------------\n",localumask) ;
467 
468  if ( treatcommand(bbftpcmd) == 0 ) {
469    if (!verbose && !statoutput) printmessage(stdout,CASE_NORMAL,0,timestamp,"%s OK\n",bbftpcmd);
470  } else {
471    if (!verbose && !statoutput) printmessage(stdout,CASE_NORMAL,0,timestamp,"%s FAILED\n",bbftpcmd);
472  }
473 
474  close_connection();
475}
476
Note: See TracBrowser for help on using the repository browser.