Ejemplo n.º 1
0
const
int snap_single(CamConfig *ccfg ){
  const char *snapfname;
  int presnaps;

  if( !(snapfname = camconfig_query_str( ccfg, SEC_MAIN, "output_snapfile")))
    return 0;

  presnaps = camconfig_query_def_int( ccfg, SEC_MAIN, "output_presnaps", 0 );
  if( picture_single( ccfg, snapfname, presnaps ) == -1 ){
    camserv_log( "snap_single", "Failed to snap picture!" );
  }
  return 1;
}
Ejemplo n.º 2
0
static
void dump_cfg_options( CamConfig *ccfg ){
  char vid_section[ 1024 ], key[ 1024 ];
  const char *path, *val;
  ModInfo *minfo;
  int i, nfilters;

  if( video_query_active_section( ccfg, vid_section, sizeof( vid_section ))){
    path = camconfig_query_str( ccfg, vid_section, "path" );
    fprintf( stderr, "*** Module: \"%s\"\n", path );

    if( (minfo = modinfo_query_so( path )) != NULL ){
      modinfo_dump( minfo );
      modinfo_destroy( minfo );
      printf("\n");
    } else
      fprintf( stderr, "Failed to dump video device; \"%s\"\n", path );
  }
  
  nfilters = camconfig_query_def_int( ccfg, SEC_FILTERS, "num_filters", 0 );
  for( i=0; i< nfilters; i++ ){
    sprintf( key, "filter%d_section", i );
    if( (val = camconfig_query_str( ccfg, SEC_FILTERS, key )) == NULL ){
      fprintf( stderr, "KEY/VALUE \"%s\" not found!\n", key );
      continue;
    }
    strncpy( key, val, sizeof( key ) - 1 );
    key[ sizeof( key ) - 1 ] = '\0';
    if( (path = camconfig_query_str( ccfg, key, "path" )) != NULL ){
      if( (minfo = modinfo_query_so( path )) != NULL ){
	fprintf( stderr, "*** Filter: \"%s\"\n", path );
	modinfo_dump( minfo );
	modinfo_destroy( minfo );
	printf("\n");
      } else
	fprintf( stderr, "Failed to dump filter: \"%s\"\n", path );
    }
  }
}
Ejemplo n.º 3
0
int main_loop( CamConfig *ccfg, Socket *picture_sock, char *picture_mem  ){
  Socket *listen_socket;
  SockSet *readset = NULL, *writeset = NULL;
  list_t *client_sockets;
  lnode_t *node;
  int cfg_listen_port, highest_fd, picture_client_ready;
  int num_sclients, num_clients;
  ClientInfo *clientinfo, *clientinfo2;

  if( (client_sockets = list_create( -1 )) == NULL)
    return -1;

  cfg_listen_port = camconfig_query_def_int( ccfg, SEC_SOCKET, 
					     "listen_port",
					     CAMCONFIG_DEF_LISTEN_PORT );

  if( (readset = sockset_new()) == NULL ||
      (writeset = sockset_new()) == NULL )
  {
    camserv_log( MODNAME, "Error allocating memory for socksets!");
    if( readset ) sockset_dest( readset );
    if( writeset ) sockset_dest( writeset );
    list_destroy( client_sockets );
    return -1;
  }

  if((listen_socket = socket_serve_tcp( NULL, cfg_listen_port, 100 )) == NULL )
  {
      camserv_log( MODNAME, "Error setting up socket on port \"%d\".  Exiting",
	       cfg_listen_port  );
      list_destroy( client_sockets );
      sockset_dest( readset );
      sockset_dest( writeset );
      return -1;
  }

  highest_fd = MAX( socket_query_fd( listen_socket ), 
		    socket_query_fd( picture_sock ));
  clientinfo = clientinfo_new( listen_socket );
  clientinfo2 = clientinfo_new( picture_sock );

  if( !clientinfo || !clientinfo2 ||
      sockset_add_fd( readset, listen_socket, clientinfo ) == -1 ||
      sockset_add_fd( readset, picture_sock, clientinfo2 ) == -1 )
  {
    camserv_log( MODNAME, "Error adding initial sockets to sockset!");
    sockset_dest( readset );
    sockset_dest( writeset );
    if( clientinfo )  clientinfo_dest( clientinfo );
    if( clientinfo2 ) clientinfo_dest( clientinfo2 );
    list_destroy( client_sockets );
    return -1;
  }

  num_clients = 0;
  num_sclients = 0;
  picture_client_ready = 1;

  setup_signals();
  Abort = 0;
  while( !Abort ){
    int sel_res, i, nset_socks;
    void **set_socks;

    /* Only need to execute this if we have a streaming client */
    if( (num_sclients > 0) && picture_client_ready == 1 ){
      send( socket_query_fd( picture_sock ), "0", sizeof( "0" ), 0 );
      picture_client_ready = 0;
    }

    sockset_reset( readset );
    sockset_reset( writeset );

    sel_res = sockset_select( highest_fd + 1, readset, writeset, NULL );
    /* Service the event */
    if( sel_res == -1 ){
      camserv_log( MODNAME, "select() failure: %s", strerror( errno ));
      break;
    } else if( sel_res == 0 ){
      camserv_log( MODNAME, "Unexpected select() fall through!" );
      continue;
    } 

    /* Readable sockets */
    set_socks = sockset_query_socks( readset );
    nset_socks = sockset_query_nsocks( readset );
    for( i=0; i< nset_socks; i++ ){
      ClientInfo *new_cinfo;

      clientinfo = set_socks[ i ];

      if( clientinfo->socket == listen_socket ) {
	/* New client */
	if( (new_cinfo = accept_client( listen_socket )) == NULL )
	  continue;

	if( (node = lnode_create( new_cinfo )) == NULL ){
	  clientinfo_dest( new_cinfo );
	  continue;
	}

	if( sockset_add_fd( readset, new_cinfo->socket, new_cinfo ) == -1 ){
	  camserv_log( MODNAME, "Failed to add socket %d to socket read set!",
		   socket_query_fd( new_cinfo->socket ));
	  clientinfo_dest( new_cinfo );
	  lnode_destroy( node );
	  continue;
	}

	if( socket_query_fd( new_cinfo->socket ) > highest_fd )
	  highest_fd = socket_query_fd( new_cinfo->socket );

	list_append( client_sockets, node );
	num_clients++;
	/* Init resource limit for this client */
	new_cinfo->create_time = time( NULL );
	new_cinfo->bytes       = 0;
	new_cinfo->frames      = 0;
	new_cinfo->max_seconds = camconfig_query_def_int( ccfg, SEC_SOCKET,
							  "max_seconds", 0 );
	new_cinfo->max_bytes   = camconfig_query_def_int( ccfg, SEC_SOCKET,
							  "max_bytes", 0 );
	new_cinfo->max_frames  = camconfig_query_def_int( ccfg, SEC_SOCKET,
							  "max_frames", 0 );

	/* Send fresh request for a picture */
	send( socket_query_fd( picture_sock ), "0", sizeof( "0" ), 0 );
	picture_client_ready = 0;
	/* Put this read socket on hold until the picture comes back */
	sockset_hold( readset, new_cinfo->socket );	

      } else {
	char cmdbuf[ 1024 ];
	int readlen;

	clientinfo = set_socks[ i ];

	/* Regular joe client, set readable */
	if( (readlen = read( socket_query_fd( clientinfo->socket), cmdbuf, 
			     sizeof( cmdbuf ) - 1)) <= 0 )
	{
	  camserv_log( MODNAME, "Closing socket: %s", 
		       socket_query_remote_name( clientinfo->socket ));

	  if (clientinfo->client_type == CLIENT_T_BROWSER ||
	      clientinfo->client_type == CLIENT_T_PROXY) {
	      num_sclients--;
	  }
	  client_remove( client_sockets, clientinfo );
	  sockset_del_fd( readset, clientinfo->socket );
	  sockset_unhold_all( writeset );
	  sockset_del_fd( writeset, clientinfo->socket );
	  clientinfo_dest( clientinfo );
	  num_clients--;
	} else {
	  if( clientinfo->socket == picture_sock ) {
	    if( dispatch_pictaker( cmdbuf, picture_mem ) == -1 )
	      camserv_log( MODNAME, "Pictaker dispatch failure!");
	    sockset_unhold_all( writeset );
	    /* Release the read hold as the picture has now been taken */
	    sockset_unhold_all( readset );
	    picture_client_ready = 1;
	  } else {
	    /* Information from a regular client */
	    cmdbuf[ readlen ] = '\0';
	    if( clientinfo->client_type == CLIENT_T_UNINIT ) {
	      char *preamble;
	      int pre_size;

	      /* Figure out what type of client we have */
	      if( !strncmp( cmdbuf, "GET", 3 )) {
		if( strstr( cmdbuf, "/singleframe" )) {
		  clientinfo->client_type = CLIENT_T_SINGLE;
		} else {
		  clientinfo->client_type = CLIENT_T_BROWSER;
		  num_sclients++;
	        }
	      } else if( !strncmp( cmdbuf, "PROXY", 5 )) {
		clientinfo->client_type = CLIENT_T_PROXY;
		/* Here we are in the same state as being done writing a pic */
		clientinfo->state       = CINFO_STATE_PICTURE;
		num_sclients++;	
		databuf_buf_set( clientinfo->writebuf, NULL, 0 ); 
	      } else 
		clientinfo->client_type = CLIENT_T_BROWSER;

	      if( clientinfo->client_type != CLIENT_T_PROXY ) {
		/* Send the initial preamble.  Only now we can decide which 
		   type of preamble to send (single vs. multi-part) */
		if( clientinfo->client_type == CLIENT_T_SINGLE )
		  preamble = get_single_preamble_text( &pre_size );
		else
		  preamble = get_multi_preamble_text( &pre_size );
		databuf_buf_set( clientinfo->writebuf, preamble, pre_size );
	      }

	      if( sockset_add_fd( writeset, clientinfo->socket, 
				  clientinfo ) == -1 )
	      {
  		  camserv_log( MODNAME, "Failed to add socket %d to write set!",
			   socket_query_fd( clientinfo->socket ));
	      }
	  } 
	} 
      } 
    } 
  } 

    if( set_socks != NULL ) free( set_socks );

    /* Writable sockets */
    set_socks = sockset_query_socks( writeset );
    nset_socks = sockset_query_nsocks( writeset );
    for( i=0; i< nset_socks; i++ ){
      ClientInfo *cinfo;

      cinfo = set_socks[ i ];
      if( cinfo->client_type == CLIENT_T_BROWSER ||
	  cinfo->client_type == CLIENT_T_SINGLE ) 
      {
	int result;

	if( (result = write_regular_client( cinfo, writeset )) != 0 ){
	  /* result: 1=close requested, -1=error detected */
	  if( result == -1 )
	    camserv_log( MODNAME, "Databuf write error on socket: %s\n",
			 socket_query_remote_name( cinfo->socket ));
	  
	  if (cinfo->client_type == CLIENT_T_BROWSER) {
	      num_sclients--;
	  }

	  client_remove( client_sockets, cinfo );
	  sockset_del_fd( readset, cinfo->socket );
	  sockset_del_fd( writeset, cinfo->socket );
	  clientinfo_dest( cinfo );
	  num_clients--;
	}
      } else {
	if( write_proxy_client( cinfo, writeset ) == -1 ){
	  camserv_log( MODNAME, "Databuf write error on socket: %d",
		   socket_query_fd( cinfo->socket ));

	  /* Should be proxy, but better check */
	  if (cinfo->client_type == CLIENT_T_PROXY) {
	      num_sclients--;
	  }
	  client_remove( client_sockets, cinfo );
	  sockset_del_fd( readset, cinfo->socket );
	  sockset_del_fd( writeset, cinfo->socket );
	  clientinfo_dest( cinfo );
	  num_clients--;
	}
      }
    }
    if( set_socks != NULL ) free( set_socks );
  }

  camserv_log( MODNAME, "Aborting.");
  sockset_dest( readset );
  sockset_dest( writeset );

  for( node = list_first( client_sockets) ; node; 
       node=list_next( client_sockets, node ))
  {
    clientinfo_dest( node->data );
  }

  /* Tell the picture taker to get out!  Get out! */
  camserv_log( MODNAME, "Closing picture taker");
  send( socket_query_fd( picture_sock ), "9", sizeof( "9" ), 0 );
  sleep( 3 );
  camserv_log( MODNAME, "done\n");

  list_destroy_nodes( client_sockets );
  list_destroy( client_sockets );
  socket_dest( listen_socket );
  return 0;
}
Ejemplo n.º 4
0
int main( int argc, char *argv[] ){
  Socket **localsocks;
  CamConfig *camcfg;
  char *shm_segment, tmpbuf[ 1024 ], cfg_path[ MAXPATHLEN ];
  int fd, shm_alloc, donecfg;
  extern int errno;

  donecfg = 0;
  if (argc >= 2) {
    strncpy( cfg_path, argv[ 1 ], sizeof( cfg_path ) );
    cfg_path[ sizeof( cfg_path ) - 1 ] = '\0';
    camserv_log( "main", "Trying to read config file \"%s\": ", cfg_path);
    if( (camcfg = read_ccfg( cfg_path )) == NULL ){
      camserv_log( "main", "Error reading config \"%s\": %s", cfg_path,
		   strerror( errno ));
    } else {
      camserv_log( "main", "Success reading config \"%s\"", cfg_path);
      donecfg=1;
    }
  } else {
    fprintf( stderr, "camserv v%s - by Jon Travis ([email protected])\n", 
	     VERSION );
    fprintf( stderr, "Syntax: %s <cfg file>\n", argv[0] );
    fprintf( stderr, "Will try %s/camserv.cfg\n", DATDIR);
   
    if (!donecfg) {
      snprintf( cfg_path, sizeof( cfg_path ), "%s/camserv.cfg", DATDIR );
      cfg_path[ sizeof( cfg_path ) - 1 ] = '\0';
      camserv_log( "main", "Trying to read config file \"%s\": ", cfg_path);
      if( (camcfg = read_ccfg( cfg_path )) == NULL ){
	camserv_log( "main", "Error reading config \"%s\": %s", cfg_path,
		     strerror( errno ));
      } else {
	camserv_log( "main", "Success reading config \"%s\"", cfg_path);
	donecfg=1;
      }
    }
  }

  if (!donecfg) {
    camserv_log( "main", "Error finding config file, exit!");
    return(-1);
  }

  /* If we took a single snapshot, we are all done */
  if( snap_single( camcfg )) 
    return 0;

  if( (localsocks = socket_unix_pair( SOCK_DGRAM )) == NULL ){
    camserv_log( "main", "Error creating communication sockets between procs");
    return -1;
  }
  
  /* Setup a temp file for making our shm */
  strcpy( tmpbuf, "/tmp/CAMSERV_XXXXXX" );
  if( (fd = mkstemp( tmpbuf )) == -1 ){
    camserv_log( "main", "Couldn't create temporary file: %s", tmpbuf );
    strcpy( tmpbuf, argv[ 0 ] ); /* Last resort */
  } else {
    close( fd );
  }

  shm_alloc = camconfig_query_def_int( camcfg, SEC_MAIN, "shm_alloc", 
				       PICTURE_MALLOC );

  if( shm_alloc < PICTURE_MALLOC )
    camserv_log( "main", "Allocated %d bytes for SHM [RISKY RISKY!]",
		 shm_alloc);

  if( (Shmid = shm_setup( tmpbuf,
			  /* Allocate generous ammount */
			  shm_alloc,
			  &shm_segment) ) == -1 ){

    socket_unix_pair_dest( localsocks );
    return -1;
  }
  unlink( tmpbuf );

/* Start the picture taker thread */
  CPid = picture_taker( shm_segment, PICTURE_MALLOC, camcfg, localsocks[ 0 ]); 
  if( CPid == -1 ){
    /* Failure setting up camerastuffs */
    camserv_log( "main",  "Picture taker could not be created!");
    socket_unix_pair_dest( localsocks );
    return -1;
  }
    
  if( main_loop( camcfg, localsocks[ 1 ], shm_segment ) == -1 ){
    camserv_log( "main", "Main loop exited abnormally");
    socket_unix_pair_dest( localsocks );
    if( CPid != -1 ) kill( CPid, SIGINT );
    return -1;
  }

  socket_unix_pair_dest( localsocks );
  return 0;
}