source: TI05-delivery/trunk/src/bbftp-server-3.2.0/bbftpd/bbftpd_readcontrol.c @ 987

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/trunk/src/bbftp-server-3.2.0/bbftpd/bbftpd_readcontrol.c@987
Revision 987, 50.5 KB checked in by spascoe, 13 years ago (diff)

Closer inspection of the bbftp code reveals I'll need to refactor the
authz interface slightly. bbftpd_private_authz has been renamed
bbftpd_private_authz_control with a slightly different prototype.
This function now doesn't authorise store/retrieve requests.

Line 
1/*
2 * bbftpd/bbftpd_readcontrol.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
24 
25 RETURN:
26         0  calling program return to main loop
27        -1 calling program exit
28 
29 bbftpd_readcontrol.c   v 2.0.0 2000/12/19  - Routine creation
30                        v 2.0.1 2001/04/23  - Correct indentation
31                        v 2.0.2 2001/05/04  - Correct return code treatment
32                                            - Correct case of file size 0
33                        v 2.1.0 2001/05/30  - Correct syslog level
34                                            - Change routines name
35                        v 2.2.0 2001/11/21  - Remote COS received can be -1
36               
37*****************************************************************************/
38#include <bbftpd.h>
39
40#include <errno.h>
41
42#include <stdio.h>
43#include <syslog.h>
44#include <utime.h>
45#include <sys/types.h>
46#include <unistd.h>
47#if HAVE_STRING_H
48# include <string.h>
49#endif
50
51#include <netinet/in.h>
52#include <common.h>
53#include <daemon.h>
54#include <daemon_proto.h>
55#include <status.h>
56#include <structures.h>
57#include <version.h>
58
59extern int  state ;
60extern int  incontrolsock ;
61extern int  outcontrolsock ;
62extern  int     recvcontrolto ;
63extern  int     sendcontrolto ;
64extern char *curfilename ;
65extern char *realfilename ;
66extern int  curfilenamelen ;
67extern int  transferoption ;
68extern int  filemode ;
69extern char lastaccess[9] ;
70extern char lastmodif[9] ;
71extern int  sendwinsize ;       
72extern int  recvwinsize ;       
73extern int  buffersizeperstream ;
74extern int  requestedstreamnumber ;
75extern my64_t  filesize ;
76extern int  *myports ;
77extern int  *mychildren ;
78extern int  *mysockets ;
79extern int  myumask ;
80extern int  mycos ;
81extern char *readbuffer ;
82extern char *compbuffer ;
83extern int  protocolversion ;
84extern  char            currentusername[MAXLEN] ;
85
86#ifndef WORDS_BIGENDIAN
87# ifndef HAVE_NTOHLL
88my64_t    ntohll(my64_t v) ;
89# endif
90#endif
91
92int bbftpd_readcontrol(int msgcode,int msglen) 
93{
94
95    int        retcode ;
96    int        i ;
97    char    *receive_buffer ;
98    int     oldumask, newumask ;
99    struct  message *msg ;
100    struct  mess_store_v2 *msg_store_v2 ;
101    struct  mess_integer *msg_integer ;
102    struct  mess_dir *msg_dir ;
103    char    logmessage[1024] ;
104    int     *portfree ;
105    struct utimbuf ftime ;
106    int     *porttosend ;   
107    /*
108    ** Depending on the state the accepted message may be different
109    */
110#ifndef WORDS_BIGENDIAN
111    msglen = ntohl(msglen) ;
112#endif
113    switch (state) {
114        /*
115        ** Case S_LOGGED :
116        **      Nothing is going on, so message accepted are :
117        **
118        **         MSG_CHCOS
119        **         MSG_CHDIR_V2
120        **         MSG_CHUMASK
121        **         MSG_CLOSE_CONN
122        **         MSG_LIST_V2
123        **         MSG_MKDIR_V2
124        **         MSG_RETR_V2
125        **         MSG_STORE_V2
126        **
127        */
128           case S_LOGGED : {
129            switch (msgcode) {
130           
131                case MSG_CHCOS : {
132                    syslog(BBFTPD_DEBUG,"Receiving MSG_CHCOS, msglen = %d",msglen) ;
133                    if ( (receive_buffer = (char *) malloc (msglen)) == NULL ) {
134                        syslog(BBFTPD_ERR,"Error allocating memory for MSG_CHCOS : %s",strerror(errno)) ;
135                        reply(MSG_BAD,"Error allocating memory for MSG_CHCOS") ;
136                        return 0 ;
137                    }
138                    if ( readmessage(incontrolsock,receive_buffer,msglen,recvcontrolto) < 0 ) {
139                        syslog(BBFTPD_ERR,"Error reading MSG_CHCOS") ;
140                        FREE(receive_buffer) ;
141                        return -1 ;
142                    }
143                    msg_integer = (struct  mess_integer *) receive_buffer ;
144#ifndef WORDS_BIGENDIAN
145                    mycos = ntohl(msg_integer->myint) ;
146#else
147                    mycos = msg_integer->myint ;
148#endif
149                    if (mycos>=0) {
150                        syslog(BBFTPD_DEBUG,"Cos set to %d",mycos) ;
151                        reply(MSG_OK,"COS set") ;
152                    } else {
153                        syslog(BBFTPD_DEBUG,"Cos received : %d",mycos) ;
154                        reply(MSG_OK,"COS not set") ;
155                    }
156                    FREE(receive_buffer) ;
157                    return 0 ;
158               }
159
160                case MSG_CHDIR_V2 : {
161                    syslog(BBFTPD_DEBUG,"Receiving MSG_CHDIR_V2, msglen = %d",msglen) ;
162                    retcode = bbftpd_cd(incontrolsock,msglen) ;
163                    return retcode ;
164                }
165               
166                case MSG_CHUMASK : {
167                    syslog(BBFTPD_DEBUG,"Receiving MSG_UMASK ") ;
168                    if ( (receive_buffer = (char *) malloc (msglen)) == NULL ) {
169                        syslog(BBFTPD_ERR,"Error allocating memory for MSG_UMASK : %s",strerror(errno)) ;
170                        reply(MSG_BAD,"Error allocating memory for MSG_UMASK") ;
171                        return 0 ;
172                    }
173                    if ( readmessage(incontrolsock,receive_buffer,msglen,recvcontrolto) < 0 ) {
174                        syslog(BBFTPD_ERR,"Error reading MSG_UMASK") ;
175                        FREE(receive_buffer) ;
176                        return -1 ;
177                    }
178                    msg_integer = (struct  mess_integer *) receive_buffer ;
179#ifndef WORDS_BIGENDIAN
180                    myumask = ntohl(msg_integer->myint) ;
181#else
182                    myumask = msg_integer->myint ;
183#endif
184                    /*
185                    ** We reset the umask first then call twice the umask
186                    ** in order to see the real umask set
187                    */
188                    oldumask = umask(0) ;
189                    umask(myumask) ;
190                    newumask = umask(myumask) ;
191                    sprintf(logmessage,"umask changed from %04o to %04o",oldumask,newumask) ;
192                    reply(MSG_OK,logmessage) ;
193                    FREE(receive_buffer) ;
194                    return 0 ;
195                }
196 
197                case MSG_CLOSE_CONN : {
198                    syslog(BBFTPD_DEBUG,"Receiving MSG_CLOSE_CONN, msglen = %d",msglen) ;
199                    return -1 ;
200                }
201               
202               
203                case MSG_LIST_V2 :{
204                   syslog(BBFTPD_DEBUG,"Receiving MSG_LIST_V2 ") ;
205                   if ( (receive_buffer = (char *) malloc (msglen+1) ) == NULL ) {
206                        syslog(BBFTPD_ERR,"Unable to malloc space for directory name (%d)",msglen) ;
207                        reply(MSG_BAD,"Unable to malloc space for directory name") ;
208                       return 0 ;
209                   }
210                  /*
211                   ** Read the characteristics of the directory
212                   */
213                   if ( readmessage(incontrolsock,receive_buffer,msglen,recvcontrolto) < 0 ) {
214                       /*
215                       ** Error ...
216                       */
217                        syslog(BBFTPD_ERR,"Error reading directory name") ;
218                       FREE(receive_buffer) ;
219                       return -1 ;
220                   }
221                   /*
222                   ** buffer contains the directory to create
223                   */
224                   receive_buffer[msglen] = '\0' ;
225                   msg_dir = (struct mess_dir *) receive_buffer ;
226#ifdef NDG_AUTH
227                    if (bbftpd_private_authz_control(msgcode, msg_dir->transferoption, msg_dir->dirname,
228                                                     logmessage) != 0) {
229                      syslog(BBFTPD_ERR, logmessage);
230                      reply(MSG_BAD, logmessage);
231                      FREE(receive_buffer);
232                      return 0;
233                    }
234#endif // NDG_AUTH
235                   transferoption  = msg_dir->transferoption ;
236                   syslog(BBFTPD_DEBUG,"Pattern = %s",msg_dir->dirname) ;
237                   retcode = bbftpd_list(msg_dir->dirname,logmessage) ;
238                   FREE(receive_buffer) ;
239                   return retcode ;
240                }
241               
242                case MSG_MKDIR_V2 : {
243                    syslog(BBFTPD_DEBUG,"Receiving MSG_MKDIR_V2 ") ;
244                    retcode = bbftpd_mkdir(incontrolsock,msglen) ;
245                    return retcode ;
246                }
247               
248                case MSG_RM : {
249                    syslog(BBFTPD_DEBUG,"Receiving MSG_RM ") ;
250                    retcode = bbftpd_rm(incontrolsock,msglen) ;
251                    return retcode ;
252                }
253               
254                case MSG_STAT : {
255                    syslog(BBFTPD_DEBUG,"Receiving MSG_STAT ") ;
256                    retcode = bbftpd_stat(incontrolsock,msglen) ;
257                    return retcode ;
258                }
259                   
260                case MSG_DF : {
261                    syslog(BBFTPD_DEBUG,"Receiving MSG_DF ") ;
262                    retcode = bbftpd_statfs(incontrolsock,msglen) ;
263                    return retcode ;
264                }
265                   
266                case MSG_RETR_V2 : {
267                    syslog(BBFTPD_DEBUG,"Receiving MSG_RETR_V2") ;
268                    if ( (receive_buffer = (char *) malloc (msglen)) == NULL ) {
269                        syslog(BBFTPD_ERR,"Error allocating memory for MSG_RETR_V2 : %s",strerror(errno)) ;
270                        return -1 ;
271                    }
272                     if ( readmessage(incontrolsock,receive_buffer,msglen,recvcontrolto) < 0 ) {
273                        syslog(BBFTPD_ERR,"Error reading MSG_RETR_V2") ;
274                        FREE(receive_buffer) ;
275                        return -1 ;
276                    }
277                    msg_store_v2 = (struct  mess_store_v2 *) receive_buffer ;
278
279                    /*
280                    ** Set up the transfer parameter, we are going only to store
281                    ** them
282                    */
283#ifndef WORDS_BIGENDIAN
284                    transferoption          = msg_store_v2->transferoption ;
285                    sendwinsize             = ntohl(msg_store_v2->sendwinsize) ;
286                    recvwinsize             = ntohl(msg_store_v2->recvwinsize) ;
287                    buffersizeperstream     = ntohl(msg_store_v2->buffersizeperstream) ;
288                    requestedstreamnumber   = ntohl(msg_store_v2->nbstream) ;
289#else
290                    transferoption          = msg_store_v2->transferoption ;
291                    sendwinsize             = msg_store_v2->sendwinsize ;
292                    recvwinsize             = msg_store_v2->recvwinsize ;
293                    buffersizeperstream     = msg_store_v2->buffersizeperstream ;
294                    requestedstreamnumber   = msg_store_v2->nbstream ;
295#endif
296                    syslog(BBFTPD_DEBUG,"transferoption         = %d ",transferoption) ;
297                    syslog(BBFTPD_DEBUG,"sendwinsize            = %d ",sendwinsize) ;
298                    syslog(BBFTPD_DEBUG,"recvwinsize            = %d ",recvwinsize) ;
299                    syslog(BBFTPD_DEBUG,"buffersizeperstream    = %d ",buffersizeperstream) ;
300                    syslog(BBFTPD_DEBUG,"requestedstreamnumber  = %d ",requestedstreamnumber) ;
301                    state = S_WAITING_FILENAME_RETR ;
302                    FREE(receive_buffer) ;
303                    return 0 ;
304                }
305               
306                case MSG_STORE_V2 :{
307                    syslog(BBFTPD_DEBUG,"Receiving MSG_STORE_V2") ;
308                    if ( (receive_buffer = (char *) malloc (msglen)) == NULL ) {
309                        syslog(BBFTPD_ERR,"Error allocating memory for MSG_STORE_V2 : %s",strerror(errno)) ;
310                        return -1 ;
311                    }
312                     if ( readmessage(incontrolsock,receive_buffer,msglen,recvcontrolto) < 0 ) {
313                        syslog(BBFTPD_ERR,"Error reading MSG_STORE_V2") ;
314                        FREE(receive_buffer) ;
315                        return -1 ;
316                    }
317                    msg_store_v2 = (struct  mess_store_v2 *) receive_buffer ;
318
319                    /*
320                    ** Set up the transfer parameter, we are going only to store
321                    ** them
322                    */
323#ifndef WORDS_BIGENDIAN
324                    transferoption          = msg_store_v2->transferoption ;
325                    filemode                = ntohl(msg_store_v2->filemode) ;
326                    strncpy(lastaccess,msg_store_v2->lastaccess,8) ;
327                    lastaccess[8] = '\0' ;
328                    strncpy(lastmodif,msg_store_v2->lastmodif,8) ;
329                    lastmodif[8] = '\0' ;
330                    sendwinsize             = ntohl(msg_store_v2->sendwinsize) ;
331                    recvwinsize             = ntohl(msg_store_v2->recvwinsize) ;
332                    buffersizeperstream     = ntohl(msg_store_v2->buffersizeperstream) ;
333                    requestedstreamnumber   = ntohl(msg_store_v2->nbstream) ;
334                    filesize                = ntohll(msg_store_v2->filesize) ;
335#else
336                    transferoption          = msg_store_v2->transferoption ;
337                    filemode                = msg_store_v2->filemode ;
338                    strncpy(lastaccess,msg_store_v2->lastaccess,8) ;
339                    lastaccess[8] = '\0' ;
340                    strncpy(lastmodif,msg_store_v2->lastmodif,8) ;
341                    lastmodif[8] = '\0' ;
342                    sendwinsize             = msg_store_v2->sendwinsize ;
343                    recvwinsize             = msg_store_v2->recvwinsize ;
344                    buffersizeperstream     = msg_store_v2->buffersizeperstream ;
345                    requestedstreamnumber   = msg_store_v2->nbstream ;
346                    filesize                = msg_store_v2->filesize ;
347#endif
348                    syslog(BBFTPD_DEBUG,"transferoption         = %d ",transferoption) ;
349                    syslog(BBFTPD_DEBUG,"filemode               = %d ",filemode) ;
350                    syslog(BBFTPD_DEBUG,"lastaccess             = %s ",lastaccess) ;
351                    syslog(BBFTPD_DEBUG,"lastmodif              = %s ",lastmodif) ;
352                    syslog(BBFTPD_DEBUG,"sendwinsize            = %d ",sendwinsize) ;
353                    syslog(BBFTPD_DEBUG,"recvwinsize            = %d ",recvwinsize) ;
354                    syslog(BBFTPD_DEBUG,"buffersizeperstream    = %d ",buffersizeperstream) ;
355                    syslog(BBFTPD_DEBUG,"requestedstreamnumber  = %d ",requestedstreamnumber) ;
356                    syslog(BBFTPD_DEBUG,"filesize               = %" LONG_LONG_FORMAT " ",filesize) ;
357                    state = S_WAITING_FILENAME_STORE ;
358                    FREE(receive_buffer) ;
359                    return 0 ;
360                }
361               
362                default :{
363                    syslog(BBFTPD_ERR,"Unkown message in logged state %d",msgcode) ;
364                    retcode = discardmessage(incontrolsock,msglen,recvcontrolto) ;
365                    reply(MSG_BAD_NO_RETRY,"Unkown message in S_LOGGED state") ;
366                    return retcode ;
367                }
368            }
369        }
370        /*
371        ** Case S_WAITING_FILENAME_STORE
372        **
373        **         MSG_FILENAME
374        */
375           case S_WAITING_FILENAME_STORE : {
376            switch (msgcode) {
377                case MSG_FILENAME :{
378                    syslog(BBFTPD_DEBUG,"Receiving MSG_FILENAME in S_WAITING_FILENAME_STORE state") ;
379                    if ( msglen == 0 ) {
380                         syslog(BBFTPD_ERR,"Filename length null") ;
381                         return -1 ;
382                    }
383                    if ( (curfilename = (char *) malloc (msglen+1)) == NULL ) {
384                        syslog(BBFTPD_ERR,"Error allocating memory for filename : %s",strerror(errno)) ;
385                        return -1 ;
386                    }
387                    /* tmp name = <name>.bbftp.tmp.<hostname in 10 chars>.<pid in 5 chars> */
388                    if ( (realfilename = (char *) malloc (msglen+30)) == NULL ) {
389                        syslog(BBFTPD_ERR,"Error allocating memory for realfilename : %s",strerror(errno)) ;
390                        free_all_var() ;
391                        return -1 ;
392                    }
393                    if ( readmessage(incontrolsock,curfilename,msglen,recvcontrolto) < 0 ) {
394                        syslog(BBFTPD_ERR,"Error reading filename") ;
395                        free_all_var() ;
396                        return -1 ;
397                    }
398                    curfilename[msglen] = '\0' ;
399                    curfilenamelen = msglen ;
400                    syslog(BBFTPD_DEBUG,"Request to store file %s",curfilename) ;
401                    if ( (retcode = bbftpd_storecheckoptions(logmessage)) < 0 ) {
402                        syslog(BBFTPD_ERR,logmessage) ;
403                        reply(MSG_BAD_NO_RETRY,logmessage) ;
404                        free_all_var() ;
405                        state = S_LOGGED ;
406                        return 0 ;
407                    }
408                    /*
409                    ** Options are corrects
410                    */
411                    if ( (transferoption & TROPT_TMP ) == TROPT_TMP ) {
412                        /*
413                        ** Caculate tempfile name if TROPT_TMP is set
414                        ** To avoid multiple access to temp file in HPSS
415                        ** file is called .bbftp.tmp.$host.$pid
416                        */
417                        char hostname[10 + 1];
418                        if (gethostname(hostname, sizeof(hostname)) < 0) {
419                                sprintf(realfilename,"%s.bbftp.tmp.%d",curfilename,getpid());
420                        } else {
421                                hostname[sizeof(hostname) - 1] = '\0';
422                                sprintf(realfilename,"%s.bbftp.tmp.%s.%d",curfilename,hostname,getpid()) ;
423                        }
424                    } else {
425                        sprintf(realfilename,"%s",curfilename) ;
426                    }
427                    /*
428                    ** Create the file
429                    */
430                    if ( (retcode = bbftpd_storecreatefile(realfilename,logmessage)) < 0 ) {
431                        syslog(BBFTPD_ERR,logmessage) ;
432                        reply(MSG_BAD_NO_RETRY,logmessage) ;
433                        free_all_var() ;
434                        state = S_LOGGED ;
435                        return 0 ;
436                    } else if ( retcode > 0 ) {
437                        syslog(BBFTPD_ERR,logmessage) ;
438                        reply(MSG_BAD,logmessage) ;
439                        free_all_var() ;
440                        state = S_LOGGED ;
441                        return 0 ;
442                    } else {
443                        if ( filesize == 0 ) {
444                            if ((transferoption & TROPT_ACC ) == TROPT_ACC ) {
445                                sscanf(lastaccess,"%08x",&ftime.actime) ;
446                                sscanf(lastmodif,"%08x",&ftime.modtime) ;
447                                if ( bbftpd_storeutime(realfilename,&ftime,logmessage) < 0 ) {
448                                    syslog(BBFTPD_ERR,logmessage) ;
449                                    bbftpd_storeunlink(realfilename) ;
450                                    reply(MSG_BAD,logmessage) ;
451                                    free_all_var() ;
452                                    state = S_LOGGED ;
453                                    return 0 ;
454                                }
455                           }
456                           if ( (transferoption & TROPT_MODE ) == TROPT_MODE ) {
457                                if ( bbftpd_storechmod(realfilename,filemode,logmessage) < 0 ) {
458                                    syslog(BBFTPD_ERR,logmessage) ;
459                                    bbftpd_storeunlink(realfilename) ;
460                                    reply(MSG_BAD,logmessage) ;
461                                    free_all_var() ;
462                                    state = S_LOGGED ;
463                                    return 0 ;
464                                }
465                            }
466                            if ( (transferoption & TROPT_TMP ) == TROPT_TMP ) {
467                                if ( bbftpd_storerename(realfilename,curfilename,logmessage) < 0 ) {
468                                    syslog(BBFTPD_ERR,logmessage) ;
469                                    bbftpd_storeunlink(realfilename) ;
470                                    reply(MSG_BAD,logmessage) ;
471                                    free_all_var() ;
472                                    state = S_LOGGED ;
473                                    return 0 ;
474                                }
475                            }
476                            reply(MSG_OK,"") ;
477                            free_all_var() ;
478                            state = S_LOGGED ;
479                            return 0 ;
480                        } else {
481                            /*
482                            ** We are reserving the memory for the ports
483                            */
484                            if ( (myports = (int *) malloc (requestedstreamnumber*sizeof(int))) == NULL ) {
485                                bbftpd_storeunlink(realfilename) ;
486                                free_all_var() ;
487                                syslog(BBFTPD_ERR,"Unable to allocate memory for myports") ;
488                                sprintf(logmessage,"Unable to allocate memory for myports") ;
489                                reply(MSG_BAD,logmessage) ;
490                                state = S_LOGGED ;
491                                return 0 ;
492                            }
493                            /*
494                            ** We are reserving the memory for the children pid
495                            */
496                            if ( (mychildren = (int *) malloc (requestedstreamnumber*sizeof(int))) == NULL) {
497                                bbftpd_storeunlink(realfilename) ;
498                                free_all_var() ;
499                                syslog(BBFTPD_ERR,"Unable to allocate memory for mychildren") ;
500                                sprintf(logmessage,"Unable to allocate memory for mychildren") ;
501                                reply(MSG_BAD,logmessage) ;
502                                state = S_LOGGED ;
503                                return 0 ;
504                            }
505                            /*
506                            ** We are reserving the memory for the readbuffer
507                            */
508                            if ( (readbuffer = (char *) malloc (buffersizeperstream*1024)) == NULL) {
509                                bbftpd_storeunlink(realfilename) ;
510                                free_all_var() ;
511                                syslog(BBFTPD_ERR,"Unable to allocate memory for readbuffer") ;
512                                sprintf(logmessage,"Unable to allocate memory for readbuffer") ;
513                                reply(MSG_BAD,logmessage) ;
514                                state = S_LOGGED ;
515                                return 0 ;
516                            }
517                            /*
518                            ** We are reserving the memory for the compression buffer
519                            ** if needed
520                            */
521                            if ( (transferoption & TROPT_GZIP ) == TROPT_GZIP ) {
522                                if ( (compbuffer = (char *) malloc (buffersizeperstream*1024)) == NULL) {
523                                    bbftpd_storeunlink(realfilename) ;
524                                    free_all_var() ;
525                                    syslog(BBFTPD_ERR,"Unable to allocate memory for compbuffer") ;
526                                    sprintf(logmessage,"Unable to allocate memory for compbuffer") ;
527                                    reply(MSG_BAD,logmessage) ;
528                                    state = S_LOGGED ;
529                                    return 0 ;
530                                }
531                            }
532                            if ( (receive_buffer = (char *) malloc (STORMESSLEN_V2)) == NULL ) {
533                                bbftpd_storeunlink(realfilename) ;
534                                syslog(BBFTPD_ERR,"Error allocating memory for MSG_TRANS_OK_V2 : %s",strerror(errno)) ;
535                                free_all_var() ;
536                                sprintf(logmessage,"Unable to allocate memory for message MSG_TRANS_OK_V2") ;
537                                reply(MSG_BAD,logmessage) ;
538                                state = S_LOGGED ;
539                                return 0 ;
540                            }
541                            msg = (struct message *) receive_buffer ;
542                            if ( protocolversion == 2) { /* ACTIVE MODE */
543                              msg->code = MSG_TRANS_OK_V2 ;
544                            } else { /* PASSIVE MODE */
545                              msg->code = MSG_TRANS_OK_V3 ;
546                            }
547#ifndef WORDS_BIGENDIAN
548                            msg->msglen = ntohl(STORMESSLEN_V2) ;
549#else
550                            msg->msglen = STORMESSLEN_V2 ;
551#endif
552                            if ( writemessage(outcontrolsock,receive_buffer,MINMESSLEN,sendcontrolto) < 0 ) {
553                                syslog(BBFTPD_ERR,"Error wtiting MSG_TRANS_OK_V2 first part") ;
554                                bbftpd_storeunlink(realfilename) ;
555                                free_all_var() ;
556                                FREE(receive_buffer) ;
557                                return -1 ;
558                            }
559                            msg_store_v2 = (struct  mess_store_v2 *) receive_buffer ;
560                            /*
561                            ** Set up the transfer parameter
562                            */
563#ifndef WORDS_BIGENDIAN
564                            msg_store_v2->transferoption       = transferoption ;
565                            msg_store_v2->filemode             = ntohl(filemode) ;
566                            strncpy(msg_store_v2->lastaccess,lastaccess,8) ;
567                            msg_store_v2->lastaccess[8] = '0' ;
568                            strncpy(msg_store_v2->lastmodif,lastmodif,8) ;
569                            msg_store_v2->lastmodif[8] = '0' ;
570                            msg_store_v2->sendwinsize          = ntohl(sendwinsize) ;
571                            msg_store_v2->recvwinsize          = ntohl(recvwinsize) ;
572                            msg_store_v2->buffersizeperstream  = ntohl(buffersizeperstream) ;
573                            msg_store_v2->nbstream             = ntohl(requestedstreamnumber) ;
574                            msg_store_v2->filesize             = ntohll(filesize) ;
575#else
576                            msg_store_v2->transferoption       = transferoption  ;       
577                            msg_store_v2->filemode             =  filemode;
578                            strncpy(msg_store_v2->lastaccess,lastaccess,8) ;
579                            msg_store_v2->lastaccess[8] = '0' ;
580                            strncpy(msg_store_v2->lastmodif,lastmodif,8) ;
581                            msg_store_v2->lastmodif[8] = '0' ;
582                            msg_store_v2->sendwinsize          = sendwinsize ;
583                            msg_store_v2->recvwinsize          = recvwinsize ;
584                            msg_store_v2->buffersizeperstream  = buffersizeperstream ;
585                            msg_store_v2->nbstream             = requestedstreamnumber;
586                            msg_store_v2->filesize             = filesize ;
587#endif
588                            if ( writemessage(outcontrolsock,receive_buffer,STORMESSLEN_V2,sendcontrolto) < 0 ) {
589                                syslog(BBFTPD_ERR,"Error wtiting MSG_TRANS_OK_V2 second part") ;
590                                bbftpd_storeunlink(realfilename) ;
591                                free_all_var() ;
592                                FREE(receive_buffer) ;
593                                return -1 ;
594                            }
595                            /* PASSIVE MODE: send ports */
596                            if ( protocolversion >= 3 ) {
597                              /*
598                              ** We are reserving the memory for the ports
599                              */
600                              if ( (mysockets = (int *) malloc (requestedstreamnumber*sizeof(int))) == NULL ) {
601                                syslog(BBFTPD_ERR,"Error allocating space for sockets") ;
602                                bbftpd_storeunlink(realfilename) ;
603                                free_all_var() ;
604                                FREE(receive_buffer) ;
605                                return -1 ;
606                              }
607                              if ( bbftpd_getdatasock(requestedstreamnumber) < 0 ) {
608                                syslog(BBFTPD_ERR,"Error creating data sockets") ;
609                                bbftpd_storeunlink(realfilename) ;
610                                free_all_var() ;
611                                FREE(receive_buffer) ;
612                                return -1 ;
613                              }
614                              portfree = (int *)receive_buffer ;
615                              porttosend = myports ;
616                              for (i=0 ; i<requestedstreamnumber  ; i++) {
617#ifndef WORDS_BIGENDIAN
618                                *portfree++  = ntohl(ntohs(*porttosend++)) ;
619#else
620                                *portfree++ = *porttosend++ ;
621#endif
622                              }
623/*          syslog(BBFTPD_INFO,"Port=%d,socket=%d\n",*myports,*mysockets) ;*/
624                              if ( writemessage(outcontrolsock,receive_buffer,requestedstreamnumber*sizeof(int),sendcontrolto) < 0) {
625                                syslog(BBFTPD_ERR,"Error writing MSG_TRANS_OK_V3 (ports)") ;
626                                bbftpd_storeunlink(realfilename) ;
627                                free_all_var() ;
628                                FREE(receive_buffer) ;
629                                return -1 ;
630                              }
631                            } /* END PASSIVE MODE */
632                            state = S_WAITING_STORE_START ;
633                            FREE(receive_buffer) ;
634                            return 0 ;
635                        }
636                    }
637                }
638                default :{
639                    syslog(BBFTPD_ERR,"Unkown message in S_WAITING_FILENAME_STORE state : %d",msgcode) ;
640                    return -1 ;
641                }
642            }
643        }
644        /*
645        ** Case S_WAITING_FILENAME_RETR
646        **
647        **         MSG_FILENAME
648        */
649           case S_WAITING_FILENAME_RETR : {
650            switch (msgcode) {
651                case MSG_FILENAME :{
652                    syslog(BBFTPD_DEBUG,"Receiving MSG_FILENAME in S_WAITING_FILENAME_RETR state") ;
653                    if ( msglen == 0 ) {
654                         syslog(BBFTPD_ERR,"Filename length null") ;
655                         return -1 ;
656                    }
657                    if ( (curfilename = (char *) malloc (msglen+1)) == NULL ) {
658                        syslog(BBFTPD_ERR,"Error allocating memory for filename : %s",strerror(errno)) ;
659                        return -1 ;
660                    }
661                    if ( readmessage(incontrolsock,curfilename,msglen,recvcontrolto) < 0 ) {
662                        syslog(BBFTPD_ERR,"Error reading filename") ;
663                        free_all_var() ;
664                        return -1 ;
665                    }
666                    curfilename[msglen] = '\0' ;
667                    curfilenamelen = msglen ;
668                    syslog(BBFTPD_DEBUG,"Request to retreive file %s",curfilename) ;
669                    /*
670                    ** Create the file
671                    */
672                    if ( (retcode = bbftpd_retrcheckfile(curfilename,logmessage)) < 0 ) {
673                        syslog(BBFTPD_ERR,logmessage) ;
674                        reply(MSG_BAD_NO_RETRY,logmessage) ;
675                        free_all_var() ;
676                        state = S_LOGGED ;
677                        return 0 ;
678                    } else if ( retcode > 0 ) {
679                        syslog(BBFTPD_ERR,logmessage) ;
680                        reply(MSG_BAD,logmessage) ;
681                        free_all_var() ;
682                        state = S_LOGGED ;
683                        return 0 ;
684                    } else {
685                        if ( filesize != 0 ) {
686                            /*
687                            ** We are reserving the memory for the ports
688                            */
689                            if ( (myports = (int *) malloc (requestedstreamnumber*sizeof(int))) == NULL ) {
690                                free_all_var() ;
691                                syslog(BBFTPD_ERR,"Unable to allocate memory for myports") ;
692                                sprintf(logmessage,"Unable to allocate memory for myports") ;
693                                reply(MSG_BAD,logmessage) ;
694                                state = S_LOGGED ;
695                                return 0 ;
696                            }
697                            /*
698                            ** We are reserving the memory for the children pid
699                            */
700                            if ( (mychildren = (int *) malloc (requestedstreamnumber*sizeof(int))) == NULL) {
701                                free_all_var() ;
702                                syslog(BBFTPD_ERR,"Unable to allocate memory for mychildren") ;
703                                sprintf(logmessage,"Unable to allocate memory for mychildren") ;
704                                reply(MSG_BAD,logmessage) ;
705                                state = S_LOGGED ;
706                                return 0 ;
707                            }
708                            /*
709                            ** We are reserving the memory for the readbuffer
710                            */
711                            if ( (readbuffer = (char *) malloc (buffersizeperstream*1024)) == NULL) {
712                                free_all_var() ;
713                                syslog(BBFTPD_ERR,"Unable to allocate memory for readbuffer") ;
714                                sprintf(logmessage,"Unable to allocate memory for readbuffer") ;
715                                reply(MSG_BAD,logmessage) ;
716                                state = S_LOGGED ;
717                                return 0 ;
718                            }
719                            /*
720                            ** We are reserving the memory for the compression buffer
721                            ** if needed
722                            */
723                            if ( (transferoption & TROPT_GZIP ) == TROPT_GZIP ) {
724#ifdef WITH_GZIP
725                                if ( (compbuffer = (char *) malloc (buffersizeperstream*1024)) == NULL) {
726                                    free_all_var() ;
727                                    syslog(BBFTPD_ERR,"Unable to allocate memory for compbuffer") ;
728                                    sprintf(logmessage,"Unable to allocate memory for compbuffer") ;
729                                    reply(MSG_BAD,logmessage) ;
730                                    state = S_LOGGED ;
731                                    return 0 ;
732                                }
733#else
734                                transferoption = transferoption & ~TROPT_GZIP ;
735#endif
736                            }
737                        }
738                        if ( (receive_buffer = (char *) malloc (STORMESSLEN_V2)) == NULL ) {
739                            syslog(BBFTPD_ERR,"Error allocating memory for MSG_TRANS_OK_V2 : %s",strerror(errno)) ;
740                            free_all_var() ;
741                            sprintf(logmessage,"Unable to allocate memory for message MSG_TRANS_OK_V2") ;
742                            reply(MSG_BAD,logmessage) ;
743                            state = S_LOGGED ;
744                            return 0 ;
745                          }
746                        msg = (struct message *) receive_buffer ;
747                        if ( protocolversion == 2) { /* ACTIVE MODE */
748                          msg->code = MSG_TRANS_OK_V2 ;
749                        } else { /* PASSIVE MODE */
750                          msg->code = MSG_TRANS_OK_V3 ;
751                        }
752#ifndef WORDS_BIGENDIAN
753                        msg->msglen = ntohl(STORMESSLEN_V2) ;
754#else
755                        msg->msglen = STORMESSLEN_V2 ;
756#endif
757                        if ( writemessage(outcontrolsock,receive_buffer,MINMESSLEN,sendcontrolto) < 0 ) {
758                            syslog(BBFTPD_ERR,"Error writing MSG_TRANS_OK_V2 first part") ;
759                            free_all_var() ;
760                            FREE(receive_buffer) ;
761                            return -1 ;
762                        }
763                        msg_store_v2 = (struct  mess_store_v2 *) receive_buffer ;
764                        /*
765                        ** Set up the transfer parameter
766                        */
767#ifndef WORDS_BIGENDIAN
768                        msg_store_v2->transferoption       = transferoption ;
769                        msg_store_v2->filemode             = ntohl(filemode) ;
770                        strncpy(msg_store_v2->lastaccess,lastaccess,8) ;
771                        msg_store_v2->lastaccess[8] = '0' ;
772                        strncpy(msg_store_v2->lastmodif,lastmodif,8) ;
773                        msg_store_v2->lastmodif[8] = '0' ;
774                        msg_store_v2->sendwinsize          = ntohl(sendwinsize) ;
775                        msg_store_v2->recvwinsize          = ntohl(recvwinsize) ;
776                        msg_store_v2->buffersizeperstream  = ntohl(buffersizeperstream) ;
777                        msg_store_v2->nbstream             = ntohl(requestedstreamnumber) ;
778                        msg_store_v2->filesize             = ntohll(filesize) ;
779#else
780                        msg_store_v2->transferoption       = transferoption  ;       
781                        msg_store_v2->filemode             =  filemode;
782                        strncpy(msg_store_v2->lastaccess,lastaccess,8) ;
783                        msg_store_v2->lastaccess[8] = '0' ;
784                        strncpy(msg_store_v2->lastmodif,lastmodif,8) ;
785                        msg_store_v2->lastmodif[8] = '0' ;
786                        msg_store_v2->sendwinsize          = sendwinsize ;
787                        msg_store_v2->recvwinsize          = recvwinsize ;
788                        msg_store_v2->buffersizeperstream  = buffersizeperstream ;
789                        msg_store_v2->nbstream             = requestedstreamnumber;
790                        msg_store_v2->filesize             = filesize ;
791#endif
792                        if ( writemessage(outcontrolsock,receive_buffer,STORMESSLEN_V2,sendcontrolto) < 0 ) {
793                            syslog(BBFTPD_ERR,"Error writing MSG_TRANS_OK_V2 second part") ;
794                            bbftpd_storeunlink(realfilename) ;
795                            free_all_var() ;
796                            FREE(receive_buffer) ;
797                            return -1 ;
798                        }
799                        if ( filesize == 0 ) {
800                            char statmessage[1024];
801                            state = S_WAITING_CREATE_ZERO ;
802                            sprintf(statmessage,"GET %s %s 0 0 0.0 0.0", currentusername, curfilename);
803                            syslog(BBFTPD_NOTICE,statmessage);
804                            free_all_var() ;
805                        } else {
806                            /* PASSIVE MODE: send ports */
807                            if ( protocolversion >= 3 ) {
808                              /*
809                              ** We are reserving the memory for the ports
810                              */
811                              if ( (mysockets = (int *) malloc (requestedstreamnumber*sizeof(int))) == NULL ) {
812                                syslog(BBFTPD_ERR,"Error allocating space for sockets") ;
813                                bbftpd_storeunlink(realfilename) ;
814                                free_all_var() ;
815                                FREE(receive_buffer) ;
816                                return -1 ;
817                              }
818                              if ( bbftpd_getdatasock(requestedstreamnumber) < 0 ) {
819                                syslog(BBFTPD_ERR,"Error creating data sockets") ;
820                                bbftpd_storeunlink(realfilename) ;
821                                free_all_var() ;
822                                FREE(receive_buffer) ;
823                                return -1 ;
824                              }
825                              portfree = (int *)receive_buffer ;
826                              porttosend = myports ;
827                              for (i=0 ; i<requestedstreamnumber  ; i++) {
828#ifndef WORDS_BIGENDIAN
829                                *portfree++  = ntohl(ntohs(*porttosend++)) ;
830#else
831                                *portfree++ = *porttosend++ ;
832#endif
833                              }
834/*          syslog(BBFTPD_INFO,"Port=%d,socket=%d\n",*myports,*mysockets) ;*/
835                              if ( writemessage(outcontrolsock,receive_buffer,requestedstreamnumber*sizeof(int),sendcontrolto) < 0) {
836                                syslog(BBFTPD_ERR,"Error writing MSG_TRANS_OK_V3 (ports)") ;
837                                bbftpd_storeunlink(realfilename) ;
838                                free_all_var() ;
839                                FREE(receive_buffer) ;
840                                return -1 ;
841                              }
842                            } /* END PASSIVE MODE */
843                            state = S_WAITING_RETR_START ;
844                        }
845                        FREE(receive_buffer) ;
846                        return 0 ;
847                    }
848                }
849                default :{
850                    syslog(BBFTPD_ERR,"Unkown message in S_WAITING_FILENAME state : %d",msgcode) ;
851                    return -1 ;
852                }
853            }
854        }
855       
856        /*
857        ** Case S_WAITING_STORE_START
858        **
859        **         MSG_TRANS_START_V2
860        **         MSG_TRANS_SIMUL
861        **         MSG_ABORT
862        */
863        case S_WAITING_STORE_START : {
864             switch (msgcode) {
865                case MSG_TRANS_START_V2 :
866                case MSG_TRANS_SIMUL :
867                case MSG_TRANS_START_V3 :
868                case MSG_TRANS_SIMUL_V3 :{
869                    int simulation = ((msgcode == MSG_TRANS_SIMUL) || (msgcode == MSG_TRANS_SIMUL_V3)?1:0);
870                    syslog(BBFTPD_DEBUG,"Receiving MSG_TRANS_START_V2") ;
871                    if ( msglen != requestedstreamnumber*sizeof(int)) {
872                        bbftpd_storeunlink(realfilename) ;
873                        free_all_var() ;
874                        reply(MSG_BAD,"Inconsistency between MSG_TRANS_START_V2 and message length") ;
875                        syslog(BBFTPD_ERR,"Inconsistency between MSG_TRANS_START_V2 and message length") ;
876                        return -1 ;
877                    }
878                    if (msgcode == MSG_TRANS_START_V2 || msgcode == MSG_TRANS_SIMUL) { /* ACTIVE MODE */
879                      /*
880                      ** Retreive port numbers
881                      */
882                      if ( readmessage(incontrolsock,(char *) myports,msglen,recvcontrolto) < 0 ) {
883                        bbftpd_storeunlink(realfilename) ;
884                        free_all_var() ;
885                        syslog(BBFTPD_ERR,"Error reading MSG_TRANS_START_V2") ;
886                        return -1 ;
887                      } else {
888#ifndef WORDS_BIGENDIAN
889                        portfree = myports ;
890                        for (i=0 ; i < requestedstreamnumber ; i++ ) {
891                            *portfree = ntohl(*portfree) ;
892                            portfree++ ;
893                        }
894#endif
895                        portfree = myports ;
896                        for (i=0 ; i < requestedstreamnumber ; i++ ) {
897                            portfree++ ;
898                        }
899                      }
900                    }
901                    if ( (retcode = bbftpd_storetransferfile(realfilename,simulation,logmessage)) == 0 ) {
902                        /*
903                        ** Everything seems to work correctly
904                        */
905                        return 0 ;
906                    }
907                    if ( retcode > 0 ) {
908                        /*
909                        ** Something goes wrong
910                        */
911                        bbftpd_storeunlink(realfilename) ;
912                        free_all_var() ;
913                        state = S_LOGGED ;
914                        return 0 ;
915                    }
916                    /*
917                    **
918                    */
919                    bbftpd_storeunlink(realfilename) ;
920                    free_all_var() ;
921                    state = S_LOGGED ;
922                    return -1 ;
923                }
924                case MSG_ABORT : {
925                    syslog(BBFTPD_ERR,"Receive ABORT message") ;
926                    bbftpd_storeunlink(realfilename) ;
927                    free_all_var() ;
928                    state = S_LOGGED ;
929                    return 0 ;
930                }
931                default :{
932                    syslog(BBFTPD_ERR,"Unkown message in S_WAITING_STORE_START state : %d",msgcode) ;
933                    bbftpd_storeunlink(realfilename) ;
934                    free_all_var() ;
935                    return -1 ;
936                }
937            }
938        }
939        /*
940        ** Case S_WAITING_CREATE_ZERO
941        **
942        **         MSG_CREATE_ZERO
943        **         MSG_ABORT
944        */
945        case S_WAITING_CREATE_ZERO : {
946             switch (msgcode) {
947                case MSG_CREATE_ZERO : {
948                    syslog(BBFTPD_ERR,"Receive MSG_CREATE_ZERO message ") ;
949                    state = S_LOGGED ;
950                    return 0 ;
951                }
952                case MSG_ABORT : {
953                    syslog(BBFTPD_ERR,"Receive ABORT message") ;
954                    state = S_LOGGED ;
955                    return 0 ;
956                }
957                default :{
958                    syslog(BBFTPD_ERR,"Unkown message in S_WAITING_CREATE_ZERO state : %d",msgcode) ;
959                    return -1 ;
960                }
961            }
962        }
963        /*
964        ** Case S_WAITING_RETR_START
965        **
966        **         MSG_TRANS_START_V2
967        **         MSG_TRANS_SIMUL
968        **         MSG_ABORT
969        */
970        case S_WAITING_RETR_START : {
971             switch (msgcode) {
972                case MSG_TRANS_START_V2 :
973                case MSG_TRANS_SIMUL :
974                case MSG_TRANS_START_V3 :
975                case MSG_TRANS_SIMUL_V3 :{
976                    int simulation = ((msgcode == MSG_TRANS_SIMUL) || (msgcode == MSG_TRANS_SIMUL_V3)?1:0);
977                    syslog(BBFTPD_DEBUG,"Receiving MSG_TRANS_START_V2") ;
978                    if ( msglen != requestedstreamnumber*sizeof(int)) {
979                        free_all_var() ;
980                        reply(MSG_BAD,"Inconsistency between MSG_TRANS_START_V2 and message length") ;
981                        syslog(BBFTPD_ERR,"Inconsistency between MSG_TRANS_START_V2 and message length") ;
982                        return -1 ;
983                    }
984                    if (msgcode == MSG_TRANS_START_V2 || msgcode == MSG_TRANS_SIMUL) { /* ACTIVE MODE */
985                      /*
986                      ** Retreive port numbers
987                      */
988                      if ( readmessage(incontrolsock,(char *) myports,msglen,recvcontrolto) < 0 ) {
989                        free_all_var() ;
990                        syslog(BBFTPD_ERR,"Error reading MSG_TRANS_START_V2") ;
991                        return -1 ;
992                      } else {
993#ifndef WORDS_BIGENDIAN
994                        portfree = myports ;
995                        for (i=0 ; i < requestedstreamnumber ; i++ ) {
996                            *portfree = ntohl(*portfree) ;
997                            portfree++ ;
998                        }
999#endif
1000                        /*portfree = myports ;
1001                        for (i=0 ; i < requestedstreamnumber ; i++ ) {
1002                            portfree++ ;
1003                                                        }*/
1004                      }
1005                    }
1006                    if ( (retcode = bbftpd_retrtransferfile(curfilename,simulation,logmessage)) == 0 ) {
1007                        /*
1008                        ** Everything seems to work correctly
1009                        */                       
1010                        return 0 ;
1011                    }
1012                    if ( retcode > 0 ) {
1013                        /*
1014                        ** Something goes wrong
1015                        */
1016                        syslog(BBFTPD_ERR,"retrtransferfile retcode > 0") ;
1017                        free_all_var() ;
1018                        state = S_LOGGED ;
1019                        return 0 ;
1020                    }
1021                    /*
1022                    **
1023                    */
1024                    syslog(BBFTPD_ERR,"retrtransferfile retcode < 0") ;
1025                    free_all_var() ;
1026                    state = S_LOGGED ;
1027                    return -1 ;
1028                }
1029                case MSG_ABORT : {
1030                    syslog(BBFTPD_ERR,"Receive ABORT message") ;
1031                    free_all_var() ;
1032                    state = S_LOGGED ;
1033                    return 0 ;
1034                }
1035                default :{
1036                    syslog(BBFTPD_ERR,"Unkown message in S_WAITING_RETR_START state : %d",msgcode) ;
1037                    return -1 ;
1038                }
1039            }
1040        }
1041        /*
1042        ** Case S_SENDING or S_RECEIVING
1043        */
1044        case S_SENDING : {
1045              switch (msgcode) {
1046                case MSG_ABORT :{
1047                    syslog(BBFTPD_ERR,"Receive MSG_ABORT while sending") ;
1048                    return -1 ;
1049                }
1050                default :{
1051                    syslog(BBFTPD_ERR,"Unkown message in S_SENDING state: %d",msgcode) ;
1052                    return -1 ;
1053                }   
1054            }
1055        }
1056        case S_RECEIVING : {
1057              switch (msgcode) {
1058                case MSG_ABORT :{
1059                    syslog(BBFTPD_ERR,"Receive MSG_ABORT while receiving") ;
1060                    bbftpd_storeclosecastfile(realfilename,logmessage) ;
1061                    bbftpd_storeunlink(realfilename) ;
1062                    return -1 ;
1063                }
1064                default :{
1065                    syslog(BBFTPD_ERR,"Unkown message in S_RECEIVING state : %d",msgcode) ;
1066                    bbftpd_storeclosecastfile(realfilename,logmessage) ;
1067                    bbftpd_storeunlink(realfilename) ;
1068                    return -1 ;
1069                }   
1070            }
1071        }
1072        /*
1073        ** Any other state
1074        */
1075        default : {
1076            syslog(BBFTPD_ERR,"Receive message in state %d",state) ;
1077            return -1 ;
1078        }
1079    }
1080}
1081       
1082       
Note: See TracBrowser for help on using the repository browser.