Esempio n. 1
0
File: recipe.c Progetto: Azizou/smac
struct recipe *recipe_read_from_file(char *filename)
{
  struct recipe *recipe=NULL;

  unsigned char *buffer;

  int fd=open(filename,O_RDONLY);
  if (fd==-1) {
    snprintf(recipe_error,1024,"Could not open recipe file '%s'\n",filename);
    return NULL;
  }

  struct stat stat;
  if (fstat(fd, &stat) == -1) {
    snprintf(recipe_error,1024,"Could not stat recipe file '%s'\n",filename);
    close(fd); return NULL;
  }

  buffer=mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0);
  if (buffer==MAP_FAILED) {
    snprintf(recipe_error,1024,"Could not memory map recipe file '%s'\n",filename);
    close(fd); return NULL; 
  }

  recipe=recipe_read(filename,(char *)buffer,stat.st_size);

  munmap(buffer,stat.st_size);
  close(fd);
  
  if (recipe&&recipe->field_count==0) {
    recipe_free(recipe);
    snprintf(recipe_error,1024,"Recipe contains no field definitions\n");
    return NULL;
  }

  return recipe;
}
Esempio n. 2
0
File: recipe.c Progetto: Azizou/smac
struct recipe *recipe_read(char *formname,char *buffer,int buffer_size)
{
  if (buffer_size<1||buffer_size>1048576) {
    snprintf(recipe_error,1024,"Recipe file empty or too large (>1MB).\n");
    return NULL;
  }

  struct recipe *recipe=calloc(sizeof(struct recipe),1);
  if (!recipe) {
    snprintf(recipe_error,1024,"Allocation of recipe structure failed.\n");
    return NULL;
  }

  // Get recipe hash
  recipe_form_hash(formname,recipe->formhash,recipe->formname);
  LOGI("recipe_read(): Computing formhash based on form name '%s'",formname);
  
  int i;
  int l=0;
  int line_number=1;
  char line[16384];
  char name[16384],type[16384];
  int min,max,precision;
  char enumvalues[16384];

  for(i=0;i<=buffer_size;i++) {
    if (l>16380) { 
      snprintf(recipe_error,1024,"line:%d:Line too long.\n",line_number);
      recipe_free(recipe); return NULL; }
    if ((i==buffer_size)||(buffer[i]=='\n')||(buffer[i]=='\r')) {
      if (recipe->field_count>1000) {
	snprintf(recipe_error,1024,"line:%d:Too many field definitions (must be <=1000).\n",line_number);
	recipe_free(recipe); return NULL;
      }
      // Process recipe line
      line[l]=0; 
      if ((l>0)&&(line[0]!='#')) {
	enumvalues[0]=0;
	if (sscanf(line,"%[^:]:%[^:]:%d:%d:%d:%[^\n]",
		   name,type,&min,&max,&precision,enumvalues)>=5) {
	  int fieldtype=recipe_parse_fieldtype(type);
	  if (fieldtype==-1) {
	    snprintf(recipe_error,1024,"line:%d:Unknown or misspelled field type '%s'.\n",line_number,type);
	    recipe_free(recipe); return NULL;
	  } else {
	    // Store parsed field
	    recipe->fields[recipe->field_count].name=strdup(name);
	    recipe->fields[recipe->field_count].type=fieldtype;
	    recipe->fields[recipe->field_count].minimum=min;
	    recipe->fields[recipe->field_count].maximum=max;
	    recipe->fields[recipe->field_count].precision=precision;

	    if (fieldtype==FIELDTYPE_ENUM||fieldtype==FIELDTYPE_MULTISELECT) {
	      char enum_value[1024];
	      int e=0;
	      int en=0;
	      int i;
	      for(i=0;i<=strlen(enumvalues);i++) {
		if ((enumvalues[i]==',')||(enumvalues[i]==0)) {
		  // End of field
		  enum_value[e]=0;
		  if (en>=MAX_ENUM_VALUES) {
		    snprintf(recipe_error,1024,"line:%d:enum has too many values (max=32)\n",line_number);
		    recipe_free(recipe);
		    return NULL;
		  }
		  recipe->fields[recipe->field_count].enum_values[en]
		    =strdup(enum_value);
		  en++;
		  e=0;
		} else {
		  // next character of field
		  enum_value[e++]=enumvalues[i];
		}
	      }
	      if (en<1) {
		snprintf(recipe_error,1024,"line:%d:Malformed enum field definition: must contain at least one value option.\n",line_number);
		recipe_free(recipe); return NULL;
	      }
	      recipe->fields[recipe->field_count].enum_count=en;
	    }

	    recipe->field_count++;
	  }
	} else {
	  snprintf(recipe_error,1024,"line:%d:Malformed field definition.\n",line_number);
	  recipe_free(recipe); return NULL;
	}
      }
      line_number++; l=0;
    } else {
      line[l++]=buffer[i];
    }
  }
  return recipe;
}
Esempio n. 3
0
File: jni.c Progetto: Azizou/smac
JNIEXPORT jobjectArray JNICALL Java_org_servalproject_succinctdata_jni_xml2succinctfragments
(JNIEnv * env, jobject jobj,
 jstring xmlforminstance,
 jstring xmlformspecification,
 jstring formname,
 jstring formversion,
 jstring succinctpath,
 jstring smacdat,
 jint mtu,
 jint debug)
{
  LOGI("  xml2succinctfragments ENTRY");
  
  const char *xmldata= (*env)->GetStringUTFChars(env,xmlforminstance,0);
  LOGI("  xml2succinctfragments E2");
  const char *formname_c= NULL; // (*env)->GetStringUTFChars(env,formname,0);
  LOGI("  xml2succinctfragments E3");
  const char *formversion_c=  NULL; // (*env)->GetStringUTFChars(env,formversion,0);
  LOGI("  xml2succinctfragments E4");
  const char *path= NULL; // (*env)->GetStringUTFChars(env,succinctpath,0);
  LOGI("  xml2succinctfragments E5");
  const char *xmlform_c= (*env)->GetStringUTFChars(env,xmlformspecification,0);
  LOGI("  xml2succinctfragments E6");
  const char *smacdat_c= (*env)->GetStringUTFChars(env,smacdat,0);
  LOGI("  xml2succinctfragments E7");
  
  char stripped[65536];
  unsigned char succinct[1024];
  int succinct_len=0;
  char filename[1024];

  int magpi_mode=0;

  LOGI("  xml2succinctfragments checkpoing 1");
  
  // Automatically detect Magpi forms versus ODK ones.
  // Magpi forms are HTML documents, where as ODK uses XML ones.
  if (xmlform_c&&(!strncasecmp("<html",xmlform_c,5))) magpi_mode=1;

  // Read public key hex

  LOGI("  xml2succinctfragments checkpoing 2: magpi_mode = %d",magpi_mode);
  
  // Default to public key of Serval succinct data server
  char publickeyhex[1024]="74f3a36029b0e60084d42bd9cafa3f2b26fe802b0a6f024ff00451481c9bba4a";

  if (path&&formname_c&&formversion_c)
  {
    LOGI("recipe: Expecting public key file");
    snprintf(filename,1024,"%s/%s.%s.publickey",path,formname_c,formversion_c);
    LOGI("recipe: Opening recipient public key file %s",filename);

    FILE *f=fopen(filename,"r");
    if (f) {
      int r=fread(publickeyhex,1,1023,f);
      if (r<64) {
	char message[1024];
	snprintf(message,1024,"Failed to read from public key file");
	return error_message(env,message);
	LOGI("recipe: failed to load publickeyhex from file (using default value)");
      }
      publickeyhex[r]=0;
    }

    // Trim CR/LF from end
    if (publickeyhex[0]) {
      while(publickeyhex[strlen(publickeyhex)-1]<' ')
	publickeyhex[strlen(publickeyhex)-1]=0;
    }
    
    fclose(f);
  }
  
  LOGI("recipe: have publixkeyhex = '%s'",publickeyhex);

  struct recipe *recipe=NULL;
  
  if (xmlformspecification==NULL||xmlform_c==NULL||!strlen(xmlform_c)) {
    // Read recipe file
    snprintf(filename,1024,"%s/%s.%s.recipe",path,formname_c,formversion_c);
    LOGI("Opening recipe file %s",filename);
    recipe=recipe_read_from_file(filename);
    if (!recipe) {
      char message[1024];
      snprintf(message,1024,"Could not read recipe file %s",filename);
      return error_message(env,message);
    }    
  } else {
    // Create recipe from form specification
    char recipetext[65536];
    int recipetextLen=65536;
    char templatetext[65536];
    int templatetextLen=65536;

    char the_form_name[1024];
    char the_form_version[1024];

    LOGI("Using form specification to create recipe on the fly (magpi_mode=%d, form spec = %d bytes)",
	 magpi_mode,strlen(xmlform_c));

    LOGI("Form specification is: %s",xmlform_c);
    
    int r;
    if (magpi_mode) {
      r=xhtmlToRecipe(xmlform_c,strlen(xmlform_c),
		      the_form_name,the_form_version,
		      recipetext,&recipetextLen,
		      templatetext,&templatetextLen);
      // Magpi forms are identified solely by the numeric formid
      strcpy(the_form_name,the_form_version);
      strcpy(the_form_version,"this should not be used");
    }
    else
      r=xmlToRecipe(xmlform_c,strlen(xmlform_c),
		      the_form_name,the_form_version,
		      recipetext,&recipetextLen,
		      templatetext,&templatetextLen);
    if (r) {
      return error_message(env,"Could not create recipe from form specification");
    }

    LOGI("Have %d bytes of recipe text (name='%s', version='%s')",
	 recipetextLen,the_form_name,the_form_version);
    if (recipetextLen<10) return error_message(env,"Could not convert form specification to recipe");

    
    formname_c=form_name; formversion_c=form_version;
    recipe = recipe_read(the_form_name,recipetext,recipetextLen);    
    if (!recipe) {
      char message[1024];
      snprintf(message,1024,"Could not set recipe");
      LOGI("Failed to read recipe from buffer");
      LOGI("Recipe is:\n%s",recipetext);
      return error_message(env,message);
    }

    LOGI("Read recipe from buffer (%d bytes). Hash = %02x%02x%02x%02x%02x%02x",
	 recipetextLen,
	 recipe->formhash[0],recipe->formhash[1],recipe->formhash[2],
	 recipe->formhash[3],recipe->formhash[4],recipe->formhash[5]
	 );
    LOGI("Recipe is:\n%s\n",recipetext);
  }

  LOGI("About to run xml2stripped");
  
  // Transform XML to stripped data first.
  int stripped_len;

  stripped_len = xml2stripped(formname_c,xmldata,strlen(xmldata),stripped,sizeof(stripped));

  LOGI("Stripped data is %d bytes long",stripped_len);
  
  if (stripped_len>0) {
    // Produce succinct data

    LOGI("About to read stats file %s",smacdat_c);

    // Get stats handle
    stats_handle *h=stats_new_handle(smacdat_c);

    stats_load_tree(h);
    LOGI("Loaded entire stats tree");
    
    if (!h) {
      recipe_free(recipe);
      char message[1024];
      snprintf(message,1024,"Could not read SMAC stats file %s",smacdat_c);
      return error_message(env,message);
    }

    LOGI("Read stats, now about to call recipe_compresS()");

    // Compress stripped data to form succinct data
    succinct_len=recipe_compress(h,recipe,stripped,stripped_len,succinct,sizeof(succinct));

    LOGI("Binary succinct data is %d bytes long",succinct_len);

    // Clean up after ourselves
    stats_handle_free(h);
    recipe_free(recipe);
    char filename[1024];
    snprintf(filename,1024,"%s/%s.%s.recipe",path,formname_c,formversion_c);

    LOGI("Cleaned up after ourselves");

    if (succinct_len<1) {
      LOGI("Failed to compress XML - reporting error and exiting");
      char message[1024];
      snprintf(message,1024,"recipe_compess failed with recipe file %s. stripped_len=%d",filename,stripped_len);
      LOGI("Exiting due to failure to produce valid Succinct Data output.");
      return error_message(env,message);
    }
  } else {
    LOGI("Failed to strop XML using recipe file -- exiting.");
    recipe_free(recipe);
    char message[1024];
    snprintf(message,1024,"Failed to strip XML using recipe file %s.",filename);
    return error_message(env,message);
  }

  LOGI("Fragmenting succinct data record");
  char *fragments[MAX_FRAGMENTS];
  int fragment_count=0;
  encryptAndFragmentBuffer(succinct,succinct_len,fragments,&fragment_count,mtu,
			   publickeyhex,debug);

  LOGI("Succinct data formed into %d fragments",fragment_count);
  
  jobjectArray result=
    (jobjectArray)(*env)->NewObjectArray(env,fragment_count,
				      (*env)->FindClass(env,"java/lang/String"),
         (*env)->NewStringUTF(env,""));
  for(int i=0;i<fragment_count;i++) {
    (*env)->SetObjectArrayElement(env,result,i,(*env)->NewStringUTF(env,fragments[i]));
    free(fragments[i]);
  }
    
  return result;  
}
Esempio n. 4
0
int backup(Jcr* jcr) {

	fingerchunk_queue = sync_queue_new(-1);
	ContainerUsageMonitor* usage_monitor = container_usage_monitor_new();
	cfl_monitor = cfl_monitor_new(read_cache_size);

	if (simulation_level == SIMULATION_ALL) {
		start_read_trace_phase(jcr);
	} else {
		start_read_phase(jcr);
		start_chunk_phase(jcr);
		start_hash_phase(jcr);
	}
	start_segment_phase(jcr);
	start_filter_phase(jcr);
	start_append_phase(jcr);

	ContainerId seed_id = -1;
	int32_t seed_len = 0;
	FingerChunk* fchunk = NULL;
	int signal = recv_fingerchunk(&fchunk);
	while (signal != STREAM_END) {
		container_usage_monitor_update(usage_monitor, fchunk->container_id,
				&fchunk->fingerprint, fchunk->length);
		jvol_append_fingerchunk(jcr->job_volume, fchunk);

		if (seed_id != -1 && seed_id != fchunk->container_id) {
			jvol_append_seed(jcr->job_volume, seed_id, seed_len);
			seed_len = 0;
		}
		/* merge sequential accesses */
		seed_id = fchunk->container_id;
		seed_len += fchunk->length;

		free(fchunk);
		signal = recv_fingerchunk(&fchunk);
	}

	if (seed_len > 0)
		jvol_append_seed(jcr->job_volume, seed_id, seed_len);
	sync_queue_free(fingerchunk_queue, NULL);

	jcr->sparse_container_num = g_hash_table_size(usage_monitor->sparse_map);
	jcr->total_container_num = g_hash_table_size(usage_monitor->dense_map)
			+ jcr->sparse_container_num;

	while ((jcr->inherited_sparse_num = container_usage_monitor_print(
			usage_monitor, jcr->job_id, jcr->historical_sparse_containers)) < 0) {
		dprint("retry!");
	}

	/* store recipes of processed file */
	int i = 0;
	for (; i < jcr->file_num; ++i) {
		Recipe *recipe = (Recipe*) sync_queue_pop(jcr->completed_files_queue);
		recipe->fileindex = i;
		if (jvol_append_meta(jcr->job_volume, recipe) != SUCCESS) {
			printf("%s, %d: some errors happened in appending recipe!\n",
			__FILE__, __LINE__);
			return FAILURE;
		}
		jcr->chunk_num += recipe->chunknum;
		recipe_free(recipe);
	}

	stop_append_phase();
	stop_filter_phase();
	stop_segment_phase();
	if (simulation_level == SIMULATION_ALL) {
		stop_read_trace_phase(jcr);
	} else {
		stop_hash_phase();
		stop_chunk_phase();
		stop_read_phase();
	}

	container_usage_monitor_free(usage_monitor);
	print_cfl(cfl_monitor);
	cfl_monitor_free(cfl_monitor);

	return 0;
}
Esempio n. 5
0
void backup_formal(int fd,char *msg){
	JCR *jcr=NULL;
	char fileset[256]={0};
	char *buf=(char *)calloc(1,SOCKET_BUF_SIZE+21);
	int len;

	int index=1;
	char vol_name[FILE_NAME_LEN];
	int vol_fd;
	Recipe *rp=NULL;
	FingerChunk *fc=NULL;
	char *p=NULL;
	int64_t rwlen=0;
	
	jobcount_init();
	jcr=jcr_new();
	jcr->dataSocket=fd;

	memset(vol_name,0,FILE_NAME_LEN);
	strcpy(vol_name,BackupVolPath);
	strcat(vol_name,"data_vol");
	vol_fd=open(vol_name,O_RDWR| O_CREAT,00644);
	if(vol_fd<0){
		err_msg1("can't open file");
		goto FAIL;
	}
	printf("%s %d vol_name:%s\n",__FILE__,__LINE__,vol_name);
        rwlen=lseek(vol_fd,0,SEEK_END);
	
	TIMER_DECLARE(gstart,gend);
	TIMER_DECLARE(wstart,wend);
	
	TIMER_START(gstart);
	if(sscanf(msg,backup_cmd,fileset)!=1){ // backup cmd
		goto FAIL;
	}
	jcr->jobv=jobv_new(fileset);
	jcr->nJobId=jcr->jobv->nJobId;
	
	printf("===========backup start==============\n");
	printf("%s,%d pathname:%s \n", __FILE__,__LINE__,fileset);

	
	while(bnet_recv(jcr->dataSocket,buf,&len)!=ERROR){ //文件名
		if(len==STREAM_END){
			printf("%s %d backup is over\n",__FILE__,__LINE__);
			break;
		}
		
		//printf("\033[40;32m recv file: %s (%d) \033[0m\n",buf,len);
		rp=recipe_new();
		memcpy(rp->filename,buf,len);
		rp->fileindex=index++;	
		
		while(bnet_recv(jcr->dataSocket,buf,&len)>0){ /*format: fingerprintf data data dta..*/
					//printf("\033[40;32m recv: file data (%d) \033[0m\n",len);	
			fc=fingerchunk_new(buf,0);
			fc->offset=rwlen;
			fc->length=len-sizeof(Fingerprint);

			check_data(fc->fingerprint,buf+sizeof(Fingerprint),fc->length);
					
			TIMER_START(wstart);
			 if(writen(vol_fd,buf+sizeof(Fingerprint),fc->length)!=fc->length)
					err_msg1("wrintn wrong");		 
			TIMER_END(wend);
			TIMER_DIFF(jcr->writeDataTime,wstart,wend);
			
			rwlen+=fc->length;		
			jcr->nChunkCount++;
			jcr->nSize+=fc->length;
			recipe_append_fingerchunk(rp,fc);
		}
				
		jcr->nFileCount++;
		if(G_VERBOSE)
			printf("receive file %s OK, total: %d\n",rp->filename,jcr->nFileCount);
		jobv_insert_recipe(jcr->jobv, rp);
		rp=NULL;	
	}
FAIL:	
	bnet_send(fd,"OK",2);  // 发送备份成功信息
	
	TIMER_END(gend);
	TIMER_DIFF(jcr->recvTime,gstart,gend);
	
	
	printf("============back over===============\n");
	printf("total time:%.4f   %.4f MB/s\n",jcr->recvTime,jcr->nSize*1.0/jcr->recvTime/1036288.0);
	printf("write time:%.4f  %.4f MB/s\n",jcr->writeDataTime,jcr->nSize*1.0/jcr->writeDataTime/1036288.0);
	printf("chunk count:%d\n",jcr->nChunkCount);
	printf("file count:%d\n",jcr->nFileCount);
	
	if(rp){
		recipe_free(rp);
	}
	
	jobv_destroy(jcr->jobv);
	jcr_free(jcr);
	jobcount_close();
	
	close(vol_fd);
}
Esempio n. 6
0
void restore_formal(int fd,char *msg){
		JCR *jcr=NULL;
		Recipe *rp=NULL;
		FingerChunk *fc=NULL;
		char *buf=(char *)calloc(1,SOCKET_BUF_SIZE+21);
		char vol_name[FILE_NAME_LEN];
		int vol_fd;
		//char stream[30]={0};
		
		memset(vol_name,0,FILE_NAME_LEN);
		strcpy(vol_name,BackupVolPath);
		strcat(vol_name,"data_vol");
		vol_fd=open(vol_name,O_RDWR| O_CREAT,00644);

		jcr=jcr_new();
		jcr->dataSocket=fd;

		if(vol_fd<0){
			err_msg1("can't open file");
			goto FAIL;

		}
		
		if(sscanf(msg,restore_cmd,&jcr->nJobId)!=1){ // backup cmd
			goto FAIL;
		}
		jcr->jobv=jobv_open(jcr->nJobId);

		if(jcr->jobv==NULL){
			goto FAIL;
		}

		printf("%s,%d restore jobid:%d \n", __FILE__,__LINE__,jcr->nJobId);

		// send pathname
		bnet_send(fd,jcr->jobv->szBackupPath,strlen(jcr->jobv->szBackupPath));
		
		
		while((rp=jobv_search_next_recipe(jcr->jobv))){

			//send file name
		
			if(G_VERBOSE)
			  	printf("send file %s \n",rp->filename);
			bnet_send(fd,rp->filename,strlen(rp->filename));
			
			//send data
			
			for(fc=rp->first;fc;fc=fc->next){
				lseek(vol_fd,fc->offset,SEEK_SET);
				if(readn(vol_fd,buf,fc->length)!=fc->length)
					err_msg1("readn wrong");
				check_data(fc->fingerprint,buf,fc->length);
				bnet_send(fd,buf,fc->length);
			}
			bnet_signal(fd,DATA_END);

			recipe_free(rp);
		}
	FAIL:
		bnet_signal(fd,STREAM_END); /* over */
		jobv_destroy(jcr->jobv);
		jcr_free(jcr);
		
}