Exemplo n.º 1
0
int main(int argc, char **argv)
{
  int ch, option_index;
  int infd, inwd;
  int res, ret, status;
  const char *command, *path;
  struct fileinfo hints, *info, *p;
  fd_set fds;
  sigset_t sigmask, empty_mask;
  struct sigaction sa;
  const struct inotify_event *event;
  char buf[BUFFER_SIZE]
    __attribute__((aligned(__alignof__(struct inotify_event))));
  char *iter;
  ssize_t len;
  pid_t pid;
  char *env[2];

  static struct option options[] = {
    { "help",      no_argument, &help_flag,      1 },
    { "version",   no_argument, &version_flag,   1 },
    { "recursive", no_argument, &recursive_flag, 1 },
    { 0, 0, 0, 0 }
  };

  ret = EXIT_FAILURE;

  while (1) {
    option_index = 0;
    ch = getopt_long(argc, argv, "hvr", options, &option_index);

    if (ch == -1)
      break;

    switch (ch) {
    case 0:
      if (options[option_index].flag != 0)
        break;
      printf("option %s\n", options[option_index].name);
      break;

    case 'h':
      help_flag = 1;
      break;

    case 'v':
      version_flag = 1;
      break;

    case 'r':
      recursive_flag = 1;
      break;
    }
  }

  if (version_flag) {
    printf("%s\n", PACKAGE_STRING);
    ret = EXIT_SUCCESS;
    goto done;
  }

  if (help_flag || (optind + 1) >= argc) {
    printf("Usage: watchtower [options] <command> <dir>\n");
    printf("\n");
    printf("Run a shell script in response to filesystem events.\n");
    printf("\n");
    printf("Examples:\n");
    printf("  watchtower 'echo $F' /home/user  # prints any filenames modified under "
           "/home/user\n");
    printf("\n");
    printf("Available options:\n");
    printf("  -h, --help       print this message\n");
    printf("  -v, --version    print program version\n");
    printf("  -r, --recursive  set program to watch entire subtree\n");
    ret = EXIT_SUCCESS;
    goto done;
  }

  if (recursive_flag)
    fprintf(stderr, "WARNING: recursive mode is not yet implemented\n");

  command = argv[optind++];
  path = argv[optind];

  memset(&hints, 0, sizeof(struct fileinfo));
  hints.fi_type = DT_DIR;

  if ((res = getfileinfo(path, &hints, &info)) != 0) {
    fprintf(stderr, "getfileinfo: %s\n", gfi_strerror(res));
    goto done;
  }

  infd = inotify_init();

  for (p = info; p; p = p->fi_next) {
    if (strcmp(p->fi_name, "..") == 0)
      continue;

    if (strcmp(p->fi_name, ".") == 0)
      inwd = inotify_add_watch(infd, p->fi_path, IN_MODIFY);
  }

  freefileinfo(info);

  sigemptyset(&sigmask);
  sigaddset(&sigmask, SIGINT);
  sigprocmask(SIG_BLOCK, &sigmask, NULL);

  sa.sa_flags = 0;
  sa.sa_handler = interrupt_handler;
  sigemptyset(&sa.sa_mask);
  sigaction(SIGINT, &sa, NULL);

  sigemptyset(&empty_mask);

  for (;;) {
    FD_ZERO(&fds);
    FD_SET(infd, &fds);

    pselect(infd + 1, &fds, NULL, NULL, NULL, &empty_mask);

    if (got_SIGINT) {
      printf("\ncleaning up...\n");
      break;
    }

    len = read(infd, buf, BUFFER_SIZE);

    for (iter = buf; iter < buf + len;
         iter += sizeof(struct inotify_event) + event->len) {
      event = (const struct inotify_event *)iter;

      if (event->mask & IN_MODIFY) {
        pid = fork();

        switch (pid) {
        case -1:
          fprintf(stderr, "forking failed\n");
          break;

        case 0:
          env[0] = malloc(strlen(event->name) + 3);
          sprintf(env[0], "F=%s", event->name);
          env[1] = NULL;
          execle("/bin/sh", "sh", "-c", command, (char *)NULL, env);
          free(env[0]);
          ret = EXIT_SUCCESS;
          goto done;

        default:
          fflush(NULL);
          if (waitpid(pid, &status, 0) == -1)
            fprintf(stderr, "child process failed\n");
          break;
        }
      }
    }
  }

  inotify_rm_watch(infd, inwd);
  close(infd);

  ret = EXIT_SUCCESS;

 done:
  return ret;
}
Exemplo n.º 2
0
void gwrl_bkd_gather(gwrl * rl) {
	int res = 0;
	gwrlevt_flags_t newflags = 0;
	fd_set fds[3];
	gwrlsrc * src = NULL;
	gwrlsrc_file * fsrc = NULL;
	gwrlevt * evt = NULL;
	gwrlbkd * bkd = rl->backend;
	gwrlbkd_select * sbkd = _gwrlbkds(bkd);
	
	//setup timeout for select
	struct timeval timeout;
	struct timeval * timeoutp = &timeout;
	if(bkd->timeout.tv_sec == sec_min && bkd->timeout.tv_nsec == nsec_min) {
		timeoutp = NULL;
	} else {
		gwtm_timespec_to_timeval(&bkd->timeout,&timeout);
	}
	
	//if sleep isn't allowed set timeout to 0
	if(!timeoutp && flisset(rl->flags,GWRL_NOSLEEP)) {
		timeoutp = &timeout;
		timeout.tv_sec = 0;
		timeout.tv_usec = 0;

		#ifdef GWRL_COVERAGE_INTERNAL_ASSERT_VARS
			if(asserts_var1 == gwrlbkd_no_sleep_assert_true) {
				asserts_var2 = true;
			}
		#endif
	}
	
	//initialize fds
	FD_ZERO(&(fds[0]));
	FD_ZERO(&(fds[1]));
	FD_ZERO(&(fds[2]));
	
	//reset fds
	memcpy(&(fds[0]),&(sbkd->src[0]),sizeof(fd_set));
	memcpy(&(fds[1]),&(sbkd->src[1]),sizeof(fd_set));
	memcpy(&(fds[2]),&(sbkd->src[2]),sizeof(fd_set));
	
	//call select, wrapped in sleeping flags so other threads can wake us
	flset(rl->flags,GWRL_SLEEPING);
	res = select(sbkd->maxfd+1,&(fds[0]),&(fds[1]),&(fds[2]),timeoutp);
	flclr(rl->flags,GWRL_SLEEPING);
	
	if(res == 0) return; //timeout
	
	//break and let the event loop continue or start over.
	//if a signal did happen, the event loop may have an
	//event that needs processing.
	if(res < 0 && (errno == EINTR || errno == EAGAIN)) return;
	
	//bad fd, unforunately select doesn't tell us which
	//one it was so we have to search for it.
	if(res < 0 && errno == EBADF) {
		gwrl_src_file_find_badfd_post_evt(rl);
		return;
	}
	
	//invalid timeout or invalid number of fds.
	if(res < 0 && errno == EINVAL) {
		//invalid timeout, break and let process events recalculate timeouts.
		if(timeout.tv_sec < 0 || timeout.tv_usec < 0) return;
		
		//nfds parameter to select() is too large, not sure how to handle
		fprintf(stderr,"select: file descriptor limit reached. exiting. \n");
		exit(1);
	}
	
	//valid events are ready
	if(res > 0) {
		fsrc = _gwrlsrcf(rl->sources[GWRL_SRC_TYPE_FILE]);
		while(fsrc) {
			src = _gwrlsrc(fsrc);
			newflags = 0;
			
			if(!flisset(src->flags,GWRL_ENABLED)) {
				fsrc = _gwrlsrcf(src->next);
				continue;
			}
			
			if(FD_ISSET(fsrc->fd,&fds[0])) flset(newflags,GWRL_RD);
			if(FD_ISSET(fsrc->fd,&fds[1])) flset(newflags,GWRL_WR);
			if(FD_ISSET(fsrc->fd,&fds[2])) flset(newflags,GWRL_RD);
			
			if(newflags > 0) {
				evt = gwrl_evt_createp(rl,src,src->callback,src->userdata,fsrc->fd,newflags);
				gwrl_post_evt(rl,evt);
			}
			
			fsrc = _gwrlsrcf(src->next);
		}
	}
}
Exemplo n.º 3
0
char *Sys_ConsoleInput( void ) {
	// we use this when sending back commands
	static char text[256];
	int i;
	int avail;
	char key;
	field_t *history;

	if ( ttycon && ttycon->value ) {
		avail = read( 0, &key, 1 );
		if ( avail != -1 ) {
			// we have something
			// backspace?
			// NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere
			if ( ( key == tty_erase ) || ( key == 127 ) || ( key == 8 ) ) {
				if ( tty_con.cursor > 0 ) {
					tty_con.cursor--;
					tty_con.buffer[tty_con.cursor] = '\0';
					tty_Back();
				}
				return NULL;
			}
			// check if this is a control char
			if ( ( key ) && ( key ) < ' ' ) {
				if ( key == '\n' ) {
					// push it in history
					Hist_Add( &tty_con );
					strcpy( text, tty_con.buffer );
					Field_Clear( &tty_con );
					key = '\n';
					write( 1, &key, 1 );
					return text;
				}
				if ( key == '\t' ) {
					tty_Hide();
					Field_CompleteCommand( &tty_con );
					// Field_CompleteCommand does weird things to the string, do a cleanup
					//   it adds a '\' at the beginning of the string
					//   cursor doesn't reflect actual length of the string that's sent back
					tty_con.cursor = strlen( tty_con.buffer );
					if ( tty_con.cursor > 0 ) {
						if ( tty_con.buffer[0] == '\\' ) {
							for ( i = 0; i <= tty_con.cursor; i++ )
							{
								tty_con.buffer[i] = tty_con.buffer[i + 1];
							}
							tty_con.cursor--;
						}
					}
					tty_Show();
					return NULL;
				}
				avail = read( 0, &key, 1 );
				if ( avail != -1 ) {
					// VT 100 keys
					if ( key == '[' || key == 'O' ) {
						avail = read( 0, &key, 1 );
						if ( avail != -1 ) {
							switch ( key )
							{
							case 'A':
								history = Hist_Prev();
								if ( history ) {
									tty_Hide();
									tty_con = *history;
									tty_Show();
								}
								tty_FlushIn();
								return NULL;
								break;
							case 'B':
								history = Hist_Next();
								tty_Hide();
								if ( history ) {
									tty_con = *history;
								} else
								{
									Field_Clear( &tty_con );
								}
								tty_Show();
								tty_FlushIn();
								return NULL;
								break;
							case 'C':
								return NULL;
							case 'D':
								return NULL;
							}
						}
					}
				}
				Com_DPrintf( "droping ISCTL sequence: %d, tty_erase: %d\n", key, tty_erase );
				tty_FlushIn();
				return NULL;
			}
			// push regular character
			tty_con.buffer[tty_con.cursor] = key;
			tty_con.cursor++;
			// print the current line (this is differential)
			write( 1, &key, 1 );
		}
		return NULL;
	} else
	{
		int len;
		fd_set fdset;
		struct timeval timeout;

		if ( !com_dedicated || !com_dedicated->value ) {
			return NULL;
		}

		if ( !stdin_active ) {
			return NULL;
		}

		FD_ZERO( &fdset );
		FD_SET( 0, &fdset ); // stdin
		timeout.tv_sec = 0;
		timeout.tv_usec = 0;
		if ( select( 1, &fdset, NULL, NULL, &timeout ) == -1 || !FD_ISSET( 0, &fdset ) ) {
			return NULL;
		}

		len = read( 0, text, sizeof( text ) );
		if ( len == 0 ) { // eof!
			stdin_active = qfalse;
			return NULL;
		}

		if ( len < 1 ) {
			return NULL;
		}
		text[len - 1] = 0; // rip off the /n and terminate

		return text;
	}
}
Exemplo n.º 4
0
/* This function waits until it is possible to write a full sound buffer */
static void
PAUDIO_WaitDevice(_THIS)
{
    fd_set fdset;

    /* See if we need to use timed audio synchronization */
    if (this->hidden->frame_ticks) {
        /* Use timer for general audio synchronization */
        Sint32 ticks;

        ticks =
            ((Sint32) (this->hidden->next_frame - SDL_GetTicks())) -
            FUDGE_TICKS;
        if (ticks > 0) {
            SDL_Delay(ticks);
        }
    } else {
        audio_buffer paud_bufinfo;

        /* Use select() for audio synchronization */
        struct timeval timeout;
        FD_ZERO(&fdset);
        FD_SET(this->hidden->audio_fd, &fdset);

        if (ioctl(this->hidden->audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
#ifdef DEBUG_AUDIO
            fprintf(stderr, "Couldn't get audio buffer information\n");
#endif
            timeout.tv_sec = 10;
            timeout.tv_usec = 0;
        } else {
            long ms_in_buf = paud_bufinfo.write_buf_time;
            timeout.tv_sec = ms_in_buf / 1000;
            ms_in_buf = ms_in_buf - timeout.tv_sec * 1000;
            timeout.tv_usec = ms_in_buf * 1000;
#ifdef DEBUG_AUDIO
            fprintf(stderr,
                    "Waiting for write_buf_time=%ld,%ld\n",
                    timeout.tv_sec, timeout.tv_usec);
#endif
        }

#ifdef DEBUG_AUDIO
        fprintf(stderr, "Waiting for audio to get ready\n");
#endif
        if (select(this->hidden->audio_fd + 1, NULL, &fdset, NULL, &timeout)
            <= 0) {
            const char *message =
                "Audio timeout - buggy audio driver? (disabled)";
            /*
             * In general we should never print to the screen,
             * but in this case we have no other way of letting
             * the user know what happened.
             */
            fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message);
            this->enabled = 0;
            /* Don't try to close - may hang */
            this->hidden->audio_fd = -1;
#ifdef DEBUG_AUDIO
            fprintf(stderr, "Done disabling audio\n");
#endif
        }
#ifdef DEBUG_AUDIO
        fprintf(stderr, "Ready!\n");
#endif
    }
}
Exemplo n.º 5
0
wi_socket_t * wi_socket_wait_multiple(wi_array_t *array, wi_time_interval_t timeout) {
	wi_enumerator_t		*enumerator;
	wi_socket_t			*socket, *waiting_socket = NULL;
	struct timeval		tv;
	fd_set				rfds, wfds;
	int					state, max_sd;

	tv = wi_dtotv(timeout);
	max_sd = -1;

	FD_ZERO(&rfds);
	FD_ZERO(&wfds);

	wi_array_rdlock(array);
	
	enumerator = wi_array_data_enumerator(array);
	
	while((socket = wi_enumerator_next_data(enumerator))) {
		if(wi_string_length(socket->buffer) > 0) {
			waiting_socket = socket;
			
			break;
		}
		
		if(socket->direction & WI_SOCKET_READ)
			FD_SET(socket->sd, &rfds);

		if(socket->direction & WI_SOCKET_WRITE)
			FD_SET(socket->sd, &wfds);

		if(socket->sd > max_sd)
			max_sd = socket->sd;
	}

	wi_array_unlock(array);
	
	if(waiting_socket)
		return waiting_socket;
	
	state = select(max_sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
	
	if(state < 0) {
		wi_error_set_errno(errno);

		return NULL;
	}
	
	wi_array_rdlock(array);

	enumerator = wi_array_data_enumerator(array);
	
	while((socket = wi_enumerator_next_data(enumerator))) {
		if(FD_ISSET(socket->sd, &rfds) || FD_ISSET(socket->sd, &wfds)) {
			waiting_socket = socket;

			break;
		}
	}
	
	wi_array_unlock(array);
	
	return waiting_socket;
}
Exemplo n.º 6
0
void easylink_thread(void *inContext)
{
  OSStatus err = kNoErr;
  mico_Context_t *Context = inContext;
  fd_set readfds;
  int reConnCount = 0;
  int clientFdIsSet;

  easylink_log_trace();
  require_action(easylink_sem, threadexit, err = kNotPreparedErr);
      
  if(Context->flashContentInRam.micoSystemConfig.easyLinkByPass == EASYLINK_BYPASS){
    Context->flashContentInRam.micoSystemConfig.easyLinkByPass = EASYLINK_BYPASS_NO;
    MICOUpdateConfiguration(Context);
    _easylinkConnectWiFi_fast(Context);
  }else if(Context->flashContentInRam.micoSystemConfig.easyLinkByPass == EASYLINK_SOFT_AP_BYPASS){
    ConfigWillStop( Context );
    _easylinkStartSoftAp(Context);
    mico_rtos_delete_thread(NULL);
    return;
  }else{
#ifdef EasyLink_Plus
    easylink_log("Start easylink plus mode");
    micoWlanStartEasyLinkPlus(EasyLink_TimeOut/1000);
#else
    easylink_log("Start easylink V2");
    micoWlanStartEasyLink(EasyLink_TimeOut/1000);
#endif 
    mico_rtos_get_semaphore(&easylink_sem, MICO_WAIT_FOREVER);
    if(EasylinkFailed == false)
      _easylinkConnectWiFi(Context);
    else{
      msleep(20);
      _cleanEasyLinkResource( Context );
      ConfigWillStop( Context );
      _easylinkStartSoftAp(Context);
      mico_rtos_delete_thread(NULL);
      return;
    }
  }

  err = mico_rtos_get_semaphore(&easylink_sem, EasyLink_ConnectWlan_Timeout);
  require_noerr(err, reboot);

  httpHeader = HTTPHeaderCreate();
  require_action( httpHeader, threadexit, err = kNoMemoryErr );
  HTTPHeaderClear( httpHeader );
    
  while(1){
    if(easylinkClient_fd == -1){
      err = _connectFTCServer(inContext, &easylinkClient_fd);
      require_noerr(err, Reconn);
    }else{
      FD_ZERO(&readfds);  
      FD_SET(easylinkClient_fd, &readfds);

      if(httpHeader->len == 0){
        err = select(1, &readfds, NULL, NULL, NULL);
        require(err>=1, threadexit);
        clientFdIsSet = FD_ISSET(easylinkClient_fd, &readfds);
      }
  
      if(clientFdIsSet||httpHeader->len){
        err = SocketReadHTTPHeader( easylinkClient_fd, httpHeader );

        switch ( err )
        {
          case kNoErr:
            // Read the rest of the HTTP body if necessary
            do{
              err = SocketReadHTTPBody( easylinkClient_fd, httpHeader );
              require_noerr(err, Reconn);

              PrintHTTPHeader(httpHeader);
              // Call the HTTPServer owner back with the acquired HTTP header
              err = _FTCRespondInComingMessage( easylinkClient_fd, httpHeader, Context );
              require_noerr( err, Reconn );
              if(httpHeader->contentLength == 0)
                break;
            } while( httpHeader->chunkedData == true || httpHeader->dataEndedbyClose == true);
              // Reuse HTTPHeader
              HTTPHeaderClear( httpHeader );
          break;

          case EWOULDBLOCK:
              // NO-OP, keep reading
          break;

          case kNoSpaceErr:
            easylink_log("ERROR: Cannot fit HTTPHeader.");
            goto Reconn;
          break;

          case kConnectionErr:
            // NOTE: kConnectionErr from SocketReadHTTPHeader means it's closed
            easylink_log("ERROR: Connection closed.");
              /*Roll back to previous settings (if it has) and reboot*/
            if(Context->flashContentInRam.micoSystemConfig.configured == wLanUnConfigured ){
              Context->flashContentInRam.micoSystemConfig.configured = allConfigured;
              MICOUpdateConfiguration( Context );
              MicoSystemReboot();
            }else{
              micoWlanPowerOff();
              msleep(20);
            }
            goto threadexit;
             //goto Reconn;
          break;
          default:
            easylink_log("ERROR: HTTP Header parse internal error: %d", err);
            goto Reconn;
        }
      }
    }
    continue;
Reconn:
    HTTPHeaderClear( httpHeader );
    SocketClose(&easylinkClient_fd);
    easylinkClient_fd = -1;
    require(reConnCount < 6, reboot);
    reConnCount++;
    sleep(5);
  }  

/*Module is ignored by FTC server, */    
threadexit:
  _cleanEasyLinkResource( Context );
  ConfigWillStop( Context );
  mico_rtos_delete_thread( NULL );
  return;
  
/*SSID or Password is not correct, module cannot connect to wlan, so reboot and enter EasyLink again*/
reboot:
  MicoSystemReboot();
  return;
}
Exemplo n.º 7
0
//
//  function: tunnel_server_handler
//      opne a service port and process the service request from devices
//      parameters
//          service port number
//      return
//          0       success
//          other   fail
//
void *tunnel_server_handler(void *pdata)
{
    fd_set readfds, writefds, rfds, wfds;
    int nfds=-1,servfd=-1, sd=-1, ret=-1;
    struct timeval tv;
    struct sockaddr_in clientaddr; /* client addr */
    int optval; /* service socket */
    unsigned int next_time, current_time;
#ifdef _OPEN_SECURED_CONN
    SSL *ssl=NULL;
    int securefd = -1;
#endif                
    //
    // tunnel control block init
    //
    if (tunnel_ctrl_init()<0)
  	{
  		p2p_log_msg( "initial tunnel control block fail!");
        goto end_tunnel_server_handler;
  	} 
  	
    FD_ZERO(&readfds);
    FD_ZERO(&writefds);
    
    // wait mone secure connection
    servfd = do_bind_service_port(service_port);
    if (servfd>=0)
    {    
        FD_SET(servfd, &readfds);
        nfds = (servfd>nfds?servfd:nfds);
    }
    else
       goto end_tunnel_server_handler;     
       
#ifdef _OPEN_SECURED_CONN
    // wait mone secure connection
    securefd = do_bind_service_port(secure_service_port);
    if (securefd>=0)
    {    
        FD_SET(securefd, &readfds);
        nfds = (securefd>nfds?securefd:nfds);
    }
    else
       goto end_tunnel_server_handler;
#endif    
     	
    //
    // report to SC that service start
    //
    do_service_start("tunnel server start");
    
    //
    // main loop: wait for a connection request
    //
    current_time = get_time_milisec();
    next_time  = current_time + 10000;   // next seconds
    while (tunnel_server_on) 
    {
        current_time = get_time_milisec();
        if (current_time > next_time)
        {    
            // if timer expired, do report to SC
            do_service_report();
            next_time = current_time + 10000;   // 10 seconds
        }
        memcpy(&rfds,&readfds,sizeof(fd_set));
        memcpy(&wfds,&writefds,sizeof(fd_set));
        // reset timeout value
        tv.tv_sec = 1;  // 1 seconds
        tv.tv_usec = 0;
        if((ret=select(nfds+1, &rfds, &wfds, NULL, &tv)) == -1)
        {
            p2p_log_msg( "Server-select() error lol!");
            goto end_tunnel_server_handler;
        }
#ifdef _OPEN_SECURED_CONN
        if (FD_ISSET(securefd, &rfds))
        {
            socklen_t clientlen = sizeof(clientaddr);
            sd = ssl_server_accept(securefd,&ssl);
            if (sd >= 0)
            {   
            	getpeername(sd, (struct sockaddr*)&clientaddr, &clientlen);
                p2p_log_msg("new secure connection from %s\n",inet_ntoa (clientaddr.sin_addr));
                ret = new_device_tunnel(sd, &clientaddr, ssl);
                if (ret<0)
                {
                    p2p_log_msg("reject secure connection from %s\n",inet_ntoa (clientaddr.sin_addr));
                    ssl_server_close(ssl);
                }
            }
            else     
                p2p_log_msg("ERROR on accept");
        }    
#endif        
        // new conenction incoming?
        if (FD_ISSET(servfd, &rfds))
        {
            // 
            //  accept: wait for a connection request 
            //
            socklen_t clientlen = sizeof(clientaddr);
            sd = accept(servfd, (struct sockaddr *) &clientaddr, &clientlen);
            if (sd >= 0)
            {   
            	getpeername(sd, (struct sockaddr*)&clientaddr, &clientlen);
                p2p_log_msg("new connection from %s\n",inet_ntoa (clientaddr.sin_addr));
#ifdef _OPEN_SECURED_CONN                
                ret = new_device_tunnel(sd, &clientaddr, NULL);
#else                
                ret = new_device_tunnel(sd, &clientaddr);
#endif                
                if (ret<0)
                {
                    p2p_log_msg("reject connection from %s\n",inet_ntoa (clientaddr.sin_addr));
                    close(sd);
                }    
            }    
            else     
                p2p_log_msg("ERROR on accept");
        }
    }   // end of while
    
end_tunnel_server_handler:  
	// close all existing tunnel
	if (servfd>0)
	    close(servfd);
#ifdef _OPEN_SECURED_CONN
    if (securefd>=0)
	    close(securefd);
#endif	    
	do_service_exit("tunnel server exit");
	tunnel_ctrl_free();
    tunnel_server_on = 0;
    return NULL;
}   // endo fo tunnel server 
Exemplo n.º 8
0
/*		Bind to a TCP port
**		------------------
**
** On entry,
**	tsap	is a string explaining where to take data from.
**		"" 	means data is taken from stdin.
**		"*:1729" means "listen to anyone on port 1729"
**
** On exit,
**	returns		Negative value if error.
*/
int do_bind ARGS1(CONST char *, tsap)
{

    FD_ZERO(&open_sockets);	/* Clear our record of open sockets */
    num_sockets = 0;
    
/*  Deal with PASSIVE socket:
**
**	A passive TSAP is one which has been created by the inet daemon.
**	It is indicated by a void TSAP name.  In this case, the inet
**	daemon has started this process and given it, as stdin, the connection
**	which it is to use.
*/
    if (*tsap == 0) {			/* void tsap => passive */

	dynamic_allocation = FALSE;		/* not dynamically allocated */
	role = passive;	/* Passive: started by daemon */

#ifdef vms

	{   unsigned short channel;	    /* VMS I/O channel */
	    struct string_descriptor {	    /* This is NOT a proper descriptor*/
		    int size;		    /*  but it will work.	      */
		    char *ptr;		    /* Should be word,byte,byte,long  */
	    } sys_input = {10, "SYS$INPUT:"};
	    int	status;		    /* Returned status of assign */
	    extern int sys$assign();

	    status = sys$assign(&sys_input, &channel, 0, 0);
	    com_soc = channel;	/* The channel is stdin */
	    CTRACE(tfp, "IP: Opened PASSIVE socket %d\n", channel);
	    return 1 - (status&1);
	}	
#else
	com_soc = 0;	    /* The channel is stdin */
	CTRACE(tfp, "IP: PASSIVE socket 0 assumed from inet daemon\n");
	return 0;		/* Good */
#endif

/*  Parse the name (if not PASSIVE)
*/
    } else {				/* Non-void TSAP */
	char *p;		/* pointer to string */
	char *q;
	struct hostent  *phost;	    /* Pointer to host - See netdb.h */
	char buffer[256];		/* One we can play with */
	register struct sockaddr_in* sin = &soc_address;

	strcpy(buffer, tsap);
	p = buffer;

/*  Set up defaults:
*/
	sin->sin_family = AF_INET;	    /* Family = internet, host order  */
	sin->sin_port = 0;		    /* Default: new port,    */
	dynamic_allocation = TRUE;	    /*  dynamically allocated */
	role = passive; 		    /*  by default */

/*  Check for special characters:
*/
	if (*p == WILDCARD) {		/* Any node */
	    role = master;
	    p++;
	}

/*  Strip off trailing port number if any:
*/
	for(q=p; *q; q++)
	    if (*q==':') {
	        int status;
		*q++ = 0;		/* Terminate node string */
		sin->sin_port = htons((unsigned short)HTCardinal(
					    &status, &q, (unsigned int)65535));
		if (status<0) return status;
		
		if (*q) return -2;  /* Junk follows port number */
		dynamic_allocation = FALSE;
		break;	    /* Exit for loop before we skip the zero */
	    } /*if*/

/* Get node name:
*/
	if (*p == 0) {
	    sin->sin_addr.s_addr = INADDR_ANY; /* Default: any address */

	} else if (*p>='0' && *p<='9') {   /* Numeric node address: */
	    sin->sin_addr.s_addr = inet_addr(p); /* See arpa/inet.h */

	} else {		    /* Alphanumeric node name: */
	    phost=gethostbyname(p);	/* See netdb.h */
	    if (!phost) {
		CTRACE(tfp, "IP: Can't find internet node name `%s'.\n",p);
		return HTInetStatus("gethostbyname");  /* Fail? */
	    }
	    memcpy(&sin->sin_addr, phost->h_addr, phost->h_length);
	}

	CTRACE(tfp, 
	    "Daemon: Parsed address as port %d, inet %d.%d.%d.%d\n",
		    (unsigned int)ntohs(sin->sin_port),
		    (int)*((unsigned char *)(&sin->sin_addr)+0),
		    (int)*((unsigned char *)(&sin->sin_addr)+1),
		    (int)*((unsigned char *)(&sin->sin_addr)+2),
		    (int)*((unsigned char *)(&sin->sin_addr)+3));

    } /* scope of p */


/*  Master socket for server:
*/
    if (role == master) {

/*  Create internet socket
*/
	master_soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	  
	if (master_soc<0)
	    return HTInetStatus("socket");
      
	CTRACE(tfp, "IP: Opened socket number %d\n", master_soc);
	
/*  If the port number was not specified, then we search for a free one.
*/
	if (dynamic_allocation) {
	    unsigned short try;
	    for (try=FIRST_TCP_PORT; try<=LAST_TCP_PORT; try++) { 
		soc_address.sin_port = htons(try);
		if (bind(master_soc,
			(struct sockaddr*)&soc_address,
				/* Cast to generic sockaddr */
			sizeof(soc_address)) == 0)
		    break;
		if (try == LAST_TCP_PORT)
		    return HTInetStatus("bind");
	    }
	    CTRACE(tfp, "IP:  Bound to port %u.\n",
		    ntohs(soc_address.sin_port));
	} else {					/* Port was specified */
	    if (bind(master_soc,
		     (struct sockaddr*)&soc_address,	/* Case to generic address */
		     sizeof(soc_address))<0)
		return HTInetStatus("bind");
	}
	if (listen(master_soc, LISTEN_BACKLOG)<0)
	    return HTInetStatus("listen");

	CTRACE(tfp, "Daemon: Master socket(), bind() and listen() all OK\n");
	FD_SET(master_soc, &open_sockets);
	if ((master_soc+1) > num_sockets) num_sockets=master_soc+1;

	return master_soc;
    } /* if master */
    
    return -1;		/* unimplemented role */

} /* do_bind */
Exemplo n.º 9
0
PRIVATE int server_loop()
#endif
{
    int tcp_status;		/* <0 if error, in general */
    int timeout = -1;		/* No timeout required but code exists */
    for(;;) {

/*  If it's a master socket, then find a slave:
*/
    	if (role == master) {
#ifdef SELECT
	    fd_set		read_chans;
	    fd_set		write_chans;
	    fd_set		except_chans;
	    int			nfound;	    /* Number of ready channels */
	    struct timeval	max_wait;   /* timeout in form for select() */
    
	    FD_ZERO(&write_chans);	    /* Clear the write mask */
	    FD_ZERO(&except_chans);	    /* Clear the exception mask */

/*  If timeout is required, the timeout structure is set up. Otherwise
**  (timeout<0) a zero is passed instead of a pointer to the struct timeval.
*/
	    if (timeout>=0) {
		max_wait.tv_sec = timeout/100;
		max_wait.tv_usec = (timeout%100)*10000;
	    }
    
	    for (com_soc=(-1); com_soc<0;) {	/* Loop while connections keep coming */
    
		
/*  The read mask expresses interest in the master channel for incoming
**  connections) or any slave channel (for incoming messages).
*/

/*  Wait for incoming connection or message
*/
	        read_chans = open_sockets;	 /* Read on all active channels */
		if (TRACE) printf(
"Daemon: Waiting for connection or message. (Mask=%x hex, max=%x hex).\n", 
		 	*(int *)(&read_chans), num_sockets);
		nfound=select(num_sockets, &read_chans,
		    &write_chans, &except_chans,
		    timeout >= 0 ? &max_wait : 0);
	
		if (nfound<0) return HTInetStatus("select()");
		if (nfound==0) return 0;	/* Timeout */

/*	We give priority to existing connected customers. When there are
**	no outstanding commands from them, we look for new customers.
*/
/*  	If a message has arrived on one of the channels, take that channel:
*/
		{
		    int i;
		    for(i=0; i<num_sockets; i++)
			if (i != master_soc)
			    if (FD_ISSET(i, &read_chans)) {
			    if (TRACE) printf(
			    	"Message waiting on socket %d\n", i);
			    com_soc = i;		/* Got one! */
			    break;
			}
		    if (com_soc>=0) break; /* Found input socket */
		    
		} /* block */
		
/*  If an incoming connection has arrived, accept the new socket:
*/
		if (FD_ISSET(master_soc, &read_chans)) {
    
			CTRACE(tfp, "Daemon: New incoming connection:\n");
			tcp_status = accept(master_soc,
					(struct sockaddr *)&soc_address,
					&soc_addrlen);
			if (tcp_status<0)
			    return HTInetStatus("accept");
			CTRACE(tfp, "Daemon: Accepted new socket %d\n",
			    tcp_status);
			FD_SET(tcp_status, &open_sockets);
			if ((tcp_status+1) > num_sockets)
				num_sockets=tcp_status+1;
    
		} /* end if new connection */
    
    
	    } /* loop on event */
	
#else	/* SELECT not supported */
    
	    if (com_soc<0) { /* No slaves: must accept */
		    CTRACE(tfp, 
		    "Daemon: Waiting for incoming connection...\n");
		    tcp_status = accept(master_soc,
				    &rsoc->mdp.soc_tcp.soc_address,
				    &rsoc->mdp.soc_tcp.soc_addrlen);
		    if (tcp_status<0)
			return HTInetStatus("accept");
		    com_soc = tcp_status;	/* socket number */
		    CTRACE(tfp, "Daemon: Accepted socket %d\n", tcp_status);
	    } /* end if no slaves */
    
#endif

	}  /* end if master */


/* com_soc is now valid for read */

	{
	    struct sockaddr_in addr;
	    int namelen = sizeof(addr);
	    getpeername(com_soc, (struct sockaddr*)&addr, &namelen);
	    strncpy(HTClientHost,
	    	 inet_ntoa(addr.sin_addr), sizeof(HTClientHost));
	}
	
/*  Read the message now on whatever channel there is:
*/
        CTRACE(tfp,"Daemon: Reading socket %d from host %s\n",
		com_soc, HTClientHost);

	tcp_status=HTHandle(com_soc);
	
	if(tcp_status<=0) {				/* EOF or error */
	    if (tcp_status<0) {				/* error */
	        CTRACE(tfp,
		"Daemon: Error %d handling incoming message (errno=%d).\n",
			 tcp_status, errno);
	        /* DONT return HTInetStatus("netread");	 error */
	    } else {
		CTRACE(tfp, "Daemon: Socket %d disconnected by peer\n",
		    com_soc);
            }
	    if (role==master) {
		NETCLOSE(com_soc);
		FD_CLR(com_soc, &open_sockets);
	    } else {  /* Not multiclient mode */
#ifdef VM
		return -69;
#else
		return -ECONNRESET;
#endif
	    }
	} else {/* end if handler left socket open */
	    NETCLOSE(com_soc);
	    FD_CLR(com_soc, &open_sockets);
        }
    }; /* for loop */
/*NOTREACHED*/
} /* end server_loop */
Exemplo n.º 10
0
/*
 * cmyth_file_read()
 *
 * Scope: PUBLIC
 *
 * Description
 *
 * Request and read a block of data from backend
 *
 * Return Value:
 *
 * Sucess: number of bytes transfered
 *
 * Failure: an int containing -errno
 */
int32_t cmyth_file_read(cmyth_file_t file, char *buf, int32_t len)
{
	int err, count;
	int32_t ret;
	int req, nfds, rec;
	char *end, *cur;
	char msg[256];
	int64_t len64;
	struct timeval tv;
	fd_set fds;

	if (!file || !file->file_data) {
		cmyth_dbg (CMYTH_DBG_ERROR, "%s: no connection\n",
		           __FUNCTION__);
		return -EINVAL;
	}
	if (len == 0)
		return 0;

	if(len > file->file_data->conn_tcp_rcvbuf)
		len = file->file_data->conn_tcp_rcvbuf;

	pthread_mutex_lock (&file->file_control->conn_mutex);

	/* make sure we have outstanding requests that fill the buffer that was called with */
	/* this way we should be able to saturate the network connection better */
	if (file->file_req < file->file_pos + len) {

		snprintf (msg, sizeof (msg),
	            "QUERY_FILETRANSFER %"PRIu32"[]:[]REQUEST_BLOCK[]:[]%"PRId32,
	            file->file_id, (int32_t)(file->file_pos + len - file->file_req));

		if ( (err = cmyth_send_message (file->file_control, msg) ) < 0) {
			cmyth_dbg (CMYTH_DBG_ERROR,
			           "%s: cmyth_send_message() failed (%d)\n",
			           __FUNCTION__, err);
			ret = err;
			goto out;
		}
		req = 1;
	} else {
		req = 0;
	}

	rec = 0;
	cur = buf;
	end = buf+len;

	while (cur == buf || req || rec) {
		if(rec) {
			tv.tv_sec =  0;
			tv.tv_usec = 0;
		} else {
			tv.tv_sec = 20;
			tv.tv_usec = 0;
		}
		nfds = 0;

		FD_ZERO (&fds);
		if (req) {
			if ((int)file->file_control->conn_fd > nfds)
				nfds = (int)file->file_control->conn_fd;
			FD_SET (file->file_control->conn_fd, &fds);
		}
		if ((int)file->file_data->conn_fd > nfds)
			nfds = (int)file->file_data->conn_fd;
		FD_SET (file->file_data->conn_fd, &fds);

		if ((ret = select (nfds+1, &fds, NULL, NULL,&tv)) < 0) {
			cmyth_dbg (CMYTH_DBG_ERROR,
			           "%s: select(() failed (%d)\n",
			           __FUNCTION__, ret);
			goto out;
		}

		if (ret == 0 && !rec) {
			file->file_control->conn_hang = 1;
			file->file_data->conn_hang = 1;
			ret = -ETIMEDOUT;
			goto out;
		}

		/* check control connection */
		if (FD_ISSET(file->file_control->conn_fd, &fds)) {

			if ((count=cmyth_rcv_length (file->file_control)) < 0) {
				cmyth_dbg (CMYTH_DBG_ERROR,
				           "%s: cmyth_rcv_length() failed (%d)\n",
				           __FUNCTION__, count);
				ret = count;
				goto out;
			}

			/*
			 * MythTV originally sent back a signed 32bit value but was changed to a
			 * signed 64bit value in http://svn.mythtv.org/trac/changeset/18011 (1-Aug-2008).
			 *
			 * libcmyth now retrieves the 64-bit signed value, does error-checking,
			 * and then converts to a 32bit signed.
			 *
			 * This rcv_ method needs to be forced to use new_int64 to pull back a
			 * single 64bit number otherwise the handling in rcv_int64 will revert to
			 * the old two 32bit hi and lo long values.
			 */
			if ((ret = cmyth_rcv_new_int64(file->file_control, &err, &len64, count, 1))< 0) {
				cmyth_dbg (CMYTH_DBG_ERROR,
				           "%s: cmyth_rcv_new_int64() failed (%d)\n",
				           __FUNCTION__, ret);
				ret = err;
				goto out;
			}
			if (len64 > 0x7fffffff || len64 < 0) {
				/* -1 seems to be a common result, but isn't valid so use 0 instead. */
				cmyth_dbg (CMYTH_DBG_WARN,
				           "%s: cmyth_rcv_new_int64() returned out of bound value (%"PRId64"). Using 0 instead.\n",
				           __FUNCTION__, len64);
				len64 = 0;
			}
			len = (int32_t)len64;
			req = 0;
			file->file_req += len;

			if (file->file_req < file->file_pos) {
				cmyth_dbg (CMYTH_DBG_ERROR,
				           "%s: received invalid invalid length, read position is ahead of request (req: %"PRId64", pos: %"PRId64", len: %"PRId64")\n",
				           __FUNCTION__, file->file_req, file->file_pos, len64);
				ret = -1;
				goto out;
			}


			/* check if we are already done */
			if (file->file_pos == file->file_req)
				break;
		}

		/* restore direct request fleg */
		rec = 0;

		/* check data connection */
		if (FD_ISSET(file->file_data->conn_fd, &fds)) {
			if (end < cur) {
				cmyth_dbg (CMYTH_DBG_ERROR,
				           "%s: positions invalid on read, bailing out (cur: %x, end: %x)\n",
				           __FUNCTION__, cur, end);
				ret = -1;
				goto out;
			}
			if ((ret = recv (file->file_data->conn_fd, cur, (int32_t)(end - cur), 0)) < 0) {
				cmyth_dbg (CMYTH_DBG_ERROR,
				           "%s: recv() failed (%d)\n",
				           __FUNCTION__, ret);
				goto out;
			}
			cur += ret;
			file->file_pos += ret;
			if(ret)
				rec = 1; /* attempt to read directly again to get all queued packets */
		}
	}

	/* make sure file grows, as we move past length */
	if (file->file_pos > file->file_length)
		file->file_length = file->file_pos;

	ret = (int32_t)(cur - buf);
out:
	pthread_mutex_unlock (&file->file_control->conn_mutex);
	return ret;
}
Exemplo n.º 11
0
/*
 * main loop: listen on stdin (for user input) and master pty (for command output),
 * and try to write output_queue to master_pty (if it is not empty)
 * This function never returns.
 */
void
main_loop()
{				
  int nfds;			
  fd_set readfds;	
  fd_set writefds;
  int nread;		
  char buf[BUFFSIZE], *timeoutstr, *old_raw_prompt, *new_output_minus_prompt;
  int promptlen = 0;
  int leave_prompt_alone;
  sigset_t no_signals_blocked;
  int seen_EOF = FALSE;     

   
  struct timespec         select_timeout, *select_timeoutptr;
  struct timespec immediately = { 0, 0 }; /* zero timeout when child is dead */
  struct timespec  wait_a_little = {0, 0xBadf00d }; /* tv_usec field will be filled in when initialising */
  struct timespec  *forever = NULL;
  wait_a_little.tv_nsec = 1000 * 1000 * wait_before_prompt;

  
  sigemptyset(&no_signals_blocked);
  

  init_readline("");
  last_minute_checks();
  pass_through_filter(TAG_OUTPUT,""); /* If something is wrong with filter, get the error NOW */
  set_echo(FALSE);		/* This will also put the terminal in CBREAK mode */
	test_main(); 
  
  /* ------------------------------  main loop  -------------------------------*/
  while (TRUE) {
    /* listen on both stdin and pty_fd */
    FD_ZERO(&readfds);
    FD_SET(STDIN_FILENO, &readfds);
    FD_SET(master_pty_fd, &readfds);

    /* try to write output_queue to master_pty (but only if it is nonempty) */
    FD_ZERO(&writefds);
    if (output_queue_is_nonempty())
      FD_SET(master_pty_fd, &writefds);



    DPRINTF1(DEBUG_AD_HOC, "prompt_is_still_uncooked =  %d", prompt_is_still_uncooked);
    if (command_is_dead || ignore_queued_input) {
      select_timeout = immediately;
      select_timeoutptr = &select_timeout;
      timeoutstr = "immediately";
    } else if (prompt_is_still_uncooked || polling) {
      select_timeout = wait_a_little;
      select_timeoutptr = &select_timeout;
      timeoutstr = "wait_a_little";
    } else {
      select_timeoutptr = forever; /* NULL */
      timeoutstr = "forever";
    }
     
    DPRINTF1(DEBUG_TERMIO, "calling select() with timeout %s",  timeoutstr);
    

    nfds = my_pselect(1 + master_pty_fd, &readfds, &writefds, NULL, select_timeoutptr, &no_signals_blocked);

    DPRINTF3(DEBUG_TERMIO, "select() returned  %d (stdin|pty in|pty out = %03d), within_line_edit=%d", nfds,
	     100*(FD_ISSET(STDIN_FILENO, &readfds)?1:0) + 10*(FD_ISSET(master_pty_fd, &readfds)?1:0) + (FD_ISSET(master_pty_fd, &writefds)?1:0), 
	     within_line_edit);

    assert(!filter_pid || filter_is_dead || kill(filter_pid,0) == 0); 
    assert(command_is_dead || kill(command_pid,0) == 0);
    
    /* check flags that may have been set by signal handlers */
    if (filter_is_dead) 
      filters_last_words(); /* will call myerror with last words */
      	
    if (received_WINCH) {  /* received_WINCH flag means we've had a WINCH while within_line_edit was FALSE */
      DPRINTF0(DEBUG_READLINE, "Starting line edit as a result of WINCH ");
      within_line_edit = TRUE;
      restore_rl_state();
      received_WINCH = FALSE;
      continue;
    }	
    
    if (nfds < 0) {		/* exception  */	
      if (errno == EINTR || errno == 0) {	/* interrupted by signal, or by a cygwin bug (errno == 0) :-( */
	continue;
      }	else
	myerror(FATAL|USE_ERRNO, "select received exception");
    } else if (nfds == 0) {
      
      /* timeout, which can only happen when .. */
      if (ignore_queued_input) {       /* ... we have read all the input keystrokes that should
					  be ignored (i.e. those that accumulated on stdin while we
				          were calling an external editor) */
	ignore_queued_input = FALSE;
	continue;
      } else if (command_is_dead) {                         /* ... or else, if child is dead, ... */
	DPRINTF2(DEBUG_SIGNALS,
		 "select returned 0, command_is_dead=%d, commands_exit_status=%d",
		 command_is_dead, commands_exit_status);
	cleanup_rlwrap_and_exit(EXIT_SUCCESS);
      }	else if (prompt_is_still_uncooked) { /* cooking time? */
	if (we_just_got_a_signal_or_EOF) {
	  we_just_got_a_signal_or_EOF = FALSE;              /* 1. If we got a signal/EOF before cooking time, we don't need special action
                                                                  to preserve the cooked prompt.
							       2. Reset we_just_got_a_signal_or_EOF  after a signal or EOF that didn't kill command */
          continue;
	}	
	if (!skip_rlwrap()) {                        /* ... or else, it is time to cook the prompt */
	  if (pre_given && accepted_lines == 0) {
            /* input_buffer and point have already been set in init_readline() */
	    DPRINTF0(DEBUG_READLINE, "Starting line edit (because of -P option)");
	    within_line_edit = TRUE;
	    restore_rl_state();
	    continue;
	  }
	  
	  if (accepted_lines == 1 && one_shot_rlwrap) 
	    cleanup_rlwrap_and_exit(EXIT_SUCCESS);

			  
	  move_cursor_to_start_of_prompt(ERASE); /* cooked prompt may be shorter than raw prompt, hence the ERASE */
	  /* move and erase before cooking, as we need to move/erase according
	     to the raw prompt */
          cook_prompt_if_necessary();
	  DPRINTF2(DEBUG_READLINE,"After cooking, raw_prompt=%s, cooked=%s",
                   mangle_string_for_debug_log(saved_rl_state.raw_prompt, MANGLE_LENGTH),
                   mangle_string_for_debug_log(saved_rl_state.cooked_prompt, MANGLE_LENGTH));
	  my_putstr(saved_rl_state.cooked_prompt);
	  rlwrap_already_prompted = TRUE;
	}
	prompt_is_still_uncooked = FALSE;
      } else if (polling) {
        completely_mirror_slaves_special_characters();
        if (mirror_arguments)
          mirror_args(command_pid);
        continue;
      } else {
	myerror(FATAL|NOERRNO, "unexpected select() timeout");
      }
    } else if (nfds > 0) {	/* Hah! something to read or write */ 

      /* -------------------------- read pty --------------------------------- */
      /* Always first read and process the slave command's output, even if there is input waiting on stdin 
         (which may happen when pasting a lot of text). E.g. when pasting "a\nb\nc" into "rlwrap cat" we want
         a 
         a
         b
         b
         c
         c

         and not
  
         a
         b
         c
         a
         b
         c
      */ 
      if (FD_ISSET(master_pty_fd, &readfds)) { /* there is something (or nothing, if EOF) to read on master pty: */
        nread = read(master_pty_fd, buf, BUFFSIZE - 1); /* read it */
        DPRINTF1(DEBUG_AD_HOC, "nread: %d", nread);
	if (nread <= 0) { 
	  if (command_is_dead || nread == 0) { /*  we catched a SIGCHLD,  or slave command has closed its stdout */
	    if (promptlen > 0)	/* commands dying words were not terminated by \n ... */
	      my_putchar('\n');	/* provide the missing \n */
	    cleanup_rlwrap_and_exit(EXIT_SUCCESS);
	  } else  if (errno == EINTR) {	/* interrupted by signal ...*/	                     
	    continue;                   /* ... don't worry */
	  } else  if (! seen_EOF) {     /* maybe command has just died (and SIGCHLD, whose handler sets command_is_dead is not  */     
            mymicrosleep(50);           /* yet caught) Therefore we wait a bit,                                                 */
            seen_EOF = TRUE;            /* set a flag                                                                           */   
            continue;                   /* and try one more time (hopefully catching the signal this time round                 */
          } else {
            myerror(FATAL|USE_ERRNO, "read error on master pty"); 
          }
	}
	  
	completely_mirror_slaves_output_settings(); /* some programs (e.g. joe) need this. Gasp!! */	
        mirror_args(command_pid);        
	
        if (skip_rlwrap()) { /* Race condition here! The client may just have finished an emacs session and
			        returned to cooked mode, while its ncurses-riddled output is stil waiting for us to be processed. */
	  write_patiently(STDOUT_FILENO, buf, nread, "to stdout");

	  DPRINTF2(DEBUG_TERMIO, "read from pty and wrote to stdout  %d  bytes in direct mode  <%s>",
                   nread, mangle_string_for_debug_log((buf[nread]='\0', buf), MANGLE_LENGTH));
	  yield();
	  continue;
	}

	DPRINTF2(DEBUG_TERMIO, "read %d bytes from pty into buffer: %s", nread,  mangle_string_for_debug_log((buf[nread]='\0', buf), MANGLE_LENGTH));
        
        remove_padding_and_terminate(buf, nread);
        
	write_logfile(buf);
	if (within_line_edit)	/* client output arrives while we're editing keyboard input:  */
	  save_rl_state();      /* temporarily disable readline and restore the screen state before readline was called */
  

	assert(saved_rl_state.raw_prompt != NULL);


        /* We *always* compute the printable part and the new raw prompt, and *always* print the printable part
           There are four possibilities:
           1. impatient before cooking.         The raw prompt has been printed,  write the new output after it
           2. patient before cooking            No raw prompt has been printed yet, don't print anything
           3. impatient after cooking
             3a  no current prompt              print the new output
             3b  some current prompt            erase it, replace by current raw prompt and print new output
           4. patient after cooking             don't print anything
        */
        
        /* sometimes we want to leave the prompt standing, e.g. after accepting a line, or when a signal arrived */
	leave_prompt_alone =
	     *saved_rl_state.raw_prompt == '\0' /* saved_rl_state.raw_prompt = "" in two distinct cases: when there is actually no prompt,
						   or just after accepting a line, when the cursor is at the end of the prompt. In both
						   cases, we dont't want to move the cursor */
          || prompt_is_still_uncooked /* in this case no prompt has been displayed yet */
          || command_is_dead                    
          || (we_just_got_a_signal_or_EOF && strrchr(buf, '\n')); /* a signal followed by output with a newline in it: treat it as
                                                                     response to user input, so leave the prompt alone */

        DPRINTF3(DEBUG_READLINE, "leave_prompt_alone: %s (raw prompt: %s, prompt_is_still_uncooked: %d)",
                 (leave_prompt_alone? "yes" : "no"), mangle_string_for_debug_log(saved_rl_state.raw_prompt, MANGLE_LENGTH), prompt_is_still_uncooked);
	
        if (!leave_prompt_alone) /* && (!impatient_prompt || !saved_rl_state.cooked_prompt)) */
	  move_cursor_to_start_of_prompt(ERASE);  
	else if (we_just_got_a_signal_or_EOF) {
	  free (saved_rl_state.raw_prompt);
	  saved_rl_state.raw_prompt =  mysavestring(""); /* prevent reprinting the prompt */
	}	

        if (impatient_prompt && !leave_prompt_alone)
          old_raw_prompt =  mysavestring(saved_rl_state.raw_prompt);

        new_output_minus_prompt = process_new_output(buf, &saved_rl_state);	/* chop off the part after the last newline and put this in
										   saved_rl_state.raw_prompt (or append buf if  no newline found)*/

	if (impatient_prompt) {   /* in impatient mode, ALL command output is passed through the OUTPUT filter, including the prompt The
				     prompt, however, is filtered separately at cooking time and then displayed */
	  char *filtered = pass_through_filter(TAG_OUTPUT, buf);
          if(!leave_prompt_alone) {
            my_putstr(old_raw_prompt);
            free(old_raw_prompt);
          }
	  my_putstr(filtered);
	  free (filtered);
	  rlwrap_already_prompted = TRUE;
	} else {
	  my_putstr(new_output_minus_prompt);
	  rlwrap_already_prompted = FALSE;
	}	
	   
	free(new_output_minus_prompt);	

		    
	prompt_is_still_uncooked = TRUE; 
       

	if (within_line_edit)
	  restore_rl_state();

	yield();  /* wait for what client has to say .... */ 
	continue; /* ... and don't attempt to process keyboard input as long as it is talking ,
		     in order to avoid re-printing the current prompt (i.e. unfinished output line) */
      }

      
      /* ----------------------------- key pressed: read stdin -------------------------*/
      if (FD_ISSET(STDIN_FILENO, &readfds)) {	/* key pressed */
	unsigned char byte_read;                /* the readline function names and documentation talk about "characters" and "keys",
						   but we're reading bytes (i.e. unsigned chars) here, and those may very well be
						   part of a multi-byte character. Example: hebrew "aleph" in utf-8 is 0xd790; pressing this key
						   will make us read 2 bytes 0x90 and then 0xd7, (or maybe the other way round depending on endianness??)
						   The readline library hides all this complexity and allows one to just "pass the bytes around" */
	nread = read(STDIN_FILENO, &byte_read, 1);  /* read next byte of input   */
	assert(sizeof(unsigned char) == 1);         /* gets optimised away       */

	if (nread <= 0) 
	  DPRINTF1(DEBUG_TERMIO, "read from stdin returned %d", nread); 
	if (nread < 0)
	  if (errno == EINTR)
	    continue;
	  else
	    myerror(FATAL|USE_ERRNO, "Unexpected error");
	else if (nread == 0)	/* EOF on stdin */
	  cleanup_rlwrap_and_exit(EXIT_SUCCESS);
        else if (ignore_queued_input)
	  continue;             /* do nothing with it*/
	assert(nread == 1);
	DPRINTF2(DEBUG_TERMIO, "read from stdin: byte 0x%02x (%s)", byte_read, mangle_char_for_debug_log(byte_read, TRUE)); 
	if (skip_rlwrap()) {	/* direct mode, just pass it on */
	                        /* remote possibility of a race condition here: when the first half of a multi-byte char is read in
				   direct mode and the second half in readline mode. Oh well... */
	  DPRINTF0(DEBUG_TERMIO, "passing it on (in transparent mode)");	
	  completely_mirror_slaves_terminal_settings(); /* this is of course 1 keypress too late: we should
							   mirror the terminal settings *before* the user presses a key.
							   (maybe using rl_event_hook??)   @@@FIXME  @@@ HOW?*/
          write_patiently(master_pty_fd, &byte_read, 1, "to master pty");
	} else {		/* hand it over to readline */
	  if (!within_line_edit) {	/* start a new line edit    */
	    DPRINTF0(DEBUG_READLINE, "Starting line edit");
	    within_line_edit = TRUE;
	    restore_rl_state();
	  } 
	                                        
	  
	  

	  if (term_eof && byte_read == term_eof && strlen(rl_line_buffer) == 0) {	/* hand a term_eof (usually CTRL-D) directly to command */ 
	    char *sent_EOF = mysavestring("?");
	    *sent_EOF = term_eof;
	    put_in_output_queue(sent_EOF);
	    we_just_got_a_signal_or_EOF = TRUE;
	    free(sent_EOF);
	  }	
	  else {
	    rl_stuff_char(byte_read);  /* stuff it back in readline's input queue */
	    DPRINTF0(DEBUG_TERMIO, "passing it to readline");	
	    DPRINTF2(DEBUG_READLINE, "rl_callback_read_char() (_rl_eof_char=%d, term_eof=%d)", _rl_eof_char, term_eof);
	    rl_callback_read_char();
	  }
	}
      }
    
      /* -------------------------- write pty --------------------------------- */
      if (FD_ISSET(master_pty_fd, &writefds)) {
	flush_output_queue();
	yield(); /*  give  slave command time to respond. If we don't do this,
		     nothing bad will happen, but the "dialogue" on screen will be
		     out of order   */
      }
    }				/* if (ndfs > 0)         */
  }				/* while (1)             */
}				/* void main_loop()      */
Exemplo n.º 12
0
main(int argc,char *argv[])
{
	CoolImage *image;
	int x,y;
	int i,j;
	PtWidget_t *win;
	PtArg_t args[3];
	PhDim_t dim={m_W,m_H};
	PhPoint_t pos={50,250};
	int fd; //Bt878 driver file descriptor
	int fd_temp;
	int size_read;
	struct timeval tv;
    fd_set rfd;
    int n;
	int error;
	int counter = 0;
	int counter_mean = 0;
	int file = 0;


	//Timing calculation
    uint64_t cps, cycle1, cycle2, ncycles;
    float sec;
    float msec;

	// if a paramater was passed, grab it as the blit type 
	if (argc>1) blittype=atoi(argv[1]);

	// initialize our connection to Photon, and create/realize a window 
	//PtInit("/net/irene2/dev/photon");
	PtInit("/dev/photon");
	PtSetArg(&args[0],Pt_ARG_POS,&pos,0);
	PtSetArg(&args[1],Pt_ARG_DIM,&dim,0);
	win=PtCreateWidget(PtWindow,Pt_NO_PARENT,2,args);
	PtRealizeWidget(win);

	// Allocate and fill a series of NUMIMAGES images with a little 
	// fading type animation.  Put your own animation in here if you like.


	/*
     *    Set a 5 second timeout.
     */
    tv.tv_sec = 5;
    tv.tv_usec = 0;

	image = AllocBuffer(m_W,m_H,fd);	
	assert(image!=0);
	
	if (file != 2)
	{
	init_bttvx(2,0, m_W,m_H,0,0);
	open_bttvx();
	
	BttvxSetImageBuffer(0, image->buffer);
	}
	fd_temp = fd;
	FD_ZERO( &rfd );
	FD_SET( fd, &rfd );
	
	
	while(1)
	{
		//fd = open("/net/europa/dev/bttvx0",O_RDWR);
		//if ( fd > 0 )
		//{
			
			///switch ( n = select( 1 + max( fd,0 ),
			///   &rfd, 0, 0, &tv ) ) 
			///{
			///  case -1:
			///	perror( "select" );
			///	return EXIT_FAILURE;
			///  case  0:
			///	puts( "select timed out" );
			///	break;
			///  default:
				//printf( "descriptor ready ...\n");
				//if( FD_ISSET( console, &rfd ) )
				//  puts( " -- console descriptor has data pending" );
				//if( FD_ISSET( serial, &rfd ) )
				//  puts( " -- serial descriptor has data pending" );
				/* Read the text */

				cycle1=ClockCycles( );

				//lseek(fd,0L,SEEK_SET);
			///	size_read = read( fd, image->buffer, W*H*deep );
		   if (file != 2)
		   {
		   BttvxWaitEvent();
		   BttvxAcquireBuffer(image->buffer);	
		    }
		   
		   switch(file)
		   {
		   	case 0:
		   		BlitBuffer(win,image);
		   		break;
		   	case 1:
		   		SaveImage(counter,image);
		   		break;
		   	case 2:
		   		
		   		LoadImage(counter,image);
		   		BlitBuffer(win,image);
		   		getchar();
		   		break;
		   };
		   
		   if (file!=2)
		   	BttvxReleaseBuffer();
		   cycle2=ClockCycles( );
		   counter++;
		   counter_mean++;

		   
		   ncycles=cycle2-cycle1;
		   //printf("%lld cycles elapsed \n", ncycles);

		   /* find out how many cycles per second */
		
		   cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
		   //printf( "This system has %lld cycles/sec.\n",cps );
		   sec=(float)ncycles/cps;
		   msec +=sec;
		   if (counter_mean == 250 )
		   {
		   	msec = msec/counter_mean;
		   	printf("The cycles in seconds is %f \n",msec);
		   	counter_mean = 0;
		   	msec = 0;
		   }
		//}else
			//sleep(2);
		}

	//printf("Blitted %d frames using method %d\n",REPS*NUMIMAGES,blittype);

	// now free the images
	FreeBuffer(image);
	close( fd );
	/// hide the window and destroy it.
	PtUnrealizeWidget(win);
	PtDestroyWidget(win);
}
/*
 * Simply download a HTTP file.
 */
int main(int argc, char **argv)
{
  CURL *http_handle;
  CURLM *multi_handle;

  int still_running; /* keep number of running handles */

  http_handle = curl_easy_init();

  /* set the options (I left out a few, you'll get the point anyway) */
  curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.haxx.se/");

  curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, my_trace);
  curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1L);

  /* init a multi stack */
  multi_handle = curl_multi_init();

  /* add the individual transfers */
  curl_multi_add_handle(multi_handle, http_handle);

  /* we start some action by calling perform right away */
  while(CURLM_CALL_MULTI_PERFORM ==
        curl_multi_perform(multi_handle, &still_running));

  while(still_running) {
    struct timeval timeout;
    int rc; /* select() return code */

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd = -1;

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* set a suitable timeout to play around with */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    /* get file descriptors from the transfers */
    curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
       case of (maxfd == -1), we call select(0, ...), which is basically equal
       to sleep. */

    rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

    switch(rc) {
    case -1:
      /* select error */
      still_running = 0;
      printf("select() returns error, this is badness\n");
      break;
    case 0:
    default:
      /* timeout or readable/writable sockets */
      while(CURLM_CALL_MULTI_PERFORM ==
            curl_multi_perform(multi_handle, &still_running));
      break;
    }
  }

  curl_multi_cleanup(multi_handle);

  curl_easy_cleanup(http_handle);

  return 0;
}
Exemplo n.º 14
0
/*
 * Source code in here hugely as reported in bug report 651464 by
 * Christopher R. Palmer.
 *
 * Use multi interface to get document over proxy with bad port number.
 * This caused the interface to "hang" in libcurl 7.10.2.
 */
int test(char *URL)
{
  CURL *c;
  int ret=0;
  CURLM *m;
  fd_set rd, wr, exc;
  CURLMcode res;
  char done = FALSE;
  int running;
  int max_fd;
  int rc;
  struct timeval ml_start;
  struct timeval mp_start;
  char ml_timedout = FALSE;
  char mp_timedout = FALSE;

  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  if ((c = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  /* the point here being that there must not run anything on the given
     proxy port */
  curl_easy_setopt(c, CURLOPT_PROXY, arg2);
  curl_easy_setopt(c, CURLOPT_URL, URL);
  curl_easy_setopt(c, CURLOPT_VERBOSE, 1);

  if ((m = curl_multi_init()) == NULL) {
    fprintf(stderr, "curl_multi_init() failed\n");
    curl_easy_cleanup(c);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  if ((res = curl_multi_add_handle(m, c)) != CURLM_OK) {
    fprintf(stderr, "curl_multi_add_handle() failed, "
            "with code %d\n", res);
    curl_multi_cleanup(m);
    curl_easy_cleanup(c);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  ml_timedout = FALSE;
  ml_start = tutil_tvnow();

  while (!done) {
    struct timeval interval;

    interval.tv_sec = 1;
    interval.tv_usec = 0;

    if (tutil_tvdiff(tutil_tvnow(), ml_start) >
        MAIN_LOOP_HANG_TIMEOUT) {
      ml_timedout = TRUE;
      break;
    }
    mp_timedout = FALSE;
    mp_start = tutil_tvnow();

    fprintf(stderr, "curl_multi_perform()\n");

    res = CURLM_CALL_MULTI_PERFORM;

    while (res == CURLM_CALL_MULTI_PERFORM) {
      res = curl_multi_perform(m, &running);
      if (tutil_tvdiff(tutil_tvnow(), mp_start) >
          MULTI_PERFORM_HANG_TIMEOUT) {
        mp_timedout = TRUE;
        break;
      }
    }
    if (mp_timedout)
      break;

    if(!running) {
      /* This is where this code is expected to reach */
      int numleft;
      CURLMsg *msg = curl_multi_info_read(m, &numleft);
      fprintf(stderr, "Expected: not running\n");
      if(msg && !numleft)
        ret = 100; /* this is where we should be */
      else
        ret = 99; /* not correct */
      break;
    }
    fprintf(stderr, "running == %d, res == %d\n", running, res);

    if (res != CURLM_OK) {
      ret = 2;
      break;
    }

    FD_ZERO(&rd);
    FD_ZERO(&wr);
    FD_ZERO(&exc);
    max_fd = 0;

    fprintf(stderr, "curl_multi_fdset()\n");
    if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
      fprintf(stderr, "unexpected failured of fdset.\n");
      ret = 3;
      break;
    }
    rc = select_test(max_fd+1, &rd, &wr, &exc, &interval);
    fprintf(stderr, "select returned %d\n", rc);
  }

  if (ml_timedout || mp_timedout) {
    if (ml_timedout) fprintf(stderr, "ml_timedout\n");
    if (mp_timedout) fprintf(stderr, "mp_timedout\n");
    fprintf(stderr, "ABORTING TEST, since it seems "
            "that it would have run forever.\n");
    ret = TEST_ERR_RUNS_FOREVER;
  }

  curl_multi_remove_handle(m, c);
  curl_easy_cleanup(c);
  curl_multi_cleanup(m);
  curl_global_cleanup();

  return ret;
}
Exemplo n.º 15
0
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {
#ifdef FASTO
    #ifdef OS_WIN
        fd_set master_set;
        FD_ZERO(&master_set);
        int max_sd = c->fd;
        FD_SET(c->fd, &master_set);

        struct timeval tm;
        tm.tv_sec  = 60;
        tm.tv_usec = 0;

        /* Only use timeout when not NULL. */
        if (timeout != NULL) {
            if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
                redisContextCloseFd(c);
                return REDIS_ERR;
            }
            tm = *timeout;
        }

        if (errno == EINPROGRESS) {
            int res;

            if ((res = select(max_sd + 1, &master_set, NULL, NULL, &tm)) == -1) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, "select(2)");
                redisContextCloseFd(c);
                return REDIS_ERR;
            } else if (res == 0) {
                errno = ETIMEDOUT;
                __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            if (redisCheckSocketError(c) != REDIS_OK)
                return REDIS_ERR;

            return REDIS_OK;
        }

        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        redisContextCloseFd(c);
        return REDIS_ERR;
    #else
        struct pollfd   wfd[1];
        long msec;

        msec          = -1;
        wfd[0].fd     = c->fd;
        wfd[0].events = POLLOUT;

        /* Only use timeout when not NULL. */
        if (timeout != NULL) {
            if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

            if (msec < 0 || msec > INT_MAX) {
                msec = INT_MAX;
            }
        }

        if (errno == EINPROGRESS) {
            int res;

            if ((res = poll(wfd, 1, msec)) == -1) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
                redisContextCloseFd(c);
                return REDIS_ERR;
            } else if (res == 0) {
                errno = ETIMEDOUT;
                __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            if (redisCheckSocketError(c) != REDIS_OK)
                return REDIS_ERR;

            return REDIS_OK;
        }

        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        redisContextCloseFd(c);
        return REDIS_ERR;
    #endif
#else
    struct pollfd   wfd[1];
    long msec;

    msec          = -1;
    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

        if (msec < 0 || msec > INT_MAX) {
            msec = INT_MAX;
        }
    }

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
#endif
}
Exemplo n.º 16
0
void BaseSocketManager::DoSelect(int pauseMicroSecs, int handleInput) {
    timeval tv;
    tv.tv_sec = 0;

    tv.tv_usec = pauseMicroSecs;

    fd_set inp_set, out_set, exc_set;
    int maxDesc;

    FD_ZERO(&inp_set);
    FD_ZERO(&out_set);
    FD_ZERO(&exc_set);

    maxDesc = 0;

    for (SocketList::iterator i = m_SockList.begin(); i != m_SockList.end(); ++i) {
        NetSocket* pSock = *i;
        if ((pSock->m_deleteFlag & 1) || pSock->m_sock == INVALID_SOCKET)
            continue;

        if (handleInput)
            FD_SET(pSock->m_sock, &inp_set);

        FD_SET(pSock->m_sock, &exc_set);

        if (pSock->VHasOutput())
            FD_SET(pSock->m_sock, &out_set);

        if ((int)pSock->m_sock > maxDesc)
            maxDesc = (int)pSock->m_sock;
    }

    int selRet = 0;

    selRet = select(maxDesc + 1, &inp_set, &out_set, &exc_set, &tv);
    if (selRet == SOCKET_ERROR) {
        GCC_ERROR("Error in DoSelect!");
        return;
    }

    if (selRet) {
        for (SocketList::iterator i = m_SockList.begin(); i != m_SockList.end(); ++i) {
            NetSocket* pSock = *i;

            if ((pSock->m_deleteFlag & 1) || pSock->m_sock == INVALID_SOCKET)
                continue;

            if (FD_ISSET(pSock->m_sock, &exc_set))
                pSock->HandleException();

            if (!(pSock->m_deleteFlag & 1) && FD_ISSET(pSock->m_sock, &out_set))
                pSock->VHandleOutput();

            if (handleInput && !(pSock->m_deleteFlag & 1) && FD_ISSET(pSock->m_sock, &inp_set)) {
                pSock->VHandleInput();
            }
        }
    }

    unsigned int timeNow = timeGetTime();

    SocketList::iterator i = m_SockList.begin();
    while (i != m_SockList.end()) {
        NetSocket* pSock = *i;
        if (pSock->m_timeOut && pSock->m_timeOut < timeNow) 
            pSock->VTimeOut();

        if (pSock->m_deleteFlag & 1) {
            switch (pSock->m_deleteFlag) {
                case 1:
                    g_pSocketManager->RemoveSocket(pSock);
                    i = m_SockList.begin();
                    break;

                case 3:
                    pSock->m_deleteFlag = 2;
                    if (pSock->m_sock != INVALID_SOCKET) {
                        closesocket(pSock->m_sock);
                        pSock->m_sock = INVALID_SOCKET;
                    }
                    break;
            }
        }
        i++;
    }
}
Exemplo n.º 17
0
/* ====================================================== */
CURLcode
Curl_SSLConnect(struct connectdata *conn)
{
  CURLcode retcode = CURLE_OK;

#ifdef USE_SSLEAY
  struct SessionHandle *data = conn->data;
  int err;
  char * str;
  SSL_METHOD *req_method;
  SSL_SESSION *ssl_sessionid=NULL;
  ASN1_TIME *certdate;

  /* mark this is being ssl enabled from here on out. */
  conn->ssl.use = TRUE;

  if(!ssl_seeded || data->set.ssl.random_file || data->set.ssl.egdsocket) {
    /* Make funny stuff to get random input */
    random_the_seed(data);

    ssl_seeded = TRUE;
  }

  /* check to see if we've been told to use an explicit SSL/TLS version */
  switch(data->set.ssl.version) {
  default:
  case CURL_SSLVERSION_DEFAULT:
    /* we try to figure out version */
    req_method = SSLv23_client_method();
    break;
  case CURL_SSLVERSION_TLSv1:
    req_method = TLSv1_client_method();
    break;
  case CURL_SSLVERSION_SSLv2:
    req_method = SSLv2_client_method();
    break;
  case CURL_SSLVERSION_SSLv3:
    req_method = SSLv3_client_method();
    break;
  }
    
  conn->ssl.ctx = SSL_CTX_new(req_method);

  if(!conn->ssl.ctx) {
    failf(data, "SSL: couldn't create a context!");
    return CURLE_OUT_OF_MEMORY;
  }
    
  if(data->set.cert) {
    if (!cert_stuff(conn,
                    data->set.cert,
                    data->set.cert_type,
                    data->set.key,
                    data->set.key_type)) {
      /* failf() is already done in cert_stuff() */
      return CURLE_SSL_CONNECT_ERROR;
    }
  }

  if(data->set.ssl.cipher_list) {
    if (!SSL_CTX_set_cipher_list(conn->ssl.ctx,
                                 data->set.ssl.cipher_list)) {
      failf(data, "failed setting cipher list");
      return CURLE_SSL_CONNECT_ERROR;
    }
  }

  if(data->set.ssl.verifypeer){
    SSL_CTX_set_verify(conn->ssl.ctx,
                       SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
                       SSL_VERIFY_CLIENT_ONCE,
                       cert_verify_callback);
    if (!SSL_CTX_load_verify_locations(conn->ssl.ctx,
                                       data->set.ssl.CAfile,
                                       data->set.ssl.CApath)) {
      failf(data,"error setting cerficate verify locations");
      return CURLE_SSL_CONNECT_ERROR;
    }
  }
  else
    SSL_CTX_set_verify(conn->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback);


  /* Lets make an SSL structure */
  conn->ssl.handle = SSL_new (conn->ssl.ctx);
  SSL_set_connect_state (conn->ssl.handle);

  conn->ssl.server_cert = 0x0;

  if(!conn->bits.reuse) {
    /* We're not re-using a connection, check if there's a cached ID we
       can/should use here! */
    if(!Get_SSL_Session(conn, &ssl_sessionid)) {
      /* we got a session id, use it! */
      SSL_set_session(conn->ssl.handle, ssl_sessionid);
      /* Informational message */
      infof (data, "SSL re-using session ID\n");
    }
  }

  /* pass the raw socket into the SSL layers */
  SSL_set_fd(conn->ssl.handle, conn->firstsocket);

  do {
    int what;
    fd_set writefd;
    fd_set readfd;
    struct timeval interval;
    long timeout_ms;

    err = SSL_connect(conn->ssl.handle);

    what = SSL_get_error(conn->ssl.handle, err);

    FD_ZERO(&writefd);
    FD_ZERO(&readfd);

    if(SSL_ERROR_WANT_READ == what)
      FD_SET(conn->firstsocket, &readfd);
    else if(SSL_ERROR_WANT_WRITE == what)
      FD_SET(conn->firstsocket, &writefd);
    else
      break; /* untreated error */

    /* Find out if any timeout is set. If not, use 300 seconds.
       Otherwise, figure out the most strict timeout of the two possible one
       and then how much time that has elapsed to know how much time we
       allow for the connect call */
    if(data->set.timeout || data->set.connecttimeout) {
      double has_passed;

      /* Evaluate in milliseconds how much time that has passed */
      has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);

#ifndef min
#define min(a, b)   ((a) < (b) ? (a) : (b))
#endif

      /* get the most strict timeout of the ones converted to milliseconds */
      if(data->set.timeout &&
         (data->set.timeout>data->set.connecttimeout))
        timeout_ms = data->set.timeout*1000;
      else
        timeout_ms = data->set.connecttimeout*1000;
      
      /* subtract the passed time */
      timeout_ms -= (long)has_passed;
      
      if(timeout_ms < 0) {
        /* a precaution, no need to continue if time already is up */
        failf(data, "SSL connection timeout");
        return CURLE_OPERATION_TIMEOUTED;
      }
    }
    else
      /* no particular time-out has been set */
      timeout_ms=300000; /* milliseconds, default to five minutes */

    interval.tv_sec = timeout_ms/1000;
    timeout_ms -= interval.tv_sec*1000;

    interval.tv_usec = timeout_ms*1000;

    what = select(conn->firstsocket+1, &readfd, &writefd, NULL, &interval);
    if(what > 0)
      /* reabable or writable, go loop yourself */
      continue;
    else if(0 == what) {
      /* timeout */
      failf(data, "SSL connection timeout");
      return CURLE_OPERATION_TIMEOUTED;
    }
    else
      break; /* get out of loop */
  } while(1);

  /* 1  is fine
     0  is "not successful but was shut down controlled"
     <0 is "handshake was not successful, because a fatal error occurred" */
  if (err <= 0) {
    err = ERR_get_error(); 
    failf(data, "SSL: %s", ERR_error_string(err, NULL));
    return CURLE_SSL_CONNECT_ERROR;
  }

  /* Informational message */
  infof (data, "SSL connection using %s\n",
         SSL_get_cipher(conn->ssl.handle));

  if(!ssl_sessionid) {
    /* Since this is not a cached session ID, then we want to stach this one
       in the cache! */
    Store_SSL_Session(conn);
  }

  
  /* Get server's certificate (note: beware of dynamic allocation) - opt */
  /* major serious hack alert -- we should check certificates
   * to authenticate the server; otherwise we risk man-in-the-middle
   * attack
   */

  conn->ssl.server_cert = SSL_get_peer_certificate (conn->ssl.handle);
  if(!conn->ssl.server_cert) {
    failf(data, "SSL: couldn't get peer certificate!");
    return CURLE_SSL_PEER_CERTIFICATE;
  }
  infof (data, "Server certificate:\n");
  
  str = X509_NAME_oneline (X509_get_subject_name (conn->ssl.server_cert),
                           NULL, 0);
  if(!str) {
    failf(data, "SSL: couldn't get X509-subject!");
    X509_free(conn->ssl.server_cert);
    return CURLE_SSL_CONNECT_ERROR;
  }
  infof(data, "\t subject: %s\n", str);
  CRYPTO_free(str);

  certdate = X509_get_notBefore(conn->ssl.server_cert);
  Curl_ASN1_UTCTIME_output(conn, "\t start date: ", certdate);

  certdate = X509_get_notAfter(conn->ssl.server_cert);
  Curl_ASN1_UTCTIME_output(conn, "\t expire date: ", certdate);

  if (data->set.ssl.verifyhost) {
    char peer_CN[257];
    if (X509_NAME_get_text_by_NID(X509_get_subject_name(conn->ssl.server_cert),
                                  NID_commonName,
                                  peer_CN,
                                  sizeof(peer_CN)) < 0) {
      failf(data, "SSL: unable to obtain common name from peer certificate");
      X509_free(conn->ssl.server_cert);
      return CURLE_SSL_PEER_CERTIFICATE;
    }

    if (!strequal(peer_CN, conn->hostname)) {
      if (data->set.ssl.verifyhost > 1) {
        failf(data, "SSL: certificate subject name '%s' does not match "
              "target host name '%s'",
              peer_CN, conn->hostname);
        X509_free(conn->ssl.server_cert);
        return CURLE_SSL_PEER_CERTIFICATE;
      }
      else
        infof(data,
              "\t common name: %s (does not match '%s')\n",
              peer_CN, conn->hostname);
    }
    else
      infof(data, "\t common name: %s (matched)\n", peer_CN);
  }

  str = X509_NAME_oneline (X509_get_issuer_name  (conn->ssl.server_cert),
                           NULL, 0);
  if(!str) {
    failf(data, "SSL: couldn't get X509-issuer name!");
    X509_free(conn->ssl.server_cert);
    return CURLE_SSL_CONNECT_ERROR;
  }
  infof(data, "\t issuer: %s\n", str);
  CRYPTO_free(str);

  /* We could do all sorts of certificate verification stuff here before
     deallocating the certificate. */

  if(data->set.ssl.verifypeer) {
    data->set.ssl.certverifyresult=SSL_get_verify_result(conn->ssl.handle);
    if (data->set.ssl.certverifyresult != X509_V_OK) {
      failf(data, "SSL certificate verify result: %d",
            data->set.ssl.certverifyresult);
      retcode = CURLE_SSL_PEER_CERTIFICATE;
    }
  }
  else
    data->set.ssl.certverifyresult=0;

  X509_free(conn->ssl.server_cert);
#else /* USE_SSLEAY */
  /* this is for "-ansi -Wall -pedantic" to stop complaining!   (rabe) */
  (void) conn;
#endif
  return retcode;
}
Exemplo n.º 18
0
int revname(int *lookup, struct in_addr *saddr, struct in6_addr *s6addr,
	    char *target, int rvnfd)
{
	struct hostent *he;
	struct rvn rpkt;
	int br;
	struct sockaddr_un su;
	socklen_t fl;
	fd_set sockset;
	struct timeval tv;
	int sstat = 0;

	memset(target, 0, 45);
	if (*lookup) {
		if (rvnfd > 0) {
			su.sun_family = AF_UNIX;
			strcpy(su.sun_path, IPTSOCKNAME);

			rpkt.type = RVN_REQUEST;
			rpkt.saddr.s_addr = saddr->s_addr;

			if (s6addr != NULL)
				memcpy(rpkt.s6addr.s6_addr, s6addr->s6_addr,
				       16);
			else
				memset(rpkt.s6addr.s6_addr, 0, 4);

			sendto(rvnfd, &rpkt, sizeof(struct rvn), 0,
			       (struct sockaddr *) &su,
			       sizeof(su.sun_family) + strlen(su.sun_path));

			fl = sizeof(su.sun_family) + strlen(su.sun_path);
			do {
				tv.tv_sec = 10;
				tv.tv_usec = 0;

				FD_ZERO(&sockset);
				FD_SET(rvnfd, &sockset);

				do {
					sstat =
					    select(rvnfd + 1, &sockset, NULL,
						   NULL, &tv);
				} while ((sstat < 0) && (errno == EINTR));

				if (FD_ISSET(rvnfd, &sockset))
					br = recvfrom(rvnfd, &rpkt,
						      sizeof(struct rvn), 0,
						      (struct sockaddr *) &su,
						      &fl);
				else
					br = -1;
			} while ((br < 0) && (errno == EINTR));

			if (br < 0) {
				if (saddr->s_addr != 0)
					strcpy(target, inet_ntoa(*saddr));
				else
					inet_ntop(AF_INET6, s6addr, target, 44);
				printipcerr();
				*lookup = 0;
				return RESOLVED;
			}
			strncpy(target, rpkt.fqdn, 44);
			return (rpkt.ready);
		} else {
			if (saddr->s_addr != 0)
				he = gethostbyaddr((char *) saddr,
						   sizeof(struct in_addr),
						   AF_INET);
			else
				he = gethostbyaddr((char *) s6addr,
						   sizeof(struct in6_addr),
						   AF_INET6);

			if (he == NULL) {
				if (saddr->s_addr != 0)
					strcpy(target, inet_ntoa(*saddr));
				else
					inet_ntop(AF_INET6, s6addr, target, 44);
			} else {
				strncpy(target, he->h_name, 44);
			}

			return RESOLVED;
		}
	} else {
		if (saddr->s_addr != 0 || s6addr == NULL)
			strcpy(target, inet_ntoa(*saddr));
		else
			inet_ntop(AF_INET6, s6addr, target, 44);

		return RESOLVED;
	}
	return NOTRESOLVED;
}
Exemplo n.º 19
0
int main (int argc, char *argv[])
{
	int    i, len, rc, on = 1;
	int    listen_sd, max_sd, new_sd;
	int    desc_ready, end_server = FALSE;
	int    close_conn;
	char   buffer[8];
	struct sockaddr_in   addr;
	struct timeval       timeout;

#if _ORI
	struct fd_set        master_set, working_set;
#else
	fd_set        master_set, working_set;
#endif

	/*************************************************************/
	/* Create an AF_INET stream socket to receive incoming       */
	/* connections on                                            */
	/*************************************************************/
	listen_sd = socket(AF_INET, SOCK_STREAM, 0);
	if (listen_sd < 0)
	{
		perror("socket() failed");
		exit(-1);
	}

	/*************************************************************/
	/* Allow socket descriptor to be reuseable                   */
	/*************************************************************/
	rc = setsockopt(listen_sd, SOL_SOCKET,  SO_REUSEADDR,
			(char *)&on, sizeof(on));
	if (rc < 0)
	{
		perror("setsockopt() failed");
		close(listen_sd);
		exit(-1);
	}

	/*************************************************************/
	/* Set socket to be non-blocking.  All of the sockets for    */
	/* the incoming connections will also be non-blocking since  */
	/* they will inherit that state from the listening socket.   */
	/*************************************************************/
#ifdef _use_setnonblocking
	setnonblocking(listen_sd);
#else
	rc = ioctl(listen_sd, FIONBIO, (char *)&on);
	if (rc < 0)
	{
		perror("ioctl() failed");
		close(listen_sd);
		exit(-1);
	}
#endif

	/*************************************************************/
	/* Bind the socket                                           */
	/*************************************************************/
	memset(&addr, 0, sizeof(addr));
	addr.sin_family      = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port        = htons(SERVER_PORT);
	rc = bind(listen_sd,
			(struct sockaddr *)&addr, sizeof(addr));
	if (rc < 0)
	{
		perror("bind() failed");
		close(listen_sd);
		exit(-1);
	}

	/*************************************************************/
	/* Set the listen back log                                   */
	/*************************************************************/
	rc = listen(listen_sd, BACKLOG);
	if (rc < 0)
	{
		perror("listen() failed");
		close(listen_sd);
		exit(-1);
	}

	/*************************************************************/
	/* Initialize the master fd_set                              */
	/*************************************************************/
	FD_ZERO(&master_set);
	max_sd = listen_sd;
	FD_SET(listen_sd, &master_set);

	/*************************************************************/
	/* Initialize the timeval struct to 3 minutes.  If no        */
	/* activity after 3 minutes this program will end.           */
	/*************************************************************/
	timeout.tv_sec  = 3 * 60;
	timeout.tv_usec = 0;

	/*************************************************************/
	/* Loop waiting for incoming connects or for incoming data   */
	/* on any of the connected sockets.                          */
	/*************************************************************/
	do
	{
		/**********************************************************/
		/* Copy the master fd_set over to the working fd_set.     */
		/**********************************************************/
		memcpy(&working_set, &master_set, sizeof(master_set));

		/**********************************************************/
		/* Call select() and wait 5 minutes for it to complete.   */
		/**********************************************************/
		printf("Waiting on select()...\n");
		rc = select(max_sd + 1, &working_set, NULL, NULL, &timeout);

		/**********************************************************/
		/* Check to see if the select call failed.                */
		/**********************************************************/
		if (rc < 0)
		{
			perror("  select() failed");
			break;
		}

		/**********************************************************/
		/* Check to see if the 5 minute time out expired.         */
		/**********************************************************/
		if (rc == 0)
		{
			printf("  select() timed out.  End program.\n");
			break;
		}

		/**********************************************************/
		/* One or more descriptors are readable.  Need to         */
		/* determine which ones they are.                         */
		/**********************************************************/
		desc_ready = rc;
		for (i=0; i <= max_sd  &&  desc_ready > 0; ++i)
		{
			/*******************************************************/
			/* Check to see if this descriptor is ready            */
			/*******************************************************/
			if (FD_ISSET(i, &working_set))
			{
				/****************************************************/
				/* A descriptor was found that was readable - one   */
				/* less has to be looked for.  This is being done   */
				/* so that we can stop looking at the working set   */
				/* once we have found all of the descriptors that   */
				/* were ready.                                      */
				/****************************************************/
				desc_ready -= 1;

				/****************************************************/
				/* Check to see if this is the listening socket     */
				/****************************************************/
				if (i == listen_sd)
				{
					printf("  Listening socket is readable\n");
					/*************************************************/
					/* Accept all incoming connections that are      */
					/* queued up on the listening socket before we   */
					/* loop back and call select again.              */
					/*************************************************/
					do
					{
						/**********************************************/
						/* Accept each incoming connection.  If       */
						/* accept fails with EWOULDBLOCK, then we     */
						/* have accepted all of them.  Any other      */
						/* failure on accept will cause us to end the */
						/* server.                                    */
						/**********************************************/
						new_sd = accept(listen_sd, NULL, NULL);
						if (new_sd < 0)
						{
							if (errno != EWOULDBLOCK)
							{
								perror("  accept() failed");
								end_server = TRUE;
							}
							break;
						}

						/**********************************************/
						/* Add the new incoming connection to the     */
						/* master read set                            */
						/**********************************************/
						printf("  New incoming connection - %d\n", new_sd);
						FD_SET(new_sd, &master_set);
						if (new_sd > max_sd)
							max_sd = new_sd;

						//[Kent] setnonblocking mode
						setnonblocking(new_sd);

						/**********************************************/
						/* Loop back up and accept another incoming   */
						/* connection                                 */
						/**********************************************/
					} while (new_sd != -1);
				}

				/****************************************************/
				/* This is not the listening socket, therefore an   */
				/* existing connection must be readable             */
				/****************************************************/
				else
				{
					printf("  Descriptor %d is readable\n", i);
					close_conn = FALSE;
					/*************************************************/
					/* Receive all incoming data on this socket      */
					/* before we loop back and call select again.    */
					/*************************************************/
					do
					{
						/**********************************************/
						/* Receive data on this connection until the  */
						/* recv fails with EWOULDBLOCK.  If any other */
						/* failure occurs, we will close the          */
						/* connection.                                */
						/**********************************************/
						rc = recv(i, buffer, sizeof(buffer), 0);
						if (rc < 0)
						{
							if (errno != EWOULDBLOCK)
							{
								perror("  recv() failed");
								close_conn = TRUE;
							}
							else
							{
								/*
								 * [Kent] If we enable non-blocking mode on clientsocket
								 * it would receive a EWOULDBLOCK when recv done.
								 *
								 * Otherwise, it enter below (rc == 0) case
								 */
								perror("  recv() < 0 ");
							}
							break;
						}

						/**********************************************/
						/* Check to see if the connection has been    */
						/* closed by the client                       */
						/**********************************************/
						if (rc == 0)
						{
							printf("  Connection closed\n");
							close_conn = TRUE;
							break;
						}

						/**********************************************/
						/* Data was recevied                          */
						/**********************************************/
						len = rc;
						printf("  %d bytes received\n", len);

						/**********************************************/
						/* Echo the data back to the client           */
						/**********************************************/
						rc = send(i, buffer, len, 0);
						if (rc < 0)
						{
							perror("  send() failed");
							close_conn = TRUE;
							break;
						}

					} while (TRUE);

					/*************************************************/
					/* If the close_conn flag was turned on, we need */
					/* to clean up this active connection.  This     */
					/* clean up process includes removing the        */
					/* descriptor from the master set and            */
					/* determining the new maximum descriptor value  */
					/* based on the bits that are still turned on in */
					/* the master set.                               */
					/*************************************************/
					if (close_conn)
					{
						close(i);
						FD_CLR(i, &master_set);
						if (i == max_sd)
						{
							while (FD_ISSET(max_sd, &master_set) == FALSE)
								max_sd -= 1;
						}
					}
				} /* End of existing connection is readable */
			} /* End of if (FD_ISSET(i, &working_set)) */
		} /* End of loop through selectable descriptors */

	} while (end_server == FALSE);

	/*************************************************************/
	/* Cleanup all of the sockets that are open                  */
	/*************************************************************/
	for (i=0; i <= max_sd; ++i)
	{
		if (FD_ISSET(i, &master_set))
			close(i);
	}
}
Exemplo n.º 20
0
SelectServer *net_serverA(tagitem *tags)
{
	SelectServer	*server;
	int	true, rc;

/* Win32 wants to be weird */
#ifdef Win32_Winsock
	WORD version_wanted = MAKEWORD(1,1);
	WSADATA wsaData;

	if(WSAStartup(version_wanted, &wsaData)) {
		fprintf(stderr, "Couldn't initialize Winsock 1.1\n");
		return 0;
	}
#endif

	server = calloc(1, sizeof(SelectServer));
	if(!server) return NULL;

	server->queue = 5;

	/* Get descriptor for listening socket */
	server->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(server->sock < 0) {
		perror("socket");
		free(server);
		return NULL;
	}

	/* We want to bind without TIME_WAIT problems */
	true = 1;
	rc = setsockopt(server->sock, SOL_SOCKET, SO_REUSEADDR,
		(char *)&true, sizeof(true));
	if(rc < 0) {
		perror("setsockopt");
		free(server);
		return NULL;
	}
	net_setnonblock(server->sock);

	server->connectlist.destructor = (void *)&destroy_socket;
	server->available.destructor = (void *)&destroy_socket;
	server->address.sin_family = AF_INET;
	server->address.sin_addr.s_addr = _SwapBE32(INADDR_ANY);
	net_tag_serverA(server, tags);

	rc =bind(server->sock, (struct sockaddr *) &server->address,
		sizeof(server->address));
	if(rc < 0) {
		perror("bind");
		net_server_free(server);
		return NULL;
	}
	rc = listen(server->sock, server->queue);
	if(rc == -1) {
		perror("listen");
		net_server_free(server);
		return NULL;
	}
	FD_ZERO(&server->set);
	FD_SET(server->sock, &server->set);
	return server;
}
Exemplo n.º 21
0
static int
ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sa, int async)
{
	int rc;
	struct timeval	tv, *opt_tv = NULL;

	if ( ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
		tv = ld->ld_options.ldo_tm_net;
		opt_tv = &tv;
	}

	oslocal_debug(ld, "ldap_connect_timeout: fd: %d tm: %ld async: %d\n",
		s, opt_tv ? tv.tv_sec : -1L, async);

	if ( ldap_pvt_ndelay_on(ld, s) == -1 ) return -1;

	if ( connect(s, (struct sockaddr *) sa, sizeof(struct sockaddr_un))
		!= AC_SOCKET_ERROR )
	{
		if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;

#ifdef LDAP_PF_LOCAL_SENDMSG
	/* Send a dummy message with access rights. Remote side will
	 * obtain our uid/gid by fstat'ing this descriptor. The
	 * descriptor permissions must match exactly, and we also
	 * send the socket name, which must also match.
	 */
sendcred:
		{
			int fds[2];
			ber_socklen_t salen = sizeof(*sa);
			if (pipe(fds) == 0) {
				/* Abandon, noop, has no reply */
				struct iovec iov;
				struct msghdr msg = {0};
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
# ifndef CMSG_SPACE
# define CMSG_SPACE(len)	(_CMSG_ALIGN( sizeof(struct cmsghdr)) + _CMSG_ALIGN(len) )
# endif
# ifndef CMSG_LEN
# define CMSG_LEN(len)		(_CMSG_ALIGN( sizeof(struct cmsghdr)) + (len) )
# endif
				union {
					struct cmsghdr cm;
					unsigned char control[CMSG_SPACE(sizeof(int))];
				} control_un;
				struct cmsghdr *cmsg;
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
				msg.msg_name = NULL;
				msg.msg_namelen = 0;
				iov.iov_base = (char *) abandonPDU;
				iov.iov_len = sizeof abandonPDU;
				msg.msg_iov = &iov;
				msg.msg_iovlen = 1;
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
				msg.msg_control = control_un.control;
				msg.msg_controllen = sizeof( control_un.control );
				msg.msg_flags = 0;

				cmsg = CMSG_FIRSTHDR( &msg );
				cmsg->cmsg_len = CMSG_LEN( sizeof(int) );
				cmsg->cmsg_level = SOL_SOCKET;
				cmsg->cmsg_type = SCM_RIGHTS;

				*((int *)CMSG_DATA(cmsg)) = fds[0];
# else
				msg.msg_accrights = (char *)fds;
				msg.msg_accrightslen = sizeof(int);
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
				getpeername( s, sa, &salen );
				fchmod( fds[0], S_ISUID|S_IRWXU );
				write( fds[1], sa, salen );
				sendmsg( s, &msg, 0 );
				close(fds[0]);
				close(fds[1]);
			}
		}
#endif
		return 0;
	}

	if ( errno != EINPROGRESS && errno != EWOULDBLOCK ) return -1;
	
#ifdef notyet
	if ( async ) return -2;
#endif

#ifdef HAVE_POLL
	{
		struct pollfd fd;
		int timeout = INFTIM;

		if( opt_tv != NULL ) timeout = TV2MILLISEC( &tv );

		fd.fd = s;
		fd.events = POLL_WRITE;

		do {
			fd.revents = 0;
			rc = poll( &fd, 1, timeout );
		} while( rc == AC_SOCKET_ERROR && errno == EINTR &&
			LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART ));

		if( rc == AC_SOCKET_ERROR ) return rc;

		if( fd.revents & POLL_WRITE ) {
			if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1;
			if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;
#ifdef LDAP_PF_LOCAL_SENDMSG
			goto sendcred;
#else
			return ( 0 );
#endif
		}
	}
#else
	{
		fd_set wfds, *z=NULL;

#ifdef FD_SETSIZE
		if ( s >= FD_SETSIZE ) {
			rc = AC_SOCKET_ERROR;
			tcp_close( s );
			ldap_pvt_set_errno( EMFILE );
			return rc;
		}
#endif
		do { 
			FD_ZERO(&wfds);
			FD_SET(s, &wfds );
			rc = select( ldap_int_tblsize, z, &wfds, z, opt_tv ? &tv : NULL );
		} while( rc == AC_SOCKET_ERROR && errno == EINTR &&
			LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART ));

		if( rc == AC_SOCKET_ERROR ) return rc;

		if ( FD_ISSET(s, &wfds) ) {
			if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1;
			if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;
#ifdef LDAP_PF_LOCAL_SENDMSG
			goto sendcred;
#else
			return ( 0 );
#endif
		}
	}
#endif

	oslocal_debug(ld, "ldap_connect_timeout: timed out\n",0,0,0);
	ldap_pvt_set_errno( ETIMEDOUT );
	return ( -1 );
}
static int
testExternalGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket maxsock;
#ifdef MHD_WINSOCK_SOCKETS
  int maxposixs; /* Max socket number unused on W32 */
#else  /* MHD_POSIX_SOCKETS */
#define maxposixs maxsock
#endif /* MHD_POSIX_SOCKETS */
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_DEBUG,
                        21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  if (d == NULL)
    return 256;
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL,
                    "http://127.0.0.1:21080/hello+world?k=v+x&hash=%23foo&space=%A0bar");
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  if (oneone)
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  else
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  /* NOTE: use of CONNECTTIMEOUT without also
     setting NOSIGNAL results in really weird
     crashes on my system! */
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);


  multi = curl_multi_init ();
  if (multi == NULL)
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 512;
    }
  mret = curl_multi_add_handle (multi, c);
  if (mret != CURLM_OK)
    {
      curl_multi_cleanup (multi);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 1024;
    }
  start = time (NULL);
  while ((time (NULL) - start < 5) && (multi != NULL))
    {
      maxsock = MHD_INVALID_SOCKET;
      maxposixs = -1;
      FD_ZERO (&rs);
      FD_ZERO (&ws);
      FD_ZERO (&es);
      curl_multi_perform (multi, &running);
      mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
      if (mret != CURLM_OK)
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 2048;
        }
      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 4096;
        }
      tv.tv_sec = 0;
      tv.tv_usec = 1000;
      if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
        {
          if (EINTR != errno)
            abort ();
        }
      curl_multi_perform (multi, &running);
      if (running == 0)
        {
          msg = curl_multi_info_read (multi, &running);
          if (msg == NULL)
            break;
          if (msg->msg == CURLMSG_DONE)
            {
              if (msg->data.result != CURLE_OK)
                printf ("%s failed at %s:%d: `%s'\n",
                        "curl_multi_perform",
                        __FILE__,
                        __LINE__, curl_easy_strerror (msg->data.result));
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              c = NULL;
              multi = NULL;
            }
        }
      MHD_run (d);
    }
  if (multi != NULL)
    {
      curl_multi_remove_handle (multi, c);
      curl_easy_cleanup (c);
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello+world"))
    return 8192;
  if (0 != strncmp ("/hello+world", cbc.buf, strlen ("/hello+world")))
    return 16384;
  return 0;
}
Exemplo n.º 23
0
void ident_check(struct descriptor_data *d, int pulse)
{
  fd_set fd, efd;
  int rc, rmt_port, our_port, len;
  char user[256], *p;

  extern struct timeval null_time;
  extern int port;

  /*
   * Each pulse, this checks if the ident is ready to proceed to the
   * next state, by calling select to see if the socket is writeable
   * (connected) or readable (response waiting).  
   */

  switch (STATE(d)) {
    case CON_IDCONING:
      /* waiting for connect() to finish */

      if (d->ident_sock != INVALID_SOCKET) {
        FD_ZERO(&fd);
        FD_ZERO(&efd);
        FD_SET(d->ident_sock, &fd);
        FD_SET(d->ident_sock, &efd);
      }

      if ((rc = select(d->ident_sock + 1, (fd_set *) 0, &fd, &efd, &null_time)) == 0)
        break;

      else if (rc < 0) {
        logerror("ident check select (conning)");
        STATE(d) = CON_ASKNAME;
        break;
      }

      if (FD_ISSET(d->ident_sock, &efd)) {
        /* exception, such as failure to connect */
        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDCONED;
      break;

    case CON_IDCONED:
      /* connected, write request */

      sprintf(buf, "%d, %d\n\r", ntohs(d->peer_port), port);

      len = strlen(buf);
#ifdef CIRCLE_WINDOWS
      if (send(d->ident_sock, buf, len, 0) < 0) {
#else
      if (write(d->ident_sock, buf, len) != len) {
        if (errno != EPIPE) /* read end closed (no remote identd) */
#endif
          logerror("ident check write (conned)");

        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDREADING;
      break;

    case CON_IDREADING:
      /* waiting to read */

      if (d->ident_sock != INVALID_SOCKET) {
        FD_ZERO(&fd);
        FD_ZERO(&efd);
        FD_SET(d->ident_sock, &fd);
        FD_SET(d->ident_sock, &efd);
      }

      if ((rc = select(d->ident_sock + 1, &fd, (fd_set *) 0, &efd, &null_time)) == 0)
        break;

      else if (rc < 0) {
        logerror("ident check select (reading)");
        STATE(d) = CON_ASKNAME;
        break;
      }

      if (FD_ISSET(d->ident_sock, &efd)) {
        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDREAD;
      break;

    case CON_IDREAD:
      /* read ready, get the info */

#ifdef CIRCLE_WINDOWS
      if ((len = recv(d->ident_sock, buf, sizeof(buf) - 1, 0)) < 0)
#else
      if ((len = read(d->ident_sock, buf, sizeof(buf) - 1)) < 0)
#endif
        logerror("ident check read (read)");

      else {
        buf[len] = '\0';
        if (sscanf(buf, "%u , %u : USERID :%*[^:]:%255s", &rmt_port, &our_port, user) != 3) {

          /* check if error or malformed */
          if (sscanf(buf, "%u , %u : ERROR : %255s", &rmt_port, &our_port, user) == 3) {
            sprintf(buf2, "Ident error from %s: \"%s\"", d->hostIP, user);
            stderr_log(buf2);
          } else {
            /* strip off trailing newline */
            for (p = buf + len - 1; p > buf && ISNEWL(*p); p--)
              ;
            p[1] = '\0';

            sprintf(buf2, "Malformed ident response from %s: \"%s\"", d->hostIP, buf);
            stderr_log(buf2);
          }
        } else {

          len = HOST_LENGTH - strlen(d->hostIP);

          if (len > 0) {
            strncpy(buf2, user, len - 1);
            buf2[len - 1] = '\0';
            strcpy(d->username, buf2);
          }

          /* if len <= 0, no space for username */
        }
      }

      STATE(d) = CON_ASKNAME;
      break;

    case CON_ASKNAME:
      /* ident complete, ask for name */

      /* close up the ident socket, if one is opened. */
      if (d->ident_sock != INVALID_SOCKET) {
        close(d->ident_sock);
        d->ident_sock = INVALID_SOCKET;
      }
      d->idle_tics = 0;

      /* extra ban check */
      if ((d->host[0] != '\0' && isbanned(d->host) == BAN_ALL) || isbanned(d->hostIP)) {
        if (d->host[0] != '\0') {
          sprintf(buf, "Connection attempt denied from [%s]", d->host);
        } else {
          sprintf(buf, "Connection attempt denied from [%s]", d->hostIP);
        }
        mudlog(buf, 'S', COM_IMMORT, TRUE);
        close_socket(d);
        return;
      }

      /* SEND_TO_Q("\x1B[2K\n\rBy what name do you wish to be known? ", d); */
      STATE(d) = CON_GET_TERMTYPE;
      return;

    default:
      return;
  }

  /*
   * Print a dot every second so the user knows he hasn't been forgotten.
   * Allow the user to go on anyways after waiting IDENT_TIMEOUT seconds.
   */
  if ((pulse % PASSES_PER_SEC) == 0) {
    SEND_TO_Q(".", d);

    if (d->idle_tics++ >= IDENT_TIMEOUT)
      STATE(d) = CON_ASKNAME;
  }
}

/* returns 1 if waiting for ident to complete, else 0 */
int waiting_for_ident(struct descriptor_data *d)
{
  switch (STATE(d)) {
    case CON_IDCONING:
    case CON_IDCONED:
    case CON_IDREADING:
    case CON_IDREAD:
    case CON_ASKNAME:
      return 1;
  }
  return 0;
}
Exemplo n.º 24
0
int main(int argc, char *argv[])
{
    //Game vars
    int playerfd[2];
    char playerid = '1';
    char board[BSIZE][BSIZE];
    char bufrack[8];
    int x, y, num;
    char bufx[3], bufy[3];
    int bag[27] = {9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1, 2};
    char **dict;
    char word[MAXWORDSIZE];
    char bufout[MAXDATASIZE];

    dict = opendict(DICT);

    srandom(time(NULL));

    clearsqarray(BSIZE, board);

    int listens, newsock, sin_size, bigfd, numbytes, i, j;
    char buffer[MAXDATASIZE];
    struct sockaddr_in localaddr, newaddr, getaddr;
    fd_set master, tempfd;
    int yes = 1;

    listens = socket(PF_INET, SOCK_STREAM, 0);
    setsockopt(listens, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

    localaddr.sin_family = AF_INET;
    localaddr.sin_port = htons(PORT);
    localaddr.sin_addr.s_addr = INADDR_ANY;
    memset(&(localaddr.sin_zero), '\0', sizeof(localaddr.sin_zero));

    bind(listens, (struct sockaddr *) &localaddr, sizeof(localaddr));
    listen(listens, 10);

    FD_ZERO(&master);
    FD_ZERO(&tempfd);

    FD_SET(listens, &master);

    bigfd = listens;

    for(;;)
    {
        tempfd = master;

        select(bigfd + 1, &tempfd, NULL, NULL, NULL);

        for(i = 0; i <= bigfd; i++)
        {
            if(FD_ISSET(i, &tempfd))
            {
                if(i == listens)
                {
                    sin_size = sizeof(newaddr);
                    newsock = accept(listens, (struct sockaddr *) &newaddr, &sin_size);
                    
                    FD_SET(newsock, &master);
                    if(newsock > bigfd) 
                        bigfd = newsock;

                    printf("Connection from: %s Socket: %i\n", inet_ntoa(newaddr.sin_addr), newsock);

                    //playerid stuff
                    if(atoi(&playerid) < 2)
                        playerfd[atoi(&playerid) - 1] = newsock;

                    send(newsock, &playerid, sizeof(char), 0);
                    playerid++;

                    //send rack
                    randomrack(bufrack, bag, RACKSIZE);
                    send(newsock, bufrack, strlen(bufrack), 0);
                }
                else
                {
                    if((numbytes = recv(i, buffer, sizeof(buffer), 0)) == 0)
                    {
                        printf("Connection closed: socket %i\n", i);
                        
                        if(playerid == '3' || playerid == '1')
                            playerid = '1';
                        else
                            playerid--;

                        close(i);
                        FD_CLR(i, &master);
                    }
                    else if(numbytes < 0)
                    {
                        perror("recv");
                    }
                    else
                    {
                        //Data handling
                        getpeername(i, (struct sockaddr *) &getaddr, &sin_size);

                        if(buffer[0] != 'c' && buffer [0] != 'r' && buffer[0] != 'p')
                            printf("DATA From: %s Socket: %i Data: %s\n", inet_ntoa(getaddr.sin_addr), i, buffer);

                        send(i, "ACK", 4, 0);

                        if(strcmp(buffer, "q") == 0)
                            exit(0);

                        switch(buffer[0])
                        {
                            case 'c':
                                printf("CHAT From: %s Player: %i Message: %s\n", inet_ntoa(getaddr.sin_addr), i - 3, buffer + 1);

                                for(j = 0; j <= bigfd; j++)
                                    if(FD_ISSET(j, &master))
                                        if(j != listens && j != i)
                                            send(j, buffer, numbytes, 0);
                                break;
                            case 'r':
                                num = atoi(buffer + 1);
                                memset(bufrack, '\0', sizeof(bufrack));
                                randomrack(bufrack, bag, num);

                                sprintf(bufout, "r%s", bufrack);
                                send(i, bufout, strlen(bufout), 0);

                                printf("RACK From: %s Player: %i Number: %i Letters: %s\n", inet_ntoa(getaddr.sin_addr), i - 3, num, bufrack); 
                                break;
                            case 'p':
                                strncpy(bufx, buffer + 2, 2);
                                bufx[2] = '\0';
                                strncpy(bufy, buffer + 4, 2);
                                bufy[2] = '\0';

                                x = atoi(bufx);
                                y = atoi(bufy);

                                strncpy(word, buffer + 6, sizeof(word)); 
                                word[strlen(buffer + 6)] = '\0';

                                printf("PLACE From: %s Player: %i Direction: %c X: %i Y: %i Word: %s\n", inet_ntoa(getaddr.sin_addr), i - 3, buffer[1], x, y, word);

                                if(searchdict(word) != 1)
                                {
                                    send(i, "c*** Word not found ***", 25, 0);
                                    printf("DICT %s not found\n", word);
                                    break;
                                }

                                switch(buffer[1])
                                {
                                    case 'a':
                                        strplc_a(x, y, BSIZE, board, word, strlen(word));
                                        break;
                                    case 'd':
                                        strplc_d(x, y, BSIZE, board, word, strlen(word));
                                        break;
                                }

                                for(j = 0; j <= bigfd; j++)
                                    if(FD_ISSET(j, &master))
                                        if(j != listens)
                                            sendboard(j, buffer, *board, BSIZE);

                                sleep(1);

                                num = strlen(word);
                                memset(bufrack, '\0', sizeof(bufrack));
                                randomrack(bufrack, bag, num);

                                sprintf(bufout, "d%sr%s", word, bufrack);
                                send(i, bufout, strlen(bufout), 0);

                                printf("RACK From: %s Player: %i Number: %i Letters: %s\n", inet_ntoa(getaddr.sin_addr), i - 3, num, bufrack);
                                break;
                        }

                        memset(buffer, '\0', strlen(buffer));
                    }
                }
            }
        }
    }

    return 0;
}
Exemplo n.º 25
0
static ssize_t run_command(int sockfd, char const *command,
			   char *buffer, size_t bufsize)
{
	char *p;
	ssize_t size, len;

	if (echo) {
		fprintf(outputfp, "%s\n", command);
	}

	/*
	 *	Write the text to the socket.
	 */
	if (write(sockfd, command, strlen(command)) < 0) return -1;
	if (write(sockfd, "\r\n", 2) < 0) return -1;

	/*
	 *	Read the response
	 */
	size = 0;
	buffer[0] = '\0';

	memset(buffer, 0, bufsize);

	while (1) {
		int rcode;
		fd_set readfds;

		FD_ZERO(&readfds);
		FD_SET(sockfd, &readfds);

		rcode = select(sockfd + 1, &readfds, NULL, NULL, NULL);
		if (rcode < 0) {
			if (errno == EINTR) continue;

			fprintf(stderr, "%s: Failed selecting: %s\n",
				progname, strerror(errno));
			exit(1);
		}

		if (rcode == 0) {
			fprintf(stderr, "%s: Server closed the connection.\n",
				progname);
			exit(1);
		}

#ifdef MSG_DONTWAIT
		len = recv(sockfd, buffer + size,
			   bufsize - size - 1, MSG_DONTWAIT);
#else
		/*
		 *	Read one byte at a time (ugh)
		 */
		len = recv(sockfd, buffer + size, 1, 0);
#endif
		if (len < 0) {
			/*
			 *	No data: keep looping
			 */
			if ((errno == EAGAIN) || (errno == EINTR)) {
				continue;
			}

			fprintf(stderr, "%s: Error reading socket: %s\n",
				progname, strerror(errno));
			exit(1);
		}
		if (len == 0) return 0;	/* clean exit */

		size += len;
		buffer[size] = '\0';

		/*
		 *	There really is a better way of doing this.
		 */
		p = strstr(buffer, "radmin> ");
		if (p &&
		    ((p == buffer) ||
		     (p[-1] == '\n') ||
		     (p[-1] == '\r'))) {
			*p = '\0';

			if (p[-1] == '\n') p[-1] = '\0';
			break;
		}
	}

	/*
	 *	Blank prompt.  Go get another command.
	 */
	if (!buffer[0]) return 1;

	buffer[size] = '\0'; /* this is at least right */

	return 2;
}
Exemplo n.º 26
0
int main( int argc, char *argv[] )
{
    int ret;

    mbedtls_net_context listen_fd, client_fd, server_fd;

    int nb_fds;
    fd_set read_fds;

    mbedtls_net_init( &listen_fd );
    mbedtls_net_init( &client_fd );
    mbedtls_net_init( &server_fd );

    get_options( argc, argv );

    /*
     * Decisions to drop/delay/duplicate packets are pseudo-random: dropping
     * exactly 1 in N packets would lead to problems when a flight has exactly
     * N packets: the same packet would be dropped on every resend.
     *
     * In order to be able to reproduce problems reliably, the seed may be
     * specified explicitly.
     */
    if( opt.seed == 0 )
    {
        opt.seed = (unsigned int) time( NULL );
        mbedtls_printf( "  . Pseudo-random seed: %u\n", opt.seed );
    }

    srand( opt.seed );

    /*
     * 0. "Connect" to the server
     */
    mbedtls_printf( "  . Connect to server on UDP/%s/%s ...",
            opt.server_addr, opt.server_port );
    fflush( stdout );

    if( ( ret = mbedtls_net_connect( &server_fd, opt.server_addr, opt.server_port,
                             MBEDTLS_NET_PROTO_UDP ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_net_connect returned %d\n\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /*
     * 1. Setup the "listening" UDP socket
     */
    mbedtls_printf( "  . Bind on UDP/%s/%s ...",
            opt.listen_addr, opt.listen_port );
    fflush( stdout );

    if( ( ret = mbedtls_net_bind( &listen_fd, opt.listen_addr, opt.listen_port,
                          MBEDTLS_NET_PROTO_UDP ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_net_bind returned %d\n\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /*
     * 2. Wait until a client connects
     */
accept:
    mbedtls_net_free( &client_fd );

    mbedtls_printf( "  . Waiting for a remote connection ..." );
    fflush( stdout );

    if( ( ret = mbedtls_net_accept( &listen_fd, &client_fd,
                                    NULL, 0, NULL ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_net_accept returned %d\n\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /*
     * 3. Forward packets forever (kill the process to terminate it)
     */
    clear_pending();
    memset( dropped, 0, sizeof( dropped ) );

    nb_fds = client_fd.fd;
    if( nb_fds < server_fd.fd )
        nb_fds = server_fd.fd;
    if( nb_fds < listen_fd.fd )
        nb_fds = listen_fd.fd;
    ++nb_fds;

    while( 1 )
    {
        FD_ZERO( &read_fds );
        FD_SET( server_fd.fd, &read_fds );
        FD_SET( client_fd.fd, &read_fds );
        FD_SET( listen_fd.fd, &read_fds );

        if( ( ret = select( nb_fds, &read_fds, NULL, NULL, NULL ) ) <= 0 )
        {
            perror( "select" );
            goto exit;
        }

        if( FD_ISSET( listen_fd.fd, &read_fds ) )
            goto accept;

        if( FD_ISSET( client_fd.fd, &read_fds ) )
        {
            if( ( ret = handle_message( "S <- C",
                                        &server_fd, &client_fd ) ) != 0 )
                goto accept;
        }

        if( FD_ISSET( server_fd.fd, &read_fds ) )
        {
            if( ( ret = handle_message( "S -> C",
                                        &client_fd, &server_fd ) ) != 0 )
                goto accept;
        }
    }

exit:

#ifdef MBEDTLS_ERROR_C
    if( ret != 0 )
    {
        char error_buf[100];
        mbedtls_strerror( ret, error_buf, 100 );
        mbedtls_printf( "Last error was: -0x%04X - %s\n\n", - ret, error_buf );
        fflush( stdout );
    }
#endif

    mbedtls_net_free( &client_fd );
    mbedtls_net_free( &server_fd );
    mbedtls_net_free( &listen_fd );

#if defined(_WIN32)
    mbedtls_printf( "  Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret != 0 );
}
    void HttpServer::WaitMessage(uint32_t ms)
    {
      fd_set fdsr;
      struct timeval tv;
      int max_sock = m_sock;

      tv.tv_sec = ms / 1000;
      tv.tv_usec = (ms % 1000 ) / 1000;

      FD_ZERO(&fdsr);

#ifdef _WIN32
      /* on Windows, a socket is not an int but a SOCKET (unsigned int) */
      FD_SET((SOCKET)m_sock, &fdsr);
#else
      FD_SET(m_sock, &fdsr);
#endif

      for(std::list<int>::iterator it = m_clients.begin() ; it != m_clients.end() ; ++it)
      {
#ifdef _WIN32
        FD_SET((SOCKET)(*it), &fdsr);
#else
        FD_SET((*it), &fdsr);
#endif

        if((*it) > max_sock)
        {
          max_sock = (*it);
        }
      }

      max_sock++;

      if(select(max_sock, &fdsr, NULL, NULL, ms ? &tv : NULL) > 0)
      {
        if(FD_ISSET(m_sock, &fdsr))
        {
          Accept();
        }

        for(std::list<int>::iterator it = m_clients.begin() ; it != m_clients.end() ; ++it)
        {
          if(FD_ISSET((*it), &fdsr))
          {
            Recv((*it));
          }
        }

        /* remove disconnect socket descriptor */
        for(std::list<int>::iterator it = m_purge.begin() ; it != m_purge.end() ; ++it)
        {
          m_clients.remove((*it));
          m_httpmsgs.erase((*it));
        }

        /* purge disconnected list */
        m_purge.erase(m_purge.begin(), m_purge.end());
      }
      else
      {
        /* error */
      }
    }
Exemplo n.º 28
0
int zmq::signaler_t::wait (int timeout_)
{
#ifdef HAVE_FORK
    if (unlikely(pid != getpid()))
    {
        // we have forked and the file descriptor is closed. Emulate an interupt
        // response.
        //printf("Child process %d signaler_t::wait returning simulating interrupt #1\n", getpid());
        errno = EINTR;
        return -1;
    }
#endif

#ifdef ZMQ_SIGNALER_WAIT_BASED_ON_POLL

    struct pollfd pfd;
    pfd.fd = r;
    pfd.events = POLLIN;
    int rc = poll (&pfd, 1, timeout_);
    if (unlikely (rc < 0)) {
        errno_assert (errno == EINTR);
        return -1;
    }
    else
    if (unlikely (rc == 0)) {
        errno = EAGAIN;
        return -1;
    }
#ifdef HAVE_FORK
    if (unlikely(pid != getpid())) {
        // we have forked and the file descriptor is closed. Emulate an interupt
        // response.
        //printf("Child process %d signaler_t::wait returning simulating interrupt #2\n", getpid());
        errno = EINTR;
        return -1;
    }
#endif
    zmq_assert (rc == 1);
    zmq_assert (pfd.revents & POLLIN);
    return 0;

#elif defined ZMQ_SIGNALER_WAIT_BASED_ON_SELECT

    fd_set fds;
    FD_ZERO (&fds);
    FD_SET (r, &fds);
    struct timeval timeout;
    if (timeout_ >= 0) {
        timeout.tv_sec = timeout_ / 1000;
        timeout.tv_usec = timeout_ % 1000 * 1000;
    }
#ifdef ZMQ_HAVE_WINDOWS
    int rc = select (0, &fds, NULL, NULL,
        timeout_ >= 0 ? &timeout : NULL);
    wsa_assert (rc != SOCKET_ERROR);
#else
    int rc = select (r + 1, &fds, NULL, NULL,
        timeout_ >= 0 ? &timeout : NULL);
    if (unlikely (rc < 0)) {
        errno_assert (errno == EINTR);
        return -1;
    }
#endif
    if (unlikely (rc == 0)) {
        errno = EAGAIN;
        return -1;
    }
    zmq_assert (rc == 1);
    return 0;

#else
#error
#endif
}
Exemplo n.º 29
0
int main(int argc, char **argv)
{
	int fd = socket(AF_INET, SOCK_STREAM, 0); // TCP

	int on = 1;
	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);

	struct sockaddr_in srvaddr;
	bzero(&srvaddr, sizeof srvaddr);
	srvaddr.sin_family = AF_INET;
	srvaddr.sin_addr.s_addr = inet_addr(HOST);
	srvaddr.sin_port = htons(DEFAULT_PORT);

	if(connect(fd, (struct sockaddr *)&srvaddr, sizeof srvaddr) == -1)
	{
		perror("connect() error");
		exit(1);
	}

	struct sockaddr_in myaddr;
	socklen_t len = sizeof myaddr;
	bzero(&myaddr, len);
	getsockname(fd, (struct sockaddr *)&myaddr, &len);
	printf("my port: %hu\n", htons(myaddr.sin_port));


	//pthread_t tid;
	//pthread_create(&tid, NULL, routine, (void *)fd);


	char buf[100];
	
	fd_set rset, wset, eset; // 这些是描述符集合
	struct timeval a;
	a.tv_sec = 0;
	a.tv_usec = 0;
	
	while(1)
	{
#if 0 
		FD_ZERO(&rset); // 添加在这里面的描述符,我们关注他们的“读就绪”状态
		FD_ZERO(&wset); // 添加在这里面的描述符,我们关注他们的“写就绪”状态
		FD_ZERO(&eset); // 添加在这里面的描述符,我们关注他们的“异常就绪”状态
		FD_SET(fd, &rset);
		FD_SET(STDIN_FILENO, &rset); // 将两个描述符添加到rset里面!

		select(fd+1, &rset, &wset, &eset, &a);
		
		bzero(&buf, 100);
		if(FD_ISSET(STDIN_FILENO, &rset)) // 用户输入数据了!
		{
			fgets(buf, 100, stdin);				
			write(fd, buf, strlen(buf));
		}
#endif
		FD_ZERO(&rset); // 添加在这里面的描述符,我们关注他们的“读就绪”状态
		FD_ZERO(&wset); // 添加在这里面的描述符,我们关注他们的“写就绪”状态
		FD_ZERO(&eset); // 添加在这里面的描述符,我们关注他们的“异常就绪”状态
		FD_SET(fd, &rset);
		FD_SET(STDIN_FILENO, &rset); // 将两个描述符添加到rset里面!

		select(fd+1, &rset, &wset, &eset, &a);
		
		char buf[100];
		bzero(buf, 100);
		if(FD_ISSET(fd, &rset)) // 对方有消息来了!
		{
			if(read(fd, buf, 100) == 0)
				break;
			printf("broadcast: %s\n", buf);
		}
		if(FD_ISSET(STDIN_FILENO, &rset)) // 用户输入数据了!
		{
			fgets(buf, 100, stdin);
			write(fd, buf, strlen(buf));
		}
	}

	return 0;
}
Exemplo n.º 30
0
int32_t
server_init(server_p srv, char const *control)
{
    struct sockaddr_un	un;
    struct sockaddr_l2cap	l2;
    int32_t			unsock, l2sock;
    socklen_t		size;
    uint16_t		imtu;

    assert(srv != NULL);
    assert(control != NULL);

    memset(srv, 0, sizeof(srv));

    /* Open control socket */
    if (unlink(control) < 0 && errno != ENOENT) {
        log_crit("Could not unlink(%s). %s (%d)",
                 control, strerror(errno), errno);
        return (-1);
    }

    unsock = socket(PF_LOCAL, SOCK_STREAM, 0);
    if (unsock < 0) {
        log_crit("Could not create control socket. %s (%d)",
                 strerror(errno), errno);
        return (-1);
    }

    memset(&un, 0, sizeof(un));
    un.sun_len = sizeof(un);
    un.sun_family = AF_LOCAL;
    strlcpy(un.sun_path, control, sizeof(un.sun_path));

    if (bind(unsock, (struct sockaddr *) &un, sizeof(un)) < 0) {
        log_crit("Could not bind control socket. %s (%d)",
                 strerror(errno), errno);
        close(unsock);
        return (-1);
    }

    if (chmod(control, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) < 0) {
        log_crit("Could not change permissions on control socket. " \
                 "%s (%d)", strerror(errno), errno);
        close(unsock);
        return (-1);
    }

    if (listen(unsock, 10) < 0) {
        log_crit("Could not listen on control socket. %s (%d)",
                 strerror(errno), errno);
        close(unsock);
        return (-1);
    }

    /* Open L2CAP socket */
    l2sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BLUETOOTH_PROTO_L2CAP);
    if (l2sock < 0) {
        log_crit("Could not create L2CAP socket. %s (%d)",
                 strerror(errno), errno);
        close(unsock);
        return (-1);
    }

    size = sizeof(imtu);
    if (getsockopt(l2sock, SOL_L2CAP, SO_L2CAP_IMTU, &imtu, &size) < 0) {
        log_crit("Could not get L2CAP IMTU. %s (%d)",
                 strerror(errno), errno);
        close(unsock);
        close(l2sock);
        return (-1);
    }

    memset(&l2, 0, sizeof(l2));
    l2.l2cap_len = sizeof(l2);
    l2.l2cap_family = AF_BLUETOOTH;
    memcpy(&l2.l2cap_bdaddr, NG_HCI_BDADDR_ANY, sizeof(l2.l2cap_bdaddr));
    l2.l2cap_psm = htole16(NG_L2CAP_PSM_SDP);

    if (bind(l2sock, (struct sockaddr *) &l2, sizeof(l2)) < 0) {
        log_crit("Could not bind L2CAP socket. %s (%d)",
                 strerror(errno), errno);
        close(unsock);
        close(l2sock);
        return (-1);
    }

    if (listen(l2sock, 10) < 0) {
        log_crit("Could not listen on L2CAP socket. %s (%d)",
                 strerror(errno), errno);
        close(unsock);
        close(l2sock);
        return (-1);
    }

    /* Allocate incoming buffer */
    srv->imtu = (imtu > SDP_LOCAL_MTU)? imtu : SDP_LOCAL_MTU;
    srv->req = (uint8_t *) calloc(srv->imtu, sizeof(srv->req[0]));
    if (srv->req == NULL) {
        log_crit("Could not allocate request buffer");
        close(unsock);
        close(l2sock);
        return (-1);
    }

    /* Allocate memory for descriptor index */
    srv->fdidx = (fd_idx_p) calloc(FD_SETSIZE, sizeof(srv->fdidx[0]));
    if (srv->fdidx == NULL) {
        log_crit("Could not allocate fd index");
        free(srv->req);
        close(unsock);
        close(l2sock);
        return (-1);
    }

    /* Register Service Discovery profile (attach it to control socket) */
    if (provider_register_sd(unsock) < 0) {
        log_crit("Could not register Service Discovery profile");
        free(srv->fdidx);
        free(srv->req);
        close(unsock);
        close(l2sock);
        return (-1);
    }

    /*
     * If we got here then everything is fine. Add both control sockets
     * to the index.
     */

    FD_ZERO(&srv->fdset);
    srv->maxfd = (unsock > l2sock)? unsock : l2sock;

    FD_SET(unsock, &srv->fdset);
    srv->fdidx[unsock].valid = 1;
    srv->fdidx[unsock].server = 1;
    srv->fdidx[unsock].control = 1;
    srv->fdidx[unsock].priv = 0;
    srv->fdidx[unsock].rsp_cs = 0;
    srv->fdidx[unsock].rsp_size = 0;
    srv->fdidx[unsock].rsp_limit = 0;
    srv->fdidx[unsock].omtu = SDP_LOCAL_MTU;
    srv->fdidx[unsock].rsp = NULL;

    FD_SET(l2sock, &srv->fdset);
    srv->fdidx[l2sock].valid = 1;
    srv->fdidx[l2sock].server = 1;
    srv->fdidx[l2sock].control = 0;
    srv->fdidx[l2sock].priv = 0;
    srv->fdidx[l2sock].rsp_cs = 0;
    srv->fdidx[l2sock].rsp_size = 0;
    srv->fdidx[l2sock].rsp_limit = 0;
    srv->fdidx[l2sock].omtu = 0; /* unknown */
    srv->fdidx[l2sock].rsp = NULL;

    return (0);
}