--- libaitio/src/aitio.c 2010/09/10 12:39:41 1.2 +++ libaitio/src/aitio.c 2011/02/10 22:01:34 1.3 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitio.c,v 1.2 2010/09/10 12:39:41 misho Exp $ +* $Id: aitio.c,v 1.3 2011/02/10 22:01:34 misho Exp $ * *************************************************************************/ #include "global.h" @@ -306,7 +306,56 @@ char *ioRegexReplace(const char *csRegex, const char * 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 @@ -354,3 +403,113 @@ end: return cx; } +/* + * 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)) +{ + glob_t g[2] = {{ 0 }, { 0 }}; + int d, kq, n = 0; + register int j, i; + struct kevent req, chg; + char wrk[MAXPATHLEN * 2], str[MAXPATHLEN] = { 0 }; + + if (!csDir || !callback) + return 0; + + strlcpy(str, csDir, MAXPATHLEN); + strlcat(str, "/*", MAXPATHLEN); + + kq = kqueue(); + if (kq == -1) { + LOGERR; + return -1; + } + d = open(csDir, O_RDONLY); + if (d == -1) { + LOGERR; + close(kq); + return -1; + } + + EV_SET(&req, d, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE, 0, NULL); + + if ((n = glob(str, GLOB_NOCHECK, NULL, &g[0]))) { + LOGERR; + close(d); + close(kq); + return -1; + } /*else + ioDEBUG(3, "Start files %d in %s\n", g[0].gl_matchc, str);*/ + + 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);*/ + + if (!glob(str, GLOB_NOCHECK, NULL, &g[1])) { + /*ioDEBUG(3, "Diffs %d <> %d\n", g[0].gl_matchc, g[1].gl_matchc);*/ + + if (g[0].gl_matchc != g[1].gl_matchc) { + /* find new items */ + for (j = 0; j < g[1].gl_matchc; j++) { + for (i = 0; i < g[0].gl_matchc; i++) + if (!strcmp(g[0].gl_pathv[i], g[1].gl_pathv[j])) + break; + if (i == g[0].gl_matchc) { + if (callback(g[1].gl_pathv[j], 1) < 0) + break; + else + n++; + } + } + /* find del items */ + for (j = 0; j < g[0].gl_matchc; j++) { + for (i = 0; i < g[1].gl_matchc; i++) + if (!strcmp(g[1].gl_pathv[i], g[0].gl_pathv[j])) + break; + if (i == g[1].gl_matchc) { + if (callback(g[0].gl_pathv[j], -1) < 0) + break; + else + n++; + } + } + } else { + /* find chg from items */ + for (j = 0; j < g[0].gl_matchc; j++) { + for (i = 0; i < g[1].gl_matchc; i++) + if (!strcmp(g[1].gl_pathv[i], g[0].gl_pathv[j])) + break; + if (i == g[1].gl_matchc) { + strlcpy(wrk, g[0].gl_pathv[j], sizeof wrk); + strlcat(wrk, ":", sizeof wrk); + } + } + /* find chg to items */ + for (j = 0; j < g[1].gl_matchc; j++) { + for (i = 0; i < g[0].gl_matchc; i++) + if (!strcmp(g[0].gl_pathv[i], g[1].gl_pathv[j])) + break; + if (i == g[0].gl_matchc) { + strlcat(wrk, g[1].gl_pathv[j], sizeof wrk); + if (callback(wrk, 0) < 0) + break; + else + n++; + } + } + } + + globfree(&g[0]); + g[0] = g[1]; + } + } + + globfree(&g[0]); + close(d); + close(kq); + return n; +}