Index: bootloader/gigabeat-s.c =================================================================== --- bootloader/gigabeat-s.c (révision 16326) +++ bootloader/gigabeat-s.c (copie de travail) @@ -51,6 +51,7 @@ char buf[MAX_PATH]; char basedir[] = "/Content/0b00/00/"; /* Where files sent via MTP are stored */ char model[5]; +char tarstring[6]; int (*kernel_entry)(void); extern void reference_system_c(void); @@ -61,11 +62,78 @@ reference_system_c(); } +void untar(int tar_fd) +{ + char buffer[157]; + char path[102]; + char copybuf[512]; + int n, size = 0, i, pos = 0; + int fd; + + while (1) + { + n = read(tar_fd, buffer, 157); + + /* Parse the size field */ + size = 0; + for (i = 124 ; i < 124 + 11 ; i++) { + size = (8 * size) + buffer[i] - '0'; + } + /* Round length up to next multiple of 512 */ + //len = (size + 511) & (~511); + + /* Skip rest of header */ + pos = lseek(tar_fd, 512 - 157, SEEK_CUR); + + if (pos + size > filesize(tar_fd)) + break; + + strcpy(path, "/"); + strcat(path, buffer); + + //printf("%s (%d)", path, size); + + if (buffer[156] == '0') /* file */ + { + int rc, total = 0; + fd = creat(path); + if (fd < 0) + printf("failed to create file (%d)", fd); + else + { + while (total < size) + { + rc = read(tar_fd, copybuf, sizeof(copybuf)); + pos += rc; + n = write(fd, copybuf, MIN(rc, size - total)); + if (n < 0) + { + printf("write failed (%d)", n); + break; + } + total += n; + } + close(fd); + } + } + else if (buffer[156] == '5') /* directory */ + { + if (path[strlen(path) - 1] == '/') + path[strlen(path) - 1] = '\0'; + + int ret = mkdir(path); + if (ret < 0 && ret != -4) + printf("failed to create dir (%d)", ret); + pos = lseek(tar_fd, (size + 511) & (~511), SEEK_CUR); + } + } +} + void main(void) { lcd_clear_display(); printf("Hello world!"); - printf("Gigabeat S Rockbox Bootloader v.00000003"); + printf("Gigabeat S Rockbox Bootloader v.00000004"); system_init(); kernel_init(); printf("kernel init done"); @@ -103,6 +171,7 @@ fd = open(buf, O_RDONLY); if (fd >= 0) { +#if 0 lseek(fd, 4, SEEK_SET); rc = read(fd, model, 4); close(fd); @@ -112,6 +181,25 @@ if (strcmp(model, "gigs") == 0) break; } +#endif + + lseek(fd, 257, SEEK_SET); + rc = read(fd, tarstring, 5); + if (rc == 5) + { + tarstring[5] = 0; + if (strcmp(tarstring, "ustar") == 0) + { + printf("Found tar file. Unarchiving"); + lseek(fd, 0, SEEK_SET); + untar(fd); + close(fd); + printf("Removing tar file"); + remove(buf); + break; + } + } + close(fd); } } } @@ -122,7 +210,7 @@ unsigned char *loadbuffer = (unsigned char *)0x0; int buffer_size = 31*1024*1024; - rc = load_firmware(loadbuffer, buf, buffer_size); + rc = load_firmware(loadbuffer, "/.rockbox/rockbox.gigabeat", buffer_size); if(rc < 0) error((int)buf, rc);