3 * (c) 2005-2006 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
20 #include "libmpdclient.h"
34 mpd_Connection
*host_conn
[MAX_HOSTS
];
36 static void print_usage(int exitnum
)
39 ("Usage: state-sync [OPTION] [originhost]:[originport] [desthost1]:[destport1] ..."
40 "\nSync multiple MPD servers." "\n\n"
41 "\n -f --force\t\tForce syncing when origin is in 'random' mode"
42 "\n -h --help\t\tThis help page."
43 "\n -p --persistant\tKeep all servers in sync with the origin."
44 "\n\nReport bugs to Avuton Olrich <avuton@gmail.com>"
45 "\nSee 'man 1 state-sync' for more information\n");
49 static void parse_args(int argc
, char **argv
)
54 static struct option long_options
[] = {
56 {"persistant", 0, 0, 'p'},
60 c
= getopt_long(argc
, argv
, "hp", long_options
, &option_index
);
84 // Extract the host and ports here
86 char *host
, *port
, *saveptr
;
88 host
= strtok_r(argv
[optind
], ":", &saveptr
);
89 port
= strtok(saveptr
, ":");
90 host_conn
[host_num
] = setup_connection(host
,port
,60);
93 // If a connection was made, concider it part of the array
94 if(host_conn
[host_num
] != NULL
)
100 puts("Requires at least 2 servers to sync");
105 h) On CTRL-C close connections and exit.
110 * Expected action: This actually encompasses the whole program,
111 * it's pretty hard and non-logical to break up this function
112 * as everything's called once for a good reason.
114 int main(int argc
, char **argv
)
116 /* Parse args will take care of all the arguments and connections */
117 parse_args(argc
, argv
);
118 printf("Found %i hosts\n",host_num
);
120 static mpd_Status
*ostatus
;
123 for(j
= 0; j
< host_num
; j
++) {
124 if(host_conn
[j
] == NULL
) {
125 printf("%i is NULL\n",j
);
127 printf("%i has connection\n",j
);
131 * Notice we start at 1; 0 is the root connection, and are set explicitly
134 for (i
= 1; i
< host_num
; i
++) {
136 * Setup the inital connection
138 static mpd_InfoEntity
*entity
;
139 static mpd_Song
*song
;
141 * Receive the baseline status from the origin MPD server
143 mpd_sendStatusCommand(host_conn
[0]);
144 ostatus
= mpd_getStatus(host_conn
[0]);
145 printErrorAndExit(host_conn
[0]);
147 mpd_sendCommandListBegin(host_conn
[i
]);
148 mpd_sendClearCommand(host_conn
[i
]);
150 * if user is running a 'ramdom' playlist warn that it cannot stay in sync
152 if (ostatus
->random
&& !force
) {
154 ("Warning: Origin is currently in 'random' mode, cannot sync");
158 * Setup to receive all the playlist information, then add to destination
160 mpd_sendPlaylistInfoCommand(host_conn
[0], -1);
161 while ((entity
= mpd_getNextInfoEntity(host_conn
[0]))) {
162 if (entity
->type
== MPD_INFO_ENTITY_TYPE_SONG
) {
163 song
= entity
->info
.song
;
164 mpd_sendAddCommand(host_conn
[i
],
167 mpd_freeInfoEntity(entity
);
169 mpd_sendRandomCommand(host_conn
[i
],
170 ostatus
->random
? 1 : 0);
171 mpd_sendRepeatCommand(host_conn
[i
],
172 ostatus
->repeat
? 1 : 0);
173 mpd_sendCrossfadeCommand(host_conn
[i
],
174 ostatus
->crossfade
? 1 : 0);
175 mpd_sendVolumeCommand(host_conn
[i
],
176 ostatus
->volume
? 1 : 0);
178 * Start in sync, this causes a msec break in the song, if playing
180 mpd_sendSeekCommand(host_conn
[0], ostatus
->song
,
181 ostatus
->elapsedTime
);
183 * Send the rest of the commands to sync the state
185 mpd_sendSeekCommand(host_conn
[i
], ostatus
->song
,
186 ostatus
->elapsedTime
);
187 mpd_sendCommandListEnd(host_conn
[i
]);
189 mpd_finishCommand(host_conn
[0]);
190 printErrorAndExit(host_conn
[i
]);
191 mpd_finishCommand(host_conn
[i
]);
193 mpd_freeStatus(ostatus
);
201 printf("Exiting...\n");
204 * Close connections, cleanup
206 mpd_closeConnection(host_conn
[0]);
207 for (i
= 1; i
< host_num
; i
++)
208 mpd_closeConnection(host_conn
[i
]);