Item *SelectProcesses(const Item *processes, const char *process_name, ProcessSelect a, bool attrselect) { Item *result = NULL; if (processes == NULL) { return result; } char *names[CF_PROCCOLS]; int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; GetProcessColumnNames(processes->name, &names[0], start, end); pcre *rx = CompileRegex(process_name); if (rx) { /* TODO: use actual time of ps-run, as time(NULL) may be later. */ time_t pstime = time(NULL); for (Item *ip = processes->next; ip != NULL; ip = ip->next) { int s, e; if (StringMatchWithPrecompiledRegex(rx, ip->name, &s, &e)) { if (NULL_OR_EMPTY(ip->name)) { continue; } if (attrselect && !SelectProcess(ip->name, pstime, names, start, end, a)) { continue; } pid_t pid = ExtractPid(ip->name, names, end); if (pid == -1) { Log(LOG_LEVEL_VERBOSE, "Unable to extract pid while looking for %s", process_name); continue; } PrependItem(&result, ip->name, ""); result->counter = (int)pid; } } pcre_free(rx); } for (int i = 0; i < CF_PROCCOLS; i++) { free(names[i]); } return result; }
Rlist *RlistFromSplitRegex(const char *string, const char *regex, size_t max_entries, bool allow_blanks) { assert(string); if (!string) { return NULL; } const char *sp = string; size_t entry_count = 0; int start = 0; int end = 0; Rlist *result = NULL; Buffer *buffer = BufferNewWithCapacity(CF_MAXVARSIZE); pcre *rx = CompileRegex(regex); if (rx) { while ((entry_count < max_entries) && StringMatchWithPrecompiledRegex(rx, sp, &start, &end)) { if (end == 0) { break; } BufferClear(buffer); BufferAppend(buffer, sp, start); if (allow_blanks || BufferSize(buffer) > 0) { RlistAppendScalar(&result, BufferData(buffer)); entry_count++; } sp += end; } pcre_free(rx); } if (entry_count < max_entries) { BufferClear(buffer); size_t remaining = strlen(sp); BufferAppend(buffer, sp, remaining); if ((allow_blanks && sp != string) || BufferSize(buffer) > 0) { RlistAppendScalar(&result, BufferData(buffer)); } } BufferDestroy(buffer); return result; }
bool StringMatchFullWithPrecompiledRegex(pcre *pattern, const char *str) { int start = 0, end = 0; if (StringMatchWithPrecompiledRegex(pattern, str, &start, &end)) { return (start == 0) && (end == strlen(str)); } else { return false; } }
bool StringMatch(const char *regex, const char *str, int *start, int *end) { pcre *pattern = CompileRegex(regex); if (pattern == NULL) { return false; } bool ret = StringMatchWithPrecompiledRegex(pattern, str, start, end); pcre_free(pattern); return ret; }
/* * Splits string on regex, returns a list of (at most max) fragments. * * NOTE: in contrast with RlistFromSplitRegex() this one will produce at most max number of elements; * last element will contain everything that lefts from original string (we use everything after * the (max-1)-th separator as the final list element, including any separators that may be embedded in it) */ Rlist *RlistFromRegexSplitNoOverflow(const char *string, const char *regex, int max) { Rlist *liststart = NULL; char node[CF_MAXVARSIZE]; int start, end; int count = 0; assert(max > 0); // ensured by FnCallStringSplit() before calling us assert(string != NULL); // ensured by FnCallStringSplit() before calling us const char *sp = string; // We will avoid compiling regex multiple times. pcre *pattern = CompileRegex(regex); if (pattern == NULL) { Log(LOG_LEVEL_DEBUG, "Error compiling regex from '%s'", regex); return NULL; } while (count < max - 1 && StringMatchWithPrecompiledRegex(pattern, sp, &start, &end)) { assert(start < CF_MAXVARSIZE); memcpy(node, sp, start); node[start] = '\0'; RlistAppendScalar(&liststart, node); count++; sp += end; } assert(count < max); RlistAppendScalar(&liststart, sp); pcre_free(pattern); return liststart; }