Fix the variables in state-sync so they're a little easier on the eyes
[state-utils.git] / src / state-sync.c
blobd055d3b043b4c265d33c98d7f8694430019fa816
1 /*
2 * state-utils
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"
21 #include "conn.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <getopt.h>
27 #include <unistd.h>
29 #define MAX_HOSTS 8
31 _Bool persistant = 1;
32 _Bool force = 1;
33 int host_num = 0;
34 mpd_Connection *host_conn[MAX_HOSTS];
36 static void print_usage(int exitnum)
38 printf
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");
46 exit(exitnum);
49 static void parse_args(int argc, char **argv)
51 while (1) {
52 int option_index = 0;
53 int c;
54 static struct option long_options[] = {
55 {"help", 0, 0, 'h'},
56 {"persistant", 0, 0, 'p'},
57 {0, 0, 0, 0}
60 c = getopt_long(argc, argv, "hp", long_options, &option_index);
62 if (c == -1)
63 break;
65 switch (c) {
67 case 'f':
68 force = 0;
69 break;
70 case 'p':
71 persistant = 0;
72 break;
73 case 'h':
74 case '?':
75 print_usage(0);
76 break;
77 default:
78 print_usage(1);
79 break;
84 // Extract the host and ports here
85 while(argc>optind) {
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);
91 optind++;
93 // If a connection was made, concider it part of the array
94 if(host_conn[host_num] != NULL)
95 host_num++;
99 if(!(host_num>1)){
100 puts("Requires at least 2 servers to sync");
101 print_usage(22);
105 h) On CTRL-C close connections and exit.
108 * int main()
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);
119 static int i;
120 static mpd_Status *ostatus;
122 int j = 0;
123 for(j = 0; j < host_num; j++) {
124 if(host_conn[j] == NULL) {
125 printf("%i is NULL\n",j);
126 } else {
127 printf("%i has connection\n",j);
131 * Notice we start at 1; 0 is the root connection, and are set explicitly
133 while(1) {
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]);
146 /* */
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) {
153 printf
154 ("Warning: Origin is currently in 'random' mode, cannot sync");
155 continue;
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],
165 song->file);
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]);
192 if(ostatus)
193 mpd_freeStatus(ostatus);
195 if(persistant)
196 break;
197 else
198 sleep(5);
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]);
210 return 0;