/** * Handle a player ban request. * * @param data the request packet * @param len the length of data * @param cli_addr the address of the sender * @param cli_len the length of cli_addr */ void *c_req_ban(char *data, unsigned int len, struct player *pl) { uint32_t ban_id; struct player *target; char *reason, *ptr; uint16_t duration; struct server *s = pl->in_chan->in_server; ptr = data + 24; ban_id = ru32(&ptr); duration = ru16(&ptr); target = get_player_by_public_id(s, ban_id); if (target != NULL) { send_acknowledge(pl); /* ACK */ if(player_has_privilege(pl, SP_ADM_BAN_IP, target->in_chan)) { reason = rstaticstring(29, &ptr); add_ban(s, new_ban(0, target->cli_addr->sin_addr, reason)); logger(LOG_INFO, "Reason for banning player %s : %s", target->name, reason); s_notify_ban(pl, target, duration, reason); remove_player(s, target); free(reason); } } return NULL; }
/** * Handles a server kick request. * * @param data the request packet * @param len the length of data * @param cli_addr the address of the sender * @param cli_len the length of cli_addr */ void *c_req_kick_server(char *data, unsigned int len, struct player *pl) { uint32_t target_id; char *reason, *ptr; struct player *target; struct server *s = pl->in_chan->in_server; if (len != 60) { logger(LOG_WARN, "c_req_kick_server, packet has invalid size : %i instead of %i.", len, 60); return NULL; } ptr = data + 24; target_id = ru32(&ptr); target = get_player_by_public_id(s, target_id); if (target != NULL) { send_acknowledge(pl); /* ACK */ if(player_has_privilege(pl, SP_OTHER_SV_KICK, target->in_chan)) { ptr = data + 28; reason = rstaticstring(29, &ptr); logger(LOG_INFO, "Reason for kicking player %s : %s", target->name, reason); s_notify_kick_server(pl, target, reason); remove_player(s, pl); free(reason); } } return NULL; }
void extract_arc_files_main(void) { arcfile_files_extracted = 0; arcfile_understood = 0; arcfile_offs = 0; /* RESET */ uint32_t test0 = ru32(); if (test0 == 0x101F4667) { mdie("this format not yet implemented"); } else { const char pathStartSeq[5] = { 0, ':', 0, '\\', 0 }; const uint8_t *dp; reset_parse: if ((dp=memmem(arcfile_data+arcfile_offs,arcfile_size-arcfile_offs, pathStartSeq, 5))) { arcfile_offs = dp - (uint8_t*)arcfile_data; arcfile_offs -= 2; while (1) { if (extract_arc_file_try()) { if (arcfile_offs>=arcfile_size) { break; /* End Of File */ } else { goto reset_parse; } } } } } }
/** * Handle a keepalive sent by the client * - check the crc * - send a keepalive back to the client * * @param data the connection packet * @param len the length of the connection packet * @param cli_addr the adress of the client * @param cli_len the length of cli_addr */ void handle_player_keepalive(char *data, unsigned int len, struct server *s) { struct player *pl; char *ptr = data; uint32_t pub_id, priv_id, ka_id; /* Check crc */ if(!packet_check_crc(data, len, 16)) return; /* Retrieve the player */ ptr += 4; priv_id = ru32(&ptr); pub_id = ru32(&ptr); ka_id = ru32(&ptr); /* Get the counter */ pl = get_player_by_ids(s, pub_id, priv_id); if (pl == NULL) { logger(LOG_WARN, "handle_player_keepalive : pl == NULL. Why????"); return; } /* Send the keepalive response */ s_resp_keepalive(pl, ka_id); /* Update the last_ping field */ gettimeofday(&pl->last_ping, NULL); }
extern "C" int zehn_load(NUC_FILE *file, void **mem_ptr, int (**entry)(int,char*[]), bool *supports_hww) { Zehn_header header; // The Zehn file may not begin at the file start size_t file_start = nuc_ftell(file); if(nuc_fread(&header, sizeof(header), 1, file) != 1) return 1; if(header.signature != ZEHN_SIGNATURE || header.version != ZEHN_VERSION || header.file_size > header.alloc_size) { puts("[Zehn] This Zehn file is not supported!"); return 1; } Storage<Zehn_reloc> relocs(header.reloc_count); Storage<Zehn_flag> flags(header.flag_count); Storage<uint8_t> extra_data(header.extra_size); if(nuc_fread(reinterpret_cast<void*>(relocs.data), sizeof(Zehn_reloc), header.reloc_count, file) != header.reloc_count || nuc_fread(reinterpret_cast<void*>(flags.data), sizeof(Zehn_flag), header.flag_count, file) != header.flag_count || nuc_fread(reinterpret_cast<void*>(extra_data.data), 1, header.extra_size, file) != header.extra_size) { puts("[Zehn] File read failed!"); return 1; } size_t remaining_mem = header.alloc_size - nuc_ftell(file) + file_start, remaining_file = header.file_size - nuc_ftell(file) + file_start; if(emu_debug_alloc_ptr) { if(emu_debug_alloc_size < remaining_mem) { puts("[Zehn] emu_debug_alloc_size too small!"); *mem_ptr = malloc(remaining_mem); } else *mem_ptr = emu_debug_alloc_ptr; } else *mem_ptr = malloc(remaining_mem); uint8_t *base = reinterpret_cast<uint8_t*>(*mem_ptr); if(!base) { puts("[Zehn] Memory allocation failed!"); return 1; } if(relocs.data[0].type == Zehn_reloc_type::FILE_COMPRESSED) { if(relocs.data[0].offset != static_cast<int>(Zehn_compress_type::ZLIB)) { puts("[Zehn] Compression format not supported!"); return 1; } Storage<uint8_t> compressed(remaining_file); if(nuc_fread(compressed.data, remaining_file, 1, file) != 1) { puts("[Zehn] File read failed!"); return 1; } uLongf dest_len = remaining_mem; if(uncompress(base, &dest_len, compressed.data, remaining_file) != Z_OK) { puts("[Zehn] Decompression failed!"); return 1; } std::fill(base + dest_len, base + remaining_mem, 0); } else { if(nuc_fread(base, remaining_file, 1, file) != 1) { puts("[Zehn] File read failed!"); return 1; } // Fill rest with zeros (.bss and other NOBITS sections) std::fill(base + remaining_file, base + remaining_mem, 0); } const char *application_name = "(unknown)", *application_author = "(unknown)", *application_notice = "(no notice)"; unsigned int application_version = 1, ndless_version_min = 0, ndless_version_max = UINT_MAX, ndless_revision_min = 0, ndless_revision_max = UINT_MAX; // Iterate through each flag for(Zehn_flag &f : flags) { const char *ptr; switch(f.type) { case Zehn_flag_type::EXECUTABLE_NAME: if(!zehn_check_string(extra_data.begin(), f, 255, &application_name)) { puts("[Zehn] Invalid application name!"); return 1; } break; case Zehn_flag_type::EXECUTABLE_NOTICE: if(zehn_check_string(extra_data.begin(), f, 1024, &ptr)) application_notice = ptr; break; case Zehn_flag_type::EXECUTABLE_AUTHOR: if(zehn_check_string(extra_data.begin(), f, 128, &ptr)) application_author = ptr; break; case Zehn_flag_type::EXECUTABLE_VERSION: application_version = f.data; break; case Zehn_flag_type::NDLESS_VERSION_MIN: ndless_version_min = f.data; break; case Zehn_flag_type::NDLESS_REVISION_MIN: ndless_revision_min = f.data; break; case Zehn_flag_type::NDLESS_VERSION_MAX: ndless_version_max = f.data; break; case Zehn_flag_type::NDLESS_REVISION_MAX: ndless_revision_max = f.data; break; case Zehn_flag_type::RUNS_ON_COLOR: if(f.data == false && has_colors) { msgbox("Error", "The application %s doesn't support CX and CM calculators!", application_name); return 2; } break; case Zehn_flag_type::RUNS_ON_CLICKPAD: if(f.data == false && !is_touchpad) { msgbox("Error", "The application %s doesn't support clickpads!", application_name); return 2; } break; case Zehn_flag_type::RUNS_ON_TOUCHPAD: if(f.data == false && is_touchpad) { msgbox("Error", "The application %s doesn't support touchpads!", application_name); return 2; } break; case Zehn_flag_type::RUNS_ON_32MB: if(f.data == false && (!has_colors || is_cm)) { msgbox("Error", "The application %s requires more than 32MB of RAM!", application_name); return 2; } break; case Zehn_flag_type::RUNS_ON_HWW: *supports_hww = f.data; break; default: break; } } // Show some information about the executable if(isKeyPressed(KEY_NSPIRE_CAT)) { char info[1536]; sprintf(info, "Name: %s Version: %u\nAuthor: %s\nNotice: %s", application_name, application_version, application_author, application_notice); show_msgbox("Information about the executable", info); return 2; } if(NDLESS_VERSION < ndless_version_min || (NDLESS_VERSION == ndless_version_min && NDLESS_REVISION < ndless_revision_min)) { msgbox("Error", "The application %s requires at least ndless %d.%d.%d!", application_name, ndless_version_min / 10, ndless_version_min % 10, ndless_revision_min); return 2; } if(NDLESS_VERSION > ndless_version_max || (NDLESS_VERSION == ndless_version_max && NDLESS_REVISION > ndless_revision_max)) { if(ndless_revision_max != UINT_MAX) msgbox("Error", "The application %s requires ndless %d.%d.%d or older!", application_name, ndless_version_max / 10, ndless_version_max % 10, ndless_revision_max); else msgbox("Error", "The application %s requires ndless %d.%d or older!", application_name, ndless_version_max / 10, ndless_version_max % 10); return 2; } // Iterate through the reloc table for(Zehn_reloc &r : relocs) { if(r.offset >= remaining_mem) { puts("[Zehn] Wrong reloc in Zehn file!"); return 1; } // No alignment guaranteed! uint32_t *place = reinterpret_cast<uint32_t*>(base + r.offset); switch(r.type) { //Handled above case Zehn_reloc_type::FILE_COMPRESSED: break; case Zehn_reloc_type::UNALIGNED_RELOC: if(r.offset != 0) { printf("[Zehn] Unexpected UNALIGNED_RELOC value %lu!\n", r.offset); return 1; } break; case Zehn_reloc_type::ADD_BASE: wu32(place, ru32(place) + reinterpret_cast<uint32_t>(base)); break; case Zehn_reloc_type::ADD_BASE_GOT: { uint32_t u32; while((u32 = ru32(place)) != 0xFFFFFFFF) wu32(place++, u32 + reinterpret_cast<uint32_t>(base)); break; } case Zehn_reloc_type::SET_ZERO: wu32(place, 0); break; default: printf("[Zehn] Unsupported reloc %d!\n", static_cast<int>(r.type)); return 1; } } *entry = reinterpret_cast<int (*)(int,char*[])>(base + header.entry_offset); return 0; }