dosfsck.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /* dosfsck.c - User interface */
  2. /* Written 1993 by Werner Almesberger */
  3. /* FAT32, VFAT, Atari format support, and various fixes additions May 1998
  4. * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
  5. #include "version.h"
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <unistd.h>
  11. #include <getopt.h>
  12. #include "common.h"
  13. #include "dosfsck.h"
  14. #include "io.h"
  15. #include "boot.h"
  16. #include "fat.h"
  17. #include "file.h"
  18. #include "check.h"
  19. int interactive = 0,list = 0,test = 0,verbose = 0,write_immed = 0;
  20. int atari_format = 0;
  21. unsigned n_files = 0;
  22. void *mem_queue = NULL;
  23. static void usage(char *name)
  24. {
  25. fprintf(stderr,"usage: %s [-aAflrtvVwy] [-d path -d ...] "
  26. "[-u path -u ...]\n%15sdevice\n",name,"");
  27. fprintf(stderr," -a automatically repair the file system\n");
  28. fprintf(stderr," -A toggle Atari file system format\n");
  29. fprintf(stderr," -d path drop that file\n");
  30. fprintf(stderr," -f salvage unused chains to files\n");
  31. fprintf(stderr," -l list path names\n");
  32. fprintf(stderr," -n no-op, check non-interactively without changing\n");
  33. fprintf(stderr," -p same as -a, for compat with other *fsck\n");
  34. fprintf(stderr," -r interactively repair the file system\n");
  35. fprintf(stderr," -t test for bad clusters\n");
  36. fprintf(stderr," -u path try to undelete that (non-directory) file\n");
  37. fprintf(stderr," -v verbose mode\n");
  38. fprintf(stderr," -V perform a verification pass\n");
  39. fprintf(stderr," -w write changes to disk immediately\n");
  40. fprintf(stderr," -y same as -a, for compat with other *fsck\n");
  41. exit(2);
  42. }
  43. /*
  44. * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant
  45. * of MS-DOS filesystem by default.
  46. */
  47. static void check_atari( void )
  48. {
  49. #ifdef __mc68000__
  50. FILE *f;
  51. char line[128], *p;
  52. if (!(f = fopen( "/proc/hardware", "r" ))) {
  53. perror( "/proc/hardware" );
  54. return;
  55. }
  56. while( fgets( line, sizeof(line), f ) ) {
  57. if (strncmp( line, "Model:", 6 ) == 0) {
  58. p = line + 6;
  59. p += strspn( p, " \t" );
  60. if (strncmp( p, "Atari ", 6 ) == 0)
  61. atari_format = 1;
  62. break;
  63. }
  64. }
  65. fclose( f );
  66. #endif
  67. }
  68. int main(int argc,char **argv)
  69. {
  70. DOS_FS fs;
  71. int rw,salvage_files,verify,c;
  72. unsigned n_files_check=0, n_files_verify=0;
  73. unsigned long free_clusters;
  74. rw = salvage_files = verify = 0;
  75. interactive = 1;
  76. check_atari();
  77. while ((c = getopt(argc,argv,"Aad:flnprtu:vVwy")) != EOF)
  78. switch (c) {
  79. case 'A': /* toggle Atari format */
  80. atari_format = !atari_format;
  81. break;
  82. case 'a':
  83. case 'p':
  84. case 'y':
  85. rw = 1;
  86. interactive = 0;
  87. salvage_files = 1;
  88. break;
  89. case 'd':
  90. file_add(optarg,fdt_drop);
  91. break;
  92. case 'f':
  93. salvage_files = 1;
  94. break;
  95. case 'l':
  96. list = 1;
  97. break;
  98. case 'n':
  99. rw = 0;
  100. interactive = 0;
  101. break;
  102. case 'r':
  103. rw = 1;
  104. interactive = 1;
  105. break;
  106. case 't':
  107. test = 1;
  108. break;
  109. case 'u':
  110. file_add(optarg,fdt_undelete);
  111. break;
  112. case 'v':
  113. verbose = 1;
  114. printf("dosfsck " VERSION " (" VERSION_DATE ")\n");
  115. break;
  116. case 'V':
  117. verify = 1;
  118. break;
  119. case 'w':
  120. write_immed = 1;
  121. break;
  122. default:
  123. usage(argv[0]);
  124. }
  125. if ((test || write_immed) && !rw) {
  126. fprintf(stderr,"-t and -w require -a or -r\n");
  127. exit(2);
  128. }
  129. if (optind != argc-1) usage(argv[0]);
  130. printf( "dosfsck " VERSION ", " VERSION_DATE ", FAT32, LFN\n" );
  131. fs_open(argv[optind],rw);
  132. read_boot(&fs);
  133. if (verify) printf("Starting check/repair pass.\n");
  134. while (read_fat(&fs), scan_root(&fs)) qfree(&mem_queue);
  135. if (test) fix_bad(&fs);
  136. if (salvage_files) reclaim_file(&fs);
  137. else reclaim_free(&fs);
  138. free_clusters = update_free(&fs);
  139. file_unused();
  140. qfree(&mem_queue);
  141. n_files_check = n_files;
  142. if (verify) {
  143. n_files = 0;
  144. printf("Starting verification pass.\n");
  145. read_fat(&fs);
  146. scan_root(&fs);
  147. reclaim_free(&fs);
  148. qfree(&mem_queue);
  149. n_files_verify = n_files;
  150. }
  151. if (fs_changed()) {
  152. if (rw) {
  153. if (interactive)
  154. rw = get_key("yn","Perform changes ? (y/n)") == 'y';
  155. else printf("Performing changes.\n");
  156. }
  157. else
  158. printf("Leaving file system unchanged.\n");
  159. }
  160. printf( "%s: %u files, %lu/%lu clusters\n", argv[optind],
  161. n_files, fs.clusters - free_clusters, fs.clusters );
  162. return fs_close(rw) ? 1 : 0;
  163. }
  164. /* Local Variables: */
  165. /* tab-width: 8 */
  166. /* End: */