/*
* This file is part of DisOrder.
- * Copyright (C) 2004, 2005, 2006 Richard Kettlewell
+ * Copyright (C) 2004, 2005, 2006, 2007 Richard Kettlewell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <stddef.h>
#include <unistd.h>
#include <assert.h>
+#include <pcre.h>
+#include <ctype.h>
#include "configuration.h"
#include "syscalls.h"
{ "version", no_argument, 0, 'V' },
{ "config", required_argument, 0, 'c' },
{ "debug", no_argument, 0, 'd' },
+ { "local", no_argument, 0, 'l' },
+ { "no-per-user-config", no_argument, 0, 'N' },
{ "help-commands", no_argument, 0, 'H' },
+ { "user", required_argument, 0, 'u' },
+ { "password", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
" --help-commands, -H List commands\n"
" --version, -V Display version number\n"
" --config PATH, -c PATH Set configuration file\n"
+ " --local, -l Force connection to local server\n"
" --debug, -d Turn on debugging\n");
xfclose(stdout);
exit(0);
/* display version number and terminate */
static void version(void) {
- xprintf("disorder version %s\n", disorder_version_string);
+ xprintf("%s", disorder_version_string);
xfclose(stdout);
exit(0);
}
static void cf_reconfigure(disorder_client *c,
char attribute((unused)) **argv) {
+ /* Re-check configuration for server */
+ if(config_read(1)) fatal(0, "cannot read configuration");
if(disorder_reconfigure(c)) exit(EXIT_FAILURE);
}
return s[0] == '/';
}
-static void cf_authorize(disorder_client attribute((unused)) *c,
+static void cf_authorize(disorder_client *c,
char **argv) {
- if(!authorize(argv[0]))
+ if(!authorize(c, argv[0]))
auto_reconfigure = 1;
}
xprintf("%s\n", nullcheck(utf82mb(*vec++)));
}
+static void cf_users(disorder_client *c,
+ char attribute((unused)) **argv) {
+ char **vec;
+
+ if(disorder_users(c, &vec, 0)) exit(EXIT_FAILURE);
+ while(*vec)
+ xprintf("%s\n", nullcheck(utf82mb(*vec++)));
+}
+
static void cf_get_global(disorder_client *c, char **argv) {
char *value;
if(disorder_unset_global(c, argv[0])) exit(EXIT_FAILURE);
}
+static int isarg_integer(const char *s) {
+ if(!*s) return 0;
+ while(*s) {
+ if(!isdigit((unsigned char)*s))
+ return 0;
+ ++s;
+ }
+ return 1;
+}
+
+static void cf_new(disorder_client *c,
+ char **argv) {
+ char **vec;
+
+ if(disorder_new_tracks(c, &vec, 0, argv[0] ? atoi(argv[0]) : 0))
+ exit(EXIT_FAILURE);
+ while(*vec)
+ xprintf("%s\n", nullcheck(utf82mb(*vec++)));
+}
+
+static void cf_rtp_address(disorder_client *c,
+ char attribute((unused)) **argv) {
+ char *address, *port;
+
+ if(disorder_rtp_address(c, &address, &port)) exit(EXIT_FAILURE);
+ xprintf("address: %s\nport: %s\n", address, port);
+}
+
+static void cf_adduser(disorder_client *c,
+ char **argv) {
+ if(disorder_adduser(c, argv[0], argv[1]))
+ exit(EXIT_FAILURE);
+}
+
+static void cf_deluser(disorder_client *c,
+ char **argv) {
+ if(disorder_deluser(c, argv[0]))
+ exit(EXIT_FAILURE);
+}
+
+static void cf_edituser(disorder_client *c,
+ char **argv) {
+ if(disorder_edituser(c, argv[0], argv[1], argv[2]))
+ exit(EXIT_FAILURE);
+}
+
+static void cf_userinfo(disorder_client *c, char **argv) {
+ char *s;
+
+ if(disorder_userinfo(c, argv[0], argv[1], &s))
+ exit(EXIT_FAILURE);
+ xprintf("%s\n", nullcheck(utf82mb(s)));
+}
+
static const struct command {
const char *name;
int min, max;
int (*isarg)(const char *);
const char *argstr, *desc;
} commands[] = {
+ { "adduser", 2, 2, cf_adduser, 0, "USER PASSWORD",
+ "Create a new user" },
{ "allfiles", 1, 2, cf_allfiles, isarg_regexp, "DIR [~REGEXP]",
"List all files and directories in DIR" },
{ "authorize", 1, 1, cf_authorize, 0, "USER",
"Authorize USER to connect to the server" },
{ "become", 1, 1, cf_become, 0, "USER",
"Become user USER" },
+ { "deluser", 1, 1, cf_deluser, 0, "USER",
+ "Delete a user" },
{ "dirs", 1, 2, cf_dirs, isarg_regexp, "DIR [~REGEXP]",
"List directories in DIR" },
{ "disable", 0, 0, cf_disable, 0, "",
"Disable play" },
{ "disable-random", 0, 0, cf_random_disable, 0, "",
"Disable random play" },
+ { "edituser", 3, 3, cf_edituser, 0, "USER PROPERTY VALUE",
+ "Set a property of a user" },
{ "enable", 0, 0, cf_enable, 0, "",
"Enable play" },
{ "enable-random", 0, 0, cf_random_enable, 0, "",
"Copy event log to stdout" },
{ "move", 2, 2, cf_move, 0, "TRACK DELTA",
"Move a track in the queue" },
+ { "new", 0, 1, cf_new, isarg_integer, "[MAX]",
+ "Get the most recently added MAX tracks" },
{ "part", 3, 3, cf_part, 0, "TRACK CONTEXT PART",
"Find a track name part" },
{ "pause", 0, 0, cf_pause, 0, "",
"Resolve alias for TRACK" },
{ "resume", 0, 0, cf_resume, 0, "",
"Resume after a pause" },
+ { "rtp-address", 0, 0, cf_rtp_address, 0, "",
+ "Report server's broadcast address" },
{ "scratch", 0, 0, cf_scratch, 0, "",
"Scratch the currently playing track" },
{ "scratch-id", 1, 1, cf_scratch, 0, "ID",
"Unset a preference" },
{ "unset-global", 1, 1, cf_unset_global, 0, "NAME",
"Unset a global preference" },
+ { "userinfo", 2, 2, cf_userinfo, 0, "USER PROPERTY",
+ "Get a property of as user" },
+ { "users", 0, 0, cf_users, 0, "",
+ "List all users" },
{ "version", 0, 0, cf_version, 0, "",
"Display the server version" },
};
}
int main(int argc, char **argv) {
- int n, i, j;
+ int n, i, j, local = 0;
disorder_client *c = 0;
- const char *s;
int status = 0;
struct vector args;
+ const char *user = 0, *password = 0;
- mem_init(1);
+ mem_init();
+ /* garbage-collect PCRE's memory */
+ pcre_malloc = xmalloc;
+ pcre_free = xfree;
if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
- while((n = getopt_long(argc, argv, "hVc:dHL", options, 0)) >= 0) {
+ while((n = getopt_long(argc, argv, "hVc:dHlNu:p:", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'H': help_commands();
case 'V': version();
case 'c': configfile = optarg; break;
case 'd': debugging = 1; break;
+ case 'l': local = 1; break;
+ case 'N': config_per_user = 0; break;
+ case 'u': user = optarg; break;
+ case 'p': password = optarg; break;
default: fatal(0, "invalid option");
}
}
- if(config_read()) fatal(0, "cannot read configuration");
+ if(config_read(0)) fatal(0, "cannot read configuration");
+ if(user) {
+ config->username = user;
+ config->password = 0;
+ }
+ if(password)
+ config->password = password;
+ if(local)
+ config->connect.n = 0;
if(!(c = disorder_new(1))) exit(EXIT_FAILURE);
- s = config_get_file("socket");
if(disorder_connect(c)) exit(EXIT_FAILURE);
n = optind;
/* accumulate command args */