/** \file aft.c Audio file table functions. */
#include <regex.h>
-#include <dirent.h> /* readdir() */
#include <sys/mman.h>
#include <fnmatch.h>
#include <sys/shm.h>
#include "string.h"
#include "afh.h"
#include "afs.h"
-#include "net.h"
#include "fd.h"
#include "ipc.h"
#include "portable_io.h"
unsigned short num_played_width;
/** size of the amp field. */
unsigned short amp_width;
+ /** size of the audio format field. */
+ unsigned short audio_format_width;
};
/** Data passed from the ls command handler to its callback function. */
*/
static int aft_hash_compare(const struct osl_object *obj1, const struct osl_object *obj2)
{
- return hash_compare((HASH_TYPE *)obj1->data, (HASH_TYPE *)obj2->data);
+ return hash_compare((unsigned char *)obj1->data, (unsigned char *)obj2->data);
}
static struct osl_column_description aft_cols[] = {
*
* \return Standard.
*/
-static int aft_get_row_of_hash(HASH_TYPE *hash, struct osl_row **row)
+static int aft_get_row_of_hash(unsigned char *hash, struct osl_row **row)
{
const struct osl_object obj = {.data = hash, .size = HASH_SIZE};
return osl(osl_get_row(audio_file_table, AFTCOL_HASH, &obj, row));
* \return The return value of the underlying call to
* get_hash_object_of_aft_row().
*/
-static int get_hash_of_row(const struct osl_row *row, HASH_TYPE **hash)
+static int get_hash_of_row(const struct osl_row *row, unsigned char **hash)
{
struct osl_object obj;
int ret = get_hash_object_of_aft_row(row, &obj);
} \
}
-static short unsigned get_duration_width(int seconds)
+__a_const static short unsigned get_duration_width(int seconds)
{
short unsigned width;
unsigned hours = seconds / 3600, mins = (seconds % 3600) / 60;
"%*d " /* image_id */
"%*d " /* lyrics_id */
"%*d " /* bitrate */
- "%s " /* audio format */
+ "%*s " /* audio format */
"%*d " /* frequency */
"%d " /* channels */
"%s " /* duration */
w->image_id_width, afsi->image_id,
w->lyrics_id_width, afsi->lyrics_id,
w->bitrate_width, afhi->bitrate,
+ w->audio_format_width,
audio_format_name(afsi->audio_format_id),
w->frequency_width, afhi->frequency,
afhi->channels,
static int make_status_items(struct audio_file_data *afd,
struct afs_info *afsi, char *path, long score,
- HASH_TYPE *hash)
+ unsigned char *hash)
{
struct ls_data d = {
.afhi = afd->afhi,
.flags = LS_FLAG_FULL_PATH | LS_FLAG_ADMISSIBLE_ONLY,
.mode = LS_MODE_VERBOSE,
};
- struct para_buffer pb = {.max_size = SHMMAX - 1};
+ struct para_buffer pb = {.max_size = shm_get_shmmax() - 1};
time_t current_time;
int ret;
free(status_items);
status_items = pb.buf;
memset(&pb, 0, sizeof(pb));
- pb.max_size = SHMMAX - 1;
+ pb.max_size = shm_get_shmmax() - 1;
pb.flags = PBF_SIZE_PREFIX;
ret = print_list_item(&d, &opts, &pb, current_time);
if (ret < 0) {
int open_and_update_audio_file(struct osl_row *aft_row, long score,
struct audio_file_data *afd)
{
- HASH_TYPE *aft_hash, file_hash[HASH_SIZE];
+ unsigned char *aft_hash, file_hash[HASH_SIZE];
struct osl_object afsi_obj;
struct afs_info old_afsi, new_afsi;
int ret = get_hash_of_row(aft_row, &aft_hash);
w->duration_width = PARA_MAX(w->duration_width, num_digits);
GET_NUM_DIGITS(d->afsi.amp, &num_digits);
w->amp_width = PARA_MAX(w->amp_width, num_digits);
+ num_digits = strlen(audio_format_name(d->afsi.audio_format_id));
+ w->audio_format_width = PARA_MAX(w->audio_format_width, num_digits);
if (options->flags & LS_FLAG_ADMISSIBLE_ONLY) {
GET_NUM_DIGITS(score, &num_digits);
num_digits++; /* add one for the sign (space or "-") */
{
struct ls_options *opts = query->data;
char *p, *pattern_start = (char *)query->data + sizeof(*opts);
- struct para_buffer b = {.max_size = SHMMAX,
+ struct para_buffer b = {.max_size = shm_get_shmmax(),
.flags = (opts->mode == LS_MODE_PARSER)? PBF_SIZE_PREFIX : 0,
.max_size_handler = pass_buffer_as_shm, .private_data = &fd};
int i = 0, ret;
prepare_ls_row));
if (ret < 0)
goto out;
- if (!opts->num_matching_paths)
+ if (opts->num_matching_paths == 0) {
+ if (opts->num_patterns > 0)
+ para_printf(&b, "no matches\n");
goto out;
+ }
ret = sort_matching_paths(opts);
if (ret < 0)
goto out;
func));
}
-static struct osl_row *find_hash_sister(HASH_TYPE *hash)
+static struct osl_row *find_hash_sister(unsigned char *hash)
{
const struct osl_object obj = {.data = hash, .size = HASH_SIZE};
struct osl_row *row;
* It's OK to call this with afhi == NULL. In this case, the audio format
* handler info won't be stored in the buffer.
*/
-static void save_add_callback_buffer(HASH_TYPE *hash, const char *path,
+static void save_add_callback_buffer(unsigned char *hash, const char *path,
struct afh_info *afhi, uint32_t flags,
uint8_t audio_format_num, struct osl_object *obj)
{
struct osl_row *pb, *aft_row;
struct osl_row *hs;
struct osl_object objs[NUM_AFT_COLUMNS];
- HASH_TYPE *hash;
+ unsigned char *hash;
char asc[2 * HASH_SIZE + 1];
int ret;
char afsi_buf[AFSI_SIZE];
uint32_t flags = read_u32(buf + CAB_FLAGS_OFFSET);
struct afs_info default_afsi = {.last_played = 0};
- struct para_buffer msg = {.max_size = SHMMAX,
+ struct para_buffer msg = {.max_size = shm_get_shmmax(),
.max_size_handler = pass_buffer_as_shm, .private_data = &fd};
uint16_t afhi_offset, chunks_offset;
- hash = (HASH_TYPE *)buf + CAB_HASH_OFFSET;
+ hash = (unsigned char *)buf + CAB_HASH_OFFSET;
hash_to_asc(hash, asc);;
objs[AFTCOL_HASH].data = buf + CAB_HASH_OFFSET;
objs[AFTCOL_HASH].size = HASH_SIZE;
objs[AFTCOL_CHUNKS].size = query->size - chunks_offset;
if (pb && !hs) { /* update pb's hash */
char old_asc[2 * HASH_SIZE + 1];
- HASH_TYPE *old_hash;
+ unsigned char *old_hash;
ret = get_hash_of_row(pb, &old_hash);
if (ret < 0)
goto out;
static void hash_sister_callback(int fd, const struct osl_object *query)
{
- HASH_TYPE *hash = query->data;
+ unsigned char *hash = query->data;
struct osl_row *hash_sister;
hash_sister = find_hash_sister(hash);
static int get_row_pointer_from_result(struct osl_object *result, void *private)
{
struct osl_row **row = private;
- *row = result->data;
+ *row = *(struct osl_row **)(result->data);
return 1;
}
struct afh_info afhi, *afhi_ptr = NULL;
struct osl_row *pb = NULL, *hs = NULL; /* path brother/hash sister */
struct osl_object map, obj = {.data = NULL}, query;
- HASH_TYPE hash[HASH_SIZE];
+ unsigned char hash[HASH_SIZE];
ret = guess_audio_format(path);
if (ret < 0 && !(pad->flags & ADD_FLAG_ALL))
struct com_touch_options *cto;
/** Message buffer. */
struct para_buffer pb;
- /** How many audio files matched the given pattern. */
- unsigned num_matches;
};
static int touch_audio_file(__a_unused struct osl_table *table,
if (tad->cto->amp >= 0)
new_afsi.amp = tad->cto->amp;
}
- tad->num_matches++;
save_afsi(&new_afsi, &obj); /* in-place update */
aced.aft_row = row;
aced.old_afsi = &old_afsi;
{
struct touch_action_data tad = {.cto = query->data,
.pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
}
ret = for_each_matching_row(&pmd);
if (ret < 0)
ret2 = para_printf(&tad.pb, "%s\n", para_strerror(-ret));
- else
- if (!tad.num_matches)
- ret2 = para_printf(&tad.pb, "no matches\n");
+ else if (pmd.num_matches == 0)
+ ret2 = para_printf(&tad.pb, "no matches\n");
if (ret2 >= 0 && tad.pb.offset)
pass_buffer_as_shm(tad.pb.buf, tad.pb.offset, &fd);
free(tad.pb.buf);
uint32_t flags;
/** Message buffer. */
struct para_buffer pb;
- /** Number of audio files removed. */
- unsigned num_removed;
};
static int remove_audio_file(__a_unused struct osl_table *table,
ret = osl(osl_del_row(audio_file_table, row));
if (ret < 0)
para_printf(&crd->pb, "%s: %s\n", name, para_strerror(-ret));
- else
- crd->num_removed++;
return ret;
}
{
struct com_rm_action_data crd = {.flags = *(uint32_t *)query->data,
.pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
}
para_printf(&crd.pb, "%s\n", para_strerror(-ret));
return;
}
- if (!crd.num_removed && !(crd.flags & RM_FLAG_FORCE))
+ if ((pmd.num_matches == 0) && !(crd.flags & RM_FLAG_FORCE))
ret = para_printf(&crd.pb, "no matches -- nothing removed\n");
- else {
- if (crd.flags & RM_FLAG_VERBOSE)
- ret = para_printf(&crd.pb, "removed %u files\n", crd.num_removed);
+ else if (crd.flags & RM_FLAG_VERBOSE) {
+ ret = para_printf(&crd.pb, "removed %u files\n",
+ pmd.num_matches);
}
if (ret >= 0 && crd.pb.offset)
pass_buffer_as_shm(crd.pb.buf, crd.pb.offset, &fd);
struct cpsi_action_data {
/** command line flags (see \ref cpsi_flags). */
unsigned flags;
- /** Number of audio files changed. */
- unsigned num_copied;
/** Message buffer. */
struct para_buffer pb;
/** Values are copied from here. */
if (cad->flags & CPSI_FLAG_COPY_ATTRIBUTES)
target_afsi.attributes = cad->source_afsi.attributes;
save_afsi(&target_afsi, &target_afsi_obj); /* in-place update */
- cad->num_copied++;
if (cad->flags & CPSI_FLAG_VERBOSE) {
ret = para_printf(&cad->pb, "copied afsi to %s\n", name);
if (ret < 0)
struct cpsi_action_data cad = {
.flags = *(unsigned *)query->data,
.pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
}
if (ret < 0)
para_printf(&cad.pb, "%s\n", para_strerror(-ret));
else if (cad.flags & CPSI_FLAG_VERBOSE) {
- if (cad.num_copied)
+ if (pmd.num_matches > 0)
para_printf(&cad.pb, "copied requested afsi from %s "
- "to %u files\n", source_path, cad.num_copied);
+ "to %u files\n", source_path, pmd.num_matches);
else
para_printf(&cad.pb, "nothing copied\n");
}
* up-to-date afs status items directly. Therefore the usual callback mechanism
* is used to pass the status items from the afs process to the command handler
* via a shared memory area and a pipe.
+ *
+ * \return The return value of the underyling call to \ref send_callback_request().
*/
int send_afs_status(struct stream_cipher_context *scc, int parser_friendly)
{
void aft_check_callback(int fd, __a_unused const struct osl_object *query)
{
struct para_buffer pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
};
{
osl_close_table(audio_file_table, OSL_MARK_CLEAN);
audio_file_table = NULL;
- free(status_items);
- status_items = NULL;
- free(parser_friendly_status_items);
- parser_friendly_status_items = NULL;
}
/**