clarifying licensing
[monky] / src / mpd.c
1 /*
2  * Conky, a system monitor, based on torsmo
3  *
4  * Any original torsmo code is licensed under the BSD license
5  *
6  * All code written since the fork of torsmo is licensed under the GPL
7  *
8  * Please see COPYING for details
9  *
10  * Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
11  * All rights reserved.
12  *
13  * This program is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation, either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
24  *
25  *  $Id$
26  */
27
28 #include "conky.h"
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include "libmpdclient.h"
33
34 static void clear_mpd_stats(struct information *current_info)
35 {
36         if (current_info->mpd.artist == NULL)
37                 current_info->mpd.artist = malloc(TEXT_BUFFER_SIZE);
38         if (current_info->mpd.album == NULL)
39                 current_info->mpd.album = malloc(TEXT_BUFFER_SIZE);
40         if (current_info->mpd.title == NULL)
41                 current_info->mpd.title = malloc(TEXT_BUFFER_SIZE);
42         if (current_info->mpd.random == NULL)
43                 current_info->mpd.random = malloc(TEXT_BUFFER_SIZE);
44         if (current_info->mpd.repeat == NULL)
45                 current_info->mpd.repeat = malloc(TEXT_BUFFER_SIZE);
46         if (current_info->mpd.track == NULL)
47                 current_info->mpd.track = malloc(TEXT_BUFFER_SIZE);
48         if (current_info->mpd.status == NULL)
49                 current_info->mpd.status = malloc(TEXT_BUFFER_SIZE);
50         if (current_info->mpd.name == NULL)
51                 current_info->mpd.name = malloc(TEXT_BUFFER_SIZE);
52         if (current_info->mpd.file == NULL)
53                 current_info->mpd.file = malloc(TEXT_BUFFER_SIZE);
54
55         *current_info->mpd.name=0;
56         *current_info->mpd.file=0;
57         *current_info->mpd.artist=0;
58         *current_info->mpd.album=0;
59         *current_info->mpd.title=0;
60         *current_info->mpd.random=0;
61         *current_info->mpd.repeat=0;
62         *current_info->mpd.track=0;
63         current_info->mpd.bitrate = 0;
64         current_info->mpd.progress = 0;
65         current_info->mpd.elapsed = 0;
66         current_info->mpd.length = 0;
67 }
68
69 void update_mpd()
70 {
71         struct information *current_info = &info;
72         if (current_info->conn == NULL) {
73                 current_info->conn = mpd_newConnection(current_info->mpd.host, current_info->mpd.port, 10);
74         }
75         if (strlen(current_info->mpd.password) > 1) {
76                 mpd_sendPasswordCommand(current_info->conn,
77                                         current_info->mpd.password);
78                 mpd_finishCommand(current_info->conn);
79         }
80
81         // This makes sure everything we need is malloc'ed and clear
82         clear_mpd_stats(current_info); 
83
84         if (current_info->conn->error) {
85                 //ERR("%MPD error: s\n", current_info->conn->errorStr);
86                 mpd_closeConnection(current_info->conn);
87                 current_info->conn = 0;
88
89                 strncpy(current_info->mpd.status, "MPD not responding", TEXT_BUFFER_SIZE - 1);
90                 return;
91         }
92
93         mpd_Status *status;
94         mpd_InfoEntity *entity;
95         mpd_sendCommandListOkBegin(current_info->conn);
96         mpd_sendStatusCommand(current_info->conn);
97         mpd_sendCurrentSongCommand(current_info->conn);
98         mpd_sendCommandListEnd(current_info->conn);
99         if ((status = mpd_getStatus(current_info->conn)) == NULL) {
100                 //ERR("MPD error: %s\n", current_info->conn->errorStr);
101                 mpd_closeConnection(current_info->conn);
102                 current_info->conn = 0;
103
104                 strncpy(current_info->mpd.status, "MPD not responding", TEXT_BUFFER_SIZE - 1);
105                 return;
106         }
107         
108         current_info->mpd.volume = status->volume;
109         //if (status->error)
110         //printf("error: %s\n", status->error);
111
112         if (status->state == MPD_STATUS_STATE_PLAY) {
113                 strncpy(current_info->mpd.status, "Playing",
114                         TEXT_BUFFER_SIZE - 1);
115         }
116         if (status->state == MPD_STATUS_STATE_STOP) {
117                 strncpy(current_info->mpd.status, "Stopped",
118                         TEXT_BUFFER_SIZE - 1);
119         }
120         if (status->state == MPD_STATUS_STATE_PAUSE) {
121                 strncpy(current_info->mpd.status, "Paused",
122                         TEXT_BUFFER_SIZE - 1);
123         }
124         if (status->state == MPD_STATUS_STATE_UNKNOWN) {
125                 // current_info was already cleaned up by clear_mpd_stats()
126         }
127         if (status->state == MPD_STATUS_STATE_PLAY ||
128             status->state == MPD_STATUS_STATE_PAUSE) {
129                 current_info->mpd.bitrate = status->bitRate;
130                 current_info->mpd.progress =
131                     (float) status->elapsedTime / status->totalTime;
132                 current_info->mpd.elapsed = status->elapsedTime;
133                 current_info->mpd.length = status->totalTime;
134                 if (status->random == 0) {
135                         strcpy(current_info->mpd.random, "Off");
136                 } else if (status->random == 1) {
137                         strcpy(current_info->mpd.random, "On");
138                 } else {
139                         *current_info->mpd.random=0;
140                 }
141                 if (status->repeat == 0) {
142                         strcpy(current_info->mpd.repeat, "Off");
143                 } else if (status->repeat == 1) {
144                         strcpy(current_info->mpd.repeat, "On");
145                 } else {
146                         *current_info->mpd.repeat=0;
147                 }
148         }
149
150         if (current_info->conn->error) {
151                 //fprintf(stderr, "%s\n", current_info->conn->errorStr);
152                 mpd_closeConnection(current_info->conn);
153                 current_info->conn = 0;
154                 return;
155         }
156
157         mpd_nextListOkCommand(current_info->conn);
158
159         while ((entity = mpd_getNextInfoEntity(current_info->conn))) {
160                 mpd_Song *song = entity->info.song;
161                 if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
162                         mpd_freeInfoEntity(entity);
163                         continue;
164                 }
165
166                 if (song->artist) {
167                         strncpy(current_info->mpd.artist, song->artist,
168                                 TEXT_BUFFER_SIZE - 1);
169                 } else {
170                         *current_info->mpd.artist=0;
171                 }
172                 if (song->album) {
173                         strncpy(current_info->mpd.album, song->album,
174                                 TEXT_BUFFER_SIZE - 1);
175                 } else {
176                         *current_info->mpd.album=0;
177                 }
178                 if (song->title) {
179                         strncpy(current_info->mpd.title, song->title,
180                                 TEXT_BUFFER_SIZE - 1);
181                 } else {
182                         *current_info->mpd.title=0;
183                 }
184                 if (song->track) {
185                         strncpy(current_info->mpd.track, song->track,
186                                 TEXT_BUFFER_SIZE - 1);
187                 } else {
188                         *current_info->mpd.track=0;
189                 }
190                 if (song->name) {
191                         strncpy(current_info->mpd.name, song->name,
192                                 TEXT_BUFFER_SIZE - 1);
193                 } else {
194                         *current_info->mpd.name=0;
195                 }
196                 if (song->file) {
197                         strncpy(current_info->mpd.file,
198                                 song->file, TEXT_BUFFER_SIZE - 1);
199                 } else {
200                         *current_info->mpd.file=0;
201                 }
202                 if (entity != NULL) {
203                         mpd_freeInfoEntity(entity);
204                         entity = NULL;
205                 }
206         }
207         if (entity != NULL) {
208                 mpd_freeInfoEntity(entity);
209                 entity = NULL;
210         }
211
212         if (current_info->conn->error) {
213                 //fprintf(stderr, "%s\n", current_info->conn->errorStr);
214                 mpd_closeConnection(current_info->conn);
215                 current_info->conn = 0;
216                 return;
217         }
218
219         mpd_finishCommand(current_info->conn);
220         if (current_info->conn->error) {
221                 //fprintf(stderr, "%s\n", current_info->conn->errorStr);
222                 mpd_closeConnection(current_info->conn);
223                 current_info->conn = 0;
224                 return;
225         }
226         mpd_freeStatus(status);
227 //      mpd_closeConnection(current_info->conn);
228 }