if(printf("Location: %s\n"
"%s\n"
"\n", url, dcgi_cookie_header()) < 0)
- fatal(errno, "error writing to stdout");
+ disorder_fatal(errno, "error writing to stdout");
}
/*$ playing
url = config->url;
if(printf("Refresh: %ld;url=%s\n",
refresh, url) < 0)
- fatal(errno, "error writing to stdout");
+ disorder_fatal(errno, "error writing to stdout");
dcgi_expand("playing", 1);
}
if(dcgi_client) {
if(!(id = cgi_get("id")))
- error(0, "missing 'id' argument");
+ disorder_error(0, "missing 'id' argument");
else if(!(q = dcgi_findtrack(id)))
- error(0, "unknown queue id %s", id);
+ disorder_error(0, "unknown queue id %s", id);
else if(q->origin == origin_scratch)
/* can't scratch scratches */
- error(0, "does not make sense to scratch or remove %s", id);
+ disorder_error(0, "does not make sense to scratch or remove %s", id);
else if(q->state == playing_paused
|| q->state == playing_started)
/* removing the playing track = scratching */
disorder_remove(dcgi_client, id);
else
/* various error states */
- error(0, "does not make sense to scratch or remove %s", id);
+ disorder_error(0, "does not make sense to scratch or remove %s", id);
}
redirect(0);
}
if(dcgi_client) {
if(!(id = cgi_get("id")))
- error(0, "missing 'id' argument");
+ disorder_error(0, "missing 'id' argument");
else if(!(delta = cgi_get("delta")))
- error(0, "missing 'delta' argument");
+ disorder_error(0, "missing 'delta' argument");
else if(!(q = dcgi_findtrack(id)))
- error(0, "unknown queue id %s", id);
+ disorder_error(0, "unknown queue id %s", id);
else switch(q->state) {
case playing_random: /* unplayed randomly chosen track */
case playing_unplayed: /* haven't played this track yet */
disorder_move(dcgi_client, id, atol(delta));
break;
default:
- error(0, "does not make sense to scratch %s", id);
+ disorder_error(0, "does not make sense to scratch %s", id);
break;
}
}
"\n"
"%s?c=%s\n", config->url, urlencodestring(confirm));
if(!(text = mime_encode_text(text, &charset, &encoding)))
- fatal(0, "cannot encode email");
+ disorder_fatal(0, "cannot encode email");
byte_xasprintf(&content_type, "text/plain;charset=%s",
quote822(charset, 0));
sendmail("", config->mail_sender, email, "Welcome to DisOrder",
mx_expand_file(found, sink_discard(), 0);
/* For unknown actions check that they aren't evil */
if(!dcgi_valid_action(name))
- fatal(0, "invalid action name '%s'", name);
+ disorder_fatal(0, "invalid action name '%s'", name);
byte_xasprintf((char **)&p, "%s.tmpl", name);
if(!(found = mx_find(p, 0/*report*/)))
- fatal(errno, "cannot find %s", p);
+ disorder_fatal(errno, "cannot find %s", p);
if(header) {
if(printf("Content-Type: text/html; charset=UTF-8\n"
"%s\n"
"\n", dcgi_cookie_header()) < 0)
- fatal(errno, "error writing to stdout");
+ disorder_fatal(errno, "error writing to stdout");
}
if(mx_expand_file(found, sink_stdio("stdout", stdout), 0) == -1
|| fflush(stdout) < 0)
- fatal(errno, "error writing to stdout");
+ disorder_fatal(errno, "error writing to stdout");
}
/** @brief Execute a web action
mx_search_path(pkgdatadir);
/* Never cache anythging */
if(printf("Cache-Control: no-cache\n") < 0)
- fatal(errno, "error writing to stdout");
+ disorder_fatal(errno, "error writing to stdout");
/* Create the initial connection, trying the cookie if we found a suitable
* one. */
dcgi_login();
/* In practice if a write fails that probably means the web server went away,
* but we log it anyway. */
if(fclose(stdout) < 0)
- fatal(errno, "error closing stdout");
+ disorder_fatal(errno, "error closing stdout");
return 0;
}
if(best_cookie != -1)
dcgi_cookie = cd.cookies[best_cookie].value;
} else
- error(0, "could not parse cookie field '%s'", cookie_env);
+ disorder_error(0, "could not parse cookie field '%s'", cookie_env);
}
}
return rc;
/* Reject relative paths */
if(dir[0] != '/') {
- error(0, "breadcrumbs: '%s' is a relative path", dir);
+ disorder_error(0, "breadcrumbs: '%s' is a relative path", dir);
return 0;
}
/* Skip the root */
void *u) {
struct read_options_state *cs = u;
- error(0, "%s:%d: %s", cs->name, cs->line, msg);
+ disorder_error(0, "%s:%d: %s", cs->name, cs->line, msg);
}
static void option__readfile(const char *name) {
if(!(cs.name = mx_find(name, 1/*report*/)))
return;
if(!(fp = fopen(cs.name, "r")))
- fatal(errno, "error opening %s", cs.name);
+ disorder_fatal(errno, "error opening %s", cs.name);
cs.line = 0;
while(!inputline(cs.name, fp, &buffer, '\n')) {
++cs.line;
if(!n)
continue;
if((i = TABLE_FIND(options, name, vec[0])) == -1) {
- error(0, "%s:%d: unknown option '%s'", cs.name, cs.line, vec[0]);
+ disorder_error(0, "%s:%d: unknown option '%s'", cs.name, cs.line, vec[0]);
continue;
}
++vec;
--n;
if(n < options[i].minargs) {
- error(0, "%s:%d: too few arguments to '%s'", cs.name, cs.line, vec[-1]);
+ disorder_error(0, "%s:%d: too few arguments to '%s'", cs.name, cs.line, vec[-1]);
continue;
}
if(n > options[i].maxargs) {
- error(0, "%s:%d: too many arguments to '%s'", cs.name, cs.line, vec[-1]);
+ disorder_error(0, "%s:%d: too many arguments to '%s'", cs.name, cs.line, vec[-1]);
continue;
}
options[i].handler(n, vec);
if(!(pw = getpwnam(user)))
/* If it's a NIS world then /etc/passwd may be a lie, but it emphasizes
* that it's talking about the login user, not the DisOrder user */
- fatal(0, "no such user as %s in /etc/passwd", user);
+ disorder_fatal(0, "no such user as %s in /etc/passwd", user);
/* Choose a random password */
gcry_randomize(pwbin, sizeof pwbin, GCRY_STRONG_RANDOM);
/* Become the target user */
if(setegid(pw->pw_gid) < 0)
- fatal(errno, "setegid %lu", (unsigned long)pw->pw_gid);
+ disorder_fatal(errno, "setegid %lu", (unsigned long)pw->pw_gid);
if(seteuid(pw->pw_uid) < 0)
- fatal(errno, "seteuid %lu", (unsigned long)pw->pw_uid);
+ disorder_fatal(errno, "seteuid %lu", (unsigned long)pw->pw_uid);
/* Make sure the configuration directory exists*/
byte_xasprintf(&configdir, "%s/.disorder", pw->pw_dir);
if(mkdir(configdir, 02700) < 0) {
if(errno != EEXIST)
- fatal(errno, "creating %s", configdir);
+ disorder_fatal(errno, "creating %s", configdir);
}
/* Make sure the configuration file does not exist */
byte_xasprintf(&configpath, "%s/passwd", configdir);
if(lstat(configpath, &sb) == 0)
- fatal(0, "%s already exists", configpath);
+ disorder_fatal(0, "%s already exists", configpath);
if(errno != ENOENT)
- fatal(errno, " checking %s", configpath);
+ disorder_fatal(errno, " checking %s", configpath);
byte_xasprintf(&configpathtmp, "%s.new", configpath);
/* Create config file with mode 600 */
if((fd = open(configpathtmp, O_WRONLY|O_CREAT, 0600)) < 0)
- fatal(errno, "error creating %s", configpathtmp);
+ disorder_fatal(errno, "error creating %s", configpathtmp);
/* Write password */
if(!(fp = fdopen(fd, "w")))
- fatal(errno, "error calling fdopen");
+ disorder_fatal(errno, "error calling fdopen");
if(fprintf(fp, "password %s\n", pwhex) < 0
|| fclose(fp) < 0)
- fatal(errno, "error writing to %s", configpathtmp);
+ disorder_fatal(errno, "error writing to %s", configpathtmp);
/* Rename config file into place */
if(rename(configpathtmp, configpath) < 0)
- fatal(errno, "error renaming %s to %s", configpathtmp, configpath);
+ disorder_fatal(errno, "error renaming %s to %s", configpathtmp, configpath);
/* Put our identity back */
if(seteuid(old_uid) < 0)
- fatal(errno, "seteuid %lu", (unsigned long)old_uid);
+ disorder_fatal(errno, "seteuid %lu", (unsigned long)old_uid);
if(setegid(old_gid) < 0)
- fatal(errno, "setegid %lu", (unsigned long)old_gid);
+ disorder_fatal(errno, "setegid %lu", (unsigned long)old_gid);
return 0;
}
static void cf_reconfigure(char attribute((unused)) **argv) {
/* Re-check configuration for server */
- if(config_read(1, NULL)) fatal(0, "cannot read configuration");
+ if(config_read(1, NULL))
+ disorder_fatal(0, "cannot read configuration");
if(disorder_reconfigure(getclient())) exit(EXIT_FAILURE);
}
int e;
if((e = xstrtol(&n, argv[1], 0, 10)))
- fatal(e, "cannot convert '%s'", argv[1]);
+ disorder_fatal(e, "cannot convert '%s'", argv[1]);
if(n > INT_MAX || n < INT_MIN)
- fatal(e, "%ld out of range", n);
+ disorder_fatal(e, "%ld out of range", n);
if(disorder_move(getclient(), argv[0], (int)n)) exit(EXIT_FAILURE);
}
case 'h': help_setup_guest();
case 'r': online_registration = 1; break;
case 'R': online_registration = 0; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if(online_registration && !config->mail_sender)
- fatal(0, "you MUST set mail_sender if you want online registration");
+ disorder_fatal(0, "you MUST set mail_sender if you want online registration");
if(disorder_adduser(getclient(), "guest", "",
online_registration ? "read,register" : "read"))
exit(EXIT_FAILURE);
if(argv[1]) {
// Read track list from file
if(!(input = fopen(argv[1], "r")))
- fatal(errno, "opening %s", argv[1]);
+ disorder_fatal(errno, "opening %s", argv[1]);
tag = argv[1];
} else {
// Read track list from standard input
vector_append(v, l);
}
if(ferror(input))
- fatal(errno, "reading %s", tag);
+ disorder_fatal(errno, "reading %s", tag);
if(input != stdin)
fclose(input);
if(disorder_playlist_lock(getclient(), argv[0])
const char *password;
while(!trackdb_readable()) {
- info("waiting for trackdb...");
+ disorder_info("waiting for trackdb...");
sleep(1);
}
trackdb_init(TRACKDB_NO_RECOVER|TRACKDB_NO_UPGRADE);
trackdb_close();
if(password)
break;
- info("waiting for root user to be created...");
+ disorder_info("waiting for root user to be created...");
sleep(1);
}
trackdb_deinit(NULL);
/* garbage-collect PCRE's memory */
pcre_malloc = xmalloc;
pcre_free = xfree;
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
- if(!setlocale(LC_TIME, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_TIME, "")) disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "+hVc:dHlNu:p:W", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'u': user = optarg; break;
case 'p': password = optarg; break;
case 'W': wfr = 1; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
- if(config_read(0, NULL)) fatal(0, "cannot read configuration");
+ if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
if(user) {
config->username = user;
config->password = 0;
/* accumulate command args */
while(n < argc) {
if((i = TABLE_FIND(commands, name, argv[n])) < 0)
- fatal(0, "unknown command '%s'", argv[n]);
+ disorder_fatal(0, "unknown command '%s'", argv[n]);
if(n + commands[i].min >= argc)
- fatal(0, "missing arguments to '%s'", argv[n]);
+ disorder_fatal(0, "missing arguments to '%s'", argv[n]);
vector_init(&args);
/* Include the command name in the args, but at element -1, for
* the benefit of subcommand getopt calls */
n += j;
}
if(client && disorder_close(client)) exit(EXIT_FAILURE);
- if(fclose(stdout) < 0) fatal(errno, "error closing stdout");
+ if(fclose(stdout) < 0) disorder_fatal(errno, "error closing stdout");
return status;
}
struct stat sb;
if((fdin = open(from, O_RDONLY)) < 0)
- fatal(errno, "error opening %s", from);
+ disorder_fatal(errno, "error opening %s", from);
if((fdout = open(to, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
- fatal(errno, "error opening %s", to);
+ disorder_fatal(errno, "error opening %s", to);
while((n = read(fdin, buffer, sizeof buffer)) > 0) {
if(write(fdout, buffer, n) < 0)
- fatal(errno, "error writing to %s", to);
+ disorder_fatal(errno, "error writing to %s", to);
}
- if(n < 0) fatal(errno, "error reading %s", from);
+ if(n < 0)
+ disorder_fatal(errno, "error reading %s", from);
if(fstat(fdin, &sb) < 0)
- fatal(errno, "error stating %s", from);
+ disorder_fatal(errno, "error stating %s", from);
if(fchown(fdout, sb.st_uid, sb.st_gid) < 0)
- fatal(errno, "error chowning %s", from);
+ disorder_fatal(errno, "error chowning %s", from);
if(fchmod(fdout, sb.st_mode & 07777) < 0)
- fatal(errno, "error chmoding %s", from);
- if(close(fdout) < 0) fatal(errno, "error closing %s", to);
+ disorder_fatal(errno, "error chmoding %s", from);
+ if(close(fdout) < 0) disorder_fatal(errno, "error closing %s", to);
xclose(fdin);
return 0;
}
* directory. In that case we'd better not descend into it when we encounter
* it in the source. */
if(!strcmp(fullsourcepath, destination)) {
- info("%s matches destination directory, not recursing", errsourcepath);
+ disorder_info("%s matches destination directory, not recursing", errsourcepath);
return;
}
/* Find out what kind of file we're dealing with */
if(stat(fullsourcepath, &sb) < 0) {
- error(errno, "cannot stat %s", errsourcepath );
+ disorder_error(errno, "cannot stat %s", errsourcepath );
++errors;
return;
}
if(S_ISREG(sb.st_mode)) {
if(copier != nocopy)
if(unlink(fulldestpath) < 0 && errno != ENOENT) {
- error(errno, "cannot remove %s", errdestpath);
+ disorder_error(errno, "cannot remove %s", errdestpath);
++errors;
return;
}
if(copier(fullsourcepath, fulldestpath) < 0) {
- error(errno, "cannot link %s to %s", errsourcepath, errdestpath);
+ disorder_error(errno, "cannot link %s to %s", errsourcepath, errdestpath);
++errors;
return;
}
/* Created new directory. Adjust permissions and ownership to match the
* old one. */
if(chown(fulldestpath, sb.st_uid, sb.st_gid) < 0) {
- error(errno, "cannot chown %s", errdestpath);
+ disorder_error(errno, "cannot chown %s", errdestpath);
++errors;
}
if(chmod(fulldestpath, sb.st_mode & 07777) < 0) {
- error(errno, "cannot chmod %s", errdestpath);
+ disorder_error(errno, "cannot chmod %s", errdestpath);
++errors;
}
}
} else if(errno != EEXIST) {
- error(errno, "cannot mkdir %s", errdestpath);
+ disorder_error(errno, "cannot mkdir %s", errdestpath);
++errors;
return;
}
/* We read the directory and visit all the files in it in any old order. */
if(!(dp = opendir(fullsourcepath))) {
- error(errno, "cannot open directory %s", errsourcepath);
+ disorder_error(errno, "cannot open directory %s", errsourcepath);
++errors;
return;
}
}
visit(childpath, childdestpath);
}
- if(errno) fatal(errno, "error reading directory %s", errsourcepath);
+ if(errno)
+ disorder_fatal(errno, "error reading directory %s", errsourcepath);
closedir(dp);
} else {
/* We don't handle special files, but we'd better warn the user. */
- info("ignoring %s", errsourcepath);
+ disorder_info("ignoring %s", errsourcepath);
}
}
struct pattern *p;
mem_init();
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, ""))
+ disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVdf:t:i:e:ET:u:wlscn", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 's': copier = symlink; break;
case 'c': copier = copy; break;
case 'n': copier = nocopy; dirmaker = nomkdir; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
- if(optind == argc) fatal(0, "missing SOURCE and DESTINATION arguments");
- else if(optind + 1 == argc) fatal(0, "missing DESTINATION argument");
- else if(optind + 2 != argc) fatal(0, "redundant extra arguments");
- if(extracttags) fatal(0, "--extract-tags is not implemented yet"); /* TODO */
+ if(optind == argc)
+ disorder_fatal(0, "missing SOURCE and DESTINATION arguments");
+ else if(optind + 1 == argc) disorder_fatal(0, "missing DESTINATION argument");
+ else if(optind + 2 != argc) disorder_fatal(0, "redundant extra arguments");
+ if(extracttags)
+ disorder_fatal(0, "--extract-tags is not implemented yet"); /* TODO */
if(tagencoding && !extracttags)
- fatal(0, "--tag-encoding without --extra-tags does not make sense");
+ disorder_fatal(0, "--tag-encoding without --extra-tags does not make sense");
if(untagged && !extracttags)
- fatal(0, "--untagged without --extra-tags does not make sense");
+ disorder_fatal(0, "--untagged without --extra-tags does not make sense");
source = argv[optind];
destination = argv[optind + 1];
nativeencoding = nl_langinfo(CODESET);
strcpy(sa.sun_path, control_socket);
sfd = xsocket(PF_UNIX, SOCK_STREAM, 0);
if(bind(sfd, (const struct sockaddr *)&sa, sizeof sa) < 0)
- fatal(errno, "error binding to %s", control_socket);
+ disorder_fatal(errno, "error binding to %s", control_socket);
if(listen(sfd, 128) < 0)
- fatal(errno, "error calling listen on %s", control_socket);
- info("listening on %s", control_socket);
+ disorder_fatal(errno, "error calling listen on %s", control_socket);
+ disorder_info("listening on %s", control_socket);
for(;;) {
salen = sizeof sa;
cfd = accept(sfd, (struct sockaddr *)&sa, &salen);
case EAGAIN:
break;
default:
- fatal(errno, "error calling accept on %s", control_socket);
+ disorder_fatal(errno, "error calling accept on %s", control_socket);
}
}
if(!(fp = fdopen(cfd, "r+"))) {
- error(errno, "error calling fdopen for %s connection", control_socket);
+ disorder_error(errno, "error calling fdopen for %s connection", control_socket);
close(cfd);
continue;
}
if(!inputline(control_socket, fp, &line, '\n')) {
if(!strcmp(line, "stop")) {
- info("stopped via %s", control_socket);
+ disorder_info("stopped via %s", control_socket);
exit(0); /* terminate immediately */
}
if(!strcmp(line, "query"))
xfree(line);
}
if(fclose(fp) < 0)
- error(errno, "error closing %s connection", control_socket);
+ disorder_error(errno, "error closing %s connection", control_socket);
}
}
case EINTR:
continue;
default:
- fatal(errno, "error reading from socket");
+ disorder_fatal(errno, "error reading from socket");
}
}
/* Ignore too-short packets */
if((size_t)n <= sizeof (struct rtp_header)) {
- info("ignored a short packet");
+ disorder_info("ignored a short packet");
continue;
}
timestamp = htonl(header.timestamp);
seq = htons(header.seq);
/* Ignore packets in the past */
if(active && lt(timestamp, next_timestamp)) {
- info("dropping old packet, timestamp=%"PRIx32" < %"PRIx32,
+ disorder_info("dropping old packet, timestamp=%"PRIx32" < %"PRIx32,
timestamp, next_timestamp);
continue;
}
break;
/* TODO support other RFC3551 media types (when the speaker does) */
default:
- fatal(0, "unsupported RTP payload type %d",
- header.mpt & 0x7F);
+ disorder_fatal(0, "unsupported RTP payload type %d", header.mpt & 0x7F);
}
/* See if packet is silent */
const uint16_t *s = p->samples_raw;
//fprintf(stderr, "%8u/%u (%u) DROPPING\n", nsamples, maxbuffer, minbuffer);
drop_first_packet();
}
- info("Buffering...");
+ disorder_info("Buffering...");
/* Wait until there's at least minbuffer samples available */
while(nsamples < minbuffer) {
//fprintf(stderr, "%8u/%u (%u) FILLING\n", nsamples, maxbuffer, minbuffer);
* basis.
*/
if(nsamples > minbuffer && silent) {
- info("dropping %zu samples (%"PRIu32" > %"PRIu32")",
- samples, nsamples, minbuffer);
+ disorder_info("dropping %zu samples (%"PRIu32" > %"PRIu32")",
+ samples, nsamples, minbuffer);
samples = 0;
}
/* Junk obsolete packets */
* timestamps in the logs */
logdate = 1;
mem_init();
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
backend = uaudio_apis[0];
while((n = getopt_long(argc, argv, "hVdD:m:x:L:R:aocC:re:P:M", options, 0)) >= 0) {
switch(n) {
case 'e': backend = &uaudio_command; uaudio_set("command", optarg); break;
case 'P': uaudio_set("pause-mode", optarg); break;
case 'M': monitor = 1; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
- if(config_read(0, NULL)) fatal(0, "cannot read configuration");
+ if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
if(!maxbuffer)
maxbuffer = 2 * minbuffer;
argc -= optind;
sl.s = argv;
break;
default:
- fatal(0, "usage: disorder-playrtp [OPTIONS] [[ADDRESS] PORT]");
+ disorder_fatal(0, "usage: disorder-playrtp [OPTIONS] [[ADDRESS] PORT]");
}
/* Look up address and port */
if(!(res = get_address(&sl, &prefs, &sockname)))
if((rtpfd = socket(res->ai_family,
res->ai_socktype,
res->ai_protocol)) < 0)
- fatal(errno, "error creating socket");
+ disorder_fatal(errno, "error creating socket");
/* Allow multiple listeners */
xsetsockopt(rtpfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
is_multicast = multicast(res->ai_addr);
mgroup.in6.sin6_port = 0;
break;
default:
- fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family);
+ disorder_fatal(0, "unsupported address family %d",
+ (int)res->ai_addr->sa_family);
}
/* Bind to to the multicast group address */
if(bind(rtpfd, res->ai_addr, res->ai_addrlen) < 0)
- fatal(errno, "error binding socket to %s", format_sockaddr(res->ai_addr));
+ disorder_fatal(errno, "error binding socket to %s",
+ format_sockaddr(res->ai_addr));
/* Add multicast group membership */
switch(mgroup.sa.sa_family) {
case PF_INET:
mreq.imr_interface.s_addr = 0; /* use primary interface */
if(setsockopt(rtpfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&mreq, sizeof mreq) < 0)
- fatal(errno, "error calling setsockopt IP_ADD_MEMBERSHIP");
+ disorder_fatal(errno, "error calling setsockopt IP_ADD_MEMBERSHIP");
break;
case PF_INET6:
mreq6.ipv6mr_multiaddr = mgroup.in6.sin6_addr;
memset(&mreq6.ipv6mr_interface, 0, sizeof mreq6.ipv6mr_interface);
if(setsockopt(rtpfd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
&mreq6, sizeof mreq6) < 0)
- fatal(errno, "error calling setsockopt IPV6_JOIN_GROUP");
+ disorder_fatal(errno, "error calling setsockopt IPV6_JOIN_GROUP");
break;
default:
- fatal(0, "unsupported address family %d", res->ai_family);
+ disorder_fatal(0, "unsupported address family %d", res->ai_family);
}
/* Report what we did */
- info("listening on %s multicast group %s",
- format_sockaddr(res->ai_addr), format_sockaddr(&mgroup.sa));
+ disorder_info("listening on %s multicast group %s",
+ format_sockaddr(res->ai_addr), format_sockaddr(&mgroup.sa));
} else {
/* Bind to 0/port */
switch(res->ai_addr->sa_family) {
break;
}
default:
- fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family);
+ disorder_fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family);
}
if(bind(rtpfd, res->ai_addr, res->ai_addrlen) < 0)
- fatal(errno, "error binding socket to %s", format_sockaddr(res->ai_addr));
+ disorder_fatal(errno, "error binding socket to %s",
+ format_sockaddr(res->ai_addr));
/* Report what we did */
- info("listening on %s", format_sockaddr(res->ai_addr));
+ disorder_info("listening on %s", format_sockaddr(res->ai_addr));
}
len = sizeof rcvbuf;
if(getsockopt(rtpfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len) < 0)
- fatal(errno, "error calling getsockopt SO_RCVBUF");
+ disorder_fatal(errno, "error calling getsockopt SO_RCVBUF");
if(target_rcvbuf > rcvbuf) {
if(setsockopt(rtpfd, SOL_SOCKET, SO_RCVBUF,
&target_rcvbuf, sizeof target_rcvbuf) < 0)
- error(errno, "error calling setsockopt SO_RCVBUF %d",
- target_rcvbuf);
+ disorder_error(errno, "error calling setsockopt SO_RCVBUF %d",
+ target_rcvbuf);
/* We try to carry on anyway */
else
- info("changed socket receive buffer from %d to %d",
- rcvbuf, target_rcvbuf);
+ disorder_info("changed socket receive buffer from %d to %d",
+ rcvbuf, target_rcvbuf);
} else
- info("default socket receive buffer %d", rcvbuf);
+ disorder_info("default socket receive buffer %d", rcvbuf);
//info("minbuffer %u maxbuffer %u", minbuffer, maxbuffer);
if(logfp)
- info("WARNING: -L option can impact performance");
+ disorder_info("WARNING: -L option can impact performance");
if(control_socket) {
pthread_t tid;
if((err = pthread_create(&tid, 0, control_thread, 0)))
- fatal(err, "pthread_create control_thread");
+ disorder_fatal(err, "pthread_create control_thread");
}
if(dumpfile) {
int fd;
size_t written;
if((fd = open(dumpfile, O_RDWR|O_TRUNC|O_CREAT, 0666)) < 0)
- fatal(errno, "opening %s", dumpfile);
+ disorder_fatal(errno, "opening %s", dumpfile);
/* Fill with 0s to a suitable size */
memset(buffer, 0, sizeof buffer);
for(written = 0; written < dump_size * sizeof(int16_t);
written += sizeof buffer) {
if(write(fd, buffer, sizeof buffer) < 0)
- fatal(errno, "clearing %s", dumpfile);
+ disorder_fatal(errno, "clearing %s", dumpfile);
}
/* Map the buffer into memory for convenience */
dump_buffer = mmap(0, dump_size * sizeof(int16_t), PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0);
if(dump_buffer == (void *)-1)
- fatal(errno, "mapping %s", dumpfile);
- info("dumping to %s", dumpfile);
+ disorder_fatal(errno, "mapping %s", dumpfile);
+ disorder_info("dumping to %s", dumpfile);
}
/* Set up output. Currently we only support L16 so there's no harm setting
* the format before we know what it is! */
backend->start(playrtp_callback, NULL);
/* We receive and convert audio data in a background thread */
if((err = pthread_create(<id, 0, listen_thread, 0)))
- fatal(err, "pthread_create listen_thread");
+ disorder_fatal(err, "pthread_create listen_thread");
/* We have a second thread to add received packets to the queue */
if((err = pthread_create(<id, 0, queue_thread, 0)))
- fatal(err, "pthread_create queue_thread");
+ disorder_fatal(err, "pthread_create queue_thread");
pthread_mutex_lock(&lock);
time_t lastlog = 0;
for(;;) {
/* Wait for the buffer to fill up a bit */
playrtp_fill_buffer();
/* Start playing now */
- info("Playing...");
+ disorder_info("Playing...");
next_timestamp = pheap_first(&packets)->timestamp;
active = 1;
pthread_mutex_unlock(&lock);
if(now >= lastlog + 60) {
int offset = nsamples - minbuffer;
double offtime = (double)offset / (uaudio_rate * uaudio_channels);
- info("%+d samples off (%d.%02ds, %d bytes)",
- offset,
- (int)fabs(offtime) * (offtime < 0 ? -1 : 1),
- (int)(fabs(offtime) * 100) % 100,
- offset * uaudio_bits / CHAR_BIT);
+ disorder_info("%+d samples off (%d.%02ds, %d bytes)",
+ offset,
+ (int)fabs(offtime) * (offtime < 0 ? -1 : 1),
+ (int)(fabs(offtime) * 100) % 100,
+ offset * uaudio_bits / CHAR_BIT);
lastlog = now;
}
}
rate((ringtail - RINGSIZE / 2) % RINGSIZE,
(ringtail - 1) % RINGSIZE)) < 0
|| fflush(stdout) < 0)
- fatal(errno, "stdout");
+ disorder_fatal(errno, "stdout");
}
}
mem_init();
if(!setlocale(LC_CTYPE, ""))
- fatal(errno, "error calling setlocale");
+ disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVb:", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'V': version("rtpmon");
case 'b': bpf = atoi(optarg); break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
argc -= optind;
sl.s = argv;
break;
default:
- fatal(0, "usage: rtpmon [OPTIONS] [ADDRESS] PORT");
+ disorder_fatal(0, "usage: rtpmon [OPTIONS] [ADDRESS] PORT");
}
if(!(res = get_address(&sl, &prefs, &sockname)))
exit(1);
if((rtpfd = socket(res->ai_family,
res->ai_socktype,
res->ai_protocol)) < 0)
- fatal(errno, "error creating socket");
+ disorder_fatal(errno, "error creating socket");
/* Allow multiple listeners */
xsetsockopt(rtpfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
is_multicast = multicast(res->ai_addr);
mgroup.in6.sin6_port = 0;
break;
default:
- fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family);
+ disorder_fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family);
}
/* Bind to to the multicast group address */
if(bind(rtpfd, res->ai_addr, res->ai_addrlen) < 0)
- fatal(errno, "error binding socket to %s", format_sockaddr(res->ai_addr));
+ disorder_fatal(errno, "error binding socket to %s",
+ format_sockaddr(res->ai_addr));
/* Add multicast group membership */
switch(mgroup.sa.sa_family) {
case PF_INET:
mreq.imr_interface.s_addr = 0; /* use primary interface */
if(setsockopt(rtpfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&mreq, sizeof mreq) < 0)
- fatal(errno, "error calling setsockopt IP_ADD_MEMBERSHIP");
+ disorder_fatal(errno, "error calling setsockopt IP_ADD_MEMBERSHIP");
break;
case PF_INET6:
mreq6.ipv6mr_multiaddr = mgroup.in6.sin6_addr;
memset(&mreq6.ipv6mr_interface, 0, sizeof mreq6.ipv6mr_interface);
if(setsockopt(rtpfd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
&mreq6, sizeof mreq6) < 0)
- fatal(errno, "error calling setsockopt IPV6_JOIN_GROUP");
+ disorder_fatal(errno, "error calling setsockopt IPV6_JOIN_GROUP");
break;
default:
- fatal(0, "unsupported address family %d", res->ai_family);
+ disorder_fatal(0, "unsupported address family %d", res->ai_family);
}
/* Report what we did */
- info("listening on %s multicast group %s",
- format_sockaddr(res->ai_addr), format_sockaddr(&mgroup.sa));
+ disorder_info("listening on %s multicast group %s",
+ format_sockaddr(res->ai_addr), format_sockaddr(&mgroup.sa));
} else {
/* Bind to 0/port */
switch(res->ai_addr->sa_family) {
memset(&in->sin_addr, 0, sizeof (struct in_addr));
if(bind(rtpfd, res->ai_addr, res->ai_addrlen) < 0)
- fatal(errno, "error binding socket to 0.0.0.0 port %d",
- ntohs(in->sin_port));
+ disorder_fatal(errno, "error binding socket to 0.0.0.0 port %d",
+ ntohs(in->sin_port));
break;
}
case AF_INET6: {
break;
}
default:
- fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family);
+ disorder_fatal(0, "unsupported family %d", (int)res->ai_addr->sa_family);
}
if(bind(rtpfd, res->ai_addr, res->ai_addrlen) < 0)
- fatal(errno, "error binding socket to %s", format_sockaddr(res->ai_addr));
+ disorder_fatal(errno, "error binding socket to %s",
+ format_sockaddr(res->ai_addr));
/* Report what we did */
- info("listening on %s", format_sockaddr(res->ai_addr));
+ disorder_info("listening on %s", format_sockaddr(res->ai_addr));
}
for(;;) {
struct rtp_header header;
case EINTR:
continue;
default:
- fatal(errno, "error reading from socket");
+ disorder_fatal(errno, "error reading from socket");
}
}
if((size_t)n <= sizeof (struct rtp_header)) {
- info("ignored a short packet");
+ disorder_info("ignored a short packet");
continue;
}
frames(&when, (n - sizeof header) / bpf);
/* garbage-collect PCRE's memory */
pcre_malloc = xmalloc;
pcre_free = xfree;
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
gtkok = gtk_init_check(&argc, &argv);
while((n = getopt_long(argc, argv, "hVc:dtHC", options, 0)) >= 0) {
switch(n) {
case 'c': configfile = optarg; break;
case 'd': debugging = 1; break;
case 't': goesupto = 11; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if(!gtkok)
- fatal(0, "failed to initialize GTK+");
+ disorder_fatal(0, "failed to initialize GTK+");
/* gcrypt initialization */
if(!gcry_check_version(NULL))
disorder_fatal(0, "gcry_check_version failed");
/* create the event loop */
D(("create main loop"));
mainloop = g_main_loop_new(0, 0);
- if(config_read(0, NULL)) fatal(0, "cannot read configuration");
+ if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
/* we'll need mixer support */
backend = uaudio_apis[0];
if(backend->configure)
exitfn = _exit;
if(!xfork()) {
execlp(browser, browser, path, (char *)0);
- fatal(errno, "error executing %s", browser);
+ disorder_fatal(errno, "error executing %s", browser);
}
_exit(0);
}
if((n = TABLE_FIND(images, name, name)) >= 0) {
/* Use the built-in copy */
if(!(pb = gdk_pixbuf_new_from_inline(-1, images[n].data, FALSE, &err))) {
- error(0, "%s", err->message);
+ disorder_error(0, "%s", err->message);
return 0;
}
} else {
/* See if there's a copy on disk */
byte_xasprintf(&path, "%s/static/%s", pkgdatadir, name);
if(!(pb = gdk_pixbuf_new_from_file(path, &err))) {
- error(0, "%s", err->message);
+ disorder_error(0, "%s", err->message);
return 0;
}
}
/* double-fork so we don't have to wait() later */
if(!(pid = xfork())) {
if(setsid() < 0)
- fatal(errno, "error calling setsid");
+ disorder_fatal(errno, "error calling setsid");
if(!(pid = xfork())) {
/* grandchild */
exitfn = _exit;
/* log errors and output somewhere reasonably sane. rtp_running()
* will have made sure the directory exists. */
if((fd = open(rtp_log, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0)
- fatal(errno, "creating %s", rtp_log);
+ disorder_fatal(errno, "creating %s", rtp_log);
if(dup2(fd, 1) < 0
|| dup2(fd, 2) < 0)
- fatal(errno, "dup2");
+ disorder_fatal(errno, "dup2");
if(close(fd) < 0)
- fatal(errno, "close");
+ disorder_fatal(errno, "close");
/* We don't want to hang onto whatever stdin was */
if((fd = open("/dev/null", O_RDONLY)) < 0)
- fatal(errno, "opening /dev/null");
+ disorder_fatal(errno, "opening /dev/null");
if(dup2(fd, 0) < 0)
- fatal(errno, "dup2");
+ disorder_fatal(errno, "dup2");
if(close(fd) < 0)
- fatal(errno, "close");
+ disorder_fatal(errno, "close");
/* execute the player */
execlp("disorder-playrtp",
"disorder-playrtp", "--socket", rtp_socket, (char *)0);
- fatal(errno, "disorder-playrtp");
+ disorder_fatal(errno, "disorder-playrtp");
} else {
/* child */
_exit(0);
if(!strcmp(vec[0], "color")) {
GdkColor *color;
if(nvec != 7) {
- error(0, "%s: malformed '%s' command", path, vec[0]);
+ disorder_error(0, "%s: malformed '%s' command", path, vec[0]);
continue;
}
for(n = 0; n < NSTYLES && strcmp(styles[n].name, vec[1]); ++n)
;
if(n >= NSTYLES) {
- error(0, "%s: unknown style '%s'", path, vec[1]);
+ disorder_error(0, "%s: unknown style '%s'", path, vec[1]);
continue;
}
for(m = 0; m < NSTATES && strcmp(states[m], vec[2]); ++m)
;
if(m >= NSTATES) {
- error(0, "%s: unknown state '%s'", path, vec[2]);
+ disorder_error(0, "%s: unknown state '%s'", path, vec[2]);
continue;
}
for(c = 0; c < NCOLORS && strcmp(colors[c].name, vec[3]); ++c)
;
if(c >= NCOLORS) {
- error(0, "%s: unknown color '%s'", path, vec[3]);
+ disorder_error(0, "%s: unknown color '%s'", path, vec[3]);
continue;
}
color = (GdkColor *)((char *)styles[n].style + colors[c].offset) + m;
color->blue = strtoul(vec[6], 0, 0);
} else if(!strcmp(vec[0], "browser")) {
if(nvec != 2) {
- error(0, "%s: malformed '%s' command", path, vec[0]);
+ disorder_error(0, "%s: malformed '%s' command", path, vec[0]);
continue;
}
browser = vec[1];
} else
/* mention errors but otherwise ignore them */
- error(0, "%s: unknown command '%s'", path, vec[0]);
+ disorder_error(0, "%s: unknown command '%s'", path, vec[0]);
}
if(ferror(fp)) {
fpopup_msg(GTK_MESSAGE_ERROR, "error reading %s: %s",
case 1:
byte_xasprintf(&name, "host * service %s", a->s[0]);
if((rc = getaddrinfo(0, a->s[0], pref, &res))) {
- error(0, "getaddrinfo %s: %s", a->s[0], gai_strerror(rc));
+ disorder_error(0, "getaddrinfo %s: %s", a->s[0], gai_strerror(rc));
return 0;
}
break;
case 2:
byte_xasprintf(&name, "host %s service %s", a->s[0], a->s[1]);
if((rc = getaddrinfo(a->s[0], a->s[1], pref, &res))) {
- error(0, "getaddrinfo %s %s: %s", a->s[0], a->s[1], gai_strerror(rc));
+ disorder_error(0, "getaddrinfo %s %s: %s",
+ a->s[0], a->s[1], gai_strerror(rc));
return 0;
}
break;
default:
- error(0, "invalid network address specification (n=%d)", a->n);
+ disorder_error(0, "invalid network address specification (n=%d)", a->n);
return 0;
}
if(!res || (pref && res->ai_socktype != pref->ai_socktype)) {
- error(0, "getaddrinfo didn't give us a suitable socket address");
+ disorder_error(0, "getaddrinfo didn't give us a suitable socket address");
if(res)
freeaddrinfo(res);
return 0;
return memcmp(&in6a->sin6_addr, &in6b->sin6_addr,
sizeof (struct in6_addr));
default:
- fatal(0, "unsupported protocol family %d", a->sa_family);
+ disorder_fatal(0, "unsupported protocol family %d", a->sa_family);
}
}
snprintf(service, sizeof service, "%d", na->port);
rc = getaddrinfo(na->address, service, hints, &res);
if(rc) {
- error(0, "getaddrinfo %s %d: %s",
- na->address ? na->address : "*",
- na->port, gai_strerror(rc));
+ disorder_error(0, "getaddrinfo %s %d: %s",
+ na->address ? na->address : "*",
+ na->port, gai_strerror(rc));
return NULL;
}
return res;
int n;
if((n = byte_vasprintf(ptrp, fmt, ap)) < 0)
- fatal(errno, "error calling byte_vasprintf");
+ disorder_fatal(errno, "error calling byte_vasprintf");
return n;
}
gcry_error_t e;
if((e = gcry_md_open(&h, id, 0))) {
- error(0, "gcry_md_open: %s", gcry_strerror(e));
+ disorder_error(0, "gcry_md_open: %s", gcry_strerror(e));
return 0;
}
}
if((q = getenv("QUERY_STRING")))
return kvp_urldecode(q, strlen(q));
- error(0, "QUERY_STRING not set, assuming empty");
+ disorder_error(0, "QUERY_STRING not set, assuming empty");
return NULL;
}
int r;
if(!(cl = getenv("CONTENT_LENGTH")))
- fatal(0, "CONTENT_LENGTH not set");
+ disorder_fatal(0, "CONTENT_LENGTH not set");
n = atol(cl);
/* We check for overflow and also limit the input to 16MB. Lower
* would probably do. */
if(!(n+1) || n > 16 * 1024 * 1024)
- fatal(0, "input is much too large");
+ disorder_fatal(0, "input is much too large");
q = xmalloc_noptr(n + 1);
while(m < n) {
r = read(0, q + m, n - m);
if(r > 0)
m += r;
else if(r == 0)
- fatal(0, "unexpected end of file reading request body");
+ disorder_fatal(0, "unexpected end of file reading request body");
else switch(errno) {
case EINTR: break;
- default: fatal(errno, "error reading request body");
+ default: disorder_fatal(errno, "error reading request body");
}
}
if(memchr(q, 0, n))
- fatal(0, "null character in request body");
+ disorder_fatal(0, "null character in request body");
q[n + 1] = 0;
*ptrp = q;
if(np)
&disposition,
&pname,
&pvalue))
- fatal(0, "error parsing Content-Disposition field");
+ disorder_fatal(0, "error parsing Content-Disposition field");
if(!strcmp(disposition, "form-data")
&& pname
&& !strcmp(pname, "name")) {
if(*namep)
- fatal(0, "duplicate Content-Disposition field");
+ disorder_fatal(0, "duplicate Content-Disposition field");
*namep = pvalue;
}
}
void *u) {
char *name = 0;
struct kvp *k, **head = u;
-
+
if(!(s = mime_parse(s, cgi__field_callback, &name)))
- fatal(0, "error parsing part header");
+ disorder_fatal(0, "error parsing part header");
if(!name)
- fatal(0, "no name found");
+ disorder_fatal(0, "no name found");
k = xmalloc(sizeof *k);
k->next = *head;
k->name = name;
cgi__input(&q, 0);
if(mime_multipart(q, cgi__part_callback, boundary, &head))
- fatal(0, "invalid multipart object");
+ disorder_fatal(0, "invalid multipart object");
return head;
}
if(!(ct = getenv("CONTENT_TYPE")))
ct = "application/x-www-form-urlencoded";
if(mime_content_type(ct, &type, &k))
- fatal(0, "invalid content type '%s'", ct);
+ disorder_fatal(0, "invalid content type '%s'", ct);
if(!strcmp(type, "application/x-www-form-urlencoded")) {
cgi__input(&q, &n);
return kvp_urldecode(q, n);
}
if(!strcmp(type, "multipart/form-data")) {
if(!(boundary = kvp_get(k, "boundary")))
- fatal(0, "no boundary parameter found");
+ disorder_fatal(0, "no boundary parameter found");
return cgi__init_multipart(boundary);
}
- fatal(0, "unrecognized content type '%s'", type);
+ disorder_fatal(0, "unrecognized content type '%s'", type);
}
/** @brief Initialize CGI arguments
cgi_args = hash_new(sizeof (char *));
if(!(p = getenv("REQUEST_METHOD")))
- error(0, "REQUEST_METHOD not set, assuming GET");
+ disorder_error(0, "REQUEST_METHOD not set, assuming GET");
if(!p || !strcmp(p, "GET"))
k = cgi__init_get();
else if(!strcmp(p, "POST"))
k = cgi__init_post();
else
- fatal(0, "unknown request method %s", p);
+ disorder_fatal(0, "unknown request method %s", p);
/* Validate the arguments and put them in a hash */
for(; k; k = k->next) {
if(!utf8_valid(k->name, strlen(k->name))
|| !utf8_valid(k->value, strlen(k->value)))
- error(0, "invalid UTF-8 sequence in cgi argument %s", k->name);
+ disorder_error(0, "invalid UTF-8 sequence in cgi argument %s", k->name);
else
hash_add(cgi_args, k->name, &k->value, HASH_INSERT_OR_REPLACE);
/* We just drop bogus arguments. */
size_t bufsize = 0, sl, dl;
if((i = iconv_open(to, from)) == (iconv_t)-1)
- fatal(errno, "error calling iconv_open");
+ disorder_fatal(errno, "error calling iconv_open");
do {
bufsize = bufsize ? 2 * bufsize : 32;
buf = xrealloc_noptr(buf, bufsize);
} while(len == (size_t)-1 && errno == E2BIG);
iconv_close(i);
if(len == (size_t)-1) {
- error(errno, "error converting from %s to %s", from, to);
+ disorder_error(errno, "error converting from %s to %s", from, to);
return 0;
}
return buf;
} else {
name = config_get_file2(c, "socket");
if(strlen(name) >= sizeof su.sun_path) {
- error(errno, "socket path is too long");
+ disorder_error(errno, "socket path is too long");
return -1;
}
memset(&su, 0, sizeof su);
return (r[0] * 10 + r[1]) * 10 + r[2] - 111 * '0';
} else {
c->last = "invalid reply format";
- error(0, "invalid reply format from %s", c->ident);
+ disorder_error(0, "invalid reply format from %s", c->ident);
return -1;
}
}
return 0;
} else {
if(c->verbose)
- error(0, "from %s: %s", c->ident, utf82mb(r));
+ disorder_error(0, "from %s: %s", c->ident, utf82mb(r));
return rc;
}
}
if(!c->fpout) {
c->last = "not connected";
- error(0, "not connected to server");
+ disorder_error(0, "not connected to server");
return -1;
}
if(cmd) {
return check_response(c, rp);
write_error:
byte_xasprintf((char **)&c->last, "write error: %s", strerror(errno));
- error(errno, "error writing to %s", c->ident);
+ disorder_error(errno, "error writing to %s", c->ident);
return -1;
}
*rp = *rr;
return 0;
}
- error(0, "invalid reply: %s", *rp);
+ disorder_error(0, "invalid reply: %s", *rp);
}
return rc;
}
c->fpin = c->fpout = 0;
if((fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) {
byte_xasprintf((char **)&c->last, "socket: %s", strerror(errno));
- error(errno, "error calling socket");
+ disorder_error(errno, "error calling socket");
return -1;
}
if(connect(fd, sa, salen) < 0) {
byte_xasprintf((char **)&c->last, "connect: %s", strerror(errno));
- error(errno, "error calling connect");
+ disorder_error(errno, "error calling connect");
goto error;
}
if((fd2 = dup(fd)) < 0) {
byte_xasprintf((char **)&c->last, "dup: %s", strerror(errno));
- error(errno, "error calling dup");
+ disorder_error(errno, "error calling dup");
goto error;
}
if(!(c->fpin = fdopen(fd, "rb"))) {
byte_xasprintf((char **)&c->last, "fdopen: %s", strerror(errno));
- error(errno, "error calling fdopen");
+ disorder_error(errno, "error calling fdopen");
goto error;
}
fd = -1;
if(!(c->fpout = fdopen(fd2, "wb"))) {
byte_xasprintf((char **)&c->last, "fdopen: %s", strerror(errno));
- error(errno, "error calling fdopen");
+ disorder_error(errno, "error calling fdopen");
goto error;
}
fd2 = -1;
goto error;
if(nrvec != 3) {
c->last = "cannot parse server greeting";
- error(0, "cannot parse server greeting %s", r);
+ disorder_error(0, "cannot parse server greeting %s", r);
goto error;
}
protocol = *rvec++;
if(strcmp(protocol, "2")) {
c->last = "unknown protocol version";
- error(0, "unknown protocol version: %s", protocol);
+ disorder_error(0, "unknown protocol version: %s", protocol);
goto error;
}
algorithm = *rvec++;
return 0; /* success */
if(!username) {
c->last = "cookie failed and no username";
- error(0, "cookie did not work and no username available");
+ disorder_error(0, "cookie did not work and no username available");
goto error;
}
}
if(!(username = config->username)) {
c->last = "no username";
- error(0, "no username configured");
+ disorder_error(0, "no username configured");
return -1;
}
password = config->password;
if(!password) {
/* Oh well */
c->last = "no password";
- error(0, "no password configured for user '%s'", username);
+ disorder_error(0, "no password configured for user '%s'", username);
return -1;
}
return disorder_connect_generic(config,
if(c->fpin) {
if(fclose(c->fpin) < 0) {
byte_xasprintf((char **)&c->last, "fclose: %s", strerror(errno));
- error(errno, "error calling fclose");
+ disorder_error(errno, "error calling fclose");
ret = -1;
}
c->fpin = 0;
if(c->fpout) {
if(fclose(c->fpout) < 0) {
byte_xasprintf((char **)&c->last, "fclose: %s", strerror(errno));
- error(errno, "error calling fclose");
+ disorder_error(errno, "error calling fclose");
ret = -1;
}
c->fpout = 0;
static void client_error(const char *msg,
void attribute((unused)) *u) {
- error(0, "error parsing reply: %s", msg);
+ disorder_error(0, "error parsing reply: %s", msg);
}
/** @brief Get currently playing track
}
if(ferror(c->fpin)) {
byte_xasprintf((char **)&c->last, "input error: %s", strerror(errno));
- error(errno, "error reading %s", c->ident);
+ disorder_error(errno, "error reading %s", c->ident);
} else {
c->last = "input error: unexpxected EOF";
- error(0, "error reading %s: unexpected EOF", c->ident);
+ disorder_error(0, "error reading %s: unexpected EOF", c->ident);
}
return -1;
}
}
if(ferror(c->fpin)) {
byte_xasprintf((char **)&c->last, "input error: %s", strerror(errno));
- error(errno, "error reading %s", c->ident);
+ disorder_error(errno, "error reading %s", c->ident);
} else {
c->last = "input error: unexpxected EOF";
- error(0, "error reading %s: unexpected EOF", c->ident);
+ disorder_error(0, "error reading %s: unexpected EOF", c->ident);
}
return -1;
}
static void pref_error_handler(const char *msg,
void attribute((unused)) *u) {
- error(0, "error handling 'prefs' reply: %s", msg);
+ disorder_error(0, "error handling 'prefs' reply: %s", msg);
}
/** @brief Get all preferences for a trcak
if(!strcmp(value, "yes")) *flagp = 1;
else if(!strcmp(value, "no")) *flagp = 0;
else {
- error(0, "malformed response to '%s'", cmd);
+ disorder_error(0, "malformed response to '%s'", cmd);
return -1;
}
return 0;
return rc;
if(sscanf(r, "%d %d", left, right) != 2) {
c->last = "malformed volume response";
- error(0, "error parsing response to 'volume': '%s'", r);
+ disorder_error(0, "error parsing response to 'volume': '%s'", r);
return -1;
}
return 0;
vec = split(r, &n, SPLIT_QUOTES, 0, 0);
if(n != 2) {
c->last = "malformed RTP address";
- error(0, "malformed rtp-address reply");
+ disorder_error(0, "malformed rtp-address reply");
return -1;
}
*addressp = vec[0];
return rc;
while(*lines) {
if(!(bits = split(*lines++, &nbits, SPLIT_QUOTES, 0, 0))) {
- error(0, "invalid schedule-get reply: cannot split line");
+ disorder_error(0, "invalid schedule-get reply: cannot split line");
return -1;
}
if(nbits != 2) {
- error(0, "invalid schedule-get reply: wrong number of fields");
+ disorder_error(0, "invalid schedule-get reply: wrong number of fields");
return -1;
}
kvp_set(actiondatap, bits[0], bits[1]);
action, key, value,
(char *)0);
} else
- fatal(0, "unknown action '%s'", action);
+ disorder_fatal(0, "unknown action '%s'", action);
va_end(ap);
return rc;
}
int n;
if(nvec != 1) {
- error(0, "%s:%d: '%s' requires one argument",
+ disorder_error(0, "%s:%d: '%s' requires one argument",
cs->path, cs->line, whoami->name);
return -1;
}
if((n = find_signal(vec[0])) == -1) {
- error(0, "%s:%d: unknown signal '%s'",
+ disorder_error(0, "%s:%d: unknown signal '%s'",
cs->path, cs->line, vec[0]);
return -1;
}
root = vec[2];
break;
case 0:
- error(0, "%s:%d: '%s' requires at least one argument",
- cs->path, cs->line, whoami->name);
+ disorder_error(0, "%s:%d: '%s' requires at least one argument",
+ cs->path, cs->line, whoami->name);
return -1;
default:
- error(0, "%s:%d: '%s' requires at most three arguments",
- cs->path, cs->line, whoami->name);
+ disorder_error(0, "%s:%d: '%s' requires at most three arguments",
+ cs->path, cs->line, whoami->name);
return -1;
}
/* Sanity check root */
if(root[0] != '/') {
- error(0, "%s:%d: collection root must start with '/'",
- cs->path, cs->line);
+ disorder_error(0, "%s:%d: collection root must start with '/'",
+ cs->path, cs->line);
return -1;
}
if(root[1] && root[strlen(root)-1] == '/') {
- error(0, "%s:%d: collection root must not end with '/'",
- cs->path, cs->line);
+ disorder_error(0, "%s:%d: collection root must not end with '/'",
+ cs->path, cs->line);
return -1;
}
/* Defaults */
int state;
if(nvec != 1) {
- error(0, "%s:%d: '%s' takes only one argument",
- cs->path, cs->line, whoami->name);
+ disorder_error(0, "%s:%d: '%s' takes only one argument",
+ cs->path, cs->line, whoami->name);
return -1;
}
if(!strcmp(vec[0], "yes")) state = 1;
else if(!strcmp(vec[0], "no")) state = 0;
else {
- error(0, "%s:%d: argument to '%s' must be 'yes' or 'no'",
- cs->path, cs->line, whoami->name);
+ disorder_error(0, "%s:%d: argument to '%s' must be 'yes' or 'no'",
+ cs->path, cs->line, whoami->name);
return -1;
}
VALUE(cs->config, int) = state;
const struct conf *whoami,
int nvec, char **vec) {
if(nvec != 1) {
- error(0, "%s:%d: '%s' takes only one argument",
- cs->path, cs->line, whoami->name);
+ disorder_error(0, "%s:%d: '%s' takes only one argument",
+ cs->path, cs->line, whoami->name);
return -1;
}
VALUE(cs->config, char *) = xstrdup(vec[0]);
char *e;
if(nvec != 1) {
- error(0, "%s:%d: '%s' takes only one argument",
- cs->path, cs->line, whoami->name);
+ disorder_error(0, "%s:%d: '%s' takes only one argument",
+ cs->path, cs->line, whoami->name);
return -1;
}
if(xstrtol(ADDRESS(cs->config, long), vec[0], &e, 0)) {
- error(errno, "%s:%d: converting integer", cs->path, cs->line);
+ disorder_error(errno, "%s:%d: converting integer", cs->path, cs->line);
return -1;
}
if(*e) {
- error(0, "%s:%d: invalid integer syntax", cs->path, cs->line);
+ disorder_error(0, "%s:%d: invalid integer syntax", cs->path, cs->line);
return -1;
}
return 0;
for(n = 0; n < nvec; ++n) {
if((i = TABLE_FIND(restrictions, name, vec[n])) < 0) {
- error(0, "%s:%d: invalid restriction '%s'",
- cs->path, cs->line, vec[n]);
+ disorder_error(0, "%s:%d: invalid restriction '%s'",
+ cs->path, cs->line, vec[n]);
return -1;
}
r |= restrictions[i].bit;
long t;
if(nvec != 1) {
- error(0, "%s:%d: wrong number of arguments", cs->path, cs->line);
+ disorder_error(0, "%s:%d: wrong number of arguments", cs->path, cs->line);
return -1;
}
if(xstrtol(&t, p, &p, 0)) {
- error(errno, "%s:%d: converting bits-per-sample", cs->path, cs->line);
+ disorder_error(errno, "%s:%d: converting bits-per-sample",
+ cs->path, cs->line);
return -1;
}
if(t != 8 && t != 16) {
- error(0, "%s:%d: bad bite-per-sample (%ld)", cs->path, cs->line, t);
+ disorder_error(0, "%s:%d: bad bite-per-sample (%ld)",
+ cs->path, cs->line, t);
return -1;
}
if(format) format->bits = t;
}
if(format) format->endian = t;
if(*p != '/') {
- error(errno, "%s:%d: expected `/' after bits-per-sample",
+ disorder_error(errno, "%s:%d: expected `/' after bits-per-sample",
cs->path, cs->line);
return -1;
}
p++;
if(xstrtol(&t, p, &p, 0)) {
- error(errno, "%s:%d: converting sample-rate", cs->path, cs->line);
+ disorder_error(errno, "%s:%d: converting sample-rate", cs->path, cs->line);
return -1;
}
if(t < 1 || t > INT_MAX) {
- error(0, "%s:%d: silly sample-rate (%ld)", cs->path, cs->line, t);
+ disorder_error(0, "%s:%d: silly sample-rate (%ld)", cs->path, cs->line, t);
return -1;
}
if(format) format->rate = t;
if(*p != '/') {
- error(0, "%s:%d: expected `/' after sample-rate",
- cs->path, cs->line);
+ disorder_error(0, "%s:%d: expected `/' after sample-rate",
+ cs->path, cs->line);
return -1;
}
p++;
if(xstrtol(&t, p, &p, 0)) {
- error(errno, "%s:%d: converting channels", cs->path, cs->line);
+ disorder_error(errno, "%s:%d: converting channels", cs->path, cs->line);
return -1;
}
if(t < 1 || t > 8) {
- error(0, "%s:%d: silly number (%ld) of channels", cs->path, cs->line, t);
+ disorder_error(0, "%s:%d: silly number (%ld) of channels",
+ cs->path, cs->line, t);
return -1;
}
if(format) format->channels = t;
if(*p) {
- error(0, "%s:%d: junk after channels", cs->path, cs->line);
+ disorder_error(0, "%s:%d: junk after channels", cs->path, cs->line);
return -1;
}
return 0;
pcre *re;
if(nvec < 3) {
- error(0, "%s:%d: namepart needs at least 3 arguments", cs->path, cs->line);
+ disorder_error(0, "%s:%d: namepart needs at least 3 arguments",
+ cs->path, cs->line);
return -1;
}
if(nvec > 5) {
- error(0, "%s:%d: namepart needs at most 5 arguments", cs->path, cs->line);
+ disorder_error(0, "%s:%d: namepart needs at most 5 arguments",
+ cs->path, cs->line);
return -1;
}
reflags = nvec >= 5 ? regsub_flags(vec[4]) : 0;
PCRE_UTF8
|regsub_compile_options(reflags),
&errstr, &erroffset, 0))) {
- error(0, "%s:%d: error compiling regexp /%s/: %s (offset %d)",
- cs->path, cs->line, vec[1], errstr, erroffset);
+ disorder_error(0, "%s:%d: compiling regexp /%s/: %s (offset %d)",
+ cs->path, cs->line, vec[1], errstr, erroffset);
return -1;
}
npl->s = xrealloc(npl->s, (npl->n + 1) * sizeof (struct namepart));
int erroffset;
if(nvec < 3) {
- error(0, "%s:%d: transform needs at least 3 arguments", cs->path, cs->line);
+ disorder_error(0, "%s:%d: transform needs at least 3 arguments",
+ cs->path, cs->line);
return -1;
}
if(nvec > 5) {
- error(0, "%s:%d: transform needs at most 5 arguments", cs->path, cs->line);
+ disorder_error(0, "%s:%d: transform needs at most 5 arguments",
+ cs->path, cs->line);
return -1;
}
reflags = (nvec >= 5 ? regsub_flags(vec[4]) : 0);
PCRE_UTF8
|regsub_compile_options(reflags),
&errstr, &erroffset, 0))) {
- error(0, "%s:%d: error compiling regexp /%s/: %s (offset %d)",
- cs->path, cs->line, vec[1], errstr, erroffset);
+ disorder_error(0, "%s:%d: compiling regexp /%s/: %s (offset %d)",
+ cs->path, cs->line, vec[1], errstr, erroffset);
return -1;
}
tl->t = xrealloc(tl->t, (tl->n + 1) * sizeof (struct namepart));
const struct conf *whoami,
int nvec, char **vec) {
if(nvec != 1) {
- error(0, "%s:%d: '%s' requires one argument",
- cs->path, cs->line, whoami->name);
+ disorder_error(0, "%s:%d: '%s' requires one argument",
+ cs->path, cs->line, whoami->name);
return -1;
}
if(parse_rights(vec[0], 0, 1)) {
- error(0, "%s:%d: invalid rights string '%s'",
- cs->path, cs->line, vec[0]);
+ disorder_error(0, "%s:%d: invalid rights string '%s'",
+ cs->path, cs->line, vec[0]);
return -1;
}
*ADDRESS(cs->config, char *) = vec[0];
struct netaddress *na = ADDRESS(cs->config, struct netaddress);
if(netaddress_parse(na, nvec, vec)) {
- error(0, "%s:%d: invalid network address", cs->path, cs->line);
+ disorder_error(0, "%s:%d: invalid network address", cs->path, cs->line);
return -1;
}
return 0;
* If @p test returns 0 then the file is not a @p what and an error
* is reported and -1 is returned.
*/
-#define VALIDATE_FILE(test, what) do { \
- struct stat sb; \
- int n; \
- \
- for(n = 0; n < nvec; ++n) { \
- if(stat(vec[n], &sb) < 0) { \
- error(errno, "%s:%d: %s", cs->path, cs->line, vec[n]); \
- return -1; \
- } \
- if(!test(sb.st_mode)) { \
- error(0, "%s:%d: %s is not a %s", \
- cs->path, cs->line, vec[n], what); \
- return -1; \
- } \
- } \
+#define VALIDATE_FILE(test, what) do { \
+ struct stat sb; \
+ int n; \
+ \
+ for(n = 0; n < nvec; ++n) { \
+ if(stat(vec[n], &sb) < 0) { \
+ disorder_error(errno, "%s:%d: %s", \
+ cs->path, cs->line, vec[n]); \
+ return -1; \
+ } \
+ if(!test(sb.st_mode)) { \
+ disorder_error(0, "%s:%d: %s is not a %s", \
+ cs->path, cs->line, vec[n], what); \
+ return -1; \
+ } \
+ } \
} while(0)
/** @brief Validate an absolute path
for(n = 0; n < nvec; ++n)
if(vec[n][0] != '/') {
- error(errno, "%s:%d: %s: not an absolute path",
- cs->path, cs->line, vec[n]);
+ disorder_error(errno, "%s:%d: %s: not an absolute path",
+ cs->path, cs->line, vec[n]);
return -1;
}
return 0;
int nvec,
char attribute((unused)) **vec) {
if(nvec < 2) {
- error(0, "%s:%d: should be at least 'player PATTERN MODULE'",
- cs->path, cs->line);
+ disorder_error(0, "%s:%d: should be at least 'player PATTERN MODULE'",
+ cs->path, cs->line);
return -1;
}
return 0;
int nvec,
char attribute((unused)) **vec) {
if(nvec < 2) {
- error(0, "%s:%d: should be at least 'tracklength PATTERN MODULE'",
- cs->path, cs->line);
+ disorder_error(0, "%s:%d: should be at least 'tracklength PATTERN MODULE'",
+ cs->path, cs->line);
return -1;
}
return 0;
int nvec,
char attribute((unused)) **vec) {
if(nvec != 2) {
- error(0, "%s:%d: must be 'allow NAME PASS'", cs->path, cs->line);
+ disorder_error(0, "%s:%d: must be 'allow NAME PASS'", cs->path, cs->line);
return -1;
}
return 0;
long n;
if(nvec < 1) {
- error(0, "%s:%d: missing argument", cs->path, cs->line);
+ disorder_error(0, "%s:%d: missing argument", cs->path, cs->line);
return -1;
}
if(nvec > 1) {
- error(0, "%s:%d: too many arguments", cs->path, cs->line);
+ disorder_error(0, "%s:%d: too many arguments", cs->path, cs->line);
return -1;
}
if(xstrtol(&n, vec[0], 0, 0)) {
- error(0, "%s:%d: %s", cs->path, cs->line, strerror(errno));
+ disorder_error(0, "%s:%d: %s", cs->path, cs->line, strerror(errno));
return -1;
}
if(n < 0) {
- error(0, "%s:%d: must not be negative", cs->path, cs->line);
+ disorder_error(0, "%s:%d: must not be negative", cs->path, cs->line);
return -1;
}
return 0;
long n;
if(nvec < 1) {
- error(0, "%s:%d: missing argument", cs->path, cs->line);
+ disorder_error(0, "%s:%d: missing argument", cs->path, cs->line);
return -1;
}
if(nvec > 1) {
- error(0, "%s:%d: too many arguments", cs->path, cs->line);
+ disorder_error(0, "%s:%d: too many arguments", cs->path, cs->line);
return -1;
}
if(xstrtol(&n, vec[0], 0, 0)) {
- error(0, "%s:%d: %s", cs->path, cs->line, strerror(errno));
+ disorder_error(0, "%s:%d: %s", cs->path, cs->line, strerror(errno));
return -1;
}
if(n <= 0) {
- error(0, "%s:%d: must be positive", cs->path, cs->line);
+ disorder_error(0, "%s:%d: must be positive", cs->path, cs->line);
return -1;
}
return 0;
struct passwd *pw;
if(!(pw = getpwnam(vec[0]))) {
- error(0, "%s:%d: no such user as '%s'", cs->path, cs->line, vec[0]);
+ disorder_error(0, "%s:%d: no such user as '%s'", cs->path, cs->line, vec[0]);
return -1;
}
return 0;
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789"));
if(s[n] != ':') {
- error(0, "%s:%d: invalid url '%s'", cs->path, cs->line, vec[0]);
+ disorder_error(0, "%s:%d: invalid url '%s'", cs->path, cs->line, vec[0]);
return -1;
}
if(!strncmp(s, "http:", 5)
s += n + 1;
/* we only do a rather cursory check */
if(strncmp(s, "//", 2)) {
- error(0, "%s:%d: invalid url '%s'", cs->path, cs->line, vec[0]);
+ disorder_error(0, "%s:%d: invalid url '%s'", cs->path, cs->line, vec[0]);
return -1;
}
}
int in_brackets = 0, c;
if(nvec < 1) {
- error(0, "%s:%d: missing argument", cs->path, cs->line);
+ disorder_error(0, "%s:%d: missing argument", cs->path, cs->line);
return -1;
}
if(nvec > 1) {
- error(0, "%s:%d: too many arguments", cs->path, cs->line);
+ disorder_error(0, "%s:%d: too many arguments", cs->path, cs->line);
return -1;
}
s = vec[0];
if(c == '}')
in_brackets = 0;
else if(!isalnum(c)) {
- error(0, "%s:%d: invalid part name in alias expansion in '%s'",
- cs->path, cs->line, vec[0]);
+ disorder_error(0, "%s:%d: invalid part name in alias expansion in '%s'",
+ cs->path, cs->line, vec[0]);
return -1;
}
} else {
++s;
} else if(c == '\\') {
if(!(c = (unsigned char)*s++)) {
- error(0, "%s:%d: unterminated escape in alias expansion in '%s'",
- cs->path, cs->line, vec[0]);
+ disorder_error(0, "%s:%d: unterminated escape in alias expansion in '%s'",
+ cs->path, cs->line, vec[0]);
return -1;
} else if(c != '\\' && c != '{') {
- error(0, "%s:%d: invalid escape in alias expansion in '%s'",
- cs->path, cs->line, vec[0]);
+ disorder_error(0, "%s:%d: invalid escape in alias expansion in '%s'",
+ cs->path, cs->line, vec[0]);
return -1;
}
}
++s;
}
if(in_brackets) {
- error(0, "%s:%d: unterminated part name in alias expansion in '%s'",
- cs->path, cs->line, vec[0]);
+ disorder_error(0,
+ "%s:%d: unterminated part name in alias expansion in '%s'",
+ cs->path, cs->line, vec[0]);
return -1;
}
return 0;
int nvec,
char **vec) {
if(nvec != 1) {
- error(0, "%s:%d: invalid algorithm specification", cs->path, cs->line);
+ disorder_error(0, "%s:%d: invalid algorithm specification", cs->path, cs->line);
return -1;
}
if(!valid_authhash(vec[0])) {
- error(0, "%s:%d: unsuported algorithm '%s'", cs->path, cs->line, vec[0]);
+ disorder_error(0, "%s:%d: unsuported algorithm '%s'", cs->path, cs->line, vec[0]);
return -1;
}
return 0;
char **vec) {
int n;
if(nvec != 1) {
- error(0, "%s:%d: invalid sound API specification", cs->path, cs->line);
+ disorder_error(0, "%s:%d: invalid sound API specification", cs->path, cs->line);
return -1;
}
if(!strcmp(vec[0], "network")) {
- error(0, "'api network' is deprecated; use 'api rtp'");
+ disorder_error(0, "'api network' is deprecated; use 'api rtp'");
return 0;
}
if(config_uaudio_apis) {
for(n = 0; config_uaudio_apis[n]; ++n)
if(!strcmp(vec[0], config_uaudio_apis[n]->name))
return 0;
- error(0, "%s:%d: unrecognized sound API '%s'", cs->path, cs->line, vec[0]);
+ disorder_error(0, "%s:%d: unrecognized sound API '%s'", cs->path, cs->line, vec[0]);
return -1;
}
/* In non-server processes we have no idea what's valid */
char **vec) {
if(nvec == 1 && (!strcmp(vec[0], "silence") || !strcmp(vec[0], "suspend")))
return 0;
- error(0, "%s:%d: invalid pause mode", cs->path, cs->line);
+ disorder_error(0, "%s:%d: invalid pause mode", cs->path, cs->line);
return -1;
}
struct netaddress na[1];
if(netaddress_parse(na, nvec, vec)) {
- error(0, "%s:%d: invalid network address", cs->path, cs->line);
+ disorder_error(0, "%s:%d: invalid network address", cs->path, cs->line);
return -1;
}
if(!na->address) {
- error(0, "%s:%d: destination address required", cs->path, cs->line);
+ disorder_error(0, "%s:%d: destination address required", cs->path, cs->line);
return -1;
}
return 0;
D(("config_set %s", vec[0]));
if(!(which = find(vec[0]))) {
- error(0, "%s:%d: unknown configuration key '%s'",
+ disorder_error(0, "%s:%d: unknown configuration key '%s'",
cs->path, cs->line, vec[0]);
return -1;
}
static void config_error(const char *msg, void *u) {
const struct config_state *cs = u;
- error(0, "%s:%d: %s", cs->path, cs->line, msg);
+ disorder_error(0, "%s:%d: %s", cs->path, cs->line, msg);
}
/** @brief Include a file by name
cs.config = c;
D(("%s: reading configuration", path));
if(!(fp = fopen(path, "r"))) {
- error(errno, "error opening %s", path);
+ disorder_error(errno, "error opening %s", path);
return -1;
}
while(!inputline(path, fp, &inputbuffer, '\n')) {
++cs.line;
if(!(buffer = mb2utf8(inputbuffer))) {
- error(errno, "%s:%d: cannot convert to UTF-8", cs.path, cs.line);
+ disorder_error(errno, "%s:%d: cannot convert to UTF-8", cs.path, cs.line);
ret = -1;
xfree(inputbuffer);
continue;
/* 'include' is special-cased */
if(!strcmp(vec[0], "include")) {
if(n != 2) {
- error(0, "%s:%d: must be 'include PATH'", cs.path, cs.line);
+ disorder_error(0, "%s:%d: must be 'include PATH'", cs.path, cs.line);
ret = -1;
} else
config_include(c, vec[1]);
xfree(buffer);
}
if(ferror(fp)) {
- error(errno, "error reading %s", path);
+ disorder_error(errno, "error reading %s", path);
ret = -1;
}
fclose(fp);
c->history = 60;
c->home = xstrdup(pkgstatedir);
if(!(pw = getpwuid(getuid())))
- fatal(0, "cannot determine our username");
+ disorder_fatal(0, "cannot determine our username");
logname = pw->pw_name;
c->username = xstrdup(logname);
c->refresh = 15;
c->api = xstrdup("rtp");
if(server) {
if(!strcmp(c->api, "command") && !c->speaker_command)
- fatal(0, "'api command' but speaker_command is not set");
+ disorder_fatal(0, "'api command' but speaker_command is not set");
if((!strcmp(c->api, "rtp")) && c->broadcast.af == -1)
- fatal(0, "'api rtp' but broadcast is not set");
+ disorder_fatal(0, "'api rtp' but broadcast is not set");
}
/* Override sample format */
if(!strcmp(c->api, "rtp")) {
/* if there's a per-user system config file for this user, read it */
if(config_per_user) {
if(!(pw = getpwuid(getuid())))
- fatal(0, "cannot determine our username");
+ disorder_fatal(0, "cannot determine our username");
if((privconf = config_usersysconf(pw))
&& access(privconf, F_OK) == 0
&& config_include(c, privconf))
if(oldconfig) {
int failed = 0;
if(strcmp(c->home, oldconfig->home)) {
- error(0, "'home' cannot be changed without a restart");
+ disorder_error(0, "'home' cannot be changed without a restart");
failed = 1;
}
if(strcmp(c->alias, oldconfig->alias)) {
- error(0, "'alias' cannot be changed without a restart");
+ disorder_error(0, "'alias' cannot be changed without a restart");
failed = 1;
}
if(strcmp(c->user, oldconfig->user)) {
- error(0, "'user' cannot be changed without a restart");
+ disorder_error(0, "'user' cannot be changed without a restart");
failed = 1;
}
if(c->nice_speaker != oldconfig->nice_speaker) {
- error(0, "'nice_speaker' cannot be changed without a restart");
+ disorder_error(0, "'nice_speaker' cannot be changed without a restart");
/* ...but we accept the new config anyway */
}
if(c->nice_server != oldconfig->nice_server) {
- error(0, "'nice_server' cannot be changed without a restart");
+ disorder_error(0, "'nice_server' cannot be changed without a restart");
/* ...but we accept the new config anyway */
}
if(namepartlist_compare(&c->namepart, &oldconfig->namepart)) {
- error(0, "'namepart' settings cannot be changed without a restart");
+ disorder_error(0, "'namepart' settings cannot be changed without a restart");
failed = 1;
}
if(stringlist_compare(&c->stopword, &oldconfig->stopword)) {
- error(0, "'stopword' settings cannot be changed without a restart");
+ disorder_error(0, "'stopword' settings cannot be changed without a restart");
failed = 1;
}
if(failed) {
- error(0, "not installing incompatible new configuration");
+ disorder_error(0, "not installing incompatible new configuration");
return -1;
}
}
config_free(config);
/* warn about obsolete directives */
if(c->restrictions)
- error(0, "'restrict' will be removed in a future version");
+ disorder_error(0, "'restrict' will be removed in a future version");
if(c->allow.n)
- error(0, "'allow' will be removed in a future version");
+ disorder_error(0, "'allow' will be removed in a future version");
if(c->trust.n)
- error(0, "'trust' will be removed in a future version");
+ disorder_error(0, "'trust' will be removed in a future version");
if(!c->lock)
- error(0, "'lock' will be removed in a future version");
+ disorder_error(0, "'lock' will be removed in a future version");
if(c->gap)
- error(0, "'gap' will be removed in a future version");
+ disorder_error(0, "'gap' will be removed in a future version");
if(c->prefsync)
- error(0, "'prefsync' will be removed in a future version");
+ disorder_error(0, "'prefsync' will be removed in a future version");
config = c;
return 0;
}
char *s;
if(!home && !pw && !(pw = getpwuid(getuid())))
- fatal(0, "cannot determine our username");
+ disorder_fatal(0, "cannot determine our username");
byte_xasprintf(&s, "%s/.disorder/passwd", home ? home : pw->pw_dir);
return s;
}
char *sig64;
if((e = gcry_md_open(&h, ALGO, GCRY_MD_FLAG_HMAC))) {
- error(0, "gcry_md_open: %s", gcry_strerror(e));
+ disorder_error(0, "gcry_md_open: %s", gcry_strerror(e));
return 0;
}
if((e = gcry_md_setkey(h, key, HASHSIZE))) {
- error(0, "gcry_md_setkey: %s", gcry_strerror(e));
+ disorder_error(0, "gcry_md_setkey: %s", gcry_strerror(e));
gcry_md_close(h);
return 0;
}
/* dollar signs aren't allowed in usernames */
if(strchr(user, '$')) {
- error(0, "make_cookie for username with dollar sign");
+ disorder_error(0, "make_cookie for username with dollar sign");
return 0;
}
/* look up the password */
password = trackdb_get_password(user);
if(!password) {
- error(0, "make_cookie for nonexistent user");
+ disorder_error(0, "make_cookie for nonexistent user");
return 0;
}
/* make sure we have a valid signing key */
/* check the revocation list */
if(revoked && hash_find(revoked, cookie)) {
- error(0, "attempt to log in with revoked cookie");
+ disorder_error(0, "attempt to log in with revoked cookie");
return 0;
}
/* parse the cookie */
errno = 0;
t = strtoimax(cookie, &c1, 16);
if(errno) {
- error(errno, "error parsing cookie timestamp");
+ disorder_error(errno, "error parsing cookie timestamp");
return 0;
}
if(*c1 != '$') {
- error(0, "invalid cookie timestamp");
+ disorder_error(0, "invalid cookie timestamp");
return 0;
}
/* There'd better be two dollar signs */
c2 = strchr(c1 + 1, '$');
if(c2 == 0) {
- error(0, "invalid cookie syntax");
+ disorder_error(0, "invalid cookie syntax");
return 0;
}
/* Extract the username */
/* check expiry */
xtime(&now);
if(now >= t) {
- error(0, "cookie has expired");
+ disorder_error(0, "cookie has expired");
return 0;
}
/* look up the password */
k = trackdb_getuserinfo(user);
if(!k) {
- error(0, "verify_cookie for nonexistent user");
+ disorder_error(0, "verify_cookie for nonexistent user");
return 0;
}
password = kvp_get(k, "password");
if(!strcmp(sig, c2 + 1))
return user;
/* that didn't match either */
- error(0, "cookie signature does not match");
+ disorder_error(0, "cookie signature does not match");
return 0;
}
'?', FALSE, output, sizeof output,
&used);
output[used] = 0;
- info("device %u %s: %s", n, description, (char *)output);
+ disorder_info("device %u %s: %s", n, description, (char *)output);
#endif
if(CFStringCompare(dev, name,
kCFCompareCaseInsensitive|kCFCompareNonliteral)
case 0:
return mktime(&t);
case 7:
- fatal(0, "date string '%s' not in a recognized format", s);
+ disorder_fatal(0, "date string '%s' not in a recognized format", s);
case 8:
- fatal(0, "date string '%s' not representable", s);
+ disorder_fatal(0, "date string '%s' not representable", s);
default:
- fatal(0, "date string '%s' produced unexpected error %d", s, rc);
+ disorder_fatal(0, "date string '%s' produced unexpected error %d", s, rc);
}
}
&& line[1] >= '0' && line[1] <= '9'
&& line[2] >= '0' && line[2] <= '9'
&& line[3] == ' '))
- fatal(0, "invalid response from server: %s", line);
+ disorder_fatal(0, "invalid response from server: %s", line);
c->rc = (line[0] * 10 + line[1]) * 10 + line[2] - 111 * '0';
c->line = line;
switch(c->rc % 10) {
} while(n < 0 && errno == EINTR);
xsigprocmask(SIG_BLOCK, &ev->sigmask, 0);
if(n < 0) {
- error(errno, "error calling select");
+ disorder_error(errno, "error calling select");
if(errno == EBADF) {
/* If there's a bad FD in the mix then check them all and log what we
* find, to ease debugging */
if(FD_ISSET(fd, &ev->mode[mode].enabled)
&& fstat(fd, &sb) < 0)
- error(errno, "mode %s fstat %d (%s)",
- modenames[mode], fd, ev->mode[mode].fds[n].what);
+ disorder_error(errno, "mode %s fstat %d (%s)",
+ modenames[mode], fd, ev->mode[mode].fds[n].what);
}
for(n = 0; n <= maxfd; ++n)
if(FD_ISSET(n, &ev->mode[mode].enabled)
&& fstat(n, &sb) < 0)
- error(errno, "mode %s fstat %d", modenames[mode], n);
+ disorder_error(errno, "mode %s fstat %d", modenames[mode], n);
}
}
return -1;
return ret;
assert(n != 0);
if(n < 0 && (errno != EINTR && errno != EAGAIN)) {
- error(errno, "error reading from signal pipe %d", ev->sigpipe[0]);
+ disorder_error(errno, "error reading from signal pipe %d", ev->sigpipe[0]);
return -1;
}
return 0;
* want the disorder server to bomb out because of it. So we just log
* the problem and ignore it.
*/
- error(errno, "error calling wait4 for PID %lu (broken ptrace?)",
- (unsigned long)ev->children[n].pid);
+ disorder_error(errno, "error calling wait4 for PID %lu (broken ptrace?)",
+ (unsigned long)ev->children[n].pid);
if(errno != ECHILD)
return -1;
}
for(n = 0; n < ev->nchildren; ++n) {
if(kill(ev->children[n].pid, SIGTERM) < 0) {
- error(errno, "sending SIGTERM to pid %lu",
- (unsigned long)ev->children[n].pid);
+ disorder_error(errno, "sending SIGTERM to pid %lu",
+ (unsigned long)ev->children[n].pid);
ev->children[n].pid = -1;
}
}
rc = waitpid(ev->children[n].pid, &w, 0);
} while(rc < 0 && errno == EINTR);
if(rc < 0) {
- error(errno, "waiting for pid %lu", (unsigned long)ev->children[n].pid);
+ disorder_error(errno, "waiting for pid %lu",
+ (unsigned long)ev->children[n].pid);
continue;
}
}
break;
#ifdef ECONNABORTED
case ECONNABORTED:
- error(errno, "error calling accept");
+ disorder_error(errno, "error calling accept");
break;
#endif
#ifdef EPROTO
case EPROTO:
/* XXX on some systems EPROTO should be fatal, but we don't know if
* we're running on one of them */
- error(errno, "error calling accept");
+ disorder_error(errno, "error calling accept");
break;
#endif
default:
- fatal(errno, "error calling accept");
+ disorder_fatal(errno, "error calling accept");
break;
}
if(errno != EINTR && errno != EAGAIN)
- error(errno, "error calling accept");
+ disorder_error(errno, "error calling accept");
return 0;
}
if(!w->abandoned) {
w->abandoned = 1;
- error(0, "abandoning writer '%s' because no writes within %ds",
- w->what, w->timebound);
+ disorder_error(0, "abandoning writer '%s' because no writes within %ds",
+ w->what, w->timebound);
w->error = ETIMEDOUT;
}
return writer_shutdown(ev, now, u);
if(!n)
return 0; /* avoid silliness */
if(w->fd == -1)
- error(0, "ev_writer_write on %s after shutdown", w->what);
+ disorder_error(0, "ev_writer_write on %s after shutdown", w->what);
if(w->spacebound && w->b.end - w->b.start + n > w->spacebound) {
/* The new buffer contents will exceed the space bound. We assume that the
* remote client has gone away and TCP hasn't noticed yet, or that it's got
* hopelessly stuck. */
if(!w->abandoned) {
w->abandoned = 1;
- error(0, "abandoning writer '%s' because buffer has reached %td bytes",
- w->what, w->b.end - w->b.start);
+ disorder_error(0, "abandoning writer '%s' because buffer has reached %td bytes",
+ w->what, w->b.end - w->b.start);
ev_fd_disable(w->ev, ev_write, w->fd);
w->error = EPIPE;
return ev_timeout(w->ev, 0, 0, writer_shutdown, w);
*/
struct sink *ev_writer_sink(ev_writer *w) {
if(!w)
- fatal(0, "ev_write_sink called with null writer");
+ disorder_fatal(0, "ev_write_sink called with null writer");
return &w->s;
}
int unhexdigit(int c) {
int d;
- if((d = unhexdigitq(c)) < 0) error(0, "invalid hex digit");
+ if((d = unhexdigitq(c)) < 0)
+ disorder_error(0, "invalid hex digit");
return d;
}
int d1, d2;
if((l = strlen(s)) & 1) {
- error(0, "hex string has odd length");
+ disorder_error(0, "hex string has odd length");
return 0;
}
p = buf = xmalloc_noptr(l / 2);
struct hostent *he;
if(uname(&u) < 0)
- fatal(errno, "error calling uname");
+ disorder_fatal(errno, "error calling uname");
if(!(he = gethostbyname(u.nodename)))
- fatal(0, "cannot resolve '%s'", u.nodename);
+ disorder_fatal(0, "cannot resolve '%s'", u.nodename);
hostname = xstrdup(he->h_name);
}
return hostname;
&((const struct sockaddr_in6 *)b)->sin6_addr,
sizeof (struct in6_addr));
default:
- fatal(0, "unknown address family %d", a->sa_family);
+ disorder_fatal(0, "unknown address family %d", a->sa_family);
}
}
}
}
if(ferror(fp)) {
- error(errno, "error reading %s", tag);
+ disorder_error(errno, "error reading %s", tag);
return -1;
} else if(feof(fp)) {
if(d.nvec != 0)
- error(0, "error reading %s: unexpected EOF", tag);
+ disorder_error(0, "error reading %s: unexpected EOF", tag);
return -1;
}
dynstr_terminate(&d);
*/
/** @file lib/log.c @brief Errors and logging
*
- * All messages are initially emitted by one of the four functions below.
- * debug() is generally invoked via D() so that mostly you just do a test
- * rather than a complete subroutine call.
+ * All messages are initially emitted by one of the four functions
+ * below. disorder_debug() is generally invoked via D() so that
+ * mostly you just do a test rather than a complete subroutine call.
*
* Messages are dispatched via @ref log_default. This defaults to @ref
* log_stderr. daemonize() will turn off @ref log_stderr and use @ref
* log_syslog instead.
*
- * fatal() will call exitfn() with a nonzero status. The default value is
- * exit(), but it should be set to _exit() anywhere but the 'main line' of the
- * program, to guarantee that exit() gets called at most once.
+ * disorder_fatal() will call exitfn() with a nonzero status. The
+ * default value is exit(), but it should be set to _exit() anywhere
+ * but the 'main line' of the program, to guarantee that exit() gets
+ * called at most once.
*/
#define NO_MEMORY_ALLOCATION
/* report a message of the given class. @errno_value@ if present an
* non-zero is included. @fatal@ terminates the process. */
-/** @brief Backward-compatibility alias for disorder_fatal() */
-#define fatal disorder_fatal
-
-/** @brief Backward-compatibility alias for disorder_error() */
-#define error disorder_error
-
-/** @brief Backward-compatibility alias for disorder_info() */
-#define info disorder_info
-
-/** @brief Backward-compatibility alias for disorder_debug() */
-#define debug disorder_debug
-
extern int debugging;
/* set when debugging enabled */
if(debugging) { \
debug_filename=__FILE__; \
debug_lineno=__LINE__; \
- debug x; \
+ disorder_debug x; \
} \
} while(0)
while((nl = memchr(ptr, '\n', bytes))) {
len = nl - (char *)ptr;
ev_reader_consume(reader, len + 1);
- info("%s: %.*s", tag, len, (char *)ptr);
+ disorder_info("%s: %.*s", tag, len, (char *)ptr);
ptr = nl + 1;
bytes -= len + 1;
}
if(eof && bytes) {
- info("%s: %.*s", tag, (int)bytes, (char *)ptr);
+ disorder_info("%s: %.*s", tag, (int)bytes, (char *)ptr);
ev_reader_consume(reader, bytes);
}
return 0;
void *u) {
const char *tag = u;
- error(errno_value, "error reading log pipe from %s", tag);
+ disorder_error(errno_value, "error reading log pipe from %s", tag);
return 0;
}
* it in the parent).
*
* Any lines written to this fd (i.e. by the subprocess) will be logged via
- * info(), with @p tag included.
+ * disorder_info(), with @p tag included.
*/
int logfd(ev_source *ev, const char *tag) {
int p[2];
nonblock(p[0]);
if(!ev_reader_new(ev, p[0], logfd_readable, logfd_error, (void *)tag,
"logfd"))
- fatal(errno, "error calling ev_reader_new");
+ disorder_fatal(errno, "error calling ev_reader_new");
return p[1];
}
if(name[0] == '/') {
if(access(name, O_RDONLY) < 0) {
if(report)
- error(errno, "cannot read %s", name);
+ disorder_error(errno, "cannot read %s", name);
return 0;
}
path = xstrdup(name);
}
if(n >= include_path.nvec) {
if(report)
- error(0, "cannot find '%s' in search path", name);
+ disorder_error(0, "cannot find '%s' in search path", name);
return 0;
}
}
/* Read the raw file. As with mx_expand_file() we insist that the file is a
* regular file. */
if((fd = open(path, O_RDONLY)) < 0)
- fatal(errno, "error opening %s", path);
+ disorder_fatal(errno, "error opening %s", path);
if(fstat(fd, &sb) < 0)
- fatal(errno, "error statting %s", path);
+ disorder_fatal(errno, "error statting %s", path);
if(!S_ISREG(sb.st_mode))
- fatal(0, "%s: not a regular file", path);
+ disorder_fatal(0, "%s: not a regular file", path);
while((n = read(fd, buffer, sizeof buffer)) > 0) {
if(sink_write(output, buffer, n) < 0) {
xclose(fd);
}
}
if(n < 0)
- fatal(errno, "error reading %s", path);
+ disorder_fatal(errno, "error reading %s", path);
xclose(fd);
return 0;
}
xdup2(p[1], 1);
xclose(p[1]);
execlp("sh", "sh", "-c", args[0], (char *)0);
- fatal(errno, "error executing sh");
+ disorder_fatal(errno, "error executing sh");
}
xclose(p[1]);
while((n = read(p[0], buffer, sizeof buffer))) {
if(errno == EINTR)
continue;
else
- fatal(errno, "error reading from pipe");
+ disorder_fatal(errno, "error reading from pipe");
}
if(output->write(output, buffer, n) < 0)
return -1;
while((n = waitpid(pid, &w, 0)) < 0 && errno == EINTR)
;
if(n < 0)
- fatal(errno, "error calling waitpid");
+ disorder_fatal(errno, "error calling waitpid");
if(w)
- error(0, "shell command '%s' %s", args[0], wstat(w));
+ disorder_error(0, "shell command '%s' %s", args[0], wstat(w));
return 0;
}
* and the name. */
dynstr_init(d);
if(input == end)
- fatal(0, "%s:%d: invalid expansion syntax (truncated)",
- filename, e->line);
+ disorder_fatal(0, "%s:%d: invalid expansion syntax (truncated)",
+ filename, e->line);
if(!isalnum((unsigned char)*input))
- fatal(0, "%s:%d: invalid expansion syntax (unexpected %#x)",
- filename, e->line, (unsigned char)*input);
+ disorder_fatal(0, "%s:%d: invalid expansion syntax (unexpected %#x)",
+ filename, e->line, (unsigned char)*input);
while(input < end && (isalnum((unsigned char)*input) || *input == '-'))
dynstr_append(d, *input++);
dynstr_terminate(d);
}
if(input >= end) {
/* We ran out of input without encountering a balanced cbracket */
- fatal(0, "%s:%d: unterminated expansion argument '%.*s'",
- filename, argument_start_line,
- (int)(input - argument_start), argument_start);
+ disorder_fatal(0, "%s:%d: unterminated expansion argument '%.*s'",
+ filename, argument_start_line,
+ (int)(input - argument_start), argument_start);
}
/* Consistency check */
assert(*input == cbracket);
/* This locates the error to the definition, which may be a line or two
* beyond the @define command itself. The backtrace generated by
* mx_expand() may help more. */
- error(0, "%s:%d: duplicate definition of '%s'",
- definition->filename, definition->line, name);
+ disorder_error(0, "%s:%d: duplicate definition of '%s'",
+ definition->filename, definition->line, name);
#endif
return -2;
}
case MX_EXPANSION:
rc = 0;
if(!(e = hash_find(expansions, m->name))) {
- error(0, "%s:%d: unknown expansion name '%s'",
- m->filename, m->line, m->name);
+ disorder_error(0, "%s:%d: unknown expansion name '%s'",
+ m->filename, m->line, m->name);
if(sink_printf(output, "[['%s' unknown]]", m->name) < 0)
return -1;
} else if(m->nargs < e->min) {
- error(0, "%s:%d: expansion '%s' requires %d args, only %d given",
- m->filename, m->line, m->name, e->min, m->nargs);
+ disorder_error(0, "%s:%d: expansion '%s' requires %d args, only %d given",
+ m->filename, m->line, m->name, e->min, m->nargs);
if(sink_printf(output, "[['%s' too few args]]", m->name) < 0)
return -1;
} else if(m->nargs > e->max) {
- error(0, "%s:%d: expansion '%s' takes at most %d args, but %d given",
+ disorder_error(0, "%s:%d: expansion '%s' takes at most %d args, but %d given",
m->filename, m->line, m->name, e->max, m->nargs);
if(sink_printf(output, "[['%s' too many args]]", m->name) < 0)
return -1;
if(rc) {
/* For non-IO errors we generate some backtrace */
if(rc != -1)
- error(0, " ...in @%s at %s:%d",
- m->name, m->filename, m->line);
+ disorder_error(0, " ...in @%s at %s:%d",
+ m->name, m->filename, m->line);
return rc;
}
break;
} else
*sp = 0;
if(rc && rc != -1 && what)
- error(0, " ...in %s at %s:%d", what, m->filename, m->line);
+ disorder_error(0, " ...in %s at %s:%d", what, m->filename, m->line);
return rc;
}
const struct mx_node *m;
if((fd = open(path, O_RDONLY)) < 0)
- fatal(errno, "error opening %s", path);
+ disorder_fatal(errno, "error opening %s", path);
if(fstat(fd, &sb) < 0)
- fatal(errno, "error statting %s", path);
+ disorder_fatal(errno, "error statting %s", path);
if(!S_ISREG(sb.st_mode))
- fatal(0, "%s: not a regular file", path);
+ disorder_fatal(0, "%s: not a regular file", path);
sofar = 0;
b = xmalloc_noptr(sb.st_size);
while(sofar < sb.st_size) {
if(n > 0)
sofar += n;
else if(n == 0)
- fatal(0, "unexpected EOF reading %s", path);
+ disorder_fatal(0, "unexpected EOF reading %s", path);
else if(errno != EINTR)
- fatal(errno, "error reading %s", path);
+ disorder_fatal(errno, "error reading %s", path);
}
xclose(fd);
m = mx_parse(path, 1, b, b + sb.st_size);
rc = mx_expand(m, output, u);
if(rc && rc != -1)
/* Mention inclusion in backtrace */
- error(0, " ...in inclusion of file '%s'", path);
+ disorder_error(0, " ...in inclusion of file '%s'", path);
return rc;
}
void *ptr;
if(!(ptr = do_malloc(n)) && n)
- fatal(errno, "error allocating memory");
+ disorder_fatal(errno, "error allocating memory");
return ptr;
}
*/
void *xrealloc(void *ptr, size_t n) {
if(!(ptr = do_realloc(ptr, n)) && n)
- fatal(errno, "error allocating memory");
+ disorder_fatal(errno, "error allocating memory");
return ptr;
}
*/
void *xcalloc(size_t count, size_t size) {
if(count > SIZE_MAX / size)
- fatal(0, "excessively large calloc");
+ disorder_fatal(0, "excessively large calloc");
return xmalloc(count * size);
}
void *ptr;
if(!(ptr = do_malloc_atomic(n)) && n)
- fatal(errno, "error allocating memory");
+ disorder_fatal(errno, "error allocating memory");
return ptr;
}
*/
void *xcalloc_noptr(size_t count, size_t size) {
if(count > SIZE_MAX / size)
- fatal(0, "excessively large calloc");
+ disorder_fatal(0, "excessively large calloc");
return xmalloc_noptr(count * size);
}
if(ptr == 0)
return xmalloc_noptr(n);
if(!(ptr = do_realloc(ptr, n)) && n)
- fatal(errno, "error allocating memory");
+ disorder_fatal(errno, "error allocating memory");
return ptr;
}
char *t;
if(!(t = do_malloc_atomic(strlen(s) + 1)))
- fatal(errno, "error allocating memory");
+ disorder_fatal(errno, "error allocating memory");
return strcpy(t, s);
}
char *t;
if(!(t = do_malloc_atomic(n + 1)))
- fatal(errno, "error allocating memory");
+ disorder_fatal(errno, "error allocating memory");
memcpy(t, s, n);
t[n] = 0;
return t;
void *xrealloc(void *, size_t);
void *xcalloc(size_t count, size_t size);
/* As malloc/realloc/calloc, but
- * 1) succeed or call fatal
+ * 1) succeed or call disorder_fatal
* 2) always clear (the unused part of) the new allocation
* 3) are garbage-collected
*/
char *xstrdup(const char *);
char *xstrndup(const char *, size_t);
/* As malloc/realloc/strdup, but
- * 1) succeed or call fatal
+ * 1) succeed or call disorder_fatal
* 2) are garbage-collected
* 3) allocated space must not contain any pointers
*
return mime_qp(s);
if(!strcmp(cte, "7bit") || !strcmp(cte, "8bit"))
return s;
- error(0, "unknown content-transfer-encoding '%s'", cte);
+ disorder_error(0, "unknown content-transfer-encoding '%s'", cte);
return 0;
}
return s;
/* We must start with a boundary string */
if(!isboundary(s, boundary, bl)) {
- error(0, "mime_multipart: first line is not the boundary string");
+ disorder_error(0, "mime_multipart: first line is not the boundary string");
return -1;
}
/* Keep going until we hit a final boundary */
start = s;
while(!isboundary(s, boundary, bl)) {
if(!(e = strstr(s, "\r\n"))) {
- error(0, "mime_multipart: line does not end CRLF");
+ disorder_error(0, "mime_multipart: line does not end CRLF");
return -1;
}
s = e + 2;
continue;
}
if(!(s = parsetoken(s, &n, cookie_separator))) {
- error(0, "parse_cookie: cannot parse attribute name");
+ disorder_error(0, "parse_cookie: cannot parse attribute name");
return -1;
- }
+ }
s = skipwhite(s, 0);
if(*s++ != '=') {
- error(0, "parse_cookie: did not find expected '='");
+ disorder_error(0, "parse_cookie: did not find expected '='");
return -1;
}
s = skipwhite(s, 0);
if(!(s = mime_parse_word(s, &v, cookie_value_separator))) {
- error(0, "parse_cookie: cannot parse value for '%s'", n);
+ disorder_error(0, "parse_cookie: cannot parse value for '%s'", n);
return -1;
}
if(n[0] == '$') {
if(cd->ncookies > 0 && cd->cookies[cd->ncookies-1].path == 0)
cd->cookies[cd->ncookies-1].path = v;
else {
- error(0, "redundant $Path in Cookie: header");
+ disorder_error(0, "redundant $Path in Cookie: header");
return -1;
}
} else if(!strcmp(n, "$Domain")) {
if(cd->ncookies > 0 && cd->cookies[cd->ncookies-1].domain == 0)
cd->cookies[cd->ncookies-1].domain = v;
else {
- error(0, "redundant $Domain in Cookie: header");
+ disorder_error(0, "redundant $Domain in Cookie: header");
return -1;
}
}
}
s = skipwhite(s, 0);
if(*s && (*s != ',' && *s != ';')) {
- error(0, "missing separator in Cookie: header");
+ disorder_error(0, "missing separator in Cookie: header");
return -1;
}
}
n = byte_snprintf(buffer, sizeof buffer, "%ld", VALUE(q, offset, long));
if(n < 0)
- fatal(errno, "error converting int");
+ disorder_fatal(errno, "error converting int");
else if((size_t)n >= sizeof buffer)
- fatal(0, "long converted to decimal is too long");
+ disorder_fatal(0, "long converted to decimal is too long");
return xstrdup(buffer);
}
n = byte_snprintf(buffer, sizeof buffer,
"%"PRIdMAX, (intmax_t)VALUE(q, offset, time_t));
if(n < 0)
- fatal(errno, "error converting time");
+ disorder_fatal(errno, "error converting time");
else if((size_t)n >= sizeof buffer)
- fatal(0, "time converted to decimal is too long");
+ disorder_fatal(0, "time converted to decimal is too long");
return xstrdup(buffer);
}
if(random_fd < 0) {
if((random_fd = open("/dev/urandom", O_RDONLY)) < 0)
- fatal(errno, "opening /dev/urandom");
+ disorder_fatal(errno, "opening /dev/urandom");
}
if((n = read(random_fd, key, sizeof key)) < 0)
- fatal(errno, "reading from /dev/urandom");
+ disorder_fatal(errno, "reading from /dev/urandom");
if((size_t)n < sizeof key)
- fatal(0, "reading from /dev/urandom: short read");
+ disorder_fatal(0, "reading from /dev/urandom: short read");
arcfour_setkey(random_ctx, key, sizeof key);
random_count = 8 * 1024 * 1024;
}
break;
}
if(rc <= 0 && rc != PCRE_ERROR_NOMATCH) {
- error(0, "pcre_exec returned %d, subject '%s'", rc, subject);
+ disorder_error(0, "pcre_exec returned %d, subject '%s'", rc, subject);
return 0;
}
if((flags & REGSUB_MUST_MATCH) && matches == 0)
if(!*s) {
/* You can't have no rights */
if(report)
- error(0, "empty rights string");
+ disorder_error(0, "empty rights string");
return -1;
}
while(*s) {
break;
if(n >= NRIGHTS) {
if(report)
- error(0, "unknown user right '%.*s'", (int)l, s);
+ disorder_error(0, "unknown user right '%.*s'", (int)l, s);
return -1;
}
r |= rights_names[n].bit;
&& line[2] >= '0' && line[2] <= '9') {
const int rc = 10 * (10 * line[0] + line[1]) + line[2] - 111 * '0';
if(rc >= 400 && rc <= 599)
- error(0, "%s: %s", tag, line);
+ disorder_error(0, "%s: %s", tag, line);
if(line[3] != '-') {
return rc;
}
/* else go round for further response lines */
} else {
- error(0, "%s: malformed response: %s", tag, line);
+ disorder_error(0, "%s: malformed response: %s", tag, line);
return -1;
}
}
if(ferror(in))
- error(errno, "%s: read error", tag);
+ disorder_error(errno, "%s: read error", tag);
else
- error(0, "%s: server closed connection", tag);
+ disorder_error(0, "%s: server closed connection", tag);
return -1;
}
rc = fflush(out);
if(rc >= 0)
return 0;
- error(errno, "%s: write error", tag);
+ disorder_error(errno, "%s: write error", tag);
return -1;
}
|| fprintf(out, "Date: %s\r\n", date) < 0
|| fprintf(out, "\r\n") < 0) {
write_error:
- error(errno, "%s: write error", tag);
+ disorder_error(errno, "%s: write error", tag);
return -1;
}
for(ptr = body; *ptr; ++ptr) {
xdup2(outpipe[1], 1);
execlp(config->sendmail,
config->sendmail, "-bs", (char *)0);
- fatal(errno, "executing %s", config->sendmail);
+ disorder_fatal(errno, "executing %s", config->sendmail);
}
xclose(inpipe[0]);
xclose(outpipe[1]);
return -1;
fdin = xsocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if(connect(fdin, ai->ai_addr, ai->ai_addrlen) < 0) {
- error(errno, "error connecting to %s", tag);
+ disorder_error(errno, "error connecting to %s", tag);
xclose(fdin);
return -1;
}
if((fdout = dup(fdin)) < 0)
- fatal(errno, "error calling dup2");
+ disorder_fatal(errno, "error calling dup2");
}
if(!(in = fdopen(fdin, "rb")))
- fatal(errno, "error calling fdopen");
+ disorder_fatal(errno, "error calling fdopen");
if(!(out = fdopen(fdout, "wb")))
- fatal(errno, "error calling fdopen");
+ disorder_fatal(errno, "error calling fdopen");
rc = sendmailfp(tag, in, out, sender, pubsender, recipient, subject,
encoding, content_type, body);
fclose(in);
while(waitpid(pid, &w, 0) < 0 && errno == EINTR)
;
if(w < 0)
- fatal(errno, "error calling waitpid");
+ disorder_fatal(errno, "error calling waitpid");
if(w)
- info("warning: %s -bs: %s", config->sendmail, wstat(w));
+ disorder_info("warning: %s -bs: %s", config->sendmail, wstat(w));
/* Not fatal - we determine success/failure from the SMTP conversation.
* Some MTAs exit nonzero if you don't QUIT, which is just stupidly
* picky. */
_exit(0);
}
if(pid < 0)
- error(errno, "error calling fork");
+ disorder_error(errno, "error calling fork");
return pid;
}
int n = fwrite(buffer, 1, nbytes, S(s)->fp);
if(n < nbytes) {
if(S(s)->name)
- fatal(errno, "error writing to %s", S(s)->name);
+ disorder_fatal(errno, "error writing to %s", S(s)->name);
else
return -1;
}
ret = write(fd, sm, sizeof *sm);
} while(ret < 0 && errno == EINTR);
if(ret < 0)
- fatal(errno, "write");
+ disorder_fatal(errno, "write");
}
/** @brief Receive a speaker message
ret = read(fd, sm, sizeof *sm);
} while(ret < 0 && errno == EINTR);
if(ret < 0) {
- if(errno != EAGAIN) fatal(errno, "recvmsg");
+ if(errno != EAGAIN)
+ disorder_fatal(errno, "recvmsg");
return -1;
}
return ret;
int mustnotbeminus1(const char *what, int ret) {
if(ret == -1)
- fatal(errno, "error calling %s", what);
+ disorder_fatal(errno, "error calling %s", what);
return ret;
}
pid_t xfork(void) {
pid_t pid;
- if((pid = fork()) < 0) fatal(errno, "error calling fork");
+ if((pid = fork()) < 0)
+ disorder_fatal(errno, "error calling fork");
return pid;
}
void xclose_guts(const char *path, int line, int fd) {
if(close(fd) < 0)
- fatal(errno, "%s:%d: close %d", path, line, fd);
+ disorder_fatal(errno, "%s:%d: close %d", path, line, fd);
}
void xdup2(int fd1, int fd2) {
* be -1 */
errno = 0;
ret = nice(inc);
- if(errno) fatal(errno, "error calling nice");
+ if(errno)
+ disorder_fatal(errno, "error calling nice");
return ret;
}
int e;
if(playlist_parse_name(name, 0, 0)) {
- error(0, "invalid playlist name '%s'", name);
+ disorder_error(0, "invalid playlist name '%s'", name);
return EINVAL;
}
WITH_TRANSACTION(trackdb_playlist_get_tid(name, who,
return e;
/* Get sharability */
if(!(s = kvp_get(k, "sharing"))) {
- error(0, "playlist '%s' has no 'sharing' key", name);
+ disorder_error(0, "playlist '%s' has no 'sharing' key", name);
s = "private";
}
/* Check the read is allowed */
*sharep = xstrdup(s);
/* Get track count */
if(!(s = kvp_get(k, "count"))) {
- error(0, "playlist '%s' has no 'count' key", name);
+ disorder_error(0, "playlist '%s' has no 'count' key", name);
s = "0";
}
ntracks = atoi(s);
if(ntracks < 0) {
- error(0, "playlist '%s' has negative count", name);
+ disorder_error(0, "playlist '%s' has negative count", name);
ntracks = 0;
}
/* Return track count */
for(int n = 0; n < ntracks; ++n) {
snprintf(b, sizeof b, "%d", n);
if(!(s = kvp_get(k, b))) {
- error(0, "playlist '%s' lacks track %d", name, n);
+ disorder_error(0, "playlist '%s' lacks track %d", name, n);
s = "unknown";
}
tracks[n] = xstrdup(s);
char *owner;
if(playlist_parse_name(name, &owner, 0)) {
- error(0, "invalid playlist name '%s'", name);
+ disorder_error(0, "invalid playlist name '%s'", name);
return EINVAL;
}
/* Check valid share types */
/* Playlists with an owner must be public or private */
if(strcmp(share, "public")
&& strcmp(share, "private")) {
- error(0, "playlist '%s' must be public or private", name);
+ disorder_error(0, "playlist '%s' must be public or private", name);
return EINVAL;
}
} else {
/* Playlists with no owner must be shared */
if(strcmp(share, "shared")) {
- error(0, "playlist '%s' must be shared", name);
+ disorder_error(0, "playlist '%s' must be shared", name);
return EINVAL;
}
}
}
/* Check that the modification is allowed */
if(!(s = kvp_get(k, "sharing"))) {
- error(0, "playlist '%s' has no 'sharing' key", name);
+ disorder_error(0, "playlist '%s' has no 'sharing' key", name);
s = "private";
}
if(!playlist_may_write(name, who, s))
/* Sanity check track count */
if(ntracks < 0 || ntracks > config->playlist_max) {
- error(0, "invalid track count %d", ntracks);
+ disorder_error(0, "invalid track count %d", ntracks);
return EINVAL;
}
/* Set the tracks */
/* Extract owner; malformed names are skipped */
if(playlist_parse_name(name, &owner, 0)) {
- error(0, "invalid playlist name '%s' found in database", name);
+ disorder_error(0, "invalid playlist name '%s' found in database", name);
continue;
}
if(!share) {
- error(0, "playlist '%s' has no 'sharing' key", name);
+ disorder_error(0, "playlist '%s' has no 'sharing' key", name);
continue;
}
/* Always list public and shared playlists
case DB_LOCK_DEADLOCK:
return e;
default:
- fatal(0, "c->c_get: %s", db_strerror(e));
+ disorder_fatal(0, "c->c_get: %s", db_strerror(e));
}
vector_terminate(v);
if(playlistsp)
char *owner;
if(playlist_parse_name(name, &owner, 0)) {
- error(0, "invalid playlist name '%s'", name);
+ disorder_error(0, "invalid playlist name '%s'", name);
return EINVAL;
}
/* We've checked as much as we can for now, now go and attempt the change */
return e;
/* Check that modification is allowed */
if(!(s = kvp_get(k, "sharing"))) {
- error(0, "playlist '%s' has no 'sharing' key", name);
+ disorder_error(0, "playlist '%s' has no 'sharing' key", name);
s = "private";
}
if(!playlist_may_write(name, who, s))
++initialized;
if(home) {
if(strcmp(home, config->home))
- fatal(0, "cannot change db home without server restart");
+ disorder_fatal(0, "cannot change db home without server restart");
home = config->home;
}
* The socket, not being a regular file, is excepted.
*/
if(!(dp = opendir(config->home)))
- fatal(errno, "error reading %s", config->home);
+ disorder_fatal(errno, "error reading %s", config->home);
while((de = readdir(dp))) {
byte_xasprintf(&p, "%s/%s", config->home, de->d_name);
if(lstat(p, &st) == 0
&& S_ISREG(st.st_mode)
&& (st.st_mode & 077)) {
if(chmod(p, st.st_mode & 07700) < 0)
- fatal(errno, "cannot chmod %s", p);
+ disorder_fatal(errno, "cannot chmod %s", p);
}
xfree(p);
}
}
/* create environment */
- if((err = db_env_create(&trackdb_env, 0))) fatal(0, "db_env_create: %s",
- db_strerror(err));
+ if((err = db_env_create(&trackdb_env, 0)))
+ disorder_fatal(0, "db_env_create: %s", db_strerror(err));
if((err = trackdb_env->set_alloc(trackdb_env,
xmalloc_noptr, xrealloc_noptr, xfree)))
- fatal(0, "trackdb_env->set_alloc: %s", db_strerror(err));
+ disorder_fatal(0, "trackdb_env->set_alloc: %s", db_strerror(err));
if((err = trackdb_env->set_lk_max_locks(trackdb_env, 10000)))
- fatal(0, "trackdb_env->set_lk_max_locks: %s", db_strerror(err));
+ disorder_fatal(0, "trackdb_env->set_lk_max_locks: %s", db_strerror(err));
if((err = trackdb_env->set_lk_max_objects(trackdb_env, 10000)))
- fatal(0, "trackdb_env->set_lk_max_objects: %s", db_strerror(err));
+ disorder_fatal(0, "trackdb_env->set_lk_max_objects: %s", db_strerror(err));
if((err = trackdb_env->open(trackdb_env, config->home,
DB_INIT_LOG
|DB_INIT_LOCK
|DB_CREATE
|recover_type[recover],
0600)))
- fatal(0, "trackdb_env->open %s: %s", config->home, db_strerror(err));
+ disorder_fatal(0, "trackdb_env->open %s: %s",
+ config->home, db_strerror(err));
trackdb_env->set_errpfx(trackdb_env, "DB");
trackdb_env->set_errfile(trackdb_env, stderr);
trackdb_env->set_verbose(trackdb_env, DB_VERB_DEADLOCK, 1);
void attribute((unused)) *u) {
db_deadlock_pid = -1;
if(initialized)
- fatal(0, "deadlock manager unexpectedly terminated: %s",
- wstat(status));
+ disorder_fatal(0, "deadlock manager unexpectedly terminated: %s",
+ wstat(status));
else
D(("deadlock manager terminated: %s", wstat(status)));
return 0;
}
/* ensure we don't leak privilege anywhere */
if(setuid(geteuid()) < 0)
- fatal(errno, "error calling setuid");
+ disorder_fatal(errno, "error calling setuid");
/* If we were negatively niced, undo it. We don't bother checking for
* error, it's not that important. */
setpriority(PRIO_PROCESS, 0, 0);
execvp(prog, (char **)args);
- fatal(errno, "error invoking %s", prog);
+ disorder_fatal(errno, "error invoking %s", prog);
}
return pid;
}
if(pid == -1)
return;
if(kill(pid, SIGTERM) < 0)
- fatal(errno, "error killing %s", what);
+ disorder_fatal(errno, "error killing %s", what);
/* wait for the rescanner to finish */
while(waitpid(pid, &err, 0) == -1 && errno == EINTR)
;
/* close the environment */
if((err = trackdb_env->close(trackdb_env, 0)))
- fatal(0, "trackdb_env->close: %s", db_strerror(err));
+ disorder_fatal(0, "trackdb_env->close: %s", db_strerror(err));
terminate_and_wait(ev, rescan_pid, "disorder-rescan");
rescan_pid = -1;
D(("open %s", path));
path = config_get_file(path);
if((err = db_create(&db, trackdb_env, 0)))
- fatal(0, "db_create %s: %s", path, db_strerror(err));
+ disorder_fatal(0, "db_create %s: %s", path, db_strerror(err));
if(dbflags)
if((err = db->set_flags(db, dbflags)))
- fatal(0, "db->set_flags %s: %s", path, db_strerror(err));
+ disorder_fatal(0, "db->set_flags %s: %s", path, db_strerror(err));
if(dbtype == DB_BTREE)
if((err = db->set_bt_compare(db, compare)))
- fatal(0, "db->set_bt_compare %s: %s", path, db_strerror(err));
+ disorder_fatal(0, "db->set_bt_compare %s: %s", path, db_strerror(err));
if((err = db->open(db, 0, path, 0, dbtype,
openflags | DB_AUTO_COMMIT, mode))) {
if((openflags & DB_CREATE) || errno != ENOENT) {
if((err2 = db->close(db, 0)))
- error(0, "db->close: %s", db_strerror(err2));
+ disorder_error(0, "db->close: %s", db_strerror(err2));
trackdb_close();
trackdb_env->close(trackdb_env,0);
trackdb_env = 0;
- fatal(0, "db->open %s: %s", path, db_strerror(err));
+ disorder_fatal(0, "db->open %s: %s", path, db_strerror(err));
}
db->close(db, 0);
db = 0;
s = trackdb_get_global("_dbversion");
/* Close the database again, we'll open it property below */
if((err = trackdb_globaldb->close(trackdb_globaldb, 0)))
- fatal(0, "error closing global.db: %s", db_strerror(err));
+ disorder_fatal(0, "error closing global.db: %s", db_strerror(err));
trackdb_globaldb = 0;
/* Convert version string to an integer */
oldversion = s ? atol(s) : 1;
if(oldversion > config->dbversion) {
/* Database is from the future; we never allow this. */
- fatal(0, "this version of DisOrder is too old for database version %ld",
- oldversion);
+ disorder_fatal(0, "this version of DisOrder is too old for database version %ld",
+ oldversion);
}
if(oldversion < config->dbversion) {
/* Database version is out of date */
switch(flags & TRACKDB_UPGRADE_MASK) {
case TRACKDB_NO_UPGRADE:
/* This database needs upgrading but this is not permitted */
- fatal(0, "database needs upgrading from %ld to %ld",
- oldversion, config->dbversion);
+ disorder_fatal(0, "database needs upgrading from %ld to %ld",
+ oldversion, config->dbversion);
case TRACKDB_CAN_UPGRADE:
/* This database needs upgrading */
- info("invoking disorder-dbupgrade to upgrade from %ld to %ld",
+ disorder_info("invoking disorder-dbupgrade to upgrade from %ld to %ld",
oldversion, config->dbversion);
pid = subprogram(0, -1, "disorder-dbupgrade", (char *)0);
while(waitpid(pid, &err, 0) == -1 && errno == EINTR)
;
if(err)
- fatal(0, "disorder-dbupgrade %s", wstat(err));
- info("disorder-dbupgrade succeeded");
+ disorder_fatal(0, "disorder-dbupgrade %s", wstat(err));
+ disorder_info("disorder-dbupgrade succeeded");
break;
case TRACKDB_OPEN_FOR_UPGRADE:
break;
}
if(oldversion == config->dbversion && (flags & TRACKDB_OPEN_FOR_UPGRADE)) {
/* This doesn't make any sense */
- fatal(0, "database is already at current version");
+ disorder_fatal(0, "database is already at current version");
}
trackdb_existing_database = 1;
} else {
if(flags & TRACKDB_OPEN_FOR_UPGRADE) {
/* Cannot upgrade a new database */
- fatal(0, "cannot upgrade a database that does not exist");
+ disorder_fatal(0, "cannot upgrade a database that does not exist");
}
/* This is a brand new database */
trackdb_existing_database = 0;
/* open the databases */
if(!(trackdb_usersdb = open_db("users.db",
0, DB_HASH, dbflags, 0600)))
- fatal(0, "cannot open users.db");
+ disorder_fatal(0, "cannot open users.db");
trackdb_tracksdb = open_db("tracks.db",
DB_RECNUM, DB_BTREE, dbflags, 0666);
trackdb_searchdb = open_db("search.db",
/* sanity checks */
assert(opened == 1);
--opened;
-#define CLOSE(N, V) do { \
- if(V && (err = V->close(V, 0))) \
- fatal(0, "error closing %s: %s", N, db_strerror(err)); \
- V = 0; \
+#define CLOSE(N, V) do { \
+ if(V && (err = V->close(V, 0))) \
+ disorder_fatal(0, "error closing %s: %s", N, db_strerror(err)); \
+ V = 0; \
} while(0)
CLOSE("tracks.db", trackdb_tracksdb);
CLOSE("search.db", trackdb_searchdb);
*kp = 0;
return err;
case DB_LOCK_DEADLOCK:
- error(0, "error querying database: %s", db_strerror(err));
+ disorder_error(0, "error querying database: %s", db_strerror(err));
return err;
default:
- fatal(0, "error querying database: %s", db_strerror(err));
+ disorder_fatal(0, "error querying database: %s", db_strerror(err));
}
}
case DB_KEYEXIST:
return err;
case DB_LOCK_DEADLOCK:
- error(0, "error updating database: %s", db_strerror(err));
+ disorder_error(0, "error updating database: %s", db_strerror(err));
return err;
default:
- fatal(0, "error updating database: %s", db_strerror(err));
+ disorder_fatal(0, "error updating database: %s", db_strerror(err));
}
}
case DB_NOTFOUND:
return 0;
case DB_LOCK_DEADLOCK:
- error(0, "error updating database: %s", db_strerror(err));
+ disorder_error(0, "error updating database: %s", db_strerror(err));
return err;
default:
- fatal(0, "error updating database: %s", db_strerror(err));
+ disorder_fatal(0, "error updating database: %s", db_strerror(err));
}
}
switch(err = db->cursor(db, tid, &c, 0)) {
case 0: break;
- default: fatal(0, "error creating cursor: %s", db_strerror(err));
+ default: disorder_fatal(0, "error creating cursor: %s", db_strerror(err));
}
return c;
}
case 0:
return err;
case DB_LOCK_DEADLOCK:
- error(0, "error closing cursor: %s", db_strerror(err));
+ disorder_error(0, "error closing cursor: %s", db_strerror(err));
return err;
default:
- fatal(0, "error closing cursor: %s", db_strerror(err));
+ disorder_fatal(0, "error closing cursor: %s", db_strerror(err));
}
}
err = 0;
break;
case DB_LOCK_DEADLOCK:
- error(0, "error updating database: %s", db_strerror(err));
+ disorder_error(0, "error updating database: %s", db_strerror(err));
break;
default:
- fatal(0, "c->c_del: %s", db_strerror(err));
+ disorder_fatal(0, "c->c_del: %s", db_strerror(err));
}
break;
case DB_NOTFOUND:
break;
case DB_LOCK_DEADLOCK:
- error(0, "error updating database: %s", db_strerror(err));
+ disorder_error(0, "error updating database: %s", db_strerror(err));
break;
default:
- fatal(0, "c->c_get: %s", db_strerror(err));
+ disorder_fatal(0, "c->c_get: %s", db_strerror(err));
}
if(trackdb_closecursor(c)) err = DB_LOCK_DEADLOCK;
return err;
int err;
if((err = trackdb_env->txn_begin(trackdb_env, 0, &tid, 0)))
- fatal(0, "trackdb_env->txn_begin: %s", db_strerror(err));
+ disorder_fatal(0, "trackdb_env->txn_begin: %s", db_strerror(err));
return tid;
}
if(tid)
if((err = tid->abort(tid)))
- fatal(0, "tid->abort: %s", db_strerror(err));
+ disorder_fatal(0, "tid->abort: %s", db_strerror(err));
}
/** @brief Commit transaction
int err;
if((err = tid->commit(tid, 0)))
- fatal(0, "tid->commit: %s", db_strerror(err));
+ disorder_fatal(0, "tid->commit: %s", db_strerror(err));
}
/* search/tags shared code ***************************************************/
case DB_KEYEXIST:
return 0;
case DB_LOCK_DEADLOCK:
- error(0, "error updating %s.db: %s", what, db_strerror(err));
+ disorder_error(0, "error updating %s.db: %s", what, db_strerror(err));
return err;
default:
- fatal(0, "error updating %s.db: %s", what, db_strerror(err));
+ disorder_fatal(0, "error updating %s.db: %s", what, db_strerror(err));
}
}
if((err = trackdb_getdata(trackdb_tracksdb, track, &t, tid))) goto done;
if((actual = kvp_get(t, "_alias_for"))) {
if(flags & GTD_NOALIAS) {
- error(0, "alias passed to gettrackdata where real path required");
+ disorder_error(0,
+ "alias passed to gettrackdata where real path required");
abort();
}
if((err = trackdb_getdata(trackdb_tracksdb, actual, &t, tid))) goto done;
make_key(&data, track), 0)) {
case 0: break;
case DB_LOCK_DEADLOCK: return err;
- default: fatal(0, "error updating noticed.db: %s", db_strerror(err));
+ default:
+ disorder_fatal(0, "error updating noticed.db: %s", db_strerror(err));
}
}
return ret;
case 0:
break;
case DB_LOCK_DEADLOCK:
- error(0, "error querying database: %s", db_strerror(err));
+ disorder_error(0, "error querying database: %s", db_strerror(err));
return err;
default:
- fatal(0, "error querying database: %s", db_strerror(err));
+ disorder_fatal(0, "error querying database: %s", db_strerror(err));
}
for(n = 0; n < nsi; ++n) {
byte_xasprintf(&str, "%s=%"PRIuMAX, si[n].name,
err = 0;
break;
case DB_LOCK_DEADLOCK:
- error(0, "error querying search database: %s", db_strerror(err));
+ disorder_error(0, "error querying search database: %s", db_strerror(err));
break;
default:
- fatal(0, "error querying search database: %s", db_strerror(err));
+ disorder_fatal(0, "error querying search database: %s", db_strerror(err));
}
if(trackdb_closecursor(cursor)) err = DB_LOCK_DEADLOCK;
if(err) return err;
d->exited = 1;
if(status)
- error(0, "disorder-stats %s", wstat(status));
+ disorder_error(0, "disorder-stats %s", wstat(status));
stats_complete(d);
char *k;
byte_xasprintf(&k, "%lu", (unsigned long)pid);
void *u) {
struct stats_details *const d = u;
- error(errno_value, "error reading from pipe to disorder-stats");
+ disorder_error(errno_value, "error reading from pipe to disorder-stats");
d->closed = 1;
stats_complete(d);
return 0;
ev_child(ev, pid, 0, stats_finished, d);
if(!ev_reader_new(ev, p[0], stats_read, stats_error, d,
"disorder-stats reader"))
- fatal(0, "ev_reader_new for disorder-stats reader failed");
+ disorder_fatal(0, "ev_reader_new for disorder-stats reader failed");
/* Remember the PID */
if(!stats_pids)
stats_pids = hash_new(1);
case DB_LOCK_DEADLOCK:
return e;
default:
- fatal(0, "c->c_get: %s", db_strerror(e));
+ disorder_fatal(0, "c->c_get: %s", db_strerror(e));
}
if((e = trackdb_closecursor(c)))
return e;
const struct rusage attribute((unused)) *rusage,
void attribute((unused)) *u) {
if(status)
- error(0, "disorder-choose %s", wstat(status));
+ disorder_error(0, "disorder-choose %s", wstat(status));
choose_status = status;
choose_finished(ev, CHOOSE_RUNNING);
return 0;
static int choose_read_error(ev_source *ev,
int errno_value,
void attribute((unused)) *u) {
- error(errno_value, "error reading disorder-choose pipe");
+ disorder_error(errno_value, "error reading disorder-choose pipe");
choose_finished(ev, CHOOSE_READING);
return 0;
}
choose_complete = 0;
if(!ev_reader_new(ev, p[0], choose_readable, choose_read_error, 0,
"disorder-choose reader")) /* owns p[0] */
- fatal(0, "ev_reader_new for disorder-choose reader failed");
+ disorder_fatal(0, "ev_reader_new for disorder-choose reader failed");
ev_child(ev, choose_pid, 0, choose_exited, 0); /* owns the subprocess */
return 0;
}
case PCRE_ERROR_NOMATCH: return 0;
default:
if(rc < 0) {
- error(0, "pcre_exec returned %d, subject '%s'", rc, track);
+ disorder_error(0, "pcre_exec returned %d, subject '%s'", rc, track);
return 0;
}
return 1;
err = 0;
break;
case DB_LOCK_DEADLOCK:
- error(0, "error querying database: %s", db_strerror(err));
+ disorder_error(0, "error querying database: %s", db_strerror(err));
break;
default:
- fatal(0, "error querying database: %s", db_strerror(err));
+ disorder_fatal(0, "error querying database: %s", db_strerror(err));
}
deadlocked:
if(trackdb_closecursor(cursor)) err = DB_LOCK_DEADLOCK;
err = 0;
break;
case DB_LOCK_DEADLOCK:
- error(0, "error querying %s database: %s", dbname, db_strerror(err));
+ disorder_error(0, "error querying %s database: %s",
+ dbname, db_strerror(err));
break;
default:
- fatal(0, "error querying %s database: %s", dbname, db_strerror(err));
+ disorder_fatal(0, "error querying %s database: %s",
+ dbname, db_strerror(err));
}
if(trackdb_closecursor(cursor)) err = DB_LOCK_DEADLOCK;
cursor = 0;
if((err = gettrackdata(v.vec[n], 0, &p, 0, 0, tid) == DB_LOCK_DEADLOCK))
goto fail;
else if(err) {
- error(0, "track %s unexpected error: %s", v.vec[n], db_strerror(err));
+ disorder_error(0, "track %s unexpected error: %s",
+ v.vec[n], db_strerror(err));
continue;
}
twords = track_to_words(v.vec[n], p);
trackdb_closecursor(cursor);
cursor = 0;
trackdb_abort_transaction(tid);
- info("retrying search");
+ disorder_info("retrying search");
}
trackdb_commit_transaction(tid);
vector_terminate(&u);
prefs = 0;
break;
case DB_LOCK_DEADLOCK:
- error(0, "getting prefs: %s", db_strerror(err));
+ disorder_error(0, "getting prefs: %s", db_strerror(err));
trackdb_closecursor(cursor);
return err;
default:
- fatal(0, "getting prefs: %s", db_strerror(err));
+ disorder_fatal(0, "getting prefs: %s", db_strerror(err));
}
/* Advance to the next track before the callback so that the callback
* may safely delete the track */
case DB_NOTFOUND:
return 0;
case DB_LOCK_DEADLOCK:
- error(0, "c->c_get: %s", db_strerror(err));
+ disorder_error(0, "c->c_get: %s", db_strerror(err));
return err;
default:
- fatal(0, "c->c_get: %s", db_strerror(err));
+ disorder_fatal(0, "c->c_get: %s", db_strerror(err));
}
}
void attribute((unused)) *u) {
if(pid == rescan_pid) rescan_pid = -1;
if(status)
- error(0, RESCAN": %s", wstat(status));
+ disorder_error(0, RESCAN": %s", wstat(status));
else
D((RESCAN" terminated: %s", wstat(status)));
/* Our cache of file lookups is out of date now */
if(rescan_pid != -1) {
trackdb_add_rescanned(rescanned, ru);
- error(0, "rescan already underway");
+ disorder_error(0, "rescan already underway");
return;
}
rescan_pid = subprogram(ev, -1, RESCAN,
int trackdb_rescan_cancel(void) {
if(rescan_pid == -1) return 0;
if(kill(rescan_pid, SIGTERM) < 0)
- fatal(errno, "error killing rescanner");
+ disorder_fatal(errno, "error killing rescanner");
rescan_pid = -1;
return 1;
}
/* log important state changes */
if(!strcmp(name, "playing")) {
state = !value || !strcmp(value, "yes");
- info("playing %s by %s",
- state ? "enabled" : "disabled",
- who ? who : "-");
+ disorder_info("playing %s by %s",
+ state ? "enabled" : "disabled",
+ who ? who : "-");
eventlog("state", state ? "enable_play" : "disable_play", (char *)0);
}
if(!strcmp(name, "random-play")) {
state = !value || !strcmp(value, "yes");
- info("random play %s by %s",
- state ? "enabled" : "disabled",
- who ? who : "-");
+ disorder_info("random play %s by %s",
+ state ? "enabled" : "disabled",
+ who ? who : "-");
eventlog("state", state ? "enable_random" : "disable_random", (char *)0);
}
}
err = trackdb_globaldb->del(trackdb_globaldb, tid, &k, 0);
if(err == DB_LOCK_DEADLOCK) return err;
if(err)
- fatal(0, "error updating database: %s", db_strerror(err));
+ disorder_fatal(0, "error updating database: %s", db_strerror(err));
return 0;
}
case DB_LOCK_DEADLOCK:
return err;
default:
- fatal(0, "error reading database: %s", db_strerror(err));
+ disorder_fatal(0, "error reading database: %s", db_strerror(err));
}
}
trackdb_closecursor(c);
return 0;
default:
- fatal(0, "error reading noticed.db: %s", db_strerror(err));
+ disorder_fatal(0, "error reading noticed.db: %s", db_strerror(err));
}
if((err = trackdb_closecursor(c)))
return 0; /* deadlock */
break;
if((err = c->c_del(c, 0))) {
if(err != DB_LOCK_DEADLOCK)
- fatal(0, "error deleting expired noticed.db entry: %s",
- db_strerror(err));
+ disorder_fatal(0, "error deleting expired noticed.db entry: %s",
+ db_strerror(err));
break;
}
++count;
if(err == DB_NOTFOUND)
err = 0;
if(err && err != DB_LOCK_DEADLOCK)
- fatal(0, "error expiring noticed.db: %s", db_strerror(err));
+ disorder_fatal(0, "error expiring noticed.db: %s", db_strerror(err));
ret = err;
if((err = trackdb_closecursor(c))) {
if(err != DB_LOCK_DEADLOCK)
- fatal(0, "error closing cursor: %s", db_strerror(err));
+ disorder_fatal(0, "error closing cursor: %s", db_strerror(err));
ret = err;
}
if(!ret && count)
- info("expired %d tracks from noticed.db", count);
+ disorder_info("expired %d tracks from noticed.db", count);
return ret;
}
config->checkpoint_kbyte,
config->checkpoint_min,
0)))
- fatal(0, "trackdb_env->txn_checkpoint: %s", db_strerror(err));
+ disorder_fatal(0, "trackdb_env->txn_checkpoint: %s", db_strerror(err));
if((err = trackdb_env->log_archive(trackdb_env, &logfiles, DB_ARCH_REMOVE)))
- fatal(0, "trackdb_env->log_archive: %s", db_strerror(err));
+ disorder_fatal(0, "trackdb_env->log_archive: %s", db_strerror(err));
/* This makes catastrophic recovery impossible. However, the user can still
* preserve the important data by using disorder-dump to snapshot their
* prefs, and later to restore it. This is likely to have much small
/* sanity check user */
if(!valid_username(user)) {
- error(0, "invalid username '%s'", user);
+ disorder_error(0, "invalid username '%s'", user);
return -1;
}
if(parse_rights(rights, 0, 1)) {
- error(0, "invalid rights string");
+ disorder_error(0, "invalid rights string");
return -1;
}
/* data for this user */
/* www-data doesn't get added */
if(!strcmp(user, "www-data")) {
- info("not adding www-data to user database");
+ disorder_info("not adding www-data to user database");
return 0;
}
/* pick rights */
switch(one_old_user(config->allow.s[n].s[0], config->allow.s[n].s[1],
tid)) {
case 0:
- info("created user %s from 'allow' directive", config->allow.s[n].s[0]);
+ disorder_info("created user %s from 'allow' directive",
+ config->allow.s[n].s[0]);
break;
case DB_KEYEXIST:
- error(0, "user %s already exists, delete 'allow' directive",
+ disorder_error(0, "user %s already exists, delete 'allow' directive",
config->allow.s[n].s[0]);
/* This won't ever become fatal - eventually 'allow' will be
* disabled. */
0/*email*/, 0/*confirmation*/,
tid, DB_NOOVERWRITE));
if(e == 0)
- info("created root user");
+ disorder_info("created root user");
}
/** @brief Find a user's password from the database
WITH_TRANSACTION(create_user(user, password, rights, email, confirmation,
tid, DB_NOOVERWRITE));
if(e) {
- error(0, "cannot create user '%s' because they already exist", user);
+ disorder_error(0, "cannot create user '%s' because they already exist",
+ user);
return -1;
} else {
if(email)
- info("created user '%s' with rights '%s' and email address '%s'",
- user, rights, email);
+ disorder_info("created user '%s' with rights '%s' and email address '%s'",
+ user, rights, email);
else
- info("created user '%s' with rights '%s'", user, rights);
+ disorder_info("created user '%s' with rights '%s'", user, rights);
eventlog("user_add", user, (char *)0);
return 0;
}
WITH_TRANSACTION(trackdb_delkey(trackdb_usersdb, user, tid));
if(e) {
- error(0, "cannot delete user '%s' because they do not exist", user);
+ disorder_error(0, "cannot delete user '%s' because they do not exist",
+ user);
return -1;
}
- info("deleted user '%s'", user);
+ disorder_info("deleted user '%s'", user);
eventlog("user_delete", user, (char *)0);
return 0;
}
if(!strcmp(key, "rights")) {
if(!value) {
- error(0, "cannot remove 'rights' key from user '%s'", user);
+ disorder_error(0, "cannot remove 'rights' key from user '%s'", user);
return -1;
}
if(parse_rights(value, 0, 1)) {
- error(0, "invalid rights string");
+ disorder_error(0, "invalid rights string");
return -1;
}
} else if(!strcmp(key, "email")) {
if(*value) {
if(!email_valid(value)) {
- error(0, "invalid email address '%s' for user '%s'", value, user);
+ disorder_error(0, "invalid email address '%s' for user '%s'",
+ value, user);
return -1;
}
} else
value = 0; /* no email -> remove key */
} else if(!strcmp(key, "created")) {
- error(0, "cannot change creation date for user '%s'", user);
+ disorder_error(0, "cannot change creation date for user '%s'", user);
return -1;
} else if(strcmp(key, "password")
&& !strcmp(key, "confirmation")) {
- error(0, "unknown user info key '%s' for user '%s'", key, user);
+ disorder_error(0, "unknown user info key '%s' for user '%s'", key, user);
return -1;
}
WITH_TRANSACTION(trackdb_edituserinfo_tid(user, key, value, tid));
if(e) {
- error(0, "unknown user '%s'", user);
+ disorder_error(0, "unknown user '%s'", user);
return -1;
} else {
eventlog("user_edit", user, key, (char *)0);
if((e = trackdb_getdata(trackdb_usersdb, user, &k, tid)))
return e;
if(!(stored_confirmation = kvp_get(k, "confirmation"))) {
- error(0, "already confirmed user '%s'", user);
+ disorder_error(0, "already confirmed user '%s'", user);
/* DB claims -30,800 to -30,999 so -1 should be a safe bet */
return -1;
}
if(!(rights = kvp_get(k, "rights"))) {
- error(0, "no rights for unconfirmed user '%s'", user);
+ disorder_error(0, "no rights for unconfirmed user '%s'", user);
return -1;
}
if(parse_rights(rights, rightsp, 1))
return -1;
if(strcmp(confirmation, stored_confirmation)) {
- error(0, "wrong confirmation string for user '%s'", user);
+ disorder_error(0, "wrong confirmation string for user '%s'", user);
return -1;
}
/* 'sall good */
WITH_TRANSACTION(trackdb_confirm_tid(user, confirmation, rightsp, tid));
switch(e) {
case 0:
- info("registration confirmed for user '%s'", user);
+ disorder_info("registration confirmed for user '%s'", user);
eventlog("user_confirm", user, (char *)0);
return 0;
case DB_NOTFOUND:
- error(0, "confirmation for nonexistent user '%s'", user);
+ disorder_error(0, "confirmation for nonexistent user '%s'", user);
return -1;
default: /* already reported */
return -1;
const struct collection *c = find_track_collection(track);
if(c)
return c->root;
- error(0, "found track in no collection '%s'", track);
+ disorder_error(0, "found track in no collection '%s'", track);
return 0;
}
switch(rc) {
case -EPIPE:
if((err = snd_pcm_prepare(alsa_pcm)))
- fatal(0, "error calling snd_pcm_prepare: %d", err);
+ disorder_fatal(0, "error calling snd_pcm_prepare: %d", err);
return 0;
case -EAGAIN:
return 0;
default:
- fatal(0, "error calling snd_pcm_writei: %d", (int)rc);
+ disorder_fatal(0, "error calling snd_pcm_writei: %d", (int)rc);
}
}
return rc * uaudio_channels;
device,
SND_PCM_STREAM_PLAYBACK,
0)))
- fatal(0, "error from snd_pcm_open: %d", err);
+ disorder_fatal(0, "error from snd_pcm_open: %d", err);
snd_pcm_hw_params_t *hwparams;
snd_pcm_hw_params_alloca(&hwparams);
if((err = snd_pcm_hw_params_any(alsa_pcm, hwparams)) < 0)
- fatal(0, "error from snd_pcm_hw_params_any: %d", err);
+ disorder_fatal(0, "error from snd_pcm_hw_params_any: %d", err);
if((err = snd_pcm_hw_params_set_access(alsa_pcm, hwparams,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
- fatal(0, "error from snd_pcm_hw_params_set_access: %d", err);
+ disorder_fatal(0, "error from snd_pcm_hw_params_set_access: %d", err);
int sample_format;
if(uaudio_bits == 16)
sample_format = uaudio_signed ? SND_PCM_FORMAT_S16 : SND_PCM_FORMAT_U16;
sample_format = uaudio_signed ? SND_PCM_FORMAT_S8 : SND_PCM_FORMAT_U8;
if((err = snd_pcm_hw_params_set_format(alsa_pcm, hwparams,
sample_format)) < 0)
- fatal(0, "error from snd_pcm_hw_params_set_format (%d): %d",
+ disorder_fatal(0, "error from snd_pcm_hw_params_set_format (%d): %d",
sample_format, err);
unsigned rate = uaudio_rate;
if((err = snd_pcm_hw_params_set_rate_near(alsa_pcm, hwparams, &rate, 0)) < 0)
- fatal(0, "error from snd_pcm_hw_params_set_rate_near (%d): %d",
+ disorder_fatal(0, "error from snd_pcm_hw_params_set_rate_near (%d): %d",
rate, err);
if((err = snd_pcm_hw_params_set_channels(alsa_pcm, hwparams,
uaudio_channels)) < 0)
- fatal(0, "error from snd_pcm_hw_params_set_channels (%d): %d",
+ disorder_fatal(0, "error from snd_pcm_hw_params_set_channels (%d): %d",
uaudio_channels, err);
if((err = snd_pcm_hw_params(alsa_pcm, hwparams)) < 0)
- fatal(0, "error calling snd_pcm_hw_params: %d", err);
+ disorder_fatal(0, "error calling snd_pcm_hw_params: %d", err);
}
static void alsa_start(uaudio_callback *callback,
void *userdata) {
if(uaudio_channels != 1 && uaudio_channels != 2)
- fatal(0, "asked for %d channels but only support 1 or 2",
+ disorder_fatal(0, "asked for %d channels but only support 1 or 2",
uaudio_channels);
if(uaudio_bits != 8 && uaudio_bits != 16)
- fatal(0, "asked for %d bits/channel but only support 8 or 16",
+ disorder_fatal(0, "asked for %d bits/channel but only support 8 or 16",
uaudio_bits);
alsa_open();
uaudio_thread_start(callback, userdata, alsa_play,
snd_mixer_selem_id_alloca(&id);
if((err = snd_mixer_open(&alsa_mixer_handle, 0)))
- fatal(0, "snd_mixer_open: %s", snd_strerror(err));
+ disorder_fatal(0, "snd_mixer_open: %s", snd_strerror(err));
if((err = snd_mixer_attach(alsa_mixer_handle, device)))
- fatal(0, "snd_mixer_attach %s: %s", device, snd_strerror(err));
+ disorder_fatal(0, "snd_mixer_attach %s: %s", device, snd_strerror(err));
if((err = snd_mixer_selem_register(alsa_mixer_handle,
0/*options*/, 0/*classp*/)))
- fatal(0, "snd_mixer_selem_register %s: %s",
+ disorder_fatal(0, "snd_mixer_selem_register %s: %s",
device, snd_strerror(err));
if((err = snd_mixer_load(alsa_mixer_handle)))
- fatal(0, "snd_mixer_load %s: %s", device, snd_strerror(err));
+ disorder_fatal(0, "snd_mixer_load %s: %s", device, snd_strerror(err));
snd_mixer_selem_id_set_name(id, channel);
snd_mixer_selem_id_set_index(id, atoi(mixer));
if(!(alsa_mixer_elem = snd_mixer_find_selem(alsa_mixer_handle, id)))
- fatal(0, "device '%s' mixer control '%s,%s' does not exist",
- device, channel, mixer);
+ disorder_fatal(0, "device '%s' mixer control '%s,%s' does not exist",
+ device, channel, mixer);
if(!snd_mixer_selem_has_playback_volume(alsa_mixer_elem))
- fatal(0, "device '%s' mixer control '%s,%s' has no playback volume",
- device, channel, mixer);
+ disorder_fatal(0,
+ "device '%s' mixer control '%s,%s' has no playback volume",
+ device, channel, mixer);
if(snd_mixer_selem_is_playback_mono(alsa_mixer_elem)) {
alsa_mixer_left = alsa_mixer_right = SND_MIXER_SCHN_MONO;
} else {
alsa_mixer_left)
|| !snd_mixer_selem_has_playback_channel(alsa_mixer_elem,
alsa_mixer_right))
- fatal(0, "device '%s' mixer control '%s,%s' lacks required playback channels",
- device, channel, mixer);
+ disorder_fatal(0, "device '%s' mixer control '%s,%s' lacks required playback channels",
+ device, channel, mixer);
snd_mixer_selem_get_playback_volume_range(alsa_mixer_elem,
&alsa_mixer_min, &alsa_mixer_max);
alsa_mixer_left, &l))
|| (err = snd_mixer_selem_get_playback_volume(alsa_mixer_elem,
alsa_mixer_right, &r)))
- fatal(0, "snd_mixer_selem_get_playback_volume: %s", snd_strerror(err));
+ disorder_fatal(0, "snd_mixer_selem_get_playback_volume: %s",
+ snd_strerror(err));
*left = to_percent(l);
*right = to_percent(r);
}
if((err = snd_mixer_selem_set_playback_volume
(alsa_mixer_elem, alsa_mixer_left,
from_percent(*left > *right ? *left : *right))))
- fatal(0, "snd_mixer_selem_set_playback_volume: %s", snd_strerror(err));
+ disorder_fatal(0, "snd_mixer_selem_set_playback_volume: %s",
+ snd_strerror(err));
} else {
/* Stereo output */
if((err = snd_mixer_selem_set_playback_volume
(alsa_mixer_elem, alsa_mixer_left, from_percent(*left)))
|| (err = snd_mixer_selem_set_playback_volume
(alsa_mixer_elem, alsa_mixer_right, from_percent(*right))))
- fatal(0, "snd_mixer_selem_set_playback_volume: %s", snd_strerror(err));
+ disorder_fatal(0, "snd_mixer_selem_set_playback_volume: %s",
+ snd_strerror(err));
}
/* Read it back to see what we ended up at */
if((err = snd_mixer_selem_get_playback_volume(alsa_mixer_elem,
alsa_mixer_left, &l))
|| (err = snd_mixer_selem_get_playback_volume(alsa_mixer_elem,
alsa_mixer_right, &r)))
- fatal(0, "snd_mixer_selem_get_playback_volume: %s", snd_strerror(err));
+ disorder_fatal(0, "snd_mixer_selem_get_playback_volume: %s",
+ snd_strerror(err));
*left = to_percent(l);
*right = to_percent(r);
}
return uaudio_apis[n];
if(!strcmp(name, "network"))
return &uaudio_rtp;
- fatal(0, "cannot find audio API '%s'", name);
+ disorder_fatal(0, "cannot find audio API '%s'", name);
}
/*
while((rc = waitpid(command_pid, &w, 0) < 0 && errno == EINTR))
;
if(rc < 0)
- fatal(errno, "waitpid");
+ disorder_fatal(errno, "waitpid");
if(w) {
ws = wstat(w);
- error(0, "command subprocess %s", ws);
+ disorder_error(0, "command subprocess %s", ws);
xfree(ws);
}
}
const char *command;
if(!(command = uaudio_get("command", NULL)))
- fatal(0, "'command' not set");
+ disorder_fatal(0, "'command' not set");
xpipe(pfd);
command_pid = xfork();
if(!command_pid) {
* format. The original intended model is that you adapt DisOrder to the
* command you run but it'd be nice to support the opposite. */
execl("/bin/sh", "sh", "-c", command, (char *)0);
- fatal(errno, "error executing /bin/sh");
+ disorder_fatal(errno, "error executing /bin/sh");
}
close(pfd[0]);
command_fd = pfd[1];
case EINTR:
return 0; /* will retry */
case EPIPE:
- error(0, "audio command subprocess terminated");
+ disorder_error(0, "audio command subprocess terminated");
command_wait();
command_open();
return 0; /* will retry */
default:
- fatal(errno, "error writing to audio command subprocess");
+ disorder_fatal(errno, "error writing to audio command subprocess");
}
}
/* TODO what if we write a partial sample? Actually reasonably unlikely but
else if(!strcmp(pausemode, "suspend"))
command_suspend_on_pause = 1;
else
- fatal(0, "unknown pause mode '%s'", pausemode);
+ disorder_fatal(0, "unknown pause mode '%s'", pausemode);
command_open();
uaudio_schedule_init();
uaudio_thread_start(callback,
}
#endif
if((oss_fd = open(device, O_WRONLY, 0)) < 0)
- fatal(errno, "error opening %s", device);
+ disorder_fatal(errno, "error opening %s", device);
#if !EMPEG_HOST
int stereo = (uaudio_channels == 2), format;
if(ioctl(oss_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
- fatal(errno, "error calling ioctl SNDCTL_DSP_STEREO %d", stereo);
+ disorder_fatal(errno, "error calling ioctl SNDCTL_DSP_STEREO %d", stereo);
if(uaudio_bits == 16)
format = uaudio_signed ? AFMT_S16_NE : AFMT_U16_NE;
else
format = uaudio_signed ? AFMT_S8 : AFMT_U8;
if(ioctl(oss_fd, SNDCTL_DSP_SETFMT, &format) < 0)
- fatal(errno, "error calling ioctl SNDCTL_DSP_SETFMT %#x", format);
+ disorder_fatal(errno, "error calling ioctl SNDCTL_DSP_SETFMT %#x", format);
int rate = uaudio_rate;
if(ioctl(oss_fd, SNDCTL_DSP_SPEED, &rate) < 0)
- fatal(errno, "error calling ioctl SNDCTL_DSP_SPEED %d", rate);
+ disorder_fatal(errno, "error calling ioctl SNDCTL_DSP_SPEED %d", rate);
if(rate != uaudio_rate)
- error(0, "asked for %dHz, got %dHz", uaudio_rate, rate);
+ disorder_error(0, "asked for %dHz, got %dHz", uaudio_rate, rate);
#endif
}
const size_t bytes = samples * uaudio_sample_size;
int rc = write(oss_fd, buffer, bytes);
if(rc < 0)
- fatal(errno, "error writing to sound device");
+ disorder_fatal(errno, "error writing to sound device");
return rc / uaudio_sample_size;
}
static void oss_start(uaudio_callback *callback,
void *userdata) {
if(uaudio_channels != 1 && uaudio_channels != 2)
- fatal(0, "asked for %d channels but only support 1 or 2",
+ disorder_fatal(0, "asked for %d channels but only support 1 or 2",
uaudio_channels);
if(uaudio_bits != 8 && uaudio_bits != 16)
- fatal(0, "asked for %d bits/channel but only support 8 or 16",
+ disorder_fatal(0, "asked for %d bits/channel but only support 8 or 16",
uaudio_bits);
#if EMPEG_HOST
/* Very specific buffer size requirements here apparently */
const char *mixer = uaudio_get("mixer-device", "/dev/mixer");
/* TODO infer mixer-device from device */
if((oss_mixer_fd = open(mixer, O_RDWR, 0)) < 0)
- fatal(errno, "error opening %s", mixer);
+ disorder_fatal(errno, "error opening %s", mixer);
const char *channel = uaudio_get("mixer-channel", "pcm");
oss_mixer_channel = oss_mixer_find_channel(channel);
if(oss_mixer_channel < 0)
- fatal(0, "no such channel as '%s'", channel);
+ disorder_fatal(0, "no such channel as '%s'", channel);
}
static void oss_close_mixer(void) {
*left = *right = 0;
if(ioctl(oss_mixer_fd, SOUND_MIXER_READ(oss_mixer_channel), &r) < 0)
- error(errno, "error getting volume");
+ disorder_error(errno, "error getting volume");
else {
*left = r & 0xff;
*right = (r >> 8) & 0xff;
static void oss_set_volume(int *left, int *right) {
int r = (*left & 0xff) + (*right & 0xff) * 256;
if(ioctl(oss_mixer_fd, SOUND_MIXER_WRITE(oss_mixer_channel), &r) == -1)
- error(errno, "error setting volume");
+ disorder_error(errno, "error setting volume");
else if(ioctl(oss_mixer_fd, SOUND_MIXER_READ(oss_mixer_channel), &r) < 0)
- error(errno, "error getting volume");
+ disorder_error(errno, "error getting volume");
else {
*left = r & 0xff;
*right = (r >> 8) & 0xff;
na->af = -1;
else
if(netaddress_parse(na, 3, vec))
- fatal(0, "invalid RTP address");
+ disorder_fatal(0, "invalid RTP address");
}
static void rtp_set_netconfig(const char *af,
written_bytes = writev(rtp_fd, vec, 2);
} while(written_bytes < 0 && errno == EINTR);
if(written_bytes < 0) {
- error(errno, "error transmitting audio data");
+ disorder_error(errno, "error transmitting audio data");
++rtp_errors;
if(rtp_errors == 10)
- fatal(0, "too many audio tranmission errors");
+ disorder_fatal(0, "too many audio tranmission errors");
return 0;
} else
rtp_errors /= 2; /* gradual decay */
if((rtp_fd = socket(res->ai_family,
res->ai_socktype,
res->ai_protocol)) < 0)
- fatal(errno, "error creating broadcast socket");
+ disorder_fatal(errno, "error creating broadcast socket");
if(multicast(res->ai_addr)) {
/* Enable multicast options */
const int ttl = atoi(uaudio_get("multicast-ttl", "1"));
case PF_INET: {
if(setsockopt(rtp_fd, IPPROTO_IP, IP_MULTICAST_TTL,
&ttl, sizeof ttl) < 0)
- fatal(errno, "error setting IP_MULTICAST_TTL on multicast socket");
+ disorder_fatal(errno, "error setting IP_MULTICAST_TTL on multicast socket");
if(setsockopt(rtp_fd, IPPROTO_IP, IP_MULTICAST_LOOP,
&loop, sizeof loop) < 0)
- fatal(errno, "error setting IP_MULTICAST_LOOP on multicast socket");
+ disorder_fatal(errno, "error setting IP_MULTICAST_LOOP on multicast socket");
break;
}
case PF_INET6: {
if(setsockopt(rtp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
&ttl, sizeof ttl) < 0)
- fatal(errno, "error setting IPV6_MULTICAST_HOPS on multicast socket");
+ disorder_fatal(errno, "error setting IPV6_MULTICAST_HOPS on multicast socket");
if(setsockopt(rtp_fd, IPPROTO_IP, IPV6_MULTICAST_LOOP,
&loop, sizeof loop) < 0)
- fatal(errno, "error setting IPV6_MULTICAST_LOOP on multicast socket");
+ disorder_fatal(errno, "error setting IPV6_MULTICAST_LOOP on multicast socket");
break;
}
default:
- fatal(0, "unsupported address family %d", res->ai_family);
+ disorder_fatal(0, "unsupported address family %d", res->ai_family);
}
- info("multicasting on %s TTL=%d loop=%s",
- format_sockaddr(res->ai_addr), ttl, loop ? "yes" : "no");
+ disorder_info("multicasting on %s TTL=%d loop=%s",
+ format_sockaddr(res->ai_addr), ttl, loop ? "yes" : "no");
} else {
struct ifaddrs *ifs;
if(getifaddrs(&ifs) < 0)
- fatal(errno, "error calling getifaddrs");
+ disorder_fatal(errno, "error calling getifaddrs");
while(ifs) {
/* (At least on Darwin) IFF_BROADCAST might be set but ifa_broadaddr
* still a null pointer. It turns out that there's a subsequent entry
}
if(ifs) {
if(setsockopt(rtp_fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof one) < 0)
- fatal(errno, "error setting SO_BROADCAST on broadcast socket");
- info("broadcasting on %s (%s)",
+ disorder_fatal(errno, "error setting SO_BROADCAST on broadcast socket");
+ disorder_info("broadcasting on %s (%s)",
format_sockaddr(res->ai_addr), ifs->ifa_name);
} else
- info("unicasting on %s", format_sockaddr(res->ai_addr));
+ disorder_info("unicasting on %s", format_sockaddr(res->ai_addr));
}
/* Enlarge the socket buffer */
len = sizeof sndbuf;
if(getsockopt(rtp_fd, SOL_SOCKET, SO_SNDBUF,
&sndbuf, &len) < 0)
- fatal(errno, "error getting SO_SNDBUF");
+ disorder_fatal(errno, "error getting SO_SNDBUF");
if(target_sndbuf > sndbuf) {
if(setsockopt(rtp_fd, SOL_SOCKET, SO_SNDBUF,
&target_sndbuf, sizeof target_sndbuf) < 0)
- error(errno, "error setting SO_SNDBUF to %d", target_sndbuf);
+ disorder_error(errno, "error setting SO_SNDBUF to %d", target_sndbuf);
else
- info("changed socket send buffer size from %d to %d",
+ disorder_info("changed socket send buffer size from %d to %d",
sndbuf, target_sndbuf);
} else
- info("default socket send buffer is %d",
- sndbuf);
+ disorder_info("default socket send buffer is %d", sndbuf);
/* We might well want to set additional broadcast- or multicast-related
* options here */
if(sres && bind(rtp_fd, sres->ai_addr, sres->ai_addrlen) < 0)
- fatal(errno, "error binding broadcast socket to %s",
- format_sockaddr(sres->ai_addr));
+ disorder_fatal(errno, "error binding broadcast socket to %s",
+ format_sockaddr(sres->ai_addr));
if(connect(rtp_fd, res->ai_addr, res->ai_addrlen) < 0)
- fatal(errno, "error connecting broadcast socket to %s",
- format_sockaddr(res->ai_addr));
+ disorder_fatal(errno, "error connecting broadcast socket to %s",
+ format_sockaddr(res->ai_addr));
}
static void rtp_start(uaudio_callback *callback,
&& uaudio_rate == 44100)
rtp_payload = 11;
else
- fatal(0, "asked for %d/%d/%d 16/44100/1 and 16/44100/2",
- uaudio_bits, uaudio_rate, uaudio_channels);
+ disorder_fatal(0, "asked for %d/%d/%d 16/44100/1 and 16/44100/2",
+ uaudio_bits, uaudio_rate, uaudio_channels);
/* Various fields are required to have random initial values by RFC3550. The
* packet contents are highly public so there's no point asking for very
* strong randomness. */
NULL,
uaudio_collect_thread_fn,
NULL)))
- fatal(e, "pthread_create");
+ disorder_fatal(e, "pthread_create");
if((e = pthread_create(&uaudio_play_thread,
NULL,
uaudio_play_thread_fn,
NULL)))
- fatal(e, "pthread_create");
+ disorder_fatal(e, "pthread_create");
}
/** @brief Shut down background threads for audio processing */
/* Figure out the server. 'MUST' be set and we don't cope if it
* is not. */
if(!(server = getenv("SERVER_NAME")))
- fatal(0, "SERVER_NAME is not set");
+ disorder_fatal(0, "SERVER_NAME is not set");
server = xstrdup(server);
/* Figure out the port. 'MUST' be set but we cope if it is not. */
} else {
/* RFC3875 s4.1.13 */
if(!(script = getenv("SCRIPT_NAME")))
- fatal(0, "SCRIPT_NAME is not set");
+ disorder_fatal(0, "SCRIPT_NAME is not set");
/* SCRIPT_NAME may be "" */
if(!*script)
script = "/";
script, urlencodestring(path_info));
}
if(script[0] != '/')
- fatal(0, "SCRIPT_NAME does not start with a '/'");
+ disorder_fatal(0, "SCRIPT_NAME does not start with a '/'");
script = xstrdup(script);
if(port == 80)
if(config->user) {
if(!(pw = getpwnam(config->user)))
- fatal(0, "cannot find user %s", config->user);
+ disorder_fatal(0, "cannot find user %s", config->user);
if(pw->pw_uid != getuid()) {
if(initgroups(config->user, pw->pw_gid))
- fatal(errno, "error calling initgroups");
- if(setgid(pw->pw_gid) < 0) fatal(errno, "error calling setgid");
- if(setuid(pw->pw_uid) < 0) fatal(errno, "error calling setgid");
- info("changed to user %s (uid %lu)", config->user, (unsigned long)getuid());
+ disorder_fatal(errno, "error calling initgroups");
+ if(setgid(pw->pw_gid) < 0)
+ disorder_fatal(errno, "error calling setgid");
+ if(setuid(pw->pw_uid) < 0)
+ disorder_fatal(errno, "error calling setgid");
+ disorder_info("changed to user %s (uid %lu)",
+ config->user, (unsigned long)getuid());
}
/* sanity checks */
- if(getuid() != pw->pw_uid) fatal(0, "wrong real uid");
- if(geteuid() != pw->pw_uid) fatal(0, "wrong effective uid");
- if(getgid() != pw->pw_gid) fatal(0, "wrong real gid");
- if(getegid() != pw->pw_gid) fatal(0, "wrong effective gid");
- if(setuid(0) != -1) fatal(0, "setuid(0) unexpectedly succeeded");
- if(seteuid(0) != -1) fatal(0, "seteuid(0) unexpectedly succeeded");
+ if(getuid() != pw->pw_uid)
+ disorder_fatal(0, "wrong real uid");
+ if(geteuid() != pw->pw_uid)
+ disorder_fatal(0, "wrong effective uid");
+ if(getgid() != pw->pw_gid)
+ disorder_fatal(0, "wrong real gid");
+ if(getegid() != pw->pw_gid)
+ disorder_fatal(0, "wrong effective gid");
+ if(setuid(0) != -1)
+ disorder_fatal(0, "setuid(0) unexpectedly succeeded");
+ if(seteuid(0) != -1)
+ disorder_fatal(0, "seteuid(0) unexpectedly succeeded");
}
}
}
/* create the directory itself */
if(mkdir(config->home, 02755) < 0)
- fatal(errno, "error creating %s", config->home);
+ disorder_fatal(errno, "error creating %s", config->home);
/* make sure it has the right ownership */
if(config->user) {
if(!(pw = getpwnam(config->user)))
- fatal(0, "cannot find user %s", config->user);
+ disorder_fatal(0, "cannot find user %s", config->user);
if(chown(config->home, pw->pw_uid, pw->pw_gid) < 0)
- fatal(errno, "error chowning %s", config->home);
+ disorder_fatal(errno, "error chowning %s", config->home);
}
}
}
|| fputs("wibble wibble\r\nspong", fp) < 0 /* ensure CONTENT_LENGTH
* honored */
|| fflush(fp) < 0)
- fatal(errno, "writing to temporary file");
+ disorder_fatal(errno, "writing to temporary file");
rewind(fp);
xdup2(fileno(fp), 0);
lseek(0, 0/*offset*/, SEEK_SET);
snprintf(buffer, sizeof buffer,
"wget http://www.unicode.org/Public/5.1.0/ucd/%s", path);
if((w = system(buffer)))
- fatal(0, "%s: %s", buffer, wstat(w));
+ disorder_fatal(0, "%s: %s", buffer, wstat(w));
if(chmod(base, 0444) < 0)
- fatal(errno, "chmod %s", base);
+ disorder_fatal(errno, "chmod %s", base);
if(!(fp = fopen(base, "r")))
- fatal(errno, "%s", base);
+ disorder_fatal(errno, "%s", base);
}
return fp;
}
buffer[bn++] = strtoul(lp, &lp, 16);
continue;
}
- fatal(0, "%s:%d: evil line: %s", path, lineno, l);
+ disorder_fatal(0, "%s:%d: evil line: %s", path, lineno, l);
}
for(n = 0; n <= bn; ++n) {
if(breakfn(buffer, bn, n) != break_allowed[n]) {
while(*s) {
errno = 0;
dynstr_ucs4_append(&d, strtoul(s, &e, 0));
- if(errno) fatal(errno, "strtoul (%s)", s);
+ if(errno)
+ disorder_fatal(errno, "strtoul (%s)", s);
s = e;
}
dynstr_ucs4_terminate(&d);
* modules use this so it's not well tested, unfortunately. */
if(q->type & DISORDER_PLAYER_PREFORK)
if(!(q->data = play_prefork(q->pl, q->track))) {
- error(0, "prefork function for %s failed", q->track);
+ disorder_error(0, "prefork function for %s failed", q->track);
return START_HARDFAIL;
}
/* Capture the player/decoder's stderr and feed it into our logs.
++optv;
--optc;
} else {
- error(0, "unknown option %s", optv[0]);
+ disorder_error(0, "unknown option %s", optv[0]);
return START_HARDFAIL;
}
}
_exit(child(q, params, bgdata));
case -1:
/* Back in disorderd (child could not be created) */
- error(errno, "error calling fork");
+ disorder_error(errno, "error calling fork");
if(q->type & DISORDER_PLAYER_PREFORK)
play_cleanup(q->pl, q->data); /* else would leak */
if(lfd != -1)
/* Reject tracks not in any collection (race between edit config and
* rescan) */
if(!find_track_root(track)) {
- info("found track not in any collection: %s", track);
+ disorder_info("found track not in any collection: %s", track);
return 0;
}
set_progname(argv);
mem_init();
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVc:dDSs", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'D': debugging = 0; break;
case 'S': logsyslog = 0; break;
case 's': logsyslog = 1; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if(logsyslog) {
openlog(progname, LOG_PID, LOG_DAEMON);
log_default = &log_syslog;
}
- if(config_read(0, NULL)) fatal(0, "cannot read configuration");
+ if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
/* Find out current queue/recent list */
queue_read();
recent_read();
trackdb_open(TRACKDB_NO_UPGRADE|TRACKDB_READ_ONLY);
global_tid = trackdb_begin_transaction();
if((err = trackdb_get_global_tid("required-tags", global_tid, &tags)))
- fatal(0, "error getting required-tags: %s", db_strerror(err));
+ disorder_fatal(0, "error getting required-tags: %s", db_strerror(err));
required_tags = parsetags(tags);
if((err = trackdb_get_global_tid("prohibited-tags", global_tid, &tags)))
- fatal(0, "error getting prohibited-tags: %s", db_strerror(err));
+ disorder_fatal(0, "error getting prohibited-tags: %s", db_strerror(err));
prohibited_tags = parsetags(tags);
if(trackdb_scan(0, collect_tracks_callback, 0, global_tid)) {
global_tid->abort(global_tid);
trackdb_deinit(NULL);
D(("ntracks=%ld total_weight=%lld", ntracks, total_weight));
if(!total_weight)
- fatal(0, "no tracks match random choice criteria");
+ disorder_fatal(0, "no tracks match random choice criteria");
if(!winning)
- fatal(0, "internal: failed to pick a track");
+ disorder_fatal(0, "internal: failed to pick a track");
/* Pick a track */
xprintf("%s", winning);
xfclose(stdout);
* /dev/null) */
do {
if((dn = open("/dev/null", O_RDWR, 0)) < 0)
- fatal(errno, "error opening /dev/null");
+ disorder_fatal(errno, "error opening /dev/null");
} while(dn < 3);
pid = xfork();
if(pid) {
exitfn = _exit;
while((r = waitpid(pid, &w, 0)) == -1 && errno == EINTR)
;
- if(r < 0) fatal(errno, "error calling waitpid");
- if(w) error(0, "subprocess exited with wait status %#x", (unsigned)w);
+ if(r < 0) disorder_fatal(errno, "error calling waitpid");
+ if(w)
+ disorder_error(0, "subprocess exited with wait status %#x", (unsigned)w);
_exit(0);
}
/* First child process. This will be the session leader, and will
* be transient. */
D(("first child pid=%lu", (unsigned long)getpid()));
- if(setsid() < 0) fatal(errno, "error calling setsid");
+ if(setsid() < 0)
+ disorder_fatal(errno, "error calling setsid");
/* we'll log to syslog */
openlog(tag, LOG_PID, fac);
log_default = &log_syslog;
if(!(fp = fopen(pidfile, "w"))
|| fprintf(fp, "%lu\n", (unsigned long)getpid()) < 0
|| fclose(fp) < 0)
- fatal(errno, "error creating %s", pidfile);
+ disorder_fatal(errno, "error creating %s", pidfile);
}
}
for(;;) {
DB_TXN *tid;
if(oldparams)
- info("database parameter string changed from %s to %s - removing old data",
+ disorder_info("database parameter string changed from %s to %s - removing old data",
oldparams, newparams);
else {
- info("new database parameter string %s - removing old data",
- newparams);
+ disorder_info("new database parameter string %s - removing old data",
+ newparams);
/* This is a slightly annoying case; the global pref wasn't present. In
* practice this is almost certainly either an upgrade (with no change to
* any relevant parameters) or a new installation (with no tracks).
switch(err) {
case 0:
trackdb_commit_transaction(tid);
- info("removed old data OK, will regenerate on rescan");
+ disorder_info("removed old data OK, will regenerate on rescan");
return;
case DB_LOCK_DEADLOCK:
/* Deadlocked, try again */
trackdb_abort_transaction(tid);
break;
default:
- fatal(0, "error updating database: %s", db_strerror(err));
+ disorder_fatal(0, "error updating database: %s", db_strerror(err));
}
}
}
/* We'll regenerate search.db based on the new set of stopwords */
if((err = trackdb_searchdb->truncate(trackdb_searchdb, tid, &count, 0))) {
- error(err, "truncating search.db: %s", db_strerror(err));
+ disorder_error(err, "truncating search.db: %s", db_strerror(err));
return err;
}
/* We'll regenerate aliases based on the new alias/namepart settings, so
cursor = trackdb_opencursor(trackdb_tracksdb, tid);
if((err = cursor->c_get(cursor, prepare_data(&k), prepare_data(&d),
DB_FIRST)) == DB_LOCK_DEADLOCK) {
- error(0, "cursor->c_get: %s", db_strerror(err));
+ disorder_error(0, "cursor->c_get: %s", db_strerror(err));
goto done;
}
while(err == 0) {
struct kvp *data = kvp_urldecode(d.data, d.size);
if(kvp_get(data, "_alias_for")) {
if((err = cursor->c_del(cursor, 0))) {
- error(0, "cursor->c_del: %s", db_strerror(err));
+ disorder_error(0, "cursor->c_del: %s", db_strerror(err));
goto done;
}
}
err = cursor->c_get(cursor, prepare_data(&k), prepare_data(&d), DB_NEXT);
}
if(err == DB_LOCK_DEADLOCK) {
- error(0, "cursor operation: %s", db_strerror(err));
+ disorder_error(0, "cursor operation: %s", db_strerror(err));
goto done;
}
if(err != DB_NOTFOUND)
- fatal(0, "cursor->c_get: %s", db_strerror(err));
+ disorder_fatal(0, "cursor->c_get: %s", db_strerror(err));
err = 0;
done:
if(trackdb_closecursor(cursor) && !err) err = DB_LOCK_DEADLOCK;
gcrypt_hash_handle h;
if((e = gcry_md_open(&h, GCRY_MD_SHA256, 0)))
- fatal(0, "gcry_md_open: %s", gcry_strerror(e));
+ disorder_fatal(0, "gcry_md_open: %s", gcry_strerror(e));
h_write_string(h, "alias");
h_write_string(h, config->alias);
for(int n = 0; n < config->stopword.n; ++n) {
break;
++count;
if(count % 1000 == 0)
- info("scanning %s, %ld so far", name, count);
+ disorder_info("scanning %s, %ld so far", name, count);
}
if(err && err != DB_NOTFOUND && err != DB_LOCK_DEADLOCK)
- fatal(0, "%s: error scanning database: %s", name, db_strerror(err));
+ disorder_fatal(0, "%s: error scanning database: %s", name, db_strerror(err));
r = (err == DB_LOCK_DEADLOCK ? err : 0);
if((err = c->c_close(c)))
- fatal(0, "%s: error closing cursor: %s", name, db_strerror(err));
- info("%s: %ld entries scanned", name, count);
+ disorder_fatal(0, "%s: error closing cursor: %s", name, db_strerror(err));
+ disorder_info("%s: %ld entries scanned", name, count);
if(values_normalized || values_already_ok)
- info("%s: %ld values converted, %ld already ok", name,
- values_normalized, values_already_ok);
+ disorder_info("%s: %ld values converted, %ld already ok", name,
+ values_normalized, values_already_ok);
if(keys_normalized || keys_already_ok)
- info("%s: %ld keys converted, %ld already OK", name,
- keys_normalized, keys_already_ok);
+ disorder_info("%s: %ld keys converted, %ld already OK", name,
+ keys_normalized, keys_already_ok);
if(aliases_removed)
- info("%s: %ld aliases removed", name, aliases_removed);
+ disorder_info("%s: %ld aliases removed", name, aliases_removed);
if(renoticed)
- info("%s: %ld tracks re-noticed", name, renoticed);
+ disorder_info("%s: %ld tracks re-noticed", name, renoticed);
return r;
}
static void scandb(const char *name, DB *db,
int (*callback)(const char *name, DB *db, DBC *c,
DBT *k, DBT *d)) {
- info("scanning %s", name);
+ disorder_info("scanning %s", name);
for(;;) {
global_tid = trackdb_begin_transaction();
if(scan_core(name, db, callback)) {
trackdb_abort_transaction(global_tid);
global_tid = 0;
- error(0, "detected deadlock, restarting scan");
+ disorder_error(0, "detected deadlock, restarting scan");
continue;
} else {
trackdb_commit_transaction(global_tid);
err = db->truncate(db, 0, &count, DB_AUTO_COMMIT);
} while(err == DB_LOCK_DEADLOCK);
if(err)
- fatal(0, "error truncating %s: %s", name, db_strerror(err));
+ disorder_fatal(0, "error truncating %s: %s", name, db_strerror(err));
}
/* scan callbacks */
if(!knfc) {
switch(badkey) {
case BADKEY_WARN:
- error(0, "%s: invalid key: %.*s", name,
- (int)k->size, (const char *)k->data);
+ disorder_error(0, "%s: invalid key: %.*s", name,
+ (int)k->size, (const char *)k->data);
break;
case BADKEY_DELETE:
- error(0, "%s: deleting invalid key: %.*s", name,
- (int)k->size, (const char *)k->data);
+ disorder_error(0, "%s: deleting invalid key: %.*s", name,
+ (int)k->size, (const char *)k->data);
if((err = c->c_del(c, 0))) {
if(err != DB_LOCK_DEADLOCK)
- fatal(0, "%s: error removing denormalized key: %s",
- name, db_strerror(err));
+ disorder_fatal(0, "%s: error removing denormalized key: %s",
+ name, db_strerror(err));
return err;
}
break;
case BADKEY_FAIL:
- fatal(0, "%s: invalid key: %.*s", name,
- (int)k->size, (const char *)k->data);
+ disorder_fatal(0, "%s: invalid key: %.*s", name,
+ (int)k->size, (const char *)k->data);
}
return 0;
}
/* To rename the key we must delete the old one and insert a new one */
if((err = c->c_del(c, 0))) {
if(err != DB_LOCK_DEADLOCK)
- fatal(0, "%s: error removing denormalized key: %s",
- name, db_strerror(err));
+ disorder_fatal(0, "%s: error removing denormalized key: %s",
+ name, db_strerror(err));
return err;
}
k->size = nknfc;
k->data = knfc;
if((err = db->put(db, global_tid, k, d, DB_NOOVERWRITE))) {
if(err != DB_LOCK_DEADLOCK)
- fatal(0, "%s: error storing normalized key: %s", name, db_strerror(err));
+ disorder_fatal(0, "%s: error storing normalized key: %s",
+ name, db_strerror(err));
return err;
}
++keys_normalized;
/* Find the normalized form of the value */
dnfc = utf8_compose_canon(d->data, d->size, &ndnfc);
if(!dnfc)
- fatal(0, "%s: cannot convert data to NFC: %.*s", name,
- (int)d->size, (const char *)d->data);
+ disorder_fatal(0, "%s: cannot convert data to NFC: %.*s", name,
+ (int)d->size, (const char *)d->data);
/* If the key is already in NFC then do nothing */
if(ndnfc == d->size && !memcmp(d->data, dnfc, ndnfc)) {
++values_already_ok;
d->data = dnfc;
if((err = db->put(db, global_tid, k, d, 0))) {
if(err != DB_LOCK_DEADLOCK)
- fatal(0, "%s: error storing normalized data: %s", name, db_strerror(err));
+ disorder_fatal(0, "%s: error storing normalized data: %s",
+ name, db_strerror(err));
return err;
}
++values_normalized;
* in the scan. */
if(kvp_get(t, "_alias_for"))
return 0;
- fatal(0, "%s: no '_path' for %.*s", name,
- (int)k->size, (const char *)k->data);
+ disorder_fatal(0, "%s: no '_path' for %.*s", name,
+ (int)k->size, (const char *)k->data);
}
switch(err = trackdb_notice_tid(track, path, global_tid)) {
case 0:
case DB_LOCK_DEADLOCK:
return err;
default:
- fatal(0, "%s: unexpected return from trackdb_notice_tid: %s",
- name, db_strerror(err));
+ disorder_fatal(0, "%s: unexpected return from trackdb_notice_tid: %s",
+ name, db_strerror(err));
}
}
/* This is an alias. We remove all the alias entries. */
if((err = c->c_del(c, 0))) {
if(err != DB_LOCK_DEADLOCK)
- fatal(0, "%s: error removing alias: %s", name, db_strerror(err));
+ disorder_fatal(0, "%s: error removing alias: %s", name, db_strerror(err));
return err;
}
++aliases_removed;
return 0;
} else if(!kvp_get(t, "_path"))
- error(0, "%s: %.*s has neither _alias_for nor _path", name,
- (int)k->size, (const char *)k->data);
+ disorder_error(0, "%s: %.*s has neither _alias_for nor _path", name,
+ (int)k->size, (const char *)k->data);
return normalize_keys(name, db, c, k, d);
}
static void upgrade(void) {
char buf[32];
- info("upgrading database to dbversion %ld", config->dbversion);
+ disorder_info("upgrading database to dbversion %ld", config->dbversion);
/* Normalize keys and values as required. We will also remove aliases as
* they will be regenerated when we re-noticed the tracks. */
- info("renormalizing keys");
+ disorder_info("renormalizing keys");
scandb("tracks.db", trackdb_tracksdb, remove_aliases_normalize_keys);
scandb("prefs.db", trackdb_prefsdb, normalize_keys);
scandb("global.db", trackdb_globaldb, normalize_keys);
scandb("noticed.db", trackdb_noticeddb, normalize_values);
/* search.db and tags.db we will rebuild */
- info("regenerating search database and aliases");
+ disorder_info("regenerating search database and aliases");
truncate_database("search.db", trackdb_searchdb);
truncate_database("tags.db", trackdb_tagsdb);
/* Regenerate the search database and aliases */
/* Finally update the database version */
snprintf(buf, sizeof buf, "%ld", config->dbversion);
trackdb_set_global("_dbversion", buf, 0);
- info("completed database upgrade");
+ disorder_info("completed database upgrade");
}
int main(int argc, char **argv) {
set_progname(argv);
mem_init();
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVc:dDSsxX", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 's': logsyslog = 1; break;
case 'x': badkey = BADKEY_DELETE; break;
case 'X': badkey = BADKEY_FAIL; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
/* If stderr is a TTY then log there, otherwise to syslog. */
openlog(progname, LOG_PID, LOG_DAEMON);
log_default = &log_syslog;
}
- if(config_read(0, NULL)) fatal(0, "cannot read configuration");
+ if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
/* Open the database */
trackdb_init(TRACKDB_NO_RECOVER);
trackdb_open(TRACKDB_OPEN_FOR_UPGRADE);
int n, err, aborted, logsyslog = !isatty(2);
set_progname(argv);
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVc:dDSs", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'D': debugging = 0; break;
case 'S': logsyslog = 0; break;
case 's': logsyslog = 1; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if(logsyslog) {
openlog(progname, LOG_PID, LOG_DAEMON);
log_default = &log_syslog;
}
- if(config_read(0, NULL)) fatal(0, "cannot read configuration");
- info("started");
+ if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
+ disorder_info("started");
trackdb_init(TRACKDB_NO_RECOVER);
while(getppid() != 1) {
if((err = trackdb_env->lock_detect(trackdb_env,
0,
DB_LOCK_DEFAULT,
&aborted)))
- fatal(0, "trackdb_env->lock_detect: %s", db_strerror(err));
+ disorder_fatal(0, "trackdb_env->lock_detect: %s", db_strerror(err));
if(aborted)
D(("aborted %d lock requests", aborted));
sleep(1);
}
/* if our parent goes away, it's time to stop */
- info("stopped (parent terminated)");
+ disorder_info("stopped (parent terminated)");
return 0;
}
/** @brief Write an 8-bit word */
static inline void output_8(int n) {
if(putc(n, outputfp) < 0)
- fatal(errno, "decoding %s: output error", path);
+ disorder_fatal(errno, "decoding %s: output error", path);
}
/** @brief Write a 16-bit word in bigendian format */
static inline void output_16(uint16_t n) {
if(putc(n >> 8, outputfp) < 0
|| putc(n, outputfp) < 0)
- fatal(errno, "decoding %s: output error", path);
+ disorder_fatal(errno, "decoding %s: output error", path);
}
/** @brief Write a 24-bit word in bigendian format */
if(putc(n >> 16, outputfp) < 0
|| putc(n >> 8, outputfp) < 0
|| putc(n, outputfp) < 0)
- fatal(errno, "decoding %s: output error", path);
+ disorder_fatal(errno, "decoding %s: output error", path);
}
/** @brief Write a 32-bit word in bigendian format */
|| putc(n >> 16, outputfp) < 0
|| putc(n >> 8, outputfp) < 0
|| putc(n, outputfp) < 0)
- fatal(errno, "decoding %s: output error", path);
+ disorder_fatal(errno, "decoding %s: output error", path);
}
/** @brief Write a block header
* @param endian @ref ENDIAN_BIG or @ref ENDIAN_LITTLE
*
* Checks that the sample format is a supported one (so other calls do not have
- * to) and calls fatal() on error.
+ * to) and calls disorder_fatal() on error.
*/
static void output_header(int rate,
int channels,
struct stream_header header;
if(bits <= 0 || bits % 8 || bits > 64)
- fatal(0, "decoding %s: unsupported sample size %d bits", path, bits);
+ disorder_fatal(0, "decoding %s: unsupported sample size %d bits",
+ path, bits);
if(channels <= 0 || channels > 2)
- fatal(0, "decoding %s: unsupported channel count %d", path, channels);
+ disorder_fatal(0, "decoding %s: unsupported channel count %d",
+ path, channels);
if(rate <= 0)
- fatal(0, "decoding %s: nonsensical sample rate %dHz", path, rate);
+ disorder_fatal(0, "decoding %s: nonsensical sample rate %dHz", path, rate);
header.rate = rate;
header.bits = bits;
header.channels = channels;
header.endian = endian;
header.nbytes = nbytes;
if(fwrite(&header, sizeof header, 1, outputfp) < 1)
- fatal(errno, "decoding %s: writing format header", path);
+ disorder_fatal(errno, "decoding %s: writing format header", path);
}
/** @brief Dithering state
/* Read new data */
n = read(inputfd, input_buffer + remain, (sizeof input_buffer) - remain);
if(n < 0)
- fatal(errno, "reading from %s", path);
+ disorder_fatal(errno, "reading from %s", path);
/* Compute total number of bytes available */
input_count = remain + n;
if(input_count)
struct mad_frame attribute((unused)) *frame) {
if(0)
/* Just generates pointless verbosity l-( */
- error(0, "decoding %s: %s (%#04x)",
- path, mad_stream_errorstr(stream), stream->error);
+ disorder_error(0, "decoding %s: %s (%#04x)",
+ path, mad_stream_errorstr(stream), stream->error);
return MAD_FLOW_CONTINUE;
}
struct mad_decoder mad[1];
if((inputfd = open(path, O_RDONLY)) < 0)
- fatal(errno, "opening %s", path);
+ disorder_fatal(errno, "opening %s", path);
mad_decoder_init(mad, 0/*data*/, mp3_input, 0/*header*/, 0/*filter*/,
mp3_output, mp3_error, 0/*message*/);
if(mad_decoder_run(mad, MAD_DECODER_MODE_SYNC))
vorbis_info *vi;
if(!(fp = fopen(path, "rb")))
- fatal(errno, "cannot open %s", path);
+ disorder_fatal(errno, "cannot open %s", path);
/* There doesn't seem to be any standard function for mapping the error codes
* to strings l-( */
if((err = ov_open(fp, vf, 0/*initial*/, 0/*ibytes*/)))
- fatal(0, "ov_fopen %s: %d", path, err);
+ disorder_fatal(0, "ov_fopen %s: %d", path, err);
if(!(vi = ov_info(vf, 0/*link*/)))
- fatal(0, "ov_info %s: failed", path);
+ disorder_fatal(0, "ov_info %s: failed", path);
while((n = ov_read(vf, input_buffer, sizeof input_buffer, 1/*bigendianp*/,
2/*bytes/word*/, 1/*signed*/, &bitstream))) {
if(n < 0)
- fatal(0, "ov_read %s: %ld", path, n);
+ disorder_fatal(0, "ov_read %s: %ld", path, n);
if(bitstream > 0)
- fatal(0, "only single-bitstream ogg files are supported");
+ disorder_fatal(0, "only single-bitstream ogg files are supported");
output_header(vi->rate, vi->channels, 16/*bits*/, n, ENDIAN_BIG);
if(fwrite(input_buffer, 1, n, outputfp) < (size_t)n)
- fatal(errno, "decoding %s: writing sample data", path);
+ disorder_fatal(errno, "decoding %s: writing sample data", path);
}
}
size_t nbytes,
void attribute((unused)) *u) {
if(fwrite(data, 1, nbytes, outputfp) < nbytes)
- fatal(errno, "decoding %s: writing sample data", path);
+ disorder_fatal(errno, "decoding %s: writing sample data", path);
return 0;
}
int err;
if((err = wav_init(f, path)))
- fatal(err, "opening %s", path);
+ disorder_fatal(err, "opening %s", path);
output_header(f->rate, f->channels, f->bits, f->datasize, ENDIAN_LITTLE);
if((err = wav_data(f, wav_write, 0)))
- fatal(err, "error decoding %s", path);
+ disorder_fatal(err, "error decoding %s", path);
}
/** @brief Metadata callback for FLAC decoder
static void flac_error(const FLAC__FileDecoder attribute((unused)) *decoder,
FLAC__StreamDecoderErrorStatus status,
void attribute((unused)) *client_data) {
- fatal(0, "error decoding %s: %s", path,
- FLAC__StreamDecoderErrorStatusString[status]);
+ disorder_fatal(0, "error decoding %s: %s", path,
+ FLAC__StreamDecoderErrorStatusString[status]);
}
/** @brief Write callback for FLAC decoder */
FLAC__FileDecoderState fs;
if(!(fd = FLAC__file_decoder_new()))
- fatal(0, "FLAC__file_decoder_new failed");
+ disorder_fatal(0, "FLAC__file_decoder_new failed");
if(!(FLAC__file_decoder_set_filename(fd, path)))
- fatal(0, "FLAC__file_set_filename failed");
+ disorder_fatal(0, "FLAC__file_set_filename failed");
FLAC__file_decoder_set_metadata_callback(fd, flac_metadata);
FLAC__file_decoder_set_error_callback(fd, flac_error);
FLAC__file_decoder_set_write_callback(fd, flac_write);
if((fs = FLAC__file_decoder_init(fd)))
- fatal(0, "FLAC__file_decoder_init: %s", FLAC__FileDecoderStateString[fs]);
+ disorder_fatal(0, "FLAC__file_decoder_init: %s", FLAC__FileDecoderStateString[fs]);
FLAC__file_decoder_process_until_end_of_file(fd);
#else
FLAC__StreamDecoder *sd = FLAC__stream_decoder_new();
FLAC__StreamDecoderInitStatus is;
if (!sd)
- fatal(0, "FLAC__stream_decoder_new failed");
+ disorder_fatal(0, "FLAC__stream_decoder_new failed");
if((is = FLAC__stream_decoder_init_file(sd, path, flac_write, flac_metadata,
flac_error, 0)))
- fatal(0, "FLAC__stream_decoder_init_file %s: %s",
- path, FLAC__StreamDecoderInitStatusString[is]);
+ disorder_fatal(0, "FLAC__stream_decoder_init_file %s: %s",
+ path, FLAC__StreamDecoderInitStatusString[is]);
FLAC__stream_decoder_process_until_end_of_stream(sd);
FLAC__stream_decoder_finish(sd);
const char *e;
set_progname(argv);
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "calling setlocale");
while((n = getopt_long(argc, argv, "hV", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'V': version("disorder-decode");
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if(optind >= argc)
- fatal(0, "missing filename");
+ disorder_fatal(0, "missing filename");
if(optind + 1 < argc)
- fatal(0, "excess arguments");
+ disorder_fatal(0, "excess arguments");
if((e = getenv("DISORDER_RAW_FD"))) {
if(!(outputfp = fdopen(atoi(e), "wb")))
- fatal(errno, "fdopen");
+ disorder_fatal(errno, "fdopen");
} else
outputfp = stdout;
path = argv[optind];
++n)
;
if(!decoders[n].pattern)
- fatal(0, "cannot determine file type for %s", path);
+ disorder_fatal(0, "cannot determine file type for %s", path);
decoders[n].decode();
xfclose(outputfp);
return 0;
static int handle_sighup(ev_source attribute((unused)) *ev_,
int attribute((unused)) sig,
void attribute((unused)) *u) {
- info("received SIGHUP");
+ disorder_info("received SIGHUP");
reconfigure(ev, RECONFIGURE_RELOADING);
return 0;
}
static int handle_sigint(ev_source attribute((unused)) *ev_,
int attribute((unused)) sig,
void attribute((unused)) *u) {
- info("received SIGINT");
+ disorder_info("received SIGINT");
quit(ev);
}
static int handle_sigterm(ev_source attribute((unused)) *ev_,
int attribute((unused)) sig,
void attribute((unused)) *u) {
- info("received SIGTERM");
+ disorder_info("received SIGTERM");
quit(ev);
}
/* static or libgc collects it! */
if(!path)
- error(0, "PATH is not set at all!");
+ disorder_error(0, "PATH is not set at all!");
if(*finkbindir && strcmp(finkbindir, "/"))
/* We appear to be a finkized mac; include fink on the path in case the
else
byte_xasprintf(&newpath, "PATH=%s:%s:%s", path, bindir, sbindir);
putenv(newpath);
- info("%s", newpath);
+ disorder_info("%s", newpath);
}
int main(int argc, char **argv) {
set_progname(argv);
mem_init();
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, ""))
+ disorder_fatal(errno, "error calling setlocale");
/* garbage-collect PCRE's memory */
pcre_malloc = xmalloc;
pcre_free = xfree;
case 'P': pidfile = optarg; break;
case 's': logsyslog = 1; break;
case 'w': wideopen = 1; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
/* go into background if necessary */
openlog(progname, LOG_PID, LOG_DAEMON);
log_default = &log_syslog;
}
- info("process ID %lu", (unsigned long)getpid());
+ disorder_info("process ID %lu", (unsigned long)getpid());
fix_path();
srand(xtime(0)); /* don't start the same every time */
/* gcrypt initialization */
/* make sure we can't have more than FD_SETSIZE files open (event.c does
* check but this provides an additional line of defence) */
if(getrlimit(RLIMIT_NOFILE, rl) < 0)
- fatal(errno, "getrlimit RLIMIT_NOFILE");
+ disorder_fatal(errno, "getrlimit RLIMIT_NOFILE");
if(rl->rlim_cur > FD_SETSIZE) {
rl->rlim_cur = FD_SETSIZE;
if(setrlimit(RLIMIT_NOFILE, rl) < 0)
- fatal(errno, "setrlimit to reduce RLIMIT_NOFILE to %lu",
- (unsigned long)rl->rlim_cur);
- info("set RLIM_NOFILE to %lu", (unsigned long)rl->rlim_cur);
+ disorder_fatal(errno, "setrlimit to reduce RLIMIT_NOFILE to %lu",
+ (unsigned long)rl->rlim_cur);
+ disorder_info("set RLIM_NOFILE to %lu", (unsigned long)rl->rlim_cur);
} else
- info("RLIM_NOFILE is %lu", (unsigned long)rl->rlim_cur);
+ disorder_info("RLIM_NOFILE is %lu", (unsigned long)rl->rlim_cur);
/* create event loop */
ev = ev_new();
- if(ev_child_setup(ev)) fatal(0, "ev_child_setup failed");
+ if(ev_child_setup(ev)) disorder_fatal(0, "ev_child_setup failed");
/* read config */
config_uaudio_apis = uaudio_apis;
if(config_read(1, NULL))
- fatal(0, "cannot read configuration");
+ disorder_fatal(0, "cannot read configuration");
/* make sure the home directory exists and has suitable permissions */
make_home();
/* Start the speaker process (as root! - so it can choose its nice value) */
/* change user */
become_mortal();
/* make sure we're not root, whatever the config says */
- if(getuid() == 0 || geteuid() == 0) fatal(0, "do not run as root");
+ if(getuid() == 0 || geteuid() == 0)
+ disorder_fatal(0, "do not run as root");
/* open a lockfile - we only want one copy of the server to run at once. */
if(1) {
const char *lockfile;
lockfile = config_get_file("lock");
if((lockfd = open(lockfile, O_RDWR|O_CREAT, 0600)) < 0)
- fatal(errno, "error opening %s", lockfile);
+ disorder_fatal(errno, "error opening %s", lockfile);
cloexec(lockfd);
memset(&lock, 0, sizeof lock);
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
if(fcntl(lockfd, F_SETLK, &lock) < 0)
- fatal(errno, "error locking %s", lockfile);
+ disorder_fatal(errno, "error locking %s", lockfile);
}
/* initialize database environment */
trackdb_init(TRACKDB_NORMAL_RECOVER|TRACKDB_MAY_CREATE);
trackdb_master(ev);
/* install new config; don't create socket */
if(reconfigure(ev, RECONFIGURE_FIRST))
- fatal(0, "failed to read configuration");
+ disorder_fatal(0, "failed to read configuration");
/* Open the database */
trackdb_open(TRACKDB_CAN_UPGRADE);
/* load the queue and recently-played list */
/* check for change to database parameters */
dbparams_check();
/* re-read config if we receive a SIGHUP */
- if(ev_signal(ev, SIGHUP, handle_sighup, 0)) fatal(0, "ev_signal failed");
+ if(ev_signal(ev, SIGHUP, handle_sighup, 0))
+ disorder_fatal(0, "ev_signal failed");
/* exit on SIGINT/SIGTERM */
- if(ev_signal(ev, SIGINT, handle_sigint, 0)) fatal(0, "ev_signal failed");
- if(ev_signal(ev, SIGTERM, handle_sigterm, 0)) fatal(0, "ev_signal failed");
+ if(ev_signal(ev, SIGINT, handle_sigint, 0))
+ disorder_fatal(0, "ev_signal failed");
+ if(ev_signal(ev, SIGTERM, handle_sigterm, 0))
+ disorder_fatal(0, "ev_signal failed");
/* ignore SIGPIPE */
signal(SIGPIPE, SIG_IGN);
/* Rescan immediately and then daily */
/* enter the event loop */
n = ev_run(ev);
/* if we exit the event loop, something must have gone wrong */
- fatal(errno, "ev_run returned %d", n);
+ disorder_fatal(errno, "ev_run returned %d", n);
}
/*
|| sink_writec(s, '\n') < 0
|| urlencode(s, d.data, d.size)
|| sink_writec(s, '\n') < 0)
- fatal(errno, "error writing to %s", tag);
+ disorder_fatal(errno, "error writing to %s", tag);
err = cursor->c_get(cursor, prepare_data(&k), prepare_data(&d),
DB_NEXT);
}
case 0:
assert(!"cannot happen");
default:
- fatal(0, "error reading %s: %s", dbname, db_strerror(err));
+ disorder_fatal(0, "error reading %s: %s", dbname, db_strerror(err));
}
}
for(;;) {
tid = trackdb_begin_transaction();
if(fseek(fp, 0, SEEK_SET) < 0)
- fatal(errno, "error calling fseek");
+ disorder_fatal(errno, "error calling fseek");
if(fflush(fp) < 0)
- fatal(errno, "error calling fflush");
+ disorder_fatal(errno, "error calling fflush");
if(ftruncate(fileno(fp), 0) < 0)
- fatal(errno, "error calling ftruncate");
+ disorder_fatal(errno, "error calling ftruncate");
if(fprintf(fp, "V0") < 0)
- fatal(errno, "error writing to %s", tag);
+ disorder_fatal(errno, "error writing to %s", tag);
for(size_t n = 0; n < NDBTABLE; ++n)
if(dump_one(s, tag,
dbtable[n].letter, dbtable[n].dbname, *dbtable[n].db,
goto fail;
if(fputs("E\n", fp) < 0)
- fatal(errno, "error writing to %s", tag);
+ disorder_fatal(errno, "error writing to %s", tag);
break;
fail:
- info("aborting transaction and retrying dump");
+ disorder_info("aborting transaction and retrying dump");
trackdb_abort_transaction(tid);
}
trackdb_commit_transaction(tid);
- if(fflush(fp) < 0) fatal(errno, "error writing to %s", tag);
+ if(fflush(fp) < 0) disorder_fatal(errno, "error writing to %s", tag);
/* caller might not be paranoid so we are paranoid on their behalf */
- if(fsync(fileno(fp)) < 0) fatal(errno, "error syncing %s", tag);
+ if(fsync(fileno(fp)) < 0) disorder_fatal(errno, "error syncing %s", tag);
}
/* delete all aliases prefs, return 0 or DB_LOCK_DEADLOCK */
struct kvp *data;
int alias, pathless;
- info("removing aliases");
+ disorder_info("removing aliases");
cursor = trackdb_opencursor(trackdb_tracksdb, tid);
if((err = cursor->c_get(cursor, prepare_data(&k), prepare_data(&d),
DB_FIRST)) == DB_LOCK_DEADLOCK) {
- error(0, "cursor->c_get: %s", db_strerror(err));
+ disorder_error(0, "cursor->c_get: %s", db_strerror(err));
goto done;
}
while(err == 0) {
alias = !!kvp_get(data, "_alias_for");
pathless = !kvp_get(data, "_path");
if(pathless && !remove_pathless)
- info("no _path for %s", utf82mb(xstrndup(k.data, k.size)));
+ disorder_info("no _path for %s", utf82mb(xstrndup(k.data, k.size)));
if(alias || (remove_pathless && pathless)) {
switch(err = cursor->c_del(cursor, 0)) {
case 0: break;
case DB_LOCK_DEADLOCK:
- error(0, "cursor->c_get: %s", db_strerror(err));
+ disorder_error(0, "cursor->c_get: %s", db_strerror(err));
goto done;
default:
- fatal(0, "cursor->c_del: %s", db_strerror(err));
+ disorder_fatal(0, "cursor->c_del: %s", db_strerror(err));
}
}
err = cursor->c_get(cursor, prepare_data(&k), prepare_data(&d), DB_NEXT);
}
if(err == DB_LOCK_DEADLOCK) {
- error(0, "cursor operation: %s", db_strerror(err));
+ disorder_error(0, "cursor operation: %s", db_strerror(err));
goto done;
}
- if(err != DB_NOTFOUND) fatal(0, "cursor->c_get: %s", db_strerror(err));
+ if(err != DB_NOTFOUND)
+ disorder_fatal(0, "cursor->c_get: %s", db_strerror(err));
err = 0;
done:
if(trackdb_closecursor(cursor) && !err) err = DB_LOCK_DEADLOCK;
switch(err = db->truncate(db, tid, &count, 0)) {
case 0: break;
case DB_LOCK_DEADLOCK:
- error(0, "db->truncate: %s", db_strerror(err));
+ disorder_error(0, "db->truncate: %s", db_strerror(err));
break;
default:
- fatal(0, "db->truncate: %s", db_strerror(err));
+ disorder_fatal(0, "db->truncate: %s", db_strerror(err));
}
return err;
}
if(inputline(tag, fp, &s, '\n')) return -1;
dynstr_init(&d);
if(urldecode(sink_dynstr(&d), s, strlen(s)))
- fatal(0, "invalid URL-encoded data in %s", tag);
+ disorder_fatal(0, "invalid URL-encoded data in %s", tag);
dbt->data = d.vec;
dbt->size = d.nvec;
return 0;
static int undump_from_fp(DB_TXN *tid, FILE *fp, const char *tag) {
int err, c;
- info("undumping");
+ disorder_info("undumping");
if(fseek(fp, 0, SEEK_SET) < 0)
- fatal(errno, "error calling fseek on %s", tag);
+ disorder_fatal(errno, "error calling fseek on %s", tag);
if((err = truncdb(tid, trackdb_prefsdb))) return err;
if((err = truncdb(tid, trackdb_globaldb))) return err;
if((err = truncdb(tid, trackdb_searchdb))) return err;
case 0:
break;
case DB_LOCK_DEADLOCK:
- error(0, "error updating %s: %s", dbname, db_strerror(err));
+ disorder_error(0, "error updating %s: %s", dbname, db_strerror(err));
return err;
default:
- fatal(0, "error updating %s: %s", dbname, db_strerror(err));
+ disorder_fatal(0, "error updating %s: %s", dbname, db_strerror(err));
}
goto next;
}
case 'V':
c = getc(fp);
if(c != '0')
- fatal(0, "unknown version '%c'", c);
+ disorder_fatal(0, "unknown version '%c'", c);
break;
case 'E':
return 0;
break;
default:
if(c >= 32 && c <= 126)
- fatal(0, "unexpected character '%c'", c);
+ disorder_fatal(0, "unexpected character '%c'", c);
else
- fatal(0, "unexpected character 0x%02X", c);
+ disorder_fatal(0, "unexpected character 0x%02X", c);
}
next:
c = getc(fp);
}
if(ferror(fp))
- fatal(errno, "error reading %s", tag);
+ disorder_fatal(errno, "error reading %s", tag);
else
- fatal(0, "unexpected EOF reading %s", tag);
+ disorder_fatal(0, "unexpected EOF reading %s", tag);
return 0;
}
struct kvp *data;
const char *path, *track;
- info("recomputing aliases");
+ disorder_info("recomputing aliases");
cursor = trackdb_opencursor(trackdb_tracksdb, tid);
if((err = cursor->c_get(cursor, prepare_data(&k), prepare_data(&d),
DB_FIRST)) == DB_LOCK_DEADLOCK) goto done;
track = xstrndup(k.data, k.size);
if(!kvp_get(data, "_alias_for")) {
if(!(path = kvp_get(data, "_path")))
- error(0, "%s is not an alias but has no path", utf82mb(track));
+ disorder_error(0, "%s is not an alias but has no path", utf82mb(track));
else
if((err = trackdb_notice_tid(track, path, tid)) == DB_LOCK_DEADLOCK)
goto done;
case DB_LOCK_DEADLOCK:
break;
default:
- fatal(0, "cursor->c_get: %s", db_strerror(err));
+ disorder_fatal(0, "cursor->c_get: %s", db_strerror(err));
}
done:
if(trackdb_closecursor(cursor) && !err) err = DB_LOCK_DEADLOCK;
|| recompute_aliases(tid)) goto fail;
break;
fail:
- info("aborting transaction and retrying undump");
+ disorder_info("aborting transaction and retrying undump");
trackdb_abort_transaction(tid);
}
- info("committing undump");
+ disorder_info("committing undump");
trackdb_commit_transaction(tid);
}
|| recompute_aliases(tid)) goto fail;
break;
fail:
- info("aborting transaction and retrying recomputation");
+ disorder_info("aborting transaction and retrying recomputation");
trackdb_abort_transaction(tid);
}
- info("committing recomputed aliases");
+ disorder_info("committing recomputed aliases");
trackdb_commit_transaction(tid);
}
case 'R': recover = TRACKDB_FATAL_RECOVER;
case 'a': recompute = 1; break;
case 'P': remove_pathless = 1; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if(dump + undump + recompute != 1)
- fatal(0, "choose exactly one of --dump, --undump or --recompute-aliases");
+ disorder_fatal(0, "choose exactly one of --dump, --undump or --recompute-aliases");
if(recompute) {
if(optind != argc)
- fatal(0, "--recompute-aliases does not take a filename");
+ disorder_fatal(0, "--recompute-aliases does not take a filename");
path = 0;
} else {
if(optind >= argc)
- fatal(0, "missing dump file name");
+ disorder_fatal(0, "missing dump file name");
if(optind + 1 < argc)
- fatal(0, "specify only a dump file name");
+ disorder_fatal(0, "specify only a dump file name");
path = argv[optind];
}
- if(config_read(0, NULL)) fatal(0, "cannot read configuration");
+ if(config_read(0, NULL))
+ disorder_fatal(0, "cannot read configuration");
trackdb_init(recover|TRACKDB_MAY_CREATE);
trackdb_open(TRACKDB_NO_UPGRADE);
if(dump) {
* sure the permissions are tight from the start. */
byte_xasprintf(&tmp, "%s.%lx.tmp", path, (unsigned long)getpid());
if((fd = open(tmp, O_CREAT|O_TRUNC|O_WRONLY, 0600)) < 0)
- fatal(errno, "error opening %s", tmp);
+ disorder_fatal(errno, "error opening %s", tmp);
if(!(fp = fdopen(fd, "w")))
- fatal(errno, "fdopen on %s", tmp);
+ disorder_fatal(errno, "fdopen on %s", tmp);
do_dump(fp, tmp);
- if(fclose(fp) < 0) fatal(errno, "error closing %s", tmp);
+ if(fclose(fp) < 0) disorder_fatal(errno, "error closing %s", tmp);
if(rename(tmp, path) < 0)
- fatal(errno, "error renaming %s to %s", tmp, path);
+ disorder_fatal(errno, "error renaming %s to %s", tmp, path);
} else if(undump) {
/* the databases or logfiles might end up with wrong permissions
* if new ones are created */
- if(getuid() == 0) info("you might need to chown database files");
- if(!(fp = fopen(path, "r"))) fatal(errno, "error opening %s", path);
+ if(getuid() == 0)
+ disorder_info("you might need to chown database files");
+ if(!(fp = fopen(path, "r")))
+ disorder_fatal(errno, "error opening %s", path);
do_undump(fp, path, remove_pathless);
xfclose(fp);
} else if(recompute) {
if(errno == EINTR)
continue;
else
- fatal(errno, "read error");
+ disorder_fatal(errno, "read error");
}
if(readden == 0)
- fatal(0, "unexpected EOF");
+ disorder_fatal(0, "unexpected EOF");
n -= readden;
written = 0;
while(written < readden) {
const ssize_t w = write(outfd, buffer + written, readden - written);
if(w < 0)
- fatal(errno, "write error");
+ disorder_fatal(errno, "write error");
written += w;
}
}
case 16: *(*pp)++ = "-w"; break;
case 32: *(*pp)++ = "-l"; break;
case 64: *(*pp)++ = "-d"; break;
- default: fatal(0, "cannot handle sample size %d", header->bits);
+ default: disorder_fatal(0, "cannot handle sample size %d", header->bits);
}
break;
case 1:
case ENDIAN_LITTLE: *(*pp)++ = "-L"; break;
}
if(header->bits % 8)
- fatal(0, "cannot handle sample size %d", header->bits);
+ disorder_fatal(0, "cannot handle sample size %d", header->bits);
*qq += sprintf((char *)(*(*pp)++ = *qq), "-%d", header->bits / 8) + 1;
break;
default:
- fatal(0, "unknown sox_generation %ld", config->sox_generation);
+ disorder_fatal(0, "unknown sox_generation %ld", config->sox_generation);
}
}
set_progname(argv);
if(!setlocale(LC_CTYPE, ""))
- fatal(errno, "error calling setlocale");
+ disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVc:dDSs", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'D': debugging = 0; break;
case 'S': logsyslog = 0; break;
case 's': logsyslog = 1; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if(config_read(1, NULL))
- fatal(0, "cannot read configuration");
+ disorder_fatal(0, "cannot read configuration");
if(logsyslog) {
openlog(progname, LOG_PID, LOG_DAEMON);
log_default = &log_syslog;
if(r < 0) {
if(errno != EINTR)
- fatal(errno, "error reading header");
+ disorder_fatal(errno, "error reading header");
} else if(r == 0) {
if(n)
- fatal(0, "EOF reading header");
+ disorder_fatal(0, "EOF reading header");
break;
} else
n += r;
break;
/* Sanity check the header */
if(header.rate < 100 || header.rate > 1000000)
- fatal(0, "implausible rate %"PRId32"Hz (%#"PRIx32")",
- header.rate, header.rate);
+ disorder_fatal(0, "implausible rate %"PRId32"Hz (%#"PRIx32")",
+ header.rate, header.rate);
if(header.channels < 1 || header.channels > 2)
- fatal(0, "unsupported channel count %d", header.channels);
+ disorder_fatal(0, "unsupported channel count %d", header.channels);
if(header.bits % 8 || !header.bits || header.bits > 64)
- fatal(0, "unsupported sample size %d bits", header.bits);
+ disorder_fatal(0, "unsupported sample size %d bits", header.bits);
if(header.endian != ENDIAN_BIG && header.endian != ENDIAN_LITTLE)
- fatal(0, "unsupported byte order %x", header.bits);
+ disorder_fatal(0, "unsupported byte order %x", header.bits);
/* Skip empty chunks regardless of their alleged format */
if(header.nbytes == 0)
continue;
/* There's a running converter, stop it */
xclose(outfd);
if(waitpid(pid, &n, 0) < 0)
- fatal(errno, "error calling waitpid");
+ disorder_fatal(errno, "error calling waitpid");
if(n)
- fatal(0, "sox failed: %#x", n);
+ disorder_fatal(0, "sox failed: %#x", n);
pid = -1;
outfd = -1;
}
xclose(p[0]);
xclose(p[1]);
execvp(av[0], (char **)av);
- fatal(errno, "sox");
+ disorder_fatal(errno, "sox");
}
xclose(p[0]);
outfd = p[1];
if(pid != -1) {
/* There's still a converter running */
if(waitpid(pid, &n, 0) < 0)
- fatal(errno, "error calling waitpid");
+ disorder_fatal(errno, "error calling waitpid");
if(n)
- fatal(0, "sox failed: %#x", n);
+ disorder_fatal(0, "sox failed: %#x", n);
}
return 0;
}
int attribute((unused)) status,
const struct rusage attribute((unused)) *rusage,
void attribute((unused)) *u) {
- fatal(0, "speaker subprocess %s",
- wstat(status));
+ disorder_fatal(0, "speaker subprocess %s", wstat(status));
}
/** @brief Called when we get a message from the speaker process */
playing->sofar = sm.data;
break;
default:
- error(0, "unknown speaker message type %d", sm.type);
+ disorder_error(0, "unknown speaker message type %d", sm.type);
}
return 0;
}
struct speaker_message sm;
if(socketpair(PF_UNIX, SOCK_DGRAM, 0, sp) < 0)
- fatal(errno, "error calling socketpair");
+ disorder_fatal(errno, "error calling socketpair");
if(!(pid = xfork())) {
exitfn = _exit;
ev_signal_atfork(ev);
log_default == &log_syslog ? "--syslog" : "--no-syslog",
(char *)0);
#endif
- fatal(errno, "error invoking %s", SPEAKER);
+ disorder_fatal(errno, "error invoking %s", SPEAKER);
}
ev_child(ev, pid, 0, speaker_terminated, 0);
speaker_fd = sp[1];
speaker_recv(speaker_fd, &sm);
nonblock(speaker_fd);
if(ev_fd(ev, ev_read, speaker_fd, speaker_readable, 0, "speaker read") < 0)
- fatal(0, "error registering speaker socket fd");
+ disorder_fatal(0, "error registering speaker socket fd");
}
/** @brief Tell the speaker to reload its configuration */
/* Regardless we always report and record the status and do cleanup for
* prefork calls. */
if(status)
- error(0, "player for %s %s", q->track, wstat(status));
+ disorder_error(0, "player for %s %s", q->track, wstat(status));
if(q->type & DISORDER_PLAYER_PREFORK)
play_cleanup(q->pl, q->data);
q->wstat = status;
if(*params->waitdevice) {
n = ao_driver_id(params->waitdevice);
if(n == -1)
- fatal(0, "invalid libao driver: %s", params->waitdevice);
+ disorder_fatal(0, "invalid libao driver: %s", params->waitdevice);
} else
n = ao_default_driver_id();
/* Make up a format. */
/* np will be the pipe to disorder-normalize */
int np[2];
if(socketpair(PF_UNIX, SOCK_STREAM, 0, np) < 0)
- fatal(errno, "error calling socketpair");
+ disorder_fatal(errno, "error calling socketpair");
/* Beware of the Leopard! On OS X 10.5.x, the order of the shutdown
* calls here DOES MATTER. If you do the SHUT_WR first then the SHUT_RD
* fails with "Socket is not connected". I think this is a bug but
"%s/speaker/socket", config->home);
int sfd = xsocket(PF_UNIX, SOCK_STREAM, 0);
if(connect(sfd, (const struct sockaddr *)&addr, sizeof addr) < 0)
- fatal(errno, "connecting to %s", addr.sun_path);
+ disorder_fatal(errno, "connecting to %s", addr.sun_path);
/* Send the ID, with a NATIVE-ENDIAN 32 bit length */
uint32_t l = strlen(q->id);
if(write(sfd, &l, sizeof l) < 0
|| write(sfd, q->id, l) < 0)
- fatal(errno, "writing to %s", addr.sun_path);
+ disorder_fatal(errno, "writing to %s", addr.sun_path);
/* Await the ack */
if (read(sfd, &l, 1) < 0)
- fatal(errno, "reading ack from %s", addr.sun_path);
+ disorder_fatal(errno, "reading ack from %s", addr.sun_path);
/* Plumbing */
xdup2(np[0], 0);
xdup2(sfd, 1);
log_default == &log_syslog ? "--syslog" : "--no-syslog",
"--config", configfile,
(char *)0);
- fatal(errno, "executing disorder-normalize");
+ disorder_fatal(errno, "executing disorder-normalize");
/* End of the great-grandchild of disorderd */
}
/* Back in the grandchild of disorderd */
char buffer[64];
snprintf(buffer, sizeof buffer, "DISORDER_RAW_FD=%d", np[1]);
if(putenv(buffer) < 0)
- fatal(errno, "error calling putenv");
+ disorder_fatal(errno, "error calling putenv");
/* Close all the FDs we don't need */
xclose(np[0]);
/* Start the decoder itself */
case DISORDER_PLAYER_STANDALONE:
if(!(playing->type & DISORDER_PLAYER_PAUSES)) {
default:
- error(0, "cannot pause because player is not powerful enough");
+ disorder_error(0, "cannot pause because player is not powerful enough");
return -1;
}
if(play_pause(playing->pl, &played, playing->data)) {
- error(0, "player indicates it cannot pause");
+ disorder_error(0, "player indicates it cannot pause");
return -1;
}
xtime(&playing->lastpaused);
speaker_send(speaker_fd, &sm);
break;
}
- if(who) info("paused by %s", who);
+ if(who)
+ disorder_info("paused by %s", who);
notify_pause(playing->track, who);
paused = 1;
if(playing->state == playing_started)
speaker_send(speaker_fd, &sm);
break;
}
- if(who) info("resumed by %s", who);
+ if(who) disorder_info("resumed by %s", who);
notify_resume(playing->track, who);
if(playing->state == playing_paused)
playing->state = playing_started;
if(access(p, R_OK) == 0) {
h = dlopen(p, RTLD_NOW);
if(!h) {
- error(0, "error opening %s: %s", p, dlerror());
+ disorder_error(0, "error opening %s: %s", p, dlerror());
continue;
}
pl = xmalloc(sizeof *pl);
return pl;
}
}
- (flags & PLUGIN_FATAL ? fatal : error)(0, "cannot find plugin '%s'", name);
+ (flags & PLUGIN_FATAL ? disorder_fatal : disorder_error)
+ (0, "cannot find plugin '%s'", name);
return 0;
}
f = (function_t *)dlsym(pl->dlhandle, symbol);
if(!f)
- fatal(0, "error looking up function '%s' in '%s': %s",
- symbol, pl->name, dlerror());
+ disorder_fatal(0, "error looking up function '%s' in '%s': %s",
+ symbol, pl->name, dlerror());
return f;
}
o = dlsym(pl->dlhandle, symbol);
if(!o)
- fatal(0, "error looking up object '%s' in '%s': %s",
- symbol, pl->name, dlerror());
+ disorder_fatal(0, "error looking up object '%s' in '%s': %s",
+ symbol, pl->name, dlerror());
return o;
}
}
if(moved) {
- info("user %s moved %s", who, q->id);
+ disorder_info("user %s moved %s", who, q->id);
notify_queue_move(q->track, who);
sprintf(buffer, "%d", moved);
eventlog("moved", who, (char *)0);
queue_insert_entry(target, q);
target = q;
/* Log the individual tracks */
- info("user %s moved %s", who, q->id);
+ disorder_info("user %s moved %s", who, q->id);
notify_queue_move(q->track, who);
}
/* Report that the queue changed to the event log */
void queue_remove(struct queue_entry *which, const char *who) {
if(who) {
- info("user %s removed %s", who, which->id);
+ disorder_info("user %s removed %s", who, which->id);
notify_queue_move(which->track, who);
}
eventlog("removed", which->id, who, (const char *)0);
/* Exit if our parent has gone away or we have been told to stop. */
static void checkabort(void) {
if(getppid() == 1) {
- info("parent has terminated");
+ disorder_info("parent has terminated");
trackdb_abort_transaction(global_tid);
exit(0);
}
if(signalled) {
- info("received signal %d", signalled);
+ disorder_info("received signal %d", signalled);
trackdb_abort_transaction(global_tid);
exit(0);
}
long ntracks = 0, nnew = 0;
checkabort();
- info("rescanning %s with %s", c->root, c->module);
+ disorder_info("rescanning %s with %s", c->root, c->module);
/* plugin runs in a subprocess */
xpipe(p);
if(!(pid = xfork())) {
xclose(p[1]);
scan(c->module, c->root);
if(fflush(stdout) < 0)
- fatal(errno, "error writing to scanner pipe");
+ disorder_fatal(errno, "error writing to scanner pipe");
_exit(0);
}
xclose(p[1]);
if(!(fp = fdopen(p[0], "r")))
- fatal(errno, "error calling fdopen");
+ disorder_fatal(errno, "error calling fdopen");
/* read tracks from the plugin */
while(!inputline("rescanner", fp, &path, 0)) {
checkabort();
/* actually we can cope relatively well within the server, but they'll go
* wrong in track listings */
if(strchr(path, '\n')) {
- error(0, "cannot cope with tracks with newlines in the name");
+ disorder_error(0, "cannot cope with tracks with newlines in the name");
continue;
}
if(!(track = any2utf8(c->encoding, path))) {
- error(0, "cannot convert track path to UTF-8: %s", path);
+ disorder_error(0, "cannot convert track path to UTF-8: %s", path);
continue;
}
if(config->dbversion > 1) {
/* We use NFC track names */
if(!(track = utf8_compose_canon(track, strlen(track), 0))) {
- error(0, "cannot convert track path to NFC: %s", path);
+ disorder_error(0, "cannot convert track path to NFC: %s", path);
continue;
}
}
nnew += !!trackdb_notice(track, path);
++ntracks;
if(ntracks % 100 == 0 && xtime(0) > last_report + 10) {
- info("rescanning %s, %ld tracks so far", c->root, ntracks);
+ disorder_info("rescanning %s, %ld tracks so far", c->root, ntracks);
xtime(&last_report);
}
}
}
/* tidy up */
if(ferror(fp)) {
- error(errno, "error reading from scanner pipe");
+ disorder_error(errno, "error reading from scanner pipe");
goto done;
}
xfclose(fp);
fp = 0;
while((r = waitpid(pid, &w, 0)) == -1 && errno == EINTR)
;
- if(r < 0) fatal(errno, "error calling waitpid");
+ if(r < 0) disorder_fatal(errno, "error calling waitpid");
pid = 0;
if(w) {
- error(0, "scanner subprocess: %s", wstat(w));
+ disorder_error(0, "scanner subprocess: %s", wstat(w));
goto done;
}
- info("rescanned %s, %ld tracks, %ld new", c->root, ntracks, nnew);
+ disorder_info("rescanned %s, %ld tracks, %ld new", c->root, ntracks, nnew);
done:
if(fp)
xfclose(fp);
if(fnmatch(config->tracklength.s[n].s[0], t->track, 0) == 0)
break;
if(n >= config->tracklength.n)
- error(0, "no tracklength plugin found for %s", t->track);
+ disorder_error(0, "no tracklength plugin found for %s", t->track);
else {
length = tracklength(config->tracklength.s[n].s[1], t->track, path);
if(length > 0) {
long nrc;
if(c)
- info("rechecking %s", c->root);
+ disorder_info("rechecking %s", c->root);
else
- info("rechecking all tracks");
+ disorder_info("rechecking all tracks");
/* Doing the checking inside a transaction locks up the server for much too
* long (because it spends lots of time thinking about each track). So we
* pull the full track list into memory and work from that.
*/
for(;;) {
checkabort();
- info("getting track list");
+ disorder_info("getting track list");
global_tid = trackdb_begin_transaction();
memset(&cs, 0, sizeof cs);
cs.c = c;
sleep(10);
checkabort();
if(c)
- info("resuming recheck of %s", c->root);
+ disorder_info("resuming recheck of %s", c->root);
else
- info("resuming global recheck");
+ disorder_info("resuming global recheck");
}
trackdb_commit_transaction(global_tid);
global_tid = 0;
++nrc;
if(nrc % 100 == 0 && xtime(0) > last_report + 10) {
if(c)
- info("rechecking %s, %ld tracks so far", c->root, nrc);
+ disorder_info("rechecking %s, %ld tracks so far", c->root, nrc);
else
- info("rechecking all tracks, %ld tracks so far", nrc);
+ disorder_info("rechecking all tracks, %ld tracks so far", nrc);
xtime(&last_report);
}
}
if(c)
- info("rechecked %s, %ld obsoleted, %ld lengths calculated",
- c->root, cs.nobsolete, cs.nlength);
+ disorder_info("rechecked %s, %ld obsoleted, %ld lengths calculated",
+ c->root, cs.nobsolete, cs.nlength);
else
- info("rechecked all tracks, %ld no collection, %ld obsoleted, %ld lengths calculated",
+ disorder_info("rechecked all tracks, %ld no collection, %ld obsoleted, %ld lengths calculated",
cs.nnocollection, cs.nobsolete, cs.nlength);
}
if(n < config->collection.n)
fn(&config->collection.s[n]);
else
- error(0, "no collection has root '%s'", s);
+ disorder_error(0, "no collection has root '%s'", s);
}
/* rescan/recheck all collections */
set_progname(argv);
mem_init();
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVc:dDSsKC", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 's': logsyslog = 1; break;
case 'K': do_check = 1; break;
case 'C': do_check = 0; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if(logsyslog) {
openlog(progname, LOG_PID, LOG_DAEMON);
log_default = &log_syslog;
}
- if(config_read(0, NULL)) fatal(0, "cannot read configuration");
+ if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
xnice(config->nice_rescan);
sa.sa_handler = signal_handler;
sa.sa_flags = SA_RESTART;
sigemptyset(&sa.sa_mask);
xsigaction(SIGTERM, &sa, 0);
xsigaction(SIGINT, &sa, 0);
- info("started");
+ disorder_info("started");
trackdb_init(TRACKDB_NO_RECOVER);
trackdb_open(TRACKDB_NO_UPGRADE);
if(optind == argc) {
}
trackdb_close();
trackdb_deinit(NULL);
- info("completed");
+ disorder_info("completed");
return 0;
}
/* Reject bogus keys */
if(!k->size || k->size > 128) {
- error(0, "bogus schedule.db key (%lu bytes)", (unsigned long)k->size);
+ disorder_error(0, "bogus schedule.db key (%lu bytes)",
+ (unsigned long)k->size);
return -1;
}
id = xstrndup(k->data, k->size);
/* Reject items without the required fields */
for(n = 0; n < NREQUIRED; ++n) {
if(!kvp_get(actiondata, schedule_required[n])) {
- error(0, "scheduled event %s: missing required field '%s'",
- id, schedule_required[n]);
+ disorder_error(0, "scheduled event %s: missing required field '%s'",
+ id, schedule_required[n]);
return -1;
}
}
case 0:
break;
case DB_LOCK_DEADLOCK:
- error(0, "error deleting from schedule.db: %s", db_strerror(err));
+ disorder_error(0, "error deleting from schedule.db: %s", db_strerror(err));
break;
default:
- fatal(0, "error deleting from schedule.db: %s", db_strerror(err));
+ disorder_fatal(0, "error deleting from schedule.db: %s", db_strerror(err));
}
return err;
}
if(priority && !strcmp(priority, "junk")) {
/* Junk actions that are in the past are discarded during startup */
/* TODO recurring events should be handled differently here */
- info("junk event %s is in the past, discarding", id);
+ disorder_info("junk event %s is in the past, discarding", id);
if(cdel(cursor))
goto deadlocked;
/* Skip this time */
err = 0;
break;
case DB_LOCK_DEADLOCK:
- error(0, "error querying schedule.db: %s", db_strerror(err));
+ disorder_error(0, "error querying schedule.db: %s", db_strerror(err));
break;
default:
- fatal(0, "error querying schedule.db: %s", db_strerror(err));
+ disorder_fatal(0, "error querying schedule.db: %s", db_strerror(err));
}
deadlocked:
if(trackdb_closecursor(cursor))
case 0:
break;
case DB_LOCK_DEADLOCK:
- error(0, "error updating schedule.db: %s", db_strerror(err));
+ disorder_error(0, "error updating schedule.db: %s", db_strerror(err));
return err;
case DB_KEYEXIST:
return err;
default:
- fatal(0, "error updating schedule.db: %s", db_strerror(err));
+ disorder_fatal(0, "error updating schedule.db: %s", db_strerror(err));
}
return 0;
}
/* Check that the required field are present */
for(n = 0; n < NREQUIRED; ++n) {
if(!kvp_get(actiondata, schedule_required[n])) {
- error(0, "new scheduled event is missing required field '%s'",
- schedule_required[n]);
+ disorder_error(0, "new scheduled event is missing required field '%s'",
+ schedule_required[n]);
return 0;
}
}
when.tv_usec = 0;
/* Reject events in the past */
if(when.tv_sec <= xtime(0)) {
- error(0, "new scheduled event is in the past");
+ disorder_error(0, "new scheduled event is in the past");
return 0;
}
do {
/* Check that the required field are present */
for(n = 0; n < NREQUIRED; ++n) {
if(!kvp_get(actiondata, schedule_required[n])) {
- error(0, "scheduled event %s is missing required field '%s'",
- id, schedule_required[n]);
+ disorder_error(0, "scheduled event %s is missing required field '%s'",
+ id, schedule_required[n]);
return 0;
}
}
/* This stuff has rather a lot in common with c_play() */
if(!track) {
- error(0, "scheduled event %s: no track field", id);
+ disorder_error(0, "scheduled event %s: no track field", id);
return;
}
if(!trackdb_exists(track)) {
- error(0, "scheduled event %s: no such track as %s", id, track);
+ disorder_error(0, "scheduled event %s: no such track as %s", id, track);
return;
}
if(!(track = trackdb_resolve(track))) {
- error(0, "scheduled event %s: cannot resolve track %s", id, track);
+ disorder_error(0, "scheduled event %s: cannot resolve track %s", id, track);
return;
}
- info("scheduled event %s: %s play %s", id, who, track);
+ disorder_info("scheduled event %s: %s play %s", id, who, track);
q = queue_add(track, who, WHERE_START, NULL, origin_scheduled);
queue_write();
if(q == qhead.next && playing)
const char *value = kvp_get(actiondata, "value");
if(!key) {
- error(0, "scheduled event %s: no key field", id);
+ disorder_error(0, "scheduled event %s: no key field", id);
return;
}
if(key[0] == '_') {
- error(0, "scheduled event %s: cannot set internal global preferences (%s)",
- id, key);
+ disorder_error(0, "scheduled event %s: cannot set internal global preferences (%s)",
+ id, key);
return;
}
if(value)
- info("scheduled event %s: %s set-global %s=%s", id, who, key, value);
+ disorder_info("scheduled event %s: %s set-global %s=%s",
+ id, who, key, value);
else
- info("scheduled event %s: %s set-global %s unset", id, who, key);
+ disorder_info("scheduled event %s: %s set-global %s unset", id, who, key);
trackdb_set_global(key, value, who);
}
/* Look up the action */
n = TABLE_FIND(schedule_actions, name, action);
if(n < 0) {
- error(0, "scheduled event %s: unrecognized action '%s'", id, action);
+ disorder_error(0, "scheduled event %s: unrecognized action '%s'",
+ id, action);
return -1;
}
/* Find the user */
if(!(userinfo = trackdb_getuserinfo(who))) {
- error(0, "scheduled event %s: user '%s' does not exist", id, who);
+ disorder_error(0, "scheduled event %s: user '%s' does not exist", id, who);
return -1;
}
/* Check that they have suitable rights */
if(!(rights = kvp_get(userinfo, "rights"))) {
- error(0, "scheduled event %s: user %s' has no rights???", id, who);
+ disorder_error(0, "scheduled event %s: user %s' has no rights???", id, who);
return -1;
}
if(parse_rights(rights, &r, 1)) {
- error(0, "scheduled event %s: user %s has invalid rights '%s'",
- id, who, rights);
+ disorder_error(0, "scheduled event %s: user %s has invalid rights '%s'",
+ id, who, rights);
return -1;
}
if(!(r & schedule_actions[n].right)) {
- error(0, "scheduled event %s: user %s lacks rights for action %s",
- id, who, action);
+ disorder_error(0, "scheduled event %s: user %s lacks rights for action %s",
+ id, who, action);
return -1;
}
return n;
static void queue_read_error(const char *msg,
void *u) {
- fatal(0, "error parsing queue %s: %s", (const char *)u, msg);
+ disorder_fatal(0, "error parsing queue %s: %s", (const char *)u, msg);
}
static void queue_do_read(struct queue_entry *head, const char *path) {
if(!(fp = fopen(path, "r"))) {
if(errno == ENOENT)
return; /* no queue */
- fatal(errno, "error opening %s", path);
+ disorder_fatal(errno, "error opening %s", path);
}
head->next = head->prev = head;
while(!inputline(path, fp, &buffer, '\n')) {
if(head == &qhead
&& (!q->track
|| !q->when))
- fatal(0, "incomplete queue entry in %s", path);
+ disorder_fatal(0, "incomplete queue entry in %s", path);
queue_insert_entry(head->prev, q);
}
- if(ferror(fp)) fatal(errno, "error reading %s", path);
+ if(ferror(fp))
+ disorder_fatal(errno, "error reading %s", path);
fclose(fp);
}
struct queue_entry *q;
byte_xasprintf(&tmp, "%s.new", path);
- if(!(fp = fopen(tmp, "w"))) fatal(errno, "error opening %s", tmp);
+ if(!(fp = fopen(tmp, "w"))) disorder_fatal(errno, "error opening %s", tmp);
/* Save version indicator */
if(fprintf(fp, "#1\n") < 0)
- fatal(errno, "error writing %s", tmp);
+ disorder_fatal(errno, "error writing %s", tmp);
for(q = head->next; q != head; q = q->next)
if(fprintf(fp, "%s\n", queue_marshall(q)) < 0)
- fatal(errno, "error writing %s", tmp);
- if(fclose(fp) < 0) fatal(errno, "error closing %s", tmp);
- if(rename(tmp, path) < 0) fatal(errno, "error replacing %s", path);
+ disorder_fatal(errno, "error writing %s", tmp);
+ if(fclose(fp) < 0) disorder_fatal(errno, "error closing %s", tmp);
+ if(rename(tmp, path) < 0) disorder_fatal(errno, "error replacing %s", path);
}
void queue_write(void) {
D(("S%x writer completed", c->tag));
} else {
if(errno_value != EPIPE)
- error(errno_value, "S%x write error on socket", c->tag);
+ disorder_error(errno_value, "S%x write error on socket", c->tag);
if(c->r) {
D(("cancel reader"));
ev_reader_cancel(c->r);
struct conn *c = u;
D(("server reader_error S%x %d", c->tag, errno_value));
- error(errno_value, "S%x read error on socket", c->tag);
+ disorder_error(errno_value, "S%x read error on socket", c->tag);
if(c->w)
ev_writer_close(c->w);
c->w = 0;
sink_printf(ev_writer_sink(c->w), "550 No such ID\n");
return 1;
}
- info("added %s as %s after %s", track, q->id, afterme);
+ disorder_info("added %s as %s after %s", track, q->id, afterme);
afterme = q->id;
}
queue_write();
* prepare the same track twice so there's no point. */
if(qhead.next != &qhead) {
prepare(c->ev, qhead.next);
- info("prepared %s", qhead.next->id);
+ disorder_info("prepared %s", qhead.next->id);
}
/* If the queue was empty but we are for some reason paused then
* unpause. */
return 1;
}
if(!right_removable(c->rights, c->who, q)) {
- error(0, "%s attempted remove but lacks required rights", c->who);
+ disorder_error(0, "%s attempted remove but lacks required rights", c->who);
sink_writes(ev_writer_sink(c->w),
"510 Not authorized to remove that track\n");
return 1;
* playing track then you will get 550 if you weren't authorized to scratch
* the currently playing track. */
if(!right_scratchable(c->rights, c->who, playing)) {
- error(0, "%s attempted scratch but lacks required rights", c->who);
+ disorder_error(0, "%s attempted scratch but lacks required rights", c->who);
sink_writes(ev_writer_sink(c->w),
"510 Not authorized to scratch that track\n");
return 1;
static int c_shutdown(struct conn *c,
char attribute((unused)) **vec,
int attribute((unused)) nvec) {
- info("S%x shut down by %s", c->tag, c->who);
+ disorder_info("S%x shut down by %s", c->tag, c->who);
sink_writes(ev_writer_sink(c->w), "250 shutting down\n");
ev_writer_flush(c->w);
quit(c->ev);
static int c_reconfigure(struct conn *c,
char attribute((unused)) **vec,
int attribute((unused)) nvec) {
- info("S%x reconfigure by %s", c->tag, c->who);
+ disorder_info("S%x reconfigure by %s", c->tag, c->who);
if(reconfigure(c->ev, 1))
sink_writes(ev_writer_sink(c->w), "550 error reading new config\n");
else
}
}
/* Report what was requested */
- info("S%x rescan by %s (%s %s)", c->tag, c->who,
- flag_wait ? "wait" : "",
- flag_fresh ? "fresh" : "");
+ disorder_info("S%x rescan by %s (%s %s)", c->tag, c->who,
+ flag_wait ? "wait" : "",
+ flag_fresh ? "fresh" : "");
if(trackdb_rescan_underway()) {
if(flag_fresh) {
/* We want a fresh rescan but there is already one underway. Arrange a
/* get connection data */
l = sizeof u;
if(getpeername(c->fd, &u.sa, &l) < 0) {
- error(errno, "S%x error calling getpeername", c->tag);
+ disorder_error(errno, "S%x error calling getpeername", c->tag);
return 0;
}
if(c->l->pf != PF_UNIX) {
if((n = getnameinfo(&u.sa, l,
host, sizeof host, 0, 0, NI_NUMERICHOST))) {
- error(0, "S%x error calling getnameinfo: %s", c->tag, gai_strerror(n));
+ disorder_error(0, "S%x error calling getnameinfo: %s",
+ c->tag, gai_strerror(n));
return 0;
}
return xstrdup(host);
k = trackdb_getuserinfo(vec[0]);
/* reject nonexistent users */
if(!k) {
- error(0, "S%x unknown user '%s' from %s", c->tag, vec[0], host);
+ disorder_error(0, "S%x unknown user '%s' from %s", c->tag, vec[0], host);
sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
return 1;
}
/* reject unconfirmed users */
if(kvp_get(k, "confirmation")) {
- error(0, "S%x unconfirmed user '%s' from %s", c->tag, vec[0], host);
+ disorder_error(0, "S%x unconfirmed user '%s' from %s",
+ c->tag, vec[0], host);
sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
return 1;
}
password = kvp_get(k, "password");
if(!password) password = "";
if(parse_rights(kvp_get(k, "rights"), &rights, 1)) {
- error(0, "error parsing rights for %s", vec[0]);
+ disorder_error(0, "error parsing rights for %s", vec[0]);
sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
return 1;
}
c->rights = rights;
/* currently we only bother logging remote connections */
if(strcmp(host, "local"))
- info("S%x %s connected from %s", c->tag, vec[0], host);
+ disorder_info("S%x %s connected from %s", c->tag, vec[0], host);
else
c->rights |= RIGHT__LOCAL;
sink_writes(ev_writer_sink(c->w), "230 OK\n");
return 1;
}
/* oops, response was wrong */
- info("S%x authentication failure for %s from %s", c->tag, vec[0], host);
+ disorder_info("S%x authentication failure for %s from %s",
+ c->tag, vec[0], host);
sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
return 1;
}
}
rights = set ? RIGHT_VOLUME : RIGHT_READ;
if(!(c->rights & rights)) {
- error(0, "%s attempted to set volume but lacks required rights", c->who);
+ disorder_error(0, "%s attempted to set volume but lacks required rights",
+ c->who);
sink_writes(ev_writer_sink(c->w), "510 Prohibited\n");
return 1;
}
return 1;
}
if(!has_move_rights(c, &q, 1)) {
- error(0, "%s attempted move but lacks required rights", c->who);
+ disorder_error(0, "%s attempted move but lacks required rights", c->who);
sink_writes(ev_writer_sink(c->w),
"510 Not authorized to move that track\n");
return 1;
return 1;
}
if(!has_move_rights(c, qs, nvec)) {
- error(0, "%s attempted moveafter but lacks required rights", c->who);
+ disorder_error(0, "%s attempted moveafter but lacks required rights",
+ c->who);
sink_writes(ev_writer_sink(c->w),
"510 Not authorized to move those tracks\n");
return 1;
c->cookie = vec[0];
c->rights = rights;
if(strcmp(host, "local"))
- info("S%x %s connected with cookie from %s", c->tag, user, host);
+ disorder_info("S%x %s connected with cookie from %s", c->tag, user, host);
else
c->rights |= RIGHT__LOCAL;
/* Response contains username so client knows who they are acting as */
const char *rights;
if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) {
- error(0, "S%x: remote adduser", c->tag);
+ disorder_error(0, "S%x: remote adduser", c->tag);
sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
return 1;
}
struct conn *d;
if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) {
- error(0, "S%x: remote deluser", c->tag);
+ disorder_error(0, "S%x: remote deluser", c->tag);
sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
return 1;
}
struct conn *d;
if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) {
- error(0, "S%x: remote edituser", c->tag);
+ disorder_error(0, "S%x: remote edituser", c->tag);
sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
return 1;
}
}
sink_writes(ev_writer_sink(c->w), "250 OK\n");
} else {
- error(0, "%s attempted edituser but lacks required rights", c->who);
+ disorder_error(0, "%s attempted edituser but lacks required rights",
+ c->who);
sink_writes(ev_writer_sink(c->w), "510 Restricted to administrators\n");
}
return 1;
if(!config->remote_userman
&& !(c->rights & RIGHT__LOCAL)
&& strcmp(vec[1], "rights")) {
- error(0, "S%x: remote userinfo %s %s", c->tag, vec[0], vec[1]);
+ disorder_error(0, "S%x: remote userinfo %s %s", c->tag, vec[0], vec[1]);
sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
return 1;
}
else
sink_writes(ev_writer_sink(c->w), "550 No such user\n");
} else {
- error(0, "%s attempted userinfo but lacks required rights", c->who);
+ disorder_error(0, "%s attempted userinfo but lacks required rights",
+ c->who);
sink_writes(ev_writer_sink(c->w), "510 Restricted to administrators\n");
}
return 1;
* letters and digits, minimizing the chance of the URL being mispasted. */
gcry_randomize(nonce, sizeof nonce, GCRY_STRONG_RANDOM);
if(basen(nonce, CONFIRM_SIZE, nonce_str, sizeof nonce_str, 62)) {
- error(0, "buffer too small encoding confirmation string");
+ disorder_error(0, "buffer too small encoding confirmation string");
sink_writes(ev_writer_sink(c->w), "550 Cannot create user\n");
}
byte_xasprintf(&cs, "%s/%s", vec[0], nonce_str);
c->cookie = 0;
c->rights = rights;
if(strcmp(host, "local"))
- info("S%x %s confirmed from %s", c->tag, user, host);
+ disorder_info("S%x %s confirmed from %s", c->tag, user, host);
else
c->rights |= RIGHT__LOCAL;
/* Response contains username so client knows who they are acting as */
if(!status) {
sink_writes(ev_writer_sink(c->w), "250 OK\n");
} else {
- error(0, "reminder subprocess %s", wstat(status));
+ disorder_error(0, "reminder subprocess %s", wstat(status));
sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
}
/* Re-enable this connection */
static hash *last_reminder;
if(!config->mail_sender) {
- error(0, "cannot send password reminders because mail_sender not set");
+ disorder_error(0, "cannot send password reminders because mail_sender not set");
sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
return 1;
}
if(!(k = trackdb_getuserinfo(vec[0]))) {
- error(0, "reminder for user '%s' who does not exist", vec[0]);
+ disorder_error(0, "reminder for user '%s' who does not exist", vec[0]);
sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
return 1;
}
if(!(email = kvp_get(k, "email"))
|| !email_valid(email)) {
- error(0, "user '%s' has no valid email address", vec[0]);
+ disorder_error(0, "user '%s' has no valid email address", vec[0]);
sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
return 1;
}
if(!(password = kvp_get(k, "password"))
|| !*password) {
- error(0, "user '%s' has no password", vec[0]);
+ disorder_error(0, "user '%s' has no password", vec[0]);
sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
return 1;
}
last = hash_find(last_reminder, vec[0]);
xtime(&now);
if(last && now < *last + config->reminder_interval) {
- error(0, "sent a password reminder to '%s' too recently", vec[0]);
+ disorder_error(0, "sent a password reminder to '%s' too recently", vec[0]);
sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
return 1;
}
"\n"
" %s\n", password);
if(!(text = mime_encode_text(text, &charset, &encoding)))
- fatal(0, "cannot encode email");
+ disorder_fatal(0, "cannot encode email");
byte_xasprintf((char **)&content_type, "text/plain;charset=%s",
quote822(charset, 0));
pid = sendmail_subprocess("", config->mail_sender, email,
return 1;
}
hash_add(last_reminder, vec[0], &now, HASH_INSERT_OR_REPLACE);
- info("sending a passsword reminder to user '%s'", vec[0]);
+ disorder_info("sending a passsword reminder to user '%s'", vec[0]);
/* We can only continue when the subprocess finishes */
ev_child(c->ev, pid, 0, sent_reminder, c);
return 0;
else {
if(commands[n].rights
&& !(c->rights & commands[n].rights)) {
- error(0, "%s attempted %s but lacks required rights", c->who ? c->who : "NULL",
+ disorder_error(0, "%s attempted %s but lacks required rights",
+ c->who ? c->who : "NULL",
commands[n].name);
sink_writes(ev_writer_sink(c->w), "510 Prohibited\n");
return 1;
}
if(eof) {
if(bytes)
- error(0, "S%x unterminated line", c->tag);
+ disorder_error(0, "S%x unterminated line", c->tag);
D(("normal reader close"));
c->r = 0;
if(c->w) {
c->w = ev_writer_new(ev, fd, writer_error, c,
"client writer");
if(!c->w) {
- error(0, "ev_writer_new for file inbound connection (fd=%d) failed",
+ disorder_error(0, "ev_writer_new for file inbound connection (fd=%d) failed",
fd);
close(fd);
return 0;
if(!c->r)
/* Main reason for failure is the FD is too big and that will already have
* been handled */
- fatal(0, "ev_reader_new for file inbound connection (fd=%d) failed", fd);
+ disorder_fatal(0,
+ "ev_reader_new for file inbound connection (fd=%d) failed",
+ fd);
ev_tie(c->r, c->w);
c->fd = fd;
c->reader = reader_callback;
fd = xsocket(pf, SOCK_STREAM, 0);
xsetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
if(bind(fd, sa, socklen) < 0) {
- error(errno, "error binding to %s", name);
+ disorder_error(errno, "error binding to %s", name);
return -1;
}
xlisten(fd, 128);
l->pf = pf;
if(ev_listen(ev, fd, listen_callback, l, "server listener"))
exit(EXIT_FAILURE);
- info("listening on %s", name);
+ disorder_info("listening on %s", name);
return fd;
}
pthread_mutex_lock(&lock);
if(n < 0) {
if(errno != EAGAIN)
- fatal(errno, "error reading sample stream");
+ disorder_fatal(errno, "error reading sample stream");
rc = 0;
} else if(n == 0) {
D(("fill %s: eof detected", t->id));
memset(buffer, 0, max_bytes);
provided_samples = max_samples;
if(playing)
- info("%zu samples silence, playing->used=%zu", provided_samples, playing->used);
+ disorder_info("%zu samples silence, playing->used=%zu",
+ provided_samples, playing->used);
else
- info("%zu samples silence, playing=NULL", provided_samples);
+ disorder_info("%zu samples silence, playing=NULL", provided_samples);
}
pthread_mutex_unlock(&lock);
return provided_samples;
pthread_mutex_lock(&lock);
if(n < 0) {
if(errno == EINTR) continue;
- fatal(errno, "error calling poll");
+ disorder_fatal(errno, "error calling poll");
}
/* Perhaps a connection has arrived */
if(fds[listen_slot].revents & POLLIN) {
if((fd = accept(listenfd, (struct sockaddr *)&addr, &addrlen)) >= 0) {
blocking(fd);
if(read(fd, &l, sizeof l) < 4) {
- error(errno, "reading length from inbound connection");
+ disorder_error(errno, "reading length from inbound connection");
xclose(fd);
} else if(l >= sizeof id) {
- error(0, "id length too long");
+ disorder_error(0, "id length too long");
xclose(fd);
} else if(read(fd, id, l) < (ssize_t)l) {
- error(errno, "reading id from inbound connection");
+ disorder_error(errno, "reading id from inbound connection");
xclose(fd);
} else {
id[l] = 0;
D(("id %s fd %d", id, fd));
t = findtrack(id, 1/*create*/);
if (write(fd, "", 1) < 0) /* write an ack */
- error(errno, "writing ack to inbound connection");
+ disorder_error(errno, "writing ack to inbound connection");
if(t->fd != -1) {
- error(0, "%s: already got a connection", id);
+ disorder_error(0, "%s: already got a connection", id);
xclose(fd);
} else {
nonblock(fd);
}
}
} else
- error(errno, "accept");
+ disorder_error(errno, "accept");
}
/* Perhaps we have a command to process */
if(fds[stdin_slot].revents & POLLIN) {
/* If finished isn't set then the server can't believe that this
* track has finished */
if(!playing->finished)
- fatal(0, "got SM_PLAY but already playing something");
+ disorder_fatal(0, "got SM_PLAY but already playing something");
/* If pending_playing is set then the server must believe that that
* is playing */
if(pending_playing)
- fatal(0, "got SM_PLAY but have a pending playing track");
+ disorder_fatal(0, "got SM_PLAY but have a pending playing track");
}
t = findtrack(sm.id, 1);
D(("SM_PLAY %s fd %d", t->id, t->fd));
if(t->fd == -1)
- error(0, "cannot play track because no connection arrived");
+ disorder_error(0,
+ "cannot play track because no connection arrived");
/* TODO as things stand we often report this error message but then
* appear to proceed successfully. Understanding why requires a look
* at play.c: we call prepare() which makes the connection in a child
* log more because there's been a bug here recently than because
* it's particularly interesting; the log message will be removed
* if no further problems show up. */
- info("SM_CANCEL for nonplaying track %s", sm.id);
+ disorder_info("SM_CANCEL for nonplaying track %s", sm.id);
sm.type = SM_STILLBORN;
}
strcpy(sm.id, t->id);
/* Probably scratching the playing track well before it's got
* going, but could indicate a bug, so we log this as an error. */
sm.type = SM_UNKNOWN;
- error(0, "SM_CANCEL for unknown track %s", sm.id);
+ disorder_error(0, "SM_CANCEL for unknown track %s", sm.id);
}
speaker_send(1, &sm);
force_report = 1;
case SM_RELOAD:
D(("SM_RELOAD"));
if(config_read(1, NULL))
- error(0, "cannot read configuration");
- info("reloaded configuration");
+ disorder_error(0, "cannot read configuration");
+ disorder_info("reloaded configuration");
break;
default:
- error(0, "unknown message type %d", sm.type);
+ disorder_error(0, "unknown message type %d", sm.type);
}
}
/* Read in any buffered data */
struct rlimit rl[1];
set_progname(argv);
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVc:dDSs", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'D': debugging = 0; break;
case 'S': logsyslog = 0; break;
case 's': logsyslog = 1; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if((d = getenv("DISORDER_DEBUG_SPEAKER"))) debugging = atoi(d);
log_default = &log_syslog;
}
config_uaudio_apis = uaudio_apis;
- if(config_read(1, NULL)) fatal(0, "cannot read configuration");
+ if(config_read(1, NULL)) disorder_fatal(0, "cannot read configuration");
/* ignore SIGPIPE */
signal(SIGPIPE, SIG_IGN);
/* set nice value */
become_mortal();
/* make sure we're not root, whatever the config says */
if(getuid() == 0 || geteuid() == 0)
- fatal(0, "do not run as root");
+ disorder_fatal(0, "do not run as root");
/* Make sure we can't have more than NFDS files open (it would bust our
* poll() array) */
if(getrlimit(RLIMIT_NOFILE, rl) < 0)
- fatal(errno, "getrlimit RLIMIT_NOFILE");
+ disorder_fatal(errno, "getrlimit RLIMIT_NOFILE");
if(rl->rlim_cur > NFDS) {
rl->rlim_cur = NFDS;
if(setrlimit(RLIMIT_NOFILE, rl) < 0)
- fatal(errno, "setrlimit to reduce RLIMIT_NOFILE to %lu",
+ disorder_fatal(errno, "setrlimit to reduce RLIMIT_NOFILE to %lu",
(unsigned long)rl->rlim_cur);
- info("set RLIM_NOFILE to %lu", (unsigned long)rl->rlim_cur);
+ disorder_info("set RLIM_NOFILE to %lu", (unsigned long)rl->rlim_cur);
} else
- info("RLIM_NOFILE is %lu", (unsigned long)rl->rlim_cur);
+ disorder_info("RLIM_NOFILE is %lu", (unsigned long)rl->rlim_cur);
/* gcrypt initialization */
if(!gcry_check_version(NULL))
disorder_fatal(0, "gcry_check_version failed");
byte_xasprintf(&dir, "%s/speaker", config->home);
unlink(dir); /* might be a leftover socket */
if(mkdir(dir, 0700) < 0 && errno != EEXIST)
- fatal(errno, "error creating %s", dir);
+ disorder_fatal(errno, "error creating %s", dir);
/* set up the listen socket */
listenfd = xsocket(PF_UNIX, SOCK_STREAM, 0);
memset(&addr, 0, sizeof addr);
snprintf(addr.sun_path, sizeof addr.sun_path, "%s/speaker/socket",
config->home);
if(unlink(addr.sun_path) < 0 && errno != ENOENT)
- error(errno, "removing %s", addr.sun_path);
+ disorder_error(errno, "removing %s", addr.sun_path);
xsetsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
if(bind(listenfd, (const struct sockaddr *)&addr, sizeof addr) < 0)
- fatal(errno, "error binding socket to %s", addr.sun_path);
+ disorder_fatal(errno, "error binding socket to %s", addr.sun_path);
xlisten(listenfd, 128);
nonblock(listenfd);
- info("listening on %s", addr.sun_path);
+ disorder_info("listening on %s", addr.sun_path);
memset(&sm, 0, sizeof sm);
sm.type = SM_READY;
speaker_send(1, &sm);
mainloop();
- info("stopped (parent terminated)");
+ disorder_info("stopped (parent terminated)");
exit(0);
}
/** @brief Quit DisOrder */
void quit(ev_source *ev) {
- info("shutting down...");
+ disorder_info("shutting down...");
quitting(ev);
trackdb_close();
trackdb_deinit(ev);
* These are not shut down currently.
*/
ev_child_killall(ev);
- info("exiting");
+ disorder_info("exiting");
exit(0);
}
/* stop the old one and remove it from the filesystem */
server_stop(ev, current_unix_fd);
if(unlink(current_unix) < 0)
- fatal(errno, "unlink %s", current_unix);
+ disorder_fatal(errno, "unlink %s", current_unix);
}
/* start the new one */
if(strlen(new_unix) >= sizeof sun.sun_path)
- fatal(0, "socket path %s is too long", new_unix);
+ disorder_fatal(0, "socket path %s is too long", new_unix);
memset(&sun, 0, sizeof sun);
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path, new_unix);
if(unlink(new_unix) < 0 && errno != ENOENT)
- fatal(errno, "unlink %s", new_unix);
+ disorder_fatal(errno, "unlink %s", new_unix);
if((current_unix_fd = server_start(ev, PF_UNIX, sizeof sun,
(const struct sockaddr *)&sun,
new_unix)) >= 0) {
current_unix = new_unix;
if(chmod(new_unix, 0777) < 0)
- fatal(errno, "error calling chmod %s", new_unix);
+ disorder_fatal(errno, "error calling chmod %s", new_unix);
} else
current_unix = 0;
}
else {
/* Tell the speaker it needs to reload its config too. */
speaker_reload();
- info("%s: installed new configuration", configfile);
+ disorder_info("%s: installed new configuration", configfile);
}
}
/* New audio API */
set_progname(argv);
mem_init();
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVc:dDSs", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'D': debugging = 0; break;
case 'S': logsyslog = 0; break;
case 's': logsyslog = 1; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if(logsyslog) {
log_default = &log_syslog;
}
if(config_read(0, NULL))
- fatal(0, "cannot read configuration");
+ disorder_fatal(0, "cannot read configuration");
trackdb_init(TRACKDB_NO_RECOVER);
trackdb_open(TRACKDB_NO_UPGRADE);
stats = trackdb_stats(0);
int n;
const char *s;
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, ""))
+ disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVc:d", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'V': version("trackname");
case 'c': configfile = optarg; break;
case 'd': debugging = 1; break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
- if(argc - optind < 3) fatal(0, "not enough arguments");
- if(argc - optind > 3) fatal(0, "too many arguments");
- if(config_read(0, NULL)) fatal(0, "cannot read configuration");
+ if(argc - optind < 3) disorder_fatal(0, "not enough arguments");
+ if(argc - optind > 3) disorder_fatal(0, "too many arguments");
+ if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
s = trackname_part(argv[optind], argv[optind+1], argv[optind+2]);
- if(!s) fatal(0, "trackname_part returned NULL");
+ if(!s) disorder_fatal(0, "trackname_part returned NULL");
xprintf("%s\n", nullcheck(utf82mb(s)));
- if(fclose(stdout) < 0) fatal(errno, "error closing stdout");
+ if(fclose(stdout) < 0) disorder_fatal(errno, "error closing stdout");
return 0;
}
set_progname(argv);
mem_init();
- if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
+ if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
while((n = getopt_long(argc, argv, "hVo:", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'V': version();
case 'o':
if(!freopen(optarg, "w", stdout))
- fatal(errno, "%s", optarg);
+ disorder_fatal(errno, "%s", optarg);
break;
- default: fatal(0, "invalid option");
+ default: disorder_fatal(0, "invalid option");
}
}
if(optind + 2 != argc)
- fatal(0, "missing arguments");
+ disorder_fatal(0, "missing arguments");
a.n = 2;
a.s = &argv[optind];
if(!(ai = get_address(&a, &pref, &name)))
fd = xsocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
nonblock(fd);
if(bind(fd, ai->ai_addr, ai->ai_addrlen) < 0)
- fatal(errno, "error binding to %s", name);
+ disorder_fatal(errno, "error binding to %s", name);
while(getppid() != 1) {
/* Wait for something to happen. We don't just block forever in recvfrom()
* as otherwise we'd never die if the parent terminated uncontrolledly. */
if(n < 0) {
if(errno == EINTR || errno == EAGAIN)
continue;
- fatal(errno, "%s: recvfrom", name);
+ disorder_fatal(errno, "%s: recvfrom", name);
}
if((err = getnameinfo(&sa.sa, len, h, sizeof h, s, sizeof s,
NI_NUMERICHOST|NI_NUMERICSERV|NI_DGRAM)))
- fatal(0, "getnameinfo: %s", gai_strerror(err));
+ disorder_fatal(0, "getnameinfo: %s", gai_strerror(err));
xprintf("from host %s service %s: %d bytes\n", h, s, n);
for(i = 0; i < n; i += 16) {
for(j = i; j < n && j < i + 16; ++j)
xprintf("%c", buffer[j] < 128 && isprint(buffer[j]) ? buffer[j] : '.');
xprintf("\n");
if(fflush(stdout) < 0)
- fatal(errno, "stdout");
+ disorder_fatal(errno, "stdout");
}
}
return 0;