|
|
| version 1.1, 2010/02/23 22:54:52 | version 1.2.2.3, 2011/02/10 21:54:23 |
|---|---|
| Line 9 | Line 9 |
| #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 301 char *ioRegexReplace(const char *csRegex, const char * | Line 304 char *ioRegexReplace(const char *csRegex, const char * |
| strlcat(str, csData + ep, len); | strlcat(str, csData + ep, len); |
| return str; | 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 | |
| * @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) | |
| { | |
| char *str, *s, *pbrk, szOld[MAXPATHLEN] = { 0 }; | |
| register int cx = -1; | |
| if (!csDir) | |
| return cx; | |
| str = strdup(csDir); | |
| if (!str) { | |
| LOGERR; | |
| return cx; | |
| } | |
| getcwd(szOld, MAXPATHLEN); | |
| if (*str == '/') | |
| chdir("/"); | |
| for (cx = 0, s = strtok_r(str, "/", &pbrk); s; s = strtok_r(NULL, "/", &pbrk)) { | |
| if (mkdir(s, mode) == -1) { | |
| if (errno != EEXIST) { | |
| LOGERR; | |
| cx = -1; | |
| goto end; | |
| } | |
| } else | |
| cx++; | |
| if (chdir(s) == -1) { | |
| LOGERR; | |
| cx = -1; | |
| goto end; | |
| } | |
| } | |
| end: | |
| chdir(szOld); | |
| free(str); | |
| 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; | |
| } | } |