void CopyList(Item **dest, const Item *source) /* Copy a list. */ { if (*dest != NULL) { ProgrammingError("CopyList - list not initialized"); } if (source == NULL) { return; } const Item *ip = source; CYCLE_DECLARE(ip, slow, toggle); Item *backwards = NULL; while (ip != NULL) { PrependFullItem(&backwards, ip->name, ip->classes, ip->counter, ip->time); ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } *dest = ReverseItemList(backwards); }
Item *SplitString(const char *string, char sep) /* Splits a string containing a separator like : into a linked list of separate items, */ { Item *liststart = NULL; const char *sp = string; char before[CF_BUFSIZE]; int i = 0; while (*sp != '\0') { if (*sp != sep) { before[i] = *sp; i++; } else if (sp > string && sp[-1] == '\\') { /* Escaped use of list separator; over-write the backslash * we copied last time round the loop (and don't increment * i, so next time round we'll continue in the right * place). */ before[i - 1] = sep; } else { before[i] = '\0'; PrependItem(&liststart, before, NULL); i = 0; } sp++; } before[i] = '\0'; PrependItem(&liststart, before, ""); return ReverseItemList(liststart); }
Item *SplitStringAsItemList(const char *string, char sep) /* Splits a string containing a separator like : into a linked list of separate items, */ { Item *liststart = NULL; char node[256]; char format[] = "%255[^\0]"; /* Overwrite format's internal \0 with sep: */ format[strlen(format)] = sep; assert(strlen(format) + 1 == sizeof(format) || sep == '\0'); for (const char *sp = string; *sp != '\0'; sp++) { if (sscanf(sp, format, node) == 1 && node[0] != '\0') { sp += strlen(node) - 1; PrependItem(&liststart, node, NULL); } } return ReverseItemList(liststart); }
int LoadProcessTable() { FILE *prp; char pscomm[CF_MAXLINKSIZE]; Item *rootprocs = NULL; Item *otherprocs = NULL; if (PROCESSTABLE) { Log(LOG_LEVEL_VERBOSE, "Reusing cached process table"); return true; } LoadPlatformExtraTable(); CheckPsLineLimitations(); const char *psopts = GetProcessOptions(); snprintf(pscomm, CF_MAXLINKSIZE, "%s %s", VPSCOMM[VPSHARDCLASS], psopts); Log(LOG_LEVEL_VERBOSE, "Observe process table with %s", pscomm); if ((prp = cf_popen(pscomm, "r", false)) == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open the process list with command '%s'. (popen: %s)", pscomm, GetErrorStr()); return false; } size_t vbuff_size = CF_BUFSIZE; char *vbuff = xmalloc(vbuff_size); # ifdef HAVE_GETZONEID char *names[CF_PROCCOLS]; int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; Seq *pidlist = SeqNew(1, NULL); Seq *rootpidlist = SeqNew(1, NULL); bool global_zone = IsGlobalZone(); if (global_zone) { int res = ZLoadProcesstable(pidlist, rootpidlist); if (res == false) { Log(LOG_LEVEL_ERR, "Unable to load solaris zone process table."); return false; } } # endif ARG_UNUSED bool header = true; /* used only if HAVE_GETZONEID */ for (;;) { ssize_t res = CfReadLine(&vbuff, &vbuff_size, prp); if (res == -1) { if (!feof(prp)) { Log(LOG_LEVEL_ERR, "Unable to read process list with command '%s'. (fread: %s)", pscomm, GetErrorStr()); cf_pclose(prp); free(vbuff); return false; } else { break; } } Chop(vbuff, vbuff_size); # ifdef HAVE_GETZONEID if (global_zone) { if (header) { /* this is the banner so get the column header names for later use*/ GetProcessColumnNames(vbuff, &names[0], start, end); } else { int gpid = ExtractPid(vbuff, names, end); if (!IsGlobalProcess(gpid, pidlist, rootpidlist)) { continue; } } } # endif AppendItem(&PROCESSTABLE, vbuff, ""); header = false; } cf_pclose(prp); /* Now save the data */ const char* const statedir = GetStateDir(); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_procs", statedir, FILE_SEPARATOR); RawSaveItemList(PROCESSTABLE, vbuff, NewLineMode_Unix); # ifdef HAVE_GETZONEID if (global_zone) /* pidlist and rootpidlist are empty if we're not in the global zone */ { Item *ip = PROCESSTABLE; while (ip != NULL) { ZCopyProcessList(&rootprocs, ip, rootpidlist, names, end); ip = ip->next; } ReverseItemList(rootprocs); ip = PROCESSTABLE; while (ip != NULL) { ZCopyProcessList(&otherprocs, ip, pidlist, names, end); ip = ip->next; } ReverseItemList(otherprocs); } else # endif { CopyList(&rootprocs, PROCESSTABLE); CopyList(&otherprocs, PROCESSTABLE); while (DeleteItemNotContaining(&rootprocs, "root")) { } while (DeleteItemContaining(&otherprocs, "root")) { } } if (otherprocs) { PrependItem(&rootprocs, otherprocs->name, NULL); } snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_rootprocs", statedir, FILE_SEPARATOR); RawSaveItemList(rootprocs, vbuff, NewLineMode_Unix); DeleteItemList(rootprocs); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_otherprocs", statedir, FILE_SEPARATOR); RawSaveItemList(otherprocs, vbuff, NewLineMode_Unix); DeleteItemList(otherprocs); free(vbuff); return true; }