- Posts: 2
- Thank you received: 0
Importing raw files by faking as disk images
- Hein
- Topic Author
- Visitor
13 years 10 months ago #5099
by Hein
Importing raw files by faking as disk images was created by Hein
Ever wondered how to get some fresh files accessible by FreeAXP without a network connection like FTP, NFS or Samba ?
Using a disk image, is a somewhat cumbersome but effective method it seems.
I tried successfully with a backup container, a zip file and en executable (self extracting zip).
Startup FreeEXP in the configuration screen; point a free device to the file to be imported; Boot FreeAXP; mount/foreign the new device; and copy blocks into a file!
A tricky part was that best I know there is no native OpenVMS tool to copy using Logical Block IO. So I wrote a tool. See below.
(sorry, the < class='quote' style='width:400px;white-space:nowrap;overflow:auto'><code style='white-space:nowrap'>...<br><br><br></code> tags still drop spaces. Sent Email!)
The cumbersome part is that a config/reboot is needed.
I don't suppose we can dynamically alter the mapping.
The buggy part was that the image is presented as truncated down to 512 bytes blocks. Fine for EXE and BCK files, not so good for ZIP.
Would it be desirable for FreeAXP to round up to the next full 512 rather then truncate? I don't know. It may cause an IO error when the last block is tried to be read. Physically add null bytes to round up?
The workaround I used for this was to APPEND some bytes to the file to fill out the last block, using ECHO or PERL. For example:
# echo "nou, eens ff kijken of we er een blockje bij kunnen toveren" >> test.zip
or
# perl -e "print q(*)x511" >> test.zip
This made it all work for me.
Now if only we had a simple ODS2 & ODS5 non-shared file manipulation tool on Windoze! Just delete and copy in and out to start with. No directory create or growth for starters. INDEXF, BITMAP...
The inverse, export process would be harder as one would need to sufficiently pre-allocate the target. Still, it coudl be a viable method to get for example a somewhat predictable SYSDUMP.DMP file of the system.
Comments?
Hein
< class='quote' style='width:400px;white-space:nowrap;overflow:auto'><code style='white-space:nowrap'>
$ type COPY_LBN_SIMPLE.C
// copy_lbn_simple.c Hein van den Heuvel, March 2011,
// HvdH Performance Consulting
// A more complete version with statistics, selectable buffers sizes
// and more feature is available. Working on double buffering.
# define DEFAULT_BLOCKS 128
#define __NEW_STARLET
#include rms
#include iodef
#include dvidef
#include prvdef
#include syidef
#include string
#include stdio
__align ( char io_buffer [ DEFAULT_BLOCKS * 512 ];
int sys$create(), sys$connect(), sys$write(), sys$close();
int sys$assign(), sys$getdviw(), sys$qiow(), sys$setprv();
struct RAB64 rab;
struct FAB fab;
main(int argc, char *argv[]) {
unsigned int privs[] = { PRV$M_LOG_IO, 0}, prvprv[2],
status, mounted, blocks_left, channel = 0, lbn = 0,
io_size = DEFAULT_BLOCKS*512,
blocks_per_io = DEFAULT_BLOCKS;
struct { short status, byte_count_low, byte_count_hi, mbz; } iosb;
struct { long count; void *address; } devnam_desc;
struct { short len, cod; void *address; int *retlen; }
getdvi_items[] = { 4, DVI$_MAXBLOCK, &blocks_left, 0,
4, DVI$_MNT, &mounted, 0, 0,0,0,0};
// Set up FAB and RAB for FIXED Length 512 Byte output file and large buffers
fab = cc$rms_fab;
rab = cc$rms_rab64;
fab.fab$b_fac = FAB$M_PUT | FAB$M_BIO ;
fab.fab$w_mrs = 512;
fab.fab$b_rfm = FAB$C_FIX;
rab.rab64$l_fab = (void *) &fab;
rab.rab64$l_rop = RAB$M_BIO;
rab.rab64$l_rbf = (char *) -1;
rab.rab64$l_ubf = (char *) -1;
rab.rab64$pq_rbf = (void *) io_buffer;
rab.rab64$q_rsz = io_size;
// Check for arguments and grab privs.
if (argc < 3 ) {
fprintf (stderr, "Usage: %s <input_device:> <output_file>\n", argv[0]);
return 268435472;
}
status = sys$setprv ( 1, privs, 0, prvprv);
if (!(status == 1) &&
((privs[0] & prvprv[0]) != privs[0])) { // SS$_NOTALLPRIV = 1665
fprintf (stderr, "Sorry, could not get required LOG_IO privilege.\n");
return status;
}
// Get a channel for QIO access, and obtain target size
devnam_desc.address = argv[1];
devnam_desc.count = strlen (argv[1]);
status=sys$assign(&devnam_desc,&channel,0,0,0);
if (status&1) status = sys$getdviw(0, channel,
0, getdvi_items, &iosb, 0,0 ,0 ,0);
if (!(status & 1)) return (status);
if ( !blocks_left || !mounted ) { // Needs, to be at least FOREIGN mounted.
fprintf (stderr, "%d blocks, device is %s mounted.\n",
blocks_left, (mounted)? "" : "NOT" );
return 124; // %SYSTEM-F-DEVNOTMOUNT, device is not mounted
}
// Create output file with initial size
fab.fab$l_fna = argv[2];
fab.fab$b_fns = strlen( argv[2] );
fab.fab$l_alq = blocks_left;
status = sys$create ( &fab);
if (status & 1) status = sys$connect ( &rab);
// Loop reading and writing while all is well and something left to copy
while (blocks_left && status & 1) {
if (blocks_left < blocks_per_io) {
blocks_per_io = blocks_left;
io_size = blocks_per_io * 512;
rab.rab64$q_rsz = io_size;
}
// Read and write IO
status = sys$qiow(0, channel, IO$_READLBLK, &iosb,
0,0, io_buffer, io_size, lbn, 0,0,0);
if (status & 1) status = iosb.status;
if (status & 1) {
status = sys$write ( &rab );
if (status & 1) {
lbn += blocks_per_io;
blocks_left -= blocks_per_io;
// Read and Write Error handling
} else {
printf ("SYS$WRITE error %d after %d blocks read at LBN %d\n",
status, blocks_per_io, lbn);
}
} else {
printf ("QIO LBN READ error %d for %d blocks read at LBN %d\n",
status, blocks_per_io, lbn);
}
}
// All done
if (status & 1) status = sys$close (&fab);
return (status);
}
<br><br><br></code>
<hr>Hein van den Heuvel
HvdH Performance Consulting
firstnamelastname.gmail.com
Using a disk image, is a somewhat cumbersome but effective method it seems.
I tried successfully with a backup container, a zip file and en executable (self extracting zip).
Startup FreeEXP in the configuration screen; point a free device to the file to be imported; Boot FreeAXP; mount/foreign the new device; and copy blocks into a file!
A tricky part was that best I know there is no native OpenVMS tool to copy using Logical Block IO. So I wrote a tool. See below.
(sorry, the < class='quote' style='width:400px;white-space:nowrap;overflow:auto'><code style='white-space:nowrap'>...<br><br><br></code> tags still drop spaces. Sent Email!)
The cumbersome part is that a config/reboot is needed.
I don't suppose we can dynamically alter the mapping.
The buggy part was that the image is presented as truncated down to 512 bytes blocks. Fine for EXE and BCK files, not so good for ZIP.
Would it be desirable for FreeAXP to round up to the next full 512 rather then truncate? I don't know. It may cause an IO error when the last block is tried to be read. Physically add null bytes to round up?
The workaround I used for this was to APPEND some bytes to the file to fill out the last block, using ECHO or PERL. For example:
# echo "nou, eens ff kijken of we er een blockje bij kunnen toveren" >> test.zip
or
# perl -e "print q(*)x511" >> test.zip
This made it all work for me.
Now if only we had a simple ODS2 & ODS5 non-shared file manipulation tool on Windoze! Just delete and copy in and out to start with. No directory create or growth for starters. INDEXF, BITMAP...
The inverse, export process would be harder as one would need to sufficiently pre-allocate the target. Still, it coudl be a viable method to get for example a somewhat predictable SYSDUMP.DMP file of the system.
Comments?
Hein
< class='quote' style='width:400px;white-space:nowrap;overflow:auto'><code style='white-space:nowrap'>
$ type COPY_LBN_SIMPLE.C
// copy_lbn_simple.c Hein van den Heuvel, March 2011,
// HvdH Performance Consulting
// A more complete version with statistics, selectable buffers sizes
// and more feature is available. Working on double buffering.
# define DEFAULT_BLOCKS 128
#define __NEW_STARLET
#include rms
#include iodef
#include dvidef
#include prvdef
#include syidef
#include string
#include stdio
__align ( char io_buffer [ DEFAULT_BLOCKS * 512 ];
int sys$create(), sys$connect(), sys$write(), sys$close();
int sys$assign(), sys$getdviw(), sys$qiow(), sys$setprv();
struct RAB64 rab;
struct FAB fab;
main(int argc, char *argv[]) {
unsigned int privs[] = { PRV$M_LOG_IO, 0}, prvprv[2],
status, mounted, blocks_left, channel = 0, lbn = 0,
io_size = DEFAULT_BLOCKS*512,
blocks_per_io = DEFAULT_BLOCKS;
struct { short status, byte_count_low, byte_count_hi, mbz; } iosb;
struct { long count; void *address; } devnam_desc;
struct { short len, cod; void *address; int *retlen; }
getdvi_items[] = { 4, DVI$_MAXBLOCK, &blocks_left, 0,
4, DVI$_MNT, &mounted, 0, 0,0,0,0};
// Set up FAB and RAB for FIXED Length 512 Byte output file and large buffers
fab = cc$rms_fab;
rab = cc$rms_rab64;
fab.fab$b_fac = FAB$M_PUT | FAB$M_BIO ;
fab.fab$w_mrs = 512;
fab.fab$b_rfm = FAB$C_FIX;
rab.rab64$l_fab = (void *) &fab;
rab.rab64$l_rop = RAB$M_BIO;
rab.rab64$l_rbf = (char *) -1;
rab.rab64$l_ubf = (char *) -1;
rab.rab64$pq_rbf = (void *) io_buffer;
rab.rab64$q_rsz = io_size;
// Check for arguments and grab privs.
if (argc < 3 ) {
fprintf (stderr, "Usage: %s <input_device:> <output_file>\n", argv[0]);
return 268435472;
}
status = sys$setprv ( 1, privs, 0, prvprv);
if (!(status == 1) &&
((privs[0] & prvprv[0]) != privs[0])) { // SS$_NOTALLPRIV = 1665
fprintf (stderr, "Sorry, could not get required LOG_IO privilege.\n");
return status;
}
// Get a channel for QIO access, and obtain target size
devnam_desc.address = argv[1];
devnam_desc.count = strlen (argv[1]);
status=sys$assign(&devnam_desc,&channel,0,0,0);
if (status&1) status = sys$getdviw(0, channel,
0, getdvi_items, &iosb, 0,0 ,0 ,0);
if (!(status & 1)) return (status);
if ( !blocks_left || !mounted ) { // Needs, to be at least FOREIGN mounted.
fprintf (stderr, "%d blocks, device is %s mounted.\n",
blocks_left, (mounted)? "" : "NOT" );
return 124; // %SYSTEM-F-DEVNOTMOUNT, device is not mounted
}
// Create output file with initial size
fab.fab$l_fna = argv[2];
fab.fab$b_fns = strlen( argv[2] );
fab.fab$l_alq = blocks_left;
status = sys$create ( &fab);
if (status & 1) status = sys$connect ( &rab);
// Loop reading and writing while all is well and something left to copy
while (blocks_left && status & 1) {
if (blocks_left < blocks_per_io) {
blocks_per_io = blocks_left;
io_size = blocks_per_io * 512;
rab.rab64$q_rsz = io_size;
}
// Read and write IO
status = sys$qiow(0, channel, IO$_READLBLK, &iosb,
0,0, io_buffer, io_size, lbn, 0,0,0);
if (status & 1) status = iosb.status;
if (status & 1) {
status = sys$write ( &rab );
if (status & 1) {
lbn += blocks_per_io;
blocks_left -= blocks_per_io;
// Read and Write Error handling
} else {
printf ("SYS$WRITE error %d after %d blocks read at LBN %d\n",
status, blocks_per_io, lbn);
}
} else {
printf ("QIO LBN READ error %d for %d blocks read at LBN %d\n",
status, blocks_per_io, lbn);
}
}
// All done
if (status & 1) status = sys$close (&fab);
return (status);
}
<br><br><br></code>
<hr>Hein van den Heuvel
HvdH Performance Consulting
firstnamelastname.gmail.com
Please Log in or Create an account to join the conversation.
- Hein
- Topic Author
- Visitor
13 years 10 months ago #5100
by Hein
Replied by Hein on topic RE: Importing raw files by faking as disk images
that was kinda stupid of me...
I tried to write a comment line with the tags for code |code| and un-code |\code| in there topic. I used the boxes, not bars, and of course they took effect.
Oh well... Hein
<hr>Hein van den Heuvel
HvdH Performance Consulting
firstnamelastname.gmail.com
I tried to write a comment line with the tags for code |code| and un-code |\code| in there topic. I used the boxes, not bars, and of course they took effect.
Oh well... Hein
<hr>Hein van den Heuvel
HvdH Performance Consulting
firstnamelastname.gmail.com
Please Log in or Create an account to join the conversation.
- malmberg
- Topic Author
- Visitor
13 years 10 months ago #5101
by malmberg
Replied by malmberg on topic RE: Importing raw files by faking as disk images
There is a tool on the freeware to read ODS-2 disks on Microsoft Windows.
Could this be modified to create a simple ODS-2 volume populated with a single file?
Could this be modified to create a simple ODS-2 volume populated with a single file?
Please Log in or Create an account to join the conversation.
- Hein
- Topic Author
- Visitor
13 years 10 months ago #5102
by Hein
Replied by Hein on topic RE: Importing raw files by faking as disk images
Along the same lines I was thinking of checking out whether DFU code could be re-used. It knows ODS and knows to find files. That would be useful to grab files from you FreeAXP drives without booting it.
To get a [b:]single[/b:] file there, I suspect that my hokey method is only slight more cumbersome than an full OpenVMS - ODS 2/5 writer on windows.
In order to write you would need access to the container file which you can not, nor should not, get while FreeAXP is running.
So to push a file there you need to shutdown, copy with special tool and reboot.
My method is to shutdown, point to target, reboot, and copy with other special tool.
A tool to truly manipulate files between windows and an ODS image would be neato.
Hein
<hr>Hein van den Heuvel
HvdH Performance Consulting
firstnamelastname.gmail.com
To get a [b:]single[/b:] file there, I suspect that my hokey method is only slight more cumbersome than an full OpenVMS - ODS 2/5 writer on windows.
In order to write you would need access to the container file which you can not, nor should not, get while FreeAXP is running.
So to push a file there you need to shutdown, copy with special tool and reboot.
My method is to shutdown, point to target, reboot, and copy with other special tool.
A tool to truly manipulate files between windows and an ODS image would be neato.
Hein
<hr>Hein van den Heuvel
HvdH Performance Consulting
firstnamelastname.gmail.com
Please Log in or Create an account to join the conversation.
13 years 10 months ago #5103
by iamcamiel
Replied by iamcamiel on topic RE: Importing raw files by faking as disk images
Hi Hein,
Interesting approach...
We're rounding down the filesize, because if the image file contains a filesystem, or if you'd like to create a filesystem on it, the OS expects every byte of every block to be there (readable and writeable).
While I can see that rounding up would be helpful in your situation, I wouldn't want to change the current default behavior. What we could do is add a configuration file parameter that will let the emulator do that.
Interesting approach...
We're rounding down the filesize, because if the image file contains a filesystem, or if you'd like to create a filesystem on it, the OS expects every byte of every block to be there (readable and writeable).
While I can see that rounding up would be helpful in your situation, I wouldn't want to change the current default behavior. What we could do is add a configuration file parameter that will let the emulator do that.
Please Log in or Create an account to join the conversation.
Moderators: iamcamiel
Time to create page: 0.197 seconds