void print_backend_config(FILE *file, const struct Backend *backend) { char address[256]; fprintf(file, "\t%s %s\n", backend->name, display_address(backend->address, address, sizeof(address))); }
int accept_listener_source_address(struct Listener *listener, char *source) { if (listener->source_address != NULL) { err("Duplicate source address: %s", source); return 0; } listener->source_address = new_address(source); if (listener->source_address == NULL) { err("Unable to parse source address: %s", source); return 0; } if (!address_is_sockaddr(listener->source_address)) { err("Only source socket addresses permitted"); free(listener->source_address); listener->source_address = NULL; return 0; } if (address_port(listener->source_address) != 0) { char address[256]; err("Source address on listener %s set to non zero port, " "this prevents multiple connection to each backend server.", display_address(listener->address, address, sizeof(address))); } return 1; }
void listeners_reload(struct Listener_head *existing_listeners, struct Listener_head *new_listeners, const struct Table_head *tables, struct ev_loop *loop) { struct Listener *iter_existing = SLIST_FIRST(existing_listeners); struct Listener *iter_new = SLIST_FIRST(new_listeners); while (iter_existing != NULL || iter_new != NULL) { int compare_result; char address[ADDRESS_BUFFER_SIZE]; if (iter_existing == NULL) compare_result = 1; else if (iter_new == NULL) compare_result = -1; else compare_result = address_compare(iter_existing->address, iter_new->address); if (compare_result > 0) { struct Listener *new_listener = iter_new; iter_new = SLIST_NEXT(iter_new, entries); notice("Listener %s added.", display_address(new_listener->address, address, sizeof(address))); SLIST_REMOVE(new_listeners, new_listener, Listener, entries); add_listener(existing_listeners, new_listener); init_listener(new_listener, tables, loop); /* -1 for removing from new_listeners */ listener_ref_put(new_listener); } else if (compare_result == 0) { notice ("Listener %s updated.", display_address(iter_existing->address, address, sizeof(address))); listener_update(iter_existing, iter_new, tables); iter_existing = SLIST_NEXT(iter_existing, entries); iter_new = SLIST_NEXT(iter_new, entries); } else { struct Listener *removed_listener = iter_existing; iter_existing = SLIST_NEXT(iter_existing, entries); notice("Listener %s removed.", display_address(removed_listener->address, address, sizeof(address))); SLIST_REMOVE(existing_listeners, removed_listener, Listener, entries); close_listener(loop, removed_listener); /* -1 for removing from existing_listeners */ listener_ref_put(removed_listener); } } }
void print_listener_config(FILE *file, const struct Listener *listener) { char address[256]; fprintf(file, "listener %s {\n", display_address(listener->address, address, sizeof(address))); fprintf(file, "\tprotocol %s\n", listener->protocol->name); if (listener->table_name) fprintf(file, "\ttable %s\n", listener->table_name); if (listener->fallback_address) fprintf(file, "\tfallback %s\n", display_address(listener->fallback_address, address, sizeof(address))); fprintf(file, "}\n\n"); }
int main() { /* using volatile variables so we can example core dumps */ struct Address *addr; char buffer[255]; int port; for (volatile unsigned int i = 0; i < sizeof(good) / sizeof(struct Test); i++) { addr = new_address(good[i].input); assert(addr != NULL); if (good[i].expected_type & TYPE_HOSTNAME && !address_is_hostname(addr)) { fprintf(stderr, "Expected %s to be a hostname\n", buffer); return 1; } if (good[i].expected_type & TYPE_SOCKADDR && !address_is_sockaddr(addr)) { fprintf(stderr, "Expected %s to be a sockaddr\n", buffer); return 1; } if (good[i].expected_type & TYPE_WILDCARD && !address_is_wildcard(addr)) { fprintf(stderr, "Expected %s to be a wildcard\n", buffer); return 1; } display_address(addr, buffer, sizeof(buffer)); if (strcmp(buffer, good[i].output)) { fprintf(stderr, "display_address(%p) returned \"%s\", expected \"%s\"\n", addr, buffer, good[i].output); return 1; } port = address_port(addr); if (good[i].port != port) { fprintf(stderr, "address_port(%p) return %d, expected %d\n", addr, port, good[i].port); return 1; } free(addr); } for (volatile unsigned int i = 0; i < sizeof(bad) / sizeof(const char *); i++) { addr = new_address(bad[i]); if (addr != NULL) { fprintf(stderr, "Accepted bad hostname \"%s\"\n", bad[i]); return 1; } } return 0; }
static void query_cb(struct Address *result, void *data) { int *query_count = (int *)data; char ip_buf[128]; if (result != NULL && address_is_sockaddr(result) && display_address(result, ip_buf, sizeof(ip_buf))) { fprintf(stderr, "query resolved to %s\n", ip_buf); query_count++; } }
/* * Initialize each listener. */ void init_listeners(struct Listener_head *listeners, const struct Table_head *tables, struct ev_loop *loop) { struct Listener *iter; char address[ADDRESS_BUFFER_SIZE]; SLIST_FOREACH(iter, listeners, entries) { if (init_listener(iter, tables, loop) < 0) { err("Failed to initialize listener %s", display_address(iter->address, address, sizeof(address))); exit(1); } } }
int my_showmem(char *str, int size) { int i; int current_address; i = 0; current_address = 0; while (i < size) { display_address(¤t_address); my_putstr(": "); display_char_hexa(&str[i], size - i); my_putchar(' '); display_string16(&str[i]); my_putchar('\n'); i = i + 16; } return (0); }
static void accept_cb(struct ev_loop *loop, struct ev_io *w, int revents) { struct Listener *listener = (struct Listener *)w->data; if (revents & EV_READ) { int result = accept_connection(listener, loop); if (result == 0 && (errno == EMFILE || errno == ENFILE)) { char address_buf[256]; int backoff_time = 2; err("File descriptor limit reached! " "Suspending accepting new connections on %s for %d seconds", display_address(listener->address, address_buf, sizeof(address_buf)), backoff_time); ev_io_stop(loop, w); ev_timer_set(&listener->backoff_timer, backoff_time, 0.0); ev_timer_start(loop, &listener->backoff_timer); } } }
int init_backend(struct Backend *backend) { if (backend->pattern_re == NULL) { const char *reerr; int reerroffset; backend->pattern_re = pcre_compile(backend->pattern, 0, &reerr, &reerroffset, NULL); if (backend->pattern_re == NULL) { err("Regex compilation of \"%s\" failed: %s, offset %d", backend->pattern, reerr, reerroffset); return 0; } char address[ADDRESS_BUFFER_SIZE]; debug("Parsed %s %s", backend->pattern, display_address(backend->address, address, sizeof(address))); } return 1; }
int init_backend(struct Backend *backend) { char address_buf[256]; const char *reerr; int reerroffset; if (backend->name_re == NULL) { backend->name_re = pcre_compile(backend->name, 0, &reerr, &reerroffset, NULL); if (backend->name_re == NULL) { err("Regex compilation failed: %s, offset %d", reerr, reerroffset); return 0; } debug("Parsed %s %s", backend->name, display_address(backend->address, address_buf, sizeof(address_buf))); } return 1; }
int main(void) { /* Early system initialisation */ board_init(); system_init_early(); leds_init(); set_busy_led(1); set_dirty_led(0); /* Due to an erratum in the LPC17xx chips anything that may change */ /* peripheral clock scalers must come before system_init_late() */ uart_init(); #ifndef SPI_LATE_INIT spi_init(SPI_SPEED_SLOW); #endif timer_init(); bus_interface_init(); i2c_init(); /* Second part of system initialisation, switches to full speed on ARM */ system_init_late(); enable_interrupts(); /* Internal-only initialisation, called here because it's faster */ buffers_init(); buttons_init(); /* Anything that does something which needs the system clock */ /* should be placed after system_init_late() */ bus_init(); // needs delay rtc_init(); // accesses I2C disk_init(); // accesses card read_configuration(); fatops_init(0); change_init(); uart_puts_P(PSTR("\r\nsd2iec " VERSION " #")); uart_puthex(device_address); uart_putcrlf(); #ifdef CONFIG_REMOTE_DISPLAY /* at this point all buffers should be free, */ /* so just use the data area of the first to build the string */ uint8_t *strbuf = buffers[0].data; ustrcpy_P(strbuf, versionstr); ustrcpy_P(strbuf+ustrlen(strbuf), longverstr); if (display_init(ustrlen(strbuf), strbuf)) { display_address(device_address); display_current_part(0); } #endif set_busy_led(0); #if defined(HAVE_SD) && BUTTON_PREV != 0 /* card switch diagnostic aid - hold down PREV button to use */ if (!(buttons_read() & BUTTON_PREV)) { while (buttons_read() & BUTTON_NEXT) { set_dirty_led(sdcard_detect()); # ifndef SINGLE_LED set_busy_led(sdcard_wp()); # endif } reset_key(0xff); } #endif bus_mainloop(); while (1); }
int main() { /* using volatile variables so we can example core dumps */ for (volatile unsigned int i = 0; i < sizeof(good) / sizeof(struct Test); i++) { int port; char buffer[255]; struct Address *addr = new_address(good[i].input); assert(addr != NULL); assert(address_compare(addr, addr) == 0); assert(address_compare(NULL, addr) < 0); assert(address_compare(addr, NULL) > 0); assert(address_len(addr) > 0); if (good[i].expected_type & TYPE_HOSTNAME) { assert(address_is_hostname(addr)); assert(!address_is_sockaddr(addr)); assert(!address_is_wildcard(addr)); assert(address_hostname(addr) != NULL); assert(address_sa(addr) == NULL); assert(address_sa_len(addr) == 0); } else if (good[i].expected_type & TYPE_SOCKADDR) { assert(!address_is_hostname(addr)); assert(address_is_sockaddr(addr)); assert(!address_is_wildcard(addr)); assert(address_hostname(addr) == NULL); assert(address_sa(addr) != NULL); assert(address_sa_len(addr) > 0); } else if (good[i].expected_type & TYPE_WILDCARD) { assert(!address_is_hostname(addr)); assert(!address_is_sockaddr(addr)); assert(address_is_wildcard(addr)); assert(address_hostname(addr) == NULL); assert(address_sa(addr) == NULL); assert(address_sa_len(addr) == 0); } display_address(addr, buffer, sizeof(buffer)); if (strcmp(buffer, good[i].output)) { fprintf(stderr, "display_address(%p) returned \"%s\", expected \"%s\"\n", addr, buffer, good[i].output); return 1; } assert(display_address(addr, NULL, 0) == NULL); port = address_port(addr); if (good[i].port != port) { fprintf(stderr, "address_port(%p) return %d, expected %d\n", addr, port, good[i].port); return 1; } address_set_port(addr, port); if (good[i].port != port) { fprintf(stderr, "address_port(%p) return %d, expected %d\n", addr, port, good[i].port); return 1; } free(addr); } for (volatile unsigned int i = 0; i < sizeof(bad) / sizeof(const char *); i++) { struct Address *addr = new_address(bad[i]); if (addr != NULL) { fprintf(stderr, "Accepted bad hostname \"%s\"\n", bad[i]); return 1; } } assert(compare_address_strings("unix:/dev/log", "127.0.0.1") < 0); assert(compare_address_strings("unix:/dev/log", "unix:/dev/logsocket") < 0); assert(compare_address_strings("0.0.0.0", "127.0.0.1") < 0); assert(compare_address_strings("127.0.0.1", "0.0.0.0") > 0); assert(compare_address_strings("127.0.0.1", "127.0.0.1") == 0); assert(compare_address_strings("127.0.0.1:80", "127.0.0.1:81") < 0); assert(compare_address_strings("*:80", "*:81") < 0); assert(compare_address_strings("*:81", "*:80") > 0); assert(compare_address_strings("example.com", "example.net") < 0); assert(compare_address_strings("example.net", "example.com") > 0); assert(compare_address_strings("example.com", "example.com.net") < 0); assert(compare_address_strings("example.com.net", "example.com") > 0); assert(compare_address_strings("example.com", "example.com:80") < 0); assert(compare_address_strings("example.com:80", "example.com") > 0); assert(compare_address_strings(NULL, "example.com") < 0); assert(compare_address_strings("example.com", NULL) > 0); assert(compare_address_strings("example.com", "::") < 0); assert(compare_address_strings("::", "example.com") > 0); assert(compare_address_strings("0.0.0.0", "*") < 0); assert(compare_address_strings("*", "0.0.0.0") > 0); do { struct Address *addr = new_address("*"); assert(addr != NULL); assert(address_len(addr) > 0); free(addr); } while (0); return 0; }
static void client_display_socks_v5(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, socks_hash_entry_t *hash_info, sock_state_t* state_info) { /* Display the protocol tree for the version. This routine uses the */ /* stored conversation information to decide what to do with the row. */ /* Per packet information would have been better to do this, but we */ /* didn't have that when I wrote this. And I didn't expect this to get */ /* so messy. */ unsigned int i; const char *AuthMethodStr; sock_state_t new_state_info; /* Either there is an error, or we're done with the state machine (so there's nothing to display) */ if (state_info == NULL) return; proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (state_info->client == clientStart) { proto_tree *AuthTree; proto_item *ti; guint8 num_auth_methods, auth; ti = proto_tree_add_text( tree, tvb, offset, -1, "Client Authentication Methods"); AuthTree = proto_item_add_subtree(ti, ett_socks_auth); num_auth_methods = tvb_get_guint8(tvb, offset); proto_item_set_len(ti, num_auth_methods+1); proto_tree_add_item( AuthTree, hf_client_auth_method_count, tvb, offset, 1, ENC_NA); offset += 1; for( i = 0; i < num_auth_methods; ++i) { auth = tvb_get_guint8( tvb, offset); AuthMethodStr = get_auth_method_name(auth); proto_tree_add_uint_format(AuthTree, hf_client_auth_method, tvb, offset, 1, auth, "Method[%u]: %u (%s)", i, auth, AuthMethodStr); offset += 1; } if ((num_auth_methods == 1) && (tvb_bytes_exist(tvb, offset + 2, 1)) && (tvb_get_guint8(tvb, offset + 2) == 0) && (tvb_reported_length_remaining(tvb, offset + 2 + num_auth_methods) > 0)) { new_state_info.client = clientV5Command; client_display_socks_v5(tvb, offset, pinfo, tree, hash_info, &new_state_info); } } else if (state_info->client == clientV5Command) { proto_tree_add_item( tree, hf_socks_cmd, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item( tree, hf_socks_reserved, tvb, offset, 1, ENC_NA); offset += 1; offset = display_address(tvb, offset, tree); proto_tree_add_item( tree, hf_client_port, tvb, offset, 2, ENC_BIG_ENDIAN); } else if ((state_info->client == clientWaitForAuthReply) && (state_info->server == serverInitReply)) { guint16 len; gchar* str; switch(hash_info->authentication_method) { case NO_AUTHENTICATION: break; case USER_NAME_AUTHENTICATION: /* process user name */ len = tvb_get_guint8(tvb, offset); str = tvb_get_string(wmem_packet_scope(), tvb, offset+1, len); proto_tree_add_string(tree, hf_socks_username, tvb, offset, len+1, str); offset += (len+1); len = tvb_get_guint8(tvb, offset); str = tvb_get_string(wmem_packet_scope(), tvb, offset+1, len); proto_tree_add_string(tree, hf_socks_password, tvb, offset, len+1, str); /* offset += (len+1); */ break; case GSS_API_AUTHENTICATION: proto_tree_add_item( tree, hf_gssapi_command, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item( tree, hf_gssapi_length, tvb, offset+1, 2, ENC_BIG_ENDIAN); len = tvb_get_ntohs(tvb, offset+1); if (len > 0) proto_tree_add_item( tree, hf_gssapi_payload, tvb, offset+3, len, ENC_NA); break; default: break; } } }
static void socks_udp_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Conversation dissector called from UDP dissector. Decode and display */ /* the socks header, the pass the rest of the data to the udp port */ /* decode routine to handle the payload. */ int offset = 0; guint32 *ptr; socks_hash_entry_t *hash_info; conversation_t *conversation; proto_tree *socks_tree; proto_item *ti; conversation = find_conversation( pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); DISSECTOR_ASSERT( conversation); /* should always find a conversation */ hash_info = (socks_hash_entry_t *)conversation_get_proto_data(conversation, proto_socks); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Socks"); col_set_str(pinfo->cinfo, COL_INFO, "Version: 5, UDP Associated packet"); if ( tree) { ti = proto_tree_add_protocol_format( tree, proto_socks, tvb, offset, -1, "Socks" ); socks_tree = proto_item_add_subtree(ti, ett_socks); proto_tree_add_item(socks_tree, hf_socks_reserved2, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(socks_tree, hf_socks_fragment_number, tvb, offset, 1, ENC_NA); offset += 1; offset = display_address( tvb, offset, socks_tree); hash_info->udp_remote_port = tvb_get_ntohs(tvb, offset); proto_tree_add_uint( socks_tree, hf_socks_dstport, tvb, offset, 2, hash_info->udp_remote_port); offset += 2; } else { /* no tree, skip past the socks header */ offset += 3; offset = get_address_v5( tvb, offset, 0) + 2; } /* set pi src/dst port and call the udp sub-dissector lookup */ if ( pinfo->srcport == hash_info->port) ptr = &pinfo->destport; else ptr = &pinfo->srcport; *ptr = hash_info->udp_remote_port; decode_udp_ports( tvb, offset, pinfo, tree, pinfo->srcport, pinfo->destport, -1); *ptr = hash_info->udp_port; }
static int init_listener(struct Listener *listener, const struct Table_head *tables, struct ev_loop *loop) { struct Table *table = table_lookup(tables, listener->table_name); if (table == NULL) { err("Table \"%s\" not defined", listener->table_name); return -1; } init_table(table); listener->table = table_ref_get(table); /* If no port was specified on the fallback address, inherit the address * from the listening address */ if (listener->fallback_address && address_port(listener->fallback_address) == 0) address_set_port(listener->fallback_address, address_port(listener->address)); int sockfd = socket(address_sa(listener->address)->sa_family, SOCK_STREAM, 0); if (sockfd < 0) { err("socket failed: %s", strerror(errno)); return -2; } /* set SO_REUSEADDR on server socket to facilitate restart */ int on = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); int result = bind(sockfd, address_sa(listener->address), address_sa_len(listener->address)); if (result < 0 && errno == EACCES) { /* Retry using binder module */ close(sockfd); sockfd = bind_socket(address_sa(listener->address), address_sa_len(listener->address)); if (sockfd < 0) { char address[128]; err("binder failed to bind to %s", display_address(listener->address, address, sizeof(address))); close(sockfd); return -3; } } else if (result < 0) { char address[128]; err("bind %s failed: %s", display_address(listener->address, address, sizeof(address)), strerror(errno)); close(sockfd); return -3; } if (listen(sockfd, SOMAXCONN) < 0) { err("listen failed: %s", strerror(errno)); close(sockfd); return -4; } int flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); listener_ref_get(listener); ev_io_init(&listener->watcher, accept_cb, sockfd, EV_READ); listener->watcher.data = listener; listener->backoff_timer.data = listener; ev_io_start(loop, &listener->watcher); return sockfd; }
static void display_socks_v5(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, socks_hash_entry_t *hash_info) { /* Display the protocol tree for the version. This routine uses the */ /* stored conversation information to decide what to do with the row. */ /* Per packet information would have been better to do this, but we */ /* didn't have that when I wrote this. And I didn't expect this to get */ /* so messy. */ unsigned int i, command; guint temp; const char *AuthMethodStr; guint8 auth_status; proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, FALSE); ++offset; if (compare_packet( hash_info->connect_row)){ proto_tree *AuthTree; proto_item *ti; temp = tvb_get_guint8(tvb, offset); /* Get Auth method count */ /* build auth tree */ ti = proto_tree_add_text( tree, tvb, offset, -1, "Client Authentication Methods"); AuthTree = proto_item_add_subtree(ti, ett_socks_auth); proto_tree_add_text( AuthTree, tvb, offset, 1, "Count: %u", temp); ++offset; for( i = 0; i < temp; ++i) { AuthMethodStr = get_auth_method_name( tvb_get_guint8( tvb, offset)); proto_tree_add_text( AuthTree, tvb, offset, 1, "Method[%u]: %u (%s)", i, tvb_get_guint8( tvb, offset), AuthMethodStr); ++offset; } proto_item_set_end( ti, tvb, offset); return; } /* Get accepted auth method */ else if (compare_packet( hash_info->auth_method_row)) { proto_tree_add_text( tree, tvb, offset, 1, "Accepted Auth Method: 0x%0x (%s)", tvb_get_guint8( tvb, offset), get_auth_method_name( tvb_get_guint8( tvb, offset))); return; } /* handle user/password auth */ else if (compare_packet( hash_info->user_name_auth_row)) { /* process user name */ offset += display_string( tvb, offset, tree, "User name"); /* process password */ offset += display_string( tvb, offset, tree, "Password"); } /* command to the server */ /* command response from server */ else if (compare_packet( hash_info->auth_version)) { auth_status = tvb_get_guint8(tvb, offset); if(auth_status != 0) proto_tree_add_text( tree, tvb, offset, 1, "Status: %u (failure)", auth_status); else proto_tree_add_text( tree, tvb, offset, 1, "Status: success"); offset ++; } else if (compare_packet( hash_info->gssapi_auth_row)) { guint16 len; proto_tree_add_item( tree, hf_gssapi_command, tvb, offset, 1, FALSE); proto_tree_add_item( tree, hf_gssapi_length, tvb, offset+1, 2, FALSE); len = tvb_get_ntohs(tvb, offset+1); if (len > 0) proto_tree_add_item( tree, hf_gssapi_payload, tvb, offset+3, len, FALSE); } else if (compare_packet( hash_info->gssapi_auth_failure_row)) { proto_tree_add_item( tree, hf_gssapi_command, tvb, offset, 1, FALSE); } else if (compare_packet( hash_info->gssapi_auth_reply_row)) { guint16 len; proto_tree_add_item( tree, hf_gssapi_command, tvb, offset, 1, FALSE); proto_tree_add_item( tree, hf_gssapi_length, tvb, offset+1, 2, FALSE); len = tvb_get_ntohs(tvb, offset+1); if (len > 0) proto_tree_add_item( tree, hf_gssapi_payload, tvb, offset+3, len, FALSE); } else if ((compare_packet( hash_info->command_row)) || (compare_packet( hash_info->cmd_reply_row)) || (compare_packet( hash_info->bind_reply_row))){ command = tvb_get_guint8(tvb, offset); if (compare_packet( hash_info->command_row)) proto_tree_add_uint( tree, hf_socks_cmd, tvb, offset, 1, command); else { proto_item *hidden_item; proto_tree_add_item( tree, hf_socks_results_5, tvb, offset, 1, FALSE); hidden_item = proto_tree_add_item(tree, hf_socks_results, tvb, offset, 1, FALSE); PROTO_ITEM_SET_HIDDEN(hidden_item); } ++offset; proto_tree_add_text( tree, tvb, offset, 1, "Reserved: 0x%0x (should = 0x00)", tvb_get_guint8(tvb, offset)); ++offset; offset = display_address(tvb, offset, tree); /*XXX Add remote port for search somehow */ /* Do remote port */ proto_tree_add_text( tree, tvb, offset, 2, "%sPort: %u", (compare_packet( hash_info->bind_reply_row) ? "Remote Host " : ""), tvb_get_ntohs(tvb, offset)); } }
void display_service(void) { if (menustate == MENU_NONE) { /* No menu active, upload+run system menu */ uint8_t i; /* Dummy read to reset the interrupt line */ i2c_read_register(DISPLAY_I2C_ADDR, DISPLAY_MENU_GETSELECTION); display_menu_reset(); i = 0; while (pgm_read_byte(systemmenu+i)) { ustrcpy_P(displaybuffer, systemmenu+i); display_menu_add(displaybuffer); i += ustrlen(displaybuffer)+1; } display_menu_show(0); menustate = MENU_SYSTEM; } else if (menustate == MENU_SYSTEM) { /* Selection on the system menu */ uint8_t sel = i2c_read_register(DISPLAY_I2C_ADDR, DISPLAY_MENU_GETSELECTION); switch (sel) { case SYSMENU_CHDIR: menu_chdir(); break; case SYSMENU_CHADDR: menu_chaddr(); break; case SYSMENU_STORE: menustate = MENU_NONE; write_configuration(); break; case SYSMENU_CANCEL: menustate = MENU_NONE; return; } } else if (menustate == MENU_CHADDR) { /* New address selected */ uint8_t sel = i2c_read_register(DISPLAY_I2C_ADDR, DISPLAY_MENU_GETSELECTION); device_address = sel+4; menustate = MENU_NONE; display_address(device_address); } else if (menustate == MENU_CHDIR) { /* New directory selected */ uint8_t sel = i2c_read_register(DISPLAY_I2C_ADDR, DISPLAY_MENU_GETSELECTION); path_t path; cbmdirent_t dent; menustate = MENU_NONE; if (sel == 0) /* Cancel */ return; /* Read directory name into displaybuffer */ path.part = current_part; path.dir = partition[current_part].current_dir; if (sel == 1) { /* Previous directory */ dent.name[0] = '_'; dent.name[1] = 0; } else { i2c_read_registers(DISPLAY_I2C_ADDR, DISPLAY_MENU_GETENTRY, sizeof(displaybuffer), displaybuffer); if (first_match(&path, displaybuffer, FLAG_HIDDEN, &dent)) return; } chdir(&path, &dent); update_current_dir(&path); } }
int main(void) { /* Early system initialisation */ early_board_init(); system_init_early(); leds_init(); set_busy_led(1); set_dirty_led(0); /* Due to an erratum in the LPC17xx chips anything that may change */ /* peripheral clock scalers must come before system_init_late() */ uart_init(); #ifndef SPI_LATE_INIT spi_init(SPI_SPEED_SLOW); #endif timer_init(); i2c_init(); /* Second part of system initialisation, switches to full speed on ARM */ system_init_late(); enable_interrupts(); /* Prompt software name and version string */ uart_puts_P(PSTR("\r\nNODISKEMU " VERSION "\r\n")); /* Internal-only initialisation, called here because it's faster */ buffers_init(); buttons_init(); /* Anything that does something which needs the system clock */ /* should be placed after system_init_late() */ rtc_init(); // accesses I2C disk_init(); // accesses card read_configuration(); // restores configuration, may change device address filesystem_init(0); // FIXME: change_init(); #ifdef CONFIG_REMOTE_DISPLAY /* at this point all buffers should be free, */ /* so just use the data area of the first to build the string */ uint8_t *strbuf = buffers[0].data; ustrcpy_P(strbuf, versionstr); ustrcpy_P(strbuf+ustrlen(strbuf), longverstr); if (display_init(ustrlen(strbuf), strbuf)) { display_address(device_address); display_current_part(0); } #endif set_busy_led(0); #if defined(HAVE_SD) /* card switch diagnostic aid - hold down PREV button to use */ if (menu_system_enabled && get_key_press(KEY_PREV)) board_diagnose(); #endif if (menu_system_enabled) lcd_splashscreen(); bus_interface_init(); bus_init(); read_configuration(); late_board_init(); for (;;) { if (menu_system_enabled) lcd_refresh(); else { lcd_clear(); lcd_printf("#%d", device_address); } /* Unit number may depend on hardware and stored settings */ /* so present it here at last */ printf("#%02d\r\n", device_address); bus_mainloop(); bus_interface_init(); bus_init(); // needs delay, inits device address with HW settings } }