uname_rs := $(shell uname -rs)
cc_version := $(shell $(CC) --version | head -n 1)
GIT_VERSION := $(shell ./GIT-VERSION-GEN git-version.h)
-COPYRIGHT_YEAR := 2018
+COPYRIGHT_YEAR := 2019
ifeq ("$(origin O)", "command line")
build_dir := $(O)
CPPFLAGS += -DLOGLEVELS='$(LOGLEVELS)'
CPPFLAGS += -DUNAME_RS='"$(uname_rs)"'
CPPFLAGS += -DCC_VERSION='"$(cc_version)"'
-CPPFLAGS += -I/usr/local/include
CPPFLAGS += -I$(lls_suite_dir)
CPPFLAGS += -I$(yy_build_dir)
CPPFLAGS += $(lopsub_cppflags)
$(object_dir)/flac%.o: CPPFLAGS += $(flac_cppflags)
$(object_dir)/mp3_afh.o: CPPFLAGS += $(id3tag_cppflags)
-$(object_dir)/crypt.o: CPPFLAGS += $(openssl_cppflags)
+$(object_dir)/openssl.o: CPPFLAGS += $(openssl_cppflags)
$(object_dir)/gcrypt.o: CPPFLAGS += $(gcrypt_cppflags)
$(object_dir)/ao_write.o: CPPFLAGS += $(ao_cppflags)
$(object_dir)/alsa%.o: CPPFLAGS += $(alsa_cppflags)
NEWS
====
+----------------------------------------------
+0.6.3 (to be announced) "generalized activity"
+----------------------------------------------
+
+- The ff command now accepts a negative argument to instruct the
+ virtual streaming system to jump backwards in the current audio
+ stream. The old syntax (e.g., "ff 30-") is still supported but it
+ is deprecated and no longer documented. The compatibility code is
+ sheduled for removal after 0.7.0.
+- para_afh: New option: --preserve to reset the modification time to
+ the value of the original file after meta data modification.
+- Overhaul of the compress filter code. The refined algorithm should
+ reduce clipping. The meaning of --aggressiveness has changed, see the
+ updated and extended documentation of the compress filter for details.
+
--------------------------------------
0.6.2 (2018-06-30) "elastic diversity"
--------------------------------------
goto out;
}
ret = xrename(tmp_name, name);
+ if (ret < 0)
+ goto out;
+ if (OPT_GIVEN(PRESERVE)) {
+ struct timespec times[2]; /* [0]: atime, [1]: mtime */
+ times[0].tv_nsec = UTIME_OMIT;
+ times[1] = sb.st_mtim;
+ /*
+ * We might well have written a file of identical size. If we
+ * keep the mtime as well, we might fool backup applications
+ * like rsync which skip files whose size and mtime haven't
+ * changed. So we change the mtime slightly.
+ */
+ times[1].tv_sec++;
+ if (futimens(output_fd, times) < 0) {
+ ret = -ERRNO_TO_PARA_ERROR(errno);
+ goto out;
+ }
+ }
out:
if (ret < 0 && output_fd >= 0)
unlink(tmp_name); /* ignore errors */
para_printf(&aca->pbout, "activating dummy mood\n");
activate_mood_or_playlist(NULL, &num_admissible, NULL);
out:
- para_printf(&aca->pbout, "activated %s (%d admissible files)\n",
- current_mop? current_mop : "dummy mood", num_admissible);
+ para_printf(&aca->pbout, "activated %s (%d admissible file%s)\n",
+ current_mop? current_mop : "dummy mood", num_admissible,
+ num_admissible == 1? "" : "s");
free_lpr:
lls_free_parse_result(aca->lpr, cmd);
return ret;
struct para_buffer *pb, void *data); \
extern struct osl_table *table_name ## _table;
+/** \cond blob_symbols */
DECLARE_BLOB_SYMBOLS(lyrics, lyr);
DECLARE_BLOB_SYMBOLS(images, img);
DECLARE_BLOB_SYMBOLS(moods, mood);
DECLARE_BLOB_SYMBOLS(playlists, pl);
+/** \endcond blob_symbols */
/** The columns of an abstract blob table. */
enum blob_table_columns {
/** The different sorting methods of the ls command. */
enum ls_sorting_method {
- /** -sp (default) */
- LS_SORT_BY_PATH,
- /** -ss */
- LS_SORT_BY_SCORE,
- /** -sl */
- LS_SORT_BY_LAST_PLAYED,
- /** -sn */
- LS_SORT_BY_NUM_PLAYED,
- /** -sf */
- LS_SORT_BY_FREQUENCY,
- /** -sc */
- LS_SORT_BY_CHANNELS,
- /** -si */
- LS_SORT_BY_IMAGE_ID,
- /** -sy */
- LS_SORT_BY_LYRICS_ID,
- /** -sb */
- LS_SORT_BY_BITRATE,
- /** -sd */
- LS_SORT_BY_DURATION,
- /** -sa */
- LS_SORT_BY_AUDIO_FORMAT,
- /** -sh */
- LS_SORT_BY_HASH,
+ LS_SORT_BY_PATH, /**< -s=p (default) */
+ LS_SORT_BY_SCORE, /**< -s=s */
+ LS_SORT_BY_LAST_PLAYED, /**< -s=l */
+ LS_SORT_BY_NUM_PLAYED, /**< -s=n */
+ LS_SORT_BY_FREQUENCY, /**< -s=f */
+ LS_SORT_BY_CHANNELS, /**< -s=c */
+ LS_SORT_BY_IMAGE_ID, /**< -s=i */
+ LS_SORT_BY_LYRICS_ID, /**< -s=y */
+ LS_SORT_BY_BITRATE, /**< -s=b */
+ LS_SORT_BY_DURATION, /**< -s=d */
+ LS_SORT_BY_AUDIO_FORMAT, /**< -s=a */
+ LS_SORT_BY_HASH, /**< -s=h */
};
/** The different listing modes of the ls command. */
enum ls_listing_mode {
- /** Default listing mode. */
- LS_MODE_SHORT,
- /** -l or -ll */
- LS_MODE_LONG,
- /** -lv */
- LS_MODE_VERBOSE,
- /** -lm */
- LS_MODE_MBOX,
- /** -lc */
- LS_MODE_CHUNKS,
- /** -lp */
- LS_MODE_PARSER,
+ LS_MODE_SHORT, /**< Default listing mode. */
+ LS_MODE_LONG, /**< -l or -l=l */
+ LS_MODE_VERBOSE, /** -l=v */
+ LS_MODE_MBOX, /** -l=m */
+ LS_MODE_CHUNKS, /** -l=c */
+ LS_MODE_PARSER, /** -l=p */
};
/**
{
uint32_t n;
- if (!afhi->chunk_table)
+ if (!afhi->chunk_table || afhi->chunks_total == 0)
return;
for (n = 0; n <= afhi->chunks_total; n++)
write_u32(buf + 4 * n, afhi->chunk_table[n]);
WRITE_STATUS_ITEM(pb, SI_file_size, "%ld\n", statbuf.st_size / 1024);
}
+/**
+ * Deallocate and invalidate the status item strings.
+ *
+ * This needs to be a public function so that afs.c can call it on shutdown.
+ */
void free_status_items(void)
{
freep(&status_items);
freep(&parser_friendly_status_items);
}
-static int make_status_items(void)
+static void make_status_items(void)
{
const struct lls_command *cmd = SERVER_CMD_CMD_PTR(LS);
char *argv[] = {"ls", "--admissible", "--listing-mode=verbose"};
free_status_items();
if (!status_item_ls_data.path) /* no audio file open */
- return 0;
+ return;
ret = lls_parse(ARRAY_SIZE(argv), argv, cmd, &opts.lpr, NULL);
assert(ret >= 0);
time(¤t_time);
parser_friendly_status_items = pb.buf;
ret = 1;
out:
- if (ret < 0)
+ if (ret < 0) {
+ PARA_WARNING_LOG("could not create status items: %s\n",
+ para_strerror(-ret));
free_status_items();
+ }
lls_free_parse_result(opts.lpr, cmd);
- return ret;
}
/**
case SF_U8:
case SF_U16_LE:
case SF_U16_BE:
- return -E_AO_BAD_SAMPLE_FORMAT;
+ return -E_BAD_SAMPLE_FORMAT;
case SF_S8:
/* no need to set byte_format */
result->bits = 8;
if (info->type == AO_TYPE_FILE)
continue;
- PARA_DEBUG_LOG("%s: %s", info->short_name, info->name);
- PARA_DEBUG_LOG("priority: %d", info->priority);
+ PARA_DEBUG_LOG("name: %s: %s\n", info->short_name, info->name);
+ PARA_DEBUG_LOG("priority: %d\n", info->priority);
for (j = 0; j < info->option_count; j++) {
tmp = make_message("%s%s%s", keys? keys : "",
keys? ", " : "",
free(keys);
keys = tmp;
}
- PARA_DEBUG_LOG("keys: %s", keys? keys : "[none]");
+ PARA_DEBUG_LOG("keys: %s\n", keys? keys : "[none]");
free(keys);
- PARA_DEBUG_LOG("comment: %s", info->comment?
+ PARA_DEBUG_LOG("comment: %s\n", info->comment?
info->comment : "[none]");
}
}
/** Define a pointer to an osl blob table with a canonical name. */
#define DEFINE_BLOB_TABLE_PTR(table_name) struct osl_table *table_name ## _table;
-
/** Define a blob table. */
#define INIT_BLOB_TABLE(table_name) \
DEFINE_BLOB_TABLE_DESC(table_name); \
para_printf(&aca->pbout, "cannot list %s\n", name);
return ret;
}
- id = *(uint32_t *)obj.data;
+ id = read_u32(obj.data);
para_printf(&aca->pbout, "%u\t%s\n", id, name);
return 1;
}
.action = print_blob,
};
int ret;
+
ret = lls_deserialize_parse_result(aca->query.data, cmd, &aca->lpr);
pmd.lpr = aca->lpr;
assert(ret >= 0);
.data = &aca->fd,
.action = cat_blob
};
+
ret = lls_deserialize_parse_result(aca->query.data, cmd, &aca->lpr);
assert(ret >= 0);
pmd.lpr = aca->lpr;
{
struct afs_callback_arg *aca = data;
int ret = osl(osl_del_row(table, row));
+
if (ret < 0) {
para_printf(&aca->pbout, "cannot remove %s\n", name);
return ret;
.data = aca,
.action = remove_blob
};
+
ret = lls_deserialize_parse_result(aca->query.data, cmd, &aca->lpr);
assert(ret >= 0);
pmd.lpr = aca->lpr;
struct osl_object objs[NUM_BLOB_COLUMNS];
char *name = aca->query.data;
size_t name_len = strlen(name) + 1;
- uint32_t id;
+ uint32_t id = (uint32_t)-1; /* STFU, gcc */
+ char id_buf[sizeof(id)];
unsigned num_rows;
int ret;
if (ret < 0)
goto out;
if (!num_rows) { /* this is the first entry ever added */
- /* insert dummy row containing the id */
- id = 2; /* this entry will be entry #1, so 2 is the next */
- objs[BLOBCOL_ID].data = &id;
- objs[BLOBCOL_ID].size = sizeof(id);
+ /*
+ * Insert dummy row containing the next free ID. Since we are
+ * about to insert the first blob with ID 1, the next free ID
+ * will be 2.
+ */
+ id = 2U;
+ write_u32(id_buf, id);
+ objs[BLOBCOL_ID].data = id_buf;
+ objs[BLOBCOL_ID].size = sizeof(id_buf);
objs[BLOBCOL_NAME].data = "";
objs[BLOBCOL_NAME].size = 1;
objs[BLOBCOL_DEF].data = "";
ret = osl(osl_get_object(table, row, BLOBCOL_ID, &obj));
if (ret < 0)
goto out;
- id = *(uint32_t *)obj.data;
+ id = read_u32(obj.data);
obj.data = name + name_len;
obj.size = aca->query.size - name_len;
ret = osl(osl_update_object(table, row, BLOBCOL_DEF, &obj));
ret = osl(osl_get_object(table, row, BLOBCOL_ID, &obj));
if (ret < 0)
goto out;
- id = *(uint32_t *)obj.data + 1;
- obj.data = &id;
+ id = read_u32(obj.data) + 1;
+ write_u32(id_buf, id);
+ obj.data = &id_buf;
ret = osl(osl_update_object(table, row, BLOBCOL_ID, &obj));
if (ret < 0)
goto out;
}
id--;
- objs[BLOBCOL_ID].data = &id;
- objs[BLOBCOL_ID].size = sizeof(id);
+ write_u32(id_buf, id);
+ objs[BLOBCOL_ID].data = &id_buf;
+ objs[BLOBCOL_ID].size = sizeof(id_buf);
objs[BLOBCOL_NAME].data = name;
objs[BLOBCOL_NAME].size = name_len;
objs[BLOBCOL_DEF].data = name + name_len;
*
* This function is called from the addblob command handlers to instruct the
* afs process to store the input in a blob table. Input is read and decrypted
- * from the file descriptor given by cc and appended to arg_obj, which contains
+ * from the file descriptor given by cc and appended to a buffer which also contains
* the name of the blob to create. The combined buffer is made available to the
* afs process via the callback method.
*/
return blob_get_name_by_id(table_name ## _table, id, name); \
}
-
static int blob_get_def_by_name(struct osl_table *table, char *name,
struct osl_object *def)
{
{
struct osl_object obj;
int ret = osl(osl_get_object(table, row, BLOBCOL_NAME, &obj));
+
if (ret < 0)
return ret;
*name = obj.data;
const char *dir)
{
int ret;
+
desc->dir = dir;
ret = osl(osl_open_table(desc, table));
if (ret >= 0)
#include "buffer_tree.h"
#include "error.h"
#include "check_wav.h"
+#include "portable_io.h"
/** Length of a standard wav header. */
#define WAV_HEADER_LEN 44
PARA_INFO_LOG("found wav header\n");
cwc->state = CWS_HAVE_HEADER;
/* Only set those values which have not already been set. */
- cwc->channels = (unsigned)a[22];
- cwc->sample_rate = a[24] + (a[25] << 8) + (a[26] << 16) + (a[27] << 24);
- bps = a[34] + ((unsigned)a[35] << 8);
+ cwc->channels = a[22];
+ cwc->sample_rate = read_u32(a + 24);
+ bps = read_u16(a + 34);
if (bps != 8 && bps != 16) {
PARA_WARNING_LOG("%u bps not supported, assuming 16\n",
bps);
}
/**
- * Send a sideband packet through a blocking file descriptor.
+ * Receive a sideband packet from a blocking file descriptor.
*
* \param scc fd and crypto keys.
* \param expected_band The expected band designator.
static int com_ff(struct command_context *cc, struct lls_parse_result *lpr)
{
long promille;
- int ret, backwards = 0;
- unsigned i;
+ int i, ret;
char c, *errctx;
ret = lls(lls_check_arg_count(lpr, 1, 1, &errctx));
send_errctx(cc, errctx);
return ret;
}
- if (!(ret = sscanf(lls_input(0, lpr), "%u%c", &i, &c)))
- return -E_COMMAND_SYNTAX;
- if (ret > 1 && c == '-')
- backwards = 1; /* jmp backwards */
+ ret = para_atoi32(lls_input(0, lpr), &i);
+ if (ret < 0) {
+ if (ret != -E_ATOI_JUNK_AT_END)
+ return ret;
+ /*
+ * Compatibility code to keep the historic syntax (ff 30-)
+ * working. This can be removed after 0.7.0.
+ */
+ ret = sscanf(lls_input(0, lpr), "%i%c", &i, &c);
+ if (ret <= 0)
+ return -E_COMMAND_SYNTAX;
+ if (ret > 1 && c == '-') {
+ PARA_WARNING_LOG("use of obsolete syntax\n");
+ i = -i;
+ }
+ }
mutex_lock(mmd_mutex);
ret = -E_NO_AUDIO_FILE;
if (!mmd->afd.afhi.chunks_total || !mmd->afd.afhi.seconds_total)
goto out;
ret = 1;
promille = (1000 * mmd->current_chunk) / mmd->afd.afhi.chunks_total;
- if (backwards)
- promille -= 1000 * i / mmd->afd.afhi.seconds_total;
- else
- promille += 1000 * i / mmd->afd.afhi.seconds_total;
+ /*
+ * We need this cast because without it the expression on the right
+ * hand side is of unsigned type.
+ */
+ promille += 1000 * i / (int)mmd->afd.afhi.seconds_total;
if (promille < 0)
promille = 0;
if (promille > 1000) {
me->loglevel = ret;
}
+/**
+ * Register functions to be called before and after a message is logged.
+ *
+ * \param pre_log_hook Called before the message is logged.
+ * \param post_log_hook Called after the message is logged.
+ *
+ * The purpose of this function is to provide a primitive for multi-threaded
+ * applications to serialize the access to the log facility, preventing
+ * interleaving log messages. This can be achieved by having the pre-log hook
+ * acquire a lock which blocks the other threads on the attempt to log a
+ * message at the same time. The post-log hook is responsible for releasing
+ * the lock.
+ *
+ * If these hooks are unnecessary, for example because the application is
+ * single-threaded, this function does not need to be called.
+ */
void daemon_set_hooks(void (*pre_log_hook)(void), void (*post_log_hook)(void))
{
me->pre_log_hook = pre_log_hook;
PARA_ERROR(AO_APPEND_OPTION, "ao append option: memory allocation failure"), \
PARA_ERROR(AO_BAD_DRIVER, "ao: invalid driver"), \
PARA_ERROR(AO_BAD_OPTION, "ao option is not of type key:value"), \
- PARA_ERROR(AO_BAD_SAMPLE_FORMAT, "ao: unsigned sample formats not supported"), \
PARA_ERROR(AO_DEFAULT_DRIVER, "ao: no usable output device"), \
PARA_ERROR(AO_EOF, "ao: end of file"), \
PARA_ERROR(AO_FILE_NOT_SUPP, "ao: file io drivers not supported"), \
enum para_error_codes {PARA_ERRORS};
#undef PARA_ERROR
#define PARA_ERROR(err, msg) msg
-/** Array of error strings. */
+/** All .c files need the declararation of the array of error strings. */
extern const char * const para_errlist[];
+/** Exactly one .c file per executable must define the array. */
#define DEFINE_PARA_ERRLIST const char * const para_errlist[] = {PARA_ERRORS}
/**
ci.argc = create_argv(ci.buffer, " ", &ci.argv);
ci.word_num = compute_word_num(ci.buffer, " ", ci.point);
+ /* determine the current word to complete */
end = ci.buffer + ci.point;
+
+ if (*end == ' ') {
+ if (ci.point == 0 || ci.buffer[ci.point - 1] == ' ') {
+ ci.word = para_strdup(NULL);
+ goto create_matches;
+ } else /* The cursor is positioned right after a word */
+ end--;
+ }
for (p = end; p > ci.buffer && *p != ' '; p--)
; /* nothing */
if (*p == ' ')
p++;
-
n = end - p + 1;
ci.word = para_malloc(n + 1);
strncpy(ci.word, p, n);
ci.word[n] = '\0';
-
+create_matches:
PARA_DEBUG_LOG("line: %s, point: %d (%c), wordnum: %d, word: %s\n",
ci.buffer, ci.point, ci.buffer[ci.point], ci.word_num, ci.word);
if (ci.word_num == 0)
The backup suffix is '~'. That is, a single tilde character is appended
to the given file name.
[/help]
+ [option preserve]
+ summary = preserve modification time
+ [help]
+ If this option is given, the mtime of the modified file is set to
+ the value prior to the modification.
+ [/help]
[option year]
short_opt = y
summary = set the year tag
[description]
para_play operates either in command mode or in insert mode. In insert
mode it presents a prompt and allows the user to enter commands like
- stop, play, pause etc. In command mode the current audio file and the
- playback position are shown and the program reads single key strokes
- from stdin. Keys may be mapped to commands so that the configured
- command is executed when a mapped key is pressed.
+ play, pause, quit, etc. In command mode the current audio file and the
+ playback position are shown instead of the prompt/command line, and
+ the program reads single key strokes from stdin. Keys may be mapped
+ to commands so that the configured command is executed whenever a
+ mapped key is pressed.
[/description]
m4_include(common-option-section.m4)
m4_include(help.m4)
summary = enable verbose mode
[subcommand ff]
- purpose = jump N seconds forward or backward
- synopsis = n[-]
+ purpose = jump forward or backward in the current audio file
+ synopsis = seconds
aux_info = VSS_READ | VSS_WRITE
[description]
- This sets the 'R' (reposition request) bit of the vss status flags
- which enqueues a request to jump n seconds forwards or backwards.
-
- Example:
-
- para_client ff 30-
-
- jumps 30 seconds backwards.
+ This enqueues a request to reposition the audio stream according to
+ the argument, which may be a signed or an unsigned integer. Negative
+ values correspond to backward jumps.
+
+ If a negative number is given whose absolute value exceeds the current
+ postition of the stream, a jump to the beginning of the audio file
+ is performed. If a positive amount of seconds is given which exceeds
+ the remaining time of the audio file, the next audio file is loaded.
[/description]
arg_info = required_arg
arg_type = string
[help]
- If this is not given, the driver with the highest priority (see below)
- will be used.
+ If this is not given, the driver with the highest priority will be
+ used. The list of available drivers and their priorities is shown in
+ debug mode.
[/help]
[option ao-option]
short_opt = o
[help]
For each time this option is given, the supplied key-value pair is
appended to the list of options for the driver. Invalid keys are
- silently ignored.
+ silently ignored. The list of available keys is shown in debug mode.
[/help]
[subcommand oss]
purpose = output plugin for the Open Sound System
arg_info = required_arg
arg_type = string
default_val = /dev/dsp
-[subcommand osx]
- purpose = output plugin for Mac OS coreaudio
- [option numbuffers]
- short_opt = n
- summary = number of audio buffers to allocate
- typestr = num
- arg_info = required_arg
- arg_type = uint32
- default_val = 20
- [help]
- Increase if you get buffer underruns.
- [/help]
[subcommand file]
purpose = output plugin that writes to a local file
[option filename]
/* Copyright (C) 1998 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
-/** \file mixer.c A volume fader and alarm clock for OSS. */
+/** \file mixer.c A volume fader and alarm clock. */
#include <regex.h>
#include <lopsub.h>
client_cmd("stop");
if (!fit || !fi_mood) /* nothing to do */
return 1;
- change_afs_mode(fi_mood);
for (;;) {
time(&t1);
if (wake_time_epoch <= t1 + fit)
(delay % 3600) / 60);
sleep(delay);
}
- client_cmd("play");
+ change_afs_mode(fi_mood);
+ if (sleep_mood) /* currently playing */
+ client_cmd("next");
+ else /* currently stopped */
+ client_cmd("play");
ret = fade(m, h, fiv, fit);
PARA_INFO_LOG("fade complete, returning\n");
return ret;
}
if (ret < 0)
goto close_mixer;
- ret = (*(mixer_subcommand_handler_t *)(lls_user_data(cmd)))(m ,h);
+ ret = (*(mixer_subcommand_handler_t *)(lls_user_data(cmd)))(m, h);
close_mixer:
m->close(&h);
free_sub_lpr:
};
static const int frame_size_index[] = {24000, 72000, 72000};
-static const char *mode_text[] = {"stereo", "joint stereo", "dual channel", "mono", "invalid"};
-
#ifdef HAVE_ID3TAG
#include <id3tag.h>
return frequencies[h->version][h->freq];
}
-static const char *header_mode(struct mp3header *h)
+static const char *header_mode(const struct mp3header *h)
{
- if (h->mode > 4)
- h->mode = 4; /* invalid */
+ const char * const mode_text[] = {"stereo", "joint stereo",
+ "dual channel", "mono"};
+
+ if (h->mode >= ARRAY_SIZE(mode_text))
+ return "invalid";
return mode_text[h->mode];
}
case SF_S16_BE: return AFMT_S16_BE;
case SF_U16_LE: return AFMT_U16_LE;
case SF_U16_BE: return AFMT_U16_BE;
- default: return AFMT_S16_LE;
+ default: return -E_BAD_SAMPLE_FORMAT;
}
}
if (ret < 0)
goto err;
/* set PCM format */
- sample_format = format = get_oss_format(sample_format);
+ ret = get_oss_format(sample_format);
+ if (ret < 0)
+ return ret;
+ sample_format = format = ret;
ret = ioctl(powd->fd, SNDCTL_DSP_SETFMT, &format);
if (ret < 0) {
ret = -ERRNO_TO_PARA_ERROR(errno);
+ PARA_ERROR_LOG("could not set sample format\n");
goto err;
}
ret = -E_BAD_SAMPLE_FORMAT;
#include <speex/speex_callbacks.h>
#include "para.h"
+#include "portable_io.h"
#include "list.h"
#include "sched.h"
#include "buffer_tree.h"
return 1;
}
-#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
-#define le_short(s) ((short) ((unsigned short) (s) << 8) | ((unsigned short) (s) >> 8))
-#else
-#define le_short(s) ((short) (s))
-#endif
-
/**
* Size of the output buffer.
*
samples = new_frame_size * psd->shi.channels;
btr_output = para_malloc(2 * samples);
for (i = 0; i < samples; i++)
- btr_output[i] = le_short(output[i + skip_idx]);
+ btr_output[i] = read_u16(output + i + skip_idx);
btr_add_output((char *)btr_output, samples * 2, btrn);
}
return 1;
}
/**
- * Print a formated message to a dynamically allocated string.
+ * Print a formatted message to a dynamically allocated string.
*
- * \param result The formated string is returned here.
+ * \param result The formatted string is returned here.
* \param fmt The format string.
* \param ap Initialized list of arguments.
*
#include "fd.h"
extern struct misc_meta_data *mmd;
-
-extern void dccp_send_init(struct sender *);
-extern void http_send_init(struct sender *);
-extern void udp_send_init(struct sender *);
-
extern const struct sender udp_sender, dccp_sender, http_sender;
const struct sender * const senders[] = {
&http_sender, &dccp_sender, &udp_sender, NULL};
}
#ifndef MAP_POPULATE
+/** As of 2018, neither FreeBSD-11.2 nor NetBSD-8.0 have MAP_POPULATE. */
#define MAP_POPULATE 0
#endif
</ul>
<b> Author: </b> André Noll,
-<a href="mailto:maan@tuebingen.mpg.de">maan@tuebingen.mpg.de</a>
+<a href="mailto:maan@tuebingen.mpg.de">maan@tuebingen.mpg.de</a>,
+Homepage: <a href="http://people.tuebingen.mpg.de/maan/">http://people.tuebingen.mpg.de/maan/</a>
<br>
Comments and bug reports are welcome. Please provide the version of
paraslash you are using and relevant parts of the logs.
Next, change to the "bar" account on client_host and generate the
key pair with the commands
- ssh-keygen -q -t rsa -b 2048 -N '' -m PEM -f $key
+ ssh-keygen -q -t rsa -b 2048 -N '' -m PEM
This generates the two files id_rsa and id_rsa.pub in ~/.ssh. Note
that para_server won't accept keys shorter than 2048 bits. Moreover,