1
0
mirror of https://github.com/DiUS/spiffsimg.git synced 2025-05-08 20:40:34 +08:00

Minimal feature set competed.

More graceful error handling would be nice, of course...
This commit is contained in:
Johny Mattsson 2015-07-15 17:32:12 +10:00
parent 96a8b2f5d8
commit 4e73803061

213
main.c
View File

@ -2,6 +2,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
@ -11,6 +12,8 @@
static spiffs fs;
static uint8_t *flash;
static int retcode = 0;
#define LOG_PAGE_SIZE 256
static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
@ -32,20 +35,125 @@ static s32_t flash_erase (u32_t addr, u32_t size) {
}
void die (const char *what)
static void die (const char *what)
{
perror (what);
exit (1);
}
static void list (void)
{
spiffs_DIR dir;
if (!SPIFFS_opendir (&fs, "/", &dir))
die ("spiffs_opendir");
struct spiffs_dirent de;
while (SPIFFS_readdir (&dir, &de))
{
static const char types[] = "?fdhs"; // file, dir, hardlink, softlink
char name[sizeof(de.name)+1] = { 0 };
memcpy (name, de.name, sizeof(de.name));
printf("%c %6u %s\n", types[de.type], de.size, name);
}
SPIFFS_closedir (&dir);
}
static void cat (char *fname)
{
spiffs_file fh = SPIFFS_open (&fs, fname, SPIFFS_RDONLY, 0);
char buff[512];
s32_t n;
while ((n = SPIFFS_read (&fs, fh, buff, sizeof (buff))) > 0)
write (STDOUT_FILENO, buff, n);
SPIFFS_close (&fs, fh);
}
static void import (char *src, char *dst)
{
int fd = open (src, O_RDONLY);
if (fd < 0)
die (src);
spiffs_file fh = SPIFFS_open (&fs, dst, SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_WRONLY, 0);
if (fh < 0)
die ("spiffs_open");
char buff[512];
s32_t n;
while ((n = read (fd, buff, sizeof (buff))) > 0)
if (SPIFFS_write (&fs, fh, buff, n) < 0)
die ("spiffs_write");
SPIFFS_close (&fs, fh);
close (fd);
}
static void export (char *src, char *dst)
{
spiffs_file fh = SPIFFS_open (&fs, src, SPIFFS_RDONLY, 0);
if (fh < 0)
die ("spiffs_open");
int fd = open (dst, O_CREAT | O_TRUNC | O_WRONLY, 0660);
if (fd < 0)
die (dst);
char buff[512];
s32_t n;
while ((n = SPIFFS_read (&fs, fh, buff, sizeof (buff))) > 0)
if (write (fd, buff, n) < 0)
die ("write");
SPIFFS_close (&fs, fh);
close (fd);
}
char *trim (char *in)
{
if (!in)
return "";
char *out = 0;
while (*in)
{
if (!out && !isspace (*in))
out = in;
++in;
}
if (!out)
return "";
while (--in > out && isspace (*in))
;
in[1] = 0;
return out;
}
void syntax (void)
{
fprintf (stderr,
"Syntax: spiffsimg -f <filename> [-c size] [-l | -i | -r <scriptname> ]\n\n"
);
exit (1);
}
int main (int argc, char *argv[])
{
if (argc == 1)
syntax ();
int opt;
const char *fname = 0;
bool create = false;
enum { CMD_LIST, CMD_INTERACTIVE, CMD_SCRIPT } command;
enum { CMD_NONE, CMD_LIST, CMD_INTERACTIVE, CMD_SCRIPT } command = CMD_NONE;
size_t sz = 0;
while ((opt = getopt (argc, argv, "f:c:lir")) != -1)
const char *script_name = 0;
while ((opt = getopt (argc, argv, "f:c:lir:")) != -1)
{
switch (opt)
{
@ -53,7 +161,7 @@ int main (int argc, char *argv[])
case 'c': create = true; sz = strtoul (optarg, 0, 0); break;
case 'l': command = CMD_LIST; break;
case 'i': command = CMD_INTERACTIVE; break;
case 'r': command = CMD_SCRIPT; break;
case 'r': command = CMD_SCRIPT; script_name = optarg; break;
default: die ("unknown option");
}
}
@ -82,7 +190,7 @@ int main (int argc, char *argv[])
flash = mmap (0, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (!flash)
die ("mmap");
die ("mmap");
if (create)
memset (flash, 0xff, sz);
@ -103,28 +211,87 @@ int main (int argc, char *argv[])
0, 0, 0) != 0)
die ("spiffs_mount");
// TODO: import/export support
spiffs_file fh = SPIFFS_open (&fs, "foo/bar", SPIFFS_CREAT | SPIFFS_RDWR, 0);
if (SPIFFS_write (&fs, fh, "hello, world\n", 12) < 0)
die ("spiffs_write");
SPIFFS_close (&fs, fh);
if (command == CMD_LIST)
if (command == CMD_NONE)
; // maybe just wanted to create an empty image?
else if (command == CMD_LIST)
list ();
else
{
spiffs_DIR dir;
if (!SPIFFS_opendir (&fs, "/", &dir))
die ("spiffs_opendir");
struct spiffs_dirent de;
while (SPIFFS_readdir (&dir, &de))
FILE *in = (command == CMD_INTERACTIVE) ? stdin : fopen (script_name, "r");
if (!in)
die ("fopen");
char buff[128] = { 0 };
if (in == stdin)
printf("> ");
while (fgets (buff, sizeof (buff) -1, in))
{
static const char types[] = "?fdhs"; // file, dir, hardlink, softlink
char name[sizeof(de.name)+1] = { 0 };
memcpy (name, de.name, sizeof(de.name));
printf("%c %6u %s\n", types[de.type], de.size, name);
char *line = trim (buff);
if (!line[0] || line[0] == '#')
continue;
if (strcmp (line, "ls") == 0)
list ();
else if (strncmp (line, "import ", 7) == 0)
{
char *src = 0, *dst = 0;
if (sscanf (line +7, " %ms %ms", &src, &dst) != 2)
{
fprintf (stderr, "SYNTAX ERROR: %s\n", line);
retcode = 1;
}
else
import (src, dst);
free (src);
free (dst);
}
else if (strncmp (line, "export ", 7) == 0)
{
char *src = 0, *dst = 0;
if (sscanf (line + 7, " %ms %ms", &src, &dst) != 2)
{
fprintf (stderr, "SYNTAX ERROR: %s\n", line);
retcode = 1;
}
else
export (src, dst);
free (src);
free (dst);
}
else if (strncmp (line, "rm ", 3) == 0)
{
if (SPIFFS_remove (&fs, trim (line + 3)) < 0)
{
fprintf (stderr, "FAILED: %s\n", line);
retcode = 1;
}
}
else if (strncmp (line, "cat ", 4) == 0)
cat (trim (line + 4));
else if (strncmp (line, "info", 4) == 0)
{
u32_t total, used;
if (SPIFFS_info (&fs, &total, &used) < 0)
{
fprintf (stderr, "FAILED: %s\n", line);
retcode = 1;
}
else
printf ("Total: %u, Used: %u\n", total, used);
}
else
{
printf ("SYNTAX ERROR: %s\n", line);
retcode = 1;
}
if (in == stdin)
printf ("> ");
}
SPIFFS_closedir (&dir);
if (in == stdin)
printf ("\n");
}
SPIFFS_unmount (&fs);
munmap (flash, sz);
return 0;
close (fd);
return retcode;
}