main(int argc, char **argv)
{
  int i, j, k, *vdm, *inv, *prod, cache_size;
  int rows, cols, blocksize, orig_size;
  int n, m, sz, *factors, tmp, factor, *exists, *map;
  char *stem, *filename,*file_name; 
  char **buffer, *buf_file, *block;
  struct stat buf;
  Condensed_Matrix *cm;
  int *mat, *id;
  FILE *f;

  if (argc != 3) /*modified by supriya*/{ 
    fprintf(stderr, "usage: rs_decode_file stem file_name\n");
    exit(1);
  }
  
  file_name=argv[2];/*added by supriya*/

  stem = argv[1];
  buf_file = (char *) malloc(sizeof(char)*(strlen(stem)+30));
  if (buf_file == NULL) { perror("malloc - buf_file"); exit(1); }
  sprintf(buf_file, "%s-info.txt", stem, i);
  f = fopen(buf_file, "r");
  if (f == NULL) { perror(buf_file); exit(1); }
  if (fscanf(f, "%d\n", &orig_size) != 1) { fprintf(stderr, "Error reading info file 1\n"); exit(1); }
  if (fscanf(f, "%d\n", &sz) != 1) { fprintf(stderr, "Error reading info file 2\n"); exit(1); }
  if (fscanf(f, "%d\n", &blocksize) != 1) { fprintf(stderr, "Error reading info file 3\n"); exit(1); }
  if (fscanf(f, "%d\n", &n) != 1) { fprintf(stderr, "Error reading info file 4\n"); exit(1); }
  if (fscanf(f, "%d\n", &m) != 1) { fprintf(stderr, "Error reading info file 5\n"); exit(1); }
  vdm = gf_read_matrix(f, &rows, &cols);
  if (vdm == NULL) { fprintf(stderr, "Error reading info file matrix\n"); exit(1); }
  fclose(f);
  
  if (rows != n+m) {
    fprintf(stderr, "Error in %s - rows != n+m\n", buf_file);
    exit(1);
  }
  if (cols != n) {
    fprintf(stderr, "Error in %s - cols != n\n", buf_file);
    exit(1);
  }

  exists = (int *) malloc(sizeof(int) * rows);
  if (exists == NULL) { perror("malloc - exists"); exit(1); }
  factors = (int *) malloc(sizeof(int) * rows);
  if (factors == NULL) { perror("malloc - factors"); exit(1); }
  map = (int *) malloc(sizeof(int) * rows);
  if (map == NULL) { perror("malloc - map"); exit(1); }

  buffer = (char **) malloc(sizeof(char *)*n);
  for (i = 0; i < n; i++) {
    buffer[i] = (char *) malloc(blocksize);
    if (buffer[i] == NULL) {
      perror("Allocating buffer to store the whole file");
      exit(1);
    }
  }

	/* Added by : Supriya */
	/*Socket program in order to fetch all the encoded files from different nodes*/

	
	int clientsocket;/* Socket descriptor for client */
	int enable=1,num=n,flag=0,p=0,pos,port=7855; 
	char file[40]="",stem_filename[40]="",ip_addr[40]="",ack[10];
	char sup[1024]="",c,line[100]="",search_string[30]="";
	int bytes_received,y;
	strcpy(search_string,file_name);
	//printf("\n%s***",search_string);
	struct sockaddr_in serverAddr;/* client address */
	socklen_t addr_size;
	
	
	/*opening the master to file*/
	FILE *fp;
	fp=fopen("Master_file.txt","r");
	
	if(!fp)
            {
                    perror("\ncould not find the file");
                    exit(0);
            }
	while ( c!= EOF )/* read a line */
           {
		c=fscanf( fp, "%s",line ) ;
		//printf("%s\n",line);

                    if(strstr(line,search_string)){
			p=1;
			break;	
			
			}
            }
		//printf("ssss");
		pos=ftell(fp);
		//printf("%d\n",n);
		pos=pos-strlen(search_string);
		fseek( fp, pos, SEEK_SET );
		if(p!=1){
			perror("\nNo such File exists");
			exit(0);
		}
		//printf("%d\n",fseek( fp, n, SEEK_SET ));
		//c=fscanf( fp, "%s",line ) ;
		//printf("%s\n",line);

	

	printf("%d\n",num);
	while(num>0)
	{
	strcpy(sup,"");
	/*reading the master file to get the ip address of different nodes*/
	fscanf(fp,"%s",file);
	fscanf(fp,"%s",stem_filename);
	fscanf(fp,"%s",ip_addr);
	//fscanf(fp,"%s",port);
	//printf("%s...%s\n",file,stem_filename);

	/* Create socket for connections */
	clientsocket=socket(PF_INET,SOCK_STREAM,0);
	printf("\n\nSocket creation: %s\n",strerror(errno));

	//printf("%d\n",clientsocket);
	port=port+1;
	num=num-1;

	
	/* Construct local address structure */
	serverAddr.sin_family=AF_INET; /* Internet address family */
	serverAddr.sin_port = htons(port);/*server port*/
	serverAddr.sin_addr.s_addr=inet_addr(ip_addr);/*server address*/
	memset(serverAddr.sin_zero,'\0',sizeof serverAddr.sin_zero);/* Zero out structure */ 

	
	
	printf("Before connect\n");
	/*reuse the same port*/
	if (setsockopt(clientsocket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
    		error("setsockopt(SO_REUSEADDR) failed");

	/*connect to the nodes to receive the encoded files*/
	connect(clientsocket,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
		printf("Connection: %s\n",strerror(errno));
	    //printf("Connected to the node with ip address : %s\n",ip_addr);

	
	printf("After connect\n");

	send(clientsocket,"Decode",7,0);
	bytes_received=recv(clientsocket,ack,sizeof(ack),0);

	send(clientsocket,stem_filename,strlen(stem_filename),0);
	bytes_received=recv(clientsocket,sup,sizeof(sup),0);

	sup[bytes_received]='\0';
	printf("**************");

	/*checking if the file has been received or not */
	if(strcmp(sup,"File does not exist")!=0){

		/*write the received content into file*/
	
		FILE *ft;
		ft=fopen(stem_filename,"w");
		
		//flag = fwrite(sup, sizeof(char), bytes_received, f);
		printf("content: %s\n",sup);
		fprintf(ft,"%s",sup);
		flag++;
		fclose(ft);

		
	}
	else{
		printf("%s \n",sup);		
         }

		//printf("%d\t%d\n",num,port);
	}	
	fclose(fp);
	

//fflush(stdin);
	if(flag<n){
	   fprintf(stderr, "Only %d fragments -- need %d.  Sorry\n", flag, n);
   	   exit(1);
	}
/*end of socket program*/


  j = 0;
  for (i = 0; i < rows && j < cols; i++) {
    sprintf(buf_file, "%s-%04d.rs", stem, i);
    if (stat(buf_file, &buf) != 0) {
      map[i] = -1;
    } else {
      if (buf.st_size != blocksize) {
        map[i] = -1;
      } else {
        map[i] = j++;
        f = fopen(buf_file, "r");
        if (f == NULL) { perror(buf_file); exit(1); }
        k = fread(buffer[map[i]], 1, blocksize, f);
        if (k != blocksize) {
          fprintf(stderr, "%s -- stat says %d bytes, but only read %d\n", 
             buf_file, buf.st_size, k);
          exit(1);
        }
      }
    }
  }
 
printf("\n********************");

  /*if (j < cols) {
    fprintf(stderr, "Only %d fragments -- need %d.  Sorry\n", j, cols);
    exit(1);
  }*/
  
  j = 0;
  for (i = 0; i < cols; i++) if (map[i] == -1) j++;
  fprintf(stderr, "Blocks to decode: %d\n", j);
  if (j == 0) {
    cache_size = orig_size;
    for (i = 0; i < cols; i++) {
      if (cache_size > 0) {
        fwrite(buffer[i], 1, (cache_size > blocksize) ? blocksize : cache_size, stdout);
        cache_size -= blocksize;
      }
    }
    exit(0);
  } 

  block = (char *) malloc(sizeof(char)*blocksize);
  if (block == NULL) { perror("malloc - block"); exit(1); }
  
  for (i = 0; i < rows; i++) exists[i] = (map[i] != -1);
  cm = gf_condense_dispersal_matrix(vdm, exists, rows, cols);
  mat = cm->condensed_matrix;
  id = cm->row_identities;
  /* Fix it so that map[i] for i = 0 to cols-1 is defined correctly.
     map[i] is the index of buffer[] that holds the blocks for row i in 
     the condensed matrix */

  for (i = 0; i < cols; i++) {
    if (map[i] == -1) map[i] = map[id[i]];
  }

  fprintf(stderr, "Inverting condensed dispersal matrix ... "); fflush(stderr);
  inv = gf_invert_matrix(mat, cols);
  if (inv == NULL) {
    fprintf(stderr, "\n\nError -- matrix unvertible\n");
    exit(1);
  }
  fprintf(stderr, "Done\n"); fflush(stderr);
  
  fprintf(stderr, "\nCondensed matrix:\n\n");
  gf_fprint_matrix(stderr, mat, cols, cols);

  fprintf(stderr, "\nInverted matrix:\n\n");
  gf_fprint_matrix(stderr, inv, cols, cols);

  for(i = 0; i < rows; i++) factors[i] = 1;

  cache_size = orig_size;
  for (i = 0; i < cols && cache_size > 0; i++) {
    if (id[i] < cols) {
      fprintf(stderr, "Writing block %d from memory ... ", i); fflush(stderr);
      if (factors[i] != 1) {
        tmp = gf_single_divide(1, factors[i]);
/*        fprintf(stderr, "Factor = %3d.  Tmp = %3d.  Before[0] = %3d.  ",
                factors[i], tmp, (unsigned char) buffer[map[i]][0]); */
        factors[i] = 1;
        gf_mult_region(buffer[map[i]], blocksize, tmp);
/*        fprintf(stderr, "After[0] = %3d.\n", (unsigned char) buffer[map[i]][0]); */
      } else {
/*        fprintf(stderr, "Factor = %3d.  Buffer[0] = %3d.\b", factors[i], 
             (unsigned char) buffer[map[i]][0]); */
      }
      fwrite(buffer[map[i]], 1, (cache_size > blocksize) ? blocksize : cache_size, stdout);
      cache_size -= blocksize;
      fprintf(stderr, "Done\n"); fflush(stderr);
    } else {
      fprintf(stderr, "Decoding block %d ... ", i); fflush(stderr);
      memset(block, 0, blocksize);
      for (j = 0; j < cols; j++) {
        tmp = inv[i*cols+j];
        factor = gf_single_divide(tmp, factors[j]);
/*        fprintf(stderr, "Factors[%d] = %3d.  Tmp = %3d.  Factor = %3d\n    Before[j][0] = %3d.  ", 
                j, factors[j], tmp, factor, (unsigned char) buffer[map[j]][0]); */
        factors[j] = tmp;
        gf_mult_region(buffer[map[j]], blocksize, factor);
/*        fprintf(stderr, "After[j][0] = %3d.  ", (unsigned char) buffer[map[j]][0]);
        fprintf(stderr, "Before-block[0] = %3d.  ", (unsigned char) block[0]); */
        gf_add_parity(buffer[map[j]], block, blocksize);
/*        fprintf(stderr, "After-block[0] = %3d.\n", (unsigned char) block[0]); */
      }
      fprintf(stderr, "writing ... "); fflush(stderr);
      fwrite(block, 1, (cache_size > blocksize) ? blocksize : cache_size, stdout);
      cache_size -= blocksize;
      fprintf(stderr, "Done\n"); fflush(stderr);
    }
  }
}
main(int argc, char **argv)
{
  int i, j, *vdm, *inv, *prod, cache_size;
  int rows, cols, blocksize, orig_size;
  int n, m, sz, *factors, tmp, factor;
  char *stem, *filename,*ip_addr; 
  char **buffer, *buf_file, *block;
  struct stat buf;
  FILE *f;

  if (argc != 5) {
    fprintf(stderr, "usage: rs_encode_file filename n m server_ip_addr\n");
    exit(1);
  }
  
  n = atoi(argv[2]);
  m = atoi(argv[3]);
  stem=argv[1];
  filename = argv[1];
  ip_addr=argv[4];
  //strcpy(*stem,*filename);/*modified*/

  //Author : Supriya
  char files[40]="",file_name_tmp[40]="";
  strcat(files,"ls ");
  strcat(files,stem);
  strcpy(file_name_tmp,filename);
  
  /*ends*/


  rows = n+m;
  cols = n;

  if (stat(filename, &buf) != 0) {
    perror(filename);
    exit(1);
  }

  sz = buf.st_size;
  orig_size = buf.st_size;
  if (sz % (n*sizeof(unit)) != 0) {
    sz += (n*sizeof(unit) - (sz % (n*sizeof(unit))));
  }
  blocksize = sz/n;

  buffer = (char **) malloc(sizeof(char *)*n);
  for (i = 0; i < n; i++) {
    buffer[i] = (char *) malloc(blocksize);
    if (buffer[i] == NULL) {
      perror("Allocating buffer to store the whole file");
      exit(1);
    }
  }


	

  f = fopen(filename, "r");
  if (f == NULL) { perror(filename); }
  cache_size = orig_size;

  for (i = 0; i < n; i++) {
    if (cache_size < blocksize) memset(buffer[i], 0, blocksize);
    if (cache_size > 0) {
      if (fread(buffer[i], 1, (cache_size > blocksize) ? blocksize : cache_size, f) <= 0) {
        fprintf(stderr, "Couldn't read the right bytes into the buffer\n");
        exit(1);
      }
    }
    cache_size -= blocksize;
  }
  fclose(f);

  buf_file = (char *) malloc(sizeof(char)*(strlen(stem)+30));
  if (buf_file == NULL) { perror("malloc - buf_file"); exit(1); }
  block = (char *) malloc(sizeof(char)*blocksize);
  if (block == NULL) { perror("malloc - block"); exit(1); }
  for (i = 0; i < n; i++) {
    sprintf(buf_file, "%s-%04d.rs", stem, i);
    printf("Writing %s ...", buf_file); fflush(stdout);
    f = fopen(buf_file, "w");
    if (f == NULL) { perror(buf_file); exit(1); }
    fwrite(buffer[i], 1, blocksize, f);
    fclose(f);
    printf(" Done\n");
  }

	// Added by : supriya 
	
	/*collect the fragments name in tmp.txt*/  
  	strcat(files,"-* >tmp.txt");
  	//printf("\n%s....",files);
 	system(files);
	char tmp_filename[]="tmp.txt";
	
	/*ends*/

	
  factors = (int *) malloc(sizeof(int)*n);
  if (factors == NULL) { perror("malloc - factors"); exit(1); }

  for (i = 0; i < n; i++) factors[i] = 1;
  
  vdm = gf_make_dispersal_matrix(rows, cols);

  for (i = cols; i < rows; i++) {
    sprintf(buf_file, "%s-%04d.rs", stem, i);
    printf("Calculating  %s ...", buf_file); fflush(stdout);
    memset(block, 0, blocksize); 
    for (j = 0; j < cols; j++) {
      tmp = vdm[i*cols+j]; 
      if (tmp != 0) {
        factor = gf_single_divide(tmp, factors[j]);
/*        printf("M[%02d,%02d] = %3d.  Factors[%02d] = %3d.  Factor = %3d.\n",
                i, j, tmp, j, factors[j], factor); */
        factors[j] = tmp;
/*        printf("     Block %2d Bef: %3d.  ", j, buffer[j][0]); */
        gf_mult_region(buffer[j], blocksize, factor);
/*        printf("Block %2d Aft: %3d.  ", j, buffer[j][0]); */
/*         printf("Block %2d Bef: %3d.  ", i, block[0]); */
        gf_add_parity(buffer[j], block, blocksize);
       /*  printf("Block %2d Aft: %3d.\n", i, block[0]); */
      }
    }
    printf(" writing  ...", buf_file); fflush(stdout);
    f = fopen(buf_file, "w");
    if (f == NULL) { perror(buf_file); exit(1); }
    fwrite(block, 1, blocksize, f);
    printf(" Done\n");
    fclose(f);
  }

  sprintf(buf_file, "%s-info.txt", stem, i);
  f = fopen(buf_file, "w");
  if (f == NULL) { perror(buf_file); exit(1); }
  fprintf(f, "%d\n", orig_size);
  fprintf(f, "%d\n", sz);
  fprintf(f, "%d\n", blocksize);
  fprintf(f, "%d\n", n);
  fprintf(f, "%d\n", m);
  gf_write_matrix(f, vdm, rows, cols);

	//Added by :supriya
	/*Socket program in order to send all the encoded files to different nodes*/


	int clientsocket;/* Socket descriptor for client */
	int enable=1,num=n,port=7856,bytes_read,a,pid;
	char sup[1024]="",msg[10]="",c[30]="",str[INET_ADDRSTRLEN],ack[10],file_name[100];
	struct sockaddr_in serverAddr;/* client address */
	socklen_t addr_size;
	
	while(num>0)
	{
		strcpy(file_name,file_name_tmp);
		/* Create socket for connections */
		clientsocket=socket(PF_INET,SOCK_STREAM,0);
		printf("\n\nSocket creation: %s\n",strerror(errno));

		/* Construct local address structure */
		serverAddr.sin_family=AF_INET;
		serverAddr.sin_port = htons(port);
		serverAddr.sin_addr.s_addr=inet_addr(ip_addr);
		memset(serverAddr.sin_zero,'\0',sizeof serverAddr.sin_zero);
		printf("\n*******%d***%d",num,port);
		--num;
		port=port+1;
		
		printf("Before connect\n");
		if (setsockopt(clientsocket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
	    		error("setsockopt(SO_REUSEADDR) failed");

		/*connect to the nodes to receive the encoded files*/
		connect(clientsocket,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
		   printf("Connection : %s\n",strerror(errno));

		printf("After connect\n");
		
		/*sending the files to the storage nodes */
		/*pid = fork();
		
	        if (pid < 0) {
		   perror("ERROR on fork");
		   exit(1);
	        }
	      
	        if (pid == 0) {	*/
	         	
		send(clientsocket,"Encode",7,0);/*option chosen*/
		bytes_read=recv(clientsocket,ack,sizeof(ack),0);

		/*Master log file is opened to write the details of storage nodes*/
		FILE *mf,*t,*fp;
		mf=fopen("Master_file.txt","a+");
	
		strcat(file_name,"\t");/*wrting the file name*/
		fprintf(mf,"%s",file_name);
				
		t=fopen(tmp_filename,"r");/*fragment file names are stored in tmp.txt*/


		a=fscanf(t,"%s",c); /*reading the names of fragment files (stem)*/
	
		fp=fopen(c,"r"); /*opening the fragments*/

			
		/*sending the fragment file name nad its content*/
		send(clientsocket,c,strlen(c),0);
		bytes_read=recv(clientsocket,msg,sizeof(msg),0);
		msg[bytes_read]='\0';

		//printf("\n\t%s\n",msg);
		if(strcmp(msg,"recv")==0)
		{
		 	bytes_read = fread(sup, sizeof(char),sizeof(sup), fp);
			sup[bytes_read]='\0';
			printf("\nFile content :  %s",sup);
		 	send(clientsocket,sup,strlen(sup),0);

			inet_ntop(AF_INET, &(serverAddr.sin_addr), str, INET_ADDRSTRLEN);
			printf("\nFile : %s has been sent to %s\n",c,str);
		}
		remove(c);
		
		
		/*Writing in the Master log file*/	
	
		strcat(c,"\t"); /*fragment name*/
		strcat(c,str);  /*ip address of the storage node receiving  above fragment*/
		strcat(c,"\n");
		fprintf(mf,"%s",c);	
		fclose(mf);
	
		/*remove the Fragment filename from file*/
		char b;
		int tmp=1;
		rewind(t);
		FILE *fp2;
		//open new file in write mode
		fp2 = fopen("copy.c", "w");
		b = getc(t);
		while (b != EOF) {
			  b= getc(t);
			  if (b == '\n')
			  tmp++;
		  //except the line to be deleted
			  if (tmp != 1)
			  {
		    //copy all lines in file copy.c
			    putc(b, fp2);
			  }
		}
		//close both the files.
		fclose(t);
		fclose(fp2);
		//remove original file
		remove(tmp_filename);
		//rename the file copy.c to original name
		rename("copy.c", tmp_filename);					      
		
		//}
		//else
		//{
			close(clientsocket);
		//}
			
	}/*end of the while */
	
   remove("tmp.txt");
	/*socket program ends*/
}
示例#3
0
void RsDecodeFile(int argc, char **argv)
{
  int i, j, k, *vdm, *inv, *prod, cache_size;
  int rows, cols, blocksize, orig_size;
  int n, m, sz, *factors, tmp, factor, *exists, *map;
  char *stem, *filename; 
  char **buffer, *buf_file, *block;
  struct stat buf;
  Condensed_Matrix *cm;
  int *mat, *id;
  FILE *f;

  if (argc != 2) {
    fprintf(stderr, "usage: rs_decode_file stem\n");
    exit(1);
  }
  
  stem = argv[1];
  buf_file = (char *) malloc(sizeof(char)*(strlen(stem)+30));
  if (buf_file == NULL) { perror("malloc - buf_file"); exit(1); }
  sprintf(buf_file, "%s-info.txt", stem, i);
  f = fopen(buf_file, "r");
  if (f == NULL) { perror(buf_file); exit(1); }
  if (fscanf(f, "%d\n", &orig_size) != 1) { fprintf(stderr, "Error reading info file 1\n"); exit(1); }
  if (fscanf(f, "%d\n", &sz) != 1) { fprintf(stderr, "Error reading info file 2\n"); exit(1); }
  if (fscanf(f, "%d\n", &blocksize) != 1) { fprintf(stderr, "Error reading info file 3\n"); exit(1); }
  if (fscanf(f, "%d\n", &n) != 1) { fprintf(stderr, "Error reading info file 4\n"); exit(1); }
  if (fscanf(f, "%d\n", &m) != 1) { fprintf(stderr, "Error reading info file 5\n"); exit(1); }
  vdm = gf_read_matrix(f, &rows, &cols);
  if (vdm == NULL) { fprintf(stderr, "Error reading info file matrix\n"); exit(1); }
  fclose(f);
  
  if (rows != n+m) {
    fprintf(stderr, "Error in %s - rows != n+m\n", buf_file);
    exit(1);
  }
  if (cols != n) {
    fprintf(stderr, "Error in %s - cols != n\n", buf_file);
    exit(1);
  }

  exists = (int *) malloc(sizeof(int) * rows);
  if (exists == NULL) { perror("malloc - exists"); exit(1); }
  factors = (int *) malloc(sizeof(int) * rows);
  if (factors == NULL) { perror("malloc - factors"); exit(1); }
  map = (int *) malloc(sizeof(int) * rows);
  if (map == NULL) { perror("malloc - map"); exit(1); }

  buffer = (char **) malloc(sizeof(char *)*n);
  for (i = 0; i < n; i++) {
    buffer[i] = (char *) malloc(blocksize);
    if (buffer[i] == NULL) {
      perror("Allocating buffer to store the whole file");
      exit(1);
    }
  }

  j = 0;
  for (i = 0; i < rows && j < cols; i++) {
    sprintf(buf_file, "%s-%04d.rs", stem, i);
    if (stat(buf_file, &buf) != 0) {
      map[i] = -1;
    } else {
      if (buf.st_size != blocksize) {
        map[i] = -1;
      } else {
        map[i] = j++;
        f = fopen(buf_file, "r");
        if (f == NULL) { perror(buf_file); exit(1); }
        k = fread(buffer[map[i]], 1, blocksize, f);
        if (k != blocksize) {
          fprintf(stderr, "%s -- stat says %d bytes, but only read %d\n", 
             buf_file, buf.st_size, k);
          exit(1);
        }
      }
    }
  }

  if (j < cols) {
    fprintf(stderr, "Only %d fragments -- need %d.  Sorry\n", j, cols);
    exit(1);
  }
  
  j = 0;
  for (i = 0; i < cols; i++) if (map[i] == -1) j++;
  fprintf(stderr, "Blocks to decode: %d\n", j);
  if (j == 0) {
    cache_size = orig_size;
    for (i = 0; i < cols; i++) {
      if (cache_size > 0) {
        fwrite(buffer[i], 1, (cache_size > blocksize) ? blocksize : cache_size, stdout);
        cache_size -= blocksize;
      }
    }
    exit(0);
  } 

  block = (char *) malloc(sizeof(char)*blocksize);
  if (block == NULL) { perror("malloc - block"); exit(1); }
  
  for (i = 0; i < rows; i++) exists[i] = (map[i] != -1);
  cm = gf_condense_dispersal_matrix(vdm, exists, rows, cols);
  mat = cm->condensed_matrix;
  id = cm->row_identities;
  /* Fix it so that map[i] for i = 0 to cols-1 is defined correctly.
     map[i] is the index of buffer[] that holds the blocks for row i in 
     the condensed matrix */

  for (i = 0; i < cols; i++) {
    if (map[i] == -1) map[i] = map[id[i]];
  }

  fprintf(stderr, "Inverting condensed dispersal matrix ... "); fflush(stderr);
  inv = gf_invert_matrix(mat, cols);
  if (inv == NULL) {
    fprintf(stderr, "\n\nError -- matrix unvertible\n");
    exit(1);
  }
  fprintf(stderr, "Done\n"); fflush(stderr);
  
  fprintf(stderr, "\nCondensed matrix:\n\n");
  gf_fprint_matrix(stderr, mat, cols, cols);

  fprintf(stderr, "\nInverted matrix:\n\n");
  gf_fprint_matrix(stderr, inv, cols, cols);

  for(i = 0; i < rows; i++) factors[i] = 1;

  cache_size = orig_size;
  for (i = 0; i < cols && cache_size > 0; i++)
  {
    if (id[i] < cols)
    {
      fprintf(stderr, "Writing block %d from memory ... ", i); fflush(stderr);
      if (factors[i] != 1)
      {
        tmp = gf_single_divide(1, factors[i]);
/*        fprintf(stderr, "Factor = %3d.  Tmp = %3d.  Before[0] = %3d.  ",
                factors[i], tmp, (unsigned char) buffer[map[i]][0]); */
        factors[i] = 1;
        gf_mult_region(buffer[map[i]], blocksize, tmp);
/*        fprintf(stderr, "After[0] = %3d.\n", (unsigned char) buffer[map[i]][0]); */
      }
      else
      {
/*        fprintf(stderr, "Factor = %3d.  Buffer[0] = %3d.\b", factors[i], 
             (unsigned char) buffer[map[i]][0]); */
      }
      fwrite(buffer[map[i]], 1, (cache_size > blocksize) ? blocksize : cache_size, stdout);
      cache_size -= blocksize;
      fprintf(stderr, "Done\n"); fflush(stderr);
    }
    else
    {
      fprintf(stderr, "Decoding block %d ... ", i); fflush(stderr);
      memset(block, 0, blocksize);
      for (j = 0; j < cols; j++)
      {
        tmp = inv[i*cols+j];
        factor = gf_single_divide(tmp, factors[j]);
/*        fprintf(stderr, "Factors[%d] = %3d.  Tmp = %3d.  Factor = %3d\n    Before[j][0] = %3d.  ", 
                j, factors[j], tmp, factor, (unsigned char) buffer[map[j]][0]); */
        factors[j] = tmp;
        gf_mult_region(buffer[map[j]], blocksize, factor);
/*        fprintf(stderr, "After[j][0] = %3d.  ", (unsigned char) buffer[map[j]][0]);
        fprintf(stderr, "Before-block[0] = %3d.  ", (unsigned char) block[0]); */
        gf_add_parity(buffer[map[j]], block, blocksize);
/*        fprintf(stderr, "After-block[0] = %3d.\n", (unsigned char) block[0]); */
      }
      fprintf(stderr, "writing ... "); fflush(stderr);
      fwrite(block, 1, (cache_size > blocksize) ? blocksize : cache_size, stdout);
      cache_size -= blocksize;
      fprintf(stderr, "Done\n"); fflush(stderr);
    }
  }
}