mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 14:08:05 +11:00
tools/cfsunpack: new tool
This commit is contained in:
parent
95b658897a
commit
6f61aa404f
@ -1,4 +1,9 @@
|
|||||||
TARGETS = cfspack
|
TARGETS = cfspack cfsunpack
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
cfspack: cfspack.c
|
cfspack: cfspack.c
|
||||||
|
cfsunpack: cfsunpack.c
|
||||||
|
$(TARGETS):
|
||||||
$(CC) -o $@ $^
|
$(CC) -o $@ $^
|
||||||
|
93
tools/cfspack/cfsunpack.c
Normal file
93
tools/cfspack/cfsunpack.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#define BLKSIZE 0x100
|
||||||
|
#define HEADERSIZE 0x20
|
||||||
|
#define MAX_FN_LEN 25 // 26 - null char
|
||||||
|
|
||||||
|
bool ensuredir(char *path)
|
||||||
|
{
|
||||||
|
char *s = path;
|
||||||
|
while (*s != '\0') {
|
||||||
|
if (*s == '/') {
|
||||||
|
*s = '\0';
|
||||||
|
struct stat path_stat;
|
||||||
|
if (stat(path, &path_stat) != 0) {
|
||||||
|
if (mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*s = '/';
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool unpackblk(char *dstpath)
|
||||||
|
{
|
||||||
|
char buf[MAX_FN_LEN+1];
|
||||||
|
if (fgets(buf, 3+1, stdin) == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (strcmp(buf, "CFS") != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int c = getchar();
|
||||||
|
uint8_t blkcnt = c;
|
||||||
|
if (blkcnt == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
c = getchar();
|
||||||
|
uint16_t fsize = c & 0xff;
|
||||||
|
c = getchar();
|
||||||
|
fsize |= (c & 0xff) << 8;
|
||||||
|
|
||||||
|
if (fgets(buf, MAX_FN_LEN+1+1, stdin) == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char fullpath[0x1000];
|
||||||
|
strcpy(fullpath, dstpath);
|
||||||
|
strcat(fullpath, "/");
|
||||||
|
strcat(fullpath, buf);
|
||||||
|
if (!ensuredir(fullpath)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int blksize = (BLKSIZE-HEADERSIZE)+(BLKSIZE*(blkcnt-1));
|
||||||
|
int skipcount = blksize - fsize;
|
||||||
|
FILE *fp = fopen(fullpath, "w");
|
||||||
|
while (fsize) {
|
||||||
|
c = getchar();
|
||||||
|
if (c == EOF) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fputc(c, fp);
|
||||||
|
fsize--;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
while (skipcount) {
|
||||||
|
getchar();
|
||||||
|
skipcount--;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "Usage: cfspack /path/to/dest\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
char *dstpath = argv[1];
|
||||||
|
// we fail if there isn't at least one block
|
||||||
|
if (!unpackblk(dstpath)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
while (unpackblk(dstpath));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user