mirror of
https://gitlab.com/bztsrc/bootboot.git
synced 2023-02-13 20:54:32 -05:00
136 lines
5.4 KiB
C
136 lines
5.4 KiB
C
/*
|
|
* mkbootimg/img.c
|
|
*
|
|
* Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab)
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation
|
|
* files (the "Software"), to deal in the Software without
|
|
* restriction, including without limitation the rights to use, copy,
|
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
* of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* This file is part of the BOOTBOOT Protocol package.
|
|
* @brief Write disk image to file
|
|
*
|
|
*/
|
|
#include "main.h"
|
|
|
|
/**
|
|
* Assemble and write out disk image
|
|
*/
|
|
void img_write(char *fn)
|
|
{
|
|
FILE *f, *d;
|
|
int i, j, n, lastpercent, k;
|
|
char key[64], *tmp, *dir, *buf;
|
|
unsigned long int size, pos;
|
|
size_t s;
|
|
time_t c = 0;
|
|
|
|
buf = malloc(1024*1024);
|
|
if(!buf) { fprintf(stderr,"mkbootimg: %s\r\n",lang[ERR_MEM]); exit(2); }
|
|
|
|
f=fopen(fn,"wb");
|
|
if(!f) { fprintf(stderr,"mkbootimg: %s %s\n", lang[ERR_WRITE],fn); exit(3); }
|
|
/* write out primary GPT table (and optional ISO9660 header) */
|
|
fwrite(gpt,es*512,1,f);
|
|
/* write out ESP */
|
|
fwrite(esp,esp_size,1,f);
|
|
fseek(f,(es+esiz)*512,SEEK_SET);
|
|
/* write out other partitions */
|
|
for(k = 1; k < np; k++) {
|
|
size = 0;
|
|
sprintf(key, "partitions.%d.%s", k, "file");
|
|
tmp = json_get(json, key);
|
|
if(tmp && *tmp) {
|
|
d = fopen(tmp, "rb");
|
|
free(tmp);
|
|
if(d) {
|
|
while((s = fread(buf, 1, 1024*1024, d)) != 0) {
|
|
fwrite(buf, 1, s, f);
|
|
size += s;
|
|
if(c > t + 1) {
|
|
pos = ftell(f);
|
|
n = pos * 100L / (tsize + 1);
|
|
if(n != lastpercent) {
|
|
lastpercent = n;
|
|
printf("\rmkbootimg: %s [",lang[WRITING]);
|
|
for(i = 0; i < 20; i++) printf(i < n/5 ? "#" : " ");
|
|
printf("] %3d%% ", n);
|
|
fflush(stdout);
|
|
}
|
|
} else
|
|
time(&c);
|
|
}
|
|
fclose(d);
|
|
}
|
|
} else {
|
|
sprintf(key, "partitions.%d.%s", k, "directory");
|
|
dir = json_get(json, key);
|
|
if(dir && *dir) {
|
|
fs_base = NULL; fs_len = 0; fs_no = k + 1;
|
|
sprintf(key, "partitions.%d.%s", k, "driver");
|
|
tmp = json_get(json, key);
|
|
if(!tmp || !*tmp) {
|
|
sprintf(key, "partitions.%d.%s", k, "type");
|
|
tmp = json_get(json, key);
|
|
}
|
|
if(tmp && *tmp) {
|
|
rd_open = NULL; rd_add = NULL; rd_close = NULL;
|
|
for(i = 0; fsdrv[i].name && fsdrv[i].add; i++)
|
|
if(!strcmp(tmp, fsdrv[i].name)) { rd_open = fsdrv[i].open; rd_add = fsdrv[i].add; rd_close = fsdrv[i].close; break; }
|
|
free(tmp);
|
|
if(rd_add) {
|
|
skipbytes = strlen(dir) + 1;
|
|
if(rd_open) (*rd_open)((gpt_t*)(gpt + 1024 + k * 128));
|
|
parsedir(dir, 0);
|
|
if(rd_close) (*rd_close)();
|
|
} else {
|
|
fprintf(stderr,"mkbootimg: partition #%d %s. %s:\r\n", np+1, lang[ERR_TYPE], lang[ERR_ACCEPTVALUES]);
|
|
for(i = 0; fsdrv[i].name; i++)
|
|
if(fsdrv[i].add) {
|
|
fprintf(stderr," \"%08X-%04X-%04X-%02X%02X-",fsdrv[i].type.Data1,fsdrv[i].type.Data2,
|
|
fsdrv[i].type.Data3, fsdrv[i].type.Data4[0],fsdrv[i].type.Data4[1]);
|
|
for(j = 2; j < 8; j++) fprintf(stderr,"%02X",fsdrv[i].type.Data4[j]);
|
|
fprintf(stderr,"\" / \"%s\"\r\n",fsdrv[i].name);
|
|
}
|
|
exit(1);
|
|
}
|
|
}
|
|
free(dir);
|
|
if(fs_base && fs_len) {
|
|
if(gpt_parts[k] < (unsigned long int)fs_len) {
|
|
fprintf(stderr,"mkbootimg: partition #%d %s.\r\n", k+1,lang[ERR_PARTSIZE]);
|
|
exit(2);
|
|
}
|
|
fwrite(fs_base, fs_len, 1, f);
|
|
free(fs_base);
|
|
size += fs_len;
|
|
}
|
|
}
|
|
}
|
|
fseek(f,gpt_parts[k] - size,SEEK_CUR);
|
|
}
|
|
/* write out backup GPT table */
|
|
fseek(f,tsize-63*512,SEEK_SET);
|
|
fwrite(gpt+1024,62*512,1,f);
|
|
fwrite(gpt2,512,1,f);
|
|
fclose(f);
|
|
printf("\r\x1b[K\r");
|
|
printf("mkbootimg: %s %s.\r\n", fn, lang[SAVED]);
|
|
free(buf);
|
|
}
|