Пример #1
0
int
main (int argc, char **argv)
{
  int s;
  struct sockaddr_un remote;
  char *socket_path = NULL;
  char *hfile;
  int arglen = argc - 1;
  int c;
  static struct option long_options[] = {
    { "server-socket", required_argument, NULL, 's' },
    { "version", no_argument, NULL, 'v' },
    { "help", no_argument, NULL, 'h' },
    { 0, 0, 0, 0 }
  };

  while ((c = getopt_long (argc, argv, "s:hv", long_options, NULL)) != -1)
    {
      switch (c)
        {
        case 's':
          socket_path = optarg;
          arglen--;
          break;

        case 'h':
          usage (argv[0]);
          exit (EXIT_SUCCESS);
          break;

        case 'v':
          printf ("bitU v" VERSION " \n");
          exit (EXIT_SUCCESS);
          break;

        default:
          fprintf (stderr, "Try `%s --help' for more information\n", argv[0]);
          exit (EXIT_FAILURE);
          break;
        }
    }

  if (socket_path == NULL)
    socket_path = SOCKET_PATH;

  if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) == -1)
    {
      perror ("socket");
      exit (EXIT_FAILURE);
    }

  remote.sun_family = AF_UNIX;
  strcpy (remote.sun_path, socket_path);
  if (connect (s, (struct sockaddr *) &remote,
               sizeof (struct sockaddr_un)) == -1)
    {
      fprintf (stderr, "Error when connecting: %s\n", strerror (errno));
      return EXIT_FAILURE;
    }

  /* Interactive shell only appears when no param is received */
  if (arglen > 0)
    {
      /* Collecting the command and its parameters to exec them on the
       * server and then feed back the user. */
      char *cmd = NULL, *cmdline = NULL;
      char *param = NULL, *tmp = NULL;
      int cmd_len, full_len;
      int allocated = 0;
      int bufsize = 128;
      int start_pos = argc - arglen;
      int plen, i;

      cmd = argv[start_pos];
      cmd_len = strlen (cmd);
      full_len = cmd_len;

      allocated = bufsize;
      cmdline = malloc (bufsize);
      memcpy (cmdline, cmd, cmd_len);

      cmdline[cmd_len] = ' ';
      full_len++;

      /* Yes, we have params to collect. */
      for (i = 1; i < arglen; i++)
        {
          /* The `_escape_param()' also returns the size of the
           * string. */
          param = _escape_param (argv[start_pos + i], &plen);

          /* Allocatting more space if it's needed */
          if ((full_len + plen) > allocated)
            {
              while (allocated < full_len + plen)
                allocated += bufsize;
              if ((tmp = realloc (cmdline, allocated)) == NULL)
                {
                  free (cmdline);
                  close (s);
                  exit (EXIT_FAILURE);
                }
              else
                cmdline = tmp;
            }

          /* Copying parameter to the command line string */
          memcpy (cmdline + full_len, param, plen);

          /* Adding the space after param */
          full_len += plen;
          cmdline[full_len] = ' ';
          full_len++;

          free (param);
        }
      cmdline[--full_len] = '\0';

      /* Sending the command to the server */
      if (send (s, cmdline, full_len, 0) == -1)
        {
          perror ("send");
          exit (EXIT_FAILURE);
        }
      free (cmdline);

      /* Receiving the answer from the server. */
      bitu_shell_recv (s, -1);
      goto finalize;
    }

  printf ("bitU v" VERSION " interactive shell connected!\n");
  printf ("Type `help' for more information\n");

  /* Initializing history library and registering a callback to write
   * back to history file when program finishes. */
  hfile = _get_history_file ();
  using_history ();
  read_history (hfile);
  atexit (_save_history_file);
  free (hfile);

  while (1)
    {
      char *line;
      size_t llen;

      /* Main readline call.*/
      line = readline (PS1);

      if (line == NULL)
        {
          _close_connection (s);
          printf ("\n");
          break;
        }
      llen = strlen (line);

      /* Handling empty lines */
      if (llen == 0)
        continue;

      /* Saving readline history */
      add_history (line);

      /* Sending command to the server. */
      if (send (s, line, llen, 0) == -1)
        {
          fprintf (stderr, "Error in send(): %s\n",
                   strerror (errno));
          goto finalize;
        }

      /* The only hardcoded command is this. It was actually sent to
       * the server but we should not wait for an answer in this
       * case. It is easier to catch it here, to finish the program
       * then implementing a full local command framework again. */
      if (strcmp (line, "exit") == 0)
        {
          free (line);
          goto finalize;
        }
      free (line);

      /* Receiving the answer from the server */
      bitu_shell_recv (s, -1);
    }

 finalize:
  close (s);
  return 0;
}
Пример #2
0
// check if a command needs processing
static void _poll_command(protocolState_t *ps)
{
	if (ps->stopped) return;

	threadIPC_t *ipc = ps->ipc;

	pthread_mutex_lock(&ipc->lock);

	switch (ipc->command) {

	case COMMAND_SHUTDOWN:
	    DBGPRINTF("omamqp1: Protocol thread processing shutdown command\n");
	    ps->stopped = true;
	    _close_connection(ps);
	    // wait for the shutdown to complete before ack'ing this command
	    break;

	case COMMAND_IS_READY:
	    DBGPRINTF("omamqp1: Protocol thread processing ready query command\n");
	    ipc->result = _is_ready(ps->sender)
	                  ? RS_RET_OK
	                  : RS_RET_SUSPENDED;
	    ipc->command = COMMAND_DONE;
	    pthread_cond_signal(&ipc->condition);
	    break;

	case COMMAND_SEND:
	    if (ps->delivery) break;  // currently processing this command
	    DBGPRINTF("omamqp1: Protocol thread processing send message command\n");
	    if (!_is_ready(ps->sender)) {
	        ipc->result = RS_RET_SUSPENDED;
	        ipc->command = COMMAND_DONE;
	        pthread_cond_signal(&ipc->condition);
	        break;
	    }

	    // send the message
	    ++ps->tag;
	    ps->delivery = pn_delivery(ps->sender,
	                               pn_dtag((const char *)&ps->tag, sizeof(ps->tag)));
	    pn_message_t *message = ipc->message;
	    assert(message);

	    int rc = 0;
	    size_t len = ps->buffer_size;
	    do {
	        rc = pn_message_encode(message, ps->encode_buffer, &len);
	        if (rc == PN_OVERFLOW) {
	            _grow_buffer(ps);
	            len = ps->buffer_size;
	        }
	    } while (rc == PN_OVERFLOW);

	    pn_link_send(ps->sender, ps->encode_buffer, len);
	    pn_link_advance(ps->sender);
	    ++ps->msgs_sent;
	    // command completes when remote updates the delivery (see PN_DELIVERY)
	    break;

	case COMMAND_DONE:
	    break;
	}

	pthread_mutex_unlock(&ipc->lock);
}