Ejemplo n.º 1
0
static int
vyyerror(char *fmt, va_list ap) {
extern	char	*cmdname;
	char	msgbuf[1024];

/*	if (synerr)
		return;	*/
	vsnprintf(msgbuf, sizeof msgbuf, fmt, ap);	/* for debugging */
	va_end(ap);
	if (!batch)
		writemessage(msgbuf, 12, 1);
	fprintf(stderr, "%s: %s\n", cmdname, msgbuf);
	
	if (curfile->fin != NULL) {
		fprintf(stderr, " near line %d, file %s\n",
			curfile->lineno, curfile->fname);
		eprint();
		synerr = 1;
#if 0
		while (srcp > src)  /* If not at level of original input, */
			nextchar(); /* skip until we are.  This is an attempt */
				    /* to clean up the buffers. -- DBK */
#endif
	}
#if 1
	if (curfile->fin == NULL) {	/* see if this works */
		eprint();
		synerr = 1;
	}
#endif
	errno = 0;
	return 0;
}
Ejemplo n.º 2
0
int bbftpd_list(char *pattern,char *logmessage) 
{

    char    *filelist ;
    int     filelistlen ;
    int     retcode ;
    char    send_buffer[MINMESSLEN] ;
    struct message *msg ;
    
    
    if ( (retcode = bbftpd_retrlistdir(pattern,&filelist,&filelistlen,logmessage) ) < 0) {
        reply(MSG_BAD_NO_RETRY,logmessage) ;
        return 0 ;
    } else if ( retcode > 0 ) {
        reply(MSG_BAD,logmessage) ;
        return 0 ;
    } else {
        msg = (struct message *) send_buffer ;
        msg->code = MSG_LIST_REPL_V2 ;
#ifndef WORDS_BIGENDIAN
        msg->msglen = ntohl(filelistlen) ;
#else 
        msg->msglen = filelistlen ;
#endif
        if ( writemessage(outcontrolsock,send_buffer,MINMESSLEN,recvcontrolto) < 0 ) {
            syslog(BBFTPD_ERR,"Error sending LISTREPL_V2 part 1") ;
            FREE(filelist) ;
            return -1 ;
        }
        if (filelistlen != 0 ) {
            if ( writemessage(outcontrolsock,filelist,filelistlen,recvcontrolto) < 0 ) {
                FREE(filelist) ;
                syslog(BBFTPD_ERR,"Error sending filelist") ;
                return -1 ;
            }
            FREE(filelist) ;
            return 0 ;
        }
        return 0 ;
    }
}
Ejemplo n.º 3
0
void init(void)
{
	writemessage();

	glClearColor(0.0, 0.0, 0.0, 0.0);
	glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);

	/* initially GL_FILL mode (default), later GL_LINE to show wireframe */
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	glEnable(GL_LIGHTING);
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
	glEnable(GL_LIGHT0);
}
Ejemplo n.º 4
0
int bbftp_list(char *line,char **filelist,int *filelistlen,int *errcode)
{

    char    minbuffer[MINMESSLEN] ;
    int     msglen ;
    int     code ;
    struct  message *msg ;
    struct  mess_integer *msg_integer ;
    fd_set  selectmask ; /* Select mask */
    int     nfds ; /* Max number of file descriptor */
    char    *buffer ;
    int     retcode ;
    
    if ( verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,">> COMMAND : list %s\n",line) ;

    msg = (struct message *)minbuffer ;
    msg->code = MSG_LIST_V2 ;
#ifndef WORDS_BIGENDIAN
    msg->msglen = ntohl(strlen(line)+sizeof(int)) ;
#else
    msg->msglen = strlen(line)+sizeof(int) ;
#endif

    if ( writemessage(outcontrolsock,minbuffer,MINMESSLEN,sendcontrolto,0) < 0 ) {
        /*
        ** We were not able to send the minimum message so
        ** we are going to close the control socket and to 
        ** tell the calling program to restart a connection
        */
        printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_LIST_V2");
        *errcode = 64 ;
        bbftp_free_all_var() ;
        bbftp_close_control() ;
        return BB_RET_CONN_BROKEN ; /* restart connection */
    }
    /* 
    ** Sending transfer options
    */
    msg_integer = (struct mess_integer*)minbuffer ;
    msg_integer->myint =  transferoption ;
    if ( writemessage(outcontrolsock,minbuffer,sizeof(int),sendcontrolto,0) < 0 ) {
        printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_LIST_V2 (transferoption)");
        *errcode = 64 ;
        bbftp_close_control() ;
        return BB_RET_CONN_BROKEN ; /* restart connection */
    }
    /* 
    ** Directory name
    */
    if ( writemessage(outcontrolsock,line,strlen(line),sendcontrolto,0) < 0 ) {
        printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_LIST_V2 (directory name)");
        *errcode = 64 ;
        bbftp_close_control() ;
        return BB_RET_CONN_BROKEN ; /* restart connection */
    }
     /*
    ** Now we are going to wait for the message on the control 
    ** connection
    */
waitcontrol:
    nfds = sysconf(_SC_OPEN_MAX) ;
    FD_ZERO(&selectmask) ;
    FD_SET(incontrolsock,&selectmask) ;
    retcode = select(FD_SETSIZE,&selectmask,0,0,0) ;
    if ( retcode < 0 ) {
        /*
        ** Select error
        */
        if ( errno != EINTR ) {
            /*
            ** we have got an error so close the connection
            ** and restart
            */
            printmessage(stderr,CASE_ERROR,66,timestamp,"Error select on control connection : %s\n",strerror(errno));
            *errcode = 66 ;
            bbftp_close_control() ;
            return BB_RET_CONN_BROKEN ;
        } else {
            /*
            ** Interrupted by a signal
            */
            FD_ZERO(&selectmask) ;
            FD_SET(incontrolsock,&selectmask) ;
            goto waitcontrol ;
        }
    } else if ( retcode == 0 ) {
        /*
        ** Impossible we do not set any timer
        */
        FD_ZERO(&selectmask) ;
        FD_SET(incontrolsock,&selectmask) ;
        goto waitcontrol ;
    } else {
        /*
        ** read the message
        */
        if ( readmessage(incontrolsock,minbuffer,MINMESSLEN,recvcontrolto,0) < 0 ) {
            printmessage(stderr,CASE_ERROR,61,timestamp,"Error waiting %s message\n","MSG_OK (on MSG_LIST_V2)");
            *errcode = 61 ;
            bbftp_close_control() ;
            return BB_RET_CONN_BROKEN ;
        }
        code = msg->code ;
        if ( code == MSG_BAD || code == MSG_BAD_NO_RETRY) {
            /*
            ** The change directory has failed so ...
            */
#ifndef WORDS_BIGENDIAN
            msglen = ntohl(msg->msglen) ;
#else
            msglen = msg->msglen ;
#endif
            if ( (buffer = (char *) malloc(msglen+1) ) == NULL) {
                printmessage(stderr,CASE_ERROR,35,timestamp,"Error allocating memory for %s : %s\n","buffer (bbftp_list)",strerror(errno)) ;
                *errcode = 35 ;
                bbftp_close_control() ;
                return BB_RET_CONN_BROKEN ;
            }
            if ( readmessage(incontrolsock,buffer,msglen,recvcontrolto,0) < 0 ) {
                printmessage(stderr,CASE_ERROR,67,timestamp,"Error reading data for %s message\n","MSG_BAD (on MSG_LIST_V2)");
                *errcode = 67 ;
                bbftp_close_control() ;
                free(buffer) ;
                if ( code == MSG_BAD ) {
                    return BB_RET_CONN_BROKEN ;
                } else {
                    return BB_RET_FT_NR_CONN_BROKEN ;
                }
            } else {
                buffer[msglen] = '\0' ;
                printmessage(stderr,CASE_ERROR,100,timestamp,"%s\n",buffer) ;
                if (verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,"<< %s\n",buffer) ;
                free(buffer) ;
                if ( code == MSG_BAD ) {
                    *errcode = 100 ;
                    return BB_RET_ERROR;
                } else {
                    /*
                    ** In case of no retry we are going to wait 2 seconds
                    ** in order for the server to finish its cleaning (in
                    ** fact if the error message is du to a server child
                    ** abnormal termination, the message is sent on the death
                    ** of the first child and the server has some cleaning
                    ** to do).
                    */
                    sleep(2) ;
                    *errcode = 100 ;
                    return BB_RET_FT_NR ;
                }
            }
        } else if (msg->code == MSG_LIST_REPL_V2 ) {
            /*
            ** At this stage the transfer is OK but we need
            ** the answer because it gives all file names
            */
#ifndef WORDS_BIGENDIAN
            msglen = ntohl(msg->msglen) ;
#else
            msglen = msg->msglen ;
#endif
            if ( msglen == 0 ) {
                /*
                ** There was no file corresponding
                */
                if ( verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,"<< OK : no file\n") ;
                *filelistlen = 0 ; 
                return BB_RET_OK ;
            } else {
                if ( ((*filelist) = (char *) malloc(msglen+1) ) == NULL) {
                    printmessage(stderr,CASE_ERROR,35,timestamp,"Error allocating memory for %s : %s\n","filelist (bbftp_list)",strerror(errno)) ;
                    *errcode = 35 ;
                    bbftp_close_control() ;
                    return BB_RET_CONN_BROKEN ;
                }
                if ( readmessage(incontrolsock,*filelist,msglen,recvcontrolto,0) < 0) {
                    printmessage(stderr,CASE_ERROR,67,timestamp,"Error reading data for %s message\n","MSG_LIST_REPL_V2 (on MSG_LIST_V2)");
                    *errcode = 67 ;
                    bbftp_close_control() ;
                    free(*filelist) ;
                    return BB_RET_CONN_BROKEN ;
                }
                (*filelist)[msglen] = '\0' ;
                *filelistlen = msglen ; 
                if ( verbose ) printmessage(stdout,CASE_NORMAL,0,timestamp,"<< OK\n") ;
                return BB_RET_OK ;
            }
        } else {
            /*
            ** Receive unkwown message so something is
            ** going wrong. close the control socket
            ** and restart
            */
            printmessage(stderr,CASE_ERROR,62,timestamp,"Unknown message while waiting for %s message\n","MSG_OK (on MSG_MKDIR_V2)");
            *errcode = 62 ;
            bbftp_close_control() ;
            return BB_RET_CONN_BROKEN ;
        }
    }
}
void clsScreen::update(void) {
    PLYR tempPlayer = Global::Enty.getPlayer();
    uint Max_Height, Max_Width; //Values for how far on the map the screen should render
    uint x_start; //place where x starts at
    Max_Height = (uint) (height/pic_size);
    Max_Width = (uint) (width/pic_size);

    //This will cause the screen to move in different segments at a time.
    x_start = (uint) (round (tempPlayer.location.x / Max_Width) ) * Max_Width;

    //clear renderer
    SDL_RenderClear(ren);

    //copy sky to cover entire screen.
    SDL_RenderCopy(ren,sky,NULL,NULL);

    SDL_Rect dst;

    //Start updating texture placements
    for (uint y = 0; (y < (Max_Height)) && (y < DEFINED_MAP_HEIGHT); y++) {
        for (uint x = x_start; (x < (x_start + Max_Width)) && (x < DEFINED_MAP_WIDTH); x++) {
            //update where we're trying to put the texture.
            dst.x = (x - x_start) * pic_size;
            dst.y = y * pic_size;
            //Query a texture to get its width and height
            //Since all the textures are the same we'll use the error one since the program would
            //not have gotten this far if that failed load.
            SDL_QueryTexture(errortex,NULL,NULL, &dst.w, &dst.h);

            switch(Global::Map.getMapCell(x,y)) {
            case tileSpace:
                //SDL_RenderCopy(ren,sky,NULL, &dst);
                break;
            case tileCoin:
                SDL_RenderCopy(ren,coin,NULL, &dst);
                break;
            case tileMonster:
                SDL_RenderCopy(ren, monster, NULL, &dst);
                break;
            case tilePlayer:
                SDL_RenderCopy(ren, player, NULL, &dst);
                break;
            case tilePole:
                SDL_RenderCopy(ren, pole, NULL, &dst);
                break;
            case tileWall:
                SDL_RenderCopy(ren, wall, NULL, &dst);
                break;
            default:
                //Don't know what this is so display an error texture.
                SDL_RenderCopy(ren, errortex, NULL, &dst);
                break;
            } //end switch
        } //end for x
    } //end for y

    //Write messages only if Message font is loaded.
    if (blnMessageFont) {
        writemessage();
    }
    //show renderer
    SDL_RenderPresent(ren);
    Global::Tick.wait();
}
Ejemplo n.º 6
0
int sendafile(int code) {

    char    receive_buffer[MAXMESSLEN] ;
    char    receive_buffer_sup[MAXMESSLEN] ;
    char    send_buffer[MAXMESSLEN] ;
    int        savederrno ;

    char    readbuffer[READBUFLEN] ;
    char    buffercomp[READBUFLEN] ;
    struct    mess_compress *msg_compress ;
#ifdef WITH_GZIP
    uLong    buflen ;
    uLong    bufcomplen ;
#endif
    my64_t    filelen64 ;
    my64_t    toprint64 ;
    
#ifdef STANDART_FILE_CALL
    off_t         nbperchild ;
    off_t         nbtosend ;
    off_t         nbread ;
    off_t         nbsent ;
    off_t         numberread ;
    off_t         startpoint ;
    off_t        realnbtosend ;
    off_t        filelen ;
    struct stat statbuf ;
#else
    off64_t     nbperchild ;
    off64_t     nbtosend ;
    off64_t     nbread ;
    off64_t     nbsent ;
    off64_t     numberread ;
    off64_t     startpoint ;
    off64_t        realnbtosend ;
    off64_t        filelen ;
    struct stat64 statbuf ;
#endif

    int        lentosend ;

    char    readfilename[MAXLENFILE] ;
    
    int        retcode ;
    int        fd ;
    int        i ;
    int        sendsock ;
    char    logmessage[256] ;
    int        compressiontype ;
    
    struct message *msg ;
    struct mess_store *msg_store ;
    struct mess_retr_ok *msg_retr_ok ;
    
    int        nfds ;
    fd_set    selectmask ; /* Select mask */
    struct timeval    wait_timer;
    
    
    /*
    ** Initilize the pid array
    */
     for ( i=0 ; i< MAXPORT ; i++) {
        pid_child[i] = 0 ;
    }
    childendinerror = 0 ; /* No child so no error */

    strcpy(currentfilename,"") ;
    if ( (retcode = readmessage(msgsock,receive_buffer,STORMESSLEN,recvcontrolto) ) < 0 ) {
        syslog(BBFTPD_ERR,"Error receiving file char") ;
        return retcode ;
    }
    msg_store = (struct mess_store *) receive_buffer ;
    strcpy(readfilename,msg_store->filename) ;
#ifndef WORDS_BIGENDIAN
    msg_store->nbport = ntohl(msg_store->nbport) ;
    for (i = 0 ; i< MAXPORT ; i++ ) {
        msg_store->port[i] = ntohl(msg_store->port[i]) ;
    }
#endif
    if ( code == MSG_RETR ) {
        compressiontype = NOCOMPRESSION ;
        syslog(BBFTPD_DEBUG,"Retreiving file %s with %d children",readfilename,msg_store->nbport) ;
    } else {
        compressiontype = COMPRESSION ;
        syslog(BBFTPD_DEBUG,"Retreiving file %s with %d children in compressed mode",readfilename,msg_store->nbport) ;
    }
    /*
    ** WARNING ----------
    **
    ** Do not use the receive buffer in father before having forked
    ** because all data related to the ports are in it
    **
    ** WARNING ----------
    */
    /*
    ** First stat the file in order to know if it is a directory
    */
#ifdef STANDART_FILE_CALL
    if ( stat(readfilename,&statbuf) < 0 ) {
#else
    if ( stat64(readfilename,&statbuf) < 0 ) {
#endif
        /*
        ** We tell the client not to retry in the following case (even in waiting
        ** WAITRETRYTIME the problem will not be solved) :
        **        EACCES        : Search permission denied
        **        ELOOP        : To many symbolic links on path
        **        ENAMETOOLONG: Path argument too long
        **        ENOENT        : The file does not exists
        **        ENOTDIR        : A component in path is not a directory
        */
        savederrno = errno ;
        sprintf(logmessage,"Error stating file %s : %s ",readfilename,strerror(savederrno)) ;
        syslog(BBFTPD_ERR,"Error stating file %s : %s ",readfilename,strerror(savederrno)) ;
        if ( savederrno == EACCES ||
            savederrno == ELOOP ||
            savederrno == ENAMETOOLONG ||
            savederrno == ENOENT ||
            savederrno == ENOTDIR ) {
            reply(MSG_BAD_NO_RETRY,logmessage) ;
            return 0 ;
        } else {
            reply(MSG_BAD,logmessage) ;
            return 0 ;
        }
    } else {
        /*
        ** The file exists so check if it is a directory
        */
        if ( (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
            syslog(BBFTPD_ERR,"file %s is a directory",readfilename) ;
            sprintf(logmessage,"File %s is a directory",readfilename) ;
            reply(MSG_BAD_NO_RETRY,logmessage) ;
            return 0 ;
        }
    }                
    /*
    ** Getting filesize in order to send it to the client
    */
#ifdef STANDART_FILE_CALL
    if ( (fd = open(readfilename,O_RDONLY)) < 0 ) {
#else
    if ( (fd = open64(readfilename,O_RDONLY)) < 0 ) {
#endif
        /*
        ** An error on openning the local file is considered
        ** as fatal. Maybe this need to be improved depending
        ** on errno
        */
        savederrno = errno ;
        syslog(BBFTPD_ERR,"Error opening local file %s : %s",readfilename,strerror(errno)) ;
        sprintf(logmessage,"Error opening local file %s : %s ",readfilename,strerror(errno)) ;
        /*
        ** We tell the client not to retry in the following case (even in waiting
        ** WAITRETRYTIME the problem will not be solved) :
        **        EACCES        : Search permission denied
        **        ELOOP        : To many symbolic links on path
        **        ENOENT        : No such file or directory
        **        ENAMETOOLONG: Path argument too long
        **        ENOTDIR        : A component in path is not a directory
        */
        if ( savederrno == EACCES ||
                savederrno == ELOOP ||
                savederrno == ENOENT ||
                savederrno == ENAMETOOLONG ||
                savederrno == ENOTDIR ) {
            reply(MSG_BAD_NO_RETRY,logmessage) ;
        } else {
            reply(MSG_BAD,logmessage) ;
        }
        return 0 ;
    }
#ifdef STANDART_FILE_CALL
    if ( (filelen = lseek(fd,0,SEEK_END) ) < 0 ) {
#else
    if ( (filelen = lseek64(fd,0,SEEK_END) ) < 0 ) {
#endif
        /*
        ** An error on seekin the local file is considered
        ** as fatal. lseek error  in this case is completly
        ** abnormal
        */
        close(fd) ;
        syslog(BBFTPD_ERR,"Error seeking local file %s : %s",readfilename,strerror(errno)) ;
        sprintf(logmessage,"Error seeking local file %s : %s ",readfilename,strerror(errno)) ;
        reply(MSG_BAD,logmessage) ;
        return 0 ;
    }
    filelen64 = filelen ;
    /*
    ** Close the file as the only interresting thing was the length
    */
    close(fd) ;
    /*
    ** We are going to send the file length 
    */
    msg = (struct message *) send_buffer ;
    msg->code = MSG_RETR_OK ;
#ifndef WORDS_BIGENDIAN
    msg->msglen = ntohl(RETROKMESSLEN) ;
#else
    msg->msglen = RETROKMESSLEN ;
#endif
    if ( writemessage(msgsock,send_buffer,MINMESSLEN,recvcontrolto) < 0 ) {
        /*
        ** Something wrong in sending message
        ** tell calling to close the connection
        */
        syslog(BBFTPD_ERR,"Error sending RETROK part 1") ;
        return -1 ;
    }
    msg_retr_ok = (struct mess_retr_ok *) send_buffer ;
#ifndef WORDS_BIGENDIAN
    msg_retr_ok->filesize = ntohll(filelen64) ;
#else
    msg_retr_ok->filesize = filelen64 ;
#endif
    if ( writemessage(msgsock,send_buffer,RETROKMESSLEN,recvcontrolto) < 0 ) {
        /*
        ** Something wrong in sending message
        ** tell calling to close the connection
        */
        syslog(BBFTPD_ERR,"Error sending RETROK part 2") ;
        return -1 ;
    }
    /*
    ** Wait for the START message
    */
    if ( readmessage(msgsock,receive_buffer_sup,MINMESSLEN,RETRSTARTTO) < 0 ) {
        /*
        ** Something wrong in receiving message
        ** tell calling to close the connection
        */
        syslog(BBFTPD_ERR,"Error receiving RETRSTART") ;
        return -1 ;
    }
    msg = (struct message *) receive_buffer_sup ;
    if ( msg->code == MSG_ABR) {
        /*
        ** In this case the client will not close the connection
        ** so do the same
        */
        syslog(BBFTPD_ERR,"Receive ABORT message") ;
        return 0 ;
    } else if ( msg->code == MSG_CREATE_ZERO ) {
        syslog(BBFTPD_INFO,"Send zero length file") ;
        return 0 ;
    } else if ( msg->code != MSG_RETR_START ) {
        syslog(BBFTPD_ERR,"Receive Unknown message code while waiting RETRSTART %d",msg->code) ;
        return -1 ;
    }
    /*
    ** So we receive the start message ...
    */
    /*
    ** Now start all our children
    */
    nbperchild = filelen/msg_store->nbport ;
    for (i = 1 ; i <= msg_store->nbport ; i++) {
        if ( i == msg_store->nbport) {
            startpoint = (i-1)*nbperchild;
            nbtosend = filelen-(nbperchild*(msg_store->nbport-1)) ;
        } else {
            startpoint = (i-1)*nbperchild;
            nbtosend = nbperchild ;
        }
        /*
        ** Now create the socket to send
        */
        sendsock = 0 ;
        while (sendsock == 0 ) {
            sendsock = createreceivesock(msg_store->port[i-1],i,logmessage) ;
        }
        if ( sendsock < 0 ) {
            /*
            ** We set childendinerror to 1 in order to prevent the father
            ** to send a BAD message which can desynchronize the client and the
            ** server (We need only one error message)
            ** Bug discovered by amlutz on 2000/03/11
            */
            if ( childendinerror == 0 ) {
                childendinerror = 1 ;
                reply(MSG_BAD,logmessage) ;
            }
            clean_child() ;
            return 0 ;
        }
        /*
        ** Set flagsighup to zero in order to be able in child
        ** not to wait STARTCHILDTO if signal was sent before 
        ** entering select. (Seen on Linux with one child)
        */
        flagsighup = 0 ;
        /*
        ** At this stage we are ready to receive packets
        ** So we are going to fork
        */
        if ( (retcode = fork()) == 0 ) {
            /*
            ** We are in child
            */
            /*
            ** Pause until father send a SIGHUP in order to prevent
            ** child to die before father has started all children
            */
            if ( flagsighup == 0) {
                nfds = sysconf(_SC_OPEN_MAX) ;
                wait_timer.tv_sec  = STARTCHILDTO ;
                wait_timer.tv_usec = 0 ;
                select(nfds,0,0,0,&wait_timer) ;
            }
            syslog(BBFTPD_DEBUG,"Child Starting") ;
            /*
            ** Close all unnecessary stuff
            */
            close(msgsock) ;
            /*
            ** And open the file 
            */
#ifdef STANDART_FILE_CALL
            if ( (fd = open(readfilename,O_RDONLY)) < 0 ) {
#else
            if ( (fd = open64(readfilename,O_RDONLY)) < 0 ) {
#endif
                /*
                ** An error on openning the local file is considered
                ** as fatal. Maybe this need to be improved depending
                ** on errno
                */
                i = errno ;
                syslog(BBFTPD_ERR,"Error opening local file %s : %s",readfilename,strerror(errno)) ;
                close(sendsock) ;
                exit(i) ;
            }
#ifdef STANDART_FILE_CALL
            if ( lseek(fd,startpoint,SEEK_SET) < 0 ) {
#else
            if ( lseek64(fd,startpoint,SEEK_SET) < 0 ) {
#endif
                i = errno ;
                close(fd) ;
                syslog(BBFTPD_ERR,"Error seeking file : %s",strerror(errno)) ;
                close(sendsock) ;
                exit(i)  ;
            }
            /*
            ** Start the sending loop
            */
            nbread = 0 ;
            while ( nbread < nbtosend ) {
                if ( (numberread = read ( fd, readbuffer, (sizeof(readbuffer) <= nbtosend - nbread) ? sizeof(readbuffer) : nbtosend-nbread) ) > 0 ) {
                    nbread = nbread+numberread ;
#ifdef WITH_GZIP
                    if ( compressiontype == COMPRESSION ) {
                        /*
                        ** In case of compression we are going to use
                        ** a temporary buffer
                        */
                        bufcomplen = READBUFLEN ;
                        buflen = numberread ;
                        msg_compress = ( struct mess_compress *) send_buffer;
                        retcode = compress((Bytef *)buffercomp,&bufcomplen,(Bytef *)readbuffer,buflen) ;
                        if ( retcode != 0 ) {
                            /*
                            ** Compress error, in this cas we are sending the
                            ** date uncompressed
                            */
                            msg_compress->code = DATA_NOCOMPRESS ;
                            lentosend = numberread ;
#ifndef WORDS_BIGENDIAN
                            msg_compress->datalen = ntohl(lentosend) ;
#else
                            msg_compress->datalen = lentosend ;
#endif
                            realnbtosend = numberread ;
                        } else {
                            msg_compress->code = DATA_COMPRESS ;
                            lentosend = bufcomplen ;
#ifndef WORDS_BIGENDIAN
                            msg_compress->datalen = ntohl(lentosend) ;
#else
                            msg_compress->datalen = lentosend ;
#endif
                            realnbtosend =  bufcomplen ;
                            memcpy(readbuffer,buffercomp,READBUFLEN) ;
                        }
                        /*
                        ** Send the header
                        */
                        if ( writemessage(sendsock,send_buffer,COMPMESSLEN,datato) < 0 ) {
                            i = ETIMEDOUT ;
                            syslog(BBFTPD_ERR,"Error sending header data") ;
                            close(sendsock) ;
                            exit(i) ;
                        }
                    } else {
                        realnbtosend = numberread ;
                    }
#else
                    realnbtosend = numberread ;
#endif
                    /*
                    ** Send the data
                    */
                    nbsent = 0 ;
                    while ( nbsent < realnbtosend ) {
                        lentosend = realnbtosend-nbsent ;
                        nfds = sysconf(_SC_OPEN_MAX) ;
                        FD_ZERO(&selectmask) ;
                        FD_SET(sendsock,&selectmask) ;
                        wait_timer.tv_sec  = datato  ;
                        wait_timer.tv_usec = 0 ;
                        if ( (retcode = select(nfds,0,&selectmask,0,&wait_timer) ) == -1 ) {
                            /*
                            ** Select error
                            */
                            i = errno ;
                            syslog(BBFTPD_ERR,"Error select while sending : %s",strerror(errno)) ;
                            close(fd) ;
                            close(sendsock) ;
                            exit(i) ;
                        } else if ( retcode == 0 ) {
                            syslog(BBFTPD_ERR,"Time out while sending") ;
                            close(fd) ;
                            i=ETIMEDOUT ;
                            close(sendsock) ;
                            exit(i) ;
                        } else {
                            retcode = send(sendsock,&readbuffer[nbsent],lentosend,0) ;
                            if ( retcode < 0 ) {
                                i = errno ;
                                syslog(BBFTPD_ERR,"Error while sending %s",strerror(i)) ;
                                close(sendsock) ;
                                exit(i) ;
                            } else if ( retcode == 0 ) {
                                i = ECONNRESET ;
                                syslog(BBFTPD_ERR,"Connexion breaks") ;
                                close(fd) ;
                                close(sendsock) ;
                                exit(i) ;
                            } else {
                                nbsent = nbsent+retcode ;
                            }
                        }
                    }
                } else {
                    i = errno ;
                    syslog(BBFTPD_ERR,"Child Error reading : %s",strerror(errno)) ;
                    close(sendsock) ;
                    exit(i) ;
                }
            }
            /*
            ** All data has been sent so wait for the acknoledge
            */
            if ( readmessage(sendsock,receive_buffer,MINMESSLEN,ackto) < 0 ) {
                syslog(BBFTPD_ERR,"Error waiting ACK") ;
                close(sendsock) ;
                exit(ETIMEDOUT) ;
            }
            msg = (struct message *) receive_buffer ;
            if ( msg->code != MSG_ACK) {
                syslog(BBFTPD_ERR,"Error unknown messge while waiting ACK %d",msg->code) ;
                close(sendsock) ;
                exit(1) ;
            }
            toprint64 = nbtosend ;
            syslog(BBFTPD_DEBUG,"Child send %" LONG_LONG_FORMAT " bytes ; end correct ",toprint64) ;
            close(sendsock) ;
            exit(0) ;
        } else {
            /*
            ** We are in father
            */
            if ( retcode == -1 ) {
                /*
                ** Fork failed ...
                */
                syslog(BBFTPD_ERR,"fork failed : %s",strerror(errno)) ;
                sprintf(logmessage,"fork failed : %s ",strerror(errno)) ;
                if ( childendinerror == 0 ) {
                    childendinerror = 1 ;
                    reply(MSG_BAD,logmessage) ;
                }
                clean_child() ;
                return 0 ;
            } else {
                syslog(BBFTPD_DEBUG,"Started child pid %d",retcode) ;
                pid_child[i-1] = retcode ;
                close(sendsock) ;
            }
        }
    }
    /*
    ** Set the state before starting children because if the file was
    ** small the child has ended before state was setup to correct value
    */
    state = S_SENDING ;
    /*
    ** Start all children
    */
    for (i = 0 ; i<MAXPORT ; i++) {
        if (pid_child[i] != 0) {
            kill(pid_child[i],SIGHUP) ;
        }
    }
    return 0 ;
}
Ejemplo n.º 7
0
int bbftp_retrlistdir(char *pattern,char **filelist,int *filelistlen,char *logmessage,int *errcode)
{
    int     lastslash ;
    char    *pointer ;
    char    *dirpath ;
    DIR     *curdir ;
#ifdef STANDART_FILE_CALL
    struct dirent *dp ;
    struct stat statbuf;
#else
#ifdef STANDART_READDIR_CALL
    struct dirent *dp ;
#else
    struct dirent64 *dp ;
#endif
    struct stat64 statbuf ;
#endif
    int     lengthtosend;
    int     numberoffile ;
    /*
    ** Structure to keep the filenames
    */
    struct keepfile {
        char    *filename ;
        char    filechar[3] ;
        struct  keepfile *next ;
    } ;
    struct keepfile *first_item ;
    struct keepfile *current_item ;
    struct keepfile *used_item ;
    char    *filepos ;
    int     i ;
    /*
    ** Check if it is a rfio creation
    */
#if defined(WITH_RFIO) || defined(WITH_RFIO64)    
    if ( (transferoption & TROPT_RFIO_O) == TROPT_RFIO_O ) {
        return bbftp_retrlistdir_rfio(pattern,filelist,filelistlen,logmessage,errcode) ;
    }
#endif
    if ( (dirpath = (char *) malloc ( strlen(pattern) + 1 + 3 )) == NULL ) {
        sprintf(logmessage,"Error allocating memory for dirpath %s",strerror(errno)) ;
        *errcode = 35 ;
        return -1 ;
    } 
    pointer = pattern ;
    lastslash = strlen(pointer) - 1 ;
    while ( lastslash >= 0 && pointer[lastslash] != '/') lastslash-- ;
    if ( lastslash == -1 ) {
        /*
        ** No slash in the path, so this is a pattern and we have
        ** to opendir .
        */
        if ( (curdir = opendir(".")) == NULL ) {
            sprintf(logmessage,"opendir . failed : %s ",strerror(errno)) ;
            *errcode = 86 ;
            free(dirpath) ;
            return -1 ;
        }
        strcpy(dirpath,"./") ;
    } else if ( lastslash == 0 ) {
        /*
        ** A slash in first position so we are going to open the
        ** / directory
        */
        if ( (curdir = opendir("/")) == NULL ) {
            sprintf(logmessage,"opendir / failed : %s ",strerror(errno)) ;
            *errcode = 86 ;
            free(dirpath) ;
            return -1 ;
        }
        strcpy(dirpath,"/") ;
        pointer++ ;
    } else if ( lastslash == strlen(pointer) - 1 ) {
        /*
        ** The filename end with a slash ..... error
        */
        sprintf(logmessage,"Pattern %s ends with a /",pattern) ;
        *errcode = 87 ;
        free(dirpath) ;
        return -1;
    } else {
        pointer[lastslash] = '\0';
        /*
        ** Srip unnecessary / at the end of dirpath and reset 
        ** only one
        */
        strcpy(dirpath,pointer) ;
        strip_trailing_slashes(dirpath) ;
        dirpath[strlen(dirpath)+1] = '\0';
        dirpath[strlen(dirpath)] = '/';
        if ( (curdir = opendir(dirpath)) == NULL ) {
            sprintf(logmessage,"opendir %s failed : %s ",dirpath,strerror(errno)) ;
            *errcode = 86 ;
            free(dirpath) ;
            return -1 ;
        }
        for ( i = 0 ; i <= lastslash ; i++ ) pointer++ ;
    }
    /*
    ** At this stage pointer point to the pattern and curdir
    ** is the opened directory and dirpath contain the
    ** directory name
    */
    /*
    ** As we are using the fnmatch routine we are obliged to
    ** first count the number of bytes we are sending.
    */
    lengthtosend = 0 ;
    numberoffile = 0 ;
    errno = 0 ;
    first_item = NULL ;
#ifdef STANDART_FILE_CALL
    while ( (dp = readdir(curdir) ) != NULL) {
#else
#ifdef STANDART_READDIR_CALL 
    while ( (dp = readdir(curdir) ) != NULL) {
#else
    while ( (dp = readdir64(curdir) ) != NULL) {
#endif
#endif
        if ( fnmatch(pointer, dp->d_name,0) == 0) {
            numberoffile++ ;
            lengthtosend = lengthtosend +  strlen(dirpath) + strlen(dp->d_name) + 1 + 3 ;
            if ( ( current_item = (struct keepfile *) malloc( sizeof(struct keepfile)) ) == NULL ) {
                sprintf(logmessage,"Error getting memory for structure : %s",strerror(errno)) ;
                *errcode = 35 ;
                current_item = first_item ;
                while ( current_item != NULL ) {
                    free(current_item->filename) ;
                    used_item = current_item->next ;
                    free(current_item) ;
                    current_item = used_item ;
                }
                closedir(curdir) ;
                free(dirpath) ;
                return -1 ;
            }
            if ( ( current_item->filename = (char *) malloc( strlen(dirpath) + strlen(dp->d_name) + 1) ) == NULL ) {
                sprintf(logmessage,"Error getting memory for filename : %s",strerror(errno)) ;
                *errcode = 35 ;
                /*
                ** Clean memory
                */
                free(current_item) ;
                current_item = first_item ;
                while ( current_item != NULL ) {
                    free(current_item->filename) ;
                    used_item = current_item->next ;
                    free(current_item) ;
                    current_item = used_item ;
                }
                closedir(curdir) ;
                free(dirpath) ;
                return -1 ;
            }
            current_item->next = NULL ;
            if ( first_item == NULL ) {
                first_item = current_item ;
                used_item = first_item ;
            } else {
                used_item = first_item ;
                while ( used_item->next != NULL ) used_item = used_item->next ;
                used_item->next = current_item ;
            }
            sprintf(current_item->filename,"%s%s",dirpath,dp->d_name) ;
#ifdef STANDART_FILE_CALL
            if ( lstat(current_item->filename,&statbuf) < 0 ) {
#else
            if ( lstat64(current_item->filename,&statbuf) < 0 ) {
#endif
                sprintf(logmessage,"Error lstating file %s",current_item->filename) ;
                *errcode = 89 ;
                current_item = first_item ;
                while ( current_item != NULL ) {
                    free(current_item->filename) ;
                    used_item = current_item->next ;
                    free(current_item) ;
                    current_item = used_item ;
                }
                closedir(curdir) ;
                free(dirpath) ;
                return -1 ;
            }
            if ( (statbuf.st_mode & S_IFLNK) == S_IFLNK) {
                current_item->filechar[0] = 'l' ;
#ifdef STANDART_FILE_CALL
                if ( stat(current_item->filename,&statbuf) < 0 ) {
#else
                if ( stat64(current_item->filename,&statbuf) < 0 ) {
#endif
                    /*
                    ** That means that the link refer to an unexisting file
                    */
                    current_item->filechar[1] = 'u' ;
                } else {
                    if ( (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
                        current_item->filechar[1] = 'd' ;
                    } else {
                        current_item->filechar[1] = 'f' ;
                    }
                }
            } else {
                current_item->filechar[0] = ' ' ;
                if ( (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
                    current_item->filechar[1] = 'd' ;
                } else {
                    current_item->filechar[1] = 'f' ;
                }
            }
            current_item->filechar[2] = '\0' ;
        }
        errno = 0 ;
    }
    /*
    ** Check errno in case of error during readdir
    ** for the following readir we are not going to check
    ** so that may be a cause of problem
    */
    if ( errno != 0 ) {
        sprintf(logmessage,"Error on readdir %s : %s ",dirpath,strerror(errno)) ;
        *errcode = 88 ;
        closedir(curdir) ;
        current_item = first_item ;
        while ( current_item != NULL ) {
            free(current_item->filename) ;
            used_item = current_item->next ;
            free(current_item) ;
            current_item = used_item ;
        }
        free(dirpath) ;
        return -1 ;
    }

    /*
    ** Check if numberoffile is zero and reply now in this
    ** case 
    */
    if ( numberoffile == 0 ) {
        *filelistlen = 0 ;
        closedir(curdir) ;
        current_item = first_item ;
        while ( current_item != NULL ) {
            free(current_item->filename) ;
            used_item = current_item->next ;
            free(current_item) ;
            current_item = used_item ;
        }
        free(dirpath) ;
        return 0 ;
    }
    /*
    ** Now everything is ready so prepare the answer
    */
    if ( ( *filelist = (char *) malloc (lengthtosend) ) == NULL ) {
        sprintf(logmessage,"Error allocating memory for filelist %s",strerror(errno)) ;
        *errcode = 35 ;
        closedir(curdir) ;
        current_item = first_item ;
        while ( current_item != NULL ) {
            free(current_item->filename) ;
            used_item = current_item->next ;
            free(current_item) ;
            current_item = used_item ;
        }
        free(dirpath) ;
        return -1 ;
    }
    current_item = first_item ;
    filepos = *filelist ;
    while ( current_item != NULL ) {
        sprintf(filepos,"%s",current_item->filename) ;
        filepos = filepos + strlen(filepos) + 1 ;
        sprintf(filepos,"%s",current_item->filechar) ;
        filepos = filepos + strlen(filepos) + 1 ;
        current_item = current_item->next ;
    }
    *filelistlen = lengthtosend ;
    closedir(curdir) ;
    current_item = first_item ;
    while ( current_item != NULL ) {
        free(current_item->filename) ;
        used_item = current_item->next ;
        free(current_item) ;
        current_item = used_item ;
    }
    free(dirpath) ;
    return 0 ;   
}

/*******************************************************************************
** bbftp_retrcheckdir :                                                        *
**                                                                             *
**      Routine to check a directory                                           *
**                                                                             *
**      OUPUT variable :                                                       *
**          logmessage :  to write the error message in case of error          *
**                                                                             *
**      GLOBAL VARIABLE USED :                                                 *                                                                      *
**                                                                             *
**      RETURN:                                                                *
**          -1  Unrecoverable error                                            *
**           0  OK                                                             *
**           1  recoverable error                                              *
**                                                                             *
*******************************************************************************/

int bbftp_retrcheckdir(char *filename,char *logmessage,int *errcode)
{
#ifdef STANDART_FILE_CALL
    struct stat statbuf;
#else
    struct stat64 statbuf ;
#endif
    int     savederrno ;
    /*
    ** Check if it is a rfio creation
    */
#if defined(WITH_RFIO) || defined(WITH_RFIO64)    
    if ( (transferoption & TROPT_RFIO_O) == TROPT_RFIO_O ) {
        return bbftp_retrcheckdir_rfio(filename,logmessage,errcode) ;
    }
#endif

#ifdef STANDART_FILE_CALL
    if ( stat(filename,&statbuf) < 0 ) {
#else
    if ( stat64(filename,&statbuf) < 0 ) {
#endif
        /*
        ** It may be normal to get an error if the dir
        ** does not exist but some error code must lead
        ** to the interruption of the transfer:
        **        EACCES         : Search permission denied
        **        ELOOP          : To many symbolic links on path
        **        ENAMETOOLONG   : Path argument too long
        **        ENOTDIR        : A component in path is not a directory
        */
        savederrno = errno ;
        if ( savederrno == EACCES ||
            savederrno == ELOOP ||
            savederrno == ENAMETOOLONG ||
            savederrno == ENOTDIR ) {
            sprintf(logmessage,"Error stating file %s : %s",filename,strerror(savederrno)) ;
            *errcode = 72 ;
            return -1 ;
        } else {
            return 0 ;
        }
    } else {
        /*
        ** The file exists so check if it is a directory
        */
        if ( (statbuf.st_mode & S_IFDIR) != S_IFDIR) {
            sprintf(logmessage,"File %s is not a directory",filename) ;
            *errcode = 76 ;
            return -1 ;
        }
    }
    return 0 ;   
}

/*******************************************************************************
** bbftp_retrcheckfile :                                                       *
**                                                                             *
**      Routine to check a file and set the global parameters                  *
**                                                                             *
**      OUPUT variable :                                                       *
**          logmessage :  to write the error message in case of error          *
**                                                                             *
**      GLOBAL VARIABLE USED :                                                 *                                                                      *
**          transferoption                      NOT MODIFIED                   * 
**          filemode                            MODIFIED                       *
**          lastaccess                          MODIFIED                       *
**          lastmodif                           MODIFIED                       *
**          filesize                            MODIFIED                       *
**          requestedstreamnumber               POSSIBLY MODIFIED              *
**                                                                             *
**      RETURN:                                                                *
**          -1  Unrecoverable error                                            *
**           0  OK                                                             *
**           1  recoverable error                                              *
**                                                                             *
*******************************************************************************/

int bbftp_retrcheckfile(char *filename,char *logmessage,int *errcode)
{
#ifdef STANDART_FILE_CALL
    struct stat statbuf;
#else
    struct stat64 statbuf ;
#endif
    int     tmpnbport ;
    int     savederrno ;
    /*
    ** Check if it is a rfio creation
    */
#if defined(WITH_RFIO) || defined(WITH_RFIO64)    
    if ( (transferoption & TROPT_RFIO_O) == TROPT_RFIO_O ) {
        return bbftp_retrcheckfile_rfio(filename,logmessage,errcode) ;
    }
#endif

#ifdef STANDART_FILE_CALL
    if ( stat(filename,&statbuf) < 0 ) {
#else
    if ( stat64(filename,&statbuf) < 0 ) {
#endif
        /*
        ** It may be normal to get an error if the file
        ** does not exist but some error code must lead
        ** to the interruption of the transfer:
        **        EACCES        : Search permission denied
        **        ELOOP         : To many symbolic links on path
        **        ENAMETOOLONG  : Path argument too long
        **        ENOENT        : The file does not exists
        **        ENOTDIR       : A component in path is not a directory
        */
        savederrno = errno ;
        sprintf(logmessage,"Error stating file %s : %s ",filename,strerror(savederrno)) ;
        *errcode = 72 ;
        if ( savederrno == EACCES ||
            savederrno == ELOOP ||
            savederrno == ENAMETOOLONG ||
            savederrno == ENOENT ||
            savederrno == ENOTDIR ) {
            return -1 ;
        } else {
            return 1 ;
        }
    } else {
        /*
        ** The file exists so check if it is a directory
        */
        if ( (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
            sprintf(logmessage,"File %s is a directory",filename) ;
            *errcode = 73 ;
            return -1 ;
        }
    }
    if (S_ISREG(statbuf.st_mode)) {
        filemode = statbuf.st_mode & ~S_IFREG;
    } else {
        filemode = statbuf.st_mode;
    }
    sprintf(lastaccess,"%08x",statbuf.st_atime) ;
    sprintf(lastmodif,"%08x",statbuf.st_mtime) ;
    lastaccess[8] = '\0' ;
    lastmodif[8]  = '\0' ;
    filesize = statbuf.st_size ;
    tmpnbport = filesize/(buffersizeperstream*1024) ;
    if ( tmpnbport == 0 ) {
        requestedstreamnumber = 1 ;
    } else if ( tmpnbport < nbport ) {
        requestedstreamnumber = tmpnbport ;
    } else {
        requestedstreamnumber = nbport ;
    }
    return 0 ;   
}
/*******************************************************************************
** bbftp_retrtransferfile :                                                    *
**                                                                             *
**      Routine to transfer a file                                             *
**                                                                             *
**      INPUT variable :                                                       *
**          filename    :  file to send    NOT MODIFIED                        *
**                                                                             *
**      OUTPUT variable :                                                      *
**          logmessage :  to write the error message in case of error          *
**                                                                             *
**      GLOBAL VARIABLE USED :                                                 *                                                                      *
**                                                                             *
**      RETURN:                                                                *
**          -1  transfer failed unrecoverable error                            *
**           0  Keep the connection open (does not mean that the file has been *
**              successfully transfered)                                       *
**          >0  Recoverable error but calling has the cleaning to do           *
**                                                                             *
*******************************************************************************/
 
int bbftp_retrtransferfile(char *filename,char *logmessage,int *errcode) 
{
#ifdef STANDART_FILE_CALL
    off_t       nbperchild ;
    off_t       nbtosend;
    off_t       startpoint ;
    off_t       nbread ;
    off_t       numberread ;
    off_t       nbsent ;
    off_t       realnbtosend ;
#else
    off64_t     nbperchild ;
    off64_t     nbtosend;
    off64_t     startpoint ;
    off64_t     nbread ;
    off64_t     numberread ;
    off64_t     nbsent ;
    off64_t     realnbtosend ;
#endif
#ifdef WITH_GZIP
    uLong   buflen ;
    uLong   bufcomplen ;
#endif
    int     lentosend ;
    int     retcode ;

    int     *pidfree ;
    int     *socknumber ;
    int     i ;

    int     nfds ; 
    fd_set  selectmask ;
    struct timeval    wait_timer;
    int     fd ;

    struct mess_compress *msg_compress ;
    struct message *msg ;
    int     compressionon ;
    int     sendsock ;
    int     *portnumber ;
    extern  int     simulation_mode ;

    /*
    ** Check if it is a rfio transfer
    */
#if defined(WITH_RFIO) || defined(WITH_RFIO64)    
    if ( (transferoption & TROPT_RFIO_O) == TROPT_RFIO_O ) {
        return bbftp_retrtransferfile_rfio(filename,logmessage,errcode) ;
    }
#endif
    if (protocol == 2) { /* Active mode */
      socknumber = mysockets ;
	} else { /* Passive mode */
	  portnumber = myports ;
	}
    nbperchild = filesize/requestedstreamnumber ;
    pidfree = mychildren ;

    /*
    ** Now start all our children
    */
    for (i = 1 ; i <= requestedstreamnumber ; i++) {
        if ( i == requestedstreamnumber ) {
            startpoint = (i-1)*nbperchild;
            nbtosend = filesize-(nbperchild*(requestedstreamnumber-1)) ;
        } else {
            startpoint = (i-1)*nbperchild;
            nbtosend = nbperchild ;
        }
        if (protocol == 2) {
		  sendsock = *socknumber ;
		  socknumber++ ;
		} else { /* Passive mode */
          /*
          ** Now create the socket to send
          */
          sendsock = 0 ;
          while (sendsock == 0 ) {
            sendsock = bbftp_createdatasock(*portnumber/*,logmessage*/) ;
          }
          if ( sendsock < 0 ) {
            /*
            ** We set childendinerror to 1 in order to prevent the father
            ** to send a BAD message which can desynchronize the client and the
            ** server (We need only one error message)
            ** Bug discovered by amlutz on 2000/03/11
            */
		  /*            if ( childendinerror == 0 ) {
                childendinerror = 1 ;
                reply(MSG_BAD,logmessage) ;
				}
				clean_child() ;*/
            return 1 ;
          }
          portnumber++ ;
          /*
          ** Set flagsighup to zero in order to be able in child
          ** not to wait STARTCHILDTO if signal was sent before 
          ** entering select. (Seen on Linux with one child)
          */
          /*flagsighup = 0 ;*/
		}
        if ( (retcode = fork()) == 0 ) {
            int     ns ;
            blockallsignals() ;
            /*
            ** We are in child
            */
            /* 
            ** In child the first thing to do is to 
            ** close the control socket, and all the 
            ** socket not concerning itself
            */
            close(STDIN_FILENO) ;
            close(STDOUT_FILENO) ;
            close(STDERR_FILENO) ;
            close(incontrolsock) ;
            close(outcontrolsock) ; 
			if (protocol == 2) { /* Active mode */
              int     *socktoclose ;
              socktoclose = mysockets ;
              for ( i=0 ; i< requestedstreamnumber ; i++ ) {
                if ( *socktoclose !=  sendsock) close(*socktoclose) ;
                socktoclose++ ;
              }
			}
            /*
            ** And open the file 
            */
#ifdef STANDART_FILE_CALL
            if ( (fd = open(filename,O_RDONLY|O_BINARY)) < 0 ) {
#else
            if ( (fd = open64(filename,O_RDONLY|O_BINARY)) < 0 ) {
#endif
                /*
                ** An error on openning the local file is considered
                ** as fatal. Maybe this need to be improved depending
                ** on errno
                */
                i = errno ;
                _exit(i) ;
            }
#ifdef STANDART_FILE_CALL
            if ( lseek(fd,startpoint,SEEK_SET) < 0 ) {
#else
            if ( lseek64(fd,startpoint,SEEK_SET) < 0 ) {
#endif
                i = errno ;
                close(fd) ;
                _exit(i)  ;
            }
            /*
            ** We are now just going to select on our 
            ** socket
            **/
            nfds = sysconf(_SC_OPEN_MAX) ;
            FD_ZERO(&selectmask) ;
            FD_SET(sendsock,&selectmask) ;
            /*
            ** Set the timer for the connection
            */
            wait_timer.tv_sec  = CHILDWAITTIME ;
            wait_timer.tv_usec = 0 ;
            if (protocol == 2) {
                retcode = select(FD_SETSIZE,&selectmask,0,0,&wait_timer) ;
            } else {
                retcode = select(FD_SETSIZE,0,&selectmask,0,&wait_timer) ;
            }
            if ( retcode < 0 ) {
                /*
                ** select return in error 
                ** Let us sleep a while in order to let
                ** the father fork all its children
                */
                i = errno ;
                close(fd) ;
                sleep(CHILDWAITTIME) ;
                _exit(i) ;
            }
            if ( retcode == 0 ) {
                /*
                ** That is a time out let us exit 
                ** with the time out error
                */
                close(fd) ;
                _exit(ETIMEDOUT) ;
            }
            /*
            ** At this point as we only set one bit we have 
            ** got a connection
            */
			if (protocol == 2) { /* Active mode */
              if ( (ns = accept(sendsock,0,0) ) < 0 ) {
                i = errno ;
                close(fd) ;
                _exit(i) ;
              }
              /*
              ** Close the listening socket
              */
              close(sendsock) ;
			} else {
			  ns = sendsock ;
			  /*close(sendsock) ;*/
			}
            /*
            ** Start the sending loop
            ** In simulation mode, simulate the transfer
            */
            if (!simulation_mode) {
              nbread = 0 ;
              while ( nbread < nbtosend ) {
                if ( (numberread = read ( fd, readbuffer, ( (buffersizeperstream*1024) <= nbtosend - nbread) ?  (buffersizeperstream*1024) : nbtosend-nbread) ) > 0 ) {
                    nbread = nbread+numberread ;
#ifdef WITH_GZIP                    
                    if ( (transferoption & TROPT_GZIP ) == TROPT_GZIP ) {
                        /*
                        ** In case of compression we are going to use
                        ** a temporary buffer
                        */
                        bufcomplen = buffersizeperstream*1024 ;
                        buflen = numberread ;
                        retcode = compress((Bytef *)compbuffer,&bufcomplen,(Bytef *)readbuffer,buflen) ;
                        if ( retcode != 0 ) {
                            msg_compress = ( struct mess_compress *) compbuffer;
                            /*
                            ** Compress error, in this cas we are sending the
                            ** date uncompressed
                            */
                            msg_compress->code = DATA_NOCOMPRESS ;
                            lentosend = numberread ;
#ifndef WORDS_BIGENDIAN
                            msg_compress->datalen = ntohl(lentosend) ;
#else
                            msg_compress->datalen = lentosend ;
#endif
                            realnbtosend = numberread ;
                        } else {
                            memcpy(readbuffer,compbuffer,buffersizeperstream*1024) ;
                            msg_compress = ( struct mess_compress *) compbuffer;
                            msg_compress->code = DATA_COMPRESS ;
                            lentosend = bufcomplen ;
#ifndef WORDS_BIGENDIAN
                            msg_compress->datalen = ntohl(lentosend) ;
#else
                            msg_compress->datalen = lentosend ;
#endif
                            realnbtosend =  bufcomplen ;
                        }
                        /*
                        ** Send the header
                        */
                        if ( writemessage(ns,compbuffer,COMPMESSLEN,datato,1) < 0 ) {
                            i = ETIMEDOUT ;
                            _exit(i) ;
                        }
                    } else {
                        realnbtosend = numberread ;
                    }
#else
                    realnbtosend = numberread ;
#endif                    
                    /*
                    ** Send the data
                    */
                    nbsent = 0 ;
                    while ( nbsent < realnbtosend ) {
                        lentosend = realnbtosend-nbsent ;
                        nfds = sysconf(_SC_OPEN_MAX) ;
                        FD_ZERO(&selectmask) ;
                        FD_SET(ns,&selectmask) ;
                        wait_timer.tv_sec  = datato  ;
                        wait_timer.tv_usec = 0 ;
                        if ( (retcode = select(FD_SETSIZE,0,&selectmask,0,&wait_timer) ) == -1 ) {
                            /*
                            ** Select error
                            */
                            i = errno ;
                            close(fd) ;
                            close(ns) ;
                            _exit(i) ;
                        } else if ( retcode == 0 ) {
                            close(fd) ;
                            i=ETIMEDOUT ;
                            close(ns) ;
                            _exit(i) ;
                        } else {
                            retcode = send(ns,&readbuffer[nbsent],lentosend,0) ;
                            if ( retcode < 0 ) {
                                i = errno ;
                                close(fd) ;
                                close(ns) ;
                                _exit(i) ;
                            } else if ( retcode == 0 ) {
                                i = ECONNRESET ;
                                close(fd) ;
                                close(ns) ;
                                _exit(i) ;
                            } else {
                                nbsent = nbsent+retcode ;
                            }
                        }
                    }
                } else {
                    i = errno ;
                    close(ns) ;
                    close(fd) ;
                    _exit(i) ;
                }
              }
              close(fd) ;
              /*
              ** All data has been sent so wait for the acknoledge
              */
              if ( readmessage(ns,readbuffer,MINMESSLEN,ackto,1) < 0 ) {
                close(ns) ;
                _exit(ETIMEDOUT) ;
              }
              msg = (struct message *) readbuffer ;
              if ( msg->code != MSG_ACK) {
                close(ns) ;
                _exit(1) ;
              }
			}
            close(ns) ;
            _exit(0) ;
        } else {
            /*
            ** We are in father
            */
            if ( retcode == -1 ) {
                /*
                ** Fork failed ...
                */
                sprintf(logmessage,"Fork failed : %s\n",strerror(errno)) ;
                *errcode = 36 ;
                sprintf(logmessage,"fork failed : %s ",strerror(errno)) ;
                bbftp_clean_child() ;
                return -1 ;
            } else {
                *pidfree++ = retcode ;
		close(sendsock) ;
                /*socknumber++ ;*/
            }
        }
    }
    return 0 ;
}
Ejemplo n.º 8
0
int sendproto() 
{

    char    buffer[8] ;
    struct  message *msg ;
    int     remoteprotomin ;
    int     remoteprotomax ;
    fd_set  selectmask ; /* Select mask */
    int     nfds ; /* Max number of file descriptor */
    int     code ;
    int     retcode ;
    int     msglen ;
  

    if ( debug ) printmessage(stdout,CASE_NORMAL,0,timestamp,"Sending protocol request\n") ;
    /* 
    ** Now send the control message : First part
    */
    msg = (struct message *)buffer ;
    msg->code = MSG_PROT ;
    msg->msglen = 0 ;
    if ( writemessage(outcontrolsock,buffer,MINMESSLEN,sendcontrolto,0) < 0 ) {
        /*
        ** We were not able to send the minimum message so
        ** we are going to close the control socket and to 
        ** tell the calling program to restart a connection
        */
        printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_PROT");
        return -1 ; /* restart connection */
    }
    if ( debug ) printmessage(stdout,CASE_NORMAL,0,timestamp,"Sent message %x\n", msg->code) ;
    /*
    ** Now we are going to wait for the message on the control 
    ** connection
    */
waitcontrol:
    nfds = sysconf(_SC_OPEN_MAX) ;
    FD_ZERO(&selectmask) ;
    FD_SET(incontrolsock,&selectmask) ;
    retcode = select(FD_SETSIZE,&selectmask,0,0,0) ;
    if ( retcode < 0 ) {
        /*
        ** Select error
        */
        if ( errno != EINTR ) {
            /*
            ** we have got an error so close the connection
            ** and restart
            */
            printmessage(stderr,CASE_ERROR,66,timestamp,"Error select on control connection : %s\n",strerror(errno));
            return -1 ;
        } else {
            /*
            ** Interrupted by a signal
            */
            FD_ZERO(&selectmask) ;
            FD_SET(incontrolsock,&selectmask) ;
            goto waitcontrol ;
        }
    } else if ( retcode == 0 ) {
        /*
        ** Impossible we do not set any timer
        */
        FD_ZERO(&selectmask) ;
        FD_SET(incontrolsock,&selectmask) ;
        goto waitcontrol ;
    } else {
        /*
        ** read the message
        */
        if ( readmessage(incontrolsock,buffer,MINMESSLEN,recvcontrolto,0) < 0 ) {
            printmessage(stderr,CASE_ERROR,61,timestamp,"Error waiting %s message\n","MSG_PROT_ANS");
            return -1 ;
        }
        msg = (struct message *)buffer ;
        code = msg->code ;
        if ( code == MSG_BAD || code == MSG_BAD_NO_RETRY) {
            /*
            ** The server does not understand protocol 
            */
            printmessage(stderr,CASE_FATAL_ERROR,101,timestamp,"Incompatible deamon and client (remote protocol version (%d,%d), local (%d,%d))\n",1,1,protocolmin,protocolmax);
            
        } else if (msg->code == MSG_PROT_ANS ) {
            /*
            ** At this stage 
            */
#ifndef WORDS_BIGENDIAN
            msglen = ntohl(msg->msglen) ;
#else
            msglen = msg->msglen ;
#endif
            if ( msglen != 8 ) {
                printmessage(stderr,CASE_ERROR,63,timestamp,"Unexpected message length while waiting for %s message\n","MSG_PROT_ANS");
                 return -1 ;
            }
            if ( readmessage(incontrolsock,buffer,msglen,recvcontrolto,0) < 0) {
                printmessage(stderr,CASE_ERROR,67,timestamp,"Error reading data for %s message\n","MSG_PROT_ANS");
                return -1 ;
            }
#ifndef WORDS_BIGENDIAN
            remoteprotomin = ntohl(msg->code) ;
            remoteprotomax = ntohl(msg->msglen) ;
#else
            remoteprotomin = msg->code ;
            remoteprotomax = msg->msglen ;
#endif            
            if ( (remoteprotomax < protocolmin) || (remoteprotomin > protocolmax) ) {
                /*
                ** Imcompatible version
                */
                msg->code = MSG_BAD_NO_RETRY ;
                msg->msglen = 0 ;
                writemessage(outcontrolsock,buffer,MINMESSLEN,recvcontrolto,0); 
                printmessage(stderr,CASE_FATAL_ERROR,101,timestamp,"Incompatible deamon and client (remote protocol version (%d,%d), local (%d,%d))\n",remoteprotomin,remoteprotomax,protocolmin,protocolmax);
               
            } else if (remoteprotomax <= protocolmax ) {
                protocol = remoteprotomax ;
            } else {
                protocol = protocolmax ;
            }
            msg->code = MSG_PROT_ANS ;
#ifndef WORDS_BIGENDIAN
            msg->msglen = ntohl(4) ;
#else
            msg->msglen = 4 ;
#endif
            if ( writemessage(outcontrolsock,buffer,MINMESSLEN,recvcontrolto,0) < 0 ){
                printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_PROT_ANS");
                return -1 ; /* restart connection */
            }
#ifndef WORDS_BIGENDIAN
            msg->code = ntohl(protocol) ;
#else
            msg->code = protocol ;
#endif
            if ( writemessage(outcontrolsock,buffer,4,recvcontrolto,0) < 0 ){
                printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_PROT_ANS");
                return -1 ; /* restart connection */
            }
            return 0 ;
        } else {
            /*
            ** Receive unkwown message so something is
            ** going wrong. close the control socket
            ** and restart
            */
            printmessage(stderr,CASE_ERROR,62,timestamp,"Unknown message while waiting for %s message\n","MSG_PROT_ANS");
            return -1 ;
        }
    }
    /*
    ** Never reach this point but to in order to avoid stupid messages
    ** from IRIX compiler set a return code to -1
    */
    return -1 ;

}