Ejemplo n.º 1
0
/* Sort the playlist by file names. */
void plist_sort_fname (struct plist *plist)
{
	struct plist_item *sorted;
	struct rb_node *x;
	int n;

	if (plist_count(plist) == 0)
		return;

	sorted = (struct plist_item *)xmalloc (plist_count(plist) *
			sizeof(struct plist_item));

	x = rb_min (plist->search_tree);
	assert (!rb_is_null(x));

	while (plist_deleted(plist, (intptr_t)rb_get_data (x)))
		x = rb_next (x);

	sorted[0] = plist->items[(intptr_t)rb_get_data (x)];
	rb_set_data (x, NULL);

	n = 1;
	while (!rb_is_null(x = rb_next(x))) {
		if (!plist_deleted(plist, (intptr_t)rb_get_data (x))) {
			sorted[n] = plist->items[(intptr_t)rb_get_data (x)];
			rb_set_data (x, (void *)(intptr_t)n++);
		}
	}

	plist->num = n;
	plist->not_deleted = n;

	memcpy (plist->items, sorted, sizeof(struct plist_item) * n);
	free (sorted);
}
Ejemplo n.º 2
0
/* Make a title from the file name for the item. If hide extension != 0, strip
 * the file name from extension. */
void make_file_title (struct plist *plist, const int num,
		const int hide_extension)
{
	
	assert (plist != NULL);
	assert (num >= 0 && num < plist->num);
	assert (!plist_deleted(plist, num));

	if (file_type(plist->items[num].file) != F_URL) {
		char *file = xstrdup (plist->items[num].file);
		
		if (hide_extension) {
			char *dot = strrchr (file, '.');

			if (dot)
				*dot = 0;
		}

		if (options_get_int ("FileNamesIconv")) 
		{
			char *old_title = file;
			file = files_iconv_str (file);
			free (old_title);
		}

		plist_set_title_file (plist, num, file);
		free (file);
	}
	else
		plist_set_title_file (plist, num, plist->items[num].file);
}
Ejemplo n.º 3
0
/* Return the index of the last non-deleted item from the playlist.
 * Return -1 if there are no items. */
int plist_last (const struct plist *plist)
{
	int i;

	i = plist->num - 1;

	while (i > 0 && plist_deleted(plist, i))
		i--;

	return i;
}
Ejemplo n.º 4
0
/* Switch playlist titles to title_file */
void switch_titles_file (struct plist *plist)
{
	int i;
	int hide_extension = options_get_int("HideFileExtension");
		
	for (i = 0; i < plist->num; i++)
		if (!plist_deleted(plist, i)) {
			if (!plist->items[i].title_file)
				make_file_title (plist, i, hide_extension);
			assert (plist->items[i].title_file != NULL);
			plist->items[i].title = plist->items[i].title_file;
		}
}
Ejemplo n.º 5
0
/* Find an item in the list.  Return the index or -1 if not found. */
int plist_find_fname (struct plist *plist, const char *file)
{
	struct rb_node *x;

	assert (plist != NULL);

	x = rb_search (plist->search_tree, file);

	if (rb_is_null(x))
		return -1;

	return !plist_deleted(plist, (intptr_t)rb_get_data (x)) ?
                                 (intptr_t)rb_get_data (x) : -1;
}
Ejemplo n.º 6
0
void plist_discard_tags (struct plist *plist)
{
	int i;

	assert (plist != NULL);

	for (i = 0; i < plist->num; i++)
		if (!plist_deleted(plist, i) && plist->items[i].tags) {
			tags_free (plist->items[i].tags);
			plist->items[i].tags = NULL;
		}

	plist->items_with_time = 0;
	plist->total_time = 0;
}
Ejemplo n.º 7
0
/* Add the content of playlist b to a by copying items. */
void plist_cat (struct plist *a, struct plist *b)
{
	int i;

	assert (a != NULL);
	assert (b != NULL);

	for (i = 0; i < b->num; i++) {
		assert (b->items[i].file != NULL);

		if (!plist_deleted (b, i) &&
		    plist_find_fname (a, b->items[i].file) == -1)
			plist_add_from_item (a, &b->items[i]);
	}
}
Ejemplo n.º 8
0
/* Find an item in the list; also find deleted items.  If there is more than
 * one item for this file, return the non-deleted one or, if all are deleted,
 * return the last of them.  Return the index or -1 if not found. */
int plist_find_del_fname (const struct plist *plist, const char *file)
{
	int i;
	int item = -1;

	assert (plist != NULL);

	for (i = 0; i < plist->num; i++) {
		if (plist->items[i].file
				&& !strcmp(plist->items[i].file, file)) {
			if (item == -1 || plist_deleted(plist, item))
				item = i;
		}
	}

	return item;
}
Ejemplo n.º 9
0
/* Switch playlist titles to title_tags */
void switch_titles_tags (struct plist *plist)
{
	int i;

	for (i = 0; i < plist->num; i++)
		if (!plist_deleted(plist, i)) {
			if (plist->items[i].title_tags)
				plist->items[i].title
					= plist->items[i].title_tags;
			else {
				if (!plist->items[i].title_file)
					make_file_title (plist, i,
							options_get_int("HideFileExtension"));
				plist->items[i].title
					= plist->items[i].title_file;
			}
		}
}
Ejemplo n.º 10
0
/* Returns the next filename that is a dead entry, or NULL if there are none
 * left.
 *
 * It will set the index on success.
 */
const char *plist_get_next_dead_entry (const struct plist *plist,
                                       int *last_index)
{
	int i;

	assert (last_index != NULL);
	assert (plist != NULL);

	for (i = *last_index; i < plist->num; i++) {
		if (plist->items[i].file
			  && ! plist_deleted(plist, i)
			  && ! can_read_file(plist->items[i].file)) {
			*last_index = i + 1;
			return plist->items[i].file;
		}
	}

	return NULL;
}
Ejemplo n.º 11
0
/* Client requested we send the queue so we get it from audio.c and
 * send it to the client. */
static int req_send_queue (struct client *cli)
{
	int i;
	struct plist *queue;

	logit ("Client with fd %d wants queue... sending it", cli->socket);

	if (!send_int(cli->socket, EV_DATA)) {
		logit ("Error while sending response; disconnecting the client");
		close (cli->socket);
		del_client (cli);
		return 0;
	}

	queue = audio_queue_get_contents ();

	for (i = 0; i < queue->num; i++)
		if (!plist_deleted(queue, i)) {
			if(!send_item(cli->socket, &queue->items[i])){
				logit ("Error sending queue; disconnecting the client");
				close (cli->socket);
				del_client (cli);
				free (queue);
				return 0;
			}
		}

	plist_free (queue);
	free (queue);

	if (!send_item (cli->socket, NULL)) {
		logit ("Error while sending end of playlist mark; "
		       "disconnecting the client");
		close (cli->socket);
		del_client (cli);
		return 0;
	}

	logit ("Queue sent");
	return 1;
}
Ejemplo n.º 12
0
/* Make a title from the tags for the item. */
void make_tags_title (struct plist *plist, const int num)
{
	assert (plist != NULL);
	assert (num >= 0 && num < plist->num);
	assert (!plist_deleted(plist, num));

	if (file_type(plist->items[num].file) == F_URL)
		make_file_title (plist, num, 0);
	else if (!plist->items[num].title_tags) {
		char *title;
		assert (plist->items[num].file != NULL);

		if (plist->items[num].tags->title) {
			title = build_title (plist->items[num].tags);
			plist_set_title_tags (plist, num, title);
			free (title);
		}
		else
			make_file_title (plist, num,
					options_get_int("HideFileExtension"));
	}
}
Ejemplo n.º 13
0
/* Save plist in m3u format. Strip paths by strip_path bytes.
 * If save_serial is not 0, the playlist serial is saved in a
 * comment. */
static int plist_save_m3u (struct plist *plist, const char *fname,
		const int strip_path, const int save_serial)
{
	FILE *file;
	int i;

	debug ("Saving playlist to '%s'", fname);

	if (!(file = fopen(fname, "w"))) {
		error ("Can't save playlist: %s", strerror(errno));
		return 0;
	}

	if (flock(fileno(file), LOCK_EX) == -1)
		logit ("Can't flock() the playlist file: %s", strerror(errno));

	if (fprintf(file, "#EXTM3U\r\n") < 0) {
		error ("Error writing playlist: %s", strerror(errno));
		fclose (file);
		return 0;
	}

	if (save_serial && fprintf(file, "#MOCSERIAL: %d\r\n",
				plist_get_serial(plist)) < 0) {
		error ("Error writing playlist: %s", strerror(errno));
		fclose (file);
		return 0;
	}

	for (i = 0; i < plist->num; i++) {
		if (!plist_deleted(plist, i)) {
			int ret;

			/* EXTM3U */
			if (plist->items[i].tags)
				ret = fprintf (file, "#EXTINF:%d,%s\r\n",
						plist->items[i].tags->time,
						plist->items[i].title_tags ?
						plist->items[i].title_tags
						: plist->items[i].title_file);
			else
				ret = fprintf (file, "#EXTINF:%d,%s\r\n", 0,
						plist->items[i].title_file);

			if (ret < 0) {
				error ("Error writing playlist: %s",
						strerror(errno));
				fclose (file);
				return 0;
			}

			/* file */
			if (fprintf(file, "%s\r\n", plist->items[i].file
						+ strip_path) < 0) {
				error ("Error writing playlist: %s",
						strerror(errno));
				fclose (file);
				return 0;
			}
		}
	}

	if (flock(fileno(file), LOCK_UN) == -1)
		logit ("Can't flock() (unlock) the playlist file: %s",
				strerror(errno));
	if (fclose(file)) {
		error ("Error writing playlist: %s", strerror(errno));
		return 0;
	}
	return 1;
}
Ejemplo n.º 14
0
/* Save plist in m3u format. Strip paths by strip_path bytes.
 * If save_serial is not 0, the playlist serial is saved in a
 * comment. */
static int plist_save_m3u (struct plist *plist, const char *fname,
                           const int strip_path, const int save_serial)
{
    FILE *file = NULL;
    int i, ret, result = 0;

    debug ("Saving playlist to '%s'", fname);

    file = fopen (fname, "w");
    if (!file) {
        error_errno ("Can't save playlist", errno);
        return 0;
    }

    /* Lock gets released by fclose(). */
    if (lockf (fileno (file), F_LOCK, 0) == -1)
        log_errno ("Can't lock the playlist file", errno);

    if (fprintf (file, "#EXTM3U\r\n") < 0) {
        error_errno ("Error writing playlist", errno);
        goto err;
    }

    if (save_serial && fprintf (file, "#MOCSERIAL: %d\r\n",
                                plist_get_serial (plist)) < 0) {
        error_errno ("Error writing playlist", errno);
        goto err;
    }

    for (i = 0; i < plist->num; i++) {
        if (!plist_deleted (plist, i)) {

            /* EXTM3U */
            if (plist->items[i].tags)
                ret = fprintf (file, "#EXTINF:%d,%s\r\n",
                               plist->items[i].tags->time,
                               plist->items[i].title_tags ?
                               plist->items[i].title_tags
                               : plist->items[i].title_file);
            else
                ret = fprintf (file, "#EXTINF:%d,%s\r\n", 0,
                               plist->items[i].title_file);

            /* file */
            if (ret >= 0)
                ret = fprintf (file, "%s\r\n",
                               plist->items[i].file + strip_path);

            if (ret < 0) {
                error_errno ("Error writing playlist", errno);
                goto err;
            }
        }
    }

    ret = fclose (file);
    file = NULL;
    if (ret)
        error_errno ("Error writing playlist", errno);
    else
        result = 1;

err:
    if (file)
        fclose (file);
    return result;
}