/* * Internal function to remove a node from a tree - used by assert() method * * Returns: * 0 - don't remove the parent node * 1 - consider removing the parent node (if no value or root) * 2 - remove the parent node (even if it has a value and/or root) */ static int removeNode(nbCELL context,BTree *tree,BTreeNode **nodeP,nbSET *argSetP){ NB_TreePath path; BTreeNode *node=*nodeP; nbCELL argCell; int code=1; argCell=nbListGetCellValue(context,argSetP); if(argCell==NULL){ if(node==NULL) return(3); // the perfect match - nothing to nothing code=2; return(2); // } else{ if(node==NULL) return(0); // can't match to empty tree if(tree->options&BTREE_OPTION_ORDER) node=(BTreeNode *)nbTreeLocateValue(&path,argCell,(NB_TreeNode **)nodeP,treeCompare,context); else node=nbTreeLocate(&path,argCell,(NB_TreeNode **)nodeP); nbCellDrop(context,argCell); if(node==NULL) return(0); // didn't find argument switch(removeNode(context,tree,&node->root,argSetP)){ case 0: return(0); case 1: if(node->root!=NULL) return(0); // still need this node break; // For case 2 we just fall thru to unlink the node } } if(node->root!=NULL) return(0); nbTreeRemove(&path); // Remove node from binary search tree if(node->bnode.key!=NULL) node->bnode.key=nbCellDrop(context,(nbCELL)node->bnode.key); // release key //if(node->root!=NULL) node->root =removeTree(context,tree,node->root); nbFree(node,sizeof(BTreeNode)); return(code); }
/* * destroy() method * * undefine <node> * */ static int auditDestroy(nbCELL context,void *skillHandle,nbAudit *audit){ if(audit->trace) nbLogMsg(context,0,'T',"auditDestroy called"); auditDisable(context,skillHandle,audit); nbCellDrop(context,audit->fileNameCell); nbCellDrop(context,audit->scheduleCell); nbCellDrop(context,audit->translatorCell); nbCellDrop(context,audit->translatorNameCell); nbFree(audit,sizeof(struct NB_MOD_AUDIT)); return(0); }
// Prune a tree at the selected node without removing the selected node // static void treePrune(nbCELL context,BTreeSkill *skillHandle,BTree *tree,nbCELL arglist,char *text){ BTreeNode *node=NULL; nbSET argSet; nbCELL argCell; void *ptr; argSet=nbListOpen(context,arglist); if(argSet==NULL){ if(tree->root!=NULL){ removeTree(context,tree,tree->root); tree->root=NULL; } } else{ ptr=&tree->root; if(argSet!=NULL){ while((argCell=nbListGetCellValue(context,&argSet))!=NULL && (node=treeFindArg(context,tree,argCell,&ptr))!=NULL){ nbCellDrop(context,argCell); ptr=&node->root; } if(argCell!=NULL){ nbLogMsg(context,0,'E',"Entry not found."); return; } if(node->root!=NULL){ removeTree(context,tree,node->root); node->root=NULL; } } } }
static void treeSet(nbCELL context,BTreeSkill *skillHandle,BTree *tree,nbCELL arglist,char *text){ NB_TreePath path; BTreeNode *node=NULL,**nodeP=&tree->root; nbSET argSet; nbCELL argCell; double average,deviation; average=strtod(text,&text); while(*text==' ') text++; if(*text!=','){ nbLogMsg(context,0,'E',"Expecting ',' at: %s",text); return; } text++; deviation=strtod(text,&text); while(*text==' ') text++; if(*text!=';'){ nbLogMsg(context,0,'E',"Expecting ';' at: %s",text); return; } if(arglist==NULL || (argSet=nbListOpen(context,arglist))==NULL){ nbLogMsg(context,0,'E',"Expecting argument list"); return; } argCell=nbListGetCellValue(context,&argSet); while(argCell!=NULL){ if(tree->options&BTREE_OPTION_ORDER) node=nbTreeLocateValue(&path,argCell,(NB_TreeNode **)nodeP,treeCompare,context); else node=nbTreeLocate(&path,argCell,(NB_TreeNode **)nodeP); if(node==NULL){ node=nbAlloc(sizeof(BTreeNode)); memset(node,0,sizeof(BTreeNode)); nbTreeInsert(&path,(NB_TreeNode *)node); nodeP=&(node->root); while((argCell=nbListGetCellValue(context,&argSet))!=NULL){ node=nbAlloc(sizeof(BTreeNode)); memset(node,0,sizeof(BTreeNode)); node->bnode.key=(void *)argCell; *nodeP=node; nodeP=&(node->root); } node->average=average; node->deviation=deviation; node->threshold=deviation*tree->tolerance; node->level=0; return; } nodeP=&(node->root); nbCellDrop(context,argCell); argCell=nbListGetCellValue(context,&argSet); } if(node){ /* matched - change value */ node->average=average; node->deviation=deviation; node->threshold=(double)((int)1<<node->level)*deviation*tree->tolerance; } return; }
// // Recursively remove all nodes in a binary tree // static void *removeTree(nbCELL context,BTree *tree,BTreeNode *node){ node->bnode.key=nbCellDrop(context,node->bnode.key); if(node->bnode.left!=NULL) node->bnode.left=removeTree(context,tree,(BTreeNode *)node->bnode.left); if(node->bnode.right!=NULL) node->bnode.right=removeTree(context,tree,(BTreeNode *)node->bnode.right); if(node->root!=NULL) node->root=removeTree(context,tree,node->root); nbFree(node,sizeof(BTreeNode)); return(NULL); }
/* * evaluate() method * * ... <node>[(<args>)] ... * * define r1 on(table("a",2,"hello")=4); * */ static nbCELL baselineEvaluate(nbCELL context,BTreeSkill *skillHandle,BTree *tree,nbCELL arglist){ nbCELL argCell; nbSET argSet; BTreeNode *node=NULL,*root=tree->root; if(skillHandle->trace || tree->options&BTREE_OPTION_TRACE){ nbLogMsg(context,0,'T',"nb_tree::baselineEvaluate()"); nbLogPut(context,"tree"); if(arglist!=NULL) nbCellShow(context,arglist); nbLogPut(context,"\n"); } if(arglist==NULL){ // request for tree value return(NB_CELL_UNKNOWN); // for now, let it be Unknown } argSet=nbListOpen(context,arglist); if(argSet==NULL) return(tree->notfound); // tree() returns default value argCell=nbListGetCellValue(context,&argSet); while(argCell!=NULL && argSet!=NULL){ if(tree->options&BTREE_OPTION_ORDER){ if(tree->options&BTREE_OPTION_PARTITION) node=nbTreeFindFloor(argCell,(NB_TreeNode *)root,treeCompare,context); else node=nbTreeFindValue(argCell,(NB_TreeNode *)root,treeCompare,context); } else node=nbTreeFind(argCell,(NB_TreeNode *)root); if(node==NULL){ nbCellDrop(context,argCell); return(tree->notfound); } nbCellDrop(context,argCell); argCell=nbListGetCellValue(context,&argSet); root=node->root; } // matched on arguments // return(tree->found); // could alternatively return a real object with value of node->value return(nbCellCreateReal(context,node->value)); }
/* * construct() method * * define <term> node <skill>[(<args>)][:<text>] * * <args> - port_number or "interface_address[:port_number]" * <text> - flag keywords * trace - display input packets * dump - display dump of SNMP UDP packets * silent - don't echo generated NodeBrain commands * * define snmptrap node snmptrap; * define snmptrap node snmptrap:dump,silent; * define snmptrap node snmptrap("127.0.0.1"); * define snmptrap node snmptrap(50162); * define snmptrap node snmptrap("127.0.0.1:50162"); * define snmptrap node snmptrap("127.0.0.1:50162"):silent; */ static void *serverConstruct(nbCELL context,void *skillHandle,nbCELL arglist,char *text){ NB_MOD_Snmptrap *snmptrap; nbCELL cell=NULL; nbSET argSet; char *cursor=text,*delim,saveDelim; double r,d; char interfaceAddr[16]; unsigned int port=162; int type,trace=0,dump=0,echo=1; int len; char *str; *interfaceAddr=0; argSet=nbListOpen(context,arglist); cell=nbListGetCellValue(context,&argSet); if(cell!=NULL){ type=nbCellGetType(context,cell); if(type==NB_TYPE_STRING){ str=nbCellGetString(context,cell); delim=strchr(str,':'); if(delim==NULL) len=strlen(str); else len=delim-str; if(len>15){ nbLogMsg(context,0,'E',"Inteface IP address may not be greater than 15 characters"); nbCellDrop(context,cell); return(NULL); } strncpy(interfaceAddr,str,len); *(interfaceAddr+len)=0; if(delim!=NULL){ delim++; port=(unsigned int)atoi(delim); } nbCellDrop(context,cell); } else if(type==NB_TYPE_REAL){ r=nbCellGetReal(context,cell); nbCellDrop(context,cell); port=(unsigned int)r; d=port; if(d!=r || d==0){ nbLogMsg(context,0,'E',"Expecting non-zero integer UDP port number"); return(NULL); } } else{ nbLogMsg(context,0,'E',"Expecting interface (\"address[:port]\") or (port) as argument list"); return(NULL); } cell=nbListGetCellValue(context,&argSet); if(cell!=NULL){ nbLogMsg(context,0,'E',"Only one argument expected - ignoring additional arguments"); nbCellDrop(context,cell); } } if(*text!=0){ cursor=text; while(*cursor==' ') cursor++; while(*cursor!=';' && *cursor!=0){ delim=strchr(cursor,' '); if(delim==NULL) delim=strchr(cursor,','); if(delim==NULL) delim=strchr(cursor,';'); if(delim==NULL) delim=cursor+strlen(cursor); // 2013-01-14 eat - VID 969-0.8.13-3 FP but replaced strchr(cursor,0) saveDelim=*delim; *delim=0; if(strcmp(cursor,"trace")==0){trace=1;} else if(strcmp(cursor,"dump")==0){trace=1;dump=1;} else if(strcmp(cursor,"silent")==0) echo=0; *delim=saveDelim; cursor=delim; if(*cursor==',') cursor++; while(*cursor==' ') cursor++; } } snmptrap=nbAlloc(sizeof(NB_MOD_Snmptrap)); snmptrap->socket=0; strcpy(snmptrap->interfaceAddr,interfaceAddr); snmptrap->port=port; snmptrap->trace=trace; snmptrap->dump=dump; snmptrap->echo=echo; snmptrap->handlerContext=NULL; snmptrap->syntaxContext=NULL; snmptrap->attributeContext=NULL; nbListenerEnableOnDaemon(context); // sign up to enable when we daemonize return(snmptrap); }
/* * construct() method * * define <term> node <skill>[("<ident>"[,<uri>])][:<text>] * * <ident> - name of translator file * <uri> - <proto>://<spec> * * <proto> - only "udp" supported currently * <spec> - only local domain socket file supported currently * * <text> - flag keywords * trace - display input packets * dump - display dump of syslog packets * silent - don't echo generated NodeBrain commands * * define syslog node syslog.client("foobar"); */ void *clientConstruct(nbCELL context,void *skillHandle,nbCELL arglist,char *text){ NB_MOD_Client *client; nbCELL cell=NULL; nbSET argSet; char *cursor=text,*delim,saveDelim; int trace=0,dump=0,echo=1; char *ident="nodebrain"; char *uri="udp://127.0.0.1:514"; char *socketname=uri+6; int sd; argSet=nbListOpen(context,arglist); cell=nbListGetCellValue(context,&argSet); if(cell){ if(nbCellGetType(context,cell)!=NB_TYPE_STRING){ nbLogMsg(context,0,'E',"First argument must be string message identifier"); return(NULL); } ident=strdup(nbCellGetString(context,cell)); if(!ident) nbExit("clientConstruct: Out of memory - terminating"); nbCellDrop(context,cell); } cell=nbListGetCellValue(context,&argSet); if(cell){ if(nbCellGetType(context,cell)!=NB_TYPE_STRING){ nbLogMsg(context,0,'E',"Second argument must be string uri"); return(NULL); } uri=strdup(nbCellGetString(context,cell)); if(!uri) nbExit("clientConstruct: Out of memory - terminating"); nbCellDrop(context,cell); cell=nbListGetCellValue(context,&argSet); if(cell){ nbLogMsg(context,0,'E',"The syslog.client skill only accepts two arguments."); return(NULL); } } while(*cursor==' ') cursor++; while(*cursor!=';' && *cursor!=0){ delim=strchr(cursor,' '); if(delim==NULL) delim=strchr(cursor,','); if(delim==NULL) delim=strchr(cursor,';'); if(delim==NULL) delim=cursor+strlen(cursor); saveDelim=*delim; *delim=0; if(strcmp(cursor,"trace")==0){trace=1;} else if(strcmp(cursor,"dump")==0){trace=1;dump=1;} else if(strcmp(cursor,"silent")==0) echo=0; *delim=saveDelim; cursor=delim; if(*cursor==',') cursor++; while(*cursor==' ' || *cursor==',') cursor++; } // figure out the uri if(strncmp(uri,"udp://",6)){ nbLogMsg(context,0,'E',"Expecting uri to start with 'udp://' - found %s",uri); return(NULL); } socketname=uri+6; // add code here to determine if local or remote sd=socket(AF_UNIX,SOCK_DGRAM,0); if(sd<0){ nbLogMsg(context,0,'E',"Unable to obtain socket for %s",uri); return(NULL); } client=nbAlloc(sizeof(NB_MOD_Client)); client->ident=ident; client->uri=uri; client->un_addr.sun_family=AF_UNIX; sprintf(client->un_addr.sun_path,"%s",socketname); client->socket=sd; client->trace=trace; client->dump=dump; client->echo=echo; return(client); }
/* * construct() method * * define <term> node <skill>("<translator>",[<binding>])[:<text>] * * <translator> - name of translator file * <binding> - port_number or "interface_address[:port_number]" * <text> - flag keywords * trace - display input packets * dump - display dump of syslog packets * silent - don't echo generated NodeBrain commands * * define syslog node syslog.server("syslog.nbx"); * define syslog node syslog.server("syslog.nbx"):dump,silent; * define syslog node syslog.server("syslog.nbx","127.0.0.1"); * define syslog node syslog.server("syslog.nbx",50162); * define syslog node syslog.server("syslog.nbx","127.0.0.1:50162"); * define syslog node syslog.server("syslog.nbx","127.0.0.1:50162"):silent; */ void *serverConstruct(nbCELL context,void *skillHandle,nbCELL arglist,char *text){ NB_MOD_Server *server; nbCELL cell=NULL; nbSET argSet; char *cursor=text,*delim,saveDelim; double r,d; char interfaceAddr[512]; unsigned int port=514; int type,trace=0,dump=0,echo=1; int len; char *str; char *transfilename; nbCELL translator; char *uri="";; *interfaceAddr=0; argSet=nbListOpen(context,arglist); cell=nbListGetCellValue(context,&argSet); if(cell==NULL){ nbLogMsg(context,0,'E',"Translator configuration file required as first argument"); return(NULL); } type=nbCellGetType(context,cell); if(type!=NB_TYPE_STRING){ nbLogMsg(context,0,'E',"First argument must be string identifying translator configuration file"); return(NULL); } transfilename=nbCellGetString(context,cell); translator=nbTranslatorCompile(context,0,transfilename); if(translator==NULL){ nbLogMsg(context,0,'E',"Unable to load translator '%s'",transfilename); return(NULL); } cell=nbListGetCellValue(context,&argSet); if(cell!=NULL){ type=nbCellGetType(context,cell); if(type==NB_TYPE_STRING){ str=nbCellGetString(context,cell); uri=strdup(str); if(!uri) nbExit("serverConstruct: Out of memory - terminating"); if(strncmp(str,"udp://",6)==0) str+=6; // allow for uri delim=strchr(str,':'); if(delim==NULL) len=strlen(str); else len=delim-str; if(len>15 && *str>='0' && *str<='9'){ nbLogMsg(context,0,'E',"Inteface IP address may not be greater than 15 characters"); nbCellDrop(context,cell); return(NULL); } if(len>sizeof(interfaceAddr)-1){ nbLogMsg(context,0,'E',"Socket specification too long for buffer at--->%s",str); nbCellDrop(context,cell); return(NULL); } strncpy(interfaceAddr,str,len); *(interfaceAddr+len)=0; if(delim!=NULL){ delim++; port=(unsigned int)atoi(delim); } nbCellDrop(context,cell); } else if(type==NB_TYPE_REAL){ r=nbCellGetReal(context,cell); nbCellDrop(context,cell); port=(unsigned int)r; d=port; if(d!=r || d==0){ nbLogMsg(context,0,'E',"Expecting non-zero integer UDP port number"); return(NULL); } } else{ nbLogMsg(context,0,'E',"Expecting (\"file\") or (\"address[:port]\") or (port) as argument list"); return(NULL); } cell=nbListGetCellValue(context,&argSet); if(cell!=NULL){ nbLogMsg(context,0,'E',"The syslog skill only accepts two argument."); return(NULL); } } while(*cursor==' ') cursor++; while(*cursor!=';' && *cursor!=0){ delim=strchr(cursor,' '); if(delim==NULL) delim=strchr(cursor,','); if(delim==NULL) delim=strchr(cursor,';'); if(delim==NULL) delim=cursor+strlen(cursor); saveDelim=*delim; *delim=0; if(strcmp(cursor,"trace")==0){trace=1;} else if(strcmp(cursor,"dump")==0){trace=1;dump=1;} else if(strcmp(cursor,"silent")==0) echo=0; *delim=saveDelim; cursor=delim; if(*cursor==',') cursor++; while(*cursor==' ' || *cursor==',') cursor++; } server=nbAlloc(sizeof(NB_MOD_Server)); server->uri=uri; server->socket=0; strcpy(server->interfaceAddr,interfaceAddr); server->port=port; server->translator=translator; server->trace=trace; server->dump=dump; server->echo=echo; nbLogMsg(context,0,'I',"calling nbListenerEnableOnDaemon"); nbListenerEnableOnDaemon(context); // sign up to enable when we daemonize return(server); }
/* * assert() method * * assert <node>[(args)][=<value>] * * assert table("a",2,"hello")=5; # set value to 5 * assert table("a",2,"hello"); # set value to 1 * assert !table("a",2,"hello"); # set value to 0 * assert ?table("a",2,"hello"); # remove from table * assert table("a",2,"hello")=?? # remove from table * */ static int baselineAssert(nbCELL context,void *skillHandle,BTree *tree,nbCELL arglist,nbCELL value){ NB_TreePath path; BTreeNode *node=NULL,**nodeP=&tree->root; nbCELL argCell; nbSET argSet; int cellType; double real; int qualifiers=0; nbCELL element[32]; double deviation; if(arglist==NULL) return(0); // perhaps we should set the value of the tree itself argSet=nbListOpen(context,arglist); if(value==NB_CELL_UNKNOWN){ if(argSet==NULL && tree->root!=NULL) tree->root=removeTree(context,tree,tree->root); else removeNode(context,tree,&tree->root,&argSet); return(0); } cellType=nbCellGetType(context,value); if(cellType!=NB_TYPE_REAL){ nbLogMsg(context,0,'E',"Value must be a number"); return(0); } real=nbCellGetReal(context,value); if(argSet==NULL) return(0); argCell=nbListGetCellValue(context,&argSet); while(argCell!=NULL){ element[qualifiers]=argCell; qualifiers++; if(tree->options&BTREE_OPTION_ORDER) node=nbTreeLocateValue(&path,argCell,(NB_TreeNode **)nodeP,treeCompare,context); else node=nbTreeLocate(&path,argCell,(NB_TreeNode **)nodeP); if(node==NULL){ node=nbAlloc(sizeof(BTreeNode)); memset(node,0,sizeof(BTreeNode)); nbTreeInsert(&path,(NB_TreeNode *)node); nodeP=&(node->root); while((argCell=nbListGetCellValue(context,&argSet))!=NULL){ node=nbAlloc(sizeof(BTreeNode)); memset(node,0,sizeof(BTreeNode)); node->bnode.key=(void *)argCell; *nodeP=node; nodeP=&(node->root); } node->value=real; // note we don't set deviation, threshold and level until the end of the period. return(0); } nodeP=&(node->root); nbCellDrop(context,argCell); argCell=nbListGetCellValue(context,&argSet); } if(tree->options&BTREE_OPTION_SUM){ // need to check for zero average and deviation here! node->value+=real; if(node->average==0 && node->deviation==0) return(0); deviation=fabs(node->value-node->average); if(node->value>node->average && deviation>node->threshold) baselineAlert(context,skillHandle,tree,node,element,qualifiers,deviation); } else{ node->value=real; // update value and check limits if(node->average==0 && node->deviation==0) return(0); deviation=fabs(node->value-node->average); if(deviation>node->threshold) baselineAlert(context,skillHandle,tree,node,element,qualifiers,deviation); } return(0); }
/* * construct() method * * define <term> node <skill>[(<args>)][:<text>] * * define <term> node baseline("<directory>",<weight>,<tolerance>,<cycle>,<interval>)[:<options>]; */ static void *baselineConstruct(nbCELL context,BTreeSkill *skillHandle,nbCELL arglist,char *text){ int options=0; nbCELL found=NULL; nbCELL notfound=NULL; nbCELL cell; BTree *tree; char *cursor=text,*delim,ident[256]; int len; nbSET argSet; char *directory; double weight=0.5,tolerance=3,cycle=7*24*60,periods=24; double interval=60; argSet=nbListOpen(context,arglist); cell=nbListGetCellValue(context,&argSet); if(cell==NULL || nbCellGetType(context,cell)!=NB_TYPE_STRING){ nbLogMsg(context,0,'E',"Baseline directory string required as first argument"); return(NULL); } directory=nbCellGetString(context,cell); // we don't drop this cell because we reference it cell=nbListGetCellValue(context,&argSet); if(cell!=NULL){ if(nbCellGetType(context,cell)!=NB_TYPE_REAL || (weight=nbCellGetReal(context,cell))<0 || weight>1){ nbLogMsg(context,0,'E',"Second argument must be numeric weight between 0 and 1"); return(NULL); } nbCellDrop(context,cell); cell=nbListGetCellValue(context,&argSet); if(cell!=NULL){ if(nbCellGetType(context,cell)!=NB_TYPE_REAL || (tolerance=nbCellGetReal(context,cell))<0){ nbLogMsg(context,0,'E',"Third argument must be non-negative numeric tolerance"); return(NULL); } nbCellDrop(context,cell); cell=nbListGetCellValue(context,&argSet); if(cell!=NULL){ if(nbCellGetType(context,cell)!=NB_TYPE_REAL || (cycle=nbCellGetReal(context,cell))<1 || cycle!=(int)cycle){ nbLogMsg(context,0,'E',"Forth argument must be positive integer number of minutes in a cycle"); return(NULL); } nbCellDrop(context,cell); cell=nbListGetCellValue(context,&argSet); if(cell!=NULL){ if(nbCellGetType(context,cell)!=NB_TYPE_REAL || (interval=nbCellGetReal(context,cell))<1 || interval!=(int)interval || (periods=cycle/interval)<1 || periods!=(int)periods){ nbLogMsg(context,0,'E',"Fifth argument must be positive integer number of minutes in an interval by which %d is evenly divisable",cycle); return(NULL); } nbCellDrop(context,cell); cell=nbListGetCellValue(context,&argSet); if(cell!=NULL){ nbLogMsg(context,0,'E',"Only five arguments supported"); return(NULL); } } } } } if(skillHandle!=NULL && skillHandle->trace) nbLogMsg(context,0,'T',"baselineConstruct() called"); while(*cursor==' ') cursor++; while(*cursor!=0 && *cursor!=';'){ delim=cursor; while(*delim>='a' && *delim<='z') delim++; len=delim-cursor; if(len>sizeof(ident)-1){ nbLogMsg(context,0,'E',"Option not recognized at \"%s\".",cursor); return(NULL); } strncpy(ident,cursor,len); *(ident+len)=0; cursor=delim; while(*cursor==' ') cursor++; if(strcmp(ident,"trace")==0) options|=BTREE_OPTION_TRACE; else if(strcmp(ident,"order")==0) options|=BTREE_OPTION_ORDER; else if(strcmp(ident,"partition")==0) options|=BTREE_OPTION_PARTITION|BTREE_OPTION_ORDER; else if(strcmp(ident,"sum")==0) options|=BTREE_OPTION_SUM; else if(strcmp(ident,"static")==0) options|=BTREE_OPTION_STATIC; else if(strcmp(ident,"found")==0 || strcmp(ident,"notfound")==0){ if(*cursor!='='){ nbLogMsg(context,0,'E',"Expecting '=' at \"%s\".",cursor); return(NULL); } cursor++; cell=nbCellParse(context,&cursor); if(cell==NULL){ nbLogMsg(context,0,'E',"Syntax error in cell expression."); return(NULL); } if(strcmp(ident,"found")==0) found=cell; else notfound=cell; } else{ nbLogMsg(context,0,'E',"Option not recognized at \"%s\".",cursor); return(NULL); } while(*cursor==' ') cursor++; if(*cursor==','){ cursor++; while(*cursor==' ') cursor++; } else if(*cursor!=0 && *cursor!=';'){ nbLogMsg(context,0,'E',"Expecting ',' ';' or end of line at \"%s\".",cursor); return(NULL); } } if(notfound==NULL) notfound=NB_CELL_UNKNOWN; if(found==NULL) found=notfound; tree=(BTree *)nbAlloc(sizeof(BTree)); tree->options=options; tree->notfound=notfound; tree->found=found; tree->root=NULL; tree->directory=directory; tree->cycle=cycle*60; tree->periods=periods; tree->interval=interval*60; tree->weight=weight; tree->tolerance=tolerance*1.25; nbListenerEnableOnDaemon(context); // sign up to enable when we daemonize return(tree); }