Page 1 of 1

Tool to strip the padding at the end of a file

Posted: Thu Dec 21, 2017 4:20 am
by amaipaipai
Sharing with MAME community a tool to strip '00' at the end of a disc image. Some communities that do dump of discs of Windows, games, arcade and other type of media with "UltraISO" with "Enable ISO Volume Filter" enabled, the tool does exact the same thing.

Code: Select all

// From Don Cragun
// https://www.unix.com/unix-for-beginners-questions-and-answers/266604-remove-truncate-trailing-nulls-file.html
// Run 'make dtn' to compile

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

char	buf[8192];	// I/O buffer
int	ec;		// exit code

// pe(format_string, format_string_argument, exit_code_modifier);
void
pe(	const char	*fmt,
	const char	*arg,
	int		ecm) {
	int	serrno;	// hold area for errno

	serrno = errno;
	snprintf(buf, sizeof(buf), fmt, arg);
	errno = serrno;
	perror(buf);
	ec |= ecm;
}

// NAME		dtn -- Delete trailing null bytes.
//
// SYNOPSIS	dtn file...
//
// DESCRIPTION	Delete trailing NUL bytes from each file named as an operand.
//		File are updated in place.
//
// OPERANDS
//	file	A pathname of a file to be truncated to have a length that does
//		not include any trailing NUL bytes.
//
// INPUT FILES	The input files must be regular files.
//
// STDERR	The standard error shall be used only for diagnostic messages.
//
// EXIT STATUS
//	0	All input files were successfully processed.
//	>0	An error occurred.
//
// CONSEQUENCES OF ERRORS
//		Default.

int
main(	int	argc,
	char	*argv[]) {

	ssize_t	buflen;	// number of bytes in buf[]
	int	fd,	// file descriptor
		i,	// loop control
		j;	// loop control
	off_t	nsize,	// new file size
		size;	// current file size

	for(i = 1; i < argc; i++) {
		if((fd = open(argv[i], O_RDWR)) == -1) {
			pe("Can't open \"%s\":", argv[i], 1);
			continue;
		}
		nsize = size = 0;
		while((buflen = read(fd, buf, sizeof(buf))) > 0) {
			for(j = 0; j < buflen; j++) {
				size++;
				if(buf[j])
					nsize = size;
			}
		}
		if(buflen) {
			pe("Read error on \"%s\": file will not be truncated:",
			    argv[i], 2);
		} else if(ftruncate(fd, nsize)) {
			pe("Truncation failed on \"%s\":", argv[i], 4);
		}
		close(fd);
	}
	return ec;
}
It can be used with readcd (cdrtools), dd, ImgBurn or any other tool.

Code: Select all

dtn file.iso
It can strip about 300 kb of zeros in some files, in a MAME world, it could save a few Terabytes of space.