/* add a host item to holder */ static void add_host_node (GHolder * h, int hits, char *data, unsigned long long bw, unsigned long long usecs) { GSubList *sub_list = new_gsublist (); char *ip = xstrdup (data); gpointer value_ptr; gboolean found; #ifdef HAVE_LIBGEOIP const char *addr = data; const char *location = NULL; #endif h->items[h->idx].bw += bw; h->items[h->idx].hits += hits; h->items[h->idx].data = xstrdup (data); if (conf.serve_usecs) h->items[h->idx].usecs = usecs; h->items[h->idx].sub_list = sub_list; #ifdef HAVE_LIBGEOIP location = get_geoip_data (addr); add_sub_item_back (sub_list, h->module, location, hits, bw); h->items[h->idx].sub_list = sub_list; h->sub_items_size++; #endif pthread_mutex_lock (&gdns_thread.mutex); found = g_hash_table_lookup_extended (ht_hostnames, ip, NULL, &value_ptr); pthread_mutex_unlock (&gdns_thread.mutex); if (!found) { dns_resolver (ip); } else if (value_ptr) { add_sub_item_back (sub_list, h->module, (char *) value_ptr, hits, bw); h->items[h->idx].sub_list = sub_list; h->sub_items_size++; } free (ip); h->idx++; }
/** * Generate JSON on complete fields for the following modules: * REQUESTS, REQUESTS_STATIC, NOT_FOUND, HOSTS */ static void print_json_complete (FILE * fp, GHolder * holder, int process) { #ifdef HAVE_LIBGEOIP const char *location = NULL; #endif char *data, *host, *method = NULL, *protocol = NULL; float percent; GHolder *h; int i, j, hits; unsigned long long bw, usecs; for (i = 0; i < 4; i++) { switch (i) { case 0: h = holder + REQUESTS; fprintf (fp, "\t\"%s\": [\n", REQUE_ID); break; case 1: h = holder + REQUESTS_STATIC; fprintf (fp, "\t\"%s\": [\n", STATI_ID); break; case 2: h = holder + NOT_FOUND; fprintf (fp, "\t\"%s\": [\n", FOUND_ID); break; case 3: h = holder + HOSTS; fprintf (fp, "\t\"%s\": [\n", HOSTS_ID); break; } for (j = 0; j < h->idx; j++) { hits = h->items[j].hits; data = h->items[j].data; percent = get_percentage (process, hits); percent = percent < 0 ? 0 : percent; bw = h->items[j].bw; usecs = h->items[j].usecs; method = h->items[j].method; protocol = h->items[j].protocol; fprintf (fp, "\t\t{\n"); fprintf (fp, "\t\t\t\"hits\": \"%d\",\n", hits); fprintf (fp, "\t\t\t\"percent\": \"%4.2f%%\",\n", percent); fprintf (fp, "\t\t\t\"data\": \""); escape_json_output (fp, data); fprintf (fp, "\",\n"); fprintf (fp, "\t\t\t\"bytes\": \"%lld\"", bw); if (h->module == HOSTS) { if (conf.enable_html_resolver) { host = reverse_ip (data); fprintf (fp, ",\n\t\t\t\"host\": \""); escape_json_output (fp, host); fprintf (fp, "\""); free (host); } #ifdef HAVE_LIBGEOIP location = get_geoip_data (data); fprintf (fp, ",\n\t\t\t\"country\": \""); escape_json_output (fp, (char *) location); fprintf (fp, "\""); #endif } if (conf.serve_usecs) fprintf (fp, ",\n\t\t\t\"time_served\": \"%lld\"", usecs); if (conf.append_protocol && protocol) fprintf (fp, ",\n\t\t\t\"protocol\": \"%s\"", protocol); if (conf.append_method && method) fprintf (fp, ",\n\t\t\t\"method\": \"%s\"", method); fprintf (fp, "\n\t\t}"); if (j != h->idx - 1) fprintf (fp, ",\n"); else fprintf (fp, "\n"); } if (i != 3) fprintf (fp, "\t],\n"); else fprintf (fp, "\t]\n"); } }
static void print_html_hosts (FILE * fp, GHolder * h, int process) { GAgents *agents; char *data, *bandwidth, *usecs, *ag, *ptr_value, *host; float percent, l; int hits; int i, j, max, until = 0, delims = 0, colspan = 6; size_t alloc = 0; #ifdef HAVE_LIBGEOIP const char *location = NULL; colspan++; #endif if (h->idx == 0) return; print_html_h2 (fp, HOSTS_HEAD, HOSTS_ID); print_p (fp, HOSTS_DESC); print_html_begin_table (fp); print_html_begin_thead (fp); fprintf (fp, "<tr>"); fprintf (fp, "<th></th>"); fprintf (fp, "<th>Hits</th>"); fprintf (fp, "<th>%%</th>"); fprintf (fp, "<th>Bandwidth</th>"); if (conf.serve_usecs) { colspan++; fprintf (fp, "<th>Time served</th>"); } fprintf (fp, "<th>IP</th>"); #ifdef HAVE_LIBGEOIP fprintf (fp, "<th>Country</th>"); #endif if (conf.enable_html_resolver) { colspan++; fprintf (fp, "<th>Hostname</th>"); } fprintf (fp, "<th style=\"width:100%%;text-align:right;\">"); fprintf (fp, "<span class=\"r\" onclick=\"t(this)\">◀</span>"); fprintf (fp, "</th>"); fprintf (fp, "</tr>"); print_html_end_thead (fp); print_html_begin_tbody (fp); until = h->idx < MAX_CHOICES ? h->idx : MAX_CHOICES; max = 0; for (i = 0; i < until; i++) { if (h->items[i].hits > max) max = h->items[i].hits; } for (i = 0; i < until; i++) { hits = h->items[i].hits; data = h->items[i].data; percent = get_percentage (process, hits); percent = percent < 0 ? 0 : percent; bandwidth = filesize_str (h->items[i].bw); l = get_percentage (max, hits); l = l < 1 ? 1 : l; #ifdef HAVE_LIBTOKYOCABINET ag = tc_db_get_str (ht_hosts_agents, data); #else ag = g_hash_table_lookup (ht_hosts_agents, data); #endif print_html_begin_tr (fp, i > OUTPUT_N ? 1 : 0); fprintf (fp, "<td>"); if (ag != NULL) fprintf (fp, "<span class=\"s\" onclick=\"a(this)\">▶</span>"); else fprintf (fp, "<span class=\"s\">-</span>"); fprintf (fp, "</td>"); fprintf (fp, "<td>%d</td>", hits); fprintf (fp, "<td>%4.2f%%</td>", percent); fprintf (fp, "<td>"); clean_output (fp, bandwidth); fprintf (fp, "</td>"); /* usecs */ if (conf.serve_usecs) { usecs = usecs_to_str (h->items[i].usecs); fprintf (fp, "<td>"); clean_output (fp, usecs); fprintf (fp, "</td>"); free (usecs); } fprintf (fp, "<td>%s</td>", data); #ifdef HAVE_LIBGEOIP location = get_geoip_data (data); fprintf (fp, "<td style=\"white-space:nowrap;\">%s</td>", location); #endif if (conf.enable_html_resolver) { host = reverse_ip (data); fprintf (fp, "<td style=\"white-space:nowrap;\">%s</td>", host); free (host); } fprintf (fp, "<td class=\"graph\">"); fprintf (fp, "<div class=\"bar\" style=\"width:%f%%\"></div>", l); fprintf (fp, "</td>"); print_html_end_tr (fp); /* render agents for each host */ if (ag != NULL) { ptr_value = (char *) ag; delims = count_occurrences (ptr_value, '|'); /* round-up + padding */ alloc = ((strlen (ptr_value) + 300 - 1) / 300) + delims + 1; agents = xmalloc (alloc * sizeof (GAgents)); memset (agents, 0, alloc * sizeof (GAgents)); /* split agents into struct */ split_agent_str (ptr_value, agents, 300); fprintf (fp, "<tr class=\"agent-hide\">\n"); fprintf (fp, "<td colspan=\"%d\">\n", colspan); fprintf (fp, "<div>"); fprintf (fp, "<table class=\"pure-table-striped\">"); /* output agents from struct */ for (j = 0; (j < 10) && (agents[j].agents != NULL); j++) { print_html_begin_tr (fp, 0); fprintf (fp, "<td>"); clean_output (fp, agents[j].agents); fprintf (fp, "</td>"); print_html_end_tr (fp); } fprintf (fp, "</table>\n"); fprintf (fp, "</div>\n"); fprintf (fp, "</td>\n"); print_html_end_tr (fp); for (j = 0; (agents[j].agents != NULL); j++) free (agents[j].agents); free (agents); #ifdef HAVE_LIBTOKYOCABINET if (ag) free (ag); #endif } free (bandwidth); } print_html_end_tbody (fp); print_html_end_table (fp); }