1/* dosfsck.c - User interface */ 2 3/* Written 1993 by Werner Almesberger */ 4 5/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 6 * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ 7 8 9#include "../version.h" 10 11#include <stdio.h> 12#include <stdlib.h> 13#include <string.h> 14#include <stdarg.h> 15#include <unistd.h> 16#include <getopt.h> 17 18#include "common.h" 19#include "dosfsck.h" 20#include "io.h" 21#include "boot.h" 22#include "fat.h" 23#include "file.h" 24#include "check.h" 25 26 27int interactive = 0,list = 0,test = 0,verbose = 0,write_immed = 0; 28int atari_format = 0; 29unsigned n_files = 0; 30void *mem_queue = NULL; 31 32 33static void usage(char *name) 34{ 35 fprintf(stderr,"usage: %s [-aAflrstvVwy] [-d path -d ...] " 36 "[-u path -u ...]\n%15sdevice\n",name,""); 37 fprintf(stderr," -a automatically repair the file system\n"); 38 fprintf(stderr," -A toggle Atari file system format\n"); 39 fprintf(stderr," -d path drop that file\n"); 40 fprintf(stderr," -f salvage unused chains to files\n"); 41 fprintf(stderr," -l list path names\n"); 42 fprintf(stderr," -r interactively repair the file system\n"); 43 fprintf(stderr," -s show the volume label, if any, and exit\n"); 44 fprintf(stderr," -t test for bad clusters\n"); 45 fprintf(stderr," -u path try to undelete that (non-directory) file\n"); 46 fprintf(stderr," -v verbose mode\n"); 47 fprintf(stderr," -V perform a verification pass\n"); 48 fprintf(stderr," -w write changes to disk immediately\n"); 49 fprintf(stderr," -y same as -a, for compat with other *fsck\n"); 50 exit(2); 51} 52 53 54/* 55 * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant 56 * of MS-DOS filesystem by default. 57 */ 58static void check_atari( void ) 59{ 60#ifdef __mc68000__ 61 FILE *f; 62 char line[128], *p; 63 64 if (!(f = fopen( "/proc/hardware", "r" ))) { 65 perror( "/proc/hardware" ); 66 return; 67 } 68 69 while( fgets( line, sizeof(line), f ) ) { 70 if (strncmp( line, "Model:", 6 ) == 0) { 71 p = line + 6; 72 p += strspn( p, " \t" ); 73 if (strncmp( p, "Atari ", 6 ) == 0) 74 atari_format = 1; 75 break; 76 } 77 } 78 fclose( f ); 79#endif 80} 81 82 83extern int filter_printf(const char *format, ...) 84{ 85 char new_format[1000]; 86 const char *follow_old; 87 char *follow_new; 88 va_list ap; 89 int result; 90 91 fprintf(stdout, "<script>check_fat_filesystem_info(\""); 92 follow_old = format; 93 follow_new = new_format; 94 while (*follow_old != 0) 95 { 96 if (*follow_old == '\n') 97 { 98 /* empty */ 99 } 100 else if (*follow_old == '"') 101 { 102 *follow_new = '\\'; 103 ++follow_new; 104 *follow_new = '"'; 105 ++follow_new; 106 } 107 else if (*follow_old == '\\') 108 { 109 *follow_new = '\\'; 110 ++follow_new; 111 *follow_new = '\\'; 112 ++follow_new; 113 } 114 else 115 { 116 *follow_new = *follow_old; 117 ++follow_new; 118 } 119 ++follow_old; 120 } 121 *follow_new = 0; 122 va_start(ap, format); 123 result = vprintf(new_format, ap); 124 va_end(ap); 125 fprintf(stdout, "\");</script>\n"); 126 fflush(stdout); 127 return result; 128} 129 130 131int main(int argc,char **argv) 132{ 133 DOS_FS fs; 134 int rw,salvage_files,verify,show_label,c; 135 unsigned long free_clusters; 136 137 rw = salvage_files = verify = show_label = 0; 138 interactive = 0; 139 check_atari(); 140 141 while ((c = getopt(argc,argv,"Aad:flrstu:vVwy")) != EOF) 142 switch (c) { 143 case 'A': /* toggle Atari format */ 144 atari_format = !atari_format; 145 break; 146 case 'a': 147 case 'y': 148 rw = 1; 149 interactive = 0; 150 salvage_files = 1; 151 break; 152 case 'd': 153 file_add(optarg,fdt_drop); 154 break; 155 case 'f': 156 salvage_files = 1; 157 break; 158 case 'l': 159 list = 1; 160 break; 161 case 'r': 162 rw = 1; 163 interactive = 1; 164 break; 165 case 's': 166 show_label = 1; 167 break; 168 case 't': 169 test = 1; 170 break; 171 case 'u': 172 file_add(optarg,fdt_undelete); 173 break; 174 case 'v': 175 verbose = 1; 176 printf("dosfsck " VERSION " (" VERSION_DATE ")\n"); 177 break; 178 case 'V': 179 verify = 1; 180 break; 181 case 'w': 182 write_immed = 1; 183 break; 184 default: 185 usage(argv[0]); 186 } 187 if ((test || write_immed) && !rw) { 188 fprintf(stderr,"-t and -w require -a or -r\n"); 189 exit(2); 190 } 191 if (optind != argc-1) usage(argv[0]); 192 193 printf( "dosfsck " VERSION ", " VERSION_DATE ", FAT32, LFN\n" ); 194 fs_open(argv[optind],rw); 195 read_boot(&fs); 196 if (show_label) { 197 if (!scan_root_for_volume_label(&fs)) 198 fprintf(stdout, "No volume label found.\n"); 199 fprintf(stdout, "Volume ID: 0x%02x%02x%02x%02x\n", 200 (unsigned)(fs.volume_id[0]), (unsigned)(fs.volume_id[1]), 201 (unsigned)(fs.volume_id[2]), (unsigned)(fs.volume_id[3])); 202 qfree(&mem_queue); 203 return fs_close(rw) ? 1 : 0; 204 } 205 if (verify) printf("Starting check/repair pass.\n"); 206 while (read_fat(&fs), scan_root(&fs)) qfree(&mem_queue); 207 if (test) fix_bad(&fs); 208 if (salvage_files) reclaim_file(&fs); 209 else reclaim_free(&fs); 210 free_clusters = update_free(&fs); 211 file_unused(); 212 qfree(&mem_queue); 213 if (verify) { 214 printf("Starting verification pass.\n"); 215 read_fat(&fs); 216 scan_root(&fs); 217 reclaim_free(&fs); 218 qfree(&mem_queue); 219 } 220 221 if (fs_changed()) { 222 if (rw) { 223 if (interactive) 224 rw = get_key("yn","Perform changes ? (y/n)") == 'y'; 225 else printf("Performing changes.\n"); 226 } 227 else 228 printf("Leaving file system unchanged.\n"); 229 } 230 231 printf( "%s: %u files, %lu/%lu clusters\n", argv[optind], 232 n_files, fs.clusters - free_clusters, fs.clusters ); 233 234 return fs_close(rw) ? 1 : 0; 235} 236 237/* Local Variables: */ 238/* tab-width: 8 */ 239/* End: */ 240