Diff for /libaitio/inc/aitio.h between versions 1.24 and 1.40

version 1.24, 2012/08/02 00:47:46 version 1.40, 2014/02/08 22:06:16
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012Copyright 2004 - 2014
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 59  SUCH DAMAGE. Line 59  SUCH DAMAGE.
 #include <sys/un.h>  #include <sys/un.h>
 #include <sys/uio.h>  #include <sys/uio.h>
 #include <net/if_dl.h>  #include <net/if_dl.h>
   #include <net/bpf.h>
 #include <netinet/in.h>  #include <netinet/in.h>
#include <atree.h>#include <elwix.h>
#include <ampool.h>#include <aitsched.h>
   
   
 #ifndef STRSIZ  #ifndef STRSIZ
#define STRSIZ          256#define STRSIZ                  256
 #endif  #endif
   
#ifndef be16toh#define IO_SOCK_ROLE_CLIENT     0
#define be16toh         betoh16#define IO_SOCK_ROLE_SERVER     1
#endif 
#ifndef be32toh 
#define be32toh         betoh32 
#endif 
#ifndef be64toh 
#define be64toh         betoh64 
#endif 
#ifndef le16toh 
#define le16toh         letoh16 
#endif 
#ifndef le32toh 
#define le32toh         letoh32 
#endif 
#ifndef le64toh 
#define le64toh         letoh64 
#endif 
   
#define IO_SYSM            0#define IO_ETHER_FILTER_PROMISC        0
#define IO_MPOOL   1#define IO_ETHER_FILTER_NOTREAD    -1
 #define IO_ETHER_FILTER_READ    1
 #define IO_ETHER_FILTER_WRITE   2
   
 #define VACUUM_LEFT     1  
 #define VACUUM_BETWEEN  2  
   
 /* AIT arrays */  
   
 typedef void ** sarr_seg_t;  
 typedef struct _tagSplitArray {  
         int             sarr_num;  
         int             sarr_seg;  
         int             sarr_siz;  
         sarr_seg_t      *sarr_data;  
 } sarr_t;  
   
 typedef struct _tagArray {  
         int     arr_last;  
         int     arr_num;  
         void    **arr_data;  
 } array_t;  
   
 /* AIT RPC variables and managment */  
   
 typedef enum {  
         empty, ptr, data,               /* empty -> variable is not set; ptr -> void*; data -> data after struct  */  
         buffer, string, blob,           /* buffer -> uint8_t*; string -> int8_t*; blob -> uint32_t blobID(+socket); */  
         f32, f64,                       /* float -> f32; double -> f64 */  
         u8, u16, u32, u64,              /* unsigned integers ... */  
         i8, i16, i32, i64,              /* integers ... */  
 } ait_type_t;  
   
 typedef struct {  typedef struct {
        uint8_t         val_type;        unsigned int                    prog_inin;      /* init progs */
        union {        unsigned int                    prog_maxn;      /* max progs */
                struct {        unsigned int                    prog_cnum;      /* current progs */
                        uint8_t val_in:1;        char                            prog_name[PATH_MAX];
                        uint8_t val_be:1; 
                        uint8_t val_le:1; 
                        uint8_t val_pad:5; 
                }; 
                uint8_t         val_opt; 
        }; 
        uint16_t        val_key; 
        uint32_t        val_len; 
        union { 
                uint64_t        net; 
   
                void            *ptr;        pthread_mutex_t                      prog_mtx;
                uint8_t              *buffer;        array_t                              *prog_fds;
                int8_t              *string;        unsigned int                    *prog_used;
                uint32_t        blob;} prog_t;
                float           f32; 
                double          f64; 
                uint8_t         u8; 
                uint16_t        u16; 
                uint32_t        u32; 
                uint64_t        u64; 
                int8_t          i8; 
                int16_t         i16; 
                int32_t         i32; 
                int64_t         i64; 
        } val; 
        uint8_t         val_data[0]; 
} __packed ait_val_t;   /* sizeof 16 bytes */ 
   
#define AIT_TYPE(_vl)                   ((ait_type_t) (_vl)->val_type)typedef struct tagCliSock sock_cli_t;
#define AIT_LEN(_vl)                    (_vl)->val_lentypedef void *(*sock_cb_t)(sock_cli_t*);
#define AIT_KEY(_vl)                    (_vl)->val_keystruct tagCliSock {
#define AIT_RAW(_vl)                    (_vl)->val.net        void                            *cli_parent;
#define AIT_ADDR(_vl)                   (_vl)->val.ptr        int                             cli_fd;
#define AIT_IN(_vl)                     (_vl)->val_in        intptr_t                        cli_pty;
#define AIT_BE(_vl)                     (_vl)->val_be        sockaddr_t                      cli_addr;
#define AIT_LE(_vl)                     (_vl)->val_le        char                            cli_name[64];
#define AIT_BLOB_CHUNKS(_vl, _n)        (AIT_LEN((_vl)) / _n + (AIT_LEN((_vl)) % _n) ? 1 : 0)        char                            cli_cmdline[PATH_MAX];
#define AIT_ISEMPTY(_vl)                (AIT_TYPE((_vl)) == empty)        pid_t                           cli_pid;
   
#define AIT_GET_LIKE(_vl, _type)        ((_type) AIT_ADDR((_vl)))        sched_task_func_t               cli_func;
   
#define AIT_GET_PTR(_vl)                (assert(AIT_TYPE((_vl)) == ptr), (_vl)->val.ptr)        ait_val_t                       cli_buf[2];
#define AIT_GET_DATA(_vl)               (assert(AIT_TYPE((_vl)) == data), (_vl)->val_data) 
#define AIT_GET_BUF(_vl)                (assert(AIT_TYPE((_vl)) == buffer), (_vl)->val.buffer) 
#define AIT_GET_STR(_vl)                (assert(AIT_TYPE((_vl)) == string), (char*) (_vl)->val.string) 
#define AIT_GET_BLOB(_vl)               (assert(AIT_TYPE((_vl)) == blob), (_vl)->val.blob) 
#define AIT_GET_U8(_vl)                 (assert(AIT_TYPE((_vl)) == u8), (_vl)->val.u8) 
#define AIT_GET_U16(_vl)                (assert(AIT_TYPE((_vl)) == u16), (_vl)->val.u16) 
#define AIT_GET_U32(_vl)                (assert(AIT_TYPE((_vl)) == u32), (_vl)->val.u32) 
#define AIT_GET_U64(_vl)                (assert(AIT_TYPE((_vl)) == u64), (_vl)->val.u64) 
#define AIT_GET_I8(_vl)                 (assert(AIT_TYPE((_vl)) == i8), (_vl)->val.i8) 
#define AIT_GET_I16(_vl)                (assert(AIT_TYPE((_vl)) == i16), (_vl)->val.i16) 
#define AIT_GET_I32(_vl)                (assert(AIT_TYPE((_vl)) == i32), (_vl)->val.i32) 
#define AIT_GET_I64(_vl)                (assert(AIT_TYPE((_vl)) == i64), (_vl)->val.i64) 
#define AIT_GET_F32(_vl)                (assert(AIT_TYPE((_vl)) == f32), (_vl)->val.f32) 
#define AIT_GET_F64(_vl)                (assert(AIT_TYPE((_vl)) == f64), (_vl)->val.f64) 
   
#define AIT_SET_DATA(_vl, _p, _len)     do { ait_val_t *__val = io_realloc((_vl), (sizeof(ait_val_t) + _len)); \        TAILQ_ENTRY(tagCliSock)         cli_node;
                                                if (__val) { \ 
                                                        void *__p = (_p); \ 
                                                        if (__p) \ 
                                                                memcpy(__val->val_data, __p, _len); \ 
                                                        __val->val_type = data; AIT_LEN(__val) = _len; \ 
                                                        (_vl) = __val; \ 
                                                } \ 
                                        } while (0); 
#define AIT_SET_PTR(_vl, _p, _len)      do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = ptr; __val->val.ptr = _p; \ 
                                                AIT_LEN(__val) = _len; } while (0) 
#define AIT_RE_BUF(_vl, _len)           do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                void *__ptr = io_realloc(AIT_GET_BUF(__val), _len); \ 
                                                if (__ptr) { \ 
                                                        __val->val.buffer = __ptr; AIT_LEN(__val) = _len; \ 
                                                } } while (0) 
#define AIT_SET_BUF2(_vl, _c, _len)     do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val.buffer = io_malloc(_len); \ 
                                                if (__val->val.buffer) { \ 
                                                        __val->val_type = buffer; AIT_LEN(__val) = _len; \ 
                                                        memset(__val->val.buffer, _c, _len); \ 
                                                } } while (0) 
#define AIT_SET_BUF(_vl, _v, _len)      do { ait_val_t *__val = (_vl); void *__p = (_v); assert(__val); \ 
                                                __val->val.buffer = io_malloc(_len); \ 
                                                if (__val->val.buffer) { \ 
                                                        __val->val_type = buffer; AIT_LEN(__val) = _len; \ 
                                                        if (__p) \ 
                                                                memcpy(__val->val.buffer, __p, _len); \ 
                                                        else \ 
                                                                memset(__val->val.buffer, 0, _len); \ 
                                                } } while (0) 
#define AIT_SET_STR(_vl, _v)            do { ait_val_t *__val = (_vl); const char *__s = (_v); assert(__val); \ 
                                                __val->val_type = string; \ 
                                                if (__s && *__s) { \ 
                                                        __val->val.string = (int8_t*) io_strdup(__s); \ 
                                                        AIT_LEN(__val) = strlen((const char*) \ 
                                                                        __val->val.string) + 1; \ 
                                                } else { \ 
                                                        __val->val.string = NULL; \ 
                                                        AIT_LEN(__val) = 0; \ 
                                                } \ 
                                        } while (0) 
#define AIT_SET_STRSIZ(_vl, _len)       do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val.string = (int8_t*) io_malloc(_len); \ 
                                                if (__val->val.string) { \ 
                                                        __val->val_type = string; AIT_LEN(__val) = _len; \ 
                                                        memset(__val->val.string, 0, _len); \ 
                                                } \ 
                                        } while (0) 
#define AIT_SET_STRCAT(_vl, _v)         do { ait_val_t *__val = (_vl); const char *__s = (_v); int __l; \ 
                                                assert(__val); assert(AIT_TYPE(__val) == string); \ 
                                                if (!__s || !*__s) \ 
                                                        break; \ 
                                                else \ 
                                                        __l = strlen(__s); \ 
                                                if (!__val->val.string) \ 
                                                        __l++; \ 
                                                void *__p = io_realloc(__val->val.string, AIT_LEN(__val) + __l); \ 
                                                if (__p) { \ 
                                                        AIT_LEN(__val) += __l; \ 
                                                        __val->val.string = __p; \ 
                                                        strlcat((char*) __val->val.string, __s, \ 
                                                                        AIT_LEN(__val)); \ 
                                                } \ 
                                        } while (0) 
#define AIT_SET_STRCPY(_vl, _v)         do { ait_val_t *__val = (_vl); const char *__s = (_v); int __l; \ 
                                                assert(__val); assert(AIT_TYPE(__val) == string); \ 
                                                if (!__s || !*__s) \ 
                                                        break; \ 
                                                else \ 
                                                        __l = strlen(__s) + 1; \ 
                                                void *__p = io_realloc(__val->val.string, __l); \ 
                                                if (__p) { \ 
                                                        AIT_LEN(__val) = __l; \ 
                                                        __val->val.string = __p; \ 
                                                        strlcpy((char*) __val->val.string, __s, \ 
                                                                        AIT_LEN(__val)); \ 
                                                } } while (0) 
#define AIT_SET_STRLCPY(_vl, _v, _len)  do { ait_val_t *__val = (_vl); const char *__s = (_v); \ 
                                                assert(__val); assert(AIT_TYPE(__val) == string); \ 
                                                if (!__s || !*__s) \ 
                                                        break; \ 
                                                void *__p = io_realloc(__val->val.string, _len); \ 
                                                if (__p) { \ 
                                                        AIT_LEN(__val) = _len; \ 
                                                        __val->val.string = __p; \ 
                                                        strlcpy((char*) __val->val.string, __s, \ 
                                                                        AIT_LEN(__val)); \ 
                                                } } while (0) 
#define AIT_SET_BLOB(_vl, _n, _len)     do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = blob; __val->val.blob = _n; \ 
                                                AIT_LEN(__val) = _len; } while (0) 
#define AIT_SET_BLOB2(_vl, _bv)         do { ait_val_t *__val = (_vl); assert(__val); assert((_bv)); \ 
                                                __val->val_type = blob; AIT_LEN(__val) = \ 
                                                        (_bv)->blob_len; \ 
                                                __val->val.blob = (_bv)->blob_var; } while (0) 
#define AIT_NEW_BLOB(_vl, _len)         AIT_SET_BLOB((_vl), 0, _len) 
 
#define AIT_SET_U8(_vl, _n)             do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = u8; __val->val.u8 = _n; \ 
                                                AIT_LEN(__val) = sizeof(uint8_t); } while (0) 
#define AIT_SET_U16(_vl, _n)            do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = u16; __val->val.u16 = _n; \ 
                                                AIT_LEN(__val) = sizeof(uint16_t); } while (0) 
#define AIT_SET_U32(_vl, _n)            do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = u32; __val->val.u32 = _n; \ 
                                                AIT_LEN(__val) = sizeof(uint32_t); } while (0) 
#define AIT_SET_U64(_vl, _n)            do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = u64; __val->val.u64 = _n; \ 
                                                AIT_LEN(__val) = sizeof(uint64_t); } while (0) 
#define AIT_SET_I8(_vl, _n)             do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = i8; __val->val.i8 = _n; \ 
                                                AIT_LEN(__val) = sizeof(int8_t); } while (0) 
#define AIT_SET_I16(_vl, _n)            do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = i16; __val->val.i16 = _n; \ 
                                                AIT_LEN(__val) = sizeof(int16_t); } while (0) 
#define AIT_SET_I32(_vl, _n)            do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = i32; __val->val.i32 = _n; \ 
                                                AIT_LEN(__val) = sizeof(int32_t); } while (0) 
#define AIT_SET_I64(_vl, _n)            do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = i64; __val->val.i64 = _n; \ 
                                                AIT_LEN(__val) = sizeof(int64_t); } while (0) 
#define AIT_SET_F32(_vl, _n)            do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = f32; __val->val.f32 = _n; \ 
                                                AIT_LEN(__val) = sizeof(float); } while (0) 
#define AIT_SET_F64(_vl, _n)            do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                __val->val_type = f64; __val->val.f64 = _n; \ 
                                                AIT_LEN(__val) = sizeof(double); } while (0) 
 
#define AIT_COPY_VAL(_vl, _v)           do { assert((_vl)); assert((_v)); \ 
                                                memcpy((_vl), (_v), sizeof(ait_val_t)); \ 
                                                switch (AIT_TYPE((_vl))) { \ 
                                                        case buffer: \ 
                                                                AIT_SET_BUF((_vl), \ 
                                                                                AIT_GET_BUF((_v)), \ 
                                                                                AIT_LEN((_v))); \ 
                                                                break; \ 
                                                        case string: \ 
                                                                AIT_SET_STR((_vl), \ 
                                                                                AIT_GET_STR((_v))); \ 
                                                                break; \ 
                                                        default: \ 
                                                                break; \ 
                                                } \ 
                                        } while (0) 
#define AIT_COPY_DATA(_vl, _v)          do { AIT_COPY_VAL((_vl), (_v)); \ 
                                                if (AIT_TYPE((_vl)) == data) \ 
                                                        AIT_SET_DATA((_vl), AIT_GET_DATA((_v)), \ 
                                                                        AIT_LEN((_v))); \ 
                                        } while (0) 
 
#define AIT_INIT_VAL(_vl)               (memset((_vl), 0, sizeof(ait_val_t))) 
#define AIT_INIT_VAL2(_vl, _t)          do { \ 
                                                AIT_INIT_VAL((_vl)); \ 
                                                (_vl)->val_type = _t; \ 
                                        } while (0) 
                                        /* if attribute zeroCopy is set not execute io_free() */ 
#define AIT_FREE_VAL(_vl)               do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                switch (AIT_TYPE(__val)) { \ 
                                                        case buffer: \ 
                                                                if (!__val->val_in && \ 
                                                                                __val->val.buffer) \ 
                                                                        io_free(__val->val.buffer); \ 
                                                                __val->val.buffer = NULL; \ 
                                                                break; \ 
                                                        case string: \ 
                                                                if (!__val->val_in && \ 
                                                                                __val->val.string) \ 
                                                                        io_free(__val->val.string); \ 
                                                                __val->val.string = NULL; \ 
                                                                break; \ 
                                                        default: \ 
                                                                break; \ 
                                                } \ 
                                                __val->val_type = empty; \ 
                                                __val->val_opt ^= __val->val_opt; \ 
                                                AIT_LEN(__val) = 0; \ 
                                                AIT_KEY(__val) = 0; \ 
                                        } while (0) 
#define AIT_ZERO_VAL(_vl)               do { ait_val_t *__val = (_vl); assert(__val); \ 
                                                switch (AIT_TYPE(__val)) { \ 
                                                        case buffer: \ 
                                                        case string: \ 
                                                                if (__val->val.buffer) \ 
                                                                        memset(__val->val.buffer, 0, \ 
                                                                                AIT_LEN(__val)); \ 
                                                                break; \ 
                                                        case data: \ 
                                                                memset(__val->val_data, 0, AIT_LEN(__val)); \ 
                                                                break; \ 
                                                        default: \ 
                                                                __val->val.net = 0LL; \ 
                                                                break; \ 
                                                } \ 
                                                AIT_KEY(__val) = 0; \ 
                                        } while (0) 
 
struct io_ether_addr { 
        u_int8_t ether_addr_octet[6]; 
 };  };
 typedef struct io_ether_addr io_ether_addr_t;  
   
typedef union {typedef struct {
        struct sockaddr_storage    ss;        int                                sock_role;
        struct sockaddr            sa;        int                             sock_backq;
        struct sockaddr_un      sun;        int                             sock_type;
        struct sockaddr_in      sin;        int                             sock_proto;
        struct sockaddr_in6     sin6;        int                             sock_fd;
        struct sockaddr_dl      sdl;        struct timespec                        sock_timeout;
} io_sockaddr_t;        sockaddr_t                      sock_addr;
#define IO_SOCKADDR_INIT        { .ss = { 0 } }        sockaddr_t                      sock_peer;
   
           ait_val_t                       sock_buf;
           prog_t                          *sock_prog;
   
#define io_align(x, a)          (((x) + (a)) & ~(a))        volatile intptr_t               sock_kill;
         sched_root_task_t               *sock_root;
   
           pthread_mutex_t                 sock_mtx;
           TAILQ_HEAD(, tagCliSock)        sock_cli;
   } sock_t;
   
   
 // io_GetErrno() Get error code of last operation  // io_GetErrno() Get error code of last operation
inline int io_GetErrno();int io_GetErrno();
 // io_GetError() Get error text of last operation  // io_GetError() Get error text of last operation
inline const char *io_GetError();const char *io_GetError();
   
   
 // io_mm_inuse() Check for memory management model  
 inline int io_mm_inuse();  
   
 /*  /*
 * ioLibInit() - Init libaitio library memory management * io_progInit() - Init program pool
  *   *
 * @mm = memory management (IO_SYSM or IO_MPOOL) * @progName = program name for execution
 * @maxmem = memory limit * @initNum = initial started programs
 * return: -1 error or !=-1 used memory management model * @maxNum = maximum started programs
  * return: NULL error or !=NULL allocated pool (must destroied with io_progDestroy())
  */   */
inline int ioLibInit(int mm, unsigned long maxmem);prog_t *io_progInit(const char *progName, 
                 unsigned int initNum, unsigned int maxNum);
 /*  /*
 * ioLibFini() - Finish libaitio library memory management * io_progOpen() - Execute number of program(s)
  *   *
 * return: none * @prg = program pool
  * @execNum = execute program(s) (0 max)
  * return: -1 error, >0 executed programs
  */   */
inline void ioLibFini();int io_progOpen(prog_t * __restrict prg, unsigned int execNum);
 
/* memory management hooks */ 
extern void *(*io_malloc)(size_t); 
extern void *(*io_calloc)(size_t, size_t); 
extern void *(*io_realloc)(void*, size_t); 
extern char *(*io_strdup)(const char*); 
extern void (*io_free)(void*); 
 
 
 /*  /*
 * io_ether_ntoa() - Convert ethernet address to string * io_progOpen2() - Start program from pool on first unused slot
  *   *
 * @n = ethernet address structure, like struct ether_addr * @prg = program pool
 * @a = string * return: -1 error, >-1 reside at slot
 * @len = string length 
 * return: NULL error or !=NULL string a 
  */   */
inline char *io_ether_ntoa(const struct io_ether_addr *n, char * __restrict a, int len);int io_progOpen2(prog_t * __restrict prg);
 /*  /*
 * io_ether_aton() - Convert string to ethernet address * io_progGrow() - Execute to number of programs in pool
  *   *
 * @a = string * @prg = program pool
 * @e = ethernet address structure, like struct ether_addr * @toNum = execute to number of programs (0 max)
 * return: NULL error or !=NULL ethernet address structure * return: 0 error or nothing to do, 
  *      >0 executed programs and abs(<0) executed programs with logged error
  */   */
inline struct io_ether_addr *io_ether_aton(const char *a, struct io_ether_addr *e);int io_progGrow(prog_t * __restrict prg, unsigned int toNum);
 /*  /*
 * io_n2port() - Extract port from network structure * io_progVacuum() - Vacuum pool to running number of programs
  *   *
 * @addr = Address * @prg = program pool
 * return: 0 not supported family type or port number * @toNum = vacuum to number of programs (0 to init number)
  * return: 0 error or >0 closed programs
  */   */
inline u_short io_n2port(io_sockaddr_t * __restrict addr);int io_progVacuum(prog_t * __restrict prg, unsigned int toNum);
 /*  /*
 * io_n2addr() - Extract address from network structure * io_progCloseAt() - Close program at pool of certain position
  *   *
 * @addr = Address * @prg = program pool
 * @val = Value for store string address * @idx = index at pool
 * return: NULL error or !=NULL string address from val * return: 0 error or !=0 closed program
  */   */
const char *io_n2addr(io_sockaddr_t * __restrict addr, ait_val_t * __restrict val);int io_progCloseAt(prog_t * __restrict prg, unsigned int idx);
 /*  /*
 * io_gethostbyname() - Get host and port and make network structure * io_progCloseOf() - Close program at pool with certain handle
  *   *
 * @psHost = Hostname * @prg = program pool
 * @port = Port * @h = handle of program
 * @addr = Network address structure * return: 0 error, >0 closed programs
 * return: NULL error or !=NULL network structure 
  */   */
io_sockaddr_t *io_gethostbyname(const char *psHost, unsigned short port, #ifdef POPEN_STREAM
                io_sockaddr_t * __restrict addr);int io_progCloseOf(prog_t * __restrict prg, FILE *h);
#else
 int io_progCloseOf(prog_t * __restrict prg, int h);
 #endif
 /*  /*
 * io_vars2buffer() - Marshaling data from array with variables to buffer * io_progClose() - Close all programs in pool
  *   *
 * @buf = Buffer * @prg = program pool
 * @buflen = Size of buffer * @closeNum = close program(s) (0 all)
 * @vars = Variable array * return: 0 error, >0 closed programs
 * return: -1 error, 0 nothing done or >0 size of marshaled data 
  */   */
inline int io_vars2buffer(unsigned char * __restrict buf, int buflen, int io_progClose(prog_t * __restrict prg, unsigned int closeNum);
                array_t * __restrict vars); 
 /*  /*
 * io_buffer2vars() - De-marshaling data from buffer to array with variables * io_progDestroy() - Destroy entire program pool
  *   *
 * @buf = Buffer * @pprg = program pool
 * @buflen = Size of buffer * return: none
 * @vnum = Number of variables into buffer 
 * @zcpy = Zero-copy for variables, if !=0 don't use io_arrayFree() for free variables and  
                *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy() 
 * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy() 
  */   */
inline array_t *io_buffer2vars(unsigned char * __restrict buf, int buflen, int vnum, int zcpy);void io_progDestroy(prog_t ** __restrict pprg);
 
 /*  /*
 * io_vars2map() - Marshaling data from array with variables to memory map * io_progCheck() - Check exit status of program pool
  *   *
 * @buf = Buffer * @prg = program pool
 * @buflen = Size of buffer * @re = resurrect program to init number
 * @vars = Variable array * return: -1 error or >-1 exited programs
 * return: -1 error, 0 nothing done or >0 size of marshaled data 
  */   */
inline int io_vars2map(unsigned char * __restrict buf, int buflen, int io_progCheck(prog_t * __restrict prg, int re);
                array_t * __restrict vars); 
/* 
 * io_map2vars() - De-marshaling data from memory map to array with variables 
 * 
 * @buf = Buffer 
 * @buflen = Size of buffer 
 * @vnum = Number of variables into buffer 
 * @zcpy = Zero-copy for variables, if !=0 don't use io_arrayFree() for free variables and  
                *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy() 
 * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy() 
 */ 
inline array_t *io_map2vars(unsigned char * __restrict buf, int buflen, int vnum, int zcpy); 
   
 /*  /*
 * io_allocVar() - Allocate memory for variable * io_progAttach() - Attach to open program
  *   *
 * return: NULL error or new variable, after use free variable with io_freeVar() * @prg = program pool
  * @newOne = Execute new one program after attach
  * return: NULL error or !=NULL attached program handle
  */   */
inline ait_val_t *io_allocVar(void);#ifdef POPEN_STREAM
 FILE *io_progAttach(prog_t * __restrict prg, int newOne);
 #else
 int io_progAttach(prog_t * __restrict prg, int newOne);
 #endif
 /*  /*
 * io_freeVar() - Free allocated memory for variable * io_progDetach() - Detch from open program
  *   *
 * @val = Variable * @prg= program pool
  * @pfd = attached program handle
  * return: none   * return: none
  */   */
inline void io_freeVar(ait_val_t ** __restrict val);#ifdef POPEN_STREAM
 void io_progDetach(prog_t * __restrict prg, FILE *pfd);
 #else
 void io_progDetach(prog_t * __restrict prg, int pfd);
 #endif
 
 
 /*  /*
 * io_makeVar() - Allocate memory and fill variable * ioInitSocket() - Init socket and allocate resources
  *   *
 * @type = type of variable * @role = Socket role
 * @... = arg1 is value of variable * @type = Socket type
 * @... = arg2 is length of variabla. Not required for numbers and strings! * @proto = Socket protocol
 * return: NULL error or new variable, after use free variable with io_freeVar() * @addr = Bind to address
  * @port = Bind to port
  * @buflen = Socket buffer, optional if =0 == BUFSIZ
  * return: NULL error or !=NULL created socket
  */   */
ait_val_t *io_makeVar(ait_type_t type, ...);sock_t *ioInitSocket(int role, int type, int proto, 
                 const char *addr, unsigned short port, size_t buflen);
 /*  /*
 * io_allocVars() - Allocate ait_val_t array * ioCloseSocket() - Close socket and free resources
  *   *
 * @varnum = Number of variables * @s = Socket
 * return: =NULL error or !=NULL allocated array * return: none
  */   */
inline array_t *io_allocVars(int varnum);void ioCloseSocket(sock_t ** __restrict s);
 #define ioKillSocket(x)         (assert((x)), (x)->sock_kill = 1)
 /*  /*
 * io_clrVars() - Clear ait_val_t elements from array * ioCloseClient() - Close client socket
  *   *
 * @vars = Variable array * @c = Client socket
 * return: -1 error or size of array * return: 0 ok or !=0 error
  */   */
inline int io_clrVars(array_t * __restrict vars);int ioCloseClient(sock_cli_t * __restrict c);
 /*  /*
 * io_freeVars() - Free ait_val_t array * ioSetupProg2Socket() - Setup program pool to socket server
  *   *
 * @vars = Variable array * @s = Socket
 * return: none * @p = Program pool
  * return: -1 error or 0 ok
  */   */
inline void io_freeVars(array_t ** __restrict vars);int ioSetupProg2Socket(sock_t * __restrict s, prog_t * __restrict p);
 /*  /*
 * io_getVars() - Get ait_val_t element from array and if not exists allocate it * ioUpSocket() - Setup socket for use
  *   *
 * @vars = Variable array * @s = Socket
 * @n = index of variable into array * @arg = Server role = listen backlog queue and Client role = peer address
 * return: NULL error or !=NULL ait_val_t element * @timeout = Socket timeout in ms (default -1 infinit)
  * return: -1 error or 0 ok
  */   */
inline ait_val_t *io_getVars(array_t ** __restrict vars, int n);int ioUpSocket(sock_t * __restrict s, void *arg, int timeout);
 /*  /*
 * io_sortVarsByKey() - Sorting array with variables by key * ioUpdTimerSocket() - Update timeout of socket
  *   *
 * @vars = Variable array * @c = Client socket
 * @order = Sort order. If =0 ascend or !=0 descend * return:  none
 * return: none 
  */   */
inline void io_sortVarsByKey(array_t * __restrict vars, int order);void ioUpdTimerSocket(sock_cli_t * __restrict c);
 /*  /*
 * io_sortVarsByVal() - Sorting array with variables by value * ioLoopSocket() - Start socket scheduler
  *   *
 * @vars = Variable array * @s = Socket
 * @order = Sort order. If =0 ascend or !=0 descend * @rcb = Read callback
 * @cmp = Custom compare function for sorting. If =NULL compare by value * return: -1 error or return result from scheduler
 * return: none 
  */   */
inline void io_sortVarsByVal(array_t * __restrict vars, int order,  int ioLoopSocket(sock_t * __restrict s, sched_task_func_t rcb);
                int (*cmp)(const void*, const void*)); 
 /*  /*
 * io_findKeyVars() - Find variable by key from array * ioBridgeProg2Socket() - Start socket scheduler and bridge program to socket
  *   *
 * @vars = Variables * @s = Socket
 * @key = Search key * @prgname = Program name
 * return: NULL error or not found, !=NULL valid element * return: 0 ok or !=0 error
  */   */
ait_val_t *io_findKeyVars(array_t * __restrict vars, u_short key);int ioBridgeProg2Socket(sock_t * __restrict s, const char *prgname);
   
   
 /*  /*
Line 605  ait_val_t *io_findKeyVars(array_t * __restrict vars, u Line 326  ait_val_t *io_findKeyVars(array_t * __restrict vars, u
  * @dataLen = Length of data   * @dataLen = Length of data
  * return: 0 EOF; -1 error:: can`t read; >0 count of readed chars   * return: 0 EOF; -1 error:: can`t read; >0 count of readed chars
 */  */
int ioPromptRead(int *h, const char *csPrompt, char * __restrict psData, int dataLen);int ioPromptRead(int *h, const char *csPrompt, 
                 char * __restrict psData, int dataLen);
 /*  /*
  * ioPromptPassword() - Read password from input h[0] with prompt to output h[1]   * ioPromptPassword() - Read password from input h[0] with prompt to output h[1]
  *   *
Line 616  int ioPromptRead(int *h, const char *csPrompt, char *  Line 338  int ioPromptRead(int *h, const char *csPrompt, char * 
  * @confirm = Confirm password, 0 - get password, !=0 Ask for confirmation   * @confirm = Confirm password, 0 - get password, !=0 Ask for confirmation
  * return: 0 EOF; -1 error:: can`t read; >0 count of readed chars   * return: 0 EOF; -1 error:: can`t read; >0 count of readed chars
 */  */
int ioPromptPassword(int *h, const char *csPrompt, char * __restrict psPass, int passLen, int confirm);int ioPromptPassword(int *h, const char *csPrompt, 
                 char * __restrict psPass, int passLen, int confirm);
   
 /*  
  * ioRegexVerify() - Function for verify data match in regex expression  
  *  
  * @csRegex = Regulare expression pattern  
  * @csData = Data for check and verify  
  * @startPos = Return start positions  
  * @endPos = Return end positions  
  * return: NULL not match or error; !=NULL begin of matched data  
 */  
 const char *ioRegexVerify(const char *csRegex, const char *csData, int *startPos, int *endPos);  
 /*  
  * ioRegexGet() - Function for get data match in regex expression  
  *  
  * @csRegex = Regulare expression pattern  
  * @csData = Data from get  
  * @psString = Returned string if match  
  * @strLen = Length of string  
  * return: 0 not match; >0 count of returned chars  
 */  
 int ioRegexGet(const char *csRegex, const char *csData, char * __restrict psString, int strLen);  
 /*  
  * ioRegexReplace() - Function for replace data match in regex expression with newdata  
  *  
  * @csRegex = Regulare expression pattern  
  * @csData = Source data  
  * @csNew = Data for replace  
  * return: NULL not match or error; !=NULL allocated new string, must be io_free after use!  
 */  
 char *ioRegexReplace(const char *csRegex, const char *csData, const char *csNew);  
   
 /*  /*
  * ioStrAst() - Function for evaluate string like asterisk variable "{text[:[-]#[:#]]}"  
  *  
  * @csString = Input string  
  * return: NULL error, !=NULL Allocated new string evaluated from input string, must be io_free()  
 */  
 char *ioStrAst(const char *csString);  
   
 /*  
  * io_UnquotStr() - Remove quots from input text string   
  *  
  * @psLine = Text string  
  * return: 0 nothing to do; 1 successful unquoted string  
 */  
 inline int io_UnquotStr(char * __restrict psLine);  
 /*  
  * io_LTrimStr() - Remove left whitespaces from text string  
  *  
  * @psLine = Text string  
  * return: 0 nothing to do; !=0 Removed bytes  
 */  
 inline int io_LTrimStr(char * __restrict psLine);  
 /*  
  * io_RTrimStr() - Remove right whitespaces from text string  
  *  
  * @psLine = Text string  
  * return: 0 nothing to do; !=0 Removed bytes  
 */  
 inline int io_RTrimStr(char * __restrict psLine);  
 /*  
  * io_TrimStr() - Remove left and right whitespaces from text string  
  *  
  * @psLine = Text string  
  * return: 0 nothing to do; !=0 Removed bytes  
 */  
 inline int io_TrimStr(char * __restrict psLine);  
 /*  
  * io_Ch2Hex() - Convert from Char string to Hex string  
  *  
  * @psLine = Text string  
  * @lineLen = Length of Text string  
  * return: NULL nothing to do or error; !=0 Allocated new converted data without term\0 (must be io_free)  
 */  
 inline unsigned char *io_Ch2Hex(unsigned char *psLine, int lineLen);  
 /*  
  * io_Hex2Ch() - Convert from Hex string to Char string  
  *  
  * @psLine = Text string  
  * @lineLen = Length of Text string  
  * return: NULL nothing to do or error; !=0 Allocated new converted string(must be io_free)  
 */  
 inline char *io_Hex2Ch(unsigned char *psLine, int lineLen);  
   
 /*  
  * io_Path2File() - Parse and make path/filename pair  
  *  
  * @csArgs = Input argument line  
  * @psPath = Output Path, if ==NULL path not returned  
  * @pathLen = Size of path array  
  * @psFile = Output File  
  * @fileLen = Size of file array  
  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items  
  */  
 inline int  
 io_Path2File(const char * __restrict csArgs, char * __restrict psPath,   
                 int pathLen, char * __restrict psFile, int fileLen);  
   
 /*  
  * io_arrayInit() - Create and initialize dynamic array  
  *  
  * @numItems = Number of Items  
  * return: NULL error, != NULL allocated memory for array  
  */  
 inline array_t *io_arrayInit(int numItems);  
 /*  
  * io_arrayDestroy() - Free and destroy dynamic array  
  *  
  * @parr = Array  
  * return: none  
  */  
 inline void io_arrayDestroy(array_t ** __restrict parr);  
 /*  
  * io_arrayFree() - Free all data in dynamic array items  
  *      (WARNING! If assign static array dont use this!!!)  
  *  
  * @arr = Array  
  * return: none  
  */  
 inline void io_arrayFree(array_t * __restrict arr);  
 /*  
  * io_arrayFrom() - Create and fill array from array with pointers  
  *  
  * @pargv = Array with pointers  
  * @argc = Number of Items, if 0 walk through argv and stop when reach NULL item  
  * return: NULL error, != NULL allocated new array  
  */  
 inline array_t *io_arrayFrom(const char *** __restrict pargv, int argc);  
 /*  
  * io_arrayTo() - Create and fill array with pointers from dynamic array  
  *  
  * @arr = Array  
  * return: NULL error, != NULL allocated memory for array, NULL terminated  
  */  
 inline char **io_arrayTo(array_t * __restrict arr);  
 /*  
  * io_arrayLen() - Get last used element in dynamic array (array Length)  
  *  
  * @arr = Array  
  * return: -1 empty or >-1 position of last used element  
  */  
 inline int io_arrayLen(array_t * __restrict arr);  
 /*  
  * io_arrayConcat() Concat source array to destination array  
  *  
  * @dest = Destination array  
  * @src = Source array  
  * return: -1 error; >0 new count of destination array  
  */  
 int io_arrayConcat(array_t * __restrict dest, array_t * __restrict src);  
 /*  
  * io_arrayCopy() Copy source array to destination array  
  *  
  * @dest = Destination array, after use free with io_arrayDestroy()  
  * @src = Source array  
  * return: -1 error; >0 count of destination array  
  */  
 int io_arrayCopy(array_t ** __restrict dest, array_t * __restrict src);  
 /*  
  * io_arrayGrow() - Grow/Shrink dynamic array, Use with care when it shrink!!!  
  *  
  * @arr = Array  
  * @newNumItems = Number of Items  
  * @freeShrink = Free elements before shrink array  
  * return: -1 error, 0 ok  
  */  
 int io_arrayGrow(array_t * __restrict arr, int newNumItems, int freeShrink);  
 /*  
  * io_arrayVacuum() - Vacuum dynamic array, empty elements will be deleted  
  *  
  * @arr = Array  
  * @fromWhere = 1 begin, 2 ALL empty elements  
  * return: -1 error, 0 ok  
  */  
 int io_arrayVacuum(array_t * __restrict arr, int fromWhere);  
   
 #define io_arraySize(_arr)              ((_arr) ? (_arr)->arr_num : 0)  
 #define io_arrayLast(_arr)              (io_arraySize((_arr)) ? (_arr)->arr_last : -1)  
 #define io_arrayZero(_arr)              (assert((_arr)), memset((_arr)->arr_data, 0, \  
                                                 io_arraySize((_arr)) * sizeof(void*)))  
   
 #define io_arrayGet2(_arr, _d)          (assert((_arr) && (_arr)->arr_num > _d), ((_arr)->arr_data + _d))  
 #define io_arrayGet(_arr, _d)           (assert((_arr) && (_arr)->arr_num > _d), (_arr)->arr_data[_d])  
 #define io_array(_arr, _d, _type)       (assert((_arr) && (_arr)->arr_num > _d), \  
                                                 ((_type) (_arr)->arr_data[_d]))  
 #define io_arraySet(_arr, _d, _ptr)     do { \  
                                                 assert((_arr) && (_arr)->arr_num > _d); \  
                                                 if ((_arr)->arr_last < _d) \  
                                                         (_arr)->arr_last = _d; \  
                                                 (_arr)->arr_data[_d] = (void*) (_ptr); \  
                                         } while (0)  
 #define io_arrayDel(_arr, _d, _fri)     do { \  
                                                 assert((_arr) && (_arr)->arr_num > _d); \  
                                                 if (_fri && (_arr)->arr_data[_d]) \  
                                                         free((_arr)->arr_data[_d]); \  
                                                 (_arr)->arr_data[_d] = NULL; \  
                                         } while (0)  
   
 /*  
  * io_arrayElem() - Always GET/PUT element into dynamic array, if not enough elements grow array  
  *  
  * @arr = Array  
  * @n = Position  
  * @data = Element, if set NULL GET element at position or !=NULL PUT element at position  
  * return: -1 error or !=-1 return element at position  
  */  
 inline void *io_arrayElem(array_t * __restrict arr, int n, void *data);  
 /*  
  * io_arrayPush() - Push element into dynamic array like stack manner, place at first empty position  
  *  
  * @arr = Array  
  * @data = Element, if set NULL return only first empty position  
  * @mayGrow = Array may to grow, if not enough room for new element  
  * return: -1 not found empty position, array is full!, >-1 return position of stored element into array  
  */  
 inline int io_arrayPush(array_t * __restrict arr, void **data, int mayGrow);  
 /*  
  * io_arrayPop() - Pop element from dynamic array like stack manner, last used position  
  *  
  * @arr = Array  
  * @data = Element, if set NULL return only last used position  
  * @delAfter = Delete after Pop element, !=0 delete element from array after return data  
  * return: -1 not found used position, array is empty!, >-1 return element position  
  */  
 inline int io_arrayPop(array_t * __restrict arr, void ** __restrict data, int delAfter);  
   
 /*  
  * io_argsNum() - Parse and calculate number of arguments  
  *  
  * @csArgs = Input arguments line  
  * @csDelim = Delimiter(s) for separate  
  * return: 0 error format; -1 error:: can`t read; >0 ok, number of items  
  */  
 inline int io_argsNum(const char *csArgs, const char *csDelim);  
   
 /*  
  * io_arrayMake() - Parse and make array from arguments ... (input string will be modified!!!   
  *      and output array must be free with io_arrayDestroy() after use!)  
  *  
  * @psArgs = Input arguments line, after execute string is modified!!!  
  * @nargs = Maximum requested count of arguments from input string psArgs, if 0 all psArgs  
  * @csDelim = Delimiter(s) for separate  
  * @parr = Output array of arguments ... (must be io_free with io_arrayDestroy() after use!)  
  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items  
  */  
 int io_arrayMake(char * __restrict psArgs, int nargs, const char *csDelim,   
                 array_t ** __restrict parr);  
   
 /*  
  * io_MakeAV() - Parse and make attribute/value pair  
  *  
  * @csArgs = Input argument line  
  * @csDelim = Delimiter for separate  
  * @psAttr = Output Attribute  
  * @attrLen = Size of attribute array  
  * @psValue = Output Value, if ==NULL this element not present value or not wanted for return  
  * @valLen = Size of value array  
  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items  
 */  
 int io_MakeAV(const char * __restrict csArgs, const char *csDelim,   
                 char * __restrict psAttr, int attrLen, char * __restrict psValue, int valLen);  
 /*  
  * io_MakeAV2() Parse and make attribute/value pair over input string  
  *  
  * @csArgs = Input argument line, will be modified!  
  * @csDelim = Delimiter for separate  
  * @psAttr = Output Attribute  
  * @psValue = Output Value, if ==NULL this element not present value or not wanted for return  
  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items  
 */  
 int io_MakeAV2(char * __restrict psArgs, const char *csDelim,   
                 char ** __restrict psAttr, char ** __restrict psValue);  
   
 /*  
  * io_sarrInit() - Create and initialize dynamic split-order array  
  *  
  * @numItems = Number of Items  
  * @segLen = Length of segment  
  * return: NULL error, != NULL allocated memory for array  
  */  
 inline sarr_t *io_sarrInit(int numItems, int segLen);  
 /*  
  * io_sarrDestroy() - Free all data in dynamic split-order array and Destroy array  
  *  
  * @parr = Array  
  * return: none  
  */  
 inline void io_sarrDestroy(sarr_t ** __restrict parr);  
 /*  
  * io_sarrGrow() - Grow/Shrink dynamic split-order array, Use with care when it shrink!!!  
  *  
  * @arr = Array  
  * @newNumItems = Number of Items  
  * return: -1 error, 0 ok  
  */  
 int io_sarrGrow(sarr_t * __restrict arr, int newNumItems);  
 /*  
  * io_sarrVacuum() - Vacuum dynamic split-order array, empty segments will be freed  
  *  
  * @arr = Array  
  * return: -1 error, >-1 freed segments  
  */  
 inline int io_sarrVacuum(sarr_t * __restrict arr);  
 #define io_sarrSize(_arr)               ((_arr) ? (_arr)->sarr_num : 0)  
 #define io_sarrSeg(_arr)                (assert((_arr)), (_arr)->sarr_seg)  
 /*  
  * io_sarrCopy() Copy source split array to destination split array  
  *  
  * @dest = Destination split array, after use free with io_sarrDestroy()  
  * @src = Source split array  
  * return: -1 error; >0 count of destination split array  
  */  
 int io_sarrCopy(sarr_t ** __restrict dest, sarr_t * __restrict src);  
 /*  
  * io_sarrGet() - Get element from dynamic split-order array  
  *  
  * @arr = Array  
  * @idx = Index (warning 1st element is at position 1)  
  * return: NULL not found, !=NULL element  
  */  
 inline void *io_sarrGet(sarr_t * __restrict arr, unsigned int idx);  
 /*  
  * io_sarrGet2() - Always get element from dynamic split-order array  
  *      Function automatic grow array. Good use for Hash tables!   
  *  
  * @arr = Array  
  * @idx = Index (warning 1st element is at position 1)  
  * return: NULL not found, !=NULL element  
  */  
 void *io_sarrGet2(sarr_t * __restrict arr, unsigned int idx);  
 /*  
  * io_sarrSet() - Set element to dynamic split-order array  
  *  
  * @arr = Array  
  * @idx = Index (warning 1st element is at position 1)  
  * @data = Value  
  * return: NULL error or empty, !=NULL old value in element  
  */  
 inline void *io_sarrSet(sarr_t * __restrict arr, unsigned int idx, void *data);  
 #define io_sarrDel(_arr, _idx)          io_sarrSet((_arr), _idx, NULL)  
 #define io_sarr(_arr, _idx, _type)      (_type)io_sarrGet((_arr), _idx)  
 /*  
  * io_sarr2array() - Convert from split-order array to dynamic array  
  *  
  * @sa = split array  
  * @sarrFree = after convert split array !=0 will be destroyed sarray  
  * return: NULL error or != NULL new array  
  */  
 array_t *io_sarr2array(sarr_t ** __restrict sa, int sarrFree);  
 /*  
  * io_array2sarr() - Convert from dynamic array to split-order array  
  *  
  * @a = array  
  * @segLen = Length of segment  
  * @arrFree = after convert array !=0 will be destroyed  
  * return: NULL error or != NULL new sarr  
  */  
 sarr_t *io_array2sarr(array_t ** __restrict a, int segLen, int arrFree);  
   
 /*  
  * io_CopyEnv() - Copy environment to new environment array;  
  *  
  * @oldenv = Environment array  
  * return: NULL error; !=NULL Allocated new environment array(must be io_free)  
 */  
 char **io_CopyEnv(const char **oldenv);  
 /*  
  * io_ExecArgs() - Build exec arguments from other array  
  *  
  * @psProg = Program name for execute  
  * @oldarg = Arguments array  
  * return: NULL error; !=NULL Allocated execution array(must be io_free)  
 */  
 char **io_ExecArgs(const char *psProg, const char **oldarg);  
 /*  
  * io_FreeNullTerm() - Free dynamic allocated null terminated array with strings  
  *  
  * @arr = Pointer to array for free  
  * return: none  
 */  
 inline void io_FreeNullTerm(char *** __restrict arr);  
   
 /*  
  * ioMkDir() - Function for racursive directory creation and validation   * ioMkDir() - Function for racursive directory creation and validation
  *   *
  * @csDir = Full directory path   * @csDir = Full directory path
Line 1028  int ioWatchDirLoop(const char *csDir, int (*callback)( Line 371  int ioWatchDirLoop(const char *csDir, int (*callback)(
  * @sig = Event for completed operations, may be =NULL   * @sig = Event for completed operations, may be =NULL
  * return: -1 error or 0 ok   * return: -1 error or 0 ok
  */   */
inline int io_aiobulk(int mode, struct aiocb ** __restrict acbs, int nacb, int io_aiobulk(int mode, struct aiocb ** __restrict acbs, int nacb, 
                 struct sigevent *sig);                  struct sigevent *sig);
 #endif  #endif
 /*  /*
Line 1065  int io_rwritev(int fd, struct iovec * __restrict bufs, Line 408  int io_rwritev(int fd, struct iovec * __restrict bufs,
  * @update = Update file handle position !0   * @update = Update file handle position !0
  * return: -1 error or !=-1 readed bytes   * return: -1 error or !=-1 readed bytes
  */   */
inline int io_rread(int fd, void * __restrict buf, size_t nbytes, off_t offset, int io_rread(int fd, void * __restrict buf, size_t nbytes, off_t offset, 
                 int update);                  int update);
 /*  /*
  * io_rwrite() - Raw VFS write function   * io_rwrite() - Raw VFS write function
Line 1077  inline int io_rread(int fd, void * __restrict buf, siz Line 420  inline int io_rread(int fd, void * __restrict buf, siz
  * @update = Update file handle position !0   * @update = Update file handle position !0
  * return: -1 error or !=-1 written bytes   * return: -1 error or !=-1 written bytes
  */   */
inline int io_rwrite(int fd, void * __restrict buf, size_t nbytes, off_t offset, int io_rwrite(int fd, void * __restrict buf, size_t nbytes, off_t offset, 
                 int update);                  int update);
   
 /* Disk I/O helper macros */  /* Disk I/O helper macros */
Line 1085  inline int io_rwrite(int fd, void * __restrict buf, si Line 428  inline int io_rwrite(int fd, void * __restrict buf, si
 #define io_write(f, b, n) io_rwrite(f, b, n, -1, 1)  #define io_write(f, b, n) io_rwrite(f, b, n, -1, 1)
   
   
 /* Debug helper macros */  
 extern int io_Debug;  
   
 #define io_enableDEBUG          int io_Debug  
 #define io_initDebug(x)         (io_Debug = (x))  
 #define io_incDebug             (io_Debug++)  
 #define io_decDebug             (io_Debug--)  
   
 /* Debug macros */  
 #define ioVERBOSE(x)            if ((x) <= io_Debug)  
 #define ioTRACE(x)              if ((x) <= io_Debug) \  
                                            syslog(LOG_DEBUG, "I'm in %s(%d)", __func__, __LINE__)  
 #define ioDEBUG(x, fmt, ...)    do { \  
                                         assert((fmt)); \  
                                         char str[STRSIZ] = { 0 }; \  
                                         snprintf(str, sizeof str, (fmt), ##__VA_ARGS__); \  
                                         if ((x) <= io_Debug) \  
                                                 syslog(LOG_DEBUG, "Debug(%d):%s(%d): %s\n", \  
                                                                 (x), __func__, __LINE__, str); \  
                                 } while (0)  
   
 /* Logger macro */  
 #define ioLOGGER(x, fmt, ...)   do { \  
                                         assert((fmt)); \  
                                         char str[STRSIZ] = { 0 }; \  
                                         snprintf(str, sizeof str, (fmt), ##__VA_ARGS__); \  
                                         syslog((x), "Logger:%s(%d): %s\n", \  
                                                                 __func__, __LINE__, str); \  
                                 } while (0)  
   
 /* Error state macros */  
 #define ioERROR(x, fmt, ...)    do { \  
                                         assert((fmt)); \  
                                         char str[STRSIZ] = { 0 }; \  
                                         snprintf(str, sizeof str, (fmt), ##__VA_ARGS__); \  
                                         syslog(LOG_ERR, "Error:%s(%d): #%d - %s\n", \  
                                                          __func__, __LINE__, (x), str); \  
                                 } while (0)  
 #define ioSYSERR(x)             do { \  
                                         if (x > 0 || errno) \  
                                                 syslog(LOG_ERR, "Error(sys):%s(%d): #%d - %s\n", \  
                                                                 __func__, __LINE__, x > 0 ? x : errno, \  
                                                                 strerror(x > 0 ? x : errno)); \  
                                 } while (0)  
 #define ioLIBERR(ait)           do { \  
                                         if (ait##_GetErrno()) \  
                                                 syslog(LOG_ERR, "Error(lib):%s(%d): #%d - %s\n", \  
                                                                 __func__, __LINE__, ait##_GetErrno(), \  
                                                                 ait##_GetError()); \  
                                 } while (0)  
   
   
 /* Crypto framework */  /* Crypto framework */
   
 /*  /*
Line 1144  extern int io_Debug; Line 435  extern int io_Debug;
  *   *
  * @pInput = input buffer   * @pInput = input buffer
  * @inLen = input buffer len   * @inLen = input buffer len
 * @ppOutput = output allocated buffe, must be io_free after use * @ppOutput = output allocated buffe, must be e_free after use
  * @Cipher = cipher engine, like EVP_bf_cbc() or etc...   * @Cipher = cipher engine, like EVP_bf_cbc() or etc...
  * @pKey = key   * @pKey = key
  * @pIV = IV, salt (8 bytes)   * @pIV = IV, salt (8 bytes)
Line 1159  int ioCipher(unsigned char *pInput, int inLen, unsigne Line 450  int ioCipher(unsigned char *pInput, int inLen, unsigne
  *   *
  * @pInput = input buffer   * @pInput = input buffer
  * @inLen = input buffer len   * @inLen = input buffer len
 * @ppOutput = output allocated buffe, must be io_free after use * @ppOutput = output allocated buffe, must be e_free after use
  * @pKey = key   * @pKey = key
  * @pIV = IV, salt (8 bytes)   * @pIV = IV, salt (8 bytes)
  * @nMode = Mode 0 - decrypting or 1 - encrypting   * @nMode = Mode 0 - decrypting or 1 - encrypting
Line 1172  int io_Blowfish(unsigned char *pInput, int inLen, unsi Line 463  int io_Blowfish(unsigned char *pInput, int inLen, unsi
  *   *
  * @pInput = Input buffer with ASCII   * @pInput = Input buffer with ASCII
  * @inLen = Input buffer data length   * @inLen = Input buffer data length
 * @ppOutput = Output buffer with cipher data, must be io_free after use * @ppOutput = Output buffer with cipher data, must be e_free after use
  * @pKey = Key   * @pKey = Key
  * @IV = IVector/Nonce/Counter, Warning: IV must be variable, because we write there!!!   * @IV = IVector/Nonce/Counter, Warning: IV must be variable, because we write there!!!
  * return: -1 error or >-1 how many cipher blocks proceeded   * return: -1 error or >-1 how many cipher blocks proceeded
Line 1192  int io_ctr_AES(unsigned char *pInput, int inLen, unsig Line 483  int io_ctr_AES(unsigned char *pInput, int inLen, unsig
  * @winz = winsize for terminal   * @winz = winsize for terminal
  * return: -1 error or 0 ok   * return: -1 error or 0 ok
  */   */
inline int ioAllocPTY(int *ptyfd, int *ttyfd, char * __restrict name, int namesiz, int ioAllocPTY(int *ptyfd, int *ttyfd, char * __restrict name, int namesiz, 
                 struct termios * __restrict term, struct winsize * __restrict winz);                  struct termios * __restrict term, struct winsize * __restrict winz);
 /*  /*
  * ioFreePTY() - Release PTY and TTY device   * ioFreePTY() - Release PTY and TTY device
Line 1201  inline int ioAllocPTY(int *ptyfd, int *ttyfd, char * _ Line 492  inline int ioAllocPTY(int *ptyfd, int *ttyfd, char * _
  * @ttyname = tty filename   * @ttyname = tty filename
  * return: none   * return: none
  */   */
inline void ioFreePTY(int ptyfd, const char *ttyname);void ioFreePTY(int ptyfd, const char *ttyname);
 /*  /*
  * ioChgWinPTY() - Change window size of PTY   * ioChgWinPTY() - Change window size of PTY
  *   *
Line 1212  inline void ioFreePTY(int ptyfd, const char *ttyname); Line 503  inline void ioFreePTY(int ptyfd, const char *ttyname);
  * @ypxl = y pixels   * @ypxl = y pixels
  * return: -1 error or 0 ok   * return: -1 error or 0 ok
  */   */
inline int ioChgWinPTY(int ptyfd, unsigned short row, unsigned short col, int ioChgWinPTY(int ptyfd, unsigned short row, unsigned short col, 
                 unsigned short xpxl, unsigned short ypxl);                  unsigned short xpxl, unsigned short ypxl);
 /*  /*
  * ioSetOwnerTTY() - Set owner to TTY   * ioSetOwnerTTY() - Set owner to TTY
Line 1238  int ioSetSidTTY(int *ttyfd, const char *ttyname); Line 529  int ioSetSidTTY(int *ttyfd, const char *ttyname);
  * @otio = saved old termios for later restore if !=NULL   * @otio = saved old termios for later restore if !=NULL
  * return: -1 error or 0 ok   * return: -1 error or 0 ok
  */   */
inline int ioSetRAWMode(int fd, struct termios *otio);int ioSetRAWMode(int fd, struct termios *otio);
 /*  /*
  * ioRestoreMode() - Restore termios to tty fd   * ioRestoreMode() - Restore termios to tty fd
  *   *
Line 1246  inline int ioSetRAWMode(int fd, struct termios *otio); Line 537  inline int ioSetRAWMode(int fd, struct termios *otio);
  * @tio = termios structure for restore   * @tio = termios structure for restore
  * return: -1 error or 0 ok   * return: -1 error or 0 ok
  */   */
inline int ioRestoreMode(int fd, struct termios tio);int ioRestoreMode(int fd, struct termios tio);
 /*  /*
  * ioForkPTY() - Fork new process with session leader and new TTY   * ioForkPTY() - Fork new process with session leader and new TTY
  *   *
Line 1268  pid_t ioForkPTY(int *ptyfd, char * __restrict name, in Line 559  pid_t ioForkPTY(int *ptyfd, char * __restrict name, in
  * @ifExists = !=0 if filename exists return error   * @ifExists = !=0 if filename exists return error
  * return: -1 error or 0 ok   * return: -1 error or 0 ok
  */   */
inline int ioCreatePIDFile(const char *csName, int ifExists);int ioCreatePIDFile(const char *csName, int ifExists);
   
 /*  /*
  * ioSendFile() - AITNET sendfile() userland implementation, not dependant from OS   * ioSendFile() - AITNET sendfile() userland implementation, not dependant from OS
Line 1293  size_t ioSendFile(int s, const char *csFile, size_t se Line 584  size_t ioSendFile(int s, const char *csFile, size_t se
  */   */
 size_t ioRecvFile(int s, const char *csFile, size_t recvLen, int over, int rcvbuf);  size_t ioRecvFile(int s, const char *csFile, size_t recvLen, int over, int rcvbuf);
   
   /*
    * ioRealFileName() - Get real file name
    *
    * @fname = filename
    * return: =NULL error or !=NULL real filename, should be free with e_free()
    */
   char *ioRealFileName(const char *fname);
   
 /* Buffered file access over memory block */  /* Buffered file access over memory block */
   
Line 1323  FILE *io_fmapopen(const char *csFile, int mode, int pe Line 621  FILE *io_fmapopen(const char *csFile, int mode, int pe
  * @mode = Permissions for new buffered file I/O   * @mode = Permissions for new buffered file I/O
  * return: NULL error or open buffered file   * return: NULL error or open buffered file
  */   */
inline FILE *io_fd2buf(int fd, const char *mode);FILE *io_fd2buf(int fd, const char *mode);
 /*  /*
  * io_dumbFile() - Create empry or dumb file with fixed size   * io_dumbFile() - Create empry or dumb file with fixed size
  *   *
Line 1333  inline FILE *io_fd2buf(int fd, const char *mode); Line 631  inline FILE *io_fd2buf(int fd, const char *mode);
  * return: -1 error or open file handle   * return: -1 error or open file handle
  */   */
 int io_dumbFile(const char *csFile, int mode, off_t size);  int io_dumbFile(const char *csFile, int mode, off_t size);
   
   
   /*
    * io_get1stiface() - Get first interface of host
    *
    * @szIface = interface string buffer
    * @iflen = size of interface buffer
    * return: -1 error or 0 ok
    */
   int io_get1stiface(char *szIface, int iflen);
   /*
    * io_getmaciface() - Get MAC address from interface name
    *
    * @csIface = interface name
    * @ea = ethernet address
    * return: -1 error, 0 ok or 1 not found
    */
   int io_getmaciface(const char *csIface, ether_addr_t * __restrict ea);
   /*
    * io_etherOpen() - Open BPF interface to device
    *
    * @csIface = interface name
    * @flags = open flags
    * @whdr = with complete headers
    * @wdlt = with data link type
    * @buflen = buffer length
    * @zcbuf = zero copy buffer, if BPF supports it and isn't NULL
    * return: -1 error or >-1 bpf handle
    */
   int io_etherOpen(const char *csIface, int flags, unsigned int whdr, 
                   unsigned int wdlt, unsigned int *buflen, void **zcbuf);
   /*
    * io_etherClose() - Close BPF interface
    *
    * @eth = bpf handle
    * @zcbuf = zero copy buffer, if BPF supports it and isn't NULL
    * return: none
    */
   void io_etherClose(int eth, void **zcbuf);
   
   /*
    * io_etherFilter() - BPF filter routine
    *
    * @eth = bpf handle
    * @io = filter direction 
    *  (IO_ETHER_FILTER_PROMISC|IO_ETHER_FILTER_NOTREAD|IO_ETHER_FILTER_READ|IO_ETHER_FILTER_WRITE)
    * @insn = BPF filter instruction array
    * @insnlen = Length of BPF filter instruction array
    * return: -1 error or 0 ok
    */
   int io_etherFilter(int eth, int io, struct bpf_insn * __restrict insn, size_t insnlen);
   
   /*
    * io_etherSend() - Send packet to bpf
    *
    * @eth = bpf handle
    * @buf = buffer
    * @buflen = buffer length
    * return: -1 error or !=-1 written bytes
    */
   ssize_t io_etherSend(int eth, const void *buf, size_t buflen);
   /*
    * io_etherRecv() - Receive packet from bpf
    *
    * @eth = bpf handle
    * @buf = buffer
    * @buflen = buffer length
    * @zcbuf = zero copy buffer, if BPF supports it and isn't NULL
    * return: -1 error or !=-1 readed bytes
    */
   ssize_t io_etherRecv(int eth, void * __restrict buf, 
                   size_t buflen, void * __restrict zcbuf);
   
   
 #endif  #endif

Removed from v.1.24  
changed lines
  Added in v.1.40


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>