236 lines
5.2 KiB
C
236 lines
5.2 KiB
C
#include <y16t_db.h>
|
|
|
|
#include <sys/file.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__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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
fd = open(dbfile, O_RDWR | O_CREAT | O_NOCTTY);
|
|
if(fd == -1) {
|
|
perror("y16t: unable to open file");
|
|
return -1;
|
|
}
|
|
|
|
if(flock(fd, LOCK_EX) == -1) {
|
|
perror("y16t: unable to lock file");
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
fd = open(dbfile, O_RDWR | O_NOCTTY);
|
|
if(fd == -1) {
|
|
perror("y16t: unable to open file");
|
|
return -1;
|
|
}
|
|
|
|
if(flock(fd, LOCK_EX) == -1) {
|
|
perror("y16t: unable to lock file");
|
|
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_RDONLY | O_NOCTTY);
|
|
if(fd == -1) {
|
|
perror("y16t: unable to open file");
|
|
return -1;
|
|
}
|
|
|
|
if(flock(fd, LOCK_SH) == -1) {
|
|
perror("y16t: unable to lock 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_RDONLY | O_NOCTTY);
|
|
if(fd == -1) {
|
|
perror("y16t: unable to open file");
|
|
return -1;
|
|
}
|
|
|
|
if(flock(fd, LOCK_SH) == -1) {
|
|
perror("y16t: unable to lock file");
|
|
return -1;
|
|
}
|
|
|
|
varname = 'x';
|
|
y16t_db_foreach_x(fd, y, y16t_cli_fecb, &varname);
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "y16t: invalid invocation / unknown subcommand\n");
|
|
return -1;
|
|
}
|
|
|
|
//if(fd != -1)
|
|
// close(fd);
|
|
|
|
return 0;
|
|
}
|