complete largefile support
diff --git a/src/libFLAC/bitbuffer.c b/src/libFLAC/bitbuffer.c
index b120de4..f6b1b74 100644
--- a/src/libFLAC/bitbuffer.c
+++ b/src/libFLAC/bitbuffer.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdlib.h> /* for malloc() */
 #include <string.h> /* for memcpy(), memset() */
 #include "private/bitbuffer.h"
diff --git a/src/libFLAC/bitmath.c b/src/libFLAC/bitmath.c
index bad52e7..a3e8b37 100644
--- a/src/libFLAC/bitmath.c
+++ b/src/libFLAC/bitmath.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include "private/bitmath.h"
 #include "FLAC/assert.h"
 
diff --git a/src/libFLAC/cpu.c b/src/libFLAC/cpu.c
index 3bb8ff3..de2bb2a 100644
--- a/src/libFLAC/cpu.c
+++ b/src/libFLAC/cpu.c
@@ -29,14 +29,14 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include "private/cpu.h"
 #include <stdlib.h>
 #include <stdio.h>
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #if defined FLAC__CPU_PPC
 # if !defined FLAC__NO_ASM
 #  if defined FLAC__SYS_DARWIN
diff --git a/src/libFLAC/crc.c b/src/libFLAC/crc.c
index dbe7f03..1d31ca3 100644
--- a/src/libFLAC/crc.c
+++ b/src/libFLAC/crc.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include "private/crc.h"
 
 /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
diff --git a/src/libFLAC/file_decoder.c b/src/libFLAC/file_decoder.c
index d2e7de4..6e499ed 100644
--- a/src/libFLAC/file_decoder.c
+++ b/src/libFLAC/file_decoder.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h> /* for malloc() */
 #include <string.h> /* for strcmp() */
@@ -36,6 +40,10 @@
 #if defined _MSC_VER || defined __MINGW32__
 #include <io.h> /* for _setmode() */
 #include <fcntl.h> /* for _O_BINARY */
+#include <sys/types.h> /* for off_t */
+//@@@ [2G limit] hacks for MSVC6
+#define fseeko fseek
+#define ftello ftell
 #elif defined __CYGWIN__
 #include <io.h> /* for setmode(), O_BINARY */
 #include <fcntl.h> /* for _O_BINARY */
@@ -606,7 +614,7 @@
 	FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
 	(void)decoder;
 
-	if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
+	if(fseeko(file_decoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
 		return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
 	else
 		return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
@@ -615,10 +623,10 @@
 FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
 {
 	FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
-	long pos;
+	off_t pos;
 	(void)decoder;
 
-	if((pos = ftell(file_decoder->private_->file)) < 0)
+	if((pos = ftello(file_decoder->private_->file)) < 0)
 		return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
 	else {
 		*absolute_byte_offset = (FLAC__uint64)pos;
diff --git a/src/libFLAC/file_encoder.c b/src/libFLAC/file_encoder.c
index 2501779..3469bfd 100644
--- a/src/libFLAC/file_encoder.c
+++ b/src/libFLAC/file_encoder.c
@@ -29,9 +29,19 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h> /* for malloc() */
 #include <string.h> /* for strlen(), strcpy() */
+#if defined _MSC_VER || defined __MINGW32__
+#include <sys/types.h> /* for off_t */
+//@@@ [2G limit] hacks for MSVC6
+#define fseeko fseek
+#define ftello ftell
+#endif
 #include "FLAC/assert.h"
 #include "protected/file_encoder.h"
 
@@ -724,7 +734,7 @@
 
 	FLAC__ASSERT(0 != file_encoder);
 
-	if(fseek(file_encoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
+	if(fseeko(file_encoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
 		return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
 	else
 		return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
@@ -733,13 +743,13 @@
 FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
 {
 	FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
-	long offset;
+	off_t offset;
 
 	(void)encoder;
 
 	FLAC__ASSERT(0 != file_encoder);
 
-	offset = ftell(file_encoder->private_->file);
+	offset = ftello(file_encoder->private_->file);
 
 	if(offset < 0) {
 		return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR;
diff --git a/src/libFLAC/fixed.c b/src/libFLAC/fixed.c
index d683352..d432962 100644
--- a/src/libFLAC/fixed.c
+++ b/src/libFLAC/fixed.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <math.h>
 #include "private/bitmath.h"
 #include "private/fixed.h"
diff --git a/src/libFLAC/float.c b/src/libFLAC/float.c
index 534aa8d..7c58f65 100644
--- a/src/libFLAC/float.c
+++ b/src/libFLAC/float.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include "FLAC/assert.h"
 
 #include "private/float.h"
diff --git a/src/libFLAC/format.c b/src/libFLAC/format.c
index 199053b..b5dfcaa 100644
--- a/src/libFLAC/format.c
+++ b/src/libFLAC/format.c
@@ -29,16 +29,16 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h> /* for qsort() */
 #include "FLAC/assert.h"
 #include "FLAC/format.h"
 #include "private/format.h"
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #ifdef min
 #undef min
 #endif
diff --git a/src/libFLAC/lpc.c b/src/libFLAC/lpc.c
index 14099da..ab73d0b 100644
--- a/src/libFLAC/lpc.c
+++ b/src/libFLAC/lpc.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <math.h>
 #include "FLAC/assert.h"
 #include "FLAC/format.h"
diff --git a/src/libFLAC/md5.c b/src/libFLAC/md5.c
index 9679387..5ea127a 100644
--- a/src/libFLAC/md5.c
+++ b/src/libFLAC/md5.c
@@ -23,15 +23,15 @@
  * Still in the public domain.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdlib.h>		/* for malloc() */
 #include <string.h>		/* for memcpy() */
 
 #include "private/md5.h"
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #ifndef FLaC__INLINE
 #define FLaC__INLINE
 #endif
diff --git a/src/libFLAC/memory.c b/src/libFLAC/memory.c
index 287a74c..956cb29 100644
--- a/src/libFLAC/memory.c
+++ b/src/libFLAC/memory.c
@@ -29,13 +29,13 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include "private/memory.h"
 #include "FLAC/assert.h"
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
 {
 	void *x;
diff --git a/src/libFLAC/metadata_iterators.c b/src/libFLAC/metadata_iterators.c
index 88d7227..525b759 100644
--- a/src/libFLAC/metadata_iterators.c
+++ b/src/libFLAC/metadata_iterators.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -37,6 +41,10 @@
 #if defined _MSC_VER || defined __MINGW32__
 #include <sys/utime.h> /* for utime() */
 #include <io.h> /* for chmod() */
+#include <sys/types.h> /* for off_t */
+//@@@ [2G limit] hacks for MSVC6
+#define fseeko fseek
+#define ftello ftell
 #else
 #include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
 #include <utime.h> /* for utime() */
@@ -109,10 +117,10 @@
 static unsigned seek_to_first_metadata_block_(FILE *f);
 
 static FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append);
-static FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, long fixup_is_last_flag_offset, FLAC__bool backup);
+static FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, off_t fixup_is_last_flag_offset, FLAC__bool backup);
 
-static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status);
-static FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status);
+static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status);
+static FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status);
 static FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status);
 static FLAC__bool copy_remaining_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__Metadata_SimpleIteratorStatus *status);
 
@@ -288,9 +296,8 @@
 	FLAC__bool has_stats;
 	FLAC__bool is_writable;
 	FLAC__Metadata_SimpleIteratorStatus status;
-	/*@@@ 2G limits here because of the offset type: */
-	long offset[SIMPLE_ITERATOR_MAX_PUSH_DEPTH];
-	long first_offset; /* this is the offset to the STREAMINFO block */
+	off_t offset[SIMPLE_ITERATOR_MAX_PUSH_DEPTH];
+	off_t first_offset; /* this is the offset to the STREAMINFO block */
 	unsigned depth;
 	/* this is the metadata block header of the current block we are pointing to: */
 	FLAC__bool is_last;
@@ -399,7 +406,7 @@
 	switch(ret) {
 		case 0:
 			iterator->depth = 0;
-			iterator->first_offset = iterator->offset[iterator->depth] = ftell(iterator->file);
+			iterator->first_offset = iterator->offset[iterator->depth] = ftello(iterator->file);
 			return read_metadata_block_header_(iterator);
 		case 1:
 			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
@@ -474,19 +481,19 @@
 	if(iterator->is_last)
 		return false;
 
-	if(0 != fseek(iterator->file, iterator->length, SEEK_CUR)) {
+	if(0 != fseeko(iterator->file, iterator->length, SEEK_CUR)) {
 		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 		return false;
 	}
 
-	iterator->offset[iterator->depth] = ftell(iterator->file);
+	iterator->offset[iterator->depth] = ftello(iterator->file);
 
 	return read_metadata_block_header_(iterator);
 }
 
 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator)
 {
-	long this_offset;
+	off_t this_offset;
 
 	FLAC__ASSERT(0 != iterator);
 	FLAC__ASSERT(0 != iterator->file);
@@ -494,7 +501,7 @@
 	if(iterator->offset[iterator->depth] == iterator->first_offset)
 		return false;
 
-	if(0 != fseek(iterator->file, iterator->first_offset, SEEK_SET)) {
+	if(0 != fseeko(iterator->file, iterator->first_offset, SEEK_SET)) {
 		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 		return false;
 	}
@@ -502,13 +509,13 @@
 	if(!read_metadata_block_header_(iterator))
 		return false;
 
-	/* we ignore any error from ftell() and catch it in fseek() */
-	while(ftell(iterator->file) + (long)iterator->length < iterator->offset[iterator->depth]) {
-		if(0 != fseek(iterator->file, iterator->length, SEEK_CUR)) {
+	/* we ignore any error from ftello() and catch it in fseeko() */
+	while(ftello(iterator->file) + (off_t)iterator->length < iterator->offset[iterator->depth]) {
+		if(0 != fseeko(iterator->file, iterator->length, SEEK_CUR)) {
 			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 			return false;
 		}
-		this_offset = ftell(iterator->file);
+		this_offset = ftello(iterator->file);
 		if(!read_metadata_block_header_(iterator))
 			return false;
 	}
@@ -543,7 +550,7 @@
 		}
 
 		/* back up to the beginning of the block data to stay consistent */
-		if(0 != fseek(iterator->file, iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH, SEEK_SET)) {
+		if(0 != fseeko(iterator->file, iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH, SEEK_SET)) {
 			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 			FLAC__metadata_object_delete(block);
 			return 0;
@@ -557,7 +564,7 @@
 
 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding)
 {
-	FLAC__ASSERT_DECLARATION(long debug_target_offset = iterator->offset[iterator->depth];)
+	FLAC__ASSERT_DECLARATION(off_t debug_target_offset = iterator->offset[iterator->depth];)
 	FLAC__bool ret;
 
 	FLAC__ASSERT(0 != iterator);
@@ -584,13 +591,13 @@
 		if(use_padding && iterator->length >= FLAC__STREAM_METADATA_HEADER_LENGTH + block->length) {
 			ret = write_metadata_block_stationary_with_padding_(iterator, block, iterator->length - FLAC__STREAM_METADATA_HEADER_LENGTH - block->length, block->is_last);
 			FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
-			FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
+			FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
 			return ret;
 		}
 		else {
 			ret = rewrite_whole_file_(iterator, block, /*append=*/false);
 			FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
-			FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
+			FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
 			return ret;
 		}
 	}
@@ -633,21 +640,21 @@
 			if(padding_leftover == 0) {
 				ret = write_metadata_block_stationary_(iterator, block);
 				FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
-				FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
+				FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
 				return ret;
 			}
 			else {
 				FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH);
 				ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last);
 				FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
-				FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
+				FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
 				return ret;
 			}
 		}
 		else {
 			ret = rewrite_whole_file_(iterator, block, /*append=*/false);
 			FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
-			FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
+			FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
 			return ret;
 		}
 	}
@@ -658,7 +665,7 @@
 	unsigned padding_leftover = 0;
 	FLAC__bool padding_is_last = false;
 
-	FLAC__ASSERT_DECLARATION(long debug_target_offset = iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length;)
+	FLAC__ASSERT_DECLARATION(off_t debug_target_offset = iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length;)
 	FLAC__bool ret;
 
 	FLAC__ASSERT(0 != iterator);
@@ -713,28 +720,28 @@
 		if(padding_leftover == 0) {
 			ret = write_metadata_block_stationary_(iterator, block);
 			FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
-			FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
+			FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
 			return ret;
 		}
 		else {
 			FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH);
 			ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last);
 			FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
-			FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
+			FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
 			return ret;
 		}
 	}
 	else {
 		ret = rewrite_whole_file_(iterator, block, /*append=*/true);
 		FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
-		FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
+		FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
 		return ret;
 	}
 }
 
 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding)
 {
-	FLAC__ASSERT_DECLARATION(long debug_target_offset = iterator->offset[iterator->depth];)
+	FLAC__ASSERT_DECLARATION(off_t debug_target_offset = iterator->offset[iterator->depth];)
 	FLAC__bool ret;
 
 	if(iterator->type == FLAC__METADATA_TYPE_STREAMINFO) {
@@ -756,14 +763,14 @@
 		FLAC__metadata_object_delete(padding);
 		if(!FLAC__metadata_simple_iterator_prev(iterator))
 			return false;
-		FLAC__ASSERT(iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length == debug_target_offset);
-		FLAC__ASSERT(ftell(iterator->file) + (long)iterator->length == debug_target_offset);
+		FLAC__ASSERT(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length == debug_target_offset);
+		FLAC__ASSERT(ftello(iterator->file) + (off_t)iterator->length == debug_target_offset);
 		return true;
 	}
 	else {
 		ret = rewrite_whole_file_(iterator, 0, /*append=*/false);
-		FLAC__ASSERT(iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length == debug_target_offset);
-		FLAC__ASSERT(ftell(iterator->file) + (long)iterator->length == debug_target_offset);
+		FLAC__ASSERT(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length == debug_target_offset);
+		FLAC__ASSERT(ftello(iterator->file) + (off_t)iterator->length == debug_target_offset);
 		return ret;
 	}
 }
@@ -788,13 +795,13 @@
 	FLAC__Metadata_Node *tail;
 	unsigned nodes;
 	FLAC__Metadata_ChainStatus status;
-	long first_offset, last_offset; /*@@@ 2G limit */
+	off_t first_offset, last_offset;
 	/*
 	 * This is the length of the chain initially read from the FLAC file.
 	 * it is used to compare against the current length to decide whether
 	 * or not the whole file has to be rewritten.
 	 */
-	unsigned initial_length; /*@@@ 4G limit */
+	off_t initial_length;
 };
 
 struct FLAC__Metadata_Iterator {
@@ -913,10 +920,10 @@
 	node_delete_(node);
 }
 
-static unsigned chain_calculate_length_(FLAC__Metadata_Chain *chain)
+static off_t chain_calculate_length_(FLAC__Metadata_Chain *chain)
 {
 	const FLAC__Metadata_Node *node;
-	unsigned length = 0;
+	off_t length = 0;
 	for(node = chain->head; node; node = node->next)
 		length += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length);
 	return length;
@@ -995,20 +1002,20 @@
 /* WATCHOUT: Make sure to also update the logic in
  * FLAC__metadata_chain_check_if_tempfile_needed() if the logic here changes.
  */
-static unsigned chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding)
+static off_t chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding)
 {
-	unsigned current_length = chain_calculate_length_(chain);
+	off_t current_length = chain_calculate_length_(chain);
 
 	if(use_padding) {
 		/* if the metadata shrank and the last block is padding, we just extend the last padding block */
 		if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {
-			const unsigned delta = chain->initial_length - current_length;
+			const off_t delta = chain->initial_length - current_length;
 			chain->tail->data->length += delta;
 			current_length += delta;
 			FLAC__ASSERT(current_length == chain->initial_length);
 		}
 		/* if the metadata shrank more than 4 bytes then there's room to add another padding block */
-		else if(current_length + FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) {
+		else if(current_length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) {
 			FLAC__StreamMetadata *padding;
 			FLAC__Metadata_Node *node;
 			if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) {
@@ -1028,16 +1035,16 @@
 		}
 		/* if the metadata grew but the last block is padding, try cutting the padding to restore the original length so we don't have to rewrite the whole file */
 		else if(current_length > chain->initial_length) {
-			const unsigned delta = current_length - chain->initial_length;
+			const off_t delta = current_length - chain->initial_length;
 			if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {
 				/* if the delta is exactly the size of the last padding block, remove the padding block */
-				if(chain->tail->data->length + FLAC__STREAM_METADATA_HEADER_LENGTH == delta) {
+				if((off_t)chain->tail->data->length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH == delta) {
 					chain_delete_node_(chain, chain->tail);
 					current_length = chain_calculate_length_(chain);
 					FLAC__ASSERT(current_length == chain->initial_length);
 				}
 				/* if there is at least 'delta' bytes of padding, trim the padding down */
-				else if(chain->tail->data->length >= delta) {
+				else if((off_t)chain->tail->data->length >= delta) {
 					chain->tail->data->length -= delta;
 					current_length -= delta;
 					FLAC__ASSERT(current_length == chain->initial_length);
@@ -1080,7 +1087,7 @@
 			chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
 			return false;
 		}
-		chain->first_offset = (long)pos;
+		chain->first_offset = (off_t)pos;
 	}
 
 	{
@@ -1125,7 +1132,7 @@
 			chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
 			return false;
 		}
-		chain->last_offset = (long)pos;
+		chain->last_offset = (off_t)pos;
 	}
 
 	chain->initial_length = chain_calculate_length_(chain);
@@ -1156,7 +1163,7 @@
 		}
 	}
 
-	/*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/
+	/*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/
 
 	chain->status = FLAC__METADATA_CHAIN_STATUS_OK;
 	return true;
@@ -1220,10 +1227,10 @@
 			return false;
 		}
 	}
-	/*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/
+	/*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/
 
 	/* copy the file postfix (everything after the metadata) */
-	if(0 != fseek(f, chain->last_offset, SEEK_SET)) {
+	if(0 != fseeko(f, chain->last_offset, SEEK_SET)) {
 		cleanup_tempfile_(&tempfile, &tempfilename);
 		chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
 		return false;
@@ -1269,7 +1276,7 @@
 			return false;
 		}
 	}
-	/*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/
+	/*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/
 
 	/* copy the file postfix (everything after the metadata) */
 	if(0 != seek_cb(handle, chain->last_offset, SEEK_SET)) {
@@ -1371,7 +1378,7 @@
 	 * but doesn't actually alter the chain.  Make sure to update the logic
 	 * here if chain_prepare_for_write_() changes.
 	 */
-	const unsigned current_length = chain_calculate_length_(chain);
+	const off_t current_length = chain_calculate_length_(chain);
 
 	FLAC__ASSERT(0 != chain);
 
@@ -1380,17 +1387,17 @@
 		if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING)
 			return false;
 		/* if the metadata shrank more than 4 bytes then there's room to add another padding block */
-		else if(current_length + FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length)
+		else if(current_length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length)
 			return false;
 		/* if the metadata grew but the last block is padding, try cutting the padding to restore the original length so we don't have to rewrite the whole file */
 		else if(current_length > chain->initial_length) {
-			const unsigned delta = current_length - chain->initial_length;
+			const off_t delta = current_length - chain->initial_length;
 			if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {
 				/* if the delta is exactly the size of the last padding block, remove the padding block */
-				if(chain->tail->data->length + FLAC__STREAM_METADATA_HEADER_LENGTH == delta)
+				if((off_t)chain->tail->data->length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH == delta)
 					return false;
 				/* if there is at least 'delta' bytes of padding, trim the padding down */
-				else if(chain->tail->data->length >= delta)
+				else if((off_t)chain->tail->data->length >= delta)
 					return false;
 			}
 		}
@@ -1403,7 +1410,7 @@
 {
 	struct stat stats;
 	const char *tempfile_path_prefix = 0;
-	unsigned current_length;
+	off_t current_length;
 
 	FLAC__ASSERT(0 != chain);
 
@@ -1447,7 +1454,7 @@
 
 FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks)
 {
-	unsigned current_length;
+	off_t current_length;
 
 	FLAC__ASSERT(0 != chain);
 
@@ -1479,7 +1486,7 @@
 
 FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks)
 {
-	unsigned current_length;
+	off_t current_length;
 
 	FLAC__ASSERT(0 != chain);
 
@@ -2410,7 +2417,7 @@
 
 FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block)
 {
-	if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
+	if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
 		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 		return false;
 	}
@@ -2421,7 +2428,7 @@
 	if(!write_metadata_block_data_(iterator->file, &iterator->status, block))
 		return false;
 
-	if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
+	if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
 		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 		return false;
 	}
@@ -2433,7 +2440,7 @@
 {
 	FLAC__StreamMetadata *padding;
 
-	if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
+	if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
 		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 		return false;
 	}
@@ -2464,7 +2471,7 @@
 
 	FLAC__metadata_object_delete(padding);
 
-	if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
+	if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
 		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 		return false;
 	}
@@ -2477,7 +2484,7 @@
 	FILE *tempfile;
 	char *tempfilename;
 	int fixup_is_last_code = 0; /* 0 => no need to change any is_last flags */
-	long fixup_is_last_flag_offset = -1;
+	off_t fixup_is_last_flag_offset = -1;
 
 	FLAC__ASSERT(0 != block || append == false);
 
@@ -2534,7 +2541,7 @@
 {
 	FLAC__ASSERT(iterator->depth > 0);
 	iterator->depth--;
-	if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
+	if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
 		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 		return false;
 	}
@@ -2605,9 +2612,9 @@
 
 FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append)
 {
-	const long offset_end = append? iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length : iterator->offset[iterator->depth];
+	const off_t offset_end = append? iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length : iterator->offset[iterator->depth];
 
-	if(0 != fseek(iterator->file, 0, SEEK_SET)) {
+	if(0 != fseeko(iterator->file, 0, SEEK_SET)) {
 		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 		return false;
 	}
@@ -2623,12 +2630,12 @@
 	return true;
 }
 
-FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, long fixup_is_last_flag_offset, FLAC__bool backup)
+FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, off_t fixup_is_last_flag_offset, FLAC__bool backup)
 {
-	long save_offset = iterator->offset[iterator->depth]; /*@@@ 2G limit */
+	off_t save_offset = iterator->offset[iterator->depth];
 	FLAC__ASSERT(0 != *tempfile);
 
-	if(0 != fseek(iterator->file, save_offset + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length, SEEK_SET)) {
+	if(0 != fseeko(iterator->file, save_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length, SEEK_SET)) {
 		cleanup_tempfile_(tempfile, tempfilename);
 		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 		return false;
@@ -2647,7 +2654,7 @@
 		 */
 		/* MAGIC NUMBERs here; we know the is_last flag is the high bit of the byte at this location */
 		FLAC__byte x;
-		if(0 != fseek(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
+		if(0 != fseeko(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
 			cleanup_tempfile_(tempfile, tempfilename);
 			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 			return false;
@@ -2665,7 +2672,7 @@
 			FLAC__ASSERT(!(x & 0x80));
 			x |= 0x80;
 		}
-		if(0 != fseek(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
+		if(0 != fseeko(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
 			cleanup_tempfile_(tempfile, tempfilename);
 			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
 			return false;
@@ -2688,7 +2695,7 @@
 	if(!simple_iterator_prime_input_(iterator, !iterator->is_writable))
 		return false;
 	if(backup) {
-		while(iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length < save_offset)
+		while(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length < save_offset)
 			if(!FLAC__metadata_simple_iterator_next(iterator))
 				return false;
 		return true;
@@ -2702,10 +2709,10 @@
 	}
 }
 
-FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status)
+FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status)
 {
 	FLAC__byte buffer[8192];
-	unsigned n;
+	size_t n;
 
 	while(bytes > 0) {
 		n = min(sizeof(buffer), bytes);
@@ -2723,10 +2730,10 @@
 	return true;
 }
 
-FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status)
+FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status)
 {
 	FLAC__byte buffer[8192];
-	unsigned n;
+	size_t n;
 
 	while(bytes > 0) {
 		n = min(sizeof(buffer), bytes);
@@ -2890,20 +2897,14 @@
 #endif
 }
 
-/* @@@ WATCHOUT @@@
- * We cast FLAC__int64 to long and use fseek()/ftell() because
- * none of our operations on metadata is ever likely to go past
- * 2 gigabytes.
- */
 int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence)
 {
-	FLAC__ASSERT(offset <= 0x7fffffff);
-	return fseek((FILE*)handle, (long)offset, whence);
+	return fseeko((FILE*)handle, (off_t)offset, whence);
 }
 
 FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle)
 {
-	return (long)ftell((FILE*)handle);
+	return ftello((FILE*)handle);
 }
 
 FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status)
diff --git a/src/libFLAC/metadata_object.c b/src/libFLAC/metadata_object.c
index a192aff..521a49b 100644
--- a/src/libFLAC/metadata_object.c
+++ b/src/libFLAC/metadata_object.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 
diff --git a/src/libFLAC/seekable_stream_decoder.c b/src/libFLAC/seekable_stream_decoder.c
index 7db8309..c301d1f 100644
--- a/src/libFLAC/seekable_stream_decoder.c
+++ b/src/libFLAC/seekable_stream_decoder.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h> /* for calloc() */
 #include <string.h> /* for memcpy()/memcmp() */
diff --git a/src/libFLAC/seekable_stream_encoder.c b/src/libFLAC/seekable_stream_encoder.c
index 771c085..b943db7 100644
--- a/src/libFLAC/seekable_stream_encoder.c
+++ b/src/libFLAC/seekable_stream_encoder.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h> /* for calloc() */
 #include <string.h> /* for memcpy() */
diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c
index e0fd36a..657ece3 100644
--- a/src/libFLAC/stream_decoder.c
+++ b/src/libFLAC/stream_decoder.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h> /* for malloc() */
 #include <string.h> /* for memset/memcpy() */
@@ -43,10 +47,6 @@
 #include "private/lpc.h"
 #include "private/memory.h"
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #ifdef max
 #undef max
 #endif
diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c
index 2ff2f1c..6ecb872 100644
--- a/src/libFLAC/stream_encoder.c
+++ b/src/libFLAC/stream_encoder.c
@@ -32,6 +32,10 @@
 /*@@@@@@*/
 #undef WINDOW_DEBUG_OUTPUT
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h> /* for malloc() */
@@ -51,10 +55,6 @@
 #include "private/stream_encoder_framing.h"
 #include "private/window.h"
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #ifdef min
 #undef min
 #endif
diff --git a/src/libFLAC/stream_encoder_framing.c b/src/libFLAC/stream_encoder_framing.c
index 311dd31..87611b7 100644
--- a/src/libFLAC/stream_encoder_framing.c
+++ b/src/libFLAC/stream_encoder_framing.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdio.h>
 #include <string.h> /* for strlen() */
 #include "private/stream_encoder_framing.h"
diff --git a/src/libFLAC/window.c b/src/libFLAC/window.c
index a13a21f..04cd662 100644
--- a/src/libFLAC/window.c
+++ b/src/libFLAC/window.c
@@ -29,6 +29,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <math.h>
 #include "FLAC/assert.h"
 #include "FLAC/format.h"