summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile22
-rw-r--r--README.txt1
-rw-r--r--buf.c107
-rw-r--r--buf.h43
-rw-r--r--cmd.c168
-rw-r--r--cmd.h33
-rw-r--r--core.c326
-rw-r--r--core.h110
-rw-r--r--doc/DOC.txt115
-rw-r--r--ihe.c569
-rw-r--r--ihe.h12
11 files changed, 1506 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7a35c26
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+PROJECT=ihe
+CC=gcc
+CFLAGS=
+SOURCES=buf.c cmd.c core.c
+OBJECTS=$(SOURCES:.c=.o)
+
+all: clean $(OBJECTS) $(PROJECT)
+
+$(PROJECT):
+ $(CC) $(CFLAGS) $(OBJECTS) $(PROJECT).c -o $(PROJECT)
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $<
+
+clean:
+ rm -f $(PROJECT)
+ rm -f *.o
+
+leak:
+ valgrind --leak-check=full --track-origins=yes --log-file=log.txt ./ihe
+ #valgrind --track-origins=yes --log-file=log.txt ./dm -f test/test.bin -m test/one_byte.dm
+
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..7678490
--- /dev/null
+++ b/README.txt
@@ -0,0 +1 @@
+interactive hex editor \ No newline at end of file
diff --git a/buf.c b/buf.c
new file mode 100644
index 0000000..440ac76
--- /dev/null
+++ b/buf.c
@@ -0,0 +1,107 @@
+#include "buf.h"
+
+buf_t* buf_init()
+{
+ buf_t *ret = NULL;
+
+ ret = malloc( sizeof(buf_t) );
+ memset(ret, 0, sizeof(buf_t));
+
+ return ret;
+}
+
+
+int buf_size( buf_t *bf, int size )
+{
+ if (bf->buf != NULL)
+ {
+ printf("Buffer should be empty\n");
+ return -1;
+ }
+
+ bf->buf = malloc( size );
+ bf->size = size;
+ bf->buf_size = size;
+
+ return 0;
+}
+
+
+int buf_used_size( buf_t *bf, int size )
+{
+ if ( size > bf->buf_size )
+ {
+ printf("Cannot set buffer size more then buffer itself\n");
+ return -1;
+ }
+
+ if ( size < 0)
+ {
+ printf("Cannot set buffer less then zero\n");
+ return -1;
+ }
+
+ bf->size = size;
+
+ return 0;
+}
+
+
+int buf_resize( buf_t *bf, int size )
+{
+ uint8_t *n=NULL;
+
+ if ( size < 1)
+ {
+ printf("Cannot set buffer size less then 1\n");
+ return -1;
+ }
+
+ n = realloc( bf->buf, size ); //resized data is not nullified at the end?
+ if ( n == NULL )
+ {
+ printf("Buffer realloc failed\n");
+ return -1;
+ }
+
+ if ( size > bf->buf_size )
+ {
+ memset(bf->buf+bf->buf_size-1, 0, size-(bf->buf_size)); //hope its correct
+ }
+
+ bf->buf_size = size;
+ bf->buf = n;
+ if (bf->size > bf->buf_size)
+ {
+ bf->size = bf->buf_size;
+ }
+
+ return 0;
+}
+
+
+int buf_zero( buf_t *bf )
+{
+ if ( bf->buf == NULL )
+ return -1;
+
+ memset( bf->buf, 0, bf->buf_size );
+
+ return 0;
+}
+
+
+void buf_free( buf_t *bf )
+{
+ if ( bf == NULL )
+ return;
+
+ if ( bf->buf != NULL )
+ {
+ free( bf->buf );
+ bf->buf = NULL;
+ }
+
+ free( bf );
+ bf = NULL;
+}
diff --git a/buf.h b/buf.h
new file mode 100644
index 0000000..8ca6014
--- /dev/null
+++ b/buf.h
@@ -0,0 +1,43 @@
+#ifndef __IHE_BUF_H
+#define __IHE_BUF_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+typedef struct buf_t
+{
+ uint8_t *buf;
+ int size;
+ int buf_size;
+} buf_t;
+
+/*
+create empty buffer structure
+*/
+buf_t* buf_init();
+/*
+if empty setup new buffer
+if not empty resize?
+*/
+int buf_size( buf_t *bf, int size );
+/*
+set used buffer size
+*/
+int buf_used_size( buf_t *bf, int size );
+/*
+change buffer size
+*/
+int buf_resize( buf_t *bf, int size );
+/*
+make buffer full of zeros
+*/
+int buf_zero( buf_t *bf );
+/*
+clean all buffer
+*/
+void buf_free( buf_t *bf );
+
+
+#endif \ No newline at end of file
diff --git a/cmd.c b/cmd.c
new file mode 100644
index 0000000..2fb1a76
--- /dev/null
+++ b/cmd.c
@@ -0,0 +1,168 @@
+#include "cmd.h"
+
+
+int cnt_sep( char *s )
+{
+ int cnt=0;
+ char *p=s;
+ while ( *p++ )
+ {
+ if (p[0]==' ')
+ {
+ cnt++;
+ }
+ }
+
+ return cnt;
+
+}
+
+
+char* cmd_line( char *prompt )
+{
+ char *ret = NULL;
+ char *pmt = ">";
+ const int buf_sz = 32;
+ int ret_sz;
+ char buf[buf_sz];
+
+
+ if ( prompt != NULL )
+ {
+ pmt = prompt;
+ }
+
+ memset( buf, 0, buf_sz );
+ write( 1, pmt, strlen(pmt) );
+ ret_sz = read( 2, buf,buf_sz);
+ if (ret_sz < 1)
+ return ret;
+
+ ret = malloc(ret_sz-1);
+ memcpy( ret, buf, ret_sz-1 );
+
+ return ret;
+}
+
+
+cmd_arg* cmd_parse( char *str )
+{
+ int cnt=0;
+ cmd_arg *ret = NULL;
+ int i,j;
+ char *last=str;
+ int sz;
+
+
+ //count white spaces
+ cnt = cnt_sep( str )+1;
+
+ ret = malloc( sizeof(cmd_arg) );
+ ret->argv = malloc( sizeof(void*)*cnt );
+
+ ret->argc = cnt;
+
+ if ( cnt == 1 )
+ {
+ ret->argv[0] = malloc( strlen(str) );
+ memcpy( ret->argv[0], str, strlen(str) );
+ return ret;
+ }
+
+ //best practices
+ j = 0;
+ for (i=0;i<strlen(str);i++)
+ {
+ if (str[i]==' ')
+ {
+ sz = (str+i)-last;
+ ret->argv[j] = malloc( sz+1 );
+ memcpy(ret->argv[j],last,sz);
+ ret->argv[j][sz] = '\0';
+ last = str+i+1;
+ j++;
+ }
+ }
+ sz = str + i - last;
+ ret->argv[j] = malloc(sz+1);
+ memcpy( ret->argv[j], last, sz );
+ ret->argv[j][sz] = '\0';
+
+ return ret;
+}
+
+int cmd_exec( cmd_arg *cmd, cmd_table *table )
+{
+ int ret = 0;
+ int fret = 0;
+ int i;
+ cmd_arg *sub_arg;
+
+ if (cmd->argc < 1)
+ {
+ printf("Hm ... no arguments\n");
+ return -1;
+ }
+
+ i = 0;
+ while ( (table[i].cmd != NULL) && (table[i].clb != NULL) )
+ {
+ if ((strlen(table[i].cmd) == strlen(cmd->argv[0]))
+ && (strlen(table[i].cmd) != 0))
+ if( strncmp( table[i].cmd, cmd->argv[0], strlen(cmd->argv[0]) ) == 0 )
+ {
+ if ( table[i].clb == NULL )
+ {
+ printf("Empty callback for %s\n",table[i].cmd);
+ ret = -1;
+ break;
+ }
+
+ sub_arg = sub_cmd( cmd );
+ fret = table[i].clb( sub_arg );
+ if ( fret != 0 )
+ {
+ printf("Command unsuccesfull execution\n");
+ ret = -1;
+ break;
+ }
+ break;
+
+ }
+
+ i++;
+ }
+
+
+ return ret;
+}
+
+
+void cmd_arg_free( cmd_arg *arg )
+{
+
+}
+
+void cmd_sub_arg_free( cmd_arg *arg )
+{
+
+}
+
+
+cmd_arg* sub_cmd( cmd_arg *arg )
+{
+ int i;
+ cmd_arg *ret=NULL;
+
+ if ( arg->argc < 1)
+ return NULL;
+
+ ret = malloc( sizeof(cmd_arg) );
+ ret->argc = arg->argc-1;
+ ret->argv = malloc( sizeof(void*)*ret->argc );
+ for (i=0;i<ret->argc;i++)
+ ret->argv[i] = arg->argv[i+1];
+
+ return ret;
+}
+
diff --git a/cmd.h b/cmd.h
new file mode 100644
index 0000000..436feac
--- /dev/null
+++ b/cmd.h
@@ -0,0 +1,33 @@
+#ifndef __IHE_CMD_H
+#define __IHE_CMD_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+typedef struct cmd_arg
+{
+ int argc;
+ char **argv;
+} cmd_arg;
+
+
+typedef struct cmd_table
+{
+ char *cmd;
+ int (*clb)(cmd_arg*);
+} cmd_table;
+
+
+int cnt_sep( char *s );
+char* cmd_line( char *prompt );
+cmd_arg* cmd_parse( char *str );
+int cmd_exec( cmd_arg *cmd, cmd_table *table );
+void cmd_arg_free( cmd_arg *arg );
+void cmd_sub_arg_free( cmd_arg *arg );
+cmd_arg* sub_cmd( cmd_arg *arg );
+
+
+#endif
diff --git a/core.c b/core.c
new file mode 100644
index 0000000..2711111
--- /dev/null
+++ b/core.c
@@ -0,0 +1,326 @@
+#include "core.h"
+
+int fd_open( const char *filename, int flags )
+{
+ int ret;
+
+ ret = open( filename, flags );
+
+ return ret;
+}
+
+
+int fd_close( int fd )
+{
+ int ret;
+
+ ret = close( fd );
+
+ return ret;
+}
+
+
+int fd_seek( int fd, off_t offset, int whence )
+{
+ int ret = 0;
+ off_t off_new=0;
+
+ off_new = lseek( fd, offset, whence );
+ if ( errno != 0)
+ {
+ printf("Cannot seek %s\n", strerror(errno));
+ errno = 0; //why i need to reset it?
+ return -1;
+ }
+
+ return ret;
+}
+
+
+off_t fd_pos( int fd )
+{
+ off_t cur = 0;
+ cur = lseek( fd, 0, SEEK_CUR );
+ return cur;
+}
+
+
+off_t fd_set_pos( int fd, off_t offset )
+{
+ off_t ret;
+
+ ret = lseek( fd, offset, SEEK_SET );
+
+ return ret;
+}
+
+
+off_t fd_size( int fd )
+{
+ off_t ret;
+ off_t old;
+
+ old = lseek( fd, 0, FD_SEEK_CUR );
+ ret = lseek( fd, 0, FD_SEEK_END );
+ lseek( fd, old, FD_SEEK_SET );
+
+ return ret;
+}
+
+
+ssize_t fd_read( int fd, void *buf, size_t count )
+{
+ ssize_t ret;
+
+ ret = read( fd, buf, count );
+
+ return ret;
+}
+
+
+ssize_t fd_write( int fd, void *buf, size_t count )
+{
+ ssize_t ret;
+
+ printf("%d %x %d\n", fd, buf, count);
+ ret = write( fd, buf, count );
+ if ( errno != 0)
+ {
+ printf("Cannot write %s\n", strerror(errno));
+ errno = 0;
+ }
+
+ return ret;
+}
+
+
+file_t *file_init()
+{
+ file_t *ret = NULL;
+
+ ret = malloc( sizeof(file_t) );
+ memset( ret, 0, sizeof(file_t) );
+
+ ret->flags = FD_RO; //di we really need that?
+
+ return ret;
+}
+
+
+int file_open_fn( file_t *ft, const char *filename, int flags )
+{
+ int ret = 0;
+ int fd;
+
+ fd = fd_open( filename, flags );
+ if ( fd < 1 )
+ {
+ printf("Couldnt open %s\n", filename);
+ return -1;
+ }
+
+ ft->fd = fd;
+ ft->flags = flags;
+ ft->filename = filename;
+
+
+ /* set current file cursor postion and file size */
+ ft->size = fd_size( fd ); /* if it RO mode - could be important */
+ ft->position = fd_pos( fd ); /* file cursor position could be bigger
+ then file size*/
+ ft->blk_size = DEFAULT_BLK_SIZE;
+
+ return ret;
+}
+
+
+int file_seek( file_t *ft, off_t offset )
+{
+ int ret = 0;
+ off_t new_off=0;
+
+
+ ret = fd_seek( ft->fd, offset, FD_SEEK_CUR );
+ if (ret == 0)
+ {
+ new_off = fd_pos( ft->fd );
+ if (new_off > ft->size)
+ {
+ fd_seek( ft->fd, ft->size, FD_SEEK_SET );
+ new_off = fd_pos( ft->fd );
+ }
+ ft->position = new_off;
+ ft->offset = offset;
+ if ( offset != new_off )
+ {
+ printf("Offset set to %zd requested %zd\n", new_off, offset);
+ }
+ } else
+ {
+ printf("Cannot set offset\n");
+ ret = -1;
+ }
+
+ return ret;
+}
+
+
+int file_pos( file_t *ft )
+{
+ int ret = 0;
+ long pos = fd_pos( ft->fd );
+ if (pos < 0)
+ {
+ printf("Cannot get file cursor position\n");
+ ret = -1;
+ }
+
+ ft->position = pos;
+ ret = pos;
+
+ return ret;
+}
+
+
+int file_size( file_t *ft )
+{
+ int ret = 0;
+ off_t size;
+
+ size = fd_size( ft->fd );
+ if (size < 0)
+ {
+ printf("Cannot get file size\n");
+ return -1;
+ }
+ ft->size = size;
+ ret = size;
+
+ return ret;
+}
+
+
+int file_open( file_t *ft, const char *filename, int flags, int mode )
+{
+ int ret = 0;
+ printf("Not implemented\n");
+ ret = -1;
+ return ret;
+}
+
+
+int file_read_blk( file_t *ft, uint8_t *buf )
+{
+ int ret = 0;
+
+ if ( ft->fd < 0 )
+ return -1;
+
+ file_pos( ft );
+ ret = fd_read( ft->fd, buf, ft->blk_size );
+ fd_set_pos( ft->fd, ft->position ); //chck err?
+
+ if ( ret < 0)
+ {
+ printf("Error while reading from file\n");
+ }
+
+ return ret;
+}
+
+
+int file_read( file_t *ft, uint8_t *buf, size_t count )
+{
+ int ret = 0;
+
+ ret = fd_read( ft->fd, buf, count );
+ if ( ret < 0 )
+ {
+ printf("Cannot read\n");
+ } else if ( ret < count )
+ {
+ printf("Requestd %d readed %d\n", count, ret);
+ }
+
+ return ret;
+}
+
+
+int file_write_blk( file_t *ft, uint8_t *buf )
+{
+ int ret = 0;
+ unsigned int sz;
+
+ file_pos( ft );
+ if ( ft->position + ft->blk_size <= ft->size )
+ {
+ sz = ft->blk_size;
+ } else
+ {
+ sz = ft->size - ft->position; //when pos 0 ans size 1 then will write 1 byte
+ }
+ printf(" %d %x %u \n", ft->fd, buf, sz);
+ ret = fd_write( ft->fd, buf, sz );
+ if ( ret < 0 )
+ {
+ printf("Error while writing block to file\n");
+ }
+ fd_set_pos( ft->fd, ft->position );
+
+
+
+ return ret;
+}
+
+
+int file_write( file_t *ft, uint8_t *buf, size_t count )
+{
+ int ret = 0;
+
+ ret = fd_write( ft->fd, buf, count );
+ if ( ret < 0 )
+ {
+ printf("Cannot write\n");
+ } else if ( ret < count )
+ {
+ printf("Requested %d written %d\n", count, ret);
+ }
+
+ return ret;
+}
+
+
+int file_s_mode( file_t *ft, int mode )
+{
+ int ret = 0;
+
+ if ( ft == NULL)
+ return -1;
+
+ ft->mode = mode;
+
+ return ret;
+}
+
+
+int file_close( file_t *ft )
+{
+ int ret = 0;
+
+ if ( ft->fd < 1 )
+ {
+ printf("File descriptor <1\n");
+ ret = -1;
+ }
+
+ if ( ft->filename == NULL )
+ {
+ printf("File name is empty\n");
+ ret = -1;
+ }
+
+ fd_close( ft->fd );
+ memset( ft, 0, sizeof(file_t) );
+
+ return ret;
+}
diff --git a/core.h b/core.h
new file mode 100644
index 0000000..02f072b
--- /dev/null
+++ b/core.h
@@ -0,0 +1,110 @@
+#ifndef __IHE_CORE_H
+#define __IHE_CORE_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+/*
+BASIC FILE OPERATIONS ON FILE
+*/
+
+#define FD_RO O_RDONLY
+#define FD_WO O_WRONLY
+#define FD_RW O_RDWR
+#define FD_MNONE 0
+
+#define FD_SEEK_CUR SEEK_CUR
+#define FD_SEEK_SET SEEK_SET
+#define FD_SEEK_END SEEK_END
+
+/*OPEN FILE BY FILE NAME*/
+int fd_open( const char *filename, int flags );
+/*CLOSE FILE BY FD*/
+int fd_close( int fd );
+/*SEEK FILE
+FD - file descriptor
+OFFSET - seek pos
+WHENCE - seek mode
+NEW_OFFSET - new pos, helps to detect if actualy moved to new pos
+*/
+int fd_seek( int fd, off_t offset, int whence );
+off_t fd_pos( int fd );
+off_t fd_set_pos( int fd, off_t offset );
+off_t fd_size( int fd );
+/*
+READ from file
+FD - file descriptor
+BUF - where to write readed output
+COUNT - how much to read
+RETURN - size readed
+*/
+ssize_t fd_read( int fd, void *buf, size_t count );
+ssize_t fd_write( int fd, void *buf, size_t count );
+
+/*
+FILE RELATED UTILITIES
+*/
+
+/*
+CHECK IF YOU HAVE PERMISSIONS TO OPEN FILE
+MAYBE THIS IS FILE OF USER OR LOWER PERMISSION USER
+*/
+
+/*
+CHECK IF PATCH TO FILE EXCISTS
+*/
+
+/*
+GET PATH FILE TYPE
+COULD BE SOME DIRECTORY OR SOME LOOP FILE?
+*/
+
+/*
+GET DEFAULT PATHES THAT WILL IS NOT SUPPORTED
+/dev/radnom is not good to open
+/dev/ttyUSB also steaming files
+/dev/input/mice also is not good alt to open
+/proc/<pid>/mmap also is not alterntice to open
+search and check for more
+*/
+
+
+/*
+FILE OPERATION MANAGMENT STRUCTURE
+*/
+
+#define DEFAULT_BLK_SIZE 256
+
+typedef struct file_t
+{
+ const char *filename;
+ int fd; /* fd is fd */
+ int flags; /* file opening flags */
+ int mode; /* file opening mode */
+ off_t offset; /* last used offset */
+ long position; /* file cursor position */
+ off_t size; /* file size*/
+ unsigned int blk_size; /*default block size to operate with*/
+} file_t;
+
+file_t *file_init();
+int file_open_fn( file_t *ft, const char *filename, int mode );
+int file_open( file_t *ft, const char *filename, int flags, int mode );
+int file_read_blk( file_t *ft, uint8_t *buf );
+int file_read( file_t *ft, uint8_t *buf, size_t count );
+int file_write_blk( file_t *ft, uint8_t *buf );
+int file_write( file_t *ft, uint8_t *buf, size_t count );
+int file_seek( file_t *ft, off_t offset );
+int file_pos( file_t *ft );
+int file_size( file_t *ft );
+int file_s_mode( file_t *ft, int mode );
+int file_close( file_t *ft );
+
+#endif \ No newline at end of file
diff --git a/doc/DOC.txt b/doc/DOC.txt
new file mode 100644
index 0000000..ad5ae54
--- /dev/null
+++ b/doc/DOC.txt
@@ -0,0 +1,115 @@
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ IHE DOC VERSION 0.0.1 (EARLY ALFA)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ ihe - interactive hex editor multi purpose hex editor basicaly to edit files
+containes experimental features and not suppose to become mainstream.
+Philosophy of editor is to be minimal and simple without any depencecies on
+third party libraries. Not suppose to be mutli-OS multi-ARCH multi-PLATFORM.
+Not suppouse to be user-friendly but suppose to be file-freindly and
+old-school friendly.
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+COMMANDS SUPPORTED
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+-- version
+
+ Show current program version
+
+-- quit
+
+ Quit programm without freeing resources
+
+-- help
+
+ Print avaliable commands
+
+-- ?
+
+ Same as HELP
+
+-- open
+
+ open file
+
+ EXAMPLE:
+ >open test/test1
+
+-- close
+
+ close currently opened file
+
+ EXAMPLE:
+ >close
+
+-- info
+
+ show various info about programm resource usage
+
+-- seek
+
+ change file cursor position. dont do anything after changing file position.
+ minimal value 0 and maximal is file size value.
+
+ EXAMPLE:
+ move cursor to +1000 positions
+ >seek 1000
+
+ go back 10 positions
+ >seek -10
+
+-- pos
+
+ show current position of file cursor
+
+-- size
+
+ show opened file size
+
+-- blk
+
+ show currently used block size
+
+-- read
+
+ read from openede file. read from current cursor position reading block size.
+ block size could be checked with BLK command.
+
+-- dump
+
+ show currently readed data in buffer. just hex in one row.
+
+-- dumpx
+
+ show buffer data as hex values like hexdump stuff
+
+-- write
+
+ supports 1 argument. write hex values at currently opened file. at current
+ buffer and write that buffer back to file. maximal write amount is maximal
+ buffer size. file cursor position stays same.
+
+ EXAMPLE:
+ write 0x00 0x11 0x22 0x33 at current position at file
+ >write 00112233
+
+-- writes
+
+ write string to current file buffer and to current file position. Support
+ only one word to write.
+
+ EXAMPLE:
+ write "Hello" to file
+ >writes Hello
+
+
+-- flags
+
+ file opening flags. now is supported R/W/RW
+
+ EXAMPLE:
+ show currently supported flags
+ >flags ?
+ show current flag mask
+ >flags
+
diff --git a/ihe.c b/ihe.c
new file mode 100644
index 0000000..d838b5c
--- /dev/null
+++ b/ihe.c
@@ -0,0 +1,569 @@
+#include "ihe.h"
+#include "cmd.h"
+#include "core.h"
+
+static int cmd_loop = 1;
+extern cmd_table tab[];
+
+/*
+ GLOBAL VARIABLES
+ */
+static file_t *g_file = NULL;
+static buf_t *g_buf = NULL;
+static int g_flags = FD_RW;
+
+
+int c_version(cmd_arg *arg)
+{
+ int argc = arg->argc;
+
+ if ( argc != 0 )
+ {
+ printf("Command should not have arguments mister\n");
+ return -1;
+ }
+
+ printf("Version 0.0.1\n");
+
+ return 0;
+}
+
+
+int c_arg( cmd_arg *arg )
+{
+ int i;
+ int argc = arg->argc;
+ char **argv = arg->argv;
+
+ for (i=0;i<argc;i++)
+ {
+ printf("arg %d: val :%s\n", i, argv[i]);
+ }
+
+ return 0;
+}
+
+
+int c_quit( cmd_arg *arg )
+{
+ cmd_loop = 0;
+ return 0;
+}
+
+
+int c_help( cmd_arg *arg )
+{
+ int i = 0;
+ printf("Command list\n");
+ while ( tab[i].cmd != NULL )
+ {
+ printf("%s - \n", tab[i].cmd);
+ i++;
+ }
+ return 0;
+}
+
+
+/*
+OPEN <FILENAME>
+*/
+int c_open( cmd_arg *arg )
+{
+
+ int argc = arg->argc;
+ char **argv = arg->argv;
+ char *fname = NULL;
+ int fret = 0;
+
+ if ( argc != 1 )
+ {
+ printf("Neeed one argument\n");
+ return -1;
+ }
+
+ fname = argv[0];
+
+ fret = file_open_fn( g_file, fname, g_flags ); //!if failure fields could be non empty inside struct
+ if ( fret < 0 )
+ {
+ printf("Cannot open file %s\n",fname);
+ return -1;
+ }
+
+
+
+ return 0;
+}
+
+
+/*
+CLOSE
+*/
+int c_close( cmd_arg *arg )
+{
+ int fret = 0;
+
+ fret = file_close( g_file );
+ if ( fret != 0 )
+ {
+ printf("Cannot close file\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+FILE
+*/
+int c_info( cmd_arg *arg )
+{
+
+ if ( g_file == NULL )
+ {
+ printf("no opened files\n");
+ } else
+ {
+ printf("FILE INFO:\n");
+ printf("NAME : %s\n", g_file->filename );
+ printf("FD : %d\n", g_file->fd );
+ printf("FLAGS : 0x%08x\n", g_file->flags );
+ printf("MODE : 0x%08x\n", g_file->mode );
+ printf("OFFSET : %zd\n", g_file->offset );
+ printf("POSITION: %d\n", g_file->position );
+ printf("SIZE : %zd\n", g_file->size );
+ printf("BLOCK : %u\n", g_file->blk_size );
+ }
+
+ if ( g_buf == NULL )
+ {
+ printf("buffer not initialised\n");
+ } else
+ {
+ printf("BUF:\n");
+ printf("ADDR : %08x\n", g_buf->buf);
+ printf("SIZE : %d\n", g_buf->size);
+ printf("BUFSIZE: %d\n", g_buf->buf_size);
+ }
+
+ return 0;
+}
+
+
+int c_seek( cmd_arg *arg )
+{
+ int fret;
+ int argc = arg->argc;
+ char **argv = arg->argv;
+ off_t offset;
+
+ if (argc != 1)
+ {
+ printf("One argument needed\n");
+ return -1;
+ }
+
+ if (g_file->fd == 0)
+ {
+ printf("File descriptor not set\n");
+ return -1;
+ }
+
+ offset = atoi( argv[0] ); //!fix that to strtol at least
+ fret = file_seek( g_file, offset );
+ if ( fret != 0 )
+ {
+ printf("Cannot seek postion to %zd\n", offset);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int c_pos( cmd_arg *arg )
+{
+ int fret = 0;
+
+ fret = file_pos( g_file );
+ if ( fret < 0)
+ {
+ printf("Cannot get file position\n");
+ return -1;
+ }
+
+ printf("POS:%d\n",fret);
+
+ return 0;
+}
+
+
+int c_size( cmd_arg *arg )
+{
+ off_t size;
+
+ size = file_size( g_file );
+ if ( size < 0 )
+ {
+ printf("Cannot get file size\n");
+ return -1;
+ }
+
+ printf("File size %zu\n", size);
+
+ return 0;
+}
+
+
+int c_blk( cmd_arg *arg )
+{
+ printf("FILE BLOCK SIZE %u\n", g_file->blk_size );
+ printf("BUFFER BLOCK SIZE %d (MAX %d)\n", g_buf->size, g_buf->buf_size );
+
+ return 0;
+}
+
+
+int c_read( cmd_arg *arg )
+{
+ int ret;
+
+ if ( g_buf->buf == NULL )
+ {
+ printf("Buffer mem not allocated\n");
+ return -1;
+ }
+
+ ret = file_read_blk( g_file, g_buf->buf );
+ printf("Readed %d bytes\n", ret);
+ if ( (ret >= 0) && (ret <= g_buf->buf_size) )
+ {
+ g_buf->size = ret;
+ }
+
+ return 0;
+}
+
+
+int c_dump( cmd_arg *arg )
+{
+ int i;
+
+ if ( g_buf->buf == NULL)
+ {
+ printf("Buffer to print empty\n");
+ return -1;
+ }
+
+ for (i=0; i<g_buf->size; i++)
+ {
+ printf("%02x",(unsigned char)g_buf->buf[i]);
+ }
+ printf("\n");
+
+ return 0;
+}
+
+
+int c_dumpx( cmd_arg *arg )
+{
+ int i,j;
+
+ if ( g_buf->buf == NULL)
+ {
+ printf("Buffer to print empty\n");
+ return -1;
+ }
+
+ for (i=0; i<g_buf->size; i+=16)
+ {
+ for (j=i; j<i+16; j++)
+ {
+ if ( j<g_buf->size )
+ {
+ printf("%02x ",(unsigned char)g_buf->buf[j]);
+ } else
+ {
+ printf(" ");
+ }
+ }
+
+ for (j=i; j<i+16; j++)
+ {
+ if ( j<g_buf->size ) //wrong place move to cycle?
+ {
+ if ( isprint(g_buf->buf[j]) )
+ {
+ printf("%c",(unsigned char)g_buf->buf[j]);
+ } else
+ {
+ printf("\e[7m.\e[0m");
+ }
+ }
+ }
+ printf("\n");
+ }
+ printf("\n");
+
+ return 0;
+}
+
+
+//support masks
+int c_write( cmd_arg *arg )
+{
+ /*
+ anonymous function
+ */
+ uint8_t hex2u8( uint8_t *buf )
+ {
+ uint8_t ret = 0x00;
+ unsigned long int uli;
+ char str[3];
+ str[0] = buf[0];
+ str[1] = buf[1];
+ str[2] = 0;
+
+ uli = strtoul( str, NULL, 16 );
+
+ ret = uli;
+
+ return ret;
+ }
+
+ int argc = arg->argc;
+ char **argv = arg->argv;
+ int i;
+ uint8_t *buf = NULL;
+ int fret;
+
+ if ( argc != 1 )
+ {
+ printf("One argument needed\n");
+ return -1;
+ }
+
+ if ( (strlen(argv[0])%2) != 0 )
+ {
+ printf("Input string should be ( str mod 2 == 0) \n");
+ return -1;
+ }
+
+ for (i=0;i<strlen(argv[0]);i++)
+ {
+ if ( !isxdigit(argv[0][i]) )
+ {
+ printf("CH %c not hexlike at pos %d\n", argv[0][i], i);
+ return -1;
+ }
+ }
+
+ if (strlen(argv[0]) > g_buf->size*2)
+ {
+ printf("Input param bigger then buffer\n");
+ return -1;
+ }
+
+
+ for (i=0; i<strlen(argv[0]); i+=2)
+ {
+ printf("%02x ",hex2u8(&argv[0][i]));
+ }
+ printf("\n");
+
+
+ buf = malloc(strlen(argv[0])/2);
+ for (i=0; i<(strlen(argv[0])/2); i++)
+ {
+ buf[i] = hex2u8(&argv[0][i*2]);
+ }
+
+ memcpy( g_buf->buf, buf, strlen(argv[0])/2 );
+ fret = file_write_blk( g_file, g_buf->buf );
+ free( buf );
+
+ if ( fret < 0)
+ {
+ printf("Couldnt write block to file\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+//white spaces should be supported
+int c_writes( cmd_arg *arg )
+{
+ int argc = arg->argc;
+ char **argv = arg->argv;
+ int fret = 0;
+
+ if ( argc != 1)
+ {
+ printf("Need one argument mister\n");
+ return -1;
+ }
+
+ if (((g_buf == NULL) || (g_file == NULL)) || (g_buf->buf == NULL))
+ {
+ printf("Buffer or file not initialised");
+ return -1;
+ }
+
+ if ( strlen(argv[0]) <= g_buf->size )
+ {
+ memcpy( g_buf->buf, argv[0], strlen(argv[0]) );
+ fret = file_write_blk( g_file, g_buf->buf );
+ if ( fret < 0 )
+ {
+ printf("Couldnt write block to file\n");
+ return -1;
+ }
+ } else
+ {
+ printf("Input bigger then buffer buf %d input %d\n", g_buf->size, strlen(argv[0]));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int c_flags( cmd_arg *arg )
+{
+ int argc = arg->argc;
+ char **argv = arg->argv;
+
+ if ( argc == 0 )
+ {
+ printf("FLAGS: 0x%08x\n", g_flags );
+ return 0;
+ }
+
+ if ( argc > 1 )
+ {
+ printf("Only one argument needed\n");
+ return -1;
+ }
+
+ if ( strncmp(argv[0],"R",2) == 0 )
+ {
+ g_flags = FD_RO;
+ } else if ( strncmp(argv[0],"W",2) == 0 )
+ {
+ g_flags = FD_WO;
+ } else if ( strncmp(argv[0],"RW",3) == 0 )
+ {
+ g_flags = FD_RW;
+ } else
+ {
+ printf("Unknown mode. Suported R/W/RW\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int c_manifesto( cmd_arg *arg )
+{
+ printf("""\
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\
++ MANIFESTO +\n\
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\
++ 1. All hardware and software that you are owner of belongs to you no software+\n\
++ neither hardware patents can stop you to reverse engineer your property. +\n\
++ Software/Hardware that you are owning should be obtained in legal way +\n\
++ except situation under chapter 7 +\n\
++ 2. Any license or patent that disagree with that is unlawfull as it against +\n\
++ to personal freedomes. +\n\
++ 3. Any compiled or non compiled code on your device is your property. +\n\
++ 4. This software is made for any kind of knowledge gaining about software or +\n\
++ hardware that are belong to you. No commercial distribution of gained +\n\
++ knowledge should be made. Only free knowledge distribution allowed. +\n\
++ 5. This software should not be used to harm any living been this doesnt apply+\n\
++ to intelectual property of any kind. With this software personal info like+\n\
++ adresses, credit cards numbers, names, surnames, passwords should not be +\n\
++ gained as it may harm living beans that owns them and surands them. +\n\
++ 6. This software is made to explore system, gain understanding of system and +\n\
++ protect from system. +\n\
++ 7. This software may be used even if any patented or licensed +\n\
++ hardware/software is used in hardware or software that may treat human +\n\
++ life (rockets, warships, missles, army robots, electronics optical +\n\
++ devices, guns, SCADA malware and so on) physicaly doesnt belong to this +\n\
++ software user but treatening this software user life. +\n\
++ 8. By using this software you take all responsibity of result that may occure+\n\
++ while you use it on yourself. +\n\
++ 9. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+\n\
++ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +\n\
++ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +\n\
++ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+\n\
++ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +\n\
++ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +\n\
++ DEALINGS IN THE SOFTWARE. +\n\
++ 10. If you disagree with any point that mentioned here please stop using this+\n\
++ peace of software. +\n\
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\
+""");
+ return 0;
+}
+
+/*
+CMD COMMANDS
+*/
+cmd_table tab[] = {
+ {"version", c_version },
+ {"arg", c_arg },
+ {"quit", c_quit},
+ {"help", c_help},
+ {"?", c_help},
+ {"open", c_open},
+ {"close", c_close},
+ {"info", c_info},
+ {"seek", c_seek},
+ {"pos", c_pos},
+ {"size", c_size},
+ {"blk", c_blk},
+ {"read", c_read},
+ {"dump", c_dump},
+ {"dumpx", c_dumpx},
+ {"write", c_write},
+ {"writes", c_writes},
+ {"flags", c_flags},
+ {"manifesto", c_manifesto},
+ {NULL, NULL }
+};
+
+
+
+int main( int argc, char **argv )
+{
+ char *cmd = NULL;
+ cmd_arg *tok = NULL;
+
+ //preapre global stuff
+ g_file = file_init();
+
+ //init basic buffer
+ g_buf = buf_init();
+ buf_size( g_buf, DEFAULT_BLK_SIZE );
+
+ //read line from cmd
+ while( cmd_loop )
+ {
+ cmd = cmd_line(NULL);
+ //printf("cmd [%s]\n", cmd);
+ //printf("cnt %d\n",cnt_sep(cmd));
+
+ tok = cmd_parse( cmd );
+ free( cmd );
+
+ cmd_exec( tok, tab );
+
+ cmd_arg_free( tok );
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/ihe.h b/ihe.h
new file mode 100644
index 0000000..9589236
--- /dev/null
+++ b/ihe.h
@@ -0,0 +1,12 @@
+#ifndef __IHE_H
+#define __IHE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "buf.h"
+#include "cmd.h"
+#include "core.h"
+
+#endif \ No newline at end of file