コード例 #1
0
ファイル: parse.c プロジェクト: fastly/rsyslog
/* Parse a quoted string ("-some-data") from the given position.
 * Leading whitespace before the first quote is skipped. During
 * parsing, escape sequences are detected and converted:
 * \\ - backslash character
 * \" - quote character
 * any other value \<somechar> is reserved for future use.
 *
 * After return, the parse pointer is paced after the trailing
 * quote.
 *
 * Output:
 * ppCStr Pointer to the parsed string - must be freed by caller and
 *        does NOT include the quotes.
 * rgerhards, 2005-09-19
 */
rsRetVal parsQuotedCStr(rsParsObj *pThis, cstr_t **ppCStr)
{
	register unsigned char *pC;
	cstr_t *pCStr = NULL;
	DEFiRet;

	rsCHECKVALIDOBJECT(pThis, OIDrsPars);

	CHKiRet(parsSkipAfterChar(pThis, '"'));
	pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;

	/* OK, we most probably can obtain a value... */
	CHKiRet(cstrConstruct(&pCStr));

	while(pThis->iCurrPos < cstrLen(pThis->pCStr)) {
		if(*pC == '"') {
			break;	/* we are done! */
		} else if(*pC == '\\') {
			++pThis->iCurrPos;
			++pC;
			if(pThis->iCurrPos < cstrLen(pThis->pCStr)) {
				/* in this case, we copy the escaped character
				 * to the output buffer (but do not rely on this,
				 * we might later introduce other things, like \007!
				 */
				CHKiRet(cstrAppendChar(pCStr, *pC));
			}
		} else { /* regular character */
			CHKiRet(cstrAppendChar(pCStr, *pC));
		}
		++pThis->iCurrPos;
		++pC;
	}
	
	if(*pC == '"') {
		++pThis->iCurrPos; /* 'eat' trailing quote */
	} else {
		/* error - improperly quoted string! */
		cstrDestruct(&pCStr);
		ABORT_FINALIZE(RS_RET_MISSING_TRAIL_QUOTE);
	}

	/* We got the string, let's finish it...  */
	CHKiRet(cstrFinalize(pCStr));

	/* done! */
	*ppCStr = pCStr;

finalize_it:
	if(iRet != RS_RET_OK) {
		if(pCStr != NULL)
			cstrDestruct(&pCStr);
	}

	RETiRet;
}
コード例 #2
0
ファイル: outchannel.c プロジェクト: DooDleZzz/rsyslog
/* helper to ochAddLine. Parses a comma-delimited field
 * The field is delimited by SP or comma. Leading whitespace
 * is "eaten" and does not become part of the field content.
 */
static rsRetVal get_Field(uchar **pp, uchar **pField)
{
	DEFiRet;
	register uchar *p;
	cstr_t *pStrB = NULL;

	assert(pp != NULL);
	assert(*pp != NULL);
	assert(pField != NULL);

	skip_Comma((char**)pp);
	p = *pp;

	CHKiRet(cstrConstruct(&pStrB));

	/* copy the field */
	while(*p && *p != ' ' && *p != ',') {
		CHKiRet(cstrAppendChar(pStrB, *p++));
	}

	*pp = p;
	CHKiRet(cstrFinalize(pStrB));
	CHKiRet(cstrConvSzStrAndDestruct(pStrB, pField, 0));

finalize_it:
	if(iRet != RS_RET_OK) {
		if(pStrB != NULL)
			cstrDestruct(&pStrB);
	}

	RETiRet;
}
コード例 #3
0
ファイル: outchannel.c プロジェクト: DooDleZzz/rsyslog
/* helper to ochAddLine. Parses everything from the
 * current position to the end of line and returns it
 * to the caller. Leading white space is removed, but
 * not trailing.
 */
static inline rsRetVal get_restOfLine(uchar **pp, uchar **pBuf)
{
	DEFiRet;
	register uchar *p;
	cstr_t *pStrB = NULL;

	assert(pp != NULL);
	assert(*pp != NULL);
	assert(pBuf != NULL);

	skip_Comma((char**)pp);
	p = *pp;

	CHKiRet(cstrConstruct(&pStrB));

	/* copy the field */
	while(*p) {
		CHKiRet(cstrAppendChar(pStrB, *p++));
	}

	*pp = p;
	CHKiRet(cstrFinalize(pStrB));
	CHKiRet(cstrConvSzStrAndDestruct(pStrB, pBuf, 0));

finalize_it:
	if(iRet != RS_RET_OK) {
		if(pStrB != NULL)
			cstrDestruct(&pStrB);
	}

	RETiRet;
}
コード例 #4
0
ファイル: cfsysline.c プロジェクト: Werkov/rsyslog
/* Parse and a word config line option. A word is a consequtive
 * sequence of non-whitespace characters. pVal must be
 * a pointer to a string which is to receive the option
 * value. The returned string must be freed by the caller.
 * rgerhards, 2007-09-07
 * To facilitate multiple instances of the same command line
 * directive, doGetWord() now checks if pVal is already a
 * non-NULL pointer. If so, we assume it was created by a previous
 * incarnation and is automatically freed. This happens only when
 * no custom handler is defined. If it is, the customer handler
 * must do the cleanup. I have checked and this was al also memory
 * leak with some code. Obviously, not a large one. -- rgerhards, 2007-12-20
 * Just to clarify: if pVal is parsed to a custom handler, this handler
 * is responsible for freeing pVal. -- rgerhards, 2008-03-20
 */
static rsRetVal doGetWord(uchar **pp, rsRetVal (*pSetHdlr)(void*, uchar*), void *pVal)
{
	DEFiRet;
	cstr_t *pStrB = NULL;
	uchar *pNewVal;

	ASSERT(pp != NULL);
	ASSERT(*pp != NULL);

	CHKiRet(getWord(pp, &pStrB));
	CHKiRet(cstrConvSzStrAndDestruct(&pStrB, &pNewVal, 0));

	DBGPRINTF("doGetWord: get newval '%s' (len %d), hdlr %p\n",
		  pNewVal, (int) ustrlen(pNewVal), pSetHdlr);
	/* we got the word, now set it */
	if(pSetHdlr == NULL) {
		/* we should set value directly to var */
		if(*((uchar**)pVal) != NULL)
			free(*((uchar**)pVal)); /* free previous entry */
		*((uchar**)pVal) = pNewVal; /* set new one */
	} else {
		/* we set value via a set function */
		CHKiRet(pSetHdlr(pVal, pNewVal));
	}

	skipWhiteSpace(pp); /* skip over any whitespace */

finalize_it:
	if(iRet != RS_RET_OK) {
		if(pStrB != NULL)
			cstrDestruct(&pStrB);
	}

	RETiRet;
}
コード例 #5
0
ファイル: vm.c プロジェクト: DooDleZzz/rsyslog
/* free the whole function registry
 */
static void
rsfrRemoveAll(void)
{
	rsf_entry_t *pEntry;
	rsf_entry_t *pEntryDel;
	
	BEGINfunc
	pEntry = funcRegRoot;
	while(pEntry != NULL) {
		pEntryDel = pEntry;
		pEntry = pEntry->pNext;
		cstrDestruct(&pEntryDel->pName);
		free(pEntryDel);
	}
	funcRegRoot = NULL;
	ENDfunc
}
コード例 #6
0
ファイル: statsobj.c プロジェクト: Whissi/rsyslog
/* get all the object's countes together as CEE. */
static rsRetVal
getStatsLineCEE(statsobj_t *pThis, cstr_t **ppcstr, const statsFmtType_t fmt, const int8_t bResetCtrs)
{
	cstr_t *pcstr = NULL;
	ctr_t *pCtr;
	json_object *root, *values;
	int locked = 0;
	DEFiRet;

	root = values = NULL;

	CHKiRet(cstrConstruct(&pcstr));

	if (fmt == statsFmt_CEE)
		CHKiRet(rsCStrAppendStrWithLen(pcstr, UCHAR_CONSTANT(CONST_CEE_COOKIE" "), CONST_LEN_CEE_COOKIE + 1));

	CHKmalloc(root = json_object_new_object());

	CHKiRet(addContextForReporting(root, UCHAR_CONSTANT("name"), pThis->name));
	
	if(pThis->origin != NULL) {
		CHKiRet(addContextForReporting(root, UCHAR_CONSTANT("origin"), pThis->origin));
	}

	if (pThis->reporting_ns == NULL) {
		values = json_object_get(root);
	} else {
		CHKmalloc(values = json_object_new_object());
		json_object_object_add(root, (const char*) pThis->reporting_ns, json_object_get(values));
	}

	/* now add all counters to this line */
	pthread_mutex_lock(&pThis->mutCtr);
	locked = 1;
	for(pCtr = pThis->ctrRoot ; pCtr != NULL ; pCtr = pCtr->next) {
		if (fmt == statsFmt_JSON_ES) {
			/* work-around for broken Elasticsearch JSON implementation:
			 * we need to replace dots by a different char, we use bang.
			 * Note: ES 2.0 does not longer accept dot in name
			 */
			uchar esbuf[256];
			strncpy((char*)esbuf, (char*)pCtr->name, sizeof(esbuf)-1);
			esbuf[sizeof(esbuf)-1] = '\0';
			for(uchar *c = esbuf ; *c ; ++c) {
				if(*c == '.')
					*c = '!';
			}
			CHKiRet(addCtrForReporting(values, esbuf, accumulatedValue(pCtr)));
		} else {
			CHKiRet(addCtrForReporting(values, pCtr->name, accumulatedValue(pCtr)));
		}
		resetResettableCtr(pCtr, bResetCtrs);
	}
	pthread_mutex_unlock(&pThis->mutCtr);
	locked = 0;
	CHKiRet(rsCStrAppendStr(pcstr, (const uchar*) json_object_to_json_string(root)));

	cstrFinalize(pcstr);
	*ppcstr = pcstr;
	pcstr = NULL;

finalize_it:
	if(locked) {
		pthread_mutex_unlock(&pThis->mutCtr);
	}

	if (pcstr != NULL) {
		cstrDestruct(&pcstr);
	}
	if (root != NULL) {
		json_object_put(root);
	}
	if (values != NULL) {
		json_object_put(values);
	}
	
	RETiRet;
}
コード例 #7
0
ファイル: parse.c プロジェクト: fastly/rsyslog
rsRetVal parsAddrWithBits(rsParsObj *pThis, struct NetAddr **pIP, int *pBits)
{
	register uchar *pC;
	uchar *pszIP;
	uchar *pszTmp;
	struct addrinfo hints, *res = NULL;
	cstr_t *pCStr;
	DEFiRet;

	rsCHECKVALIDOBJECT(pThis, OIDrsPars);
	assert(pIP != NULL);
	assert(pBits != NULL);

	CHKiRet(cstrConstruct(&pCStr));

	parsSkipWhitespace(pThis);
	pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;

	/* we parse everything until either '/', ',' or
	 * whitespace. Validity will be checked down below.
	 */
	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)
	      && *pC != '/' && *pC != ',' && !isspace((int)*pC)) {
		if((iRet = cstrAppendChar(pCStr, *pC)) != RS_RET_OK) {
			cstrDestruct (&pCStr);
			FINALIZE;
		}
		++pThis->iCurrPos;
		++pC;
	}
	
	/* We got the string, let's finish it...  */
	if((iRet = cstrFinalize(pCStr)) != RS_RET_OK) {
		cstrDestruct(&pCStr);
		FINALIZE;
	}

	/* now we have the string and must check/convert it to
	 * an NetAddr structure.
	 */	
  	CHKiRet(cstrConvSzStrAndDestruct(pCStr, &pszIP, 0));

	*pIP = calloc(1, sizeof(struct NetAddr));
	
	if (*((char*)pszIP) == '[') {
		pszTmp = (uchar*)strchr ((char*)pszIP, ']');
		if (pszTmp == NULL) {
			free (pszIP);
			ABORT_FINALIZE(RS_RET_INVALID_IP);
		}
		*pszTmp = '\0';

		memset (&hints, 0, sizeof (struct addrinfo));
		hints.ai_family = AF_INET6;
#		ifdef AI_ADDRCONFIG
			hints.ai_flags  = AI_ADDRCONFIG | AI_NUMERICHOST;
#		else
			hints.ai_flags  = AI_NUMERICHOST;
#		endif
		
		switch(getaddrinfo ((char*)pszIP+1, NULL, &hints, &res)) {
		case 0: 
			(*pIP)->addr.NetAddr = MALLOC (res->ai_addrlen);
			memcpy ((*pIP)->addr.NetAddr, res->ai_addr, res->ai_addrlen);
			freeaddrinfo (res);
			break;
		case EAI_NONAME:
			F_SET((*pIP)->flags, ADDR_NAME|ADDR_PRI6);
			(*pIP)->addr.HostWildcard = strdup ((const char*)pszIP+1);
			break;
		default:
			free (pszIP);
			free (*pIP);
			ABORT_FINALIZE(RS_RET_ERR);
		}
		
		if(*pC == '/') {
			/* mask bits follow, let's parse them! */
			++pThis->iCurrPos; /* eat slash */
			if((iRet = parsInt(pThis, pBits)) != RS_RET_OK) {
				free (pszIP);
				free (*pIP);
				FINALIZE;
			}
			/* we need to refresh pointer (changed by parsInt()) */
			pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;
		} else {
			/* no slash, so we assume a single host (/128) */
			*pBits = 128;
		}
	} else { /* now parse IPv4 */
		memset (&hints, 0, sizeof (struct addrinfo));
		hints.ai_family = AF_INET;
#		ifdef AI_ADDRCONFIG
			hints.ai_flags  = AI_ADDRCONFIG | AI_NUMERICHOST;
#		else
			hints.ai_flags  = AI_NUMERICHOST;
#		endif
		
		switch(getaddrinfo ((char*)pszIP, NULL, &hints, &res)) {
		case 0: 
			(*pIP)->addr.NetAddr = MALLOC (res->ai_addrlen);
			memcpy ((*pIP)->addr.NetAddr, res->ai_addr, res->ai_addrlen);
			freeaddrinfo (res);
			break;
		case EAI_NONAME:
			F_SET((*pIP)->flags, ADDR_NAME);
			(*pIP)->addr.HostWildcard = strdup ((const char*)pszIP);
			break;
		default:
			free (pszIP);
			free (*pIP);
			ABORT_FINALIZE(RS_RET_ERR);
		}
			
		if(*pC == '/') {
			/* mask bits follow, let's parse them! */
			++pThis->iCurrPos; /* eat slash */
			if((iRet = parsInt(pThis, pBits)) != RS_RET_OK) {
				free (pszIP);
				free (*pIP);
				FINALIZE;
			}
			/* we need to refresh pointer (changed by parsInt()) */
			pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;
		} else {
			/* no slash, so we assume a single host (/32) */
			*pBits = 32;
		}
	}
	free(pszIP); /* no longer needed */

	/* skip to next processable character */
	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)
	      && (*pC == ',' || isspace((int)*pC))) {
		++pThis->iCurrPos;
		++pC;
	}

	iRet = RS_RET_OK;

finalize_it:
	RETiRet;
}