All pastes #1015627 Raw Edit

Unnamed

public text v1 · immutable
#1015627 ·published 2008-05-12 10:50 UTC
rendered paste body
/* 

    USB ADVANCE Linux HDD installer

    Original source: Zer0-X @ ps2-scene.org
    Linux port: crazyc @ ps2-scene.org
    Current version: tesla @ nixCoders.org

    Changes:
	- added support for large files (DVD iso rips)
        - added retry on error when reading disks
	- added progress info 
	- clean up code to make it compile without warnings 

    Jah bless and enjoy!

*/

#define _GNU_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/param.h>

#define WHRIL "\\|/-!"
#define RETRYCOUNT 255

#define BUFSIZE	(2048 * 8192) /* must be an even factor of 2^30 */


typedef struct {
	char name[32];
	char file_name[15];
	char part;
	char media;
	char pad1[4];
	char unk;
	char pad2[10];
} usbex_info_t;

int error_exit(const char *msg)
{
	printf("%s: %s\n", strerror(errno), msg);
	exit(-1);
}

unsigned int crc32(char *string)
{
	int crc, table, count, byte;
	unsigned int crctab[256];

	for (table=0; table<256; table++)
	{
		crc = table << 24;

		for (count=8; count>0; count--)
		{
			if (crc < 0) crc = crc << 1;
			else crc = (crc << 1) ^ 0x04C11DB7;
		}
		crctab[255-table] = crc;
	}

	do {
		byte = string[count++];
		crc = crctab[byte ^ ((crc >> 24) & 0xFF)] ^ ((crc << 8) & 0xFFFFFF00);
	} while (string[count-1] != 0);

	return crc;
}

int main(int argc, char **argv)
{
	int fdin, fdout, ret, i, w_i, ret_control, retry_count = 0, part = 0;
	char outfile[MAXPATHLEN + 1];
	void *buffer;
	usbex_info_t img_cnf;
	unsigned int crc = 0;
	unsigned long int r_bytes = 0;

	if(argc != 6)
	{
		printf("usage: %s SOURCE DEST TITLE EXECFILE CD/DVD\nExample: ui_install /dev/cdrom /mnt/usbdisk My\\ very\\ 1st\\ demo SLUS_123.45 CD\n",argv[0]);
		return 1;
	}

	if(strlen(argv[3]) > 31)
	{
		printf("Title %s is too long", argv[3]);
		exit(-1);
	}

	if(!strcasecmp(argv[5], "CD"))
		img_cnf.media = 0x12;
	else if(!strcasecmp(argv[5], "DVD"))
		img_cnf.media = 0x14;
	else
	{
		printf("Invalid media type %s", argv[5]);
		exit(-1);
	}
	strncpy(img_cnf.file_name, "ul.", 3);
	strncpy(&img_cnf.file_name[3], argv[4], 11);
	strncpy(img_cnf.name, argv[3], 31);
	img_cnf.unk = 0x08;

	crc = crc32(argv[3]);

	if((fdin = open(argv[1], O_RDONLY | O_LARGEFILE )) == -1)
		error_exit(argv[1]);
/* 
   ^^
   Added to enable reading big iso files of DVD rips.
   Note: in order to make it read cue/bin images, convert them using bin2iso 
   tool.
*/

	buffer = (void *)malloc(BUFSIZE);

	sprintf(outfile, "%s/ul.%08X.%s.%02X", argv[2], crc, argv[4], part);
	if((fdout = open(outfile, O_WRONLY | O_TRUNC | O_CREAT)) == -1)
		error_exit(outfile);
	printf("\n\033[1m\033[33m*\033[37m USB ADVANCE Linux HDD instaler. \033[33m*\033[0m\n\n");
	printf("=> Ripping \033[32m%s\033[0m to \033[32m%s\033[0m\n",argv[1],argv[2]);
	printf("=> Game title:\033[33m%s\033[0m\n",argv[3]);
	printf("=> Disk type:\033[32m%s\033[0m\n",argv[5]);
	printf("=> ELF:\033[32m%s\033[0m\n",argv[4]);

	w_i = 0;
	printf("%c [ %s:\033[1m\033[34mREAD\033[0m | HDD:\033[34mwrite\033[0m ] [ 0MB ]",WHRIL[w_i],argv[5]);

	for(i = 0; ret = read(fdin, buffer, BUFSIZE); i += ret_control)
	{
		w_i++;
		if(WHRIL[w_i] == '!') w_i = 0;
		if (ret != -1) {
		    r_bytes += ret;
		    ret_control = ret;
		    printf("\r%c [ %s:\033[34mread\033[0m | HDD:\033[1m\033[34mWRITE\033[0m ] [ %dMB ],%d",WHRIL[w_i],argv[5],(r_bytes/1024)/1024,i);
		} else {
		    ret_control = 0;
		    printf("\r%c [ %s:\033[1m\033[31mERR!\033[0m | HDD:\033[1m\033[34mWAIT!\033[0m ] [ %dMB ] ERR:%d",WHRIL[w_i],argv[5],(r_bytes/1024)/1024,retry_count);
		    close(fdin); 
		    if((fdin = open(argv[1], O_RDONLY | O_LARGEFILE )) == -1)
			    error_exit(argv[1]);
		    lseek(fdin,r_bytes,SEEK_SET);
/* 
    ^^
    This is not a low level error handling. Just reopens file/device,
    sets pointer value to r_bytes and tries to read again.
*/
    		}
		w_i++;
		if(WHRIL[w_i] == '!') w_i = 0;
		fflush(stdout);		
		
		if(ret == -1 && retry_count >= RETRYCOUNT)
			error_exit("read");

		if(i == (1<<30))
		{
			close(fdout);
			sprintf(outfile, "%s/ul.%08X.%s.%02X", argv[2], crc, argv[4], ++part);
			if((fdout = open(outfile, O_WRONLY | O_TRUNC | O_CREAT)) == -1)
				error_exit(outfile);
			i = 0;
		}
		if(ret != -1) {
		    if(write(fdout, buffer, ret) == -1)
			    error_exit("write");
		} else {
		    retry_count++;
		    sleep(1);
		}
		    printf("\r%c [ %s:\033[1m\033[34mREAD\033[0m | HDD:\033[34mwrite\033[0m ] [ %dMB ]",WHRIL[w_i],argv[5],(r_bytes/1024)/1024);
		    fflush(stdout);		
		

	}
	free(buffer);
	close(fdin);
	close(fdout);

	printf("\r=> Finished:\033[1m%d\033[0mMB in \033[1m%d\033[0m parts                                  \n",(r_bytes/1024)/1024,(part+1));

	img_cnf.part = ++part;
	sprintf(outfile, "%s/ul.cfg", argv[2]);
	if((fdout = open(outfile, O_WRONLY | O_APPEND | O_CREAT)) == -1)
		error_exit(outfile);

	write(fdout, &img_cnf, sizeof(img_cnf));
	close(fdout);
	return 0;
}