Was cooking in next for three weeks.
* t/lib_arg_with:
build: Fix curses detection.
build: Convert curses detection to new macros.
build: Convert libreadline detection to new macros.
build: Convert oss detection to new macros.
build: Convert libsamplerate detection to new macros.
build: Convert libao detection to new macros.
build: Convert alsa detection to new macros.
build: Convert flac detection to new macros.
build: Convert libid3tag detection to new macros.
build: Convert mad detection to new macros.
build: Convert faad detection to new macros.
build: Convert crypto detection/selection to new macros.
build: Convert opus detection to new macros.
build: Convert speex detection to new macros.
build: convert vorbis detection to new macros.
build: Convert ogg detection to new macros.
build: Reduce redundancy in configure.ac, convert osl detection.
paraslash-*.tar.bz2
web/dia/overview.pdf
*.swp
+*.rej
+*~
error2.h
web_sync
confdefs.h
- 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.
+ - New autoconf macros to avoid duplication in configure.ac.
+
Download: ./releases/paraslash-git.tar.bz2 (tarball)
------------------------------------------
* copied. It then notifies the afs process that the callback function \a f
* should be executed by sending the shared memory identifier (shmid) to the
* socket.
-
+ *
* If the callback produces a result, it sends any number of shared memory
* identifiers back via the socket. For each such identifier received, \a
* result_handler is called. The contents of the sma identified by the received
if (ret < 0)
goto out;
- *(uint32_t *) buf = afs_socket_cookie;
- *(int *) (buf + sizeof(afs_socket_cookie)) = query_shmid;
+ *(uint32_t *)buf = afs_socket_cookie;
+ *(int *)(buf + sizeof(afs_socket_cookie)) = query_shmid;
ret = connect_local_socket(conf.afs_socket_arg);
if (ret < 0)
activate_mood_or_playlist(NULL, &num_admissible);
}
} else
- ret2 = para_printf(&pb, "activated %s (%d admissible files)\n", current_mop?
- current_mop : "dummy mood", num_admissible);
+ ret2 = para_printf(&pb, "activated %s (%d admissible files)\n",
+ current_mop? current_mop : "dummy mood",
+ num_admissible);
out:
if (ret2 >= 0 && pb.offset)
pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset);
return ret;
ret = mmap_full_file(path, O_RDONLY, &map.data, &map.size, &afd->fd);
if (ret < 0)
- goto err;
+ goto out;
hash_function(map.data, map.size, file_hash);
ret = hash_compare(file_hash, aft_hash);
para_munmap(map.data, map.size);
if (ret) {
ret = -E_HASH_MISMATCH;
- goto err;
+ goto out;
}
new_afsi = old_afsi;
new_afsi.num_played++;
load_chunk_table(&afd->afhi, chunk_table_obj.data);
ret = make_status_items(afd, &old_afsi, path, score, file_hash);
if (ret < 0)
- goto err;
+ goto out;
aced.aft_row = aft_row;
aced.old_afsi = &old_afsi;
afs_event(AFSI_CHANGE, NULL, &aced);
ret = save_afd(afd);
-err:
+out:
free(afd->afhi.chunk_table);
osl_close_disk_object(&chunk_table_obj);
if (ret < 0)
static char *alsa_mix_get_channels(struct mixer_handle *handle)
{
+ int ret;
char *list = NULL;
snd_mixer_selem_id_t *sid;
snd_mixer_elem_t *elem;
- snd_mixer_selem_id_alloca(&sid);
+ ret = snd_mixer_selem_id_malloc(&sid);
+ assert(ret >= 0);
elem = snd_mixer_first_elem(handle->mixer);
for (; elem; elem = snd_mixer_elem_next(elem)) {
char *tmp = list;
name);
free(tmp);
}
+ snd_mixer_selem_id_free(sid);
return list;
}
if (!mixer_channel)
mixer_channel = "Master";
- snd_mixer_selem_id_alloca(&sid);
+ ret = snd_mixer_selem_id_malloc(&sid);
+ assert(ret >= 0);
snd_mixer_selem_id_set_index(sid, selem_id);
snd_mixer_selem_id_set_name(sid, mixer_channel);
h->elem = snd_mixer_find_selem(h->mixer, sid);
PARA_NOTICE_LOG("unable to find simple control '%s',%i\n",
snd_mixer_selem_id_get_name(sid),
snd_mixer_selem_id_get_index(sid));
- return -E_BAD_CHANNEL;
+ ret = -E_BAD_CHANNEL;
+ goto out;
}
ret = snd_mixer_selem_get_playback_volume_range(h->elem,
&h->pmin, &h->pmax);
if (ret < 0) {
PARA_NOTICE_LOG("unable to get %s range (%s): %s\n",
mixer_channel, h->card, snd_strerror(ret));
- return -E_ALSA_MIX_RANGE;
+ ret = -E_ALSA_MIX_RANGE;
+ goto out;
}
if (h->pmin >= h->pmax) {
PARA_NOTICE_LOG("alsa reported %s range %ld-%ld (%s)\n",
mixer_channel, h->pmin, h->pmax, h->card);
- return -E_ALSA_MIX_RANGE;
+ ret = -E_ALSA_MIX_RANGE;
+ goto out;
}
- return 1;
+ ret = 1;
+out:
+ snd_mixer_selem_id_free(sid);
+ return ret;
}
static int alsa_mix_get(struct mixer_handle *h)
static int alsa_init(struct private_alsa_write_data *pad,
struct alsa_write_args_info *conf)
{
- snd_pcm_hw_params_t *hwparams;
- snd_pcm_sw_params_t *swparams;
+ snd_pcm_hw_params_t *hwparams = NULL;
+ snd_pcm_sw_params_t *swparams = NULL;
snd_pcm_uframes_t start_threshold, stop_threshold;
snd_pcm_uframes_t buffer_size, period_size;
snd_output_t *output_log;
SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
if (ret < 0)
goto fail;
- snd_pcm_hw_params_alloca(&hwparams);
+ ret = snd_pcm_hw_params_malloc(&hwparams);
+ assert(ret >= 0);
msg = "Broken alsa configuration";
ret = snd_pcm_hw_params_any(pad->handle, hwparams);
if (ret < 0)
goto fail;
/* software parameter setup */
- snd_pcm_sw_params_alloca(&swparams);
+ ret = snd_pcm_sw_params_malloc(&swparams);
+ assert(ret >= 0);
snd_pcm_sw_params_current(pad->handle, swparams);
snd_pcm_sw_params_set_avail_min(pad->handle, swparams, period_size);
if (buffer_size < 1)
}
snd_output_close(output_log);
}
- return 1;
+ ret = 1;
+ goto out;
fail:
if (ret < 0)
PARA_ERROR_LOG("%s: %s\n", msg, snd_strerror(-ret));
else
PARA_ERROR_LOG("%s\n", msg);
- return -E_ALSA;
+ ret = -E_ALSA;
+out:
+ snd_pcm_hw_params_free(hwparams);
+ snd_pcm_sw_params_free(swparams);
+ return ret;
}
static void alsa_write_pre_select(struct sched *s, void *context)
struct timeval restart_barrier;
};
+/* Describes one instance of a receiver-filter-writer chain. */
+struct slot_info {
+ /* Number of the audio format in this slot. */
+ int format;
+ /* The stream_start status item announced by para_server. */
+ struct timeval server_stream_start;
+ /* The offset status item announced by para_server. */
+ unsigned offset_seconds;
+ /* The seconds_total status item announced by para_server. */
+ unsigned seconds_total;
+ /* The receiver info associated with this slot. */
+ struct receiver_node *receiver_node;
+ /* The array of filter nodes. */
+ struct filter_node *fns;
+ /* The array of writers attached to the last filter. */
+ struct writer_node *wns;
+};
+
+/** Maximal number of simultaneous instances. */
+#define MAX_STREAM_SLOTS 5
+
+/** Iterate over all slots. */
+#define FOR_EACH_SLOT(_slot) for (_slot = 0; _slot < MAX_STREAM_SLOTS; _slot++)
+
/**
* para_audiod uses \p MAX_STREAM_SLOTS different slots, each of which may
* be associated with a receiver/filter/writer triple. This array holds all
return -E_UNSUPPORTED_AUDIO_FORMAT;
}
+/**
+ * Return the flags for the \a decoder_flags status item.
+ *
+ * Allocates a string which contains one octal digit per slot. Bit zero (value
+ * 1) is set if a receiver is active. Bit one (value 2) and bit three (value 4)
+ * have the analogous meaning for filter and writer, respectively.
+ *
+ * \return String that must be freed by the caller.
+ */
+__malloc char *audiod_get_decoder_flags(void)
+{
+ int i;
+ char flags[MAX_STREAM_SLOTS + 1];
+
+ FOR_EACH_SLOT(i) {
+ struct slot_info *s = &slot[i];
+ char flag = '0';
+ if (s->receiver_node)
+ flag += 1;
+ if (s->fns)
+ flag += 2;
+ if (s->wns)
+ flag += 4;
+ flags[i] = flag;
+ }
+ flags[MAX_STREAM_SLOTS] = '\0';
+ return para_strdup(flags);
+}
+
static int get_matching_audio_format_nums(const char *re)
{
int i, ret;
return ret;
}
+static int get_play_time_slot_num(void)
+{
+ int i, oldest_slot = -1;
+ struct timeval oldest_wstime = {0, 0};
+
+ FOR_EACH_SLOT(i) {
+ struct slot_info *s = &slot[i];
+ struct timeval wstime;
+ if (!s->wns || !s->wns[0].btrn)
+ continue;
+ btr_get_node_start(s->wns[0].btrn, &wstime);
+ if (oldest_slot >= 0 && tv_diff(&wstime, &oldest_wstime, NULL) > 0)
+ continue;
+ oldest_wstime = wstime;
+ oldest_slot = i;
+ }
+ return oldest_slot;
+}
+
/**
- * Compute the play time based on information of the given slot.
- *
- * \param slot_num The slot number (negative means: no slot).
+ * Compute the play time based on information of the current slot.
*
* This computes a string of the form "0:07 [3:33] (3%/3:40)" using information
* from the status items received from para_server and the start time of the
- * (first) writer of the given slot.
+ * (first) writer of the current slot.
*
* It has to take into account that the stream was probably not started at
* the beginning of the file, that the clock between the server and the client
* host may differ and that playback of the stream was delayed, e.g. because
- * the prebuffer filter is used in the filter configuration of the given slot.
+ * the prebuffer filter is used in the filter configuration.
*
- * If no writer is active in the given slot, or \a slot_num is negative
- * (indicating that para_audiod runs in standby mode), an approximation based
- * only on the status items is computed and the returned string is prefixed
- * with "~".
+ * If no writer is active, for example because para_audiod runs in standby
+ * mode, an approximation based only on the status items is computed and the
+ * returned string is prefixed with "~".
*
* \return A string that must be freed by the caller.
*/
-char *get_time_string(int slot_num)
+char *get_time_string(void)
{
int ret, seconds = 0, length;
struct timeval *tmp, sum, sss, /* server stream start */
wstime, /* writer start time */
wtime, /* now - writer start */
rskip; /* receiver start - sss */
+ int slot_num = get_play_time_slot_num();
struct slot_info *s = slot_num < 0? NULL : &slot[slot_num];
char *msg;
/** array of audio format names supported by para_audiod */
extern const char *audio_formats[];
-/** maximal number of simultaneous instances */
-#define MAX_STREAM_SLOTS 5
-
/**
* the possible modes of operation
*
const char *help;
};
-/**
- * Describes one instance of a receiver-filter-writer chain.
- *
- * \sa receiver_node, receiver, filter, filter_node, writer, writer_node,
- * writer_node_group.
- */
-struct slot_info {
- /** Number of the audio format in this slot. */
- int format;
- /** The stream_start status item announced by para_server. */
- struct timeval server_stream_start;
- /** The offset status item announced by para_server. */
- unsigned offset_seconds;
- /** The seconds_total status item announced by para_server. */
- unsigned seconds_total;
- /** The receiver info associated with this slot. */
- struct receiver_node *receiver_node;
- /** The array of filter nodes. */
- struct filter_node *fns;
- /** The array of writers attached to the last filter. */
- struct writer_node *wns;
-};
-
-extern struct slot_info slot[MAX_STREAM_SLOTS];
+__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);
void audiod_status_dump(bool force);
-char *get_time_string(int slot_num);
+char *get_time_string(void);
struct btr_node *audiod_get_btr_root(void);
void stat_client_write_item(int item_num);
void clear_and_dump_items(void);
void close_stat_clients(void);
-
-/** iterate over all slots */
-#define FOR_EACH_SLOT(_slot) for (_slot = 0; _slot < MAX_STREAM_SLOTS; _slot++)
return para_strdup(status);
}
-static int get_play_time_slot_num(void)
-{
- int i, oldest_slot = -1;
- struct timeval oldest_wstime = {0, 0};
-
- FOR_EACH_SLOT(i) {
- struct slot_info *s = &slot[i];
- struct timeval wstime;
- if (!s->wns || !s->wns[0].btrn)
- continue;
- btr_get_node_start(s->wns[0].btrn, &wstime);
- if (oldest_slot >= 0 && tv_diff(&wstime, &oldest_wstime, NULL) > 0)
- continue;
- oldest_wstime = wstime;
- oldest_slot = i;
- }
- //PARA_CRIT_LOG("oldest slot: %d\n", oldest_slot);
- return oldest_slot;
-}
-
-__malloc static char *decoder_flags(void)
-{
- int i;
- char flags[MAX_STREAM_SLOTS + 1];
-
- FOR_EACH_SLOT(i) {
- struct slot_info *s = &slot[i];
- char flag = '0';
- if (s->receiver_node)
- flag += 1;
- if (s->fns)
- flag += 2;
- if (s->wns)
- flag += 4;
- flags[i] = flag;
- }
- flags[MAX_STREAM_SLOTS] = '\0';
- return para_strdup(flags);
-}
-
static int dump_commands(int fd)
{
char *buf = para_strdup(""), *tmp = NULL;
*/
void audiod_status_dump(bool force)
{
- int slot_num = get_play_time_slot_num();
char *old, *new;
old = stat_item_values[SI_PLAY_TIME];
- new = get_time_string(slot_num);
+ new = get_time_string();
if (new) {
if (force || !old || strcmp(old, new)) {
free(old);
free(new);
old = stat_item_values[SI_DECODER_FLAGS];
- new = decoder_flags();
+ new = audiod_get_decoder_flags();
if (force || !old || strcmp(old, new)) {
free(old);
stat_item_values[SI_DECODER_FLAGS] = new;
* check if perms are sufficient to exec a command having perms cmd_perms.
* Returns 0 if perms are sufficient, -E_PERM otherwise.
*/
-static int check_perms(unsigned int perms, struct server_command *cmd_ptr)
+static int check_perms(unsigned int perms, const struct server_command *cmd_ptr)
{
PARA_DEBUG_LOG("checking permissions\n");
return (cmd_ptr->perms & perms) < cmd_ptr->perms ? -E_PERM : 0;
/** Argument vector. */
char **argv;
/** The command being executed. */
- struct server_command *cmd;
+ const struct server_command *cmd;
/** File descriptor and crypto keys. */
struct stream_cipher_context scc;
};
}
/** S-expression for the public part of an RSA key. */
-#define RSA_PUBKEY_SEXP "(public-key (rsa (n %m) (e %m)))"
+#define RSA_PUBKEY_SEXP "(public-key (rsa (n %m) (e %m)))"
/** S-expression for a private RSA key. */
#define RSA_PRIVKEY_SEXP "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))"
key[j++] = begin[i];
}
key[j] = '\0';
- //PARA_CRIT_LOG("key: %s\n", key);
blob_size = key_size * 2;
blob = para_malloc(blob_size);
ret = base64_decode(key, blob, blob_size);
/* bit 6 has value 0 */
static inline bool is_primitive(unsigned char c)
{
- return ((c & (1<<6)) == 0);
+ return (c & (1<<6)) == 0;
}
static inline bool is_primitive_integer(unsigned char c)
{
if (!is_primitive(c))
return false;
- return ((c & 0x1f) == ASN1_TYPE_INTEGER);
+ return (c & 0x1f) == ASN1_TYPE_INTEGER;
}
/* Bit 8 is zero (and bits 7-1 give the length) */
{
const unsigned char *p = data, *end = data + len;
- /* the whole thing istarts with one sequence */
+ /* the whole thing starts with one sequence */
if (*p != ASN1_TYPE_SEQUENCE)
return -E_ASN1_PARSE;
p++;
if (p >= end)
return -E_ASN1_PARSE;
- /* Skip next integer */
+ /* skip next integer */
if (*p != ASN1_TYPE_INTEGER)
return -E_ASN1_PARSE;
p++;
}
key = para_malloc(sizeof(*key));
key->sexp = sexp;
+ key->num_bytes = n_size;
*result = key;
ret = n_size;
PARA_INFO_LOG("successfully read %u bit asn public key\n", n_size * 8);
size_t nr_scanned, erroff, decoded_size;
gcry_mpi_t e = NULL, n = NULL;
- PARA_DEBUG_LOG("decoding %d byte public rsa-ssh key\n", size);
+ PARA_DEBUG_LOG("decoding %d byte public rsa-ssh key\n", size);
if (size > INT_MAX / 4)
return -ERRNO_TO_PARA_ERROR(EOVERFLOW);
blob = para_malloc(2 * size);
#define MMD_INFO_SIZE 16384
/** The maximum length of the host component in an URL */
-#define MAX_HOSTLEN 256
+#define MAX_HOSTLEN 256
-/** Holds the arguments for the para_server's sender command. */
-struct sender_command_data{
- /** Greater than 0 indicates that a sender cmd is already queued. */
+/** Arguments for the sender command. */
+struct sender_command_data {
+ /** Greater than zero indicates that a sender cmd is already queued. */
int cmd_num;
/** The number of the sender in question. */
int sender_num;