/* * Parse the attributes component of a PCP connection string. * Optionally, an initial attribute:value pair can be passed * in as well to add to the parsed set. */ static int parseAttributeSpec( const char *spec, /* the original, complete string to parse */ char **position, /* parse from here onward and update at end */ int attribute, char *value, __pmHashCtl *attributes, char **errmsg) { char *s, *start, *v = NULL; char buffer[32]; /* must be large enough to hold largest attr name */ int buflen, attr, len, sts; if (attribute != PCP_ATTR_NONE) if ((sts = __pmHashAdd(attribute, (void *)value, attributes)) < 0) return sts; for (s = start = *position; s != NULL; s++) { /* parse: foo=bar&moo&goo=blah ... go! */ if (*s == '\0' || *s == '/' || *s == '&') { if ((*s == '\0' || *s == '/') && s == start) break; len = v ? (v - start - 1) : (s - start); buflen = (len < sizeof(buffer)-1) ? len : sizeof(buffer)-1; strncpy(buffer, start, buflen); buffer[buflen] = '\0'; attr = __pmLookupAttrKey(buffer, buflen+1); if (attr != PCP_ATTR_NONE) { char *val = NULL; if (v && (val = strndup(v, s - v)) == NULL) { sts = -ENOMEM; goto fail; } if ((sts = __pmHashAdd(attr, (void *)val, attributes)) < 0) { free(val); goto fail; } } v = NULL; if (*s == '\0' || *s == '/') break; start = s + 1; /* start of attribute name */ continue; } if (*s == '=') { v = s + 1; /* start of attribute value */ } } *position = s; return 0; fail: if (attribute != PCP_ATTR_NONE) /* avoid double free in caller */ __pmHashDel(attribute, (void *)value, attributes); __pmFreeAttrsSpec(attributes); return sts; }
void DeleteClient(ClientInfo *cp) { int i; for (i = 0; i < nClients; i++) if (cp == &client[i]) break; if (i == nClients) { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) { __pmNotifyErr(LOG_ERR, "DeleteClient: tried to delete non-existent client\n"); Shutdown(); exit(1); } #endif return; } if (cp->fd != -1) { __pmFD_CLR(cp->fd, &clientFds); __pmCloseSocket(cp->fd); } if (i == nClients-1) { i--; while (i >= 0 && !client[i].status.connected) i--; nClients = (i >= 0) ? i + 1 : 0; } if (cp->fd == maxClientFd) { maxClientFd = -1; for (i = 0; i < nClients; i++) { if (client[i].fd > maxClientFd) maxClientFd = client[i].fd; } } for (i = 0; i < cp->szProfile; i++) { if (cp->profile[i] != NULL) { __pmFreeProfile(cp->profile[i]); cp->profile[i] = NULL; } } __pmFreeAttrsSpec(&cp->attrs); __pmHashClear(&cp->attrs); __pmSockAddrFree(cp->addr); cp->addr = NULL; cp->status.connected = 0; cp->fd = -1; NotifyEndContext(cp-client); }
void __pmFreeHostAttrsSpec(pmHostSpec *hosts, int count, __pmHashCtl *attrs) { __pmFreeHostSpec(hosts, count); __pmFreeAttrsSpec(attrs); }