diff -ru genisovh-0.1/main.c gen-mips-cd/genisovh-dev/main.c --- genisovh-0.1/main.c 2002-09-28 01:49:03.000000000 +1000 +++ gen-mips-cd/genisovh-dev/main.c 2003-02-18 15:27:59.000000000 +1100 @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include "dvh.h" @@ -20,6 +22,8 @@ #define BYTES_PER_SECTOR 2048 #endif +#define CYL_BYTES (SECTORS_PER_TRACK * BYTES_PER_SECTOR) + #define __u16 unsigned short #define __u32 unsigned int @@ -53,6 +57,16 @@ #define cpu_to_be16(x) ((__u16)(x)) #endif +void usage(void) { + printf("Usage:\n"); + printf( +"genisovh :,[,] ... \n" +"\n" +"If a name is used, a bootfile is created. If a number is used, a partition\n" +"is created.\n" + ); + exit(1); +} __u32 vh_calc_checksum(struct volume_header *vh) { __u32 oldchecksum, @@ -71,20 +85,118 @@ return(newsum); } -void usage(void ) { - printf("Usage:\ngenisovh ... \n"); - exit(1); +struct entry { + enum { ENTRY_FILE, ENTRY_PARTITION } type; + union { + int num; + char name[BFNAMESIZE + 1]; + } u; + int start, len; + int has_source; + char source[300]; /* file to get image from */ +}; + +void parse_entry(const char* cmd, struct entry* entry) +{ + int i; + + memset(entry->u.name, 0, BFNAMESIZE); + + if (isalpha(*cmd)) { + entry->type = ENTRY_FILE; + + i = 0; + while (isalnum(*cmd)) { + char ch = *cmd++; + if (i <= BFNAMESIZE) + entry->u.name[i++] = ch; + } + } else { + entry->type = ENTRY_PARTITION; + entry->u.num = atoi(cmd); + while (isdigit(*cmd)) + cmd++; + } + + if (*cmd++ != ':') + usage(); + + entry->start = atoi(cmd); + while (isdigit(*cmd)) + cmd++; + + if (*cmd++ != ',') + usage(); + + entry->len = atoi(cmd); + while (isdigit(*cmd)) + cmd++; + + if (*cmd++ == ',') { + entry->has_source = 1; + i = 0; + while (*cmd && !isspace(*cmd)) { + char ch = *cmd++; + if (i < 299) + entry->source[i++] = ch; + } + entry->source[i] = 0; + } else { + entry->has_source = 0; + } +} + +int round_up_to(int a, int b) +{ + return (a % b == 0) + ? a + : a + b - (a % b); +} + +void copy_file(FILE* target, const char *name, int start, int len) { + FILE* f; + struct stat st; + int size; + char buf[4096]; + int pos; + + f = fopen(name, "r"); + if (!f) { + perror(name); + exit(1); + } + + fstat(fileno(f), &st); + size = st.st_size; + if (size > len) { + printf("%s: too big to fit in %d+%d\n", name, start, len); + exit(1); + } + + if (fseek(target, start, SEEK_SET)) { + perror("[iso image]"); + exit(1); + } + assert(ftell(target) == start); + + for (pos = 0; pos < len; pos += 4096) { + int r_status = fread(buf, 1, 4096, f); + if (r_status < 0) { + perror(name); + exit(1); + } + assert (r_status <= 4096); + fwrite(buf, 1, r_status, target); + if (r_status < 4096) + break; + } + + fclose(f); } int main(int argc, char **argv) { - int fd, - i, - v, - block, - size; - char *isoname, - *cline, - *pos; + FILE* iso_f; + int i, file_count = 0; struct stat st; struct volume_header vh; @@ -92,19 +204,12 @@ if (argc < 2) usage(); - isoname=argv[1]; - - if (!(fd=open(isoname, O_RDWR))) { - printf("File not found %s\n", isoname); + if (!(iso_f = fopen(argv[1], "r+")) + || fstat(fileno(iso_f), &st)) { + perror(argv[1]); exit(1); } - if (fstat(fd, &st)) { - printf("Failed to stat file %s\n", isoname); - close(fd); - exit(1); - } - memset(&vh, 0, sizeof(struct volume_header)); vh.vh_magic = cpu_to_be32(VHMAGIC); @@ -118,38 +223,38 @@ vh.vh_dp.dp_cyls=cpu_to_be16((st.st_size + BYTES_PER_SECTOR - 1) / (SECTORS_PER_TRACK*BYTES_PER_SECTOR)); - for(i=2,v=0;i= NVDIR) + printf("Too many boot files\n"); + + start = ent.start; + len = ent.len; + + vh.vh_vd[file_count].vd_lbn = cpu_to_be32(start); + vh.vh_vd[file_count].vd_nbytes = cpu_to_be32(len); + strncpy(vh.vh_vd[file_count].vd_name, ent.u.name, + VDNAMESIZE); + file_count++; } - *pos=0x0; - - /* copy name */ - strncpy(vh.vh_vd[v].vd_name, cline, VDNAMESIZE); - - cline=pos+1; - - if (!(pos=strchr(cline, ','))) { - printf("Could find , in parameter %s\n", cline); - usage(); - } - - *pos=0x0; - - block=atoi(cline); - vh.vh_vd[v].vd_lbn=cpu_to_be32(block); - - cline=pos+1; - - size=atoi(cline); - vh.vh_vd[v].vd_nbytes=cpu_to_be32(size); - + if (ent.has_source) + copy_file(iso_f, ent.source, start, len); } /* Create volume header partition on WHOLE cd iso */ @@ -159,11 +264,12 @@ /* Create checksum */ vh.vh_csum=cpu_to_be32(vh_calc_checksum(&vh)); - if (write(fd, &vh, sizeof(struct volume_header)) != sizeof(struct volume_header)) { + rewind(iso_f); + if (fwrite(&vh, sizeof(struct volume_header), 1, iso_f) != 1) { printf("Failed to write volume header to iso image"); - close(fd); exit(1); } - close(fd); + fclose(iso_f); + return 0; }