int main( int argc, char **argv ) { int id = 0; time_t now = time( NULL ); int seconds = 100; int shift = 0; id = event_list_add( 0, now + seconds, seconds, shift, NULL, NULL ); printf("Event id: %d\n", id); id = event_list_add( 0, now + seconds, seconds, shift, NULL, NULL ); printf("Event id: %d\n", id); int numEvents = 0; numEvents = count_events(); printf("Number of events: %d\n", numEvents); event_list_clean(); numEvents = count_events(); printf("Number of events: %d\n", numEvents); return 0; }
struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *dc, struct plot_info *pi) { int idx, maxtime, nr, i; int lastdepth, lasttime, lasttemp = 0; struct plot_data *plot_data; struct event *ev = dc->events; maxtime = pi->maxtime; /* * We want to have a plot_info event at least every 10s (so "maxtime/10+1"), * but samples could be more dense than that (so add in dc->samples). We also * need to have one for every event (so count events and add that) and * additionally we want two surface events around the whole thing (thus the * additional 4). There is also one extra space for a final entry * that has time > maxtime (because there can be surface samples * past "maxtime" in the original sample data) */ nr = dc->samples + 6 + maxtime / 10 + count_events(dc); plot_data = calloc(nr, sizeof(struct plot_data)); pi->entry = plot_data; if (!plot_data) return NULL; pi->nr = nr; idx = 2; /* the two extra events at the start */ lastdepth = 0; lasttime = 0; /* skip events at time = 0 */ while (ev && ev->time.seconds == 0) ev = ev->next; for (i = 0; i < dc->samples; i++) { struct plot_data *entry = plot_data + idx; struct sample *sample = dc->sample + i; int time = sample->time.seconds; int offset, delta; int depth = sample->depth.mm; int sac = sample->sac.mliter; /* Add intermediate plot entries if required */ delta = time - lasttime; if (delta <= 0) { time = lasttime; delta = 1; // avoid divide by 0 } for (offset = 10; offset < delta; offset += 10) { if (lasttime + offset > maxtime) break; /* Add events if they are between plot entries */ while (ev && ev->time.seconds < lasttime + offset) { INSERT_ENTRY(ev->time.seconds, interpolate(lastdepth, depth, ev->time.seconds - lasttime, delta), sac); ev = ev->next; } /* now insert the time interpolated entry */ INSERT_ENTRY(lasttime + offset, interpolate(lastdepth, depth, offset, delta), sac); /* skip events that happened at this time */ while (ev && ev->time.seconds == lasttime + offset) ev = ev->next; } /* Add events if they are between plot entries */ while (ev && ev->time.seconds < time) { INSERT_ENTRY(ev->time.seconds, interpolate(lastdepth, depth, ev->time.seconds - lasttime, delta), sac); ev = ev->next; } entry->sec = time; entry->depth = depth; entry->running_sum = (entry - 1)->running_sum + (time - (entry - 1)->sec) * (depth + (entry - 1)->depth) / 2; entry->stopdepth = sample->stopdepth.mm; entry->stoptime = sample->stoptime.seconds; entry->ndl = sample->ndl.seconds; entry->tts = sample->tts.seconds; pi->has_ndl |= sample->ndl.seconds; entry->in_deco = sample->in_deco; entry->cns = sample->cns; if (dc->divemode == CCR) { entry->o2pressure.mbar = entry->o2setpoint.mbar = sample->setpoint.mbar; // for rebreathers entry->o2sensor[0].mbar = sample->o2sensor[0].mbar; // for up to three rebreather O2 sensors entry->o2sensor[1].mbar = sample->o2sensor[1].mbar; entry->o2sensor[2].mbar = sample->o2sensor[2].mbar; } else { entry->pressures.o2 = sample->setpoint.mbar / 1000.0; } /* FIXME! sensor index -> cylinder index translation! */ // entry->cylinderindex = sample->sensor; SENSOR_PRESSURE(entry) = sample->cylinderpressure.mbar; O2CYLINDER_PRESSURE(entry) = sample->o2cylinderpressure.mbar; if (sample->temperature.mkelvin) entry->temperature = lasttemp = sample->temperature.mkelvin; else entry->temperature = lasttemp; entry->heartbeat = sample->heartbeat; entry->bearing = sample->bearing.degrees; entry->sac = sample->sac.mliter; if (sample->rbt.seconds) entry->rbt = sample->rbt.seconds; /* skip events that happened at this time */ while (ev && ev->time.seconds == time) ev = ev->next; lasttime = time; lastdepth = depth; idx++; if (time > maxtime) break; } /* Add two final surface events */ plot_data[idx++].sec = lasttime + 1; plot_data[idx++].sec = lasttime + 2; pi->nr = idx; return plot_data; }
void do_eventlog(FILE *output, int maxcount, int maxminutes, char *fromtime, char *totime, char *pageregex, char *expageregex, char *hostregex, char *exhostregex, char *testregex, char *extestregex, char *colrregex, int ignoredialups, f_hostcheck hostcheck, event_t **eventlist, countlist_t **hostcounts, countlist_t **servicecounts, countsummary_t counttype, eventsummary_t sumtype, char *periodstring) { FILE *eventlog; char eventlogfilename[PATH_MAX]; time_t firstevent = 0; time_t lastevent = getcurrenttime(NULL); event_t *eventhead = NULL; struct stat st; char l[MAX_LINE_LEN]; char title[200]; /* For the PCRE matching */ const char *errmsg = NULL; int errofs = 0; pcre *pageregexp = NULL; pcre *expageregexp = NULL; pcre *hostregexp = NULL; pcre *exhostregexp = NULL; pcre *testregexp = NULL; pcre *extestregexp = NULL; pcre *colrregexp = NULL; countlist_t *hostcounthead = NULL, *svccounthead = NULL; if (eventlist) *eventlist = NULL; if (hostcounts) *hostcounts = NULL; if (servicecounts) *servicecounts = NULL; havedoneeventlog = 1; if ((maxminutes > 0) && (fromtime || totime)) { fprintf(output, "<B>Only one time interval type is allowed!</B>"); return; } if (fromtime) { firstevent = eventreport_time(fromtime); if(firstevent < 0) { if (output) fprintf(output,"<B>Invalid 'from' time: %s</B>", htmlquoted(fromtime)); return; } } else if (maxminutes == -1) { /* Unlimited number of minutes */ firstevent = 0; } else if (maxminutes > 0) { firstevent = getcurrenttime(NULL) - maxminutes*60; } else { firstevent = getcurrenttime(NULL) - 86400; } if (totime) { lastevent = eventreport_time(totime); if (lastevent < 0) { if (output) fprintf(output,"<B>Invalid 'to' time: %s</B>", htmlquoted(totime)); return; } if (lastevent < firstevent) { if (output) fprintf(output,"<B>'to' time must be after 'from' time.</B>"); return; } } if (!maxcount) maxcount = 100; if (pageregex && *pageregex) pageregexp = pcre_compile(pageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (expageregex && *expageregex) expageregexp = pcre_compile(expageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (hostregex && *hostregex) hostregexp = pcre_compile(hostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (exhostregex && *exhostregex) exhostregexp = pcre_compile(exhostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (testregex && *testregex) testregexp = pcre_compile(testregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (extestregex && *extestregex) extestregexp = pcre_compile(extestregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (colrregex && *colrregex) colrregexp = pcre_compile(colrregex, PCRE_CASELESS, &errmsg, &errofs, NULL); sprintf(eventlogfilename, "%s/allevents", xgetenv("XYMONHISTDIR")); eventlog = fopen(eventlogfilename, "r"); if (eventlog && (stat(eventlogfilename, &st) == 0)) { time_t curtime; int done = 0; int unlimited = (maxcount == -1); if (unlimited) maxcount = 1000; do { /* Find a spot in the eventlog file close to where the firstevent time is */ fseeko(eventlog, 0, SEEK_END); do { /* Go back maxcount*80 bytes - one entry is ~80 bytes */ if (ftello(eventlog) > maxcount*80) { unsigned int uicurtime; fseeko(eventlog, -maxcount*80, SEEK_CUR); if (fgets(l, sizeof(l), eventlog) && /* Skip to start of line */ fgets(l, sizeof(l), eventlog)) { sscanf(l, "%*s %*s %u %*u %*u %*s %*s %*d", &uicurtime); curtime = uicurtime; done = (curtime < firstevent); if (unlimited && !done) maxcount += 1000; } else { if (output) fprintf(output,"Error reading eventlog file %s: %s\n", eventlogfilename, strerror(errno)); return; } } else { rewind(eventlog); curtime = 0; done = 1; } } while (!done); if (unlimited) unlimited = ((curtime > firstevent) && (ftello(eventlog) > 0)); } while (unlimited); } eventhead = NULL; while (eventlog && (fgets(l, sizeof(l), eventlog))) { time_t eventtime, changetime, duration; unsigned int uievt, uicht, uidur; char hostname[MAX_LINE_LEN], svcname[MAX_LINE_LEN], newcol[MAX_LINE_LEN], oldcol[MAX_LINE_LEN]; char *newcolname, *oldcolname; int state, itemsfound, colrmatch; event_t *newevent; void *eventhost; struct htnames_t *eventcolumn; int ovector[30]; eventcount_t *countrec; itemsfound = sscanf(l, "%s %s %u %u %u %s %s %d", hostname, svcname, &uievt, &uicht, &uidur, newcol, oldcol, &state); eventtime = uievt; changetime = uicht; duration = uidur; oldcolname = colorname(eventcolor(oldcol)); newcolname = colorname(eventcolor(newcol)); /* For DURATION counts, we must parse all events until now */ if ((counttype != XYMON_COUNT_DURATION) && (eventtime > lastevent)) break; eventhost = hostinfo(hostname); eventcolumn = getname(svcname, 1); if ( (itemsfound == 8) && (eventtime >= firstevent) && (eventhost && !xmh_item(eventhost, XMH_FLAG_NONONGREEN)) && (wanted_eventcolumn(svcname)) ) { if (eventfilter(eventhost, svcname, pageregexp, expageregexp, hostregexp, exhostregexp, testregexp, extestregexp, ignoredialups, hostcheck) == 0) continue; /* For duration counts, record all events. We'll filter out the colors later. */ if (colrregexp && (counttype != XYMON_COUNT_DURATION)) { colrmatch = ( (pcre_exec(colrregexp, NULL, newcolname, strlen(newcolname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0) || (pcre_exec(colrregexp, NULL, oldcolname, strlen(oldcolname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0) ); } else colrmatch = 1; if (!colrmatch) continue; newevent = (event_t *) malloc(sizeof(event_t)); newevent->host = eventhost; newevent->service = eventcolumn; newevent->eventtime = eventtime; newevent->changetime = changetime; newevent->duration = duration; newevent->newcolor = eventcolor(newcol); newevent->oldcolor = eventcolor(oldcol); newevent->next = eventhead; eventhead = newevent; if (counttype != XYMON_COUNT_DURATION) { countrec = (eventcount_t *)xmh_item(eventhost, XMH_DATA); while (countrec && (countrec->service != eventcolumn)) countrec = countrec->next; if (countrec == NULL) { countrec = (eventcount_t *)calloc(1, sizeof(eventcount_t)); countrec->service = eventcolumn; countrec->next = (eventcount_t *)xmh_item(eventhost, XMH_DATA); xmh_set_item(eventhost, XMH_DATA, (void *)countrec); } countrec->count++; } } } /* Count the state changes per host */ svccounthead = hostcounthead = NULL; switch (counttype) { case XYMON_COUNT_EVENTS: count_events(&hostcounthead, &svccounthead); break; case XYMON_COUNT_DURATION: count_duration(firstevent, lastevent, pageregexp, expageregexp, hostregexp, exhostregexp, testregexp, extestregexp, ignoredialups, hostcheck, eventhead, &hostcounthead, &svccounthead); break; default: break; } if (hostcounthead) hostcounthead = msort(hostcounthead, record_compare, record_getnext, record_setnext); if (svccounthead) svccounthead = msort(svccounthead, record_compare, record_getnext, record_setnext); if (eventhead && (output != NULL)) { char *bgcolors[2] = { "#000000", "#000033" }; int bgcolor = 0; struct event_t *ewalk, *lasttoshow = eventhead; countlist_t *cwalk; unsigned long totalcount = 0; if (periodstring) fprintf(output, "<p><font size=+1>%s</font></p>\n", htmlquoted(periodstring)); switch (sumtype) { case XYMON_S_HOST_BREAKDOWN: /* Request for a specific service, show breakdown by host */ for (cwalk = hostcounthead; (cwalk); cwalk = cwalk->next) totalcount += cwalk->total; fprintf(output, "<table summary=\"Breakdown by host\" border=0>\n"); fprintf(output, "<tr><th align=left>Host</th><th colspan=2>%s</th></tr>\n", (counttype == XYMON_COUNT_EVENTS) ? "State changes" : "Seconds red/yellow"); fprintf(output, "<tr><td colspan=3><hr width=\"100%%\"></td></tr>\n"); for (cwalk = hostcounthead; (cwalk && (cwalk->total > 0)); cwalk = cwalk->next) { fprintf(output, "<tr><td align=left>%s</td><td align=right>%lu</td><td align=right>(%6.2f %%)</tr>\n", xmh_item(cwalk->src, XMH_HOSTNAME), cwalk->total, ((100.0 * cwalk->total) / totalcount)); } fprintf(output, "</table>\n"); break; case XYMON_S_SERVICE_BREAKDOWN: /* Request for a specific host, show breakdown by service */ for (cwalk = svccounthead; (cwalk); cwalk = cwalk->next) totalcount += cwalk->total; fprintf(output, "<table summary=\"Breakdown by service\" border=0>\n"); fprintf(output, "<tr><th align=left>Service</th><th colspan=2>%s</th></tr>\n", (counttype == XYMON_COUNT_EVENTS) ? "State changes" : "Seconds red/yellow"); fprintf(output, "<tr><td colspan=3><hr width=\"100%%\"></td></tr>\n"); for (cwalk = svccounthead; (cwalk && (cwalk->total > 0)); cwalk = cwalk->next) { fprintf(output, "<tr><td align=left>%s</td><td align=right>%lu</td><td align=right>(%6.2f %%)</tr>\n", ((htnames_t *)cwalk->src)->name, cwalk->total, ((100.0 * cwalk->total) / totalcount)); } fprintf(output, "</table>\n"); break; case XYMON_S_NONE: break; } if (sumtype == XYMON_S_NONE) { int count; count=0; ewalk=eventhead; do { count++; lasttoshow = ewalk; ewalk = ewalk->next; } while (ewalk && (count<maxcount)); if (ewalk) ewalk->next = NULL; /* Terminate list if any items left */ if (maxminutes > 0) { sprintf(title, "%d events received in the past %u minutes", count, (unsigned int)((getcurrenttime(NULL) - lasttoshow->eventtime) / 60)); } else { sprintf(title, "%d events received.", count); } } else { strcpy(title, "Events in summary"); } fprintf(output, "<BR><BR>\n"); fprintf(output, "<TABLE SUMMARY=\"$EVENTSTITLE\" BORDER=0>\n"); fprintf(output, "<TR BGCOLOR=\"#333333\">\n"); fprintf(output, "<TD ALIGN=CENTER COLSPAN=6><FONT SIZE=-1 COLOR=\"#33ebf4\">%s</FONT></TD></TR>\n", htmlquoted(title)); for (ewalk=eventhead; (ewalk); ewalk=ewalk->next) { char *hostname = xmh_item(ewalk->host, XMH_HOSTNAME); if ( (counttype == XYMON_COUNT_DURATION) && (ewalk->oldcolor < COL_YELLOW) && (ewalk->newcolor < COL_YELLOW) ) continue; if ( (counttype == XYMON_COUNT_DURATION) && (ewalk->eventtime >= lastevent) ) continue; fprintf(output, "<TR BGCOLOR=%s>\n", bgcolors[bgcolor]); bgcolor = ((bgcolor + 1) % 2); fprintf(output, "<TD ALIGN=CENTER>%s</TD>\n", ctime(&ewalk->eventtime)); if (ewalk->newcolor == COL_CLEAR) { fprintf(output, "<TD ALIGN=CENTER BGCOLOR=black><FONT COLOR=white>%s</FONT></TD>\n", hostname); } else { fprintf(output, "<TD ALIGN=CENTER BGCOLOR=%s><FONT COLOR=black>%s</FONT></TD>\n", colorname(ewalk->newcolor), hostname); } fprintf(output, "<TD ALIGN=LEFT>%s</TD>\n", ewalk->service->name); fprintf(output, "<TD><A HREF=\"%s\">\n", histlogurl(hostname, ewalk->service->name, ewalk->changetime, NULL)); fprintf(output, "<IMG SRC=\"%s/%s\" HEIGHT=\"%s\" WIDTH=\"%s\" BORDER=0 ALT=\"%s\" TITLE=\"%s\"></A>\n", xgetenv("XYMONSKIN"), dotgiffilename(ewalk->oldcolor, 0, 0), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH"), colorname(ewalk->oldcolor), colorname(ewalk->oldcolor)); fprintf(output, "<IMG SRC=\"%s/arrow.gif\" BORDER=0 ALT=\"From -> To\">\n", xgetenv("XYMONSKIN")); fprintf(output, "<TD><A HREF=\"%s\">\n", histlogurl(hostname, ewalk->service->name, ewalk->eventtime, NULL)); fprintf(output, "<IMG SRC=\"%s/%s\" HEIGHT=\"%s\" WIDTH=\"%s\" BORDER=0 ALT=\"%s\" TITLE=\"%s\"></A></TD>\n", xgetenv("XYMONSKIN"), dotgiffilename(ewalk->newcolor, 0, 0), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH"), colorname(ewalk->newcolor), colorname(ewalk->newcolor)); fprintf(output, "</TR>\n"); } fprintf(output, "</TABLE>\n"); } else if (output != NULL) { /* No events during the past maxminutes */ if (eventlog) sprintf(title, "No events received in the last %d minutes", maxminutes); else strcpy(title, "No events logged"); fprintf(output, "<CENTER><BR>\n"); fprintf(output, "<TABLE SUMMARY=\"%s\" BORDER=0>\n", title); fprintf(output, "<TR BGCOLOR=\"#333333\">\n"); fprintf(output, "<TD ALIGN=CENTER COLSPAN=6><FONT SIZE=-1 COLOR=\"#33ebf4\">%s</FONT></TD>\n", htmlquoted(title)); fprintf(output, "</TR>\n"); fprintf(output, "</TABLE>\n"); fprintf(output, "</CENTER>\n"); } if (eventlog) fclose(eventlog); if (pageregexp) pcre_free(pageregexp); if (hostregexp) pcre_free(hostregexp); if (testregexp) pcre_free(testregexp); if (colrregexp) pcre_free(colrregexp); /* Return the event- and count-lists, if wanted - or clean them up */ if (eventlist) { *eventlist = eventhead; } else { event_t *zombie, *ewalk = eventhead; while (ewalk) { zombie = ewalk; ewalk = ewalk->next; xfree(zombie); } } if (hostcounts) { *hostcounts = hostcounthead; } else { countlist_t *zombie, *hwalk = hostcounthead; while (hwalk) { zombie = hwalk; hwalk = hwalk->next; xfree(zombie); } } if (servicecounts) { *servicecounts = svccounthead; } else { countlist_t *zombie, *swalk = svccounthead; while (swalk) { zombie = swalk; swalk = swalk->next; xfree(zombie); } } }