Bug Summary

File:build-analysis/../src/xmms/main.c
Warning:line 723, column 2
Value stored to 'cv' is never read

Annotated Source Code

1/* XMMS2 - X Music Multiplexer System
2 * Copyright (C) 2003-2017 XMMS2 Team
3 *
4 * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 */
16
17/**
18 * @mainpage
19 * @image html pixmaps/xmms2-128.png
20 */
21
22/** @file
23 * This file controls the XMMS2 main loop.
24 */
25
26#include <locale.h>
27#include <glib.h>
28
29#include <xmms_configuration.h>
30#include <xmmsc/xmmsc_util.h>
31#include <xmmspriv/xmms_plugin.h>
32#include <xmmspriv/xmms_config.h>
33#include <xmmspriv/xmms_courier.h>
34#include <xmmspriv/xmms_playlist.h>
35#include <xmmspriv/xmms_playlist_updater.h>
36#include <xmmspriv/xmms_collsync.h>
37#include <xmmspriv/xmms_collection.h>
38#include <xmmspriv/xmms_signal.h>
39#include <xmmspriv/xmms_symlink.h>
40#include <xmmspriv/xmms_checkroot.h>
41#include <xmmspriv/xmms_thread_name.h>
42#include <xmmspriv/xmms_medialib.h>
43#include <xmmspriv/xmms_mediainfo.h>
44#include <xmmspriv/xmms_output.h>
45#include <xmmspriv/xmms_ipc.h>
46#include <xmmspriv/xmms_log.h>
47#include <xmmspriv/xmms_xform_object.h>
48#include <xmmspriv/xmms_bindata.h>
49#include <xmmspriv/xmms_utils.h>
50#include <xmmspriv/xmms_visualization.h>
51
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55#include <unistd.h>
56#include <signal.h>
57#include <sys/stat.h>
58#include <fcntl.h>
59
60/*
61 * Forward declarations of the methods in the main object
62 */
63static void xmms_main_client_quit (xmms_object_t *object, xmms_error_t *error);
64static xmmsv_t *xmms_main_client_stats (xmms_object_t *object, xmms_error_t *error);
65static xmmsv_t *xmms_main_client_list_plugins (xmms_object_t *main, gint32 type, xmms_error_t *err);
66static gint64 xmms_main_client_hello (xmms_object_t *object, gint protocolver, const gchar *client, gint64 id, xmms_error_t *error);
67static void install_scripts (const gchar *into_dir);
68static void spawn_script_setup (gpointer data);
69
70#include "main_ipc.c"
71
72/** @defgroup XMMSServer XMMSServer
73 * @brief look at this if you want to code inside the server.
74 * The XMMS2 project is split into a server and a multiple clients.
75 * This documents the server part.
76 */
77
78/**
79 * @defgroup Main Main
80 * @ingroup XMMSServer
81 * @brief main object
82 * @{
83 */
84
85
86/**
87 * Main object, when this is unreffed, XMMS2 is quiting.
88 */
89struct xmms_main_St {
90 xmms_object_t object;
91 xmms_output_t *output_object;
92 xmms_bindata_t *bindata_object;
93 xmms_coll_dag_t *colldag_object;
94 xmms_medialib_t *medialib_object;
95 xmms_playlist_t *playlist_object;
96 xmms_coll_sync_t *collsync_object;
97 xmms_playlist_updater_t *plsupdater_object;
98 xmms_xform_object_t *xform_object;
99 xmms_mediainfo_reader_t *mediainfo_object;
100 xmms_visualization_t *visualization_object;
101 xmms_courier_t *courier_object;
102 time_t starttime;
103};
104
105typedef struct xmms_main_St xmms_main_t;
106
107/** This is the mainloop of the xmms2 server */
108static GMainLoop *mainloop;
109
110/** The path of the configfile */
111static gchar *conffile = NULL((void*)0);
112
113static void
114query_total_size_duration (xmms_main_t *mainobj, xmms_error_t *error,
115 int64_t *size, int64_t *duration)
116{
117 xmmsv_t *coll, *universe, *spec, *ret;
118 xmms_medialib_session_t *session;
119
120 /* Fetch the size in bytes and duration in milliseconds for the whole media library */
121 universe = xmmsv_new_coll (XMMS_COLLECTION_TYPE_UNIVERSE);
122
123 coll = xmmsv_new_coll (XMMS_COLLECTION_TYPE_MATCH);
124 xmmsv_coll_attribute_set_string (coll, "field", "status");
125 xmmsv_coll_attribute_set_string (coll, "value", "1");
126 xmmsv_coll_add_operand (coll, universe);
127 xmmsv_unref (universe);
128
129 spec = xmmsv_build_dict (
130 XMMSV_DICT_ENTRY_STR ("type", "metadata")__xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata")))
,
131 XMMSV_DICT_ENTRY ("fields", xmmsv_build_list (__xmmsv_identity_const_charp ("fields"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("duration"))), __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("size"))), ((void*)0)))
132 XMMSV_LIST_ENTRY_STR ("duration"),__xmmsv_identity_const_charp ("fields"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("duration"))), __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("size"))), ((void*)0)))
133 XMMSV_LIST_ENTRY_STR ("size"),__xmmsv_identity_const_charp ("fields"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("duration"))), __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("size"))), ((void*)0)))
134 XMMSV_LIST_END))__xmmsv_identity_const_charp ("fields"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("duration"))), __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("size"))), ((void*)0)))
,
135 XMMSV_DICT_ENTRY ("get", xmmsv_build_list (__xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv (
xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("field"))), __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0)))
136 XMMSV_LIST_ENTRY_STR ("field"),__xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv (
xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("field"))), __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0)))
137 XMMSV_LIST_ENTRY_STR ("value"),__xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv (
xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("field"))), __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0)))
138 XMMSV_LIST_END))__xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv (
xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("field"))), __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0)))
,
139 XMMSV_DICT_ENTRY_STR ("aggregate", "sum")__xmmsv_identity_const_charp ("aggregate"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("sum")))
,
140 XMMSV_DICT_END((void*)0));
141
142 do {
143 session = xmms_medialib_session_begin_ro (mainobj->medialib_object);
144 ret = xmms_medialib_query (session, coll, spec, error);
145 } while (!xmms_medialib_session_commit (session));
146
147 xmmsv_dict_entry_get_int64 (ret, "size", size);
148 xmmsv_dict_entry_get_int64 (ret, "duration", duration);
149
150 xmmsv_unref (spec);
151 xmmsv_unref (ret);
152}
153
154static void
155query_total_playtime (xmms_main_t *mainobj, xmms_error_t *error,
156 int64_t *playtime)
157{
158 xmmsv_t *coll, *universe, *spec, *ret, *value;
159 xmms_medialib_session_t *session;
160 xmmsv_dict_iter_t *iter;
161 const gchar *key;
162
163 /* Fetch the sum of duration clustered by timesplayed, for timesplayed > 0 */
164 universe = xmmsv_new_coll (XMMS_COLLECTION_TYPE_UNIVERSE);
165
166 coll = xmmsv_new_coll (XMMS_COLLECTION_TYPE_GREATER);
167 xmmsv_coll_attribute_set_string (coll, "field", "timesplayed");
168 xmmsv_coll_attribute_set_string (coll, "value", "0");
169 xmmsv_coll_add_operand (coll, universe);
170 xmmsv_unref (universe);
171
172 spec = xmmsv_build_dict (
173 XMMSV_DICT_ENTRY_STR ("type", "cluster-dict")__xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("cluster-dict")))
,
174 XMMSV_DICT_ENTRY_STR ("cluster-by", "value")__xmmsv_identity_const_charp ("cluster-by"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("value")))
,
175 XMMSV_DICT_ENTRY_STR ("cluster-field", "timesplayed")__xmmsv_identity_const_charp ("cluster-field"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("timesplayed")))
,
176 XMMSV_DICT_ENTRY ("data", xmmsv_build_dict (__xmmsv_identity_const_charp ("data"), __xmmsv_identity_xmmsv
(xmmsv_build_dict ( __xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata"))), __xmmsv_identity_const_charp
("fields"), __xmmsv_identity_xmmsv (xmmsv_build_list ( __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("duration"))), ((void
*)0))), __xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0))), __xmmsv_identity_const_charp
("aggregate"), __xmmsv_identity_xmmsv (__xmmsv_null_to_none (
xmmsv_new_string ("sum"))), ((void*)0)))
177 XMMSV_DICT_ENTRY_STR ("type", "metadata"),__xmmsv_identity_const_charp ("data"), __xmmsv_identity_xmmsv
(xmmsv_build_dict ( __xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata"))), __xmmsv_identity_const_charp
("fields"), __xmmsv_identity_xmmsv (xmmsv_build_list ( __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("duration"))), ((void
*)0))), __xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0))), __xmmsv_identity_const_charp
("aggregate"), __xmmsv_identity_xmmsv (__xmmsv_null_to_none (
xmmsv_new_string ("sum"))), ((void*)0)))
178 XMMSV_DICT_ENTRY ("fields", xmmsv_build_list (__xmmsv_identity_const_charp ("data"), __xmmsv_identity_xmmsv
(xmmsv_build_dict ( __xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata"))), __xmmsv_identity_const_charp
("fields"), __xmmsv_identity_xmmsv (xmmsv_build_list ( __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("duration"))), ((void
*)0))), __xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0))), __xmmsv_identity_const_charp
("aggregate"), __xmmsv_identity_xmmsv (__xmmsv_null_to_none (
xmmsv_new_string ("sum"))), ((void*)0)))
179 XMMSV_LIST_ENTRY_STR ("duration"),__xmmsv_identity_const_charp ("data"), __xmmsv_identity_xmmsv
(xmmsv_build_dict ( __xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata"))), __xmmsv_identity_const_charp
("fields"), __xmmsv_identity_xmmsv (xmmsv_build_list ( __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("duration"))), ((void
*)0))), __xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0))), __xmmsv_identity_const_charp
("aggregate"), __xmmsv_identity_xmmsv (__xmmsv_null_to_none (
xmmsv_new_string ("sum"))), ((void*)0)))
180 XMMSV_LIST_END)),__xmmsv_identity_const_charp ("data"), __xmmsv_identity_xmmsv
(xmmsv_build_dict ( __xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata"))), __xmmsv_identity_const_charp
("fields"), __xmmsv_identity_xmmsv (xmmsv_build_list ( __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("duration"))), ((void
*)0))), __xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0))), __xmmsv_identity_const_charp
("aggregate"), __xmmsv_identity_xmmsv (__xmmsv_null_to_none (
xmmsv_new_string ("sum"))), ((void*)0)))
181 XMMSV_DICT_ENTRY ("get", xmmsv_build_list (__xmmsv_identity_const_charp ("data"), __xmmsv_identity_xmmsv
(xmmsv_build_dict ( __xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata"))), __xmmsv_identity_const_charp
("fields"), __xmmsv_identity_xmmsv (xmmsv_build_list ( __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("duration"))), ((void
*)0))), __xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0))), __xmmsv_identity_const_charp
("aggregate"), __xmmsv_identity_xmmsv (__xmmsv_null_to_none (
xmmsv_new_string ("sum"))), ((void*)0)))
182 XMMSV_LIST_ENTRY_STR ("value"),__xmmsv_identity_const_charp ("data"), __xmmsv_identity_xmmsv
(xmmsv_build_dict ( __xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata"))), __xmmsv_identity_const_charp
("fields"), __xmmsv_identity_xmmsv (xmmsv_build_list ( __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("duration"))), ((void
*)0))), __xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0))), __xmmsv_identity_const_charp
("aggregate"), __xmmsv_identity_xmmsv (__xmmsv_null_to_none (
xmmsv_new_string ("sum"))), ((void*)0)))
183 XMMSV_LIST_END)),__xmmsv_identity_const_charp ("data"), __xmmsv_identity_xmmsv
(xmmsv_build_dict ( __xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata"))), __xmmsv_identity_const_charp
("fields"), __xmmsv_identity_xmmsv (xmmsv_build_list ( __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("duration"))), ((void
*)0))), __xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0))), __xmmsv_identity_const_charp
("aggregate"), __xmmsv_identity_xmmsv (__xmmsv_null_to_none (
xmmsv_new_string ("sum"))), ((void*)0)))
184 XMMSV_DICT_ENTRY_STR ("aggregate", "sum"),__xmmsv_identity_const_charp ("data"), __xmmsv_identity_xmmsv
(xmmsv_build_dict ( __xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata"))), __xmmsv_identity_const_charp
("fields"), __xmmsv_identity_xmmsv (xmmsv_build_list ( __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("duration"))), ((void
*)0))), __xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0))), __xmmsv_identity_const_charp
("aggregate"), __xmmsv_identity_xmmsv (__xmmsv_null_to_none (
xmmsv_new_string ("sum"))), ((void*)0)))
185 XMMSV_DICT_END))__xmmsv_identity_const_charp ("data"), __xmmsv_identity_xmmsv
(xmmsv_build_dict ( __xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("metadata"))), __xmmsv_identity_const_charp
("fields"), __xmmsv_identity_xmmsv (xmmsv_build_list ( __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("duration"))), ((void
*)0))), __xmmsv_identity_const_charp ("get"), __xmmsv_identity_xmmsv
(xmmsv_build_list ( __xmmsv_identity_xmmsv (__xmmsv_null_to_none
(xmmsv_new_string ("value"))), ((void*)0))), __xmmsv_identity_const_charp
("aggregate"), __xmmsv_identity_xmmsv (__xmmsv_null_to_none (
xmmsv_new_string ("sum"))), ((void*)0)))
,
186 XMMSV_DICT_END((void*)0));
187
188 do {
189 session = xmms_medialib_session_begin_ro (mainobj->medialib_object);
190 ret = xmms_medialib_query (session, coll, spec, error);
191 } while (!xmms_medialib_session_commit (session));
192
193 xmmsv_get_dict_iter (ret, &iter);
194 while (xmmsv_dict_iter_pair (iter, &key, &value)) {
195 int64_t sum, timesplayed;
196 gchar *endptr = NULL((void*)0);
197
198 if (xmmsv_get_int64 (value, &sum)) {
199 timesplayed = strtol (key, &endptr, 10);
200 if (*endptr == '\0')
201 *playtime += timesplayed * sum;
202 }
203
204 xmmsv_dict_iter_next (iter);
205 }
206
207 xmmsv_unref (spec);
208 xmmsv_unref (ret);
209}
210
211/**
212 * This returns the main stats for the server
213 */
214static xmmsv_t *
215xmms_main_client_stats (xmms_object_t *object, xmms_error_t *error)
216{
217 xmms_main_t *mainobj = (xmms_main_t *) object;
218 gint uptime = time (NULL((void*)0)) - mainobj->starttime;
219 int64_t size, duration, playtime;
220
221 size = duration = playtime = 0;
222
223 query_total_playtime (mainobj, error, &playtime);
224 query_total_size_duration (mainobj, error, &size, &duration);
225
226 return xmmsv_build_dict (XMMSV_DICT_ENTRY_STR ("version", XMMS_VERSION)__xmmsv_identity_const_charp ("version"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string ("clang-analysis")))
,
227 XMMSV_DICT_ENTRY_INT ("uptime", uptime)__xmmsv_identity_const_charp ("uptime"), __xmmsv_identity_xmmsv
(xmmsv_new_int (uptime))
,
228 XMMSV_DICT_ENTRY_INT ("size", size)__xmmsv_identity_const_charp ("size"), __xmmsv_identity_xmmsv
(xmmsv_new_int (size))
,
229 XMMSV_DICT_ENTRY_INT ("duration", duration)__xmmsv_identity_const_charp ("duration"), __xmmsv_identity_xmmsv
(xmmsv_new_int (duration))
,
230 XMMSV_DICT_ENTRY_INT ("playtime", playtime)__xmmsv_identity_const_charp ("playtime"), __xmmsv_identity_xmmsv
(xmmsv_new_int (playtime))
,
231 XMMSV_DICT_END((void*)0));
232}
233
234static gboolean
235xmms_main_client_list_foreach (xmms_plugin_t *plugin, gpointer data)
236{
237 xmmsv_t *list, *dict;
238
239 list = (xmmsv_t *) data;
240
241 dict = xmmsv_build_dict (
242 XMMSV_DICT_ENTRY_STR ("name", xmms_plugin_name_get (plugin))__xmmsv_identity_const_charp ("name"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string (xmms_plugin_name_get
(plugin))))
,
243 XMMSV_DICT_ENTRY_STR ("shortname", xmms_plugin_shortname_get (plugin))__xmmsv_identity_const_charp ("shortname"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string (xmms_plugin_shortname_get
(plugin))))
,
244 XMMSV_DICT_ENTRY_STR ("version", xmms_plugin_version_get (plugin))__xmmsv_identity_const_charp ("version"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string (xmms_plugin_version_get
(plugin))))
,
245 XMMSV_DICT_ENTRY_STR ("description", xmms_plugin_description_get (plugin))__xmmsv_identity_const_charp ("description"), __xmmsv_identity_xmmsv
(__xmmsv_null_to_none (xmmsv_new_string (xmms_plugin_description_get
(plugin))))
,
246 XMMSV_DICT_ENTRY_INT ("type", xmms_plugin_type_get (plugin))__xmmsv_identity_const_charp ("type"), __xmmsv_identity_xmmsv
(xmmsv_new_int (xmms_plugin_type_get (plugin)))
,
247 XMMSV_DICT_END((void*)0));
248
249 xmmsv_list_append (list, dict);
250 xmmsv_unref (dict);
251
252 return TRUE(!(0));
253}
254
255static xmmsv_t *
256xmms_main_client_list_plugins (xmms_object_t *main, gint32 type, xmms_error_t *err)
257{
258 xmmsv_t *list = xmmsv_new_list ();
259 xmms_plugin_foreach (type, xmms_main_client_list_foreach, list);
260 return list;
261}
262
263
264/**
265 * @internal Execute all programs or scripts in a directory. Used when starting
266 * up and shutting down the daemon.
267 *
268 * @param[in] scriptdir Directory to search for executable programs/scripts.
269 * started.
270 * @param arg1 value passed to executed scripts as argument 1. This makes
271 * it possible to handle start and stop in one script
272 */
273static void
274do_scriptdir (const gchar *scriptdir, const gchar *arg1)
275{
276 GError *err = NULL((void*)0);
277 GDir *dir;
278 const gchar *f;
279 gchar *argv[3] = {NULL((void*)0), NULL((void*)0), NULL((void*)0)};
280
281 XMMS_DBG ("Running scripts in %s", scriptdir)g_debug ("../src/xmms/main.c" ":" "281" ": " "Running scripts in %s"
, scriptdir)
;
282 if (!g_file_test (scriptdir, G_FILE_TEST_IS_DIR)) {
283 g_mkdir_with_parents (scriptdir, 0755);
284 install_scripts (scriptdir);
285 }
286
287 dir = g_dir_open (scriptdir, 0, &err);
288 if (!dir) {
289 xmms_log_error ("Could not open script dir '%s' error: %s", scriptdir, err->message)g_warning ("../src/xmms/main.c" ":" "289" ": " "Could not open script dir '%s' error: %s"
, scriptdir, err->message)
;
290 return;
291 }
292
293 argv[1] = g_strdup (arg1);
294 while ((f = g_dir_read_name (dir))) {
295 argv[0] = g_strdup_printf ("%s/%s", scriptdir, f);
296 if (g_file_test (argv[0], G_FILE_TEST_IS_EXECUTABLE)) {
297 if (!g_spawn_async (g_get_home_dir (), argv, NULL((void*)0), 0,
298 spawn_script_setup, NULL((void*)0), NULL((void*)0), &err)) {
299 xmms_log_error ("Could not run script '%s', error: %s",g_warning ("../src/xmms/main.c" ":" "300" ": " "Could not run script '%s', error: %s"
, argv[0], err->message)
300 argv[0], err->message)g_warning ("../src/xmms/main.c" ":" "300" ": " "Could not run script '%s', error: %s"
, argv[0], err->message)
;
301 }
302 }
303 g_free (argv[0]);
304 }
305 g_free (argv[1]);
306
307 g_dir_close (dir);
308
309}
310
311/**
312 * @internal Setup function for processes spawned by do_scriptdir
313 */
314static void
315spawn_script_setup (gpointer data)
316{
317 xmms_signal_restore ();
318}
319
320/**
321 * @internal Load the xmms2d configuration file. Creates the config directory
322 * if needed.
323 */
324static void
325load_config (void)
326{
327 gchar configdir[XMMS_PATH_MAX255];
328
329 if (!conffile) {
330 conffile = XMMS_BUILD_PATH ("xmms2.conf")xmms_build_path ("xmms2.conf", ((void*)0));
331 }
332
333 g_assert (strlen (conffile) <= XMMS_MAX_CONFIGFILE_LEN)do { if (strlen (conffile) <= 255) ; else g_assertion_message_expr
("", "../src/xmms/main.c", 333, ((const char*) (__func__)), "strlen (conffile) <= XMMS_MAX_CONFIGFILE_LEN"
); } while (0)
;
334
335 if (!xmms_userconfdir_get (configdir, sizeof (configdir))) {
336 xmms_log_error ("Could not get path to config dir")g_warning ("../src/xmms/main.c" ":" "336" ": " "Could not get path to config dir"
)
;
337 } else if (!g_file_test (configdir, G_FILE_TEST_IS_DIR)) {
338 g_mkdir_with_parents (configdir, 0755);
339 }
340
341 xmms_config_init (conffile);
342}
343
344/**
345 * @internal Switch to using another output plugin
346 * @param object An object
347 * @param data The name of the output plugin to switch to
348 * @param userdata The #xmms_main_t object
349 */
350static void
351change_output (xmms_object_t *object, xmmsv_t *_data, gpointer userdata)
352{
353 xmms_output_plugin_t *plugin;
354 xmms_main_t *mainobj = (xmms_main_t*)userdata;
355 const gchar *outname;
356
357 if (!mainobj->output_object)
358 return;
359
360 outname = xmms_config_property_get_string ((xmms_config_property_t *) object);
361
362 xmms_log_info ("Switching to output %s", outname)g_message ("../src/xmms/main.c" ":" "362" ": " "Switching to output %s"
, outname)
;
363
364 plugin = (xmms_output_plugin_t *)xmms_plugin_find (XMMS_PLUGIN_TYPE_OUTPUT, outname);
365 if (!plugin) {
366 xmms_log_error ("Baaaaad output plugin, try to change the output.plugin config variable to something useful")g_warning ("../src/xmms/main.c" ":" "366" ": " "Baaaaad output plugin, try to change the output.plugin config variable to something useful"
)
;
367 } else {
368 if (!xmms_output_plugin_switch (mainobj->output_object, plugin)) {
369 xmms_log_error ("Baaaaad output plugin, try to change the output.plugin config variable to something useful")g_warning ("../src/xmms/main.c" ":" "369" ": " "Baaaaad output plugin, try to change the output.plugin config variable to something useful"
)
;
370 }
371 }
372}
373
374/**
375 * @internal Destroy the main object
376 * @param[in] object The object to destroy
377 */
378static void
379xmms_main_destroy (xmms_object_t *object)
380{
381 xmms_main_t *mainobj = (xmms_main_t *) object;
382 xmms_config_property_t *cv;
383
384 cv = xmms_config_lookup ("core.shutdownpath");
385 do_scriptdir (xmms_config_property_get_string (cv), "stop");
386
387 xmms_object_unref (mainobj->xform_object);
388 xmms_object_unref (mainobj->visualization_object);
389 xmms_object_unref (mainobj->output_object);
390 xmms_object_unref (mainobj->bindata_object);
391 xmms_object_unref (mainobj->playlist_object);
392 xmms_object_unref (mainobj->colldag_object);
393 xmms_object_unref (mainobj->medialib_object);
394 xmms_object_unref (mainobj->mediainfo_object);
395 xmms_object_unref (mainobj->plsupdater_object);
396 xmms_object_unref (mainobj->collsync_object);
397 xmms_object_unref (mainobj->courier_object);
398
399 xmms_config_save ();
400
401 xmms_config_shutdown ();
402
403 xmms_plugin_shutdown ();
404
405 xmms_main_unregister_ipc_commands ();
406
407 xmms_ipc_shutdown ();
408
409 xmms_log_shutdown ();
410}
411
412/**
413 * @internal Function to respond to the 'hello' sent from clients on connect
414 */
415static gint64
416xmms_main_client_hello (xmms_object_t *object, gint protocolver, const gchar *client, gint64 id, xmms_error_t *error)
417{
418 if (protocolver != XMMS_IPC_PROTOCOL_VERSION24) {
419 xmms_log_info ("Client '%s' with bad protocol version (%d, not %d) connected", client, protocolver, XMMS_IPC_PROTOCOL_VERSION)g_message ("../src/xmms/main.c" ":" "419" ": " "Client '%s' with bad protocol version (%d, not %d) connected"
, client, protocolver, 24)
;
420 xmms_error_set (error, XMMS_ERROR_INVAL, "Bad protocol version");
421 } else {
422 XMMS_DBG ("Client '%s' connected", client)g_debug ("../src/xmms/main.c" ":" "422" ": " "Client '%s' connected"
, client)
;
423 }
424
425 return id;
426}
427
428static gboolean
429kill_server (gpointer object) {
430 xmms_main_t *mainobj = (xmms_main_t *) object;
431 gint uptime = time (NULL((void*)0)) - mainobj->starttime;
432
433 xmms_object_emit (XMMS_OBJECT (object)((xmms_object_t *)object),
434 XMMS_IPC_SIGNAL_MAIN_QUIT,
435 xmmsv_new_int (uptime));
436
437 xmms_object_unref (object);
438
439 exit (EXIT_SUCCESS0);
440}
441
442
443/**
444 * @internal Function to respond to the 'quit' command sent from a client
445 */
446static void
447xmms_main_client_quit (xmms_object_t *object, xmms_error_t *error)
448{
449 /*
450 * to be able to return from this method
451 * we add a timeout that will kill the server
452 * very "ugly"
453 */
454 g_timeout_add (1, kill_server, object);
455}
456
457static void
458install_scripts (const gchar *into_dir)
459{
460 GDir *dir;
461 GError *err = NULL((void*)0);
462 gchar path[XMMS_PATH_MAX255];
463 const gchar *f;
464 gchar *s;
465
466 s = strrchr (into_dir, G_DIR_SEPARATOR'/');
467 if (!s)
468 return;
469
470 s++;
471
472 g_snprintf (path, XMMS_PATH_MAX255, "%s/scripts/%s", SHAREDDIR"/usr/local/share/xmms2", s);
473 xmms_log_info ("Installing scripts from %s", path)g_message ("../src/xmms/main.c" ":" "473" ": " "Installing scripts from %s"
, path)
;
474 dir = g_dir_open (path, 0, &err);
475 if (!dir) {
476 xmms_log_error ("Global script directory not found")g_warning ("../src/xmms/main.c" ":" "476" ": " "Global script directory not found"
)
;
477 return;
478 }
479
480 while ((f = g_dir_read_name (dir))) {
481 gchar *source = g_strdup_printf ("%s/%s", path, f);
482 gchar *dest = g_strdup_printf ("%s/%s", into_dir, f);
483 if (!xmms_symlink_file (source, dest)) {
484 g_free (source);
485 g_free (dest);
486 break;
487 }
488 g_free (source);
489 g_free (dest);
490 }
491
492 g_dir_close (dir);
493}
494
495/**
496 * Just print version and quit
497 */
498static void
499print_version (void)
500{
501 printf ("XMMS2 version " XMMS_VERSION"clang-analysis" "\n");
502 printf ("Copyright (C) 2003-2017 XMMS2 Team\n");
503 printf ("This is free software; see the source for copying conditions.\n");
504 printf ("There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n");
505 printf ("PARTICULAR PURPOSE.\n");
506 printf (" Using glib version %d.%d.%d (compiled against "
507 G_STRINGIFY (GLIB_MAJOR_VERSION)"2" "."
508 G_STRINGIFY (GLIB_MINOR_VERSION)"40" "."
509 G_STRINGIFY (GLIB_MICRO_VERSION)"2" ")\n",
510 glib_major_version,
511 glib_minor_version,
512 glib_micro_version);
513
514 exit (EXIT_SUCCESS0);
515}
516
517/**
518 * The xmms2 daemon main initialisation function
519 */
520int
521main (int argc, char **argv)
522{
523 xmms_output_plugin_t *o_plugin;
524 xmms_config_property_t *cv;
525 xmms_main_t *mainobj;
526 int loglevel = 1;
527 gchar default_path[XMMS_PATH_MAX255 + 16], *tmp;
528 gboolean verbose = FALSE(0);
529 gboolean quiet = FALSE(0);
530 gboolean version = FALSE(0);
531 gboolean runasroot = FALSE(0);
532 gboolean showhelp = FALSE(0);
533 const gchar *outname = NULL((void*)0);
534 const gchar *ipcpath = NULL((void*)0);
535 gchar *uuid, *ppath = NULL((void*)0);
536 int status_fd = -1;
537 GOptionContext *context = NULL((void*)0);
538 GError *error = NULL((void*)0);
539
540 setlocale (LC_ALL6, "");
541
542 /**
543 * The options that the server accepts.
544 */
545 GOptionEntry opts[] = {
546 {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Increase verbosity", NULL((void*)0)},
547 {"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, "Decrease verbosity", NULL((void*)0)},
548 {"version", 'V', 0, G_OPTION_ARG_NONE, &version, "Print version", NULL((void*)0)},
549 {"output", 'o', 0, G_OPTION_ARG_STRING, &outname, "Use 'x' as output plugin", "<x>"},
550 {"ipc-socket", 'i', 0, G_OPTION_ARG_FILENAME, &ipcpath, "Listen to socket 'url'", "<url>"},
551 {"plugindir", 'p', 0, G_OPTION_ARG_FILENAME, &ppath, "Search for plugins in directory 'foo'", "<foo>"},
552 {"conf", 'c', 0, G_OPTION_ARG_FILENAME, &conffile, "Specify alternate configuration file", "<file>"},
553 {"status-fd", 's', 0, G_OPTION_ARG_INT, &status_fd, "Specify a filedescriptor to write to when started", "fd"},
554 {"yes-run-as-root", 0, 0, G_OPTION_ARG_NONE, &runasroot, "Give me enough rope to shoot myself in the foot", NULL((void*)0)},
555 {"show-help", 'h', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &showhelp, "Use --help or -? instead", NULL((void*)0)},
556 {NULL((void*)0)}
557 };
558
559 /** Check that we are running against the correct glib version */
560 if (glib_major_version != GLIB_MAJOR_VERSION2 ||
561 glib_minor_version < GLIB_MINOR_VERSION40) {
562 g_print ("xmms2d is build against version %d.%d,\n"
563 "but is (runtime) linked against %d.%d.\n"
564 "Refusing to start.\n",
565 GLIB_MAJOR_VERSION2, GLIB_MINOR_VERSION40,
566 glib_major_version, glib_minor_version);
567 exit (EXIT_FAILURE1);
568 }
569
570 xmms_signal_block ();
571
572 context = g_option_context_new ("- XMMS2 Daemon");
573 g_option_context_add_main_entries (context, opts, NULL((void*)0));
574 if (!g_option_context_parse (context, &argc, &argv, &error) || error) {
575 g_print ("Error parsing options: %s\n", error->message);
576 g_clear_error (&error);
577 exit (EXIT_FAILURE1);
578 }
579 if (showhelp) {
580#if GLIB_CHECK_VERSION(2,14,0)(2 > (2) || (2 == (2) && 40 > (14)) || (2 == (2
) && 40 == (14) && 2 >= (0)))
581 g_print ("%s", g_option_context_get_help (context, TRUE(!(0)), NULL((void*)0)));
582 exit (EXIT_SUCCESS0);
583#else
584 g_print ("Please use --help or -? for help\n");
585 exit (EXIT_FAILURE1);
586#endif
587 }
588 g_option_context_free (context);
589
590 if (argc != 1) {
591 g_print ("There were unknown options, aborting!\n");
592 exit (EXIT_FAILURE1);
593 }
594
595 if (xmms_checkroot ()) {
596 if (runasroot) {
597 g_print ("***************************************\n");
598 g_print ("Warning! You are running XMMS2D as root, this is a bad idea!\nBut I'll allow it since you asked nicely.\n");
599 g_print ("***************************************\n\n");
600 } else {
601 g_print ("PLEASE DON'T RUN XMMS2D AS ROOT!\n\n(if you really must, read the help)\n");
602 exit (EXIT_FAILURE1);
603 }
604 }
605
606 if (verbose) {
607 loglevel++;
608 } else if (quiet) {
609 loglevel--;
610 }
611
612 if (version) {
613 print_version ();
614 }
615
616 g_random_set_seed (time (NULL((void*)0)));
617
618 xmms_log_init (loglevel);
619 xmms_ipc_init ();
620
621 load_config ();
622
623 cv = xmms_config_property_register ("core.logtsfmt",
624 "%H:%M:%S ",
625 NULL((void*)0), NULL((void*)0));
626
627 xmms_log_set_format (xmms_config_property_get_string (cv));
628
629 xmms_fallback_ipcpath_get (default_path, sizeof (default_path));
630
631 cv = xmms_config_property_register ("core.ipcsocket",
632 default_path,
633 on_config_ipcsocket_change,
634 NULL((void*)0));
635
636 if (!ipcpath) {
637 /*
638 * if not ipcpath is specifed on the cmd line we
639 * grab it from the config
640 */
641 ipcpath = xmms_config_property_get_string (cv);
642 }
643
644 if (!xmms_ipc_setup_server (ipcpath)) {
645 xmms_ipc_shutdown ();
646 xmms_log_fatal ("IPC failed to init!")g_error ("../src/xmms/main.c" ":" "646" ": " "IPC failed to init!"
)
;
647 }
648
649 if (!xmms_plugin_init (ppath)) {
650 exit (EXIT_FAILURE1);
651 }
652
653 mainobj = xmms_object_new (xmms_main_t, xmms_main_destroy)(xmms_main_t *) __int_xmms_object_new (sizeof (xmms_main_t), xmms_main_destroy
)
;
654
655 mainobj->medialib_object = xmms_medialib_init ();
656 mainobj->colldag_object = xmms_collection_init (mainobj->medialib_object);
657 mainobj->mediainfo_object = xmms_mediainfo_reader_start (mainobj->medialib_object);
658 mainobj->playlist_object = xmms_playlist_init (mainobj->medialib_object,
659 mainobj->colldag_object);
660
661 uuid = xmms_medialib_uuid (mainobj->medialib_object);
662 mainobj->collsync_object = xmms_coll_sync_init (uuid,
663 mainobj->colldag_object,
664 mainobj->playlist_object);
665 g_free (uuid);
666 mainobj->plsupdater_object = xmms_playlist_updater_init (mainobj->playlist_object);
667
668 mainobj->xform_object = xmms_xform_object_init ();
669 mainobj->bindata_object = xmms_bindata_init ();
670 mainobj->courier_object = xmms_courier_init();
671
672 /* find output plugin. */
673 cv = xmms_config_property_register ("output.plugin",
674 XMMS_OUTPUT_DEFAULT"pulse",
675 change_output, mainobj);
676
677 if (outname) {
678 xmms_config_property_set_data (cv, outname);
679 }
680
681 outname = xmms_config_property_get_string (cv);
682 xmms_log_info ("Using output plugin: %s", outname)g_message ("../src/xmms/main.c" ":" "682" ": " "Using output plugin: %s"
, outname)
;
683 o_plugin = (xmms_output_plugin_t *) xmms_plugin_find (XMMS_PLUGIN_TYPE_OUTPUT, outname);
684 if (!o_plugin) {
685 xmms_log_error ("Baaaaad output plugin, try to change the"g_warning ("../src/xmms/main.c" ":" "686" ": " "Baaaaad output plugin, try to change the"
"output.plugin config variable to something useful")
686 "output.plugin config variable to something useful")g_warning ("../src/xmms/main.c" ":" "686" ": " "Baaaaad output plugin, try to change the"
"output.plugin config variable to something useful")
;
687 }
688
689 mainobj->output_object = xmms_output_new (o_plugin,
690 mainobj->playlist_object,
691 mainobj->medialib_object);
692 if (!mainobj->output_object) {
693 xmms_log_fatal ("Failed to create output object!")g_error ("../src/xmms/main.c" ":" "693" ": " "Failed to create output object!"
)
;
694 }
695
696 mainobj->visualization_object = xmms_visualization_new (mainobj->output_object);
697
698 if (status_fd != -1) {
699 write (status_fd, "+", 1);
700 }
701
702 xmms_signal_init (XMMS_OBJECT (mainobj)((xmms_object_t *)mainobj));
703
704 xmms_main_register_ipc_commands (XMMS_OBJECT (mainobj)((xmms_object_t *)mainobj));
705
706 /* Save the time we started in order to count uptime */
707 mainobj->starttime = time (NULL((void*)0));
708
709 /* Dirty hack to tell XMMS_PATH a valid path */
710 g_strlcpy (default_path, ipcpath, sizeof (default_path));
711
712 tmp = strchr (default_path, ';');
713 if (tmp) {
714 *tmp = '\0';
715 }
716
717 g_setenv ("XMMS_PATH", default_path, TRUE(!(0)));
718
719 /* Also put the full path for clients that understands */
720 g_setenv("XMMS_PATH_FULL", ipcpath, TRUE(!(0)));
721
722 tmp = XMMS_BUILD_PATH ("shutdown.d")xmms_build_path ("shutdown.d", ((void*)0));
723 cv = xmms_config_property_register ("core.shutdownpath",
Value stored to 'cv' is never read
724 tmp, NULL((void*)0), NULL((void*)0));
725 g_free (tmp);
726
727 tmp = XMMS_BUILD_PATH ("startup.d")xmms_build_path ("startup.d", ((void*)0));
728 cv = xmms_config_property_register ("core.startuppath",
729 tmp, NULL((void*)0), NULL((void*)0));
730 g_free (tmp);
731
732 /* Startup dir */
733 do_scriptdir (xmms_config_property_get_string (cv), "start");
734
735 mainloop = g_main_loop_new (NULL((void*)0), FALSE(0));
736
737 g_main_loop_run (mainloop);
738
739 return EXIT_SUCCESS0;
740}
741
742/** @} */