Esempio n. 1
0
int
__pmDecodeLabelReq(__pmPDU *pdubuf, int *ident, int *otype)
{
    label_req_t	*pp;
    char	*pduend;
    int		type;

    pp = (label_req_t *)pdubuf;
    pduend = (char *)pdubuf + pp->hdr.len;

    if (pduend - (char*)pp < sizeof(label_req_t))
	return PM_ERR_IPC;

    type = *otype = ntohl(pp->type);
    if (type & PM_LABEL_DOMAIN)
        *ident = ntohl(pp->ident);
    else if (type & (PM_LABEL_CLUSTER|PM_LABEL_ITEM|PM_LABEL_INSTANCES))
	*ident = __ntohpmID(pp->ident);
    else if (type & PM_LABEL_INDOM)
        *ident = __ntohpmInDom(pp->ident);
    else
        *ident = PM_ID_NULL;

    return 0;
}
Esempio n. 2
0
int
__pmDecodeInstanceReq(__pmPDU *pdubuf, __pmTimeval *when, pmInDom *indom, int *inst, char **name)
{
    instance_req_t	*pp;
    char		*pdu_end;
    int			namelen;

    pp = (instance_req_t *)pdubuf;
    pdu_end = (char *)pdubuf + pp->hdr.len;

    if (pdu_end - (char *)pp < sizeof(instance_req_t) - sizeof(pp->name))
	return PM_ERR_IPC;

    when->tv_sec = ntohl(pp->when.tv_sec);
    when->tv_usec = ntohl(pp->when.tv_usec);
    *indom = __ntohpmInDom(pp->indom);
    *inst = ntohl(pp->inst);
    namelen = ntohl(pp->namelen);
    if (namelen > 0) {
	if (namelen >= INT_MAX - 1 || namelen > pp->hdr.len)
	    return PM_ERR_IPC;
	if (pdu_end - (char *)pp < sizeof(instance_req_t) - sizeof(pp->name) + namelen)
	    return PM_ERR_IPC;
	if ((*name = (char *)malloc(namelen+1)) == NULL)
	    return -oserror();
	strncpy(*name, pp->name, namelen);
	(*name)[namelen] = '\0';
    }
    else if (namelen < 0) {
	return PM_ERR_IPC;
    } else {
	*name = NULL;
    }
    return 0;
}
Esempio n. 3
0
int
__pmDecodeDesc(__pmPDU *pdubuf, pmDesc *desc)
{
    desc_t	*pp;
    char	*pduend;

    pp = (desc_t *)pdubuf;
    pduend = (char *)pdubuf + pp->hdr.len;

    if (pduend - (char*)pp != sizeof(desc_t))
	return PM_ERR_IPC;

    desc->type = ntohl(pp->desc.type);
    desc->sem = ntohl(pp->desc.sem);
    desc->indom = __ntohpmInDom(pp->desc.indom);
    desc->units = __ntohpmUnits(pp->desc.units);
    desc->pmid = __ntohpmID(pp->desc.pmid);
    return 0;
}
Esempio n. 4
0
int
__pmDecodeTextReq(__pmPDU *pdubuf, int *ident, int *type)
{
    text_req_t	*pp;
    char	*pduend;

    pp = (text_req_t *)pdubuf;
    pduend = (char *)pdubuf + pp->hdr.len;

    if (pduend - (char*)pp < sizeof(text_req_t))
	return PM_ERR_IPC;

    *type = ntohl(pp->type);
    if ((*type) & PM_TEXT_PMID)
	*ident = __ntohpmID(pp->ident);
    else if ((*type) & PM_TEXT_INDOM)
	*ident = __ntohpmInDom(pp->ident);
    else
	*ident = PM_INDOM_NULL;

    return 0;
}
Esempio n. 5
0
File: libpcp.c Progetto: Aconex/pcp
/*
 * load _all_ of the hashed pmDesc and __pmLogInDom structures from the metadata
 * log file -- used at the initialization (NewContext) of an archive
 * If version 2 then
 * load all the names from the meta data and create l_pmns.
 */
int
__pmLogLoadMeta(__pmLogCtl *lcp)
{
    int		rlen;
    int		check;
    pmDesc	*dp;
    int		sts = 0;
    __pmLogHdr	h;
    FILE	*f = lcp->l_mdfp;
    int         version2 = ((lcp->l_label.ill_magic & 0xff) == PM_LOG_VERS02);
    int		numpmid = 0;
    int		n;
    
    if (version2) {
       if ((sts = __pmNewPMNS(&(lcp->l_pmns))) < 0) {
          goto end;
       }
    }

    fseek(f, (long)(sizeof(__pmLogLabel) + 2*sizeof(int)), SEEK_SET);
    for ( ; ; ) {
	n = (int)fread(&h, 1, sizeof(__pmLogHdr), f);

	/* swab hdr */
	h.len = ntohl(h.len);
	h.type = ntohl(h.type);

	if (n != sizeof(__pmLogHdr) || h.len <= 0) {
            if (feof(f)) {
		clearerr(f);
                sts = 0;
		goto end;
            }
#ifdef PCP_DEBUG
	    if (pmDebug & DBG_TRACE_LOGMETA) {
		fprintf(stderr, "__pmLogLoadMeta: header read -> %d: expected: %d\n",
			n, (int)sizeof(__pmLogHdr));
	    }
#endif
	    if (ferror(f)) {
		clearerr(f);
		sts = -errno;
	    }
	    else
		sts = PM_ERR_LOGREC;
	    goto end;
	}
#ifdef PCP_DEBUG
	if (pmDebug & DBG_TRACE_LOGMETA) {
	    fprintf(stderr, "__pmLogLoadMeta: record len=%d, type=%d @ offset=%d\n",
		h.len, h.type, (int)(ftell(f) - sizeof(__pmLogHdr)));
	}
#endif
	rlen = h.len - (int)sizeof(__pmLogHdr) - (int)sizeof(int);
	if (h.type == TYPE_DESC) {
            numpmid++;
	    if ((dp = (pmDesc *)malloc(sizeof(pmDesc))) == NULL) {
		sts = -errno;
		goto end;
	    }
	    if ((n = (int)fread(dp, 1, sizeof(pmDesc), f)) != sizeof(pmDesc)) {
#ifdef PCP_DEBUG
		if (pmDebug & DBG_TRACE_LOGMETA) {
		    fprintf(stderr, "__pmLogLoadMeta: pmDesc read -> %d: expected: %d\n",
			    n, (int)sizeof(pmDesc));
		}
#endif
		if (ferror(f)) {
		    clearerr(f);
		    sts = -errno;
		}
		else
		    sts = PM_ERR_LOGREC;
		goto end;
	    }
	    else {
		/* swab desc */
		dp->type = ntohl(dp->type);
		dp->sem = ntohl(dp->sem);
		dp->indom = __ntohpmInDom(dp->indom);
		dp->units = __ntohpmUnits(dp->units);
		dp->pmid = __ntohpmID(dp->pmid);
	    }

	    if ((sts = __pmHashAdd((int)dp->pmid, (void *)dp, &lcp->l_hashpmid)) < 0)
		goto end;

            if (version2) {
                char name[MAXPATHLEN];
                int numnames;
		int i;
		int len;

                /* read in the names & store in PMNS tree ... */
		if ((n = (int)fread(&numnames, 1, sizeof(numnames), f)) != 
                     sizeof(numnames)) {
#ifdef PCP_DEBUG
		    if (pmDebug & DBG_TRACE_LOGMETA) {
			fprintf(stderr, "__pmLogLoadMeta: numnames read -> %d: expected: %d\n",
				n, (int)sizeof(numnames));
		    }
#endif
		    if (ferror(f)) {
			clearerr(f);
			sts = -errno;
		    }
		    else
			sts = PM_ERR_LOGREC;
		    goto end;
		}
		else {
		    /* swab numnames */
		    numnames = ntohl(numnames);
		}

 		for (i = 0; i < numnames; i++) {
		    if ((n = (int)fread(&len, 1, sizeof(len), f)) != 
			 sizeof(len)) {
#ifdef PCP_DEBUG
			if (pmDebug & DBG_TRACE_LOGMETA) {
			    fprintf(stderr, "__pmLogLoadMeta: len name[%d] read -> %d: expected: %d\n",
				    i, n, (int)sizeof(len));
			}
#endif
			if (ferror(f)) {
			    clearerr(f);
			    sts = -errno;
			}
			else
			    sts = PM_ERR_LOGREC;
			goto end;
		    }
		    else {
			/* swab len */
			len = ntohl(len);
		    }

		    if ((n = (int)fread(name, 1, len, f)) != len) {
#ifdef PCP_DEBUG
			if (pmDebug & DBG_TRACE_LOGMETA) {
			    fprintf(stderr, "__pmLogLoadMeta: name[%d] read -> %d: expected: %d\n",
				    i, n, len);
			}
#endif
			if (ferror(f)) {
			    clearerr(f);
			    sts = -errno;
			}
			else
			    sts = PM_ERR_LOGREC;
			goto end;
		    }
                    name[len] = '\0';
#ifdef PCP_DEBUG
		    if (pmDebug & DBG_TRACE_LOGMETA) {
			fprintf(stderr, "__pmLogLoadMeta: PMID: %s name: %s\n",
				pmIDStr(dp->pmid), name);
		    }
#endif

                    if ((sts = __pmAddPMNSNode(lcp->l_pmns, dp->pmid, name)) < 0) {
			/*
			 * If we see a duplicate PMID, its a recoverable error.
			 * We wont be able to see all of the data in the log, but
			 * its better to provide access to some rather than none,
			 * esp. when only one or two metric IDs may be corrupted
			 * in this way (which we may not be interested in anyway).
			 */
			if (sts != PM_ERR_PMID)
			    goto end;
			sts = 0;
		    } 
		}/*for*/
            }/*version2*/
	}
	else if (h.type == TYPE_INDOM) {
	    int			*tbuf;
	    pmInDom		indom;
	    __pmTimeval		*when;
	    int			numinst;
	    int			*instlist;
	    char		**namelist;
	    char		*namebase;
	    int			*stridx;
	    int			i;
	    int			k;
	    int			allinbuf;

	    if ((tbuf = (int *)malloc(rlen)) == NULL) {
		sts = -errno;
		goto end;
	    }
	    if ((n = (int)fread(tbuf, 1, rlen, f)) != rlen) {
#ifdef PCP_DEBUG
		if (pmDebug & DBG_TRACE_LOGMETA) {
		    fprintf(stderr, "__pmLogLoadMeta: indom read -> %d: expected: %d\n",
			    n, rlen);
		}
#endif
		if (ferror(f)) {
		    clearerr(f);
		    sts = -errno;
		}
		else
		    sts = PM_ERR_LOGREC;
		goto end;
	    }

	    k = 0;
	    when = (__pmTimeval *)&tbuf[k];
	    when->tv_sec = ntohl(when->tv_sec);
	    when->tv_usec = ntohl(when->tv_usec);
	    k += sizeof(*when)/sizeof(int);
	    indom = __ntohpmInDom((unsigned int)tbuf[k++]);
	    numinst = ntohl(tbuf[k++]);
	    if (numinst > 0) {
		instlist = &tbuf[k];
		k += numinst;
		stridx = &tbuf[k];
#if defined(HAVE_32BIT_PTR)
		namelist = (char **)stridx;
		allinbuf = 1; /* allocation is all in tbuf */
#else
		allinbuf = 0; /* allocation for namelist + tbuf */
		/* need to allocate to hold the pointers */
		namelist = (char **)malloc(numinst*sizeof(char*));
		if (namelist == NULL) {
		    sts = -errno;
		    goto end;
		}
#endif
		k += numinst;
		namebase = (char *)&tbuf[k];
	        for (i = 0; i < numinst; i++) {
		    instlist[i] = ntohl(instlist[i]);
	            namelist[i] = &namebase[ntohl(stridx[i])];
		}
	    }
	    else {
		/* no instances, or an error */
		instlist = NULL;
		namelist = NULL;
	    }
	    if ((sts = addindom(lcp, indom, when, numinst, instlist, namelist, tbuf, allinbuf)) < 0)
		goto end;
	}
	else
	    fseek(f, (long)rlen, SEEK_CUR);
	n = (int)fread(&check, 1, sizeof(check), f);
	check = ntohl(check);
	if (n != sizeof(check) || h.len != check) {
#ifdef PCP_DEBUG
	    if (pmDebug & DBG_TRACE_LOGMETA) {
		fprintf(stderr, "__pmLogLoadMeta: trailer read -> %d or len=%d: expected %d @ offset=%d\n",
		    n, check, h.len, (int)(ftell(f) - sizeof(check)));
	    }
#endif
	    if (ferror(f)) {
		clearerr(f);
		sts = -errno;
	    }
	    else
		sts = PM_ERR_LOGREC;
	    goto end;
	}
    }/*for*/
end:
    
    fseek(f, (long)(sizeof(__pmLogLabel) + 2*sizeof(int)), SEEK_SET);

    if (version2 && sts == 0) {
        __pmFixPMNSHashTab(lcp->l_pmns, numpmid, 1);
    }
    return sts;
}
Esempio n. 6
0
int
__pmDecodeProfile(__pmPDU *pdubuf, int *ctxnump, __pmProfile **resultp)
{
    __pmProfile		*instprof;
    __pmInDomProfile	*prof, *p_end;
    profile_t		*pduProfile;
    instprof_t		*pduInstProf;
    __pmPDU		*p = (__pmPDU *)pdubuf;
    char		*pdu_end;
    int			ctxnum;
    int			sts = 0;

    /* First the profile */
    pduProfile = (profile_t *)pdubuf;
    pdu_end = (char*)pdubuf + pduProfile->hdr.len;
    if (pdu_end - (char*)pdubuf < sizeof(profile_t))
	return PM_ERR_IPC;

    ctxnum = ntohl(pduProfile->ctxnum);
    if (ctxnum < 0 || ctxnum > LIMIT_CTXNUM)
	return PM_ERR_IPC;
    if ((instprof = (__pmProfile *)malloc(sizeof(__pmProfile))) == NULL)
	return -oserror();
    instprof->state = ntohl(pduProfile->g_state);
    instprof->profile = NULL;
    instprof->profile_len = ntohl(pduProfile->numprof);
    if (instprof->profile_len < 0) {
	sts = PM_ERR_IPC;
	goto fail;
    }

    p += sizeof(profile_t) / sizeof(__pmPDU);

    if (instprof->profile_len > 0) {
	if (instprof->profile_len >= INT_MAX / sizeof(__pmInDomProfile) ||
	    instprof->profile_len >= pduProfile->hdr.len) {
	    sts = PM_ERR_IPC;
	    goto fail;
	}
	if ((instprof->profile = (__pmInDomProfile *)calloc(
	     instprof->profile_len, sizeof(__pmInDomProfile))) == NULL) {
	    sts = -oserror();
	    goto fail;
	}

	/* Next the profiles (if any) all together */
	for (prof = instprof->profile, p_end = prof + instprof->profile_len;
	     prof < p_end;
	     prof++) {
	    if ((char *)p >= pdu_end) {
		sts = PM_ERR_IPC;
		goto fail;
	    }
	    pduInstProf = (instprof_t *)p;
	    prof->indom = __ntohpmInDom(pduInstProf->indom);
	    prof->state = ntohl(pduInstProf->state);
	    prof->instances = NULL;
	    prof->instances_len = ntohl(pduInstProf->numinst);
	    p += sizeof(instprof_t) / sizeof(__pmPDU);
	}

	/* Finally, all the instances for all profiles (if any) together */
	for (prof = instprof->profile, p_end = prof+instprof->profile_len;
	     prof < p_end;
	     prof++) {
	    int j;

	    if (prof->instances_len > 0) {
		if (prof->instances_len >= INT_MAX / sizeof(int) ||
		    prof->instances_len >= pduProfile->hdr.len) {
		    sts = PM_ERR_IPC;
		    goto fail;
		}
		prof->instances = (int *)calloc(prof->instances_len, sizeof(int));
		if (prof->instances == NULL) {
		    sts = -oserror();
		    goto fail;
		}
		for (j = 0; j < prof->instances_len; j++, p++) {
		    if ((char *)p >= pdu_end) {
			sts = PM_ERR_IPC;
			goto fail;
		    }
		    prof->instances[j] = ntohl(*p);
		}
	    } else if (prof->instances_len < 0) {
		sts = PM_ERR_IPC;
		goto fail;
	    } else {
		prof->instances = NULL;
	    }
	}
    }
    else {
	instprof->profile = NULL;
    }

    *resultp = instprof;
    *ctxnump = ctxnum;
    return 0;

fail:
    if (instprof != NULL) {
	if (instprof->profile != NULL) {
	    for (prof = instprof->profile, p_end = prof+instprof->profile_len;
		 prof < p_end;
		 prof++) {
		if (prof->instances != NULL)
		    free(prof->instances);
	    }
	    free(instprof->profile);
	}
	free(instprof);
    }
    return sts;
}
Esempio n. 7
0
int
__pmDecodeInstance(__pmPDU *pdubuf, __pmInResult **result)
{
    int			i;
    int			j;
    instance_t		*rp;
    instlist_t		*ip;
    __pmInResult	*res;
    int			sts;
    char		*p;
    char		*pdu_end;
    int			keep_instlist;
    int			keep_namelist;

    rp = (instance_t *)pdubuf;
    pdu_end = (char *)pdubuf + rp->hdr.len;

    if (pdu_end - (char *)pdubuf < sizeof(instance_t) - sizeof(__pmPDU))
	return PM_ERR_IPC;

    if ((res = (__pmInResult *)malloc(sizeof(*res))) == NULL)
	return -oserror();
    res->instlist = NULL;
    res->namelist = NULL;
    res->indom = __ntohpmInDom(rp->indom);
    res->numinst = ntohl(rp->numinst);

    if (res->numinst >= (INT_MAX / sizeof(res->instlist[0])) ||
	res->numinst >= (INT_MAX / sizeof(res->namelist[0])) ||
	res->numinst >= rp->hdr.len) {
	sts = PM_ERR_IPC;
	goto badsts;
    }
    if ((res->instlist = (int *)malloc(res->numinst * sizeof(res->instlist[0]))) == NULL) {
	sts = -oserror();
	goto badsts;
    }
    if ((res->namelist = (char **)malloc(res->numinst * sizeof(res->namelist[0]))) == NULL) {
	sts = -oserror();
	goto badsts;
    }
    /* required for __pmFreeInResult() in the event of a later error */
    memset(res->namelist, 0, res->numinst * sizeof(res->namelist[0]));

    if (res->numinst == 1)
	keep_instlist = keep_namelist = 0;
    else
	keep_instlist = keep_namelist = 1;

    for (i = j = 0; i < res->numinst; i++) {
	ip = (instlist_t *)&rp->rest[j/sizeof(__pmPDU)];
	if (sizeof(instlist_t) - sizeof(ip->name) > (size_t)(pdu_end - (char *)ip)) {
	    sts = PM_ERR_IPC;
	    goto badsts;
	}

	res->instlist[i] = ntohl(ip->inst);
	if (res->instlist[i] != PM_IN_NULL)
	    keep_instlist = 1;
	ip->namelen = ntohl(ip->namelen);
	if (ip->namelen > 0)
	    keep_namelist = 1;
	if (ip->namelen < 0) {
	    sts = PM_ERR_IPC;
	    goto badsts;
	}
	if (sizeof(instlist_t) - sizeof(int) + ip->namelen > (size_t)(pdu_end - (char *)ip)) {
	    sts = PM_ERR_IPC;
	    goto badsts;
	}
	if ((p = (char *)malloc(ip->namelen + 1)) == NULL) {
	    sts = -oserror();
	    goto badsts;
	}
	memcpy((void *)p, (void *)ip->name, ip->namelen);
	p[ip->namelen] = '\0';
	res->namelist[i] = p;
	j += sizeof(*ip) - sizeof(ip->name) + PM_PDU_SIZE_BYTES(ip->namelen);
    }
    if (keep_instlist == 0) {
	free(res->instlist);
	res->instlist = NULL;
    }
    if (keep_namelist == 0) {
	free(res->namelist[0]);
	free(res->namelist);
	res->namelist = NULL;
    }

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_INDOM)
	__pmDumpInResult(stderr, res);
#endif
    *result = res;
    return 0;

badsts:
    __pmFreeInResult(res);
    return sts;
}