File: | build-analysis/../src/xmms/main.c |
Warning: | line 723, column 2 Value stored to 'cv' is never read |
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 | */ |
63 | static void xmms_main_client_quit (xmms_object_t *object, xmms_error_t *error); |
64 | static xmmsv_t *xmms_main_client_stats (xmms_object_t *object, xmms_error_t *error); |
65 | static xmmsv_t *xmms_main_client_list_plugins (xmms_object_t *main, gint32 type, xmms_error_t *err); |
66 | static gint64 xmms_main_client_hello (xmms_object_t *object, gint protocolver, const gchar *client, gint64 id, xmms_error_t *error); |
67 | static void install_scripts (const gchar *into_dir); |
68 | static 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 | */ |
89 | struct 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 | |
105 | typedef struct xmms_main_St xmms_main_t; |
106 | |
107 | /** This is the mainloop of the xmms2 server */ |
108 | static GMainLoop *mainloop; |
109 | |
110 | /** The path of the configfile */ |
111 | static gchar *conffile = NULL((void*)0); |
112 | |
113 | static void |
114 | query_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 | |
154 | static void |
155 | query_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 | */ |
214 | static xmmsv_t * |
215 | xmms_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 | |
234 | static gboolean |
235 | xmms_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 | |
255 | static xmmsv_t * |
256 | xmms_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 | */ |
273 | static void |
274 | do_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 | */ |
314 | static void |
315 | spawn_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 | */ |
324 | static void |
325 | load_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 | */ |
350 | static void |
351 | change_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 | */ |
378 | static void |
379 | xmms_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 | */ |
415 | static gint64 |
416 | xmms_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 | |
428 | static gboolean |
429 | kill_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 | */ |
446 | static void |
447 | xmms_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 | |
457 | static void |
458 | install_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 | */ |
498 | static void |
499 | print_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 | */ |
520 | int |
521 | main (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 | /** @} */ |