/** * Build the PATRICIA that maps a message name string into our internal * message ID. */ static void g2_msg_build_map(void) { uint i; STATIC_ASSERT(G2_MSG_MAX == N_ITEMS(g2_msg_english_names)); STATIC_ASSERT(G2_MSG_MAX == N_ITEMS(g2_msg_symbolic_names)); g_assert(NULL == g2_msg_pt); /* * We must be prepared to handle all the possible packet names, not just * the ones we know. Therefore, the PATRICIA key size is computed to be * able to handle the maximum architected size. */ g2_msg_pt = patricia_create(G2_FRAME_NAME_LEN_MAX * 8); /* Size in bits */ for (i = 0; i < N_ITEMS(g2_msg_symbolic_names); i++) { const char *key = g2_msg_symbolic_names[i]; size_t len = strlen(key); patricia_insert_k(g2_msg_pt, key, len * 8, int_to_pointer(i)); } }
/** * Mark a file descriptor as being preserved from closing by * fd_close_unpreserved_from(). */ void fd_preserve(int fd) { g_assert(!is_a_socket(fd)); ONCE_FLAG_RUN(fd_preserved_allocated, fd_preserved_allocate); hset_insert(fd_preserved, int_to_pointer(fd)); }
/** * Notifies that a socket descriptor has been closed. * * This is only required on Windows, since we need to keep track of opened * socket descriptors, in order to close them before exec(). Failure to * do so would leave listen sockets around, and because we use SO_REUSEADDR * to bind our listening sockets, we would have two processes listening on * the same socket -- a recipe for blackouts on Windows! */ void fd_notify_socket_closed(socket_fd_t fd) { if (!is_running_on_mingw()) { s_carp_once("%s(): not needed on UNIX", G_STRFUNC); return; } else { if G_LIKELY(fd_sockets != NULL) hset_remove(fd_sockets, int_to_pointer(fd)); } }
/** * Closes the file and sets the descriptor to -1. Does nothing if * the descriptor is already -1. * * @param fd_ptr Must point to a non-negative file descriptor or -1. * * @return 0 on success, -1 on error. */ int fd_close(int *fd_ptr) { int ret, fd; g_assert(NULL != fd_ptr); fd = *fd_ptr; g_assert(fd >= -1); if (fd < 0) { ret = 0; } else { if (fd_preserved != NULL) hset_remove(fd_preserved, int_to_pointer(fd)); ret = close(fd); *fd_ptr = -1; } return ret; }
static inline void ul_stats_set_row(struct ul_stats *us, int row) { ul_stats_set_user_data(us, int_to_pointer(row)); }
int main(void) { struct fibheap *a; void *arr[10]; int i; a = fh_makekeyheap(); for (i=1 ; i < 10 ; i++) { arr[i]= fh_insertkey(a,0,int_to_pointer(i)); printf("adding: 0 %d \n",i); } printf(" \n"); fh_replacekey(a, arr[1],-38); fh_replacekey(a, arr[7],-34); printf("wert(minkey) %d\n",fh_minkey(a)); printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a))); fh_replacekey(a, arr[2],-55); fh_replacekey(a, arr[5],-56); printf("Wert(minkey) %d\n",fh_minkey(a)); printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a))); fh_replacekey(a, arr[4],-1); fh_replacekey(a, arr[2],-102); fh_replacekey(a, arr[6],-1); fh_replacekey(a, arr[9],-1); fh_replacekey(a, arr[8],-4); printf("Wert(minkey) %d\n",fh_minkey(a)); printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a))); fh_replacekey(a, arr[3],-74); fh_replacekey(a, arr[8],-55); fh_replacekey(a, arr[4],-2); printf("Wert(minkey) %d\n",fh_minkey(a)); printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a))); fh_replacekey(a, arr[4],-3); fh_replacekey(a, arr[6],-2); fh_replacekey(a, arr[7],-99); printf("Wert(minkey) %d\n",fh_minkey(a)); printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a))); fh_replacekey(a, arr[6],-3); fh_replacekey(a, arr[4],-4); fh_replacekey(a, arr[8],-94); fh_replacekey(a, arr[9],-2); printf("Wert(minkey) %d\n",fh_minkey(a)); printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a))); fh_replacekey(a, arr[6],-4); printf("Wert(minkey) %d\n",fh_minkey(a)); printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a))); printf("Wert(minkey) %d\n",fh_minkey(a)); printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a))); /*fh_replacekey(a, arr[9],-3);*/ printf("Wert(minkey) %d\n",fh_minkey(a)); printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a))); /*fh_replacekey(a, arr[9],-49);*/ fh_deleteheap(a); return 0; }
/** * Initiates a new TLS session. * * @return 0 on success, -1 on error. */ int tls_init(struct gnutella_socket *s) { /** * ANON-DH is enabled because we don't use PKI. * DEFLATE is disabled because it seems to cause crashes. * ARCFOUR-40 is disabled because it is deprecated. */ static const char prio_want[] = "NORMAL:+ANON-DH:-ARCFOUR-40:-COMP-DEFLATE"; /* "-COMP-DEFLATE" is causing an error on MinGW with GnuTLS 2.10.2 */ static const char prio_must[] = "NORMAL:+ANON-DH:-ARCFOUR-40"; const bool server = SOCK_CONN_INCOMING == s->direction; struct tls_context *ctx; const char *fn; int e; #define TRY(function) (fn = (#function)), e = function socket_check(s); WALLOC0(ctx); ctx->s = s; s->tls.ctx = ctx; if ( TRY(gnutls_init)(&ctx->session, server ? GNUTLS_SERVER : GNUTLS_CLIENT) ) { ctx->session = NULL; goto failure; } if (TRY(gnutls_priority_set_direct)(ctx->session, prio_want, NULL)) { const char *error; if (TRY(gnutls_priority_set_direct)(ctx->session, prio_must, &error)) { g_warning("%s() failed at \"%s\"", fn, error); goto failure; } } if (TRY(gnutls_credentials_set)(ctx->session, GNUTLS_CRD_CERTIFICATE, cert_cred)) goto failure; gnutls_dh_set_prime_bits(ctx->session, TLS_DH_BITS); #ifdef USE_TLS_CUSTOM_IO gnutls_transport_set_ptr(ctx->session, s); gnutls_transport_set_push_function(ctx->session, tls_push); gnutls_transport_set_pull_function(ctx->session, tls_pull); #if !HAS_TLS(2, 12) /* * This routine has been removed starting TLS 3.0. It was used to disable * the lowat feature, and apparently this is now always the case in recent * TLS versions. --RAM, 2011-09-28 * * It's also flagged as deprecated in 2.12.x, so don't use it there. * --RAM, 2011-12-15 */ gnutls_transport_set_lowat(ctx->session, 0); #endif #else /* !USE_TLS_CUSTOM_IO */ g_assert(is_valid_fd(s->file_desc)); gnutls_transport_set_ptr(ctx->session, int_to_pointer(s->file_desc)); #endif /* USE_TLS_CUSTOM_IO */ if (server) { if (TRY(gnutls_anon_allocate_server_credentials)(&ctx->server_cred)) goto failure; gnutls_anon_set_server_dh_params(ctx->server_cred, get_dh_params()); if (TRY(gnutls_credentials_set)(ctx->session, GNUTLS_CRD_ANON, ctx->server_cred)) goto failure; } else { if (TRY(gnutls_anon_allocate_client_credentials)(&ctx->client_cred)) goto failure; if (TRY(gnutls_credentials_set)(ctx->session, GNUTLS_CRD_ANON, ctx->client_cred)) goto failure; } return 0; failure: g_warning("%s() failed: %s", EMPTY_STRING(fn), gnutls_strerror(e)); tls_free(s); return -1; #undef TRY }
/** * Get a new index in the cache, and update LRU data structures. * * @param db the database * @param num page number in the DB for which we want a cache index * * * @return -1 on error, or the allocated cache index. */ static int getidx(DBM *db, long num) { struct lru_cache *cache = db->cache; long n; /* Cache index */ /* * If we invalidated pages, reuse their indices. * If we have not used all the pages yet, get the next one. * Otherwise, use the least-recently requested page. */ if (slist_length(cache->available)) { void *v = slist_shift(cache->available); n = pointer_to_int(v); g_assert(n >= 0 && n < cache->pages); g_assert(!cache->dirty[n]); g_assert(-1 == cache->numpag[n]); hash_list_prepend(cache->used, int_to_pointer(n)); } else if (cache->next < cache->pages) { n = cache->next++; cache->dirty[n] = FALSE; hash_list_prepend(cache->used, int_to_pointer(n)); } else { void *last = hash_list_tail(cache->used); long oldnum; gboolean had_ioerr = booleanize(db->flags & DBM_IOERR_W); hash_list_moveto_head(cache->used, last); n = pointer_to_int(last); /* * This page is no longer cached as its cache index is being reused * Flush it to disk if dirty before discarding it. */ g_assert(n >= 0 && n < cache->pages); oldnum = cache->numpag[n]; if (cache->dirty[n] && !writebuf(db, oldnum, n)) { hash_list_iter_t *iter; void *item; gboolean found = FALSE; /* * Cannot flush dirty page now, probably because we ran out of * disk space. Look through the cache whether we can reuse a * non-dirty page instead, which would let us keep the dirty * page a little longer in the cache, in the hope it can then * be properly flushed later. */ iter = hash_list_iterator_tail(cache->used); while (NULL != (item = hash_list_iter_previous(iter))) { long i = pointer_to_int(item); g_assert(i >= 0 && i < cache->pages); if (!cache->dirty[i]) { found = TRUE; /* OK, reuse cache slot #i then */ n = i; oldnum = cache->numpag[i]; break; } } hash_list_iter_release(&iter); if (found) { g_assert(item != NULL); hash_list_moveto_head(cache->used, item); /* * Clear error condition if we had none prior to the flush * attempt, since we can do without it for now. */ if (!had_ioerr) db->flags &= ~DBM_IOERR_W; g_warning("sdbm: \"%s\": " "reusing cache slot used by clean page #%ld instead", sdbm_name(db), oldnum); } else { g_warning("sdbm: \"%s\": cannot discard dirty page #%ld", sdbm_name(db), oldnum); return -1; } } g_hash_table_remove(cache->pagnum, ulong_to_pointer(oldnum)); cache->dirty[n] = FALSE; } /* * Record the association between the cache index and the page number. */ g_assert(n >= 0 && n < cache->pages); cache->numpag[n] = num; g_hash_table_insert(cache->pagnum, ulong_to_pointer(num), int_to_pointer(n)); return n; }
/** * Closes all file descriptors greater or equal to ``first_fd'', skipping * preserved ones if ``preserve'' is TRUE. */ static void fd_close_from_internal(const int first_fd, bool preserve) { int fd; g_return_if_fail(first_fd >= 0); if (!preserve && try_close_from(first_fd)) return; fd = getdtablesize() - 1; while (fd >= first_fd) { if (preserve && hset_contains(fd_preserved, int_to_pointer(fd))) goto next; #ifdef HAVE_GTKOSXAPPLICATION /* OS X doesn't allow fds being closed not opened by us. During * GUI initialisation a new kqueue fd is created for UI events. This * is visible to us as a fifo which we are not allowed to close. * Set close on exec on all fifo's so we won't leak any of our other * fifo's * -- JA 2011-11-28 */ if (is_a_fifo(fd)) fd_set_close_on_exec(fd); else #endif /* OS X frowns upon random fds being closed --RAM 2011-11-13 */ if (fd_is_opened(fd)) { if (close(fd)) { #if defined(F_MAXFD) fd = fcntl(0, F_MAXFD); continue; #endif /* F_MAXFD */ } } next: fd--; } /* * When called with a first_fd of 3, and we are on Windows, also make * sure we close all the known sockets we have. This lets the process * safely auto-restart, avoiding multiple listening sockets on the same * port. * --RAM, 2015-04-05 */ if ( is_running_on_mingw() && !preserve && 3 == first_fd && NULL != fd_sockets ) { hset_t *fds = fd_sockets; /* * We're about to exec() another process, and we may be crashing, * hence do not bother using hset_foreach_remove() to ensure minimal * processing. We also reset the fd_sockets pointer to NULL to * make sure s_close() will do nothing when fd_notify_socket_closed() * is called. */ fd_sockets = NULL; /* We don't expect race conditions here */ hset_foreach(fds, fd_socket_close, NULL); /* Don't bother freeing / clearing set, we're about to exec() */ } }