~vdupras/collapseos

ref: ac3629b817115b1af75096856ee9499cfbbd3392 collapseos/tools/blkpack.c -rw-r--r-- 2.3 KiB
ac3629b8Virgil Dupras Make BLK@* and BLK!* into ialiases 1 year, 10 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#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;
}