static bool GatherProcessUsers(Item **userList, int *userListSz, int *numRootProcs, int *numOtherProcs) { char pscomm[CF_BUFSIZE]; xsnprintf(pscomm, sizeof(pscomm), "%s %s", VPSCOMM[VPSHARDCLASS], VPSOPTS[VPSHARDCLASS]); FILE *pp; if ((pp = cf_popen(pscomm, "r", true)) == NULL) { /* FIXME: no logging */ return false; } size_t vbuff_size = CF_BUFSIZE; char *vbuff = xmalloc(vbuff_size); /* Ignore first line -- header */ ssize_t res = CfReadLine(&vbuff, &vbuff_size, pp); if (res <= 0) { /* FIXME: no logging */ cf_pclose(pp); free(vbuff); return false; } for (;;) { res = CfReadLine(&vbuff, &vbuff_size, pp); if (res == -1) { if (!feof(pp)) { /* FIXME: no logging */ cf_pclose(pp); free(vbuff); return false; } else { break; } } char user[64]; int ret = sscanf(vbuff, " %63s ", user); /* CFE-1560: Skip the username if it starts with a digit, this means * that we are reading the PID! Happens on some platforms (e.g. AIX) * where zombie processes have an empty username field in ps. */ if (ret != 1 || user[0] == '\0' || isdigit(user[0])) { continue; } if (!IsItemIn(*userList, user)) { PrependItem(userList, user, NULL); (*userListSz)++; } if (strcmp(user, "root") == 0) { (*numRootProcs)++; } else { (*numOtherProcs)++; } } if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { char *s = ItemList2CSV(*userList); Log(LOG_LEVEL_DEBUG, "Users in the process table: (%s)", s); free(s); } cf_pclose(pp); free(vbuff); return true; }
static bool GetSysUsers( int *userListSz, int *numRootProcs, int *numOtherProcs) { FILE *fp; char user[CF_BUFSIZE]; char vbuff[CF_BUFSIZE]; char cbuff[CF_BUFSIZE]; /* * The best would be to ask only "user" field from ps, but we are asking * for "user,pid". The reason is that we try to mimic cf-monitord's * behaviour, else a different number of users might be detected by the * test, as printing "user,pid" truncates the user column. TODO fix the * ps command to use only "-o user" in both mon_processes.c and this test. */ #if defined(__sun) xsnprintf(cbuff, CF_BUFSIZE, "/bin/ps -eo user,pid > %s/users.txt", CFWORKDIR); #elif defined(_AIX) xsnprintf(cbuff, CF_BUFSIZE, "/bin/ps -N -eo user,pid > %s/users.txt", CFWORKDIR); #elif defined(__hpux) xsnprintf(cbuff, CF_BUFSIZE, "UNIX95=1 /bin/ps -eo user,pid > %s/users.txt", CFWORKDIR); /* SKIP on HP-UX since cf-monitord doesn't count processes correctly! */ return false; #else xsnprintf(cbuff, CF_BUFSIZE, "ps -eo user:30,pid > %s/users.txt", CFWORKDIR); #endif Item *userList = NULL; system(cbuff); xsnprintf(cbuff, CF_BUFSIZE, "%s/users.txt", CFWORKDIR); if ((fp = fopen(cbuff, "r")) == NULL) { return false; } while (fgets(vbuff, CF_BUFSIZE, fp) != NULL) { int ret = sscanf(vbuff, " %s ", user); if (ret != 1 || strcmp(user, "") == 0 || strcmp(user, "USER") == 0 || isdigit(user[0])) { continue; } if (!IsItemIn(userList, user)) { PrependItem(&userList, user, NULL); (*userListSz)++; } if (strcmp(user, "root") == 0) { (*numRootProcs)++; } else { (*numOtherProcs)++; } } fclose(fp); if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { char *s = ItemList2CSV(userList); Log(LOG_LEVEL_DEBUG, "Users in the process table detected from the test: (%s)", s); free(s); } DeleteItemList(userList); return true; }
static void MonLogSymbolicValue(EvalContext *ctx, const char *handle, Item *stream, Attributes a, const Promise *pp, PromiseResult *result) { char value[CF_BUFSIZE], sdate[CF_MAXVARSIZE], filename[CF_BUFSIZE], *v; int count = 1, found = false, match_count = 0; Item *ip, *match = NULL, *matches = NULL; time_t now = time(NULL); FILE *fout; if (stream == NULL) { Log(LOG_LEVEL_VERBOSE, "No stream to measure"); return; } Log(LOG_LEVEL_VERBOSE, "Locate and log sample ..."); for (ip = stream; ip != NULL; ip = ip->next) { if (ip->name == NULL) { continue; } if (count == a.measure.select_line_number) { Log(LOG_LEVEL_VERBOSE, "Found line %d by number...", count); found = true; match_count = 1; match = ip; if (a.measure.extraction_regex) { Log(LOG_LEVEL_VERBOSE, "Now looking for a matching extractor \"%s\"", a.measure.extraction_regex); strncpy(value, ExtractFirstReference(a.measure.extraction_regex, match->name), CF_MAXVARSIZE - 1); Log(LOG_LEVEL_INFO, "Extracted value \"%s\" for promise \"%s\"", value, handle); AppendItem(&matches, value, NULL); } break; } if (a.measure.select_line_matching && StringMatchFull(a.measure.select_line_matching, ip->name)) { Log(LOG_LEVEL_VERBOSE, "Found line %d by pattern...", count); found = true; match = ip; match_count++; if (a.measure.extraction_regex) { Log(LOG_LEVEL_VERBOSE, "Now looking for a matching extractor \"%s\"", a.measure.extraction_regex); strncpy(value, ExtractFirstReference(a.measure.extraction_regex, match->name), CF_MAXVARSIZE - 1); Log(LOG_LEVEL_INFO, "Extracted value \"%s\" for promise \"%s\"", value, handle); AppendItem(&matches, value, NULL); } } count++; } if (!found) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Promiser '%s' found no matching line.", pp->promiser); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return; } if (match_count > 1) { Log(LOG_LEVEL_INFO, "Warning: %d lines matched the line_selection \"%s\"- matching to last", match_count, a.measure.select_line_matching); } switch (a.measure.data_type) { case CF_DATA_TYPE_COUNTER: Log(LOG_LEVEL_VERBOSE, "Counted %d for %s", match_count, handle); snprintf(value, CF_MAXVARSIZE, "%d", match_count); break; case CF_DATA_TYPE_STRING_LIST: v = ItemList2CSV(matches); snprintf(value, CF_BUFSIZE, "%s", v); free(v); break; default: snprintf(value, CF_BUFSIZE, "%s", matches->name); } DeleteItemList(matches); if (a.measure.history_type && strcmp(a.measure.history_type, "log") == 0) { snprintf(filename, CF_BUFSIZE, "%s%cstate%c%s_measure.log", CFWORKDIR, FILE_SEPARATOR, FILE_SEPARATOR, handle); if ((fout = fopen(filename, "a")) == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to open the output log \"%s\"", filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); PromiseRef(LOG_LEVEL_ERR, pp); return; } strncpy(sdate, ctime(&now), CF_MAXVARSIZE - 1); if (Chop(sdate, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } fprintf(fout, "%s,%ld,%s\n", sdate, (long) now, value); Log(LOG_LEVEL_VERBOSE, "Logging: %s,%s to %s", sdate, value, filename); fclose(fout); } else // scalar or static { CF_DB *dbp; char id[CF_MAXVARSIZE]; if (!OpenDB(&dbp, dbid_static)) { return; } snprintf(id, CF_MAXVARSIZE - 1, "%s:%d", handle, a.measure.data_type); WriteDB(dbp, id, value, strlen(value) + 1); CloseDB(dbp); } }