/*
 * Copyright (c) 2004-2015 Douglas Gilbert.
 * All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the BSD_LICENSE file.
 */

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
#include "sg_pr2serr.h"

/* A utility program for the Linux OS SCSI subsystem.
 *
 * This program issues the SCSI VERIFY(10) or VERIFY(16) command to the given
 * SCSI block device.
 *
 * N.B. This utility should, but doesn't, check the logical block size with
 * the SCSI READ CAPACITY command. It is up to the user to make sure that
 * the count of blocks requested and the number of bytes transferred (when
 * BYTCHK>0) are "in sync". That caclculation is somewhat complicated by
 * the possibility of protection data (DIF).
 */

static const char * version_str = "1.21 20140516";    /* sbc4r01 */

#define ME "sg_verify: "

#define EBUFF_SZ 256


static struct option long_options[] = {
        {"16", no_argument, 0, 'S'},
        {"bpc", required_argument, 0, 'b'},
        {"bytchk", required_argument, 0, 'B'},
        {"count", required_argument, 0, 'c'},
        {"dpo", no_argument, 0, 'd'},
        {"ebytchk", required_argument, 0, 'E'},
        {"group", required_argument, 0, 'g'},
        {"help", no_argument, 0, 'h'},
        {"in", required_argument, 0, 'i'},
        {"lba", required_argument, 0, 'l'},
        {"nbo", required_argument, 0, 'n'},
        {"quiet", no_argument, 0, 'q'},
        {"readonly", no_argument, 0, 'r'},
        {"verbose", no_argument, 0, 'v'},
        {"version", no_argument, 0, 'V'},
        {"vrprotect", required_argument, 0, 'P'},
        {0, 0, 0, 0},
};

static void
usage()
{
    pr2serr("Usage: sg_verify [--16] [--bpc=BPC] [--count=COUNT] [--dpo] "
            "[--ebytchk=BCH]\n"
            "                 [--group=GN] [--help] [--in=IF] "
            "[--lba=LBA] [--ndo=NDO]\n"
            "                 [--quiet] [--readonly] [--verbose] "
            "[--version]\n"
            "                 [--vrprotect=VRP] DEVICE\n"
            "  where:\n"
            "    --16|-S             use VERIFY(16) (def: use "
            "VERIFY(10) )\n"
            "    --bpc=BPC|-b BPC    max blocks per verify command "
            "(def: 128)\n"
            "    --count=COUNT|-c COUNT    count of blocks to verify "
            "(def: 1).\n"
            "                              If BCH=3 then COUNT must "
            "be 1 .\n"
            "    --dpo|-d            disable page out (cache retention "
            "priority)\n"
            "    --ebytchk=BCH|-E BCH    sets BYTCHK value, either 1, 2 "
            "or 3 (def: 0).\n"
            "                            BCH overrides BYTCHK=1 set by "
            "'--ndo='. If\n"
            "                            BCH is 3 then NDO must be the LBA "
            "size\n"
            "                            (plus protection size if DIF "
            "active)\n"
            "    --group=GN|-g GN    set group number field to GN (def: 0)\n"
            "    --help|-h           print out usage message\n"
            "    --in=IF|-i IF       input from file called IF (def: "
            "stdin)\n"
            "                        only active if --bytchk=N given\n"
            "    --lba=LBA|-l LBA    logical block address to start "
            "verify (def: 0)\n"
            "    --ndo=NDO|-n NDO    NDO is number of bytes placed in "
            "data-out buffer.\n"
            "                        These are fetched from IF (or "
            "stdin) and used\n"
            "                        to verify the device data against. "
            "Forces\n"
            "                        --bpc=COUNT. Sets BYTCHK (byte check) "
            "to 1\n"
            "    --quiet|-q          suppress miscompare report to stderr, "
            "still\n"
            "                        causes an exit status of 14\n"
            "    --readonly|-r       open DEVICE read-only (def: open it "
            "read-write)\n"
            "    --verbose|-v        increase verbosity\n"
            "    --version|-V        print version string and exit\n"
            "    --vrprotect=VRP|-P VRP    set vrprotect field to VRP "
            "(def: 0)\n"
            "Performs one or more SCSI VERIFY(10) or SCSI VERIFY(16) "
            "commands. sbc3r34\nmade the BYTCHK field two bits wide "
            "(it was a single bit).\n");
}

int
main(int argc, char * argv[])
{
    int sg_fd, res, c, num, nread, infd;
    int64_t ll;
    int dpo = 0;
    int bytchk = 0;
    int ndo = 0;
    char *ref_data = NULL;
    int vrprotect = 0;
    int64_t count = 1;
    int64_t orig_count;
    int bpc = 128;
    int bpc_given = 0;
    int got_stdin = 0;
    int group = 0;
    uint64_t lba = 0;
    uint64_t orig_lba;
    int quiet = 0;
    int readonly = 0;
    int verbose = 0;
    int verify16 = 0;
    const char * device_name = NULL;
    const char * file_name = NULL;
    const char * vc;
    int ret = 0;
    unsigned int info = 0;
    uint64_t info64 = 0;
    char ebuff[EBUFF_SZ];

    while (1) {
        int option_index = 0;

        c = getopt_long(argc, argv, "b:B:c:dE:g:hi:l:n:P:qrSvV", long_options,
                        &option_index);
        if (c == -1)
            break;

        switch (c) {
        case 'b':
            bpc = sg_get_num(optarg);
            if (bpc < 1) {
                pr2serr("bad argument to '--bpc'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            ++bpc_given;
            break;
        case 'c':
            count = sg_get_llnum(optarg);
            if (count < 0) {
                pr2serr("bad argument to '--count'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            break;
        case 'd':
            dpo = 1;
            break;
        case 'E':
            bytchk = sg_get_num(optarg);
            if ((bytchk < 1) || (bytchk > 3)) {
                pr2serr("bad argument to '--ebytchk'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            break;
        case 'g':
            group = sg_get_num(optarg);
            if ((group < 0) || (group > 31)) {
                pr2serr("bad argument to '--group'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            break;
        case 'h':
        case '?':
            usage();
            return 0;
        case 'i':
            file_name = optarg;
            break;
        case 'l':
            ll = sg_get_llnum(optarg);
            if (-1 == ll) {
                pr2serr("bad argument to '--lba'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            lba = (uint64_t)ll;
            break;
        case 'n':
        case 'B':       /* undocumented, old --bytchk=NDO option */
            ndo = sg_get_num(optarg);
            if (ndo < 1) {
                pr2serr("bad argument to '--ndo'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            break;
        case 'P':
            vrprotect = sg_get_num(optarg);
            if (-1 == vrprotect) {
                pr2serr("bad argument to '--vrprotect'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            if ((vrprotect < 0) || (vrprotect > 7)) {
                pr2serr("'--vrprotect' requires a value from 0 to 7 "
                        "(inclusive)\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            break;
        case 'q':
            ++quiet;
            break;
        case 'r':
            ++readonly;
            break;
        case 'S':
            ++verify16;
            break;
        case 'v':
            ++verbose;
            break;
        case 'V':
            pr2serr(ME "version: %s\n", version_str);
            return 0;
        default:
            pr2serr("unrecognised option code 0x%x ??\n", c);
            usage();
            return SG_LIB_SYNTAX_ERROR;
        }
    }
    if (optind < argc) {
        if (NULL == device_name) {
            device_name = argv[optind];
            ++optind;
        }
        if (optind < argc) {
            for (; optind < argc; ++optind)
                pr2serr("Unexpected extra argument: %s\n", argv[optind]);
            usage();
            return SG_LIB_SYNTAX_ERROR;
        }
    }
    if (ndo > 0) {
        if (0 == bytchk)
            bytchk = 1;
        if (bpc_given && (bpc != count))
            pr2serr("'bpc' argument ignored, using --bpc=%" PRIu64 "\n",
                    count);
        if (count > 0x7fffffffLL) {
            pr2serr("count exceed 31 bits, way too large\n");
            return SG_LIB_SYNTAX_ERROR;
        }
        if ((3 == bytchk) && (1 != count)) {
            pr2serr("count must be 1 when bytchk=3\n");
            return SG_LIB_SYNTAX_ERROR;
        }
        bpc = (int)count;
    } else if (bytchk > 0) {
        pr2serr("when the 'ebytchk=BCH' option is given, then '--bytchk=NDO' "
                "must also be given\n");
        return SG_LIB_SYNTAX_ERROR;
    }

    if ((bpc > 0xffff) && (0 == verify16)) {
        pr2serr("'%s' exceeds 65535, so use VERIFY(16)\n",
                (ndo > 0) ? "count" : "bpc");
        ++verify16;
    }
    if (((lba + count - 1) > 0xffffffffLLU) && (0 == verify16)) {
        pr2serr("'lba' exceed 32 bits, so use VERIFY(16)\n");
        ++verify16;
    }
    if ((group > 0) && (0 == verify16))
        pr2serr("group number ignored with VERIFY(10) command, use the --16 "
                "option\n");

    orig_count = count;
    orig_lba = lba;

    if (ndo > 0) {
        ref_data = (char *)malloc(ndo);
        if (NULL == ref_data) {
            pr2serr("failed to allocate %d byte buffer\n", ndo);
            return SG_LIB_FILE_ERROR;
        }
        if ((NULL == file_name) || (0 == strcmp(file_name, "-"))) {
            ++got_stdin;
            infd = STDIN_FILENO;
            if (sg_set_binary_mode(STDIN_FILENO) < 0)
                perror("sg_set_binary_mode");
        } else {
            if ((infd = open(file_name, O_RDONLY)) < 0) {
                snprintf(ebuff, EBUFF_SZ,
                         ME "could not open %s for reading", file_name);
                perror(ebuff);
                ret = SG_LIB_FILE_ERROR;
                goto err_out;
            } else if (sg_set_binary_mode(infd) < 0)
                perror("sg_set_binary_mode");
        }
        if (verbose && got_stdin)
                pr2serr("about to wait on STDIN\n");
        for (nread = 0; nread < ndo; nread += res) {
            res = read(infd, ref_data + nread, ndo - nread);
            if (res <= 0) {
                pr2serr("reading from %s failed at file offset=%d\n",
                        (got_stdin ? "stdin" : file_name), nread);
                ret = SG_LIB_FILE_ERROR;
                goto err_out;
            }
        }
        if (! got_stdin)
            close(infd);
    }

    if (NULL == device_name) {
        pr2serr("missing device name!\n");
        usage();
        ret = SG_LIB_SYNTAX_ERROR;
        goto err_out;
    }
    sg_fd = sg_cmds_open_device(device_name, readonly, verbose);
    if (sg_fd < 0) {
        pr2serr(ME "open error: %s: %s\n", device_name, safe_strerror(-sg_fd));
        ret = SG_LIB_FILE_ERROR;
        goto err_out;
    }

    vc = verify16 ? "VERIFY(16)" : "VERIFY(10)";
    for (; count > 0; count -= bpc, lba += bpc) {
        num = (count > bpc) ? bpc : count;
        if (verify16)
            res = sg_ll_verify16(sg_fd, vrprotect, dpo, bytchk,
                                 lba, num, group, ref_data,
                                 ndo, &info64, !quiet , verbose);
        else
            res = sg_ll_verify10(sg_fd, vrprotect, dpo, bytchk,
                                 (unsigned int)lba, num, ref_data,
                                 ndo, &info, !quiet, verbose);
        if (0 != res) {
            char b[80];

            ret = res;
            switch (res) {
            case SG_LIB_CAT_ILLEGAL_REQ:
                pr2serr("bad field in %s cdb, near lba=0x%" PRIx64 "\n", vc,
                        lba);
                break;
            case SG_LIB_CAT_MEDIUM_HARD:
                pr2serr("%s medium or hardware error near lba=0x%" PRIx64 "\n",
                        vc, lba);
                break;
            case SG_LIB_CAT_MEDIUM_HARD_WITH_INFO:
                if (verify16)
                    pr2serr("%s medium or hardware error, reported lba=0x%"
                            PRIx64 "\n", vc, info64);
                else
                    pr2serr("%s medium or hardware error, reported lba=0x%x\n",
                            vc, info);
                break;
            case SG_LIB_CAT_MISCOMPARE:
                if ((0 == quiet) || verbose)
                    pr2serr("%s reported MISCOMPARE\n", vc);
                break;
            default:
                sg_get_category_sense_str(res, sizeof(b), b, verbose);
                pr2serr("%s: %s\n", vc, b);
                pr2serr("    failed near lba=%" PRIu64 " [0x%" PRIx64 "]\n",
                        lba, lba);
                break;
            }
            break;
        }
    }

    if (verbose && (0 == ret) && (orig_count > 1))
        pr2serr("Verified %" PRId64 " [0x%" PRIx64 "] blocks from lba %" PRIu64
                " [0x%" PRIx64 "]\n    without error\n", orig_count,
                (uint64_t)orig_count, orig_lba, orig_lba);

    res = sg_cmds_close_device(sg_fd);
    if (res < 0) {
        pr2serr("close error: %s\n", safe_strerror(-res));
        if (0 == ret)
            ret = SG_LIB_FILE_ERROR;
    }

 err_out:
    if (ref_data)
        free(ref_data);
    return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
}
