Ejemplo n.º 1
0
int
main(int argc, char *argv[])
{
    int k;
    int ret = 0;
    unsigned int ui;
    size_t s;
    struct opts_t opts;
    struct opts_t * op;
    char b[2048];
    FILE * fp = NULL;
    const char * cp;

    op = &opts;
    memset(op, 0, sizeof(opts));
    memset(b, 0, sizeof(b));
    ret = process_cl(op, argc, argv);
    if (ret != 0) {
        usage();
        return ret;
    } else if (op->do_help) {
        usage();
        return 0;
    } else if (op->do_version) {
        pr2serr("version: %s\n", version_str);
        return 0;
    }


    if (op->do_status) {
        sg_get_scsi_status_str(op->sstatus, sizeof(b) - 1, b);
        printf("SCSI status: %s\n", b);
    }

    if ((0 == op->sense_len) && op->no_space_str) {
        if (op->do_verbose > 2)
            pr2serr("no_space str: %s\n", op->no_space_str);
        cp = op->no_space_str;
        for (k = 0; isxdigit(cp[k]) && isxdigit(cp[k + 1]); k += 2) {
            if (1 != sscanf(cp + k, "%2x", &ui)) {
                pr2serr("bad no_space hex string: %s\n", cp);
                return SG_LIB_SYNTAX_ERROR;
            }
            op->sense[op->sense_len++] = (unsigned char)ui;
        }
    }

    if ((0 == op->sense_len) && (! op->do_binary) && (! op->do_file)) {
        if (op->do_status)
            return 0;
        pr2serr(">> Need sense data on the command line or in a file\n\n");
        usage();
        return SG_LIB_SYNTAX_ERROR;
    }
    if (op->sense_len && (op->do_binary || op->do_file)) {
        pr2serr(">> Need sense data on command line or in a file, not "
                "both\n\n");
        return SG_LIB_SYNTAX_ERROR;
    }
    if (op->do_binary && op->do_file) {
        pr2serr(">> Either a binary file or a ASCII hexadecimal, file not "
                "both\n\n");
        return SG_LIB_SYNTAX_ERROR;
    }

    if (op->do_binary) {
        fp = fopen(op->fname, "r");
        if (NULL == fp) {
            pr2serr("unable to open file: %s\n", op->fname);
            return SG_LIB_SYNTAX_ERROR;
        }
        s = fread(op->sense, 1, MAX_SENSE_LEN, fp);
        fclose(fp);
        if (0 == s) {
            pr2serr("read nothing from file: %s\n", op->fname);
            return SG_LIB_SYNTAX_ERROR;
        }
        op->sense_len = s;
    } else if (op->do_file) {
        ret = f2hex_arr(op->fname, op->no_space, op->sense, &op->sense_len,
                        MAX_SENSE_LEN);
        if (ret) {
            pr2serr("unable to decode ASCII hex from file: %s\n", op->fname);
            return SG_LIB_SYNTAX_ERROR;
        }
    }

    if (op->sense_len) {
        if (op->wfname) {
            if ((fp = fopen(op->wfname, "w"))) {
                write2wfn(fp, op);
                fclose(fp);
            } else {
                perror("open");
                pr2serr("trying to write to %s\n", op->wfname);
            }
        }
        if (op->do_cdb) {
            int sa, opcode;

            opcode = op->sense[0];
            if ((0x75 == opcode) || (0x7e == opcode) || (op->sense_len > 16))
                sa = sg_get_unaligned_be16(op->sense + 8);
            else if (op->sense_len > 1)
                sa = op->sense[1] & 0x1f;
            else
                sa = 0;
            sg_get_opcode_sa_name(opcode, sa, 0, sizeof(b), b);
        } else
            sg_get_sense_str(NULL, op->sense, op->sense_len,
                             op->do_verbose, sizeof(b) - 1, b);
        printf("%s\n", b);
    }

    return 0;
}
Ejemplo n.º 2
0
static int
process_cl(struct opts_t * op, int argc, char *argv[])
{
    while (1) {
        int c, n;

        c = getopt_long(argc, argv, "bhi:k:no:r:Rs:t:vV", long_options, NULL);
        if (c == -1)
            break;

        switch (c) {
        case 'b':
            op->datain_binary = 1;
            break;
        case 'h':
        case '?':
            op->do_help = 1;
            return 0;
        case 'i':
            if (op->dataout_file) {
                fprintf(stderr, "Too many '--infile=' options\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            op->dataout_file = optarg;
            break;
        case 'k':
            n = sg_get_num(optarg);
            if (n < 0) {
                fprintf(stderr, "Invalid argument to '--skip'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            op->dataout_offset = n;
            break;
        case 'n':
            op->no_sense = 1;
            break;
        case 'o':
            if (op->datain_file) {
                fprintf(stderr, "Too many '--outfile=' options\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            op->datain_file = optarg;
            break;
        case 'r':
            op->do_datain = 1;
            n = sg_get_num(optarg);
            if (n < 0 || n > MAX_SCSI_DXLEN) {
                fprintf(stderr, "Invalid argument to '--request'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            op->datain_len = n;
            break;
        case 'R':
            ++op->readonly;
            break;
        case 's':
            op->do_dataout = 1;
            n = sg_get_num(optarg);
            if (n < 0 || n > MAX_SCSI_DXLEN) {
                fprintf(stderr, "Invalid argument to '--send'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            op->dataout_len = n;
            break;
        case 't':
            n = sg_get_num(optarg);
            if (n < 0) {
                fprintf(stderr, "Invalid argument to '--timeout'\n");
                return SG_LIB_SYNTAX_ERROR;
            }
            op->timeout = n;
            break;
        case 'v':
            ++op->do_verbose;
            break;
        case 'V':
            op->do_version = 1;
            return 0;
        default:
            return SG_LIB_SYNTAX_ERROR;
        }
    }

    if (optind >= argc) {
        fprintf(stderr, "No device specified\n");
        return SG_LIB_SYNTAX_ERROR;
    }
    op->device_name = argv[optind];
    ++optind;

    while (optind < argc) {
        char *opt = argv[optind++];
        char *endptr;
        int cmd = strtol(opt, &endptr, 16);
        if (*opt == '\0' || *endptr != '\0' || cmd < 0x00 || cmd > 0xff) {
            fprintf(stderr, "Invalid command byte '%s'\n", opt);
            return SG_LIB_SYNTAX_ERROR;
        }

        if (op->cdb_length > MAX_SCSI_CDBSZ) {
            fprintf(stderr, "CDB too long (max. %d bytes)\n", MAX_SCSI_CDBSZ);
            return SG_LIB_SYNTAX_ERROR;
        }
        op->cdb[op->cdb_length] = cmd;
        ++op->cdb_length;
    }

    if (op->cdb_length < MIN_SCSI_CDBSZ) {
        fprintf(stderr, "CDB too short (min. %d bytes)\n", MIN_SCSI_CDBSZ);
        return SG_LIB_SYNTAX_ERROR;
    }
    if (op->do_verbose > 2) {
        int sa;
        char b[80];

        if (op->cdb_length > 16) {
            sa = (op->cdb[8] << 8) + op->cdb[9];
            if (0x7f != op->cdb[0])
                printf(">>> Unlikely to be SCSI CDB since all over 16 "
                       "bytes long should\n>>> start with 0x7f\n");
        } else
            sa = op->cdb[1] & 0x1f;
        sg_get_opcode_sa_name(op->cdb[0], sa, 0, sizeof(b), b);
        printf("Attempt to decode cdb name: %s\n", b);
    }
    return 0;
}