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); }
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; }
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); } } }