Exemplo n.º 1
0
void t01_server_one(){
  INIT_LOCAL();

  o=onion_new(O_ONE);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set(1,0.1,1,0);
  onion_free(o);

  o=onion_new(O_ONE_LOOP);
  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set(1,0.1,1,1);
  onion_free(o);

  o=onion_new(O_ONE_LOOP);

  // change poller queue size
  onion_poller *p=onion_get_poller(o);
  onion_poller_set_queue_size_per_thread(p, 1);

  onion_set_root_handler(o,onion_handler_new((void*)process_request,NULL,NULL));
  do_petition_set(1,0.001,100,1);
  onion_free(o);

  END_LOCAL();
}
Exemplo n.º 2
0
/**
 * @short Launches one handler for the given request
 * @ingroup request
 *
 * Once the request is ready, launch it.
 *
 * @returns The connection status: if it should be closed, error codes...
 */
onion_connection_status onion_request_process(onion_request *req){
	onion_response *res=onion_response_new(req);
	if (!req->path){
		onion_request_polish(req);
	}
	// Call the main handler.
	onion_connection_status hs=onion_handler_handle(req->connection.listen_point->server->root_handler, req, res);

	if (hs==OCS_INTERNAL_ERROR ||
		hs==OCS_NOT_IMPLEMENTED ||
		hs==OCS_NOT_PROCESSED){
		if (hs==OCS_INTERNAL_ERROR)
			req->flags|=OR_INTERNAL_ERROR;
		if (hs==OCS_NOT_IMPLEMENTED)
			req->flags|=OR_NOT_IMPLEMENTED;
		if (hs==OCS_NOT_PROCESSED)
			req->flags|=OR_NOT_FOUND;
		if (hs==OCS_FORBIDDEN)
			req->flags|=OR_FORBIDDEN;

		hs=onion_handler_handle(req->connection.listen_point->server->internal_error_handler, req, res);
	}

	if (hs==OCS_YIELD){
		// Remove from the poller, and yield thread to poller. From now on it will be processed somewhere else (longpoll thread).
		onion_poller *poller=onion_get_poller(req->connection.listen_point->server);
		onion_poller_slot *slot=onion_poller_get(poller, req->connection.fd);
		onion_poller_slot_set_shutdown(slot, NULL, NULL);

		return hs;
	}
	int rs=onion_response_free(res);
	if (hs>=0 && rs==OCS_KEEP_ALIVE) // if keep alive, reset struct to get the new petition.
		onion_request_clean(req);
	return hs>0 ? rs : hs;
}
Exemplo n.º 3
0
/// Creates a new oterm
process *oterm_new(oterm_data *data, oterm_session *session, const char *username, char impersonate){
	process *oterm=malloc(sizeof(process));

	const char *command_name;
	int i;
	for (i=strlen(data->exec_command);i>=0;i--)
		if (data->exec_command[i]=='/')
			break;
	command_name=&data->exec_command[i+1];

  
  /// Get the UUID, linux nicely gives it.
  {
    int fd=open("/proc/sys/kernel/random/uuid", O_RDONLY);
    if (fd>=0){
      int r=read(fd, oterm->uuid, sizeof(oterm->uuid)-1);
      close(fd);
      if (r!=sizeof(oterm->uuid)-1) // So we will use the pseudo random generator.
        fd=-1;
    }
    if (fd<0){
      const char random_chars[]="0123456789abcdef-";
      for (i=0;i<sizeof(oterm->uuid)-1;i++){
        oterm->uuid[i]=random_chars[rand()%sizeof(random_chars)];
      }
    }
    oterm->uuid[sizeof(oterm->uuid)-1]=0;
    ONION_DEBUG("New UUID for this terminal is %s", oterm->uuid);
  }
  
	oterm->buffer=calloc(1, BUFFER_SIZE);
	oterm->buffer_pos=0;
	pthread_mutex_init(&oterm->mutex, NULL);
	pthread_cond_init(&oterm->dataReady, NULL);
	
	ONION_DEBUG("Creating new terminal, exec %s (%s)", data->exec_command, command_name);
	
	oterm->pid=forkpty(&oterm->fd, NULL, NULL, NULL);
	if ( oterm->pid== 0 ){ // on child
		// Copy env vars.
		char **envs=malloc(sizeof(char*)*(1+ONION_CLEARENV_COUNT+ONION_EXTRAENV_COUNT));
		int i,j=0;
		for (i=0;i<ONION_CLEARENV_COUNT;i++){
			const char *env=onion_clearenvs[i];
			const char *val=getenv(env);
			if (val){
				int l=strlen(env)+1+strlen(val)+1;
				envs[j]=malloc(l);
				sprintf(envs[j],"%s=%s",env,val);
				j++;
			}
		}
		for (i=0;i<ONION_EXTRAENV_COUNT;i++){
			envs[j]=strdup(onion_extraenvs[i]);
			j++;
		}
		envs[j]=NULL;

		// Change personality to that user
		if (impersonate){
			struct passwd *pw;
			pw=getpwnam(username);
			int error;
			if (!pw){
				ONION_ERROR("Cant find user to drop priviledges: %s", username);
				exit(1);
			}
			else{
				error=setgid(pw->pw_gid);
				error|=setuid(pw->pw_uid);
			}
			if (error){
				ONION_ERROR("Cant set the uid/gid for user %s", username);
				exit(1);
			}
		}
		for (i=3;i<256;i++) // Force close file descriptors. Dirty but it works.
			close(i);

		int ok=execle(data->exec_command, command_name, NULL, envs);
		fprintf(stderr,"%s:%d Could not exec shell: %d\n",__FILE__,__LINE__,ok);
		perror("");
		exit(1);
	}
	oterm->title=strdup(data->exec_command);
	ONION_DEBUG("Default title is %s", oterm->title);
	oterm->next=NULL;
	// I set myself at end
	pthread_mutex_lock( &session->head_mutex );
	if (!session->head)
		session->head=oterm;
	else{
		process *next=session->head;
		while (next->next) next=next->next;
		next->next=oterm;
	}
  onion_poller_slot *sl=onion_poller_slot_new(oterm->fd, (void*)oterm_data_ready, oterm);
  onion_poller_add(onion_get_poller(data->onion), sl);
  pthread_mutex_unlock( &session->head_mutex );
	
  onion_dict_add(data->processes, oterm->uuid, oterm, 0);
	
	return oterm;
}