static s4_t * xmms_medialib_database_convert (const gchar *database_name, const gchar *indices[]) { const gchar *coll_conf, *conv_conf; gchar *cmdline, *new_name, *obsolete_name; xmms_config_property_t *cfg; gint exit_status; s4_t *s4; cfg = xmms_config_lookup ("collection.directory"); coll_conf = xmms_config_property_get_string (cfg); cfg = xmms_config_lookup ("sqlite2s4.path"); conv_conf = xmms_config_property_get_string (cfg); new_name = xmms_medialib_database_converted_name (database_name); cmdline = g_strjoin (" ", conv_conf, database_name, new_name, coll_conf, NULL); xmms_log_info ("Attempting to migrate database to new format."); if (!g_spawn_command_line_sync (cmdline, NULL, NULL, &exit_status, NULL) || exit_status) { xmms_log_fatal ("Could not run \"%s\", try to run it manually", cmdline); } g_free (cmdline); s4 = s4_open (new_name, indices, 0); /* Now we give up */ if (s4 == NULL) { xmms_log_fatal ("Could not open the S4 database"); } xmms_log_info ("Migration successful."); /* Move the sqlite database */ obsolete_name = g_strconcat (database_name, ".obsolete", NULL); g_rename (database_name, obsolete_name); g_free (obsolete_name); /* Update the config path */ cfg = xmms_config_lookup ("medialib.path"); xmms_config_property_set_data (cfg, new_name); g_free (new_name); return s4; }
/* delete a vis client. don't use this method without mutex! */ void delete_client (int32_t id) { xmms_vis_client_t *c; if (id < 0 || id >= vis->clientc) { return; } c = vis->clientv[id]; if (c == NULL) { return; } if (c->type == VIS_UNIXSHM) { cleanup_shm (&c->transport.shm); } else if (c->type == VIS_UDP) { cleanup_udp (&c->transport.udp, vis->socket); } g_free (c); vis->clientv[id] = NULL; xmms_log_info ("Removed visualization client %d", id); }
/* * Private stuff */ static CdIo_t * open_cd (xmms_xform_t *xform) { CdIo_t *cdio; xmms_config_property_t *val; const gchar *device; const gchar *accessmode; cdio_log_set_handler (log_handler); val = xmms_xform_config_lookup (xform, "device"); device = xmms_config_property_get_string (val); val = xmms_xform_config_lookup (xform, "accessmode"); accessmode = xmms_config_property_get_string (val); XMMS_DBG ("Trying to open device '%s', using '%s' access mode.", device, accessmode); if (g_ascii_strcasecmp (accessmode, "default") == 0) { cdio = cdio_open (device, DRIVER_UNKNOWN); } else { cdio = cdio_open_am (device, DRIVER_UNKNOWN, accessmode); } if (!cdio) { xmms_log_error ("Failed to open device '%s'.", device); } else { cdio_set_speed (cdio, 1); xmms_log_info ("Opened device '%s'.", device); } return cdio; }
void xmms_log_shutdown () { xmms_log_info ("Logging says bye bye :)"); g_free (logts_format); logts_format = NULL; }
static void xmms_id3v1_set (xmms_xform_t *xform, const char *key, const unsigned char *value, int len, const char *encoding) { gsize readsize,writsize; GError *err = NULL; gchar *tmp; /* property already set? */ /* if (xmms_xform_metadata_has_val (xform, key)) { return; } */ g_clear_error (&err); tmp = g_convert ((const char *)value, len, "UTF-8", encoding, &readsize, &writsize, &err); if (!tmp) { /* in case of not supported encoding, we try to fallback to latin1 */ xmms_log_info ("Converting ID3v1 tag '%s' failed (check id3v1_encoding property): %s", key, err ? err->message : "Error not set"); err = NULL; tmp = g_convert ((const char *)value, len, "UTF-8", "ISO8859-1", &readsize, &writsize, &err); } if (tmp) { g_strstrip (tmp); if (tmp[0] != '\0') { xmms_xform_metadata_set_str (xform, key, tmp); } g_free (tmp); } }
void xmms_log_init (gint verbosity) { g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL, xmms_log_handler, GINT_TO_POINTER (verbosity)); xmms_log_info ("Initialized logging system :)"); }
static gboolean xmms_gvfs_plugin_setup (xmms_xform_plugin_t *xform_plugin) { GVfs *vfs; const gchar * const *schemes, * const *i; gint j; xmms_xform_methods_t methods; g_type_init (); vfs = g_vfs_get_default (); if (!g_vfs_is_active (vfs)) { xmms_log_info ("GVfs not active - disabling gvfs transport"); return FALSE; } XMMS_XFORM_METHODS_INIT (methods); methods.init = xmms_gvfs_init; methods.destroy = xmms_gvfs_destroy; methods.read = xmms_gvfs_read; methods.seek = xmms_gvfs_seek; methods.browse = xmms_gvfs_browse; xmms_xform_plugin_methods_set (xform_plugin, &methods); xmms_xform_plugin_indata_add (xform_plugin, XMMS_STREAM_TYPE_MIMETYPE, "application/x-url", XMMS_STREAM_TYPE_URL, "file://*", XMMS_STREAM_TYPE_END); schemes = g_vfs_get_supported_uri_schemes (vfs); for (i = schemes; *i; i++) { gchar *tmp = g_strconcat (*i, "://*", NULL); gint priority = XMMS_STREAM_TYPE_PRIORITY_FALLBACK; for (j = 0; j < G_N_ELEMENTS (scheme_priorities); j++) { if (g_ascii_strcasecmp (scheme_priorities[j].scheme, *i) == 0) { priority = scheme_priorities[j].priority; } } xmms_xform_plugin_indata_add (xform_plugin, XMMS_STREAM_TYPE_PRIORITY, priority, XMMS_STREAM_TYPE_MIMETYPE, "application/x-url", XMMS_STREAM_TYPE_URL, tmp, XMMS_STREAM_TYPE_END); g_free (tmp); } return TRUE; }
/** * @internal Function to respond to the 'hello' sent from clients on connect */ static void xmms_main_client_hello (xmms_object_t *object, gint protocolver, const gchar *client, xmms_error_t *error) { if (protocolver != XMMS_IPC_PROTOCOL_VERSION) { xmms_log_info ("Client '%s' with bad protocol version (%d, not %d) connected", client, protocolver, XMMS_IPC_PROTOCOL_VERSION); xmms_error_set (error, XMMS_ERROR_INVAL, "Bad protocol version"); return; } XMMS_DBG ("Client '%s' connected", client); }
/** * Start the server */ gboolean xmms_ipc_setup_server (const gchar *path) { xmms_ipc_transport_t *transport; xmms_ipc_t *ipc; gchar **split; gint i = 0, num_init = 0; g_return_val_if_fail (path, FALSE); split = g_strsplit (path, ";", 0); for (i = 0; split && split[i]; i++) { ipc = g_new0 (xmms_ipc_t, 1); if (!ipc) { XMMS_DBG ("No IPC server initialized."); continue; } transport = xmms_ipc_server_init (split[i]); if (!transport) { g_free (ipc); xmms_log_error ("Couldn't setup IPC listening on '%s'.", split[i]); continue; } ipc->mutex_lock = g_mutex_new (); ipc->transport = transport; ipc->signals = ipc_object_pool->signals; ipc->broadcasts = ipc_object_pool->broadcasts; ipc->objects = ipc_object_pool->objects; xmms_ipc_setup_server_internaly (ipc); xmms_log_info ("IPC listening on '%s'.", split[i]); g_mutex_lock (ipc_servers_lock); ipc_servers = g_list_prepend (ipc_servers, ipc); g_mutex_unlock (ipc_servers_lock); num_init++; } g_strfreev (split); /* If there is less than one socket, there is sth. wrong. */ if (num_init < 1) return FALSE; XMMS_DBG ("IPC setup done."); return TRUE; }
static void chain_finalize (xmms_xform_t *xform, xmms_medialib_entry_t entry, const gchar *url, gboolean rehashing) { GString *namestr; namestr = g_string_new (""); xmms_xform_metadata_collect (xform, namestr, rehashing); xmms_log_info ("Successfully setup chain for '%s' (%d) containing %s", url, entry, namestr->str); g_string_free (namestr, TRUE); }
static xmms_xform_t * xmms_xform_new_effect (xmms_xform_t *last, xmms_medialib_entry_t entry, GList *goal_formats, const gchar *name) { xmms_plugin_t *plugin; xmms_xform_plugin_t *xform_plugin; xmms_xform_t *xform; gint priority; plugin = xmms_plugin_find (XMMS_PLUGIN_TYPE_XFORM, name); if (!plugin) { xmms_log_error ("Couldn't find any effect named '%s'", name); return last; } xform_plugin = (xmms_xform_plugin_t *) plugin; if (!xmms_xform_plugin_supports (xform_plugin, last->out_type, &priority)) { xmms_log_info ("Effect '%s' doesn't support format, skipping", xmms_plugin_shortname_get (plugin)); xmms_object_unref (plugin); return last; } xform = xmms_xform_new (xform_plugin, last, entry, goal_formats); if (xform) { xmms_object_unref (last); last = xform; } else { xmms_log_info ("Effect '%s' failed to initialize, skipping", xmms_plugin_shortname_get (plugin)); } xmms_xform_plugin_config_property_register (xform_plugin, "enabled", "0", NULL, NULL); xmms_object_unref (plugin); return last; }
static gint64 xmms_ofa_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *error) { xmms_ofa_data_t *data; data = xmms_xform_private_data_get (xform); if (data->run_ofa) { xmms_log_info ("Seeking requested, disabling ofa calculation!"); data->run_ofa = FALSE; } return xmms_xform_seek (xform, samples, whence, error); }
static void log_handler (cdio_log_level_t level, const char *message) { switch (level) { case CDIO_LOG_DEBUG: XMMS_DBG ("libcdio (%d): %s.", level, message); break; case CDIO_LOG_INFO: case CDIO_LOG_WARN: xmms_log_info ("libcdio (%d): %s.", level, message); break; default: xmms_log_error ("libcdio (%d): %s.", level, message); break; } }
/** * @internal Switch to using another output plugin * @param object An object * @param data The name of the output plugin to switch to * @param userdata The #xmms_main_t object */ static void change_output (xmms_object_t *object, xmmsv_t *_data, gpointer userdata) { xmms_output_plugin_t *plugin; xmms_main_t *mainobj = (xmms_main_t*)userdata; const gchar *outname; if (!mainobj->output) return; outname = xmms_config_property_get_string ((xmms_config_property_t *) object); xmms_log_info ("Switching to output %s", outname); plugin = (xmms_output_plugin_t *)xmms_plugin_find (XMMS_PLUGIN_TYPE_OUTPUT, outname); if (!plugin) { xmms_log_error ("Baaaaad output plugin, try to change the output.plugin config variable to something usefull"); } else { if (!xmms_output_plugin_switch (mainobj->output, plugin)) { xmms_log_error ("Baaaaad output plugin, try to change the output.plugin config variable to something usefull"); } } }
static void install_scripts (const gchar *into_dir) { GDir *dir; GError *err = NULL; gchar path[PATH_MAX]; const gchar *f; gchar *s; s = strrchr (into_dir, G_DIR_SEPARATOR); if (!s) return; s++; g_snprintf (path, PATH_MAX, "%s/scripts/%s", SHAREDDIR, s); xmms_log_info ("Installing scripts from %s", path); dir = g_dir_open (path, 0, &err); if (!dir) { xmms_log_error ("Global script directory not found"); return; } while ((f = g_dir_read_name (dir))) { gchar *source = g_strdup_printf ("%s/%s", path, f); gchar *dest = g_strdup_printf ("%s/%s", into_dir, f); if (!xmms_symlink_file (source, dest)) { g_free (source); g_free (dest); break; } g_free (source); g_free (dest); } g_dir_close (dir); }
/* create an uninitialised vis client. don't use this method without mutex! */ static int32_t create_client (void) { int32_t id; for (id = 0; id < vis->clientc; ++id) { if (!vis->clientv[id]) { break; } } if (id == vis->clientc) { vis->clientc++; } vis->clientv = g_renew (xmms_vis_client_t*, vis->clientv, vis->clientc); if (!vis->clientv || (!(vis->clientv[id] = g_new (xmms_vis_client_t, 1)))) { vis->clientc = 0; id = -1; } xmms_log_info ("Attached visualization client %d", id); return id; }
static gboolean xmms_wave_init (xmms_xform_t *xform) { xmms_wave_data_t *data; xmms_error_t error; xmms_sample_format_t sample_fmt; xmms_wave_format_t fmt; guint8 buf[1024]; gint read; g_return_val_if_fail (xform, FALSE); data = g_new0 (xmms_wave_data_t, 1); g_return_val_if_fail (data, FALSE); xmms_xform_private_data_set (xform, data); read = xmms_xform_peek (xform, (gchar *) buf, sizeof (buf), &error); if (read < WAVE_HEADER_MIN_SIZE) { xmms_log_error ("Could not read wave header"); return FALSE; } fmt = read_wave_header (data, buf, read); switch (fmt) { case WAVE_FORMAT_UNDEFINED: xmms_log_error ("Not a valid Wave stream"); return FALSE; case WAVE_FORMAT_MP3: xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE, "audio/mpeg", XMMS_STREAM_TYPE_END); break; case WAVE_FORMAT_PCM: xmms_wave_get_media_info (xform); if (read < data->header_size) { xmms_log_info ("Wave header too big?"); return FALSE; } /* skip over the header */ xmms_xform_read (xform, (gchar *) buf, data->header_size, &error); sample_fmt = (data->bits_per_sample == 8 ? XMMS_SAMPLE_FORMAT_U8 : XMMS_SAMPLE_FORMAT_S16); xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE, "audio/pcm", XMMS_STREAM_TYPE_FMT_FORMAT, sample_fmt, XMMS_STREAM_TYPE_FMT_CHANNELS, data->channels, XMMS_STREAM_TYPE_FMT_SAMPLERATE, data->samplerate, XMMS_STREAM_TYPE_END); } return TRUE; }
static xmms_wave_format_t read_wave_header (xmms_wave_data_t *data, guint8 *buf, gint bytes_read) { gchar stmp[5]; guint32 tmp32, data_size; guint16 tmp16; gint bytes_left = bytes_read; xmms_wave_format_t ret = WAVE_FORMAT_UNDEFINED; if (bytes_left < WAVE_HEADER_MIN_SIZE) { xmms_log_error ("Not enough data for wave header"); return ret; } GET_STR (buf, stmp, 4); if (strcmp (stmp, "RIFF")) { xmms_log_error ("No RIFF data"); return ret; } GET_32 (buf, data_size); data_size += 8; GET_STR (buf, stmp, 4); if (strcmp (stmp, "WAVE")) { xmms_log_error ("No Wave data"); return ret; } GET_STR (buf, stmp, 4); if (strcmp (stmp, "fmt ")) { xmms_log_error ("Format chunk missing"); return ret; } GET_32 (buf, tmp32); /* format chunk length */ XMMS_DBG ("format chunk length: %i", tmp32); GET_16 (buf, tmp16); /* format tag */ ret = tmp16; switch (tmp16) { case WAVE_FORMAT_PCM: if (tmp32 != 16) { xmms_log_error ("Format chunk length not 16."); return WAVE_FORMAT_UNDEFINED; } GET_16 (buf, data->channels); XMMS_DBG ("channels %i", data->channels); if (data->channels < 1 || data->channels > 2) { xmms_log_error ("Unhandled number of channels: %i", data->channels); return WAVE_FORMAT_UNDEFINED; } GET_32 (buf, data->samplerate); XMMS_DBG ("samplerate %i", data->samplerate); if (data->samplerate != 8000 && data->samplerate != 11025 && data->samplerate != 22050 && data->samplerate != 44100) { xmms_log_error ("Invalid samplerate: %i", data->samplerate); return WAVE_FORMAT_UNDEFINED; } GET_32 (buf, tmp32); GET_16 (buf, tmp16); GET_16 (buf, data->bits_per_sample); XMMS_DBG ("bits per sample %i", data->bits_per_sample); if (data->bits_per_sample != 8 && data->bits_per_sample != 16) { xmms_log_error ("Unhandled bits per sample: %i", data->bits_per_sample); return WAVE_FORMAT_UNDEFINED; } break; case WAVE_FORMAT_MP3: SKIP (tmp32 - sizeof (tmp16)); /* set up so that seeking works with "bytes" as seek unit */ data->bits_per_sample = 8; data->channels = 1; break; default: xmms_log_error ("unhandled format tag: 0x%x", tmp16); return WAVE_FORMAT_UNDEFINED; } GET_STR (buf, stmp, 4); while (strcmp (stmp, "data")) { GET_32 (buf, tmp32); if (bytes_left < (tmp32 + 8)) { xmms_log_error ("Data chunk missing"); return WAVE_FORMAT_UNDEFINED; } buf += tmp32; bytes_left -= tmp32; GET_STR (buf, stmp, 4); } GET_32 (buf, data->bytes_total); data->header_size = bytes_read - bytes_left; if (data->bytes_total + data->header_size != data_size) { xmms_log_info ("Data chunk size doesn't match RIFF chunk size"); /* don't return FALSE here, we try to read it anyway */ } return ret; }
static gboolean xmms_gvfs_init (xmms_xform_t *xform) { xmms_gvfs_data_t *data; GFile *file; GFileInfo *info; GFileInputStream *handle; GError *error = NULL; const gchar *url; url = xmms_xform_indata_get_str (xform, XMMS_STREAM_TYPE_URL); g_return_val_if_fail (url, FALSE); /* This is an ugly hack to handle files with chars needing url encoding */ if (!g_ascii_strncasecmp (url, "file://", 7)) { file = g_file_new_for_path (url+7); } else { file = g_file_new_for_uri (url); } handle = g_file_read (file, NULL, &error); g_object_unref (file); if (!handle) { xmms_log_error ("Failed to upen url %s for reading: %s", url, error->message); return FALSE; } data = g_new (xmms_gvfs_data_t, 1); data->handle = G_INPUT_STREAM (handle); xmms_xform_private_data_set (xform, data); info = g_file_input_stream_query_info (handle, (char *)query_attributes, NULL, &error); if (!info) { xmms_log_info ("failed to query information for %s", url); } else { int i; for (i = 0; i < G_N_ELEMENTS (attr_map); i++) { if (!g_file_info_has_attribute (info, attr_map[i].gvfs)) { continue; } switch (attr_map[i].type) { case XMMSV_TYPE_STRING: { gchar *attr = g_file_info_get_attribute_as_string (info, attr_map[i].gvfs); xmms_xform_metadata_set_str (xform, attr_map[i].mlib, attr); g_free (attr); break; } case XMMSV_TYPE_INT32: { /* right now the xform metadata api only handles strings * and 32 bit ints. however the gvfs api returns uint64 for * the numeric attributes we're interested in and we just * pass that to the xform and pray that it doesn't overflow * as we know it's unsafe. */ gint64 attr = g_file_info_get_attribute_uint64 (info, attr_map[i].gvfs); xmms_xform_metadata_set_int (xform, attr_map[i].mlib, attr); break; } default: g_assert_not_reached (); } } g_object_unref (info); } xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE, "application/octet-stream", XMMS_STREAM_TYPE_END); return TRUE; }
int32_t init_udp (xmms_visualization_t *vis, int32_t id, xmms_error_t *err) { // TODO: we need the currently used port, not only the default one! */ int32_t port = XMMS_DEFAULT_TCP_PORT; xmms_vis_client_t *c; // setup socket if needed if (!xmms_socket_valid (vis->socket)) { struct addrinfo hints; struct addrinfo *result, *rp; int s; memset (&hints, 0, sizeof (hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; hints.ai_protocol = 0; if ((s = getaddrinfo (NULL, G_STRINGIFY (XMMS_DEFAULT_TCP_PORT), &hints, &result)) != 0) { xmms_log_error ("Could not setup socket! getaddrinfo: %s", gai_strerror (s)); xmms_error_set (err, XMMS_ERROR_NO_SAUSAGE, "Could not setup socket!"); return -1; } for (rp = result; rp != NULL; rp = rp->ai_next) { vis->socket = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (!xmms_socket_valid (vis->socket)) { continue; } if (bind (vis->socket, rp->ai_addr, rp->ai_addrlen) != -1) { break; } else { close (vis->socket); } } if (rp == NULL) { xmms_log_error ("Could not bind socket!"); xmms_error_set (err, XMMS_ERROR_NO_SAUSAGE, "Could not bind socket!"); freeaddrinfo (result); return -1; } freeaddrinfo (result); /* register into mainloop: */ /* perhaps needed, perhaps not .. #ifdef __WIN32__ vis->socketio = g_io_channel_win32_new_socket (vis->socket); #else */ vis->socketio = g_io_channel_unix_new (vis->socket); /*#endif */ g_io_channel_set_encoding (vis->socketio, NULL, NULL); g_io_channel_set_buffered (vis->socketio, FALSE); g_io_add_watch (vis->socketio, G_IO_IN, (GIOFunc) udpwatcher, vis); } /* set up client structure */ x_fetch_client (id); c->type = VIS_UDP; memset (&c->transport.udp.addr, 0, sizeof (c->transport.udp.addr)); c->transport.udp.socket[0] = 0; x_release_client (); xmms_log_info ("Visualization client %d initialised using UDP", id); return port; }
xmms_xing_t * xmms_xing_parse (struct mad_bitptr ptr) { xmms_xing_t *xing; guint32 xing_magic; xing_magic = mad_bit_read (&ptr, 4*8); /* Xing or Info */ if (xing_magic != 0x58696e67 && xing_magic != 0x496e666f) { return NULL; } xing = g_new0 (xmms_xing_t, 1); g_return_val_if_fail (xing, NULL); xing->flags = mad_bit_read (&ptr, 32); if (xmms_xing_has_flag (xing, XMMS_XING_FRAMES)) xing->frames = mad_bit_read (&ptr, 32); if (xmms_xing_has_flag (xing, XMMS_XING_BYTES)) xing->bytes = mad_bit_read (&ptr, 32); if (xmms_xing_has_flag (xing, XMMS_XING_TOC)) { gint i; for (i = 0; i < 100; i++) xing->toc[i] = mad_bit_read (&ptr, 8); } if (xmms_xing_has_flag (xing, XMMS_XING_SCALE)) { /* just move the pointer forward */ mad_bit_read (&ptr, 32); } xing->lame = parse_lame (&ptr); /* if (strncmp ((gchar *)ptr.byte, "LAME", 4) == 0) { lame = g_new0 (xmms_xing_lame_t, 1); XMMS_DBG ("Parsing LAME tag"); mad_bit_skip (&ptr, 4 * 8); mad_bit_nextbyte (&ptr); mad_bit_skip (&ptr, (8 * 5) + 12); lame->peak_amplitude = mad_bit_read (&ptr, 32); lame->radio_gain = mad_bit_read (&ptr, 16); lame->audiophile_gain = mad_bit_read (&ptr, 16); mad_bit_skip (&ptr, 16); lame->encoder_delay_start = mad_bit_read (&ptr, 12); lame->encoder_delay_stop = mad_bit_read (&ptr, 12); mad_bit_skip (&ptr, 8); lame->mp3_gain = mad_bit_read (&ptr, 8); xing->lame = lame; } */ if (xmms_xing_has_flag (xing, XMMS_XING_FRAMES) && xing->frames == 0) { xmms_log_info ("Corrupt xing header (frames == 0), ignoring"); xmms_xing_free (xing); return NULL; } if (xmms_xing_has_flag (xing, XMMS_XING_BYTES) && xing->bytes == 0) { xmms_log_info ("Corrupt xing header (bytes == 0), ignoring"); xmms_xing_free (xing); return NULL; } if (xmms_xing_has_flag (xing, XMMS_XING_TOC)) { gint i; for (i = 0; i < 99; i++) { if (xing->toc[i] > xing->toc[i + 1]) { xmms_log_info ("Corrupt xing header (toc not monotonic), ignoring"); xmms_xing_free (xing); return NULL; } } } return xing; }
/** * The xmms2 daemon main initialisation function */ int main (int argc, char **argv) { xmms_output_plugin_t *o_plugin; xmms_config_property_t *cv; xmms_main_t *mainobj; int loglevel = 1; xmms_playlist_t *playlist; gchar default_path[XMMS_PATH_MAX + 16], *tmp; gboolean verbose = FALSE; gboolean quiet = FALSE; gboolean version = FALSE; gboolean nologging = FALSE; gboolean runasroot = FALSE; gboolean showhelp = FALSE; const gchar *outname = NULL; const gchar *ipcpath = NULL; gchar *ppath = NULL; int status_fd = -1; GOptionContext *context = NULL; GError *error = NULL; setlocale (LC_ALL, ""); /** * The options that the server accepts. */ GOptionEntry opts[] = { {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Increase verbosity", NULL}, {"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, "Decrease verbosity", NULL}, {"version", 'V', 0, G_OPTION_ARG_NONE, &version, "Print version", NULL}, {"no-logging", 'n', 0, G_OPTION_ARG_NONE, &nologging, "Disable logging", NULL}, {"output", 'o', 0, G_OPTION_ARG_STRING, &outname, "Use 'x' as output plugin", "<x>"}, {"ipc-socket", 'i', 0, G_OPTION_ARG_FILENAME, &ipcpath, "Listen to socket 'url'", "<url>"}, {"plugindir", 'p', 0, G_OPTION_ARG_FILENAME, &ppath, "Search for plugins in directory 'foo'", "<foo>"}, {"conf", 'c', 0, G_OPTION_ARG_FILENAME, &conffile, "Specify alternate configuration file", "<file>"}, {"status-fd", 's', 0, G_OPTION_ARG_INT, &status_fd, "Specify a filedescriptor to write to when started", "fd"}, {"yes-run-as-root", 0, 0, G_OPTION_ARG_NONE, &runasroot, "Give me enough rope to shoot myself in the foot", NULL}, {"show-help", 'h', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &showhelp, "Use --help or -? instead", NULL}, {NULL} }; /** Check that we are running against the correct glib version */ if (glib_major_version != GLIB_MAJOR_VERSION || glib_minor_version < GLIB_MINOR_VERSION) { g_print ("xmms2d is build against version %d.%d,\n" "but is (runtime) linked against %d.%d.\n" "Refusing to start.\n", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, glib_major_version, glib_minor_version); exit (EXIT_FAILURE); } xmms_signal_block (); context = g_option_context_new ("- XMMS2 Daemon"); g_option_context_add_main_entries (context, opts, NULL); if (!g_option_context_parse (context, &argc, &argv, &error) || error) { g_print ("Error parsing options: %s\n", error->message); g_clear_error (&error); exit (EXIT_FAILURE); } if (showhelp) { #if GLIB_CHECK_VERSION(2,14,0) g_print ("%s", g_option_context_get_help (context, TRUE, NULL)); exit (EXIT_SUCCESS); #else g_print ("Please use --help or -? for help\n"); exit (EXIT_FAILURE); #endif } g_option_context_free (context); if (argc != 1) { g_print ("There were unknown options, aborting!\n"); exit (EXIT_FAILURE); } if (xmms_checkroot ()) { if (runasroot) { g_print ("***************************************\n"); g_print ("Warning! You are running XMMS2D as root, this is a bad idea!\nBut I'll allow it since you asked nicely.\n"); g_print ("***************************************\n\n"); } else { g_print ("PLEASE DON'T RUN XMMS2D AS ROOT!\n\n(if you really must, read the help)\n"); exit (EXIT_FAILURE); } } if (verbose) { loglevel++; } else if (quiet) { loglevel--; } if (version) { print_version (); } g_thread_init (NULL); g_random_set_seed (time (NULL)); xmms_log_init (loglevel); xmms_ipc_init (); load_config (); cv = xmms_config_property_register ("core.logtsfmt", "%H:%M:%S ", NULL, NULL); xmms_log_set_format (xmms_config_property_get_string (cv)); xmms_fallback_ipcpath_get (default_path, sizeof (default_path)); cv = xmms_config_property_register ("core.ipcsocket", default_path, on_config_ipcsocket_change, NULL); if (!ipcpath) { /* * if not ipcpath is specifed on the cmd line we * grab it from the config */ ipcpath = xmms_config_property_get_string (cv); } if (!xmms_ipc_setup_server (ipcpath)) { xmms_ipc_shutdown (); xmms_log_fatal ("IPC failed to init!"); } if (!xmms_plugin_init (ppath)) { return 1; } playlist = xmms_playlist_init (); xform_obj = xmms_xform_object_init (); bindata_obj = xmms_bindata_init (); mainobj = xmms_object_new (xmms_main_t, xmms_main_destroy); /* find output plugin. */ cv = xmms_config_property_register ("output.plugin", XMMS_OUTPUT_DEFAULT, change_output, mainobj); if (outname) { xmms_config_property_set_data (cv, outname); } outname = xmms_config_property_get_string (cv); xmms_log_info ("Using output plugin: %s", outname); o_plugin = (xmms_output_plugin_t *)xmms_plugin_find (XMMS_PLUGIN_TYPE_OUTPUT, outname); if (!o_plugin) { xmms_log_error ("Baaaaad output plugin, try to change the" "output.plugin config variable to something usefull"); } mainobj->output = xmms_output_new (o_plugin, playlist); if (!mainobj->output) { xmms_log_fatal ("Failed to create output object!"); } mainobj->vis = xmms_visualization_new (mainobj->output); if (status_fd != -1) { write (status_fd, "+", 1); } xmms_signal_init (XMMS_OBJECT (mainobj)); xmms_ipc_object_register (XMMS_IPC_OBJECT_MAIN, XMMS_OBJECT (mainobj)); xmms_ipc_broadcast_register (XMMS_OBJECT (mainobj), XMMS_IPC_SIGNAL_QUIT); xmms_object_cmd_add (XMMS_OBJECT (mainobj), XMMS_IPC_CMD_QUIT, XMMS_CMD_FUNC (quit)); xmms_object_cmd_add (XMMS_OBJECT (mainobj), XMMS_IPC_CMD_HELLO, XMMS_CMD_FUNC (hello)); xmms_object_cmd_add (XMMS_OBJECT (mainobj), XMMS_IPC_CMD_PLUGIN_LIST, XMMS_CMD_FUNC (plugin_list)); xmms_object_cmd_add (XMMS_OBJECT (mainobj), XMMS_IPC_CMD_STATS, XMMS_CMD_FUNC (stats)); /* Save the time we started in order to count uptime */ mainobj->starttime = time (NULL); /* Dirty hack to tell XMMS_PATH a valid path */ g_strlcpy (default_path, ipcpath, sizeof (default_path)); tmp = strchr (default_path, ';'); if (tmp) { *tmp = '\0'; } g_setenv ("XMMS_PATH", default_path, TRUE); /* Also put the full path for clients that understands */ g_setenv("XMMS_PATH_FULL", ipcpath, TRUE); tmp = XMMS_BUILD_PATH ("shutdown.d"); cv = xmms_config_property_register ("core.shutdownpath", tmp, NULL, NULL); g_free (tmp); tmp = XMMS_BUILD_PATH ("startup.d"); cv = xmms_config_property_register ("core.startuppath", tmp, NULL, NULL); g_free (tmp); /* Startup dir */ do_scriptdir (xmms_config_property_get_string (cv), "start"); mainloop = g_main_loop_new (NULL, FALSE); g_main_loop_run (mainloop); return 0; }
static void xmms_sid_get_songlength (xmms_xform_t *xform) { xmms_config_property_t *config; const gchar *tmp, *md5sum, *songlength_path; gint subtune = 1; GIOChannel* io; GString *buf; g_return_if_fail (xform); config = xmms_xform_config_lookup (xform, "songlength_path"); g_return_if_fail (config); songlength_path = xmms_config_property_get_string (config); if (!songlength_path[0]) return; if (xmms_xform_metadata_get_str (xform, "subtune", &tmp)) { subtune = atoi (tmp); } if (!xmms_xform_metadata_get_str (xform, "HVSCfingerprint", &md5sum)) { return; } io = g_io_channel_new_file (songlength_path, "r", NULL); if (!io) { xmms_log_error ("Unable to load songlengths database '%s'", songlength_path); return; } buf = g_string_new (""); while (g_io_channel_read_line_string (io, buf, NULL, NULL) == G_IO_STATUS_NORMAL) { if (buf->len > 33 && g_ascii_strncasecmp (buf->str, md5sum, 32) == 0) { gint cur = 0; gchar *b; b = buf->str + 33; while (*b) { gint min, sec; /* read timestamp */ if (sscanf (b, "%d:%d", &min, &sec) != 2) { /* no more timestamps on this line */ break; } else { cur++; } if (cur == subtune) { const gchar *metakey; gchar ms_str[10 + 1]; /* LONG_MAX in str, \w NULL */ glong ms; ms = (min * 60 + sec) * 1000; metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION; xmms_xform_metadata_set_int (xform, metakey, ms); if (g_snprintf (ms_str, 10 + 1, "%ld", ms) > 0) { metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_STARTMS; xmms_xform_metadata_set_str (xform, metakey, "0"); metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_STOPMS; xmms_xform_metadata_set_str (xform, metakey, ms_str); } goto done; } /* forward to next possible timestamp */ b = strchr (b, ' '); if (!b) { /* no more timestamps on this line */ break; } b++; } } } xmms_log_info ("Couldn't find sid tune in songlength.txt"); done: g_io_channel_unref (io); }