static FnCall *DefaultServiceBundleCall(const Promise *pp, ServicePolicy service_policy) { Rlist *args = NULL; switch (service_policy) { case SERVICE_POLICY_START: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "start", RVAL_TYPE_SCALAR); break; case SERVICE_POLICY_RESTART: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "restart", RVAL_TYPE_SCALAR); break; case SERVICE_POLICY_RELOAD: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "restart", RVAL_TYPE_SCALAR); break; case SERVICE_POLICY_STOP: case SERVICE_POLICY_DISABLE: default: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "stop", RVAL_TYPE_SCALAR); break; } FnCall *call = FnCallNew("standard_services", args); return call; }
static void test_filter(void) { Rlist *list = NULL; for (int i = 0; i < 10; i++) { char *item = StringFromLong(i); RlistAppend(&list, item, RVAL_TYPE_SCALAR); } assert_int_equal(10, RlistLen(list)); int mod_by = 0; RlistFilter(&list, is_even, &mod_by, free); assert_int_equal(5, RlistLen(list)); int i = 0; for (Rlist *rp = list; rp; rp = rp->next) { int k = StringToLong(rp->val.item); assert_int_equal(i, k); i += 2; } RlistDestroy(list); }
Rlist *RlistAppend(Rlist **start, const void *item, RvalType type) { Rlist *rp, *lp = *start; switch (type) { case RVAL_TYPE_SCALAR: return RlistAppendScalar(start, item); case RVAL_TYPE_FNCALL: break; case RVAL_TYPE_LIST: for (rp = (Rlist *) item; rp != NULL; rp = rp->next) { lp = RlistAppend(start, rp->item, rp->type); } return lp; default: Log(LOG_LEVEL_DEBUG, "Cannot append %c to rval-list '%s'", type, (char *) item); return NULL; } rp = xmalloc(sizeof(Rlist)); if (*start == NULL) { *start = rp; } else { for (lp = *start; lp->next != NULL; lp = lp->next) { } lp->next = rp; } rp->item = RvalCopy((Rval) {(void *) item, type}).item; rp->type = type; /* scalar, builtin function */ ThreadLock(cft_lock); if (type == RVAL_TYPE_LIST) { rp->state_ptr = rp->item; } else { rp->state_ptr = NULL; } rp->next = NULL; ThreadUnlock(cft_lock); return rp; }
static void test_hostinnetgroup_not_found(void **state) { FnCallResult res; Rlist *args = NULL; RlistAppend(&args, "invalid_netgroup", 's'); res = FnCallHostInNetgroup(NULL, args); assert_string_equal("!any", (char *) res.rval.item); }
void RlistFlatten(EvalContext *ctx, Rlist **list) { for (Rlist *rp = *list; rp != NULL;) { if (rp->type != RVAL_TYPE_SCALAR) { rp = rp->next; continue; } char naked[CF_BUFSIZE] = ""; if (IsNakedVar(rp->item, '@')) { GetNaked(naked, rp->item); Rval rv; if (EvalContextVariableGet(ctx, (VarRef) { NULL, ScopeGetCurrent()->scope, naked }, &rv, NULL)) { switch (rv.type) { case RVAL_TYPE_LIST: for (const Rlist *srp = rv.item; srp != NULL; srp = srp->next) { RlistAppend(list, srp->item, srp->type); } Rlist *next = rp->next; RlistDestroyEntry(list, rp); rp = next; continue; default: ProgrammingError("List variable does not resolve to a list"); RlistAppend(list, rp->item, rp->type); break; } } } rp = rp->next; } }
static FnCall *DefaultServiceBundleCall(const Promise *pp, const char *service_policy) { Rlist *args = NULL; FnCall *call = NULL; RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, service_policy, RVAL_TYPE_SCALAR); Rval name = DefaultBundleConstraint(pp, "service"); if (PolicyGetBundle(PolicyFromPromise(pp), PromiseGetBundle(pp)->ns, "agent", (char *)name.item)) { Log(LOG_LEVEL_VERBOSE, "Found service special bundle %s in ns %s\n", (char *)name.item, PromiseGetBundle(pp)->ns); call = FnCallNew(name.item, args); } else { call = FnCallNew("standard_services", args); } return call; }
static void GetMacAddress(AgentType ag, int fd, struct ifreq *ifr, struct ifreq *ifp, Rlist **interfaces, Rlist **hardware) { char name[CF_MAXVARSIZE]; if ((ag != AGENT_TYPE_KNOW) && (ag != AGENT_TYPE_GENDOC)) { snprintf(name, CF_MAXVARSIZE, "hardware_mac[%s]", ifp->ifr_name); } else { snprintf(name, CF_MAXVARSIZE, "hardware_mac[interface_name]"); } # if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR) char hw_mac[CF_MAXVARSIZE]; ioctl(fd, SIOCGIFHWADDR, ifr); snprintf(hw_mac, CF_MAXVARSIZE - 1, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (unsigned char) ifr->ifr_hwaddr.sa_data[0], (unsigned char) ifr->ifr_hwaddr.sa_data[1], (unsigned char) ifr->ifr_hwaddr.sa_data[2], (unsigned char) ifr->ifr_hwaddr.sa_data[3], (unsigned char) ifr->ifr_hwaddr.sa_data[4], (unsigned char) ifr->ifr_hwaddr.sa_data[5]); NewScalar("sys", name, hw_mac, DATA_TYPE_STRING); RlistAppend(hardware, hw_mac, RVAL_TYPE_SCALAR); RlistAppend(interfaces, ifp->ifr_name, RVAL_TYPE_SCALAR); snprintf(name, CF_MAXVARSIZE, "mac_%s", CanonifyName(hw_mac)); HardClass(name); # else NewScalar("sys", name, "mac_unknown", DATA_TYPE_STRING); HardClass("mac_unknown"); # endif }
Rlist *ExpandList(EvalContext *ctx, const char *ns, const char *scope, const Rlist *list, int expandnaked) { Rlist *start = NULL; Rval returnval; for (const Rlist *rp = list; rp != NULL; rp = rp->next) { if (!expandnaked && (rp->val.type == RVAL_TYPE_SCALAR) && IsNakedVar(RlistScalarValue(rp), '@')) { returnval = RvalNew(RlistScalarValue(rp), RVAL_TYPE_SCALAR); } else if ((rp->val.type == RVAL_TYPE_SCALAR) && IsNakedVar(RlistScalarValue(rp), '@')) { char naked[CF_MAXVARSIZE]; GetNaked(naked, RlistScalarValue(rp)); if (!IsExpandable(naked)) { VarRef *ref = VarRefParseFromScope(naked, scope); DataType value_type = DATA_TYPE_NONE; const void *value = EvalContextVariableGet(ctx, ref, &value_type); if (value) { returnval = ExpandPrivateRval(ctx, ns, scope, value, DataTypeToRvalType(value_type)); } else { returnval = ExpandPrivateRval(ctx, ns, scope, rp->val.item, rp->val.type); } VarRefDestroy(ref); } else { returnval = ExpandPrivateRval(ctx, ns, scope, rp->val.item, rp->val.type); } } else { returnval = ExpandPrivateRval(ctx, ns, scope, rp->val.item, rp->val.type); } RlistAppend(&start, returnval.item, returnval.type); RvalDestroy(returnval); } return start; }
Rlist *ExpandList(EvalContext *ctx, const char *ns, const char *scope, const Rlist *list, int expandnaked) { Rlist *start = NULL; for (const Rlist *rp = list; rp != NULL; rp = rp->next) { Rval returnval = ExpandListEntry(ctx, ns, scope, expandnaked, rp->val); RlistAppend(&start, returnval.item, returnval.type); RvalDestroy(returnval); } return start; }
Rlist *RlistCopy(const Rlist *list) { Rlist *start = NULL; if (list == NULL) { return NULL; } for (const Rlist *rp = list; rp != NULL; rp = rp->next) { RlistAppend(&start, rp->item, rp->type); // allocates memory for objects } return start; }
static void test_filter_everything(void) { Rlist *list = NULL; for (int i = 1; i < 10; i += 2) { char *item = StringFromLong(i); RlistAppend(&list, item, RVAL_TYPE_SCALAR); } assert_int_equal(5, RlistLen(list)); int mod_by = 0; RlistFilter(&list, is_even, &mod_by, free); assert_int_equal(0, RlistLen(list)); assert_true(list == NULL); }
static Rval RvalCopyList(Rval rval) { assert(rval.type == RVAL_TYPE_LIST); if (!rval.item) { return ((Rval) {NULL, RVAL_TYPE_LIST}); } Rlist *start = NULL; for (const Rlist *rp = rval.item; rp != NULL; rp = rp->next) { RlistAppend(&start, rp->item, rp->type); } return (Rval) {start, RVAL_TYPE_LIST}; }
static Rlist *NewExpArgs(EvalContext *ctx, const Policy *policy, const FnCall *fp) { { const FnCallType *fn = FnCallTypeGet(fp->name); int len = RlistLen(fp->args); if (!(fn->options & FNCALL_OPTION_VARARG)) { if (len != FnNumArgs(fn)) { Log(LOG_LEVEL_ERR, "Arguments to function '%s' do not tally. Expected %d not %d", fp->name, FnNumArgs(fn), len); PromiseRef(LOG_LEVEL_ERR, fp->caller); exit(EXIT_FAILURE); } } } Rlist *expanded_args = NULL; for (const Rlist *rp = fp->args; rp != NULL; rp = rp->next) { Rval rval; switch (rp->val.type) { case RVAL_TYPE_FNCALL: { FnCall *subfp = RlistFnCallValue(rp); rval = FnCallEvaluate(ctx, policy, subfp, fp->caller).rval; assert(rval.item); } break; default: rval = ExpandPrivateRval(ctx, NULL, NULL, rp->val.item, rp->val.type); assert(rval.item); break; } RlistAppend(&expanded_args, rval.item, rval.type); RvalDestroy(rval); } return expanded_args; }
Rlist *NewExpArgs(EvalContext *ctx, const FnCall *fp, const Promise *pp) { int len; Rval rval; Rlist *newargs = NULL; FnCall *subfp; const FnCallType *fn = FnCallTypeGet(fp->name); len = RlistLen(fp->args); if (!fn->varargs) { if (len != FnNumArgs(fn)) { CfOut(OUTPUT_LEVEL_ERROR, "", "Arguments to function %s(.) do not tally. Expect %d not %d", fp->name, FnNumArgs(fn), len); PromiseRef(OUTPUT_LEVEL_ERROR, pp); exit(1); } } for (const Rlist *rp = fp->args; rp != NULL; rp = rp->next) { switch (rp->type) { case RVAL_TYPE_FNCALL: subfp = (FnCall *) rp->item; rval = FnCallEvaluate(ctx, subfp, pp).rval; break; default: rval = ExpandPrivateRval(ScopeGetCurrent()->scope, (Rval) {rp->item, rp->type}); break; } CfDebug("EXPARG: %s.%s\n", ScopeGetCurrent()->scope, (char *) rval.item); RlistAppend(&newargs, rval.item, rval.type); RvalDestroy(rval); } return newargs; }
Rlist *RlistAppendIdemp(Rlist **start, void *item, RvalType type) { Rlist *rp, *ins = NULL; if (type == RVAL_TYPE_LIST) { for (rp = (Rlist *) item; rp != NULL; rp = rp->next) { ins = RlistAppendIdemp(start, rp->item, rp->type); } return ins; } if (!RlistKeyIn(*start, (char *) item)) { return RlistAppend(start, (char *) item, type); } else { return NULL; } }
static void DoVerifyServices(Attributes a, Promise *pp, const ReportContext *report_context) { FnCall *default_bundle = NULL; Rlist *args = NULL; // Need to set up the default service pack to eliminate syntax if (ConstraintGetRvalValue("service_bundle", pp, RVAL_TYPE_SCALAR) == NULL) { switch (a.service.service_policy) { case cfsrv_start: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "start", RVAL_TYPE_SCALAR); break; case cfsrv_restart: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "restart", RVAL_TYPE_SCALAR); break; case cfsrv_reload: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "restart", RVAL_TYPE_SCALAR); break; case cfsrv_stop: case cfsrv_disable: default: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "stop", RVAL_TYPE_SCALAR); break; } default_bundle = FnCallNew("default:standard_services", args); PromiseAppendConstraint(pp, "service_bundle", (Rval) {default_bundle, RVAL_TYPE_FNCALL }, "any", false); a.havebundle = true; } // Set $(this.service_policy) for flexible bundle adaptation switch (a.service.service_policy) { case cfsrv_start: NewScalar("this", "service_policy", "start", DATA_TYPE_STRING); break; case cfsrv_restart: NewScalar("this", "service_policy", "restart", DATA_TYPE_STRING); break; case cfsrv_reload: NewScalar("this", "service_policy", "reload", DATA_TYPE_STRING); break; case cfsrv_stop: case cfsrv_disable: default: NewScalar("this", "service_policy", "stop", DATA_TYPE_STRING); break; } const Bundle *bp = PolicyGetBundle(PolicyFromPromise(pp), NULL, "agent", default_bundle->name); if (!bp) { bp = PolicyGetBundle(PolicyFromPromise(pp), NULL, "common", default_bundle->name); } if (default_bundle && bp == NULL) { cfPS(OUTPUT_LEVEL_INFORM, CF_FAIL, "", pp, a, " !! Service %s could not be invoked successfully\n", pp->promiser); } if (!DONTDO) { VerifyMethod("service_bundle", a, pp, report_context); // Send list of classes to set privately? } }
static void test_map_iterators_from_rval_naked_list_var_namespace(void **state) { EvalContext *ctx = *state; Policy *p = PolicyNew(); Bundle *bp = PolicyAppendBundle(p, "ns", "scope", "agent", NULL, NULL); { Rlist *list = NULL; RlistAppend(&list, "jersey", RVAL_TYPE_SCALAR); VarRef *lval = VarRefParse("ns:scope.jwow"); EvalContextVariablePut(ctx, lval, list, CF_DATA_TYPE_STRING_LIST, NULL); VarRefDestroy(lval); RlistDestroy(list); } EvalContextStackPushBundleFrame(ctx, bp, NULL, false); { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; MapIteratorsFromRval(ctx, bp, (Rval) { "${jwow}", RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_int_equal(1, RlistLen(lists)); assert_string_equal("jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; char *str = xstrdup("${scope.jwow}"); MapIteratorsFromRval(ctx, bp, (Rval) { str, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_string_equal("${scope#jwow}", str); free(str); assert_int_equal(1, RlistLen(lists)); assert_string_equal("scope#jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; char *str = xstrdup("${ns:scope.jwow}"); MapIteratorsFromRval(ctx, bp, (Rval) { str, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_string_equal("${ns*scope#jwow}", str); free(str); assert_int_equal(1, RlistLen(lists)); assert_string_equal("ns*scope#jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } EvalContextStackPopFrame(ctx); PolicyDestroy(p); }
Rlist *RlistAppend(Rlist **start, const void *item, RvalType type) /* Allocates new memory for objects - careful, could leak! */ { Rlist *rp, *lp = *start; FnCall *fp; switch (type) { case RVAL_TYPE_SCALAR: return RlistAppendScalar(start, item); case RVAL_TYPE_FNCALL: CfDebug("Appending function to rval-list function call: "); fp = (FnCall *) item; if (DEBUG) { FnCallShow(stdout, fp); } CfDebug("\n"); break; case RVAL_TYPE_LIST: CfDebug("Expanding and appending list object\n"); for (rp = (Rlist *) item; rp != NULL; rp = rp->next) { lp = RlistAppend(start, rp->item, rp->type); } return lp; default: CfDebug("Cannot append %c to rval-list [%s]\n", type, (char *) item); return NULL; } rp = xmalloc(sizeof(Rlist)); if (*start == NULL) { *start = rp; } else { for (lp = *start; lp->next != NULL; lp = lp->next) { } lp->next = rp; } rp->item = RvalCopy((Rval) {(void *) item, type}).item; rp->type = type; /* scalar, builtin function */ ThreadLock(cft_lock); if (type == RVAL_TYPE_LIST) { rp->state_ptr = rp->item; } else { rp->state_ptr = NULL; } rp->next = NULL; ThreadUnlock(cft_lock); return rp; }
void GetInterfacesInfo(AgentType ag) { int fd, len, i, j, first_address = false, ipdefault = false; struct ifreq ifbuf[CF_IFREQ], ifr, *ifp; struct ifconf list; struct sockaddr_in *sin; struct hostent *hp; char *sp, workbuf[CF_BUFSIZE]; char ip[CF_MAXVARSIZE]; char name[CF_MAXVARSIZE]; char last_name[CF_BUFSIZE]; Rlist *interfaces = NULL, *hardware = NULL, *ips = NULL; CfDebug("GetInterfacesInfo()\n"); // Long-running processes may call this many times DeleteItemList(IPADDRESSES); IPADDRESSES = NULL; memset(ifbuf, 0, sizeof(ifbuf)); InitIgnoreInterfaces(); last_name[0] = '\0'; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { CfOut(OUTPUT_LEVEL_ERROR, "socket", "Couldn't open socket"); exit(1); } list.ifc_len = sizeof(ifbuf); list.ifc_req = ifbuf; # ifdef SIOCGIFCONF if (ioctl(fd, SIOCGIFCONF, &list) == -1 || (list.ifc_len < (sizeof(struct ifreq)))) # else if ((ioctl(fd, OSIOCGIFCONF, &list) == -1) || (list.ifc_len < (sizeof(struct ifreq)))) # endif { CfOut(OUTPUT_LEVEL_ERROR, "ioctl", "Couldn't get interfaces - old kernel? Try setting CF_IFREQ to 1024"); exit(1); } last_name[0] = '\0'; for (j = 0, len = 0, ifp = list.ifc_req; len < list.ifc_len; len += SIZEOF_IFREQ(*ifp), j++, ifp = (struct ifreq *) ((char *) ifp + SIZEOF_IFREQ(*ifp))) { if (ifp->ifr_addr.sa_family == 0) { continue; } if ((ifp->ifr_name == NULL) || (strlen(ifp->ifr_name) == 0)) { continue; } /* Skip virtual network interfaces for Linux, which seems to be a problem */ if (IgnoreInterface(ifp->ifr_name)) { continue; } if (strstr(ifp->ifr_name, ":")) { #ifdef __linux__ CfOut(OUTPUT_LEVEL_VERBOSE, "", "Skipping apparent virtual interface %d: %s\n", j + 1, ifp->ifr_name); continue; #endif } else { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Interface %d: %s\n", j + 1, ifp->ifr_name); } // Ignore the loopback if (strcmp(ifp->ifr_name, "lo") == 0) { continue; } if (strncmp(last_name, ifp->ifr_name, sizeof(ifp->ifr_name)) == 0) { first_address = false; } else { strncpy(last_name, ifp->ifr_name, sizeof(ifp->ifr_name)); if (!first_address) { NewScalar("sys", "interface", last_name, DATA_TYPE_STRING); first_address = true; } } snprintf(workbuf, CF_BUFSIZE, "net_iface_%s", CanonifyName(ifp->ifr_name)); HardClass(workbuf); if (ifp->ifr_addr.sa_family == AF_INET) { strncpy(ifr.ifr_name, ifp->ifr_name, sizeof(ifp->ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) { CfOut(OUTPUT_LEVEL_ERROR, "ioctl", "No such network device"); continue; } if ((ifr.ifr_flags & IFF_UP) && (!(ifr.ifr_flags & IFF_LOOPBACK))) { sin = (struct sockaddr_in *) &ifp->ifr_addr; if (IgnoreJailInterface(j + 1, sin)) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Ignoring interface %d", j + 1); continue; } CfDebug("Adding hostip %s..\n", inet_ntoa(sin->sin_addr)); HardClass(inet_ntoa(sin->sin_addr)); if ((hp = gethostbyaddr((char *) &(sin->sin_addr.s_addr), sizeof(sin->sin_addr.s_addr), AF_INET)) == NULL) { CfDebug("No hostinformation for %s found\n", inet_ntoa(sin->sin_addr)); } else { if (hp->h_name != NULL) { CfDebug("Adding hostname %s..\n", hp->h_name); HardClass(hp->h_name); if (hp->h_aliases != NULL) { for (i = 0; hp->h_aliases[i] != NULL; i++) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Adding alias %s..\n", hp->h_aliases[i]); HardClass(hp->h_aliases[i]); } } } } if (strcmp(inet_ntoa(sin->sin_addr), "0.0.0.0") == 0) { // Maybe we need to do something windows specific here? CfOut(OUTPUT_LEVEL_VERBOSE, "", " !! Cannot discover hardware IP, using DNS value"); strcpy(ip, "ipv4_"); strcat(ip, VIPADDRESS); AppendItem(&IPADDRESSES, VIPADDRESS, ""); RlistAppend(&ips, VIPADDRESS, RVAL_TYPE_SCALAR); for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; HardClass(ip); } } strcpy(ip, VIPADDRESS); i = 3; for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; snprintf(name, CF_MAXVARSIZE - 1, "ipv4_%d[%s]", i--, CanonifyName(VIPADDRESS)); NewScalar("sys", name, ip, DATA_TYPE_STRING); } } continue; } strncpy(ip, "ipv4_", CF_MAXVARSIZE); strncat(ip, inet_ntoa(sin->sin_addr), CF_MAXVARSIZE - 6); HardClass(ip); if (!ipdefault) { ipdefault = true; NewScalar("sys", "ipv4", inet_ntoa(sin->sin_addr), DATA_TYPE_STRING); strcpy(VIPADDRESS, inet_ntoa(sin->sin_addr)); } AppendItem(&IPADDRESSES, inet_ntoa(sin->sin_addr), ""); RlistAppend(&ips, inet_ntoa(sin->sin_addr), RVAL_TYPE_SCALAR); for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; HardClass(ip); } } // Set the IPv4 on interface array strcpy(ip, inet_ntoa(sin->sin_addr)); if ((ag != AGENT_TYPE_KNOW) && (ag != AGENT_TYPE_GENDOC)) { snprintf(name, CF_MAXVARSIZE - 1, "ipv4[%s]", CanonifyName(ifp->ifr_name)); } else { snprintf(name, CF_MAXVARSIZE - 1, "ipv4[interface_name]"); } NewScalar("sys", name, ip, DATA_TYPE_STRING); i = 3; for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; if ((ag != AGENT_TYPE_KNOW) && (ag != AGENT_TYPE_GENDOC)) { snprintf(name, CF_MAXVARSIZE - 1, "ipv4_%d[%s]", i--, CanonifyName(ifp->ifr_name)); } else { snprintf(name, CF_MAXVARSIZE - 1, "ipv4_%d[interface_name]", i--); } NewScalar("sys", name, ip, DATA_TYPE_STRING); } } } // Set the hardware/mac address array GetMacAddress(ag, fd, &ifr, ifp, &interfaces, &hardware); } } close(fd); NewList("sys", "interfaces", interfaces, DATA_TYPE_STRING_LIST); NewList("sys", "hardware_addresses", hardware, DATA_TYPE_STRING_LIST); NewList("sys", "ip_addresses", ips, DATA_TYPE_STRING_LIST); RlistDestroy(interfaces); RlistDestroy(hardware); RlistDestroy(ips); FindV6InterfacesInfo(); }