- /* Calculate amount of required memory (incl. 0-term) */
- rootfsname_sz = strlen(sysupgrade.file_name) + 7 + 1;
- zipfsname_sz = strlen(sysupgrade.file_name) + 7 + 4 + 1;
-
- /* Allocate required memory */
- if (!(rootfsname = (char*) malloc(rootfsname_sz)) || !(zipfsname =
- (char*) malloc(zipfsname_sz))) {
- /* Error */
- ERR("Out of memory!\n");
- goto cleanup;
- }
-
- /* Create filenames */
- if (snprintf(rootfsname, rootfsname_sz, "%s.rootfs", sysupgrade.file_name)
- >= rootfsname_sz
- || snprintf(zipfsname, zipfsname_sz, "%s.rootfs.zip",
- sysupgrade.file_name) >= zipfsname_sz) {
- /* Error */
- ERR("Buffer too small!\n");
- goto cleanup;
- }
-
- /* Buffer all files */
- if (bufferFile(&sysupgrade)) {
- /* Error */
- goto cleanup;
- }
-
- DBG("Building header: %s %s %2X %s\n", hwID, hwVer, swVer, magic);
-
- /* Construct the firmware header/magic */
- header.file_name = NULL;
- header.file_size = HEADER_SIZE;
-
- if (!(header.file_data = (char*) calloc(1, HEADER_SIZE))) {
- /* Error */
- ERR("Out of memory!\n");
- goto cleanup;
- }
-
- strncpy(header.file_data + 0, magic, 7);
- memcpy(header.file_data + 7, version, sizeof(version));
- strncpy(header.file_data + 11, hwID, 34);
- strncpy(header.file_data + 45, hwVer, 10);
- memcpy(header.file_data + 55, &swVer, sizeof(swVer));
- strncpy(header.file_data + 63, magic, 7);
-
- DBG("Creating rootfs ..\n");
-
- /* Construct a rootfs */
- rootfs.file_name = rootfsname;
- rootfs.file_size = ALIGN(
- sysupgrade.file_size + kernel_offset + header.file_size,
- ROOTFS_ALIGN);
-
- if (!(rootfs.file_data = calloc(1, rootfs.file_size))) {
- /* Error */
- ERR("Out of memory!\n");
- goto cleanup;
- }
-
- /* copy Owrt image to kernel location */
- memcpy(rootfs.file_data + kernel_offset, sysupgrade.file_data,
- sysupgrade.file_size);
-
- /* Append header after the owrt image. The updater searches for it */
- memcpy(rootfs.file_data + kernel_offset + sysupgrade.file_size,
- header.file_data, header.file_size);
-
- /* Write to file */
- if (writeFile(&rootfs)) {
- /* Error */
- goto cleanup;
- }
-
- /* Construct a zip */
- DBG("Preparing to zip ..\n");
-
- /* now that we got the rootfs, repeat the whole thing again(sorta):
- * 1. zip the rootfs */
- zipcmd_sz = 3 + 1 + strlen(zipfsname) + 1 + strlen(rootfs.file_name) + 1;
-
- if (!(zipcmd = malloc(zipcmd_sz))) {
- /* Error */
- ERR("Out of memory!\n");
- goto cleanup;
- }
-
- if (snprintf(zipcmd, zipcmd_sz, "%s %s %s", "zip", zipfsname,
- rootfs.file_name) >= zipcmd_sz) {
- /* Error */
- ERR("Buffer too small!\n");
- goto cleanup;
- }
-
- if (system(zipcmd)) {
- /* Error */
- ERR("Error creating a zip file!\n");
- goto cleanup;
- }
-
- /* and load zipped fs */
- zippedfs.file_name = zipfsname;
-
- if (bufferFile(&zippedfs)) {
- /* Error */
- goto cleanup;
- }
-
- DBG("Creating Image.\n");
-
- /* 2. create new file 512 + rootfs size */
- image.file_size = zippedfs.file_size + 512;
- if (!(image.file_data = malloc(zippedfs.file_size + 512))) {
- /* Error */
- ERR("Out of memory!\n");
- goto cleanup;
- }
-
- /* 3. add header to file */
- memcpy(image.file_data, header.file_data, header.file_size);
-
- /* 4. clear remaining space */
- if (header.file_size < 512)
- memset(image.file_data + header.file_size, 0, 512 - header.file_size);
-
- /* 5. copy zipfile at loc 512 */
- memcpy(image.file_data + 512, zippedfs.file_data, zippedfs.file_size);
-
- /* 6. do a checksum run, and compute checksum */
- chkSum = getCheckSum(image.file_data, image.file_size);
-
- DBG("Checksum for Image: %hhX\n", chkSum);
-
- /* 7. write the checksum inverted into byte 511 to bring it to 0 on verification */
- chkSum = (chkSum ^ 0xFF) + 1;
- image.file_data[511] = (char) chkSum;
-
- chkSum = getCheckSum(image.file_data, image.file_size);
- DBG("Checksum for after fix: %hhX\n", chkSum);
-
- if (chkSum != 0) {
- ERR("Invalid checksum!\n")
- goto cleanup;
- }
-
- /* 8. pray that the updater will accept the file */
- if (writeFile(&image)) {
- /* Error */
- goto cleanup;
- }
-
- /* All seems OK */
- ret = 0;
-
- cleanup:
-
- if (rootfs.file_name && !access(rootfs.file_name, F_OK | W_OK))
- remove(rootfs.file_name);
-
- if (zippedfs.file_name && !access(zippedfs.file_name, F_OK | W_OK))
- remove(zippedfs.file_name);
-
- fi_clean(&sysupgrade);
- fi_clean(&header);
- fi_clean(&rootfs);
- fi_clean(&zippedfs);
- fi_clean(&image);
-
- if (rootfsname)
- free(rootfsname);
-
- if (zipfsname)
- free(zipfsname);
-
- if (zipcmd)
- free(zipcmd);