int update_combotests(int showeval, int cleanexpr) { testspec_t *t; int pending; int remaining = 0; init_timestamp(); loadtests(); /* * Loop over the tests to allow us "forward refs" in expressions. * We continue for as long as progress is being made. */ remaining = testcount; do { pending = remaining; for (t=testhead; (t); t = t->next) { if (t->result == -1) { t->result = evaluate(t->expression, &t->resultexpr, &t->valuelist, &t->errbuf); if (t->result != -1) remaining--; } } } while (pending != remaining); combo_start(); for (t=testhead; (t); t = t->next) { char msgline[MAX_LINE_LEN]; int color; value_t *vwalk; color = (t->result ? COL_GREEN : COL_RED); init_status(color); sprintf(msgline, "status %s.%s %s %s\n\n", commafy(t->reshostname), ( t->restestname ? t->restestname : "combostatuserror" ), colorname(color), timestamp); addtostatus(msgline); if (t->comment) { addtostatus(t->comment); addtostatus("\n\n"); } if (showeval) { addtostatus(printify(t->expression, cleanexpr)); addtostatus(" = "); addtostatus(printify(t->resultexpr, cleanexpr)); addtostatus(" = "); sprintf(msgline, "%ld\n", t->result); addtostatus(msgline); for (vwalk = t->valuelist; (vwalk); vwalk = vwalk->next) { sprintf(msgline, "&%s <a href=\"%s/svcstatus.sh?HOST=%s&SERVICE=%s\">%s</a>\n", colorname(vwalk->color), xgetenv("CGIBINURL"), textornull(gethname(vwalk->symbol)), textornull(gettname(vwalk->symbol)), textornull(vwalk->symbol)); addtostatus(msgline); } if (t->errbuf) { addtostatus("\nErrors occurred during evaluation:\n"); addtostatus(t->errbuf); } } finish_status(); } combo_end(); return 0; }
static void loadtests(void) { static time_t lastupdate = 0; static char *fn = NULL; struct stat st; FILE *fd; strbuffer_t *inbuf; if (!fn) { fn = (char *)malloc(1024 + strlen(xgetenv("XYMONHOME"))); *fn = '\0'; } sprintf(fn, "%s/etc/combo.cfg", xgetenv("XYMONHOME")); if ((stat(fn, &st) == 0) && (st.st_mtime == lastupdate)) return; lastupdate = st.st_mtime; fd = stackfopen(fn, "r", NULL); if (fd == NULL) { errprintf("Cannot open %s/combo.cfg\n", xgetenv("XYMONHOME")); *fn = '\0'; return; } flush_testlist(); inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { char *p, *comment; char *inp, *outp; p = strchr(STRBUF(inbuf), '\n'); if (p) *p = '\0'; /* Strip whitespace */ for (inp=outp=STRBUF(inbuf); ((*inp >= ' ') && (*inp != '#')); inp++) { if (isspace((int)*inp)) { } else { *outp = *inp; outp++; } } *outp = '\0'; if (strlen(inp)) memmove(outp, inp, strlen(inp)+1); strbufferrecalc(inbuf); if (STRBUFLEN(inbuf) && (*STRBUF(inbuf) != '#') && (p = strchr(STRBUF(inbuf), '=')) ) { testspec_t *newtest; char *hname, *tname; hname = gethname(STRBUF(inbuf)); tname = gettname(STRBUF(inbuf)); if (hname && tname) { *p = '\0'; comment = strchr(p+1, '#'); if (comment) *comment = '\0'; newtest = (testspec_t *) malloc(sizeof(testspec_t)); newtest->reshostname = strdup(gethname(STRBUF(inbuf))); newtest->restestname = strdup(gettname(STRBUF(inbuf))); newtest->expression = strdup(p+1); newtest->comment = (comment ? strdup(comment+1) : NULL); newtest->resultexpr = NULL; newtest->valuelist = NULL; newtest->result = -1; newtest->errbuf = NULL; newtest->next = testhead; testhead = newtest; testcount++; } else { errprintf("Invalid combo test %s - missing host/test names. Perhaps you need to escape dashes?\n", STRBUF(inbuf)); } } } stackfclose(fd); freestrbuffer(inbuf); }
static long evaluate(char *symbolicexpr, char **resultexpr, value_t **valuelist, char **errbuf) { char expr[MAX_LINE_LEN]; char *inp, *outp, *symp; char symbol[MAX_LINE_LEN]; int done; int insymbol = 0; int result, error; long oneval; int onecolor; value_t *valhead = NULL, *valtail = NULL; value_t *newval; char errtext[1024]; done = 0; inp=symbolicexpr; outp=expr; symp = NULL; while (!done) { if (isalpha((int)*inp) || (isdigit((int)*inp) && insymbol && *(inp+1) && (*(inp+1) > ' ') && *(inp+2) && (*(inp+2) > ' ')) ) { /* puke */ if (!insymbol) { insymbol = 1; symp = symbol; } *symp = *inp; symp++; } else if (insymbol && (isdigit((int) *inp) || (*inp == '.'))) { *symp = *inp; symp++; } else if (insymbol && ((*inp == '\\') && (*(inp+1) > ' '))) { *symp = *(inp+1); symp++; inp++; } else { if (insymbol) { /* Symbol finished - evaluate the symbol */ char *hname, *tname; *symp = '\0'; insymbol = 0; hname = gethname(symbol); tname = gettname(symbol); if (hname && tname) { oneval = getvalue(gethname(symbol), gettname(symbol), &onecolor, errbuf); if (oneval == -1) { dbgprintf("Forward lookup of '%s.%s' pending for '%s'\n", hname, tname, symbolicexpr); return -1; } } else { errprintf("Invalid data for symbol calculation - missing host/testname: %s\n", symbol); oneval = 0; onecolor = COL_CLEAR; } sprintf(outp, "%ld", oneval); outp += strlen(outp); newval = (value_t *) malloc(sizeof(value_t)); newval->symbol = strdup(symbol); newval->color = onecolor; newval->next = NULL; if (valhead == NULL) { valtail = valhead = newval; } else { valtail->next = newval; valtail = newval; } } *outp = *inp; outp++; symp = NULL; } if (*inp == '\0') done = 1; else inp++; } *outp = '\0'; if (resultexpr) *resultexpr = strdup(expr); dbgprintf("Symbolic '%s' converted to '%s'\n", symbolicexpr, expr); error = 0; result = compute(expr, &error); if (error) { sprintf(errtext, "compute(%s) returned error %d\n", expr, error); if (*errbuf == NULL) { *errbuf = strdup(errtext); } else { *errbuf = (char *)realloc(*errbuf, strlen(*errbuf)+strlen(errtext)+1); strcat(*errbuf, errtext); } } *valuelist = valhead; return result; }
int openlib(char tlbname[],struct liblink *lhead) //char ftype[], //建立数据库,前提初始化链表,tlbname为对应库文件的文件,其必须在编译文件同目录下,lhead为建立输出的链表,可以拆分参数为文件名和文件后序名(对应上面注释项) //下面有对应的文件名连接项 { int i,k,brun=0; char checkstr[50]={'\0'},sistr[20]={'\0'},tname[50]={'\0'},lbname[20]={'\0'},temp[10]={'\0'}; FILE *lib; struct liblink *p1=NULL; struct dlink *p2=NULL,*p3=NULL; p1=lhead; p1->next=NULL; strcpy(lbname,tlbname); //strcat(lbname,ftype); //上面是连接文件名;对应函数名后面的注释的参数 lib=fopen(lbname,"r"); if(lib==NULL) { brun=-1; return brun; }//读取对应库文件,不存在就出错 while(!feof(lib)) { for(i=0;i<50;i++) checkstr[i]='\0'; fscanf(lib,"%s\n",checkstr); //循环读取数据,以每行为单位读取 for(i=0;i<20;i++) sistr[i]='\0'; //初始化对应变量 if(checkstr[0]=='#') { //读取首字符,区别为结构数据和记录数据,#号为结构数据,|号为记录数据 garb(checkstr,sistr,6); for(i=0;i<50;i++) tname[i]='\0'; gettname(checkstr,tname); /*提取对应标记字符串,#table:区分为表头,#tbend|区分为表尾 若为表头,建立对应表头数据,提取表名,提取自加序列数,建立对应对应记录数据链表头*/ if(!strcmp(sistr,"#table:")) { strcpy(p1->tname,tname); p1->idno=0; p1->idno=getnum(p1->tname);//得到当前表的记录数 k=0;i=0; while(k<20) { if(p1->tname[k]=='$') i=1; if(i==1) p1->tname[k]='\0'; k++; }//标记表名结束位置,并且清除后面的记录数数据 fscanf(lib,"%s",p1->lname); //向下读取表的字段名 p1->dhead=NULL; p2=p1->dhead; p3=p2; } else if(!strcmp(sistr,"#tbend|")) { /*若为表尾,设置对应下一个表头并初始化*/ if(!feof(lib))//判断是否为文件结束,若为结束,就不创建 { p1->next=(struct liblink *)malloc(sizeof(struct liblink)); p1=p1->next; p1->next=NULL; p2=p1->dhead; } else p1->next=NULL; } } else if(checkstr[0]=='|') { /*若为记录数据,在记录表上进行处理,先初始化链表下一个单元,提取对应id名,和记录对应数据段*/ if(p2==NULL) { p2=(struct dlink *)malloc(sizeof(struct dlink));//开辟记录数据空间 p2->id=0; strcpy(p2->value,""); strcpy(p2->oval,"");//初始化对应空间的变量 p2->dnext=NULL; if(p3==NULL) p3=p2;//标记上一个链表单元 strcpy(p2->value,""); if(p1->dhead==NULL) p1->dhead=p2;//数据链表头赋值,给回数据库表的对应变量位置 if(p3!=p2) { p3->dnext=p2; p3=p3->dnext; }//对应指针移位,为一前一后的指针位置,标记连接 strcpy(p2->value,checkstr); for(i=0;i<10;i++) temp[i]='\0'; match(checkstr,1,temp,'|'); i=0; i=chchaint(temp); p2->id=i;//分离出id号,为每条记录的主键 p2=p2->dnext; } } for(i=0;i<50;i++) checkstr[i]='\0'; //对检测字符串进行重复初始化 } fclose(lib); brun=1; return brun; }