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

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

bbftpc.run() has been split into run(), docommand() and close().
Multiple commands per connection should now be possible.

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
176void bbftpc_final(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
192static void bbftpc_connect(void) {
193  /*
194  ** Set the signals
195  */
196  bbftp_setsignals() ;
197 
198 
199  if ( debug )
200    printmessage(stdout,CASE_NORMAL,0,timestamp,"Connecting to server ----------------\n",localumask) ;
201  reconnecttoserver() ;
202  if ( debug )
203    printmessage(stdout,CASE_NORMAL,0,timestamp,"Connecting end ---------------------\n",localumask) ;
204}
205
206int bbftpc_init(int argc, char **argv, char **envp) {
207  bbftpc_reset_globals();
208 
209  extern char *optarg;
210  extern int optind, opterr, optopt;
211  /*
212  ** Variable set by options
213  */
214  char    *outputfile = NULL ;
215  /*
216  ** For hostname
217  */ 
218  int     hosttype = 0 ;
219  char    *calchostname ;
220  /*
221  ** For local user
222  */
223  char    *bbftprcfile = NULL ;
224 
225  int     retcode ;
226  int     i, j, k ;
227  int     alluse ;
228  char    logmessage[1024] ;
229  /*
230  ** Get local umask
231  */
232  localumask = umask(0) ;
233  /*
234  ** and reset it to the correct value
235  */
236  umask(localumask) ;
237  /*
238  ** First check for timestamp in order to have a common output
239  */
240  opterr = 0 ;
241  while ((j = getopt(argc, argv, OPTIONS)) != -1) {
242    switch (j) {
243    case 't' :
244      timestamp = SETTOONE ;
245      break ; 
246    }
247  }
248 
249  useprivate = SETTOONE ;
250  usessh = SETTOZERO ;
251   
252  /*
253  ** Check for -v option
254  */
255  opterr = 0 ;
256  optind = 1 ;
257  while ((j = getopt(argc, argv, OPTIONS)) != -1) {
258    switch (j) {
259    case 'v' :
260      print_version();
261      exit(0) ; 
262    }
263  }
264   
265  /**
266   * @todo replace getopt arguments with python calls.
267   */
268 
269  /*
270  ** Now all the others
271  */
272  opterr = 0 ;
273  optind = 1 ;
274  while ((j = getopt(argc, argv, OPTIONS)) != -1) {
275    switch (j) {
276    case 'c' :
277#ifdef WITH_GZIP               
278      transferoption = transferoption | TROPT_GZIP ;
279#else
280      printmessage(stderr,CASE_FATAL_ERROR,7,timestamp,"option -c is not available: bbftp was built without compression utility\n") ;
281#endif               
282      break ;
283     
284    case 'd' :
285      debug = 1 ;
286      break ;
287     
288    case 'D' :
289      if (optarg) {
290        if ((sscanf(optarg,"%d:%d",&i, &k) == 2) && (i < k)) {
291          pasvport_min = i; pasvport_max = k;
292        } else {
293          printmessage(stderr,CASE_FATAL_ERROR,4,timestamp,"Invalid port range : %s\n",optarg) ;
294        }
295      } else {
296#ifdef PORT_RANGE
297        sscanf(PORT_RANGE,"%d:%d",&pasvport_min, &pasvport_max) ;
298#endif
299        if (0 == pasvport_max) {
300          pasvport_min = 0;
301          pasvport_max = 1;
302        }
303      }
304      protocolmax = 2 ;
305      break ;
306     
307    case 'm' :
308      statoutput = SETTOONE ;
309      break ;
310     
311    case 'n':
312      simulation_mode = SETTOONE ;
313      break ;
314     
315    case 'o' :
316      outputfile = optarg ;
317      break ;
318     
319    case 'P' :
320      privatestr = optarg ;
321      break ;
322     
323    case 'q' :
324      transferoption = transferoption | TROPT_QBSS ;
325      break ;
326     
327    case 'p' :
328      retcode = sscanf(optarg,"%d",&alluse) ;
329      if ( retcode != 1 || alluse < 0) {
330        printmessage(stderr,CASE_FATAL_ERROR,3,timestamp,"Number of streams must be numeric and > 0\n") ;
331      }
332      nbport = alluse ;
333      break ;
334     
335    case 'r' :
336      retcode = sscanf(optarg,"%d",&alluse) ;
337      if ( retcode != 1 || alluse <= 0) {
338        printmessage(stderr,CASE_FATAL_ERROR,4,timestamp,"Number of tries must be numeric > 0\n") ;
339      }
340      globaltrymax = alluse ;
341      break ;
342     
343    case 'R' :
344      bbftprcfile = optarg ;
345      break ;
346     
347    case 't' :
348      timestamp = SETTOONE ;
349      break ;
350     
351    case 'u' :
352      username = optarg ;
353      break ;
354     
355    case 'V':
356      verbose = SETTOONE ;
357      break ;
358     
359    case 'w' :
360      retcode = sscanf(optarg,"%d",&alluse) ;
361      if ( retcode != 1 || alluse <= 0) {
362        printmessage(stderr,CASE_FATAL_ERROR,4,timestamp,"Control port must be numeric\n") ;
363      }
364      newcontrolport = alluse ;
365      break ;
366     
367    case 'W':
368      warning = SETTOONE ;
369      break ;
370     
371    default :
372      Usage() ;
373      printmessage(stderr,CASE_FATAL_ERROR,6,timestamp,"Error on command line (unsupported option -%c)\n",optopt) ;
374     
375    }
376  }
377 
378  /*
379  ** Reset all outputs variable if statoutput is set to one
380  */
381  if ( statoutput ) {
382    debug     = SETTOZERO ;
383    verbose   = SETTOZERO ;
384    warning   = SETTOZERO ;
385    timestamp = SETTOZERO ;
386  }
387 
388
389 
390  /**
391   * @todo replace hostname code with something better.
392   */
393 
394  /*
395  ** Check hostname
396  */         
397  if ( optind == argc-1 ) {
398    hostname= argv[optind] ;
399  }
400  else {
401    printmessage(stderr,CASE_FATAL_ERROR,24,timestamp,"Unable to find hostname\n");
402  }
403  if (hostname == NULL || strlen(hostname) == 0) {
404    Usage() ;
405    printmessage(stderr,CASE_FATAL_ERROR,14,timestamp,"No hostname on command line\n") ;
406  }   
407  /*
408  ** Check if hostname is in numeric format
409  */
410  for (j=0 ; j < strlen(hostname) ; j++) {
411    if ( isalpha(hostname[j]) ) {
412      /*
413      ** One alpha caractere means no numeric form
414      */
415      hosttype = 1 ;
416      break ;
417    } else if ( isdigit(hostname[j]) ) {
418    } else if ( hostname[j] == '.' ) {
419    } else {
420      printmessage(stderr,CASE_FATAL_ERROR,15,timestamp,"Invalid hostname (%s)\n",hostname) ;
421    }
422  }
423  if ( hosttype == 0 ) {
424    /*
425    ** Numeric format
426    */
427    hisctladdr.sin_addr.s_addr = 0 ;
428    hisctladdr.sin_addr.s_addr = inet_addr(hostname) ;
429    if (hisctladdr.sin_addr.s_addr == -1 ) {
430      printmessage(stderr,CASE_FATAL_ERROR,16,timestamp,"Invalid IP address (%s)\n",hostname) ;
431    }
432    calchostname = (char *)inet_ntoa(hisctladdr.sin_addr) ;
433    if ( strcmp(hostname,calchostname) ) {
434      printmessage(stderr,CASE_FATAL_ERROR,16,timestamp,"Invalid IP address (%s)\n",hostname) ;
435    }
436  } else {
437    /*
438    ** Alpha format
439    */
440    if ( (hp = gethostbyname((char *)hostname) ) == NULL ) {
441      printmessage(stderr,CASE_FATAL_ERROR,17,timestamp,"Hostname no found (%s)\n",hostname) ;
442    } else {
443      if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {
444        hp->h_length = sizeof(hisctladdr.sin_addr);
445      }
446      memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length) ;
447    }
448  }
449  /*
450  ** Check username if not in   certificate authentication mode
451  */         
452  if ( username == NULL ) {
453    Usage() ;
454    printmessage(stderr,CASE_FATAL_ERROR,18,timestamp,"No username given\n") ;
455  }
456  if ( debug ) {
457    print_debug();
458  }
459 
460  if ( bbftp_private_getargs(logmessage) < 0 ) {
461    printmessage(stderr,CASE_FATAL_ERROR,19,timestamp,"Error while private authentication : %s\n",logmessage) ;
462  }     
463 
464  bbftpc_connect();
465}
466
Note: See TracBrowser for help on using the repository browser.