示例#1
0
int
main(int argc, char * argv[])
{
    int sg_fd, res, c;
    int do_origin = 0;
    int do_set = 0;
    int do_srep = 0;
    int do_raw = 0;
    int readonly = 0;
    bool secs_given = false;
    int verbose = 0;
    uint64_t secs = 0;
    uint64_t msecs = 0;
    int64_t ll;
    const char * device_name = NULL;
    const char * cmd_name;
    int ret = 0;

    while (1) {
        int option_index = 0;

        c = getopt_long(argc, argv, "hm:orRs:SvV", long_options,
                        &option_index);
        if (c == -1)
            break;

        switch (c) {
        case 'h':
        case '?':
            usage();
            return 0;
        case 'm':
            ll = sg_get_llnum(optarg);
            if (-1 == ll) {
                pr2serr("bad argument to '--milliseconds=MS'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            msecs = (uint64_t)ll;
            ++do_set;
            break;
        case 'o':
            ++do_origin;
            break;
        case 'r':
            ++do_raw;
            break;
        case 'R':
            ++readonly;
            break;
        case 's':
            ll = sg_get_llnum(optarg);
            if (-1 == ll) {
                pr2serr("bad argument to '--seconds=SEC'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            secs = (uint64_t)ll;
            ++do_set;
            secs_given = true;
            break;
        case 'S':
            ++do_srep;
            break;
        case 'v':
            ++verbose;
            break;
        case 'V':
            pr2serr("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 (do_set > 1) {
        pr2serr("either --milliseconds=MS or --seconds=SEC may be given, "
                "not both\n");
        usage();
        return SG_LIB_SYNTAX_ERROR;
    }

    if (NULL == device_name) {
        pr2serr("missing device name!\n");
        usage();
        return SG_LIB_SYNTAX_ERROR;
    }

    sg_fd = sg_cmds_open_device(device_name, readonly, verbose);
    if (sg_fd < 0) {
        pr2serr("open error: %s: %s\n", device_name,
                safe_strerror(-sg_fd));
        return SG_LIB_FILE_ERROR;
    }

    memset(d_buff, 0, 12);
    if (do_set) {
        cmd_name = "Set timestamp";
        sg_put_unaligned_be48(secs_given ? (secs * 1000) : msecs, d_buff + 4);
        res = sg_ll_set_timestamp(sg_fd, d_buff, 12, 1, verbose);
    } else {
        cmd_name = "Report timestamp";
        res = sg_ll_rep_timestamp(sg_fd, d_buff, 12, NULL, 1, verbose);
        if (0 == res) {
            if (do_raw)
                dStrRaw((const char *)d_buff, 12);
            else {
                int len = sg_get_unaligned_be16(d_buff + 0);
                if (len < 8)
                    pr2serr("timestamp parameter data length too short, "
                            "expect >= 10, got %d\n", len + 2);
                else {
                    if (do_origin)
                        printf("Device clock %s\n",
                               ts_origin_arr[0x7 & d_buff[2]]);
                    msecs = sg_get_unaligned_be48(d_buff + 4);
                    printf("%" PRIu64 "\n", do_srep ? (msecs / 1000) : msecs);
                }
            }
        }
    }
    ret = res;
    if (res) {
        if (SG_LIB_CAT_INVALID_OP == res)
            pr2serr("%s command not supported\n", cmd_name);
        else {
            char b[80];

            sg_get_category_sense_str(res, sizeof(b), b, verbose);
            pr2serr("%s command: %s\n", cmd_name, b);
        }
    }

    res = sg_cmds_close_device(sg_fd);
    if (res < 0) {
        pr2serr("close error: %s\n", safe_strerror(-res));
        if (0 == ret)
            return SG_LIB_FILE_ERROR;
    }
    return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
}
示例#2
0
static void
helper_full_attr(const unsigned char * alp, int len, int id,
                 const struct attr_name_info_t * anip,
                 const struct opts_t * op)
{
    int k;
    const unsigned char * bp;

    if (op->verbose)
        printf("[r%c] ", (0x80 & alp[2]) ? 'o' : 'w');
    if (op->verbose > 3)
        pr2serr("%s: id=0x%x, len=%d, anip->format=%d, anip->len=%d\n",
                __func__, id, len, anip->format, anip->len);
    switch (id) {
    case 0x224:         /* logical position of first encrypted block */
        k = all_ffs_or_last_fe(alp + 5, len - 5);
        if (1 == k)
            printf("<unknown> [ff]\n");
        else if (2 == k)
            printf("<unknown [fe]>\n");
        else {
            if ((len - 5) <= 8)
                printf("%" PRIx64, sg_get_unaligned_be(len - 5, alp + 5));
            else {
                printf("\n");
                dStrHex((const char *)(alp + 5), len - 5, 0);
            }
        }
        break;
    case 0x225:         /* logical position of first unencrypted block
                         * after first encrypted block */
        k = all_ffs_or_last_fe(alp + 5, len - 5);
        if (1 == k)
            printf("<unknown> [ff]\n");
        else if (2 == k)
            printf("<unknown [fe]>\n");
        else {
            if ((len - 5) <= 8)
                printf("%" PRIx64, sg_get_unaligned_be(len - 5, alp + 5));
            else {
                printf("\n");
                dStrHex((const char *)(alp + 5), len - 5, 0);
            }
        }
        break;
    case 0x340:         /* Medium Usage history */
        bp = alp + 5;
        printf("\n");
        if ((len - 5) < 90) {
            pr2serr("%s: expected 90 bytes, got %d\n", __func__, len - 5);
            break;
        }
        printf("    Current amount of data written [MiB]: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 0));
        printf("    Current write retry count: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 6));
        printf("    Current amount of data read [MiB]: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 12));
        printf("    Current read retry count: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 18));
        printf("    Previous amount of data written [MiB]: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 24));
        printf("    Previous write retry count: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 30));
        printf("    Previous amount of data read [MiB]: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 36));
        printf("    Previous read retry count: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 42));
        printf("    Total amount of data written [MiB]: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 48));
        printf("    Total write retry count: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 54));
        printf("    Total amount of data read [MiB]: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 60));
        printf("    Total read retry count: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 66));
        printf("    Load count: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 72));
        printf("    Total change partition count: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 78));
        printf("    Total partition initialization count: %" PRIu64 "\n",
               sg_get_unaligned_be48(bp + 84));
        break;
    case 0x341:         /* Partition Usage history */
        bp = alp + 5;
        printf("\n");
        if ((len - 5) < 60) {
            pr2serr("%s: expected 60 bytes, got %d\n", __func__, len - 5);
            break;
        }
        printf("    Current amount of data written [MiB]: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 0));
        printf("    Current write retry count: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 4));
        printf("    Current amount of data read [MiB]: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 8));
        printf("    Current read retry count: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 12));
        printf("    Previous amount of data written [MiB]: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 16));
        printf("    Previous write retry count: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 20));
        printf("    Previous amount of data read [MiB]: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 24));
        printf("    Previous read retry count: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 28));
        printf("    Total amount of data written [MiB]: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 32));
        printf("    Total write retry count: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 36));
        printf("    Total amount of data read [MiB]: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 40));
        printf("    Total read retry count: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 44));
        printf("    Load count: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 48));
        printf("    change partition count: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 52));
        printf("    partition initialization count: %" PRIu32 "\n",
               sg_get_unaligned_be32(bp + 56));
        break;
    default:
        pr2serr("%s: unknown attribute id: 0x%x\n", __func__, id);
        printf("  In hex:\n");
        dStrHex((const char *)alp, len, 0);
        break;
    }
}