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