y16t/bin/main.c
2023-01-03 23:13:32 +01:00

218 lines
4.9 KiB
C

#include <y16t_db.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
enum subcmd_t {
YSC__UNKNOWN,
YSC__HELP,
YSC_INSERT,
YSC_DELETE,
YSC_SELEQ_X,
YSC_SELEQ_Y
};
static enum subcmd_t
y16t_parse_subcommand(const char *arg)
{
if(!strcmp(arg, "--help")) return YSC__HELP;
else if(!strcmp(arg, "i")) return YSC_INSERT;
else if(!strcmp(arg, "d")) return YSC_DELETE;
else if(!strcmp(arg, "x=")) return YSC_SELEQ_X;
else if(!strcmp(arg, "y=")) return YSC_SELEQ_Y;
else return YSC__UNKNOWN;
}
static int8_t y16t_parse_hex(const char x)
{
if('0' <= x && x <= '9') return x - '9';
if('a' <= x && x <= 'f') return x - 'a' + 10;
if('A' <= x && x <= 'F') return x - 'A' + 10;
return -1;
}
static int16_t y16t_parse_hex2(const char *arg)
{
if(!arg) return -1;
int8_t a = y16t_parse_hex(arg[0]);
if(a < 0) return -1;
int8_t b = y16t_parse_hex(arg[1]);
if(b < 0) return -1;
return (((int16_t)a) << 8) + b;
}
static int y16t_parse_coordinate(const char *arg, uint8_t *coord, size_t maxlen)
{
*coord = 0;
while(*arg && maxlen) {
int16_t tmp = y16t_parse_hex2(arg);
if(tmp == -1) {
*coord = 0;
return -1;
}
*coord = tmp;
coord += 1;
maxlen -= 1;
}
return 0;
}
static int y16t_cli_fecb(const uint8_t *xy, const uint8_t *z, void *varname) {
int i;
printf("%c=", *((const char *)varname));
for(i = 0; i < 16; ++i) printf("%02x", xy[i]);
printf(" z=");
for(i = 0; i < 16; ++i) printf("%02x", xy[i]);
return 0;
}
int main(int argc, const char *argv[])
{
if(argc < 3) {
fprintf(stderr, "USAGE: y16t DBFILE SUBCOMMAND|--help ARGS...\n");
return -1;
}
const char *dbfile = argv[1];
int fd = -1, tmp = -1;
uint8_t x[16] = {0}, y[16] = {0}, z[16] = {0};
char varname = 0;
switch(y16t_parse_subcommand(argv[2])) {
case YSC__UNKNOWN:
fprintf(stderr, "y16t: unknown subcommand\n");
return -1;
case YSC__HELP:
puts("available subcommands:");
puts(" --help prints this help text");
puts(" i X Y Z inserts an entry");
puts(" d X Y Z removes an entry");
puts(" x= X iterates over all entries with x=X");
puts(" y= Y iterates over all entries with y=Y");
puts("");
puts("coordinates (X, Y, Z) format:");
puts(" a hex string ([0-9a-fA-F]) of 16 bytes (32 bytes encoded)");
return 0;
case YSC_INSERT:
if(argc < 6) {
fprintf(stderr, "y16t/insert: invalid invocation\n");
return -1;
}
fd = open(dbfile, O_RDWR | O_CREAT | O_NOCTTY);
if(fd == -1) {
perror("y16t: unable to open file");
return -1;
}
if(-1 == y16t_parse_coordinate(argv[3], x, sizeof(x))) {
fprintf(stderr, "y16t: invalid coordinate X\n");
return -1;
}
if(-1 == y16t_parse_coordinate(argv[4], y, sizeof(y))) {
fprintf(stderr, "y16t: invalid coordinate Y\n");
return -1;
}
if(-1 == y16t_parse_coordinate(argv[5], z, sizeof(z))) {
fprintf(stderr, "y16t: invalid coordinate Z\n");
return -1;
}
tmp = y16t_db_insert(fd, x, y, z);
if(tmp < 0) {
fprintf(stderr, "y16t: insert failed with %s\n", strerror(-tmp));
return -1;
}
break;
case YSC_DELETE:
if(argc < 6) {
fprintf(stderr, "y16t/delete: invalid invocation\n");
return -1;
}
fd = open(dbfile, O_RDWR | O_NOCTTY);
if(fd == -1) {
perror("y16t: unable to open file");
return -1;
}
if(-1 == y16t_parse_coordinate(argv[3], x, sizeof(x))) {
fprintf(stderr, "y16t: invalid coordinate X\n");
return -1;
}
if(-1 == y16t_parse_coordinate(argv[4], y, sizeof(y))) {
fprintf(stderr, "y16t: invalid coordinate Y\n");
return -1;
}
if(-1 == y16t_parse_coordinate(argv[5], z, sizeof(z))) {
fprintf(stderr, "y16t: invalid coordinate Z\n");
return -1;
}
//tmp = y16t_db_remove(fd, x, y, z);
tmp = -EOPNOTSUPP;
if(tmp < 0) {
fprintf(stderr, "y16t: insert failed with %s\n", strerror(-tmp));
return -1;
}
break;
case YSC_SELEQ_X:
if(argc < 4) {
fprintf(stderr, "y16t/x=: invalid invocation\n");
return -1;
}
if(-1 == y16t_parse_coordinate(argv[3], x, sizeof(x))) {
fprintf(stderr, "y16t: invalid coordinate X\n");
return -1;
}
fd = open(dbfile, O_RDWR | O_NOCTTY);
if(fd == -1) {
perror("y16t: unable to open file");
return -1;
}
varname = 'y';
y16t_db_foreach_y(fd, x, y16t_cli_fecb, &varname);
break;
case YSC_SELEQ_Y:
if(argc < 4) {
fprintf(stderr, "y16t/y=: invalid invocation\n");
return -1;
}
if(-1 == y16t_parse_coordinate(argv[3], y, sizeof(y))) {
fprintf(stderr, "y16t: invalid coordinate Y\n");
return -1;
}
fd = open(dbfile, O_RDWR | O_NOCTTY);
if(fd == -1) {
perror("y16t: unable to open file");
return -1;
}
varname = 'x';
y16t_db_foreach_x(fd, y, y16t_cli_fecb, &varname);
break;
default:
fprintf(stderr, "y16t: invalid invocation\n");
}
//if(fd != -1)
// close(fd);
return 0;
}