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

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

Eliminated many socket related compile time warnings. These
were due to missing #include statements in the bbftp source.

MOST test cases now succeed on callisto! cross-platform stability
is looking more optimistic :-)

Line 
1/*
2 * bbftpc/bbftpstatus.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#include <bbftp.h>
23
24#include <stdlib.h>
25
26#include <errno.h>
27#include <fcntl.h>
28#include <netdb.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
31#include <pwd.h>
32#include <stdio.h>
33#include <stdarg.h>
34#include <sys/stat.h>
35#include <sys/types.h>
36#include <sys/socket.h>
37#include <unistd.h>
38#if TIME_WITH_SYS_TIME
39# include <sys/time.h>
40# include <time.h>
41#else
42# if HAVE_SYS_TIME_H
43#  include <sys/time.h>
44# else
45#  include <time.h>
46# endif
47#endif
48#if HAVE_STRING_H
49# include <string.h>
50#endif
51
52#include <client.h>
53#include <client_proto.h>
54#include <common.h>
55#include <config.h>
56#include <structures.h>
57#include <version.h>
58
59#define SETTOZERO    0
60#define SETTOONE     1
61
62#ifdef PRIVATE_AUTH
63#define OPTIONS "qbcde:f:i:l:mno:p:P:r:R:tu:vVw:WD::"
64#else
65#define OPTIONS "qbcde:E:f:g:i:I:l:L:mno:p:r:R:sStu:vVw:WD::"
66#endif
67/*
68#endif
69*/
70
71int     newcontrolport = CONTROLPORT ;
72/*
73** hisctladdr:
74**      the remote address
75*/
76struct sockaddr_in hisctladdr ;
77/*
78** myctladdr:
79**      the local address
80*/
81struct sockaddr_in myctladdr ;
82
83int     incontrolsock ;
84int     outcontrolsock ;
85/*
86** myexitcode :
87**      Contains the first error code that has to be return when program
88**      is ended
89*/
90int     myexitcode = SETTOZERO ;
91char    *hostname   = NULL ;
92struct hostent  *hp = NULL ;
93char    *username   = NULL ;
94char    *password   = NULL ;
95/*
96**
97*/
98int connectionisbroken = SETTOZERO ;
99
100int     timestamp ;
101int     debug ;
102int             recvcontrolto   = CONTROLSOCKTO;
103int             sendcontrolto   = SENDCONTROLTO;
104
105void PRINTMESSAGE(FILE *strm , int flag, int errcode, int tok, char *fmt, ...) 
106{
107    va_list ap;
108    time_t  logtime ;
109    char    clogtime[50] ;
110   
111    va_start(ap,fmt);
112   
113    /*
114    ** If timestamp start to print the time
115    */
116    if (tok) {
117        /*
118        ** Get time
119        */
120        if ( time(&logtime) == -1 ) {
121            strcpy(clogtime,"") ;
122        } else {
123            if ( strftime(clogtime,sizeof(clogtime),"%a %b %d %H:%M:%S (%Z)",localtime(&logtime)) == 0 )    {
124                strcpy(clogtime,"") ;
125            }
126        }
127        /*
128        ** And print it
129        */
130        if ( strlen(clogtime) > 0 ) {
131            (void) fprintf(strm,"%s : ",clogtime) ;
132        }
133    }
134    /*
135    ** Check if it is an error
136    */
137    if ( flag == CASE_ERROR || flag == CASE_FATAL_ERROR ) {
138        /*
139        ** It is an error
140        */
141        (void) fprintf(strm,"BBFTP-ERROR-%05d : ",errcode) ;
142    } else if ( flag == CASE_WARNING ) {
143        /*
144        ** It is a warning
145        */
146        (void) fprintf(strm,"BBFTP-WARNING-%05d : ",errcode) ;
147    }
148    /*
149    ** And print the requested string
150    */
151    (void) vfprintf(strm, fmt, ap);
152    fflush(strm) ;
153    if ( flag == CASE_FATAL_ERROR ) {
154        /*
155        ** exit in case of error
156        */
157        exit(errcode) ;
158    }
159    va_end(ap);
160}
161
162void bbftp_close_control() 
163{
164
165    close(incontrolsock) ;
166    if ( incontrolsock != outcontrolsock) close(outcontrolsock) ;
167}
168
169main(argc, argv, envp)
170    int argc;
171    char **argv;
172    char **envp;
173{
174    extern char *optarg;
175    extern int optind, opterr, optopt;
176/*
177** Variable set by options
178*/
179    char    *inputfile  = NULL ;
180    char    *resultfile = NULL ;
181    char    *outputfile = NULL ;
182    char    *errorfile  = NULL ;
183    char    *bbftpcmd   = NULL ;
184    int     background  = SETTOZERO ;
185/*
186** For hostname
187*/ 
188    int     hosttype = 0 ;
189    char    *calchostname ;
190/*
191** For local user
192*/
193    struct  passwd  *mypasswd ;
194    char    *bbftprcfile = NULL ;
195    int     fd ;
196    char    *carret ;
197    char    *startcmd ;
198    int     nooption ;
199   
200    struct  stat    statbuf ;
201    int     retcode ;
202    int     i, j, k ;
203    int     stderrfd ;
204    int     stdoutfd ;
205    int     infd ;
206    char    calcmaxline[1] ;
207    int     maxlen ;
208    int     lengthread ;
209    char    *buffercmd ;
210    int     alluse ;
211    char    *tmpsshremotecmd ;
212    char    logmessage[1024] ;
213    char    minbuffer[MINMESSLEN] ;
214    struct  message *msg ;
215/*
216** Get local umask
217*/
218    /*localumask = umask(0) ;*/
219/*
220** and reset it to the correct value
221*/
222    /*umask(localumask) ;*/
223/*
224** Check for -v option
225*/
226    debug = 0 ;
227
228    opterr = 0 ;
229    optind = 1 ;
230    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
231        switch (j) {
232            case 'v' :{
233                fprintf(stdout,"bbftpstatus version %s\n",VERSION) ;
234                fprintf(stdout,"Compiled with  :   default port %d\n",CONTROLPORT) ;
235                exit(0) ;
236            }
237        }
238    }
239
240/*
241** Check for stderr replacement
242*/
243    opterr = 0 ;
244    optind = 1 ;
245    while ((j = getopt(argc, argv, OPTIONS)) != -1) {
246        switch (j) {
247            case 'w' :{
248                retcode = sscanf(optarg,"%d",&alluse) ;
249                if ( retcode != 1 || alluse <= 0) {
250                    fprintf(stderr,"Control port must be numeric\n") ;
251                    exit(1);
252                }
253                newcontrolport = alluse ;
254                break ;
255            }
256            default : {
257                fprintf(stderr,"Error on command line (unsupported option -%c)\n",optopt) ;
258                exit(1);
259            }
260        }
261    }
262/*
263** Check hostname
264*/         
265    if ( optind == argc-1 ) {
266        hostname= argv[optind] ;
267    } else {
268        fprintf(stderr,"No hostname on command line\n") ;
269        exit(1);
270    }   
271/*
272** Check if hostname is in numeric format
273*/
274    for (j=0 ; j < strlen(hostname) ; j++) {
275        if ( isalpha(hostname[j]) ) {
276            /*
277            ** One alpha caractere means no numeric form
278            */
279            hosttype = 1 ;
280            break ;
281        } else if ( isdigit(hostname[j]) ) {
282        } else if ( hostname[j] == '.' ) {
283        } else {
284            fprintf(stderr,"Invalid hostname (%s)\n",hostname) ;
285            exit(1);
286        }
287    }
288    if ( hosttype == 0 ) {
289       /*
290       ** Numeric format
291       */
292        hisctladdr.sin_addr.s_addr = 0 ;
293        hisctladdr.sin_addr.s_addr = inet_addr(hostname) ;
294        if (hisctladdr.sin_addr.s_addr == -1 ) {
295            fprintf(stderr,"Invalid IP address (%s)\n",hostname) ;
296            exit(1);
297        }
298        calchostname = (char *)inet_ntoa(hisctladdr.sin_addr) ;
299        if ( strcmp(hostname,calchostname) ) {
300            fprintf(stderr,"Invalid IP address (%s)\n",hostname) ;
301            exit(1);
302        }
303    } else {
304       /*
305       ** Alpha format
306       */
307        if ( (hp = gethostbyname((char *)hostname) ) == NULL ) {
308            fprintf(stderr,"Hostname no found (%s)\n",hostname) ;
309            exit(1);
310        } else {
311            if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {
312                hp->h_length = sizeof(hisctladdr.sin_addr);
313            }
314            memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length) ;
315        }
316    }
317
318/*
319** Now we've got all informations to make the connection
320*/
321
322   
323/*
324** Send the STATUS message
325*/
326    {
327    char    *buffer ;
328   
329    char    minbuffer[MINMESSLEN] ;
330    int     retcode ;
331    int     msglen ;
332    int     code ;
333    fd_set  selectmask ; /* Select mask */
334    int     nfds ; /* Max number of file descriptor */
335    struct  message *msg ;
336    struct  mess_integer *msg_integer ;
337   
338#if defined(HAVE_SOCKLEN_T)
339    socklen_t addrlen;
340#else
341#if defined(SUNOS) || defined(_HPUX_SOURCE) || defined(IRIX)
342    int     addrlen ;
343#else
344    size_t  addrlen ;
345#endif
346#endif
347    int     tmpctrlsock ;
348    char    *readbuffer ;
349
350    hisctladdr.sin_family = AF_INET;
351    hisctladdr.sin_port = htons(newcontrolport);
352    if ( (tmpctrlsock = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP )) < 0 ) {
353        PRINTMESSAGE(stderr,CASE_ERROR,51,timestamp, "Cannot create control socket : %s\n",strerror(errno));
354        return -1 ;
355    }
356    /*
357    ** Connect to the server
358    */
359    addrlen = sizeof(hisctladdr) ;
360    if ( connect(tmpctrlsock,(struct sockaddr*)&hisctladdr,addrlen) < 0 ) {
361        close(tmpctrlsock) ;
362        PRINTMESSAGE(stderr,CASE_ERROR,52,timestamp, "Cannot connect to control socket: %s\n",strerror(errno));
363        return -1 ;
364    }
365    /*
366    ** Get the socket name
367    */
368    addrlen = sizeof(myctladdr) ;
369    if (getsockname(tmpctrlsock,(struct sockaddr*) &myctladdr, &addrlen) < 0) {
370        close(tmpctrlsock) ;
371        PRINTMESSAGE(stderr,CASE_ERROR,53,timestamp,"Error getsockname on control socket: %s\n",strerror(errno)) ;
372        return -1 ;
373    }
374    /*
375    ** Connection is correct get the encryption
376    */
377
378        if (debug) PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Connection established\n") ;
379    /*
380    **    Read the encryption supported
381    */
382    if ( readmessage(tmpctrlsock,minbuffer,MINMESSLEN,recvcontrolto,0) < 0 ) {
383        close(tmpctrlsock) ;
384        PRINTMESSAGE(stderr,CASE_ERROR,54,timestamp,"Error reading encryption message\n") ;
385        return -1 ;
386    }
387    msg = (struct message *) minbuffer ;
388    if ( msg->code != MSG_CRYPT) {
389        close(tmpctrlsock) ;
390        PRINTMESSAGE(stderr,CASE_ERROR,55,timestamp,"No encryption message \n") ;
391        return -1 ;
392    }
393        if (debug) PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Received message 1\n") ;
394#ifndef WORDS_BIGENDIAN
395    msglen = ntohl(msg->msglen) ;
396#else
397    msglen = msg->msglen ;
398#endif
399    if ( ( readbuffer = (char *) malloc (msglen + 1) ) == NULL ) {
400        close(tmpctrlsock) ;
401        PRINTMESSAGE(stderr,CASE_ERROR,54,timestamp,"Error reading encryption message : malloc failed (%s)\n",strerror(errno)) ;
402        return -1 ;
403    }
404    if ( readmessage(tmpctrlsock,readbuffer,msglen,recvcontrolto,0) < 0 ) {
405        free(readbuffer) ;
406        close(tmpctrlsock) ;
407        PRINTMESSAGE(stderr,CASE_ERROR,56,timestamp,"Error reading encrypted message : %s\n","type") ;
408        return -1 ;
409    }
410        if (debug) PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Received message 2\n") ;
411    msg = (struct message *)minbuffer ;
412    msg->code = MSG_SERVER_STATUS ;
413#ifndef WORDS_BIGENDIAN
414    msg->msglen = ntohl(CRYPTMESSLEN+RSAMESSLEN) ;
415#else
416    msg->msglen = CRYPTMESSLEN+RSAMESSLEN ;
417#endif
418    if ( writemessage(tmpctrlsock,minbuffer,MINMESSLEN,sendcontrolto,0) < 0 ) {
419        /*
420        ** We were not able to send the minimum message so
421        ** we are going to close the control socket and to
422        ** tell the calling program to restart a connection
423        */
424        fprintf(stderr,"Error sending %s message\n","MSG_SERVER_STATUS");
425        close(tmpctrlsock) ;
426        return -1 ;
427    }
428        if (debug) PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"Sent message \n") ;
429    /*
430    ** Now we are going to wait for the message on the control
431    ** connection
432    */
433        if ( readmessage(tmpctrlsock,minbuffer,MINMESSLEN,recvcontrolto,0) < 0 ) {
434            fprintf(stderr,"Error waiting %s message\n","MSG_OK (on MSG_SERVER_STATUS)");
435            close(tmpctrlsock) ;
436            return -1 ;
437        }
438        msg = (struct message *) minbuffer ;
439        code = msg->code ;
440
441        if (msg->code == MSG_OK ) {
442            /*
443            */
444#ifndef WORDS_BIGENDIAN
445            msglen = ntohl(msg->msglen) ;
446#else
447            msglen = msg->msglen ;
448#endif
449            if ( (buffer = (char *) malloc(msglen+1) ) == NULL) {
450                fprintf(stderr,"Error allocating memory for %s : %s\n","buffer (bbftp_statfs)",strerror(errno)) ;
451                close(tmpctrlsock) ;
452                return -1 ;
453            }
454            if ( readmessage(tmpctrlsock,buffer,msglen,recvcontrolto,0) < 0) {
455                fprintf(stderr,"Error reading data for %s message\n","MSG_OK (on MSG_DF)");
456                free(buffer) ;
457                close(tmpctrlsock) ;
458                return -1 ;
459            } 
460            buffer[msglen] = '\0' ;
461            PRINTMESSAGE(stdout,CASE_NORMAL,0,timestamp,"%s\n", buffer) ;
462            free(buffer) ;
463            close(tmpctrlsock) ;
464            return 0 ;
465        } else {
466            /*
467            ** Receive unkwown message so something is
468            ** going wrong. close the control socket
469            ** and restart
470            */
471            fprintf(stderr,"The server cannot understand the STATUS command\n");
472            close(tmpctrlsock) ;
473            return -1 ;
474        }
475
476
477    msg = (struct message *)minbuffer ;
478    msg->code = MSG_CLOSE_CONN ;
479    msg->msglen = 0 ;
480    /*
481    ** We do not care of the result because this routine is called
482    ** only at the end of the client
483    */
484    writemessage(tmpctrlsock,minbuffer,MINMESSLEN,sendcontrolto,0) ;
485    sleep(1) ;
486    bbftp_close_control() ;
487    exit(0) ;
488    }
489}
Note: See TracBrowser for help on using the repository browser.