diff --git a/extracters/ods2/ODS2.vcxproj b/extracters/ods2/ODS2.vcxproj
index 84603f5..7d7938c 100644
--- a/extracters/ods2/ODS2.vcxproj
+++ b/extracters/ods2/ODS2.vcxproj
@@ -119,7 +119,6 @@
-
diff --git a/extracters/ods2/ODS2.vcxproj.filters b/extracters/ods2/ODS2.vcxproj.filters
index 046e7f0..dc87ef1 100644
--- a/extracters/ods2/ODS2.vcxproj.filters
+++ b/extracters/ods2/ODS2.vcxproj.filters
@@ -65,9 +65,6 @@
Header Files
-
- Header Files
-
Header Files
diff --git a/extracters/ods2/access.c b/extracters/ods2/access.c
index 67adf08..3e35a16 100644
--- a/extracters/ods2/access.c
+++ b/extracters/ods2/access.c
@@ -17,6 +17,7 @@
'RMS' routines.
*/
+#include
#include
#include
#include
@@ -25,6 +26,7 @@
#include "access.h"
#include "phyio.h"
#include "compat.h"
+#include "sysmsg.h"
#define DEBUGx
@@ -78,8 +80,8 @@ void fid_copy(struct fiddef *dst,struct fiddef *src,unsigned rvn)
unsigned deaccesshead(struct VIOC *vioc,struct HEAD *head,unsigned idxblk)
{
if (head && idxblk) {
- unsigned short check = checksum((vmsword *) head);
- head->fh2$w_checksum = VMSWORD(check);
+ unsigned short check = checksum((vmsword *) head);
+ head->fh2$w_checksum = VMSWORD(check);
}
return deaccesschunk(vioc,idxblk,1,1);
}
@@ -564,7 +566,7 @@ unsigned deaccessfile(struct FCB *fcb)
cache_refcount((struct CACHE *) fcb->vioc);
if (refcount != 0) {
printf("File reference counts non-zero %d (%d)\n",refcount,
- fcb->cache.hashval);
+ fcb->cache.hashval);
#ifdef DEBUG
printf("File reference counts non-zero %d %d\n",
cache_refcount((struct CACHE *) fcb->wcb),cache_refcount((struct CACHE *) fcb->vioc));
@@ -738,24 +740,35 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],stru
register unsigned device,sts = 0;
struct VCB *vcb;
struct VCBDEV *vcbdev;
+ struct VOLSETREC *volsetSYS = NULL;
UNUSED(label);
+#ifdef DEBUG
if (sizeof(struct HOME) != 512 || sizeof(struct HEAD) != 512) return SS$_NOTINSTALL;
- vcb = (struct VCB *) malloc(sizeof(struct VCB) + (devices - 1) * sizeof(struct VCBDEV));
+#endif
+ vcb = (struct VCB *) calloc(1, sizeof(struct VCB) + (devices - 1) * sizeof(struct VCBDEV));
if (vcb == NULL) return SS$_INSFMEM;
vcb->status = 0;
if (flags & 1) vcb->status |= VCB_WRITE;
vcb->fcb = NULL;
vcb->dircache = NULL;
vcbdev = vcb->vcbdev;
- for (device = 0; device < devices; device++) {
+ for( device = 0; device < devices; device++, vcbdev++ ) {
sts = SS$_NOSUCHVOL;
vcbdev->dev = NULL;
- if (strlen(devnam[device])) {
+ if (strlen(devnam[device])) { /* Really want to allow skipping volumes? */
unsigned int hba;
+ if( label[device] != NULL && strlen(label[device]) > sizeof( volsetSYS[0].vsr$t_label ) ) {
+ sts = SS$_BADPARAM;
+ break;
+ }
sts = device_lookup(strlen(devnam[device]),devnam[device],1,&vcbdev->dev);
- if (!(sts & 1)) break;
+ if( !(sts & 1) ) break;
+ if (vcbdev->dev->vcb != NULL) {
+ sts = SS$_DEVMOUNT;
+ break;
+ }
for (hba = 1; hba <= HOME_LIMIT; hba++) {
sts = phyio_read(vcbdev->dev->handle,hba,sizeof(struct HOME),(char *) &vcbdev->home);
if (!(sts & 1)) break;
@@ -763,26 +776,38 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],stru
memcmp(vcbdev->home.hm2$t_format,"DECFILE11B ",12) == 0) break;
sts = SS$_DATACHECK;
}
- if (sts & 1) {
- if (VMSWORD(vcbdev->home.hm2$w_checksum2) != checksum((unsigned short *) &vcbdev->home)) {
- sts = SS$_DATACHECK;
- } else {
- if (VMSWORD(vcbdev->home.hm2$w_rvn) != device + 1)
- if (VMSWORD(vcbdev->home.hm2$w_rvn) > 1 || device != 0)
- sts = SS$_UNSUPVOLSET;
- if (vcbdev->dev->vcb != NULL) {
- sts = SS$_DEVMOUNT;
+ if( !(sts & 1) ) break;
+ if (VMSWORD(vcbdev->home.hm2$w_checksum2) != checksum((unsigned short *) &vcbdev->home)) {
+ sts = SS$_DATACHECK;
+ break;
+ }
+ if( label[device] != NULL ) {
+ int i;
+ char lbl[12+1]; /* Pad CLI-supplied label to match ODS */
+ snprintf( lbl, sizeof(lbl), "%-12s", label[device] );
+ for( i = 0; i < 12; i++ ) {
+ if( toupper(lbl[i]) != vcbdev->home.hm2$t_volname[i] ) {
+ printf( "%%ODS2-W-WRONGVOL, Device %s contains volume '%12.12s', '%s' expected\n",
+ devnam[device], vcbdev->home.hm2$t_volname, lbl );
+ sts = SS$_ITEMNOTFOUND;
+ break;
}
}
+ if( (sts & 1) == 0 ) break;
+ }
+ if( (VMSWORD(vcbdev->home.hm2$w_rvn) != device + 1) &&
+ !(VMSWORD(vcbdev->home.hm2$w_rvn) == 0 && device == 0) ) {
+ printf( "%%ODS2-E-WRONGVOL, Device %s contains RVN %u, RVN %u expected\n",
+ devnam[device], VMSWORD(vcbdev->home.hm2$w_rvn), device+1 );
+ sts = SS$_UNSUPVOLSET;
}
if (!(sts & 1)) break;
- }
- vcbdev++;
+ } /* for(each device) */
}
if (sts & 1) {
vcb->devices = devices;
vcbdev = vcb->vcbdev;
- for (device = 0; device < devices; device++) {
+ for( device = 0; device < devices; device++, vcbdev++ ) {
vcbdev->idxfcb = NULL;
vcbdev->mapfcb = NULL;
vcbdev->clustersize = 0;
@@ -791,42 +816,150 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],stru
if (strlen(devnam[device])) {
struct fiddef idxfid = {1,1,0,0};
idxfid.fid$b_rvn = device + 1;
- sts = accessfile(vcb,&idxfid,&vcbdev->idxfcb,flags & 1);
+ sts = accessfile( vcb, &idxfid, &vcbdev->idxfcb, (vcb->status & VCB_WRITE) != 0 );
if (!(sts & 1)) {
- vcbdev->dev = NULL;
- } else {
- vcbdev->dev->vcb = vcb;
- if (flags & 1) {
- struct fiddef mapfid = {2,2,0,0};
- mapfid.fid$b_rvn = device + 1;
- sts = accessfile(vcb,&mapfid,&vcbdev->mapfcb,1);
- if (sts & 1) {
- struct VIOC *vioc;
- struct SCB *scb;
- sts = accesschunk(vcbdev->mapfcb,1,&vioc,(char **) &scb,NULL,0);
- if (sts & 1) {
- if (scb->scb$w_cluster == vcbdev->home.hm2$w_cluster) {
- vcbdev->clustersize = vcbdev->home.hm2$w_cluster;
- vcbdev->max_cluster = (scb->scb$l_volsize + scb->scb$w_cluster - 1) / scb->scb$w_cluster;
- deaccesschunk(vioc,0,0,0);
- sts = update_freecount(vcbdev,&vcbdev->free_clusters);
-#ifdef DEBUG
- printf( "%d of %d blocks are free on %12.12s\n",
- vcbdev->free_clusters * vcbdev->clustersize, scb->scb$l_volsize,
- vcbdev->home.hm2$t_volname );
-#endif
- }
+ vcbdev->dev = NULL; /*** DECREF ***/
+ continue;
+ }
+ vcbdev->dev->vcb = vcb;
+ if( VMSWORD(vcbdev->home.hm2$w_rvn) != 0 ) {
+ if( device == 0 ) {
+ struct fiddef vsfid = {6,6,1,0};
+ struct FCB *vsfcb = NULL;
+ struct VIOC *vioc = NULL;
+ unsigned recs = 0;
+ int rec;
+ unsigned int vbn = 1;
+ struct VOLSETREC *bufp;
+ int setcount = VMSWORD(vcbdev->home.hm2$w_setcount);
+
+ if( setcount != (int)devices ) {
+ printf( "%%ODS2-E-VOLCOUNT, Volume set %12.12s has %u members, but %u specified\n",
+ vcbdev->home.hm2$t_strucname, setcount, devices );
+ sts = SS$_DEVNOTMOUNT;
+ break;
+ }
+ /* Read VOLSET.SYS */
+ volsetSYS = (struct VOLSETREC *)malloc( (1+setcount) * sizeof( struct VOLSETREC ) );
+ sts = accessfile( vcb, &vsfid, &vsfcb, 0 );
+ if( (sts & 1) == 0 ) {
+ printf( "%%ODS2-E-NOVOLSET, Unable to access VOLSET.SYS: %s\n", getmsg(sts, MSG_TEXT) );
+ break;
+ }
+ for( rec = 0; rec <= setcount; rec++ ) {
+ if( recs == 0 ) {
+ if( vbn != 1 ) deaccesschunk(vioc,0,0,0);
+ sts = accesschunk(vsfcb,vbn, &vioc,(char **)&bufp, &recs, 0);
+ if( (sts & 1) == 0 ) break;
+ vbn += recs;
+ recs *= 512 / sizeof( struct VOLSETREC );
}
+ memcpy(volsetSYS+rec, bufp++, sizeof( struct VOLSETREC ));
+ }
+ deaccesschunk(vioc,0,0,0);
+ { int st2;
+ st2 = deaccessfile(vsfcb);
+ if( sts & 1 ) sts = st2;
+ }
+ if( (sts & 1) == 0 ) {
+ printf( "%%ODS2-E-VOLIOERR, Error reading VOLSET.SYS: %s\n", getmsg(sts, MSG_TEXT) );
+ break;
+ }
+ if( memcmp(vcbdev->home.hm2$t_strucname, volsetSYS[0].vsr$t_label, 12 ) != 0 ) {
+ printf( "%%ODS2-E-INCONVOL, Volume set name is '%12.12s', but VOLSET.SYS is for '%12.12s'\n",
+ vcbdev->home.hm2$t_strucname, volsetSYS[0].vsr$t_label );
+ sts = SS$_NOSUCHVOL;
+ break;
+ }
+ } else { /* device != 0 */
+ if( vcb->vcbdev[0].dev == NULL ) {
+ printf( "%%ODS2-F-NORVN1, RVN 1 must be mounted\n" );
+ sts = SS$_NOSUCHVOL;
+ break;
+ }
+ if( memcmp(vcbdev->home.hm2$t_strucname, vcb->vcbdev[0].home.hm2$t_strucname, 12) != 0 ) {
+ printf( "%%ODS2-E-INCONVOL, Volume '%12.12s' on %s is a member of '%12.12s', not a member of '%12.12s'\n",
+ vcbdev->home.hm2$t_volname, devnam[device], vcbdev->home.hm2$t_strucname,
+ vcb->vcbdev[0].home.hm2$t_strucname );
+ sts = SS$_NOSUCHVOL;
+ break;
}
}
+
+ 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,
+ volsetSYS[device+1].vsr$t_label, devnam[device], vcbdev->home.hm2$t_volname );
+ sts = SS$_NOSUCHVOL;
+ break;
+ }
+ } /* rvn != 0 */
+
+ if( vcb->status & VCB_WRITE ) {
+ struct fiddef mapfid = {2,2,0,0};
+ mapfid.fid$b_rvn = device + 1;
+ sts = accessfile( vcb, &mapfid, &vcbdev->mapfcb, 1);
+ if (sts & 1) {
+ struct VIOC *vioc;
+ struct SCB *scb;
+ sts = accesschunk(vcbdev->mapfcb,1,&vioc,(char **) &scb,NULL,0);
+ if (sts & 1) {
+ if (scb->scb$w_cluster == vcbdev->home.hm2$w_cluster) {
+ vcbdev->clustersize = vcbdev->home.hm2$w_cluster;
+ vcbdev->max_cluster = (scb->scb$l_volsize + scb->scb$w_cluster - 1) / scb->scb$w_cluster;
+ deaccesschunk(vioc,0,0,0);
+ sts = update_freecount(vcbdev,&vcbdev->free_clusters);
+#ifdef DEBUG
+ printf( "%d of %d blocks are free on %12.12s\n",
+ vcbdev->free_clusters * vcbdev->clustersize, scb->scb$l_volsize,
+ vcbdev->home.hm2$t_volname );
+#endif
+ }
+ }
+ } else {
+ printf( "%%ODS2-E-NOBITMAP, Unable to access BITMAP.SYS: %s\n", getmsg(sts, MSG_TEXT) );
+ vcbdev->mapfcb = NULL;
+ break;
+ }
}
+ if( (sts & 1) && (flags & 2) ) {
+ printf("%%MOUNT-I-MOUNTED, Volume %12.12s mounted on %s\n",
+ vcbdev->home.hm2$t_volname, vcbdev->dev->devnam);
+ }
+ } /* device len */
+ } /* for( each device ) */
+ if( !(sts & 1) ) {
+ vcbdev = vcb->vcbdev;
+ for( device = 0; device < devices; device++, vcbdev++ ) {
+ if (vcbdev->dev == NULL) continue;
+
+ if( vcb->status & VCB_WRITE && vcbdev->mapfcb != NULL ) {
+ /* sts = */
+ deaccessfile(vcbdev->mapfcb);
+ /* if( !(sts & 1) ) ??; */
+ vcbdev->idxfcb->status &= ~FCB_WRITE;
+ vcbdev->mapfcb = NULL;
+ }
+ cache_remove( &vcb->fcb->cache );
+ /* sts = */
+ deaccesshead(vcbdev->idxfcb->headvioc,vcbdev->idxfcb->head,vcbdev->idxfcb->headvbn);
+ /* if (!(sts & 1)) ??; */
+ vcbdev->idxfcb->headvioc = NULL;
+ cache_untouch(&vcbdev->idxfcb->cache,0);
+ vcbdev->dev->vcb = NULL;
+ /* ?? vcbdev->dev = NULL *//* **DECREF **/
}
- vcbdev++;
+ cache_remove( &vcb->fcb->cache );
+ while( vcb->dircache ) cache_delete( (struct CACHE *) vcb->dircache );
}
- } else {
+ } else { /* *** DECREF *** */
free(vcb);
vcb = NULL;
}
+ if( (sts & 1) && (flags & 2) && 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( volsetSYS != NULL ) free( volsetSYS );
if (retvcb != NULL) *retvcb = vcb;
return sts;
}
diff --git a/extracters/ods2/access.h b/extracters/ods2/access.h
index edc023a..604867a 100644
--- a/extracters/ods2/access.h
+++ b/extracters/ods2/access.h
@@ -173,6 +173,11 @@ struct SCB {
vmsword scb$w_checksum;
};
+struct VOLSETREC {
+ char vsr$t_label[12];
+ char vsr$b_reserved[52];
+};
+
#ifdef __ALPHA
#pragma member_alignment restore
#endif
diff --git a/extracters/ods2/descrip.mms b/extracters/ods2/descrip.mms
index 47b5f96..eb2b249 100644
--- a/extracters/ods2/descrip.mms
+++ b/extracters/ods2/descrip.mms
@@ -55,7 +55,7 @@ cache$(OBJ) : cache.c cache.h ssdef.h
phyvms$(OBJ) : phyvms.c phyio.h ssdef.h
-device$(OBJ) : device.c ssdef.h access.h phyio.h
+device$(OBJ) : device.c ssdef.h access.h phyio.h sysmsg.h
access$(OBJ) : access.c ssdef.h access.h phyio.h
diff --git a/extracters/ods2/diskio.c b/extracters/ods2/diskio.c
index 6705f19..905b22a 100644
--- a/extracters/ods2/diskio.c
+++ b/extracters/ods2/diskio.c
@@ -40,7 +40,10 @@ unsigned read_count = 0;
unsigned write_count = 0;
#define MAX_DEVS 64
-FILE *handles[1+MAX_DEVS];
+struct handle {
+ FILE *fh;
+ int drive;
+} handles[1+MAX_DEVS];
void phyio_show(void)
{
@@ -152,7 +155,6 @@ int diskio_showdrives( void ) {
}
if( n == 0 ) {
printf( "No drives assigned\n" );
- sts = 0;
}
return sts;
}
@@ -177,7 +179,7 @@ unsigned phyio_init( int devlen,char *devnam,unsigned *handle,struct phyio_info
info->sectorsize = 0;
*handle = ~0;
- for( hi = 1; hi < MAX_DEVS && handles[hi] != NULL; hi++ )
+ for( hi = 1; hi < MAX_DEVS && handles[hi].fh != NULL; hi++ )
;
if( hi >= MAX_DEVS ) {
@@ -195,11 +197,12 @@ unsigned phyio_init( int devlen,char *devnam,unsigned *handle,struct phyio_info
return SS$_NOSUCHFILE;
}
- handles[hi] = openf ( diskfiles[i], (drives[i][3] & 1)? "rb+": "rb" );
- if( handles[hi] == NULL ) {
+ handles[hi].fh = openf ( diskfiles[i], (drives[i][3] & 1)? "rb+": "rb" );
+ if( handles[hi].fh == NULL ) {
perror( diskfiles[i] );
return SS$_NOSUCHFILE;
}
+ handles[hi].drive = i;
++init_count;
@@ -208,25 +211,27 @@ unsigned phyio_init( int devlen,char *devnam,unsigned *handle,struct phyio_info
}
unsigned phyio_close(unsigned handle) {
- if( handle == 0 || handle > MAX_DEVS || handles[handle] == NULL ) {
+ if( handle == 0 || handle > MAX_DEVS || handles[handle].fh == NULL ) {
return SS$_NOIOCHAN;
}
- fclose ( handles[handle] );
- handles[handle] = NULL;
+ fclose ( handles[handle].fh );
+ handles[handle].fh = NULL;
+ if( diskio_unmapdrive(drives[handles[handle].drive] ) == 0 )
+ abort();
return SS$_NORMAL;
}
unsigned phyio_read( unsigned handle,unsigned block,unsigned length,char *buffer ) {
- if( handle == 0 || handle > MAX_DEVS || handles[handle] == NULL ) {
+ if( handle == 0 || handle > MAX_DEVS || handles[handle].fh == NULL ) {
return SS$_IVCHAN;
}
- if( fseek( handles[handle], block * 512, SEEK_SET ) == -1 ) {
+ if( fseek( handles[handle].fh, block * 512, SEEK_SET ) == -1 ) {
perror( "seek" );
return SS$_DATACHECK;
}
- if( fread( buffer, 1, length, handles[handle] ) != length ) {
+ if( fread( buffer, 1, length, handles[handle].fh ) != length ) {
perror( "read" );
return SS$_DATACHECK;
}
@@ -236,16 +241,16 @@ unsigned phyio_read( unsigned handle,unsigned block,unsigned length,char *buffer
}
unsigned phyio_write( unsigned handle,unsigned block,unsigned length,char *buffer ) {
- if( handle == 0 || handle > MAX_DEVS || handles[handle] == NULL ) {
+ if( handle == 0 || handle > MAX_DEVS || handles[handle].fh == NULL ) {
return SS$_IVCHAN;
}
- if( fseek( handles[handle], block * 512, SEEK_SET ) == -1 ) {
+ if( fseek( handles[handle].fh, block * 512, SEEK_SET ) == -1 ) {
perror( "seek" );
return SS$_DATACHECK;
}
abort();
- if( fwrite( buffer, 1, length, handles[handle] ) != length ) {
+ if( fwrite( buffer, 1, length, handles[handle].fh ) != length ) {
perror( "write" );
return SS$_DATACHECK;
}
diff --git a/extracters/ods2/header.h b/extracters/ods2/header.h
deleted file mode 100644
index 9b0c5bd..0000000
--- a/extracters/ods2/header.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Header.h v1.0 Definitions for ODS2 file headers */
-
-/* Small macro to swap words in a longword */
-
-#define swapw(w) (w[0]<<16 | w[1])
-
-/* File characteristic definitions */
-
-#define FCH$M_NOBACKUP 0x2
-#define FCH$M_CONTIGB 0x20
-#define FCH$M_LOCKED 0x40
-#define FCH$M_CONTIG 0x80
-#define FCH$M_DIRECTORY 0x2000
-#define FCH$M_MARKDEL 0x8000
-#define FCH$M_ERASE 0x20000
-
-/* File and record attribute definitions */
-
-#define FAT$C_FIXED 0x1
-#define FAT$C_VARIABLE 0x2
-#define FAT$C_VFC 0x3
-#define FAT$C_UNDEFINED 0x0
-#define FAT$C_STREAM 0x4
-#define FAT$C_STREAMLF 0x5
-#define FAT$C_STREAMCR 0x6
-
-#define FAT$C_DIRECT 0x3
-#define FAT$C_INDEXED 0x2
-#define FAT$C_RELATIVE 0x1
-#define FAT$C_SEQUENTIAL 0x0
-
-#define FAT$M_FORTRANCC 0x1
-#define FAT$M_IMPLIEDCC 0x2
-#define FAT$M_PRINTCC 0x4
-#define FAT$M_NOSPAN 0x8
-#define FAT$M_MSBRCW 0x10
-
-/* Type definitions for basic data types */
-
-typedef unsigned char u_byte;
-typedef unsigned short u_word;
-typedef unsigned int u_long;
-
-/* Structure of time */
-
-struct TIME {
- unsigned char time[8];
-};
-
-/* Definition of a UIC */
-
-struct UIC {
- u_word uic$w_mem;
- u_word uic$w_grp;
-};
-
-/* Definition for a FID */
-
-struct fiddef {
- u_word fid$w_num;
- u_word fid$w_seq;
- u_byte fid$b_rvn;
- u_byte fid$b_nmx;
-};
-
-/* RMS record definition */
-
-struct RECATTR {
- u_byte fat$b_rtype;
- u_byte fat$b_rattrib;
- u_word fat$w_rsize;
- u_word fat$l_hiblk[2];
- u_word fat$l_efblk[2];
- u_word fat$w_ffbyte;
- u_byte fat$b_bktsize;
- u_byte fat$b_vfcsize;
- u_word fat$w_maxrec;
- u_word fat$w_defext;
- u_word fat$w_gbc;
- u_byte fat$_UU0[8];
- u_word fat$w_versions;
-};
-
-/* Layout of the volume home block... */
-
-struct HOME {
- u_long hm2$l_homelbn;
- u_long hm2$l_alhomelbn;
- u_long hm2$l_altidxlbn;
- u_word hm2$w_struclev;
- u_word hm2$w_cluster;
- u_word hm2$w_homevbn;
- u_word hm2$w_alhomevbn;
- u_word hm2$w_altidxvbn;
- u_word hm2$w_ibmapvbn;
- u_long hm2$l_ibmaplbn;
- u_long hm2$l_maxfiles;
- u_word hm2$w_ibmapsize;
- u_word hm2$w_resfiles;
- u_word hm2$w_devtype;
- u_word hm2$w_rvn;
- u_word hm2$w_setcount;
- u_word hm2$w_volchar;
- struct UIC hm2$w_volowner;
- u_long hm2$l_reserved1;
- u_word hm2$w_protect;
- u_word hm2$w_fileprot;
- u_word hm2$w_reserved2;
- u_word hm2$w_checksum1;
- struct TIME hm2$q_credate;
- u_byte hm2$b_window;
- u_byte hm2$b_lru_lim;
- u_word hm2$w_extend;
- struct TIME hm2$q_retainmin;
- struct TIME hm2$q_retainmax;
- struct TIME hm2$q_revdate;
- u_byte hm2$r_min_class[20];
- u_byte hm2$r_max_class[20];
- u_byte hm2$t_reserved3[320];
- u_long hm2$l_serialnum;
- char hm2$t_strucname[12];
- char hm2$t_volname[12];
- char hm2$t_ownername[12];
- char hm2$t_format[12];
- u_word hm2$w_reserved4;
- u_word hm2$w_checksum2;
-};
-
-/* Structure of the header identification area */
-
-struct IDENT {
- char fi2$t_filename[20];
- u_word fi2$w_revision;
- struct TIME fi2$q_credate;
- struct TIME fi2$q_revdate;
- struct TIME fi2$q_expdate;
- struct TIME fi2$q_bakdate;
- char fi2$t_filenamext[66];
-};
-
-/* File header layout */
-
-struct HEAD {
- u_byte fh2$b_idoffset;
- u_byte fh2$b_mpoffset;
- u_byte fh2$b_acoffset;
- u_byte fh2$b_rsoffset;
- u_word fh2$w_seg_num;
- u_word fh2$w_struclev;
- struct fiddef fh2$w_fid;
- struct fiddef fh2$w_ext_fid;
- struct RECATTR fh2$w_recattr;
- u_long fh2$l_filechar;
- u_word fh2$w_reserved1;
- u_byte fh2$b_map_inuse;
- u_byte fh2$b_acc_mode;
- struct UIC fh2$l_fileowner;
- u_word fh2$w_fileprot;
- struct fiddef fh2$w_backlink;
- u_byte fh2$b_journal;
- u_byte fh2$b_ru_active;
- u_word fh2$w_reserved2;
- u_long fh2$l_highwater;
- u_byte fh2$b_reserved3[8];
- u_byte fh2$r_class_prot[20];
- u_byte fh2$r_restofit[402];
- u_word fh2$w_checksum;
-};
-
-/* Storage control block layout */
-
-struct SCB {
- u_word scb$w_struclev;
- u_word scb$w_cluster;
- u_long scb$l_volsize;
- u_long scb$l_blksize;
- u_long scb$l_sectors;
- u_long scb$l_tracks;
- u_long scb$l_cylinders;
- u_long scb$l_status;
- u_long scb$l_status2;
- u_word scb$w_writecnt;
- char scb$t_volockname[12];
- struct TIME scb$q_mounttime;
- u_word scb$w_backrev;
- u_long scb$q_genernum[2];
- char scb$b_reserved[446];
- u_word scb$w_checksum;
-};
diff --git a/extracters/ods2/makefile.generic b/extracters/ods2/makefile.generic
index da02a23..26f0767 100644
--- a/extracters/ods2/makefile.generic
+++ b/extracters/ods2/makefile.generic
@@ -55,7 +55,7 @@ ods2 : $(ODS2_OBJS) $(LIBS)
ods2i : $(ODS2I_OBJS)
$(CC) $(CCFLAGS) -o ods2i $(ODS2I_OBJS) $(LDFLAGS)
-access$(OBJ) : access.c ssdef.h access.h phyio.h compat.h
+access$(OBJ) : access.c ssdef.h access.h phyio.h compat.h sysmsg.h
$(CC) -c $(CCFLAGS) $(DEFS) access.c
cache$(OBJ) : cache.c cache.h ssdef.h
diff --git a/extracters/ods2/ods2.c b/extracters/ods2/ods2.c
index 3f56090..d13e27a 100644
--- a/extracters/ods2/ods2.c
+++ b/extracters/ods2/ods2.c
@@ -296,7 +296,7 @@ int prvmstime(VMSTIME vtime, const char *sfx) {
timdsc.dsc_w_length = 23;
timdsc.dsc_a_pointer = tim;
sts = sys_asctim(0,&timdsc,vtime,0);
- if ((sts & 1) == 0) printf("Asctim error: %s\n",getmsg(sts));
+ if ((sts & 1) == 0) printf("%%ODS2-W-TIMERR, SYS$ASCTIM error: %s\n",getmsg(sts, MSG_TEXT));
tim[23] = '\0';
printf(" %s",tim);
} else {
@@ -563,7 +563,7 @@ unsigned dir(int argc,char *argv[],int qualc,char *qualv[])
}
sts = sys_open(&fab);
if ((sts & 1) == 0) {
- printf("Open error: %s\n", getmsg(sts));
+ printf("%%ODS2-E-OPENERR, Open error: %s\n", getmsg(sts, MSG_TEXT));
} else {
sts = sys_close(&fab);
if (options & dir_fileid) {
@@ -739,7 +739,7 @@ Journaling enabled: None
if (sts & 1) {
if (filecount < 1) printf("%%DIRECT-W-NOFILES, no files found\n");
} else {
- printf("%%DIR-E-ERROR Status: %s\n",getmsg(sts));
+ printf("%%DIR-E-ERROR Status: %s\n",getmsg(sts, MSG_TEXT));
}
return sts;
}
@@ -784,7 +784,7 @@ unsigned copy(int argc,char *argv[],int qualc,char *qualv[])
while ((sts = sys_search(&fab)) & 1) {
sts = sys_open(&fab);
if ((sts & 1) == 0) {
- printf("%%COPY-F-OPENFAIL, Open error: %s\n",getmsg(sts));
+ printf("%%COPY-F-OPENFAIL, Open error: %s\n",getmsg(sts, MSG_TEXT));
perror("-COPY-F-ERR ");
} else {
struct RAB rab = cc$rms_rab;
@@ -859,7 +859,7 @@ unsigned copy(int argc,char *argv[],int qualc,char *qualv[])
printf("%%COPY-S-COPIED, %s copied to %s (%d record%s)\n",
rsa,name,records,(records == 1 ? "" : "s"));
} else {
- printf("%%COPY-F-ERROR Status: %s for %s\n",getmsg(sts),rsa);
+ printf("%%COPY-F-ERROR Status: %s for %s\n",getmsg(sts, MSG_TEXT),rsa);
sts = 1;
}
}
@@ -872,7 +872,7 @@ unsigned copy(int argc,char *argv[],int qualc,char *qualv[])
if (filecount > 0) printf("%%COPY-S-NEWFILES, %d file%s created\n",
filecount,(filecount == 1 ? "" : "s"));
} else {
- printf("%%COPY-F-ERROR Status: %s\n",getmsg(sts));
+ printf("%%COPY-F-ERROR Status: %s\n",getmsg(sts, MSG_TEXT));
}
return sts;
}
@@ -916,10 +916,10 @@ unsigned import(int argc,char *argv[],int qualc,char *qualv[])
}
fclose(fromf);
if (!(sts & 1)) {
- printf("%%IMPORT-F-ERROR Status: %s\n",getmsg(sts));
+ printf("%%IMPORT-F-ERROR Status: %s\n",getmsg(sts, MSG_TEXT));
}
} else {
- printf("Can't open %s\n",argv[1]);
+ printf("%%ODS2-E-OPENERR, Can't open %s\n",argv[1]);
}
return sts;
}
@@ -946,7 +946,7 @@ unsigned diff(int argc,char *argv[],int qualc,char *qualv[])
fab.fab$b_fns = strlen(fab.fab$l_fna);
tof = openf(argv[2],"r");
if (tof == NULL) {
- printf("Could not open file %s\n",argv[1]);
+ printf("%%ODS2-E-OPENERR, Could not open file %s\n",argv[1]);
sts = 0;
} else {
if ((sts = sys_open(&fab)) & 1) {
@@ -978,7 +978,7 @@ unsigned diff(int argc,char *argv[],int qualc,char *qualv[])
if (sts & 1) {
printf("%%DIFF-I-Compared %d records\n",records);
} else {
- printf("%%DIFF-F-Error %s in difference\n",getmsg(sts));
+ printf("%%DIFF-F-Error %s in difference\n",getmsg(sts, MSG_TEXT));
}
return sts;
}
@@ -1021,7 +1021,7 @@ unsigned typ(int argc,char *argv[],int qualc,char *qualv[])
if (sts == RMS$_EOF) sts = 1;
}
if ((sts & 1) == 0) {
- printf("%%TYPE-F-ERROR Status: %s\n",getmsg(sts));
+ printf("%%TYPE-F-ERROR Status: %s\n",getmsg(sts, MSG_TEXT));
}
return sts;
}
@@ -1075,7 +1075,7 @@ unsigned search(int argc,char *argv[],int qualc,char *qualv[])
while ((sts = sys_search(&fab)) & 1) {
sts = sys_open(&fab);
if ((sts & 1) == 0) {
- printf("%%SEARCH-F-OPENFAIL, Open error: %s\n",getmsg(sts));
+ printf("%%SEARCH-F-OPENFAIL, Open error: %s\n",getmsg(sts, MSG_TEXT));
} else {
struct RAB rab = cc$rms_rab;
rab.rab$l_fab = &fab;
@@ -1132,7 +1132,7 @@ unsigned search(int argc,char *argv[],int qualc,char *qualv[])
if (findcount < 1) printf("%%SEARCH-I-NOMATCHES, no strings matched\n");
}
} else {
- printf("%%SEARCH-F-ERROR Status: %s\n",getmsg(sts));
+ printf("%%SEARCH-F-ERROR Status: %s\n",getmsg(sts, MSG_TEXT));
}
return sts;
}
@@ -1181,7 +1181,7 @@ unsigned del(int argc,char *argv[],int qualc,char *qualv[])
while ((sts = sys_search(&fab)) & 1) {
sts = sys_erase(&fab);
if ((sts & 1) == 0) {
- printf("%%DELETE-F-DELERR, Delete error: %s\n",getmsg(sts));
+ printf("%%DELETE-F-DELERR, Delete error: %s\n",getmsg(sts, MSG_TEXT));
break;
} else {
filecount++;
@@ -1198,7 +1198,7 @@ unsigned del(int argc,char *argv[],int qualc,char *qualv[])
printf("%%DELETE-W-NOFILES, no files deleted\n");
}
} else {
- printf("%%DELETE-F-ERROR Status: %s\n",getmsg(sts));
+ printf("%%DELETE-F-ERROR Status: %s\n",getmsg(sts, MSG_TEXT));
}
return sts;
@@ -1249,7 +1249,7 @@ unsigned extend(int argc,char *argv[],int qualc,char *qualv[])
sys_close(&fab);
}
if ((sts & 1) == 0) {
- printf("%%EXTEND-F-ERROR Status: %s\n",getmsg(sts));
+ printf("%%EXTEND-F-ERROR Status: %s\n",getmsg(sts, MSG_TEXT));
}
return sts;
}
@@ -1318,7 +1318,7 @@ unsigned show(int argc,char *argv[],int qualc,char *qualv[]) {
curdir[curlen] = '\0';
printf(" %s\n",curdir);
} else {
- printf("Error %s getting default\n",getmsg(sts));
+ printf("%%ODS2-E-GETDEF, Error %s getting default\n",getmsg(sts, MSG_TEXT));
}
return sts;
}
@@ -1338,7 +1338,7 @@ unsigned show(int argc,char *argv[],int qualc,char *qualv[]) {
timstr[timlen] = '\0';
printf(" %s\n",timstr);
} else {
- printf("%%SHOW-W-TIMERR error %s\n",getmsg(sts));
+ printf("%%SHOW-W-TIMERR error %s\n",getmsg(sts, MSG_TEXT));
}
}
return SS$_NORMAL;
@@ -1410,7 +1410,7 @@ void setdef(char *newdef)
if ((sts = sys_setddir(&defdsc,NULL,NULL)) & 1) {
setdef_count++;
} else {
- printf("Error %s setting default to %s\n",getmsg(sts),newdef);
+ printf("%%ODS2-E-SETDEF, Error %s setting default to %s\n",getmsg(sts, MSG_TEXT),newdef);
}
}
@@ -1490,7 +1490,7 @@ unsigned set(int argc,char *argv[],int qualc,char *qualv[])
return SS$_BADPARAM;
case 0: /* default */
if( qualc ) {
- printf( "No qualifiers are permitted\n" );
+ printf( "%%ODS2-E-NOQUAL, No qualifiers are permitted\n" );
return 0;
}
setdef(argv[2]);
@@ -1548,14 +1548,11 @@ unsigned dodismount(int argc,char *argv[],int qualc,char *qualv[])
if (sts & 1) {
if (dev->vcb != NULL) {
sts = dismount(dev->vcb);
-#ifdef DISKIMAGE
- sts = diskio_unmapdrive( dev->devnam );
-#endif
} else {
sts = SS$_DEVNOTMOUNT;
}
}
- if ((sts & 1) == 0) printf("%%DISMOUNT-E-STATUS Error: %s\n",getmsg(sts));
+ if ((sts & 1) == 0) printf("%%DISMOUNT-E-STATUS Error: %s\n",getmsg(sts, MSG_TEXT));
return sts;
}
@@ -1589,6 +1586,9 @@ unsigned domount(int argc,char *argv[],int qualc,char *qualv[])
UNUSED(argc);
+ memset( labs, 0, sizeof(labs) );
+ memset( devs, 0, sizeof(devs) );
+
while (*lab != '\0') {
labs[devices++] = lab;
while (*lab != ',' && *lab != '\0') lab++;
@@ -1609,9 +1609,10 @@ unsigned domount(int argc,char *argv[],int qualc,char *qualv[])
}
}
if (devices > 0) {
- unsigned i;
struct VCB *vcb;
#ifdef DISKIMAGE
+ unsigned i;
+
for( i = 0; i < (unsigned)devices; i++ ) {
char *drive;
drive = diskio_mapfile( devs[i], (options & mnt_write) != 0 );
@@ -1620,14 +1621,11 @@ unsigned domount(int argc,char *argv[],int qualc,char *qualv[])
devs[i] = drive;
}
#endif
- sts = mount(options&mnt_write,devices,devs,labs,&vcb);
+ sts = mount( ((options & mnt_write) != 0) | 2, devices, devs, labs, &vcb );
if (sts & 1) {
- for (i = 0; i < vcb->devices; i++)
- if (vcb->vcbdev[i].dev != NULL)
- printf("%%MOUNT-I-MOUNTED, Volume %12.12s mounted on %s\n",
- vcb->vcbdev[i].home.hm2$t_volname,vcb->vcbdev[i].dev->devnam);
if (setdef_count == 0) {
- char *colon,tmp[256],defdir[256];
+ char *colon,tmp[256],defdir[256];
+
snprintf( tmp, sizeof(tmp), "%s", vcb->vcbdev[0].dev->devnam);
colon = strchr(tmp,':');
if (colon != NULL) *colon = '\0';
@@ -1636,10 +1634,10 @@ unsigned domount(int argc,char *argv[],int qualc,char *qualv[])
test_vcb = vcb;
}
} else {
- printf("Mount failed with %s\n",getmsg(sts));
+ printf("%%ODS2-E-MOUNTERR, Mount failed with %s\n", getmsg(sts, MSG_TEXT));
#ifdef DISKIMAGE
for( i = 0; i < (unsigned)devices; i++ ) {
- sts = diskio_unmapdrive( devs[i] );
+ (void) diskio_unmapdrive( devs[i] );
}
#endif
}
@@ -2026,13 +2024,13 @@ int cmdsplit(char *str)
continue;
}
if( qualc >= MAXITEMS ) {
- printf( "Too many qualifiers specified\n" );
+ printf( "%%ODS2-E-CMDERR, Too many qualifiers specified\n" );
return 0;
}
qualv[qualc++] = sp;
} else {
if( argc >= MAXITEMS ) {
- printf( "Too many arguments specified\n" );
+ printf( "%%ODS2-E-CMDERR, Too many arguments specified\n" );
return 0;
}
argv[argc++] = sp;
@@ -2045,11 +2043,11 @@ int cmdsplit(char *str)
if( *sp == '"' ) {
*sp++ = '\0';
if( *sp && *sp != ' ' ) {
- printf( "Unterminated string\n" );
+ printf( "%%ODS2-E-CMDERR, Unterminated string\n" );
return 0;
}
} else {
- printf( "Unterminated string\n" );
+ printf( "%%ODS2-E-CMDERR, Unterminated string\n" );
return 0;
}
continue;
@@ -2072,38 +2070,75 @@ int cmdsplit(char *str)
#include
#include
-char *getcmd(char *inp, char *prompt)
-{
- struct dsc_descriptor prompt_d = {strlen(prompt),DSC$K_DTYPE_T,
- DSC$K_CLASS_S, prompt};
- struct dsc_descriptor input_d = {1024,DSC$K_DTYPE_T,
- DSC$K_CLASS_S, inp};
+char *getcmd( char *inp, size_t max, char *prompt ) {
+ struct dsc_descriptor prompt_d = { strlen(prompt),DSC$K_DTYPE_T,
+ DSC$K_CLASS_S, prompt };
+ struct dsc_descriptor input_d = { max -1,DSC$K_DTYPE_T,
+ DSC$K_CLASS_S, inp };
int status;
char *retstat;
static unsigned long key_table_id = 0;
static unsigned long keyboard_id = 0;
if (key_table_id == 0) {
- status = smg$create_key_table (&key_table_id);
- if (status & 1)
- status = smg$create_virtual_keyboard (&keyboard_id);
- if (!(status & 1)) return (NULL);
+ status = smg$create_key_table( &key_table_id );
+ if (status & 1)
+ status = smg$create_virtual_keyboard( &keyboard_id );
+ if (!(status & 1)) return (NULL);
}
status = smg$read_composed_line (&keyboard_id, &key_table_id,
- &input_d, &prompt_d, &input_d, 0,0,0,0,0,0,0);
+ &input_d, &prompt_d, &input_d, 0,0,0,0,0,0,0);
if (status == SMG$_EOF)
- retstat = NULL;
+ retstat = NULL;
else {
- inp[input_d.dsc_w_length] = '\0';
- retstat = inp;
+ inp[input_d.dsc_w_length] = '\0';
+ retstat = inp;
}
return(retstat);
}
#endif /* VMS */
+/* Read a line of input - unlimited length
+ * Removes \n, returns NULL at EOF
+ * Caller responsible for free()
+ */
+char *fgetline( FILE *stream ) {
+ size_t bufsize = 0,
+ xpnsize = 80,
+ idx = 0;
+ char *buf = NULL;
+ int c;
+
+ while( (c = fgetc(stream)) != EOF && c != '\n' ) {
+ if( idx + 2 > bufsize ) {
+ char *nbuf;
+ bufsize += xpnsize;
+ nbuf = (char *) realloc( buf, bufsize );
+ if( nbuf == NULL ) {
+ perror( "realloc" );
+ abort();
+ }
+ buf = nbuf;
+ }
+ buf[idx++] = c;
+ }
+ if( c == EOF && idx == 0 ) {
+ free( buf );
+ return NULL;
+ }
+ if( bufsize == 0 ) {
+ buf = (char *) malloc( 1 );
+ if( buf == NULL ) {
+ perror( "malloc" );
+ abort();
+ }
+ }
+ buf[idx] = '\0';
+ return buf;
+}
/* main: the simple mainline of this puppy... */
@@ -2120,20 +2155,20 @@ char *getcmd(char *inp, char *prompt)
* ./ods2 -c 'mount scd1 $ set def [hartmut] $ copy *.com $ exit'
*
* The same command concatenation can be implemented for the prompted input.
- * As for indirect command files (@), it isn't checked if one of the chained
- * commands fails. The user has to be careful, all the subsequent commands
- * are executed!
*/
int main(int argc,char *argv[])
{
- char str[2048];
+ int sts;
char *command_line = NULL;
FILE *atfile = NULL;
+ char *rl = NULL;
+#ifdef VMS
+ char str[2048];
+#endif
#ifdef USE_READLINE
char *p;
wordexp_t wex;
- char *rl = NULL;
char *hfname = NULL;
char mname[3+sizeof( MNAME(MODULE_NAME) )];
@@ -2154,127 +2189,128 @@ int main(int argc,char *argv[])
}
#endif
- if (argc>1) {
- int i, l = 0;
- for (i=1; i 1 ) {
+ int i, l = 0;
+ for( i = 1; i < argc; i++ ) {
+ int al;
+ char *newp;
- if (command_line == NULL) {
- command_line = (char *)malloc(1);
- *command_line = '\0';
- l = 0;
- }
- al = strlen(argv[i]);
- newp = (char *)realloc(command_line,l+1+al+1);
- if( newp == NULL ) {
- perror( "realloc" );
- exit (1);
- }
- command_line = newp;
- snprintf(command_line+l,1+al+1," %s",argv[i]);
- l += 1+al;
- }
- } else command_line = NULL;
- while (1) {
- char *ptr;
- if (command_line) {
- static int i=0;
- unsigned j=0;
- for (; j < sizeof str && command_line[i]; i++)
- if (command_line[i] == '$') {
- ++i;
- break;
- } else str[j++] = command_line[i];
- if (j %s\n",str);
- }
- ptr = str;
- } else {
-#ifdef VMS
- if (getcmd (str, "$> ") == NULL) break;
- ptr = str;
-#elif( defined USE_READLINE )
- if (rl != NULL) {
- free( rl );
+ if (command_line == NULL) {
+ command_line = (char *)malloc(1);
+ *command_line = '\0';
+ l = 0;
}
- rl =
- ptr = readline( MNAME(MODULE_NAME) "$> " );
- if (rl == NULL) {
- break;
- } else {
- if (*rl != '\0') {
- add_history( rl );
- }
+ al = strlen(argv[i]);
+ newp = (char *)realloc(command_line,l+1+al+1);
+ if( newp == NULL ) {
+ perror( "realloc" );
+ exit (1);
}
-#else
- printf("$> ");
- if (fgets(str, sizeof(str), stdin) == NULL) break;
- ptr = strchr(str, '\n');
- if(ptr != NULL) *ptr = '\0';
- ptr = str;
-#endif
+ command_line = newp;
+ snprintf(command_line+l,1+al+1," %s",argv[i]);
+ l += 1+al;
}
- }
+ }
+ while( 1 ) {
+ char *ptr = NULL;
+ if( command_line ) {
+ static int i = 0;
+ char *p;
- while (*ptr == ' ' || *ptr == '\t') ptr++;
- if (strlen(ptr) && *ptr != '!') {
- if (*ptr == '@') {
- if (atfile != NULL) {
- printf("%%ODS2-W-INDIRECT, indirect indirection not permitted\n");
+ ptr = command_line + i;
+ if( (p = strchr( ptr, '$' )) == NULL ) {
+ if( *ptr == '\0' ) {
+ free( command_line );
+ command_line = NULL;
+ ptr = NULL;
} else {
- if ((atfile = openf(ptr + 1,"r")) == NULL) {
- perror("%%Indirection failed");
- printf("\n");
- free(command_line);
- command_line = NULL;
- *str = '\0';
- }
+ i += strlen( ptr );
}
} else {
- int sts;
-
- sts = cmdsplit(ptr);
- if( sts == -1 )
+ *p = '\0';
+ i += strlen( ptr ) +1;
+ }
+ }
+ if( ptr == NULL ) {
+ if (atfile != NULL) {
+ if( rl != NULL ) free( rl );
+ if( (rl = fgetline(atfile)) == NULL) {
+ fclose(atfile);
+ atfile = NULL;
+ } else {
+#ifndef _WIN32
+ ptr = strchr( rl, '\r' );
+ if( ptr != NULL )
+ *ptr = '\0';
+#endif
+ if( verify_cmd )
+ printf("$> %s\n", rl);
+ }
+ ptr = rl;
+ } else {
+#ifdef VMS
+ if( getcmd( str, sizeof(str), "$> " ) == NULL ) break;
+ ptr = str;
+#else
+ if( rl != NULL ) {
+ free( rl );
+ }
+#ifdef USE_READLINE
+ rl =
+ ptr = readline( MNAME(MODULE_NAME) "$> " );
+ if (rl == NULL) {
break;
- if ((sts & 1) == 0) {
- if( atfile != NULL ) {
- fclose(atfile);
- atfile = NULL;
+ } else {
+ if( *rl != '\0' ) {
+ add_history( rl );
}
+ }
+#else
+ printf("$> ");
+ if( (rl = fgetline(stdin)) == NULL) break;
+ ptr = rl;
+#endif
+#endif
+ }
+ }
+
+ while( *ptr == ' ' || *ptr == '\t' )
+ ptr++;
+ if( !strlen(ptr) || *ptr == '!' || *ptr == ';' )
+ continue;
+
+ if (*ptr == '@') {
+ if (atfile != NULL) {
+ printf("%%ODS2-W-INDIRECT, nested indirect command files not supported\n");
+ } else {
+ if ((atfile = openf(ptr + 1,"r")) == NULL) {
+ perror("%%ODS2-E-INDERR, Failed to open indirect command file");
+ printf("\n");
free(command_line);
command_line = NULL;
- *str = '\0';
- }
+ }
}
+ continue;
}
+
+ sts = cmdsplit(ptr);
+ if( sts == -1 )
+ break;
+ if ((sts & 1) == 0) {
+ if( atfile != NULL ) {
+ fclose(atfile);
+ atfile = NULL;
+ }
+ free(command_line);
+ command_line = NULL;
+ }
+ } /* while 1 */
+
+ if( rl != NULL ) {
+ free( rl );
}
#ifdef USE_READLINE
- if (rl != NULL) {
- free( rl );
- }
- if (hfname != NULL) {
+ if( hfname != NULL ) {
write_history( hfname );
}
#endif
diff --git a/extracters/ods2/sysmsg.c b/extracters/ods2/sysmsg.c
index c5eb90c..b5c5605 100644
--- a/extracters/ods2/sysmsg.c
+++ b/extracters/ods2/sysmsg.c
@@ -4,6 +4,7 @@
#include
#include
+#include
/* Should replace with lib$sys_getmsg under VMS
@@ -13,6 +14,7 @@
#include "ssdef.h"
#include "rms.h"
#include "compat.h"
+#include "sysmsg.h"
static
const struct VMSMSG {
@@ -70,17 +72,26 @@ const struct VMSMSG {
{0, NULL},
};
-const char *getmsg( unsigned int vmscode ) {
- char fmt[] = "%SYSTEM-E-NOSUCHMSG, Unknown message code %08X";
- static char buf[sizeof(fmt)+8+1];
+const char *getmsg( unsigned int vmscode, unsigned int flags ) {
+ const char fmt[] = "%%SYSTEM-E-NOSUCHMSG, Unknown message code %08X";
+ static char buf[sizeof(fmt)+8+1];
+ const char *txtp = NULL;
- for( mp = vms2text; mp->text; mp++ ) {
- if( vmscode == mp-> code ) {
- return mp->text;
+ for( mp = vms2text; mp->text; mp++ ) {
+ if( vmscode == mp-> code ) {
+ txtp = mp->text;
+ break;
+ }
}
- }
- snprintf( buf, sizeof(buf), fmt, vmscode );
- return buf;
+ if( txtp == NULL ) {
+ txtp = buf;
+ }
+ if( flags == MSG_TEXT ) {
+ txtp = strchr( txtp, ',' );
+ if( txtp == NULL ) abort();
+ return txtp+2;
+ }
+ return txtp;
}
/*
diff --git a/extracters/ods2/sysmsg.h b/extracters/ods2/sysmsg.h
index 2e8d828..1e52012 100644
--- a/extracters/ods2/sysmsg.h
+++ b/extracters/ods2/sysmsg.h
@@ -1,6 +1,8 @@
#ifndef SYSMSG_H
#define SYSMSG_H
-const char *getmsg( unsigned int vmscode );
+#define MSG_TEXT 0
+#define MSG_FULL 1
+const char *getmsg( unsigned int vmscode, unsigned int flags );
#endif