Cooking in next since 2015-04-26.
* refs/heads/t/taggers:
aac: Fix compilation without libmp4v2.
The mp4 tagger.
The mp3 tagger.
The flac tagger.
The ogg/speex tagger.
The ogg/vorbis tagger.
The ogg/opus tagger.
The wma tagger.
+++ /dev/null
-Features
-========
-
-------------------------------------------------------------------------------
-
- * Runs on Linux, Mac OS, FreeBSD, NetBSD, Solaris and probably other
- Unixes
- * Mp3, ogg/vorbis, ogg/speex, aac (m4a), wma, flac and ogg/opus support
- * Native Alsa, OSS, CoreAudio output support
- * Support for ESD, Pulseaudio, AIX, Solaris, IRIX through libao
- * Local or remote http, dccp and udp network audio streaming
- * IPv6 support
- * Forward error correction allows receivers to recover from packet losses
- * Volume normalizer
- * Stream grabbing at any point in the filter chain
- * Stand-alone command line receiver/decoder/normalizer/player/tagger
- * Sophisticated audio file selector
- * Small memory footprint
- * Command line interface for easy scripting in high-level languages
- * Interactive sessions offer command completion and command line history
- * RSA user authentication
- * Encrypted communications
- * GPL licensed
- * Written in C
- * Well documented
- * Complete API-Reference
- * Easily extendible due to its modular design
- * Curses-based gui
- * Volume fader and alarm clock
exec_prefix := @exec_prefix@
# These two use prefix and exec_prefix
-BINDIR := @bindir@
+bindir := @bindir@
datarootdir := @datarootdir@
PACKAGE_TARNAME := @PACKAGE_TARNAME@
PACKAGE_VERSION := @PACKAGE_VERSION@
-INSTALL := @install@
-GENGETOPT := @gengetopt@
-HELP2MAN := @help2man@
+INSTALL := @INSTALL@
+GENGETOPT := @GENGETOPT@
+HELP2MAN := @HELP2MAN@
ggo_descriptions_declared := @ggo_descriptions_declared@
object_executable_matrix := @object_executable_matrix@
-VARDIR := /var/paraslash
-MANDIR := $(datarootdir)/man/man1
+vardir := /var/paraslash
+mandir := $(datarootdir)/man/man1
STRIP := $(CROSS_COMPILE)strip
HOSTCC ?= cc
MKDIR_P := mkdir -p
$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,\
$(subst z,Z,$1))))))))))))))))))))))))))
-CPPFLAGS += -DBINDIR='"$(BINDIR)"'
-CPPFLAGS += -DBUILD_DATE='"$(build_date)"'
-CPPFLAGS += -DUNAME_RS='"$(uname_rs)"'
-CPPFLAGS += -DCC_VERSION='"$(cc_version)"'
+CPPFLAGS += -DBINDIR='"$(bindir)"'
+CPPFLAGS += -DBUILD_DATE='"$(shell date)"'
+CPPFLAGS += -DUNAME_RS='"$(shell uname -rs)"'
+CPPFLAGS += -DCC_VERSION='"$(shell $(CC) --version | head -n 1)"'
CPPFLAGS += -DMAIN_INPUT_FILE_IS_$(*F)
CPPFLAGS += $(arch_cppflags)
CPPFLAGS += -I/usr/local/include
ifeq ($(uname_s),Linux)
# these cause warnings on *BSD
+ CPPFLAGS += -Wunused-macros
STRICT_CFLAGS += -fdata-sections -ffunction-sections
STRICT_CFLAGS += -Wstrict-prototypes
STRICT_CFLAGS += -Wshadow
$(cmdlist_dir)/%.command_list.man: %.cmd %.c | $(cmdlist_dir)
@[ -z "$(Q)" ] || echo 'GEN $@'
$(Q) ./command_util.bash man < $< > $@
-$(cmdlist_dir)/%.completion.h: %.cmd %.c | $(cmdlist_dir)
+$(cmdlist_dir)/%.completion.h: %.cmd | $(cmdlist_dir)
@[ -z "$(Q)" ] || echo 'GEN $@'
$(Q) ./command_util.bash compl $(strip $(call TOUPPER,$(*F)))_COMPLETERS \
$(strip $(call TOUPPER,$(*F)))_COMMANDS < $< > $@
maintainer-clean: distclean
@[ -z "$(Q)" ] || echo 'MAINTAINER-CLEAN'
$(Q) rm -f *.tar.bz2 config.h configure config.h.in
- $(Q) rm -rf web_sync
install: all man
- $(MKDIR_P) $(BINDIR) $(MANDIR)
+ $(MKDIR_P) $(bindir) $(mandir)
$(INSTALL) -s --strip-program $(STRIP) -m 755 \
- $(prefixed_executables) $(BINDIR)
- $(INSTALL) -m 644 $(man_pages) $(MANDIR)
- $(MKDIR_P) $(VARDIR) >/dev/null 2>&1 || true # not fatal, so don't complain
+ $(prefixed_executables) $(bindir)
+ $(INSTALL) -m 644 $(man_pages) $(mandir)
+ $(MKDIR_P) $(vardir) >/dev/null 2>&1 || true # not fatal, so don't complain
$(tarball):
$(Q) rm -rf $(tarball) $(tarball_pfx)
NEWS
====
------------------------------------------
-current master branch "magnetic momentum"
------------------------------------------
+------------------------------------------
+current master branch "cascading gradient"
+------------------------------------------
+
+ - para_afh learned to modify meta tags of mp3 wma ogg spx
+ opus flac aac files.
+
+--------------------------------------
+0.5.5 (2015-09-20) "magnetic momentum"
+--------------------------------------
+
+Many new features and a lot of other improvements.
+
- On Linux systems, local sockets are now created in the
abstract name space by default. This allows to get rid of
the socket specials in /var/paraslash.
+ - The --user-allow option of para_audiod now accepts also
+ usernames rather than only user IDs.
- New autoconf macros to avoid duplication in configure.ac.
- Status items (as shown by para_gui) are updated correctly
when the meta information of the current audio changes.
-
-Download: ./releases/paraslash-git.tar.bz2 (tarball)
+ - para_server and para_audiod no longer refuse to start in
+ the background if no log file is given. Instead, all log
+ messages go to /dev/null in this case.
+ - Web page cleanup.
+ - New syntax for the -l and -s options of the ls command.
+ These options should now be specified as -l=v rather than
+ -lv, for example. The old syntax still works, but support
+ will be dropped in v0.6.0.
+
+Download: ./releases/paraslash-0.5.5.tar.bz2 (tarball)
+./releases/paraslash-0.5.5.tar.bz2.asc (signature)
------------------------------------------
0.5.4 (2015-01-23) "exponential alignment"
},
{
.name = "flac",
-#ifdef HAVE_FLAC
+#if defined(HAVE_OGG) && defined(HAVE_FLAC)
.init = flac_afh_init,
#endif
},
name = (char *)name_obj.data;
if ((!name || !*name) && (pmd->pm_flags & PM_SKIP_EMPTY_NAME))
return 1;
- if (!pmd->patterns.size && (pmd->pm_flags & PM_NO_PATTERN_MATCHES_EVERYTHING))
+ if (pmd->patterns.size == 0 &&
+ (pmd->pm_flags & PM_NO_PATTERN_MATCHES_EVERYTHING)) {
+ pmd->num_matches++;
return pmd->action(pmd->table, row, name, pmd->data);
+ }
for (p = pattern_txt; p < pattern_txt + pmd->patterns.size;
p += strlen(p) + 1) {
ret = fnmatch(p, name, pmd->fnmatch_flags);
N: ls
P: AFS_READ
D: List audio files.
-U: ls [-l[s|l|v|m]] [-p] [-a] [-r] [-d] [-s{p|s|l|n|f|c|i|y|b|d|a}] [pattern...]
+U: ls [-l=mode] [-p] [-a] [-r] [-d] [-s=order] [pattern...]
H: Print a list of all audio files matching pattern.
H:
H: Options:
H:
-H: -l Change listing mode. Defaults to short listing if not given.
+H: -l=mode Change listing mode. Defaults to short listing if not given.
H:
-H: -ls: short listing mode
-H: -ll: long listing mode (equivalent to -l)
-H: -lv: verbose listing mode
-H: -lp: parser-friendly mode
-H: -lm: mbox listing mode
-H: -lc: chunk-table listing mode
+H: Available modes:
+H: s: short listing mode
+H: l: long listing mode (equivalent to -l)
+H: v: verbose listing mode
+H: p: parser-friendly mode
+H: m: mbox listing mode
+H: c: chunk-table listing mode
H:
H: -p List full paths. If this option is not specified, only the basename
H: of each file is printed.
H:
H: -d Print dates as seconds after the epoch.
H:
-H: -s Change sort order. Defaults to alphabetical path sort if not given.
-H:
-H: -sp: by path
-H: -sl: by last played time
-H: -ss: by score (implies -a)
-H: -sn: by num played count
-H: -sf: by frequency
-H: -sc: by number of channels
-H: -si: by image id
-H: -sy: by lyrics id
-H: -sb: by bit rate
-H: -sd: by duration
-H: -sa: by audio format
+H: -s=order Change sort order. Defaults to alphabetical path sort if not given.
+H:
+H: Possible values for order:
+H: p: by path
+H: l: by last played time
+H: s: by score (implies -a)
+H: n: by num played count
+H: f: by frequency
+H: c: by number of channels
+H: i: by image id
+H: y: by lyrics id
+H: b: by bit rate
+H: d: by duration
+H: a: by audio format
---
N: lsatt
P: AFS_READ
N: ls@member@
O: int com_ls@member@(struct command_context *cc);
P: AFS_READ
-D: List blobs of type @member@ matching a pattern.
+D: List blobs of type @member@ which match a pattern.
U: ls@member@ [-i] [-l] [-r] [pattern]
H: Print the list of all blobs which match the given pattern. If no
H: pattern is given, the full list is printed.
H:
H: Options:
H:
-H: -i Sort attributes by id. The default is to sort
-H: alphabetically by name.
+H: -i Sort by identifier. The default is to sort alphabetically by name.
H:
-H: -l Print a long listing containing both identifier and
-H: attribute name. The default is to print only the name.
+H: -l Print identifier and name. The default is to print only the name.
H:
H: -r Reverse sort order.
---
O: int com_mv@member@(struct command_context *cc);
P: AFS_READ | AFS_WRITE
D: Rename a blob of type @member@.
-U: mv@member@ old_@member@_name new_@member@_name
-H: Rename the blob identified by old_@member@_name to new_@member@_name.
-H: This command fails if new_@member@_name already exists.
+U: mv@member@ source_@member@_name dest_@member@_name
+H: Rename the blob identified by the source blob name to the destination blob
+H: name. The command fails if the source does not exist, or if the destination
+H: already exists.
i++;
break;
}
+ /*
+ * Compatibility: Prior to 0.5.5 it was necessary to specify
+ * the listing mode without the '=' character as in -lv, for
+ * example. Now the variant with '=' is preferred and
+ * documented but we still accept the old way to specify the
+ * listing mode.
+ *
+ * Support for the legacy syntax can be dropped at 0.6.0
+ * or later.
+ */
if (!strncmp(arg, "-l", 2)) {
- if (!*(arg + 2)) {
- mode = LS_MODE_LONG;
- continue;
- }
- if (*(arg + 3))
- return -E_AFT_SYNTAX;
- switch(*(arg + 2)) {
+ arg += 2;
+ if (*arg == '=')
+ arg++;
+ switch (*arg) {
case 's':
mode = LS_MODE_SHORT;
continue;
case 'l':
+ case '\0':
mode = LS_MODE_LONG;
continue;
case 'v':
flags |= LS_FLAG_UNIXDATE;
continue;
}
+ /* The compatibility remark above applies also to -s. */
if (!strncmp(arg, "-s", 2)) {
- if (!*(arg + 2) || *(arg + 3))
- return -E_AFT_SYNTAX;
- switch(*(arg + 2)) {
+ arg += 2;
+ if (*arg == '=')
+ arg++;
+ switch (*arg) {
case 'p':
sort = LS_SORT_BY_PATH;
continue;
/** The format of the data stored by save_audio_file_data(). */
enum com_add_buffer_offsets {
- /** afhi (if present) starts here. */
+ /* afhi (if present) starts at this offset. */
CAB_AFHI_OFFSET_POS = 0,
/** Start of the chunk table (if present). */
- CAB_CHUNKS_OFFSET_POS = 2,
- /** Audio format id. */
- CAB_AUDIO_FORMAT_OFFSET = 4,
+ CAB_CHUNKS_OFFSET_POS = 4,
/** Flags given to the add command. */
- CAB_FLAGS_OFFSET = 5,
+ CAB_FLAGS_OFFSET = 8,
+ /** Audio format id. */
+ CAB_AUDIO_FORMAT_ID_OFFSET = 12,
/** The hash of the audio file being added. */
- CAB_HASH_OFFSET = 9,
+ CAB_HASH_OFFSET = 13,
/** Start of the path of the audio file. */
CAB_PATH_OFFSET = (CAB_HASH_OFFSET + HASH_SIZE),
};
size_t size = CAB_PATH_OFFSET + path_len + afhi_size
+ sizeof_chunk_table(afhi);
char *buf = para_malloc(size);
- uint16_t pos;
-
- write_u8(buf + CAB_AUDIO_FORMAT_OFFSET, audio_format_num);
- write_u32(buf + CAB_FLAGS_OFFSET, flags);
-
- memcpy(buf + CAB_HASH_OFFSET, hash, HASH_SIZE);
- strcpy(buf + CAB_PATH_OFFSET, path);
+ uint32_t pos;
pos = CAB_PATH_OFFSET + path_len;
- PARA_DEBUG_LOG("size: %zu, afhi starts at %d\n", size, pos);
- PARA_DEBUG_LOG("last afhi byte: %p, pos %zu\n", buf + pos + afhi_size - 1,
- pos + afhi_size - 1);
- write_u16(buf + CAB_AFHI_OFFSET_POS, pos);
+ write_u32(buf + CAB_AFHI_OFFSET_POS, pos);
save_afhi(afhi, buf + pos);
-
pos += afhi_size;
- PARA_DEBUG_LOG("size: %zu, chunks start at %d\n", size, pos);
- write_u16(buf + CAB_CHUNKS_OFFSET_POS, pos);
+
+ write_u32(buf + CAB_CHUNKS_OFFSET_POS, pos);
if (afhi)
save_chunk_table(afhi, buf + pos);
- PARA_DEBUG_LOG("last byte in buf: %p\n", buf + size - 1);
+
+ write_u32(buf + CAB_FLAGS_OFFSET, flags);
+ write_u8(buf + CAB_AUDIO_FORMAT_ID_OFFSET, audio_format_num);
+
+ memcpy(buf + CAB_HASH_OFFSET, hash, HASH_SIZE);
+ strcpy(buf + CAB_PATH_OFFSET, path);
+
obj->data = buf;
obj->size = size;
}
goto out;
}
/* no hs or force mode, child must have sent afhi */
- afhi_offset = read_u16(buf + CAB_AFHI_OFFSET_POS);
- chunks_offset = read_u16(buf + CAB_CHUNKS_OFFSET_POS);
+ afhi_offset = read_u32(buf + CAB_AFHI_OFFSET_POS);
+ chunks_offset = read_u32(buf + CAB_CHUNKS_OFFSET_POS);
objs[AFTCOL_AFHI].data = buf + afhi_offset;
objs[AFTCOL_AFHI].size = chunks_offset - afhi_offset;
goto out;
}
default_afsi.last_played = time(NULL) - 365 * 24 * 60 * 60;
- default_afsi.audio_format_id = read_u8(buf + CAB_AUDIO_FORMAT_OFFSET);
+ default_afsi.audio_format_id = read_u8(buf + CAB_AUDIO_FORMAT_ID_OFFSET);
objs[AFTCOL_AFSI].data = &afsi_buf;
objs[AFTCOL_AFSI].size = AFSI_SIZE;
unsigned char hash[HASH_SIZE];
ret = guess_audio_format(path);
- if (ret < 0 && !(pad->flags & ADD_FLAG_ALL))
+ if (ret < 0 && !(pad->flags & ADD_FLAG_ALL)) {
+ ret = 0;
goto out_free;
+ }
query.data = (char *)path;
query.size = strlen(path) + 1;
ret = send_callback_request(path_brother_callback, &query,
break;
p[len - 1] = '\0';
ret = get_attribute_bitnum_by_name(p, &bitnum);
- if (ret < 0)
+ if (ret < 0) {
+ para_printf(&cad.pb, "attribute not found: %s\n", p);
goto out;
+ }
if (c == '+')
cad.add_mask |= (1UL << bitnum);
else
if (!cad.add_mask && !cad.del_mask)
goto out;
pmd.patterns.data = p;
- assert(p < (char *)query->data + query->size);
+ if (p >= (char *)query->data + query->size)
+ goto out;
pmd.patterns.size = (char *)query->data + query->size - p;
ret = for_each_matching_row(&pmd);
if (ret < 0)
PARA_INFO_LOG("audio file table contains %d files\n", num);
return ret;
}
- PARA_INFO_LOG("failed to open audio file table\n");
+ PARA_NOTICE_LOG("failed to open audio file table\n");
audio_file_table = NULL;
- if (ret >= 0 || ret == -OSL_ERRNO_TO_PARA_ERROR(E_OSL_NOENT))
+ if (ret == -OSL_ERRNO_TO_PARA_ERROR(E_OSL_NOENT))
return 1;
return ret;
}
};
struct pattern_match_data pmd = {
.table = attribute_table,
- .loop_col_num = ATTCOL_BITNUM,
+ .loop_col_num = ATTCOL_NAME,
.match_col_num = ATTCOL_NAME,
.patterns = {.data = (char *)query->data + sizeof(laad.flags),
.size = query->size - sizeof(laad.flags)},
.action = print_attribute
};
if (laad.flags & LSATT_FLAG_SORT_BY_ID)
- pmd.loop_col_num = ATTCOL_NAME;
+ pmd.loop_col_num = ATTCOL_BITNUM;
if (laad.flags & LSATT_FLAG_REVERSE)
pmd.pm_flags |= PM_REVERSE_LOOP;
for_each_matching_row(&pmd);
return ret;
}
attribute_table = NULL;
- if (ret >= 0 || ret == -OSL_ERRNO_TO_PARA_ERROR(E_OSL_NOENT))
+ if (ret == -OSL_ERRNO_TO_PARA_ERROR(E_OSL_NOENT))
return 1;
return ret;
}
#include <sys/un.h>
#include <netdb.h>
#include <signal.h>
+#include <pwd.h>
#include "para.h"
#include "error.h"
static struct status_task status_task_struct;
+static uid_t *uid_whitelist;
+
/**
* the task that calls the status command of para_server
*
static void parse_config_or_die(void)
{
- int ret;
+ int ret, i;
char *config_file;
struct audiod_cmdline_parser_params params = {
.override = 0,
ret = file_exists(config_file);
if (conf.config_file_given && !ret) {
PARA_EMERG_LOG("can not read config file %s\n", config_file);
+ free(config_file);
goto err;
}
if (ret) {
daemon_set_loglevel(conf.loglevel_arg);
}
free(config_file);
+ if (conf.user_allow_given > 0) {
+ uid_whitelist = para_malloc(conf.user_allow_given
+ * sizeof(uid_t));
+ for (i = 0; i < conf.user_allow_given; i++) {
+ int32_t val;
+ struct passwd *pw;
+ ret = para_atoi32(conf.user_allow_arg[i], &val);
+ if (ret >= 0) {
+ uid_whitelist[i] = val;
+ continue;
+ }
+ errno = 0; /* see getpwnam(3) */
+ pw = getpwnam(conf.user_allow_arg[i]);
+ if (!pw) {
+ PARA_EMERG_LOG("invalid username: %s\n",
+ conf.user_allow_arg[i]);
+ goto err;
+ }
+ uid_whitelist[i] = pw->pw_uid;
+ }
+ }
return;
err:
- free(config_file);
exit(EXIT_FAILURE);
}
for (i = 0; i < 2; i++) {
if (ct->fd[i] < 0)
continue;
- ret = handle_connect(ct->fd[i], &s->rfds);
+ ret = handle_connect(ct->fd[i], &s->rfds, uid_whitelist);
if (ret < 0) {
PARA_ERROR_LOG("%s\n", para_strerror(-ret));
if (ret == -E_AUDIOD_TERM) {
close_unused_slots();
audiod_cmdline_parser_free(&conf);
close_stat_clients();
+ free(uid_whitelist);
}
/*
PARA_EMERG_LOG("%s\n", para_strerror(-ret));
exit(EXIT_FAILURE);
}
- daemon_log_welcome("para_audiod");
+ daemon_log_welcome("audiod");
daemon_set_start_time();
set_initial_status();
FOR_EACH_SLOT(i)
*/
enum audiod_status_info {AUDIOD_OFF, AUDIOD_ON, AUDIOD_STANDBY};
-/** defines one command of para_audiod */
-struct audiod_command {
- /** the name of the command */
- const char *name;
- /** pointer to the function that handles the command */
- int (*handler)(int, int, char**);
- /** one-line description of the command */
- const char *description;
- /** summary of the command line options */
- const char *usage;
- /** the long help text */
- const char *help;
-};
-
-__malloc char *audiod_get_decoder_flags(void);
extern struct audiod_args_info conf;
extern int audiod_status;
-int handle_connect(int accept_fd, fd_set *rfds);
+int handle_connect(int accept_fd, fd_set *rfds, uid_t *uid_whitelist);
void audiod_status_dump(bool force);
+__malloc char *audiod_get_decoder_flags(void);
char *get_time_string(void);
struct btr_node *audiod_get_btr_root(void);
#include "para.h"
#include "audiod.cmdline.h"
+#include "audiod.command_list.h"
#include "list.h"
#include "sched.h"
#include "ggo.h"
#include "write.h"
#include "fd.h"
#include "version.h"
-#include "audiod.command_list.h"
extern struct sched sched;
extern char *stat_item_values[NUM_STAT_ITEMS];
+typedef int audiod_command_handler_t(int, int, char **);
+static audiod_command_handler_t AUDIOD_COMMAND_HANDLERS;
+
+/* Defines one command of para_audiod. */
+struct audiod_command {
+ const char *name;
+ /* Pointer to the function that handles the command. */
+ audiod_command_handler_t *handler;
+ /* One-line description. */
+ const char *description;
+ /* Summary of the command line options. */
+ const char *usage;
+ /* The long help text. */
+ const char *help;
+};
static struct audiod_command audiod_cmds[] = {DEFINE_AUDIOD_CMD_ARRAY};
int fd;
/** Bitmask of those status items the client is interested in. */
uint64_t item_mask;
- /** See \ref stat_client flags. s*/
+ /** See \ref stat_client flags. */
unsigned flags;
/** Its entry in the list of stat clients. */
struct list_head node;
static int stat_client_add(int fd, uint64_t mask, int parser_friendly)
{
struct stat_client *new_client;
+ int ret;
if (num_clients >= MAX_STAT_CLIENTS) {
PARA_ERROR_LOG("maximal number of stat clients (%d) exceeded\n",
MAX_STAT_CLIENTS);
return -E_TOO_MANY_CLIENTS;
}
- PARA_INFO_LOG("adding client on fd %d\n", fd);
- new_client = para_calloc(sizeof(struct stat_client));
- new_client->fd = fd;
+ ret = dup(fd);
+ if (ret < 0)
+ return -ERRNO_TO_PARA_ERROR(errno);
+ new_client = para_calloc(sizeof(*new_client));
+ new_client->fd = ret;
+ PARA_INFO_LOG("adding client on fd %d\n", new_client->fd);
new_client->item_mask = mask;
if (parser_friendly)
new_client->flags = SCF_PARSER_FRIENDLY;
return ret;
}
-/*
- * command handlers don't close their fd on errors (ret < 0) so that
- * its caller can send an error message. Otherwise (ret >= 0) it's up
- * to each individual command to close the fd if necessary.
- */
-
static int com_help(int fd, int argc, char **argv)
{
int i, ret;
char *buf;
const char *dflt = "No such command. Available commands:\n";
- if (argc < 2) {
- ret = dump_commands(fd);
- goto out;
- }
+ if (argc < 2)
+ return dump_commands(fd);
FOR_EACH_COMMAND(i) {
if (strcmp(audiod_cmds[i].name, argv[1]))
continue;
);
ret = client_write(fd, buf);
free(buf);
- goto out;
+ return ret;
}
ret = client_write(fd, dflt);
if (ret > 0)
ret = dump_commands(fd);
-out:
- if (ret >= 0)
- close(fd);
return ret;
}
{
char *tl = get_task_list(&sched);
int ret = 1;
+
if (tl)
ret = client_write(fd, tl);
free(tl);
- if (ret > 0)
- close(fd);
return ret;
}
return grab_client_new(fd, argc, argv, &sched);
}
-static int com_term(int fd, __a_unused int argc, __a_unused char **argv)
+static int com_term(__a_unused int fd, __a_unused int argc, __a_unused char **argv)
{
- close(fd);
return -E_AUDIOD_TERM;
}
-static int com_on(int fd, __a_unused int argc, __a_unused char **argv)
+static int com_on(__a_unused int fd, __a_unused int argc, __a_unused char **argv)
{
audiod_status = AUDIOD_ON;
- close(fd);
return 1;
}
-static int com_off(int fd, __a_unused int argc, __a_unused char **argv)
+static int com_off(__a_unused int fd, __a_unused int argc, __a_unused char **argv)
{
audiod_status = AUDIOD_OFF;
- close(fd);
return 1;
}
-static int com_sb(int fd, __a_unused int argc, __a_unused char **argv)
+static int com_sb(__a_unused int fd, __a_unused int argc, __a_unused char **argv)
{
audiod_status = AUDIOD_STANDBY;
- close(fd);
return 1;
}
-static int com_cycle(int fd, int argc, char **argv)
+static int com_cycle(__a_unused int fd, int argc, char **argv)
{
switch (audiod_status) {
case AUDIOD_ON:
return com_off(fd, argc, argv);
break;
}
- close(fd);
return 1;
}
msg = make_message("%s\n", version_single_line("audiod"));
ret = client_write(fd, msg);
free(msg);
- if (ret >= 0)
- close(fd);
return ret;
}
-static int check_perms(uid_t uid)
+static int check_perms(uid_t uid, uid_t *whitelist)
{
int i;
if (!conf.user_allow_given)
return 1;
for (i = 0; i < conf.user_allow_given; i++)
- if (uid == conf.user_allow_arg[i])
+ if (uid == whitelist[i])
return 1;
return -E_UCRED_PERM;
}
*
* \param accept_fd The fd to accept connections on.
* \param rfds If \a accept_fd is not set in \a rfds, do nothing.
+ * \param uid_whitelist Array of UIDs which are allowed to connect.
*
* This is called in each iteration of the select loop. If there is an incoming
* connection on \a accept_fd, this function reads the command sent by the peer,
*
* \sa para_accept(), recv_cred_buffer()
* */
-int handle_connect(int accept_fd, fd_set *rfds)
+int handle_connect(int accept_fd, fd_set *rfds, uid_t *uid_whitelist)
{
int i, argc, ret, clifd;
char buf[MAXLINE], **argv = NULL;
if (ret < 0)
goto out;
uid = ret;
- PARA_INFO_LOG("connection from user %i, buf: %s\n", ret, buf);
- ret = check_perms(uid);
+ PARA_INFO_LOG("connection from user %i, buf: %s\n", ret, buf);
+ ret = check_perms(uid, uid_whitelist);
if (ret < 0)
goto out;
ret = create_argv(buf, "\n", &argv);
ret = -E_INVALID_AUDIOD_CMD;
out:
free_argv(argv);
- if (clifd > 0 && ret < 0 && ret != -E_CLIENT_WRITE) {
+ if (ret < 0 && ret != -E_CLIENT_WRITE) {
char *tmp = make_message("%s\n", para_strerror(-ret));
client_write(clifd, tmp);
free(tmp);
- close(clifd);
}
+ close(clifd);
return ret;
}
#include "wma.h"
#include "bitstream.h"
-/** Read an 8, 16, or 32 bit entity from a VLC table. */
-#define GET_DATA(v, table, i, size) \
-{\
- const uint8_t *ptr = (const uint8_t *)table + i * size; \
- switch (size) { \
- case 1: \
- v = *(const uint8_t *)ptr; \
- break; \
- case 2: \
- v = *(const uint16_t *)ptr; \
- break; \
- default: \
- v = *(const uint32_t *)ptr; \
- break; \
- } \
+static inline uint32_t get_data(const void *table, int i, int size)
+{
+ const uint8_t *ptr = (const uint8_t *)table + i * size;
+ uint32_t v;
+
+ switch (size) {
+ case 1:
+ v = *(const uint8_t *)ptr;
+ break;
+ case 2:
+ v = *(const uint16_t *)ptr;
+ break;
+ default:
+ v = *(const uint32_t *)ptr;
+ break;
+ }
+ return v;
}
static void alloc_table(struct vlc *vlc, int size)
/* map codes and compute auxiliary table sizes */
for (i = 0; i < nb_codes; i++) {
- GET_DATA(n, bits, i, 1);
+ n = get_data(bits, i, 1);
/* we accept tables with holes */
n -= n_prefix;
if (n <= 0)
continue;
- GET_DATA(code, codes, i, codes_size);
+ code = get_data(codes, i, codes_size);
/* if code matches the prefix, it is in the table */
if ((code >> n) != code_prefix)
continue;
ret2 = para_printf(&rmbd.pb, "no matches, nothing removed\n");
else {
ret2 = para_printf(&rmbd.pb, "removed %d blobs\n", pmd.num_matches);
- afs_event(BLOB_RENAME, NULL, table);
+ afs_event(BLOB_REMOVE, NULL, table);
}
out:
if (ret2 >= 0 && rmbd.pb.offset)
struct i9e_completion_result *cr)
{
char *opts[] = {
- "--", "-l", "-ls", "-ll", "-lv", "-lp", "-lm", "-lc", "-p",
- "-a", "-r", "-d", "-sp", "-sl", "-ss", "-sn", "-sf", "-sc",
- "-si", "-sy", "-sb", "-sd", "-sa", NULL
+ "--", "-l", "-l=s", "-l=l", "-l=v", "-l=p", "-l=m", "-l=c",
+ "-p", "-a", "-r", "-d", "-s=p", "-s=l", "-s=s", "-s=n", "-s=f",
+ "-s=c", "-s=i", "-s=y", "-s=b", "-s=d", "-s=a", NULL
};
if (ci->word[0] == '-')
i9e_complete_option(opts, ci, cr);
#include "signal.h"
#include "version.h"
+typedef int server_command_handler_t(struct command_context *);
+static server_command_handler_t SERVER_COMMAND_HANDLERS;
+server_command_handler_t AFS_COMMAND_HANDLERS;
+
+/* Defines one command of para_server. */
+struct server_command {
+ /* The name of the command. */
+ const char *name;
+ /* Pointer to the function that handles the command. */
+ server_command_handler_t *handler;
+ /* The privileges a user must have to execute this command. */
+ unsigned int perms;
+ /* One-line description of the command. */
+ const char *description;
+ /* Summary of the command line options. */
+ const char *usage;
+ /* The long help text. */
+ const char *help;
+};
+
static struct server_command afs_cmds[] = {DEFINE_AFS_CMD_ARRAY};
static struct server_command server_cmds[] = {DEFINE_SERVER_CMD_ARRAY};
const char *subcmds[] = {"add", "delete", "allow", "deny", "on", "off", NULL};
scd->sender_num = -1;
- if (argc < 2)
+ if (argc < 3)
return -E_COMMAND_SYNTAX;
for (i = 0; senders[i].name; i++)
if (!strcmp(senders[i].name, argv[1]))
#define HANDSHAKE_BUFSIZE 4096
-static int parse_sb_command(struct command_context *cc, struct iovec *iov)
+static int run_command(struct command_context *cc, struct iovec *iov,
+ const char *peername)
{
int ret, i;
char *p, *end;
+ struct server_command *cmd;
- ret = -E_BAD_CMD;
if (iov->iov_base == NULL || iov->iov_len == 0)
- goto out;
+ return -E_BAD_CMD;
p = iov->iov_base;
p[iov->iov_len - 1] = '\0'; /* just to be sure */
- cc->cmd = get_cmd_ptr(p, NULL);
- if (!cc->cmd)
- goto out;
- ret = check_perms(cc->u->perms, cc->cmd);
+ cmd = get_cmd_ptr(p, NULL);
+ if (!cmd)
+ return -E_BAD_CMD;
+ ret = check_perms(cc->u->perms, cmd);
if (ret < 0)
- goto out;
+ return ret;
end = iov->iov_base + iov->iov_len;
for (i = 0; p < end; i++)
p += strlen(p) + 1;
p += strlen(p) + 1;
}
cc->argv[cc->argc] = NULL;
- ret = cc->argc;
-out:
- free(iov->iov_base);
+ PARA_NOTICE_LOG("calling com_%s() for %s@%s\n", cmd->name,
+ cc->u->name, peername);
+ ret = cmd->handler(cc);
+ free_argv(cc->argv);
+ mutex_lock(mmd_mutex);
+ mmd->num_commands++;
+ if (ret >= 0 && (cmd->perms & AFS_WRITE))
+ mmd->events++;
+ mutex_unlock(mmd_mutex);
return ret;
}
ret = recv_sb(&cc->scc, SBD_COMMAND, MAX_COMMAND_LEN, &iov);
if (ret < 0)
goto net_err;
- ret = parse_sb_command(cc, &iov);
+ ret = run_command(cc, &iov, peername);
+ free(iov.iov_base);
if (ret < 0)
goto err_out;
- cc->argc = ret;
- PARA_NOTICE_LOG("calling com_%s() for %s@%s\n", cc->cmd->name,
- cc->u->name, peername);
- ret = cc->cmd->handler(cc);
- free_argv(cc->argv);
- mutex_lock(mmd_mutex);
- mmd->num_commands++;
- mutex_unlock(mmd_mutex);
if (ret >= 0)
goto out;
err_out:
free(buf);
free(command);
mutex_lock(mmd_mutex);
- if (cc->cmd && (cc->cmd->perms & AFS_WRITE) && ret >= 0)
- mmd->events++;
mmd->active_connections--;
mutex_unlock(mmd_mutex);
if (ret >= 0) {
int argc;
/** Argument vector. */
char **argv;
- /** The command being executed. */
- const struct server_command *cmd;
/** File descriptor and crypto keys. */
struct stream_cipher_context scc;
};
-/**
- * Defines one command of para_server.
- */
-struct server_command {
- /** The name of the command. */
- const char *name;
- /** Pointer to the function that handles the command. */
- int (*handler)(struct command_context *);
- /** The privileges a user must have to execute this command. */
- unsigned int perms;
- /** One-line description of the command. */
- const char *description;
- /** Summary of the command line options. */
- const char *usage;
- /** The long help text. */
- const char *help;
-};
-
int send_sb(struct stream_cipher_context *scc, void *buf, size_t numbytes,
int band, bool dont_free);
__printf_3_4 int send_sb_va(struct stream_cipher_context *scc, int band,
done
}
-make_proto()
+cmd_handler_name()
{
- local regex='\(__noreturn \)*\(static \)*int com_'
- local source_file match="" all_commands CR='
-'
- if test -n "$prototype"; then
- result="$prototype$CR"
- return
- fi
- all_commands="$(cat $source_files | grep "$regex")"
- result=
- for source_file in $source_files; do
- match=$(grep "$regex$name_txt(" <<< "$all_commands" | head -n 1 | sed -e 's/$/;/1')
- if test -n "$match"; then
- result="$result$match$CR"
- break
- fi
- done
+ result="com_$name_txt,"
}
make_array_member()
com_header()
{
- local array_members CR='
+ local array_members handlers= CR='
'
while : ; do
break
fi
if test $template -eq 0; then
- make_proto
- printf "%s" "$result"
+ cmd_handler_name
+ handlers+="$result"
make_array_member
array_members="$array_members$result"
continue
fi
- template_loop make_proto
- printf "%s" "$result"
+ template_loop cmd_handler_name
+ handlers+="$result"
template_loop make_array_member
array_members="$array_members$result"
done
array_members="$array_members{.name = NULL} \\$CR"
- echo "#define DEFINE_$(tr 'a-z' 'A-Z' <<< "$base_name")_CMD_ARRAY $array_members"
+ echo "#define DEFINE_${base_name^^}_CMD_ARRAY $array_members"
+ echo "#define ${base_name^^}_COMMAND_HANDLERS ${handlers%,}"
}
com_completion()
LIBS="$OLD_LIBS"
])
AC_DEFUN([LIB_SUBST_FLAGS], [
- if test "$HAVE_[]m4_toupper([$1])" == 'yes'; then
+ if test "$HAVE_[]m4_toupper([$1])" = 'yes'; then
AC_DEFINE(HAVE_[]m4_toupper([$1]), 1,
define to 1 to turn on $1 support)
else
AC_C_BIGENDIAN()
-AC_PATH_PROG([gengetopt], [gengetopt])
-test -z "$gengetopt" && AC_MSG_ERROR(
+AC_PATH_PROG([GENGETOPT], [gengetopt])
+test -z "$GENGETOPT" && AC_MSG_ERROR(
[gengetopt is required to build this package])
-AC_PATH_PROG([help2man], [help2man])
-test -z "$help2man" && AC_MSG_ERROR(
+AC_PATH_PROG([HELP2MAN], [help2man])
+test -z "$HELP2MAN" && AC_MSG_ERROR(
[help2man is required to build this package])
-AC_PATH_PROG([install], [install])
-test -z "$install" && AC_MSG_ERROR(
+AC_PATH_PROG([INSTALL], [install])
+test -z "$INSTALL" && AC_MSG_ERROR(
[The install program is required to build this package])
AC_PROG_CC
AC_DEFINE(HAVE_UCRED, 1, define to 1 you have struct ucred)
fi
########################################################################### gengetopt
-echo 'option "z" z "" flag off' | $gengetopt --file-name conftest-ggo &&
+echo 'option "z" z "" flag off' | $GENGETOPT --file-name conftest-ggo &&
AC_CHECK_DECL(
[gengetopt_args_info_description],
[ggo_descriptions_declared=yes],
goto err;
if (chdir("/") < 0)
goto err;
- null = open("/dev/null", O_RDONLY);
+ null = open("/dev/null", O_RDWR);
if (null < 0)
goto err;
if (dup2(null, STDIN_FILENO) < 0)
/**
* Log the startup message containing the paraslash version.
+ *
+ * \param name The name of the executable.
+ *
+ * First the given \a name is prefixed with the string "para_". Next the git
+ * version is appended. The resulting string is logged with priority "INFO".
*/
-void daemon_log_welcome(const char *whoami)
+void daemon_log_welcome(const char *name)
{
- PARA_INFO_LOG("welcome to %s " PACKAGE_VERSION " ("BUILD_DATE")\n",
- whoami);
+ PARA_INFO_LOG("welcome to para_%s-" PACKAGE_VERSION " \n", name);
}
/**
#define AFT_ERRORS \
- PARA_ERROR(BAD_AFSI, "invaiid afs info"), \
+ PARA_ERROR(BAD_AFSI, "invalid afs info"), \
PARA_ERROR(LOCALTIME, "localtime() failed"), \
PARA_ERROR(STRFTIME, "strftime() failed"), \
PARA_ERROR(BAD_PATH, "invalid path"), \
#define STRING_ERRORS \
PARA_ERROR(ATOI_OVERFLOW, "value too large"), \
- PARA_ERROR(STRTOLL, "unknown strtoll error"), \
PARA_ERROR(ATOI_NO_DIGITS, "no digits found in string"), \
PARA_ERROR(ATOI_JUNK_AT_END, "further characters after number"), \
PARA_ERROR(SIZE_PREFIX, "bad size prefix"), \
ret = gc_check_args(argc, argv, gc);
if (ret < 0)
goto err_out;
- gc->fd = fd;
+ ret = dup(fd);
+ if (ret < 0) {
+ ret = -ERRNO_TO_PARA_ERROR(errno);
+ goto err_out;
+ }
+ gc->fd = ret;
para_list_add(&gc->node, &inactive_grab_client_list);
gc_activate(gc, s);
return 1;
option "user-allow" -
#~~~~~~~~~~~~~~~~~~~~
-"allow this uid"
-int typestr="uid"
-default="-1"
+"allow this user to connect to audiod"
+string typestr = "username"
optional
multiple
-details="
- Allow the user identified by \"uid\" to connect to para_audiod.
- May be specified multiple times. If not specified at all,
- all users are allowed to connect.
-
- This feature requires unix socket credentials and is currently
- only supported on Linux systems. On other operating systems,
- the option is silently ignored and all local users are allowed
- to connect to para_audiod.
+details = "
+ Allow the user identified by username (either a string or
+ a UID) to connect to para_audiod. This option may be given
+ multiple times. If not specified at all, all users are allowed
+ to connect.
+
+ This feature is based on the ability to send unix
+ credentials through local sockets using ancillary data
+ (SCM_CREDENTIALS). Currently it only works on Linux. On
+ other operating systems the option is silently ignored and
+ all local users are allowed to connect.
"
option "clock-diff-count" -
define(DEFAULT_CONFIG_FILE,~/.paraslash/client.conf)
define(DEFAULT_HISTORY_FILE,~/.paraslash/client.history)
<qu>
-option "hostname" i "ip or host to connect" string typestr="host" default="localhost" optional
-option "user" u "paraslash username" string typestr="username" default="<current user>" optional
-option "server-port" p "port to connect" int typestr="port" default="2990" optional
-option "key-file" k "(default='~/.paraslash/key.<user>')" string typestr="filename" optional
+option "hostname" i
+#~~~~~~~~~~~~~~~~~~
+"ip or host to connect"
+string typestr = "host"
+default = "localhost"
+optional
+
+option "user" u
+#~~~~~~~~~~~~~~
+"paraslash username"
+string typestr = "username"
+default = "<current user>"
+optional
+
+option "server-port" p
+#~~~~~~~~~~~~~~~~~~~~~
+"port to connect"
+int typestr = "port"
+default = "2990"
+optional
+
+option "key-file" k
+#~~~~~~~~~~~~~~~~~~
+"path to private key"
+string typestr = "filename"
+optional
+details = "
+ If not given, the following files are tried, in order:
+ $HOME/.paraslash/key.$LOGNAME, $HOME/.ssh/id_rsa. It is a fatal
+ error if the key file can not be opened, or is world-readable.
+"
</qu>
include(loglevel.m4)
#~~~~~~~~~~~~~~~~
"run as background daemon"
flag off
-dependon="logfile"
-details="
- Note that </qu>CURRENT_PROGRAM<qu> refuses to start in daemon mode if no
- logfile was specified.
+details = "
+ If this option is given and no logfile was specified, all
+ messages go to /dev/null.
"
</qu>
#include "afs.h"
#include "mm.h"
+/** The comparators for numeric mood methods (year, bitrate, ...). */
#define MOOD_COMPARATORS \
MC(LESS, <) \
MC(LESS_OR_EQUAL, <=) \
MC(GREATER, >) \
MC(GREATER_OR_EQUAL, >=) \
+/** Prefix mood comparator name with "_MC", example: MC_LESS. */
#define MC(a, b) MC_ ## a,
+/** Each mood comparator is identified by an integer of this type. */
enum mood_comparator_id {MOOD_COMPARATORS NUM_MOOD_COMPARATORS};
#undef MC
+/** Stringfied mood comparator, example: "<". */
#define MC(a, b) # b,
+/** Array of mood comparators represented as C strings ("<", "<=", ...). */
static const char *mood_comparators[] = {MOOD_COMPARATORS};
#undef MC
int ret;
char *mood_name = NULL;
+ ret = clear_score_table();
+ if (ret < 0)
+ return ret;
if (!current_mood)
return 1;
PARA_NOTICE_LOG("reloading %s\n", current_mood->name?
int moods_event_handler(enum afs_events event, __a_unused struct para_buffer *pb,
void *data)
{
- int ret;
-
if (!current_mood)
return 0;
switch (event) {
case BLOB_ADD:
if (data == moods_table || data == playlists_table)
return 1; /* no reload necessary for these */
- ret = clear_score_table();
- if (ret < 0)
- PARA_CRIT_LOG("clear score table returned %s\n",
- para_strerror(-ret));
return reload_current_mood();
/* these also require reload of the score table */
case ATTRIBUTE_ADD:
return ret;
}
+/** Suspend decoding if output queue size is larger than that. */
#define OGGDEC_MAX_OUTPUT_SIZE (96 * 1024)
+
+/**
+ * Allocate chunks of this size and produce at most one chunk of output per
+ * ->post_select() invocation. If the buffer could only be filled partially
+ * due to insufficient input being available, it is shrunk to the real output
+ * size and the resized buffer is fed into the output queue.
+ */
#define OGGDEC_OUTPUT_CHUNK_SIZE (32 * 1024)
static void ogg_pre_select(struct sched *s, void *context)
return result;
}
+#include "play.command_list.h"
+
+typedef int play_command_handler_t(struct play_task *, int, char**);
+static play_command_handler_t PLAY_COMMAND_HANDLERS;
+
/* defines one command of para_play */
struct pp_command {
const char *name;
- int (*handler)(struct play_task *, int, char**);
+ play_command_handler_t *handler;
const char *description;
const char *usage;
const char *help;
};
-#include "play.command_list.h"
static struct pp_command pp_cmds[] = {DEFINE_PLAY_CMD_ARRAY};
#define FOR_EACH_COMMAND(c) for (c = 0; pp_cmds[c].name; c++)
/**
* \mainpage Main data structures and selected APIs:
*
- * - Server: \ref server_command, \ref sender,
+ * - Senders: \ref sender,
* - Audio file selector: \ref afs_info, \ref afs_table,
* - Audio format handler: \ref audio_format_handler, \ref afh_info
* - Receivers/filters/writers: \ref receiver, \ref receiver_node,
/**
* Pointer to shared memory area for communication between para_server
- * and its children. Exported to vss.c. command.c and to afs.
+ * and its children. Exported to vss.c, command.c and to afs.
*/
struct misc_meta_data *mmd;
daemon_drop_privileges_or_die(conf.user_arg, conf.group_arg);
/* parse config file, open log and set defaults */
parse_config_or_die(0);
- daemon_log_welcome("para_server");
+ daemon_log_welcome("server");
init_ipc_or_die(); /* init mmd struct and mmd->lock */
daemon_set_start_time();
init_user_list(user_list_file);
};
/**
- * Used for parent-child communication.
+ * Miscellaneous data for communication between server and command handlers.
*
- * There's only one struct of this type which lives in shared memory
- * for communication between the server instances. Access to this
- * area is serialized via mmd_lock() and mmd_unlock(). There are two
- * reasons for a variable to be included here:
+ * There's only one instance of this structure which lives in a shared memory
+ * area. Command handlers communicate with the server process through this
+ * area. Changes made by the command handlers stay after the command handler
+ * exits. Conversely, changes made by the server process propagate to the
+ * command handlers. Access to this area is serialized via mmd_lock() and
+ * mmd_unlock().
*
- * - At least one command (i.e. child of the server) must be able to
- * change its value.
- *
- * or
- *
- * - The contents are listed in the stat command and have to be up to
- * date.
+ * There are two reasons for a variable to be included here: (a) at least one
+ * command handler changes its value, or (b) updates by the server must
+ * propagate to the stat command handlers.
*/
struct misc_meta_data {
/** The size of the current audio file in bytes. */
unsigned int vss_status_flags;
/** The new status flags -- commands may set them. */
unsigned int new_vss_status_flags;
- /** The number of data chunks sent for the current audio file. */
+ /** The number of data chunks sent so far. */
long unsigned chunks_sent;
/** Set by the jmp/ff commands to the new position in chunks. */
long unsigned repos_request;
- /** The number of the chunk currently sent out. */
+ /** The number of the chunk currently being sent. */
long unsigned current_chunk;
/** The milliseconds that have been skipped of the current audio file. */
long offset;
/**
* The event counter.
*
- * Commands may increase this to force a status update to be sent to all
- * connected clients.
+ * Commands may increase this to force a status update to be sent to
+ * all connected stat clients.
*/
unsigned int events;
/** The number of audio files already sent. */
int lookahead;
/** The state information about the current stream. */
ogg_stream_state os;
- /** Whether \a os initialized. */
+ /** Whether \a os is initialized. */
bool stream_init;
};
tmp = strtoll(str, &endptr, 10);
if (errno == ERANGE && (tmp == LLONG_MAX || tmp == LLONG_MIN))
return -E_ATOI_OVERFLOW;
- if (errno != 0 && tmp == 0) /* other error */
- return -E_STRTOLL;
+ /*
+ * If there were no digits at all, strtoll() stores the original value
+ * of str in *endptr.
+ */
if (endptr == str)
return -E_ATOI_NO_DIGITS;
+ /*
+ * The implementation may also set errno and return 0 in case no
+ * conversion was performed.
+ */
+ if (errno != 0 && tmp == 0)
+ return -E_ATOI_NO_DIGITS;
if (*endptr != '\0') /* Further characters after number */
return -E_ATOI_JUNK_AT_END;
*value = tmp;
mmd->offset = tv2ms(&offset);
}
-/*
- * Compute the timeout for the main select-loop of the scheduler.
- *
- * Before the timeout is computed, the current vss status flags are evaluated
- * and acted upon by calling appropriate functions from the lower layers.
- * Possible actions include
- *
- * - request a new audio file from afs,
- * - shutdown of all senders (stop/pause command),
- * - reposition the stream (ff/jmp command).
- */
static void vss_pre_select(struct sched *s, void *context)
{
int i;
struct vss_task *vsst = context;
- if (!vsst->map || vss_next() || vss_paused() || vss_repos()) {
- struct fec_client *fc, *tmp;
- for (i = 0; senders[i].name; i++)
- if (senders[i].shutdown_clients)
- senders[i].shutdown_clients();
- list_for_each_entry_safe(fc, tmp, &fec_client_list, node)
- fc->state = FEC_STATE_NONE;
- mmd->stream_start.tv_sec = 0;
- mmd->stream_start.tv_usec = 0;
- }
- if (vss_next())
- vss_eof(vsst);
- else if (vss_paused()) {
- if (mmd->chunks_sent)
- set_eof_barrier(vsst);
- mmd->chunks_sent = 0;
- } else if (vss_repos()) {
- tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier);
- set_eof_barrier(vsst);
- mmd->chunks_sent = 0;
- mmd->current_chunk = afh_get_start_chunk(mmd->repos_request,
- &mmd->afd.afhi);
- mmd->new_vss_status_flags &= ~VSS_REPOS;
- set_mmd_offset();
- }
if (need_to_request_new_audio_file(vsst)) {
PARA_DEBUG_LOG("ready and playing, but no audio file\n");
para_fd_set(vsst->afs_socket, &s->wfds, &s->max_fileno);
int ret, i;
struct vss_task *vsst = context;
+ if (!vsst->map || vss_next() || vss_paused() || vss_repos()) {
+ /* shut down senders and fec clients */
+ struct fec_client *fc, *tmp;
+ for (i = 0; senders[i].name; i++)
+ if (senders[i].shutdown_clients)
+ senders[i].shutdown_clients();
+ list_for_each_entry_safe(fc, tmp, &fec_client_list, node)
+ fc->state = FEC_STATE_NONE;
+ mmd->stream_start.tv_sec = 0;
+ mmd->stream_start.tv_usec = 0;
+ }
+ if (vss_next())
+ vss_eof(vsst);
+ else if (vss_paused()) {
+ if (mmd->chunks_sent)
+ set_eof_barrier(vsst);
+ mmd->chunks_sent = 0;
+ } else if (vss_repos()) { /* repositioning due to ff/jmp command */
+ tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier);
+ set_eof_barrier(vsst);
+ mmd->chunks_sent = 0;
+ mmd->current_chunk = afh_get_start_chunk(mmd->repos_request,
+ &mmd->afd.afhi);
+ mmd->new_vss_status_flags &= ~VSS_REPOS;
+ set_mmd_offset();
+ }
+ /* If a sender command is pending, run it. */
if (mmd->sender_cmd_data.cmd_num >= 0) {
int num = mmd->sender_cmd_data.cmd_num,
sender_num = mmd->sender_cmd_data.sender_num;
AddDescription "Digital signature" *.asc
AddIcon ../tar-icon.png *.tgz *.tar.bz2
- AddDescription "current master snapshot" -git.tar.bz2
+ AddDescription "current master snapshot" -git.tar.bz2 .g*.tar.bz2 .g*.dirty.tar.bz2
AddDescription "release tarball" *.tgz *.tar.bz2
</ifmodule>
--- /dev/null
+<h1>About</h1>
+<hr>
+
+Paraslash is a collection of network audio streaming tools for Unix
+systems. It is written in C and released under the GPLv2.
+
+<ul>
+ <li> Runs on Linux, Mac OS, FreeBSD, NetBSD </li>
+ <li> Mp3, ogg/vorbis, ogg/speex, aac (m4a), wma, flac and ogg/opus support </li>
+ <li> http, dccp and udp network streaming </li>
+ <li> Stand-alone decoder, player, tagger </li>
+ <li> Curses-based gui (<a href="gui.png">screenshot</a>) </li>
+ <li> Integrated volume normalizer, fader, alarm clock </li>
+ <li> Sophisticated audio file selector </li>
+ <li> Command line interface with tab-completion </li>
+ <li> Open source and well documented </li>
+</ul>
+
+<b> Author: </b> André Noll,
+<a href="mailto:maan@tuebingen.mpg.de">maan@tuebingen.mpg.de</a>
+<br>
+Comments and bug reports are welcome. Please provide the version of
+paraslash you are using and relevant parts of the logs.
+++ /dev/null
-<h1>Contact</h1>
-<hr>
-
-<p> André Noll, <a
-href="mailto:maan@tuebingen.mpg.de">maan@tuebingen.mpg.de</a> </p>
-
-Comments and bug reports are welcome (english, german, or spanish
-language). Please provide enough info such as the version of paraslash
-you are using and relevant parts of the logs. Including the string
-[paraslash] in the subject line is also a good idea.
<tr>
<td valign="top">
<br>
- <a href="index.html">Home</a><br>
- <a href="FEATURES.html">Features</a><br>
- <a href="screenshots.html">Screenshots</a><br>
+ <a href=".">About</a><br>
+ <a href="news.html">News</a><br>
<a href="download.html">Download</a><br>
<a href="documentation.html">Documentation</a><br>
<a href="devel.html">Development</a><br>
- <a href="license.html">License</a><br>
- <a href="contact.html">Contact</a><br>
- <a href="CREDITS.html">Credits</a><br>
</td>
<td>
<tr>
<td valign="top">
<br>
- <a href="../../index.html">Home</a><br>
- <a href="../../FEATURES.html">Features</a><br>
- <a href="../../screenshots.html">Screenshots</a><br>
+ <a href="../..">About</a><br>
+ <a href="../../news.html">News</a><br>
<a href="../../download.html">Download</a><br>
<a href="../../documentation.html">Documentation</a><br>
<a href="../../devel.html">Development</a><br>
- <a href="../../license.html">License</a><br>
- <a href="../../contact.html">Contact</a><br>
- <a href="../../CREDITS.html">Credits</a><br>
</td>
<td>
<h1>API Reference</h1>
+++ /dev/null
-<h1>License</h1>
-<hr>
-
-<p> Paraslash is licensed under the <a
-href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GNU
-General Public License, Version 2</a>, which is generally just
-abbreviated as the GPL license, or just the GPL.</p>
-
-<p> Check out the <a
-href="http://www.gnu.org/cgi-bin/license-quiz.cgi">GPL
-License Quiz</a> or take a look at the <a
-href="http://www.gnu.org/licenses/gpl-faq.html">Frequently Asked
-Questions about the GNU GPL</a>. </p>
-
-<p> As of this writing (June 2007) the author
-does not see any benefits in switching to the new <a
-href="http://www.gnu.org/licenses/gpl-3.0.txt"> version 3 of the
-GPL</a> just released. However, this may change once version 3 becomes
-widely used.</p>
The command
- para_client -- ls -lv
+ para_client -- ls -l=v
gives you a verbose listing of your audio files also showing which
attributes are set.
from the client to the server.
There is no knowledge about the server commands built into para_client,
-so it does not know about addblob commands. Instead, it inspects the
-first data package sent by the server for a magic string. If this
-string was found, it sends STDIN to the server, otherwise it dumps
-data from the server to STDOUT.
+so it does not know about addblob commands. Instead, the server sends
+a special "awaiting data" packet for these commands. If the client
+receives this packet, it sends STDIN to the server, otherwise it
+dumps data from the server to STDOUT.
Streaming protocols
~~~~~~~~~~~~~~~~~~~
operates on undecoded PCM data (visualizers, equalizers etc.). Such
filters are called _decoders_ in general, and xxxdec is the name of
the paraslash decoder for the audio format xxx. For example, the mp3
-decoder filter is called mp3dec.
+decoder is called mp3dec.
Note that the output of the decoder is about 10 times larger than
its input. This means that filters that operate on the decoded audio
Paraslash relies on external libraries for most decoders, so these
libraries must be installed for the decoder to be included in the
-para_filter and para_audiod executables. The oggdec filter depends
-on the libogg and libvorbis libraries for example.
+executables. For example, the mp3dec filter depends on the mad library.
Forward error correction
~~~~~~~~~~~~~~~~~~~~~~~~
+++ /dev/null
-<h1>Screenshots</h1>
-<hr>
-
-<p> The main part of paraslash is a client-server application,
-so it doesn't have much to take a screenshot of. However, here's a
-screenshot of
- <a href="gui.png">para_gui</a>,
-and a text file containing the startup part of
- <a href="server.log">para_server's logfile</a>
-and a similar thing for the logfile of
- <a href="audiod.log">para_audiod</a>.
-Both log files show log output at maximal verbosity.
-</p>
+++ /dev/null
-Dec 29 02:18:32 klar (0) check_receiver_arg: checking udp
-Dec 29 02:18:32 klar (0) check_receiver_arg: checking udp
-Dec 29 02:18:32 klar (0) check_receiver_arg: checking udp
-Dec 29 02:18:32 klar (0) check_receiver_arg: checking udp
-Dec 29 02:18:32 klar (0) check_receiver_arg: checking udp
-Dec 29 02:18:32 klar (0) check_receiver_arg: checking udp
-Dec 29 02:18:32 klar (0) check_receiver_arg: checking udp
-Dec 29 02:18:32 klar (1) parse_receiver_args: receiving wma streams via udp receiver
-Dec 29 02:18:32 klar (1) parse_receiver_args: receiving ogg streams via udp receiver
-Dec 29 02:18:32 klar (1) parse_receiver_args: receiving spx streams via udp receiver
-Dec 29 02:18:32 klar (1) parse_receiver_args: receiving opus streams via udp receiver
-Dec 29 02:18:32 klar (1) parse_receiver_args: receiving aac streams via udp receiver
-Dec 29 02:18:32 klar (1) parse_receiver_args: receiving mp3 streams via udp receiver
-Dec 29 02:18:32 klar (1) parse_receiver_args: receiving flac streams via udp receiver
-Dec 29 02:18:32 klar (1) add_filter: wma filter 0: fecdec
-Dec 29 02:18:32 klar (1) add_filter: ogg filter 0: fecdec
-Dec 29 02:18:32 klar (1) add_filter: spx filter 0: fecdec
-Dec 29 02:18:32 klar (1) add_filter: opus filter 0: fecdec
-Dec 29 02:18:32 klar (1) add_filter: aac filter 0: fecdec
-Dec 29 02:18:32 klar (1) add_filter: mp3 filter 0: fecdec
-Dec 29 02:18:32 klar (1) add_filter: flac filter 0: fecdec
-Dec 29 02:18:32 klar (1) add_filter: mp3 filter 1: mp3dec
-Dec 29 02:18:32 klar (1) add_filter: ogg filter 1: oggdec
-Dec 29 02:18:32 klar (1) add_filter: aac filter 1: aacdec
-Dec 29 02:18:32 klar (1) add_filter: wma filter 1: wmadec
-Dec 29 02:18:32 klar (1) add_filter: spx filter 1: spxdec
-Dec 29 02:18:32 klar (1) add_filter: flac filter 1: flacdec
-Dec 29 02:18:32 klar (1) add_filter: opus filter 1: opusdec
-Dec 29 02:18:32 klar (1) add_filter: wma filter 2: amp
-Dec 29 02:18:32 klar (1) add_filter: ogg filter 2: amp
-Dec 29 02:18:32 klar (1) add_filter: spx filter 2: amp
-Dec 29 02:18:32 klar (1) add_filter: opus filter 2: amp
-Dec 29 02:18:32 klar (1) add_filter: aac filter 2: amp
-Dec 29 02:18:32 klar (1) add_filter: mp3 filter 2: amp
-Dec 29 02:18:32 klar (1) add_filter: flac filter 2: amp
-Dec 29 02:18:32 klar (1) add_filter: wma filter 3: compress
-Dec 29 02:18:32 klar (1) add_filter: ogg filter 3: compress
-Dec 29 02:18:32 klar (1) add_filter: spx filter 3: compress
-Dec 29 02:18:32 klar (1) add_filter: opus filter 3: compress
-Dec 29 02:18:32 klar (1) add_filter: aac filter 3: compress
-Dec 29 02:18:32 klar (1) add_filter: mp3 filter 3: compress
-Dec 29 02:18:32 klar (1) add_filter: flac filter 3: compress
-Dec 29 02:18:32 klar (1) parse_writer_args: wma writer: alsa (default)
-Dec 29 02:18:32 klar (1) parse_writer_args: ogg writer: alsa (default)
-Dec 29 02:18:32 klar (1) parse_writer_args: spx writer: alsa (default)
-Dec 29 02:18:32 klar (1) parse_writer_args: opus writer: alsa (default)
-Dec 29 02:18:32 klar (1) parse_writer_args: aac writer: alsa (default)
-Dec 29 02:18:32 klar (1) parse_writer_args: mp3 writer: alsa (default)
-Dec 29 02:18:32 klar (1) parse_writer_args: flac writer: alsa (default)
-Dec 29 02:18:32 klar (1) log_welcome: welcome to para_audiod git (Sun Dec 29 01:49:51 MET 2013)
-Dec 29 02:18:32 klar (1) clear_slot: clearing slot 0
-Dec 29 02:18:32 klar (1) clear_slot: clearing slot 1
-Dec 29 02:18:32 klar (1) clear_slot: clearing slot 2
-Dec 29 02:18:32 klar (1) clear_slot: clearing slot 3
-Dec 29 02:18:32 klar (1) clear_slot: clearing slot 4
-Dec 29 02:18:32 klar (1) setup_signal_handling: signal pipe: fd 4
-Dec 29 02:18:32 klar (0) para_sigaction: catching signal 2
-Dec 29 02:18:32 klar (0) para_sigaction: catching signal 15
-Dec 29 02:18:32 klar (0) para_sigaction: catching signal 1
-Dec 29 02:18:32 klar (0) para_sigaction: catching signal 13
-Dec 29 02:18:32 klar (1) btr_new_node: added stat as btr root
-Dec 29 02:18:32 klar (2) audiod_get_socket: local socket: /var/paraslash/audiod_socket.klar
-Dec 29 02:18:32 klar (1) register_task: registering signal task (0x807fc2c)
-Dec 29 02:18:32 klar (0) register_task: pre_select: 0x807fc2c
-Dec 29 02:18:32 klar (0) register_task: post_select: 0x807fc30
-Dec 29 02:18:32 klar (1) register_task: registering command task (0xbf84acd0)
-Dec 29 02:18:32 klar (0) register_task: pre_select: 0xbf84acd0
-Dec 29 02:18:32 klar (0) register_task: post_select: 0xbf84acd4
-Dec 29 02:18:32 klar (1) register_task: registering stat (0x807fabc)
-Dec 29 02:18:32 klar (0) register_task: pre_select: 0x807fabc
-Dec 29 02:18:32 klar (0) register_task: post_select: 0x807fac0
-Dec 29 02:18:32 klar (1) client_parse_config: loglevel: warning
-Dec 29 02:18:32 klar (1) client_parse_config: config_file: /home/maan/.paraslash/client.conf
-Dec 29 02:18:32 klar (1) client_parse_config: key_file: /home/maan/.paraslash/key.maan
-Dec 29 02:18:32 klar (2) client_connect: connecting p133:2990
-Dec 29 02:18:32 klar (1) btr_new_node: new root: client recv (was stat)
-Dec 29 02:18:32 klar (1) btr_new_node: added client send as btr root
-Dec 29 02:18:32 klar (1) register_task: registering client (0x80db404)
-Dec 29 02:18:32 klar (0) register_task: pre_select: 0x80db404
-Dec 29 02:18:32 klar (0) register_task: post_select: 0x80db408
-Dec 29 02:18:32 klar (1) parse_features: server feature: sideband
-Dec 29 02:18:32 klar (1) client_post_select: --> auth rsa maan sideband
-Dec 29 02:18:32 klar (1) client_post_select: <-- [challenge] (256 bytes)
-Dec 29 02:18:33 klar (1) client_post_select: --> 3c9229389de0fd26030b79ab4b10719801372d98
-Dec 29 02:18:33 klar (0) send_sb_command: --> stat
-Dec 29 02:18:33 klar (0) dispatch_sbb: band: OUTPUT
-Dec 29 02:18:33 klar (0) dispatch_sbb: band: OUTPUT
-Dec 29 02:18:33 klar (1) clear_slot: clearing slot 0
-Dec 29 02:18:33 klar (1) btr_new_node: added udp as btr root
-Dec 29 02:18:33 klar (1) udp_recv_open: receiving from 224.0.1.38:8000, fd=8
-Dec 29 02:18:33 klar (1) btr_pool_new: udp_recv, 327680 bytes
-Dec 29 02:18:33 klar (2) open_receiver: started ogg: udp receiver in slot 0
-Dec 29 02:18:33 klar (1) register_task: registering udp receiver node (0x80dbfcc)
-Dec 29 02:18:33 klar (0) register_task: pre_select: 0x80dbfcc
-Dec 29 02:18:33 klar (0) register_task: post_select: 0x80dbfd0
-Dec 29 02:18:33 klar (1) open_filters: opening ogg filters
-Dec 29 02:18:33 klar (1) btr_new_node: new leaf node: fecdec (child of udp)
-Dec 29 02:18:33 klar (1) register_task: registering (0x80dc8c8)
-Dec 29 02:18:33 klar (0) register_task: pre_select: 0x80dc8c8
-Dec 29 02:18:33 klar (0) register_task: post_select: 0x80dc8cc
-Dec 29 02:18:33 klar (2) open_filters: ogg filter 0/4 (fecdec) started in slot 0
-Dec 29 02:18:33 klar (1) btr_new_node: new leaf node: oggdec (child of fecdec)
-Dec 29 02:18:33 klar (1) register_task: registering (0x80dca04)
-Dec 29 02:18:33 klar (0) register_task: pre_select: 0x80dca04
-Dec 29 02:18:33 klar (0) register_task: post_select: 0x80dca08
-Dec 29 02:18:33 klar (2) open_filters: ogg filter 1/4 (oggdec) started in slot 0
-Dec 29 02:18:33 klar (1) btr_new_node: new leaf node: amp (child of oggdec)
-Dec 29 02:18:33 klar (1) amp_open: amplification: 0 (scaling factor: 1.00)
-Dec 29 02:18:33 klar (1) register_task: registering (0x80dcb40)
-Dec 29 02:18:33 klar (0) register_task: pre_select: 0x80dcb40
-Dec 29 02:18:33 klar (0) register_task: post_select: 0x80dcb44
-Dec 29 02:18:33 klar (2) open_filters: ogg filter 2/4 (amp) started in slot 0
-Dec 29 02:18:33 klar (1) btr_new_node: new leaf node: compress (child of amp)
-Dec 29 02:18:33 klar (1) register_task: registering (0x80dcc7c)
-Dec 29 02:18:33 klar (0) register_task: pre_select: 0x80dcc7c
-Dec 29 02:18:33 klar (0) register_task: post_select: 0x80dcc80
-Dec 29 02:18:33 klar (2) open_filters: ogg filter 3/4 (compress) started in slot 0
-Dec 29 02:18:33 klar (1) btr_new_node: new leaf node: alsa writer (child of compress)
-Dec 29 02:18:33 klar (1) register_task: registering alsa writer (0x80dc270)
-Dec 29 02:18:33 klar (0) register_task: pre_select: 0x80dc270
-Dec 29 02:18:33 klar (0) register_task: post_select: 0x80dc274
-Dec 29 02:18:33 klar (2) open_writers: alsa writer started in slot 0
-Dec 29 02:18:33 klar (2) udp
-Dec 29 02:18:33 klar (2) fecdec
-Dec 29 02:18:33 klar (2) oggdec
-Dec 29 02:18:33 klar (2) amp
-Dec 29 02:18:33 klar (2) compress
-Dec 29 02:18:33 klar (2) alsa writer
-Dec 29 02:18:33 klar (2) btr_splice_out_node: splicing out amp
-Dec 29 02:18:33 klar (1) btr_splice_out_node: parent(compress): oggdec
-Dec 29 02:18:33 klar (1) unregister_task: unregistering amp (slot 0) (no amplification necessary)
-Dec 29 02:18:33 klar (0) add_slice: group 374 complete, ignoring slice 26
-Dec 29 02:18:33 klar (0) add_slice: group 375 complete, ignoring slice 26
-Dec 29 02:18:33 klar (2) dispatch_slice: init fec (26, 27)
-Dec 29 02:18:33 klar (1) btr_pool_new: fecdec, 131072 bytes
-Dec 29 02:18:33 klar (0) decode_group: decoding group 375 (26 slices)
-Dec 29 02:18:33 klar (0) decode_group: writing group 375 (4245/8710 decoded data bytes)
-Dec 29 02:18:33 klar (1) decode_group: writing audio file header
-Dec 29 02:18:33 klar (0) decode_group: decoding group 376 (26 slices)
-Dec 29 02:18:33 klar (0) decode_group: writing group 376 (4157/4160 decoded data bytes)
-Dec 29 02:18:33 klar (2) ogg_init: iqs: 12752, min_iqs: 8000, opening ov callbacks
-Dec 29 02:18:33 klar (0) cb_read: vorbis requests 65536 bytes have 12752
-Dec 29 02:18:33 klar (2) ogg_init: 2 channels, 44100 Hz
-Dec 29 02:18:33 klar (0) add_slice: group 376 complete, ignoring slice 26
-Dec 29 02:18:34 klar (0) decode_group: decoding group 377 (26 slices)
-Dec 29 02:18:34 klar (0) decode_group: writing group 377 (4370/4394 decoded data bytes)
-Dec 29 02:18:34 klar (0) add_slice: group 377 complete, ignoring slice 26
-Dec 29 02:18:34 klar (0) decode_group: decoding group 378 (26 slices)
-Dec 29 02:18:34 klar (0) decode_group: writing group 378 (4230/4238 decoded data bytes)
-Dec 29 02:18:34 klar (0) add_slice: group 378 complete, ignoring slice 26
-Dec 29 02:18:34 klar (0) decode_group: decoding group 379 (26 slices)
-Dec 29 02:18:34 klar (0) decode_group: writing group 379 (4193/4212 decoded data bytes)
-Dec 29 02:18:34 klar (0) cb_read: vorbis requests 65536 bytes have 12793
-Dec 29 02:18:34 klar (1) btr_exec_up: executing sample_rate on oggdec
-Dec 29 02:18:34 klar (1) btr_exec_up: sample_rate(oggdec): 44100
-Dec 29 02:18:34 klar (1) btr_exec_up: executing channels on oggdec
-Dec 29 02:18:34 klar (1) btr_exec_up: channels(oggdec): 2
-Dec 29 02:18:34 klar (1) btr_exec_up: executing sample_format on oggdec
-Dec 29 02:18:34 klar (1) btr_exec_up: sample_format(oggdec): 2
-Dec 29 02:18:34 klar (1) alsa_write_post_select: 2 channel(s), 44100Hz
-Dec 29 02:18:34 klar (1) alsa_init: opening default
-Dec 29 02:18:35 klar (1) alsa_init: dumping alsa configuration
-Dec 29 02:18:35 klar (1) alsa_init: Plug PCM: Rate conversion PCM (48000, sformat=S16_LE)
-Dec 29 02:18:35 klar (1) alsa_init: Converter: linear-interpolation
-Dec 29 02:18:35 klar (1) alsa_init: Protocol version: 10002
-Dec 29 02:18:35 klar (1) alsa_init: Its setup is:
-Dec 29 02:18:35 klar (1) alsa_init: stream : PLAYBACK
-Dec 29 02:18:35 klar (1) alsa_init: access : RW_INTERLEAVED
-Dec 29 02:18:35 klar (1) alsa_init: format : S16_LE
-Dec 29 02:18:35 klar (1) alsa_init: subformat : STD
-Dec 29 02:18:35 klar (1) alsa_init: channels : 2
-Dec 29 02:18:35 klar (1) alsa_init: rate : 44100
-Dec 29 02:18:35 klar (1) alsa_init: exact rate : 44100 (44100/1)
-Dec 29 02:18:35 klar (1) alsa_init: msbits : 16
-Dec 29 02:18:35 klar (1) alsa_init: buffer_size : 15052
-Dec 29 02:18:35 klar (1) alsa_init: period_size : 940
-Dec 29 02:18:35 klar (1) alsa_init: period_time : 21333
-Dec 29 02:18:35 klar (1) alsa_init: tstamp_mode : NONE
-Dec 29 02:18:35 klar (1) alsa_init: period_step : 1
-Dec 29 02:18:35 klar (1) alsa_init: avail_min : 940
-Dec 29 02:18:35 klar (1) alsa_init: period_event : 0
-Dec 29 02:18:35 klar (1) alsa_init: start_threshold : 15052
-Dec 29 02:18:35 klar (1) alsa_init: stop_threshold : 15052
-Dec 29 02:18:35 klar (1) alsa_init: silence_threshold: 0
-Dec 29 02:18:35 klar (1) alsa_init: silence_size : 0
-Dec 29 02:18:35 klar (1) alsa_init: boundary : 986447872
-Dec 29 02:18:35 klar (1) alsa_init: Slave: Direct Stream Mixing PCM
-Dec 29 02:18:35 klar (1) alsa_init: Its setup is:
-Dec 29 02:18:35 klar (1) alsa_init: stream : PLAYBACK
-Dec 29 02:18:35 klar (1) alsa_init: access : MMAP_INTERLEAVED
-Dec 29 02:18:35 klar (1) alsa_init: format : S16_LE
-Dec 29 02:18:35 klar (1) alsa_init: subformat : STD
-Dec 29 02:18:35 klar (1) alsa_init: channels : 2
-Dec 29 02:18:35 klar (1) alsa_init: rate : 48000
-Dec 29 02:18:35 klar (1) alsa_init: exact rate : 48000 (48000/1)
-Dec 29 02:18:35 klar (1) alsa_init: msbits : 16
-Dec 29 02:18:35 klar (1) alsa_init: buffer_size : 16384
-Dec 29 02:18:35 klar (1) alsa_init: period_size : 1024
-Dec 29 02:18:35 klar (1) alsa_init: period_time : 21333
-Dec 29 02:18:35 klar (1) alsa_init: tstamp_mode : NONE
-Dec 29 02:18:35 klar (1) alsa_init: period_step : 1
-Dec 29 02:18:35 klar (1) alsa_init: avail_min : 1024
-Dec 29 02:18:35 klar (1) alsa_init: period_event : 0
-Dec 29 02:18:35 klar (1) alsa_init: start_threshold : 16384
-Dec 29 02:18:35 klar (1) alsa_init: stop_threshold : 16384
-Dec 29 02:18:35 klar (1) alsa_init: silence_threshold: 0
-Dec 29 02:18:35 klar (1) alsa_init: silence_size : 0
-Dec 29 02:18:35 klar (1) alsa_init: boundary : 1073741824
-Dec 29 02:18:35 klar (1) alsa_init: Hardware PCM card 0 'Ensoniq AudioPCI' device 0 subdevice 0
-Dec 29 02:18:35 klar (1) alsa_init: Its setup is:
-Dec 29 02:18:35 klar (1) alsa_init: stream : PLAYBACK
-Dec 29 02:18:35 klar (1) alsa_init: access : MMAP_INTERLEAVED
-Dec 29 02:18:35 klar (1) alsa_init: format : S16_LE
-Dec 29 02:18:35 klar (1) alsa_init: subformat : STD
-Dec 29 02:18:35 klar (1) alsa_init: channels : 2
-Dec 29 02:18:35 klar (1) alsa_init: rate : 48000
-Dec 29 02:18:35 klar (1) alsa_init: exact rate : 48000 (1572864000/32768)
-Dec 29 02:18:35 klar (1) alsa_init: msbits : 16
-Dec 29 02:18:35 klar (1) alsa_init: buffer_size : 16384
-Dec 29 02:18:35 klar (1) alsa_init: period_size : 1024
-Dec 29 02:18:35 klar (1) alsa_init: period_time : 21333
-Dec 29 02:18:35 klar (1) alsa_init: tstamp_mode : ENABLE
-Dec 29 02:18:35 klar (1) alsa_init: period_step : 1
-Dec 29 02:18:35 klar (1) alsa_init: avail_min : 1024
-Dec 29 02:18:35 klar (1) alsa_init: period_event : 0
-Dec 29 02:18:35 klar (1) alsa_init: start_threshold : 1
-Dec 29 02:18:35 klar (1) alsa_init: stop_threshold : 1073741824
-Dec 29 02:18:35 klar (1) alsa_init: silence_threshold: 0
-Dec 29 02:18:35 klar (1) alsa_init: silence_size : 1073741824
-Dec 29 02:18:35 klar (1) alsa_init: boundary : 1073741824
-Dec 29 02:18:35 klar (1) alsa_init: appl_ptr : 0
-Dec 29 02:18:35 klar (1) alsa_init: hw_ptr : 1040
-Dec 29 02:18:35 klar (0) add_slice: group 379 complete, ignoring slice 26
-Dec 29 02:18:35 klar (0) decode_group: decoding group 380 (26 slices)
-Dec 29 02:18:35 klar (0) decode_group: writing group 380 (4158/4160 decoded data bytes)
-Dec 29 02:18:35 klar (0) add_slice: group 380 complete, ignoring slice 26
-Dec 29 02:18:35 klar (0) decode_group: decoding group 381 (26 slices)
-Dec 29 02:18:35 klar (0) decode_group: writing group 381 (4241/4264 decoded data bytes)
-Dec 29 02:18:35 klar (0) add_slice: group 381 complete, ignoring slice 26
-Dec 29 02:18:35 klar (0) cb_read: vorbis requests 65536 bytes have 8399
-Dec 29 02:18:35 klar (0) cb_read: vorbis requests 65536 bytes have 0
-Dec 29 02:18:35 klar (0) decode_group: decoding group 382 (26 slices)
-Dec 29 02:18:35 klar (0) decode_group: writing group 382 (4281/4290 decoded data bytes)
-Dec 29 02:18:35 klar (0) add_slice: group 382 complete, ignoring slice 26
-Dec 29 02:18:35 klar (0) cb_read: vorbis requests 65536 bytes have 4281
-Dec 29 02:18:35 klar (0) cb_read: vorbis requests 65536 bytes have 0
+++ /dev/null
-Dec 29 02:12:57 (1) (16077) log_welcome: welcome to para_server git (Sun Dec 29 01:49:51 MET 2013)
-Dec 29 02:12:57 (0) (16077) populate_user_list: found entry for user maan
-Dec 29 02:12:57 (0) (16077) populate_user_list: found 4 perm entries
-Dec 29 02:12:57 (0) (16077) populate_user_list: found entry for user sshmaan
-Dec 29 02:12:57 (1) (16077) get_asymmetric_key: decoding public rsa-ssh key /home/maan/.ssh/id_rsa.pub
-Dec 29 02:12:57 (0) (16077) check_ssh_key_header: type: ssh-rsa, rlen: 7
-Dec 29 02:12:57 (0) (16077) read_bignum: bnsize: 3
-Dec 29 02:12:57 (0) (16077) read_bignum: bnsize: 257
-Dec 29 02:12:57 (0) (16077) populate_user_list: found 4 perm entries
-Dec 29 02:12:57 (0) (16077) populate_user_list: found entry for user install
-Dec 29 02:12:57 (3) (16077) populate_user_list: public key /home/maan/.paraslash/key.pub.install too short (64)
-Dec 29 02:12:57 (0) (16077) populate_user_list: found entry for user www
-Dec 29 02:12:57 (3) (16077) populate_user_list: public key /home/maan/.paraslash/key.pub.www too short (64)
-Dec 29 02:12:57 (0) (16077) populate_user_list: found entry for user maan@albrecht
-Dec 29 02:12:57 (0) (16077) populate_user_list: found 2 perm entries
-Dec 29 02:12:57 (2) (16077) server_init: initializing audio format handlers
-Dec 29 02:12:57 (1) (16077) afh_init: supported audio formats: mp3 wma ogg spx aac flac
-Dec 29 02:12:57 (2) (16077) afh_init: initializing mp3 handler
-Dec 29 02:12:57 (2) (16077) afh_init: initializing ogg handler
-Dec 29 02:12:57 (2) (16077) afh_init: initializing aac handler
-Dec 29 02:12:57 (2) (16077) afh_init: initializing wma handler
-Dec 29 02:12:57 (2) (16077) afh_init: initializing spx handler
-Dec 29 02:12:57 (2) (16077) afh_init: initializing flac handler
-Dec 29 02:12:57 (2) (16077) afh_init: initializing opus handler
-Dec 29 02:12:57 (0) (16077) para_sigaction: catching signal 10
-Dec 29 02:12:57 (0) (16077) para_block_signal: blocking signal 17
-Dec 29 02:12:57 (2) (16077) server_init: initializing the audio file selector
-Dec 29 02:12:57 (1) (16077) init_afs: afs_socket: 4, afs_socket_cookie: 3213854017
-Dec 29 02:12:57 (2) (16077) init_signal_task: setting up signal handling
-Dec 29 02:12:57 (0) (16077) para_sigaction: catching signal 2
-Dec 29 02:12:57 (0) (16077) para_sigaction: catching signal 15
-Dec 29 02:12:57 (0) (16078) para_sigaction: catching signal 13
-Dec 29 02:12:57 (0) (16077) para_sigaction: catching signal 1
-Dec 29 02:12:57 (0) (16077) para_sigaction: catching signal 17
-Dec 29 02:12:57 (0) (16077) para_sigaction: catching signal 13
-Dec 29 02:12:57 (1) (16077) register_task: registering signal task (0x807c3e4)
-Dec 29 02:12:57 (0) (16077) register_task: pre_select: 0x807c3e4
-Dec 29 02:12:57 (0) (16077) register_task: post_select: 0x807c3e8
-Dec 29 02:12:57 (0) (16077) para_unblock_signal: unblocking signal 17
-Dec 29 02:12:57 (2) (16077) server_init: initializing virtual streaming system
-Dec 29 02:12:57 (1) (16078) register_signal_task: signal pipe: fd 4
-Dec 29 02:12:57 (0) (16078) para_sigaction: catching signal 2
-Dec 29 02:12:57 (0) (16078) para_sigaction: catching signal 15
-Dec 29 02:12:57 (1) (16077) init_vss_task: announce timeval: 300ms
-Dec 29 02:12:57 (0) (16078) para_sigaction: catching signal 1
-Dec 29 02:12:57 (2) (16077) init_vss_task: initializing http sender
-Dec 29 02:12:57 (1) (16078) register_task: registering signal task (0x807cec4)
-Dec 29 02:12:57 (0) (16078) register_task: pre_select: 0x807cec4
-Dec 29 02:12:57 (1) (16077) acl_add_entry: adding 192.168.0.0/24 to access list
-Dec 29 02:12:57 (0) (16078) register_task: post_select: 0x807cec8
-Dec 29 02:12:57 (1) (16077) acl_add_entry: adding 127.0.0.1/32 to access list
-Dec 29 02:12:57 (1) (16078) get_database_dir: afs_database dir /home/maan/.paraslash/afs_database-0.4
-Dec 29 02:12:57 (2) (16078) open_afs_tables: opening 7 osl tables in /home/maan/.paraslash/afs_database-0.4
-Dec 29 02:12:57 (1) (16077) para_listen: listening on TCP port 8000, fd 7
-Dec 29 02:12:57 (2) (16077) init_vss_task: initializing dccp sender
-Dec 29 02:12:57 (1) (16077) para_listen: listening on DCCP port 8000, fd 8
-Dec 29 02:12:57 (2) (16077) init_vss_task: initializing udp sender
-Dec 29 02:12:57 (1) (16077) udp_com_add: adding to target list (224.0.1.38:8000)
-Dec 29 02:12:57 (1) (16077) udp_com_add: adding to target list (192.168.0.2:8000)
-Dec 29 02:12:57 (0) (16077) udp_send_init: udp sender init complete
-Dec 29 02:12:57 (1) (16077) register_task: registering vss task (0x807c65c)
-Dec 29 02:12:57 (0) (16077) register_task: pre_select: 0x807c65c
-Dec 29 02:12:57 (0) (16077) register_task: post_select: 0x807c660
-Dec 29 02:12:57 (2) (16077) init_server_command_task: initializing tcp command socket
-Dec 29 02:12:57 (1) (16077) para_listen: listening on TCP port 2990, fd 11
-Dec 29 02:12:57 (1) (16077) register_task: registering server command task (0x807c2c0)
-Dec 29 02:12:57 (0) (16077) register_task: pre_select: 0x807c2c0
-Dec 29 02:12:57 (0) (16077) register_task: post_select: 0x807c2c4
-Dec 29 02:12:57 (2) (16077) server_init: server init complete
-Dec 29 02:12:57 (0) (16077) status_refresh: 0 events, forcing status update
-Dec 29 02:12:57 (1) (16078) aft_open: audio file table contains 9212 files
-Dec 29 02:12:57 (1) (16078) afs_init: server_socket: 5, afs_socket_cookie: 3213854017
-Dec 29 02:12:57 (0) (16078) parse_mood_line: accept entry added, method: 0x806fdac
-Dec 29 02:12:57 (2) (16078) change_current_mood: computing statistics of admissible files
-Dec 29 02:12:57 (1) (16078) log_statistics: last_played mean: 1385279255, last_played sigma: 2805987
-Dec 29 02:12:57 (1) (16078) log_statistics: num_played mean: 48, num_played sigma: 18
-Dec 29 02:12:57 (1) (16078) change_current_mood: 26 admissible files
-Dec 29 02:12:57 (2) (16078) change_current_mood: loaded mood gulp
-Dec 29 02:12:57 (1) (16078) setup_command_socket_or_die: listening on socket /var/paraslash/afs_command_socket-0.4 (fd 7)
-Dec 29 02:12:57 (1) (16078) register_task: registering afs command task (0x807cfec)
-Dec 29 02:12:57 (0) (16078) register_task: pre_select: 0x807cfec
-Dec 29 02:12:57 (0) (16078) register_task: post_select: 0x807cff0
-Dec 29 02:12:57 (1) (16077) command_post_select: got connection from 192.168.0.4:60731, forking
-Dec 29 02:12:57 (0) (16079) close_listed_fds: closing fd 11
-Dec 29 02:12:57 (0) (16079) close_listed_fds: closing fd 10
-Dec 29 02:12:57 (0) (16079) close_listed_fds: closing fd 9
-Dec 29 02:12:57 (0) (16079) close_listed_fds: closing fd 8
-Dec 29 02:12:57 (0) (16079) close_listed_fds: closing fd 7
-Dec 29 02:12:57 (0) (16079) close_listed_fds: closing fd 5
-Dec 29 02:12:57 (0) (16079) close_listed_fds: closing fd 4
-Dec 29 02:12:57 (0) (16079) para_sigaction: catching signal 17
-Dec 29 02:12:57 (0) (16079) para_sigaction: catching signal 2
-Dec 29 02:12:57 (0) (16079) para_sigaction: catching signal 15
-Dec 29 02:12:57 (0) (16079) para_sigaction: catching signal 1
-Dec 29 02:12:57 (0) (16079) parse_auth_request: received auth request for user maan
-Dec 29 02:12:57 (0) (16079) handle_connect: received auth request for user maan
-Dec 29 02:12:57 (0) (16079) handle_connect: sending 64 byte challenge + rc4 keys (256 bytes)
-Dec 29 02:12:57 (0) (16079) handle_connect: received 20 bytes challenge response
-Dec 29 02:12:57 (1) (16079) handle_connect: good auth for maan
-Dec 29 02:12:57 (0) (16079) check_perms: checking permissions
-Dec 29 02:12:57 (2) (16079) handle_connect: calling com_stat() for maan@192.168.0.4:60731
-Dec 29 02:12:57 (0) (16079) para_sigaction: catching signal 10
-Dec 29 02:13:02 (1) (16077) command_post_select: got connection from 192.168.0.1:58527, forking
-Dec 29 02:13:02 (0) (16080) close_listed_fds: closing fd 11
-Dec 29 02:13:02 (0) (16080) close_listed_fds: closing fd 10
-Dec 29 02:13:02 (0) (16080) close_listed_fds: closing fd 9
-Dec 29 02:13:02 (0) (16080) close_listed_fds: closing fd 8
-Dec 29 02:13:02 (0) (16080) close_listed_fds: closing fd 7
-Dec 29 02:13:02 (0) (16080) close_listed_fds: closing fd 5
-Dec 29 02:13:02 (0) (16080) close_listed_fds: closing fd 4
-Dec 29 02:13:02 (0) (16080) para_sigaction: catching signal 17
-Dec 29 02:13:02 (0) (16080) para_sigaction: catching signal 2
-Dec 29 02:13:02 (0) (16080) para_sigaction: catching signal 15
-Dec 29 02:13:02 (0) (16080) para_sigaction: catching signal 1
-Dec 29 02:13:02 (0) (16080) parse_auth_request: received auth request for user maan
-Dec 29 02:13:02 (0) (16080) handle_connect: received auth request for user maan
-Dec 29 02:13:02 (0) (16080) handle_connect: sending 64 byte challenge + rc4 keys (256 bytes)
-Dec 29 02:13:02 (0) (16080) handle_connect: received 20 bytes challenge response
-Dec 29 02:13:02 (1) (16080) handle_connect: good auth for maan
-Dec 29 02:13:02 (0) (16080) check_perms: checking permissions
-Dec 29 02:13:02 (2) (16080) handle_connect: calling com_stat() for maan@192.168.0.1:58527
-Dec 29 02:13:02 (0) (16080) para_sigaction: catching signal 10
-Dec 29 02:13:09 (1) (16077) command_post_select: got connection from 192.168.0.1:58528, forking
-Dec 29 02:13:09 (0) (16089) close_listed_fds: closing fd 11
-Dec 29 02:13:09 (0) (16089) close_listed_fds: closing fd 10
-Dec 29 02:13:09 (0) (16089) close_listed_fds: closing fd 9
-Dec 29 02:13:09 (0) (16089) close_listed_fds: closing fd 8
-Dec 29 02:13:09 (0) (16089) close_listed_fds: closing fd 7
-Dec 29 02:13:09 (0) (16089) close_listed_fds: closing fd 5
-Dec 29 02:13:09 (0) (16089) close_listed_fds: closing fd 4
-Dec 29 02:13:09 (0) (16089) para_sigaction: catching signal 17
-Dec 29 02:13:09 (0) (16089) para_sigaction: catching signal 2
-Dec 29 02:13:09 (0) (16089) para_sigaction: catching signal 15
-Dec 29 02:13:09 (0) (16089) para_sigaction: catching signal 1
-Dec 29 02:13:09 (0) (16089) parse_auth_request: received auth request for user maan
-Dec 29 02:13:09 (0) (16089) handle_connect: received auth request for user maan
-Dec 29 02:13:09 (0) (16089) handle_connect: sending 64 byte challenge + rc4 keys (256 bytes)
-Dec 29 02:13:09 (0) (16089) handle_connect: received 20 bytes challenge response
-Dec 29 02:13:09 (1) (16089) handle_connect: good auth for maan
-Dec 29 02:13:09 (0) (16089) check_perms: checking permissions
-Dec 29 02:13:09 (2) (16089) handle_connect: calling com_play() for maan@192.168.0.1:58528
-Dec 29 02:13:09 (0) (16077) para_next_signal: next signal: 17
-Dec 29 02:13:09 (0) (16077) para_reap_child: child 16089 exited. Exit status: 0
-Dec 29 02:13:09 (0) (16077) vss_pre_select: ready and playing, but no audio file
-Dec 29 02:13:09 (0) (16077) status_refresh: 1 events, forcing status update
-Dec 29 02:13:09 (2) (16077) vss_post_select: requesting new fd from afs
-Dec 29 02:13:09 (2) (16078) open_next_audio_file: getting next audio file
-Dec 29 02:13:09 (2) (16078) open_and_update_audio_file: /home/mp3/checked/dvd_07/cd_45/The_G.U.L.P.__Popstar.ogg
-Dec 29 02:13:09 (1) (16078) shm_get_shmmax: shmmax: 33554432
-Dec 29 02:13:09 (0) (16078) mood_update_audio_file: score: -11
-Dec 29 02:13:09 (0) (16078) mood_update_audio_file: moving from rank 26 to 29%
-Dec 29 02:13:09 (0) (16078) score_update: new score: -13, rank 8/26
-Dec 29 02:13:09 (0) (16078) score_update: new score: -67, rank 1/26
-Dec 29 02:13:09 (0) (16078) pass_afd: passing 8 bytes and fd 8
-Dec 29 02:13:09 (0) (16077) recv_afs_result: fd: 12, code: 0, shmid: 121700353
-Dec 29 02:13:09 (0) (16077) vorbis_get_header_callback: processing ogg packet #0
-Dec 29 02:13:09 (0) (16077) add_ogg_page: header/body/old/new: 28/30/0/58
-Dec 29 02:13:09 (1) (16077) process_packets_2_and_3: ogg page serial: 867600341
-Dec 29 02:13:09 (0) (16077) vorbis_get_header_callback: processing ogg packet #1
-Dec 29 02:13:09 (1) (16077) vorbis_get_header_callback: replacing metadata packet
-Dec 29 02:13:09 (1) (16077) process_packets_2_and_3: ogg page serial: 867600341
-Dec 29 02:13:09 (0) (16077) vorbis_get_header_callback: processing ogg packet #2
-Dec 29 02:13:09 (0) (16077) add_ogg_page: header/body/old/new: 45/4247/58/4350
-Dec 29 02:13:09 (1) (16077) vorbis_get_header: created 4350 byte ogg vorbis header
-Dec 29 02:13:09 (0) (16077) chk_barrier: data send barrier: 203ms left
-Dec 29 02:13:09 (0) (16077) status_refresh: 2 events, forcing status update
-Dec 29 02:13:09 (0) (16079) connect_local_socket: connecting to /var/paraslash/afs_command_socket-0.4
-Dec 29 02:13:09 (0) (16080) connect_local_socket: connecting to /var/paraslash/afs_command_socket-0.4
-Dec 29 02:13:09 (2) (16077) udp_init_session: sending to udp 192.168.0.2:8000
-Dec 29 02:13:09 (1) (16077) udp_init_fec: current MPS = 548 bytes
-Dec 29 02:13:09 (1) (16077) initialize_fec_client: mps: 548, k: 26, n: 28, extra slices: 12
-Dec 29 02:13:09 (0) (16077) set_group_timing: durations (group/chunk/slice): 226/226/8
-Dec 29 02:13:09 (0) (16077) setup_next_fec_group: FEC group 0: 1 chunks (0 - 0), 4350 bytes
-Dec 29 02:13:09 (0) (16077) setup_next_fec_group: slice_bytes: 168, 0 header slices, 26 data slices
-Dec 29 02:13:09 (0) (16077) vss_send: sending 0:0 (168 bytes)
-Dec 29 02:13:09 (2) (16077) udp_init_session: sending to udp 224.0.1.38:8000
-Dec 29 02:13:09 (1) (16077) udp_init_fec: current MPS = 548 bytes
-Dec 29 02:13:09 (1) (16077) initialize_fec_client: mps: 548, k: 26, n: 27, extra slices: 24
-Dec 29 02:13:09 (0) (16077) set_group_timing: durations (group/chunk/slice): 226/226/8
-Dec 29 02:13:09 (0) (16077) setup_next_fec_group: FEC group 0: 1 chunks (0 - 0), 4350 bytes
-Dec 29 02:13:09 (0) (16077) setup_next_fec_group: slice_bytes: 168, 0 header slices, 26 data slices
-Dec 29 02:13:09 (0) (16077) vss_send: sending 0:0 (168 bytes)
-Dec 29 02:13:09 (0) (16077) status_refresh: 3 events, forcing status update
-Dec 29 02:13:09 (0) (16079) connect_local_socket: connecting to /var/paraslash/afs_command_socket-0.4
-Dec 29 02:13:09 (0) (16080) connect_local_socket: connecting to /var/paraslash/afs_command_socket-0.4
-Dec 29 02:13:09 (0) (16077) vss_send: sending 0:1 (168 bytes)
-Dec 29 02:13:09 (0) (16077) vss_send: sending 0:1 (168 bytes)
-Dec 29 02:13:09 (0) (16077) vss_send: sending 0:2 (168 bytes)
-Dec 29 02:13:09 (0) (16077) vss_send: sending 0:2 (168 bytes)
-Dec 29 02:13:09 (0) (16077) vss_send: sending 0:3 (168 bytes)