예제 #1
0
파일: lyrics.c 프로젝트: Manishearth/moc
/* 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;
}
예제 #2
0
파일: log.c 프로젝트: Manishearth/moc
/* 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);
}
예제 #3
0
파일: main.c 프로젝트: oopsmonk/moc-git
/* Log the command line which launched MOC. */
static void log_command_line (int argc, char *argv[])
{
	lists_t_strs *cmdline;
	char *str;

	assert (argc >= 0);
	assert (argv != NULL);
	assert (argv[argc] == NULL);

	cmdline = lists_strs_new (argc);
	if (lists_strs_load (cmdline, argv) > 0)
		str = lists_strs_fmt (cmdline, "%s ");
	else
		str = xstrdup ("No command line available");
	logit ("%s", str);
	free (str);
	lists_strs_free (cmdline);
}
예제 #4
0
파일: common.c 프로젝트: gitkaste/moc
/* Read and return a line from 'stream' in a dynamically allocated buffer.
 * Return NULL at end of file. */
char *xgetline (FILE *stream)
{
	static char buffer[64];
	char *result;
	lists_t_strs *line;

	line = lists_strs_new (4);

	do {
		if (!fgets (buffer, sizeof (buffer), stream))
			break;
		lists_strs_append (line, buffer);
	} while (buffer[strlen (buffer) - 1] != '\n');

	result = lists_strs_cat (line);
	lists_strs_free (line);

	return result;
}
예제 #5
0
파일: sndfile.c 프로젝트: jonsafari/mocp
static void load_extn_list ()
{
	const int counts[] = {SFC_GET_SIMPLE_FORMAT_COUNT,
	                      SFC_GET_FORMAT_MAJOR_COUNT};
	const int formats[] = {SFC_GET_SIMPLE_FORMAT,
	                       SFC_GET_FORMAT_MAJOR};

	supported_extns = lists_strs_new (16);

	for (size_t ix = 0; ix < ARRAY_SIZE(counts); ix += 1) {
		int limit;
		SF_FORMAT_INFO format_info;

		sf_command (NULL, counts[ix], &limit, sizeof (limit));
		for (int iy = 0 ; iy < limit ; iy += 1) {
			format_info.format = iy ;
			sf_command (NULL, formats[ix], &format_info, sizeof (format_info));
			if (!lists_strs_exists (supported_extns, format_info.extension))
				lists_strs_append (supported_extns, format_info.extension);
		}
	}

	/* These are synonyms of supported extensions. */
	if (lists_strs_exists (supported_extns, "aiff"))
		lists_strs_append (supported_extns, "aif");
	if (lists_strs_exists (supported_extns, "au"))
		lists_strs_append (supported_extns, "snd");
	if (lists_strs_exists (supported_extns, "wav")) {
		lists_strs_append (supported_extns, "nist");
		lists_strs_append (supported_extns, "sph");
	}
	if (lists_strs_exists (supported_extns, "iff"))
		lists_strs_append (supported_extns, "svx");
	if (lists_strs_exists (supported_extns, "oga"))
		lists_strs_append (supported_extns, "ogg");
	if (lists_strs_exists (supported_extns, "sf"))
		lists_strs_append (supported_extns, "ircam");
	if (lists_strs_exists (supported_extns, "mat")) {
		lists_strs_append (supported_extns, "mat4");
		lists_strs_append (supported_extns, "mat5");
	}
}
예제 #6
0
파일: decoder.c 프로젝트: dpbriggs/mocp
/* Add a new preference for an audio format. */
static void load_each_preference (const char *preference)
{
    const char *prefix;
    lists_t_strs *tokens;
    decoder_t_preference *pref;

    assert (preference && preference[0]);

    tokens = lists_strs_new (4);
    lists_strs_split (tokens, preference, "(,)");
    prefix = lists_strs_at (tokens, 0);
    pref = make_preference (prefix);
#ifdef DEBUG
    pref->source = preference;
#endif
    load_decoders (pref, tokens);
    pref->next = preferences;
    preferences = pref;
    lists_strs_free (tokens);
}
예제 #7
0
파일: decoder.c 프로젝트: dpbriggs/mocp
/* Return a string of concatenated driver names. */
static char *list_decoder_names (int *decoder_list, int count)
{
    int ix;
    char *result;
    lists_t_strs *names;

    if (count == 0)
        return xstrdup ("");

    names = lists_strs_new (count);
    for (ix = 0; ix < count; ix += 1)
        lists_strs_append (names, plugins[decoder_list[ix]].name);
    if (have_tremor) {
        ix = lists_strs_find (names, "vorbis");
        if (ix < lists_strs_size (names))
            lists_strs_replace (names, ix, "vorbis(tremor)");
    }
    result = lists_strs_fmt (names, " %s");
    lists_strs_free (names);

    return result;
}
예제 #8
0
파일: server.c 프로젝트: jonsafari/mocp
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;
}
예제 #9
0
파일: lyrics.c 프로젝트: Manishearth/moc
		len = max;
	}
	strcpy (&result[len], "\n");

	return result;
}

/* Centre all the lines in the lyrics. */
static lists_t_strs *centre_style (lists_t_strs *lines, int height ATTR_UNUSED,
                                   int width, void *data ATTR_UNUSED)
{
	lists_t_strs *result;
	int ix, size;

	size = lists_strs_size (lines);
	result = lists_strs_new (size);
	for (ix = 0; ix < size; ix += 1) {
		char *old_line, *new_line;

		old_line = lists_strs_at (lines, ix);
		new_line = centre_line (old_line, width);
		lists_strs_push (result, new_line);
	}

	return result;
}

/* Formatting function information. */
static lyrics_t_formatter *lyrics_formatter = centre_style;
static lyrics_t_reaper *formatter_reaper = NULL;
static void *formatter_data = NULL;
예제 #10
0
파일: main.c 프로젝트: oopsmonk/moc-git
int main (int argc, char *argv[])
{
	struct parameters params;
	lists_t_strs *deferred_overrides;
	lists_t_strs *args;

#ifdef HAVE_UNAME_SYSCALL
	int rc;
	struct utsname uts;
#endif

#ifdef PACKAGE_REVISION
	logit ("This is Music On Console (revision %s)", PACKAGE_REVISION);
#else
	logit ("This is Music On Console (version %s)", PACKAGE_VERSION);
#endif

#ifdef CONFIGURATION
	logit ("Configured:%s", CONFIGURATION);
#endif

#ifdef HAVE_UNAME_SYSCALL
	rc = uname (&uts);
	if (rc == 0)
		logit ("Running on: %s %s %s", uts.sysname, uts.release, uts.machine);
#endif

	log_command_line (argc, argv);

	files_init ();

	if (get_home () == NULL)
		fatal ("Could not determine user's home directory!");

	memset (&params, 0, sizeof(params));
	options_init ();
	deferred_overrides = lists_strs_new (4);

	/* set locale according to the environment variables */
	if (!setlocale(LC_ALL, ""))
		logit ("Could not set locale!");

	args = process_command_line (argc, argv, &params, deferred_overrides);

	if (params.dont_run_iface && params.only_server)
		fatal ("-c, -a and -p options can't be used with --server!");

	if (!params.config_file)
		params.config_file = xstrdup (create_file_name ("config"));
	options_parse (params.config_file);
	if (params.config_file)
		free (params.config_file);
	params.config_file = NULL;

	process_deferred_overrides (deferred_overrides);
	lists_strs_free (deferred_overrides);
	deferred_overrides = NULL;

	check_moc_dir ();

	io_init ();
	rcc_init ();
	decoder_init (params.debug);
	srand (time(NULL));

	if (!params.only_server && params.dont_run_iface)
		server_command (&params, args);
	else
		start_moc (&params, args);

	lists_strs_free (args);
	options_free ();
	decoder_cleanup ();
	io_cleanup ();
	rcc_cleanup ();
	files_cleanup ();
	compat_cleanup ();

	exit (EXIT_SUCCESS);
}
예제 #11
0
파일: main.c 프로젝트: oopsmonk/moc-git
/* Process the command line options and arguments. */
static lists_t_strs *process_command_line (int argc, char *argv[],
                                           struct parameters *params,
                                           lists_t_strs *deferred)
{
	int ret, opt_index = 0;
	const char *jump_type;
	lists_t_strs *result;

	struct option long_options[] = {
		{ "version",		0, NULL, 'V' },
		{ "help",		0, NULL, 'h' },
#ifndef NDEBUG
		{ "debug",		0, NULL, 'D' },
#endif
		{ "server",		0, NULL, 'S' },
		{ "foreground",		0, NULL, 'F' },
		{ "sound-driver",	1, NULL, 'R' },
		{ "music-dir",		0, NULL, 'm' },
		{ "append",		0, NULL, 'a' },
		{ "enqueue",		0, NULL, 'q' },
		{ "clear", 		0, NULL, 'c' },
		{ "play", 		0, NULL, 'p' },
		{ "playit",		0, NULL, 'l' },
		{ "stop",		0, NULL, 's' },
		{ "next",		0, NULL, 'f' },
		{ "previous",		0, NULL, 'r' },
		{ "exit",		0, NULL, 'x' },
		{ "theme",		1, NULL, 'T' },
		{ "config",		1, NULL, 'C' },
		{ "set-option",		1, NULL, 'O' },
		{ "moc-dir",		1, NULL, 'M' },
		{ "pause",		0, NULL, 'P' },
		{ "unpause",		0, NULL, 'U' },
		{ "toggle-pause",	0, NULL, 'G' },
		{ "sync",		0, NULL, 'y' },
		{ "nosync",		0, NULL, 'n' },
		{ "ascii",		0, NULL, 'A' },
		{ "info",		0, NULL, 'i' },
		{ "recursively",	0, NULL, 'e' },
		{ "seek",		1, NULL, 'k' },
		{ "jump",		1, NULL, 'j' },
		{ "format",		1, NULL, 'Q' },
		{ "volume",		1, NULL, 'v' },
		{ "toggle",		1, NULL, 't' },
		{ "on",			1, NULL, 'o' },
		{ "off",		1, NULL, 'u' },
		{ "playnum",		1, NULL, 'N' },
		{ 0, 0, 0, 0 }
	};

	assert (argc >= 0);
	assert (argv != NULL);
	assert (argv[argc] == NULL);
	assert (params != NULL);
	assert (deferred != NULL);

	while ((ret = getopt_long(argc, argv,
					"VhDSFR:macpsxT:C:O:M:PUynArfiGelk:j:v:t:o:u:Q:qN:",
					long_options, &opt_index)) != -1) {
		switch (ret) {
			case 'V':
				show_version ();
				exit (EXIT_SUCCESS);
			case 'h':
				show_usage (argv[0]);
				exit (EXIT_SUCCESS);
#ifndef NDEBUG
			case 'D':
				params->debug = 1;
				break;
#endif
			case 'S':
				params->only_server = 1;
				break;
			case 'F':
				params->foreground = 1;
				params->only_server = 1;
				break;
			case 'R':
				if (!options_check_list ("SoundDriver", optarg))
					fatal ("No such sound driver: %s", optarg);
				options_set_list ("SoundDriver", optarg, false);
				options_ignore_config ("SoundDriver");
				break;
			case 'm':
				options_set_int ("StartInMusicDir", 1);
				options_ignore_config ("StartInMusicDir");
				break;
			case 'a':
			case 'e':
				params->append = 1;
				params->dont_run_iface = 1;
				break;
			case 'q':
				params->enqueue = 1;
				params->dont_run_iface = 1;
				break;
			case 'c':
				params->clear = 1;
				params->dont_run_iface = 1;
				break;
			case 'i':
				params->get_file_info = 1;
				params->dont_run_iface = 1;
				break;
			case 'p':
				params->play = 1;
				params->dont_run_iface = 1;
				break;
			case 'l':
				params->playit = 1;
				params->dont_run_iface = 1;
				break;
			case 's':
				params->stop = 1;
				params->dont_run_iface = 1;
				break;
			case 'f':
				params->next = 1;
				params->dont_run_iface = 1;
				break;
			case 'r':
				params->previous = 1;
				params->dont_run_iface = 1;
				break;
			case 'x':
				params->exit = 1;
				params->dont_run_iface = 1;
				break;
			case 'P':
				params->pause = 1;
				params->dont_run_iface = 1;
				break;
			case 'U':
				params->unpause = 1;
				params->dont_run_iface = 1;
				break;
			case 'T':
				options_set_str ("ForceTheme", optarg);
				break;
			case 'C':
				params->config_file = xstrdup (optarg);
				break;
			case 'O':
				override_config_option (optarg, deferred);
				break;
			case 'M':
				options_set_str ("MOCDir", optarg);
				options_ignore_config ("MOCDir");
				break;
			case 'y':
				options_set_int ("SyncPlaylist", 1);
				options_ignore_config ("SyncPlaylist");
				break;
			case 'n':
				options_set_int ("SyncPlaylist", 0);
				options_ignore_config ("SyncPlaylist");
				break;
			case 'A':
				options_set_int ("ASCIILines", 1);
				options_ignore_config ("ASCIILines");
				break;
			case 'G':
				params->toggle_pause = 1;
				params->dont_run_iface = 1;
				break;
			case 'k':
				params->seek_by = get_num_param (optarg, NULL);
				params->dont_run_iface = 1;
				break;
			case 'j':
				params->jump_to = get_num_param (optarg, &jump_type);
				if (*jump_type)
					if (!jump_type[1])
						if (*jump_type == '%' || tolower (*jump_type) == 's') {
							params->jump_type = tolower (*jump_type);
							params->dont_run_iface = 1;
							break;
						}
				//TODO: Add message explaining the error
				show_usage (argv[0]);
				exit (EXIT_FAILURE);
			case 'v' :
				params->adj_volume = optarg;
				params->dont_run_iface = 1;
				break;
			case 't' :
				params->toggle = optarg;
				params->dont_run_iface = 1;
				break;
			case 'o' :
				params->on = optarg;
				params->dont_run_iface = 1;
				break;
			case 'u' :
				params->off = optarg;
				params->dont_run_iface = 1;
				break;
			case 'Q':
				params->formatted_into_param = optarg;
				params->get_formatted_info = 1;
				params->dont_run_iface = 1;
				break;
			case 'N' :
				params->play_num = optarg;
				params->dont_run_iface = 1;
				break;
			default:
				show_usage (argv[0]);
				exit (EXIT_FAILURE);
		}
	}

	result = lists_strs_new (argc - optind);
	lists_strs_load (result, argv + optind);

	return result;
}