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(); }
/** * @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; }
/// 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; }