Diff for /libaitio/src/aitio.c between versions 1.9 and 1.17.8.4

version 1.9, 2012/03/29 01:31:33 version 1.17.8.4, 2016/08/10 14:33:23
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012Copyright 2004 - 2016
         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 58  char io_Error[STRSIZ]; Line 55  char io_Error[STRSIZ];
   
   
 // io_GetErrno() Get error code of last operation  // io_GetErrno() Get error code of last operation
inline intint
 io_GetErrno()  io_GetErrno()
 {  {
         return io_Errno;          return io_Errno;
 }  }
   
 // io_GetError() Get error text of last operation  // io_GetError() Get error text of last operation
inline const char *const char *
 io_GetError()  io_GetError()
 {  {
         return io_Error;          return io_Error;
 }  }
   
 // io_SetErr() Set error to variables for internal use!!!  // io_SetErr() Set error to variables for internal use!!!
inline voidvoid
 io_SetErr(int eno, char *estr, ...)  io_SetErr(int eno, char *estr, ...)
 {  {
         va_list lst;          va_list lst;
   
         io_Errno = eno;          io_Errno = eno;
        memset(io_Error, 0, STRSIZ);        memset(io_Error, 0, sizeof io_Error);
         va_start(lst, estr);          va_start(lst, estr);
        vsnprintf(io_Error, STRSIZ, estr, lst);        vsnprintf(io_Error, sizeof io_Error, estr, lst);
         va_end(lst);          va_end(lst);
 }  }
   
   
 /*  /*
 * 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
Line 124  ioPromptRead(int *h, const char *csPrompt, char * __re Line 121  ioPromptRead(int *h, const char *csPrompt, char * __re
                 memset(szLine, 0, BUFSIZ);                  memset(szLine, 0, BUFSIZ);
                 if (!fgets(szLine, BUFSIZ, inp)) {                  if (!fgets(szLine, BUFSIZ, inp)) {
                         clearerr(inp);                          clearerr(inp);
   #ifdef HAVE_FPURGE
                         fpurge(out);                          fpurge(out);
   #else
                           __fpurge(out);
   #endif
                         fflush(out);                          fflush(out);
                         return 0;                          return 0;
                 }                  }
Line 140  ioPromptRead(int *h, const char *csPrompt, char * __re Line 141  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
Line 155  ioPromptPassword(int *h, const char *csPrompt, char *  Line 156  ioPromptPassword(int *h, const char *csPrompt, char * 
         int ret, ok = 0;          int ret, ok = 0;
         FILE *inp, *out;          FILE *inp, *out;
         char szLine[2][STRSIZ];          char szLine[2][STRSIZ];
   #ifndef __linux__
         struct sgttyb tty_state;          struct sgttyb tty_state;
   #else
           struct termios o;
   #endif
   
         if (!psPass || !passLen)          if (!psPass || !passLen)
                 return -1;                  return -1;
Line 171  ioPromptPassword(int *h, const char *csPrompt, char *  Line 176  ioPromptPassword(int *h, const char *csPrompt, char * 
                 return -1;                  return -1;
         }          }
   
   #ifndef __linux__
         if (ioctl(fileno(inp), TIOCGETP, &tty_state) == -1) {          if (ioctl(fileno(inp), TIOCGETP, &tty_state) == -1) {
                 LOGERR;                  LOGERR;
                 return -1;                  return -1;
Line 181  ioPromptPassword(int *h, const char *csPrompt, char *  Line 187  ioPromptPassword(int *h, const char *csPrompt, char * 
                         return -1;                          return -1;
                 }                  }
         }          }
   #else
           if (tcgetattr(fileno(inp), &o) == -1) {
                   LOGERR;
                   return -1;
           } else {
                   o.c_lflag &= ~ECHO;
                   if (tcsetattr(fileno(inp), TCSANOW, &o) == -1) {
                           LOGERR;
                           return -1;
                   }
           }
   #endif
   
         while (!ok) {          while (!ok) {
                 switch ((ret = ioPromptRead(h, (!csPrompt || !*csPrompt) ? "Password:" : csPrompt,                   switch ((ret = ioPromptRead(h, (!csPrompt || !*csPrompt) ? "Password:" : csPrompt, 
Line 217  ioPromptPassword(int *h, const char *csPrompt, char *  Line 235  ioPromptPassword(int *h, const char *csPrompt, char * 
         }          }
   
 next:  next:
   #ifndef __linux__
         tty_state.sg_flags |= ECHO;          tty_state.sg_flags |= ECHO;
         if (ioctl(fileno(inp), TIOCSETP, &tty_state) == -1) {          if (ioctl(fileno(inp), TIOCSETP, &tty_state) == -1) {
                 LOGERR;                  LOGERR;
                 return -1;                  return -1;
         }          }
#else
        return ok;        o.c_lflag |= ECHO;
}        if (tcsetattr(fileno(inp), TCSANOW, &o) == -1) {
                LOGERR;
/* 
 * 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) 
{ 
        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;                  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);  
         }          }
   #endif
   
        return len;        return ok;
 }  }
   
 /*  /*
 * ioRegexReplace() Function for replace data match in regex expression with newdata * ioMkDir() - Function for racursive directory creation and validation
  *   *
  * @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;  
 }  
   
 /*  
  * ioStrAst() Function for evaluate string like asterisk variable "{text[:[-]#[:#]]}"  
  *  
  * @csString = Input string  
  * return: NULL error, !=NULL Allocated new string evaluated from input string, must be free()  
 */  
 char *  
 ioStrAst(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 423  ioMkDir(const char *csDir, int mode) Line 268  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 451  ioMkDir(const char *csDir, int mode) Line 296  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
Line 466  int Line 311  int
 ioWatchDirLoop(const char *csDir, int (*callback)(const char *csName, int nOp))  ioWatchDirLoop(const char *csDir, int (*callback)(const char *csName, int nOp))
 {  {
         glob_t g[2] = {{ 0 }, { 0 }};          glob_t g[2] = {{ 0 }, { 0 }};
        int d, kq, n = 0;        int d, n = 0;
         register int j, i;          register int j, i;
   #ifndef __linux__
           int kq;
         struct kevent req, chg;          struct kevent req, chg;
   #else
           int in;
           struct inotify_event evt;
   #endif
         char wrk[MAXPATHLEN * 2], str[MAXPATHLEN] = { 0 };          char wrk[MAXPATHLEN * 2], str[MAXPATHLEN] = { 0 };
   
         if (!csDir || !callback)          if (!csDir || !callback)
Line 477  ioWatchDirLoop(const char *csDir, int (*callback)(cons Line 328  ioWatchDirLoop(const char *csDir, int (*callback)(cons
         strlcpy(str, csDir, MAXPATHLEN);          strlcpy(str, csDir, MAXPATHLEN);
         strlcat(str, "/*", MAXPATHLEN);          strlcat(str, "/*", MAXPATHLEN);
   
   #ifndef __linux__
           d = open(csDir, O_RDONLY);
           if (d == -1) {
                   LOGERR;
                   return -1;
           }
   
         kq = kqueue();          kq = kqueue();
         if (kq == -1) {          if (kq == -1) {
                 LOGERR;                  LOGERR;
                   close(d);
                 return -1;                  return -1;
         }          }
        d = open(csDir, O_RDONLY);
        if (d == -1) {        EV_SET(&req, d, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE, 0, 0);
 #else
         in = inotify_init();
         if (in == -1) {
                 LOGERR;                  LOGERR;
                 close(kq);  
                 return -1;                  return -1;
         }          }
   
        EV_SET(&req, d, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE, 0, 0);        d = inotify_add_watch(in, csDir, IN_CREATE | IN_DELETE);
 #endif
   
         if ((n = glob(str, GLOB_NOCHECK, NULL, &g[0]))) {          if ((n = glob(str, GLOB_NOCHECK, NULL, &g[0]))) {
                 LOGERR;                  LOGERR;
                close(d);#ifndef __linux__
                 close(kq);                  close(kq);
                   close(d);
   #else
                   inotify_rm_watch(in, d);
                   close(in);
   #endif
                 return -1;                  return -1;
         } /*else          } /*else
                 ioDEBUG(3, "Start files %d in %s\n", g[0].gl_matchc, str);*/                  ioDEBUG(3, "Start files %d in %s\n", g[0].gl_matchc, str);*/
   
   #ifndef __linux__
         while (kevent(kq, &req, 1, &chg, 1, NULL) > 0) {          while (kevent(kq, &req, 1, &chg, 1, NULL) > 0) {
                 /*ioDEBUG(1, "Event:: req=0x%x -> chg=0x%x data=%x\n", req.fflags, chg.fflags, chg.data);*/                  /*ioDEBUG(1, "Event:: req=0x%x -> chg=0x%x data=%x\n", req.fflags, chg.fflags, chg.data);*/
   
Line 560  ioWatchDirLoop(const char *csDir, int (*callback)(cons Line 428  ioWatchDirLoop(const char *csDir, int (*callback)(cons
                         g[0] = g[1];                          g[0] = g[1];
                 }                  }
         }          }
   #endif
   
         globfree(&g[0]);          globfree(&g[0]);
        close(d);#ifndef __linux__
         close(kq);          close(kq);
           close(d);
   #else
           inotify_rm_watch(in, d);
           close(in);
   #endif
         return n;          return n;
 }  }
   
 /*  /*
 * ioCreatePIDFile() Create PID file * ioCreatePIDFile() - Create PID file
  *   *
  * @csName = PID filename   * @csName = PID filename
  * @ifExists = !=0 if filename exists return error   * @ifExists = !=0 if filename exists return error
  * return: -1 error or 0 ok   * return: -1 error or 0 ok
  */   */
inline intint
 ioCreatePIDFile(const char *csName, int ifExists)  ioCreatePIDFile(const char *csName, int ifExists)
 {  {
         int fd;          int fd;
Line 596  ioCreatePIDFile(const char *csName, int ifExists) Line 470  ioCreatePIDFile(const char *csName, int ifExists)
   
   
 /*  /*
 * ioSendFile() AITNET sendfile() userland implementation, not dependant from OS * ioSendFile() - AITNET sendfile() userland implementation, not dependant from OS
  *   *
  * @s = socket   * @s = socket
  * @csFile = file for send   * @csFile = file for send
Line 663  ioSendFile(int s, const char *csFile, size_t sendLen,  Line 537  ioSendFile(int s, const char *csFile, size_t sendLen, 
 }  }
   
 /*  /*
 * ioRecvFile() Receive file from socket, fastest (zero-copy) way * ioRecvFile() - Receive file from socket, fastest (zero-copy) way
  *   *
  * @s = socket   * @s = socket
  * @csFile = file for receive   * @csFile = file for receive
Line 698  ioRecvFile(int s, const char *csFile, size_t recvLen,  Line 572  ioRecvFile(int s, const char *csFile, size_t recvLen, 
                 unlink(csFile);                  unlink(csFile);
                 return 0;                  return 0;
         }          }
        if (lseek(fd, recvLen - 1, SEEK_SET) == -1) {        if (ftruncate(fd, recvLen) == -1) {
                 LOGERR;                  LOGERR;
                 close(fd);                  close(fd);
                 unlink(csFile);                  unlink(csFile);
                 return 0;                  return 0;
         }          }
         if (write(fd, "", 1) == -1) {  
                 LOGERR;  
                 close(fd);  
                 unlink(csFile);  
                 return 0;  
         }  
         addr = mmap(NULL, recvLen, PROT_WRITE, MAP_SHARED, fd, 0);          addr = mmap(NULL, recvLen, PROT_WRITE, MAP_SHARED, fd, 0);
         if (addr == MAP_FAILED) {          if (addr == MAP_FAILED) {
                 LOGERR;                  LOGERR;
Line 736  ioRecvFile(int s, const char *csFile, size_t recvLen,  Line 604  ioRecvFile(int s, const char *csFile, size_t recvLen, 
   
         munmap(addr, recvLen);          munmap(addr, recvLen);
         return len;          return len;
   }
   
   /*
    * 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)
   {
           char *str = NULL;
           struct stat sb;
   
           if (!fname)
                   return NULL;
   
           str = e_malloc(MAXPATHLEN);
           if (!str) {
                   io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                   return NULL;
           } else
                   memset(str, 0, MAXPATHLEN);
           if (readlink(fname, str, MAXPATHLEN) == -1) {
                   if (stat(fname, &sb) == -1) {
                           LOGERR;
                           e_free(str);
                           return NULL;
                   } else
                           strlcpy(str, fname, MAXPATHLEN);
           }
   
           return str;
 }  }

Removed from v.1.9  
changed lines
  Added in v.1.17.8.4


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