static void do_test_json_send_clients_with_backup(const char *path, struct sd *sd, int s, const char *specific_client) { struct asfd *asfd; struct cstat *c=NULL; struct cstat *clist=NULL; const char *cnames[] = {"cli1", "cli2", "cli3", NULL}; fail_unless(recursive_delete(CLIENTCONFDIR)==0); build_clientconfdir_files(cnames, NULL); fail_unless(!cstat_get_client_names(&clist, CLIENTCONFDIR)); assert_cstat_list(clist, cnames); for(c=clist; c; c=c->next) { c->permitted=1; c->protocol=PROTO_1; fail_unless((c->sdirs=setup_sdirs(c->protocol, c->name))!=NULL); build_storage_dirs((struct sdirs *)c->sdirs, sd, s); fail_unless(!cstat_set_backup_list(c)); fail_unless(c->bu!=NULL); // Hack the cntr timestamps so that they are always the same. c->cntr->ent[(uint8_t)CMD_TIMESTAMP]->count=200; c->cntr->ent[(uint8_t)CMD_TIMESTAMP_END]->count=400; } asfd=asfd_setup(path); c=NULL; if(specific_client) fail_unless((c=cstat_get_by_name(clist, specific_client))!=NULL); fail_unless(!json_send(asfd, clist, c, NULL, NULL, NULL, 0/*cache*/)); cstat_list_free_sdirs(clist); cstat_list_free(&clist); fail_unless(!recursive_delete(SDIRS)); tear_down(&asfd); }
static int input_string(void *ctx, const unsigned char *val, size_t len) { char *str; if(!(str=(char *)malloc_w(len+2, __func__))) return 0; snprintf(str, len+1, "%s", val); if(in_counters) { if(!strcmp(lastkey, "name")) { // Ignore 'name' in a counters object. We use 'type' // instead. } else if(!strcmp(lastkey, "type")) { if(!current) goto error; cntr_ent=current->cntr->ent[(uint8_t)*str]; } else { goto error; } goto end; } else if(!strcmp(lastkey, "name")) { if(cnew) goto error; if(!(current=cstat_get_by_name(*cslist, str))) { if(!(cnew=cstat_alloc()) || cstat_init(cnew, str, NULL)) goto error; current=cnew; } goto end; } else if(!strcmp(lastkey, "run_status")) { if(!current) goto error; current->run_status=run_str_to_status(str); goto end; } else if(!strcmp(lastkey, "phase")) { if(!current) goto error; current->cntr->cntr_status=cntr_str_to_status(str); goto end; } else if(!strcmp(lastkey, "flags")) { if(!current) goto error; if(is_wrap(str, "hardlinked", BU_HARDLINKED) || is_wrap(str, "deletable", BU_DELETABLE) || is_wrap(str, "working", BU_WORKING) || is_wrap(str, "finishing", BU_FINISHING) || is_wrap(str, "current", BU_CURRENT) || is_wrap(str, "manifest", BU_MANIFEST)) goto end; } else if(!strcmp(lastkey, "counters")) // Do we need this? { goto end; } else if(!strcmp(lastkey, "list")) { if(is_wrap(str, "backup", BU_LOG_BACKUP) || is_wrap(str, "restore", BU_LOG_RESTORE) || is_wrap(str, "verify", BU_LOG_VERIFY) || is_wrap(str, "backup_stats", BU_STATS_BACKUP) || is_wrap(str, "restore_stats", BU_STATS_RESTORE) || is_wrap(str, "verify_stats", BU_STATS_VERIFY)) goto end; } else if(!strcmp(lastkey, "logs")) { goto end; } else if(!strcmp(lastkey, "logline")) { goto end; } else if(!strcmp(lastkey, "backup") || !strcmp(lastkey, "restore") || !strcmp(lastkey, "verify") || !strcmp(lastkey, "backup_stats") || !strcmp(lastkey, "restore_stats") || !strcmp(lastkey, "verify_stats")) { // Log file contents. if(lline_add(&ll_list, str)) goto error; goto end; } error: logp("Unexpected string: %s %s\n", lastkey, str); free_w(&str); return 0; end: free_w(&str); return 1; }
static int parse_client_data(struct asfd *srfd, struct cstat *clist, struct conf **confs) { int ret=0; char *command=NULL; char *client=NULL; char *backup=NULL; char *logfile=NULL; char *browse=NULL; const char *cp=NULL; struct cstat *cstat=NULL; struct bu *bu=NULL; //printf("got client data: '%s'\n", srfd->rbuf->buf); cp=srfd->rbuf->buf; // The client monitor will send an initial blank line to kick things // off. Until it is sent, we will not even have entered the code // in this file. So, without it, data from the parent will not have // been read, and the monitor client will be given incomplete // information for its first response. // Just ignore the new line at this point, it has served its purpose. if(srfd->rbuf->len==1 && !strcmp(cp, "\n")) { ret=0; goto end; } command=get_str(&cp, "j:", 0); client=get_str(&cp, "c:", 0); backup=get_str(&cp, "b:", 0); logfile=get_str(&cp, "l:", 0); browse=get_str(&cp, "p:", 1); if(command) { if(!strcmp(command, "pretty-print-on")) { json_set_pretty_print(1); if(json_send_warn(srfd, "Pretty print on")) goto error; } else if(!strcmp(command, "pretty-print-off")) { json_set_pretty_print(0); if(json_send_warn(srfd, "Pretty print off")) goto error; } else { if(json_send_warn(srfd, "Unknown command")) goto error; } goto end; } if(browse) { free_w(&logfile); if(!(logfile=strdup_w("manifest", __func__))) goto error; strip_trailing_slashes(&browse); } //dump_cbno(clist, "pcd"); if(client && *client) { if(!(cstat=cstat_get_by_name(clist, client))) { if(json_send_warn(srfd, "Could not find client")) goto error; goto end; } if(cstat_set_backup_list(cstat)) { if(json_send_warn(srfd, "Could not get backup list")) goto error; goto end; } } if(cstat && backup) { unsigned long bno=0; if(!(bno=strtoul(backup, NULL, 10))) { if(json_send_warn(srfd, "Could not get backup number")) goto error; goto end; } for(bu=cstat->bu; bu; bu=bu->prev) if(bu->bno==bno) break; if(!bu) { if(json_send_warn(srfd, "Backup not found")) goto error; goto end; } } if(logfile) { if(strcmp(logfile, "manifest") && strcmp(logfile, "backup") && strcmp(logfile, "restore") && strcmp(logfile, "verify") && strcmp(logfile, "backup_stats") && strcmp(logfile, "restore_stats") && strcmp(logfile, "verify_stats")) { if(json_send_warn(srfd, "File not supported")) goto error; goto end; } } /* printf("client: %s\n", client?:""); printf("backup: %s\n", backup?:""); printf("logfile: %s\n", logfile?:""); */ if(cstat) { if(!cstat->run_status) cstat_set_run_status(cstat); } else for(cstat=clist; cstat; cstat=cstat->next) { if(!cstat->run_status) cstat_set_run_status(cstat); } if(json_send(srfd, clist, cstat, bu, logfile, browse, get_int(confs[OPT_MONITOR_BROWSE_CACHE]))) goto error; goto end; error: ret=-1; end: free_w(&client); free_w(&backup); free_w(&logfile); free_w(&browse); return ret; }