Clean up unix show devices. Add show volumes.

Also, clean up virtual devices in mount error paths.

Update MOUNT help.
This commit is contained in:
Timothe Litt 2016-03-05 15:10:17 -05:00
parent 886c1fae06
commit 0935e31ba3
9 changed files with 309 additions and 86 deletions

Binary file not shown.

View File

@ -31,6 +31,8 @@
#include "stsdef.h"
#include "compat.h"
#include "sysmsg.h"
#include "vmstime.h"
#ifndef TRUE
#define TRUE ( 0 == 0 )
#endif
@ -38,6 +40,8 @@
#define FALSE ( 0 != 0 )
#endif
struct VCB *vcb_list = NULL;
/* WCBKEY passes info to compare/create routines */
struct WCBKEY {
@ -319,7 +323,7 @@ static void *wcb_create( unsigned hashval, void *keyval, unsigned *retsts ) {
break;
default:
printf( "Unknown type %x\n", (VMSWORD(*mp)>>14) );
exit(1);
abort();
}
curvbn += phylen;
if (phylen != 0 && curvbn > wcb->loblk) {
@ -790,6 +794,8 @@ unsigned dismount(struct VCB * vcb)
vcbdev++;
}
if (sts & STS$M_SUCCESS) {
struct VCB *lp;
cache_remove(&vcb->fcb->cache);
#ifdef DEBUG
printf( "--->dismount(): cache_remove()\n" );
@ -800,6 +806,12 @@ unsigned dismount(struct VCB * vcb)
printf( "--->dismount(): cache_delete()\n" );
#endif
}
for( lp = (struct VCB *)&vcb_list; lp->next != NULL; lp = lp->next ) {
if( lp->next == vcb ) {
lp->next = vcb->next;
break;
}
}
free(vcb);
}
}
@ -832,6 +844,7 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],
if (flags & MOU_WRITE) vcb->status |= VCB_WRITE;
vcb->fcb = NULL;
vcb->dircache = NULL;
vcb->devices = 0;
vcbdev = vcb->vcbdev;
for( device = 0; device < devices; device++, vcbdev++ ) {
char *dname;
@ -865,7 +878,8 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],
vcbdev->dev->access = flags; /* Requested mount options */
/* (e.g., /Write) */
sts = phyio_init( vcbdev->dev );
if ( !( sts & STS$M_SUCCESS ) ) break;
if ( !( sts & STS$M_SUCCESS ) ) break;
vcb->devices++;
if (vcbdev->dev->vcb != NULL) {
sts = SS$_DEVMOUNT;
break;
@ -930,7 +944,6 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],
} /* for(each device) */
}
if (sts & STS$M_SUCCESS) {
vcb->devices = devices;
vcbdev = vcb->vcbdev;
for( device = 0; device < devices; device++, vcbdev++ ) {
char *dname;
@ -1017,7 +1030,7 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],
if( memcmp(vcbdev->home.hm2$t_volname, volsetSYS[device+1].vsr$t_label, 12 ) != 0 ) {
printf( "%%ODS2-E-WRONGVOL, RVN %u of '%12.12s' is '%12.12s'. %s contains '%12.12s'\n",
device+1, vcb->vcbdev[0].home.hm2$t_strucname,
device+1, vcb->vcbdev[0].home.hm2$t_strucname,
volsetSYS[device+1].vsr$t_label, dname, vcbdev->home.hm2$t_volname );
sts = SS$_NOSUCHVOL;
break;
@ -1083,20 +1096,202 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],
/* if (!(sts & 1)) ??; */
vcbdev->idxfcb->headvioc = NULL;
cache_untouch(&vcbdev->idxfcb->cache,0);
vcbdev->dev->vcb = NULL;
vcbdev->dev->vcb = NULL;
/* ?? vcbdev->dev = NULL *//* **DECREF **/
sts = phyio_done( vcbdev->dev );
}
cache_remove( &vcb->fcb->cache );
while( vcb->dircache ) cache_delete( (struct CACHE *) vcb->dircache );
}
} else { /* *** DECREF *** */
if( flags & MOU_VIRTUAL ) {
vcbdev = vcb->vcbdev;
for( device = 0; device < vcb->devices; device++, vcbdev++ ) {
phyio_done( vcbdev->dev );
}
}
free(vcb);
vcb = NULL;
}
if( (sts & 1) && (flags & 2) && VMSWORD(vcb->vcbdev[0].home.hm2$w_rvn) != 0 ) {
if( (sts & 1) && (flags & MOU_LOG) && VMSWORD(vcb->vcbdev[0].home.hm2$w_rvn) != 0 ) {
printf ( "%%MOUNT-I-MOUNTEDVS, Volume set %12.12s mounted\n", vcb->vcbdev[0].home.hm2$t_strucname );
}
if( vcb != NULL ) {
vcb->next = vcb_list;
vcb_list = vcb;
}
if( volsetSYS != NULL ) free( volsetSYS );
if (retvcb != NULL) *retvcb = vcb;
return sts;
}
/***************************************************************** show_volumes */
/* First, some private helper routines */
/********************************************************** print_volhdr */
static void print_volhdr( int volset, size_t devwid ) {
size_t i;
if( volset )
printf( " RVN " );
else
printf( " " );
printf(
"%-*s Volume Lvl Clust Owner/CreateDate VolProt/Default FileProt\n",
(int)devwid, "Dev" );
if( volset )
printf( " --- " );
else
printf( " " );
for( i= 0; i < devwid; i++ )
putchar( '-' );
printf(
" ------------ --- ----- ----------------- ---------------------------\n" );
return;
}
/********************************************************** print_prot() */
static void print_prot( vmsword code, int vol ) {
static const char grp[4] = { "SOGW" };
static const char acc[2][4] = {{"RWED"}, {"RWCD"}};
int g, b, w;
w = 27;
for( g = 0; g < 4; g++ ) {
w -= printf( "%c:", grp[g] );
for( b = 0; b < 4; b++ ) {
if( !(code & (1<<(b + (4*g)))) ) {
putchar( acc[vol][b] );
w--;
}
}
if( g < 3 ) {
putchar( ',' );
w--;
}
}
while( w-- ) putchar( ' ' );
}
/********************************************************** print_volinf() */
static void print_volinf( struct VCB *vcb,
size_t devwid,
unsigned device,
size_t wrap ) {
struct VCBDEV *vcbdev;
size_t n;
vmsword timbuf[7];
vcbdev = vcb->vcbdev+device;
for( n = 0; n < strlen( vcbdev->dev->devnam ); n++ ) {
if( vcbdev->dev->devnam[n] == ':' )
break;
putchar( vcbdev->dev->devnam[n] );
}
printf( "%*s ", (int)(devwid-n), "" );
printf( "%12.12s", vcbdev->home.hm2$t_volname );
printf( " %u.%u %5u [%6o,%6o]",
VMSWORD( vcbdev->home.hm2$w_struclev ) >> 8,
VMSWORD( vcbdev->home.hm2$w_struclev ) & 0xFF,
VMSWORD( vcbdev->home.hm2$w_cluster ),
VMSWORD( vcbdev->home.hm2$w_volowner.uic$w_grp ),
VMSWORD( vcbdev->home.hm2$w_volowner.uic$w_mem )
);
printf( " " );
print_prot( VMSWORD( vcbdev->home.hm2$w_protect ), 1 );
if( !(vcb->status & VCB_WRITE) )
printf( " write-locked" );
printf( "\n%*s ", (int)(wrap+devwid+23), "" );
if( sys$numtim( timbuf, vcbdev->home.hm2$q_credate ) & STS$M_SUCCESS ) {
static const char *months =
"-JAN-FEB-MAR-APR-MAY-JUN-JUL-AUG-SEP-OCT-NOV-DEC-";
printf( "%2u%.5s%4u %2u:%2u ", timbuf[2],
months+(4*(timbuf[1]-1)), timbuf[0],
timbuf[3], timbuf[4]);
} else
printf( "%*s", 41-23, "" );
print_prot( VMSWORD( vcbdev->home.hm2$w_fileprot ), 0 );
putchar( '\n' );
}
/********************************************************** show_volumes() */
void show_volumes( void ) {
struct VCB *vcb;
size_t maxd = sizeof( "Dev" ) -1;
int nvol = 0;
unsigned device;
if( vcb_list == NULL ) {
printf( " No volumes mounted\n" );
return;
}
for( vcb = vcb_list; vcb != NULL; vcb = vcb->next ) {
struct VCBDEV *vcbdev;
if( vcb->devices == 0 ) {
printf( "No devices for volume\n" );
abort();
}
nvol++;
vcbdev = vcb->vcbdev;
for( device = 0; device < vcb->devices; device++, vcbdev++ ) {
size_t n;
for( n = 0; n < strlen( vcbdev->dev->devnam ); n++ )
if( vcbdev->dev->devnam[n] == ':' )
break;
if( n > maxd )
maxd = n;
}
}
for( vcb = vcb_list; vcb != NULL; vcb = vcb->next ) {
struct VCBDEV *vcbdev;
unsigned device;
vcbdev = vcb->vcbdev;
if( VMSWORD(vcbdev->home.hm2$w_rvn) == 0 )
continue;
nvol--;
printf( " Volume set %12.12s\n", vcbdev->home.hm2$t_strucname );
print_volhdr( TRUE, maxd );
for( device = 0; device < vcb->devices; device++, vcbdev++ ) {
printf( " %3d ", VMSWORD(vcbdev->home.hm2$w_rvn) );
print_volinf( vcb, maxd, device, 8 );
}
}
if( nvol == 0 )
return;
printf( "\n" );
print_volhdr( FALSE, maxd );
for( vcb = vcb_list; vcb != NULL; vcb = vcb->next ) {
struct VCBDEV *vcbdev;
unsigned device;
vcbdev = vcb->vcbdev;
if( VMSWORD(vcbdev->home.hm2$w_rvn) != 0 )
continue;
vcbdev = vcb->vcbdev;
for( device = 0; device < vcb->devices; device++, vcbdev++ ) {
printf( " " );
print_volinf( vcb, maxd, device, 2 );
}
}
return;
}

View File

@ -245,6 +245,7 @@ struct VCBDEV {
struct HOME home; /* Volume home block */
};
struct VCB {
struct VCB *next; /* Next in mounted volume list (Must be first item) */
unsigned status; /* Volume status */
unsigned devices; /* Number of volumes in set */
struct FCB *fcb; /* File control block tree */
@ -252,6 +253,9 @@ struct VCB {
struct VCBDEV vcbdev[1]; /* List of volumes devices */
}; /* Volume control block */
extern struct VCB *vcb_list;
void show_volumes( void );
/* RVN_TO_DEV( vcb, rvn ) - returns device from relative volume number */
/* returns NULL if RVN illegal or device not mounted */

View File

@ -5,7 +5,7 @@
CCFLAGS = "-Oxs"
# For the direct SCSI module
#DEFS = -DUSE_WNASPI32
#DEFS = -DUSE_ASPI
#LDFLAGS = wnaspi32.lib
#PHYSIOH = wnaspi32.h scsidefs.h
#LIBS = wnaspi32.lib

View File

@ -1444,6 +1444,7 @@ static struct qual showkwds[] = { {"default", 0, 0, NV, "Default directo
{"time", 4, 0, NV, "Time"},
{"verify", 5, 0, NV, "Command file echo" },
{"version", 6, 0, NV, "Version"},
{"volumes", 7, 0, NV, "Mounted volume information" },
{NULL, 0, 0, NV, NULL }
};
static struct param showpars[] = { {"item_name", REQ, KEYWD, PA(showkwds), NULL },
@ -1509,6 +1510,9 @@ unsigned doshow(int argc,char *argv[],int qualc,char *qualv[]) {
case 6:
show_version();
return SS$_NORMAL;
case 7:
show_volumes();
return SS$_NORMAL;
}
return SS$_NORMAL;
}
@ -1681,9 +1685,9 @@ static struct qual mouquals[] = { {"image", MOU_VIRTUAL, 0, NV, "Moun
{NULL, 0, 0, NV, NULL } };
static struct param moupars[] = { {"volumes", REQ, LIST, NOPA,
"devices or disk image(s) in volume set separated by comma"
"devices or disk image(s) of volume set in RVN order separated by comma"
},
{"labels", OPT, LIST, NOPA, "volume labels separated by comma" },
{"labels", OPT, LIST, NOPA, "volume labels in RVN order separated by comma" },
{ NULL, 0, 0, NOPA, NULL }
};
@ -2006,10 +2010,12 @@ static unsigned dohelp(int argc,char *argv[],int qualc,char *qualv[]) {
if( argc <= 1 ) {
show_version();
printf( "\n The orginal version of ods2 was developed by Paul Nankervis <Paulnank@au1.ibm.com>\n" );
printf( " This modified version was developed by Timothe Litt, and incorporated\n" );
printf( " significant previous modifications by Larry Baker of the USGS and by Hunter Goatley\n" );
printf("\n Please send problems/comments to litt@ieee.org\n");
printf( " The orginal version of ods2 was developed by Paul Nankervis\n" );
printf( " <Paulnank@au1.ibm.com>\n" );
printf( " This modified version was developed by Timothe Litt, and\n" );
printf( " incorporates significant previous modifications by Larry \n" );
printf( " Baker of the USGS and by Hunter Goatley\n" );
printf("\n Please send problems/comments to litt@ieee.org\n\n");
printf(" Commands are:\n");
cmdhelp( cmdset );
@ -2032,8 +2038,27 @@ static unsigned dohelp(int argc,char *argv[],int qualc,char *qualv[]) {
qualhelp( 0, cmd->validquals );
if( cmd->params != NULL )
parhelp( cmd, 0, NULL );
if( strcmp(cmd->name, "mount") == 0 )
if( strcmp(cmd->name, "mount") == 0 ) {
printf( "\n" );
printf( "You can mount a volume(-set) from either physical devices\n" );
printf( "such a CDROM or hard disk drive, or files containing an\n" );
printf( "image of a volume, such as a .ISO file or simulator disk\n\n" );
printf( "To mount a disk image, use the %cimage qualifier and\n",
(vms_qual? '/': '-') );
printf( "specify the filename as the parameter.\n\n" );
printf( "If the filename contains %c, specify it in double quotes\n\n",
(vms_qual? '/': '-') );
printf( "Mount will assign a virtual device name to each volume.\n" );
printf( "You can select a virtual device name using the format\n" );
printf( " dka100=my_files.iso\n\n" );
printf( "To mount a physical device, use the format:\n" );
phyio_help(stdout);
printf( "To mount a volume set, specify all the members in RVN order\n" );
printf( "as a comma-separated list.\n\n" );
printf( "If you specify a list of volume labels, they must be in\n" );
printf( "the same order as the volumes, and each must match the label\n" );
printf( "stored in the data\n" );
}
return 1;
}
}
@ -2319,7 +2344,8 @@ int main( int argc,char *argv[] ) {
printf("$> %s\n", rl);
}
ptr = rl;
} else {
}
if( ptr == NULL ) {
#ifdef VMS
if( getcmd( str, sizeof(str), "$> " ) == NULL ) break;
ptr = str;

View File

@ -803,17 +803,15 @@ void phyio_show( showtype_t type ) {
/*************************************************************** phyio_help() */
void phyio_help(FILE *fp ) {
fprintf( fp, "Specify the device to be mounted as a drive letter.\n" );
fprintf( fp, "E.g. mount D:\n" );
fprintf( fp, " mount D:\n" );
fprintf( fp, "Any drive letter mapped to a physical drive can be used\n" );
#ifdef USE_ASPI
fprintf( fp, "If the drive letter is C: or higher, commands are\n" );
fprintf( fp, "sent directly to the drive, bypassing system drivers.\n" );
fprintf( fp, "The drive must be a SCSI device\n" );
#endif
fprintf( fp, "The drive letter must be between A: and Z:.\n" );
fprintf( fp, "The drive is accessed as a physical device, which may require privileges.\n" );
fprintf( fp, "Use show DEVICES for a list of available devices.\n" );
fprintf( fp, "Use ODS2-Image to work with disk images such as .ISO or simulator files.\n" );
fprintf( fp, "For a list of devices, see SHOW DEVICES\n\n" );
return;
}

View File

@ -81,26 +81,28 @@ static int devcmp( const void *d1, const void *d2 ) {
static void showdevs( void ) {
DIR *dirp;
struct dirent *dp;
size_t i, cpl, n = 0, max = 0;
struct devdat (*list)[1] = NULL;
if( (dirp = opendir( DEV_PREFIX )) == NULL )
return;
do {
struct stat stb;
errno = 0;
if( (dp = readdir(dirp)) != NULL ) {
char *fs;
errno = 0;
if( (dirp = opendir( DEV_PREFIX )) != NULL ) {
do {
int nml;
size_t len;
unsigned unit;
char *fs;
struct dirent *dp;
struct devdat (*nl)[1];
struct stat stb;
errno = 0;
if( (dp = readdir(dirp)) == NULL )
break;
len = strlen( dp->d_name );
fs = malloc( sizeof( DEV_PREFIX ) + len );
if( fs == NULL ) {
perror( "malloc" );
exit( 1 );
}
if( fs == NULL )
break;
memcpy( fs, DEV_PREFIX, sizeof( DEV_PREFIX ) -1 );
memcpy( fs + sizeof( DEV_PREFIX ) -1, dp->d_name, len +1 );
@ -109,64 +111,61 @@ static void showdevs( void ) {
free( fs );
continue;
}
if( S_ISBLK( stb.st_mode ) ) {
struct devdat (*nl)[1];
unsigned unit = ~0;
int nml;
struct devdat *devp;
if( !S_ISBLK( stb.st_mode ) )
continue;
if( sscanf( fs, DEV_PREFIX "%*[^0123456789]%n%u",
&nml, &unit ) == 1 ) {
fs[nml] = '\0';
}
for( i = 0; i < n; i++ ) {
devp = (*list)+i;
if( strcmp( devp->name, fs ) == 0 ) {
if( unit != ~0U ) {
if( unit > devp->high )
devp->high = unit;
if( unit < devp->low )
devp->low = unit;
}
break;
memmove( fs, fs + sizeof( DEV_PREFIX ) -1, len +1 );
unit = ~0;
if( sscanf( fs, "%*[^0123456789]%n%u", &nml, &unit ) == 1 )
fs[nml] = '\0';
for( i = 0; i < n; i++ ) {
if( strcmp( (*list)[i].name, fs ) == 0 ) {
if( unit != ~0U ) {
if( unit > (*list)[i].high )
(*list)[i].high = unit;
if( unit < (*list)[i].low )
(*list)[i].low = unit;
}
}
if( i >= n ) {
nl = (struct devdat (*)[1]) realloc( list, (n+1) * sizeof( struct devdat ) );
if( nl == NULL ) {
for( i = 0; i < n; i++ )
free( (*list)[i].name );
free( list );
perror( "malloc" );
exit( 1 );
}
list = nl;
(*list)[n].name = fs;
(*list)[n].low = unit;
(*list)[n++].high = unit;
break;
}
}
}
} while( dp != NULL );
if( i >= n ) {
nl = (struct devdat (*)[1])
realloc( list, (n+1) * sizeof( struct devdat ) );
if( nl == NULL )
break;
list = nl;
(*list)[n].name = fs;
(*list)[n].low = unit;
(*list)[n++].high = unit;
}
} while( TRUE );
(void) closedir(dirp);
}
if( errno != 0 ) {
printf( "%%ODS2-W-DIRERR, Error reading %s\n", DEV_PREFIX );
perror( " - " );
for( i = 0; i < n; i++ )
free( (*list)[i].name );
free( list );
return;
}
(void) closedir(dirp);
if( n == 0 ) {
printf( "%%ODS2-I-NODEV, No devices found\n" );
return;
}
qsort( list, n, sizeof( struct devdat ), &devcmp );
for( i = 0; i < n; i++ ) {
char buf[128];
int p;
p = snprintf( buf, sizeof(buf), "%s", (*list)[i].name + sizeof( DEV_PREFIX)-1 );
p = snprintf( buf, sizeof(buf), "%s", (*list)[i].name );
if( (*list)[i].low != ~0U ) {
p+= snprintf( buf+p, sizeof(buf)-p, "%u", (*list)[i].low );
p += snprintf( buf+p, sizeof(buf)-p, "%u", (*list)[i].low );
if( (*list)[i].high != (*list)[i].low )
p+= snprintf( buf+p, sizeof(buf)-p, "-%u", (*list)[i].high );
p += snprintf( buf+p, sizeof(buf)-p, "-%u", (*list)[i].high );
}
if( p > (int)max )
max = p;
@ -174,14 +173,16 @@ static void showdevs( void ) {
cpl = 50 / (max + 1);
if( cpl == 0 )
cpl = 1;
for( i = 0; i < n; i++ ) {
int p;
if( (i % cpl) == 0 ) {
if( i ) putchar( '\n' );
putchar( ' ' );
}
p = printf( " %s", (*list)[i].name + sizeof( DEV_PREFIX)-1 ) -1;
p = printf( " %s", (*list)[i].name ) -1;
free( (*list)[i].name );
if( (*list)[i].low != ~0U ) {
p += printf( "%u", (*list)[i].low );
if( (*list)[i].high != (*list)[i].low )
@ -217,14 +218,11 @@ void phyio_show( showtype_t type ) {
}
void phyio_help(FILE *fp ) {
fprintf( fp, "Specify the device to be mounted as using the format:\n" );
fprintf( fp, " mount %s%s\n\n", DEV_PREFIX, "device" );
fprintf( fp, " mount device\nThe device must be in %.*s.\n\n",
(int)(sizeof( DEV_PREFIX ) -2), DEV_PREFIX );
fprintf( fp, "For example, if you are using " DEV_PREFIX "%s\n", "cdrom0" );
fprintf( fp, " ODS2$> mount cdrom0\n\n" );
fprintf( fp, "Use ODS2-Image to work with disk images such as .ISO or simulator files.\n" );
fprintf( fp, "Alternatively, you can mount the image on a loop device.\n" );
fprintf( fp, " ODS2$> mount cdrom0\n" );
fprintf( fp, "For a list of devices, see SHOW DEVICES\n\n" );
return;
}

View File

@ -37,7 +37,7 @@ static struct VDEV {
char *path;
} *virt_device_list = NULL;
static int virt_compare( unsigned keylen, const char *keynam,
static int virt_compare( unsigned keylen, const char *keynam,
const char *devnam );
static struct VDEV *virt_insert( const char *devnam, unsigned devsiz,
const char *path );
@ -82,7 +82,7 @@ void virt_show( const char *devnam ) {
for ( vp = virt_device_list; vp != NULL; vp = vp->next ) {
n = strlen( vp->path );
printf( " %-*s %.*s\n", (int)maxd, vp->devnam, (int)maxp,
(n > 64)? vp->path+(n-64): vp->path );
(n > maxp)? vp->path+(n-maxp): vp->path );
}
} else {
devlen = strlen( devnam );
@ -164,7 +164,7 @@ unsigned virt_device( char *devnam, char **vname ) {
if( (p = strchr( devnam, '=' )) != NULL ) {
*p = '\0';
path = p+1;
path = ++p;
} else {
path = devnam;
devnam = autodev();

View File

@ -110,10 +110,12 @@ void phyio_show( showtype_t type ) {
}
void phyio_help(FILE *fp ) {
fprintf( fp, "Specify the device to be mounted as a VMS device or logical name\n" );
fprintf( fp, "E.g. mount DUB0:\n" );
fprintf( fp, "mount DUB0:\n" );
fprintf( fp, "The device can be specified as a physical device or logical name\n" );
fprintf( fp, "You will need the LOGIO privilege\n" );
fprintf( fp, "Use ODS2-Image to work with disk images such as .ISO or simulator files.\n" );
fprintf( fp, "Use show DEVICES for a list of available devices.\n" );
fprintf( fp, "For a list of devices, use the DCL SHOW DEVICE command.\n\n" );
return;
}