예제 #1
0
void env_universal_barrier()
{
    ASSERT_IS_MAIN_THREAD();
    message_t *msg;
    fd_set fds;

    if (!s_env_univeral_inited || is_dead())
        return;

    barrier_reply = 0;

    /*
      Create barrier request
    */
    msg= create_message(BARRIER, 0, 0);
    msg->count=1;
    env_universal_server.unsent.push(msg);

    /*
      Wait until barrier request has been sent
    */
    debug(3, L"Create barrier");
    while (1)
    {
        try_send_all(&env_universal_server);
        check_connection();

        if (env_universal_server.unsent.empty())
            break;

        if (env_universal_server.fd == -1)
        {
            reconnect();
            debug(2, L"barrier interrupted, exiting");
            return;
        }

        FD_ZERO(&fds);
        FD_SET(env_universal_server.fd, &fds);
        select(env_universal_server.fd+1, 0, &fds, 0, 0);
    }

    /*
      Wait for barrier reply
    */
    debug(3, L"Sent barrier request");
    while (!barrier_reply)
    {
        if (env_universal_server.fd == -1)
        {
            reconnect();
            debug(2, L"barrier interrupted, exiting (2)");
            return;
        }
        FD_ZERO(&fds);
        FD_SET(env_universal_server.fd, &fds);
        select(env_universal_server.fd+1, &fds, 0, 0, 0);
        env_universal_read_all();
    }
    debug(3, L"End barrier");
}
예제 #2
0
static int
give_write_copy (int requester_id, int request_id, int page_number) {
    int result;
    printf("%d: pre-lock\n", thisid);
    pthread_mutex_lock(&locks[page_number]);
    printf("%d: post-lock\n", thisid);
    int owner_id = get_owner(page_number);
    if (owner_id != thisid) {
        printf("%d: wtf\n", thisid);
        pthread_mutex_unlock(&locks[page_number]);
        return -E_INCORRECT_OWNER;
    }
    struct PageStatus *page_status = get_page_status(page_number);
    printf("%d: page_status->status: %d\n", thisid, page_status->status);
    switch (page_status->status) {
        case READABLE: {
            int i;
            int had_read_only;
            for (i = 0; i < nowners; i++) {
                if (i == requester_id) {
                    had_read_only = (page_status->status_by_owner[i] == READING);
                    continue;
                }
                if (i == thisid) {
                    if (page_status->status_by_owner[i] == READING) {
                        // Set local page to PROT_NONE at end of function
                        continue;
                    } else {
                        // This shouldn't happen - the local copy should become
                        //   readable as soon the page status becomes READABLE
                        result = -E_INCONSISTENT_STATE;
                        break;
                    }
                }
                if (page_status->status_by_owner[i] == READING) {
                    // Tell i that it is INVALIDATED
                    printf("%d: Telling %d that it is INVALIDATED\n", thisid, i);
                    struct Message m = create_message(SET_PERMISSION,
                            INVALIDATED, page_number);
                    printf("%d: sending message of type %c\n", thisid, m.msg_type);
                    result = send_to(i, &m);
                    if (result < 0) break;
                    page_status->status_by_owner[i] = INVALIDATED;
                }
            }
            page_status->status_by_owner[requester_id] = MODIFYING;
            page_status->modifying_owner = requester_id;
            page_status->status = MODIFIED;
            if (requester_id == thisid) {
                // Set local page to PROT_READ_WRITE
                printf("%d: Setting local page %d to PROT_READ_WRITE\n", thisid,
                        page_number);
                result = set_permissions((void *) get_pageaddr(page_number),
                        PGSIZE, PROT_READ_WRITE);
                if (result < 0) break;
            } else {
                if (had_read_only) {
                    // Tell requester_id that it has PROT_READ_WRITE access
                    struct Message m = create_message(SET_PERMISSION,
                            MODIFYING, page_number);
                    m.is_response = 1;
                    if (request_id == NO_RESPONSE) {
                        result = E_INCONSISTENT_STATE;
                        break;
                    }
                    m.index = request_id;
                    result = send_to(requester_id, &m);
                    if (result < 0) break;
                } else {
                    // Transfer page over network to requester_id and tell it
                    //   it has PROT_READ_WRITE access
                    struct Message m = create_message(SEND_PAGE, MODIFYING,
                            page_number);
                    memcpy((void *) m.page, (void *) get_pageaddr(page_number),
                            PGSIZE);
                    m.is_response = 1;
                    if (request_id == NO_RESPONSE) {
                        result = E_INCONSISTENT_STATE;
                        break;
                    }
                    m.index = request_id;
                    result = send_to(requester_id, &m);
                    if (result < 0) break;
                }
            }
            // Set local page to PROT_NONE
            result = set_permissions((void *) get_pageaddr(page_number),
                    PGSIZE, PROT_NONE);
            if (result < 0) break;
            page_status->status_by_owner[thisid] = INVALIDATED;
            result = 0;
            break;
        }
        case MODIFIED: {
            int modifier = page_status->modifying_owner;
            if (modifier == requester_id) {
                // The modifier should have read-write permissions, in which
                //   case a page not fault should not be thrown and this
                //   should never be called.
                result = -E_INCONSISTENT_STATE;
                break;
            }
            if (modifier == thisid) {
                // Set local page to PROT_NONE at end of method
            } else {
                // Tell modifier that it is INVALIDATED
                // Get modified page from modifier
                struct Message m = create_message(REQUEST_PAGE, INVALIDATED,
                        page_number);
                // Upon receiving the message we should map the page locally
                result = send_and_wait_for_response(modifier, &m);
                if (result < 0) break;
                // Local page should already be set PROT_READ
            }
            page_status->status_by_owner[modifier] = INVALIDATED;
            page_status->status_by_owner[requester_id] = MODIFYING;
            page_status->modifying_owner = requester_id;
            if (requester_id == thisid) {
                // Set local page to PROT_READ_WRITE
                result = set_permissions((void *) get_pageaddr(page_number),
                        PGSIZE, PROT_READ_WRITE);
                if (result < 0) break;
            } else {
                // Transfer page over network to requester_id and tell it it has
                //   PROT_READ_WRITE access
                struct Message m = create_message(SEND_PAGE, MODIFYING,
                        page_number);
                memcpy((void *) m.page, (void *) get_pageaddr(page_number),
                        PGSIZE);
                m.is_response = 1;
                if (request_id == NO_RESPONSE) {
                    result = E_INCONSISTENT_STATE;
                    break;
                }
                m.index = request_id;
                result = send_to(requester_id, &m);
                if (result < 0) break;
                // Set local page to PROT_NONE
                result = set_permissions((void *) get_pageaddr(page_number),
                        PGSIZE, PROT_NONE);
                if (result < 0) break;
            }
            result = 0;
            break;
        }
        default: {
            printf("Unhandled page status in give_write_copy.\n");
            exit(-E_UNHANDLED_PAGE_STATUS);
        }
    }
    pthread_mutex_unlock(&locks[page_number]);
    return result;
}
예제 #3
0
int
receive_message (int sender_id, struct Message *m) {
    printf("%d: received message from %d of type %c\n", thisid, sender_id,
            m->msg_type);
    int result;
    switch (m->msg_type) {
        case (REQUEST_PAGE): {
            pthread_mutex_lock(&locks[m->page_number]);
            void *pageaddr = (void *) get_pageaddr(m->page_number);
            result = set_permissions(pageaddr, PGSIZE, m->permissions);
            if (result < 0) break;
            struct Message response = create_message(SEND_PAGE, READING,
                    m->page_number);
            if (m->index == NO_RESPONSE) {
                result = E_INCONSISTENT_STATE;
                break;
            }
            response.index = m->index;
            response.is_response = 1;
            memcpy((void *) response.page, pageaddr, PGSIZE);
            result = send_to(sender_id, &response);
            pthread_mutex_lock(&locks[m->page_number]);
            break;
        }
        case (SEND_PAGE): {
            pthread_mutex_lock(&locks[m->page_number]);
            void *pageaddr = (void *) get_pageaddr(m->page_number);
            result = set_permissions(pageaddr, PGSIZE, PROT_READ_WRITE);
            if (result < 0) break;
            memcpy(pageaddr, (void *) m->page, PGSIZE);
            result = set_permissions(pageaddr, PGSIZE, m->permissions);
            if (m->is_response) {
                pthread_cond_signal(&waits[m->index]);
            }
            pthread_mutex_unlock(&locks[m->page_number]);
            break;
        }
        case (SET_PERMISSION): {
            pthread_mutex_lock(&locks[m->page_number]);
            void *pageaddr = (void *) get_pageaddr(m->page_number);
            result = set_permissions(pageaddr, PGSIZE, m->permissions);
            if (m->is_response) {
                pthread_cond_signal(&waits[m->index]);
            }
            pthread_mutex_unlock(&locks[m->page_number]);
            break;
        }
        case (REQUEST_PERMISSION): {
            if (m->permissions = READING) {
                give_read_copy(sender_id, m->index, m->page_number);
            } else if (m->permissions = MODIFYING) {
                give_write_copy(sender_id, m->index, m->page_number);
            } else {
                result = -E_UNHANDLED_PAGE_STATUS;
                break;
            }
            break;
        }
        default: {
            printf("Unhandled message type in give_read_copy: %c\n", m->msg_type);
            exit(-E_UNHANDLED_MESSAGE_TYPE);
        }
    }
    return result;
}
예제 #4
0
파일: scanner.c 프로젝트: ybakos/wayland
static void
start_element(void *data, const char *element_name, const char **atts)
{
	struct parse_context *ctx = data;
	struct interface *interface;
	struct message *message;
	struct arg *arg;
	struct enumeration *enumeration;
	struct entry *entry;
	struct description *description = NULL;
	const char *name = NULL;
	const char *type = NULL;
	const char *interface_name = NULL;
	const char *value = NULL;
	const char *summary = NULL;
	const char *since = NULL;
	const char *allow_null = NULL;
	const char *enumeration_name = NULL;
	const char *bitfield = NULL;
	int i, version = 0;

	ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
	for (i = 0; atts[i]; i += 2) {
		if (strcmp(atts[i], "name") == 0)
			name = atts[i + 1];
		if (strcmp(atts[i], "version") == 0) {
			version = strtouint(atts[i + 1]);
			if (version == -1)
				fail(&ctx->loc, "wrong version (%s)", atts[i + 1]);
		}
		if (strcmp(atts[i], "type") == 0)
			type = atts[i + 1];
		if (strcmp(atts[i], "value") == 0)
			value = atts[i + 1];
		if (strcmp(atts[i], "interface") == 0)
			interface_name = atts[i + 1];
		if (strcmp(atts[i], "summary") == 0)
			summary = atts[i + 1];
		if (strcmp(atts[i], "since") == 0)
			since = atts[i + 1];
		if (strcmp(atts[i], "allow-null") == 0)
			allow_null = atts[i + 1];
		if (strcmp(atts[i], "enum") == 0)
			enumeration_name = atts[i + 1];
		if (strcmp(atts[i], "bitfield") == 0)
			bitfield = atts[i + 1];
	}

	ctx->character_data_length = 0;
	if (strcmp(element_name, "protocol") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no protocol name given");

		ctx->protocol->name = xstrdup(name);
		ctx->protocol->uppercase_name = uppercase_dup(name);
	} else if (strcmp(element_name, "copyright") == 0) {

	} else if (strcmp(element_name, "interface") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no interface name given");

		if (version == 0)
			fail(&ctx->loc, "no interface version given");

		interface = create_interface(ctx->loc, name, version);
		ctx->interface = interface;
		wl_list_insert(ctx->protocol->interface_list.prev,
			       &interface->link);
	} else if (strcmp(element_name, "request") == 0 ||
		   strcmp(element_name, "event") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no request name given");

		message = create_message(ctx->loc, name);

		if (strcmp(element_name, "request") == 0)
			wl_list_insert(ctx->interface->request_list.prev,
				       &message->link);
		else
			wl_list_insert(ctx->interface->event_list.prev,
				       &message->link);

		if (type != NULL && strcmp(type, "destructor") == 0)
			message->destructor = 1;

		version = version_from_since(ctx, since);

		if (version < ctx->interface->since)
			warn(&ctx->loc, "since version not increasing\n");
		ctx->interface->since = version;
		message->since = version;

		if (strcmp(name, "destroy") == 0 && !message->destructor)
			fail(&ctx->loc, "destroy request should be destructor type");

		ctx->message = message;
	} else if (strcmp(element_name, "arg") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no argument name given");

		arg = create_arg(name);
		if (!set_arg_type(arg, type))
			fail(&ctx->loc, "unknown type (%s)", type);

		switch (arg->type) {
		case NEW_ID:
			ctx->message->new_id_count++;
			/* fallthrough */
		case OBJECT:
			if (interface_name)
				arg->interface_name = xstrdup(interface_name);
			break;
		default:
			if (interface_name != NULL)
				fail(&ctx->loc, "interface attribute not allowed for type %s", type);
			break;
		}

		if (allow_null) {
			if (strcmp(allow_null, "true") == 0)
				arg->nullable = 1;
			else if (strcmp(allow_null, "false") != 0)
				fail(&ctx->loc,
				     "invalid value for allow-null attribute (%s)",
				     allow_null);

			if (!is_nullable_type(arg))
				fail(&ctx->loc,
				     "allow-null is only valid for objects, strings, and arrays");
		}

		if (enumeration_name == NULL || strcmp(enumeration_name, "") == 0)
			arg->enumeration_name = NULL;
		else
			arg->enumeration_name = xstrdup(enumeration_name);

		if (summary)
			arg->summary = xstrdup(summary);

		wl_list_insert(ctx->message->arg_list.prev, &arg->link);
		ctx->message->arg_count++;
	} else if (strcmp(element_name, "enum") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no enum name given");

		enumeration = create_enumeration(name);

		if (bitfield == NULL || strcmp(bitfield, "false") == 0)
			enumeration->bitfield = false;
		else if (strcmp(bitfield, "true") == 0)
			enumeration->bitfield = true;
		else
			fail(&ctx->loc,
			     "invalid value (%s) for bitfield attribute (only true/false are accepted)",
			     bitfield);

		wl_list_insert(ctx->interface->enumeration_list.prev,
			       &enumeration->link);

		ctx->enumeration = enumeration;
	} else if (strcmp(element_name, "entry") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no entry name given");

		entry = create_entry(name, value);
		version = version_from_since(ctx, since);

		if (version < ctx->enumeration->since)
			warn(&ctx->loc, "since version not increasing\n");
		ctx->enumeration->since = version;
		entry->since = version;

		if (summary)
			entry->summary = xstrdup(summary);
		else
			entry->summary = NULL;
		wl_list_insert(ctx->enumeration->entry_list.prev,
			       &entry->link);
	} else if (strcmp(element_name, "description") == 0) {
		if (summary == NULL)
			fail(&ctx->loc, "description without summary");

		description = xzalloc(sizeof *description);
		description->summary = xstrdup(summary);

		if (ctx->message)
			ctx->message->description = description;
		else if (ctx->enumeration)
			ctx->enumeration->description = description;
		else if (ctx->interface)
			ctx->interface->description = description;
		else
			ctx->protocol->description = description;
		ctx->description = description;
	}
}
예제 #5
0
static int
give_read_copy (int requester_id, int request_id, int page_number) {
    int result;
    pthread_mutex_lock(&locks[page_number]);
    int owner_id = get_owner(page_number);
    if (owner_id != thisid) {
        pthread_mutex_unlock(&locks[page_number]);
        return -E_INCORRECT_OWNER;
    }
    struct PageStatus *page_status = get_page_status(page_number);
    switch (page_status->status) {
        case READABLE: {
            if (requester_id == thisid) {
                // Status should not be readable without local copy having
                //   read permissions; with these permissions, a page fault
                //   should not be thrown and this should never be called
                result = -E_INCONSISTENT_STATE;
                break;
            }
            // Transfer page over network to owner_id and tell it it
            //   has PROT_READ access
            struct Message m = create_message(SEND_PAGE, READING, page_number);
            memcpy((void *) m.page, (void *) get_pageaddr(page_number), PGSIZE);
            m.is_response = 1;
            if (request_id == NO_RESPONSE) {
                result = E_INCONSISTENT_STATE;
                break;
            }
            m.index = request_id;
            if ((result = send_to(owner_id, &m)) < 0) break;
            page_status->status_by_owner[requester_id] = READABLE;
            result = 0;
            break;
        }
        case MODIFIED: {
            int modifier = page_status->modifying_owner;
            if (modifier == requester_id) {
                // The modifier should have read-write permissions, in which
                //   case a page not fault should not be thrown and this
                //   should never be called.
                result = -E_INCONSISTENT_STATE;
                break;
            }
            if (modifier != thisid) {
                // Request page from modifier and tell it to set its
                //   permissions to PROT_READ
                struct Message m =
                    create_message(REQUEST_PAGE, READING, page_number);
                // Upon receiving the message we should map the page locally
                if ((result = send_and_wait_for_response(modifier, &m)) < 0) {
                    break;
                }
                // Local page should already be set PROT_READ
                page_status->status_by_owner[thisid] = READING;
            }
            page_status->status_by_owner[modifier] = READING;
            page_status->modifying_owner = NO_OWNER;
            page_status->status = READABLE;
            if (requester_id != thisid) {
                // Transfer page over network to requester_id and tell it it
                //   has PROT_READ access
                struct Message m =
                        create_message(SEND_PAGE, READING, page_number);
                memcpy((void *) m.page, (void *) get_pageaddr(page_number),
                        PGSIZE);
                m.is_response = 1;
                if (request_id == NO_RESPONSE) {
                    result = E_INCONSISTENT_STATE;
                    break;
                }
                m.index = request_id;
                result = send_to(requester_id, &m);
                if (result < 0) break;
                page_status->status_by_owner[requester_id] = READING;
            }
            result = 0;
            break;
        }
        default:
            printf("Unhandled page status in give_read_copy.\n");
            exit(-E_UNHANDLED_PAGE_STATUS);
    }
    pthread_mutex_unlock(&locks[page_number]);
    return result;
}
예제 #6
0
static void cb_adc_available(void)
{
    static uint8_t led_count = 0;
    static uint32_t timestamp_counter = 0;
    static uint32_t timestamp_last_frame = 0;
    static uint16_t missed_adc = 0;
    static uint16_t high_adc = 0;
    static uint16_t low_adc = 0xffff;

    uint16_t missed;
    uint16_t adc_value;
    uint16_t dxdt;
    uint32_t timestamp_ms;
    uint8_t send_adc_only = 0;

#if FPS_SEND_ADC_ONLY
    send_adc_only = 1;
#endif

    // Get ADC reading for light sensor
    sc_adc_channel_get(&adc_value, &timestamp_ms);

    // Check if we missed an ADC reading
    ++timestamp_counter;
    missed = timestamp_ms - timestamp_counter;
    timestamp_counter = timestamp_ms;

    missed_adc += missed;

    led_count += missed;
    if (led_count++ > 100) {
        led_count = 0;
        sc_led_toggle();
    }

    // Store lowest and highest values for debugging
    if (adc_value > high_adc) {
        high_adc = adc_value;
    }
    if (adc_value < low_adc) {
        low_adc = adc_value;
    }



    if (handle_adc(adc_value, timestamp_ms, &dxdt) || send_adc_only) {
        uint8_t buf[64];
        uint8_t len;

        if (send_adc_only) {
            len = create_adc_msg(buf, 64, adc_value, timestamp_ms);
        } else {
            len = create_message(buf, 64,
                                 timestamp_ms,
                                 timestamp_ms - timestamp_last_frame,
                                 missed_adc,
                                 low_adc,
                                 high_adc,
                                 dxdt);
        }
        sc_uart_send_msg(SC_UART_LAST, buf, len);
        high_adc = 0;
        low_adc = 0xffff;
        timestamp_last_frame = timestamp_ms;
        missed_adc = 0;
    }
}
예제 #7
0
/**
   Parse message msg
*/
static void parse_message( wchar_t *msg, 
						   connection_t *src )
{
//	debug( 3, L"parse_message( %ls );", msg );
	
	if( msg[0] == L'#' )
		return;
	
	if( match( msg, SET_STR ) || match( msg, SET_EXPORT_STR ))
	{
		wchar_t *name, *tmp;
		int exportv = match( msg, SET_EXPORT_STR );
		
		name = msg+(exportv?wcslen(SET_EXPORT_STR):wcslen(SET_STR));
		while( wcschr( L"\t ", *name ) )
			name++;
		
		tmp = wcschr( name, L':' );
		if( tmp )
		{
			wchar_t *key;
			wchar_t *val;
			
			key = (wchar_t *)malloc( sizeof( wchar_t)*(tmp-name+1));
			memcpy( key, name, sizeof( wchar_t)*(tmp-name));
			key[tmp-name]=0;
			
			val = tmp+1;
			val = unescape( val, 0 );
			
			env_universal_common_set( key, val, exportv );
			
			free( val );
			free( key );
		}
		else
		{
			debug( 1, PARSE_ERR, msg );
		}			
	}
	else if( match( msg, ERASE_STR ) )
	{
		wchar_t *name, *tmp;
		
		name = msg+wcslen(ERASE_STR);
		while( wcschr( L"\t ", *name ) )
			name++;
		
		tmp = name;
		while( iswalnum( *tmp ) || *tmp == L'_')
			tmp++;
		
		*tmp = 0;
		
		if( !wcslen( name ) )
		{
			debug( 1, PARSE_ERR, msg );
		}

		env_universal_common_remove( name );
		
		if( callback )
		{
			callback( ERASE, name, 0 );
		}
	}
	else if( match( msg, BARRIER_STR) )
	{
		message_t *msg = create_message( BARRIER_REPLY, 0, 0 );
		msg->count = 1;
        src->unsent->push(msg);
		try_send_all( src );
	}
	else if( match( msg, BARRIER_REPLY_STR ) )
	{
		if( callback )
		{
			callback( BARRIER_REPLY, 0, 0 );
		}
	}
	else
	{
		debug( 1, PARSE_ERR, msg );
	}		
}
예제 #8
0
파일: network.c 프로젝트: jkew/intheory
int __send_local(long ticket, unsigned short type, int slot, long value, unsigned short flags) {
  message *msg = create_message(my_id(), my_id(), ticket, type, slot, value, flags);
  log_message("send_local", msg);
  add_message(msg);
  return 1;
}
예제 #9
0
파일: bot.c 프로젝트: ct187/irc-bot
static int fill_recv_buf()
{
	int retval = 0;
	fd_set rfds;
	struct timeval tv;

	if (sockfd == -1) {
		debug("sockfd is -1");
		if (time(NULL) - last_activity > LAG_INTERVAL) {
			debug("LAG_INTERVAL has been reached");
			log_info("Trying to reconnect...");
			sockfd = connect_to_server();
			if (sockfd == -1) {
				log_info("Failed: %s", strerror(errno));
				return -1;
			} else
				log_info("Succeeded!");
		}
		else {
			debug("LAG_INTERVAL not reached; sleeping...");
			sleep(5);
			return -1;
		}
	}

	FD_ZERO(&rfds);
	FD_SET(sockfd, &rfds);
	tv.tv_sec = 0;
	tv.tv_usec = 500000;

	retval = select(sockfd + 1, &rfds, NULL, NULL, &tv);
	if (retval == -1) {
		log_err("Error waiting for socket: %s", strerror(errno));
		close(sockfd);
		sockfd = -1;
		return -1;
	} else if (!retval) {
		time_t curr;
		time(&curr);

		if (curr - last_activity > LAG_INTERVAL) {
			debug("appear to have lost connection");
			if (!waiting_for_ping) {
				struct irc_message *ping_msg;
				debug("sending ping..");
				ping_msg = create_message(NULL, "PING",
						":ping");
				send_msg(ping_msg);
				free_message(ping_msg);
				waiting_for_ping = 1;
			}
			else if (curr - last_activity >
					LAG_INTERVAL + PING_WAIT_TIME) {
				log_info("Lost connection...");
				waiting_for_ping = 0;
				close(sockfd);
				sockfd = -1;
				reset();
			}
		}
		return -1;
	}

	recv_buf_size = recv(sockfd, recv_buf, RECV_BUF_LENGTH - 1, 0);
	if (recv_buf_size == 0) {
		// connection has been terminated
		// likely due to ping timeout
		sockfd = -1;
		log_info("Connection terminated. Reconnecting..");
		return -1;
	} else if (recv_buf_size == -1) {
		log_err("Error receiving packets: %s",
				strerror(errno));
		kill_bot();
		return -1;
	}

	recv_buf[recv_buf_size] = '\0';
	recv_buf_pos = recv_buf;

	time(&last_activity);
	waiting_for_ping = 0;
	return 0;
}
예제 #10
0
void
mcview_do_search (mcview_t * view)
{
    off_t search_start = 0;
    gboolean isFound = FALSE;
    gboolean need_search_again = TRUE;

    Dlg_head *d = NULL;

    size_t match_len;

    if (verbose)
    {
        d = create_message (D_NORMAL, _("Search"), _("Searching %s"), view->last_search_string);
        tty_refresh ();
    }

    /*for avoid infinite search loop we need to increase or decrease start offset of search */

    if (view->search_start != 0)
    {
        if (!view->text_nroff_mode)
            search_start = view->search_start + (mcview_search_options.backwards ? -2 : 0);
        else
        {
            if (mcview_search_options.backwards)
            {
                mcview_nroff_t *nroff;
                nroff = mcview_nroff_seq_new_num (view, view->search_start);
                if (mcview_nroff_seq_prev (nroff) != -1)
                    search_start =
                        -(mcview__get_nroff_real_len (view, nroff->index - 1, 2) +
                          nroff->char_width + 1);
                else
                    search_start = -2;

                mcview_nroff_seq_free (&nroff);
            }
            else
            {
                search_start = mcview__get_nroff_real_len (view, view->search_start + 1, 2);
            }
            search_start += view->search_start;
        }
    }

    if (mcview_search_options.backwards && (int) search_start < 0)
        search_start = 0;

    /* Compute the percent steps */
    mcview_search_update_steps (view);
    view->update_activate = 0;

    tty_enable_interrupt_key ();

    do
    {
        off_t growbufsize;

        if (view->growbuf_in_use)
            growbufsize = mcview_growbuf_filesize (view);
        else
            growbufsize = view->search->original_len;

        if (mcview_find (view, search_start, &match_len))
        {
            mcview_search_show_result (view, &d, match_len);
            need_search_again = FALSE;
            isFound = TRUE;
            break;
        }

        if (view->search->error_str == NULL)
            break;

        search_start = growbufsize - view->search->original_len;
        if (search_start <= 0)
        {
            search_start = 0;
            break;
        }
    }
    while (mcview_may_still_grow (view));

    if (view->search_start != 0 && !isFound && need_search_again
        && !mcview_search_options.backwards)
    {
        int result;

        mcview_update (view);

        result =
            query_dialog (_("Search done"), _("Continue from beginning?"), D_NORMAL, 2, _("&Yes"),
                          _("&No"));

        if (result != 0)
            isFound = TRUE;
        else
            search_start = 0;
    }

    if (!isFound && view->search->error_str != NULL && mcview_find (view, search_start, &match_len))
    {
        mcview_search_show_result (view, &d, match_len);
        isFound = TRUE;
    }

    tty_disable_interrupt_key ();

    if (verbose)
    {
        dlg_run_done (d);
        destroy_dlg (d);
    }

    if (!isFound && view->search->error_str != NULL)
        message (D_NORMAL, _("Search"), "%s", view->search->error_str);

    view->dirty++;
    mcview_update (view);
}
예제 #11
0
파일: command.c 프로젝트: MacNarek/android
int start_command(JNIEnv *env, jclass clazz __attribute__((unused)), jstring jhandler, jstring jcmd) {
  char status;
  char *pos, *start, *end, *rpos, *wpos;
  const char *utf;
  jstring *utf_parent;
  handler *h;
  uint32_t msg_size; // big enought to check for uint16_t overflow
  int id;
  size_t arg_len, escapes;
  struct cmd_start_info *start_info;
  message *m;
  child_node *c;
  
  id = -1;
  m=NULL;
  c=NULL;
  
  if(!authenticated()) {
    LOGE("%s: not authenticated", __func__);
    return -1;
  }
  
  utf = (*env)->GetStringUTFChars(env, jhandler, NULL);
  utf_parent = &jhandler;
  
  if(!utf) {
    LOGE("%s: cannot get handler name", __func__);
    goto jni_error;
  }
  
  arg_len = (*env)->GetStringUTFLength(env, jhandler);
  
  if(!arg_len) {
    LOGE("%s: empty handler name", __func__);
    goto jni_error;
  }
  
  arg_len++; // test even the '\0'
  
  for(h=(handler *) handlers.list.head;h && strncmp(utf, h->name, arg_len);h=(handler *) h->next);
  
  if(!h) {
    LOGE("%s: handler \"%s\" not found", __func__, utf);
    goto exit;
  }
  
  (*env)->ReleaseStringUTFChars(env, jhandler, utf);
  utf = (*env)->GetStringUTFChars(env, jcmd, NULL);
  utf_parent = &jcmd;
  
  if(!utf) {
    LOGE("%s: cannot get command string", __func__);
    goto jni_error;
  }
  
  LOGD("%s: parsing \"%s\"", __func__, utf);
  
  msg_size = sizeof(struct cmd_start_info);
  m = create_message(get_sequence(&ctrl_seq, &ctrl_seq_lock),
                      msg_size, CTRL_ID);
  
  if(!m) {
    LOGE("%s: cannot create messages", __func__);
    goto exit;
  }
  
  start_info = (struct cmd_start_info *) m->data;
  start_info->cmd_action = CMD_START;
  start_info->hid = h->id;
  
  status = 0;
  arg_len = 0;
  escapes = 0;
  start = end = NULL;
  
  for(pos=(char *) utf;!(status & END_OF_STRING);pos++) {
    
    // string status parser
    switch (*pos) {
      case '"':
        if(status & ESCAPE_FOUND) {
          escapes++;
        } else if(status & (INSIDE_SINGLE_QUOTE)) {
          // copy it as a normal char
        } else if(status & INSIDE_DOUBLE_QUOTE) {
          status &= ~INSIDE_DOUBLE_QUOTE;
          end = pos;
        } else {
          status |= INSIDE_DOUBLE_QUOTE;
        }
        break;
      case '\'':
        if(status & ESCAPE_FOUND) {
          escapes++;
        } else if(status & INSIDE_DOUBLE_QUOTE) {
          // copy it as a normal char
        } else if(status & INSIDE_SINGLE_QUOTE) {
          status &= ~INSIDE_SINGLE_QUOTE;
          end = pos;
        } else {
          status |= INSIDE_SINGLE_QUOTE;
        }
        break;
      case '\\':
        if(status & ESCAPE_FOUND) {
          // copy it as normal char
          escapes++;
        } else {
          status |= ESCAPE_FOUND;
          continue;
        }
        break;
      case ' ': // if(isspace(*pos))
      case '\t':
        if(status & ESCAPE_FOUND) {
          escapes++;
        } else if(!status && start) {
          end=pos;
        }
        break;
      case '\0':
        status |= END_OF_STRING;
        end=pos;
        break;
      default:
        if(!start)
          start=pos;
    }
    
    status &= ~ESCAPE_FOUND;
    
    // copy the arg if found
    if(start && end) {
      
      LOGD("%s: argument found: start=%d, end=%d", __func__, (start-utf), (end-utf));
      arg_len=(end-start);
      arg_len-= escapes;
      
      msg_size+=arg_len + 1;
      
      if(msg_size > UINT16_MAX) {
        LOGW("%s: command too long: \"%s\"", __func__, utf);
        goto exit;
      }
      
      m->data = realloc(m->data, msg_size);
      
      if(!m->data) {
        LOGE("%s: realloc: %s", __func__, strerror(errno));
        goto exit;
      }
      
      wpos = m->data + m->head.size;
      for(rpos=start;rpos<end;rpos++) {
        if(status & ESCAPE_FOUND) {
          status &= ~ESCAPE_FOUND;
          if( *rpos != '\\' &&
              *rpos != '"' &&
              *rpos != '\'' &&
              *rpos != ' ' &&
              *rpos != '\t') {
            // unrecognized escape sequence, copy the backslash as it is.
            *wpos = '\\';
            wpos++;
          }
        } else if(*rpos == '\\') {
          status |= ESCAPE_FOUND;
          continue;
        }
        *wpos=*rpos;
        wpos++;
      }
      *(m->data + msg_size -1) = '\0';
      
      m->head.size = msg_size;
      
      start = end = NULL;
      escapes = 0;
    }
  }
  
  // create child
  
  c = create_child(m->head.seq);
  
  if(!c) {
    LOGE("%s: cannot craete child", __func__);
    goto exit;
  }
  
  c->handler = h;
  
  // add child to list
  
  pthread_mutex_lock(&(children.control.mutex));
  list_add(&(children.list), (node *) c);
  pthread_mutex_unlock(&(children.control.mutex));
  
  // send message to dSploitd
  
  pthread_mutex_lock(&write_lock);
  // OPTIMIZATION: use escapes to store return value for later check
  escapes = send_message(sockfd, m);
  pthread_mutex_unlock(&write_lock);
  
  if(escapes) {
    LOGE("%s: cannot send messages", __func__);
    goto exit;
  }
  
  // wait for CMD_STARTED or CMD_FAIL
  
  pthread_mutex_lock(&(children.control.mutex));
  
  while(c->seq && children.control.active)
    pthread_cond_wait(&(children.control.cond), &(children.control.mutex));
  
  if(c->id == CTRL_ID || c->seq) { // command failed
    list_del(&(children.list), (node *) c);
  } else {
    id = c->id;
  }
  
  c->pending = 0;
  
  pthread_mutex_unlock(&(children.control.mutex));
  
  pthread_cond_broadcast(&(children.control.cond));
  
  if(id != -1) {
    LOGI("%s: child #%d started", __func__, id);
  } else if(c->seq) {
    LOGW("%s: pending child cancelled", __func__);
  } else {
    LOGW("%s: cannot start command", __func__);
  }
  
  goto exit;
  
  jni_error:
  if((*env)->ExceptionCheck(env)) {
    (*env)->ExceptionDescribe(env);
    (*env)->ExceptionClear(env);
  }
  
  exit:
  if(c && id==-1) {
    pthread_mutex_lock(&(children.control.mutex));
    list_del(&(children.list), (node *) c);
    pthread_mutex_unlock(&(children.control.mutex));
    pthread_cond_broadcast(&(children.control.cond));
    free_child(c);
  }
  
  if(m)
    free_message(m);
  
  if(utf)
    (*env)->ReleaseStringUTFChars(env, *utf_parent, utf);
  
  return id;
}
예제 #12
0
파일: game_arbiter.cpp 프로젝트: ejrh/hex
void GameArbiter::process_command(Message *command) {
    switch (command->type) {
        case UnitMove: {
            auto cmd = dynamic_cast<UnitMoveMessage *>(command);
            int stack_id = cmd->data1;
            IntSet units = cmd->data2;
            Path& path = cmd->data3;
            int target_id = cmd->data4;

            UnitStack::pointer stack = game->stacks.get(stack_id);
            if (units.empty() || !stack->has_units(units) || path.empty()) {
                throw DataError() << "Invalid UnitMove message";
            }

            /* Check that the move is allowed; shorten it if necessary */
            Point end_pos = path.back();
            UnitStack::pointer end_stack = game->level.tiles[end_pos].stack;
            int end_stack_id = end_stack ? end_stack->id : 0;
            if (end_stack_id != target_id) {
                path.pop_back();
                target_id = 0;
            }

            MovementModel movement(game);
            UnitStack::pointer selected_stack = stack->copy_subset(units);
            unsigned int allowed_steps = movement.check_path(*selected_stack, path);
            bool truncated = allowed_steps < path.size();
            int attack_target_id = target_id;
            if (truncated)
                target_id = 0;
            path.resize(allowed_steps);

            if (!path.empty()) {
                end_pos = path.back();
                /* Generate updates. */
                Faction::pointer faction = stack->owner;
                bool move = units.size() == stack->units.size() && target_id == 0;
                bool split = units.size() < stack->units.size() && target_id == 0;
                bool merge = units.size() == stack->units.size() && target_id != 0;

                UnitStack::pointer target = game->stacks.find(target_id);

                if (move)
                    target_id = stack_id;
                if (split)
                    target_id = game->get_free_stack_id();

                // Send the moves
                for (auto iter = path.begin(); iter != path.end(); iter++) {
                    emit(create_message(MoveUnits, stack_id, units, *iter));
                }
                // If the stack is splitting to a new empty position, create a stack there
                if (split) {
                    emit(create_message(CreateStack, target_id, end_pos, faction->id));
                }
                emit(create_message(TransferUnits, stack_id, units, path, target_id));
                // If the whole stack merged with an existing one, destroy it
                if (merge) {
                    emit(create_message(DestroyStack, stack_id));
                }
            } else {
                end_pos = stack->position;
            }

            UnitStack::pointer attack_target = game->stacks.find(attack_target_id);
            bool attack = attack_target && (attack_target->owner != stack->owner);
            if (attack) {
                BOOST_LOG_TRIVIAL(debug) << "Attack!";
                Point target_point = attack_target->position;
                Point attacking_point = end_pos;
                Battle battle(game, target_point, attacking_point);
                battle.run();
                emit(create_message(DoBattle, end_stack_id, target_point, battle.moves));
            }
        } break;

        case FactionReady: {
            auto cmd = dynamic_cast<FactionReadyMessage *>(command);
            int faction_id = cmd->data1;
            bool ready = cmd->data2;
            if (game->mark_faction_ready(faction_id, ready)) {
                emit(create_message(FactionReady, faction_id, ready));
            }

            if (game->all_factions_ready()) {
                emit(create_message(TurnEnd));
                // process turn end

                spawn_units();
                game->turn_number++;
                emit(create_message(TurnBegin, game->turn_number));
            }
        } break;

        case Chat: {
            auto chat_msg = dynamic_cast<ChatMessage *>(command);
            emit(create_message(Chat, chat_msg->data));
        } break;

        case SetLevelData:
        case CreateStructure:
        case DestroyStructure: {
            emit(command->shared_from_this());
        } break;

        default:
            break;
    }
}
예제 #13
0
int start_command(JNIEnv *env, jclass clazz __attribute__((unused)), jstring jhandler, jstring jcmd, jobjectArray jenv) {
  const char *utf;
  handler *h;
  int id;
  struct cmd_start_info *start_info;
  message *m;
  child_node *c;
  
  id = -1;
  m=NULL;
  c=NULL;
  utf=NULL;
  
  if(!authenticated()) {
    LOGE("%s: not authenticated", __func__);
    return -1;
  }
  
  if(!jhandler) {
    LOGE("%s: handler cannot be null", __func__);
    return -1;
  }
  
  utf = (*env)->GetStringUTFChars(env, jhandler, NULL);
  
  if(!utf) {
    LOGE("%s: cannot get handler name", __func__);
    goto jni_error;
  }
  
  h = get_handler_by_name(utf);
  
  if(!h) {
    LOGE("%s: handler \"%s\" not found", __func__, utf);
    goto exit;
  }
  
  (*env)->ReleaseStringUTFChars(env, jhandler, utf);
  utf=NULL;
  
  m = create_message(get_sequence(&ctrl_seq, &ctrl_seq_lock),
                      sizeof(struct cmd_start_info), CTRL_ID);
  
  if(!m) {
    LOGE("%s: cannot create messages", __func__);
    goto exit;
  }
  
  start_info = (struct cmd_start_info *) m->data;
  start_info->cmd_action = CMD_START;
  start_info->hid = h->id;
  
  if(jcmd && parse_cmd(env, h, jcmd, m)) {
    LOGE("%s: cannot parse command", __func__);
    goto exit;
  }
  
  if(jenv && parse_env(env, jenv, m)) {
    LOGE("%s: cannot parse environment", __func__);
    goto exit;
  }
  
  // create child
  
  c = create_child(m->head.seq);
  
  if(!c) {
    LOGE("%s: cannot craete child", __func__);
    goto exit;
  }
  
  c->handler = h;
  
  // add child to list
  
  pthread_mutex_lock(&(children.control.mutex));
  list_add(&(children.list), (node *) c);
  pthread_mutex_unlock(&(children.control.mutex));
  
  // send message to cSploitd
  
  pthread_mutex_lock(&write_lock);
  // OPTIMIZATION: use id to store return value for later check
  id = send_message(sockfd, m);
  pthread_mutex_unlock(&write_lock);
  
  if(id) {
    LOGE("%s: cannot send messages", __func__);
    // mark it as failed
    c->id = CTRL_ID;
    c->seq = 0;
  }
  
  id=-1;
  
  // wait for CMD_STARTED or CMD_FAIL
  
  pthread_mutex_lock(&(children.control.mutex));
  
  while(c->seq && children.control.active)
    pthread_cond_wait(&(children.control.cond), &(children.control.mutex));
  
  if(c->id == CTRL_ID || c->seq) { // command failed
    list_del(&(children.list), (node *) c);
  } else {
    id = c->id;
  }
  
  c->pending = 0;
  
  pthread_mutex_unlock(&(children.control.mutex));
  
  pthread_cond_broadcast(&(children.control.cond));
  
  if(id != -1) {
    LOGI("%s: child #%d started", __func__, id);
  } else if(c->seq) {
    LOGW("%s: pending child cancelled", __func__);
  } else {
    LOGW("%s: cannot start command", __func__);
  }
  
  goto exit;
  
  jni_error:
  if((*env)->ExceptionCheck(env)) {
    (*env)->ExceptionDescribe(env);
    (*env)->ExceptionClear(env);
  }
  
  exit:
  
  if(m)
    free_message(m);
  
  if(utf)
    (*env)->ReleaseStringUTFChars(env, jhandler, utf);
  
  return id;
}
예제 #14
0
void SocketSPI::send_message(const int code, wstring data) {
    char * msg = create_message(code, encoder.decode(data).c_str());
    send(this->client_sfd, (void *) msg, strlen(msg), 0);
}