Exemplo n.º 1
0
/*
 * If we have an FSInfo block, update it.
 */
static int
msdosfs_fsiflush(struct msdosfsmount *pmp, int waitfor)
{
	struct fsinfo *fp;
	struct buf *bp;
	int error;

	MSDOSFS_LOCK_MP(pmp);
	if (pmp->pm_fsinfo == 0 || (pmp->pm_flags & MSDOSFS_FSIMOD) == 0) {
		error = 0;
		goto unlock;
	}
	error = bread(pmp->pm_devvp, pmp->pm_fsinfo, pmp->pm_BytesPerSec,
	    NOCRED, &bp);
	if (error != 0) {
		brelse(bp);
		goto unlock;
	}
	fp = (struct fsinfo *)bp->b_data;
	putulong(fp->fsinfree, pmp->pm_freeclustercount);
	putulong(fp->fsinxtfree, pmp->pm_nxtfree);
	pmp->pm_flags &= ~MSDOSFS_FSIMOD;
	if (waitfor == MNT_WAIT)
		error = bwrite(bp);
	else
		bawrite(bp);
unlock:
	MSDOSFS_UNLOCK_MP(pmp);
	return (error);
}
Exemplo n.º 2
0
/* write the values into a directory entry */
void write_dirent(struct direntry *dirent, char *filename, uint16_t start_cluster, uint32_t size)
{
    char *p, *p2;
    char *uppername;
    int len, i;

    /* clean out anything old that used to be here */
    memset(dirent, 0, sizeof(struct direntry));

    /* extract just the filename part */
    uppername = strdup(filename);
    p2 = uppername;
    for (i = 0; i < strlen(filename); i++) 
    {
	if (p2[i] == '/' || p2[i] == '\\') 
	{
	    uppername = p2+i+1;
	}
    }

    /* convert filename to upper case */
    for (i = 0; i < strlen(uppername); i++) 
    {
	uppername[i] = toupper(uppername[i]);
    }

    /* set the file name and extension */
    memset(dirent->deName, ' ', 8);
    p = strchr(uppername, '.');
    memcpy(dirent->deExtension, "___", 3);
    if (p == NULL) 
    {
	fprintf(stderr, "No filename extension given - defaulting to .___\n");
    }
    else 
    {
	*p = '\0';
	p++;
	len = strlen(p);
	if (len > 3) len = 3;
	memcpy(dirent->deExtension, p, len);
    }

    if (strlen(uppername)>8) 
    {
	uppername[8]='\0';
    }
    memcpy(dirent->deName, uppername, strlen(uppername));
    free(p2);

    /* set the attributes and file size */
    dirent->deAttributes = ATTR_NORMAL;
    putushort(dirent->deStartCluster, start_cluster);
    putulong(dirent->deFileSize, size);

    /* could also set time and date here if we really
       cared... */
}
Exemplo n.º 3
0
/*
 * worker function that checks and repairs incosistency errors
 */
void chkerr(struct direntry* dirent, char* filename, 
                   uint8_t *image_buf, struct bpb33* bpb) {
    int num_clusters = count_clusters(dirent, image_buf, bpb);
    uint32_t entry_size = getulong(dirent->deFileSize);

    // remove empty files
    if (entry_size == 0) {
        if (dirent->deAttributes == ATTR_NORMAL && dirent->deName[0] != 
            SLOT_EMPTY && dirent->deName[0] != SLOT_DELETED) {
            printf("Empty file found... removing. \n\n");
            dirent->deName[0] = SLOT_DELETED;
        }
    }
    
    // fix size inconsistencies
    if (num_clusters != 0 && entry_size < num_clusters - 512 ) { // take entry to be right
        printf("OUT OF BOUNDS: \n\tFilename: %s \n\t\tsize in directory entry: %d, size in FAT chain: %d.) \n\n", filename, entry_size, num_clusters);
        repair(dirent, image_buf, bpb, entry_size);
    } else if (entry_size > num_clusters) { // take FAT to be right
        printf("OUT OF BOUNDS: \n\tFilename: %s \n\t\tsize in directory entry: %d, size in FAT chain: %d \n\n", filename, entry_size, num_clusters);
        putulong(dirent->deFileSize, num_clusters);
    }
}
Exemplo n.º 4
0
static void vprint(printer *p, const char *format, va_list ap)
{
     const char *s = format;
     char c;
     INT ival;

     while ((c = *s++)) {
          switch (c) {
	      case '%':
		   switch ((c = *s++)) {
		       case 'M': {
			    /* md5 value */
			    md5uint x = va_arg(ap, md5uint);
			    putulong(p, (unsigned long)(0xffffffffUL & x),
				     16, 8);
			    break;
		       }
		       case 'c': {
			    int x = va_arg(ap, int);
			    p->putchr(p, x);
			    break;
		       }
		       case 's': {
			    char *x = va_arg(ap, char *);
			    if (x)
				 myputs(p, x);
			    else
				 goto putnull;
			    break;
		       }
		       case 'd': {
			    int x = va_arg(ap, int);
			    ival = (INT)x;
			    goto putival;
		       }
		       case 'D': {
			    ival = va_arg(ap, INT);
			    goto putival;
		       }
		       case 'v': {
			    /* print optional vector length */
			    ival = va_arg(ap, INT);
			    if (ival > 1) {
				 myputs(p, "-x");
				 goto putival;
			    }
			    break;
		       }
		       case 'o': {
			    /* integer option.  Usage: %oNAME= */
			    ival = va_arg(ap, INT);
			    if (ival)
				 p->putchr(p, '/');
			    while ((c = *s++) != '=')
				 if (ival)
				      p->putchr(p, c);
			    if (ival) {
				 p->putchr(p, '=');
				 goto putival;
			    }
			    break;
		       }
		       case 'u': {
			    unsigned x = va_arg(ap, unsigned);
			    putulong(p, (unsigned long)x, 10, 0);
			    break;
		       }
		       case 'x': {
			    unsigned x = va_arg(ap, unsigned);
			    putulong(p, (unsigned long)x, 16, 0);
			    break;
		       }
		       case '(': {
			    /* newline, augment indent level */
			    p->indent += p->indent_incr;
			    newline(p);
			    break;
		       }
		       case ')': {
			    /* decrement indent level */
			    p->indent -= p->indent_incr;
			    break;
		       }
		       case 'p': {  /* note difference from C's %p */
			    /* print plan */
			    plan *x = va_arg(ap, plan *);
			    if (x) 
				 x->adt->print(x, p);
			    else 
				 goto putnull;
			    break;
		       }
		       case 'P': {
			    /* print problem */
			    problem *x = va_arg(ap, problem *);
			    if (x)
				 x->adt->print(x, p);
			    else
				 goto putnull;
			    break;
		       }
		       case 'T': {
			    /* print tensor */
			    tensor *x = va_arg(ap, tensor *);
			    if (x)
				 X(tensor_print)(x, p);
			    else
				 goto putnull;
			    break;
		       }
		       default:
			    A(0 /* unknown format */);
			    break;

		   putnull:
			    myputs(p, "(null)");
			    break;

		   putival:
			    putint(p, ival);
			    break;
		   }
		   break;
	      default:
		   p->putchr(p, c);
		   break;
          }
     }
}
Exemplo n.º 5
0
/************PRINT_DIRENT***************/
uint16_t print_dirent(struct direntry *dirent, int indent, uint8_t *image_buf, struct bpb33* bpb, int *refcount )
{
    uint16_t followclust = 0;

    int i;
    char name[9];
    char extension[4];
    uint32_t size;
    uint16_t file_cluster;
    name[8] = ' ';
    extension[3] = ' ';
    memcpy(name, &(dirent->deName[0]), 8);
    memcpy(extension, dirent->deExtension, 3);
    if (name[0] == SLOT_EMPTY)
    {
	return followclust;
    }

    /* skip over deleted entries */
    if (((uint8_t)name[0]) == SLOT_DELETED)
    {
	return followclust;
    }

    if (((uint8_t)name[0]) == 0x2E)
    {
	// dot entry ("." or "..")
	// skip it
        return followclust;
    }

    /* names are space padded - remove the spaces */
    for (i = 8; i > 0; i--) 
    {
	if (name[i] == ' ') 
	    name[i] = '\0';
	else 
	    break;
    }

    /* remove the spaces from extensions */
    for (i = 3; i > 0; i--) 
    {
	if (extension[i] == ' ') 
	    extension[i] = '\0';
	else 
	    break;
    }

    if ((dirent->deAttributes & ATTR_WIN95LFN) == ATTR_WIN95LFN)
    {
	// ignore any long file name extension entries
	//
	// printf("Win95 long-filename entry seq 0x%0x\n", dirent->deName[0]);
    }
    else if ((dirent->deAttributes & ATTR_VOLUME) != 0) 
    {
	printf("Volume: %s\n", name);
    } 
    else if ((dirent->deAttributes & ATTR_DIRECTORY) != 0) 
    {
        // don't deal with hidden directories; MacOS makes these
        // for trash directories and such; just ignore them.
	if ((dirent->deAttributes & ATTR_HIDDEN) != ATTR_HIDDEN)
        {
	    print_indent(indent);
    	    printf("%s/ (directory)\n", name);
            file_cluster = getushort(dirent->deStartCluster);
            followclust = file_cluster;
        }
    }
    else 
    {
        /*
         * a "regular" file entry
         * print attributes, size, starting cluster, etc.
         */
	int ro = (dirent->deAttributes & ATTR_READONLY) == ATTR_READONLY;
	int hidden = (dirent->deAttributes & ATTR_HIDDEN) == ATTR_HIDDEN;
	int sys = (dirent->deAttributes & ATTR_SYSTEM) == ATTR_SYSTEM;
	int arch = (dirent->deAttributes & ATTR_ARCHIVE) == ATTR_ARCHIVE;

	size = getulong(dirent->deFileSize);
	print_indent(indent);
	printf("%s.%s (%u bytes) (starting cluster %d) %c%c%c%c\n", 
	       name, extension, size, getushort(dirent->deStartCluster),
	       ro?'r':' ', 
               hidden?'h':' ', 
               sys?'s':' ', 
               arch?'a':' ');

		
		int cluster_count = 0;
        
		uint16_t curr_cluster = getushort(dirent->deStartCluster);
		uint16_t original_cluster = curr_cluster;
        
        uint16_t previous;

        while(is_valid_cluster(curr_cluster,bpb))
		{
            refcount[curr_cluster]++;
			if(refcount[curr_cluster] > 1) //problem
			{
				printf("ERROR REFCOUNT > 1 FOR:  %d, refcount = %d\n", curr_cluster, refcount[curr_cluster]);  
				dirent->deName[0] = SLOT_DELETED;
				refcount[curr_cluster]--;
			}

			previous = curr_cluster;
			curr_cluster = get_fat_entry(curr_cluster, image_buf, bpb);
			if(previous == curr_cluster) //points to itself
			{
				printf("ERROR POINTS TO SELF\n");
				set_fat_entry(curr_cluster, FAT12_MASK & CLUST_EOFS, image_buf, bpb);
				cluster_count++;
				break;
			}
			if(curr_cluster == (FAT12_MASK & CLUST_BAD))
			{
				printf("BAD CLUSTER\n");
				set_fat_entry(curr_cluster, FAT12_MASK & CLUST_FREE, image_buf, bpb);
				set_fat_entry(previous, FAT12_MASK & CLUST_EOFS, image_buf, bpb);
				break;
			}
			cluster_count++;
		}
		
		int clusters = 0;
		if(size%512 == 0)
		{
			clusters = size/512;
		}
		else
		{
			clusters = (size/512)+1;
		}
		if(clusters < cluster_count)
		{
			printf("ERROR: FILE SIZE TOO SMALL FOR NUM CLUSTERS\n");
			curr_cluster = get_fat_entry(original_cluster+clusters - 1, image_buf, bpb);
			printf("FIXED \n");
			while(is_valid_cluster(curr_cluster, bpb))
			{
				previous = curr_cluster;
				set_fat_entry(previous, FAT12_MASK & CLUST_FREE, image_buf, bpb);
				curr_cluster = get_fat_entry(curr_cluster, image_buf, bpb);
			}
			set_fat_entry(original_cluster +clusters -1, FAT12_MASK &CLUST_EOFS, image_buf, bpb);
			}
		else if(clusters > cluster_count)
		{
			printf("ERROR: FILE SIZE TOO LARGE FOR NUM CLUSTERS\n");
			uint32_t correct_size = cluster_count * bpb->bpbBytesPerSec;
			putulong(dirent->deFileSize, correct_size);
			printf("FIXED \n");
		}
		

    }

    return followclust;
}
Exemplo n.º 6
0
int compare(char *filename, uint16_t followclust, struct direntry *dirent, uint8_t *image_buf, struct bpb33* bpb){
	//will loop through fat until eof marking the good/bad/free clusters and freeing them
	uint32_t realsize = getulong(dirent->deFileSize);
	uint32_t clustersize = bpb->bpbSecPerClust*bpb->bpbBytesPerSec;
	int expected_num_clust = (realsize+511)/clustersize;  // finds num clusters according to the meta data
	
	//find actual num clusters in fat
	uint16_t fatent = get_fat_entry(followclust, image_buf, bpb);
	uint16_t prev_fatent = fatent;
	int count = 1;
	
	while(!is_end_of_file(fatent)) {  //loops through checking if eof
		uint16_t temp =get_fat_entry(fatent, image_buf, bpb);
		if (fatent == (FAT12_MASK & CLUST_BAD)){ //if the fatent is bad it will mark it in the array
			printf("Bad cluster");
			desperation[followclust+count]=-1;
			printf("File is inconsistant: name is: %s\n",filename);
			}
		
		

		if(count>=expected_num_clust)	//if we have more clusters than expected
			{	
			
			if (count==expected_num_clust) {  //will only happen once
				printf("count is greater\n");
				//will set the previous entry to be eof and fee the current cluster
				//will also set desperation =2 at the eof and 3 at the free cluster
				// this is becasue we want a record in desperation of free normal or not looked at clusters
				set_fat_entry(prev_fatent,FAT12_MASK&CLUST_EOFS, image_buf, bpb);
				desperation[followclust+count-1]=2;
				set_fat_entry(fatent, FAT12_MASK&CLUST_FREE, image_buf, bpb);
				desperation[followclust+count]=3;
				printf("file is inconsistant!!! name is: %s\n",filename);
			
				}
		
			else {
				// if we are over the size just free current cluster
				set_fat_entry(fatent, FAT12_MASK&CLUST_FREE, image_buf, bpb);
			
				}
			//when count is over expected we will put 3 in every cluster over size eof
			desperation[followclust+count]=3;
			fatent=temp;
			count++;
			}
		
		else {

			//if we are still running through the clusters then if we find a free set it as 3 or if it is just normal then set it as 1
			if (fatent == (FAT12_MASK&CLUST_FREE)) {
				printf("FREE CLUSTER BEFORE EOF WEEWOOWEEWOO");
				desperation[followclust+count]=3;
				
				}
			else {
				desperation[followclust+count]=1;
				}
			prev_fatent=fatent;
			fatent=get_fat_entry(fatent,image_buf, bpb);
			count++;
			}
			
		
		}
	desperation[followclust+count]=2;//set this block as an eof in desperation
	if (expected_num_clust>count){
		//if at the end cluster is greater than expected change the size in the meta data to be what the fat size is
		uint32_t clustersize = bpb->bpbSecPerClust*bpb->bpbBytesPerSec;
		putulong(dirent->deFileSize, (count*clustersize));
		printf("File is inconsistant!!! name is: %s \n", filename);
	}
	//loop through the current files clusters on desperation and until you hit the eof
	int i= followclust;
	int countgucci=0;
	while (desperation[i]!=2)
		{
		if (desperation[i]==1) {
			countgucci++;
			}
		}
	//put the newsize into the metadata
	putulong(dirent->deFileSize, (countgucci*clustersize));
	return count;
}