/**************************************************************** if the client is capable of 'wanting hack', then the server will send the client a filename in the packet_join_game_reply packet. this function creates the file with a suitably random string in it and then sends the string to the server. If the server can open and read the string, then the client is given hack access. *****************************************************************/ void send_client_wants_hack(const char *filename) { if (filename[0] != '\0') { struct packet_single_want_hack_req req; struct section_file *file; if (!is_safe_filename(filename)) { return; } /* get the full filename path */ interpret_tilde(challenge_fullname, sizeof(challenge_fullname), "~/.freeciv/"); make_dir(challenge_fullname); sz_strlcat(challenge_fullname, filename); /* generate an authentication token */ randomize_string(req.token, sizeof(req.token)); file = secfile_new(FALSE); secfile_insert_str(file, req.token, "challenge.token"); if (!secfile_save(file, challenge_fullname, 0, FZ_PLAIN)) { log_error("Couldn't write token to temporary file: %s", challenge_fullname); } secfile_destroy(file); /* tell the server what we put into the file */ send_packet_single_want_hack_req(&client.conn, &req); } }
static int test(void) { pj_rbtree rb; node_key *key; pj_rbtree_node *node; pj_pool_t *pool; int err=0; int count = MIN_COUNT; int i; unsigned size; pj_rbtree_init(&rb, (pj_rbtree_comp*)&compare_node); size = MAX_COUNT*(sizeof(*key)+PJ_RBTREE_NODE_SIZE) + PJ_RBTREE_SIZE + PJ_POOL_SIZE; pool = pj_pool_create( mem, "pool", size, 0, NULL); if (!pool) { PJ_LOG(3,("test", "...error: creating pool of %u bytes", size)); return -10; } key = (node_key *)pj_pool_alloc(pool, MAX_COUNT*sizeof(*key)); if (!key) return -20; node = (pj_rbtree_node*)pj_pool_alloc(pool, MAX_COUNT*sizeof(*node)); if (!node) return -30; for (i=0; i<LOOP; ++i) { int j; pj_rbtree_node *prev, *it; pj_timestamp t1, t2, t_setup, t_insert, t_search, t_erase; pj_assert(rb.size == 0); t_setup.u32.lo = t_insert.u32.lo = t_search.u32.lo = t_erase.u32.lo = 0; for (j=0; j<count; j++) { randomize_string(key[j].str, STRSIZE); pj_get_timestamp(&t1); node[j].key = &key[j]; node[j].user_data = key[j].str; key[j].hash = pj_hash_calc(0, key[j].str, PJ_HASH_KEY_STRING); pj_get_timestamp(&t2); t_setup.u32.lo += (t2.u32.lo - t1.u32.lo); pj_get_timestamp(&t1); pj_rbtree_insert(&rb, &node[j]); pj_get_timestamp(&t2); t_insert.u32.lo += (t2.u32.lo - t1.u32.lo); } pj_assert(rb.size == (unsigned)count); // Iterate key, make sure they're sorted. prev = NULL; it = pj_rbtree_first(&rb); while (it) { if (prev) { if (compare_node((node_key*)prev->key,(node_key*)it->key)>=0) { ++err; PJ_LOG(3, (THIS_FILE, "Error: %s >= %s", (char*)prev->user_data, (char*)it->user_data)); } } prev = it; it = pj_rbtree_next(&rb, it); } // Search. for (j=0; j<count; j++) { pj_get_timestamp(&t1); it = pj_rbtree_find(&rb, &key[j]); pj_get_timestamp(&t2); t_search.u32.lo += (t2.u32.lo - t1.u32.lo); pj_assert(it != NULL); if (it == NULL) ++err; } // Erase node. for (j=0; j<count; j++) { pj_get_timestamp(&t1); it = pj_rbtree_erase(&rb, &node[j]); pj_get_timestamp(&t2); t_erase.u32.lo += (t2.u32.lo - t1.u32.lo); } PJ_LOG(4, (THIS_FILE, "...count:%d, setup:%d, insert:%d, search:%d, erase:%d", count, t_setup.u32.lo / count, t_insert.u32.lo / count, t_search.u32.lo / count, t_erase.u32.lo / count)); count = 2 * count; if (count > MAX_COUNT) break; } pj_pool_release(pool); return err; }