static void test_block_text_match2(void) { EvalContext *ctx = EvalContextNew(); int start, end; assert_int_not_equal(BlockTextMatch(ctx, "[a-z]+", "1234abcd6789", &start, &end), 0); assert_int_equal(start, 4); assert_int_equal(end, 8); EvalContextDestroy(ctx); }
static void test_block_text_match(void) { EvalContext *ctx = EvalContextNew(); int start, end; assert_int_not_equal(BlockTextMatch(ctx, "#[^\n]*", "line 1:\nline2: # comment to end\nline 3: blablab", &start, &end), 0); assert_int_equal(start, 15); assert_int_equal(end, 31); EvalContextDestroy(ctx); }
Rlist *RlistFromSplitRegex(const char *string, const char *regex, int max, int blanks) /* Splits a string containing a separator like "," into a linked list of separate items, */ // NOTE: this has a bad side-effect of creating scope match and variables, // see RegExMatchSubString in matching.c - could leak memory { Rlist *liststart = NULL; char node[CF_MAXVARSIZE]; int start, end; int count = 0; if (string == NULL) { return NULL; } CfDebug("\n\nSplit \"%s\" with regex \"%s\" (up to maxent %d)\n\n", string, regex, max); const char *sp = string; while ((count < max) && BlockTextMatch(regex, sp, &start, &end)) { if (end == 0) { break; } memset(node, 0, CF_MAXVARSIZE); strncpy(node, sp, start); if (blanks || strlen(node) > 0) { RlistAppendScalar(&liststart, node); count++; } sp += end; } if (count < max) { memset(node, 0, CF_MAXVARSIZE); strncpy(node, sp, CF_MAXVARSIZE - 1); if ((blanks && sp != string) || strlen(node) > 0) { RlistAppendScalar(&liststart, node); } } return liststart; }
Item *SelectProcesses(EvalContext *ctx, 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); for (Item *ip = processes->next; ip != NULL; ip = ip->next) { int s, e; if (BlockTextMatch(ctx, process_name, ip->name, &s, &e)) { if (NULL_OR_EMPTY(ip->name)) { continue; } if (attrselect && !SelectProcess(ctx, ip->name, 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; } } for (int i = 0; i < CF_PROCCOLS; i++) { free(names[i]); } return result; }
static int FindPidMatches(Item *procdata, Item **killlist, Attributes a, Promise *pp) { Item *ip; int pid = -1, matches = 0, i, s, e, promised_zero; pid_t cfengine_pid = getpid(); char *names[CF_PROCCOLS]; /* ps headers */ int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; if (procdata == NULL) { return 0; } GetProcessColumnNames(procdata->name, (char **) names, start, end); for (ip = procdata->next; ip != NULL; ip = ip->next) { CF_OCCUR++; if (BlockTextMatch(pp->promiser, ip->name, &s, &e)) { if (NULL_OR_EMPTY(ip->name)) { continue; } if (!SelectProcess(ip->name, names, start, end, a, pp)) { continue; } pid = ExtractPid(ip->name, names, start, end); if (pid == -1) { CfOut(cf_verbose, "", "Unable to extract pid while looking for %s\n", pp->promiser); continue; } CfOut(cf_verbose, "", " -> Found matching pid %d\n (%s)", pid, ip->name); matches++; if (pid == 1) { if ((RlistLen(a.signals) == 1) && IsStringIn(a.signals, "hup")) { CfOut(cf_verbose, "", "(Okay to send only HUP to init)\n"); } else { continue; } } if (pid < 4 && a.signals) { CfOut(cf_verbose, "", "Will not signal or restart processes 0,1,2,3 (occurred while looking for %s)\n", pp->promiser); continue; } promised_zero = a.process_count.min_range == 0 && a.process_count.max_range == 0; if (a.transaction.action == cfa_warn && promised_zero) { CfOut(cf_error, "", "Process alert: %s\n", procdata->name); /* legend */ CfOut(cf_error, "", "Process alert: %s\n", ip->name); continue; } if (pid == cfengine_pid && a.signals) { CfOut(cf_verbose, "", " !! cf-agent will not signal itself!\n"); continue; } PrependItem(killlist, ip->name, ""); (*killlist)->counter = pid; } } // Free up allocated memory for (i = 0; i < CF_PROCCOLS; i++) { if (names[i] != NULL) { free(names[i]); } } return matches; }