unsigned int countBlocks(Stream_t *Dir, unsigned int block) { Stream_t *Stream = GetFs(Dir); DeclareThis(Fs_t); return _countBlocks(This, block); }
int dir_grow(Stream_t *Dir, int size) { Stream_t *Stream = GetFs(Dir); DeclareThis(FsPublic_t); int ret; int buflen; char *buffer; if (!getfreeMinClusters(Dir, 1)) return -1; buflen = This->cluster_size * This->sector_size; if(! (buffer=malloc(buflen)) ){ perror("dir_grow: malloc"); return -1; } memset((char *) buffer, '\0', buflen); ret = force_write(Dir, buffer, (mt_off_t) size * MDIR_SIZE, buflen); free(buffer); if(ret < buflen) return -1; return 0; }
static __inline__ int print_volume_label(Stream_t *Dir, char drive) { Stream_t *Stream = GetFs(Dir); direntry_t entry; DeclareThis(FsPublic_t); char shortname[13]; char longname[VBUFSIZE]; int r; RootDir = OpenRoot(Stream); if(concise) return 0; /* find the volume label */ initializeDirentry(&entry, RootDir); if((r=vfat_lookup(&entry, 0, 0, ACCEPT_LABEL | MATCH_ANY, shortname, longname)) ) { if (r == -2) { /* I/O Error */ return -1; } printf(" Volume in drive %c has no label", drive); } else if (*longname) printf(" Volume in drive %c is %s (abbr=%s)", drive, longname, shortname); else printf(" Volume in drive %c is %s", drive, shortname); if(This->serialized) printf("\n Volume Serial Number is %04lX-%04lX", (This->serial_number >> 16) & 0xffff, This->serial_number & 0xffff); return 0; }
static void leaveDrive(int haveError) { if(!currentDrive) return; leaveDirectory(haveError); if(!concise && !haveError) { if(dirsOnDrive > 1) { printf("\nTotal files listed:\n"); printSummary(filesOnDrive, bytesOnDrive); } if(RootDir && !fast) { char *s1 = NULL; mt_off_t bytes = getfree(RootDir); if(bytes == -1) { fprintf(stderr, "Fat error\n"); goto exit_1; } printf(" %s bytes free\n\n", dotted_num(bytes,17, &s1)); #ifdef TEST_SIZE ((Fs_t*)GetFs(RootDir))->freeSpace = 0; bytes = getfree(RootDir); printf(" %s bytes free\n\n", dotted_num(bytes,17, &s1)); #endif if(s1) free(s1); } } exit_1: FREE(&RootDir); currentDrive = '\0'; }
/* returns number of bytes in a directory. Represents a file size, and * can hence be not bigger than 2^32 */ static size_t countBytes(struct Stream_t *Dir, unsigned int block) { struct Stream_t *Stream = GetFs(Dir); DeclareThis(struct Fs_t); return _countBlocks(This, block) * This->sector_size * This->cluster_size; }
int fat_free(Stream_t *Dir, unsigned int fat) { Stream_t *Stream = GetFs(Dir); DeclareThis(Fs_t); unsigned int next_no_step; /* a zero length file? */ if (fat == 0) return(0); /* CONSTCOND */ while (!This->fat_error) { /* get next cluster number */ next_no_step = fatDecode(This,fat); /* mark current cluster as empty */ fatDeallocate(This,fat); if (next_no_step >= This->last_fat) break; fat = next_no_step; } return(0); }
void mlabel(int argc, char **argv, int type) { char *newLabel; int verbose, clear, interactive, show; direntry_t entry; int result=0; char longname[VBUFSIZE]; char shortname[45]; ClashHandling_t ch; struct MainParam_t mp; Stream_t *RootDir; int c; int mangled; enum { SER_NONE, SER_RANDOM, SER_SET } set_serial = SER_NONE; long serial = 0; int need_write_boot = 0; int have_boot = 0; char *eptr; union bootsector boot; Stream_t *Fs=0; int r; struct label_blk_t *labelBlock; int isRo=0; int *isRop=NULL; init_clash_handling(&ch); ch.name_converter = label_name; ch.ignore_entry = -2; verbose = 0; clear = 0; show = 0; if(helpFlag(argc, argv)) usage(0); while ((c = getopt(argc, argv, "i:vcsnN:h")) != EOF) { switch (c) { case 'i': set_cmd_line_image(optarg, 0); break; case 'v': verbose = 1; break; case 'c': clear = 1; break; case 's': show = 1; break; case 'n': set_serial = SER_RANDOM; srandom((long)time (0)); serial=random(); break; case 'N': set_serial = SER_SET; serial = strtol(optarg, &eptr, 16); if(*eptr) { fprintf(stderr, "%s not a valid serial number\n", optarg); exit(1); } break; case 'h': usage(0); default: usage(1); } } if (argc - optind != 1 || !argv[optind][0] || argv[optind][1] != ':') usage(1); init_mp(&mp); newLabel = argv[optind]+2; if(strlen(newLabel) > VBUFSIZE) { fprintf(stderr, "Label too long\n"); FREE(&RootDir); exit(1); } interactive = !show && !clear &&!newLabel[0] && (set_serial == SER_NONE); if(!clear && !newLabel[0]) { isRop = &isRo; } RootDir = open_root_dir(argv[optind][0], isRop ? 0 : O_RDWR, isRop); if(isRo) { show = 1; interactive = 0; } if(!RootDir) { fprintf(stderr, "%s: Cannot initialize drive\n", argv[0]); exit(1); } initializeDirentry(&entry, RootDir); r=vfat_lookup(&entry, 0, 0, ACCEPT_LABEL | MATCH_ANY, shortname, longname); if (r == -2) { FREE(&RootDir); exit(1); } if(show || interactive){ if(isNotFound(&entry)) printf(" Volume has no label\n"); else if (*longname) printf(" Volume label is %s (abbr=%s)\n", longname, shortname); else printf(" Volume label is %s\n", shortname); } /* ask for new label */ if(interactive){ newLabel = longname; fprintf(stderr,"Enter the new volume label : "); if(fgets(newLabel, VBUFSIZE, stdin) == NULL) { newLabel[0] = '\0'; fprintf(stderr, "\n"); } if(newLabel[0]) newLabel[strlen(newLabel)-1] = '\0'; } if((!show || newLabel[0]) && !isNotFound(&entry)){ /* if we have a label, wipe it out before putting new one */ if(interactive && newLabel[0] == '\0') if(ask_confirmation("Delete volume label (y/n): ")){ FREE(&RootDir); exit(0); } entry.dir.attr = 0; /* for old mlabel */ wipeEntry(&entry); } if (newLabel[0] != '\0') { ch.ignore_entry = 1; result = mwrite_one(RootDir,newLabel,0,labelit,NULL,&ch) ? 0 : 1; } have_boot = 0; if( (!show || newLabel[0]) || set_serial != SER_NONE) { Fs = GetFs(RootDir); have_boot = (force_read(Fs,boot.characters,0,sizeof(boot)) == sizeof(boot)); } if(WORD_S(fatlen)) { labelBlock = &boot.boot.ext.old.labelBlock; } else { labelBlock = &boot.boot.ext.fat32.labelBlock; } if(!show || newLabel[0]){ dos_name_t dosname; const char *shrtLabel; doscp_t *cp; if(!newLabel[0]) shrtLabel = "NO NAME "; else shrtLabel = newLabel; cp = GET_DOSCONVERT(Fs); label_name(cp, shrtLabel, verbose, &mangled, &dosname); if(have_boot && boot.boot.descr >= 0xf0 && labelBlock->dos4 == 0x29) { strncpy(labelBlock->label, dosname.base, 11); need_write_boot = 1; } } if((set_serial != SER_NONE) & have_boot) { if(have_boot && boot.boot.descr >= 0xf0 && labelBlock->dos4 == 0x29) { set_dword(labelBlock->serial, serial); need_write_boot = 1; } } if(need_write_boot) { force_write(Fs, (char *)&boot, 0, sizeof(boot)); } FREE(&RootDir); exit(result); }
void mbadblocks(int argc, char **argv, int type) { unsigned int i; unsigned int startSector=2; unsigned int endSector=0; struct MainParam_t mp; Fs_t *Fs; Stream_t *Dir; int ret; char *filename = NULL; char c; unsigned int badClus; int sectorMode=0; int writeMode=0; while ((c = getopt(argc, argv, "i:s:cwS:E:")) != EOF) { switch(c) { case 'i': set_cmd_line_image(optarg, 0); break; case 'c': checkListTwice(filename); filename = strdup(optarg); break; case 's': checkListTwice(filename); filename = strdup(optarg); sectorMode = 1; break; case 'S': startSector = atol(optarg); break; case 'E': endSector = atol(optarg); break; case 'w': writeMode = 1; break; case 'h': usage(0); default: usage(1); } } if (argc != optind+1 || !argv[optind][0] || argv[optind][1] != ':' || argv[optind][2]) { usage(1); } init_mp(&mp); Dir = open_root_dir(argv[optind][0], O_RDWR, NULL); if (!Dir) { fprintf(stderr,"%s: Cannot initialize drive\n", argv[0]); exit(1); } Fs = (Fs_t *)GetFs(Dir); in_len = Fs->cluster_size * Fs->sector_size; in_buf = malloc(in_len); if(!in_buf) { printOom(); ret = 1; goto exit_0; } if(writeMode) { int i; pat_buf=malloc(in_len * N_PATTERN); if(!pat_buf) { printOom(); ret = 1; goto exit_0; } srandom(time(NULL)); for(i=0; i < in_len * N_PATTERN; i++) { pat_buf[i] = random(); } } for(i=0; i < Fs->clus_start; i++ ){ ret = READS(Fs->Next, in_buf, sectorsToBytes((Stream_t*)Fs, i), Fs->sector_size); if( ret < 0 ){ perror("early error"); goto exit_0; } if(ret < (signed int) Fs->sector_size){ fprintf(stderr,"end of file in file_read\n"); ret = 1; goto exit_0; } } ret = 0; badClus = Fs->last_fat + 1; if(startSector < 2) startSector = 2; if(endSector > Fs->num_clus + 2 || endSector <= 0) endSector = Fs->num_clus + 2; if(filename) { char line[80]; FILE *f = fopen(filename, "r"); if(f == NULL) { fprintf(stderr, "Could not open %s (%s)\n", filename, strerror(errno)); ret = 1; goto exit_0; } while(fgets(line, sizeof(line), f)) { char *ptr = line + strspn(line, " \t"); long offset = strtoul(ptr, 0, 0); if(sectorMode) offset = (offset-Fs->clus_start)/Fs->cluster_size + 2; if(offset < 2) { fprintf(stderr, "Sector before start\n"); } else if(offset >= Fs->num_clus) { fprintf(stderr, "Sector beyond end\n"); } else { mark(Fs, offset, badClus); ret = 1; } } } else { Stream_t *dev; dev = Fs->Next; if(dev->Next) dev = dev->Next; in_len = Fs->cluster_size * Fs->sector_size; if(writeMode) { /* Write pattern */ for(i=startSector; i< endSector; i++){ if(got_signal) break; progress(i, Fs->num_clus); ret |= scan(Fs, dev, i, badClus, pat_buf + in_len * (i % N_PATTERN), 1); } /* Flush cache, so that we are sure we read the data back from disk, rather than from the cache */ if(!got_signal) DISCARD(dev); /* Read data back, and compare to pattern */ for(i=startSector; i< endSector; i++){ if(got_signal) break; progress(i, Fs->num_clus); ret |= scan(Fs, dev, i, badClus, pat_buf + in_len * (i % N_PATTERN), 0); } } else { for(i=startSector; i< endSector; i++){ if(got_signal) break; progress(i, Fs->num_clus); ret |= scan(Fs, dev, i, badClus, NULL, 0); } } } exit_0: FREE(&Dir); exit(ret); }
int fatlabel_set_label(const char* device_name, const char* new_label) { if (strlen(new_label) > VBUFSIZE) return -1; /* * 1. Init clash handling */ struct ClashHandling_t ch; init_clash_handling(&ch); ch.name_converter = label_name; ch.ignore_entry = -2; /* * 2. Open root dir */ struct Stream_t* RootDir = fs_init(device_name, O_RDWR); if (RootDir) RootDir = OpenRoot(RootDir); if (!RootDir) { fprintf(stderr, "Opening root dir failed.\n"); return -2; } /* * 3. Init dir entry */ struct direntry_t entry; initializeDirentry(&entry, RootDir); /* * 4. Lookup vfat */ char longname[VBUFSIZE]; char shortname[45]; if (vfat_lookup(&entry, 0, 0, ACCEPT_LABEL | MATCH_ANY, shortname, longname) == -2) { fprintf(stderr, "Looking up vfat failed.\n"); free_stream(&RootDir); return -3; } /* * 5. Wipe existing entry. */ if (!isNotFound(&entry)) { /* if we have a label, wipe it out before putting new one */ entry.dir.attr = 0; /* for old mlabel */ wipeEntry(&entry); } /* * 6. Write new entry */ ch.ignore_entry = 1; /* don't try to write the label if it's empty */ int result = strlen(new_label) ? mwrite_one(RootDir, new_label, labelit, &ch) : 0; /* * 7. Load FAT boot record */ union bootsector boot; struct Stream_t* Fs = GetFs(RootDir); int have_boot = force_read(Fs, boot.characters, 0, sizeof(boot)) == sizeof(boot); struct label_blk_t* labelBlock = WORD_S(fatlen) ? &boot.boot.ext.old.labelBlock : &boot.boot.ext.fat32.labelBlock; /* * 8. Get "dosconvert" struct */ struct dos_name_t dosname; struct doscp_t* cp = GET_DOSCONVERT(Fs); /* * 9. Convert label */ int mangled = 0; label_name(cp, new_label, &mangled, &dosname); /* * 10. Overwrite FAT boot record */ if (have_boot && boot.boot.descr >= 0xf0 && labelBlock->dos4 == 0x29) { strncpy(labelBlock->label, dosname.base, 11); force_write(Fs, (char *)&boot, 0, sizeof(boot)); } free_stream(&RootDir); fs_close(Fs); return result; }