struct bondStretch * getBondStretch(int element1, int element2, char bondOrder) { struct bondStretch *entry; char bondName[256]; // XXX Can overflow for long atom type names entry = getBondStretchEntry(element1, element2, bondOrder); if (entry->parameterQuality < QualityWarningLevel && !entry->warned) { if (!ComputedParameterWarning) { WARNING("Using a reduced quality parameter, see the trace output for details"); ComputedParameterWarning = 1; } generateBondName(bondName, element1, element2, bondOrder); INFO2("Using quality %d parameters for %s stretch", entry->parameterQuality, bondName); INFO4("Computed ks: %e, r0: %e, de: %e, beta: %e", entry->ks, entry->r0, entry->de, entry->beta); entry->warned = 1; } if (entry->maxPhysicalTableIndex == -1) { // Only call initializeBondStretchInterpolater when we're actually // going to use it. That way, we don't warn about too large of an // ExcessiveEnergyLevel initializeBondStretchInterpolater(entry); } return entry; }
/* Actually open the connection and do some http parsing, handle any 302 * responses within here. */ static int open_relay_connection (client_t *client, relay_server *relay, relay_server_master *master) { int redirects = 0; http_parser_t *parser = NULL; connection_t *con = &client->connection; char *server = strdup (master->ip); char *mount = strdup (master->mount); int port = master->port, timeout = master->timeout, ask_for_metadata = relay->mp3metadata; char *auth_header = NULL; if (relay->username && relay->password) { char *esc_authorisation; unsigned len = strlen(relay->username) + strlen(relay->password) + 2; DEBUG2 ("using username %s for %s", relay->username, relay->localmount); auth_header = malloc (len); snprintf (auth_header, len, "%s:%s", relay->username, relay->password); esc_authorisation = util_base64_encode(auth_header); free(auth_header); len = strlen (esc_authorisation) + 24; auth_header = malloc (len); snprintf (auth_header, len, "Authorization: Basic %s\r\n", esc_authorisation); free(esc_authorisation); } while (redirects < 10) { sock_t streamsock; char *bind = NULL; /* policy decision, we assume a source bind even after redirect, possible option */ if (master->bind) bind = strdup (master->bind); if (bind) INFO4 ("connecting to %s:%d for %s, bound to %s", server, port, relay->localmount, bind); else INFO3 ("connecting to %s:%d for %s", server, port, relay->localmount); con->con_time = time (NULL); relay->in_use = master; streamsock = sock_connect_wto_bind (server, port, bind, timeout); free (bind); if (connection_init (con, streamsock, server) < 0) { WARN2 ("Failed to connect to %s:%d", server, port); break; } parser = get_relay_response (con, mount, server, ask_for_metadata, auth_header); if (parser == NULL) { ERROR4 ("Problem trying to start relay on %s (%s:%d%s)", relay->localmount, server, port, mount); break; } if (strcmp (httpp_getvar (parser, HTTPP_VAR_ERROR_CODE), "302") == 0) { /* better retry the connection again but with different details */ const char *uri, *mountpoint; int len; uri = httpp_getvar (parser, "location"); INFO1 ("redirect received %s", uri); if (strncmp (uri, "http://", 7) != 0) break; uri += 7; mountpoint = strchr (uri, '/'); free (mount); if (mountpoint) mount = strdup (mountpoint); else mount = strdup ("/"); len = strcspn (uri, ":/"); port = 80; if (uri [len] == ':') port = atoi (uri+len+1); free (server); server = calloc (1, len+1); strncpy (server, uri, len); connection_close (con); httpp_destroy (parser); parser = NULL; } else { if (httpp_getvar (parser, HTTPP_VAR_ERROR_MESSAGE)) { ERROR3 ("Error from relay request on %s (%s %s)", relay->localmount, master->mount, httpp_getvar(parser, HTTPP_VAR_ERROR_MESSAGE)); client->parser = NULL; break; } sock_set_blocking (streamsock, 0); thread_rwlock_wlock (&relay->source->lock); client->parser = parser; // old parser will be free in the format clear thread_rwlock_unlock (&relay->source->lock); client->connection.discon_time = 0; client->connection.con_time = time (NULL); client_set_queue (client, NULL); free (server); free (mount); free (auth_header); return 0; } redirects++; } /* failed, better clean up */ free (server); free (mount); free (auth_header); if (parser) httpp_destroy (parser); connection_close (con); con->con_time = time (NULL); // sources count needs to drop in such cases if (relay->in_use) relay->in_use->skip = 1; return -1; }
/* rval < 0: error, > 0: have audio or video */ int mm_open_fp(mm_file *mf, FILE *file) { int retval = -1; int res = 0; int have_vorbis = 0; int have_theora = 0; ogg_page pg; assert(mf); memset(mf, 0, sizeof(*mf)); mf->file = file; // This is important. If there is no file // then we need to reset the audio and video // pointers so that the other functions // ignore the file. if (!mf->file) { mf->audio = NULL; mf->video = NULL; return retval; } ogg_sync_init(&mf->sync); /* get first page to start things up */ if (get_page(mf, &pg) <= 0) { goto err; } DEBUG1("trying theora decoder..."); res = init_theora(mf, &pg); if (res < 0) { goto err; } else { have_theora = !!res * MEDIA_VIDEO; } DEBUG1("trying vorbis decoder..."); res = init_vorbis(mf, &pg); if (res < 0) { goto err; } else { have_vorbis = !!res * MEDIA_AUDIO; } if (have_vorbis) { unsigned c = 0, r = 0; mm_audio_info(mf, &c, &r); INFO3("audio %u channel(s) at %u Hz", c, r); } if (have_theora) { unsigned w, h; float fps; mm_video_info(mf, &w, &h, &fps); INFO4("video %ux%u pixels at %g fps", w, h, fps); } return have_vorbis | have_theora; err: WARNING1("unable to decode stream"); mm_close(mf); return retval; }