- int ctrl;
- int verify;
- struct stat st;
- struct floppy_struct param;
-
- if (argc < 2) {
- bb_show_usage();
- }
- verify = !bb_getopt_ulflags(argc, argv, "n");
- argv += optind;
-
- if (stat(*argv,&st) < 0 || access(*argv,W_OK) < 0) {
- bb_perror_msg_and_die(*argv);
- }
- if (!S_ISBLK(st.st_mode)) {
- bb_error_msg_and_die("%s: not a block device",*argv);
- /* do not test major - perhaps this was an USB floppy */
- }
-
- ctrl = bb_xopen(*argv,O_WRONLY);
- if (ioctl(ctrl,FDGETPRM,(long) ¶m) < 0) {
- bb_perror_msg_and_die("Could not determine current format type");
- }
- printf("%s-sided, %d tracks, %d sec/track. Total capacity %d kB.\n",
- (param.head == 2) ? "Double" : "Single",
- param.track, param.sect,param.size >> 1);
- format_disk(ctrl, *argv, ¶m);
- close(ctrl);
-
- if (verify) {
- verify_disk(*argv, ¶m);
- }
- return EXIT_SUCCESS;
+ int fd, n, cyl, read_bytes, verify;
+ unsigned char *data;
+ struct stat st;
+ struct floppy_struct param;
+ struct format_descr descr;
+
+ if (argc < 2) {
+ bb_show_usage();
+ }
+ verify = !bb_getopt_ulflags(argc, argv, "n");
+ argv += optind;
+
+ /* R_OK is needed for verifying */
+ if (stat(*argv,&st) < 0 || access(*argv,W_OK | R_OK ) < 0) {
+ bb_perror_msg_and_die(*argv);
+ }
+ if (!S_ISBLK(st.st_mode)) {
+ bb_error_msg_and_die("%s: not a block device",*argv);
+ /* do not test major - perhaps this was an USB floppy */
+ }
+
+
+ /* O_RDWR for formatting and verifying */
+ fd = bb_xopen(*argv,O_RDWR );
+
+ bb_xioctl(fd, FDGETPRM, ¶m, "FDGETPRM");/*original message was: "Could not determine current format type" */
+
+ print_and_flush("%s-sided, %d tracks, %d sec/track. Total capacity %d kB.\n",
+ (param.head == 2) ? "Double" : "Single",
+ param.track, param.sect, param.size >> 1);
+
+ /* FORMAT */
+ print_and_flush("Formatting ... ", NULL);
+ bb_xioctl(fd, FDFMTBEG,NULL,"FDFMTBEG");
+
+ /* n == track */
+ for (n = 0; n < param.track; n++)
+ {
+ descr.head = 0;
+ descr.track = n;
+ bb_xioctl(fd, FDFMTTRK,&descr,"FDFMTTRK");
+ print_and_flush("%3d\b\b\b", n);
+ if (param.head == 2) {
+ descr.head = 1;
+ bb_xioctl(fd, FDFMTTRK,&descr,"FDFMTTRK");
+ }
+ }
+
+ bb_xioctl(fd,FDFMTEND,NULL,"FDFMTEND");
+ print_and_flush("done\n", NULL);
+
+ /* VERIFY */
+ if(verify) {
+ /* n == cyl_size */
+ n = param.sect*param.head*512;
+
+ data = xmalloc(n);
+ print_and_flush("Verifying ... ", NULL);
+ for (cyl = 0; cyl < param.track; cyl++) {
+ print_and_flush("%3d\b\b\b", cyl);
+ if((read_bytes = safe_read(fd,data,n))!= n ) {
+ if(read_bytes < 0) {
+ bb_perror_msg("Read: ");
+ }
+ bb_error_msg_and_die("Problem reading cylinder %d, expected %d, read %d", cyl, n, read_bytes);
+ }
+ /* Check backwards so we don't need a counter */
+ while(--read_bytes>=0) {
+ if( data[read_bytes] != FD_FILL_BYTE) {
+ print_and_flush("bad data in cyl %d\nContinuing ... ",cyl);
+ }
+ }
+ }
+ /* There is no point in freeing blocks at the end of a program, because
+ all of the program's space is given back to the system when the process
+ terminates.*/
+
+ if (ENABLE_FEATURE_CLEAN_UP) free(data);
+
+ print_and_flush("done\n", NULL);
+ }
+
+ if (ENABLE_FEATURE_CLEAN_UP) close(fd);
+
+ /* Don't bother closing. Exit does
+ * that, so we can save a few bytes */
+ return EXIT_SUCCESS;