/* * Add a client to ClientQueue. * - Every client-field is just a reference (except 'Web'). * - Return a unique number for identifying the client. */ static int Cache_client_enqueue(const DilloUrl *Url, DilloWeb *Web, CA_Callback_t Callback, void *CbData) { static int ClientKey = 0; /* Provide a primary key for each client */ CacheClient_t *NewClient; if (ClientKey < INT_MAX) /* check for integer overflow */ ClientKey++; else ClientKey = 1; NewClient = dNew(CacheClient_t, 1); NewClient->Key = ClientKey; NewClient->Url = Url; NewClient->Version = 0; NewClient->Buf = NULL; NewClient->BufSize = 0; NewClient->Callback = Callback; NewClient->CbData = CbData; NewClient->Web = Web; dList_append(ClientQueue, NewClient); return ClientKey; }
/* * Increment the reference count and add to the list if not present */ static void Capi_conn_ref(capi_conn_t *conn) { if (++conn->Ref == 1) { /* add the connection data to list */ dList_append(CapiConns, (void *)conn); } _MSG(" Capi_conn_ref #%d %p\n", conn->Ref, conn); }
/* * Set a call to Cache_process_queue from the main cycle. */ static void Cache_delayed_process_queue(CacheEntry_t *entry) { /* there's no need to repeat entries in the queue */ if (!dList_find(DelayedQueue, entry)) dList_append(DelayedQueue, entry); if (DelayedQueueIdleId == 0) { _MSG(" Setting timeout callback\n"); a_Timeout_add(0.0, Cache_delayed_process_queue_callback, NULL); DelayedQueueIdleId = 1; } }
static HostConnection_t *Http_host_connection_get(const char *host) { int i; HostConnection_t *hc; for (i = 0; i < dList_length(host_connections); i++) { hc = (HostConnection_t*) dList_nth_data(host_connections, i); if (dStrAsciiCasecmp(host, hc->host) == 0) return hc; } hc = dNew0(HostConnection_t, 1); Http_socket_queue_init(&hc->queue); hc->host = dStrdup(host); dList_append(host_connections, hc); return hc; }
/* * Extract multiple fields from the header. */ static Dlist *Cache_parse_multiple_fields(const char *header, const char *fieldname) { uint_t i, j; Dlist *fields = dList_new(8); char *field; for (i = 0; header[i]; i++) { /* Search fieldname */ for (j = 0; fieldname[j]; j++) if (D_ASCII_TOLOWER(fieldname[j]) != D_ASCII_TOLOWER(header[i + j])) break; if (fieldname[j]) { /* skip to next line */ for (i += j; header[i] != '\n'; i++); continue; } i += j; if (header[i] == ':') { /* Field found! */ while (header[++i] == ' ' || header[i] == '\t'); for (j = 0; header[i + j] != '\n'; j++); while (j && (header[i + j - 1] == ' ' || header[i + j - 1] == '\t')) j--; field = dStrndup(header + i, j); dList_append(fields, field); } else { while (header[i] != '\n') i++; } } if (dList_length(fields) == 0) { dList_free(fields); fields = NULL; } return fields; }
static void Auth_realm_add_path(AuthRealm_t *realm, const char *path) { int len, i; char *realm_path, *n_path; n_path = dStrdup(path); len = strlen(n_path); /* remove trailing '/' */ if (len && n_path[len - 1] == '/') n_path[--len] = 0; /* delete existing paths that are inside the new one */ for (i = 0; (realm_path = dList_nth_data(realm->paths, i)); i++) { if (Auth_path_is_inside(realm_path, path, len)) { dList_remove_fast(realm->paths, realm_path); dFree(realm_path); i--; /* reconsider this slot */ } } dList_append(realm->paths, n_path); }
static void Auth_do_auth_dialog_cb(const char *user, const char *password, void *vData) { AuthDialogData_t *data; AuthHost_t *host; AuthRealm_t *realm; data = (AuthDialogData_t *)vData; /* find or create the host */ if (!(host = Auth_host_by_url(data->url))) { /* create a new host */ host = dNew(AuthHost_t, 1); host->scheme = dStrdup(URL_SCHEME(data->url)); host->authority = dStrdup(URL_AUTHORITY(data->url)); host->realms = dList_new(1); dList_append(auth_hosts, host); } /* find or create the realm */ if (!(realm = Auth_realm_by_name(host, data->auth_parse->realm))) { realm = dNew0(AuthRealm_t, 1); realm->name = dStrdup(data->auth_parse->realm); realm->paths = dList_new(1); dList_append(host->realms, realm); } realm->type = data->auth_parse->type; dFree(realm->authorization); realm->authorization = NULL; Auth_realm_add_path(realm, URL_PATH(data->url)); if (realm->type == BASIC) { char *user_password = dStrconcat(user, ":", password, NULL); char *response = a_Misc_encode_base64(user_password); char *authorization = dStrconcat("Authorization: Basic ", response, "\r\n", NULL); dFree(realm->authorization); realm->authorization = authorization; dFree(response); dStrshred(user_password); dFree(user_password); } else if (realm->type == DIGEST) { dFree(realm->username); realm->username = dStrdup(user); realm->nonce_count = 0; dFree(realm->nonce); realm->nonce = dStrdup(data->auth_parse->nonce); dFree(realm->opaque); realm->opaque = dStrdup(data->auth_parse->opaque); realm->algorithm = data->auth_parse->algorithm; dFree(realm->domain); realm->domain = dStrdup(data->auth_parse->domain); realm->qop = data->auth_parse->qop; dFree(realm->cnonce); if (realm->qop != QOPNOTSET) realm->cnonce = a_Digest_create_cnonce(); if (!a_Digest_compute_digest(realm, user, password)) { MSG("Auth_do_auth_dialog_cb: a_Digest_compute_digest failed.\n"); dList_remove_fast(host->realms, realm); Auth_realm_delete(realm); } } else { MSG("Auth_do_auth_dialog_cb: Unknown auth type: %i\n", realm->type); } dStrshred((char *)password); }
/*! Add services reading a dpidrc file * each non empty or commented line has the form * service = path_relative_to_dpidir * \Return: * \li Returns number of available services on success * \li -1 on failure */ int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list) { FILE *dpidrc_stream; char *p, *line = NULL, *service, *path; int i, st; struct service *s; char *user_dpidir = NULL, *sys_dpidir = NULL, *dpidrc = NULL; user_dpidir = dStrconcat(dGethomedir(), "/", dotDILLO_DPI, NULL); if (access(user_dpidir, F_OK) == -1) { /* no dpis in user's space */ dFree(user_dpidir); user_dpidir = NULL; } dpidrc = dStrconcat(dGethomedir(), "/", dotDILLO_DPIDRC, NULL); if (access(dpidrc, F_OK) == -1) { dFree(dpidrc); dpidrc = dStrdup(DPIDRC_SYS); if (access(dpidrc, F_OK) == -1) { dFree(dpidrc); dpidrc = NULL; } } if (!dpidrc || (sys_dpidir = get_dpi_dir(dpidrc)) == NULL) sys_dpidir = NULL; if (!user_dpidir && !sys_dpidir) { ERRMSG("fill_services_list", "Fatal error ", 0); MSG_ERR("\n - Can't find the directory for dpis.\n"); exit(1); } if ((dpidrc_stream = fopen(dpidrc, "r")) == NULL) { ERRMSG("fill_services_list", "popen failed", errno); dFree(dpidrc); dFree(sys_dpidir); dFree(user_dpidir); return (-1); } if (*services_list != NULL) { ERRMSG("fill_services_list", "services_list parameter is not NULL", 0); return -1; } *services_list = dList_new(8); /* dpidrc parser loop */ for (;(line = dGetline(dpidrc_stream)) != NULL; dFree(line)) { st = dParser_parse_rc_line(&line, &service, &path); if (st < 0) { MSG_ERR("dpid: Syntax error in %s: service=\"%s\" path=\"%s\"\n", dpidrc, service, path); continue; } else if (st != 0) { continue; } _MSG("dpid: service=%s, path=%s\n", service, path); /* ignore dpi_dir silently */ if (strcmp(service, "dpi_dir") == 0) continue; s = dNew(struct service, 1); /* init services list entry */ s->name = dStrdup(service); s->dp_index = -1; dList_append(*services_list, s); /* search the dpi for a service by its path */ for (i = 0; i < numdpis; i++) if ((p = strstr(attlist[i].path, path)) && *(p - 1) == '/' && strlen(p) == strlen(path)) break; /* if the dpi exist bind service and dpi */ if (i < numdpis) s->dp_index = i; } fclose(dpidrc_stream); dList_sort(*services_list, (dCompareFunc)services_alpha_comp); dFree(dpidrc); dFree(sys_dpidir); dFree(user_dpidir); return (dList_length(*services_list)); }