Example #1
0
/* Return a list of lyrics lines loaded from a file, or NULL on error. */
lists_t_strs *lyrics_load_file (const char *filename)
{
	FILE *lyrics_file = NULL;
	const char *mime;
	char *line;
	lists_t_strs *result;

	assert (filename);

	lyrics_message = "[No lyrics file!]";
	if (!file_exists (filename))
		return NULL;
	mime = file_mime_type (filename);
	if (mime && strncmp (mime, "text/plain", 10))
		return NULL;

	lyrics_file = fopen (filename, "r");
	if (lyrics_file == NULL) {
		lyrics_message = "[Lyrics file cannot be read!]";
		logit ("Error reading '%s': %s", filename, strerror (errno));
		return NULL;
	}

	result = lists_strs_new (0);
	while ((line = read_line (lyrics_file)) != NULL)
		lists_strs_push (result, line);
	fclose (lyrics_file);

	lyrics_message = NULL;
	return result;
}
Example #2
0
/* Put something into the log */
void internal_logit (const char *file, const int line, const char *function,
		const char *format, ...)
{
	int len;
	char *msg, time_str[20];
	struct timeval utc_time;
	va_list va;
	struct tm tm_time;
	const char fmt[] = "%s.%06u: %s:%d %s(): %s\n";

	if (!logfp) {
		switch (logging_state) {
		case UNINITIALISED:
			buffered_log = lists_strs_new (128);
			logging_state = BUFFERING;
			break;
		case BUFFERING:
			/* Don't let storage run away on us. */
			if (lists_strs_size (buffered_log) < lists_strs_capacity (buffered_log))
				break;
			log_records_spilt += 1;
			return;
		case LOGGING:
			return;
		}
	}

	va_start (va, format);
	len = vsnprintf (NULL, 0, format, va) + 1;
	va_end (va);
	msg = xmalloc (len);
	va_start (va, format);
	vsnprintf (msg, len, format, va);
	va_end (va);

	gettimeofday (&utc_time, NULL);
	localtime_r (&utc_time.tv_sec, &tm_time);
	strftime (time_str, sizeof (time_str), "%b %e %T", &tm_time);

	if (logfp) {
		fprintf (logfp, fmt, time_str, (unsigned)utc_time.tv_usec,
		                     file, line, function, msg);
		fflush (logfp);
	}
	else {
		char *str;

		len = snprintf (NULL, 0, fmt, time_str, (unsigned)utc_time.tv_usec,
		                              file, line, function, msg);
		str = xmalloc (len + 1);
		snprintf (str, len + 1, fmt, time_str, (unsigned)utc_time.tv_usec,
		                             file, line, function, msg);

		lists_strs_push (buffered_log, str);
	}

	free (msg);
}
Example #3
0
/* Copy a string and append it to the end of a list. */
void lists_strs_append (lists_t_strs *list, const char *s)
{
	char *str;

	assert (list);
	assert (s);

	str = xstrdup (s);
	lists_strs_push (list, str);
}
Example #4
0
static void on_song_change ()
{
	static char *last_file = NULL;
	static lists_t_strs *on_song_change = NULL;

	int ix;
	bool same_file, unpaused;
	char *curr_file, **args;
	struct file_tags *curr_tags;
	lists_t_strs *arg_list;

	/* We only need to do OnSongChange tokenisation once. */
	if (on_song_change == NULL) {
		char *command;

		on_song_change = lists_strs_new (4);
		command = options_get_str ("OnSongChange");

		if (command)
			lists_strs_tokenise (on_song_change, command);
	}

	if (lists_strs_empty (on_song_change))
		return;

	curr_file = audio_get_sname ();

	if (curr_file == NULL)
		return;

	same_file = (last_file && !strcmp (last_file, curr_file));
	unpaused = (audio_get_prev_state () == STATE_PAUSE);
	if (same_file && (unpaused || !options_get_bool ("RepeatSongChange"))) {
		free (curr_file);
		return;
	}

	curr_tags = tags_cache_get_immediate (tags_cache, curr_file,
	                                      TAGS_COMMENTS | TAGS_TIME);
	arg_list = lists_strs_new (lists_strs_size (on_song_change));
	for (ix = 0; ix < lists_strs_size (on_song_change); ix += 1) {
		char *arg, *str;

		arg = lists_strs_at (on_song_change, ix);
		if (arg[0] != '%')
			lists_strs_append (arg_list, arg);
		else if (!curr_tags)
			lists_strs_append (arg_list, "");
		else {
			switch (arg[1]) {
			case 'a':
				str = curr_tags->artist ? curr_tags->artist : "";
				lists_strs_append (arg_list, str);
				break;
			case 'r':
				str = curr_tags->album ? curr_tags->album : "";
				lists_strs_append (arg_list, str);
				break;
			case 't':
				str = curr_tags->title ? curr_tags->title : "";
				lists_strs_append (arg_list, str);
				break;
			case 'n':
				if (curr_tags->track >= 0) {
					str = (char *) xmalloc (sizeof (char) * 4);
					snprintf (str, 4, "%d", curr_tags->track);
					lists_strs_push (arg_list, str);
				}
				else
					lists_strs_append (arg_list, "");
				break;
			case 'f':
				lists_strs_append (arg_list, curr_file);
				break;
			case 'D':
				if (curr_tags->time >= 0) {
					str = (char *) xmalloc (sizeof (char) * 10);
					snprintf (str, 10, "%d", curr_tags->time);
					lists_strs_push (arg_list, str);
				}
				else
					lists_strs_append (arg_list, "");
				break;
			case 'd':
				if (curr_tags->time >= 0) {
					str = (char *) xmalloc (sizeof (char) * 12);
					sec_to_min (str, curr_tags->time);
					lists_strs_push (arg_list, str);
				}
				else
					lists_strs_append (arg_list, "");
				break;
			default:
				lists_strs_append (arg_list, arg);
			}
		}
	}
	tags_free (curr_tags);

#ifndef NDEBUG
	{
		char *cmd;

		cmd = lists_strs_fmt (arg_list, " %s");
		debug ("Running command: %s", cmd);
		free (cmd);
	}
#endif

	switch (fork ()) {
	case 0:
		args = lists_strs_save (arg_list);
		execve (args[0], args, environ);
		exit (EXIT_FAILURE);
	case -1:
		log_errno ("Failed to fork()", errno);
	}

	lists_strs_free (arg_list);
	free (last_file);
	last_file = curr_file;
}