summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZoRo <dos21h@gmail.com>2016-12-15 19:17:14 +0000
committerZoRo <dos21h@gmail.com>2016-12-15 19:17:14 +0000
commita588aa017512d3cc70dde6627d1218020e755259 (patch)
treea070cd171d18f3efbaedb7cfa0f9d54e2bb3b362
downloadagni-a588aa017512d3cc70dde6627d1218020e755259.tar.gz
agni-a588aa017512d3cc70dde6627d1218020e755259.zip
Initial commit
-rw-r--r--Makefile9
-rw-r--r--agni.c512
-rw-r--r--buf.c156
-rw-r--r--buf.h39
-rw-r--r--config_servers.h40
-rw-r--r--darray.c334
-rw-r--r--darray.h51
-rw-r--r--debug.h69
-rw-r--r--mmm.c26
-rw-r--r--mmm.h50
-rw-r--r--mmm_config.h18
-rw-r--r--mq_cmd.c192
-rw-r--r--mq_cmd.h29
13 files changed, 1525 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e0bf9ea
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+make:
+ gcc buf.c -c
+ gcc mmm.c -c
+ gcc darray.c -c
+ gcc mq_cmd.c -c
+ gcc mq_cmd.o buf.o mmm.o darray.o agni.c -o agni -std=c11 -lrt
+
+clean:
+ rm -f agni *.o \ No newline at end of file
diff --git a/agni.c b/agni.c
new file mode 100644
index 0000000..5705543
--- /dev/null
+++ b/agni.c
@@ -0,0 +1,512 @@
+#define _GNU_SOURCE
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/syscall.h>
+#include <sched.h>
+#include <stdatomic.h>
+
+#include <sys/stat.h>
+#include <sched.h>
+#include <mqueue.h>
+
+#include "config_servers.h"
+
+#include "darray.h"
+#include "buf.h"
+#include "mq_cmd.h"
+
+/*
+no defence programming, no error checking, no argument checking just PoC
+nothing else
+*/
+
+#define MQ_MSG_SIZE 8192
+
+/*
+return fd!=ifconnection there
+*/
+int irc_connect( char *hostname, char *port )
+{
+ int fd=0;
+
+ struct addrinfo serv, *res;
+
+ memset(&serv, 0, sizeof(serv));
+ serv.ai_family = AF_INET;
+ serv.ai_socktype = SOCK_STREAM;
+ getaddrinfo(hostname, port, &serv, &res);
+ fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ connect(fd, res->ai_addr, res->ai_addrlen);
+
+ return fd;
+}
+
+char *create_mq_cmd(char *out, size_t out_sz, int id, char *cmd, size_t cmd_sz, char *payload, size_t p_sz)
+{
+ char *ret = out;
+ int n,i;
+
+ n = snprintf(out, out_sz, ":%d:%s ", id, cmd);
+ if (n < 0)
+ {
+ return NULL;
+ }
+ for (i=0;i<p_sz,n<out_sz-1;i++,n++)
+ {
+ out[n] = payload[i];
+ }
+ out[n++]=0x0;
+ return ret;
+}
+
+/*
+supposed format agni-[id]-[in/out]
+in is for input of thread (send to in and thread will recieve),
+out if for output of thread (read from out to recieve from thread)
+*/
+#define MQ_PREFIX "/agni-"
+typedef struct mq_ntf_mdt
+{
+ int id;
+ mqd_t mq_in;
+ mqd_t mq_out;
+ //_Atomic int used; nado?
+} mq_ntf_mdt;
+
+/*
+return -1 on error
+*/
+int mq_ntf_open(mq_ntf_mdt *mq, int id)
+{
+ const int name_size = 32;
+ char name[name_size];
+
+ if (!mq)
+ {
+ return -1;
+ }
+ mq->id = id;
+ snprintf(name, name_size, MQ_PREFIX"%d-in",id);
+ /*create with default configs*/
+ mq->mq_in = mq_open(name,
+ O_RDWR | O_CREAT, 0666, NULL);
+ if (mq->mq_in == -1)
+ {
+ perror("mq_open");
+ return -1;
+ }
+ snprintf(name, name_size, MQ_PREFIX"%d-out",id);
+ /*create with default configs*/
+ mq->mq_out = mq_open(name,
+ O_RDWR | O_CREAT, 0666, NULL);
+ if (mq->mq_out == -1)
+ {
+ perror("mq_open");
+ return -1;
+ }
+ return 0;
+}
+
+
+/* return number if there is something to read */
+int mq_ntf_select(mq_ntf_mdt *mq)
+{
+
+ return 0;
+}
+
+
+/* read from input queue */
+int mq_ntf_read_in(mq_ntf_mdt *mq, char *buf, size_t size)
+{
+ struct mq_attr attr;
+ char *msg;
+ size_t bytes;
+ unsigned int prio = 10;
+ int fret;
+ fret = mq_getattr(mq->mq_in, &attr);
+ if (attr.mq_maxmsg == attr.mq_curmsgs)
+ {
+ printf("queue %d in full", mq->id);
+ return -1;
+ }
+ bytes = mq_receive(mq->mq_in, buf,
+ size > attr.mq_msgsize ? attr.mq_msgsize : size,
+ &prio);
+ if (bytes == -1)
+ {
+ perror("mq_receive read in");
+ return -1;
+ }
+ return 0;
+}
+
+/* read from output queue */
+int mq_ntf_read_out(mq_ntf_mdt *mq, char *buf, size_t size)
+{
+ struct mq_attr attr;
+ char *msg;
+ size_t bytes;
+ unsigned int prio = 10;
+ int fret;
+ fret = mq_getattr(mq->mq_out, &attr);
+ if (attr.mq_maxmsg == attr.mq_curmsgs)
+ {
+ printf("queue %d out full", mq->id);
+ return -1;
+ }
+ bytes = mq_receive(mq->mq_out, buf,
+ size > attr.mq_msgsize ? attr.mq_msgsize : size,
+ &prio);
+ if (bytes == -1)
+ {
+ perror("mq_receive read out");
+ return -1;
+ }
+ return 0;
+}
+
+
+/* write to output quque */
+int mq_ntf_write_out(mq_ntf_mdt *mq, const char *buf, size_t size)
+{
+ struct mq_attr attr;
+ char *msg;
+ size_t bytes;
+ unsigned int prio = 10;
+ int fret;
+ fret = mq_getattr(mq->mq_out, &attr);
+ if (attr.mq_maxmsg == attr.mq_curmsgs)
+ {
+ printf("queue %d out full", mq->id);
+ return -1;
+ }
+ bytes = mq_send(mq->mq_out, buf,
+ size > attr.mq_msgsize ? attr.mq_msgsize : size,
+ prio);
+ if (bytes == -1)
+ {
+ perror("mq_send");
+ return -1;
+ }
+ return 0;
+}
+
+/* write to input quque */
+int mq_ntf_write_in(mq_ntf_mdt *mq, const char *buf, size_t size)
+{
+ struct mq_attr attr;
+ char *msg;
+ size_t bytes;
+ unsigned int prio = 10;
+ int fret;
+ fret = mq_getattr(mq->mq_in, &attr);
+ if (attr.mq_maxmsg == attr.mq_curmsgs)
+ {
+ printf("queue %d in full", mq->id);
+ return -1;
+ }
+ bytes = mq_send(mq->mq_in, buf,
+ size > attr.mq_msgsize ? attr.mq_msgsize : size,
+ prio);
+ if (bytes == -1)
+ {
+ perror("mq_send");
+ return -1;
+ }
+ return 0;
+}
+
+/* drain all messages from quque */
+int mq_ntf_drain(mq_ntf_mdt *mq)
+{
+ int i,j;
+ struct mq_attr curattr;
+ char *buf;
+ ssize_t bytes;
+ int prio = 10;
+ mqd_t mqlist[2] = {mq->mq_in, mq->mq_out};
+
+ for (i=0;i<2;i++)
+ {
+ mq_getattr(mqlist[i], &curattr);
+ buf = malloc(curattr.mq_maxmsg);
+ for (j=0; j<curattr.mq_curmsgs; j++)
+ {
+ bytes = mq_receive(mqlist[i], buf, curattr.mq_maxmsg, &prio);
+ if (bytes == -1)
+ {
+ perror("mq_receive drain");
+ }
+ printf("Drain %d bytes\n", bytes);
+ }
+ free(buf);
+ }
+
+ return 0;
+}
+
+/* check if there is space in quque */
+int mq_ntf_full(mq_ntf_mdt *mq)
+{
+
+ return 0;
+}
+
+
+/* close queue */
+int mq_ntf_close(mq_ntf_mdt *mq)
+{
+ const int name_size = 32;
+ char name[name_size];
+ int id;
+
+ id = mq->id;
+ snprintf(name, name_size, MQ_PREFIX"%d-in",id);
+ mq_unlink(name);
+
+ snprintf(name, name_size, MQ_PREFIX"%d-out",id);
+ mq_unlink(name);
+
+ return 0;
+}
+
+//send command
+int mq_ntf_cmd_send(mq_ntf_mdt *mq, mq_cmd *cmd)
+{
+
+ return 0;
+}
+
+//recieve command from other end
+int mq_ntf_cmd_recv(mq_ntf_mdt *mq, mq_cmd *cmd)
+{
+ return 0;
+}
+
+/*
+
+|--------|<--IN---|---------|
+| SERVER | | MANAGER |
+|--------|--OUT-->|---------|
+
+*/
+#define STACK_SIZE (1024*16)
+/* not supposed to be changed. */
+typedef struct server_cfg
+{
+ /* thread params */
+ int tid;
+ void *stack;
+ //atomic_int running;
+ _Atomic int running;
+ mq_ntf_mdt *mq;
+ /* irc server config */
+ char *user;
+ char *password;
+ char *server;
+ char **channels;
+ int port;
+ int ssl;
+} server_cfg;
+
+
+/* server_cfg struct as input */
+#define TH_STATE_INIT 0
+#define TH_STATE_START 1
+#define TH_STATE_LISTEN_IN 2
+#define TH_STATE_LISTEN_OUT 3
+#define TH_STATE_SEND_IN 4
+#define TH_STATE_SEND_OUT 5
+#define TH_STATE_TERMINATION 6
+#define TH_STATE_EXIT 7
+
+int th_start_client(void *data)
+{
+
+ int cmd_id = 1;
+ int ret = 0;
+ char cmd_buf[MQ_MSG_SIZE];
+ mq_cmd *cmd=NULL;
+
+ server_cfg *cfg = data;
+ mq_ntf_mdt *mq = cfg->mq;
+ atomic_fetch_add(&cfg->running,1);
+ printf("Start client\n");
+ printf("Server %d\n",cfg->tid);
+ sleep(10);
+
+ //send command wait for response
+
+ cmd = CMD_CREATE(cmd_id,"PING","NOPARAM");
+ if (cmd != NULL)
+ {
+ if (ret = mq_ntf_write_out(mq,cmd->buf,cmd->sz) == -1)
+ {
+ printf("Couldnt send command\n");
+ }
+
+ }
+
+ cmd_id += 1;
+
+
+ printf("End client\n");
+ atomic_fetch_sub( &cfg->running,1);
+
+ return 0;
+}
+
+
+#define EVENT_HND_STACK_SIZE (16*1024)
+typedef struct event_handler_cfg {
+ /* thread params*/
+ void *stack;
+ mq_ntf_mdt *mq_listen;
+ int mq_num;
+ _Atomic int running;
+
+} event_handler_cfg;
+
+/* server_cfg struct as input */
+#define EH_STATE_INIT 0
+#define EH_STATE_START 1
+#define EH_STATE_LISTEN_IN 2
+#define EH_STATE_LISTEN_OUT 3
+#define EH_STATE_SEND_IN 4
+#define EH_STATE_SEND_OUT 5
+#define EH_STATE_TERMINATION 6
+#define EH_STATE_EXIT 7
+
+/* Thread to reacieve messages and return them back */
+int th_event_manager(void *data)
+{
+ int state;
+ int i;
+ event_handler_cfg *cfg = data;
+ atomic_fetch_add(&cfg->running,1);
+ const int buf_size=MQ_MSG_SIZE;
+ char buf[buf_size];
+ int ret;
+ //read any command
+ mq_cmd *cmd = NULL;
+
+
+
+ printf("Start event thread\n");
+ state = EH_STATE_INIT;
+ while (state != EH_STATE_EXIT)
+ switch (state)
+ {
+ case EH_STATE_INIT:
+ printf("TH STATE INIT\n");
+ sleep(1);
+ state = TH_STATE_START;
+ break;
+ case EH_STATE_START:
+ printf("TH STATE START\n");
+ sleep(1);
+ state = TH_STATE_EXIT;
+ break;
+ case EH_STATE_EXIT:
+ printf("TH STATE EXIT\n");
+ sleep(1);
+ state = TH_STATE_EXIT;
+ break;
+ default:
+ printf("Wrong state\n");
+ }
+ printf("End event thread\n");
+
+ atomic_fetch_sub( &cfg->running,1);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ int cnt_servers,cnt_running;
+ server_cfg *cfg_list;
+ event_handler_cfg *evhnd_cfg;
+ mq_ntf_mdt *mq_array;
+
+ /* Load configuration */
+ cnt_servers = SIZEOF_SERVER_LIST;
+ for (i=0;i<SIZEOF_SERVER_LIST;i++)
+ {
+ printf("Load config for server %s\n",server_list[i].server);
+ }
+
+ cfg_list = malloc(sizeof(server_cfg)*cnt_servers);
+ mq_array = malloc(sizeof(mq_ntf_mdt)*cnt_servers);
+
+ /* For each configuration create listener */
+
+ for (i=0;i<SIZEOF_SERVER_LIST;i++)
+ {
+ /*initialise server config*/
+ server_cfg *srvc = cfg_list+i;
+ irc_server_conf *isrvc = &server_list[i];
+ srvc->tid = i;
+ srvc->stack = malloc(STACK_SIZE); //NULL will brake everything ;)
+ srvc->user = isrvc->user;
+ srvc->password = isrvc->password;
+ srvc->server = isrvc->server;
+ srvc->channels = isrvc->channels;
+ srvc->port = isrvc->port;
+ srvc->ssl = isrvc->ssl;
+
+ //atomic_init( &srvc->running, 1);
+ atomic_store(&srvc->running, 0);
+
+ /* initalise posix mq */
+ if (0 != mq_ntf_open(&mq_array[i], i))
+ {
+ printf("Couldnt open mq_ntf_open\n");
+ }
+ srvc->mq = &mq_array[i];
+
+ /* clone new proc */
+ clone(th_start_client, srvc->stack+STACK_SIZE, CLONE_VM|CLONE_FILES, (void *)srvc);
+ }
+
+ /* event handler thread */
+ evhnd_cfg = malloc(sizeof(event_handler_cfg));
+ memset(evhnd_cfg, 0, sizeof(event_handler_cfg));
+ evhnd_cfg->stack = malloc(EVENT_HND_STACK_SIZE);
+ atomic_store(&evhnd_cfg->running, 0);
+ evhnd_cfg->mq_num = cnt_servers;
+ evhnd_cfg->mq_listen = mq_array;
+ clone(th_event_manager, evhnd_cfg->stack+EVENT_HND_STACK_SIZE, CLONE_VM|CLONE_FILES, (void *)evhnd_cfg);
+
+ /* run until all threads are up */
+ cnt_running = 1;
+ while(cnt_running != 0)
+ {
+ //printf("Count\n");
+ /*count how many proceses is running there*/
+ int val;
+ cnt_running = 0;
+ for (i=0;i<cnt_servers;i++)
+ {
+ val = atomic_load(&cfg_list[i].running);
+ if (val != 0)
+ cnt_running += 1;
+ }
+ printf("cnt_running %d\n",cnt_running);
+ sleep(1);
+ }
+
+ free(cfg_list);
+
+ return 0;
+} \ No newline at end of file
diff --git a/buf.c b/buf.c
new file mode 100644
index 0000000..ac7e83a
--- /dev/null
+++ b/buf.c
@@ -0,0 +1,156 @@
+#include "buf.h"
+
+
+bbuf* bbuf_new(int size)
+{
+ bbuf *ret = NULL;
+ ret = malloc(sizeof(bbuf));
+ if (!ret)
+ {
+ return NULL;
+ }
+ ret->buf = malloc(size);
+ if (!ret->buf)
+ {
+ free(ret);
+ return NULL;
+ }
+ ret->buf_size = size;
+ ret->size = 0;
+ return ret;
+}
+
+//set buffer value
+int bbuf_set(bbuf *a, char *val, int size)
+{
+ if (!a)
+ return -1;
+
+ if (!a->buf)
+ return -1;
+
+ if (size<0)
+ return -1;
+
+ if (size > a->buf_size)
+ {
+ a->size = a->buf_size;
+ } else
+ {
+ a->size = size;
+ }
+ memcpy(a->buf, val, a->size);
+
+ return a->size;
+}
+
+
+//get copy of buffer
+bbuf *bbuf_copy(bbuf *buf)
+{
+ bbuf *ret = NULL;
+
+ if (!buf)
+ {
+ return NULL;
+ }
+
+ ret = malloc(sizeof(bbuf));
+ memcpy(ret, buf, sizeof(bbuf));
+ ret->buf = malloc(buf->buf_size);
+ if (!ret->buf)
+ {
+ free(ret);
+ return NULL;
+ }
+ memcpy(ret->buf, buf->buf, buf->buf_size);
+ ret->size = buf->size;
+ ret->buf_size = buf->buf_size;
+
+ return ret;
+}
+
+
+//get buffer from buffer, mapped pointer, plz dont modify
+int bbuf_get(bbuf *buf, char **val, int *size)
+{
+ if (!buf)
+ {
+ return -1;
+ }
+
+ if (!val)
+ {
+ return -1;
+ }
+
+ *size = buf->size;
+ *val = buf->buf;
+
+ return 0;
+}
+
+
+//resize buffer
+int bbuf_realloc(bbuf *buf, int size)
+{
+ int ret = -1;
+ char *ptr=NULL;
+ if (!buf)
+ return -1;
+ if (size < 0)
+ return -1;
+ if (buf->buf_size == size)
+ return size;
+
+ ret = buf->buf_size;
+ ptr = realloc(buf->buf, size);
+ if (ptr != NULL)
+ {
+ buf->buf = ptr;
+ ret = size;
+ }
+
+ return ret;
+}
+
+
+//increase buffer for size
+int bbuf_inc(bbuf *a, char *b, int size)
+{
+ printf("Not implemented\n");
+ return -1;
+}
+
+
+//decrease buffer for size
+int bbuf_dec(bbuf *a, char *b, int size)
+{
+ printf("Not implemented\n");
+ return -1;
+}
+
+
+//free buffer
+void bbuf_free(bbuf *buf)
+{
+ if (buf == NULL)
+ {
+ return;
+ }
+ if (buf->buf != NULL)
+ {
+ memset(buf->buf, 0, buf->buf_size);
+ free(buf->buf);
+ buf->buf = NULL;
+ memset(buf, 0, sizeof(bbuf));
+ free(buf);
+ }
+}
+
+int bbuf_concat(bbuf *a, bbuf *b)
+{
+ printf("Not implemented\n");
+ return -1;
+}
+
diff --git a/buf.h b/buf.h
new file mode 100644
index 0000000..99872ef
--- /dev/null
+++ b/buf.h
@@ -0,0 +1,39 @@
+#ifndef __BUF_H
+#define __BUF_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+typedef struct bbuf {
+ int size;
+ int buf_size;
+ char *buf;
+} bbuf;
+
+//operations on plain buffers also operations on bufer to buffer should be
+//supoorted
+
+//create new buffer without content
+bbuf* bbuf_new(int size);
+
+//set buffer value
+int bbuf_set(bbuf *a, char *val, int size);
+//get copy of buffer
+bbuf *bbuf_copy(bbuf *buf);
+//get buffer from buffer
+int bbuf_get(bbuf *buf, char **val, int *size);
+//resize buffer
+int bbuf_realloc(bbuf *buf, int size);
+//increase buffer for size
+int bbuf_inc(bbuf *a, char *b, int size);
+//decrease buffer for size
+int bbuf_dec(bbuf *a, char *b, int size);
+//free buffer
+void bbuf_free(bbuf *buf);
+
+int bbuf_concat(bbuf *a, bbuf *b);
+
+void bbuf_free(bbuf *buf);
+
+#endif \ No newline at end of file
diff --git a/config_servers.h b/config_servers.h
new file mode 100644
index 0000000..3e4ee94
--- /dev/null
+++ b/config_servers.h
@@ -0,0 +1,40 @@
+#ifndef __CONFIG_SERVERS_H
+#define __CONFIG_SERVERS_H
+
+#include <stdint.h>
+
+
+
+typedef struct irc_server_conf
+{
+ char *user;
+ char *password;
+ char *server;
+ char **channels;
+ int port;
+ int ssl;
+} irc_server_conf;
+
+static irc_server_conf server_list[] =
+{
+ {
+ .user = "agni",
+ .password = NULL,
+ .server = "irc.freenode.net",
+ .channels = {"#mainlv",NULL},
+ .port = 6667,
+ .ssl = 0,
+ },
+ {
+ .user = "agni",
+ .password = NULL,
+ .server = "irc.hacking.allowed.org",
+ .channels = {"#default","#bot",NULL},
+ .port = 6697,
+ .ssl = 1,
+ }
+};
+
+#define SIZEOF_SERVER_LIST (sizeof(server_list)/sizeof(irc_server_conf))
+
+#endif \ No newline at end of file
diff --git a/darray.c b/darray.c
new file mode 100644
index 0000000..231bc5b
--- /dev/null
+++ b/darray.c
@@ -0,0 +1,334 @@
+#include "darray.h"
+
+/*****************************************************************************/
+darray* darr_create(ssize_t data_size, ssize_t init_size)
+{
+ //PRINT("\n");
+ int i = 0;
+ darray *arr = NULL;
+
+ if ( init_size <= 0 )
+ {
+ printf("initial darray size should be >0\n");
+ goto error;
+ }
+
+ arr = malloc(sizeof(darray));
+ if ( arr == NULL )
+ {
+ printf("cannot allocalte mem\n");
+ goto error;
+ }
+ arr->max = init_size;
+
+ arr->data = malloc(init_size*sizeof(uint8_t *));
+ if (arr->data == NULL)
+ {
+ printf("Cannot allocate mem for data\n");
+ goto error;
+ }
+
+ for (i=0;i<init_size;i++)
+ {
+ arr->data[i] = NULL;
+ }
+
+ arr->end = 0;
+ arr->size = data_size;
+ arr->expand = DEFAULT_EXPAND_RATE;
+
+ return arr;
+
+error:
+ if ( arr != NULL )
+ {
+ free( arr );
+ arr = NULL;
+ }
+ ERROR("\n");
+ return NULL;
+}
+
+
+/*****************************************************************************/
+void darr_destroy(darray *da)
+{
+ //PRINT("\n");
+ if(da)
+ {
+ if(da->data)
+ {
+ free(da->data);
+ }
+ free(da);
+ da = NULL;
+ }
+}
+
+
+/*****************************************************************************/
+void darr_clear(darray *da)
+{
+ //PRINT("\n");
+ int i = 0;
+ if(da->size > 0)
+ {
+ for(i = 0; i < da->max; i++)
+ {
+ if(da->data[i] != NULL)
+ {
+ free(da->data[i]);
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+void darr_clear_idx(darray *da, int idx)
+{
+ if ( idx > da->max )
+ {
+ return;
+ }
+ if (idx > da->end )
+ {
+ return;
+ }
+ if (da->data[idx] != NULL)
+ {
+ //PRINT("free=0x%08x\n", da->data[idx]);
+ free( da->data[idx] );
+ da->data[idx] = NULL;
+ }
+}
+
+/*****************************************************************************/
+int darr_expand(darray *da)
+{
+ //PRINT("\n");
+ size_t old_max = da->max;
+
+ if ( darr_resize(da, da->max + da->expand ) != 0 )
+ {
+ printf("Couldnt resize\n");
+ goto error;
+ }
+
+ memset(da->data + old_max, 0, da->expand + 1);
+ return 0;
+
+error:
+ ERROR("\n");
+ return -1;
+}
+
+
+/*****************************************************************************/
+int darr_resize(darray *da, ssize_t size)
+{
+ //PRINT("\n");
+ int i = 0;
+ void *data = NULL;
+
+ if (size < 1)
+ {
+ printf("new size smaller then 1\n");
+ goto error;
+ }
+
+ //PRINT("max-0x%08x=new-0x%08x\n",da->max, size);
+
+ if (size < da->max)
+ {
+ i = da->max;
+ do
+ {
+ if ( da->data[i-1] != NULL )
+ {
+ free(da->data[i-1]);
+ da->data[i-1] = NULL;
+ }
+ i -= 1;
+ } while ( i-1 == size );
+ }
+
+ da->max = size;
+
+
+
+
+ data = realloc(da->data, da->max * sizeof(void *));
+ // check contents and assume realloc doesn't harm the original on error
+
+ if ( data == NULL )
+ {
+ printf("Cannot relocate data\n");
+ goto error;
+ }
+
+ da->data = data;
+
+ return 0;
+error:
+ ERROR("\n");
+ return -1;
+}
+
+
+/*****************************************************************************/
+int darr_contract(darray *da)
+{
+ //PRINT("\n");
+ int sz = -1;
+
+ if ( da->end < da->expand )
+ {
+ sz = da->expand;
+ } else {
+ sz = da->end;
+ }
+
+ return darr_resize(da, sz + 1);
+}
+
+
+/*****************************************************************************/
+int darr_push(darray *da, void *val)
+{
+ //PRINT("\n");
+ if (da->data[da->end] != NULL)
+ {
+ ERROR("\n");
+ }
+
+ da->data[da->end] = val;
+ da->end++;
+
+ if(darr_end(da) >= darr_max(da))
+ {
+ return darr_expand(da);
+ }
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+void* darr_pop(darray *da)
+{
+ //PRINT("\n");
+ void *val = NULL;
+
+ if ( da->end-1 < 0 )
+ {
+ printf("Cannot pop value empty stack\n");
+ goto error;
+ }
+
+ val = darr_remove(da, da->end - 1);
+ da->end--;
+
+ if((darr_end(da) > (int)da->expand) &&
+ (darr_end(da) % da->expand))
+ {
+ darr_contract(da);
+ }
+
+ return val;
+
+error:
+ ERROR("\n");
+ return NULL;
+}
+
+
+/*****************************************************************************/
+void darr_clear_destroy(darray *da)
+{
+ //PRINT("\n");
+ darr_clear(da);
+ darr_destroy(da);
+}
+
+
+/*****************************************************************************/
+int darr_set(darray *da, int idx, void *val)
+{
+ //PRINT("\n");
+ if ( idx >= da->max )
+ {
+ printf("setting param out of range\n");
+ goto error;
+ }
+ if(idx > da->end)
+ {
+ da->end = idx;
+ }
+
+ //PRINT("idx=%d ptr=%x\n",idx,val);
+
+ da->data[idx] = val;
+ return 0;
+error:
+ ERROR("\n");
+ return -1;
+}
+
+
+/*****************************************************************************/
+void* darr_get(darray *da, int idx)
+{
+ //PRINT("\n");
+ if ( idx >= da->end )
+ {
+ printf("gettin value out of range\n");
+ goto error;
+ }
+ //PRINT("idx=%d\n",idx);
+ //PRINT("end=%d\n",da->end);
+ //PRINT("max=%d\n",da->max);
+ //PRINT("data=0x%x\n",da->data);
+ return da->data[idx];
+error:
+ ERROR("\n");
+ return NULL;
+}
+
+
+/*****************************************************************************/
+void* darr_remove(darray *da, int idx)
+{
+ //PRINT("\n");
+ void *val = NULL;
+ val = da->data[idx];
+ da->data[idx] = NULL;
+ return val;
+}
+
+
+/*****************************************************************************/
+void* darr_new(darray *da)
+{
+ //PRINT("\n");
+ if ( da->size < 1 )
+ {
+ printf("data element size <1\n");
+ goto error;
+ }
+
+ return calloc(1, da->size);
+
+error:
+ ERROR("\n");
+ return NULL;
+}
+
+/*****************************************************************************/
+int darr_isidx(darray *da, int idx)
+{
+ if ( idx < 0)
+ return 0;
+ if ( idx < da->end )
+ return 1;
+ return 0;
+}
diff --git a/darray.h b/darray.h
new file mode 100644
index 0000000..3cf7e16
--- /dev/null
+++ b/darray.h
@@ -0,0 +1,51 @@
+/* Some thx goes to http://c.learncodethehardway.org/book/ex34.html */
+#ifndef __LIBADT_DARRAY_H
+#define __LIBADT_DARRAY_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include "debug.h"
+#include "mmm.h"
+
+#define DEFAULT_EXPAND_RATE 10
+
+typedef struct darray {
+ int end; //element amount. end <= max
+ int max; //maximal element number
+ size_t size; //single element size
+ size_t expand; //expand size
+ void **data;
+} darray;
+
+darray* darr_create(ssize_t data_size, ssize_t init_size);
+void darr_destroy(darray *da);
+void darr_clear(darray *da);
+void darr_clear_idx(darray *da, int idx);
+int darr_expand(darray *da);
+int darr_resize(darray *da, ssize_t size);
+int darr_contract(darray *da);
+int darr_push(darray *da, void *val);
+void* darr_pop(darray *da);
+void darr_clear_destroy(darray *da);
+int darr_set(darray *da, int idx, void *val);
+void* darr_get(darray *da, int idx);
+void* darr_remove(darray *da, int idx);
+void* darr_new(darray *da);
+int darr_isidx(darray *da, int idx);
+
+#define darr_last(A) ((A)->data[(A)->end - 1])
+#define darr_first(A) ((A)->data[0])
+#define darr_end(A) ((A)->end)
+#define darr_count(A) darr_end(A)
+#define darr_max(A) ((A)->max)
+#define darr_free(E) free((E))
+
+/*
+when do set it just overwrite data without checking if there is some or not
+if set more then max then no error and no resize happens
+when get element if error then NULL if value NULL then NULL how distinguish
+*/
+
+#endif
diff --git a/debug.h b/debug.h
new file mode 100644
index 0000000..a8bf211
--- /dev/null
+++ b/debug.h
@@ -0,0 +1,69 @@
+#ifndef __RB_DEBUG_UTILS_H
+#define __RB_DEBUG_UTILS_H
+
+//what about kprintf?
+
+//config options
+#define PRINTF printf
+#define COLORIZE
+#define PRINT_LINENUM
+#define PRINT_FILENAME
+#define PRINT_DEBUG
+
+
+//use color
+#ifdef COLORIZE
+ #define D_COLOR "1;32m"
+ #define D_COLOR_S "\033[" D_COLOR
+ #define D_COLOR_E "\033[0m"
+ #define E_COLOR "1;31m"
+ #define E_COLOR_S "\033[" E_COLOR
+ #define E_COLOR_E "\033[0m"
+#else
+ #define D_COLOR
+ #define D_COLOR_S
+ #define D_COLOR_E
+ #define E_COLOR
+ #define E_COLOR_S
+ #define E_COLOR_E
+#endif
+
+//print debug line
+#ifdef PRINT_LINENUM
+ #define PRINT_LINE_F "LINE:%d "
+ #define PRINT_LINE_D __LINE__
+#else
+ #define PRINT_LINE_F ""
+ #define PRINT_LINE_D ""
+#endif
+
+//print
+#ifdef PRINT_FILENAME
+ #define PRINT_FILE_F "FILE:%s "
+ #define PRINT_FILE_D __FILE__
+#else
+ #define PRINT_FILE_F ""
+ #define PRINT_FILE_D ""
+#endif
+
+//print debug string
+#ifdef PRINT_DEBUG
+ #define PRINT_DEBUG_F "Debug: "
+#else
+ #define PRINT_DEBUG_F ""
+#endif
+
+#define PRINT( format, args ... ) PRINTF( D_COLOR_S PRINT_DEBUG_F \
+ PRINT_FILE_F PRINT_LINE_F format D_COLOR_E, PRINT_FILE_D, \
+ PRINT_LINE_D, ##args);
+
+#define ERROR( format, args ... ) PRINTF( E_COLOR_S PRINT_DEBUG_F \
+ PRINT_FILE_F PRINT_LINE_F format E_COLOR_E, PRINT_FILE_D, \
+ PRINT_LINE_D, ##args);
+
+#define PNL() PRINT("\n");
+
+#define ENL() ERROR("\n");
+
+
+#endif
diff --git a/mmm.c b/mmm.c
new file mode 100644
index 0000000..4dc9a04
--- /dev/null
+++ b/mmm.c
@@ -0,0 +1,26 @@
+#include "mmm.h"
+
+#ifdef MMM_PLAIN
+#endif
+
+#ifdef MMM_RECORD
+
+
+void* mmm_malloc(size_t size, const char *fname, int line )
+{
+ void *ret=NULL;
+ ret = malloc( size );
+ printf("alloc,0x%8p,%zu,%s,%d\n",(void *)ret,size,fname,line);
+ return ret;
+}
+
+
+void mmm_free( void *ptr, const char *fname, int line )
+{
+ printf("free,0x%8p,%s,%d\n",(void *)ptr,fname,line);
+ free( ptr );
+}
+
+#endif
+
+
diff --git a/mmm.h b/mmm.h
new file mode 100644
index 0000000..4b1c368
--- /dev/null
+++ b/mmm.h
@@ -0,0 +1,50 @@
+#ifndef __LIBMM_MMM_H
+#define __LIBMM_MMM_H
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <dlfcn.h>
+
+#include "mmm_config.h"
+
+//----------------------------------------------------------------------
+#ifdef MMM_PLAIN
+
+#define MALLOC(SIZE) malloc(SIZE);
+#define FREE(PTR) free(PTR);
+#define CALLOC(NMEMB,SIZE) calloc(NMEMB, SIZE);
+#define REALLOC(PTR,SIZE) realloc(PTR,SIZE);
+
+#endif
+
+//----------------------------------------------------------------------
+#ifdef MMM_PLAIN_SAFE
+
+#define MALLOC(SIZE) malloc(SIZE);
+#define FREE(PTR) if (PTR!=NULL){free(PTR);PTR=NULL;};
+#define CALLOC(NMEMB,SIZE) calloc(NMEMB, SIZE);
+#define REALLOC(PTR,SIZE) realloc(PTR,SIZE);
+
+#endif
+
+//----------------------------------------------------------------------
+#ifdef MMM_RECORD
+
+#define MALLOC(SIZE) mmm_malloc(SIZE,__FILE__,__LINE__);
+#define FREE(PTR) mmm_free((PTR),__FILE__,__LINE__);
+#define CALLOC(NMEMB,SIZE) calloc(NMEMB,SIZE);
+#define REALLOC(PTR,SIZE) realloc(PTR,SIZE);
+
+void* mmm_malloc(size_t, const char *, int );
+void mmm_free( void *, const char *, int );
+
+#endif
+
+
+
+
+#endif
diff --git a/mmm_config.h b/mmm_config.h
new file mode 100644
index 0000000..cca4f6a
--- /dev/null
+++ b/mmm_config.h
@@ -0,0 +1,18 @@
+#ifndef __LIBMMM_CONFIG_H
+#define __LIBMMM_CONFIG_H
+
+//---------------------------------------------------------------------
+//ONLY ONE OF OPTION CAN BE USED
+
+//noting is done with memory. only plain wrappers is usded.
+#define MMM_PLAIN
+
+//cleans free after free if free is not NULL
+//#define MMM_PLAIN_SAFE
+
+//show in terminal some data about used malocc and free
+//#define MMM_RECORD
+//---------------------------------------------------------------------
+
+
+#endif
diff --git a/mq_cmd.c b/mq_cmd.c
new file mode 100644
index 0000000..7f1887a
--- /dev/null
+++ b/mq_cmd.c
@@ -0,0 +1,192 @@
+#include "mq_cmd.h"
+
+#define MQ_CMD_MSG_SIZE 8192
+//last string element should be string ;]
+mq_cmd* mq_cmd_create(int id, char *cmd, size_t cmd_sz, char *param, size_t param_sz)
+{
+ mq_cmd *ret = NULL;
+
+ if (cmd == NULL)
+ return NULL;
+ if (param == NULL)
+ return NULL;
+
+ ret = malloc(sizeof(mq_cmd));
+ if (ret == NULL)
+ return NULL;
+
+ ret->id = id;
+ ret->sz = MQ_CMD_MSG_SIZE;
+ ret->buf = malloc(ret->sz);
+ if (!ret->buf)
+ {
+ free(ret);
+ return NULL;
+ }
+ //if not null string that everything will blow up pal
+ //cmd[cmd_sz-1] = 0x0;
+ //param[param_sz-1] = 0x0;
+ snprintf(ret->buf,ret->sz-1,":%d:%s: %s", id, cmd, param);
+
+ return ret;
+}
+
+int mq_cmd_id(mq_cmd *cmd, int *id)
+{
+ int i,j,strt,sz;
+ int ret=-1;
+ int id_parse;
+ char buf[16]; //fix this
+ /*:[ID]:*/
+
+ if (cmd == NULL)
+ return -1;
+ if (id == NULL)
+ return -1;
+
+ i = 0;
+ while ((cmd->buf[i] != 0) && (i<cmd->sz))
+ {
+ if (cmd->buf[i] == ':')
+ {
+ i++;
+ strt = i;
+ sz = 0;
+ while ((cmd->buf[i] != ':')&&
+ (cmd->buf[i] != '\0')&&
+ (i<cmd->sz))
+ {
+ sz++;
+ i++;
+ }
+ for (j=0;j<(strt+sz)||j<15;j++)
+ {
+ buf[j] = cmd->buf[strt+j];
+ }
+ buf[j] = 0x0;
+ id_parse = atoi(buf);
+ *id = id_parse;
+ return 0;
+ }
+ i++;
+ }
+ return -1;
+}
+
+//buf contains pointer to cmd
+//sz contains size of buf
+//%s formatting should work badly, writting to buf modifies cmd
+//be carefull
+char* mq_cmd_cmd(mq_cmd *cmd, char **buf, size_t *sz)
+{
+ size_t sz_parse;
+ int i,j,strt,cnt,l_c;
+ char *p;
+
+ if (cmd == NULL)
+ return NULL;
+ if (buf == NULL)
+ return NULL;
+ if (sz == NULL)
+ return NULL;
+
+ p = cmd->buf;
+
+ i = 0;
+ l_c = 0;
+ while ((cmd->buf[i] != 0)&&(i<cmd->sz))
+ {
+ if (cmd->buf[i] == ':')
+ {
+ l_c += 1;
+ if (l_c == 2)
+ {
+ i++;
+ break;
+
+ }
+ }
+ i++;
+ }
+ strt = i;
+ cnt = 0;
+ while ((cmd->buf[i] != 0)&&(i<cmd->sz))
+ {
+
+ if (cmd->buf[i] == ':')
+ break;
+ cnt++;
+ i++;
+ }
+ *buf = cmd->buf+strt;
+ *sz = cnt;
+
+ return 0;
+}
+
+int mq_cmd_param(mq_cmd *cmd, char **param, size_t *sz)
+{
+ size_t sz_parse;
+ int i,j,strt,cnt,l_c;
+ char *p;
+
+ p = cmd->buf;
+
+ i = 0;
+ l_c = 0;
+ while ((cmd->buf[i] != 0)&&(i<cmd->sz))
+ {
+ if (cmd->buf[i] == ':')
+ {
+ l_c += 1;
+ if (l_c == 3)
+ {
+ i++;
+ break;
+ }
+ }
+ i++;
+ }
+
+ while ((cmd->buf[i] != 0)&&(i<cmd->sz))
+ {
+ if (cmd->buf[i] != ' ') break;
+ i++;
+ }
+ strt = i;
+ *param = cmd->buf+strt;
+ *sz = cmd->sz - strt+1;
+
+ return 0;
+}
+
+size_t mq_cmd_size(mq_cmd *cmd)
+{
+ if (cmd == NULL)
+ {
+ return -1;
+ }
+ return cmd->sz;
+}
+
+char *mq_cmd_buf(mq_cmd *cmd)
+{
+ if (cmd == NULL)
+ {
+ return NULL;
+ }
+
+ return cmd->buf;
+}
+
+void mq_cmd_free(mq_cmd *mq)
+{
+ if (mq != NULL)
+ {
+ free(mq->buf);
+ mq->buf = NULL;
+ free(mq);
+ }
+
+}
+
diff --git a/mq_cmd.h b/mq_cmd.h
new file mode 100644
index 0000000..ef255d9
--- /dev/null
+++ b/mq_cmd.h
@@ -0,0 +1,29 @@
+#ifndef __AGNI_MQ_CMD_H
+#define __AGNI_MQ_CMD_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+typedef struct mq_cmd
+{
+ int id;
+ char *buf;
+ size_t sz;
+} mq_cmd;
+
+mq_cmd* mq_cmd_create(int id, char *cmd, size_t cmd_sz, char *param, size_t param_sz);
+int mq_cmd_id(mq_cmd *cmd, int *id);
+char* mq_cmd_cmd(mq_cmd *cmd, char **buf, size_t *sz);
+int mq_cmd_param(mq_cmd *cmd, char **param, size_t *sz);
+size_t mq_cmd_size(mq_cmd *cmd);
+char *mq_cmd_buf(mq_cmd *cmd);
+void mq_cmd_free(mq_cmd *mq);
+
+
+
+#define CMD_CREATE(ID,CMD,PARAM) mq_cmd_create(ID,CMD,strlen(CMD),PARAM,strlen(PARAM));
+#define CMD_FREE(CMD_T) mq_cmd_free(CMD_T);
+
+
+#endif \ No newline at end of file