static INT64_T do_statfs(int argc, char **argv) { struct chirp_statfs info; int metric_power = -1; if(argc > 1) { if(!strcmp(argv[1], "-k")) { metric_power = 1; } else if(!strcmp(argv[1], "-m")) { metric_power = 2; } else if(!strcmp(argv[1], "-g")) { metric_power = 3; } else if(!strcmp(argv[1], "-t")) { metric_power = 4; } else { errno = EINVAL; return -1; } } if(chirp_reli_statfs(current_host, "/", &info, stoptime) < 0) { return -1; } else { printf("/\n"); printf("%sB TOTAL\n", string_metric(info.f_blocks * info.f_bsize, metric_power, 0)); printf("%sB INUSE\n", string_metric((info.f_blocks - info.f_bfree) * info.f_bsize, metric_power, 0)); return 0; } }
static INT64_T do_put(int argc, char **argv) { char target_full_path[CHIRP_PATH_MAX]; char source_full_path[CHIRP_PATH_MAX]; timestamp_t start, stop; double elapsed; INT64_T result; if(!argv[2]) argv[2] = (char *) path_basename(argv[1]); complete_local_path(argv[1], source_full_path); complete_remote_path(argv[2], target_full_path); start = timestamp_get(); result = chirp_recursive_put(current_host, source_full_path, target_full_path, stoptime); stop = timestamp_get(); elapsed = (stop - start) / 1000000.0; if(result > 0) { printf("%sB written in %.2fs ", string_metric(result, -1, 0), elapsed); printf("(%sB/s)\n", string_metric(result / elapsed, -1, 0)); } return result; }
void nvpair_print_html_with_link(struct nvpair *n, FILE * s, struct nvpair_header *h, const char *linkname, const char *linktext) { fprintf(s, "<tr bgcolor=%s>\n", color_counter % 2 ? COLOR_ONE : COLOR_TWO); color_counter++; while(h->name) { const char *text = nvpair_lookup_string(n, h->name); if(!text) text = "???"; fprintf(s, "<td align=%s>", align_string(h)); if(h->mode == NVPAIR_MODE_URL) { fprintf(s, "<a href=%s>%s</a>\n", text, text); } else if(h->mode == NVPAIR_MODE_METRIC) { char line[1024]; string_metric(atof(text), -1, line); fprintf(s, "%sB\n", line); } else { if(linkname && !strcmp(linkname, h->name)) { fprintf(s, "<a href=%s>%s</a>\n", linktext, text); } else { fprintf(s, "%s\n", text); } } h++; } }
static INT64_T do_audit(int argc, char **argv) { struct chirp_audit *list; int result; int raw_mode = 0; if(argc > 1) { if(!strcmp(argv[1], "-r")) { raw_mode = 1; } else { printf("audit: unknown option: %s\n", argv[1]); return -1; } } result = chirp_reli_audit(current_host, "/", &list, stoptime); if(result >= 0) { int i; if(!raw_mode) printf(" FILES DIRS DATA OWNER\n"); for(i = 0; i < result; i++) { if(raw_mode) { printf("%" PRId64 " %" PRId64 " %" PRId64 " %s\n", list[i].nfiles, list[i].ndirs, list[i].nbytes, list[i].name); } else { printf("%8" PRId64 " %8" PRId64 " %8sB %s\n", list[i].nfiles, list[i].ndirs, string_metric(list[i].nbytes, -1, 0), list[i].name); } } free(list); } return result; }
void chirp_alloc_init(const char *rootpath, INT64_T size) { struct alloc_state *a; time_t start, stop; INT64_T inuse, avail; #ifdef CCTOOLS_OPSYS_CYGWIN fatal("sorry, CYGWIN cannot employ space allocation because it does not support file locking."); #endif alloc_enabled = 1; recovery_in_progress = 1; debug(D_ALLOC, "### begin allocation recovery scan ###"); if(!alloc_state_create(rootpath, size)) fatal("couldn't create allocation in %s: %s\n", rootpath, strerror(errno)); a = alloc_state_cache_exact(rootpath); if(!a) fatal("couldn't find allocation in %s: %s\n", rootpath, strerror(errno)); start = time(0); recover(rootpath); size = a->size; inuse = a->inuse; avail = a->avail; chirp_alloc_flush(); stop = time(0); debug(D_ALLOC, "### allocation recovery took %d seconds ###", stop - start); debug(D_ALLOC, "%sB total", string_metric(size, -1, 0)); debug(D_ALLOC, "%sB in use", string_metric(inuse, -1, 0)); debug(D_ALLOC, "%sB available", string_metric(avail, -1, 0)); recovery_in_progress = 0; }
static INT64_T do_lsalloc(int argc, char **argv) { char full_path[CHIRP_PATH_MAX]; char alloc_path[CHIRP_PATH_MAX]; INT64_T total, inuse; int result; if(argc != 2) argv[1] = "."; complete_remote_path(argv[1], full_path); result = chirp_reli_lsalloc(current_host, full_path, alloc_path, &total, &inuse, stoptime); if(result >= 0) { printf("%s\n", alloc_path); printf("%sB TOTAL\n", string_metric(total, -1, 0)); printf("%sB INUSE\n", string_metric(inuse, -1, 0)); } return result; }
static void recover(const char *path) { char newpath[CHIRP_PATH_MAX]; struct alloc_state *a, *b; struct chirp_dir *dir; struct chirp_dirent *d; a = alloc_state_cache_exact(path); if(!a) fatal("couldn't open alloc state in %s: %s", path, strerror(errno)); dir = cfs->opendir(path); if(!dir) fatal("couldn't open %s: %s\n", path, strerror(errno)); while((d = cfs->readdir(dir))) { if(!strcmp(d->name, ".")) continue; if(!strcmp(d->name, "..")) continue; if(!strncmp(d->name, ".__", 3)) continue; sprintf(newpath, "%s/%s", path, d->name); if(S_ISDIR(d->info.cst_mode)) { recover(newpath); b = alloc_state_cache_exact(newpath); if(a != b) alloc_state_update(a, b->size); } else if(S_ISREG(d->info.cst_mode)) { alloc_state_update(a, space_consumed(d->info.cst_size)); } else { debug(D_ALLOC, "warning: unknown file type: %s\n", newpath); } } cfs->closedir(dir); debug(D_ALLOC, "%s (%sB)", path, string_metric(a->inuse, -1, 0)); }
void nvpair_print_table(struct nvpair *n, FILE * s, struct nvpair_header *h) { while(h->name) { const char *text = nvpair_lookup_string(n, h->name); char *aligned = xxmalloc(h->width + 1); char *line; if(!text) { line = xxstrdup("???"); } else if(h->mode == NVPAIR_MODE_METRIC) { line = xxmalloc(10); string_metric(atof(text), -1, line); strcat(line, "B"); } else if(h->mode == NVPAIR_MODE_TIMESTAMP || h->mode == NVPAIR_MODE_TIME) { line = xxmalloc(h->width); timestamp_t ts; int ret = 0; if(sscanf(text, "%" SCNu64, &ts) == 1) { if(h->mode == NVPAIR_MODE_TIME) { ts *= 1000000; } ret = timestamp_fmt(line, h->width, "%R %b %d, %Y", ts); } if(ret == 0) { strcpy(line, "???"); } } else { line = xxmalloc(strlen(text) + 1); strcpy(line, text); } fill_string(line, aligned, h->width, h->align); printf("%s ", aligned); free(line); free(aligned); h++; } printf("\n"); }
int main(int argc, char *argv[]) { struct catalog_query *q; struct nvpair *n; time_t timeout = 60, stoptime; const char *catalog_host = 0; signed char c; int i; int count = 0; int mode = MODE_TABLE; INT64_T total = 0, avail = 0; const char *filter_name = 0; const char *filter_value = 0; debug_config(argv[0]); static struct option long_options[] = { {"catalog", required_argument, 0, 'c'}, {"debug", required_argument, 0, 'd'}, {"debug-file", required_argument, 0, 'o'}, {"debug-rotate-max", required_argument, 0, 'O'}, {"server-space", required_argument, 0, 'A'}, {"all", no_argument, 0, 'a'}, {"timeout", required_argument, 0, 't'}, {"brief", no_argument, 0, 's'}, {"verbose", no_argument, 0, 'l'}, {"totals", no_argument, 0, 'T'}, {"version", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; while((c = getopt_long(argc, argv, "aA:c:d:t:o:O:sTlvh", long_options, NULL)) > -1) { switch (c) { case 'a': show_all_types = 1; break; case 'c': catalog_host = optarg; break; case 'd': debug_flags_set(optarg); break; case 't': timeout = string_time_parse(optarg); break; case 'A': minavail = string_metric_parse(optarg); break; case 'o': debug_config_file(optarg); break; case 'O': debug_config_file_size(string_metric_parse(optarg)); break; case 'v': cctools_version_print(stdout, argv[0]); return 1; case 's': mode = MODE_SHORT; break; case 'l': mode = MODE_LONG; break; case 'T': mode = MODE_TOTAL; break; case 'h': default: show_help(argv[0]); return 1; } } cctools_version_debug(D_DEBUG, argv[0]); if(argc - optind == 0) { // fine, keep going } else if((argc - optind) == 1) { filter_name = "name"; filter_value = argv[optind]; } else if((argc - optind) == 2) { filter_name = argv[optind]; filter_value = argv[optind + 1]; } else { show_help(argv[0]); return 1; } stoptime = time(0) + timeout; q = catalog_query_create(catalog_host, 0, stoptime); if(!q) { fprintf(stderr, "couldn't query catalog: %s\n", strerror(errno)); return 1; } if(mode == MODE_TABLE) { nvpair_print_table_header(stdout, headers); } while((n = catalog_query_read(q, stoptime))) { table[count++] = n; } qsort(table, count, sizeof(*table), (int (*)(const void *, const void *)) compare_entries); for(i = 0; i < count; i++) { const char *etype = nvpair_lookup_string(table[i], "type"); if(!show_all_types) { if(etype) { if(!strcmp(etype, "chirp") || !strcmp(etype, "catalog")) { /* ok, keep going */ } else { continue; } } else { continue; } } if(minavail != 0) { if(minavail > nvpair_lookup_integer(table[i], "avail")) { continue; } } if(filter_name) { const char *v = nvpair_lookup_string(table[i], filter_name); if(!v || strcmp(filter_value, v)) continue; } if(mode == MODE_SHORT) { const char *t = nvpair_lookup_string(table[i], "type"); if(t && !strcmp(t, "chirp")) { printf("%s:%d\n", nvpair_lookup_string(table[i], "name"), (int) nvpair_lookup_integer(table[i], "port")); } } else if(mode == MODE_LONG) { nvpair_print_text(table[i], stdout); } else if(mode == MODE_TABLE) { nvpair_print_table(table[i], stdout, headers); } else if(mode == MODE_TOTAL) { avail += nvpair_lookup_integer(table[i], "avail"); total += nvpair_lookup_integer(table[i], "total"); } } if(mode == MODE_TOTAL) { printf("NODES: %4d\n", count); printf("TOTAL: %6sB\n", string_metric(total, -1, 0)); printf("AVAIL: %6sB\n", string_metric(avail, -1, 0)); printf("INUSE: %6sB\n", string_metric(total - avail, -1, 0)); } if(mode == MODE_TABLE) { nvpair_print_table_footer(stdout, headers); } return 0; }
void makeflow_summary_create(struct dag *d, const char *filename, const char *email_summary_to, timestamp_t runtime, timestamp_t time_completed, int argc, char *argv[], const char *dagfile, struct batch_queue *remote_queue, int abort_flag, int failed_flag ) { char buffer[50]; FILE *summary_file = NULL; FILE *summary_email = NULL; if(filename) summary_file = fopen(filename, "w"); if(email_summary_to) { summary_email = popen("sendmail -t", "w"); fprintf(summary_email, "To: %s\n", email_summary_to); timestamp_fmt(buffer, 50, "%c", time_completed); fprintf(summary_email, "Subject: Makeflow Run Summary - %s \n", buffer); } int i; for(i = 0; i < argc; i++) summarize(summary_file, summary_email, "%s ", argv[i]); summarize(summary_file, summary_email, "\n"); if(abort_flag) summarize(summary_file, summary_email, "Workflow aborted:\t "); else if(failed_flag) summarize(summary_file, summary_email, "Workflow failed:\t "); else summarize(summary_file, summary_email, "Workflow completed:\t "); timestamp_fmt(buffer, 50, "%c\n", time_completed); summarize(summary_file, summary_email, "%s", buffer); int seconds = runtime / 1000000; int hours = seconds / 3600; int minutes = (seconds - hours * 3600) / 60; seconds = seconds - hours * 3600 - minutes * 60; summarize(summary_file, summary_email, "Total runtime:\t\t %d:%02d:%02d\n", hours, minutes, seconds); summarize(summary_file, summary_email, "Workflow file:\t\t %s\n", dagfile); struct dag_node *n; struct dag_file *f; const char *fn; dag_node_state_t state; struct list *output_files; output_files = list_create(); struct list *failed_tasks; failed_tasks = list_create(); int total_tasks = itable_size(d->node_table); int tasks_completed = 0; int tasks_aborted = 0; int tasks_unrun = 0; for(n = d->nodes; n; n = n->next) { state = n->state; if(state == DAG_NODE_STATE_FAILED && !list_find(failed_tasks, (int (*)(void *, const void *)) string_equal, (void *) fn)) list_push_tail(failed_tasks, (void *) n->command); else if(state == DAG_NODE_STATE_ABORTED) tasks_aborted++; else if(state == DAG_NODE_STATE_COMPLETE) { tasks_completed++; list_first_item(n->source_files); while((f = list_next_item(n->source_files))) { fn = f->filename; if(!list_find(output_files, (int (*)(void *, const void *)) string_equal, (void *) fn)) list_push_tail(output_files, (void *) fn); } } else tasks_unrun++; } summarize(summary_file, summary_email, "Number of tasks:\t %d\n", total_tasks); summarize(summary_file, summary_email, "Completed tasks:\t %d/%d\n", tasks_completed, total_tasks); if(tasks_aborted != 0) summarize(summary_file, summary_email, "Aborted tasks:\t %d/%d\n", tasks_aborted, total_tasks); if(tasks_unrun != 0) summarize(summary_file, summary_email, "Tasks not run:\t\t %d/%d\n", tasks_unrun, total_tasks); if(list_size(failed_tasks) > 0) summarize(summary_file, summary_email, "Failed tasks:\t\t %d/%d\n", list_size(failed_tasks), total_tasks); for(list_first_item(failed_tasks); (fn = list_next_item(failed_tasks)) != NULL;) summarize(summary_file, summary_email, "\t%s\n", fn); if(list_size(output_files) > 0) { summarize(summary_file, summary_email, "Output files:\n"); for(list_first_item(output_files); (fn = list_next_item(output_files)) != NULL;) { const char *size; struct stat buf; batch_fs_stat(remote_queue, fn, &buf); size = string_metric(buf.st_size, -1, NULL); summarize(summary_file, summary_email, "\t%s\t%s\n", fn, size); } } list_free(output_files); list_delete(output_files); list_free(failed_tasks); list_delete(failed_tasks); if(filename) { fprintf(stderr, "writing summary to %s.\n", filename); fclose(summary_file); } if(email_summary_to) { fprintf(stderr, "emailing summary to %s.\n", email_summary_to); fclose(summary_email); } }
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); }
int main(int argc, char *argv[]) { enum { LONGOPT_SERVER_LASTHEARDFROM = INT_MAX-0, LONGOPT_SERVER_PROJECT = INT_MAX-1, LONGOPT_WHERE = INT_MAX-2, }; static const struct option long_options[] = { {"all", no_argument, 0, 'a'}, {"brief", no_argument, 0, 's'}, {"catalog", required_argument, 0, 'c'}, {"debug", required_argument, 0, 'd'}, {"debug-file", required_argument, 0, 'o'}, {"debug-rotate-max", required_argument, 0, 'O'}, {"help", no_argument, 0, 'h'}, {"server-lastheardfrom", required_argument, 0, LONGOPT_SERVER_LASTHEARDFROM}, {"server-project", required_argument, 0, LONGOPT_SERVER_PROJECT}, {"server-space", required_argument, 0, 'A'}, {"timeout", required_argument, 0, 't'}, {"totals", no_argument, 0, 'T'}, {"verbose", no_argument, 0, 'l'}, {"version", no_argument, 0, 'v'}, {"where", required_argument, 0, LONGOPT_WHERE }, {0, 0, 0, 0} }; struct catalog_query *q; struct jx *j; time_t timeout = 60, stoptime; const char *catalog_host = 0; int i; int c; int count = 0; int mode = MODE_TABLE; INT64_T sum_total = 0, sum_avail = 0; const char *filter_name = 0; const char *filter_value = 0; const char *where_expr = "true"; int show_all_types = 0; const char *server_project = NULL; time_t server_lastheardfrom = 0; uint64_t server_avail = 0; debug_config(argv[0]); while((c = getopt_long(argc, argv, "aA:c:d:t:o:O:sTlvh", long_options, NULL)) > -1) { switch (c) { case 'a': show_all_types = 1; break; case 'c': catalog_host = optarg; break; case 'd': debug_flags_set(optarg); break; case 't': timeout = string_time_parse(optarg); break; case 'A': server_avail = string_metric_parse(optarg); break; case 'o': debug_config_file(optarg); break; case 'O': debug_config_file_size(string_metric_parse(optarg)); break; case 'v': cctools_version_print(stdout, argv[0]); return 1; case 's': mode = MODE_SHORT; break; case 'l': mode = MODE_LONG; break; case 'T': mode = MODE_TOTAL; break; case LONGOPT_SERVER_LASTHEARDFROM: server_lastheardfrom = time(0)-string_time_parse(optarg); break; case LONGOPT_SERVER_PROJECT: server_project = xxstrdup(optarg); break; case LONGOPT_WHERE: where_expr = optarg; break; case 'h': default: show_help(argv[0]); return 1; } } cctools_version_debug(D_DEBUG, argv[0]); if(argc - optind == 0) { // fine, keep going } else if((argc - optind) == 1) { filter_name = "name"; filter_value = argv[optind]; } else if((argc - optind) == 2) { filter_name = argv[optind]; filter_value = argv[optind + 1]; } else { show_help(argv[0]); return 1; } stoptime = time(0) + timeout; const char *query_expr; if(show_all_types) { query_expr = where_expr; } else { query_expr = string_format("%s && (type==\"chirp\" || type==\"catalog\")",where_expr); } struct jx *jexpr = jx_parse_string(query_expr); if(!jexpr) { fprintf(stderr,"invalid expression: %s\n",query_expr); return 1; } q = catalog_query_create(catalog_host, 0, jexpr, stoptime); if(!q) { fprintf(stderr, "couldn't query catalog: %s\n", strerror(errno)); return 1; } if(mode == MODE_TABLE) { jx_table_print_header(headers,stdout); } else if(mode==MODE_LONG) { printf("[\n"); } while((j = catalog_query_read(q, stoptime))) { table[count++] = j; } catalog_query_delete(q); qsort(table, count, sizeof(*table), (int (*)(const void *, const void *)) compare_entries); for(i = 0; i < count; i++) { const char *lastheardfrom = jx_lookup_string(table[i], "lastheardfrom"); if (lastheardfrom && (time_t)strtoul(lastheardfrom, NULL, 10) < server_lastheardfrom) continue; const char *avail = jx_lookup_string(table[i], "avail"); if (avail && strtoul(avail, NULL, 10) < server_avail) continue; const char *project = jx_lookup_string(table[i], "project"); if (server_project && (project == NULL || !(strcmp(project, server_project) == 0))) continue; if(filter_name) { const char *v = jx_lookup_string(table[i], filter_name); if(!v || strcmp(filter_value, v)) continue; } if(mode == MODE_SHORT) { const char *t = jx_lookup_string(table[i], "type"); if(t && !strcmp(t, "chirp")) { printf("%s:%d\n", jx_lookup_string(table[i], "name"), (int) jx_lookup_integer(table[i], "port")); } } else if(mode == MODE_LONG) { if(i!=0) printf(",\n"); jx_print_stream(table[i],stdout); } else if(mode == MODE_TABLE) { jx_table_print(headers, table[i], stdout); } else if(mode == MODE_TOTAL) { sum_avail += jx_lookup_integer(table[i], "avail"); sum_total += jx_lookup_integer(table[i], "total"); } } for(i=0;i<count;i++) { jx_delete(table[i]); } if(mode == MODE_TOTAL) { printf("NODES: %4d\n", count); printf("TOTAL: %6sB\n", string_metric(sum_total, -1, 0)); printf("AVAIL: %6sB\n", string_metric(sum_avail, -1, 0)); printf("INUSE: %6sB\n", string_metric(sum_total - sum_avail, -1, 0)); } else if(mode == MODE_TABLE) { jx_table_print_footer(headers,stdout); } else if(mode==MODE_LONG) { printf("\n]\n"); } return 0; }