static int compat_checkpoint_read( struct jx_database *db, const char *filename ) { FILE * file = fopen(filename,"r"); if(!file) return 0; while(1) { struct nvpair *nv = nvpair_create(); if(nvpair_parse_stream(nv,file)) { const char *key = nvpair_lookup_string(nv,"key"); if(key) { nvpair_delete(hash_table_remove(db->table,key)); struct jx *j = nvpair_to_jx(nv); hash_table_insert(db->table,key,j); } nvpair_delete(nv); } else { nvpair_delete(nv); break; } } fclose(file); return 1; }
static int compat_checkpoint_read( struct deltadb *db, const char *filename ) { FILE * file = fopen(filename,"r"); if(!file) return 0; while(1) { struct nvpair *nv = nvpair_create(); if(nvpair_parse_stream(nv,file)) { const char *key = nvpair_lookup_string(nv,"key"); if(key) { nvpair_delete(hash_table_remove(db->table,key)); struct jx *j = nvpair_to_jx(nv); /* skip objects that don't match the filter */ if(deltadb_boolean_expr(db->filter_expr,j)) { hash_table_insert(db->table,key,j); } else { jx_delete(j); } } nvpair_delete(nv); } else { nvpair_delete(nv); break; } } fclose(file); return 1; }
int main( int argc, char *argv[] ) { int count =0; int first = 0; printf("{\n"); while(1) { struct nvpair *nv = nvpair_create(); int r = nvpair_parse_stream(nv,stdin); if(r) { struct jx *j = nvpair_to_jx(nv); const char *name = jx_lookup_string(j,"name"); const char *host = jx_lookup_string(j,"host"); int port = jx_lookup_integer(j,"port"); if(first) { first = 0; } else { printf(",\n"); } printf("\"%s:%s:%d\":",name,host,port); jx_print_stream(j,stdout); count++; } else if(r<0) { fprintf(stderr,"nvpair conversion error!\n"); } else { break; } } printf("\n}\n"); fprintf(stderr,"%d records converted.\n",count); return 0; }
static int log_replay( struct jx_database *db, const char *filename, time_t snapshot) { char line[LOG_LINE_MAX]; char value[LOG_LINE_MAX]; char name[LOG_LINE_MAX]; char key[LOG_LINE_MAX]; int n; struct jx *jvalue, *jobject; long long current = 0; FILE *file = fopen(filename,"r"); if(!file) return 0; while(fgets(line,sizeof(line),file)) { if(line[0]=='C') { n = sscanf(line,"C %s %[^\n]",key,value); if(n==1) { struct nvpair *nv = nvpair_create(); nvpair_parse_stream(nv,file); jvalue = nvpair_to_jx(nv); hash_table_insert(db->table,key,jvalue); } else if(n==2) { jvalue = jx_parse_string(value); if(jvalue) { hash_table_insert(db->table,key,jvalue); } else { corrupt_data(filename,line); } } else { corrupt_data(filename,line); continue; } } else if(line[0]=='D') { n = sscanf(line,"D %s\n",key); if(n!=1) { corrupt_data(filename,line); continue; } jx_delete(hash_table_remove(db->table,key)); } else if(line[0]=='U') { n=sscanf(line,"U %s %s %[^\n],",key,name,value); if(n!=3) { corrupt_data(filename,line); continue; } jobject = hash_table_lookup(db->table,key); if(!jobject) { corrupt_data(filename,line); continue; } jvalue = jx_parse_string(value); if(!jvalue) jvalue = jx_string(value); struct jx *jname = jx_string(name); jx_delete(jx_remove(jobject,jname)); jx_insert(jobject,jname,jvalue); } else if(line[0]=='R') { n=sscanf(line,"R %s %s",key,name); if(n!=2) { corrupt_data(filename,line); continue; } jobject = hash_table_lookup(db->table,key); if(!jobject) { corrupt_data(filename,line); continue; } struct jx *jname = jx_string(name); jx_delete(jx_remove(jobject,jname)); jx_delete(jname); } else if(line[0]=='T') { n = sscanf(line,"T %lld",¤t); if(n!=1) { corrupt_data(filename,line); continue; } if(current>snapshot) break; } else if(line[0]=='\n') { continue; } else { corrupt_data(filename,line); } } fclose(file); return 1; }
static void handle_update( const char *addr, int port, const char *raw_data, int raw_data_length, const char *protocol ) { char key[LINE_MAX]; unsigned long data_length; struct jx *j; // If the packet starts with Control-Z (0x1A), it is compressed, // so uncompress it to data[]. Otherwise just copy to data[];. if(raw_data[0]==0x1A) { data_length = sizeof(data); int success = uncompress((Bytef*)data,&data_length,(const Bytef*)&raw_data[1],raw_data_length-1); if(success!=Z_OK) { debug(D_DEBUG,"warning: %s:%d sent invalid compressed data (ignoring it)\n",addr,port); return; } } else { memcpy(data,raw_data,raw_data_length); data_length = raw_data_length; } // Make sure the string data is null terminated. data[data_length] = 0; // Once uncompressed, if it starts with a bracket, // then it is JX/JSON, otherwise it is the legacy nvpair format. if(data[0]=='{') { j = jx_parse_string(data); if(!j) { debug(D_DEBUG,"warning: %s:%d sent invalid JSON data (ignoring it)\n%s\n",addr,port,data); return; } if(!jx_is_constant(j)) { debug(D_DEBUG,"warning: %s:%d sent non-constant JX data (ignoring it)\n%s\n",addr,port,data); jx_delete(j); return; } } else { struct nvpair *nv = nvpair_create(); if(!nv) return; nvpair_parse(nv, data); j = nvpair_to_jx(nv); nvpair_delete(nv); } jx_insert_string(j, "address", addr); jx_insert_integer(j, "lastheardfrom", time(0)); /* If the server reports unbelievable numbers, simply reset them */ if(max_server_size > 0) { INT64_T total = jx_lookup_integer(j, "total"); INT64_T avail = jx_lookup_integer(j, "avail"); if(total > max_server_size || avail > max_server_size) { jx_insert_integer(j, "total", max_server_size); jx_insert_integer(j, "avail", max_server_size); } } /* Do not believe the server's reported name, just resolve it backwards. */ char name[DOMAIN_NAME_MAX]; if(domain_name_cache_lookup_reverse(addr, name)) { /* Special case: Prior bug resulted in multiple name entries in logged data. When removing the name property, keep looking until all items are removed. */ struct jx *jname = jx_string("name"); struct jx *n; while((n=jx_remove(j,jname))) { jx_delete(n); } jx_delete(jname); jx_insert_string(j,"name",name); } else if (jx_lookup_string(j, "name") == NULL) { /* If rDNS is unsuccessful, then we use the name reported if given. * This allows for hostnames that are only valid in the subnet of * the reporting server. Here we set the "name" field to the IP * Address, addr, because it was not set by the reporting server. */ jx_insert_string(j, "name", addr); } make_hash_key(j, key); if(logfile) { if(!jx_database_lookup(table,key)) { jx_print_stream(j,logfile); fprintf(logfile,"\n"); fflush(logfile); } } jx_database_insert(table, key, j); debug(D_DEBUG, "received %s update from %s",protocol,key); }