示例#1
0
/* Start a new thread and add it to the list of currently
 * executing threads. It is added at the end of the list.
 * rgerhards, 2007-12-14
 */
rsRetVal thrdCreate(rsRetVal (*thrdMain)(thrdInfo_t*), rsRetVal(*afterRun)(thrdInfo_t *), sbool bNeedsCancel, uchar *name)
{
	DEFiRet;
	thrdInfo_t *pThis;

	assert(thrdMain != NULL);

	CHKiRet(thrdConstruct(&pThis));
	pThis->bIsActive = 1;
	pThis->pUsrThrdMain = thrdMain;
	pThis->pAfterRun = afterRun;
	pThis->bNeedsCancel = bNeedsCancel;
	pThis->name = ustrdup(name);
	pthread_create(&pThis->thrdID,
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
			   &default_thread_attr,
#else
			   NULL,
#endif
			   thrdStarter, pThis);
	CHKiRet(llAppend(&llThrds, NULL, pThis));

finalize_it:
	RETiRet;
}
示例#2
0
文件: imkmsg.c 项目: henrid14/rsyslog
/* enqueue the the kernel message into the message queue.
 * The provided msg string is not freed - thus must be done
 * by the caller.
 * rgerhards, 2008-04-12
 */
static rsRetVal
enqMsg(uchar *msg, uchar* pszTag, syslog_pri_t pri, struct timeval *tp, struct json_object *json)
{
	struct syslogTime st;
	msg_t *pMsg;
	DEFiRet;

	assert(msg != NULL);
	assert(pszTag != NULL);

	if(tp == NULL) {
		CHKiRet(msgConstruct(&pMsg));
	} else {
		datetime.timeval2syslogTime(tp, &st);
		CHKiRet(msgConstructWithTime(&pMsg, &st, tp->tv_sec));
	}
	MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY);
	MsgSetInputName(pMsg, pInputName);
	MsgSetRawMsgWOSize(pMsg, (char*)msg);
	MsgSetMSGoffs(pMsg, 0);	/* we do not have a header... */
	MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp());
	MsgSetRcvFromIP(pMsg, pLocalHostIP);
	MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()));
	MsgSetTAG(pMsg, pszTag, ustrlen(pszTag));
	msgSetPRI(pMsg, pri);
	pMsg->json = json;
	CHKiRet(submitMsg(pMsg));

finalize_it:
	RETiRet;
}
示例#3
0
文件: cfsysline.c 项目: OPSF/uClinux
/* Parse a number from the configuration line.
 * rgerhards, 2007-07-31
 */
static rsRetVal doGetInt(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *pVal)
{
	uchar *p;
	DEFiRet;
	int64 i;	

	assert(pp != NULL);
	assert(*pp != NULL);
	
	CHKiRet(parseIntVal(pp, &i));
	p = *pp;

	if(pSetHdlr == NULL) {
		/* we should set value directly to var */
		*((int*)pVal) = (int) i;
	} else {
		/* we set value via a set function */
		CHKiRet(pSetHdlr(pVal, (int) i));
	}

	*pp = p;

finalize_it:
	RETiRet;
}
示例#4
0
文件: wtp.c 项目: OPSF/uClinux
/* Construction finalizer
 * rgerhards, 2008-01-17
 */
rsRetVal
wtpConstructFinalize(wtp_t *pThis)
{
	DEFiRet;
	int i;
	uchar pszBuf[64];
	size_t lenBuf;
	wti_t *pWti;

	ISOBJ_TYPE_assert(pThis, wtp);

	dbgprintf("%s: finalizing construction of worker thread pool\n", wtpGetDbgHdr(pThis));
	/* alloc and construct workers - this can only be done in finalizer as we previously do
	 * not know the max number of workers
	 */
	if((pThis->pWrkr = malloc(sizeof(wti_t*) * pThis->iNumWorkerThreads)) == NULL)
		ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);

	for(i = 0 ; i < pThis->iNumWorkerThreads ; ++i) {
		CHKiRet(wtiConstruct(&pThis->pWrkr[i]));
		pWti = pThis->pWrkr[i];
		lenBuf = snprintf((char*)pszBuf, sizeof(pszBuf), "%s/w%d", wtpGetDbgHdr(pThis), i);
		CHKiRet(wtiSetDbgHdr(pWti, pszBuf, lenBuf));
		CHKiRet(wtiSetpWtp(pWti, pThis));
		CHKiRet(wtiConstructFinalize(pWti));
	}
		

finalize_it:
	RETiRet;
}
示例#5
0
/* Parse a number from the configuration line.
 * rgerhards, 2007-07-31
 */
static rsRetVal doGetInt(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *pVal)
{
	uchar *p;
	DEFiRet;
	int64 i;	
	uchar errMsg[256];	/* for dynamic error messages */

	assert(pp != NULL);
	assert(*pp != NULL);
	
	CHKiRet(doGetSize(pp, NULL,&i));
	p = *pp;
	if(i > 2147483648ll) { /*2^31*/
		snprintf((char*) errMsg, sizeof(errMsg)/sizeof(uchar),
		         "value %lld too large for integer argument.", i);
		errmsg.LogError(0, RS_RET_INVALID_VALUE, "%s", errMsg);
		ABORT_FINALIZE(RS_RET_INVALID_VALUE);
	}

	if(pSetHdlr == NULL) {
		/* we should set value directly to var */
		*((int*)pVal) = (int) i;
	} else {
		/* we set value via a set function */
		CHKiRet(pSetHdlr(pVal, (int) i));
	}

	*pp = p;

finalize_it:
	RETiRet;
}
示例#6
0
/* Add a socket to the select set */
static rsRetVal
Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp)
{
	DEFiRet;
	nsdsel_gtls_t *pThis = (nsdsel_gtls_t*) pNsdsel;
	nsd_gtls_t *pNsdGTLS = (nsd_gtls_t*) pNsd;

	ISOBJ_TYPE_assert(pThis, nsdsel_gtls);
	ISOBJ_TYPE_assert(pNsdGTLS, nsd_gtls);
	if(pNsdGTLS->iMode == 1) {
		if(waitOp == NSDSEL_RD && gtlsHasRcvInBuffer(pNsdGTLS)) {
			++pThis->iBufferRcvReady;
			FINALIZE;
		}
		if(pNsdGTLS->rtryCall != gtlsRtry_None) {
			if(gnutls_record_get_direction(pNsdGTLS->sess) == 0) {
				CHKiRet(nsdsel_ptcp.Add(pThis->pTcp, pNsdGTLS->pTcp, NSDSEL_RD));
			} else {
				CHKiRet(nsdsel_ptcp.Add(pThis->pTcp, pNsdGTLS->pTcp, NSDSEL_WR));
			}
			FINALIZE;
		}
	}

	/* if we reach this point, we need no special handling */
	CHKiRet(nsdsel_ptcp.Add(pThis->pTcp, pNsdGTLS->pTcp, waitOp));

finalize_it:
	RETiRet;
}
示例#7
0
文件: mmaudit.c 项目: dpocock/rsyslog
/* parse the audit record and create libee structure
 */
static rsRetVal
audit_parse(uchar *buf, struct json_object **jsonRoot)
{
	struct json_object *json;
	struct json_object *jval;
	char name[1024];
	char val[1024];
	DEFiRet;

	*jsonRoot = json_object_new_object();
	if(*jsonRoot == NULL) {
		ABORT_FINALIZE(RS_RET_ERR);
	}
	json = json_object_new_object();
	json_object_object_add(*jsonRoot, "data", json);

	while(*buf) {
		CHKiRet(parseName(&buf, name, sizeof(name)));
		if(*buf != '=') {
			ABORT_FINALIZE(RS_RET_ERR);
		}
		++buf;
		CHKiRet(parseValue(&buf, val, sizeof(val)));
		jval = json_object_new_string(val);
		json_object_object_add(json, name, jval);
	}
	

finalize_it:
	RETiRet;
}
示例#8
0
/* 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;
}
示例#9
0
/* check if a socket is ready for IO */
static rsRetVal
IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
{
	DEFiRet;
	nsdsel_gtls_t *pThis = (nsdsel_gtls_t*) pNsdsel;
	nsd_gtls_t *pNsdGTLS = (nsd_gtls_t*) pNsd;

	ISOBJ_TYPE_assert(pThis, nsdsel_gtls);
	ISOBJ_TYPE_assert(pNsdGTLS, nsd_gtls);
	if(pNsdGTLS->iMode == 1) {
		if(waitOp == NSDSEL_RD && gtlsHasRcvInBuffer(pNsdGTLS)) {
			*pbIsReady = 1;
			FINALIZE;
		}
		if(pNsdGTLS->rtryCall != gtlsRtry_None) {
			CHKiRet(doRetry(pNsdGTLS));
			/* we used this up for our own internal processing, so the socket
			 * is not ready from the upper layer point of view.
			 */
			*pbIsReady = 0;
			FINALIZE;
		}
	}

	CHKiRet(nsdsel_ptcp.IsReady(pThis->pTcp, pNsdGTLS->pTcp, waitOp, pbIsReady));

finalize_it:
	RETiRet;
}
示例#10
0
/* this function can be used to obtain all stats lines. In this case,
 * a callback must be provided. This module than iterates over all objects and
 * submits each stats line to the callback. The callback has two parameters:
 * the first one is a caller-provided void*, the second one the cstr_t with the
 * line. If the callback reports an error, processing is stopped.
 */
static rsRetVal
getAllStatsLines(rsRetVal(*cb)(void*, cstr_t*), void *usrptr, statsFmtType_t fmt, int8_t bResetCtrs)
{
	statsobj_t *o;
	cstr_t *cstr;
	DEFiRet;

	for(o = objRoot ; o != NULL ; o = o->next) {
		switch(fmt) {
		case statsFmt_Legacy:
			CHKiRet(getStatsLine(o, &cstr, bResetCtrs));
			break;
		case statsFmt_CEE:
			CHKiRet(getStatsLineCEE(o, &cstr, 1, bResetCtrs));
			break;
		case statsFmt_JSON:
			CHKiRet(getStatsLineCEE(o, &cstr, 0, bResetCtrs));
			break;
		}
		CHKiRet(cb(usrptr, cstr));
		rsCStrDestruct(&cstr);
	}

finalize_it:
	RETiRet;
}
示例#11
0
文件: wti.c 项目: Joungkyun/rsyslog
/* Construction finalizer
 * rgerhards, 2008-01-17
 */
rsRetVal
wtiConstructFinalize(wti_t *pThis)
{
	DEFiRet;
	int iDeqBatchSize;

	ISOBJ_TYPE_assert(pThis, wti);

	DBGPRINTF("%s: finalizing construction of worker instance data (for %d actions)\n",
		  wtiGetDbgHdr(pThis), iActionNbr);

	/* initialize our thread instance descriptor (no concurrency here) */
	pThis->bIsRunning = WRKTHRD_STOPPED;

	/* must use calloc as we need zero-init */
	CHKmalloc(pThis->actWrkrInfo = calloc(iActionNbr, sizeof(actWrkrInfo_t)));

	if(pThis->pWtp == NULL) {
		dbgprintf("wtiConstructFinalize: pWtp not set, this may be intentional\n");
		FINALIZE;
	}

	/* we now alloc the array for user pointers. We obtain the max from the queue itself. */
	CHKiRet(pThis->pWtp->pfGetDeqBatchSize(pThis->pWtp->pUsr, &iDeqBatchSize));
	CHKiRet(batchInit(&pThis->batch, iDeqBatchSize));

finalize_it:
	RETiRet;
}
示例#12
0
/* enqueue the the kernel message into the message queue.
 * The provided msg string is not freed - thus must be done
 * by the caller.
 * rgerhards, 2008-04-12
 */
static rsRetVal
enqMsg(uchar *msg, uchar* pszTag, int iFacility, int iSeverity)
{
	DEFiRet;
	msg_t *pMsg;

	assert(msg != NULL);
	assert(pszTag != NULL);

	CHKiRet(msgConstruct(&pMsg));
	MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY);
	MsgSetInputName(pMsg, pInputName);
	MsgSetRawMsgWOSize(pMsg, (char*)msg);
	MsgSetMSGoffs(pMsg, 0);	/* we do not have a header... */
	MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp());
	MsgSetRcvFromIP(pMsg, pLocalHostIP);
	MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()));
	MsgSetTAG(pMsg, pszTag, ustrlen(pszTag));
	pMsg->iFacility = LOG_FAC(iFacility);
	pMsg->iSeverity = LOG_PRI(iSeverity);
	pMsg->bParseHOSTNAME = 0;
	CHKiRet(submitMsg(pMsg));

finalize_it:
	RETiRet;
}
示例#13
0
/* get all the object's countes together with object name as one line.
 */
static rsRetVal
getStatsLine(statsobj_t *pThis, cstr_t **ppcstr, int8_t bResetCtrs)
{
	cstr_t *pcstr;
	ctr_t *pCtr;
	DEFiRet;

	CHKiRet(cstrConstruct(&pcstr));
	rsCStrAppendStr(pcstr, pThis->name);
	rsCStrAppendStrWithLen(pcstr, UCHAR_CONSTANT(": "), 2);

	/* now add all counters to this line */
	pthread_mutex_lock(&pThis->mutCtr);
	for(pCtr = pThis->ctrRoot ; pCtr != NULL ; pCtr = pCtr->next) {
		rsCStrAppendStr(pcstr, pCtr->name);
		cstrAppendChar(pcstr, '=');
		switch(pCtr->ctrType) {
		case ctrType_IntCtr:
			rsCStrAppendInt(pcstr, *(pCtr->val.pIntCtr)); // TODO: OK?????
			break;
		case ctrType_Int:
			rsCStrAppendInt(pcstr, *(pCtr->val.pInt));
			break;
		}
		cstrAppendChar(pcstr, ' ');
		resetResettableCtr(pCtr, bResetCtrs);
	}
	pthread_mutex_unlock(&pThis->mutCtr);

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

finalize_it:
	RETiRet;
}
示例#14
0
/* accept an incoming connection request
 * The netstrm instance that had the incoming request must be provided. If
 * the connection request succeeds, a new netstrm object is created and 
 * passed back to the caller. The caller is responsible for destructing it.
 * pReq is the nsd_t obj that has the accept request.
 * rgerhards, 2008-04-21
 */
static rsRetVal
AcceptConnReq(netstrm_t *pThis, netstrm_t **ppNew)
{
	nsd_t *pNewNsd = NULL;
	DEFiRet;

	ISOBJ_TYPE_assert(pThis, netstrm);
	assert(ppNew != NULL);

	/* accept the new connection */
	CHKiRet(pThis->Drvr.AcceptConnReq(pThis->pDrvrData, &pNewNsd));
	/* construct our object so that we can use it... */
	CHKiRet(objUse(netstrms, DONT_LOAD_LIB)); /* use netstrms obj if not already done so */
	CHKiRet(netstrms.CreateStrm(pThis->pNS, ppNew));
	(*ppNew)->pDrvrData = pNewNsd;

finalize_it:
	if(iRet != RS_RET_OK) {
		/* the close may be redundant, but that doesn't hurt... */
		if(pNewNsd != NULL)
			pThis->Drvr.Destruct(&pNewNsd);
	}

	RETiRet;
}
示例#15
0
/* 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;
}
示例#16
0
/* 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;
}
示例#17
0
/* parse a whitespace-delimited word from the provided string. This is a
 * helper function for a number of syntaxes. The parsed value is returned
 * in ppStrB (which must be provided by caller).
 * rgerhards, 2008-02-14
 */
static rsRetVal
getWord(uchar **pp, cstr_t **ppStrB)
{
	DEFiRet;
	uchar *p;

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

	CHKiRet(cstrConstruct(ppStrB));

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

	/* parse out the word */
	p = *pp;

	while(*p && !isspace((int) *p)) {
		CHKiRet(cstrAppendChar(*ppStrB, *p++));
	}
	CHKiRet(cstrFinalize(*ppStrB));

	*pp = p;

finalize_it:
	RETiRet;
}
示例#18
0
/* Parse a number from the configuration line.
 * rgerhards, 2007-07-31
 */
static rsRetVal doGetInt(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *pVal)
{
	uchar *p;
	DEFiRet;
	int64 i;	

	assert(pp != NULL);
	assert(*pp != NULL);
	
	CHKiRet(doGetSize(pp, NULL,&i));
	p = *pp;
	if(i > 2147483648ll) { /*2^31*/
		LogError(0, RS_RET_INVALID_VALUE, 
		         "value %lld too large for integer argument.", i);
		ABORT_FINALIZE(RS_RET_INVALID_VALUE);
	}

	if(pSetHdlr == NULL) {
		/* we should set value directly to var */
		*((int*)pVal) = (int) i;
	} else {
		/* we set value via a set function */
		CHKiRet(pSetHdlr(pVal, (int) i));
	}

	*pp = p;

finalize_it:
	RETiRet;
}
示例#19
0
/* parse a syslog name from the string. This is the generic code that is
 * called by the facility/severity functions. Note that we do not check the
 * validity of numerical values, something that should probably change over
 * time (TODO). -- rgerhards, 2008-02-14
 */
static rsRetVal
doSyslogName(uchar **pp, rsRetVal (*pSetHdlr)(void*, int),
	  	    void *pVal, syslogName_t *pNameTable)
{
	DEFiRet;
	cstr_t *pStrB;
	int iNewVal;

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

	CHKiRet(getWord(pp, &pStrB)); /* get word */
	iNewVal = decodeSyslogName(cstrGetSzStr(pStrB), pNameTable);

	if(pSetHdlr == NULL) {
		/* we should set value directly to var */
		*((int*)pVal) = iNewVal; /* set new one */
	} else {
		/* we set value via a set function */
		CHKiRet(pSetHdlr(pVal, iNewVal));
	}

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

finalize_it:
	if(pStrB != NULL)
		rsCStrDestruct(&pStrB);

	RETiRet;
}
示例#20
0
文件: ommysql.c 项目: Xat59/rsyslog
/* The following function writes the current log entry
 * to an established MySQL session.
 * Initially added 2004-10-28 mmeckelein
 */
rsRetVal writeMySQL(wrkrInstanceData_t *pWrkrData, uchar *psz)
{
	DEFiRet;

	/* see if we are ready to proceed */
	if(pWrkrData->hmysql == NULL) {
		CHKiRet(initMySQL(pWrkrData, 0));
		
	}

	/* try insert */
	if(mysql_query(pWrkrData->hmysql, (char*)psz)) {
		/* error occured, try to re-init connection and retry */
		closeMySQL(pWrkrData); /* close the current handle */
		CHKiRet(initMySQL(pWrkrData, 0)); /* try to re-open */
		if(mysql_query(pWrkrData->hmysql, (char*)psz)) { /* re-try insert */
			/* we failed, giving up for now */
			reportDBError(pWrkrData, 0);
			closeMySQL(pWrkrData); /* free ressources */
			ABORT_FINALIZE(RS_RET_SUSPENDED);
		}
	}

finalize_it:
	if(iRet == RS_RET_OK) {
		pWrkrData->uLastMySQLErrno = 0; /* reset error for error supression */
	}

	RETiRet;
}
示例#21
0
rsRetVal
dynstatsClassInit(void) {
	DEFiRet;
	CHKiRet(objGetObjInterface(&obj));
	CHKiRet(objUse(errmsg, CORE_COMPONENT));
	CHKiRet(objUse(statsobj, CORE_COMPONENT));
finalize_it:
	RETiRet;
}
示例#22
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;
}
示例#23
0
/* retry an interrupted GTLS operation
 * rgerhards, 2008-04-30
 */
static rsRetVal
doRetry(nsd_gtls_t *pNsd)
{
	DEFiRet;
	int gnuRet;

	dbgprintf("GnuTLS requested retry of %d operation - executing\n", pNsd->rtryCall);

	/* We follow a common scheme here: first, we do the systen call and
	 * then we check the result. So far, the result is checked after the
	 * switch, because the result check is the same for all calls. Note that
	 * this may change once we deal with the read and write calls (but
	 * probably this becomes an issue only when we begin to work on TLS
	 * for relp). -- rgerhards, 2008-04-30
	 */
	switch(pNsd->rtryCall) {
		case gtlsRtry_handshake:
			gnuRet = gnutls_handshake(pNsd->sess);
			if(gnuRet == 0) {
				pNsd->rtryCall = gtlsRtry_None; /* we are done */
				/* we got a handshake, now check authorization */
				CHKiRet(gtlsChkPeerAuth(pNsd));
			}
			break;
		case gtlsRtry_recv:
			dbgprintf("retrying gtls recv, nsd: %p\n", pNsd);
			CHKiRet(gtlsRecordRecv(pNsd));
			pNsd->rtryCall = gtlsRtry_None; /* we are done */
			gnuRet = 0;
			break;
		case gtlsRtry_None:
		default:
			assert(0); /* this shall not happen! */
			dbgprintf("ERROR: pNsd->rtryCall invalid in nsdsel_gtls.c:%d\n", __LINE__);
			gnuRet = 0; /* if it happens, we have at least a defined behaviour... ;) */
			break;
	}

	if(gnuRet == 0) {
		pNsd->rtryCall = gtlsRtry_None; /* we are done */
	} else if(gnuRet != GNUTLS_E_AGAIN && gnuRet != GNUTLS_E_INTERRUPTED) {
		uchar *pErr = gtlsStrerror(gnuRet);
		errmsg.LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error %d in %s:%d: %s\n", gnuRet, __FILE__, __LINE__, pErr); \
		free(pErr);
		pNsd->rtryCall = gtlsRtry_None; /* we are also done... ;) */
		ABORT_FINALIZE(RS_RET_GNUTLS_ERR);
	}
	/* if we are interrupted once again (else case), we do not need to
	 * change our status because we are already setup for retries.
	 */
		
finalize_it:
	if(iRet != RS_RET_OK && iRet != RS_RET_CLOSED && iRet != RS_RET_RETRY)
		pNsd->bAbortConn = 1; /* request abort */
	RETiRet;
}
示例#24
0
文件: lookup.c 项目: schiele/rsyslog
rsRetVal
lookupClassInit(void)
{
	DEFiRet;
	CHKiRet(objGetObjInterface(&obj));
	CHKiRet(objUse(glbl, CORE_COMPONENT));
	CHKiRet(objUse(errmsg, CORE_COMPONENT));
finalize_it:
	RETiRet;
}
示例#25
0
/* add new listener port to listener port list
 * rgerhards, 2009-05-21
 */
static inline rsRetVal
addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort, int bSuppOctetFram, uchar *pszAddr)
{
	tcpLstnPortList_t *pEntry;
	uchar statname[64];
	DEFiRet;

	ISOBJ_TYPE_assert(pThis, tcpsrv);

	/* create entry */
	CHKmalloc(pEntry = MALLOC(sizeof(tcpLstnPortList_t)));
	if((pEntry->pszPort = ustrdup(pszPort)) == NULL) {
		DBGPRINTF("tcpsrv/addNewLstnPort: OOM in strdup()\n");
		free(pEntry);
		ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
	}

        pEntry->pszAddr = NULL;
        /* only if a bind adress is defined copy it in struct */
        if (pszAddr != NULL) {
		if((pEntry->pszAddr = ustrdup(pszAddr)) == NULL) {
			DBGPRINTF("tcpsrv/addNewLstnPort: OOM in strdup() 2\n");
			free(pEntry->pszPort);
			free(pEntry);
			ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
		}
	}

	strcpy((char*)pEntry->dfltTZ, (char*)pThis->dfltTZ);
	pEntry->bSPFramingFix = pThis->bSPFramingFix;
	pEntry->pSrv = pThis;
	pEntry->pRuleset = pThis->pRuleset;
	pEntry->bSuppOctetFram = bSuppOctetFram;

	/* we need to create a property */ 
	CHKiRet(prop.Construct(&pEntry->pInputName));
	CHKiRet(prop.SetString(pEntry->pInputName, pThis->pszInputName, ustrlen(pThis->pszInputName)));
	CHKiRet(prop.ConstructFinalize(pEntry->pInputName));

	/* and add to list */
	pEntry->pNext = pThis->pLstnPorts;
	pThis->pLstnPorts = pEntry;

	/* support statistics gathering */
	CHKiRet(statsobj.Construct(&(pEntry->stats)));
	snprintf((char*)statname, sizeof(statname), "%s(%s)", pThis->pszInputName, pszPort);
	statname[sizeof(statname)-1] = '\0'; /* just to be on the save side... */
	CHKiRet(statsobj.SetName(pEntry->stats, statname));
	CHKiRet(statsobj.SetOrigin(pEntry->stats, pThis->pszOrigin));
	CHKiRet(ratelimitNew(&pEntry->ratelimiter, "tcperver", NULL));
	ratelimitSetLinuxLike(pEntry->ratelimiter, pThis->ratelimitInterval, pThis->ratelimitBurst);
	ratelimitSetThreadSafe(pEntry->ratelimiter);
	STATSCOUNTER_INIT(pEntry->ctrSubmit, pEntry->mutCtrSubmit);
	CHKiRet(statsobj.AddCounter(pEntry->stats, UCHAR_CONSTANT("submitted"),
		ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pEntry->ctrSubmit)));
	CHKiRet(statsobj.ConstructFinalize(pEntry->stats));

finalize_it:
	RETiRet;
}
示例#26
0
/* set the local host IP address to a specific string. Helper to
 * small set of functions. No checks done, caller must ensure it is
 * ok to call. Most importantly, the IP address must not already have 
 * been set. -- rgerhards, 2012-03-21
 */
static inline rsRetVal
storeLocalHostIPIF(uchar *myIP)
{
	DEFiRet;
	CHKiRet(prop.Construct(&propLocalIPIF));
	CHKiRet(prop.SetString(propLocalIPIF, myIP, ustrlen(myIP)));
	CHKiRet(prop.ConstructFinalize(propLocalIPIF));
	DBGPRINTF("rsyslog/glbl: using '%s' as localhost IP\n", myIP);
finalize_it:
	RETiRet;
}
示例#27
0
/* unlinks and immediately deletes an element. Previous element must
 * be given (or zero if the root element is to be deleted).
 * rgerhards, 2007-11-21
 */
static rsRetVal llUnlinkAndDelteElt(linkedList_t *pThis, llElt_t *pElt, llElt_t *pEltPrev)
{
	DEFiRet;

	assert(pElt != NULL);

	CHKiRet(llUnlinkElt(pThis, pElt, pEltPrev));
	CHKiRet(llDestroyElt(pThis, pElt));

finalize_it:
	RETiRet;
}
示例#28
0
rsRetVal
rsyslogd_InitStdRatelimiters(void)
{
	DEFiRet;
	CHKiRet(ratelimitNew(&dflt_ratelimiter, "rsyslogd", "dflt"));
	/* TODO: add linux-type limiting capability */
	CHKiRet(ratelimitNew(&internalMsg_ratelimiter, "rsyslogd", "internal_messages"));
	ratelimitSetLinuxLike(internalMsg_ratelimiter, 5, 500);
	/* TODO: make internalMsg ratelimit settings configurable */
finalize_it:
	RETiRet;
}
示例#29
0
文件: tcpsrv.c 项目: adruch/rsyslog
/* process a receive request on one of the streams
 * If pPoll is non-NULL, we have a netstream in epoll mode, which means we need
 * to remove any descriptor we close from the epoll set.
 * rgerhards, 2009-07-020
 */
static rsRetVal
doReceive(tcpsrv_t *pThis, tcps_sess_t **ppSess, nspoll_t *pPoll)
{
	char buf[128*1024]; /* reception buffer - may hold a partial or multiple messages */
	ssize_t iRcvd;
	rsRetVal localRet;
	DEFiRet;
	uchar *pszPeer;
	int lenPeer;

	ISOBJ_TYPE_assert(pThis, tcpsrv);
	DBGPRINTF("netstream %p with new data\n", (*ppSess)->pStrm);
	/* Receive message */
	iRet = pThis->pRcvData(*ppSess, buf, sizeof(buf), &iRcvd);
	switch(iRet) {
	case RS_RET_CLOSED:
		if(pThis->bEmitMsgOnClose) {
			errno = 0;
			prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer);
			errmsg.LogError(0, RS_RET_PEER_CLOSED_CONN, "Netstream session %p closed by remote peer %s.\n",
					(*ppSess)->pStrm, pszPeer);
		}
		CHKiRet(closeSess(pThis, ppSess, pPoll));
		break;
	case RS_RET_RETRY:
		/* we simply ignore retry - this is not an error, but we also have not received anything */
		break;
	case RS_RET_OK:
		/* valid data received, process it! */
		localRet = tcps_sess.DataRcvd(*ppSess, buf, iRcvd);
		if(localRet != RS_RET_OK && localRet != RS_RET_QUEUE_FULL) {
			/* in this case, something went awfully wrong.
			 * We are instructed to terminate the session.
			 */
			prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer);
			errmsg.LogError(0, localRet, "Tearing down TCP Session from %s - see "
					    "previous messages for reason(s)\n", pszPeer);
			CHKiRet(closeSess(pThis, ppSess, pPoll));
		}
		break;
	default:
		errno = 0;
		prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer);
		errmsg.LogError(0, iRet, "netstream session %p from %s will be closed due to error\n",
				(*ppSess)->pStrm, pszPeer);
		CHKiRet(closeSess(pThis, ppSess, pPoll));
		break;
	}

finalize_it:
	RETiRet;
}
示例#30
0
文件: parser.c 项目: FrogyYen/rsyslog
/* Add a an already existing parser to the default list. As usual, order
 * of calls is important (most importantly, that means the legacy parser,
 * which can process everything, MUST be added last!).
 * rgerhards, 2009-11-04
 */
static rsRetVal
AddDfltParser(uchar *pName)
{
	parser_t *pParser;
	DEFiRet;

	CHKiRet(FindParser(&pParser, pName));
	CHKiRet(AddParserToList(&pDfltParsLst, pParser));
	DBGPRINTF("Parser '%s' added to default parser set.\n", pName);
	
finalize_it:
	RETiRet;
}