Error 94,20 on open statement on a 23 character file namefile - filenames

I'm Importing csv files provided by a third party vendor into a COBOL application. The file names are 23 characters long in .csv format. These files as delivered read successfully and correctly into Excel, Word and Vi.
When I open any of these files using the provided file names I get a COBOL error 94,20 - file not found. This occurs in both SCO OpenServer 5.0.7 (Unix) and Windows 7 runtime environments.
However if I shorten the file name (arbitrarily to 4 characters) I can open, read and close the file with no problems.
Is there a COBOL limit on the number of characters allowed in a sequential input file name? What else might cause such an open failure?
I'm running Micro-focus/ACUCOBOL-GT V7.00 compiler and ACUCOBOL-GT runtime version 5.2.1.

Older versions of SCO Unix (predecessor of SCO OpenServer) had a 14-character filename limit. If your files are named 'something.csv' then the 'something' part would have been limited to 10 chars.
This limit should not apply on OpenServer 5.0.7. However, if the COBOL you're using was compiled on a much older release, or if it's newer but voluntarily restricts its filename support in an attempt to maintain backwards compatibility, that might be the problem. You could probe this by testing it against 13, 14, 15-char filenames -- well, in general, probe different lengths to learn the actual limit.
Your 5.0.7 system should have the system call tracer command truss(C), and may also have trace(CP) (if you have the C development system installed). Running truss how-you-start-a-cobol-program longfilename.csv may produce useful output, e.g. the actual syscall and system error number which result in the error you see. The OSR5 versions of both truss and trace are moderately flaky (in different ways), so try both. Read their man pages for stuff like the "-o" flag to write output to a file.

Related

Openvms: Extracting RMS Indexed file t to Windows as a sequential flat file

I haven't used openvms for 20+ years. It was my 1st OS. I've been asked if it possible to copy the data from RMS files from openvms server to windows as a text file - so that it's readable.
No-one has experience or knowledge of the record structures etc.
The files are xyz.DAT and are relative files. I'm hoping the dat files are fixed length.
My 1st attempt would be to try and use Datatrieve (DTR) but get an error that the image isn't loaded.
Thought it might be as easy using CONVERT/FDL = nnnn.FDL - by changing the Relative to Sequential. The file seems still to be unreadable.
Is there an easy way to stream an RMS index file to a flat ASCII file?
I use to use COBOL and C to access the data in the past but had lots of libraries to help....
I've notice some solution may use odbc to connect but not sure what I can or cannot install on the server.
I can FTP using Filezilla to the server....
Another plan writing C application to read a file and output out as string.....or DCL too.....doesn't have to be quick...
Any ideas
Has mentioned before
The simple solution MIGHT be to to just use: $ TYPE/OUT=test.TXT test.DAT.
This will handle Relatie and Indexed files alike.
It is much the same as $ CONVERT / FDL=NL: test.DAT test.TXT
Both will just read records from the source and transfer the bytes, byte for byte, to the records in a sequential file.
FTP in ASCII mode will transfer that nicely to windows.
You can also use an 'inline' FDL file to generate a 'unix' LF file like:
$ conv /fdl="record; format stream_lf" test.DAT test.TXT
Or CR-LF file using:
$ conv /fdl="record; format stream" test.DAT test.TXT
Both can be transferring in Binary or Ascii with FTP.
MOSTLY - because this really only works well for TEXT ONLY source .DAT file.
There should be no CR, LF, FF or NUL characters in the source or things will break.
As 'habo' points out, use DUMP /RECORD=COUNT=3 to see how 'readable' the source data is.
If you spot 'binary' data using DUMP then you will need to find a record defintion somewhere which maps byte to Integers or Floating points or Dates as needed.
These defintions can be COBOL LIB files, or BASIC MAPS and are often stores IN the CDD (Common Data Dictionary) or indeed in DATATRIEVE .DIC DICTIONARIES
To use such definition you likely need a program to just read following the 'map' and write/print as text. Normally that's not too hard - notably not when you can find an example program on the server to tweak.
If it is just one or two 'suspect' byte ranges, then you can create a DCL loop to read and write and use F$EXTRACT to select the chunks you like.
If you want further help, kindly describe in words what kind of data is expected and perhaps provide the output from DUMP for 3 or 5 rows.
Good luck!
Hein.

How to do an incremental read of binary files

TL;DR: can I do an incremental read of binary files with Red or Rebol?
I would like to use Red to process some large (13MB to 2GB) structured binary files (Kurzweil synthesizer files). I've used other languages (C, Go, Tcl, Ruby, Dart) to walk through these files, and now I'd like to do the same with Red or Rebol.
Is there a way to incrementally read binary files, byte by byte? All I see is read/binary which seems to slurp the entire file at once (or a part of a file).
I'll need to jump around a little bit, too (either peek at the next byte, or skip to the end of a section, or skip past variable length strings to the start of data).
(Yes, I could make some helpers that tracked the position and used read/part/seek.)
I would like to make a call to the low level OS read/seek if that is possible - something new to learn.
This is on macos, but a portable solution would be great.
Thanks!
PS: "open/read %abc" gives an error "*** Script Error: open does not allow file! for its port argument", even though the help message say the port argument is "port [port! file! url! block!]"
Rebol has ports for that, which are planned for 0.7.0 release in Red. So, current I/O is very basic and buffer-only, and open is a preliminary stub.
I would like to make a call to the low level OS read/seek if that is possible - something new to learn.
You can leverage Rebol or Red/System FFI as a learning excercise.
Here is how you would do it in Rebol:
>> file: open/direct/binary %file.dat
>> until [none? probe copy/part file 20]
>> close file
#{732F7072696E74657253657474696E6773312E62}
#{696E504B01022D00140006000800000021006149}
#{0910890100001103000010000000000000000000}
...
#{000000006A290000646F6350726F70732F617070}
#{2E786D6C504B0506000000000D000D0068030000}
#{292C00000000}
none
first file or pick file 1 will return the next byte value (integer!)
This even works with text files: open/lines/direct, in that case copy/part file 20 will return 20 lines, or you can use pick file 1 or first file to get the next line.
Soon this will be available on Red too.

Patching AIX binary

I am attached to a running proces using dbx on AIX. There is a bug in the program, the offset in the opcode below is 0x9b8, but should be 0xbe8:
(dbx) listi 0x100001b14
0x100001b14 (..........+0x34) e88109b8 ld r4,0x9b8(r1)
I am able to fix that using the command below:
(dbx) assign 0x100001b14 = 0xe8810be8
but that affects only the running process and its memory. How can I change the on disk binary? I am not able to locate the pattern e88109b8 in the binary file,
otherwise I would use e.g. dd utility to patch it.
Best regards,
Pavel Filipensky

finding a corrupted part from the parts of a split archive

I have 7 files with extensions like xyz.rar.001 - xyz.rar.007 clearly they are parts of a single file. I have all the 7 parts. I join them using a file joiner into a single file xyz.rar and try to unrar them with WINRAR , it says that archive is corrupted It is clear that 1 or 2 parts are corrupted. IS THERE ANY WAY TO FIND THEM ? Please help I don't want to re download all of them NOTE- winrar can detect a corrupt part if the parts were splitted using winrar (with extensions like part1.rar , part2.rar etc. ) but not if they are named as rar.001
Parts .001 - .006 should have the same size. Check if there is a file with a different byte size.
Are there multiple files in the RAR or just the one? With multiple you could run a Test and see which is the first file to fail.
I think it's strange that there is a second tool used to split the RAR archive up. (e.g. HJSplit) This lets me think that .002 could be a RAR archive too. Try opening xyz.rar.001 with WinRAR and test/exctract. It happens more that RAR archives have the extension .001 instead of .rar. An example.
Naming your archives in WinRAR like this can be accomplished by putting "xyz.rar.001" as Archive name on the General tab and checking "Old style volume names" on the Advanced tab.
If I then join the files with HJSplit, I get one .rar file (that is corrupt). When I Test it, it says "Next volume is required". In the diagnostic messages I can see "The required volume is absent" and "CRC failed in X. The file is corrupt"
If there is one file stored inside the RAR and the RAR is indeed just chopped up into 7 pieces, there is no way of telling without additional files such as .sfv or .par2. (unless the RAR does not use compression: you can parse the underlying file for errors and calculate the part where it goes wrong)

Why doesn't this process start?

I'm trying to start the process Store.Client.UI.exe which is located at: "C:\Program Files\Intel\IntelAppStore\bin\Store.Client.UI.exe", or "C:\Program Files (x86)\Intel\IntelAppStore\bin\Store.Client.UI.exe" for 64bit like me, so I use the code:
If My.Settings.instpathtype = 86 Then
Process.Start("C:\Program Files\Intel\IntelAppStore\bin\Store.Client.UI.exe")
Else
Process.Start("C:\Program Files (x86)\Intel\IntelAppStore\bin\Store.Client.UI.exe")
End If
Where my.settings.instpathtype is whether the computer is 64 or 32 bit. But when I run it, it doesn't run Store.Client.UI.exe for some reason. When I go into Explorer and type "C:\Program Files (x86)\Intel\IntelAppStore\bin\Store.Client.UI.exe" it runs Store.Client.UI.exe. What's wrong?
From the code that you posted, I don't know where/how you're getting the value for instpathtype, or what type it is declared as.
But regardless, you really shouldn't be doing it this way. Hard-coding paths to the file system is a very bad practice if you want your code to "Just Work." What you posted above will not only break depending on the bitness of the OS, but also if the user has renamed or moved their Program Files folder. If my boot drive is E:, your code will fail on my computer as well.
Instead, you should be using the special system folders. That way, you don't even need to check whether you're running on a 32-bit or 64-bit operating system. The .NET Framework provides a really easy way of getting at these values with the Environment.GetFolderPath method, and specifying the type of folder you want to retrieve.
In this case, you want the 32-bit Program Files folder, regardless of the host OS's bitness, so you can use the ProgramFilesX86 value to retrieve the appropriate folder, like so:
Process.Start(System.Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) & "\\Intel\\IntelAppStore\\bin\\Store.Client.UI.exe")
When you are encountering problems like this, debugging comes in. Try to display what My.Settings.instpathtype outputs, by a simple MessageBox or similar. If your testing machine is 32 bit, and if the output is different from 86, change it.
EDIT: So I guess you have a 64 bit machine? Try it the other way around. Swap the statements under If and Else, then put My.Settings.instpathtype's output at the condition.
EDIT: If there are no errors on the condition, then it might be because \ is being read as an escape character. You can fix it by adding another \ before it.
If My.Settings.instpathtype = 86 Then
Process.Start("C:\\Program Files\\Intel\\IntelAppStore\\bin\\Store.Client.UI.exe")
Else
Process.Start("C:\\Program Files (x86)\\Intel\\IntelAppStore\\bin\\Store.Client.UI.exe")
End If
It's possible the process is starting and then exiting immediately with an error. Use the return process from Process.Start and check some of its properties, such as proc.exitcode, proc.starttime, and proc.exittime.
dim proc as process
...
proc = Process.Start("C:\\Program Files\\Intel\\IntelAppStore\\bin\\Store.Client.UI.exe")