/***************************************************************************
The Disc Image Chef
----------------------------------------------------------------------------
Filename : main.c
Author(s) : Natalia Portillo
Component : DiscImageChef.Device.Report
--[ Description ] ----------------------------------------------------------
For Linux, opens a device and generates a report, without needing a .NET
environment, for systems that don't have it.
--[ License ] --------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
----------------------------------------------------------------------------
Copyright © 2011-2018 Natalia Portillo
****************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include "main.h"
#include "scsi.h"
#include "ata.h"
#include "atapi.h"
#include "atapi_report.h"
#include "scsi_report.h"
#include "ata_report.h"
int main(int argc, void *argv[])
{
int fd, rc;
unsigned char *scsi_sense = NULL;
unsigned char *scsi_inq_data = NULL;
unsigned char *ata_ident = NULL;
unsigned char *atapi_ident = NULL;
AtaErrorRegistersCHS *ata_error_chs;
int scsi_error, ata_error;
unsigned char *manufacturer;
unsigned char *product;
unsigned char *revision;
int deviceType = DEVICE_TYPE_UNKNOWN;
char *xmlFilename = malloc(NAME_MAX + 1);
xmlTextWriterPtr xmlWriter;
const char *ataName = "ATA";
printf("The Disc Image Chef Device Reporter for Linux %s\n", DIC_VERSION);
printf("%s\n", DIC_COPYRIGHT);
if(argc != 2)
{
printf("Usage:\n");
printf("%s \n", argv[0]);
return 1;
}
fd = open(argv[1], O_RDONLY | O_NONBLOCK);
if(fd < 0)
{
printf("Error opening device: %s\n", strerror(errno));
return 2;
}
// TODO: Support MMC, USB, FireWire, PCMCIA
scsi_error = Inquiry(fd, &scsi_inq_data, &scsi_sense);
if(scsi_error)
scsi_inq_data = NULL;
if(scsi_inq_data != NULL)
{
manufacturer = malloc(9);
manufacturer[8] = 0;
product = malloc(17);
product[16] = 0;
revision = malloc(5);
revision[4] = 0;
strncpy(manufacturer, scsi_inq_data + 8, 8);
strncpy(product, scsi_inq_data + 16, 16);
strncpy(revision, scsi_inq_data + 32, 4);
deviceType = DEVICE_TYPE_SCSI;
ata_error = IdentifyPacket(fd, &atapi_ident, &ata_error_chs);
if(!ata_error)
deviceType = DEVICE_TYPE_ATAPI;
}
if(scsi_inq_data == NULL || !strncmp((const char *)manufacturer, ataName, 3))
{
ata_error = Identify(fd, &ata_ident, &ata_error_chs);
if(!ata_error)
{
deviceType = DEVICE_TYPE_ATA;
revision = AtaToCString(ata_ident + (23 * 2), 8);
product = AtaToCString(ata_ident + (27 * 2), 40);
}
}
printf("Device type: %s\n", DeviceType[deviceType]);
printf("Manufacturer: %s\n", manufacturer);
printf("Product: %s\n", product);
printf("Revision: %s\n", revision);
if(deviceType != DEVICE_TYPE_ATA && deviceType != DEVICE_TYPE_ATAPI && deviceType != DEVICE_TYPE_SCSI)
{
printf("Unsupported device type %s.", DeviceType[deviceType]);
return 3;
}
sprintf(xmlFilename, "%s_%s_%s.xml", manufacturer, product, revision);
xmlWriter = xmlNewTextWriterFilename(xmlFilename, 0);
if(xmlWriter == NULL)
{
printf("Could not create XML report file.\n");
return 4;
}
rc = xmlTextWriterStartDocument(xmlWriter, NULL, XML_ENCODING, NULL);
if(rc < 0)
{
printf("Could not create XML report file.\n");
return 4;
}
rc = xmlTextWriterStartElement(xmlWriter, BAD_CAST DIC_REPORT_ROOT);
if(rc < 0)
{
printf("Could not create XML report file.\n");
return 4;
}
char *xmlComment = malloc(255);
sprintf(xmlComment, "Report created with DiscImageChef.Device.Report v%s", DIC_VERSION);
rc = xmlTextWriterWriteComment(xmlWriter, xmlComment);
if(rc < 0)
{
printf("Could not create XML report file.\n");
return 4;
}
if(deviceType == DEVICE_TYPE_ATAPI)
AtapiReport(fd, xmlWriter);
if(deviceType == DEVICE_TYPE_ATAPI || deviceType == DEVICE_TYPE_SCSI)
ScsiReport(fd, xmlWriter);
if(deviceType == DEVICE_TYPE_ATA)
AtaReport(fd, xmlWriter);
rc = xmlTextWriterEndDocument(xmlWriter);
if(rc < 0)
{
printf("Could not close XML report file.\n");
return 4;
}
close(fd);
return 0;
}