/*
 * Copyright (c) 2006-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>
#include <ctype.h>
#include <errno.h>

#include "sg_lib.h"

/* A utility program for the Linux OS SCSI subsystem.
 *
 * This program takes a asc_ascq.txt file from www.t10.org and
 * checks it against the additional sense codes held in the
 * sg_lib.c file.
 * The online version of the asc_ascq codes can be found at:
 * http://www.t10.org/lists/asc-num.txt
 */

static char * version_str = "1.05 20150105";


#define MAX_LINE_LEN 1024


static struct option long_options[] = {
        {"help", 0, 0, 'h'},
        {"verbose", 0, 0, 'v'},
        {"version", 0, 0, 'V'},
        {0, 0, 0, 0},
};

static void usage()
{
    fprintf(stderr, "Usage: "
            "sg_chk_asc [--help] [--offset=POS] [--verbose] [--version]\n"
            "                  <asc_ascq_file>\n"
            "  where:\n"
            "    --help|-h          print out usage message\n"
            "    --offset=POS|-o POS    line position in file where "
            "text starts\n"
            "                           origin 0 (def: 24 (was 25))\n"
            "    --verbose|-v       increase verbosity\n"
            "    --version|-V       print version string and exit\n\n"
            "Checks asc/ascq codes in <asc_ascq_file> against the sg3_utils "
            "library.\nThe additional sense code (asc_ascq) can be found at\n"
            "www.t10.org/lists/asc-num.txt .\n"
           );

}

int main(int argc, char * argv[])
{
    int k, j, res, c, num, len, asc, ascq;
    FILE * fp;
    int offset = 24;
    int verbose = 0;
    char file_name[256];
    char line[MAX_LINE_LEN];
    char b[MAX_LINE_LEN];
    char bb[MAX_LINE_LEN];
    char * cp;
    int ret = 1;

    memset(file_name, 0, sizeof file_name);
    memset(line, 0, sizeof file_name);
    while (1) {
        int option_index = 0;

        c = getopt_long(argc, argv, "ho:vV", long_options,
                        &option_index);
        if (c == -1)
            break;

        switch (c) {
        case 'h':
        case '?':
            usage();
            return 0;
        case 'o':
            offset = sg_get_num(optarg);
            if (offset < 0) {
                fprintf(stderr, "bad argument to --offset\n");
                return 1;
            }
            break;
        case 'v':
            ++verbose;
            break;
        case 'V':
            fprintf(stderr, "version: %s\n", version_str);
            return 0;
        default:
            fprintf(stderr, "unrecognised switch code 0x%x ??\n", c);
            usage();
            return 1;
        }
    }
    if (optind < argc) {
        if ('\0' == file_name[0]) {
            strncpy(file_name, argv[optind], sizeof(file_name) - 1);
            file_name[sizeof(file_name) - 1] = '\0';
            ++optind;
        }
        if (optind < argc) {
            for (; optind < argc; ++optind)
                fprintf(stderr, "Unexpected extra argument: %s\n",
                        argv[optind]);
            usage();
            return 1;
        }
    }

    if (0 == file_name[0]) {
        fprintf(stderr, "missing file name!\n");
        usage();
        return 1;
    }
    fp = fopen(file_name, "r");
    if (NULL == fp) {
        fprintf(stderr, "open error: %s: %s\n", file_name,
                safe_strerror(errno));
        return 1;
    }
    for (k = 0; (cp = fgets(line, sizeof(line) - 1, fp)); ++k) {
        len = strlen(line);
        if (len < 1)
            continue;
        if (! isdigit(line[0]))
            continue;
        num = sscanf(line, "%xh/%xh", &asc, &ascq);
        if (1 == num)
            ascq = -1;
        if (num < 1) {
            if (verbose)
                fprintf(stderr, "Badly formed line number %d (num=%d)\n",
                        k + 1, num);
            continue;
        }
        if (len < 26)
            continue;
#if 0
strncpy(b , line, sizeof(b) - 1);
b[sizeof(b) - 1] = '\0';
num = strlen(b);
if (0xd == b[num - 2]) {
    b[num - 2] = '\0';
    b[num - 1] = '\0';
}
printf("\"%s\",\n", b);
#endif
        strncpy(b , line + offset, sizeof(b) - 1);
        b[sizeof(b) - 1] = '\0';
        num = strlen(b);
        if (0xd == b[num - 2]) {
            b[num - 2] = '\0';
            b[num - 1] = '\0';
        }
        num = strlen(b);
        for (j = 0; j < num; ++j)
            b[j] = toupper(b[j]);

        bb[0] = '\0';
        if (ascq >= 0) {
            cp = sg_get_asc_ascq_str(asc, ascq, sizeof(bb) - 1, bb);
            if (NULL == cp) {
                fprintf(stderr, "no entry for %x,%x : %s\n", asc, ascq, b);
                continue;
            }
            num = strlen(cp);
// fprintf(stderr, "file: asc=%x  acsq=%x  strlen=%d %s\n", asc, ascq, num,
//         cp);
//            if (num < 20)
//                continue;
            if ((num > 6) &&
                ((0 == memcmp("ASC", cp, 3)) ||
                 (0 == memcmp("vendor", cp, 6)))) {
                fprintf(stderr, "%x,%x differ, ref: %s, sg_lib_data: "
                        "<missing>\n", asc, ascq, b);
                continue;
            }
            if (num > 20) {
                cp += 18;
                num -= 18;
                for (j = 0; j < num; ++j)
                    cp[j] = toupper(cp[j]);
            }
            if (0 != strcmp(b, cp))
                fprintf(stderr, "%x,%x differ, ref: %s, sg_lib_data: "
                        "%s\n", asc, ascq, b, cp);
        }
    }
    if (NULL == cp) {
        if (feof(fp)) {
            if (verbose > 2)
                fprintf(stderr, "EOF detected\n");
        } else
            fprintf(stderr, "fgets: %s\n", safe_strerror(errno));
    } else
        fprintf(stderr, "%s\n", line);

    res = fclose(fp);
    if (EOF == res) {
        fprintf(stderr, "close error: %s\n", safe_strerror(errno));
        return 1;
    }
    return ret;
}
