2 * Copyright 2005-2006 Timo Hirvonen
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * 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
30 #include <sys/types.h>
31 #include <sys/socket.h>
38 static int raw_args
= 0;
40 static void remote_connect(const char *server
)
42 struct sockaddr_un addr
;
44 sock
= socket(PF_UNIX
, SOCK_STREAM
, 0);
47 addr
.sun_family
= AF_UNIX
;
48 strncpy(addr
.sun_path
, server
, sizeof(addr
.sun_path
) - 1);
49 if (connect(sock
, (struct sockaddr
*)&addr
, sizeof(addr
))) {
50 if (errno
== ENOENT
|| errno
== ECONNREFUSED
) {
51 /* "cmus-remote -C" can be used to check if cmus is running */
53 warn(PACKAGE
" is not running\n");
60 static void write_line(const char *line
)
62 if (write_all(sock
, line
, strlen(line
)) == -1)
66 static void send_cmd(const char *format
, ...)
72 vsnprintf(buf
, sizeof(buf
), format
, ap
);
99 #define NR_FLAGS (FLAG_RAW + 1)
102 static struct option options
[NR_FLAGS
+ 1] = {
112 { 'R', "repeat", 0 },
113 { 'S', "shuffle", 0 },
114 { 'v', "volume", 1 },
117 { 'l', "library", 0 },
118 { 'P', "playlist", 0 },
126 static int flags
[NR_FLAGS
] = { 0, };
128 static const char *usage
=
129 "Usage: %s [OPTION]... [FILE|DIR|PLAYLIST]...\n"
130 " or: %s -C COMMAND...\n"
132 "Control cmus through socket.\n"
134 " --server SOCKET connect using socket SOCKET instead of /tmp/cmus-$USER\n"
135 " --help display this help and exit\n"
136 " --version " VERSION
"\n"
139 " -p, --play player-play\n"
140 " -u, --pause player-pause\n"
141 " -s, --stop player-stop\n"
142 " -n, --next player-next\n"
143 " -r, --prev player-prev\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 <" PACKAGE_BUGREPORT
">.\n";
163 int main(int argc
, char *argv
[])
165 char server_buf
[256];
172 program_name
= argv
[0];
178 idx
= get_option(&argv
, options
, &arg
);
183 switch ((enum flags
)idx
) {
185 printf(usage
, program_name
, program_name
, program_name
);
188 printf(PACKAGE
" " VERSION
"\nCopyright 2004-2006 Timo Hirvonen\n");
226 if (nr_cmds
&& raw_args
)
227 die("don't mix raw and cooked stuff\n");
229 if (server
== NULL
) {
230 const char *user_name
;
232 user_name
= getenv("USER");
233 if (user_name
== NULL
|| user_name
[0] == 0) {
234 user_name
= getenv("USERNAME");
235 if (user_name
== NULL
|| user_name
[0] == 0)
236 die("neither USER or USERNAME environment variable is set\n");
238 snprintf(server_buf
, sizeof(server_buf
), "/tmp/cmus-%s", user_name
);
242 remote_connect(server
);
246 send_cmd("%s\n", *argv
++);
250 if (nr_cmds
== 0 && argv
[0] == NULL
) {
253 while (fgets(line
, sizeof(line
), stdin
))
258 if (flags
[FLAG_CLEAR
])
259 send_cmd("clear -%c\n", context
);
260 for (i
= 0; argv
[i
]; i
++) {
263 if (strncmp(argv
[i
], "http://", 7) == 0) {
264 filename
= xstrdup(argv
[i
]);
266 filename
= path_absolute(argv
[i
]);
267 if (filename
== NULL
) {
268 warn_errno("get_current_dir_name");
272 send_cmd("add -%c %s\n", context
, filename
);
275 if (flags
[FLAG_REPEAT
])
276 send_cmd("toggle repeat\n");
277 if (flags
[FLAG_SHUFFLE
])
278 send_cmd("toggle shuffle\n");
279 if (flags
[FLAG_STOP
])
280 send_cmd("player-stop\n");
281 if (flags
[FLAG_NEXT
])
282 send_cmd("player-next\n");
283 if (flags
[FLAG_PREV
])
284 send_cmd("player-prev\n");
285 if (flags
[FLAG_PLAY
])
286 send_cmd("player-play\n");
287 if (flags
[FLAG_PAUSE
])
288 send_cmd("player-pause\n");
290 send_cmd("vol %s\n", volume
);
292 send_cmd("seek %s\n", seek
);