1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-15 16:48:05 +11:00
collapseos/tools/blkpack.c
Virgil Dupras 95ab1ad588 Transform "blk/" folders into "blk.fs" text files
Working in "blk/" folder from a modern system is harder than it
should be. Moving blocks around is a bit awkward, grepping is a
bit less convenient than it could be, git blame has troubles
following, etc.

In this commit, we modify blkpack and blkunpack to work with single
text files with blocks being separated by a special markup.

I think this will make the code significantly more convenient to
work into.
2020-11-14 18:34:15 -05:00

98 lines
2.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
static int lineno;
static void emptylines(int n)
{
for (int i=0; i<64*n; i++) putchar(0);
}
static int getmarker(char *line) // returns -1 on error, blkid otherwise
{
int blkid;
int r = sscanf(line, "( ----- %d )\n", &blkid);
if (r == 1) {
return blkid;
} else {
return -1;
}
}
static int expectmarker(char *line)
{
int blkid = getmarker(line);
if (blkid < 0) { // could not scan
fprintf(
stderr, "Error at line %d: expecting block marker\n", lineno);
}
return blkid;
}
static void usage()
{
fprintf(stderr, "Usage: blkpack < blk.fs > blkfs\n");
}
int main(int argc, char *argv[])
{
int prevblkid = -1;
int blkid;
char *line = NULL;
if (argc != 1) {
usage();
return 1;
}
lineno = 1;
size_t n = 0;
ssize_t cnt = getline(&line, &n, stdin);
if (cnt <= 0) {
fprintf(stderr, "No input\n");
return 1;
}
while (1) {
blkid = expectmarker(line);
if (blkid < 0) return 1;
if (blkid <= prevblkid) {
fprintf(
stderr,
"Wrong blkid (%d) at line %d: blocks must be ordered\n",
blkid, lineno);
return 1;
}
emptylines((blkid-prevblkid-1)*16);
int blkline;
for (blkline=0; blkline<16; blkline++) {
lineno++;
cnt = getline(&line, &n, stdin);
if (cnt <= 0) break; // EOF
if (cnt > 65) {
fprintf(stderr, "Line %d too long (blk %d)\n", lineno, blkid);
return 1;
}
if (getmarker(line) >= 0) break; // we have a marker early
line[cnt-1] = '\0'; // remove newline
printf("%s", line);
// pad line to 64 chars
for (int i=cnt-1; i<64; i++) putchar(0);
}
if (blkline == 16) {
lineno++;
cnt = getline(&line, &n, stdin);
} else {
// fill to 16 lines
emptylines(16-blkline);
}
if (cnt <= 0) break; // EOF
prevblkid = blkid;
}
free(line);
return 0;
}