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

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

Several more includes missing. Stand alone daemon/client are now built
with more warnings displayed.

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