--- libaitio/inc/aitio.h 2011/04/20 22:56:32 1.8 +++ libaitio/inc/aitio.h 2016/08/18 09:06:31 1.42 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitio.h,v 1.8 2011/04/20 22:56:32 misho Exp $ +* $Id: aitio.h,v 1.42 2016/08/18 09:06:31 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 +Copyright 2004 - 2016 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -47,300 +47,306 @@ SUCH DAMAGE. #define __AITIO_H +#define COMPAT_43TTY + #include +#include #include +#include +#include +#include +#include +#ifndef __linux__ +#include +#include +#include +#include +#endif +#include +#include +#include -#define VACUUM_LEFT 1 -#define VACUUM_BETWEEN 2 +#ifndef STRSIZ +#define STRSIZ 256 +#endif +#define IO_SOCK_ROLE_CLIENT 0 +#define IO_SOCK_ROLE_SERVER 1 -typedef struct _tagArray { - int arr_num; - void **arr_data; -} array_t; +#define IO_ETHER_FILTER_PROMISC 0 +#define IO_ETHER_FILTER_NOTREAD -1 +#define IO_ETHER_FILTER_READ 1 +#define IO_ETHER_FILTER_WRITE 2 -typedef struct _tagURLItem { - int vallen; - char *value; -} url_Item_t; -struct tagIOURL { - unsigned char url_line[BUFSIZ]; +typedef struct { + unsigned int prog_inin; /* init progs */ + unsigned int prog_maxn; /* max progs */ + unsigned int prog_cnum; /* current progs */ + char prog_name[PATH_MAX]; - url_Item_t url_tech; - 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; + pthread_mutex_t prog_mtx; + array_t *prog_fds; + unsigned int *prog_used; +} prog_t; - char *url_reserved; -}; +typedef struct tagCliSock sock_cli_t; +typedef void *(*sock_cb_t)(sock_cli_t*); +struct tagCliSock { + void *cli_parent; + int cli_fd; + intptr_t cli_pty; + sockaddr_t cli_addr; + char cli_name[64]; + char cli_cmdline[PATH_MAX]; + pid_t cli_pid; -struct tagReqXML { - unsigned char xml_line[BUFSIZ]; + sched_task_func_t cli_func; - 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_val_t cli_buf[2]; + + TAILQ_ENTRY(tagCliSock) cli_node; }; +typedef struct { + int sock_role; + int sock_backq; + int sock_type; + int sock_proto; + int sock_fd; + struct timespec sock_timeout; + sockaddr_t sock_addr; + sockaddr_t sock_peer; -// io_GetErrno() Get error code of last operation -inline int io_GetErrno(); -// io_GetError() Get error text of last operation -inline const char *io_GetError(); + ait_val_t sock_buf; + prog_t *sock_prog; + volatile intptr_t sock_kill; + sched_root_task_t *sock_root; -/* - * 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 - * @csPrompt = Prompt before input, may be NULL - * @psData = Readed data - * @dataLen = Length of data - * 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); -/* - * 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 - * @csPrompt = Prompt before input, may be NULL - * @psPass = Readed password - * @passLen = Length of password - * @confirm = Confirm password, 0 - get password, !=0 Ask for confirmation - * 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); + pthread_mutex_t sock_mtx; + TAILQ_HEAD(, tagCliSock) sock_cli; +} sock_t; -/* - * 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[:[-]#[:#]]}" - * @csString = Input string - * return: NULL error, !=NULL Allocated new string evaluated from input string, must be free() -*/ -char *ioVarAst(const char *csString); +// io_GetErrno() Get error code of last operation +int io_GetErrno(); +// io_GetError() Get error text of last operation +const char *io_GetError(); -/* - * 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_UnquotStr() Remove quots from input text string - * @psLine = Text string - * return: 0 nothing to do; 1 successful unquoted string -*/ -inline int io_UnquotStr(unsigned char * __restrict psLine); + * io_progInit() - Init program pool + * + * @progName = program name for execution + * @initNum = initial started programs + * @maxNum = maximum started programs + * return: NULL error or !=NULL allocated pool (must destroied with io_progDestroy()) + */ +prog_t *io_progInit(const char *progName, + unsigned int initNum, unsigned int maxNum); /* - * io_LTrimStr() Remove left whitespaces from text string - * @psLine = Text string - * return: 0 nothing to do; !=0 Removed bytes -*/ -inline int io_LTrimStr(unsigned char * __restrict psLine); + * io_progOpen() - Execute number of program(s) + * + * @prg = program pool + * @execNum = execute program(s) (0 max) + * return: -1 error, >0 executed programs + */ +int io_progOpen(prog_t * __restrict prg, unsigned int execNum); /* - * io_RTrimStr() Remove right whitespaces from text string - * @psLine = Text string - * return: 0 nothing to do; !=0 Removed bytes -*/ -inline int io_RTrimStr(unsigned char * __restrict psLine); + * io_progOpen2() - Start program from pool on first unused slot + * + * @prg = program pool + * return: -1 error, >-1 reside at slot + */ +int io_progOpen2(prog_t * __restrict prg); /* - * 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(unsigned char * __restrict psLine); + * io_progGrow() - Execute to number of programs in pool + * + * @prg = program pool + * @toNum = execute to number of programs (0 max) + * return: 0 error or nothing to do, + * >0 executed programs and abs(<0) executed programs with logged error + */ +int io_progGrow(prog_t * __restrict prg, unsigned int toNum); /* - * 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 free) -*/ -inline unsigned char *io_Ch2Hex(unsigned char *psLine, int lineLen); + * io_progVacuum() - Vacuum pool to running number of programs + * + * @prg = program pool + * @toNum = vacuum to number of programs (0 to init number) + * return: 0 error or >0 closed programs + */ +int io_progVacuum(prog_t * __restrict prg, unsigned int toNum); /* - * 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 free) -*/ -inline char *io_Hex2Ch(unsigned char *psLine, int lineLen); - + * io_progCloseAt() - Close program at pool of certain position + * + * @prg = program pool + * @idx = index at pool + * return: 0 error or !=0 closed program + */ +int io_progCloseAt(prog_t * __restrict prg, unsigned int idx); /* - * io_arrayInit() - Create and initialize dynamic array - * @numItems = Number of Items - * return: NULL error, != NULL allocated memory for array + * io_progCloseOf() - Close program at pool with certain handle + * + * @prg = program pool + * @h = handle of program + * return: 0 error, >0 closed programs */ -inline array_t *io_arrayInit(int numItems); +#ifdef POPEN_STREAM +int io_progCloseOf(prog_t * __restrict prg, FILE *h); +#else +int io_progCloseOf(prog_t * __restrict prg, int h); +#endif /* - * io_arrayDestroy() - Free all data in dynamic array and Destroy dynamic array - * @parr = Array - * return: none + * io_progClose() - Close all programs in pool + * + * @prg = program pool + * @closeNum = close program(s) (0 all) + * return: 0 error, >0 closed programs */ -inline void io_arrayDestroy(array_t ** __restrict parr); +int io_progClose(prog_t * __restrict prg, unsigned int closeNum); /* - * io_arrayFree() - Free all data in dynamic array - * (WARNING! If assign static array dont use this!!!) - * @arr = Array + * io_progDestroy() - Destroy entire program pool + * + * @pprg = program pool * return: none */ -inline void io_arrayFree(array_t * __restrict arr); +void io_progDestroy(prog_t ** __restrict pprg); + /* - * io_arrayLen() - Get last used element in dynamic array (array Length) - * @arr = Array - * return: -1 error, 0 empty or >0 position of last used element + * io_progCheck() - Check exit status of program pool + * + * @prg = program pool + * @re = resurrect program to init number + * return: -1 error or >-1 exited programs */ -inline int io_arrayLen(array_t * __restrict arr); +int io_progCheck(prog_t * __restrict prg, int re); + /* - * io_arrayGrow() - Grow/Shrink dynamic array, Use with care when it shrink!!! - * @arr = Array - * @newNumItems = Number of Items - * return: -1 error, 0 ok + * io_progAttach() - Attach to open program + * + * @prg = program pool + * @newOne = Execute new one program after attach + * return: NULL error or !=NULL attached program handle */ -int io_arrayGrow(array_t * __restrict arr, int newNumItems); +#ifdef POPEN_STREAM +FILE *io_progAttach(prog_t * __restrict prg, int newOne); +#else +int io_progAttach(prog_t * __restrict prg, int newOne); +#endif /* - * io_arrayVacuum() - Vacuum dynamic array, empty elements will be deleted - * @arr = Array - * @fromWhere = 1 begin, 2 ALL empty elements - * return: -1 error, 0 ok + * io_progDetach() - Detch from open program + * + * @prg= program pool + * @pfd = attached program handle + * return: none */ -int io_arrayVacuum(array_t * __restrict arr, int fromWhere); +#ifdef POPEN_STREAM +void io_progDetach(prog_t * __restrict prg, FILE *pfd); +#else +void io_progDetach(prog_t * __restrict prg, int pfd); +#endif -#define io_arraySize(_arr) ((assert(_arr)), _arr->arr_num) -#define io_arrayGet(_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) - /* - * 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 - * return: -1 not found empty position, array is full!, >-1 return position of stored element into array + * ioInitSocket() - Init socket and allocate resources + * + * @role = Socket role + * @type = Socket type + * @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 */ -inline int io_arrayPush(array_t * __restrict arr, void **data); +sock_t *ioInitSocket(int role, int type, int proto, + const char *addr, unsigned short port, size_t buflen); /* - * io_arrayPop() - Pop element from dynamic array like stack manner, last used position - * @arr = Array - * @data = Element, if set NULL return only first empty 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 + * ioCloseSocket() - Close socket and free resources + * + * @s = Socket + * return: none */ -inline int io_arrayPop(array_t * __restrict arr, void ** __restrict data, int delAfter); - +void ioCloseSocket(sock_t ** __restrict s); +#define ioKillSocket(x) (assert((x)), (x)->sock_kill = 1) /* - * 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 + * ioCloseClient() - Close client socket + * + * @c = Client socket + * return: 0 ok or !=0 error */ -inline int io_argsNum(const char *csArgs, const char *csDelim); - +int ioCloseClient(sock_cli_t * __restrict c); /* - * 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 + * ioSetupProg2Socket() - Setup program pool to socket server + * + * @s = Socket + * @p = Program pool + * return: -1 error or 0 ok */ -int io_arrayMake(char * __restrict psArgs, int nargs, const char *csDelim, - array_t ** __restrict parr); - +int ioSetupProg2Socket(sock_t * __restrict s, prog_t * __restrict p); /* - * 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); - - + * 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); /* - * 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); + * ioUpdTimerSocket() - Update timeout of socket + * + * @c = Client socket + * return: none + */ +void ioUpdTimerSocket(sock_cli_t * __restrict c); /* - * 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); + * 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); /* - * 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); + * 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); /* - * 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 + * 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 + * @csPrompt = Prompt before input, may be NULL + * @psData = Readed data + * @dataLen = Length of data + * return: 0 EOF; -1 error:: can`t read; >0 count of readed chars */ -int ioXMLGet(const char *csXML, struct tagReqXML *xml); +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] + * + * @h = file handles h[0] = input, h[1] = output, if NULL use stdin, stdout + * @csPrompt = Prompt before input, may be NULL + * @psPass = Readed password + * @passLen = Length of password + * @confirm = Confirm password, 0 - get password, !=0 Ask for confirmation + * 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); /* - * ioMkDir() Function for racursive directory creation and validation + * 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 @@ -348,7 +354,8 @@ int ioXMLGet(const char *csXML, struct tagReqXML *xml) int ioMkDir(const char *csDir, int mode); /* - * ioWatchDirLoop() Function for watching changes in directory and fire callback + * 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 @@ -356,74 +363,81 @@ int ioMkDir(const char *csDir, int mode); int ioWatchDirLoop(const char *csDir, int (*callback)(const char *csName, int nOp)); +#ifdef AIO_OPS /* - * io_rread() Raw VFS read function + * io_aiobulk() - AIO bulk R/W function + * + * @mode = Bulk wait mode + * @acbs = List of aiocb structures + * @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_rreadv() - Raw VFS bulk read function + * * @fd = File handle + * @bufs = Read buffers + * @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_rwritev() - Raw VFS bulk write function + * + * @fd = File handle + * @bufs = Write buffers + * @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_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 */ -inline int io_rread(int fd, void * __restrict buf, size_t nbytes, off_t offset, int update); +int io_rread(int fd, void * __restrict buf, size_t nbytes, off_t offset, + int update); /* - * io_rwrite() Raw VFS write function + * 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 + * return: -1 error or !=-1 written bytes */ -inline int io_rwrite(int fd, void * __restrict buf, size_t nbytes, off_t offset, int update); +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, STRSIZ, (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, STRSIZ, (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 + * ioCipher() - Cipher wrapper for all supported crypto algorythms + * * @pInput = input buffer * @inLen = input buffer len - * @ppOutput = output allocated buffe, must be free after use + * @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) @@ -434,10 +448,11 @@ int ioCipher(unsigned char *pInput, int inLen, unsigne unsigned char *pKey, unsigned char *pIV, int nMode); /* - * io_Blowfish() Blowfish cipher algorythm, work with ASCII hex strings + * 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 + * @ppOutput = output allocated buffe, must be e_free after use * @pKey = key * @pIV = IV, salt (8 bytes) * @nMode = Mode 0 - decrypting or 1 - encrypting @@ -445,6 +460,238 @@ int ioCipher(unsigned char *pInput, int inLen, unsigne */ 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 + */ +int io_ctr_AES(unsigned char *pInput, int inLen, unsigned char **ppOutput, + unsigned char *pKey, unsigned char IV[AES_BLOCK_SIZE]); + + +/* + * ioAllocPTY() - Allocate new PTY and TTY + * + * @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 + */ +int ioAllocPTY(int *ptyfd, int *ttyfd, char * __restrict name, int namesiz, + struct termios * __restrict term, struct winsize * __restrict winz); +/* + * ioFreePTY() - Release PTY and TTY device + * + * @ptyfd = master fd, pty (==-1 skip closing pty) + * @ttyname = tty filename + * return: none + */ +void ioFreePTY(int ptyfd, const char *ttyname); +/* + * ioChgWinPTY() - Change window size of PTY + * + * @ptyfd = master fd, pty + * @row = row + * @col = col + * @xpxl = x pixels + * @ypxl = y pixels + * return: -1 error or 0 ok + */ +int ioChgWinPTY(int ptyfd, unsigned short row, unsigned short col, + unsigned short xpxl, unsigned short ypxl); +/* + * ioSetOwnerTTY() - Set owner to TTY + * + * @ttyname = tty filename + * @UID = uid + * @GID = gid + * return: -1 error or 0 ok + */ +int ioSetOwnerTTY(const char *ttyname, uid_t UID, gid_t GID); +/* + * ioSetSidTTY() - Makes the process's controlling TTY and sets it to sane modes. + * + * @ttyfd = slave fd, tty + * @ttyname = tty filename + * return: -1 error or 0 ok + */ +int ioSetSidTTY(int *ttyfd, const char *ttyname); +/* + * ioSetRAWMode() - Enter into RAW mode + * + * @fd = tty fd + * @otio = saved old termios for later restore if !=NULL + * return: -1 error or 0 ok + */ +int ioSetRAWMode(int fd, struct termios *otio); +/* + * ioRestoreMode() - Restore termios to tty fd + * + * @fd = tty fd + * @tio = termios structure for restore + * return: -1 error or 0 ok + */ +int ioRestoreMode(int fd, struct termios tio); +/* + * ioForkPTY() - Fork new process with session leader and new TTY + * + * @ptyfd = master fd, pty + * @name = tty device name if not null + * @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 + */ +pid_t ioForkPTY(int *ptyfd, char * __restrict name, int namesiz, struct termios * __restrict term, + struct winsize * __restrict winz, struct termios * __restrict otio); + +/* + * ioCreatePIDFile() - Create PID file + * + * @csName = PID filename + * @ifExists = !=0 if filename exists return error + * return: -1 error or 0 ok + */ +int ioCreatePIDFile(const char *csName, int ifExists); + +/* + * ioSendFile() - AITNET sendfile() userland implementation, not dependant from OS + * + * @s = socket + * @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 + */ +size_t ioSendFile(int s, const char *csFile, size_t sendLen, off_t offset, int sndbuf); +/* + * ioRecvFile() - Receive file from socket, fastest (zero-copy) way + * + * @s = socket + * @csFile = file for receive + * @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 + */ +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 */ + +/* + * io_fmemopen() - File buffered stream operations over memory block + * + * @base = Base address of memory block, if =NULL Infinit length(auto-grow) + * @basesize = Size of memory block + * return: NULL error or !=NULL Opened file resource + */ +FILE *io_fmemopen(void ** __restrict base, off_t basesize); +/* + * io_fmapopen() - File buffered stream operations over MMAP block + * + * @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 + */ +FILE *io_fmapopen(const char *csFile, int mode, int perm, int prot, int flags, off_t offset); +/* + * io_fd2buf() - Convert open file handle to buffered file I/O + * + * @fd = File handle + * @mode = Permissions for new buffered file I/O + * return: NULL error or open buffered file + */ +FILE *io_fd2buf(int fd, const char *mode); +/* + * io_dumbFile() - Create empry or dumb file with fixed size + * + * @csFile = Filename for create + * @mode = File access permissions + * @size = File size + * return: -1 error or open file handle + */ +int io_dumbFile(const char *csFile, int mode, off_t size); +#define io_emptyFile io_dumbFile + + +/* + * io_etherOpen() - Open BPF interface to device + * + * @csIface = interface name + * @flags = open flags + * @whdr = with complete headers + * @wdlt = with data link type, on Linux is protocol number + * @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); + +#ifndef __linux__ +/* + * 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); +#endif + +/* + * 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