static void handle_query(struct link *query_link) { FILE *stream; char line[LINE_MAX]; char url[LINE_MAX]; char path[LINE_MAX]; char action[LINE_MAX]; char version[LINE_MAX]; char hostport[LINE_MAX]; char addr[LINK_ADDRESS_MAX]; char key[LINE_MAX]; int port; time_t current; char *hkey; struct nvpair *nv; int i, n; link_address_remote(query_link, addr, &port); debug(D_DEBUG, "www query from %s:%d", addr, port); if(link_readline(query_link, line, LINE_MAX, time(0) + HANDLE_QUERY_TIMEOUT)) { string_chomp(line); if(sscanf(line, "%s %s %s", action, url, version) != 3) { return; } // Consume the rest of the query while(1) { if(!link_readline(query_link, line, LINE_MAX, time(0) + HANDLE_QUERY_TIMEOUT)) { return; } if(line[0] == 0) { break; } } } else { return; } // Output response stream = fdopen(link_fd(query_link), "w"); if(!stream) { return; } link_nonblocking(query_link, 0); current = time(0); fprintf(stream, "HTTP/1.1 200 OK\n"); fprintf(stream, "Date: %s", ctime(¤t)); fprintf(stream, "Server: catalog_server\n"); fprintf(stream, "Connection: close\n"); if(sscanf(url, "http://%[^/]%s", hostport, path) == 2) { // continue on } else { strcpy(path, url); } /* load the hash table entries into one big array */ n = 0; nvpair_database_firstkey(table); while(nvpair_database_nextkey(table, &hkey, &nv)) { array[n] = nv; n++; } /* sort the array by name before displaying */ qsort(array, n, sizeof(struct nvpair *), compare_nvpair); if(!strcmp(path, "/query.text")) { fprintf(stream, "Content-type: text/plain\n\n"); for(i = 0; i < n; i++) nvpair_print_text(array[i], stream); } else if(!strcmp(path, "/query.json")) { fprintf(stream, "Content-type: text/plain\n\n"); fprintf(stream,"[\n"); for(i = 0; i < n; i++) { nvpair_print_json(array[i], stream); fprintf(stream,",\n"); } fprintf(stream,"]\n"); } else if(!strcmp(path, "/query.oldclassads")) { fprintf(stream, "Content-type: text/plain\n\n"); for(i = 0; i < n; i++) nvpair_print_old_classads(array[i], stream); } else if(!strcmp(path, "/query.newclassads")) { fprintf(stream, "Content-type: text/plain\n\n"); for(i = 0; i < n; i++) nvpair_print_new_classads(array[i], stream); } else if(!strcmp(path, "/query.xml")) { fprintf(stream, "Content-type: text/xml\n\n"); fprintf(stream, "<?xml version=\"1.0\" standalone=\"yes\"?>\n"); fprintf(stream, "<catalog>\n"); for(i = 0; i < n; i++) nvpair_print_xml(array[i], stream); fprintf(stream, "</catalog>\n"); } else if(sscanf(path, "/detail/%s", key) == 1) { struct nvpair *nv; fprintf(stream, "Content-type: text/html\n\n"); nv = nvpair_database_lookup(table, key); if(nv) { const char *name = nvpair_lookup_string(nv, "name"); if(!name) name = "unknown"; fprintf(stream, "<title>%s catalog server: %s</title>\n", preferred_hostname, name); fprintf(stream, "<center>\n"); fprintf(stream, "<h1>%s catalog server</h1>\n", preferred_hostname); fprintf(stream, "<h2>%s</h2>\n", name); fprintf(stream, "<p><a href=/>return to catalog view</a><p>\n"); nvpair_print_html_solo(nv, stream); fprintf(stream, "</center>\n"); } else { fprintf(stream, "<title>%s catalog server</title>\n", preferred_hostname); fprintf(stream, "<center>\n"); fprintf(stream, "<h1>%s catalog server</h1>\n", preferred_hostname); fprintf(stream, "<h2>Unknown Item!</h2>\n"); fprintf(stream, "</center>\n"); } } else { char avail_line[LINE_MAX]; char total_line[LINE_MAX]; INT64_T sum_total = 0; INT64_T sum_avail = 0; INT64_T sum_devices = 0; fprintf(stream, "Content-type: text/html\n\n"); fprintf(stream, "<title>%s catalog server</title>\n", preferred_hostname); fprintf(stream, "<center>\n"); fprintf(stream, "<h1>%s catalog server</h1>\n", preferred_hostname); fprintf(stream, "<a href=/query.text>text</a> - "); fprintf(stream, "<a href=/query.html>html</a> - "); fprintf(stream, "<a href=/query.xml>xml</a> - "); fprintf(stream, "<a href=/query.json>json</a> - "); fprintf(stream, "<a href=/query.oldclassads>oldclassads</a> - "); fprintf(stream, "<a href=/query.newclassads>newclassads</a>"); fprintf(stream, "<p>\n"); for(i = 0; i < n; i++) { nv = array[i]; sum_total += nvpair_lookup_integer(nv, "total"); sum_avail += nvpair_lookup_integer(nv, "avail"); sum_devices++; } string_metric(sum_avail, -1, avail_line); string_metric(sum_total, -1, total_line); fprintf(stream, "<b>%sB available out of %sB on %d devices</b><p>\n", avail_line, total_line, (int) sum_devices); nvpair_print_html_header(stream, html_headers); for(i = 0; i < n; i++) { nv = array[i]; make_hash_key(nv, key); sprintf(url, "/detail/%s", key); nvpair_print_html_with_link(nv, stream, html_headers, "name", url); } nvpair_print_html_footer(stream, html_headers); fprintf(stream, "</center>\n"); } fclose(stream); }
void nvpair_print_html(struct nvpair *n, FILE * s, struct nvpair_header *h) { nvpair_print_html_with_link(n, s, h, 0, 0); }