/*****************************************************************************
 * Author   : Jim Brooks <jim@jimbrooks.org>
 * Purpose  : Linux code to read blocks on a disk partition.
 *            Could be developed into a bad disk block checker.
 * WARNING  : The code here is intended as examples or skeletons
 *            which you should modify or adapt yourself.
 *            Don't blindly compile the sources and try running the code!!!
 * Legal    : Released without restrictions into the public domain.
 *            This software is provided "AS-IS" without any express or implied
 *            warranty nor guarantee.  In no event will the author be held
 *            liable for any damages arising from the use of this software
 *            nor derivative works.
 *****************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define DEV_PART    "/dev/hda9"     /* IDE disk partition */
/*#define DEV_PART  "/dev/sdb9"*/   /* SCSI disk partition */
#define BLK_SIZE    1024
#define PRINT_PROGRESS_INTERVAL (BLK_SIZE * 1000)

int
main( int argc, char** argv )
{
    int         fd          = -1;
    char*       pBuf        = NULL;
    long long   blocks      = 0;
    long long   bytes       = 0;        /* int is insufficient for partitions > 4GB */
    long long   bytesRead   = 0;

    pBuf = malloc( BLK_SIZE * 2 );

    fd = open( DEV_PART, O_RDONLY );
    if ( fd < 0 )
        goto Error;

    bytes = blocks = 0;

    for (;;)
    {
        bytesRead = read( fd, pBuf, BLK_SIZE );
        if ( bytesRead <= 0 )
            break;

        bytes += bytesRead;

        blocks = bytes / BLK_SIZE;

        if ( bytes % PRINT_PROGRESS_INTERVAL == 0 )
            printf( "...read %lld blocks (%lld bytes) \n", blocks, bytes );
    }

    printf( "Done.  Total: read %lld blocks (%lld bytes) \n", blocks, bytes );
    exit( 0 );

Error:
    perror( "" );
    exit( 1 );
}
