3 * (c) 2005-2009 by Avuton Olrich <avuton@gmail.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "libmpdclient.h"
30 * void exit_on_help(char ** argv):
31 * Takes argv as an argument
33 * Expected action: Simply check for -h or --help as an argument
34 * and if it exists show usage.
39 static void exit_on_help(char **argv
)
41 if (!(argv
[1] && argv
[1][0] == '-'))
44 if ((argv
[1][1] == '-' && argv
[1][2] == 'h') || (argv
[1][1] == 'h')) {
45 printf("Usage: state-save [STATE NAME]"
46 "\nExample: state-save my_cool_statefile"
48 "\n -h, --help\t\tThis usage"
49 "\n\nReport bugs to Avuton Olrich <avuton@gmail.com>"
50 "\nSee 'man 1 state-save' for more information\n");
57 * FILE * get_fp(int,char):
58 * Takes argc,argv as it's arguments.
60 * Expected action: This simply formats the filename, gets
61 * the current user's home directory name, if it doesn't yet
62 * exist it creats it, then turns the filename into a file
65 * Returns: A file pointer
67 static FILE *get_fp(int argc
, char **argv
)
69 char filename
[FILENAME_MAX
];
70 char dirname
[FILENAME_MAX
];
73 sprintf(dirname
, "%s/.mpd_states", get_home_dir());
76 sprintf(filename
, "%s/default", dirname
);
78 sprintf(filename
, "%s/%s", dirname
, argv
[1]);
82 * Create the directory/file if necessary and
83 * make sure things are coherant.
86 while (!(fp
= fopen(filename
, "w"))) {
87 /* ENOENT: No such file or directory */
88 if (errno
== ENOENT
) {
91 if (mkdir(dirname
, (mode_t
) 0700)) {
95 check_perror(errno
, "Couldn't create state-utils directory");
101 * void print_playlist(FILE,conn):
102 * Takes a file pointer and the connection as arguments
104 * Expected action: Print the playlist from connection
105 * to the file pointer
107 * Returns: void, There's no need to do anything other
108 * than log the error and return.
112 * 0:Albums/Sublime/40 Oz. To Freedom/01.sublime_-_waiting_for_my_ruca.flac
113 * 1:Albums/Sublime/40 Oz. To Freedom/02.sublime_-_40_oz._to_freedom.flac
117 static void print_playlist(FILE * fp
, mpd_Connection
* conn
)
120 mpd_InfoEntity
*entity
= NULL
;
121 mpd_sendPlaylistInfoCommand(conn
, -1);
123 entity
= mpd_getNextInfoEntity(conn
);
126 * Don't freak if we can't get playlist
127 * user may simply not have permissions.
129 if (conn
->error
|| !entity
) {
130 fprintf(stderr
, "Cannot get the playlist, continuing...\n");
131 mpd_clearError(conn
);
135 fprintf(fp
, "playlist_begin\n");
137 if (entity
->type
== MPD_INFO_ENTITY_TYPE_SONG
) {
138 fprintf(fp
, "%i:%s\n",
139 entity
->info
.song
->pos
,
140 entity
->info
.song
->file
);
142 mpd_freeInfoEntity(entity
);
143 } while ((entity
= mpd_getNextInfoEntity(conn
)));
144 mpd_finishCommand(conn
);
145 fprintf(fp
, "playlist_end\n");
146 printErrorAndExit(conn
);
150 * void print_outputs(FILE,conn)
151 * Takes a file pointer and the connection as arguments
153 * Expected action: Print the outputs from the connection to
156 * Returns: void, There's no need to do anything other than log the
161 * 0:1:ALSA output (emu10k1)
162 * 1:1:ALSA output (intel8x0)
165 * Explanation of output:
166 * The first number is the device number, sequentially.
167 * The second number is 0 is disabled, 1 is enabled.
168 * The third is the name as defined in the MPD.
170 static void print_outputs(FILE * fp
, mpd_Connection
* conn
)
172 mpd_OutputEntity
*output
= NULL
;
173 mpd_sendOutputsCommand(conn
);
175 output
= mpd_getNextOutput(conn
);
178 * Don't freak if we can't get outputs
179 * user may simply not have permissions.
181 if (conn
->error
|| !output
) {
184 "Cannot get the outputs due to: %s, continuing...\n",
186 } else { /* !output */
188 "Cannot get the outputs, this is not necessarily an error, continuing...\n");
190 mpd_clearError(conn
);
194 fprintf(fp
, "outputs_begin\n");
196 if (output
->id
>= 0) {
197 fprintf(fp
, "%i:%i:%s\n",
198 output
->id
, output
->enabled
, output
->name
);
200 mpd_freeOutputElement(output
);
201 } while ((output
= mpd_getNextOutput(conn
)));
202 mpd_finishCommand(conn
);
203 fprintf(fp
, "outputs_end\n");
204 printErrorAndExit(conn
);
208 * void print_status(FILE,conn)
209 * Takes a file pointer and connection as arguments
211 * Expected action: Get all useful information from the MPD
212 * status conn and output to the file pointer.
214 * Returns: void, There's no need to do anything other than log
215 * or exit() if required.
226 static void print_status(FILE * fp
, mpd_Connection
* conn
)
230 mpd_sendStatusCommand(conn
);
231 printErrorAndExit(conn
);
233 status
= mpd_getStatus(conn
);
234 printErrorAndExit(conn
);
237 fprintf(stderr
, "Out of memory");
241 mpd_nextListOkCommand(conn
);
242 printErrorAndExit(conn
);
245 fprintf(fp
, "state: ");
246 if (status
->state
== MPD_STATUS_STATE_PLAY
) {
247 fprintf(fp
, "play\n");
248 } else if (status
->state
== MPD_STATUS_STATE_PAUSE
) {
249 fprintf(fp
, "pause\n");
251 fprintf(fp
, "stop\n");
255 fprintf(fp
, "current: %i\n", status
->song
);
258 fprintf(fp
, "time: %i\n", status
->elapsedTime
);
261 fprintf(fp
, "random: %i\n", status
->random
? 1 : 0);
264 fprintf(fp
, "repeat: %i\n", status
->repeat
? 1 : 0);
266 if (status
->single
) {
268 fprintf(fp
, "single: %i\n", status
->single
? 1 : 0);
271 if (status
->consume
) {
273 fprintf(fp
, "consume: %i\n", status
->consume
? 1 : 0);
277 fprintf(fp
, "crossfade: %i\n", status
->crossfade
? 1 : 0);
279 fprintf(fp
, "volume: %i\n", status
->volume
);
281 mpd_finishCommand(conn
);
283 mpd_freeStatus(status
);
284 printErrorAndExit(conn
);
290 int main(int argc
, char **argv
)
293 mpd_Connection
*conn
;
296 fp
= get_fp(argc
, argv
);
297 conn
= setup_connection(NULL
, NULL
);
299 print_status(fp
, conn
);
300 print_playlist(fp
, conn
);
301 print_outputs(fp
, conn
);
304 mpd_closeConnection(conn
);