#include #include #include #include #include #include #include #include #include #include #define __packed __attribute__((__packed__)) #define MAC_NUM 3 typedef union mac { uint8_t b[6]; uint64_t n:48; } __packed mac; struct serial { uint16_t date; unsigned version:4; unsigned number:12; } __packed; struct xioh_data { char magic[4]; uint16_t version; uint8_t cksum; uint8_t reserved; struct serial serial; mac addr[MAC_NUM]; } __packed; void print_mac_be(union mac mac) { printf("%02x:%02x:%02x:%02x:%02x:%02x", mac.b[0], mac.b[1], mac.b[2], mac.b[3], mac.b[4], mac.b[5]); } void dump_xioh_data(struct xioh_data *xioh_data) { int i; time_t time = xioh_data->serial.date * 86400; char *timestr = ctime(&time); timestr[strlen(timestr)-1] = '\0'; printf("Magic: %c%c%c%c\n" "Version: %u\n" "Checksum: %02x\n" "Serial:\n" "\tDate: %04x (%s)\n" "\tHardware version: %u\n" "\tNumber: %u\n", xioh_data->magic[0], xioh_data->magic[1], xioh_data->magic[2], xioh_data->magic[3], xioh_data->version, xioh_data->cksum, xioh_data->serial.date, timestr, xioh_data->serial.version, xioh_data->serial.number); printf("MAC addresses:\n"); for (i = 0; i < MAC_NUM; i++) { printf("\t"); print_mac_be(xioh_data->addr[i]); printf("\n"); } } bool dump_all(const char *fname) { FILE *f = fopen(fname, "r"); struct xioh_data xioh_data; if (!f) { printf("Can't open file \"%s\": %s\n", fname, strerror(errno)); exit(errno); } while (0 < fread(&xioh_data, sizeof(xioh_data), 1, f)) dump_xioh_data(&xioh_data); fclose(f); return false; } int main(int argc, char *argv[]) { int rc; if (argc != 3) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(127); } //dump_all(argv[1]); sqlite3 *db; sqlite3_stmt *stmt; rc = sqlite3_open(argv[2], &db); if (SQLITE_OK != rc) { fprintf(stderr, "could not open sqlite database \"%s\" (error %d)\n", argv[2], rc); sqlite3_close(db); exit(2); } rc = sqlite3_prepare_v2(db, "CREATE TABLE IF NOT EXISTS xioh_data (" "xioh_data blob," "version integer," "date ihnteger," "hardware_version integer," "serial_number integer," "mac1 blob," "mac2 blob," "mac3 blob" ")", -1, &stmt, NULL); if (SQLITE_OK != rc) { fprintf(stderr, "could not compile statement (error %d)\n", rc); sqlite3_close(db); exit(3); } rc = sqlite3_step(stmt); if (SQLITE_DONE != rc) { fprintf(stderr, "could not execute statement (error %d)\n", rc); sqlite3_finalize(stmt); sqlite3_close(db); exit(4); } sqlite3_finalize(stmt); rc = sqlite3_prepare_v2(db, "INSERT INTO xioh_data (xioh_data, version, date," "hardware_version, serial_number, mac1, mac2, mac3 ) " "VALUES (?, ?, ?, ?, ?, ?, ?, ?)", -1, &stmt, NULL); if (SQLITE_OK != rc) { fprintf(stderr, "could not compile statement (error %d)\n", rc); sqlite3_close(db); exit(5); } FILE *f = fopen(argv[1], "r"); struct xioh_data xioh_data; if (!f) { printf("Can't open file \"%s\": %s\n", argv[1], strerror(errno)); exit(errno); } while (0 < fread(&xioh_data, sizeof(xioh_data), 1, f)) { int i; sqlite3_reset(stmt); sqlite3_bind_blob(stmt, 1, &xioh_data, sizeof(xioh_data), SQLITE_TRANSIENT); sqlite3_bind_int(stmt, 2, xioh_data.version); sqlite3_bind_int(stmt, 3, xioh_data.serial.date); sqlite3_bind_int(stmt, 4, xioh_data.serial.version); sqlite3_bind_int(stmt, 5, xioh_data.serial.number); for (i = 0; i < MAC_NUM; i++) sqlite3_bind_blob(stmt, 6, &xioh_data.addr[i], sizeof(*xioh_data.addr), SQLITE_TRANSIENT); rc = sqlite3_step(stmt); if (SQLITE_DONE != rc) { fprintf(stderr, "could not insert into database: (error %d)\n", rc); dump_xioh_data(&xioh_data); sqlite3_finalize(stmt); sqlite3_close(db); exit(4); } } fclose(f); sqlite3_finalize(stmt); rc = sqlite3_close(db); if (SQLITE_OK != rc) { fprintf(stderr, "Error on closing database (error %d)\n", rc); exit(2); } fprintf(stderr, "Database converted successfully\n"); return 0; }