Exemplo n.º 1
0
static void process_write_frontend(struct conn_context *ctx)
{
	int front_fd;
	char *buf;
	int data_len;
	int cpu_id;
	int ret;

	cpu_id = ctx->cpu_id;
	front_fd = ctx->fd;
	buf = ctx->buf;
	data_len = ctx->data_len;

	if (ctx->flags & PROXY_BACKEND_EVENT) {
		printf("Write to front end socket while back end socket enabled\n");
		goto free_back;
	}

	ret = write(front_fd, buf, data_len);
	if (ret < 0) {
		perror("Can't write front-end socket");
		goto free_back;
	}

	print_d("Write %d to front end socket %d\n", data_len, front_fd);

	wdata[cpu_id].trancnt++;

free_back:

	process_close(ctx);
	free_context(ctx);

	return;
}
Exemplo n.º 2
0
static void process_write_backend(struct conn_context *ctx)
{
	int ep_fd, end_fd;
	int events = ctx->events;
	char *buf;
	int data_len;
	int ret;

	ep_fd = ctx->ep_fd;
	end_fd = ctx->end_fd;
	buf = ctx->buf;
	data_len = ctx->data_len;

	print_d("Process write event[%02x] on back-end socket %d\n", events, end_fd);

	if (events & (EPOLLHUP | EPOLLERR)) {
		printf("process_write_backend() with events HUP or ERR 0x%x\n", events);
		goto free_back;
	}

	struct epoll_event evt;

	if (!(ctx->flags & PROXY_BACKEND_EVENT))
	{
		printf("Write to back-end socket while back end socket not enabled\n");
		goto free_back;
	}

	ret = write(end_fd, buf, data_len);
	if (ret < 0) {
		perror("process_write() can't write back end socket");
		goto free_back;
	}

	print_d("Write %d to back-end socket %d\n", ret, end_fd);

	ctx->handler = process_read_backend;
	ctx->flags |= PROXY_BACKEND_EVENT;

	evt.events = EPOLLIN | EPOLLHUP | EPOLLERR;
	evt.data.ptr = ctx;

	ret = epoll_ctl(ep_fd, EPOLL_CTL_MOD, end_fd, &evt);
	if (ret < 0) {
		perror("Unable to add client socket read event to epoll");
		goto free_back;
	}

	goto back;

free_back:

	process_close(ctx);
	free_context(ctx);

back:

	return;
}
Exemplo n.º 3
0
static void process_write(struct conn_context *client_ctx)
{
	int ep_fd, fd;
	int events = client_ctx->events;
	int cpu_id = client_ctx->cpu_id;
	int ret;
	struct epoll_event evt;

	ep_fd = client_ctx->ep_fd;
	fd = client_ctx->fd;

	print_d("Process write event[%02x]\n", events);

	if (events & (EPOLLHUP | EPOLLERR)) {
		printf("process_write() with events HUP or ERR\n");
		goto free_back;
	}

	ret = write(fd, http_response, http_response_len);
	if (ret < 0) {
		wdata[cpu_id].write_cnt++;
		perror("process_write() can't write client socket");
		goto free_back;
	}

	print_d("Write %d to socket %d\n", ret, fd);

	wdata[cpu_id].trancnt++;

	if (!enable_keepalive)
		goto free_back;

	client_ctx->handler = process_read;

	evt.events = EPOLLIN | EPOLLHUP | EPOLLERR;
	evt.data.ptr = client_ctx;

	ret = epoll_ctl(ep_fd, EPOLL_CTL_MOD, fd, &evt);
	if (ret < 0) {
		perror("Unable to add client socket read event to epoll");
		goto free_back;
	}

	goto back;

free_back:

	process_close(client_ctx);
	free_context(client_ctx);
back:

	return;
}
Exemplo n.º 4
0
static gboolean
process_and_relay_close (CockpitWebService *self,
                         CockpitSocket *socket,
                         const gchar *channel,
                         GBytes *payload)
{
  gboolean valid;

  valid = process_close (self, socket, channel);
  if (valid && !self->sent_done)
    cockpit_transport_send (self->transport, NULL, payload);

  return valid;
}
Exemplo n.º 5
0
//SIGINT and SIGTERM signal handler
static void quit(int sig)
{
	//let all the processes continue if stopped
	struct list_node *node = NULL;
	for (node=pf.members.first; node!= NULL; node=node->next) {
		struct process *p = (struct process*)(node->data);
		kill(p->pid, SIGCONT);
		process_close(p);
	}
	//free all the memory
	cleanup_process_family(&pf);
	//fix ^C little problem
	printf("\r");
	fflush(stdout);
	exit(0);
}
Exemplo n.º 6
0
/// Iterates the table, sending SIGTERM to stopped jobs and SIGKILL to those
/// that didn't die from SIGTERM after a while(exit_timeout is 0).
static void job_stop_timer_cb(uv_timer_t *handle)
{
  Job *job;
  uint64_t now = os_hrtime();

  for (size_t i = 0; i < MAX_RUNNING_JOBS; i++) {
    if ((job = table[i]) == NULL || !job->stopped_time) {
      continue;
    }

    uint64_t elapsed = now - job->stopped_time;

    if (!job->term_sent && elapsed >= TERM_TIMEOUT) {
      ILOG("Sending SIGTERM to job(id: %d)", job->id);
      uv_kill(job->pid, SIGTERM);
      job->term_sent = true;
    } else if (elapsed >= KILL_TIMEOUT) {
      ILOG("Sending SIGKILL to job(id: %d)", job->id);
      uv_kill(job->pid, SIGKILL);
      process_close(job);
    }
  }
}
Exemplo n.º 7
0
static void chld_handler(uv_signal_t *handle, int signum)
{
  int stat = 0;
  int pid;

  do {
    pid = waitpid(-1, &stat, WNOHANG);
  } while (pid < 0 && errno == EINTR);

  if (pid <= 0) {
    return;
  }

  if (WIFSTOPPED(stat) || WIFCONTINUED(stat)) {
    // Only care for processes that exited
    return;
  }

  Job *job = NULL;
  // find the job corresponding to the exited pid
  for (int i = 0; i < MAX_RUNNING_JOBS; i++) {
    if ((job = table[i]) != NULL && job->pid == pid) {
      if (WIFEXITED(stat)) {
        job->status = WEXITSTATUS(stat);
      } else if (WIFSIGNALED(stat)) {
        job->status = WTERMSIG(stat);
      }
      if (exiting) {
        // don't enqueue more events when exiting
        process_close(job);
      } else {
        event_push((Event) {.handler = job_exited, .data = job}, false);
      }
      break;
    }
  }
Exemplo n.º 8
0
void SFTP::process(void)
{
  const u_int msg_len = buffer_get_int (&iqueue);
	const u_int type = buffer_get_char(&iqueue);
	switch (type) {
	case SSH2_FXP_INIT:
		process_init();
		break;
	case SSH2_FXP_OPEN:
		process_open();
		break;
	case SSH2_FXP_CLOSE:
		process_close();
		break;
	case SSH2_FXP_READ:
		process_read();
		break;
	case SSH2_FXP_WRITE:
		process_write();
		break;
	case SSH2_FXP_LSTAT:
		process_lstat();
		break;
	case SSH2_FXP_FSTAT:
		process_fstat();
		break;
	case SSH2_FXP_SETSTAT:
		process_setstat();
		break;
	case SSH2_FXP_FSETSTAT:
		process_fsetstat();
		break;
	case SSH2_FXP_OPENDIR:
		process_opendir();
		break;
	case SSH2_FXP_READDIR:
		process_readdir();
		break;
	case SSH2_FXP_REMOVE:
		process_remove();
		break;
	case SSH2_FXP_MKDIR:
		process_mkdir();
		break;
	case SSH2_FXP_RMDIR:
		process_rmdir();
		break;
	case SSH2_FXP_REALPATH:
		process_realpath();
		break;
	case SSH2_FXP_STAT:
		process_stat();
		break;
	case SSH2_FXP_RENAME:
		process_rename();
		break;
	case SSH2_FXP_READLINK:
		process_readlink();
		break;
	case SSH2_FXP_SYMLINK:
		process_symlink();
		break;
	case SSH2_FXP_EXTENDED:
		process_extended();
		break;
	default:
		error("Unknown message %d", type);
		break;
	}

  /* discard the remaining bytes from the current packet */
	
  if (msg_len < buffer_len(&iqueue)) {
		error("iqueue grew unexpectedly");
		sftp_server_cleanup_exit(255);
	}
	u_int consumed = msg_len - buffer_len(&iqueue);
	if (msg_len < consumed) {
		error("msg_len %d < consumed %d", msg_len, consumed);
		sftp_server_cleanup_exit(255);
	}
	if (msg_len > consumed)
		buffer_consume(&iqueue, msg_len - consumed);
}
Exemplo n.º 9
0
// Opens a library and returns a handle
static struct MuLibrary*
sh_open (struct MuLoader* self, const char* path, MuError** err)
{
    ShLibrary* library = NULL;
    Process handle;
    array* tests = NULL;
    char* line = NULL;
    char* dot = NULL;
    unsigned int len;
    struct stat statbuf;

    /* As a sanity check, make sure the file is actually valid */
    if (stat(path, &statbuf) != 0)
    {
        MU_RAISE_GOTO(error, err, MU_ERROR_LOAD_LIBRARY, "%s: %s",
                      path, strerror(errno));
    }

    if (!S_ISREG(statbuf.st_mode))
    {
        MU_RAISE_GOTO(error, err, MU_ERROR_LOAD_LIBRARY, "%s: not a file",
                      path);
    }

    library = calloc(1, sizeof(ShLibrary));

    library->base.loader = self;
    library->path = strdup(path);
    library->name = strdup(basename_pure(path));

    dot = strrchr(library->name, '.');
    if (dot)
    {
        *dot = '\0';
    }

    mu_sh_exec(&handle, path, "mu_enum_test_functions >& ${MU_CMD_OUT}");

    while ((len = process_channel_read_line(&handle, 4, &line)))
    {
        ShTest* test = calloc(1, sizeof(ShTest));
        char* div1, *div2;

        line[len-1] = '\0';
        div1 = strchr(line, '_');
        div2 = strchr(div1+1, '_');

        if (div1 && div2)
        {
            test->base.loader = self;
            test->base.library = (MuLibrary*) library;
            test->function = strdup(line);

            *div1 = *div2 = '\0';

            test->suite = strdup(div1+1);
            test->name = strdup(div2+1);

            tests = array_append(tests, test);
        }

        free(line);
    }

    process_close(&handle);

    library->tests = (ShTest**) tests;

error:

    return (MuLibrary*) library;
}
Exemplo n.º 10
0
static void process_accept(struct conn_context * listen_ctx)
{
	int client_fd, listen_fd;
	int events = listen_ctx->events;
	struct epoll_event evt;

	struct context_pool *pool;
	struct conn_context *client_ctx;

	int cpu_id = listen_ctx->cpu_id;
	int ret = 0;
	int i;

	listen_fd = listen_ctx->fd;

	//TODO: What else should I do.
	if (events & (EPOLLHUP | EPOLLERR))
		return;

	for (i = 0; i < ACCEPT_PER_LISTEN_EVENT; i++) {
		int flags;

		client_fd = accept(listen_fd, NULL, NULL);
		if (client_fd < 0) {
			wdata[cpu_id].accept_cnt++;
			goto back;
		}

		flags = fcntl(client_fd, F_GETFL, 0);
		flags |= O_NONBLOCK;
		fcntl(client_fd, F_SETFL, flags);

		print_d("Accept socket %d from %d\n", client_fd, listen_fd);
	}

	pool = listen_ctx->pool;
	client_ctx = alloc_context(pool);
	assert(client_ctx);

	client_ctx->fd = client_fd;

	if (enable_proxy)
		client_ctx->handler = process_read_frontend;
	else
		client_ctx->handler = process_read;

	client_ctx->cpu_id = listen_ctx->cpu_id;
	client_ctx->ep_fd = listen_ctx->ep_fd;

	evt.events = EPOLLIN | EPOLLHUP | EPOLLERR;
	evt.data.ptr = client_ctx;

	ret = epoll_ctl(client_ctx->ep_fd, EPOLL_CTL_ADD, client_ctx->fd, &evt);
	if (ret < 0) {
		perror("Unable to add client socket read event to epoll");
		goto free_back;
	}

	client_ctx->fd_added = 1;

	goto back;

free_back:

	print_d("cpu[%d] close socket %d\n", cpu_id, client_ctx->fd);

	process_close(client_ctx);
	free_context(client_ctx);
back:
	return;
}
Exemplo n.º 11
0
static void process_read(struct conn_context *client_ctx)
{
	int ep_fd, fd;
	int events = client_ctx->events;
	struct epoll_event evt;
	int ret;
	char *buf = client_ctx->buf;
	int cpu_id = client_ctx->cpu_id;

	ep_fd = client_ctx->ep_fd;
	fd = client_ctx->fd;

	//FIXME: What else should I do.
	if (events & EPOLLHUP) {
		print_d("process_read() with events HUP\n");
		goto free_back;
	}
	if (events & EPOLLERR) {
		print_d("process_read() with events ERR\n");
		goto free_back;
	}

	print_d("Process read event[%02x] on socket %d\n", events, fd);

	ret = read(fd, buf, MAX_BUFSIZE);
	if (ret < 0) {
		wdata[cpu_id].read_cnt++;
		perror("process_read() can't read client socket");
		goto free_back;
	} else if (ret == 0) {
		goto free_back;
		print_d("Socket %d is closed\n", fd);
	}

	client_ctx->data_len = ret;

	print_d("Read %d from socket %d\n", ret, fd);

	client_ctx->handler = process_write;

	evt.events = EPOLLOUT | EPOLLHUP | EPOLLERR;
	evt.data.ptr = client_ctx;

	ret = epoll_ctl(ep_fd, EPOLL_CTL_MOD, fd, &evt);
	if (ret < 0) {
		perror("Unable to add client socket read event to epoll");
		goto free_back;
	}

	goto back;


free_back:

	print_d("cpu[%d] close socket %d\n", cpu_id, client_ctx->fd);

	process_close(client_ctx);
	free_context(client_ctx);

back:
	return;
}
Exemplo n.º 12
0
static void process_read_frontend(struct conn_context *ctx)
{
	int ep_fd, front_fd, end_fd;
	char *buf = ctx->buf;
	int events = ctx->events;
	struct epoll_event evt;
	struct sockaddr_in addr_in;
	int ret;
	int cpu_id = ctx->cpu_id;

	ep_fd = ctx->ep_fd;
	front_fd = ctx->fd;

	//FIXME: What else should I do.
	if (events & (EPOLLHUP | EPOLLERR)) {
		printf("process_read_frontend() with events HUP or ERR\n");
		goto free_back;
	}

	print_d("Process read event[%02x] on front-end socket %d\n", events, front_fd);

	ret = read(front_fd, buf, MAX_BUFSIZE);
	if (ret < 0)
	{
		wdata[cpu_id].read_cnt++;
		perror("process_read_frontend() can't read client socket");
		goto free_back;
	}

	ctx->data_len = ret;

	print_d("Read %d from front-end socket %d\n", ret, front_fd);

	//Remove interested read event for front-end socket
	evt.events = EPOLLHUP | EPOLLERR;
	evt.data.ptr = ctx;

	ret = epoll_ctl(ep_fd, EPOLL_CTL_MOD, front_fd, &evt);
	if (ret < 0) {
		perror("Unable to add client socket read event to epoll");
		goto free_back;
	}

	int flags;

	ret = socket(AF_INET, SOCK_STREAM, 0);
	if (ret < 0) {
		perror("Unable to create new socket for backend");
		goto free_back;
	}

	end_fd = ret;
	ctx->end_fd = end_fd;

	print_d("Create socket %d\n", ret);

	flags = fcntl(ret, F_GETFL, 0);
	flags |= O_NONBLOCK;
	fcntl(ret, F_SETFL, flags);

	struct linger ling = {1, 0};

	ret = setsockopt(end_fd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));
	if (ret < 0) {
		perror("Unable to set socket linger option");
		goto free_back;
	}

	select_backend(&addr_in);

	ret = connect(end_fd, (struct sockaddr *)&addr_in, sizeof(struct sockaddr));
	if (ret < 0) {
		if (errno != EINPROGRESS) {
			perror("Unable to connect to back end server");
			goto free_back;
		}
	}

	ctx->handler = process_write_backend;
	ctx->flags |= PROXY_BACKEND_EVENT;

	evt.events = EPOLLOUT | EPOLLHUP | EPOLLERR;
	evt.data.ptr = ctx;

	ret = epoll_ctl(ep_fd, EPOLL_CTL_ADD, end_fd, &evt);
	if (ret < 0) {
		perror("Unable to add client socket read event to epoll");
		goto free_back;
	}

	ctx->end_fd_added = 1;

	print_d("Add back-end socket %d to epoll\n", end_fd);

	goto back;

free_back:

	print_d("cpu[%d] close socket %d\n", cpu_id, ctx->fd);

	process_close(ctx);
	free_context(ctx);

back:
	return;
}
Exemplo n.º 13
0
static void process_read_backend(struct conn_context *ctx)
{
	int front_fd, end_fd, ep_fd;
	char *buf;
	int cpu_id;
	struct epoll_event evt;
	int ret;

	cpu_id = ctx->cpu_id;
	ep_fd = ctx->ep_fd;
	end_fd = ctx->end_fd;
	front_fd = ctx->fd;

	buf = ctx->buf;

	if (!(ctx->flags & PROXY_BACKEND_EVENT)) {
		printf("Process back end read while backend socket not enable\n");
		goto free_back;
	}

	ret = read(end_fd, buf, MAX_BUFSIZE);
	if (ret < 0) {
		wdata[cpu_id].read_cnt++;
		perror("process_read_backend() can't read client socket");
		goto free_back;
	}

	print_d("Read %d from back end socket %d\n", ret, end_fd);

	ctx->handler = process_write_frontend;
	ctx->flags &= ~PROXY_BACKEND_EVENT;
	ctx->data_len = ret;

	evt.events = EPOLLOUT | EPOLLHUP | EPOLLERR;
	evt.data.ptr = ctx;

	ret = epoll_ctl(ep_fd, EPOLL_CTL_MOD, front_fd, &evt);
	if (ret < 0) {
		perror("Unable to add client socket read event to epoll");
		goto free_back;
	}

	evt.events = EPOLLHUP | EPOLLERR;
	evt.data.ptr = ctx;

	//FIXME: Why monitor end fd?
	ret = epoll_ctl(ep_fd, EPOLL_CTL_MOD, end_fd, &evt);
	if (ret < 0)
	{
		perror("Unable to add client socket read event to epoll");
		goto free_back;
	}

	goto back;

free_back:

	process_close(ctx);
	free_context(ctx);

back:

	return;
}
static void
process(void)
{
	u_int msg_len;
	u_int buf_len;
	u_int consumed;
	u_int type;
	u_char *cp;

	buf_len = buffer_len(&iqueue);
	if (buf_len < 5)
		return;		/* Incomplete message. */
	cp = buffer_ptr(&iqueue);
	msg_len = get_u32(cp);
	if (msg_len > SFTP_MAX_MSG_LENGTH) {
		error("bad message from %s local user %s",
		    client_addr, pw->pw_name);
		sftp_server_cleanup_exit(11);
	}
	if (buf_len < msg_len + 4)
		return;
	buffer_consume(&iqueue, 4);
	buf_len -= 4;
	type = buffer_get_char(&iqueue);
	switch (type) {
	case SSH2_FXP_INIT:
		process_init();
		break;
	case SSH2_FXP_OPEN:
		process_open();
		break;
	case SSH2_FXP_CLOSE:
		process_close();
		break;
	case SSH2_FXP_READ:
		process_read();
		break;
	case SSH2_FXP_WRITE:
		process_write();
		break;
	case SSH2_FXP_LSTAT:
		process_lstat();
		break;
	case SSH2_FXP_FSTAT:
		process_fstat();
		break;
	case SSH2_FXP_SETSTAT:
		process_setstat();
		break;
	case SSH2_FXP_FSETSTAT:
		process_fsetstat();
		break;
	case SSH2_FXP_OPENDIR:
		process_opendir();
		break;
	case SSH2_FXP_READDIR:
		process_readdir();
		break;
	case SSH2_FXP_REMOVE:
		process_remove();
		break;
	case SSH2_FXP_MKDIR:
		process_mkdir();
		break;
	case SSH2_FXP_RMDIR:
		process_rmdir();
		break;
	case SSH2_FXP_REALPATH:
		process_realpath();
		break;
	case SSH2_FXP_STAT:
		process_stat();
		break;
	case SSH2_FXP_RENAME:
		process_rename();
		break;
	case SSH2_FXP_READLINK:
		process_readlink();
		break;
	case SSH2_FXP_SYMLINK:
		process_symlink();
		break;
	case SSH2_FXP_EXTENDED:
		process_extended();
		break;
	default:
		error("Unknown message %d", type);
		break;
	}
	/* discard the remaining bytes from the current packet */
	if (buf_len < buffer_len(&iqueue)) {
		error("iqueue grew unexpectedly");
		sftp_server_cleanup_exit(255);
	}
	consumed = buf_len - buffer_len(&iqueue);
	if (msg_len < consumed) {
		error("msg_len %d < consumed %d", msg_len, consumed);
		sftp_server_cleanup_exit(255);
	}
	if (msg_len > consumed)
		buffer_consume(&iqueue, msg_len - consumed);
}
Exemplo n.º 15
0
/// Tries to start a new job.
///
/// @param[out] status The job id if the job started successfully, 0 if the job
///             table is full, -1 if the program could not be executed.
/// @return The job pointer if the job started successfully, NULL otherwise
Job *job_start(JobOptions opts, int *status)
{
  int i;
  Job *job;

  // Search for a free slot in the table
  for (i = 0; i < MAX_RUNNING_JOBS; i++) {
    if (table[i] == NULL) {
      break;
    }
  }

  if (i == MAX_RUNNING_JOBS) {
    // No free slots
    shell_free_argv(opts.argv);
    *status = 0;
    return NULL;
  }

  job = xmalloc(sizeof(Job));
  // Initialize
  job->id = i + 1;
  *status = job->id;
  job->status = -1;
  job->refcount = 1;
  job->stopped_time = 0;
  job->term_sent = false;
  job->in = NULL;
  job->out = NULL;
  job->err = NULL;
  job->opts = opts;
  job->closed = false;

  process_init(job);

  if (opts.writable) {
    handle_set_job((uv_handle_t *)job->proc_stdin, job);
    job->refcount++;
  }

  if (opts.stdout_cb) {
    handle_set_job((uv_handle_t *)job->proc_stdout, job);
    job->refcount++;
  }

  if (opts.stderr_cb) {
    handle_set_job((uv_handle_t *)job->proc_stderr, job);
    job->refcount++;
  }

  // Spawn the job
  if (!process_spawn(job)) {
    if (opts.writable) {
      uv_close((uv_handle_t *)job->proc_stdin, close_cb);
    }
    if (opts.stdout_cb) {
      uv_close((uv_handle_t *)job->proc_stdout, close_cb);
    }
    if (opts.stderr_cb) {
      uv_close((uv_handle_t *)job->proc_stderr, close_cb);
    }
    process_close(job);
    event_poll(0);
    // Manually invoke the close_cb to free the job resources
    *status = -1;
    return NULL;
  }

  if (opts.writable) {
    job->in = wstream_new(opts.maxmem);
    wstream_set_stream(job->in, job->proc_stdin);
  }

  // Start the readable streams
  if (opts.stdout_cb) {
    job->out = rstream_new(read_cb, rbuffer_new(JOB_BUFFER_SIZE), job);
    rstream_set_stream(job->out, job->proc_stdout);
    rstream_start(job->out);
  }

  if (opts.stderr_cb) {
    job->err = rstream_new(read_cb, rbuffer_new(JOB_BUFFER_SIZE), job);
    rstream_set_stream(job->err, job->proc_stderr);
    rstream_start(job->err);
  }
  // Save the job to the table
  table[i] = job;

  return job;
}
Exemplo n.º 16
0
static void job_exited(Event event)
{
  Job *job = event.data;
  process_close(job);
}
Exemplo n.º 17
0
static gboolean
on_transport_control (CockpitTransport *transport,
                      const gchar *command,
                      const gchar *channel,
                      JsonObject *options,
                      GBytes *payload,
                      gpointer user_data)
{
  const gchar *problem = "protocol-error";
  CockpitWebService *self = user_data;
  CockpitSocket *socket = NULL;
  gboolean valid = FALSE;
  gboolean forward;

  if (!channel)
    {
      if (g_strcmp0 (command, "init") == 0)
        {
          problem = process_transport_init (self, transport, options);
          valid = (problem == NULL);
        }
      else if (!self->init_received)
        {
          g_message ("bridge did not send 'init' message first");
          valid = FALSE;
        }
      else if (g_strcmp0 (command, "authorize") == 0)
        {
          valid = process_transport_authorize (self, transport, options);
        }
      else
        {
          g_debug ("received a %s unknown control command", command);
          valid = TRUE;
        }
    }
  else
    {
      socket = cockpit_socket_lookup_by_channel (&self->sockets, channel);

      /* Usually all control messages with a channel are forwarded */
      forward = TRUE;

      if (g_strcmp0 (command, "close") == 0)
        {
          valid = process_close (self, socket, channel);
        }
      else
        {
          valid = TRUE;
        }

      if (forward)
        {
          /* Forward this message to the right websocket */
          if (socket && web_socket_connection_get_ready_state (socket->connection) == WEB_SOCKET_STATE_OPEN)
            {
              web_socket_connection_send (socket->connection, WEB_SOCKET_DATA_TEXT,
                                          self->control_prefix, payload);
            }
        }
    }

  if (!valid)
    {
      outbound_protocol_error (self, transport, problem);
    }

  return TRUE; /* handled */
}
static void
process(void)
{
	u_int msg_len;
	u_int buf_len;
	u_int consumed;
	u_int type;
	u_char *cp;

	buf_len = buffer_len(&iqueue);
	if (buf_len < 5)
		return;		/* Incomplete message. */
	cp = buffer_ptr(&iqueue);
	msg_len = GET_32BIT(cp);
	if (msg_len > 256 * 1024) {
		error("bad message ");
		exit(11);
	}
	if (buf_len < msg_len + 4)
		return;
	buffer_consume(&iqueue, 4);
	buf_len -= 4;
	type = buffer_get_char(&iqueue);
	switch (type) {
	case SSH2_FXP_INIT:
		process_init();
		break;
	case SSH2_FXP_OPEN:
		process_open();
		break;
	case SSH2_FXP_CLOSE:
		process_close();
		break;
	case SSH2_FXP_READ:
		process_read();
		break;
	case SSH2_FXP_WRITE:
		process_write();
		break;
	case SSH2_FXP_LSTAT:
		process_lstat();
		break;
	case SSH2_FXP_FSTAT:
		process_fstat();
		break;
	case SSH2_FXP_SETSTAT:
		process_setstat();
		break;
	case SSH2_FXP_FSETSTAT:
		process_fsetstat();
		break;
	case SSH2_FXP_OPENDIR:
		process_opendir();
		break;
	case SSH2_FXP_READDIR:
		process_readdir();
		break;
	case SSH2_FXP_REMOVE:
		process_remove();
		break;
	case SSH2_FXP_MKDIR:
		process_mkdir();
		break;
	case SSH2_FXP_RMDIR:
		process_rmdir();
		break;
	case SSH2_FXP_REALPATH:
		process_realpath();
		break;
	case SSH2_FXP_STAT:
		process_stat();
		break;
	case SSH2_FXP_RENAME:
		process_rename();
		break;
	case SSH2_FXP_READLINK:
		process_readlink();
		break;
	case SSH2_FXP_SYMLINK:
		process_symlink();
		break;
	case SSH2_FXP_EXTENDED:
		process_extended();
		break;
	default:
		error("Unknown message %d", type);
		break;
	}
	/* discard the remaining bytes from the current packet */
	if (buf_len < buffer_len(&iqueue))
		fatal("iqueue grows");
	consumed = buf_len - buffer_len(&iqueue);
	if (msg_len < consumed)
		fatal("msg_len %d < consumed %d", msg_len, consumed);
	if (msg_len > consumed)
		buffer_consume(&iqueue, msg_len - consumed);
}
Exemplo n.º 19
0
	/**
	 * Deletes this process manager.
	 */
	virtual ~Process() { StackTrace trace(__METHOD__, __FILE__, __LINE__);
		if (_handle) {
			process_close(_handle);
		}
	}