static void grab_ipt_netflow_snmp(time_t now) { static char buf[4096]; int fd; int n; char *p = buf; if ((now - totals_ts) < (TOTAL_INTERVAL + 1)) return; if ((fd = open("/proc/net/stat/ipt_netflow_snmp", O_RDONLY)) < 0) return; n = read(fd, buf, sizeof(buf) - 1); close(fd); if (n <= 0) return; buf[n] = '\0'; DEBUGMSGTL(("netflow", "%s\n", buf)); clear_data_set(cpu_data_set); clear_data_set(sock_data_set); while (*p) { struct snmp_vars *sys; char *name = p; char *val; if (!(p = strpbrk(p, " \t"))) break; *p++ = '\0'; val = p + strspn(p, " \t"); p = index(p, '\n'); *p++ = '\0'; if (!strncmp(name, "cpu", 3)) { parse_table_row(atoi(name + 3), val, cputable, cpu_data_set); continue; } else if (!strncmp(name, "sock", 4)) { parse_table_row(atoi(name + 4), val, socktable, sock_data_set); continue; } if (!(sys = find_varinfo_str(totals, name))) continue; if (index(val, '.')) { double d = strtod(val, NULL); sys->val64 = (long long)(d * 100); } else sys->val64 = strtoll(val, NULL, 10); sys->ts = now; } totals_ts = now; }
static size_t parse_table_header(struct buf *ob, struct render *rndr, char *data, size_t size, size_t *columns, int **column_data) { int pipes; size_t i = 0, col, header_end, under_end; pipes = 0; while (i < size && data[i] != '\n') if (data[i++] == '|') pipes++; if (i == size || pipes == 0) return 0; header_end = i; if (data[0] == '|') pipes--; if (i > 2 && data[i - 1] == '|') pipes--; *columns = pipes + 1; *column_data = calloc(*columns, sizeof(int)); /* Parse the header underline */ i++; if (i < size && data[i] == '|') i++; under_end = i; while (under_end < size && data[under_end] != '\n') under_end++; for (col = 0; col < *columns && i < under_end; ++col) { if (data[i] == ':') { i++; (*column_data)[col] |= MKD_TABLE_ALIGN_L; } while (i < under_end && data[i] == '-') i++; if (i < under_end && data[i] == ':') { i++; (*column_data)[col] |= MKD_TABLE_ALIGN_R; } if (i < under_end && data[i] != '|') break; i++; } if (col < *columns) return 0; parse_table_row(ob, rndr, data, header_end, *columns, *column_data); return under_end + 1; }
static size_t parse_table(struct buf *ob, struct render *rndr, char *data, size_t size) { size_t i; struct buf *header_work = 0; struct buf *body_work = 0; size_t columns; int *col_data = NULL; header_work = rndr_newbuf(rndr); body_work = rndr_newbuf(rndr); i = parse_table_header(header_work, rndr, data, size, &columns, &col_data); if (i > 0) { while (i < size) { size_t row_start; int pipes = 0; row_start = i; while (i < size && data[i] != '\n') if (data[i++] == '|') pipes++; if (pipes == 0 || i == size) { i = row_start; break; } parse_table_row(body_work, rndr, data + row_start, i - row_start, columns, col_data); i++; } if (rndr->make.table) rndr->make.table(ob, header_work, body_work, rndr->make.opaque); } free(col_data); rndr_popbuf(rndr); rndr_popbuf(rndr); return i; }
/* parse_table • parsing of a whole table */ static size_t parse_table(struct buf *ob, struct render *rndr, char *data, size_t size) { size_t i = 0, head_end, col; size_t align_size = 0; int *aligns = 0; struct buf *head = 0; struct buf *rows = new_work_buffer(rndr); /* skip the first (presumably header) line */ while (i < size && data[i] != '\n') i += 1; head_end = i; /* fallback on end of input */ if (i >= size) { parse_table_row(rows, rndr, data, size, 0, 0, 0); rndr->make.table(ob, 0, rows, rndr->make.opaque); release_work_buffer(rndr, rows); return i; } /* attempt to parse a table rule, i.e. blanks, dash, colons and sep */ i += 1; col = 0; while (i < size && (data[i] == ' ' || data[i] == '\t' || data[i] == '-' || data[i] == ':' || data[i] == '|')) { if (data[i] == '|') align_size += 1; if (data[i] == ':') col = 1; i += 1; } if (i < size && data[i] == '\n') { align_size += 1; /* render the header row */ head = new_work_buffer(rndr); parse_table_row(head, rndr, data, head_end, 0, 0, MKD_CELL_HEAD); /* parse alignments if provided */ if (col && (aligns = malloc(align_size * sizeof *aligns)) != 0){ for (i = 0; i < align_size; i += 1) aligns[i] = 0; col = 0; i = head_end + 1; /* skip initial white space and optional separator */ while (i < size && (data[i] == ' ' || data[i] == '\t')) i += 1; if (data[i] == '|') i += 1; /* compute default alignment for each column */ while (i < size && data[i] != '\n') { if (data[i] == ':') aligns[col] |= MKD_CELL_ALIGN_LEFT; while (i < size && data[i] != '|' && data[i] != '\n') i += 1; if (data[i - 1] == ':') aligns[col] |= MKD_CELL_ALIGN_RIGHT; if (i < size && data[i] == '|') i += 1; col += 1; } } /* point i to the beginning of next line/row */ i += 1; } else { /* there is no valid ruler, continuing without header */ i = 0; } /* render the table body lines */ while (i < size && is_tableline(data + i, size - i)) i += parse_table_row(rows, rndr, data + i, size - i, aligns, align_size, 0); /* render the full table */ rndr->make.table(ob, head, rows, rndr->make.opaque); /* cleanup */ if (head) release_work_buffer(rndr, head); release_work_buffer(rndr, rows); free(aligns); return i; }