Exemple #1
0
static int
parse_log(void)
{
	pkgentry_t *ent, *look;
	avl_index_t where;
	int num = 0;
	int logfd;
	struct stat stb;
	int mlen = strlen(marker);
	off_t realend;
	ptrdiff_t off;
	char *p, *q, *map;

	logfd = open(PKGLOG, O_RDONLY);

	if (logfd < 0) {
		if (errno == ENOENT)
			return (0);
		progerr(gettext("cannot read "PKGLOG": %s"), strerror(errno));
		exit(2);
	}

	if (fstat(logfd, &stb) != 0) {
		progerr(gettext("cannot stat "PKGLOG": %s"), strerror(errno));
		exit(2);
	}

	if (stb.st_size == 0) {
		(void) close(logfd);
		/* Force pkgdump && remove of the logfile. */
		return (1);
	}

	map = mmap(0, stb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
	    logfd, 0);
	(void) close(logfd);
	if (map == (char *)-1) {
		progerr(gettext("Cannot mmap the "PKGLOG": %s"),
		    strerror(errno));
		exit(2);
	}

	cind = 0;

	realend = stb.st_size;

	if (memcmp(map + realend - mlen, marker, mlen) != 0) {
		progerr(gettext(PKGLOG" is not complete"));

		map[stb.st_size - 1] = '\0'; /* for strstr() */
		realend = 0;
		for (p = map; q = strstr(p, marker); ) {
			if (q == map || q[-1] == '\n')
				realend = q - map + mlen;
			p = q + mlen;
		}
		progerr(gettext("Ignoring %ld bytes from log"),
		    (long)(stb.st_size - realend));
	}

	for (off = 0; off < realend; off += q - p) {
		p = map + off;
		q = memchr(p, '\n', realend - off);
		if (q == NULL)
			break;

		q++;
		num++;
		if (p[0] == '#' || p[0] == '\n') {
			if (memcmp(marker, p, mlen) == 0)
				cind = 0;
			else
				handle_comments(p, q - p);
			continue;
		}

		ent = parse_line(p + 1, q - (p + 1) - 1, p[0] != '-');
		if (ent == NULL)
			continue;
		look = avl_find(list, ent, &where);
		/*
		 * The log can be replayed; so any value of "look" is
		 * not unexpected.
		 */
		switch (p[0]) {
		case '+':
		case '=':
			if (look != NULL)
				swapentry(look, ent);
			else
				avl_insert(list, ent, where);
			break;
		case '-':
			if (look != NULL) {
				avl_remove(list, look);
				freeentry(look);
			}
			freeentry(ent);
			break;
		default:
			freeentry(ent);
			progerr(gettext("log %d: bad line"), num);
			break;
		}
	}
	(void) munmap(map, stb.st_size);

	/* Force pkgdump && remove of the logfile if there are no valid mods. */
	return (num == 0 ? 1 : num);
}
Exemple #2
0
static gboolean
xmms_flac_init (xmms_xform_t *xform)
{
	xmms_flac_data_t *data;
	xmms_sample_format_t sample_fmt;
	FLAC__bool retval;
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
	FLAC__StreamDecoderState init_status;
#else
	FLAC__StreamDecoderInitStatus init_status;
#endif
	gint filesize;
	const gchar *metakey;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_flac_data_t, 1);

	xmms_xform_private_data_set (xform, data);

	data->flacdecoder = FLAC__stream_decoder_new ();

	/* we don't need to explicitly tell the decoder to respond to
	 * FLAC__METADATA_TYPE_STREAMINFO here, it always does.
	 */
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
	FLAC__seekable_stream_decoder_set_metadata_respond (data->flacdecoder,
	                                                    FLAC__METADATA_TYPE_VORBIS_COMMENT);
	FLAC__seekable_stream_decoder_set_eof_callback (data->flacdecoder,
	                                                flac_callback_eof);
	FLAC__seekable_stream_decoder_set_read_callback (data->flacdecoder,
	                                                 flac_callback_read);
	FLAC__seekable_stream_decoder_set_seek_callback (data->flacdecoder,
	                                                 flac_callback_seek);
	FLAC__seekable_stream_decoder_set_tell_callback (data->flacdecoder,
	                                                 flac_callback_tell);
	FLAC__seekable_stream_decoder_set_write_callback (data->flacdecoder,
	                                                  flac_callback_write);
	FLAC__seekable_stream_decoder_set_error_callback (data->flacdecoder,
	                                                  flac_callback_error);
	FLAC__seekable_stream_decoder_set_length_callback (data->flacdecoder,
	                                                   flac_callback_length);
	FLAC__seekable_stream_decoder_set_metadata_callback (data->flacdecoder,
	                                                     flac_callback_metadata);

	FLAC__seekable_stream_decoder_set_client_data (data->flacdecoder, xform);

	init_status = FLAC__seekable_stream_decoder_init (data->flacdecoder);

	if (init_status != FLAC__SEEKABLE_STREAM_DECODER_OK) {
		const gchar *errmsg = FLAC__seekable_stream_decoder_get_resolved_state_string (data->flacdecoder);
		XMMS_DBG ("FLAC init failed: %s", errmsg);
		goto err;
	}
#else
	FLAC__stream_decoder_set_metadata_respond (data->flacdecoder,
	                                           FLAC__METADATA_TYPE_VORBIS_COMMENT);
	FLAC__stream_decoder_set_metadata_respond (data->flacdecoder,
	                                           FLAC__METADATA_TYPE_PICTURE);

	init_status =
		FLAC__stream_decoder_init_stream (data->flacdecoder,
		                                  flac_callback_read,
		                                  flac_callback_seek,
		                                  flac_callback_tell,
		                                  flac_callback_length,
		                                  flac_callback_eof,
		                                  flac_callback_write,
		                                  flac_callback_metadata,
		                                  flac_callback_error,
		                                  xform);

	if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
		XMMS_DBG ("FLAC init failed: %s",
		          FLAC__stream_decoder_get_resolved_state_string (data->flacdecoder));
		goto err;
	}
#endif

	retval = FLAC__stream_decoder_process_until_end_of_metadata (data->flacdecoder);
	if (!retval)
		goto err;

	if (data->vorbiscomment) {
		handle_comments (xform, data);
	}

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE;
	xmms_xform_metadata_set_int (xform, metakey, (gint) data->bit_rate);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
	if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
		gint32 val = (gint32) data->total_samples / data->sample_rate * 1000;

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
		xmms_xform_metadata_set_int (xform, metakey, val);
	}

	if (data->bits_per_sample == 8) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S8;
	} else if (data->bits_per_sample == 16) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S16;
	} else if (data->bits_per_sample == 24) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S32;
	} else if (data->bits_per_sample == 32) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S32;
	} else {
		goto err;
	}

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             sample_fmt,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             data->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             data->sample_rate,
	                             XMMS_STREAM_TYPE_END);

	data->buffer = g_string_new (NULL);

	return TRUE;

err:

	FLAC__stream_decoder_finish (data->flacdecoder);
	FLAC__stream_decoder_delete (data->flacdecoder);
	g_free (data);
	xmms_xform_private_data_set (xform, NULL);

	return FALSE;

}
Exemple #3
0
static void
parse_contents(void)
{
	int cnt;
	pkgentry_t *ent, *e2;
	avl_index_t where;
	int num = 0;
	struct stat stb;
	ptrdiff_t off;
	char *p, *q, *map;
	pkgentry_t *lastentry = NULL;
	int d;
	int cntserrs = 0;

	cnt = open(CONTENTS, O_RDONLY);

	cind = 0;

	if (cnt == -1) {
		if (errno == ENOENT)
			return;
		exit(99);
	}

	if (fstat(cnt, &stb) != 0) {
		(void) close(cnt);
		exit(99);
	}
	if (stb.st_size == 0) {
		(void) close(cnt);
		return;
	}

	map = mmap(0, stb.st_size, PROT_READ, MAP_PRIVATE, cnt, 0);
	(void) close(cnt);
	if (map == (char *)-1)
		return;

	(void) madvise(map, stb.st_size, MADV_WILLNEED);

	for (off = 0; off < stb.st_size; off += q - p) {
		p = map + off;
		q = memchr(p, '\n', stb.st_size - off);
		if (q == NULL)
			break;

		q++;
		num++;
		if (p[0] == '#' || p[0] == '\n') {
			handle_comments(p, q - p);
			continue;
		}
		ent = parse_line(p, q - p - 1, B_TRUE);

		if (ent == NULL) {
			cntserrs++;
			continue;
		}

		/*
		 * We save time by assuming the database is sorted; by
		 * using avl_insert_here(), building the tree is nearly free.
		 * lastentry always contains the last entry in the AVL tree.
		 */
		if (lastentry == NULL) {
			avl_add(list, ent);
			lastentry = ent;
		} else if ((d = avlcmp(ent, lastentry)) == 1) {
			avl_insert_here(list, ent, lastentry, AVL_AFTER);
			lastentry = ent;
		} else if (d == 0 ||
		    (e2 = avl_find(list, ent, &where)) != NULL) {
			/*
			 * This can only happen if the contents file is bad;
			 * this can, e.g., happen with the old SQL contents DB,
			 * it didn't sort properly.  Assume the first one
			 * is the correct one, but who knows?
			 */
			if (d == 0)
				e2 = lastentry;
			if (strcmp(ent->line, e2->line) != 0) {
				progerr(gettext("two entries for %.*s"),
				    ent->pathlen, ent->line);
				cntserrs++;
			}
			freeentry(ent);
		} else {
			/* Out of order: not an error for us, really. */
			progerr(gettext("bad read of contents file"));
			logerr(gettext("pathname: Unknown"));
			logerr(gettext(
			    "problem: unable to read pathname field"));
			if (one_shot)
				exit(2);
			avl_insert(list, ent, where);
		}
	}

	cind = 0;

	(void) munmap(map, stb.st_size);

	/* By default, we ignore bad lines, keep them in a copy. */
	if (cntserrs > 0 && stb.st_nlink == 1) {
		char bcf[sizeof (BADCONTENTS)];

		(void) strcpy(bcf, BADCONTENTS);
		if (mktemp(bcf) != NULL) {
			(void) link(CONTENTS, bcf);
			syslog(LOG_WARNING, "A bad contents file was saved: %s",
			    bcf);
		}
	}
}