2 * Copyright 2005-2006 Timo Hirvonen
9 #include "config/version.h"
14 #include <sys/types.h>
15 #include <sys/socket.h>
22 static int raw_args
= 0;
24 static void remote_connect(const char *server
)
26 struct sockaddr_un addr
;
28 sock
= socket(PF_UNIX
, SOCK_STREAM
, 0);
31 addr
.sun_family
= AF_UNIX
;
32 strncpy(addr
.sun_path
, server
, sizeof(addr
.sun_path
) - 1);
33 if (connect(sock
, (struct sockaddr
*)&addr
, sizeof(addr
))) {
34 if (errno
== ENOENT
|| errno
== ECONNREFUSED
) {
35 /* "cmus-remote -C" can be used to check if cmus is running */
37 warn("cmus is not running\n");
44 static void write_line(const char *line
)
46 if (write_all(sock
, line
, strlen(line
)) == -1)
50 static void send_cmd(const char *format
, ...)
56 vsnprintf(buf
, sizeof(buf
), format
, ap
);
62 static char *file_url_absolute(const char *str
)
66 if (strncmp(str
, "http://", 7) == 0)
69 absolute
= path_absolute(str
);
71 die_errno("get_current_dir_name");
97 #define NR_FLAGS (FLAG_RAW + 1)
100 static struct option options
[NR_FLAGS
+ 1] = {
111 { 'R', "repeat", 0 },
112 { 'S', "shuffle", 0 },
113 { 'v', "volume", 1 },
116 { 'l', "library", 0 },
117 { 'P', "playlist", 0 },
125 static int flags
[NR_FLAGS
] = { 0, };
127 static const char *usage
=
128 "Usage: %s [OPTION]... [FILE|DIR|PLAYLIST]...\n"
129 " or: %s -C COMMAND...\n"
131 "Control cmus through socket.\n"
133 " --server SOCKET connect using socket SOCKET instead of /tmp/cmus-$USER\n"
134 " --help display this help and exit\n"
135 " --version " VERSION
"\n"
138 " -p, --play player-play\n"
139 " -u, --pause player-pause\n"
140 " -s, --stop player-stop\n"
141 " -n, --next player-next\n"
142 " -r, --prev player-prev\n"
143 " -f, --file player-play FILE\n"
144 " -R, --repeat toggle repeat\n"
145 " -S, --shuffle toggle shuffle\n"
146 " -v, --volume VOL vol VOL\n"
147 " -k, --seek SEEK seek SEEK\n"
149 " -l, --library modify library instead of playlist\n"
150 " -P, --playlist modify playlist (default)\n"
151 " -q, --queue modify play queue instead of playlist\n"
152 " -c, --clear clear playlist, library (-l) or play queue (-q)\n"
154 " Add FILE/DIR/PLAYLIST to playlist, library (-l) or play queue (-q).\n"
157 " -C, --raw treat arguments (instead of stdin) as raw commands\n"
159 " By default cmus-remote reads raw commands from stdin (one command per line).\n"
161 "Report bugs to <cmus-devel@lists.sourceforge.net>.\n";
163 int main(int argc
, char *argv
[])
165 char server_buf
[256];
167 char *play_file
= NULL
;
173 program_name
= argv
[0];
179 idx
= get_option(&argv
, options
, &arg
);
184 switch ((enum flags
)idx
) {
186 printf(usage
, program_name
, program_name
, program_name
);
189 printf("cmus " VERSION
"\nCopyright 2004-2006 Timo Hirvonen\n");
231 if (nr_cmds
&& raw_args
)
232 die("don't mix raw and cooked stuff\n");
234 if (server
== NULL
) {
235 const char *home
= getenv("HOME");
238 die("error: environment variable HOME not set\n");
239 snprintf(server_buf
, sizeof(server_buf
), "%s/.cmus/socket", home
);
243 remote_connect(server
);
247 send_cmd("%s\n", *argv
++);
251 if (nr_cmds
== 0 && argv
[0] == NULL
) {
254 while (fgets(line
, sizeof(line
), stdin
))
259 if (flags
[FLAG_CLEAR
])
260 send_cmd("clear -%c\n", context
);
261 for (i
= 0; argv
[i
]; i
++) {
262 char *filename
= file_url_absolute(argv
[i
]);
264 send_cmd("add -%c %s\n", context
, filename
);
267 if (flags
[FLAG_REPEAT
])
268 send_cmd("toggle repeat\n");
269 if (flags
[FLAG_SHUFFLE
])
270 send_cmd("toggle shuffle\n");
271 if (flags
[FLAG_STOP
])
272 send_cmd("player-stop\n");
273 if (flags
[FLAG_NEXT
])
274 send_cmd("player-next\n");
275 if (flags
[FLAG_PREV
])
276 send_cmd("player-prev\n");
277 if (flags
[FLAG_PLAY
])
278 send_cmd("player-play\n");
279 if (flags
[FLAG_PAUSE
])
280 send_cmd("player-pause\n");
281 if (flags
[FLAG_FILE
])
282 send_cmd("player-play %s\n", file_url_absolute(play_file
));
284 send_cmd("vol %s\n", volume
);
286 send_cmd("seek %s\n", seek
);