Diff for /libaitio/inc/aitio.h between versions 1.11.2.10 and 1.38.10.1

version 1.11.2.10, 2011/09/01 08:13:10 version 1.38.10.1, 2013/12/04 10:08:40
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, 2011Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
         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 47  SUCH DAMAGE. Line 47  SUCH DAMAGE.
 #define __AITIO_H  #define __AITIO_H
   
   
   #define COMPAT_43TTY
   
 #include <assert.h>  #include <assert.h>
   #include <syslog.h>
 #include <openssl/evp.h>  #include <openssl/evp.h>
   #include <openssl/aes.h>
   #include <sys/tty.h>
   #include <sys/ioctl_compat.h>
   #include <sys/socket.h>
   #include <sys/un.h>
   #include <sys/uio.h>
   #include <net/if_dl.h>
   #include <net/bpf.h>
   #include <netinet/in.h>
   #include <elwix.h>
   #include <aitsched.h>
   
   
#define VACUUM_LEFT     1#ifndef STRSIZ
#define VACUUM_BETWEEN  2#define STRSIZ                  256
 #endif
   
/* AIT arrays */#define IO_SOCK_ROLE_CLIENT     0
 #define IO_SOCK_ROLE_SERVER     1
   
typedef void ** sarr_seg_t;#define IO_ETHER_FILTER_PROMISC 0
typedef struct _tagSplitArray {#define IO_ETHER_FILTER_NOTREAD -1
        int             sarr_num;#define IO_ETHER_FILTER_READ    1
        int             sarr_seg;#define IO_ETHER_FILTER_WRITE   2
        int             sarr_siz; 
        sarr_seg_t      *sarr_data; 
} sarr_t; 
   
 typedef struct _tagArray {  
         int     arr_num;  
         void    **arr_data;  
 } array_t;  
   
/* URL staff ... */typedef struct tagCliSock sock_cli_t;
 typedef void *(*sock_cb_t)(sock_cli_t*);
 struct tagCliSock {
         void                            *cli_parent;
         int                             cli_fd;
         int                             cli_pty;
         sockaddr_t                      cli_addr;
         char                            cli_name[64];
         char                            cli_cmdline[PATH_MAX];
         pid_t                           cli_pid;
   
typedef struct _tagURLItem {        sched_task_func_t               cli_func;
        int     vallen; 
        char    *value; 
} url_Item_t; 
   
struct tagIOURL {        ait_val_t                       cli_buf[2];
        unsigned char   url_line[BUFSIZ]; 
   
        url_Item_t      url_tech;        TAILQ_ENTRY(tagCliSock)         cli_node;
        url_Item_t      url_user; 
        url_Item_t      url_pass; 
        url_Item_t      url_host; 
        url_Item_t      url_port; 
        url_Item_t      url_path; 
        url_Item_t      url_args; 
 
        char            *url_reserved; 
 };  };
   
 struct tagReqXML {  
         unsigned char   xml_line[BUFSIZ];  
   
         url_Item_t      xml_namespace;  
         union {  
                 url_Item_t      container;  
                 url_Item_t      path;  
         }               xml_node;  
         url_Item_t      xml_data;  
         url_Item_t      xml_attribute;  
         url_Item_t      xml_value;  
 };  
   
 /* AIT RPC variables and managment */  
   
 typedef enum {  
         empty,                          /* empty -> variable is not set */  
         buffer, string, blob,           /* buffer -> uint8_t*; string -> int8_t*; blob -> void*(+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;        int                             sock_role;
        uint32_t        val_len;        int                             sock_backq;
        union {        int                             sock_type;
                uint64_t        net;        int                             sock_proto;
         int                             sock_fd;
         struct timespec                 sock_timeout;
         sockaddr_t                      sock_addr;
         sockaddr_t                      sock_peer;
   
                uint8_t         *buffer;        ait_val_t                       sock_buf;
                int8_t          *string; 
                uint32_t        blob; 
                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; 
} __packed ait_val_t; 
   
#define AIT_TYPE(_vl)                   ((ait_type_t) (_vl)->val_type)        volatile intptr_t               sock_kill;
#define AIT_LEN(_vl)                    (_vl)->val_len        sched_root_task_t               *sock_root;
#define AIT_BLOB_CHUNKS(_vl, _n)        (assert((_vl)), AIT_LEN((_vl)) / _n + (AIT_LEN((_vl)) % _n) ? 1 : 0) 
#define AIT_ISEMPTY(_vl)                (assert((_vl)), AIT_TYPE((_vl)) == empty) 
   
#define AIT_GET_BUF(_vl)                (assert((_vl)), assert(AIT_TYPE((_vl)) == buffer), (_vl)->val.buffer)        pthread_mutex_t                 sock_mtx;
#define AIT_GET_STR(_vl)                (assert((_vl)), assert(AIT_TYPE((_vl)) == string), (_vl)->val.string)        TAILQ_HEAD(, tagCliSock)        sock_cli;
#define AIT_GET_BLOB(_vl)               (assert((_vl)), assert(AIT_TYPE((_vl)) == blob), (_vl)->val.blob)} sock_t;
#define AIT_GET_U8(_vl)                 (assert((_vl)), assert(AIT_TYPE((_vl)) == u8), (_vl)->val.u8) 
#define AIT_GET_U16(_vl)                (assert((_vl)), assert(AIT_TYPE((_vl)) == u16), (_vl)->val.u16) 
#define AIT_GET_U32(_vl)                (assert((_vl)), assert(AIT_TYPE((_vl)) == u32), (_vl)->val.u32) 
#define AIT_GET_U64(_vl)                (assert((_vl)), assert(AIT_TYPE((_vl)) == u64), (_vl)->val.u64) 
#define AIT_GET_I8(_vl)                 (assert((_vl)), assert(AIT_TYPE((_vl)) == i8), (_vl)->val.i8) 
#define AIT_GET_I16(_vl)                (assert((_vl)), assert(AIT_TYPE((_vl)) == i16), (_vl)->val.i16) 
#define AIT_GET_I32(_vl)                (assert((_vl)), assert(AIT_TYPE((_vl)) == i32), (_vl)->val.i32) 
#define AIT_GET_I64(_vl)                (assert((_vl)), assert(AIT_TYPE((_vl)) == i64), (_vl)->val.i64) 
#define AIT_GET_F32(_vl)                (assert((_vl)), assert(AIT_TYPE((_vl)) == f32), (_vl)->val.f32) 
#define AIT_GET_F64(_vl)                (assert((_vl)), assert(AIT_TYPE((_vl)) == f64), (_vl)->val.f64) 
   
 #define AIT_SET_BUF(_vl, _v, _len)      do { ait_val_t *__val = (_vl); assert(__val); assert((_v)); \  
                                                 __val->val.buffer = malloc(_len); \  
                                                 if (__val->val.buffer) { \  
                                                         __val->val_type = buffer; AIT_LEN(__val) = _len; \  
                                                         memcpy(__val->val.buffer, (_v), _len); \  
                                                 } } while (0)  
 #define AIT_SET_STR(_vl, _v)            do { ait_val_t *__val = (_vl); assert(__val); \  
                                                 __val->val.string = (int8_t*) strdup((_v)); \  
                                                 if (__val->val.string) { \  
                                                         __val->val_type = string; \  
                                                         AIT_LEN(__val) = strlen((_v)) + 1; \  
                                                 } } while (0)  
 #define AIT_SET_BLOB(_vl, _n, _len)     do { ait_val_t *__val = (_vl); assert(__val); \  
                                                 __val->val_type = blob; AIT_LEN(__val) = _len; \  
                                                 __val->val.blob = _n; } 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_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)  
   
                                         /* if attribute zeroCopy is set not execute free() */  
 #define AIT_FREE_VAL(_vl)               do { ait_val_t *__val = (_vl); assert(__val); \  
                                                 switch (__val->val_type) { \  
                                                         case buffer: \  
                                                                 if (__val->val.buffer) { \  
                                                                         free(__val->val.buffer); \  
                                                                         __val->val.buffer = NULL; \  
                                                                 } \  
                                                                 break; \  
                                                         case string: \  
                                                                 if (__val->val.string) { \  
                                                                         free(__val->val.string); \  
                                                                         __val->val.string = NULL; \  
                                                                 } \  
                                                                 break; \  
                                                         default: \  
                                                                 break; \  
                                                 } \  
                                                 __val->val_type = empty; \  
                                                 AIT_LEN(__val) = 0; \  
                                         } while (0)  
   
   
 // 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_vals2buffer() Marshaling data from array with variables to buffer * ioInitSocket() - Init socket and allocate resources
 * @buf = Buffer *
 * @buflen = Size of buffer * @role = Socket role
 * @vars = Variable array * @type = Socket type
 * return: -1 error, 0 nothing done or >0 size of marshaled data * @proto = Socket protocol
  * @addr = Bind to address
  * @port = Bind to port
  * @buflen = Socket buffer, optional if =0 == BUFSIZ
  * return: NULL error or !=NULL created socket
  */   */
int io_vals2buffer(unsigned char *buf, int buflen, array_t *vars);sock_t *ioInitSocket(int role, int type, int proto, 
                 const char *addr, unsigned short port, size_t buflen);
 /*  /*
 * io_buffer2vals() De-marshaling data from buffer to array with variables * ioCloseSocket() - Close socket and free resources
 * @buf = Buffer *
 * @buflen = Size of buffer * @s = Socket
 * @vnum = Number of variables into buffer * return: none
 * @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() 
  */   */
array_t *io_buffer2vals(unsigned char *buf, int buflen, int vnum, int zcpy);void ioCloseSocket(sock_t ** __restrict s);
 #define ioKillSocket(x)         (assert((x)), (x)->sock_kill = 1)
 /*
  * ioCloseClient() - Close client socket
  *
  * @c = Client socket
  * return: 0 ok or !=0 error
  */
 int ioCloseClient(sock_cli_t * __restrict c);
 /*
  * ioUpSocket() - Setup socket for use
  *
  * @s = Socket
  * @arg = Server role = listen backlog queue and Client role = peer address
  * @timeout = Socket timeout in ms (default -1 infinit)
  * return: -1 error or 0 ok
  */
 int ioUpSocket(sock_t * __restrict s, void *arg, int timeout);
 /*
  * ioUpdTimerSocket() - Update timeout of socket
  *
  * @c = Client socket
  * return:  none
  */
 void ioUpdTimerSocket(sock_cli_t * __restrict c);
 /*
  * ioLoopSocket() - Start socket scheduler
  *
  * @s = Socket
  * @rcb = Read callback
  * return: -1 error or return result from scheduler
  */
 int ioLoopSocket(sock_t * __restrict s, sched_task_func_t rcb);
 /*
  * ioBridgeProg2Socket() - Start socket scheduler and bridge program to socket
  *
  * @s = Socket
  * @prgname = Program name
  * return: 0 ok or !=0 error
  */
 int ioBridgeProg2Socket(sock_t * __restrict s, const char *prgname);
   
 /*  /*
 * ioPromptRead() Read data from input h[0] with prompt to output h[1] * ioPromptRead() - Read data from input h[0] with prompt to output h[1]
  *
  * @h = file handles h[0] = input, h[1] = output, if NULL use stdin, stdout   * @h = file handles h[0] = input, h[1] = output, if NULL use stdin, stdout
  * @csPrompt = Prompt before input, may be NULL   * @csPrompt = Prompt before input, may be NULL
  * @psData = Readed data   * @psData = Readed data
  * @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]
  *
  * @h = file handles h[0] = input, h[1] = output, if NULL use stdin, stdout   * @h = file handles h[0] = input, h[1] = output, if NULL use stdin, stdout
  * @csPrompt = Prompt before input, may be NULL   * @csPrompt = Prompt before input, may be NULL
  * @psPass = Readed password   * @psPass = Readed password
Line 270  int ioPromptRead(int *h, const char *csPrompt, char *  Line 204  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 free after use!  
 */  
 char *ioRegexReplace(const char *csRegex, const char *csData, const char *csNew);  
   
 /*  /*
 * ioVarAst() Function for evaluate string like asterisk variable "{text[:[-]#[:#]]}" * ioMkDir() - Function for racursive directory creation and validation
 * @csString = Input string *
 * return: NULL error, !=NULL Allocated new string evaluated from input string, must be free() * @csDir = Full directory path
  * @mode = Mode for directory creation if missing dir
  * return: -1 error, 0 directory path exist, >0 created missing dirs
 */  */
char *ioVarAst(const char *csString);int ioMkDir(const char *csDir, int mode);
   
 /*  /*
 * io_Path2File() Parse and make path/filename pair * ioWatchDirLoop() - Function for watching changes in directory and fire callback
 * @csArgs = Input argument line *
 * @psPath = Output Path, if ==NULL path not returned * @csDir = Full directory path
 * @pathLen = Size of path array * @callback = Callback if raise event! nOp -1 delete, 0 change/move, 1 create
 * @psFile = Output File * return: -1 error, !=-1 ok, number of total signaled events
 * @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, int ioWatchDirLoop(const char *csDir, int (*callback)(const char *csName, int nOp));
                char * __restrict psFile, int fileLen); 
   
   
   #ifdef AIO_OPS
 /*  /*
 * io_UnquotStr() Remove quots from input text string  * io_aiobulk() - AIO bulk R/W function
 * @psLine = Text string *
 * return: 0 nothing to do; 1 successful unquoted string * @mode = Bulk wait mode
*/ * @acbs = List of aiocb structures
inline int io_UnquotStr(unsigned char * __restrict psLine); * @nacb = Number of aiocb in list
  * @sig = Event for completed operations, may be =NULL
  * return: -1 error or 0 ok
  */
 int io_aiobulk(int mode, struct aiocb ** __restrict acbs, int nacb, 
                 struct sigevent *sig);
 #endif
 /*  /*
 * io_LTrimStr() Remove left whitespaces from text string * io_rreadv() - Raw VFS bulk read function
 * @psLine = Text string *
 * return: 0 nothing to do; !=0 Removed bytes * @fd = File handle
*/ * @bufs = Read buffers
inline int io_LTrimStr(unsigned char * __restrict psLine); * @nbufs = Number of read buffers
  * @offset = Read from position, if -1 read nbytes from current position
  * @update = Update file handle position !0
  * return: -1 error or !=-1 readed bytes
  */
 int io_rreadv(int fd, struct iovec * __restrict bufs, int nbufs, off_t offset, 
                 int update);
 /*  /*
 * io_RTrimStr() Remove right whitespaces from text string * io_rwritev() - Raw VFS bulk write function
 * @psLine = Text string *
 * return: 0 nothing to do; !=0 Removed bytes * @fd = File handle
*/ * @bufs = Write buffers
inline int io_RTrimStr(unsigned char * __restrict psLine); * @nbufs = Number of write buffers
  * @offset = Write to position, if -1 write nbytes to current position
  * @update = Update file handle position !0
  * return: -1 error or !=-1 written bytes
  */
 int io_rwritev(int fd, struct iovec * __restrict bufs, int nbufs, off_t offset, 
                 int update);
 /*  /*
 * io_TrimStr() Remove left and right whitespaces from text string * io_rread() - Raw VFS read function
 * @psLine = Text string *
 * return: 0 nothing to do; !=0 Removed bytes * @fd = File handle
*/ * @buf = Read buffer
inline int io_TrimStr(unsigned char * __restrict psLine); * @nbytes = Read buffer size
  * @offset = Read from position, if -1 read nbytes from current position
  * @update = Update file handle position !0
  * return: -1 error or !=-1 readed bytes
  */
 int io_rread(int fd, void * __restrict buf, size_t nbytes, off_t offset, 
                 int update);
 /*  /*
 * io_Ch2Hex() Convert from Char string to Hex string * io_rwrite() - Raw VFS write function
 * @psLine = Text string *
 * @lineLen = Length of Text string * @fd = File handle
 * return: NULL nothing to do or error; !=0 Allocated new converted data without term\0 (must be free) * @buf = Write buffer
*/ * @nbytes = Write bytes from buffer
inline unsigned char *io_Ch2Hex(unsigned char *psLine, int lineLen); * @offset = Write at position, if -1 write nbytes from current position
  * @update = Update file handle position !0
  * return: -1 error or !=-1 written bytes
  */
 int io_rwrite(int fd, void * __restrict buf, size_t nbytes, off_t offset, 
                 int update);
 
 /* Disk I/O helper macros */
 #define io_read(f, b, n) io_rread(f, b, n, -1, 1)
 #define io_write(f, b, n) io_rwrite(f, b, n, -1, 1)
 
 
 /* Crypto framework */
 
 /*  /*
 * io_Hex2Ch() Convert from Hex string to Char string * ioCipher() - Cipher wrapper for all supported crypto algorythms
 * @psLine = Text string *
 * @lineLen = Length of Text string * @pInput = input buffer
 * return: NULL nothing to do or error; !=0 Allocated new converted string(must be free) * @inLen = input buffer len
  * @ppOutput = output allocated buffe, must be e_free after use
  * @Cipher = cipher engine, like EVP_bf_cbc() or etc...
  * @pKey = key
  * @pIV = IV, salt (8 bytes)
  * @nMode = Mode 0 - decrypting or 1 - encrypting
  * return: 0 not present data or error!; >0 number of processed and returned bytes into ppOutput
 */  */
inline char *io_Hex2Ch(unsigned char *psLine, int lineLen);int ioCipher(unsigned char *pInput, int inLen, unsigned char **ppOutput, const EVP_CIPHER *Cipher, 
                 unsigned char *pKey, unsigned char *pIV, int nMode);
   
 /*  /*
 * io_arrayInit() - Create and initialize dynamic array * io_Blowfish() - Blowfish cipher algorythm, work with ASCII hex strings
 * @numItems = Number of Items *
 * return: NULL error, != NULL allocated memory for array * @pInput = input buffer
  * @inLen = input buffer len
  * @ppOutput = output allocated buffe, must be e_free after use
  * @pKey = key
  * @pIV = IV, salt (8 bytes)
  * @nMode = Mode 0 - decrypting or 1 - encrypting
  * return: 0 not present data or error!; >0 number of processed and returned bytes into ppOutput
 */
 int io_Blowfish(unsigned char *pInput, int inLen, unsigned char **ppOutput, 
                 unsigned char *pKey, unsigned char *pIV, int nMode);
 /*
  * io_ctr_AES() - Encrypt/Decrypt stream cipher CTR_AES
  *
  * @pInput = Input buffer with ASCII
  * @inLen = Input buffer data length
  * @ppOutput = Output buffer with cipher data, must be e_free after use
  * @pKey = Key
  * @IV = IVector/Nonce/Counter, Warning: IV must be variable, because we write there!!!
  * return: -1 error or >-1 how many cipher blocks proceeded
  */   */
inline array_t *io_arrayInit(int numItems);int io_ctr_AES(unsigned char *pInput, int inLen, unsigned char **ppOutput, 
                 unsigned char *pKey, unsigned char IV[AES_BLOCK_SIZE]);
 
 
 /*  /*
 * io_arrayDestroy() - Free and destroy dynamic array * ioAllocPTY() - Allocate new PTY and TTY
 * @parr = Array *
 * return: none * @ptyfd = master fd, pty
  * @ttyfd = slave fd, tty
  * @name = tty device name if not null
  * @namesiz = name length, must be above 63 bytes.
  * @term = termios for terminal
  * @winz = winsize for terminal
  * return: -1 error or 0 ok
  */   */
inline void io_arrayDestroy(array_t ** __restrict parr);int ioAllocPTY(int *ptyfd, int *ttyfd, char * __restrict name, int namesiz, 
                 struct termios * __restrict term, struct winsize * __restrict winz);
 /*  /*
 * io_arrayFree() - Free all data in dynamic array items * ioFreePTY() - Release PTY and TTY device
 *      (WARNING! If assign static array dont use this!!!) *
 * @arr = Array * @ptyfd = master fd, pty (==-1 skip closing pty)
  * @ttyname = tty filename
  * return: none   * return: none
  */   */
inline void io_arrayFree(array_t * __restrict arr);void ioFreePTY(int ptyfd, const char *ttyname);
 /*  /*
 * io_arrayFrom() - Create and fill array from array with pointers * ioChgWinPTY() - Change window size of PTY
 * @pargv = Array with pointers *
 * @argc = Number of Items, if 0 walk through argv and stop when reach NULL item * @ptyfd = master fd, pty
 * return: NULL error, != NULL allocated new array * @row = row
  * @col = col
  * @xpxl = x pixels
  * @ypxl = y pixels
  * return: -1 error or 0 ok
  */   */
inline array_t *io_arrayFrom(const char *** __restrict pargv, int argc);int ioChgWinPTY(int ptyfd, unsigned short row, unsigned short col, 
                 unsigned short xpxl, unsigned short ypxl);
 /*  /*
 * io_arrayTo() - Create and fill array with pointers from dynamic array * ioSetOwnerTTY() - Set owner to TTY
 * @arr = Array *
 * return: NULL error, != NULL allocated memory for array, NULL terminated * @ttyname = tty filename
  * @UID = uid
  * @GID = gid
  * return: -1 error or 0 ok
  */   */
inline char **io_arrayTo(array_t * __restrict arr);int ioSetOwnerTTY(const char *ttyname, uid_t UID, gid_t GID);
 /*  /*
 * io_arrayLen() - Get last used element in dynamic array (array Length) * ioSetSidTTY() - Makes the process's controlling TTY and sets it to sane modes.
 * @arr = Array *
 * return: -1 error, 0 empty or >0 position of last used element * @ttyfd = slave fd, tty
  * @ttyname = tty filename
  * return: -1 error or 0 ok
  */   */
inline int io_arrayLen(array_t * __restrict arr);int ioSetSidTTY(int *ttyfd, const char *ttyname);
 /*  /*
 * io_arrayConcat() Concat source array to destination array * ioSetRAWMode() - Enter into RAW mode
 * @dest = Destination array *
 * @src = Source array * @fd = tty fd
 * return: -1 error; >0 new count of destination array * @otio = saved old termios for later restore if !=NULL
  * return: -1 error or 0 ok
  */   */
int io_arrayConcat(array_t * __restrict dest, array_t * __restrict src);int ioSetRAWMode(int fd, struct termios *otio);
 /*  /*
 * io_arrayCopy() Copy source array to destination array * ioRestoreMode() - Restore termios to tty fd
 * @dest = Destination array, after use free with io_arrayDestroy() *
 * @src = Source array * @fd = tty fd
 * return: -1 error; >0 count of destination array * @tio = termios structure for restore
  * return: -1 error or 0 ok
  */   */
int io_arrayCopy(array_t ** __restrict dest, array_t * __restrict src);int ioRestoreMode(int fd, struct termios tio);
 /*  /*
 * io_arrayGrow() - Grow/Shrink dynamic array, Use with care when it shrink!!! * ioForkPTY() - Fork new process with session leader and new TTY
 * @arr = Array *
 * @newNumItems = Number of Items * @ptyfd = master fd, pty
 * @freeShrink = Free elements before shrink array * @name = tty device name if not null
 * return: -1 error, 0 ok * @namesiz = name length, must be above 63 bytes.
  * @term = termios for terminal
  * @winz = winsize for terminal
  * @otio = old termios structure for restore
  * return: -1 error, 0 child process or >0 parent: pid of child
  */   */
int io_arrayGrow(array_t * __restrict arr, int newNumItems, int freeShrink);pid_t ioForkPTY(int *ptyfd, char * __restrict name, int namesiz, struct termios * __restrict term, 
                 struct winsize * __restrict winz, struct termios * __restrict otio);
 
 /*  /*
 * io_arrayVacuum() - Vacuum dynamic array, empty elements will be deleted * ioCreatePIDFile() - Create PID file
 * @arr = Array *
 * @fromWhere = 1 begin, 2 ALL empty elements * @csName = PID filename
 * return: -1 error, 0 ok * @ifExists = !=0 if filename exists return error
  * return: -1 error or 0 ok
  */   */
int io_arrayVacuum(array_t * __restrict arr, int fromWhere);int ioCreatePIDFile(const char *csName, int ifExists);
   
 #define io_arraySize(_arr)              ((_arr) ? (_arr)->arr_num : 0)  
 #define io_arrayZero(_arr)              (assert((_arr)), memset((_arr)->arr_data, 0, \  
                                                 io_arraySize((_arr)) * sizeof(void*)))  
   
 #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); \  
                                                 *((_arr)->arr_data + _d) = (void*) (_ptr); \  
                                         } while (0)  
 #define io_arrayDel(_arr, _d, _fri)     do { \  
                                                 assert((_arr) && (_arr)->arr_num > _d); \  
                                                 if (_fri) \  
                                                         free(*((_arr)->arr_data + _d)); \  
                                                 *((_arr)->arr_data + _d) = NULL; \  
                                         } while (0)  
   
 /*  /*
 * io_arrayPush() - Push element into dynamic array like stack manner, place at first empty position * ioSendFile() - AITNET sendfile() userland implementation, not dependant from OS
 * @arr = Array *
 * @data = Element, if set NULL return only first empty position * @s = socket
 * return: -1 not found empty position, array is full!, >-1 return position of stored element into array * @csFile = file for send
  * @sendLen = bytes to send, if 0 send all data
  * @offset = start file offset
  * @sndbuf = SO_SNDBUF value, if 0 use default
  * return: 0 error, >0 ok, sended bytes
  */   */
inline int io_arrayPush(array_t * __restrict arr, void **data);size_t ioSendFile(int s, const char *csFile, size_t sendLen, off_t offset, int sndbuf);
 /*  /*
 * io_arrayPop() - Pop element from dynamic array like stack manner, last used position * ioRecvFile() - Receive file from socket, fastest (zero-copy) way
 * @arr = Array *
 * @data = Element, if set NULL return only last used position * @s = socket
 * @delAfter = Delete after Pop element, !=0 delete element from array after return data * @csFile = file for receive
 * return: -1 not found used position, array is empty!, >-1 return element position * @recvLen = receive bytes
  * @over = overwrite file if exists with mode like 0644
  * @rcvbuf = SO_RCVBUF value, if 0 use default
  * return: 0 error, >0 ok, received bytes
  */   */
inline int io_arrayPop(array_t * __restrict arr, void ** __restrict data, int delAfter);size_t ioRecvFile(int s, const char *csFile, size_t recvLen, int over, int rcvbuf);
   
 /*  /*
 * io_argsNum() Parse and calculate number of arguments * ioRealFileName() - Get real file name
 * @csArgs = Input arguments line *
 * @csDelim = Delimiter(s) for separate * @fname = filename
 * return: 0 error format; -1 error:: can`t read; >0 ok, number of items * return: =NULL error or !=NULL real filename, should be free with e_free()
  */   */
inline int io_argsNum(const char *csArgs, const char *csDelim);char *ioRealFileName(const char *fname);
   
/*/* Buffered file access over memory block */
 * 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 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 * io_fmemopen() - File buffered stream operations over memory block
 * @csArgs = Input argument line *
 * @csDelim = Delimiter for separate * @base = Base address of memory block, if =NULL Infinit length(auto-grow)
 * @psAttr = Output Attribute * @basesize = Size of memory block
 * @attrLen = Size of attribute array * return: NULL error or !=NULL Opened file resource
 * @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_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);FILE *io_fmemopen(void ** __restrict base, off_t basesize);
 /*  /*
 * io_sarrDestroy() - Free all data in dynamic split-order array and Destroy array * io_fmapopen() - File buffered stream operations over MMAP block
 * @parr = Array *
 * return: none * @csFile = Filename for MMAP, if =NULL private MMAP block
  * @mode = File open mode
  * @perm = If file not exists will be created with this access permissions
  * @prot = MMAP protection
  * @flags = MMAP mode flags
  * @offset = Map from file offset, if csFile==NULL then this is size of MMAP private block
  * return: NULL error or !=NULL Opened file resource
  */   */
inline void io_sarrDestroy(sarr_t ** __restrict parr);FILE *io_fmapopen(const char *csFile, int mode, int perm, int prot, int flags, off_t offset);
 /*  /*
 * io_sarrGrow() - Grow/Shrink dynamic split-order array, Use with care when it shrink!!! * io_fd2buf() - Convert open file handle to buffered file I/O
 * @arr = Array *
 * @newNumItems = Number of Items * @fd = File handle
 * return: -1 error, 0 ok * @mode = Permissions for new buffered file I/O
  * return: NULL error or open buffered file
  */   */
int io_sarrGrow(sarr_t * __restrict arr, int newNumItems);FILE *io_fd2buf(int fd, const char *mode);
 /*  /*
 * io_sarrVacuum() - Vacuum dynamic split-order array, empty segments will be freed * io_dumbFile() - Create empry or dumb file with fixed size
 * @arr = Array *
 * return: -1 error, >-1 freed segments * @csFile = Filename for create
  * @mode = File access permissions
  * @size = File size
  * return: -1 error or open file handle
  */   */
inline int io_sarrVacuum(sarr_t * __restrict arr);int io_dumbFile(const char *csFile, int mode, off_t size);
#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 * io_get1stiface() - Get first interface of host
 * @dest = Destination split array, after use free with io_sarrDestroy() *
 * @src = Source split array * @szIface = interface string buffer
 * return: -1 error; >0 count of destination split array * @iflen = size of interface buffer
  * return: -1 error or 0 ok
  */   */
int io_sarrCopy(sarr_t ** __restrict dest, sarr_t * __restrict src);int io_get1stiface(char *szIface, int iflen);
 /*  /*
 * io_sarrGet() - Get element from dynamic split-order array * io_getmaciface() - Get MAC address from interface name
 * @arr = Array *
 * @idx = Index (warning 1st element is at position 1) * @csIface = interface name
 * return: NULL not found, !=NULL element * @ea = ethernet address
  * return: -1 error, 0 ok or 1 not found
  */   */
inline void *io_sarrGet(sarr_t * __restrict arr, unsigned int idx);int io_getmaciface(const char *csIface, ether_addr_t * __restrict ea);
 /*  /*
 * io_sarrGet2() - Always get element from dynamic split-order array * io_etherOpen() - Open BPF interface to device
 *      Function automatic grow array. Good use for Hash tables!  *
 * @arr = Array * @csIface = interface name
 * @idx = Index (warning 1st element is at position 1) * @flags = open flags
 * return: NULL not found, !=NULL element * @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
  */   */
void *io_sarrGet2(sarr_t * __restrict arr, unsigned int idx);int io_etherOpen(const char *csIface, int flags, int whdr, int wdlt, 
                 unsigned int *buflen, void **zcbuf);
 /*  /*
 * io_sarrSet() - Set element to dynamic split-order array * io_etherClose() - Close BPF interface
 * @arr = Array *
 * @idx = Index (warning 1st element is at position 1) * @eth = bpf handle
 * @data = Value * @zcbuf = zero copy buffer, if BPF supports it and isn't NULL
 * return: NULL error or empty, !=NULL old value in element * return: none
  */   */
inline void *io_sarrSet(sarr_t * __restrict arr, unsigned int idx, void *data);void io_etherClose(int eth, void **zcbuf);
#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 * io_etherFilter() - BPF filter routine
 * @sa = split array *
 * @sarrFree = after convert split array !=0 will be destroyed sarray * @eth = bpf handle
 * return: NULL error or != NULL new array * @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
  */   */
array_t *io_sarr2array(sarr_t ** __restrict sa, int sarrFree);int io_etherFilter(int eth, int io, struct bpf_insn * __restrict insn, size_t insnlen);
 
 /*  /*
 * io_array2sarr() - Convert from dynamic array to split-order array * io_etherSend() - Send packet to bpf
 * @a = array *
 * @segLen = Length of segment * @eth = bpf handle
 * @arrFree = after convert array !=0 will be destroyed * @buf = buffer
 * return: NULL error or != NULL new sarr * @buflen = buffer length
  * return: -1 error or !=-1 written bytes
  */   */
sarr_t *io_array2sarr(array_t ** __restrict a, int segLen, int arrFree);ssize_t io_etherSend(int eth, const void *buf, size_t buflen);
 
 /*  /*
 * io_CopyEnv() Copy environment to new environment array; * io_etherRecv() - Receive packet from bpf
 * @oldenv = Environment array *
 * return: NULL error; !=NULL Allocated new environment array(must be free) * @eth = bpf handle
*/ * @buf = buffer
char **io_CopyEnv(const char **oldenv); * @buflen = buffer length
/* * @zcbuf = zero copy buffer, if BPF supports it and isn't NULL
 * 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 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); 
 
/* 
 * ioURLGet() Parse and get data from input URL 
 * @csURL = Input URL line 
 * @url = Output parsed URL 
 * return: 0 error format not find tech:// and return URL like path;  
                -1 error:: can`t read; >0 ok, up bits for known elements 
*/ 
int ioURLGet(const char *csURL, struct tagIOURL *url); 
/* 
 * ioURLGetValue() Get value from parsed URL 
 * @url = Input parsed URL 
 * @csAttr = Attribute for search 
 * @psValue = Return value of attribute, if ==NULL only check for existence of attribute 
 * @valLen = Size of psValue array 
 * return: 0 error attribute not find; -1 error:: can`t read; >0 ok, find at position 
*/ 
int ioURLGetValue(struct tagIOURL *url, const char *csAttr, char * __restrict psValue, int valLen); 
/* 
 * ioURLGetFile() Get file from parsed URL 
 * @url = Input parsed URL 
 * @psValue = Return filename, if not specified file in url path, replace with / 
 * @valLen = Size of psValue array 
 * return: -1 error:: can`t read; 0 ok 
*/ 
int ioURLGetFile(struct tagIOURL *url, char * __restrict psValue, int valLen); 
 
 
/* 
 * ioXMLGet() Parse and get data from input XML request string [ns:]container[|attribute[=value]][?data] 
 * @csXML = Input XML request line 
 * @xml = Output parsed XML request 
 * return: 0 error format incorrect, -1 error:: can`t read; >0 ok readed elements bits 
*/ 
int ioXMLGet(const char *csXML, struct tagReqXML *xml); 
 
 
/* 
 * ioMkDir() Function for racursive directory creation and validation 
 * @csDir = Full directory path 
 * @mode = Mode for directory creation if missing dir 
 * return: -1 error, 0 directory path exist, >0 created missing dirs 
*/ 
int ioMkDir(const char *csDir, int mode); 
 
/* 
 * ioWatchDirLoop() Function for watching changes in directory and fire callback 
 * @csDir = Full directory path 
 * @callback = Callback if raise event! nOp -1 delete, 0 change/move, 1 create 
 * return: -1 error, !=-1 ok, number of total signaled events 
*/ 
int ioWatchDirLoop(const char *csDir, int (*callback)(const char *csName, int nOp)); 
 
 
/* 
 * io_rread() Raw VFS read function 
 * @fd = File handle 
 * @buf = Read buffer 
 * @nbytes = Read buffer size 
 * @offset = Read from position, if -1 read nbytes from current position 
 * @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 update);ssize_t io_etherRecv(int eth, void * __restrict buf, 
/*                size_t buflen, void * __restrict zcbuf);
 * io_rwrite() Raw VFS write function 
 * @fd = File handle 
 * @buf = Write buffer 
 * @nbytes = Write bytes from buffer 
 * @offset = Write at position, if -1 write nbytes from current position 
 * @update = Update file handle position !0 
 * return: -1 error or !=-1 writed bytes 
 */ 
inline int io_rwrite(int fd, void * __restrict buf, size_t nbytes, off_t offset, int update); 
 
/* Disk I/O helper macros */ 
#define io_read(f, b, n) io_rread(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_initDebug(x)         io_Debug = (x); 
#define io_addDebug             io_Debug++ 
#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, "ioDebug(%d):%s(%d): %s\n", \ 
                                                                (x), __func__, __LINE__, str); \ 
                                } while (0) 
 
#define ioERROR(x, fmt, ...)    do { \ 
                                        assert((fmt)); \ 
                                        char str[STRSIZ] = { 0 }; \ 
                                        snprintf(str, sizeof str, (fmt), ##__VA_ARGS__); \ 
                                        syslog(LOG_ERR, "ioError():%s(%d): #%d - %s\n", \ 
                                                         __func__, __LINE__, (x), str); \ 
                                } while (0) 
#define io_sysERROR(x)          do { \ 
                                        if (x > 0 || errno) \ 
                                                syslog(LOG_ERR, "ioError(sys):%s(%d): #%d - %s\n", \ 
                                                                __func__, __LINE__, x > 0 ? x : errno, \ 
                                                                strerror(x > 0 ? x : errno)); \ 
                                } while (0) 
#define io_aitERROR(ait)        do { \ 
                                        if (ait##_GetErrno()) \ 
                                                syslog(LOG_ERR, "ioError(ait):%s(%d): #%d - %s\n", \ 
                                                                __func__, __LINE__, ait##_GetErrno(), \ 
                                                                ait##_GetError()); \ 
                                } while (0) 
 
 
/* Crypto framework */ 
 
/* 
 * ioCipher() Cipher wrapper for all supported crypto algorythms 
 * @pInput = input buffer 
 * @inLen = input buffer len 
 * @ppOutput = output allocated buffe, must be free after use 
 * @Cipher = cipher engine, like EVP_bf_cbc() or etc... 
 * @pKey = key 
 * @pIV = IV, salt (8 bytes) 
 * @nMode = Mode 0 - decrypting or 1 - encrypting 
 * return: 0 not present data or error!; >0 number of processed and returned bytes into ppOutput 
*/ 
int ioCipher(unsigned char *pInput, int inLen, unsigned char **ppOutput, const EVP_CIPHER *Cipher,  
                unsigned char *pKey, unsigned char *pIV, int nMode); 
 
/* 
 * io_Blowfish() Blowfish cipher algorythm, work with ASCII hex strings 
 * @pInput = input buffer 
 * @inLen = input buffer len 
 * @ppOutput = output allocated buffe, must be free after use 
 * @pKey = key 
 * @pIV = IV, salt (8 bytes) 
 * @nMode = Mode 0 - decrypting or 1 - encrypting 
 * return: 0 not present data or error!; >0 number of processed and returned bytes into ppOutput 
*/ 
int io_Blowfish(unsigned char *pInput, int inLen, unsigned char **ppOutput,  
                unsigned char *pKey, unsigned char *pIV, int nMode); 
   
   
 #endif  #endif

Removed from v.1.11.2.10  
changed lines
  Added in v.1.38.10.1


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