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

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/trunk/src/python_ext/bbftpc_main.c@1448
Revision 1265, 13.8 KB checked in by spascoe, 14 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 * 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.