Exemple #1
0
void nonBlockFifo(int clientFd) 
/*
 * See if the input is a fifo, and setup the fcntl correctly
 */
{
	struct stat info;
	int flags;
	int dataFd = fileno(gDataFile);
	fstat(dataFd, &info);
	if ( info.st_mode & S_IFIFO ) {
		if ( gReadRewind ) {
			CapError(clientFd, CAP_SEV_FATAL, gProgramName, 
					 "Cannot -r (rewind) FIFO");
			exit(1);
		}
#ifndef _WIN32
		flags = fcntl(dataFd,F_GETFL);
		fcntl(dataFd,F_SETFL,flags|FNONBLK);
#endif
	}
}
Exemple #2
0
static void get_data(int client_fd)
{

	channelInfo *chan = gChannels;
	char *tokBuffer;
	char *lp;
	int i;
	char *errOverFlow =
		"Input buffer overflow line length greater than -b %d";

	if ( gReadReopen ) {
		if ( NULL != gDataFile )
			fclose(gDataFile);

		gDataFile = fopen(gDataPath, "r");

		if (NULL == gDataFile) {
			CapError(client_fd, CAP_SEV_FATAL, gProgramName, NULL);
			exit(1);
		}

		nonBlockFifo(client_fd);
	} else if ( gReadRewind )
		rewind(gDataFile);


	/*
	 * find the data record
	 */
	while ( lp = fgets(gBuffers[gReadBuffer] + gBufferOffset,
					   gBufferSize - gBufferOffset, gDataFile) )
	{
		gBufferOffset = strlen(lp);
				
		if ( '\n' == lp[gBufferOffset-1] ) {
			/* This completes a full record */
			gReadBuffer   = 1 - gReadBuffer;
			gBufferOffset = 0;
			/*
			 * RFE: add support for leading character "comments"
			 */
			if (gReadNext)
				break;
		} else if ( gBufferSize <= gBufferOffset ) {
			CapError(client_fd, CAP_SEV_FATAL, gProgramName, 
					 errOverFlow, gBufferSize );
			exit(1);
		}
	}

	/*
	 * gReadBuffer is the buffer to read or in process 1-grb is complete!
	 */
	tokBuffer = gBuffers[1 - gReadBuffer];
	while (chan != NULL) {
		float val;
		channelInfo *next = chan->next;
		for ( i = 0; i< chan->info->p1.dim; i++) {
			char *tok = strtok(tokBuffer," \n\t");
			tokBuffer = NULL; /* how strtok works ;-o */
			if ( NULL == tok || ( 1 != sscanf(tok,"%g", &val) )) {
				next = NULL;
				break;
			}
			chan->data[i] = val;
		}
		chan = next;
	}


	channelInfoSetData(gChannels, 1, NULL);

	return;
}
Exemple #3
0
static int handle_client(int client_fd)
{
	int status;
	size_t size, nitems;
	FILE *serial_file;
	char buf[1024];	/* buffer for serial IO */
	CapCommand cmd;
	char ruser[64], rhost[64], realhost[64];
	double rate, time;
	fd_set rd_fds;
	struct timeval timeout, now, *timeoutPtr;
	int    recording = 0;
	double recordNow    = 0.;
	double recordNext   = 0.;
	double recordPeriod = 0.;
	double recordDelta  = 0.;
#ifdef _WIN32
	int ms;
#endif

	while (1)
	{
		FD_ZERO(&rd_fds);
		FD_SET(client_fd, &rd_fds);

		if ( !recording ) {
			timeoutPtr = NULL;
		} else {
			/* record and schedule the next recording */
#ifdef LINUX
			gettimeofday(&now, NULL);
#else
			gettimeofday(&now);
#endif
			recordNow   = toDouble(now);
			if ( recordNext == 0.0 ) /* The first record */
				recordNext = recordNow;

			while ( recordNext <= recordNow ) {
				get_data(client_fd);
				recordNext = recordNext + recordPeriod;
			}
			
			timeout = toTimeval( recordNext - recordNow );
			timeoutPtr = &timeout;
		}

		/*
		 * wait for commands or a timeout
		 */
#ifndef _WIN32
		status = select(FD_SETSIZE, &rd_fds, NULL, NULL, timeoutPtr);
#else
		/* Should really use CapWaitTimeout when possible */
		ms = -1;
		if (timeoutPtr)
			ms = timeoutPtr->tv_sec*1000 + timeoutPtr->tv_usec/1000;
		status = CapWaitTimeout(client_fd, ms);
#endif


		if (status < 0 ) {
			if (errno == EINTR) {
				/* Ignore signals and try again */
				continue;
			}

			/* Otherwise, give a fatal error message */
			CapError(client_fd, CAP_SEV_FATAL, gProgramName, "select failed");
			CapError(client_fd, CAP_SEV_FATAL, "select", NULL);
			exit(1);
		}
		else if (status == 0) {
			/* Try again */
			continue;
		}

		/* There is data on the client file descriptor */
		cmd = CapGetCommand(client_fd);
		switch (cmd) {
		case CAP_CMD_QUIT:
			return 0;

		case CAP_CMD_AUTHORIZE:
			status = CapGetAuthInfo(client_fd, ruser, rhost, realhost);
			if (status < 0)
			{
				return -1;
			}

			/*
			 * If user@host is not authorized to use this server then:
			 *
			 * status = CapAuthorize(client_fd, 0);
			 */
			status = CapAuthorize(client_fd, 1);
			break;

		case CAP_CMD_INIT:	/* Initial client/server handshake */
			status = CapInitialize(client_fd, gProgramName);
			break;

		case CAP_CMD_VERSION:	/* Send version information */
			status = CapVersion(client_fd, gProgramName, "1.0",
								"Extern server (example) - v1.0");
			break;

		case CAP_CMD_INFO:
			if (NULL == gChannels)
			{
				/* Only create the channel data once */
				gChannels = create_channels(gConfigFile, client_fd);
				if ( NULL == gChannels)
				{
					status = CapError(client_fd, CAP_SEV_ERROR, 
									  gProgramName,
									  "Missing or empty config file");  
				}
			}
			/* Return the recording information. gMaxRecordRate <= 0.
			 * says recording is not supported
			 */
			{
				size_t buf_size = 0;
				if ( 0. < gMaxRecordRate) 
					buf_size = INT_MAX;
				status = CapInfo(client_fd, gMinRecordRate, 
								 gMaxRecordRate, gDefRecordRate, 
								 buf_size, 1);
			}
			break;
	  
		case CAP_CMD_DATA:	/* Send frame data */
			if (!recording )
				get_data(client_fd);
			status = CapData(client_fd);
			break;


		case CAP_CMD_START_RECORD:	/* Start recording */
			rate = CapGetRequestedRecordRate(client_fd);
			size = CapGetRequestedRecordSize(client_fd);

			/* 
			 * Set up for recording operations
			 */
			if (rate < gMinRecordRate ) 
				rate = gMinRecordRate;
			else if (rate > gMaxRecordRate ) 
				rate = gMaxRecordRate;

			status = CapStartRecord(client_fd, rate, size);
			if (status != -1)
			{
				recordPeriod = 1.0 / rate;
				recordNext   = 0.;
				recording = 1;
			}
			break;

		case CAP_CMD_STOP_RECORD:		/* Stop recording */
			status = CapStopRecord(client_fd);
			recording = 0;
			break;

		default:			/* Ignore unknown commands */
			status = CapError(client_fd, CAP_SEV_ERROR, gProgramName,
							  "Unknown server command.");
			break;
		}

		if (status < 0)
		{
			return -1;
		}
		
	}

	/* return 0; */
}
Exemple #4
0
int main(int argc, char **argv)
{

	int status;
	int client_fd = -1;

	/*
	 * on err, this exits...
	 */
	parseArgs( argc, argv);


	/*
	 * Initialization...
	 */
	gBuffers[0] = malloc(gBufferSize);
	gBuffers[1] = malloc(gBufferSize);
	if ( ( NULL == gBuffers[0] ) || ( NULL == gBuffers[1] ) ) {
		CapError(-1, CAP_SEV_FATAL, gProgramName, 
				 "out of memory, -b %d failed",gBufferSize);
		exit(1);
	}
	*(gBuffers[0]) = '\0';
	*(gBuffers[1]) = '\0';


	if (gInetdMode) {
		/*
		 * The socket to the client is open on file descriptor 0.
		 * Handle one client and then exit.
		 */
		client_fd = 0;
	}

	if (gDaemonMode) {
		/*
		 * Convert this process into a standard unix type daemon process.
		 * It will be running in the background with no controlling terminal
		 * and using syslog to report error messages.
		 */
		status = CapDaemonize();
		if (status < 0)	{
			CapError(-1, CAP_SEV_FATAL, gProgramName, NULL);
			exit(1);
		}
	}

	/*
	 * open the configuration and data files
	 */
    gChannels = create_channels(gConfigFile, client_fd);
	if ( NULL == gChannels ) {
		CapError(-1, CAP_SEV_FATAL, gProgramName, NULL);
		exit(1);
	}

	if ( 0 == strcmp(gDataPath,"-") ) {
		gDataFile = stdin;
	} else {
		/*
		 * RFE: delay opening until first read
		 */
		gDataFile = fopen(gDataPath, "r");
		if ( !gReadReopen && (NULL == gDataFile) ) {
			CapError(-1, CAP_SEV_FATAL, gProgramName, NULL);
			exit(1);
		}
	}

	if ( NULL != gDataFile ) 
		nonBlockFifo(-1);
			
	if (gInetdMode)
	{
		/*
		 * The socket to the client is already open on file descriptor 0.
		 * Handle one client and then exit.
		 */
		status = handle_client(client_fd);
		exit(status);
	}
	else
	{
		while (1)
		{
			/*
			 * Set up the server socket and wait for a connection.
			 */
			client_fd = CapServe(gServerName);
			if (client_fd < 0)
			{
				CapError(-1, CAP_SEV_FATAL, gProgramName, NULL);
				exit(1);
			}
      
			/* Handle client requests */
			status = handle_client(client_fd);

			if (status < 0)
			{
				CapError(-1, CAP_SEV_FATAL, gProgramName, NULL);
			}

			/* Shutdown the client */
			closesocket(client_fd);
			client_fd = -1;

			/* Go back and wait for another connection request */
			continue;
		}
	}
}
Exemple #5
0
static int handle_client(int client_fd)
{
  int status;
  CapCommand cmd;
  char ruser[64], rhost[64], realhost[64];
  fd_set rd_fds;
  struct timeval base_timeout, timeout;
  int recording = 0;

  static int channels_created = 0;

  base_timeout.tv_sec  = 1;
  base_timeout.tv_usec = 0;

  while (1)
  {
    FD_ZERO(&rd_fds);
    FD_SET((unsigned int)client_fd, &rd_fds);
    timeout.tv_sec  = base_timeout.tv_sec;
    timeout.tv_usec = base_timeout.tv_usec;
    
	status = select(FD_SETSIZE, &rd_fds, NULL, NULL, &timeout);
    if (status < 0)
    {
#ifndef _WIN32
      if (errno == EINTR)
      {
	/* Ignore signals and try again */
	continue;
      }
#endif /*WIN32*/

      /* Otherwise, give a fatal error message */
      CapError(client_fd, CAP_SEV_FATAL, program, "select failed");
      CapError(client_fd, CAP_SEV_FATAL, "select", NULL);
      exit(1);
    }
    else if (status == 0)
    {
      /* We got a timeout */
      if (recording) get_data(client_fd);

      /* Try again */
      continue;
    }
    else
    {
      /* There is data on the client file descriptor */
      cmd = CapGetCommand(client_fd);
      switch (cmd)
      {
	case CAP_CMD_QUIT:
	  return 0;

#ifdef _WIN32
	case CAP_CMD_ERROR:
		return -1;
#endif

	case CAP_CMD_AUTHORIZE:
	  status = CapGetAuthInfo(client_fd, ruser, rhost, realhost);
	  if (status < 0)
	  {
	    return -1;
	  }

	  /*
	   * If user@host is not authorized to use this server then:
	   *
	   * status = CapAuthorize(client_fd, 0);
	   */
	  status = CapAuthorize(client_fd, 1);
	  break;

	case CAP_CMD_INIT:	/* Initial client/server handshake */
	  status = CapInitialize(client_fd, program);
	  break;

	case CAP_CMD_VERSION:	/* Send version information */
	  status = CapVersion(client_fd, program, "1.0",
				  "Clock capture server - v1.0");
	  break;

	case CAP_CMD_INFO:
	  if (!channels_created)
	  {
	    /* Only create the channel data once */
	    status = create_channels(client_fd);
	    if (status < 0)
	    {
	      break;
	    }
	    channels_created = 1;
	  }

#ifdef SERVER_SIDE_RECORDING
	/* The server side recording returns incorrect time in
	 * the current version
	 */
	  status = CapInfo(client_fd, 1.0, 100.0, 10.0, 512 * 1024, 1);
#else
	  status = CapInfo(client_fd, 0.0, 0.0, 0.0, 512 * 1024, 1);
#endif

	  break;
	  
	case CAP_CMD_DATA:	/* Send frame data */
	  get_data(client_fd);
	  status = CapData(client_fd);
	  break;

#ifdef SERVER_SIDE_RECORDING
	/* The server side recording returns incorrect time in
	 * the current version
	 */
	case CAP_CMD_START_RECORD:	/* Start recording */
    {
      int size = 0;
      float rate = 0.0f, time = 0.0f;
	  rate = CapGetRequestedRecordRate(client_fd);
	  size = CapGetRequestedRecordSize(client_fd);

	  /* Convert rate in Hz to a timeout value in a timeval structure */
	  if (rate <   1.0) rate =   1.0;
	  if (rate > 100.0) rate = 100.0;

	  time = 1.0 / rate;
	  base_timeout.tv_sec  = time;
	  base_timeout.tv_usec = (time - base_timeout.tv_sec) * 1000000;

	  status = CapStartRecord(client_fd, rate, size);
	  if (status != -1)
	  {
	    recording = 1;
	  }
	  break;
    }

	case CAP_CMD_STOP_RECORD:		/* Stop recording */
	  status = CapStopRecord(client_fd);
	  recording = 0;
	  base_timeout.tv_sec  = 1;
	  base_timeout.tv_usec = 0;
	  break;
#endif /* server side recording */

	default:			/* Ignore unknown commands */
	  status = CapError(client_fd, CAP_SEV_ERROR, program,
			    "Unknown server command.");
	  break;
      }

      if (status < 0)
      {
	return -1;
      }
    }
  }

  /* return 0; */
}
Exemple #6
0
int main(int argc, char **argv)
{
  int opt;
#ifndef _WIN32
  char *cptr;
#endif
  int status;
  int client_fd = -1;


  /*
   * Grab a copy of the program name
   */
#ifdef _WIN32
  _splitpath (argv[0], NULL, NULL, program, NULL);
#else
  cptr = strrchr(argv[0], '/');
  if (cptr)
  {
    strcpy(program, (cptr + 1));
  }
  else
  {
    strcpy(program, argv[0]);
  }
#endif //WIN32

  /*
   * Parse the options
   */
#ifdef DEVEL
  while ((opt = getopt(argc, argv, "hdvDin:")) != -1)
#else /* DEVEL */
  while ((opt = getopt(argc, argv, "hdn:")) != -1)
#endif /* DEVEL */
  {
    switch (opt)
    {
      case 'h':
	show_usage++;
	break;

      case 'd':
	daemon_mode++;
	break;

      case 'D':
	debug_mode++;
	break;

      case 'i':
	inetd_mode++;
	break;

      case 'n':
	server_name = optarg;
	break;

      case 'v':
	verbose++;
	break;

      case GETOPTHUH:
	show_usage++;
    }
  }

  /*
   * Check for errors
   */
  if (daemon_mode && inetd_mode) show_usage++;
  if (optind < argc) show_usage++;

  if (show_usage)
  {
    fprintf(stderr, "Usage:\n");
#ifdef DEVEL
    fprintf(stderr, "    %s [-hdvDi] [-n name]\n", program);
#else /* DEVEL */
    fprintf(stderr, "    %s [-hd] [-n name]\n", program);
#endif /* DEVEL */
    fprintf(stderr, "\n");
    fprintf(stderr, "        -h        Print this help message\n");
    fprintf(stderr, "        -d        Run as a daemon in the background\n");
#ifdef DEVEL
    fprintf(stderr, "        -i        Run from inetd\n");
    fprintf(stderr, "        -D        Set the debug flag\n");
    fprintf(stderr, "        -v        Set the vebose flag\n");
#endif /* DEVEL */
    fprintf(stderr, "        -n name   Set the UNIX socket name to name\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Defaults:\n");
    fprintf(stderr, "    %s -n %s\n", program, program);
    fprintf(stderr, "\n");

    exit(1);
  }

  if (inetd_mode)
  {
    /*
     * The socket to the client is open on file descriptor 0.
     * Handle one client and then exit.
     */
    client_fd = 0;
  }

  if (daemon_mode)
  {
    /*
     * Convert this process into a standard unix type daemon process.
     * It will be running in the background with no controlling terminal
     * and using syslog to report error messages.
     */
    status = CapDaemonize();
    if (status < 0)
    {
      CapError(-1, CAP_SEV_FATAL, program, NULL);
      exit(1);
    }
  }

  if (inetd_mode)
  {
    /*
     * The socket to the client is already open on file descriptor 0.
     * Handle one client and then exit.
     */
    status = handle_client(client_fd);
    exit(status);
  }
  else
  {
    while (1)
    {
      /*
       * Set up the server socket and wait for a connection.
       */
      client_fd = CapServe(server_name);
      if (client_fd < 0)
      {
		CapError(-1, CAP_SEV_FATAL, program, NULL);
		exit(1);
      }
      
      /* Handle client requests */
      status = handle_client(client_fd);

      if (status < 0)
      {
		CapError(-1, CAP_SEV_FATAL, program, NULL);
      }

      /* Shutdown the client */
      closesocket(client_fd);
      client_fd = -1;

      /* Go back and wait for another connection request */
      continue;
    }
  }
  return 0;
}