Files
Fish (David B. Trout) b5a7337898 New "dasdser" serial number utility
[skip travis]
2019-08-31 10:57:20 -07:00

152 lines
5.4 KiB
C

/* DASDSER.C (C) Copyright "Fish" (David B. Trout), 2019 */
/* Hercules DASD Serial Number Utility */
/* */
/* Released under "The Q Public License Version 1" */
/* (http://www.hercules-390.org/herclic.html) as modifications to */
/* Hercules. */
/*-------------------------------------------------------------------*/
/* This program displays or writes (updates) the serial number of */
/* an existing dasd image file. */
/* */
/* dasdser filename (query) */
/* dasdser filename serial (update) */
/* */
/* filename is the base CKD dasd image file to be updated. */
/* Only base CKD dasd image types are supported */
/* (CKD, CKD64, CCKD and CCKD64). Shadow files and */
/* FBA image types are not supported. */
/* */
/* [serial] is the optional 12-digit numeric serial number */
/* to be assigned to the specified dasd image file. */
/* If not specified the current serial is reported. */
/* */
/*-------------------------------------------------------------------*/
#include "hstdinc.h"
#include "hercules.h"
#include "dasdblks.h"
#include "ccwarn.h"
#define UTILITY_NAME "dasdser"
#define UTILITY_DESC "DASD serial number utility"
static int retcode( int rc )
{
exit( rc ); // (convenient place to set breakpoint)
}
/*-------------------------------------------------------------------*/
/* DASDSER program main entry point */
/*-------------------------------------------------------------------*/
int main( int argc, char* argv[] )
{
char* pgm; /* Less any extension (.ext) */
BYTE serial[12+1] = {0}; /* Serial number to assign */
CKD_DEVHDR devhdr; /* DASD Image Device Header */
int fd; /* File descriptor */
int rc; /* Return code */
INITIALIZE_UTILITY( UTILITY_NAME, UTILITY_DESC, &pgm );
/* Display help if needed or requested */
if (argc < 2 || argc > 3)
{
// "Usage: ..."
FWRMSG( stderr, HHC03100, "I", pgm );
return retcode( -1 );
}
/* New serial number to be assigned? */
if (argc > 2)
{
/* Valid 12-digit numeric serial number? */
if (0
|| !is_numeric( argv[2] )
|| strlen( argv[2] ) != sizeof( devhdr.dh_serial )
)
{
// "Invalid %s \"%s\""
FWRMSG( stderr, HHC03101, "E", "serial", argv[2] );
return retcode( -1 );
}
/* Save serial number */
memcpy( serial, argv[2], sizeof( devhdr.dh_serial ));
serial[12] = 0;
}
/* Open the dasd image file */
if ((fd = open( argv[1], O_BINARY | (argc > 2 ? O_RDWR : O_RDONLY))) < 0)
{
// "Error in function %s: %s"
FWRMSG( stderr, HHC03102, "E", "open()", strerror( errno ));
return retcode( -1 );
}
/* Read the device header */
if ((rc = read( fd, &devhdr, sizeof( devhdr ))) < (int) sizeof( devhdr ))
{
if (rc < 0)
{
// "Error in function %s: %s"
FWRMSG( stderr, HHC03102, "E", "read()", strerror( errno ));
}
else
{
// "Unsupported dasd image file format"
FWRMSG( stderr, HHC03103, "E" );
}
return retcode( -1 );
}
/* Normal (uncompressed) FBA types don't have device headers! */
if (!is_dh_devid_typ( devhdr.dh_devid, CKD_CMP_OR_NML_TYP ))
{
// "Unsupported dasd image file format"
FWRMSG( stderr, HHC03103, "E" );
return retcode( -1 );
}
/* Set new serial number or display current serial number... */
if (argc > 2) // (assign/update/set?)
{
/* Seek back to beginning of file where the device header is */
if (lseek( fd, 0, SEEK_SET ) != 0)
{
// "Error in function %s: %s"
FWRMSG( stderr, HHC03102, "E", "lseek()", strerror( errno ));
return retcode( -1 );
}
/* Assign/update/set new serial number */
memcpy( devhdr.dh_serial, serial, sizeof( devhdr.dh_serial ));
/* Rewrite the device header with the new serial number */
if ((rc = write( fd, &devhdr, sizeof( devhdr ))) != sizeof( devhdr ))
{
// "Error in function %s: %s"
FWRMSG( stderr, HHC03102, "E", "write()", strerror( errno ));
return retcode( -1 );
}
// "%-14s set to %s"
WRMSG( HHC02204, "I", "SERIAL NUMBER", (const char*) serial );
}
else /* Display existing serial number */
{
memcpy( serial, devhdr.dh_serial, sizeof( devhdr.dh_serial ));
serial[12] = 0;
// "%-14s: %s"
WRMSG( HHC02203, "I", "SERIAL NUMBER", (const char*) serial );
}
/* Close the file */
close( fd );
/* DONE! */
return retcode( 0 );
}