00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <sys/types.h>
00019 #include <sys/ioc_disk.h>
00020 #include <minix/partition.h>
00021 #include <minix/u64.h>
00022 #include <time.h>
00023 #include <fcntl.h>
00024 #include <unistd.h>
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027
00028 #define CHUNK 25
00029 #define BLOCK_SIZE 1024
00030 #define RESUME 200
00031 #define DIVISOR 1000
00032 #define STORE 4096
00033
00034 int chunk = CHUNK;
00035 long goodies;
00036 long errors;
00037 int normal = 1;
00038 int total = 0;
00039 char *name;
00040
00041 char a[CHUNK * BLOCK_SIZE];
00042 long rotten[STORE];
00043
00044 _PROTOTYPE(int main, (int argc, char **argv));
00045 static _PROTOTYPE(void output, (long blocks_read));
00046
00047
00048
00049
00050 void
00051 prettyprogress(long b, long nblocks, time_t starttime)
00052 {
00053
00054 time_t spent, now;
00055 long bpsec;
00056 time(&now);
00057 spent = now - starttime;
00058 if(spent > 0 && (bpsec = b / spent) > 0) {
00059 int len, i;
00060 long secremain, minremain, hremain;
00061 secremain = (nblocks - b) / bpsec;
00062 minremain = (secremain / 60) % 60;
00063 hremain = secremain / 3600;
00064 len = fprintf(stderr, "Remain %ld blocks. ETA: %d:%02d:%02d [",
00065 nblocks - b,
00066 hremain, minremain, secremain % 60);
00067 #define WIDTH 77
00068 len = WIDTH - len;
00069 for(i = 0; i < (b * (len-1) / nblocks); i++)
00070 fprintf(stderr, "=");
00071 fprintf(stderr, "|");
00072 for(; i < len-2; i++)
00073 fprintf(stderr, "-");
00074 fprintf(stderr, "]\r");
00075 fflush(stderr);
00076 }
00077
00078 return;
00079 }
00080
00081 int main(argc, argv)
00082 int argc;
00083 char *argv[];
00084 {
00085 struct partition entry;
00086 int fd, s, i, badprinted;
00087 long b = 0, nblocks;
00088 char *p;
00089 time_t starttime;
00090
00091 if (argc != 2 && argc != 3) {
00092 fprintf(stderr, "Usage: readall [-b | -t] file\n");
00093 exit(1);
00094 }
00095 i = 1;
00096
00097 p = argv[1];
00098 if (*p == '-' && *(p + 1) == 'b' && *(p + 2) == '\0') {
00099 normal = 0;
00100 i++;
00101 name = argv[i];
00102 }
00103 if (*p == '-' && *(p + 1) == 't' && *(p + 2) == '\0') {
00104 normal = 0;
00105 total = 1;
00106 i++;
00107 name = argv[i];
00108 }
00109 fd = open(argv[i], O_RDONLY);
00110 if (fd < 0) {
00111 perror(argv[i]);
00112 fprintf(stderr, "%s is not readable\n", argv[i]);
00113 exit(1);
00114 }
00115
00116
00117 if(ioctl(fd, DIOCGETP, &entry) < 0) {
00118 perror("ioctl DIOCGETP");
00119 return 1;
00120 }
00121 nblocks = div64u(entry.size, BLOCK_SIZE);
00122
00123 time(&starttime);
00124
00125
00126 while (1) {
00127 if(lseek(fd, BLOCK_SIZE * b, SEEK_SET) < 0) {
00128 perror("lseek");
00129 return 1;
00130 }
00131 s = read(fd, a, BLOCK_SIZE * chunk);
00132 if (s == BLOCK_SIZE * chunk) {
00133
00134 b += chunk;
00135 goodies++;
00136 if (chunk == 1) {
00137 if (goodies >= RESUME && b % DIVISOR == 0)
00138 chunk = CHUNK;
00139 }
00140 if(b % DIVISOR == 0 && !normal) {
00141 prettyprogress(b, nblocks, starttime);
00142 }
00143 } else if (s < 0) {
00144
00145 if (chunk != 1) {
00146 chunk = 1;
00147 continue;
00148 }
00149 if (errors == STORE) {
00150 fprintf(stderr,
00151 "\n%ld Bad blocks is too many. Exiting\n",
00152 errors);
00153 exit(1);
00154 }
00155 rotten[(int) errors] = b;
00156 b += chunk;
00157 errors++;
00158 } else {
00159
00160 b += s / BLOCK_SIZE;
00161 if (normal) {
00162 output(b);
00163 fprintf(stderr, "\n");
00164 } else fprintf(stderr, "\r%*s\n", -WIDTH, "Done scanning.");
00165 if (total) printf("%8ld\n", b);
00166 if ((errors == 0) || total) exit(0);
00167 badprinted = 0;
00168 if (normal) printf("Summary of bad blocks\n");
00169
00170
00171 for (i = 0; i < errors; i++) {
00172 if (normal == 0 && badprinted == 0) {
00173 printf("badblocks %s ", name);
00174 badprinted = 1;
00175 }
00176 printf("%6ld ", rotten[i]);
00177 if ((i + 1) % 7 == 0) {
00178 printf("\n");
00179 badprinted = 0;
00180 }
00181 }
00182 printf("\n");
00183 exit(0);
00184 }
00185 if (normal && b % DIVISOR == 0) output(b);
00186 }
00187 }
00188
00189 static void output(blocks_read)
00190 long blocks_read;
00191 {
00192 fprintf(stderr, "%8ld blocks read, %5ld errors\r", blocks_read, errors);
00193 fflush(stderr);
00194 }