diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-06-18 18:12:38 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-06-18 18:12:38 +0000 |
commit | 7d4ffb868403377922d9cd0c8b4531cb77ec901c (patch) | |
tree | eddfaf14e1fd5c9b85e7e25ccb1c27a2c6a5cf5e | |
parent | 73b9f7c362dde15dee4331b02f1c75e29e49fbeb (diff) |
aux/txt2uimage: helper for generating uimage script files
-rw-r--r-- | sys/src/cmd/aux/mkfile | 1 | ||||
-rw-r--r-- | sys/src/cmd/aux/txt2uimage.c | 108 |
2 files changed, 109 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/mkfile b/sys/src/cmd/aux/mkfile index f38fda5d7..1ef302c45 100644 --- a/sys/src/cmd/aux/mkfile +++ b/sys/src/cmd/aux/mkfile @@ -43,6 +43,7 @@ TARG=\ tablet\ timesync\ trampoline\ + txt2uimage\ unbflz\ usage\ write\ diff --git a/sys/src/cmd/aux/txt2uimage.c b/sys/src/cmd/aux/txt2uimage.c new file mode 100644 index 000000000..5fec8c7c9 --- /dev/null +++ b/sys/src/cmd/aux/txt2uimage.c @@ -0,0 +1,108 @@ +#include <u.h> +#include <libc.h> +#include <flate.h> + +int infd, outfd; +ulong dcrc; +ulong *tab; +uchar buf[65536]; + +enum { + IH_TYPE_SCRIPT = 6, +}; + +void +put(uchar *p, u32int v) +{ + *p++ = v >> 24; + *p++ = v >> 16; + *p++ = v >> 8; + *p = v; +} + +void +usage(void) +{ + fprint(2, "usage: %s a.out\n", argv0); + exits("usage"); +} + +void +block(int n) +{ + int rc; + + rc = readn(infd, buf, n); + if(rc < 0) sysfatal("read: %r"); + if(rc < n) sysfatal("input file truncated"); + if(write(outfd, buf, n) < 0) sysfatal("write: %r"); + dcrc = blockcrc(tab, dcrc, buf, n); +} + +void +copy(int n) +{ + int i; + + for(i = sizeof(buf) - 1; i < n; i += sizeof(buf)) + block(sizeof(buf)); + i = n & sizeof(buf) - 1; + if(i > 0) + block(i); +} + +void +main(int argc, char **argv) +{ + uchar header[64]; + char *ofile; + Dir *dir; + + ofile = nil; + ARGBEGIN { + case 'o': ofile = strdup(EARGF(usage())); break; + default: usage(); + } ARGEND; + + if(argc == 0) + infd = 0; + else { + if(argc != 1) usage(); + infd = open(argv[0], OREAD); + if(infd < 0) sysfatal("infd: %r"); + } + dir = dirfstat(infd); + if(dir == nil) sysfatal("stat: %r"); + if(dir->length > 0xFFFFFFFF-8) sysfatal("file too big"); + if(ofile == nil) ofile = smprint("%s.u", dir->name); + outfd = create(ofile, OWRITE|OTRUNC, 0666); + if(outfd < 0) sysfatal("create: %r"); + + tab = mkcrctab(0xEDB88320); + seek(outfd, sizeof(header), 0); + put(buf+0, dir->length); + put(buf+4, 0); + dcrc = blockcrc(tab, 0, buf, 8); + if(write(outfd, buf, 8) != 8) sysfatal("write: %r"); + copy(dir->length); + + memset(header, 0, sizeof(header)); + put(&header[0], 0x27051956); /* magic */ + put(&header[8], time(0)); /* time */ + put(&header[12], 8+dir->length); /* image size */ + put(&header[16], 0); /* load address */ + put(&header[20], 0); /* entry point */ + put(&header[24], dcrc); /* data crc */ + header[28] = 0; + header[29] = 0; + header[30] = IH_TYPE_SCRIPT; + header[31] = 0; /* compressed = no */ + + strncpy((char*)&header[32], dir->name, sizeof(header)-32); + put(&header[4], blockcrc(tab, 0, header, sizeof(header))); + + seek(outfd, 0, 0); + if(write(outfd, header, sizeof(header)) < sizeof(header)) sysfatal("write: %r"); + + exits(nil); +} |