feat(tools): add mktar ramdisk builder and sample fsroot content
This commit is contained in:
1 parent
d4bc2a209f
commit
2455b4718f
4 files changed
+162
No files matched your search
+147
@@ -0,0 +1,147 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
char name[100];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char checksum[8];
|
||||
char typeflag;
|
||||
char linkname[100];
|
||||
char magic[6];
|
||||
char version[2];
|
||||
char uname[32];
|
||||
char gname[32];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char prefix[155];
|
||||
char padding[12];
|
||||
} UstarHeader;
|
||||
|
||||
static void setOctal(char* field, int width, unsigned long value)
|
||||
{
|
||||
char tmp[32];
|
||||
snprintf(tmp, sizeof tmp, "%0*lo", width - 1, value);
|
||||
memcpy(field, tmp, (size_t)(width - 1));
|
||||
field[width - 1] = '\0';
|
||||
}
|
||||
|
||||
static void writeChecksum(UstarHeader* header)
|
||||
{
|
||||
memset(header->checksum, ' ', 8);
|
||||
unsigned int sum = 0;
|
||||
unsigned char* bytes = (unsigned char*)header;
|
||||
for (int i = 0; i < 512; i++)
|
||||
sum += bytes[i];
|
||||
char tmp[8];
|
||||
snprintf(tmp, sizeof tmp, "%06o", sum & 0777777u);
|
||||
memcpy(header->checksum, tmp, 6);
|
||||
header->checksum[6] = '\0';
|
||||
header->checksum[7] = ' ';
|
||||
}
|
||||
|
||||
static void emitHeader(FILE* out, const char* name, char typeflag, unsigned long size)
|
||||
{
|
||||
UstarHeader header;
|
||||
memset(&header, 0, sizeof header);
|
||||
strncpy(header.name, name, sizeof header.name - 1);
|
||||
setOctal(header.mode, 8, 0644);
|
||||
setOctal(header.uid, 8, 0);
|
||||
setOctal(header.gid, 8, 0);
|
||||
setOctal(header.size, 12, size);
|
||||
setOctal(header.mtime, 12, 0);
|
||||
header.typeflag = typeflag;
|
||||
memcpy(header.magic, "ustar", 5);
|
||||
header.magic[5] = '\0';
|
||||
header.version[0] = '0';
|
||||
header.version[1] = '0';
|
||||
writeChecksum(&header);
|
||||
fwrite(&header, 1, 512, out);
|
||||
}
|
||||
|
||||
static void padTo512(FILE* out, unsigned long size)
|
||||
{
|
||||
unsigned long remainder = size % 512;
|
||||
if (remainder)
|
||||
for (unsigned long i = 0; i < 512 - remainder; i++)
|
||||
fputc(0, out);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s out.tar [--dir apath | --file apath hostpath]...\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE* out = fopen(argv[1], "wb");
|
||||
if (!out) {
|
||||
fprintf(stderr, "mktar: cannot write %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int i = 2;
|
||||
while (i < argc) {
|
||||
if (strcmp(argv[i], "--dir") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
fprintf(stderr, "mktar: --dir needs a path\n");
|
||||
return 1;
|
||||
}
|
||||
char namebuf[101];
|
||||
strncpy(namebuf, argv[i + 1], 99);
|
||||
namebuf[99] = 0;
|
||||
size_t l = strlen(namebuf);
|
||||
if (l == 0 || namebuf[l - 1] != '/') {
|
||||
namebuf[l] = '/';
|
||||
namebuf[l + 1] = 0;
|
||||
}
|
||||
emitHeader(out, namebuf, '5', 0);
|
||||
i += 2;
|
||||
} else if (strcmp(argv[i], "--file") == 0) {
|
||||
if (i + 2 >= argc) {
|
||||
fprintf(stderr, "mktar: --file needs apath hostpath\n");
|
||||
return 1;
|
||||
}
|
||||
const char* apath = argv[i + 1];
|
||||
const char* hostpath = argv[i + 2];
|
||||
|
||||
FILE* in = fopen(hostpath, "rb");
|
||||
if (!in) {
|
||||
fprintf(stderr, "mktar: cannot open %s\n", hostpath);
|
||||
return 1;
|
||||
}
|
||||
fseek(in, 0, SEEK_END);
|
||||
long size = ftell(in);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
if (size < 0)
|
||||
size = 0;
|
||||
|
||||
unsigned char* buffer = malloc(size > 0 ? (size_t)size : 1);
|
||||
if (size > 0 && fread(buffer, 1, (size_t)size, in) != (size_t)size) {
|
||||
fprintf(stderr, "mktar: short read on %s\n", hostpath);
|
||||
return 1;
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
emitHeader(out, apath, '0', (unsigned long)size);
|
||||
if (size > 0)
|
||||
fwrite(buffer, 1, (size_t)size, out);
|
||||
padTo512(out, (unsigned long)size);
|
||||
free(buffer);
|
||||
i += 3;
|
||||
} else {
|
||||
fprintf(stderr, "mktar: unknown argument %s\n", argv[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (int block = 0; block < 1024; block++)
|
||||
fputc(0, out);
|
||||
fclose(out);
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user