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; }
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 ; } }
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); }
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(); }
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 ; }
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 ; }
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 ; }