Diff for /libaitio/src/aitio.c between versions 1.5.4.1 and 1.13.8.1

version 1.5.4.1, 2011/05/10 20:47:31 version 1.13.8.1, 2013/01/17 12:52:35
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 46  SUCH DAMAGE. Line 46  SUCH DAMAGE.
 #include "global.h"  #include "global.h"
   
   
 int io_Debug;  
   
   
 #pragma GCC visibility push(hidden)  #pragma GCC visibility push(hidden)
   
 int io_Errno;  int io_Errno;
Line 86  io_SetErr(int eno, char *estr, ...) Line 83  io_SetErr(int eno, char *estr, ...)
   
   
 /*  /*
 * 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
Line 139  ioPromptRead(int *h, const char *csPrompt, char * __re Line 137  ioPromptRead(int *h, const char *csPrompt, char * __re
 }  }
   
 /*  /*
 * 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 225  next: Line 224  next:
 }  }
   
 /*  /*
 * ioRegexVerify() Function for verify data match in regex expression * ioMkDir() - Function for racursive directory creation and validation
 * @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) 
{ 
        regex_t re; 
        regmatch_t match; 
        char szErr[STRSIZ]; 
        int ret, flg; 
        const char *pos; 
 
        if (!csRegex || !csData) 
                return NULL; 
 
        if ((ret = regcomp(&re, csRegex, REG_EXTENDED))) { 
                regerror(ret, &re, szErr, STRSIZ); 
                io_SetErr(ret, "Error:: %s\n", szErr); 
                regfree(&re); 
                return NULL; 
        } 
 
        for (ret = flg = 0, pos = csData; !(ret = regexec(&re, pos, 1, &match, flg));  
                        pos += match.rm_eo, flg = REG_NOTBOL) { 
                if (startPos) 
                        *startPos = match.rm_so; 
                if (endPos) 
                        *endPos = match.rm_eo; 
 
                pos += match.rm_so; 
                break; 
        } 
 
        if (ret) { 
                regerror(ret, &re, szErr, STRSIZ); 
                io_SetErr(ret, "Error:: %s\n", szErr); 
                pos = NULL; 
        } 
 
        regfree(&re); 
        return pos; 
} 
 
/* 
 * 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) 
{ 
        int sp, ep, len; 
        const char *str; 
 
        if (!csRegex || !csData) 
                return -1; 
 
        str = ioRegexVerify(csRegex, csData, &sp, &ep); 
        if (!str) 
                return 0; 
 
        len = ep - sp; 
        if (psString && strLen) { 
                memset(psString, 0, strLen); 
                strncpy(psString, str, strLen <= len ? strLen - 1 : len); 
        } 
 
        return len; 
} 
 
/* 
 * 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) 
{ 
        int sp, ep, len; 
        char *str = NULL; 
 
        if (!csRegex || !csData) 
                return NULL; 
 
        if (!ioRegexVerify(csRegex, csData, &sp, &ep)) 
                return NULL; 
 
        // ___ before match 
        len = sp + 1; 
        str = malloc(len); 
        if (!str) { 
                LOGERR; 
                return NULL; 
        } else 
                strlcpy(str, csData, len); 
        // * replace match * 
        if (csNew) { 
                len += strlen(csNew); 
                str = realloc(str, len); 
                if (!str) { 
                        LOGERR; 
                        return NULL; 
                } else 
                        strlcat(str, csNew, len); 
        } 
        // after match ___ 
        len += strlen(csData) - ep; 
        str = realloc(str, len); 
        if (!str) { 
                LOGERR; 
                return NULL; 
        } else 
                strlcat(str, csData + ep, len); 
 
        return str; 
} 
 
/* 
 * 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) 
{ 
        char *ext, *str, *out = NULL; 
        int e[2] = { 0 }; 
 
        if (!csString) 
                return NULL; 
 
        if (!strchr(csString, '{') || !strrchr(csString, '}')) { 
                memset(io_Error, 0, STRSIZ); 
                snprintf(io_Error, STRSIZ, "Error:: Invalid input string format ... " 
                                "must be like {text[:[-]#[:#]]}"); 
                io_Errno = EINVAL; 
                return NULL; 
        } else { 
                str = strdup(strchr(csString, '{') + 1); 
                *strrchr(str, '}') = 0; 
        } 
 
        if ((ext = strchr(str, ':'))) { 
                *ext++ = 0; 
                e[0] = strtol(ext, NULL, 0); 
                if ((ext = strchr(ext, ':'))) 
                        e[1] = strtol(++ext, NULL, 0); 
 
                /* make cut prefix */ 
                if (e[0] >= 0) 
                        ext = str + e[0]; 
                else 
                        ext = str + strlen(str) + e[0]; 
                /* make cut suffix */ 
                if (e[1] > 0) 
                        *(ext + e[1]) = 0; 
        } else 
                /* ok, clear show */ 
                ext = str; 
 
        out = strdup(ext); 
        free(str); 
 
        return out; 
} 
 
 
/* 
 * ioMkDir() Function for racursive directory creation and validation 
  * @csDir = Full directory path   * @csDir = Full directory path
  * @mode = Mode for directory creation if missing dir   * @mode = Mode for directory creation if missing dir
  * return: -1 error, 0 directory path exist, >0 created missing dirs   * return: -1 error, 0 directory path exist, >0 created missing dirs
Line 416  ioMkDir(const char *csDir, int mode) Line 239  ioMkDir(const char *csDir, int mode)
         if (!csDir)          if (!csDir)
                 return cx;                  return cx;
   
        str = strdup(csDir);        str = e_strdup(csDir);
         if (!str) {          if (!str) {
                 LOGERR;                  LOGERR;
                 return cx;                  return cx;
Line 444  ioMkDir(const char *csDir, int mode) Line 267  ioMkDir(const char *csDir, int mode)
         }          }
 end:  end:
         chdir(szOld);          chdir(szOld);
        free(str);        e_free(str);
         return cx;          return cx;
 }  }
   
 /*  /*
 * ioWatchDirLoop() Function for watching changes in directory and fire callback * ioWatchDirLoop() - Function for watching changes in directory and fire callback
  *
  * @csDir = Full directory path   * @csDir = Full directory path
  * @callback = Callback if raise event! nOp -1 delete, 0 change/move, 1 create   * @callback = Callback if raise event! nOp -1 delete, 0 change/move, 1 create
  * return: -1 error, !=-1 ok, number of total signaled events   * return: -1 error, !=-1 ok, number of total signaled events
Line 557  ioWatchDirLoop(const char *csDir, int (*callback)(cons Line 381  ioWatchDirLoop(const char *csDir, int (*callback)(cons
         close(d);          close(d);
         close(kq);          close(kq);
         return n;          return n;
   }
   
   /*
    * ioCreatePIDFile() - Create PID file
    *
    * @csName = PID filename
    * @ifExists = !=0 if filename exists return error
    * return: -1 error or 0 ok
    */
   inline int
   ioCreatePIDFile(const char *csName, int ifExists)
   {
           int fd;
           char str[STRSIZ] = { 0 };
   
           if (!csName)
                   return -1;
   
           fd = open(csName, O_WRONLY | O_CREAT | (ifExists ? O_EXCL : 0), 0644);
           if (fd == -1) {
                   LOGERR;
                   return -1;
           }
           snprintf(str, sizeof str, "%d", getpid());
           write(fd, str, strlen(str));
           close(fd);
           return 0;
   }
   
   
   /*
    * 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)
   {
           void *addr;
           int fd;
           size_t len = 0;
           register size_t off = 0;
   
           if (!csFile)
                   return 0;
   
           if (sndbuf)
                   if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof sndbuf) == -1) {
                           LOGERR;
                           return 0;
                   }
   
           fd = open(csFile, O_RDONLY);
           if (fd == -1) {
                   LOGERR;
                   return 0;
           }
           if (!sendLen) {
                   sendLen = lseek(fd, 0, SEEK_END);
                   if (sendLen == -1) {
                           LOGERR;
                           close(fd);
                           return 0;
                   }
           }
           addr = mmap(NULL, sendLen, PROT_READ, MAP_SHARED, fd, offset);
           if (addr == MAP_FAILED) {
                   LOGERR;
                   close(fd);
                   return 0;
           } else
                   close(fd);
   
           while (off < sendLen && (len = write(s, addr + off, sendLen - off)) != -1)
                   off += len;
           if (len == -1) {
                   LOGERR;
                   munmap(addr, sendLen);
                   return 0;
           } else
                   len = off;
   
           if (len != sendLen) {
                   io_SetErr(ECANCELED, "Different sizes - request %u bytes, actually sended %u bytes\n", 
                                   sendLen, len);
                   len ^= len;
           }
   
           munmap(addr, sendLen);
           return len;
   }
   
   /*
    * 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)
   {
           void *addr;
           int fd;
           size_t len = 0;
           register size_t off = 0;
           struct pollfd pfd = { s, POLLIN | POLLPRI, 0 };
   
           if (!csFile || !recvLen)
                   return 0;
           if (!over && !access(csFile, F_OK))
                   return 0;
   
           if (rcvbuf)
                   if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof rcvbuf) == -1) {
                           LOGERR;
                           return 0;
                   }
   
           fd = open(csFile, O_WRONLY | O_CREAT | O_TRUNC, over);
           if (fd == -1) {
                   LOGERR;
                   unlink(csFile);
                   return 0;
           }
           if (ftruncate(fd, recvLen) == -1) {
                   LOGERR;
                   close(fd);
                   unlink(csFile);
                   return 0;
           }
           addr = mmap(NULL, recvLen, PROT_WRITE, MAP_SHARED, fd, 0);
           if (addr == MAP_FAILED) {
                   LOGERR;
                   close(fd);
                   unlink(csFile);
                   return 0;
           } else
                   close(fd);
   
           while (off < recvLen && poll(&pfd, 1, RECV_TIMEOUT) != -1)
                   while (off < recvLen && (len = read(s, addr + off, recvLen - off)) != -1)
                           off += len;
           if (len == -1) {
                   LOGERR;
                   munmap(addr, recvLen);
                   unlink(csFile);
                   return 0;
           } else
                   len = off;
   
           if (len != recvLen)
                   io_SetErr(EAGAIN, "Different sizes - request %u bytes, actually received %u bytes\n", 
                                   recvLen, len);
   
           munmap(addr, recvLen);
           return len;
 }  }

Removed from v.1.5.4.1  
changed lines
  Added in v.1.13.8.1


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