mirror of
https://github.com/open-simh/simtools.git
synced 2026-01-13 23:36:03 +00:00
Bug fixes and compiler warnings. Unix readline support, pass 1
Fix various compiler warnings. Fix bug causing double free when a file isn't found. Fix bug using uninitialized variable parsing null filename. Fix bug causing crash when format 3 retrieval pointer encountered. Add support for readline (command line editing and history on Unix) Untangle NT I/O so it builds without the direct access SCSI API & works. Report errors as text messages everywhere. Add MSVC project files. Implement most of dir/full Partially implement XABITM Add help to command tables. Allow choice of VMS qualifiers or Unix options. mount /write // /dev/cdrom or mount -write /dev/cdrom Parse quoted strings as command parameters. Mount /write "/dev/cdrom" search [*...]*.txt "My words for you" Resolve command, parameter & qualifier ambiguity from tables. Consolidate the various makefiles into a common file with very small platform-specific wrappers. This simplifies maintenance. Add diskio module to allow easy access to .iso images and simulator files. Removes requirement for loop device or equivalent. Builds as a separate executable. Writes to the ODS2 volumes are broken.
This commit is contained in:
parent
3b052a6aa6
commit
61c8001044
245
.gitignore
vendored
245
.gitignore
vendored
@ -2,3 +2,248 @@
|
||||
*~
|
||||
*.bak
|
||||
*.o
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
|
||||
43
extracters/ods2/00INSTALL.TXT
Normal file
43
extracters/ods2/00INSTALL.TXT
Normal file
@ -0,0 +1,43 @@
|
||||
ODS-2 builds on most platforms using the make utility.
|
||||
|
||||
Most of the make logic is in makefile.generic, which is
|
||||
included by a platform-specific makefile.
|
||||
|
||||
The platform-specific files are:
|
||||
makefile.unix -- Most Unix/Linux platforms
|
||||
makefile.solaris -- Solaris
|
||||
makefile.tru64 -- Tru64/DEC OSF/1
|
||||
makefile.nt -- Windows NT
|
||||
|
||||
Select the appropriate platform file & review the definitions.
|
||||
|
||||
The easiest way to build ODS-2 is to softlink Makefile to
|
||||
the platform file. For example:
|
||||
ln -s makefile.unix Makefile
|
||||
make clean && make
|
||||
|
||||
Alternatively, the following equivalent command can be used:
|
||||
make -f makefile.unix clean && make -f makefile.unix
|
||||
|
||||
If your make doesn't support the "include" directive, you
|
||||
can run makefile.generic manually. Instructions are in that file.
|
||||
|
||||
Copy the resulting object file to a convenient location on your path,
|
||||
e.g. /usr/local/bin on unix, or add the build directory to the PATH
|
||||
environment variable on windows.
|
||||
|
||||
If you need different definitions for another platform, please
|
||||
add a new platform-specific file rather than changing makefile.generic.
|
||||
|
||||
On VMS, you can use the DCL command procedure build.com to build
|
||||
with DECC or GCC, with
|
||||
$ @build
|
||||
|
||||
build.com will automatically select decc,vaxc or gcc.
|
||||
|
||||
If you have MMS/mmk, use descrip.mms, with
|
||||
$ mmk
|
||||
To build with VAXC
|
||||
$ mmk/macro=vaxc=1
|
||||
|
||||
|
||||
87
extracters/ods2/ODS2-Image/ODS2-Image.vcxproj
Normal file
87
extracters/ods2/ODS2-Image/ODS2-Image.vcxproj
Normal file
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{1FF595D0-8CF9-4EF5-9A1B-A3FF3F3CF24C}</ProjectGuid>
|
||||
<RootNamespace>ODS2Image</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>DEBUG_BUILD;DISKIMAGE;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>access;cache;compat;device;direct;rms;sysmsg;update;vmstime;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>DISKIMAGE;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>access;cache;compat;device;direct;rms;sysmsg;update;vmstime;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\access.h" />
|
||||
<ClInclude Include="..\..\compat.h" />
|
||||
<ClInclude Include="..\..\descrip.h" />
|
||||
<ClInclude Include="..\..\phyio.h" />
|
||||
<ClInclude Include="..\..\rms.h" />
|
||||
<ClInclude Include="..\..\ssdef.h" />
|
||||
<ClInclude Include="..\..\sysmsg.h" />
|
||||
<ClInclude Include="..\diskio.h" />
|
||||
<ClInclude Include="..\version.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\diskio.c" />
|
||||
<ClCompile Include="..\ods2.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
54
extracters/ods2/ODS2-Image/ODS2-Image.vcxproj.filters
Normal file
54
extracters/ods2/ODS2-Image/ODS2-Image.vcxproj.filters
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\access.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\compat.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\descrip.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\phyio.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\rms.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\ssdef.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sysmsg.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\diskio.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\diskio.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ods2.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
29
extracters/ods2/ODS2.sln
Normal file
29
extracters/ods2/ODS2.sln
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C++ Express 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ODS2", "ODS2.vcxproj", "{BCCEAED2-1732-D796-1F70-040DE5DA42AD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ODS2-Image", "ODS2-Image\ODS2-Image.vcxproj", "{1FF595D0-8CF9-4EF5-9A1B-A3FF3F3CF24C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{BCCEAED2-1732-D796-1F70-040DE5DA42AD} = {BCCEAED2-1732-D796-1F70-040DE5DA42AD}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{BCCEAED2-1732-D796-1F70-040DE5DA42AD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BCCEAED2-1732-D796-1F70-040DE5DA42AD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BCCEAED2-1732-D796-1F70-040DE5DA42AD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BCCEAED2-1732-D796-1F70-040DE5DA42AD}.Release|Win32.Build.0 = Release|Win32
|
||||
{1FF595D0-8CF9-4EF5-9A1B-A3FF3F3CF24C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1FF595D0-8CF9-4EF5-9A1B-A3FF3F3CF24C}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1FF595D0-8CF9-4EF5-9A1B-A3FF3F3CF24C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1FF595D0-8CF9-4EF5-9A1B-A3FF3F3CF24C}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
111
extracters/ods2/ODS2.vcxproj
Normal file
111
extracters/ods2/ODS2.vcxproj
Normal file
@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>DEBUG_BUILD;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>
|
||||
</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="access.c" />
|
||||
<ClCompile Include="cache.c" />
|
||||
<ClCompile Include="compat.c" />
|
||||
<ClCompile Include="device.c" />
|
||||
<ClCompile Include="direct.c" />
|
||||
<ClCompile Include="ods2.c" />
|
||||
<ClCompile Include="phynt.c" />
|
||||
<ClCompile Include="rms.c" />
|
||||
<ClCompile Include="sysmsg.c" />
|
||||
<ClCompile Include="update.c" />
|
||||
<ClCompile Include="vmstime.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="access.h" />
|
||||
<ClInclude Include="cache.h" />
|
||||
<ClInclude Include="compat.h" />
|
||||
<ClInclude Include="descrip.h" />
|
||||
<ClInclude Include="direct.h" />
|
||||
<ClInclude Include="fibdef.h" />
|
||||
<ClInclude Include="header.h" />
|
||||
<ClInclude Include="memory.h" />
|
||||
<ClInclude Include="phyio.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="rms.h" />
|
||||
<ClInclude Include="scsidefs.h" />
|
||||
<ClInclude Include="ssdef.h" />
|
||||
<ClInclude Include="sysmsg.h" />
|
||||
<ClInclude Include="version.h" />
|
||||
<ClInclude Include="vmstime.h" />
|
||||
<ClInclude Include="wnaspi32.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ods2.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
110
extracters/ods2/ODS2.vcxproj.filters
Normal file
110
extracters/ods2/ODS2.vcxproj.filters
Normal file
@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="access.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cache.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="device.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="direct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ods2.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="phynt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rms.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="update.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vmstime.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sysmsg.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="compat.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="access.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cache.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="descrip.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="direct.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fibdef.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="header.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="memory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="phyio.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rms.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="scsidefs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ssdef.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="vmstime.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="compat.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sysmsg.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="wnaspi32.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ods2.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -46,6 +46,8 @@ How do I build it?
|
||||
compile using the gcc command:-
|
||||
gcc -fdollars-in-identifiers ods2.c,rms.c,direct.c,
|
||||
access.c,device.c,cache.c,phyos2.c,vmstime.c
|
||||
On unix, use "CCFLAGS=-DUSE_READLINE" "LDFLAGS=-lreadline" for
|
||||
readline (command history and editing) support.
|
||||
|
||||
What can it do?
|
||||
Basically ODS2 provides cut down DIRECTORY, COPY and
|
||||
@ -148,18 +150,27 @@ Can I see a command sample?
|
||||
|
||||
What commands are supported?
|
||||
A summary is:-
|
||||
mount DRIVE:[,DRIVE:...]
|
||||
mount /write DRIVE:[,DRIVE:...]
|
||||
directory [/file|/size|/date] [FILE-SPEC]
|
||||
copy FILE-SPEC OUTPUT-FILE
|
||||
copy VMSFILE-SPEC HOST-OUTPUT-FILE
|
||||
delete
|
||||
difference VMSNAME hostname (0-terminated string diff?!)
|
||||
dismount DRIVE:
|
||||
extend
|
||||
import hostname VMSNAME copy file to ODS-2
|
||||
search FILE-SPEC STRING
|
||||
set default DIR-SPEC
|
||||
show default
|
||||
show time
|
||||
statistics
|
||||
type VMSNAME
|
||||
exit
|
||||
Note - DRIVE: is normally the native system drive name,
|
||||
for example D: might be a CD on a PC - xxx: might be
|
||||
/dev/xxx on a Unix system.
|
||||
/dev/xxx on a Unix system. (Actually, on a unix
|
||||
system, '/' can't be parsed. So specify the last
|
||||
component - the rest is hardcoded. E.g. /dev/loop0
|
||||
is specified as /loop0.
|
||||
- when a list of drives is specified on the mount command
|
||||
they are assumed to contain a single valid volume set
|
||||
(this is not validated!!)
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
#include "ssdef.h"
|
||||
#include "access.h"
|
||||
#include "phyio.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#define DEBUGx
|
||||
|
||||
@ -158,6 +158,9 @@ int wcb_compare(unsigned hashval,void *keyval,void *thiswcb)
|
||||
{
|
||||
register struct WCBKEY *wcbkey = (struct WCBKEY *) keyval;
|
||||
register struct WCB *wcb = (struct WCB *) thiswcb;
|
||||
|
||||
UNUSED(hashval);
|
||||
|
||||
if (wcbkey->vbn < wcb->loblk) {
|
||||
return -1; /* Search key is less than this window maps... */
|
||||
} else {
|
||||
@ -215,6 +218,9 @@ struct HEAD *premap_indexf(struct FCB *fcb,unsigned *retsts)
|
||||
void *wcb_create(unsigned hashval,void *keyval,unsigned *retsts)
|
||||
{
|
||||
register struct WCB *wcb = (struct WCB *) malloc(sizeof(struct WCB));
|
||||
|
||||
UNUSED(hashval);
|
||||
|
||||
if (wcb == NULL) {
|
||||
*retsts = SS$_INSFMEM;
|
||||
} else {
|
||||
@ -276,6 +282,10 @@ void *wcb_create(unsigned hashval,void *keyval,unsigned *retsts)
|
||||
phylen = ((VMSWORD(*mp) & 037777) << 16) + VMSWORD(mp[1]) + 1;
|
||||
phyblk = (VMSWORD(mp[3]) << 16) | VMSWORD(mp[2]);
|
||||
mp += 4;
|
||||
break;
|
||||
default:
|
||||
printf( "Unknown type %x\n", (VMSWORD(*mp)>>14) );
|
||||
exit(1);
|
||||
}
|
||||
curvbn += phylen;
|
||||
if (phylen != 0 && curvbn > wcb->loblk) {
|
||||
@ -368,16 +378,19 @@ unsigned getwindow(struct FCB * fcb,unsigned vbn,struct VCBDEV **devptr,
|
||||
void *vioc_manager(struct CACHE * cacheobj,int flushonly)
|
||||
{
|
||||
register struct VIOC *vioc = (struct VIOC *) cacheobj;
|
||||
|
||||
UNUSED(flushonly);
|
||||
|
||||
if (vioc->modmask != 0) {
|
||||
register struct FCB *fcb = vioc->fcb;
|
||||
register int length = VIOC_CHUNKSIZE;
|
||||
register unsigned int length = VIOC_CHUNKSIZE;
|
||||
register unsigned curvbn = vioc->cache.hashval + 1;
|
||||
register char *address = (char *) vioc->data;
|
||||
register unsigned modmask = vioc->modmask;
|
||||
printf("\nvioc_manager writing vbn %d\n",curvbn);
|
||||
do {
|
||||
register unsigned sts;
|
||||
int wrtlen = 0;
|
||||
unsigned int wrtlen = 0;
|
||||
unsigned phyblk,phylen;
|
||||
struct VCBDEV *vcbdev;
|
||||
while (length > 0 && (1 & modmask) == 0) {
|
||||
@ -448,7 +461,7 @@ void *vioc_create(unsigned hashval,void *keyval,unsigned *retsts)
|
||||
if (vioc == NULL) {
|
||||
*retsts = SS$_INSFMEM;
|
||||
} else {
|
||||
register int length;
|
||||
register unsigned int length;
|
||||
register unsigned curvbn = hashval + 1;
|
||||
register char *address;
|
||||
register struct FCB *fcb = (struct FCB *) keyval;
|
||||
@ -499,7 +512,7 @@ unsigned accesschunk(struct FCB *fcb,unsigned vbn,struct VIOC **retvioc,
|
||||
char **retbuff,unsigned *retblocks,unsigned wrtblks)
|
||||
{
|
||||
unsigned sts;
|
||||
register int blocks;
|
||||
register unsigned int blocks;
|
||||
register struct VIOC *vioc;
|
||||
#ifdef DEBUG
|
||||
printf("Access chunk %8x %d (%x)\n",base,vbn,fcb->cache.hashval);
|
||||
@ -590,6 +603,10 @@ void *fcb_manager(struct CACHE *cacheobj,int flushonly)
|
||||
void *fcb_create(unsigned filenum,void *keyval,unsigned *retsts)
|
||||
{
|
||||
register struct FCB *fcb = (struct FCB *) malloc(sizeof(struct FCB));
|
||||
|
||||
UNUSED(filenum);
|
||||
UNUSED(keyval);
|
||||
|
||||
if (fcb == NULL) {
|
||||
*retsts = SS$_INSFMEM;
|
||||
} else {
|
||||
@ -718,9 +735,12 @@ unsigned dismount(struct VCB * vcb)
|
||||
|
||||
unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],struct VCB **retvcb)
|
||||
{
|
||||
register unsigned device,sts;
|
||||
register unsigned device,sts = 0;
|
||||
struct VCB *vcb;
|
||||
struct VCBDEV *vcbdev;
|
||||
|
||||
UNUSED(label);
|
||||
|
||||
if (sizeof(struct HOME) != 512 || sizeof(struct HEAD) != 512) return SS$_NOTINSTALL;
|
||||
vcb = (struct VCB *) malloc(sizeof(struct VCB) + (devices - 1) * sizeof(struct VCBDEV));
|
||||
if (vcb == NULL) return SS$_INSFMEM;
|
||||
@ -733,7 +753,7 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],stru
|
||||
sts = SS$_NOSUCHVOL;
|
||||
vcbdev->dev = NULL;
|
||||
if (strlen(devnam[device])) {
|
||||
int hba;
|
||||
unsigned int hba;
|
||||
sts = device_lookup(strlen(devnam[device]),devnam[device],1,&vcbdev->dev);
|
||||
if (!(sts & 1)) break;
|
||||
for (hba = 1; hba <= HOME_LIMIT; hba++) {
|
||||
@ -789,8 +809,12 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],stru
|
||||
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);
|
||||
printf("Freespace is %d\n",vcbdev->free_clusters);
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ typedef unsigned int vmsswap;
|
||||
typedef unsigned int vmslong;
|
||||
|
||||
#define FH2$M_NOBACKUP 0x2
|
||||
#define FH2$M_CONTIGB 0x20
|
||||
#define FH2$M_CONTIG 0x80
|
||||
#define FH2$M_DIRECTORY 0x2000
|
||||
#define FH2$M_MARKDEL 0x8000
|
||||
@ -229,20 +230,21 @@ struct DIRCACHE {
|
||||
|
||||
#define VCB_WRITE 1
|
||||
|
||||
struct VCBDEV {
|
||||
struct DEV *dev; /* Pointer to device info */
|
||||
struct FCB *idxfcb; /* Index file control block */
|
||||
struct FCB *mapfcb; /* Bitmap file control block */
|
||||
unsigned clustersize; /* Cluster size of the device */
|
||||
unsigned max_cluster; /* Total clusters on the device */
|
||||
unsigned free_clusters; /* Free clusters on disk volume */
|
||||
struct HOME home; /* Volume home block */
|
||||
};
|
||||
struct VCB {
|
||||
unsigned status; /* Volume status */
|
||||
unsigned devices; /* Number of volumes in set */
|
||||
struct FCB *fcb; /* File control block tree */
|
||||
struct DIRCACHE *dircache; /* Directory cache tree */
|
||||
struct VCBDEV {
|
||||
struct DEV *dev; /* Pointer to device info */
|
||||
struct FCB *idxfcb; /* Index file control block */
|
||||
struct FCB *mapfcb; /* Bitmap file control block */
|
||||
unsigned clustersize; /* Cluster size of the device */
|
||||
unsigned max_cluster; /* Total clusters on the device */
|
||||
unsigned free_clusters; /* Free clusters on disk volume */
|
||||
struct HOME home; /* Volume home block */
|
||||
} vcbdev[1]; /* List of volumes devices */
|
||||
struct VCBDEV vcbdev[1]; /* List of volumes devices */
|
||||
}; /* Volume control block */
|
||||
|
||||
|
||||
@ -251,7 +253,7 @@ struct DEV {
|
||||
struct VCB *vcb; /* Pointer to volume (if mounted) */
|
||||
unsigned handle; /* Device physical I/O handle */
|
||||
unsigned status; /* Device physical status */
|
||||
unsigned sectors; /* Device physical sectors */
|
||||
unsigned long long sectors; /* Device physical sectors */
|
||||
unsigned sectorsize; /* Device physical sectorsize */
|
||||
char devnam[1]; /* Device name */
|
||||
}; /* Device information */
|
||||
|
||||
@ -1,237 +0,0 @@
|
||||
/* Access.h v1.2 Definitions for file access routines */
|
||||
|
||||
/*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
email address: Paulnank@au1.ibm.com
|
||||
|
||||
ODS2 is distributed freely for all members of the
|
||||
VMS community to use. However all derived works
|
||||
must maintain comments in their source to acknowledge
|
||||
the contibution of the original author.
|
||||
*/
|
||||
|
||||
|
||||
#include "cache.h"
|
||||
#include "vmstime.h"
|
||||
|
||||
#define swapw(w) (w[0]<<16 | w[1])
|
||||
|
||||
#define FH2$M_NOBACKUP 0x2
|
||||
#define FH2$M_CONTIG 0x80
|
||||
#define FH2$M_DIRECTORY 0x2000
|
||||
#define FH2$M_MARKDEL 0x8000
|
||||
#define FH2$M_ERASE 0x20000
|
||||
|
||||
typedef unsigned char u_byte;
|
||||
typedef unsigned short u_word;
|
||||
typedef unsigned int u_long;
|
||||
|
||||
|
||||
struct UIC {
|
||||
u_word u_grp;
|
||||
u_word u_mem;
|
||||
};
|
||||
|
||||
|
||||
struct fiddef {
|
||||
u_word fid$w_num;
|
||||
u_word fid$w_seq;
|
||||
u_byte fid$b_rvn;
|
||||
u_byte fid$b_nmx;
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
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];
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
struct EXT {
|
||||
unsigned phylen;
|
||||
unsigned phyblk;
|
||||
}; /* Physical extent entry */
|
||||
|
||||
|
||||
#define EXTMAX 20
|
||||
|
||||
struct WCB {
|
||||
struct CACHE cache;
|
||||
unsigned loblk,hiblk; /* Range of window */
|
||||
unsigned hd_base; /* File blocks prior to header */
|
||||
unsigned extcount; /* Extents in use */
|
||||
struct EXT ext[EXTMAX]; /* Mapping extents */
|
||||
struct fiddef hd_fid; /* Header info to create other WCBs */
|
||||
}; /* Window control block */
|
||||
|
||||
|
||||
#define VIOC_CHUNKSIZE 4
|
||||
|
||||
struct VIOC {
|
||||
struct CACHE cache;
|
||||
struct FCB *fcb; /* File this chunk is for */
|
||||
unsigned wrtmask; /* Bit mask for writable blocks */
|
||||
unsigned modmask; /* Bit mask for modified blocks */
|
||||
char data[VIOC_CHUNKSIZE][512]; /* Chunk data */
|
||||
}; /* Chunk of a file */
|
||||
|
||||
|
||||
struct FCB {
|
||||
struct CACHE cache;
|
||||
struct VCB *vcb; /* Volume this file is for */
|
||||
struct VIOC *headvioc; /* Index file chunk for file header */
|
||||
struct HEAD *head; /* Pointer to header block */
|
||||
struct WCB *wcb; /* Window control block tree */
|
||||
struct VIOC *vioc; /* Virtual I/O chunk tree */
|
||||
unsigned modmask; /* headvioc chunk modmask */
|
||||
unsigned hiblock; /* Highest block mapped */
|
||||
unsigned highwater; /* First high water block */
|
||||
unsigned char rvn; /* Initial file relative volume */
|
||||
}; /* File control block */
|
||||
|
||||
|
||||
struct DIRCACHE {
|
||||
struct CACHE cache;
|
||||
int dirlen; /* Length of directory name */
|
||||
struct fiddef dirid; /* File ID of directory */
|
||||
char dirnam[1]; /* Directory name */
|
||||
}; /* Directory cache entry */
|
||||
|
||||
|
||||
#define VCB_WRITE 1
|
||||
|
||||
struct VCB {
|
||||
unsigned status; /* Volume status */
|
||||
unsigned devices; /* Number of volumes in set */
|
||||
struct HEAD *idxboot; /* Pointer to index file boot header */
|
||||
struct FCB *fcb; /* File control block tree */
|
||||
struct DIRCACHE *dircache; /* Directory cache tree */
|
||||
struct VCBDEV {
|
||||
struct DEV *dev; /* Pointer to device info */
|
||||
struct FCB *idxfcb; /* Index file control block */
|
||||
struct FCB *mapfcb; /* Bitmap file control block */
|
||||
struct HOME home; /* Volume home block */
|
||||
} vcbdev[1]; /* List of volumes devices */
|
||||
}; /* Volume control block */
|
||||
|
||||
|
||||
struct DEV {
|
||||
struct CACHE cache;
|
||||
struct VCB *vcb; /* Pointer to volume (if mounted) */
|
||||
unsigned handle; /* Device physical I/O handle */
|
||||
unsigned status; /* Device physical status */
|
||||
unsigned sectors; /* Device physical sectors */
|
||||
unsigned sectorsize; /* Device physical sectorsize */
|
||||
int devlen; /* Length of device name */
|
||||
char devnam[1]; /* Device name */
|
||||
}; /* Device information */
|
||||
|
||||
|
||||
unsigned device_lookup(unsigned devlen,char *devnam,int create,struct DEV **retdev);
|
||||
|
||||
unsigned dismount(struct VCB *vcb);
|
||||
unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],struct VCB **vcb);
|
||||
|
||||
unsigned accesserase(struct VCB *vcb,struct fiddef *fid);
|
||||
unsigned deaccessfile(struct FCB *fcb);
|
||||
unsigned accessfile(struct VCB *vcb,struct fiddef *fid,
|
||||
struct FCB **fcb,unsigned wrtflg);
|
||||
|
||||
unsigned deaccesschunk(struct VIOC *vioc,unsigned modmask,int reuse);
|
||||
unsigned accesschunk(struct FCB *fcb,unsigned vbn,struct VIOC **retvioc,
|
||||
char **retbuff,unsigned *retblocks,unsigned wrtblks,
|
||||
unsigned *retmodmask);
|
||||
@ -14,13 +14,16 @@ $ default=f$parse(f$environment("PROCEDURE"),,,"DEVICE","SYNTAX_ONLY")+ -
|
||||
$ set def 'default'
|
||||
$
|
||||
$ call cc ods2 'p1'
|
||||
$ call cc ods2 'p1'+"/object=ods2i.obj/define=DISKIMAGE"
|
||||
$ call cc rms 'p1'
|
||||
$ call cc direct 'p1'
|
||||
$ call cc diskio 'p1'
|
||||
$ call cc access 'p1'
|
||||
$ call cc device 'p1'
|
||||
$ call cc cache 'p1'
|
||||
$ call cc phyvms 'p1'
|
||||
$ call cc update 'p1'
|
||||
$ call cc sysmsg 'p1'
|
||||
$ call cc vmstime 'p1'
|
||||
$
|
||||
$ write sys$error "''f$time()' Linking..."
|
||||
@ -29,12 +32,13 @@ $ then library = ",vaxcrtl.tmp/option"
|
||||
$ create vaxcrtl.tmp
|
||||
sys$share:vaxcrtl/share
|
||||
$ endif
|
||||
$ link 'p2' ods2,rms,direct,access,device,cache,phyvms,vmstime,update 'library'
|
||||
$ link 'p2' /exe=ods2i.exe ods2i,rms,direct,access,device,cache,diskio,sysmsg,vmstime,update 'library'
|
||||
$ link 'p2' ods2,rms,direct,access,device,cache,phyvms,sysmsg,vmstime,update 'library'
|
||||
$ write sys$error "''f$time()' Done"
|
||||
$ exit
|
||||
$
|
||||
$cc: subroutine
|
||||
$ if f$search(p1+".obj;").nes."" then if f$cvtime(f$file(p1+".obj;","CDT")).ges.f$cvtime(f$file(p1+".c;","CDT")) then exit
|
||||
$!$ if f$search(p1+".obj;").nes."" then if f$cvtime(f$file(p1+".obj;","CDT")).ges.f$cvtime(f$file(p1+".c;","CDT")) then exit
|
||||
$ write sys$error "''f$time()' Compiling ''p1'..."
|
||||
$ cc 'p2' 'p1'
|
||||
$ exit
|
||||
|
||||
@ -1,411 +0,0 @@
|
||||
/* Cache.c v1.2 Caching control routines */
|
||||
|
||||
/*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
email address: Paulnank@au1.ibm.com
|
||||
|
||||
ODS2 is distributed freely for all members of the
|
||||
VMS community to use. However all derived works
|
||||
must maintain comments in their source to acknowledge
|
||||
the contibution of the original author.
|
||||
*/
|
||||
|
||||
/* Caching seems to have a big impact on performance!!!
|
||||
This version based on number of objects - probably
|
||||
should change it to use space occupied by objects.
|
||||
Currently use vanilla binary trees - could either
|
||||
use hashing or balanced trees for better performance. */
|
||||
|
||||
/* The theory is that all cachable objects share a common
|
||||
cache pool. Any object with a reference count of zero
|
||||
is a candidate for destruction. All cacheable objects
|
||||
have a 'struct CACHE' as the first item of the object
|
||||
so that cache pointers and object pointers are interchangeable.
|
||||
All cache objects are also part of a binary tree so that
|
||||
they can be located. There are many instances of these
|
||||
binary trees: for files on a volume, for chunks (segments)
|
||||
of files, etc. Also each object can have an object manager:
|
||||
a routine to handle special object deletion requirements
|
||||
(for example to remove all file chunks before removing a
|
||||
file), or to flush objects (write modified chunks to disk). */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include "ssdef.h"
|
||||
#include "cache.h"
|
||||
|
||||
|
||||
#define DEBUG on
|
||||
|
||||
/* Set limits for number of unaccessed cache entries... */
|
||||
|
||||
#define CACHELIM 64
|
||||
#define CACHEGOAL 25
|
||||
|
||||
int cachesearches = 0;
|
||||
int cachecreated = 0;
|
||||
int cachedeleted = 0;
|
||||
int cachepeak = 0;
|
||||
int cachecount = 0;
|
||||
int cachefreecount = 0;
|
||||
|
||||
struct CACHE cachelist = {NULL,NULL,NULL,&cachelist,&cachelist,NULL,0,0,1};
|
||||
|
||||
|
||||
/* cacheshow - to print cache statistics */
|
||||
|
||||
void cacheshow(void)
|
||||
{
|
||||
printf("CACHESHOW Searches: %d Created: %d Peak: %d Count: %d Free: %d\n",
|
||||
cachesearches,cachecreated,cachepeak,cachecount,cachefreecount);
|
||||
}
|
||||
|
||||
|
||||
void cachedump(void)
|
||||
{
|
||||
register struct CACHE *cacheobj = cachelist.lstcache;
|
||||
printf("%8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s cachelist\n","Object",
|
||||
"Parent","Left","Right","Value","Status","Count");
|
||||
while (cacheobj != &cachelist) {
|
||||
printf("%8p %8p %8p %8p %8x %8x %8d\n",
|
||||
cacheobj,cacheobj->parent,cacheobj->left,cacheobj->right,
|
||||
cacheobj->keyval,cacheobj->status,cacheobj->refcount);
|
||||
cacheobj = cacheobj->lstcache;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* cacheprint - debugging tool to print out a cache subtree... */
|
||||
|
||||
void cacheprint(struct CACHE *cacheobj,int level)
|
||||
{
|
||||
if (cacheobj != NULL) {
|
||||
int i;
|
||||
cacheprint(cacheobj->left,level + 1);
|
||||
for (i = 0; i < level; i++) printf(" ");
|
||||
printf("%8x %8x %8x %d\n",
|
||||
cacheobj,cacheobj->keyval,cacheobj->status,cacheobj->refcount);
|
||||
cacheprint(cacheobj->right,level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* cacherefcount - compute reference count for cache subtree... */
|
||||
|
||||
int cacherefcount(struct CACHE *cacheobj)
|
||||
{
|
||||
register int refcount = 0;
|
||||
if (cacheobj != NULL) {
|
||||
if (cacheobj->left != NULL) refcount += cacherefcount(cacheobj->left);
|
||||
if (cacheobj->right != NULL) refcount += cacherefcount(cacheobj->right);
|
||||
refcount += cacheobj->refcount;
|
||||
}
|
||||
return refcount;
|
||||
}
|
||||
|
||||
|
||||
/* cachefree - blow away item from cache - allow item to select a proxy (!)
|
||||
and adjust 'the tree' containing the item. */
|
||||
|
||||
int freeactive = 0; /* In case object managers re-call cachefree... :-( */
|
||||
|
||||
struct CACHE *cachefree(struct CACHE *cacheobj)
|
||||
{
|
||||
if (cacheobj->refcount != 0) {
|
||||
char str[100];
|
||||
printf("cachelist, object to delete still inuse?\n");
|
||||
printf("%8p %8p %8p %8p %8x %8x %8d\n",
|
||||
cacheobj,cacheobj->parent,cacheobj->left,cacheobj->right,
|
||||
cacheobj->keyval,cacheobj->status,cacheobj->refcount);
|
||||
printf("Type RETURN: ");
|
||||
fgets(str, sizeof(str)-1, stdin);
|
||||
return NULL;
|
||||
} else {
|
||||
register struct CACHE *proxyobj;
|
||||
while (cacheobj->objmanager != NULL) {
|
||||
freeactive = 1;
|
||||
proxyobj = (*cacheobj->objmanager) (cacheobj);
|
||||
freeactive = 0;
|
||||
if (proxyobj == NULL) return NULL;
|
||||
if (proxyobj == cacheobj) break;
|
||||
cacheobj = proxyobj;
|
||||
}
|
||||
if ((cacheobj->status & CACHE_MODIFIED) && cacheobj->objmanager == NULL)
|
||||
printf("cachelist No manager to write modified cache\n");
|
||||
cacheobj->lstcache->nxtcache = cacheobj->nxtcache;
|
||||
cacheobj->nxtcache->lstcache = cacheobj->lstcache;
|
||||
if (cacheobj->parent != NULL) { /* Check if in tree... */
|
||||
if (cacheobj->left == NULL) {
|
||||
if (cacheobj->right == NULL) {
|
||||
*(cacheobj->parent) = NULL;
|
||||
} else {
|
||||
cacheobj->right->parent = cacheobj->parent;
|
||||
*(cacheobj->parent) = cacheobj->right;
|
||||
}
|
||||
} else {
|
||||
if (cacheobj->right == NULL) {
|
||||
cacheobj->left->parent = cacheobj->parent;
|
||||
*(cacheobj->parent) = cacheobj->left;
|
||||
} else {
|
||||
register struct CACHE *leftpath = cacheobj->left;
|
||||
register struct CACHE *rightpath = cacheobj->right;
|
||||
while (1) {
|
||||
if (leftpath->right == NULL) {
|
||||
leftpath->right = cacheobj->right;
|
||||
cacheobj->right->parent = &leftpath->right;
|
||||
cacheobj->left->parent = cacheobj->parent;
|
||||
*(cacheobj->parent) = cacheobj->left;
|
||||
break;
|
||||
} else {
|
||||
if (rightpath->left == NULL) {
|
||||
rightpath->left = cacheobj->left;
|
||||
cacheobj->left->parent = &rightpath->left;
|
||||
cacheobj->right->parent = cacheobj->parent;
|
||||
*(cacheobj->parent) = cacheobj->right;
|
||||
break;
|
||||
} else {
|
||||
leftpath = leftpath->right;
|
||||
rightpath = rightpath->left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (--cachecount < 0) printf("cachelist, cache current too small\n");
|
||||
cachefreecount--;
|
||||
cachedeleted--;
|
||||
#ifdef DEBUG
|
||||
cacheobj->parent = NULL;
|
||||
cacheobj->left = NULL;
|
||||
cacheobj->right = NULL;
|
||||
cacheobj->nxtcache = NULL;
|
||||
cacheobj->lstcache = NULL;
|
||||
cacheobj->objmanager = NULL;
|
||||
cacheobj->keyval = 0;
|
||||
cacheobj->status = 0;
|
||||
cacheobj->refcount = 0;
|
||||
#endif
|
||||
free(cacheobj);
|
||||
return cacheobj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* cachepurge - trim size of free list */
|
||||
|
||||
void cachepurge()
|
||||
{
|
||||
register struct CACHE *cacheobj = cachelist.lstcache;
|
||||
while (cachefreecount > CACHEGOAL && cacheobj != &cachelist) {
|
||||
register struct CACHE *lastobj = cacheobj->lstcache;
|
||||
#ifdef DEBUG
|
||||
if (cacheobj->lstcache->nxtcache != cacheobj ||
|
||||
cacheobj->nxtcache->lstcache != cacheobj ||
|
||||
*(cacheobj->parent) != cacheobj) {
|
||||
printf("CACHE pointers in bad shape! %p %p %p - %p\n",
|
||||
cacheobj->lstcache->nxtcache,cacheobj,cacheobj->nxtcache->lstcache,*(cacheobj->parent));
|
||||
}
|
||||
#endif
|
||||
if (cacheobj->refcount == 0) {
|
||||
if (cachefree(cacheobj) != lastobj) cacheobj = lastobj;
|
||||
} else {
|
||||
cacheobj = lastobj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* cacheflush - flush modified entries in cache */
|
||||
|
||||
void cacheflush()
|
||||
{
|
||||
register struct CACHE *cacheobj = cachelist.lstcache;
|
||||
while (cacheobj != &cachelist) {
|
||||
if (cacheobj->status & CACHE_MODIFIED) {
|
||||
if (cacheobj->objmanager != NULL) {
|
||||
(*cacheobj->objmanager) (cacheobj);
|
||||
} else {
|
||||
printf("CACHEFLUSH No manager to write modified cache\n");
|
||||
}
|
||||
}
|
||||
cacheobj = cacheobj->lstcache;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* cachedelete - delete an object from cache */
|
||||
|
||||
struct CACHE *cachedelete(struct CACHE *cacheobj)
|
||||
{
|
||||
if (cacheobj != NULL) {
|
||||
register struct CACHE *cachedel;
|
||||
do {
|
||||
cachedel = cachefree(cacheobj);
|
||||
} while (cachedel != NULL && cachedel != cacheobj);
|
||||
}
|
||||
return cacheobj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* cachedeltree: delete cache subtree */
|
||||
|
||||
void cachedeltree(struct CACHE *cacheobj)
|
||||
{
|
||||
if (cacheobj != NULL) {
|
||||
if (cacheobj->left != NULL) cachedeltree(cacheobj->left);
|
||||
if (cacheobj->right != NULL) cachedeltree(cacheobj->right);
|
||||
if (cacheobj->refcount == 0) cachedelete(cacheobj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* cacheuntouch - decrement object reference count */
|
||||
|
||||
unsigned cacheuntouch(struct CACHE *cacheobj,unsigned reuse,unsigned modflg)
|
||||
{
|
||||
if (cacheobj->refcount < 1) {
|
||||
char str[100];
|
||||
printf("%8p %8p %8p %8p %8x %8x %8d\n",
|
||||
cacheobj,cacheobj->parent,cacheobj->left,cacheobj->right,
|
||||
cacheobj->keyval,cacheobj->status,cacheobj->refcount);
|
||||
printf("CACHE untouch TOO FAR!\n");
|
||||
printf("Type RETURN: ");
|
||||
fgets(str, sizeof(str), stdin);
|
||||
return 64;
|
||||
} else {
|
||||
if (modflg) {
|
||||
if ((cacheobj->status & CACHE_WRITE) == 0) return SS$_WRITLCK;
|
||||
cacheobj->status |= CACHE_MODIFIED;
|
||||
}
|
||||
if (--cacheobj->refcount == 0) {
|
||||
/* Move to new list position... */
|
||||
if (reuse == 0 && cacheobj != cachelist.lstcache) {
|
||||
cacheobj->lstcache->nxtcache = cacheobj->nxtcache;
|
||||
cacheobj->nxtcache->lstcache = cacheobj->lstcache;
|
||||
cacheobj->nxtcache = &cachelist;
|
||||
cacheobj->lstcache = cachelist.lstcache;
|
||||
cachelist.lstcache->nxtcache = cacheobj;
|
||||
cachelist.lstcache = cacheobj;
|
||||
}
|
||||
cacheobj->status &= ~CACHE_WRITE;
|
||||
if (++cachefreecount > CACHELIM && freeactive == 0) cachepurge();
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* cachetouch - add one to reference count */
|
||||
|
||||
void cachetouch(struct CACHE *cacheobj)
|
||||
{
|
||||
if (cacheobj->refcount++ < 1) {
|
||||
#ifdef DEBUG
|
||||
if (cacheobj->lstcache->nxtcache != cacheobj ||
|
||||
cacheobj->nxtcache->lstcache != cacheobj ||
|
||||
*(cacheobj->parent) != cacheobj) {
|
||||
printf("CACHE pointers in bad shape! %p %p %p - %p\n",
|
||||
cacheobj->lstcache->nxtcache,cacheobj,cacheobj->nxtcache->lstcache,*(cacheobj->parent));
|
||||
}
|
||||
#endif
|
||||
cachefreecount--;
|
||||
}
|
||||
/* Move object to head of list... */
|
||||
if (cacheobj != cachelist.nxtcache) {
|
||||
cacheobj->lstcache->nxtcache = cacheobj->nxtcache;
|
||||
cacheobj->nxtcache->lstcache = cacheobj->lstcache;
|
||||
cacheobj->lstcache = &cachelist;
|
||||
cacheobj->nxtcache = cachelist.nxtcache;
|
||||
cachelist.nxtcache->lstcache = cacheobj;
|
||||
cachelist.nxtcache = cacheobj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* cachesearch - to find or create cache entries...
|
||||
|
||||
The grand plan here was to use a hash code as a quick key
|
||||
and call a compare function for duplicates. So far no data
|
||||
type actually works like this - they either have a unique binary
|
||||
key, or all records rely on the compare function - sigh!
|
||||
Never mind, the potential is there! :-) */
|
||||
|
||||
void *cachesearch(void **root,unsigned keyval,unsigned keylen,void *key,
|
||||
int (*cmpfunc) (unsigned keylen,void *key,void *node),
|
||||
unsigned *createsize)
|
||||
{
|
||||
register struct CACHE *parentobj = NULL;
|
||||
register struct CACHE *cacheobj,**parent = (struct CACHE **) root;
|
||||
cachesearches++;
|
||||
while ((cacheobj = *parent) != NULL) {
|
||||
parentobj = cacheobj;
|
||||
if (cacheobj->keyval == keyval) {
|
||||
register int cmp = 0;
|
||||
if (cmpfunc != NULL)
|
||||
cmp = (*cmpfunc) (keylen,key,(void *) cacheobj);
|
||||
if (cmp == 0) {
|
||||
cachetouch(cacheobj);
|
||||
return cacheobj;
|
||||
} else {
|
||||
if (cmp < 0) {
|
||||
parent = &cacheobj->left;
|
||||
} else {
|
||||
parent = &cacheobj->right;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cacheobj->keyval < keyval) {
|
||||
parent = &cacheobj->left;
|
||||
} else {
|
||||
parent = &cacheobj->right;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*createsize > sizeof(struct CACHE)) {
|
||||
cacheobj = (struct CACHE *) malloc(*createsize);
|
||||
if (cacheobj != NULL) {
|
||||
cacheobj->parent = parent;
|
||||
cacheobj->left = NULL;
|
||||
cacheobj->right = NULL;
|
||||
cacheobj->objmanager = NULL;
|
||||
cacheobj->keyval = keyval;
|
||||
cacheobj->status = 0;
|
||||
cacheobj->refcount = 1;
|
||||
*parent = cacheobj;
|
||||
*createsize = 0;
|
||||
cachecreated++;
|
||||
/* Add to cache list... */
|
||||
cacheobj->lstcache = &cachelist;
|
||||
cacheobj->nxtcache = cachelist.nxtcache;
|
||||
cachelist.nxtcache->lstcache = cacheobj;
|
||||
cachelist.nxtcache = cacheobj;
|
||||
if (parentobj != NULL) {
|
||||
/* Attempt to mix up the tree a little... */
|
||||
if (parentobj->left == NULL) {
|
||||
*parentobj->parent = cacheobj;
|
||||
cacheobj->parent = parentobj->parent;
|
||||
parentobj->parent = &cacheobj->left;
|
||||
cacheobj->left = parentobj;
|
||||
parentobj->right = NULL;
|
||||
} else {
|
||||
if (parentobj->right == NULL) {
|
||||
*parentobj->parent = cacheobj;
|
||||
cacheobj->parent = parentobj->parent;
|
||||
parentobj->parent = &cacheobj->right;
|
||||
cacheobj->right = parentobj;
|
||||
parentobj->left = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cachecount++ >= cachepeak) cachepeak = cachecount;
|
||||
}
|
||||
}
|
||||
return cacheobj;
|
||||
}
|
||||
78
extracters/ods2/compat.c
Normal file
78
extracters/ods2/compat.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* Timothe Litt February 2016 */
|
||||
|
||||
/* This module contains compatibility code, currently just
|
||||
* to support Microsoft Windows.
|
||||
*
|
||||
* Microsoft deprecates sprintf, but doesn't supply standard
|
||||
* replacement until very recent IDEs.
|
||||
* Microsoft doesn't like fopen.
|
||||
* One needs to use a M$ call to translate system errors.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
|
||||
#include <stdio.h>
|
||||
#include "compat.h"
|
||||
|
||||
int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
|
||||
{
|
||||
int count = -1;
|
||||
|
||||
if (size != 0)
|
||||
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
|
||||
if (count == -1)
|
||||
count = _vscprintf(format, ap);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
|
||||
{
|
||||
int count;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
count = c99_vsnprintf(outBuf, size, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <errno.h>
|
||||
#include <windows.h>
|
||||
|
||||
FILE *openf( const char *filename, const char *mode ) {
|
||||
errno_t err;
|
||||
FILE *fd = NULL;
|
||||
|
||||
err = fopen_s( &fd, filename, mode );
|
||||
if( err == 0 ) {
|
||||
return fd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
TCHAR *w32_errstr( DWORD eno, ... ) {
|
||||
va_list ap;
|
||||
TCHAR *msg;
|
||||
|
||||
if( eno == 0 )
|
||||
eno = GetLastError();
|
||||
va_start(ap,eno);
|
||||
|
||||
if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM, NULL, eno, 0,
|
||||
(LPSTR)&msg, 1, &ap ) == 0 ) {
|
||||
msg = (TCHAR *)malloc( 32 );
|
||||
snprintf( msg, 32, "(%u)", eno );
|
||||
}
|
||||
va_end(ap);
|
||||
return msg;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* For ISO C compliance, ensure that there's something in this module */
|
||||
void dummy_compat ( void ) { return; }
|
||||
30
extracters/ods2/compat.h
Normal file
30
extracters/ods2/compat.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef COMPAT_H
|
||||
#define COMPAT_H
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
|
||||
#define snprintf c99_snprintf
|
||||
#define vsnprintf c99_vsnprintf
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap);
|
||||
int c99_snprintf(char *outBuf, size_t size, const char *format, ...);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
FILE *openf( const char *filename, const char *mode );
|
||||
|
||||
TCHAR *w32_errstr( DWORD eno, ... );
|
||||
|
||||
#else
|
||||
#define openf fopen
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#endif
|
||||
@ -29,28 +29,46 @@ OPTFILE =
|
||||
OPTIONS =
|
||||
.ENDIF
|
||||
|
||||
OBJS = ODS2,RMS,DIRECT,ACCESS,DEVICE,CACHE,PHYVMS,UPDATE,VMSTIME
|
||||
OBJS = $(ODS2_OBJS) $(ODS2I_OBJS)
|
||||
|
||||
COMMON_OBJS = RMS,DIRECT,ACCESS,DEVICE,CACHE,UPDATE,SYSMSG,VMSTIME
|
||||
|
||||
ODS2_OBJS = ODS2$(OBJ) $(COMMON_OBJS) PHYVMS
|
||||
|
||||
ODS2I_OBJS = ODS2I$(OBJ) $(COMON_OBJS) DISKIO
|
||||
|
||||
ODS2 : ODS2$(EXE) ODS2I(EXE)
|
||||
|
||||
ODS2I$(EXE) : ODS2I$(OLB)($(ODS2I_OBJS))$(OPTFILE)
|
||||
$(LINK) $(LINKFLAGS) ODS2I$(OLB)/INCLUDE=($(ODS2I_OBJS))$(OPTIONS)
|
||||
|
||||
ODS2$(EXE) : ODS2$(OLB)($(OBJS))$(OPTFILE)
|
||||
$(LINK)$(LINKFLAGS) ODS2$(OLB)/INCLUDE=($(OBJS))$(OPTIONS)
|
||||
$(LINK)$(LINKFLAGS) ODS2$(OLB)/INCLUDE=($(ODS2_OBJS))$(OPTIONS)
|
||||
|
||||
vmstime$(obj) : vmstime.c vmstime.h
|
||||
vmstime$(OBJ) : vmstime.c vmstime.h
|
||||
|
||||
cache$(obj) : cache.c cache.h ssdef.h
|
||||
sysmsg$(OBJ) : sysmsg.c sysmsg.h ssdef.h rms.h
|
||||
|
||||
phyvms$(obj) : phyvms.c phyio.h ssdef.h
|
||||
diskio$(OBJ) : diskio sysmsg.h ssdef.h rms.h
|
||||
|
||||
device$(obj) : device.c ssdef.h access.h phyio.h
|
||||
cache$(OBJ) : cache.c cache.h ssdef.h
|
||||
|
||||
access$(obj) : access.c ssdef.h access.h phyio.h
|
||||
phyvms$(OBJ) : phyvms.c phyio.h ssdef.h
|
||||
|
||||
update$(obj) : update.c ssdef.h access.h
|
||||
device$(OBJ) : device.c ssdef.h access.h phyio.h
|
||||
|
||||
direct$(obj) : direct.c direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
access$(OBJ) : access.c ssdef.h access.h phyio.h
|
||||
|
||||
rms$(obj) : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
update$(OBJ) : update.c ssdef.h access.h
|
||||
|
||||
ods2$(obj) : ods2.c ssdef.h descrip.h access.h rms.h
|
||||
direct$(OBJ) : direct.c direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
|
||||
rms$(OBJ) : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
|
||||
ods2$(OBJ) : ods2.c compat.h sysmsg.h phyio.h ssdef.h descrip.h access.h rms.h
|
||||
|
||||
CFLAGS=$(CFLAGS)/DEFINE=DISKIMAGE
|
||||
ods2i$(OBJ) : ods2.c compat.h diskio.h sysmsg.h phyio.h ssdef.h descrip.h access.h rms.h
|
||||
|
||||
VAXCRTL.OPT :
|
||||
@ open/write tmp $(MMS$TARGET)
|
||||
|
||||
@ -136,12 +136,15 @@ int name_match(char *spec,int spec_len,char *dirent,int dirent_len)
|
||||
register char sch = *name;
|
||||
if (sch != '*') {
|
||||
register char ech = *entry;
|
||||
if (sch != ech) if (toupper(sch) != toupper(ech))
|
||||
if (sch == '%') {
|
||||
percent = MAT_NE;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (sch != ech) {
|
||||
if (toupper(sch) != toupper(ech)) {
|
||||
if (sch == '%') {
|
||||
percent = MAT_NE;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -294,7 +297,8 @@ unsigned insert_ent(struct FCB * fcb,unsigned eofblk,unsigned curblk,
|
||||
struct VIOC *newvioc;
|
||||
unsigned newblk = eofblk + 1;
|
||||
direct_splits++;
|
||||
printf("Splitting record... %d %d\n",dr,de);
|
||||
printf("Splitting record... %s %u,%u,%u,%u\n", dr->dir$name,de->dir$fid.fid$w_num,
|
||||
de->dir$fid.fid$w_seq,de->dir$fid.fid$b_rvn,de->dir$fid.fid$b_nmx);
|
||||
if (newblk > fcb->hiblock) {
|
||||
printf("I can't extend a directory yet!!\n");
|
||||
exit(0);
|
||||
@ -353,7 +357,8 @@ unsigned insert_ent(struct FCB * fcb,unsigned eofblk,unsigned curblk,
|
||||
register unsigned reclen = (dr->dir$namecount +
|
||||
sizeof(struct dir$rec)) & ~1;
|
||||
register struct dir$rec *nbr = (struct dir$rec *) newbuf;
|
||||
printf("Super split %d %d\n",dr,de);
|
||||
printf("Super split %s %u,%u,%u,%u\n", dr->dir$name,de->dir$fid.fid$w_num,
|
||||
de->dir$fid.fid$w_seq,de->dir$fid.fid$b_rvn,de->dir$fid.fid$b_nmx);
|
||||
memcpy(newbuf,buffer,reclen);
|
||||
memcpy(newbuf + reclen,de,((char *) nr - (char *) de) + 2);
|
||||
nbr->dir$size = VMSWORD(reclen + ((char *) nr - (char *) de) - 2);
|
||||
|
||||
218
extracters/ods2/diskio.c
Normal file
218
extracters/ods2/diskio.c
Normal file
@ -0,0 +1,218 @@
|
||||
/* diskio.c - ANSI C Disk I/O - for .ISO and simulator disks */
|
||||
|
||||
/* Timothe Litt Feb 2016
|
||||
*
|
||||
* This is part of ODS2 written by Paul Nankervis,
|
||||
* email address: Paulnank@au1.ibm.com
|
||||
*
|
||||
* ODS2 is distributed freely for all members of the
|
||||
* VMS community to use. However all derived works
|
||||
* must maintain comments in their source to acknowledge
|
||||
* the contibution of the original author.
|
||||
*/
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#if __FILE_OFFSET_BITS == 64
|
||||
# undef fseek
|
||||
# ifdef _WIN32
|
||||
# define fseek _fseeki64
|
||||
# undef off_t
|
||||
# define off_t __int64
|
||||
# else
|
||||
# define fseek fseeko
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include "phyio.h"
|
||||
#include "ssdef.h"
|
||||
|
||||
unsigned init_count = 0;
|
||||
unsigned read_count = 0;
|
||||
unsigned write_count = 0;
|
||||
|
||||
#define MAX_DEVS 64
|
||||
FILE *handles[1+MAX_DEVS];
|
||||
|
||||
void phyio_show(void)
|
||||
{
|
||||
printf("PHYIO_SHOW Initializations: %d Reads: %d Writes: %d\n",
|
||||
init_count,read_count,write_count);
|
||||
}
|
||||
|
||||
void phyio_help(FILE *fp ) {
|
||||
fprintf( fp, "Specify the file containing a disk image to be mounted.\n" );
|
||||
fprintf( fp, "E.g. mount mydisk.iso\n" );
|
||||
fprintf( fp, "A drive letter will be assigned to the image. Use that\n" );
|
||||
fprintf( fp, "letter to refer to the VMS volume in subsequent commands\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
static char *diskfiles[26];
|
||||
static char drives[26][4];
|
||||
|
||||
/* Deeper code assumes that the device name is terminated by ':' and that this is
|
||||
* the physical device. To keep it happy, map the next free drive letter to this
|
||||
* filename, and use it to identify the device. phyio_init will check the mapping table
|
||||
* to get the actual filename to open.
|
||||
*/
|
||||
|
||||
char *diskio_mapfile( const char *filename, int options ) {
|
||||
int l, L = -1;
|
||||
for( l = 0; l < 26; l++ ) {
|
||||
if( diskfiles[l] == NULL && L < 0 ) L = l;
|
||||
if( diskfiles[l] && strcmp( diskfiles[l], filename ) == 0 ) {
|
||||
printf( "%s is already mounted as drive %s\n", filename, drives[l] );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if( L < 0 ) {
|
||||
printf( "No free drive letters for %s\n", filename );
|
||||
return 0;
|
||||
}
|
||||
snprintf(drives[L], 3, "%c:", L + 'A');
|
||||
drives[L][3] = options;
|
||||
free(diskfiles[L]);
|
||||
diskfiles[L] = (char *) malloc( (l = strlen(filename) + 1) );
|
||||
snprintf( diskfiles[L], l, "%s", filename );
|
||||
|
||||
printf( "%s assigned to %s\n", drives[L], diskfiles[L] );
|
||||
|
||||
return drives[L];
|
||||
}
|
||||
|
||||
int diskio_showdrives( void ) {
|
||||
int n = 0;
|
||||
int l;
|
||||
size_t max;
|
||||
int sts = 1;
|
||||
|
||||
max = sizeof( "Filename" ) -1;
|
||||
|
||||
for( l = 0; l < 26; l++ ) {
|
||||
if( diskfiles[l] != NULL && strlen(diskfiles[l]) > max )
|
||||
max = strlen(diskfiles[l]);
|
||||
}
|
||||
for( l = 0; l < 26; l++ ) {
|
||||
if( diskfiles[l] == NULL )
|
||||
continue;
|
||||
|
||||
if( !n++ ) {
|
||||
printf( "Drv Sts Filename\n"
|
||||
"--- --- " );
|
||||
while( max-- ) fputc( '-', stdout );
|
||||
printf( "\n" );
|
||||
}
|
||||
printf( " %s %-3s %s\n", drives[l], (drives[l][3] &1)? "RW": "RO", diskfiles[l] );
|
||||
}
|
||||
if( n == 0 ) {
|
||||
printf( "No drives assigned\n" );
|
||||
sts = 0;
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
int diskio_unmapdrive( const char *drive ) {
|
||||
if( diskfiles[drive[0]-'A'] == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
free(diskfiles[drive[0]-'A']);
|
||||
diskfiles[drive[0]-'A'] = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned phyio_init( int devlen,char *devnam,unsigned *handle,struct phyio_info *info ) {
|
||||
size_t hi;
|
||||
int i;
|
||||
|
||||
UNUSED ( devlen );
|
||||
|
||||
info->status = 0;
|
||||
info->sectors = 0;
|
||||
info->sectorsize = 0;
|
||||
*handle = ~0;
|
||||
|
||||
for( hi = 1; hi < MAX_DEVS && handles[hi] != NULL; hi++ )
|
||||
;
|
||||
|
||||
if( hi >= MAX_DEVS ) {
|
||||
return SS$_IVCHAN;
|
||||
}
|
||||
|
||||
if( (devnam[0] < 'A' || devnam[0] > 'Z') || devnam[1] != ':' ) {
|
||||
printf ( "%s is not a mapped device name\n", devnam );
|
||||
return SS$_NOSUCHFILE;
|
||||
}
|
||||
|
||||
i = *devnam - 'A';
|
||||
if( diskfiles[i] == NULL ) {
|
||||
printf ( "%s is not a mapped device name\n", devnam );
|
||||
return SS$_NOSUCHFILE;
|
||||
}
|
||||
|
||||
handles[hi] = openf ( diskfiles[i], (drives[i][3] & 1)? "rb+": "rb" );
|
||||
if( handles[hi] == NULL ) {
|
||||
perror( diskfiles[i] );
|
||||
return SS$_NOSUCHFILE;
|
||||
}
|
||||
|
||||
++init_count;
|
||||
|
||||
*handle = hi;
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
unsigned phyio_close(unsigned handle) {
|
||||
if( handle == 0 || handle > MAX_DEVS || handles[handle] == NULL ) {
|
||||
return SS$_NOIOCHAN;
|
||||
}
|
||||
fclose ( handles[handle] );
|
||||
handles[handle] = NULL;
|
||||
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
unsigned phyio_read( unsigned handle,unsigned block,unsigned length,char *buffer ) {
|
||||
if( handle == 0 || handle > MAX_DEVS || handles[handle] == NULL ) {
|
||||
return SS$_IVCHAN;
|
||||
}
|
||||
|
||||
if( fseek( handles[handle], block * 512, SEEK_SET ) == -1 ) {
|
||||
perror( "seek" );
|
||||
return SS$_DATACHECK;
|
||||
}
|
||||
if( fread( buffer, 1, length, handles[handle] ) != length ) {
|
||||
perror( "read" );
|
||||
return SS$_DATACHECK;
|
||||
}
|
||||
|
||||
++read_count;
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
unsigned phyio_write( unsigned handle,unsigned block,unsigned length,char *buffer ) {
|
||||
if( handle == 0 || handle > MAX_DEVS || handles[handle] == NULL ) {
|
||||
return SS$_IVCHAN;
|
||||
}
|
||||
|
||||
if( fseek( handles[handle], block * 512, SEEK_SET ) == -1 ) {
|
||||
perror( "seek" );
|
||||
return SS$_DATACHECK;
|
||||
}
|
||||
abort();
|
||||
if( fwrite( buffer, 1, length, handles[handle] ) != length ) {
|
||||
perror( "write" );
|
||||
return SS$_DATACHECK;
|
||||
}
|
||||
++write_count;
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
43
extracters/ods2/diskio.h
Normal file
43
extracters/ods2/diskio.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef DISKIO_H
|
||||
#define DISKIO_H
|
||||
|
||||
/* diskio.h - ANSI C Disk I/O - for .ISO and simulator disks */
|
||||
|
||||
/* Timothe Litt Feb 2016
|
||||
*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
email address: Paulnank@au1.ibm.com
|
||||
|
||||
ODS2 is distributed freely for all members of the
|
||||
VMS community to use. However all derived works
|
||||
must maintain comments in their source to acknowledge
|
||||
the contibution of the original author.
|
||||
*/
|
||||
|
||||
/* To set up physical I/O for a new system a group of phyio
|
||||
routines need to be set up. They are:-
|
||||
phyio_show() which doesn't need to do anything - but
|
||||
it would generally print some statistics
|
||||
about the other phyio calls.
|
||||
phyio_init() to prepare a device for use by future
|
||||
read/write calls. The device name would usually
|
||||
map to a local device - for example rra: to /dev/rra
|
||||
on a Unix system. The call needs to return a handle
|
||||
(channel, file handle, reference number...) for
|
||||
future reference, and optionally some device
|
||||
information.
|
||||
phyio_read() will return a specified number of bytes into a
|
||||
buffer from the start of a 512 byte block on the
|
||||
device referred to by the handle.
|
||||
phyio_write() will write a number of bytes out to a 512 byte block
|
||||
address on a device.
|
||||
|
||||
*/
|
||||
|
||||
char *diskio_mapfile( const char *filename, int options );
|
||||
|
||||
int diskio_unmapdrive( const char *drive );
|
||||
|
||||
int diskio_showdrives( void );
|
||||
|
||||
#endif
|
||||
95
extracters/ods2/makefile.generic
Normal file
95
extracters/ods2/makefile.generic
Normal file
@ -0,0 +1,95 @@
|
||||
# Generic makefile for ods2
|
||||
#
|
||||
# See makefile.<osname>, which normally includes it
|
||||
#
|
||||
# If your make doesn't support include, these can be
|
||||
# specified manually, for example:
|
||||
# make CC=gcc "CCFLAGS=-O4 -f" OBJ=.o \
|
||||
# PHYSIO=phyunix DEFS=-DUSE_READLINE LDFLAGS=-lreadline
|
||||
#
|
||||
# or just combine the files you need with an editor.
|
||||
#
|
||||
# ###
|
||||
|
||||
# OS-Specific defines
|
||||
# These variables are available
|
||||
|
||||
# Other defines = "-DDEBUG_BUILD" "-D_FILE_OFFSET_BITS=32"
|
||||
#DEFS =
|
||||
|
||||
# Libraries, e.g. -lreadline
|
||||
#LDFLAGS =
|
||||
|
||||
# Object file suffix
|
||||
#OBJ = .o
|
||||
|
||||
# Physical IO module
|
||||
#PHYSIO = phyunix
|
||||
|
||||
# Extra physical IO headers
|
||||
#PHYSIOH =
|
||||
|
||||
# #####################################################
|
||||
|
||||
all : ods2 ods2i
|
||||
|
||||
OBJS = $(ODS2_OBJS) $(ODS2I_OBJS)
|
||||
|
||||
COMMON_OBJS = \
|
||||
access$(OBJ) \
|
||||
cache$(OBJ) \
|
||||
compat$(OBJ)\
|
||||
device$(OBJ) \
|
||||
direct$(OBJ) \
|
||||
rms$(OBJ) \
|
||||
sysmsg$(OBJ) \
|
||||
update$(OBJ) \
|
||||
vmstime$(OBJ)
|
||||
|
||||
ODS2_OBJS = ods2$(OBJ) $(COMMON_OBJS) $(PHYSIO)$(OBJ)
|
||||
ODS2I_OBJS = ods2i$(OBJ) $(COMMON_OBJS) diskio$(OBJ)
|
||||
|
||||
ods2 : $(ODS2_OBJS) $(LIBS)
|
||||
$(CC) $(CCFLAGS) -o ods2 $(ODS2_OBJS) $(LDFLAGS)
|
||||
|
||||
ods2i : $(ODS2I_OBJS)
|
||||
$(CC) $(CCFLAGS) -o ods2i $(ODS2I_OBJS) $(LDFLAGS)
|
||||
|
||||
access$(OBJ) : access.c ssdef.h access.h phyio.h compat.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) access.c
|
||||
|
||||
cache$(OBJ) : cache.c cache.h ssdef.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) cache.c
|
||||
|
||||
compat$(OBJ) : compat.c compat.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) compat.c
|
||||
|
||||
device$(OBJ) : device.c ssdef.h access.h phyio.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) device.c
|
||||
|
||||
direct$(OBJ) : direct.c direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) direct.c
|
||||
|
||||
diskio$(OBJ) : diskio.c diskio.h compat.h phyio.h ssdef.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) diskio.c
|
||||
|
||||
ods2$(OBJ) : ods2.c compat.h sysmsg.h phyio.h ssdef.h descrip.h access.h rms.h version.h
|
||||
$(CC) -c $(CCFLAGS) $(VERSION) $(DEFS) ods2.c
|
||||
|
||||
ods2i$(OBJ) : ods2.c compat.h diskio.h sysmsg.h phyio.h ssdef.h descrip.h access.h rms.h version.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) -DDISKIMAGE -o ods2i$(OBJ) ods2.c
|
||||
|
||||
$(PHYSIO)$(OBJ) : $(PHYSIO).c phyio.h ssdef.h compat.h $(PHYSIOH)
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) $(PHYSIO).c
|
||||
|
||||
rms$(OBJ) : rms.c rms.h compat.h direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) rms.c
|
||||
|
||||
sysmsg$(OBJ) : sysmsg.c sysmsg.h rms.h ssdef.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) sysmsg.c
|
||||
|
||||
update$(OBJ) : update.c ssdef.h access.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) update.c
|
||||
|
||||
vmstime$(OBJ) : vmstime.c vmstime.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) vmstime.c
|
||||
@ -1,53 +1,23 @@
|
||||
|
||||
# Makefile for Windows NT
|
||||
#
|
||||
|
||||
CCFLAGS = "-Oxs"
|
||||
|
||||
DEFS = "-DVERSION=\"v1.3\""
|
||||
# For the direct SCSI module
|
||||
#DEFS = -DUSE_WNASPI32
|
||||
#LDFLAGS = wnaspi32.lib
|
||||
#PHYSIOH = wnaspi32.h scsidefs.h
|
||||
#LIBS = wnaspi32.lib
|
||||
|
||||
all : ods2
|
||||
OBJ = .OBJ
|
||||
PHYSIO = phynt
|
||||
|
||||
OBJS = ods2.obj \
|
||||
rms.obj \
|
||||
direct.obj \
|
||||
update.obj \
|
||||
access.obj \
|
||||
device.obj \
|
||||
phynt.obj \
|
||||
cache.obj \
|
||||
vmstime.obj
|
||||
|
||||
ods2 : $(OBJS) wnaspi32.lib
|
||||
$(CC) $(CCFLAGS) -oods2 $(OBJS) wnaspi32.lib
|
||||
|
||||
vmstime.obj : vmstime.c vmstime.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) vmstime.c
|
||||
|
||||
cache.obj : cache.c cache.h ssdef.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) cache.c
|
||||
|
||||
phynt.obj : phynt.c phyio.h ssdef.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) phynt.c
|
||||
|
||||
device.obj : device.c ssdef.h access.h phyio.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) device.c
|
||||
|
||||
access.obj : access.c ssdef.h access.h phyio.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) access.c
|
||||
|
||||
update.obj : update.c ssdef.h access.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) update.c
|
||||
|
||||
direct.obj : direct.c direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) direct.c
|
||||
|
||||
rms.obj : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) rms.c
|
||||
|
||||
ods2.obj : ods2.c ssdef.h descrip.h access.h rms.h
|
||||
$(CC) -c $(CCFLAGS) $(DEFS) ods2.c
|
||||
include makefile.generic
|
||||
|
||||
wnaspi32.lib : wnaspi32.def
|
||||
LIB /DEF:WNASPI32.DEF /MACHINE:IX86
|
||||
|
||||
clean:
|
||||
del *.obj
|
||||
del *.exe
|
||||
del $(OBJS)
|
||||
del ods2.exe
|
||||
|
||||
@ -1,36 +1,22 @@
|
||||
# Makefile for solaris OS
|
||||
|
||||
CCFLAGS = "-g"
|
||||
# Use gcc
|
||||
|
||||
DEFS = "-DVERSION=\"v1.3\""
|
||||
CC=gcc
|
||||
|
||||
all : ods2
|
||||
CCFLAGS = -O4 -g
|
||||
|
||||
ods2 : ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o
|
||||
gcc $(CCFLAGS) -oods2 ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o
|
||||
DEFS = -DUSE_READLINE
|
||||
LDFLAGS = -lreadline
|
||||
|
||||
vmstime.o : vmstime.c vmstime.h
|
||||
gcc -c $(CCFLAGS) $(DEFS) vmstime.c
|
||||
# Object file extension
|
||||
OBJ = .o
|
||||
|
||||
cache.o : cache.c cache.h ssdef.h
|
||||
gcc -c $(CCFLAGS) $(DEFS) cache.c
|
||||
# Physical I/O module
|
||||
PHYSIO = phyunix
|
||||
PHYSIOH =
|
||||
|
||||
phyunix.o : phyunix.c phyio.h ssdef.h
|
||||
gcc -c $(CCFLAGS) $(DEFS) phyunix.c
|
||||
include makefile.generic
|
||||
|
||||
device.o : device.c ssdef.h access.h phyio.h
|
||||
gcc -c $(CCFLAGS) $(DEFS) device.c
|
||||
|
||||
access.o : access.c ssdef.h access.h phyio.h
|
||||
gcc -c $(CCFLAGS) $(DEFS) access.c
|
||||
|
||||
update.o : update.c ssdef.h access.h
|
||||
gcc -c $(CCFLAGS) $(DEFS) update.c
|
||||
|
||||
direct.o : direct.c direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
gcc -c $(CCFLAGS) $(DEFS) direct.c
|
||||
|
||||
rms.o : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
gcc -c $(CCFLAGS) $(DEFS) rms.c
|
||||
|
||||
ods2.o : ods2.c ssdef.h descrip.h access.h rms.h
|
||||
gcc -c $(CCFLAGS) $(DEFS) ods2.c
|
||||
clean:
|
||||
rm -f ods2 $(OBJS)
|
||||
|
||||
@ -1,34 +1,19 @@
|
||||
# Makefile for Tru64 (DEC/OSF1)
|
||||
#
|
||||
|
||||
CCFLAGS = "-g"
|
||||
CCFLAGS = -O4 -g
|
||||
|
||||
all : ods2
|
||||
# DEFS = -DUSE_READLINE
|
||||
# LDFLAGS = -lreadline
|
||||
|
||||
ods2 : ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o
|
||||
cc $(CCFLAGS) -o ods2 ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o
|
||||
# Object file extension
|
||||
OBJ = .o
|
||||
|
||||
vmstime.o : vmstime.c vmstime.h
|
||||
cc -c $(CCFLAGS) $(DEFS) vmstime.c
|
||||
# Physical I/O module
|
||||
PHYSIO = phyunix
|
||||
PHYSIOH =
|
||||
|
||||
cache.o : cache.c cache.h ssdef.h
|
||||
cc -c $(CCFLAGS) $(DEFS) cache.c
|
||||
include makefile.generic
|
||||
|
||||
phyunix.o : phyunix.c phyio.h ssdef.h
|
||||
cc -c $(CCFLAGS) $(DEFS) phyunix.c
|
||||
|
||||
device.o : device.c ssdef.h access.h phyio.h
|
||||
cc -c $(CCFLAGS) $(DEFS) device.c
|
||||
|
||||
access.o : access.c ssdef.h access.h phyio.h
|
||||
cc -c $(CCFLAGS) $(DEFS) access.c
|
||||
|
||||
update.o : update.c ssdef.h access.h
|
||||
cc -c $(CCFLAGS) $(DEFS) update.c
|
||||
|
||||
direct.o : direct.c direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
cc -c $(CCFLAGS) $(DEFS) direct.c
|
||||
|
||||
rms.o : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
cc -c $(CCFLAGS) $(DEFS) rms.c
|
||||
|
||||
ods2.o : ods2.c ssdef.h descrip.h access.h rms.h
|
||||
cc -c $(CCFLAGS) $(DEFS) ods2.c
|
||||
clean:
|
||||
rm -f ods2 $(OBJS)
|
||||
|
||||
@ -1,36 +1,24 @@
|
||||
# Makefile for most Unix distributions
|
||||
#
|
||||
|
||||
CCFLAGS = -O4
|
||||
CCFLAGS = -O4 -g
|
||||
#-O0 -g -DUSE_READLINE -Wall -pedantic
|
||||
# Extra warns about $ in identifiers...
|
||||
# -Wextra
|
||||
|
||||
DEFS = "-DVERSION=\"v1.3\""
|
||||
# Include readline support
|
||||
|
||||
all : ods2
|
||||
DEFS = -DUSE_READLINE
|
||||
LDFLAGS = -lreadline
|
||||
|
||||
ods2 : ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o
|
||||
cc $(CCFLAGS) -o ods2 ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o
|
||||
# Object file extension
|
||||
OBJ = .o
|
||||
|
||||
vmstime.o : vmstime.c vmstime.h
|
||||
cc -c $(CCFLAGS) $(DEFS) vmstime.c
|
||||
# Physical I/O module
|
||||
PHYSIO = phyunix
|
||||
PHYSIOH =
|
||||
|
||||
cache.o : cache.c cache.h ssdef.h
|
||||
cc -c $(CCFLAGS) $(DEFS) cache.c
|
||||
include makefile.generic
|
||||
|
||||
phyunix.o : phyunix.c phyio.h ssdef.h
|
||||
cc -c $(CCFLAGS) $(DEFS) phyunix.c
|
||||
|
||||
device.o : device.c ssdef.h access.h phyio.h
|
||||
cc -c $(CCFLAGS) $(DEFS) device.c
|
||||
|
||||
access.o : access.c ssdef.h access.h phyio.h
|
||||
cc -c $(CCFLAGS) $(DEFS) access.c
|
||||
|
||||
update.o : update.c ssdef.h access.h
|
||||
cc -c $(CCFLAGS) $(DEFS) update.c
|
||||
|
||||
direct.o : direct.c direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
cc -c $(CCFLAGS) $(DEFS) direct.c
|
||||
|
||||
rms.o : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h
|
||||
cc -c $(CCFLAGS) $(DEFS) rms.c
|
||||
|
||||
ods2.o : ods2.c ssdef.h descrip.h access.h rms.h
|
||||
cc -c $(CCFLAGS) $(DEFS) ods2.c
|
||||
clean:
|
||||
rm -f ods2 ods2i $(OBJS)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,895 +0,0 @@
|
||||
/* ODS2.C v1.2 Mainline ODS2 program */
|
||||
|
||||
/*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
email address: Paulnank@au1.ibm.com
|
||||
|
||||
ODS2 is distributed freely for all members of the
|
||||
VMS community to use. However all derived works
|
||||
must maintain comments in their source to acknowledge
|
||||
the contibution of the original author.
|
||||
|
||||
The modules in ODS2 are:-
|
||||
|
||||
ACCESS.C Routines for accessing ODS2 disks
|
||||
CACHE.C Routines for managing memory cache
|
||||
DEVICE.C Routines to maintain device information
|
||||
DIRECT.C Routines for handling directories
|
||||
ODS2.C The mainline program
|
||||
PHYVMS.C Routine to perform physical I/O
|
||||
RMS.C Routines to handle RMS structures
|
||||
VMSTIME.C Routines to handle VMS times
|
||||
|
||||
On non-VMS platforms PHYVMS.C should be replaced as follows:-
|
||||
|
||||
OS/2 PHYOS2.C
|
||||
Windows 95/NT PHYNT.C
|
||||
|
||||
For example under OS/2 the program is compiled using the GCC
|
||||
compiler with the single command:-
|
||||
|
||||
gcc -fdollars-in-identifiers ods2.c,rms.c,direct.c,
|
||||
access.c,device.c,cache.c,phyos2.c,vmstime.c
|
||||
*/
|
||||
|
||||
/* This version will compile and run using normal VMS I/O by
|
||||
defining VMSIO
|
||||
*/
|
||||
|
||||
/* This is the top level set of routines. It is fairly
|
||||
simple minded asking the user for a command, doing some
|
||||
primitive command parsing, and then calling a set of routines
|
||||
to perform whatever function is required (for example COPY).
|
||||
Some routines are implemented in different ways to test the
|
||||
underlying routines - for example TYPE is implemented without
|
||||
a NAM block meaning that it cannot support wildcards...
|
||||
(sorry! - could be easily fixed though!)
|
||||
*/
|
||||
|
||||
#define DEBUGx on
|
||||
#define VMSIOx on
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "descrip.h"
|
||||
#include "ssdef.h"
|
||||
|
||||
#ifdef VMSIO
|
||||
#include <starlet.h>
|
||||
#include <rms.h>
|
||||
unsigned sys$setddir();
|
||||
#else
|
||||
#include "rms.h"
|
||||
#include "access.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define PRINT_ATTR (FAB$M_CR | FAB$M_PRN | FAB$M_FTN)
|
||||
|
||||
|
||||
|
||||
/* keycomp: routine to compare parameter to a keyword - case insensitive! */
|
||||
|
||||
int keycomp(char *param,char *keywrd)
|
||||
{
|
||||
while (*param != '\0') {
|
||||
if (tolower(*param++) != *keywrd++) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* checkquals: routine to find a qualifer in a list of possible values */
|
||||
|
||||
int checkquals(char *qualset[],int qualc,char *qualv[])
|
||||
{
|
||||
int result = 0;
|
||||
while (qualc-- > 0) {
|
||||
int i = 0;
|
||||
while (qualset[i] != NULL) {
|
||||
if (keycomp(qualv[qualc],qualset[i])) {
|
||||
result |= 1 << i;
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (i >= 0) printf("%%ODS2-W-ILLQUAL, Unknown qualifer '%s' ignored\n",qualv[qualc]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* dir: a directory routine */
|
||||
|
||||
char *dirquals[] = {"date","file","size",NULL};
|
||||
|
||||
unsigned dir(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
char res[NAM$C_MAXRSS + 1],rsa[NAM$C_MAXRSS + 1];
|
||||
int sts,options;
|
||||
int filecount = 0;
|
||||
struct NAM nam = cc$rms_nam;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
struct XABDAT dat = cc$rms_xabdat;
|
||||
struct XABFHC fhc = cc$rms_xabfhc;
|
||||
nam.nam$l_esa = res;
|
||||
nam.nam$b_ess = NAM$C_MAXRSS;
|
||||
fab.fab$l_nam = &nam;
|
||||
fab.fab$l_xab = &dat;
|
||||
dat.xab$l_nxt = &fhc;
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = strlen(fab.fab$l_fna);
|
||||
fab.fab$l_dna = "*.*;*";
|
||||
fab.fab$b_dns = strlen(fab.fab$l_dna);
|
||||
options = checkquals(dirquals,qualc,qualv);
|
||||
sts = sys$parse(&fab);
|
||||
if (sts & 1) {
|
||||
char dir[NAM$C_MAXRSS + 1];
|
||||
int namelen;
|
||||
int dirlen = 0;
|
||||
int dirfiles = 0,dircount = 0;
|
||||
int dirblocks = 0,totblocks = 0;
|
||||
int printcol = 0;
|
||||
#ifdef DEBUG
|
||||
res[nam.nam$b_esl] = '\0';
|
||||
printf("Parse: %s\n",res);
|
||||
#endif
|
||||
nam.nam$l_rsa = rsa;
|
||||
nam.nam$b_rss = NAM$C_MAXRSS;
|
||||
fab.fab$l_fop = FAB$M_NAM;
|
||||
while ((sts = sys$search(&fab)) & 1) {
|
||||
if (dirlen != nam.nam$b_dev + nam.nam$b_dir ||
|
||||
memcmp(rsa,dir,nam.nam$b_dev + nam.nam$b_dir) != 0) {
|
||||
if (dirfiles > 0) {
|
||||
if (printcol > 0) printf("\n");
|
||||
printf("\nTotal of %d file%s",dirfiles,(dirfiles == 1 ? "" : "s"));
|
||||
if (options & 4) {
|
||||
printf(", %d block%s.\n",dirblocks,(dirblocks == 1 ? "" : "s"));
|
||||
} else {
|
||||
fputs(".\n",stdout);
|
||||
}
|
||||
}
|
||||
dirlen = nam.nam$b_dev + nam.nam$b_dir;
|
||||
memcpy(dir,rsa,dirlen);
|
||||
dir[dirlen] = '\0';
|
||||
printf("\nDirectory %s\n\n",dir);
|
||||
filecount += dirfiles;
|
||||
totblocks += dirblocks;
|
||||
dircount++;
|
||||
dirfiles = 0;
|
||||
dirblocks = 0;
|
||||
printcol = 0;
|
||||
}
|
||||
rsa[nam.nam$b_rsl] = '\0';
|
||||
namelen = nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver;
|
||||
if (options == 0) {
|
||||
if (printcol > 0) {
|
||||
int newcol = (printcol + 20) / 20 * 20;
|
||||
if (newcol + namelen >= 80) {
|
||||
fputs("\n",stdout);
|
||||
printcol = 0;
|
||||
} else {
|
||||
printf("%*s",newcol - printcol," ");
|
||||
printcol = newcol;
|
||||
}
|
||||
}
|
||||
fputs(rsa + dirlen,stdout);
|
||||
printcol += namelen;
|
||||
} else {
|
||||
if (namelen > 18) {
|
||||
printf("%s\n ",rsa + dirlen);
|
||||
} else {
|
||||
printf("%-19s",rsa + dirlen);
|
||||
}
|
||||
sts = sys$open(&fab);
|
||||
if ((sts & 1) == 0) {
|
||||
printf("Open error: %d\n",sts);
|
||||
} else {
|
||||
sts = sys$close(&fab);
|
||||
if (options & 2) {
|
||||
char fileid[100];
|
||||
sprintf(fileid,"(%d,%d,%d)",
|
||||
(nam.nam$b_fid_nmx << 16) | nam.nam$w_fid_num,
|
||||
nam.nam$w_fid_seq,nam.nam$b_fid_rvn);
|
||||
printf(" %-22s",fileid);
|
||||
}
|
||||
if (options & 4) {
|
||||
unsigned filesize = fhc.xab$l_ebk;
|
||||
if (fhc.xab$w_ffb == 0) filesize--;
|
||||
printf("%9d",filesize);
|
||||
dirblocks += filesize;
|
||||
}
|
||||
if (options & 1) {
|
||||
char tim[24];
|
||||
struct dsc$descriptor timdsc;
|
||||
timdsc.dsc$w_length = 23;
|
||||
timdsc.dsc$a_pointer = tim;
|
||||
sts = sys$asctim(0,&timdsc,&dat.xab$q_cdt,0);
|
||||
if ((sts & 1) == 0) printf("Asctim error: %d\n",sts);
|
||||
tim[23] = '\0';
|
||||
printf(" %s",tim);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
dirfiles++;
|
||||
}
|
||||
if (sts == RMS$_NMF) sts = 1;
|
||||
if (printcol > 0) printf("\n");
|
||||
if (dirfiles > 0) {
|
||||
printf("\nTotal of %d file%s",dirfiles,(dirfiles == 1 ? "" : "s"));
|
||||
if (options & 4) {
|
||||
printf(", %d block%s.\n",dirblocks,(dirblocks == 1 ? "" : "s"));
|
||||
} else {
|
||||
fputs(".\n",stdout);
|
||||
}
|
||||
filecount += dirfiles;
|
||||
totblocks += dirblocks;
|
||||
if (dircount > 1) {
|
||||
printf("\nGrand total of %d director%s, %d file%s",
|
||||
dircount,(dircount == 1 ? "y" : "ies"),
|
||||
filecount,(filecount == 1 ? "" : "s"));
|
||||
if (options & 4) {
|
||||
printf(", %d block%s.\n",totblocks,(totblocks == 1 ? "" : "s"));
|
||||
} else {
|
||||
fputs(".\n",stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sts & 1) {
|
||||
if (filecount < 1) printf("%%DIRECT-W-NOFILES, no files found\n");
|
||||
} else {
|
||||
printf("%%DIR-E-ERROR Status: %d\n",sts);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
/* copy: a file copy routine */
|
||||
|
||||
#define MAXREC 32767
|
||||
|
||||
unsigned copy(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
int sts;
|
||||
struct NAM nam = cc$rms_nam;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
char res[NAM$C_MAXRSS + 1],rsa[NAM$C_MAXRSS + 1];
|
||||
int filecount = 0;
|
||||
nam.nam$l_esa = res;
|
||||
nam.nam$b_ess = NAM$C_MAXRSS;
|
||||
fab.fab$l_nam = &nam;
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = strlen(fab.fab$l_fna);
|
||||
sts = sys$parse(&fab);
|
||||
if (sts & 1) {
|
||||
nam.nam$l_rsa = rsa;
|
||||
nam.nam$b_rss = NAM$C_MAXRSS;
|
||||
fab.fab$l_fop = FAB$M_NAM;
|
||||
while ((sts = sys$search(&fab)) & 1) {
|
||||
sts = sys$open(&fab);
|
||||
if ((sts & 1) == 0) {
|
||||
printf("%%COPY-F-OPENFAIL, Open error: %d\n",sts);
|
||||
perror("-COPY-F-ERR ");
|
||||
} else {
|
||||
struct RAB rab = cc$rms_rab;
|
||||
rab.rab$l_fab = &fab;
|
||||
if ((sts = sys$connect(&rab)) & 1) {
|
||||
FILE *tof;
|
||||
char name[NAM$C_MAXRSS + 1];
|
||||
unsigned records = 0;
|
||||
{
|
||||
char *out = name,*inp = argv[2];
|
||||
int dot = 0;
|
||||
while (*inp != '\0') {
|
||||
if (*inp == '*') {
|
||||
inp++;
|
||||
if (dot) {
|
||||
memcpy(out,nam.nam$l_type + 1,nam.nam$b_type - 1);
|
||||
out += nam.nam$b_type - 1;
|
||||
} else {
|
||||
unsigned length = nam.nam$b_name;
|
||||
if (*inp == '\0') length += nam.nam$b_type;
|
||||
memcpy(out,nam.nam$l_name,length);
|
||||
out += length;
|
||||
}
|
||||
} else {
|
||||
if (*inp == '.') {
|
||||
dot = 1;
|
||||
} else {
|
||||
if (strchr(":]\\/",*inp)) dot = 0;
|
||||
}
|
||||
*out++ = *inp++;
|
||||
}
|
||||
}
|
||||
*out++ = '\0';
|
||||
}
|
||||
tof = fopen(name,"w");
|
||||
if (tof == NULL) {
|
||||
printf("%%COPY-F-OPENOUT, Could not open %s\n",name);
|
||||
perror("-COPY-F-ERR ");
|
||||
} else {
|
||||
char rec[MAXREC + 2];
|
||||
filecount++;
|
||||
rab.rab$l_ubf = rec;
|
||||
rab.rab$w_usz = MAXREC;
|
||||
while ((sts = sys$get(&rab)) & 1) {
|
||||
unsigned rsz = rab.rab$w_rsz;
|
||||
if (fab.fab$b_rat & PRINT_ATTR) rec[rsz++] = '\n';
|
||||
if (fwrite(rec,rsz,1,tof) == 1) {
|
||||
records++;
|
||||
} else {
|
||||
printf("%%COPY-F- fwrite error!!\n");
|
||||
perror("-COPY-F-ERR ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fclose(tof)) {
|
||||
printf("%%COPY-F- fclose error!!\n");
|
||||
perror("-COPY-F-ERR ");
|
||||
}
|
||||
}
|
||||
sys$disconnect(&rab);
|
||||
if (sts == RMS$_EOF) {
|
||||
rsa[nam.nam$b_rsl] = '\0';
|
||||
printf("%%COPY-S-COPIED, %s copied to %s (%d record%s)\n",
|
||||
rsa,name,records,(records == 1 ? "" : "s"));
|
||||
sts = 1;
|
||||
}
|
||||
}
|
||||
sys$close(&fab);
|
||||
}
|
||||
}
|
||||
if (sts == RMS$_NMF) sts = 1;
|
||||
}
|
||||
if (sts & 1) {
|
||||
if (filecount > 0) printf("%%COPY-S-NEWFILES, %d file%s created\n",
|
||||
filecount,(filecount == 1 ? "" : "s"));
|
||||
} else {
|
||||
printf("%%COPY-F-ERROR Status: %d\n",sts);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
/* diff: a simple file difference routine */
|
||||
|
||||
unsigned diff(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
int sts;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
FILE *tof;
|
||||
int records = 0;
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = strlen(fab.fab$l_fna);
|
||||
tof = fopen(argv[2],"r");
|
||||
if (tof == NULL) {
|
||||
printf("Could not open file %s\n",argv[1]);
|
||||
sts = 0;
|
||||
} else {
|
||||
if ((sts = sys$open(&fab)) & 1) {
|
||||
struct RAB rab = cc$rms_rab;
|
||||
rab.rab$l_fab = &fab;
|
||||
if ((sts = sys$connect(&rab)) & 1) {
|
||||
char rec[MAXREC + 2],cpy[MAXREC + 1];
|
||||
rab.rab$l_ubf = rec;
|
||||
rab.rab$w_usz = MAXREC;
|
||||
while ((sts = sys$get(&rab)) & 1) {
|
||||
strcpy(rec + rab.rab$w_rsz,"\n");
|
||||
fgets(cpy,MAXREC,tof);
|
||||
if (strcmp(rec,cpy) != 0) {
|
||||
printf("%%DIFF-F-DIFFERENT Files are different!\n");
|
||||
sts = 4;
|
||||
break;
|
||||
} else {
|
||||
records++;
|
||||
}
|
||||
}
|
||||
sys$disconnect(&rab);
|
||||
}
|
||||
sys$close(&fab);
|
||||
}
|
||||
fclose(tof);
|
||||
if (sts == RMS$_EOF) sts = 1;
|
||||
}
|
||||
if (sts & 1) {
|
||||
printf("%%DIFF-I-Compared %d records\n",records);
|
||||
} else {
|
||||
printf("%%DIFF-F-Error %d in difference\n",sts);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
/* typ: a file TYPE routine */
|
||||
|
||||
unsigned typ(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
int sts;
|
||||
int records = 0;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = strlen(fab.fab$l_fna);
|
||||
if ((sts = sys$open(&fab)) & 1) {
|
||||
struct RAB rab = cc$rms_rab;
|
||||
rab.rab$l_fab = &fab;
|
||||
if ((sts = sys$connect(&rab)) & 1) {
|
||||
char rec[MAXREC + 2];
|
||||
rab.rab$l_ubf = rec;
|
||||
rab.rab$w_usz = MAXREC;
|
||||
while ((sts = sys$get(&rab)) & 1) {
|
||||
unsigned rsz = rab.rab$w_rsz;
|
||||
if (fab.fab$b_rat & PRINT_ATTR) rec[rsz++] = '\n';
|
||||
rec[rsz++] = '\0';
|
||||
fputs(rec,stdout);
|
||||
records++;
|
||||
}
|
||||
sys$disconnect(&rab);
|
||||
}
|
||||
sys$close(&fab);
|
||||
if (sts == RMS$_EOF) sts = 1;
|
||||
}
|
||||
if ((sts & 1) == 0) {
|
||||
printf("%%TYPE-F-ERROR Status: %d\n",sts);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* search: a simple file search routine */
|
||||
|
||||
unsigned search(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
int sts = 0;
|
||||
int filecount = 0;
|
||||
int findcount = 0;
|
||||
char res[NAM$C_MAXRSS + 1],rsa[NAM$C_MAXRSS + 1];
|
||||
struct NAM nam = cc$rms_nam;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
register char *searstr = argv[2];
|
||||
register char firstch = tolower(*searstr++);
|
||||
register char *searend = searstr + strlen(searstr);
|
||||
{
|
||||
char *str = searstr;
|
||||
while (str < searend) {
|
||||
*str = tolower(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
nam = cc$rms_nam;
|
||||
fab = cc$rms_fab;
|
||||
nam.nam$l_esa = res;
|
||||
nam.nam$b_ess = NAM$C_MAXRSS;
|
||||
fab.fab$l_nam = &nam;
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = strlen(fab.fab$l_fna);
|
||||
fab.fab$l_dna = "";
|
||||
fab.fab$b_dns = strlen(fab.fab$l_dna);
|
||||
sts = sys$parse(&fab);
|
||||
if (sts & 1) {
|
||||
nam.nam$l_rsa = rsa;
|
||||
nam.nam$b_rss = NAM$C_MAXRSS;
|
||||
fab.fab$l_fop = FAB$M_NAM;
|
||||
while ((sts = sys$search(&fab)) & 1) {
|
||||
sts = sys$open(&fab);
|
||||
if ((sts & 1) == 0) {
|
||||
printf("%%SEARCH-F-OPENFAIL, Open error: %d\n",sts);
|
||||
} else {
|
||||
struct RAB rab = cc$rms_rab;
|
||||
rab.rab$l_fab = &fab;
|
||||
if ((sts = sys$connect(&rab)) & 1) {
|
||||
int printname = 1;
|
||||
char rec[MAXREC + 2];
|
||||
filecount++;
|
||||
rab.rab$l_ubf = rec;
|
||||
rab.rab$w_usz = MAXREC;
|
||||
while ((sts = sys$get(&rab)) & 1) {
|
||||
register char *strng = rec;
|
||||
register char *strngend = strng + (rab.rab$w_rsz - (searend - searstr));
|
||||
while (strng < strngend) {
|
||||
register char ch = *strng++;
|
||||
if (ch == firstch || (ch >= 'A' && ch <= 'Z' && ch + 32 == firstch)) {
|
||||
register char *str = strng;
|
||||
register char *cmp = searstr;
|
||||
while (cmp < searend) {
|
||||
register char ch2 = *str++;
|
||||
ch = *cmp;
|
||||
if (ch2 != ch && (ch2 < 'A' || ch2 > 'Z' || ch2 + 32 != ch)) break;
|
||||
cmp++;
|
||||
}
|
||||
if (cmp >= searend) {
|
||||
findcount++;
|
||||
rec[rab.rab$w_rsz] = '\0';
|
||||
if (printname) {
|
||||
rsa[nam.nam$b_rsl] = '\0';
|
||||
printf("\n******************************\n%s\n\n",rsa);
|
||||
printname = 0;
|
||||
}
|
||||
fputs(rec,stdout);
|
||||
if (fab.fab$b_rat & PRINT_ATTR) fputc('\n',stdout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sys$disconnect(&rab);
|
||||
}
|
||||
if (sts == SS$_NOTINSTALL) {
|
||||
printf("%%SEARCH-W-NOIMPLEM, file operation not implemented\n");
|
||||
sts = 1;
|
||||
}
|
||||
sys$close(&fab);
|
||||
}
|
||||
}
|
||||
if (sts == RMS$_NMF || sts == RMS$_FNF) sts = 1;
|
||||
}
|
||||
if (sts & 1) {
|
||||
if (filecount < 1) {
|
||||
printf("%%SEARCH-W-NOFILES, no files found\n");
|
||||
} else {
|
||||
if (findcount < 1) printf("%%SEARCH-I-NOMATCHES, no strings matched\n");
|
||||
}
|
||||
} else {
|
||||
printf("%%SEARCH-F-ERROR Status: %d\n",sts);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
/* del: you don't want to know! */
|
||||
|
||||
unsigned del(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
int sts = 0;
|
||||
struct NAM nam = cc$rms_nam;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
char res[NAM$C_MAXRSS + 1],rsa[NAM$C_MAXRSS + 1];
|
||||
int filecount = 0;
|
||||
nam.nam$l_esa = res;
|
||||
nam.nam$b_ess = NAM$C_MAXRSS;
|
||||
fab.fab$l_nam = &nam;
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = strlen(fab.fab$l_fna);
|
||||
printf("WARNING! This bit is broken - volume corruption VERY likely!\n");
|
||||
sts = sys$parse(&fab);
|
||||
if (sts & 1) {
|
||||
if (nam.nam$b_ver < 2) {
|
||||
printf("%%DELETE-F-NOVER, you must specify a version!!\n");
|
||||
} else {
|
||||
nam.nam$l_rsa = rsa;
|
||||
nam.nam$b_rss = NAM$C_MAXRSS;
|
||||
fab.fab$l_fop = FAB$M_NAM;
|
||||
while ((sts = sys$search(&fab)) & 1) {
|
||||
sts = sys$erase(&fab);
|
||||
if ((sts & 1) == 0) {
|
||||
printf("%%DELETE-F-DELERR, Delete error: %d\n",sts);
|
||||
} else {
|
||||
filecount++;
|
||||
rsa[nam.nam$b_rsl] = '\0';
|
||||
printf("%%DELETE-I-DELETED, Deleted %s\n",rsa);
|
||||
}
|
||||
}
|
||||
if (sts == RMS$_NMF) sts = 1;
|
||||
}
|
||||
if (sts & 1) {
|
||||
if (filecount < 1) {
|
||||
printf("%%DELETE-W-NOFILES, no files deleted\n");
|
||||
}
|
||||
} else {
|
||||
printf("%%DELETE-F-ERROR Status: %d\n",sts);
|
||||
}
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
/* show: the show command */
|
||||
|
||||
unsigned show(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
unsigned sts = 1;
|
||||
if (keycomp(argv[1],"default")) {
|
||||
unsigned short curlen;
|
||||
char curdir[NAM$C_MAXRSS + 1];
|
||||
struct dsc$descriptor curdsc;
|
||||
curdsc.dsc$w_length = NAM$C_MAXRSS;
|
||||
curdsc.dsc$a_pointer = curdir;
|
||||
if ((sts = sys$setddir(NULL,&curlen,&curdsc)) & 1) {
|
||||
curdir[curlen] = '\0';
|
||||
printf(" %s\n",curdir);
|
||||
} else {
|
||||
printf("Error %d getting default\n",sts);
|
||||
}
|
||||
} else {
|
||||
if (keycomp(argv[1],"time")) {
|
||||
char timstr[24];
|
||||
unsigned short timlen;
|
||||
struct dsc$descriptor timdsc;
|
||||
timdsc.dsc$w_length = 23;
|
||||
timdsc.dsc$a_pointer = timstr;
|
||||
sys$asctim(&timlen,&timdsc,NULL,0);
|
||||
timstr[timlen] = '\0';
|
||||
printf(" %s\n",timstr);
|
||||
} else {
|
||||
printf("%%SHOW-W-WHAT '%s'?\n",argv[1]);
|
||||
}
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
/* set: the set command */
|
||||
|
||||
unsigned set(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
unsigned sts = 1;
|
||||
if (keycomp(argv[1],"default")) {
|
||||
struct dsc$descriptor defdsc;
|
||||
defdsc.dsc$a_pointer = argv[2];
|
||||
defdsc.dsc$w_length = strlen(defdsc.dsc$a_pointer);
|
||||
if (((sts = sys$setddir(&defdsc,NULL,NULL)) & 1) == 0) {
|
||||
printf("Error %d setting default to %s\n",sts,argv[2]);
|
||||
}
|
||||
} else {
|
||||
printf("%%SET-W-WHAT '%s'?\n",argv[1]);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
#ifndef VMSIO
|
||||
|
||||
/* The bits we need when we don't have real VMS routines underneath... */
|
||||
|
||||
unsigned dodismount(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
struct DEV *dev;
|
||||
register int sts = device_lookup(strlen(argv[1]),argv[1],0,&dev);
|
||||
if (sts & 1) {
|
||||
if (dev->vcb != NULL) {
|
||||
sts = dismount(dev->vcb);
|
||||
} else {
|
||||
sts = SS$_DEVNOTMOUNT;
|
||||
}
|
||||
}
|
||||
if ((sts & 1) == 0) printf("%%DISMOUNT-E-STATUS Error: %d\n",sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
char *mouquals[] = {"write",NULL};
|
||||
|
||||
unsigned domount(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
char *dev = argv[1];
|
||||
char *lab = argv[2];
|
||||
int sts = 1,devices = 0;
|
||||
char *devs[100],*labs[100];
|
||||
int options = checkquals(mouquals,qualc,qualv);
|
||||
while (*lab != '\0') {
|
||||
labs[devices++] = lab;
|
||||
while (*lab != ',' && *lab != '\0') lab++;
|
||||
if (*lab != '\0') {
|
||||
*lab++ = '\0';
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
devices = 0;
|
||||
while (*dev != '\0') {
|
||||
devs[devices++] = dev;
|
||||
while (*dev != ',' && *dev != '\0') dev++;
|
||||
if (*dev != '\0') {
|
||||
*dev++ = '\0';
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (devices > 0) {
|
||||
unsigned i;
|
||||
struct VCB *vcb;
|
||||
sts = mount(options,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);
|
||||
} else {
|
||||
printf("Mount failed with %d\n",sts);
|
||||
}
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
void directshow(void);
|
||||
void phyio_show(void);
|
||||
|
||||
/* statis: print some simple statistics */
|
||||
|
||||
unsigned statis(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
printf("Statistics:-\n");
|
||||
directshow();
|
||||
cacheshow();
|
||||
phyio_show();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* dump: a simple debugging aid */
|
||||
|
||||
unsigned dump(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
printf("Cache Dump:-\n");
|
||||
cachedump();
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* help: a routine to print a pre-prepared help text... */
|
||||
|
||||
unsigned help(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
printf("\nODS2 v1.2\n");
|
||||
printf(" Please send problems/comments to Paulnank@au1.ibm.com\n");
|
||||
printf(" Commands are:\n");
|
||||
printf(" copy difference directory exit\n");
|
||||
printf(" mount show_default show_time search\n");
|
||||
printf(" set_default type\n");
|
||||
printf(" Example:-\n $ mount e:\n");
|
||||
printf(" $ search e:[vms$common.decc*...]*.h rms$_wld\n");
|
||||
printf(" $ set default e:[sys0.sysmgr]\n");
|
||||
printf(" $ copy *.com;-1 c:\\*.*\n");
|
||||
printf(" $ directory/file/size/date [-.sys*...].%%\n");
|
||||
printf(" $ exit\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* informaion about the commands we know... */
|
||||
|
||||
struct CMDSET {
|
||||
char *name;
|
||||
unsigned (*proc) (int argc,char *argv[],int qualc,char *qualv[]);
|
||||
int minlen;
|
||||
int minargs;
|
||||
int maxargs;
|
||||
int maxquals;
|
||||
} cmdset[] = {
|
||||
{
|
||||
"copy",copy,3,3,3,0
|
||||
},
|
||||
{
|
||||
"delete",del,3,2,2,0
|
||||
},
|
||||
{
|
||||
"difference",diff,3,3,3,0
|
||||
},
|
||||
{
|
||||
"directory",dir,3,1,2,6
|
||||
},
|
||||
{
|
||||
"exit",NULL,2,0,0,0
|
||||
},
|
||||
{
|
||||
"help",help,2,1,1,0
|
||||
},
|
||||
{
|
||||
"show",show,2,2,2,0
|
||||
},
|
||||
{
|
||||
"search",search,3,3,3,0
|
||||
},
|
||||
{
|
||||
"set",set,3,2,3,0
|
||||
},
|
||||
#ifndef VMSIO
|
||||
{
|
||||
"dismount",dodismount,3,2,2,0
|
||||
},
|
||||
{
|
||||
"mount",domount,3,2,3,2
|
||||
},
|
||||
{
|
||||
"statistics",statis,3,1,1,0
|
||||
},
|
||||
{
|
||||
"dump",dump,3,1,1,0
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"type",typ,3,2,2,0
|
||||
},
|
||||
{
|
||||
NULL,NULL,0,0,0,0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* cmdexecute: identify and execute a command */
|
||||
|
||||
int cmdexecute(int argc,char *argv[],int qualc,char *qualv[])
|
||||
{
|
||||
char *ptr = argv[0];
|
||||
struct CMDSET *cmd = cmdset;
|
||||
unsigned cmdsiz = strlen(ptr);
|
||||
while (*ptr != '\0') {
|
||||
*ptr = tolower(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
while (cmd->name != NULL) {
|
||||
if (cmdsiz >= cmd->minlen && cmdsiz <= strlen(cmd->name)) {
|
||||
if (keycomp(argv[0],cmd->name)) {
|
||||
if (cmd->proc == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
if (argc < cmd->minargs || argc > cmd->maxargs) {
|
||||
printf("%%ODS2-E-PARAMS, Incorrect number of command parameters\n");
|
||||
} else {
|
||||
if (qualc > cmd->maxquals) {
|
||||
printf("%%ODS2-E-QUALS, Too many command qualifiers\n");
|
||||
} else {
|
||||
(*cmd->proc) (argc,argv,qualc,qualv);
|
||||
#ifndef VMSIO
|
||||
cacheflush();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
cmd++;
|
||||
}
|
||||
printf("%%ODS2-E-ILLCMD, Illegal or ambiguous command '%s'\n",argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* cmdsplit: break a command line into its components */
|
||||
|
||||
int cmdsplit(char *str)
|
||||
{
|
||||
int argc = 0,qualc = 0;
|
||||
char *argv[32],*qualv[32];
|
||||
char *sp = str;
|
||||
int i;
|
||||
for (i = 0; i < 32; i++) argv[i] = qualv[i] = "";
|
||||
while (*sp != '\0') {
|
||||
while (*sp == ' ') sp++;
|
||||
if (*sp != '\0') {
|
||||
if (*sp == '/') {
|
||||
*sp++ = '\0';
|
||||
qualv[qualc++] = sp;
|
||||
} else {
|
||||
argv[argc++] = sp;
|
||||
}
|
||||
while (*sp != ' ' && *sp != '/' && *sp != '\0') sp++;
|
||||
if (*sp == '\0') {
|
||||
break;
|
||||
} else {
|
||||
if (*sp != '/') *sp++ = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (argc > 0) return cmdexecute(argc,argv,qualc,qualv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* main: the simple mainline of this puppy... */
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
char str[2048];
|
||||
printf(" ODS2 v1.2\n");
|
||||
while (1) {
|
||||
printf("$> ");
|
||||
if (gets(str) == NULL) break;
|
||||
if (strlen(str)) if ((cmdsplit(str) & 1) == 0) break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
#include "windows.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
@ -28,8 +28,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,3
|
||||
PRODUCTVERSION 1,0,0,3
|
||||
FILEVERSION 1,0,0,4
|
||||
PRODUCTVERSION 1,0,0,4
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -46,15 +46,15 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "Comments", "This application reads ODS-2 (VMS) disks under Windows NT and Windows 2000\0"
|
||||
VALUE "CompanyName", "Paul Nankervis <paulnank@au1.ibm.com>\0"
|
||||
VALUE "FileDescription", "ODS-2 Reader for Windows\0"
|
||||
VALUE "FileVersion", "V1.3\0"
|
||||
VALUE "FileDescription", "ODS-2 Reader for Windows (Modified)\0"
|
||||
VALUE "FileVersion", "V1.4\0"
|
||||
VALUE "InternalName", "ODS2\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2001\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "ODS2.EXE\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "ODS2\0"
|
||||
VALUE "ProductVersion", "V1.3\0"
|
||||
VALUE "ProductVersion", "V1.4\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
@ -80,7 +80,7 @@ END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
/* Phyio.h v1.2-2 Definition of Physical I/O routines */
|
||||
#ifndef PHYIO_H
|
||||
#define PHYIO_H
|
||||
|
||||
/* Phyio.h v1.2-2 Definition of Physical I/O routines */
|
||||
|
||||
/*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
@ -30,11 +33,13 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define PHYIO_READONLY 1
|
||||
|
||||
struct phyio_info {
|
||||
unsigned status;
|
||||
unsigned sectors;
|
||||
unsigned long long sectors;
|
||||
unsigned sectorsize;
|
||||
};
|
||||
|
||||
@ -42,3 +47,6 @@ void phyio_show(void);
|
||||
unsigned phyio_init(int devlen,char *devnam,unsigned *handle,struct phyio_info *info);
|
||||
unsigned phyio_read(unsigned handle,unsigned block,unsigned length,char *buffer);
|
||||
unsigned phyio_write(unsigned handle,unsigned block,unsigned length,char *buffer);
|
||||
void phyio_help(FILE *fp );
|
||||
|
||||
#endif
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#include <memory.h>
|
||||
|
||||
#include "ssdef.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
|
||||
/*
|
||||
@ -42,6 +42,7 @@
|
||||
you find a better way please let me know... Paulnank@au1.ibm.com
|
||||
*/
|
||||
|
||||
#ifdef USE_WNASPI32
|
||||
#include "wnaspi32.h"
|
||||
#include "scsidefs.h"
|
||||
|
||||
@ -239,8 +240,25 @@ unsigned aspi_initialize(short *dev_type,short *dev_bus,short *dev_id,unsigned *
|
||||
printf("Could not find suitable ASPI device\n");
|
||||
return 8;
|
||||
}
|
||||
#else
|
||||
unsigned aspi_read(short bus,short id,unsigned sector,unsigned sectorsize,char *buffer)
|
||||
{
|
||||
fprintf( stderr, "wnaspi32 support not compiled in this version\n" );
|
||||
exit(1);
|
||||
}
|
||||
unsigned aspi_write(short bus,short id,unsigned sector,unsigned sectorsize,char *buffer)
|
||||
{
|
||||
fprintf( stderr, "wnaspi32 support not compiled in this version\n" );
|
||||
exit(1);
|
||||
}
|
||||
unsigned aspi_initialize(short *dev_type,short *dev_bus,short *dev_id,unsigned *sectsize)
|
||||
{
|
||||
fprintf( stderr, "wnaspi32 support not compiled in this version\n" );
|
||||
exit(1);
|
||||
}
|
||||
unsigned int ASPI_status = 0,ASPI_HaStat = 0,ASPI_TargStat = 0;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Some NT definitions... */
|
||||
@ -412,7 +430,9 @@ unsigned phy_getsect(unsigned chan,unsigned sector)
|
||||
®,sizeof(reg),
|
||||
&cb,0);
|
||||
if (!fResult || (reg.reg_Flags & 0x0001)) {
|
||||
printf("Sector %d read failed %d\n",sector,GetLastError());
|
||||
TCHAR *msg = w32_errstr(0);
|
||||
printf("Sector %d read failed %s\n",sector,msg);
|
||||
LocalFree(msg);
|
||||
sts = SS$_PARITY;
|
||||
}
|
||||
}
|
||||
@ -464,111 +484,147 @@ void phyio_show(void)
|
||||
|
||||
/* Initialize device by opening it, locking it and getting it ready.. */
|
||||
|
||||
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" );
|
||||
#ifdef USE_WNASPI32
|
||||
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" );
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned phyio_init(int devlen,char *devnam,unsigned *chanptr,struct phyio_info *info)
|
||||
{
|
||||
unsigned sts = 1;
|
||||
unsigned chan = chan_count;
|
||||
if (chan < CHAN_MAX - 1 && devlen == 2 &&
|
||||
toupper(*devnam) >= 'A' && *(devnam + 1) == ':') {
|
||||
HANDLE hDrive;
|
||||
chantab[chan].device_status = 0;
|
||||
chantab[chan].device_name = toupper(*devnam);
|
||||
chantab[chan].device_dtype = -1;
|
||||
if (chan >= CHAN_MAX - 1)
|
||||
return SS$_IVCHAN;
|
||||
|
||||
if( !(devlen == 2 &&
|
||||
toupper(*devnam) >= 'A' && toupper(*devnam) <= 'Z' && *(devnam + 1) == ':') )
|
||||
return SS$_NOSUCHDEV;
|
||||
|
||||
chantab[chan].device_status = 0;
|
||||
chantab[chan].device_name = toupper(*devnam);
|
||||
chantab[chan].device_dtype = -1;
|
||||
|
||||
do {
|
||||
HANDLE hDrive;
|
||||
|
||||
#ifdef USE_WNASPI32
|
||||
/* Use ASPI for devices past C... */
|
||||
|
||||
if (toupper(*devnam) > 'C') {
|
||||
sts = aspi_initialize(&chantab[chan].device_dtype,
|
||||
&chantab[chan].device_bus,&chantab[chan].device_id,
|
||||
&chantab[chan].sectorsize);
|
||||
&chantab[chan].device_bus,&chantab[chan].device_id,
|
||||
&chantab[chan].sectorsize);
|
||||
if ((sts & 1) == 0) return sts;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (is_NT > 1) getsysversion();
|
||||
|
||||
if (is_NT > 1) getsysversion();
|
||||
/* NT stuff */
|
||||
|
||||
/* NT stuff */
|
||||
|
||||
if (is_NT) {
|
||||
char ntname[20];
|
||||
DISK_GEOMETRY Geometry;
|
||||
sprintf(ntname,"\\\\.\\%s",devnam);
|
||||
chantab[chan].handle = hDrive = CreateFile(ntname,
|
||||
GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING,NULL);
|
||||
if (hDrive == INVALID_HANDLE_VALUE) {
|
||||
printf("Open %s failed %d\n",devnam,GetLastError());
|
||||
return SS$_NOSUCHDEV;
|
||||
}
|
||||
if (LockVolume(hDrive) == FALSE) {
|
||||
printf("LockVolume %s failed %d\n",devnam,GetLastError());
|
||||
return 72;
|
||||
}
|
||||
if (!GetDiskGeometry(hDrive,&Geometry)) {
|
||||
printf("GetDiskGeometry %s failed %d\n",devnam,GetLastError());
|
||||
return 80;
|
||||
}
|
||||
chantab[chan].sectorsize = Geometry.BytesPerSector;
|
||||
info->sectors = Geometry.Cylinders.QuadPart * Geometry.TracksPerCylinder *
|
||||
Geometry.SectorsPerTrack;
|
||||
} else {
|
||||
|
||||
/* W95 stuff */
|
||||
|
||||
DIOC_REGISTERS reg;
|
||||
DEVICEPARAM deviceparam;
|
||||
BOOL fResult;
|
||||
DWORD cb;
|
||||
chantab[chan].handle = hDrive = CreateFile("\\\\.\\vwin32",
|
||||
0,0,NULL,0,FILE_FLAG_DELETE_ON_CLOSE,NULL);
|
||||
if (hDrive == INVALID_HANDLE_VALUE) {
|
||||
printf("Open %s failed %d\n",devnam,GetLastError());
|
||||
return SS$_NOSUCHDEV;
|
||||
}
|
||||
reg.reg_EAX = 0x440d;
|
||||
reg.reg_EBX = chantab[chan].device_name - 'A' + 1;
|
||||
reg.reg_ECX = 0x084a; /* Lock volume */
|
||||
reg.reg_EDX = 0;
|
||||
reg.reg_Flags = 0x0000; /* Permission */
|
||||
|
||||
fResult = DeviceIoControl(hDrive,VWIN32_DIOC_DOS_IOCTL,
|
||||
®,sizeof(reg),®,sizeof(reg),&cb,0);
|
||||
|
||||
if (!fResult || (reg.reg_Flags & 0x0001)) {
|
||||
printf("Volume lock failed (%d)\n",GetLastError());
|
||||
return SS$_DEVNOTALLOC;
|
||||
}
|
||||
reg.reg_EAX = 0x440d;
|
||||
reg.reg_EBX = chantab[chan].device_name - 'A' + 1;
|
||||
reg.reg_ECX = 0x0860; /* Get device parameters */
|
||||
reg.reg_EDX = (DWORD) & deviceparam;
|
||||
reg.reg_Flags = 0x0001; /* set carry flag */
|
||||
|
||||
fResult = DeviceIoControl(hDrive,
|
||||
VWIN32_DIOC_DOS_IOCTL,
|
||||
®,sizeof(reg),
|
||||
®,sizeof(reg),
|
||||
&cb,0);
|
||||
|
||||
if (!fResult || (reg.reg_Flags & 0x0001)) {
|
||||
printf("Volume get parameters failed (%d)\n",GetLastError());
|
||||
return 8;
|
||||
}
|
||||
chantab[chan].sectorsize = deviceparam.sec_size;
|
||||
if (is_NT) {
|
||||
char ntname[20];
|
||||
DISK_GEOMETRY Geometry;
|
||||
snprintf(ntname,sizeof(ntname),"\\\\.\\%s",devnam);
|
||||
chantab[chan].handle = hDrive = CreateFile(ntname,
|
||||
GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING,NULL);
|
||||
if (hDrive == INVALID_HANDLE_VALUE) {
|
||||
TCHAR *msg = w32_errstr(0);
|
||||
printf("Open %s failed %s\n",devnam,msg);
|
||||
LocalFree(msg);
|
||||
return SS$_NOSUCHDEV;
|
||||
}
|
||||
info->sectors = 0;
|
||||
if (LockVolume(hDrive) == FALSE) {
|
||||
TCHAR *msg = w32_errstr(0);
|
||||
printf("LockVolume %s failed %s\n",devnam,msg);
|
||||
LocalFree(msg);
|
||||
return 72;
|
||||
}
|
||||
if (!GetDiskGeometry(hDrive,&Geometry)) {
|
||||
TCHAR *msg = w32_errstr(0);
|
||||
printf("GetDiskGeometry %s failed %s\n",devnam,msg);
|
||||
LocalFree(msg);
|
||||
return 80;
|
||||
}
|
||||
chantab[chan].sectorsize = Geometry.BytesPerSector;
|
||||
info->sectors = Geometry.Cylinders.QuadPart * Geometry.TracksPerCylinder *
|
||||
Geometry.SectorsPerTrack;
|
||||
break;
|
||||
}
|
||||
|
||||
chantab[chan].IoBuffer = VirtualAlloc(NULL,chantab[chan].sectorsize,
|
||||
MEM_COMMIT,PAGE_READWRITE);
|
||||
chantab[chan].last_sector = 99999;
|
||||
*chanptr = chan_count++;
|
||||
info->status = 0;
|
||||
info->sectorsize = chantab[chan].sectorsize;
|
||||
init_count++;
|
||||
return 1;
|
||||
} else {
|
||||
return SS$_IVCHAN;
|
||||
}
|
||||
/* W95 stuff */
|
||||
|
||||
{
|
||||
DIOC_REGISTERS reg;
|
||||
DEVICEPARAM deviceparam;
|
||||
BOOL fResult;
|
||||
DWORD cb;
|
||||
chantab[chan].handle = hDrive = CreateFile("\\\\.\\vwin32",
|
||||
0,0,NULL,0,FILE_FLAG_DELETE_ON_CLOSE,NULL);
|
||||
if (hDrive == INVALID_HANDLE_VALUE) {
|
||||
TCHAR *msg = w32_errstr(0);
|
||||
printf("Open %s failed %s\n",devnam,msg);
|
||||
LocalFree(msg);
|
||||
return SS$_NOSUCHDEV;
|
||||
}
|
||||
reg.reg_EAX = 0x440d;
|
||||
reg.reg_EBX = chantab[chan].device_name - 'A' + 1;
|
||||
reg.reg_ECX = 0x084a; /* Lock volume */
|
||||
reg.reg_EDX = 0;
|
||||
reg.reg_Flags = 0x0000; /* Permission */
|
||||
|
||||
fResult = DeviceIoControl(hDrive,VWIN32_DIOC_DOS_IOCTL,
|
||||
®,sizeof(reg),®,sizeof(reg),&cb,0);
|
||||
|
||||
if (!fResult || (reg.reg_Flags & 0x0001)) {
|
||||
TCHAR *msg = w32_errstr(0);
|
||||
printf("Volume lock failed (%s)\n",msg);
|
||||
LocalFree(msg);
|
||||
return SS$_DEVNOTALLOC;
|
||||
}
|
||||
reg.reg_EAX = 0x440d;
|
||||
reg.reg_EBX = chantab[chan].device_name - 'A' + 1;
|
||||
reg.reg_ECX = 0x0860; /* Get device parameters */
|
||||
reg.reg_EDX = (DWORD) & deviceparam;
|
||||
reg.reg_Flags = 0x0001; /* set carry flag */
|
||||
|
||||
fResult = DeviceIoControl(hDrive,
|
||||
VWIN32_DIOC_DOS_IOCTL,
|
||||
®,sizeof(reg),
|
||||
®,sizeof(reg),
|
||||
&cb,0);
|
||||
|
||||
if (!fResult || (reg.reg_Flags & 0x0001)) {
|
||||
TCHAR *msg = w32_errstr(0);
|
||||
printf("Volume get parameters failed (%s)\n",msg);
|
||||
LocalFree(msg);
|
||||
return 8;
|
||||
}
|
||||
chantab[chan].sectorsize = deviceparam.sec_size;
|
||||
info->sectors = 0;
|
||||
break;
|
||||
}
|
||||
} while(0);
|
||||
|
||||
chantab[chan].IoBuffer = VirtualAlloc(NULL,chantab[chan].sectorsize,
|
||||
MEM_COMMIT,PAGE_READWRITE);
|
||||
chantab[chan].last_sector = ~0U;
|
||||
*chanptr = chan_count++;
|
||||
info->status = 0;
|
||||
info->sectorsize = chantab[chan].sectorsize;
|
||||
init_count++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -61,6 +61,15 @@ struct HANDLE {
|
||||
int hand_drive;
|
||||
} handle[HANDLE_MAX];
|
||||
|
||||
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, "The drive letter must be between A: and Z:\n" );
|
||||
fprintf( fp, "The drive is accessed as a physical device\n" );
|
||||
fprintf( fp, "Use ODS2-Image to work with disk images such as .ISO or simulator files.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned phyio_init(int devlen,char *devnam,unsigned *hand,struct phyio_info *info)
|
||||
{
|
||||
if (hand_count < HANDLE_MAX - 1) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* PHYVMS.c v1.3 Physical I/O module for Unix */
|
||||
/* PHYUNIX.c v1.3 Physical I/O module for Unix */
|
||||
|
||||
/*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
@ -14,13 +14,21 @@
|
||||
If the user mounts cd0 we open up /dev/cd0 for access.
|
||||
*/
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "phyio.h"
|
||||
#include "ssdef.h"
|
||||
#include "compat.h"
|
||||
|
||||
#if defined(__digital__) && defined(__unix__)
|
||||
#define DEV_PREFIX "/devices/rdisk/%s"
|
||||
@ -42,16 +50,30 @@ void phyio_show(void)
|
||||
init_count,read_count,write_count);
|
||||
}
|
||||
|
||||
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, "For example, if you are using " DEV_PREFIX "\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" );
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned phyio_init(int devlen,char *devnam,unsigned *handle,struct phyio_info *info)
|
||||
{
|
||||
int vmsfd;
|
||||
char *cp,devbuf[200];
|
||||
|
||||
UNUSED(devlen);
|
||||
|
||||
init_count++;
|
||||
info->status = 0; /* We don't know anything about this device! */
|
||||
info->sectors = 0;
|
||||
info->sectorsize = 0;
|
||||
sprintf(devbuf,DEV_PREFIX,devnam);
|
||||
snprintf(devbuf,sizeof(devbuf),DEV_PREFIX,devnam);
|
||||
cp = strchr(devbuf,':');
|
||||
if (cp != NULL) *cp = '\0';
|
||||
vmsfd = open(devbuf,O_RDWR);
|
||||
@ -71,19 +93,19 @@ unsigned phyio_close(unsigned handle)
|
||||
|
||||
unsigned phyio_read(unsigned handle,unsigned block,unsigned length,char *buffer)
|
||||
{
|
||||
int res;
|
||||
off_t res;
|
||||
#ifdef DEBUG
|
||||
printf("Phyio read block: %d into %x (%d bytes)\n",block,buffer,length);
|
||||
#endif
|
||||
read_count++;
|
||||
if ((res = lseek(handle,block*512,0)) < 0) {
|
||||
perror("lseek ");
|
||||
printf("lseek failed %d\n",res);
|
||||
printf("lseek failed %" PRIuMAX "u\n",(uintmax_t)res);
|
||||
return SS$_PARITY;
|
||||
}
|
||||
if ((res = read(handle,buffer,length)) != length) {
|
||||
if ((res = read(handle,buffer,length)) != (ssize_t)length) {
|
||||
perror("read ");
|
||||
printf("read failed %d\n",res);
|
||||
printf("read failed %" PRIuMAX "u\n",(uintmax_t)res);
|
||||
return SS$_PARITY;
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
|
||||
@ -60,6 +60,14 @@ void phyio_show(void)
|
||||
init_count,read_count,write_count);
|
||||
}
|
||||
|
||||
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, "You will need the LOGIO privilege\n" );
|
||||
fprintf( fp, "Use ODS2-Image to work with disk images such as .ISO or simulator files.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
unsigned phyio_init(int devlen,char *devnam,unsigned *handle,struct phyio_info *info)
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/* check for cr - return terminator - update file length */
|
||||
/* RMS.c v1.3 RMS components */
|
||||
/* RMS.c v1.4 RMS components */
|
||||
|
||||
/*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
@ -34,7 +34,7 @@
|
||||
#include "rms.h"
|
||||
#include "access.h"
|
||||
#include "direct.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
/* Table of file name component delimeters... */
|
||||
|
||||
@ -49,7 +49,7 @@ char char_delim[] = {
|
||||
|
||||
unsigned name_delim(char *str,int len,int size[5])
|
||||
{
|
||||
register unsigned ch;
|
||||
register unsigned ch = 0;
|
||||
register char *curptr = str;
|
||||
register char *endptr = curptr + len;
|
||||
register char *begptr = curptr;
|
||||
@ -190,9 +190,13 @@ unsigned dircache(struct VCB *vcb,char *dirnam,int dirlen,struct fiddef *dirid)
|
||||
#define STATUS_TMPDIR 2
|
||||
#define STATUS_WILDCARD 4
|
||||
|
||||
#define WCDALLOC_SIZE(size) (sizeof(struct WCCDIR)+(size))
|
||||
struct WCCDIR {
|
||||
struct WCCDIR *wcd_next;
|
||||
struct WCCDIR *wcd_prev;
|
||||
#ifdef DEBUG
|
||||
size_t size;
|
||||
#endif
|
||||
int wcd_status;
|
||||
int wcd_wcc;
|
||||
int wcd_prelen;
|
||||
@ -207,6 +211,12 @@ struct WCCDIR {
|
||||
#define STATUS_TMPWCC 16
|
||||
#define MAX_FILELEN 1024
|
||||
|
||||
/* Allocation sise for WCCFILE = block + max len wcd_sernam.
|
||||
* WCCDIRs are allocated smaller on the chain..
|
||||
* Why 256? The byte lengths?
|
||||
*/
|
||||
#define WCFALLOC_SIZE (sizeof(struct WCCFILE)+256)
|
||||
|
||||
struct WCCFILE {
|
||||
struct FAB *wcf_fab;
|
||||
struct VCB *wcf_vcb;
|
||||
@ -220,21 +230,31 @@ struct WCCFILE {
|
||||
|
||||
/* Function to remove WCCFILE and WCCDIR structures when not required */
|
||||
|
||||
void cleanup_wcf(struct WCCFILE *wccfile)
|
||||
void cleanup_wcf(struct WCCFILE **wccfilep)
|
||||
{
|
||||
struct WCCFILE *wccfile;
|
||||
|
||||
wccfile = *wccfilep;
|
||||
*wccfilep = NULL;
|
||||
if (wccfile != NULL) {
|
||||
struct WCCDIR *wcc = wccfile->wcf_wcd.wcd_next;
|
||||
wccfile->wcf_wcd.wcd_next = NULL;
|
||||
wccfile->wcf_wcd.wcd_prev = NULL;
|
||||
/* should deaccess volume */
|
||||
free(wccfile);
|
||||
while (wcc != NULL) {
|
||||
struct WCCDIR *next = wcc->wcd_next;
|
||||
wcc->wcd_next = NULL;
|
||||
wcc->wcd_prev = NULL;
|
||||
#ifdef DEBUG
|
||||
memset(wcc,0,wcc->size);
|
||||
#endif
|
||||
free(wcc);
|
||||
wcc = next;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
memset(wccfile,0,WCFALLOC_SIZE);
|
||||
#endif
|
||||
free(wccfile);
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,7 +269,10 @@ unsigned do_search(struct FAB *fab,struct WCCFILE *wccfile)
|
||||
struct dsc_descriptor fibdsc,resdsc;
|
||||
struct NAM *nam = fab->fab$l_nam;
|
||||
wcc = &wccfile->wcf_wcd;
|
||||
if (fab->fab$w_ifi != 0) return RMS$_IFI;
|
||||
if (fab->fab$w_ifi != 0) {
|
||||
sts = RMS$_IFI;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* if first time through position at top directory... WCCDIR */
|
||||
|
||||
@ -322,7 +345,8 @@ unsigned do_search(struct FAB *fab,struct WCCFILE *wccfile)
|
||||
if (nam->nam$b_rsl <= nam->nam$b_rss) {
|
||||
memcpy(nam->nam$l_rsa,wccfile->wcf_result,nam->nam$b_rsl);
|
||||
} else {
|
||||
return RMS$_RSS;
|
||||
sts = RMS$_RSS;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
memcpy(&wccfile->wcf_fid,&fibblk.fib$w_fid_num,sizeof(struct fiddef));
|
||||
@ -348,11 +372,17 @@ unsigned do_search(struct FAB *fab,struct WCCFILE *wccfile)
|
||||
if (wcc->wcd_prev != NULL) wcc->wcd_prev->wcd_next = wcc->wcd_next;
|
||||
wcc = wcc->wcd_next;
|
||||
memcpy(wccfile->wcf_result + wcc->wcd_prelen + wcc->wcd_reslen - 6,".DIR;1",6);
|
||||
#ifdef DEBUG
|
||||
memset(savwcc, 0, savwcc->size);
|
||||
#endif
|
||||
free(savwcc);
|
||||
} else {
|
||||
if ((wccfile->wcf_status & STATUS_RECURSE) && wcc->wcd_prev == NULL) {
|
||||
struct WCCDIR *newwcc;
|
||||
newwcc = (struct WCCDIR *) malloc(sizeof(struct WCCDIR) + 8);
|
||||
newwcc = (struct WCCDIR *) calloc(1,WCDALLOC_SIZE(8));
|
||||
#ifdef DEBUG
|
||||
newwcc->size = WCDALLOC_SIZE(8);
|
||||
#endif
|
||||
newwcc->wcd_next = wcc->wcd_next;
|
||||
newwcc->wcd_prev = wcc;
|
||||
newwcc->wcd_wcc = 0;
|
||||
@ -368,7 +398,6 @@ unsigned do_search(struct FAB *fab,struct WCCFILE *wccfile)
|
||||
memcpy(newwcc->wcd_sernam,"*.DIR;1",7);
|
||||
newwcc->wcd_prelen = wcc->wcd_prelen;
|
||||
wcc = newwcc;
|
||||
|
||||
} else {
|
||||
if (wcc->wcd_next != NULL) {
|
||||
#ifdef DEBUG
|
||||
@ -394,9 +423,10 @@ unsigned do_search(struct FAB *fab,struct WCCFILE *wccfile)
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanup_wcf(wccfile);
|
||||
if (nam != NULL) nam->nam$l_wcc = 0;
|
||||
fab->fab$w_ifi = 0; /* must dealloc memory blocks! */
|
||||
cleanup:
|
||||
cleanup_wcf(&wccfile);
|
||||
if (nam != NULL) nam->nam$l_wcc = 0;
|
||||
return sts;
|
||||
}
|
||||
|
||||
@ -407,7 +437,8 @@ unsigned sys_search(struct FAB *fab)
|
||||
{
|
||||
struct NAM *nam = fab->fab$l_nam;
|
||||
struct WCCFILE *wccfile;
|
||||
if (nam == NULL) return RMS$_NAM;
|
||||
if (nam == NULL)
|
||||
return RMS$_NAM;
|
||||
wccfile = (struct WCCFILE *) nam->nam$l_wcc;
|
||||
if (wccfile == NULL) return RMS$_WCC;
|
||||
return do_search(fab,wccfile);
|
||||
@ -430,12 +461,15 @@ unsigned do_parse(struct FAB *fab,struct WCCFILE **wccret)
|
||||
char *dna = fab->fab$l_dna;
|
||||
struct NAM *nam = fab->fab$l_nam;
|
||||
int sts;
|
||||
int fna_size[5] = {0, 0, 0, 0, 0},dna_size[5] = {0, 0, 0, 0, 0};
|
||||
if (fab->fab$w_ifi != 0) return RMS$_IFI;
|
||||
if (nam != NULL) if (nam->nam$l_wcc == 0) {
|
||||
cleanup_wcf((struct WCCFILE *) nam->nam$l_wcc);
|
||||
nam->nam$l_wcc = 0;
|
||||
}
|
||||
int fna_size[5] = {0, 0, 0, 0, 0},
|
||||
dna_size[5] = {0, 0, 0, 0, 0};
|
||||
if (fab->fab$w_ifi != 0)
|
||||
return RMS$_IFI;
|
||||
if (nam != NULL && nam->nam$l_wcc == 0) {
|
||||
struct WCCFILE *wcc = (struct WCCFILE *)nam->nam$l_wcc;
|
||||
cleanup_wcf(&wcc);
|
||||
nam->nam$l_wcc = 0;
|
||||
}
|
||||
/* Break up file specifications... */
|
||||
|
||||
sts = name_delim(fna,fab->fab$b_fns,fna_size);
|
||||
@ -447,9 +481,9 @@ unsigned do_parse(struct FAB *fab,struct WCCFILE **wccret)
|
||||
/* Make WCCFILE entry for rest of processing */
|
||||
|
||||
{
|
||||
wccfile = (struct WCCFILE *) malloc(sizeof(struct WCCFILE) + 256);
|
||||
if (wccfile == NULL) return SS$_INSFMEM;
|
||||
memset(wccfile,0,sizeof(struct WCCFILE)+256);
|
||||
wccfile = (struct WCCFILE *) calloc(1,WCFALLOC_SIZE);
|
||||
if (wccfile == NULL)
|
||||
return SS$_INSFMEM;
|
||||
wccfile->wcf_fab = fab;
|
||||
wccfile->wcf_vcb = NULL;
|
||||
wccfile->wcf_fcb = NULL;
|
||||
@ -496,7 +530,10 @@ memset(wccfile,0,sizeof(struct WCCFILE)+256);
|
||||
len--;
|
||||
src++;
|
||||
if (count < 2 || (count == 7 &&
|
||||
memcmp(dir,"[000000",7) == 0)) return RMS$_DIR;
|
||||
memcmp(dir,"[000000",7) == 0)) {
|
||||
cleanup_wcf(&wccfile);
|
||||
return RMS$_DIR;
|
||||
}
|
||||
while (count > 1) {
|
||||
if (dir[--count] == '.') break;
|
||||
}
|
||||
@ -505,13 +542,19 @@ memset(wccfile,0,sizeof(struct WCCFILE)+256);
|
||||
src = "[000000]";
|
||||
dirlen = len = 8;
|
||||
} else {
|
||||
if (*src != '.' && *src != ']') return RMS$_DIR;
|
||||
if (*src != '.' && *src != ']') {
|
||||
cleanup_wcf(&wccfile);
|
||||
return RMS$_DIR;
|
||||
}
|
||||
if (*src == '.' && count < 2) {
|
||||
src++;
|
||||
len--;
|
||||
}
|
||||
dirlen = len + count;
|
||||
if ((ess -= count) < 0) return RMS$_ESS;
|
||||
if ((ess -= count) < 0) {
|
||||
cleanup_wcf(&wccfile);
|
||||
return RMS$_ESS;
|
||||
}
|
||||
memcpy(esa,dir,count);
|
||||
esa += count;
|
||||
}
|
||||
@ -523,7 +566,10 @@ memset(wccfile,0,sizeof(struct WCCFILE)+256);
|
||||
}
|
||||
dna += dna_size[field];
|
||||
def += default_size[field];
|
||||
if ((ess -= len) < 0) return RMS$_ESS;
|
||||
if ((ess -= len) < 0) {
|
||||
cleanup_wcf(&wccfile);
|
||||
return RMS$_ESS;
|
||||
}
|
||||
while (len-- > 0) {
|
||||
register char ch;
|
||||
*esa++ = ch = *src++;
|
||||
@ -549,12 +595,14 @@ memset(wccfile,0,sizeof(struct WCCFILE)+256);
|
||||
if (nam->nam$b_esl <= nam->nam$b_ess) {
|
||||
memcpy(nam->nam$l_esa,wccfile->wcf_result,nam->nam$b_esl);
|
||||
} else {
|
||||
cleanup_wcf(&wccfile);
|
||||
return RMS$_ESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
sts = 1;
|
||||
if (nam != NULL) if (nam->nam$b_nop & NAM$M_SYNCHK) sts = 0;
|
||||
if (nam != NULL && (nam->nam$b_nop & NAM$M_SYNCHK))
|
||||
sts = 0;
|
||||
|
||||
/* Now build up WCC structures as required */
|
||||
|
||||
@ -564,8 +612,14 @@ memset(wccfile,0,sizeof(struct WCCFILE)+256);
|
||||
struct WCCDIR *wcc;
|
||||
struct DEV *dev;
|
||||
sts = device_lookup(fna_size[0],wccfile->wcf_result,0,&dev);
|
||||
if ((sts & 1) == 0) return sts;
|
||||
if ((wccfile->wcf_vcb = dev->vcb) == NULL) return SS$_DEVNOTMOUNT;
|
||||
if ((sts & 1) == 0) {
|
||||
cleanup_wcf(&wccfile);
|
||||
return sts;
|
||||
}
|
||||
if ((wccfile->wcf_vcb = dev->vcb) == NULL) {
|
||||
cleanup_wcf(&wccfile);
|
||||
return SS$_DEVNOTMOUNT;
|
||||
}
|
||||
wcc = &wccfile->wcf_wcd;
|
||||
wcc->wcd_prev = NULL;
|
||||
wcc->wcd_next = NULL;
|
||||
@ -606,11 +660,16 @@ memset(wccfile,0,sizeof(struct WCCFILE)+256);
|
||||
if (char_delim[*dirptr++ & 127]) break;
|
||||
seglen++;
|
||||
} while (dirsiz + seglen < dirlen);
|
||||
wcd = (struct WCCDIR *) malloc(sizeof(struct WCCDIR) + seglen + 8);
|
||||
wcd = (struct WCCDIR *) calloc(1,WCDALLOC_SIZE(seglen + 8));
|
||||
#ifdef DEBUG
|
||||
wcd->size = WCDALLOC_SIZE(seglen + 8);
|
||||
#endif
|
||||
/* calloc()
|
||||
wcd->wcd_wcc = 0;
|
||||
wcd->wcd_status = 0;
|
||||
wcd->wcd_prelen = 0;
|
||||
wcd->wcd_reslen = 0;
|
||||
*/
|
||||
memcpy(wcd->wcd_sernam,dirnam + dirsiz,seglen);
|
||||
memcpy(wcd->wcd_sernam + seglen,".DIR;1",7);
|
||||
wcd->wcd_serdsc.dsc_w_length = seglen + 6;
|
||||
@ -628,6 +687,10 @@ memset(wccfile,0,sizeof(struct WCCFILE)+256);
|
||||
wcc->wcd_reslen = 0;
|
||||
wcc->wcd_serdsc.dsc_w_length = fna_size[2] + fna_size[3] + fna_size[4];
|
||||
wcc->wcd_serdsc.dsc_a_pointer = wcc->wcd_sernam;
|
||||
if (wcc->wcd_serdsc.dsc_w_length >= 256) {
|
||||
printf( "serdsc length too long %u\n", wcc->wcd_serdsc.dsc_w_length );
|
||||
abort();
|
||||
}
|
||||
memcpy(wcc->wcd_sernam,wccfile->wcf_result + fna_size[0] + fna_size[1],
|
||||
wcc->wcd_serdsc.dsc_w_length);
|
||||
#ifdef DEBUG
|
||||
@ -708,6 +771,8 @@ unsigned sys_connect(struct RAB *rab)
|
||||
|
||||
unsigned sys_disconnect(struct RAB *rab)
|
||||
{
|
||||
UNUSED(rab);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -739,30 +804,32 @@ unsigned sys_get(struct RAB *rab)
|
||||
switch (rfm = rab->rab$l_fab->fab$b_rfm) {
|
||||
case FAB$C_STMLF:
|
||||
delim = 1;
|
||||
break;
|
||||
break;
|
||||
case FAB$C_STMCR:
|
||||
delim = 2;
|
||||
break;
|
||||
break;
|
||||
case FAB$C_STM:
|
||||
delim = 3;
|
||||
break;
|
||||
break;
|
||||
case FAB$C_VFC:
|
||||
reclen += rab->rab$l_fab->fab$b_fsz;
|
||||
break;
|
||||
case FAB$C_FIX:
|
||||
if (reclen < rab->rab$l_fab->fab$w_mrs) return RMS$_RTB;
|
||||
if (reclen < rab->rab$l_fab->fab$w_mrs)
|
||||
return RMS$_RTB;
|
||||
reclen = rab->rab$l_fab->fab$w_mrs;
|
||||
break;
|
||||
}
|
||||
|
||||
offset = rab->rab$w_rfa[2] % 512;
|
||||
block = (rab->rab$w_rfa[1] << 16) + rab->rab$w_rfa[0];
|
||||
if (block == 0) block = 1;
|
||||
|
||||
if (block == 0)
|
||||
block = 1;
|
||||
{
|
||||
unsigned eofblk = VMSSWAP(fcb->head->fh2$w_recattr.fat$l_efblk);
|
||||
if (block > eofblk || (block == eofblk &&
|
||||
offset >= VMSWORD(fcb->head->fh2$w_recattr.fat$w_ffbyte))) return RMS$_EOF;
|
||||
offset >= VMSWORD(fcb->head->fh2$w_recattr.fat$w_ffbyte)))
|
||||
return RMS$_EOF;
|
||||
}
|
||||
|
||||
sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,0);
|
||||
@ -784,9 +851,9 @@ unsigned sys_get(struct RAB *rab)
|
||||
cpylen = 0;
|
||||
while (1) {
|
||||
int dellen = 0;
|
||||
int seglen = blocks * 512 - offset;
|
||||
if (delim) {
|
||||
if (delim >= 3) {
|
||||
unsigned int seglen = blocks * 512 - offset;
|
||||
if (delim) {
|
||||
if (delim >= 3) {
|
||||
char *ptr = buffer + offset;
|
||||
if (dellen == 1 && *ptr != '\n') {
|
||||
if (cpylen >= reclen) {
|
||||
@ -812,10 +879,11 @@ unsigned sys_get(struct RAB *rab)
|
||||
if (ch == '\r') dellen = 1;
|
||||
}
|
||||
seglen = ptr - (buffer + offset) - dellen;;
|
||||
} else {
|
||||
} else {
|
||||
char *ptr = buffer + offset;
|
||||
char term = '\r';
|
||||
if (delim == 1) term = '\n';
|
||||
if (delim == 1)
|
||||
term = '\n';
|
||||
while (seglen-- > 0) {
|
||||
if (*ptr++ == term) {
|
||||
dellen = 1;
|
||||
@ -826,11 +894,14 @@ unsigned sys_get(struct RAB *rab)
|
||||
seglen = ptr - (buffer + offset) - dellen;;
|
||||
}
|
||||
} else {
|
||||
if (seglen > reclen - cpylen) seglen = reclen - cpylen;
|
||||
if (seglen > reclen - cpylen)
|
||||
seglen = reclen - cpylen;
|
||||
if (rfm == FAB$C_VFC && cpylen < rab->rab$l_fab->fab$b_fsz) {
|
||||
unsigned fsz = rab->rab$l_fab->fab$b_fsz - cpylen;
|
||||
if (fsz > seglen) fsz = seglen;
|
||||
if (rab->rab$l_rhb) memcpy(rab->rab$l_rhb + cpylen,buffer + offset,fsz);
|
||||
if (fsz > seglen)
|
||||
fsz = seglen;
|
||||
if (rab->rab$l_rhb)
|
||||
memcpy(rab->rab$l_rhb + cpylen,buffer + offset,fsz);
|
||||
cpylen += fsz;
|
||||
offset += fsz;
|
||||
seglen -= fsz;
|
||||
@ -841,7 +912,7 @@ unsigned sys_get(struct RAB *rab)
|
||||
seglen = reclen - cpylen;
|
||||
sts = RMS$_RTB;
|
||||
}
|
||||
memcpy(recbuff,buffer + offset,seglen);
|
||||
memcpy(recbuff,buffer + offset,seglen);
|
||||
recbuff += seglen;
|
||||
cpylen += seglen;
|
||||
}
|
||||
@ -852,8 +923,8 @@ unsigned sys_get(struct RAB *rab)
|
||||
block += offset / 512;
|
||||
offset %= 512;
|
||||
if ((delim == 0 && cpylen >= reclen) || delim == 99) {
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
} else {
|
||||
sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,0);
|
||||
if ((sts & 1) == 0) {
|
||||
if (sts == SS$_ENDOFFILE) sts = RMS$_EOF;
|
||||
@ -862,7 +933,8 @@ unsigned sys_get(struct RAB *rab)
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
if (rfm == FAB$C_VFC) cpylen -= rab->rab$l_fab->fab$b_fsz;
|
||||
if (rfm == FAB$C_VFC)
|
||||
cpylen -= rab->rab$l_fab->fab$b_fsz;
|
||||
rab->rab$w_rsz = cpylen;
|
||||
|
||||
rab->rab$w_rfa[0] = block & 0xffff;
|
||||
@ -887,33 +959,33 @@ unsigned sys_put(struct RAB *rab)
|
||||
recbuff = rab->rab$l_rbf;
|
||||
delim = 0;
|
||||
switch (rfm = rab->rab$l_fab->fab$b_rfm) {
|
||||
case FAB$C_STMLF:
|
||||
if (reclen < 1) {
|
||||
delim = 1;
|
||||
} else {
|
||||
if (recbuff[reclen] != '\n') delim = 1;
|
||||
}
|
||||
break;
|
||||
case FAB$C_STMCR:
|
||||
if (reclen < 1) {
|
||||
delim = 2;
|
||||
} else {
|
||||
if (recbuff[reclen] != '\r') delim = 2;
|
||||
}
|
||||
break;
|
||||
case FAB$C_STM:
|
||||
if (reclen < 2) {
|
||||
delim = 3;
|
||||
} else {
|
||||
if (recbuff[reclen-1] != '\r' || recbuff[reclen] != '\n') delim = 3;
|
||||
}
|
||||
break;
|
||||
case FAB$C_VFC:
|
||||
reclen += rab->rab$l_fab->fab$b_fsz;
|
||||
break;
|
||||
case FAB$C_FIX:
|
||||
if (reclen != rab->rab$l_fab->fab$w_mrs) return RMS$_RSZ;
|
||||
break;
|
||||
case FAB$C_STMLF:
|
||||
if (reclen < 1) {
|
||||
delim = 1;
|
||||
} else {
|
||||
if (recbuff[reclen] != '\n') delim = 1;
|
||||
}
|
||||
break;
|
||||
case FAB$C_STMCR:
|
||||
if (reclen < 1) {
|
||||
delim = 2;
|
||||
} else {
|
||||
if (recbuff[reclen] != '\r') delim = 2;
|
||||
}
|
||||
break;
|
||||
case FAB$C_STM:
|
||||
if (reclen < 2) {
|
||||
delim = 3;
|
||||
} else {
|
||||
if (recbuff[reclen-1] != '\r' || recbuff[reclen] != '\n') delim = 3;
|
||||
}
|
||||
break;
|
||||
case FAB$C_VFC:
|
||||
reclen += rab->rab$l_fab->fab$b_fsz;
|
||||
break;
|
||||
case FAB$C_FIX:
|
||||
if (reclen != rab->rab$l_fab->fab$w_mrs) return RMS$_RSZ;
|
||||
break;
|
||||
}
|
||||
|
||||
block = VMSSWAP(fcb->head->fh2$w_recattr.fat$l_efblk);
|
||||
@ -930,55 +1002,58 @@ unsigned sys_put(struct RAB *rab)
|
||||
|
||||
cpylen = 0;
|
||||
while (1) {
|
||||
int seglen = blocks * 512 - offset;
|
||||
unsigned int seglen = blocks * 512 - offset;
|
||||
if (seglen > reclen - cpylen) seglen = reclen - cpylen;
|
||||
if (rfm == FAB$C_VFC && cpylen < rab->rab$l_fab->fab$b_fsz) {
|
||||
unsigned fsz = rab->rab$l_fab->fab$b_fsz - cpylen;
|
||||
if (fsz > seglen) fsz = seglen;
|
||||
|
||||
if (fsz > seglen)
|
||||
fsz = seglen;
|
||||
if (rab->rab$l_rhb) {
|
||||
memcpy(buffer + offset,rab->rab$l_rhb + cpylen,fsz);
|
||||
} else {
|
||||
memset(buffer + offset,0,fsz);
|
||||
}
|
||||
}
|
||||
cpylen += fsz;
|
||||
offset += fsz;
|
||||
seglen -= fsz;
|
||||
}
|
||||
if (seglen) {
|
||||
memcpy(buffer + offset,recbuff,seglen);
|
||||
memcpy(buffer + offset,recbuff,seglen);
|
||||
recbuff += seglen;
|
||||
cpylen += seglen;
|
||||
offset += seglen;
|
||||
}
|
||||
if (delim && offset < blocks * 512) {
|
||||
if (delim && offset < blocks * 512) {
|
||||
offset++;
|
||||
switch (delim) {
|
||||
case 1:
|
||||
*buffer = '\n';
|
||||
delim = 0;
|
||||
break;
|
||||
case 2:
|
||||
*buffer = '\r';
|
||||
delim = 0;
|
||||
break;
|
||||
case 3:
|
||||
*buffer = '\r';
|
||||
if (offset < blocks * 512) {
|
||||
offset++;
|
||||
*buffer = '\n';
|
||||
delim = 0;
|
||||
} else {
|
||||
delim = 2;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
*buffer = '\n';
|
||||
delim = 0;
|
||||
break;
|
||||
case 2:
|
||||
*buffer = '\r';
|
||||
delim = 0;
|
||||
break;
|
||||
case 3:
|
||||
*buffer = '\r';
|
||||
if (offset < blocks * 512) {
|
||||
offset++;
|
||||
*buffer = '\n';
|
||||
delim = 0;
|
||||
} else {
|
||||
delim = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
sts = deaccesschunk(vioc,block,blocks,1);
|
||||
if ((sts & 1) == 0) return sts;
|
||||
if ((sts & 1) == 0)
|
||||
return sts;
|
||||
block += blocks;
|
||||
if (cpylen >= reclen && delim == 0) {
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
} else {
|
||||
sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,1);
|
||||
if ((sts & 1) == 0) return sts;
|
||||
offset = 0;
|
||||
@ -1004,8 +1079,10 @@ unsigned sys_display(struct FAB *fab)
|
||||
struct HEAD *head = ifi_table[fab->fab$w_ifi]->wcf_fcb->head;
|
||||
unsigned short *pp = (unsigned short *) head;
|
||||
struct IDENT *id = (struct IDENT *) (pp + head->fh2$b_idoffset);
|
||||
|
||||
int ifi_no = fab->fab$w_ifi;
|
||||
if (ifi_no == 0 || ifi_no >= IFI_MAX) return RMS$_IFI;
|
||||
if (ifi_no == 0 || ifi_no >= IFI_MAX)
|
||||
return RMS$_IFI;
|
||||
fab->fab$l_alq = VMSSWAP(head->fh2$w_recattr.fat$l_hiblk);
|
||||
fab->fab$b_bks = head->fh2$w_recattr.fat$b_bktsize;
|
||||
fab->fab$w_deq = VMSWORD(head->fh2$w_recattr.fat$w_defext);
|
||||
@ -1017,36 +1094,67 @@ unsigned sys_display(struct FAB *fab)
|
||||
fab->fab$b_rat = head->fh2$w_recattr.fat$b_rattrib;
|
||||
while (xab != NULL) {
|
||||
switch (xab->xab$b_cod) {
|
||||
case XAB$C_DAT:
|
||||
memcpy(&xab->xab$q_bdt,id->fi2$q_bakdate,sizeof(id->fi2$q_bakdate));
|
||||
memcpy(&xab->xab$q_cdt,id->fi2$q_credate,sizeof(id->fi2$q_credate));
|
||||
memcpy(&xab->xab$q_edt,id->fi2$q_expdate,sizeof(id->fi2$q_expdate));
|
||||
memcpy(&xab->xab$q_rdt,id->fi2$q_revdate,sizeof(id->fi2$q_revdate));
|
||||
xab->xab$w_rvn = id->fi2$w_revision;
|
||||
case XAB$C_DAT:{
|
||||
memcpy(&xab->xab$q_bdt,id->fi2$q_bakdate,sizeof(id->fi2$q_bakdate));
|
||||
memcpy(&xab->xab$q_cdt,id->fi2$q_credate,sizeof(id->fi2$q_credate));
|
||||
memcpy(&xab->xab$q_edt,id->fi2$q_expdate,sizeof(id->fi2$q_expdate));
|
||||
memcpy(&xab->xab$q_rdt,id->fi2$q_revdate,sizeof(id->fi2$q_revdate));
|
||||
xab->xab$w_rvn = id->fi2$w_revision;
|
||||
}
|
||||
break;
|
||||
case XAB$C_FHC:{
|
||||
struct XABFHC *fhc = (struct XABFHC *) xab;
|
||||
fhc->xab$b_atr = head->fh2$w_recattr.fat$b_rattrib;
|
||||
fhc->xab$b_bkz = head->fh2$w_recattr.fat$b_bktsize;
|
||||
fhc->xab$w_dxq = VMSWORD(head->fh2$w_recattr.fat$w_defext);
|
||||
fhc->xab$l_ebk = VMSSWAP(head->fh2$w_recattr.fat$l_efblk);
|
||||
fhc->xab$w_ffb = VMSWORD(head->fh2$w_recattr.fat$w_ffbyte);
|
||||
if (fhc->xab$l_ebk == 0) {
|
||||
fhc->xab$l_ebk = fab->fab$l_alq;
|
||||
if (fhc->xab$w_ffb == 0) fhc->xab$l_ebk++;
|
||||
}
|
||||
fhc->xab$w_gbc = VMSWORD(head->fh2$w_recattr.fat$w_gbc);
|
||||
fhc->xab$l_hbk = VMSSWAP(head->fh2$w_recattr.fat$l_hiblk);
|
||||
fhc->xab$b_hsz = head->fh2$w_recattr.fat$b_vfcsize;
|
||||
fhc->xab$w_lrl = VMSWORD(head->fh2$w_recattr.fat$w_maxrec);
|
||||
fhc->xab$w_verlimit = VMSWORD(head->fh2$w_recattr.fat$w_versions);
|
||||
}
|
||||
break;
|
||||
case XAB$C_PRO:{
|
||||
struct XABPRO *pro = (struct XABPRO *) xab;
|
||||
pro->xab$w_pro = VMSWORD(head->fh2$w_fileprot);
|
||||
memcpy(&pro->xab$l_uic,&head->fh2$l_fileowner,4);
|
||||
}
|
||||
break;
|
||||
case XAB$C_ITM:{
|
||||
struct XABITM *itm = (struct XABITM *) xab;
|
||||
struct item_list *list;
|
||||
vmslong fch = VMSLONG( head->fh2$l_filechar );
|
||||
|
||||
if( itm->xab$b_mode != XAB$K_SENSEMODE )
|
||||
break;
|
||||
case XAB$C_FHC:{
|
||||
struct XABFHC *fhc = (struct XABFHC *) xab;
|
||||
fhc->xab$b_atr = head->fh2$w_recattr.fat$b_rattrib;
|
||||
fhc->xab$b_bkz = head->fh2$w_recattr.fat$b_bktsize;
|
||||
fhc->xab$w_dxq = VMSWORD(head->fh2$w_recattr.fat$w_defext);
|
||||
fhc->xab$l_ebk = VMSSWAP(head->fh2$w_recattr.fat$l_efblk);
|
||||
fhc->xab$w_ffb = VMSWORD(head->fh2$w_recattr.fat$w_ffbyte);
|
||||
if (fhc->xab$l_ebk == 0) {
|
||||
fhc->xab$l_ebk = fab->fab$l_alq;
|
||||
if (fhc->xab$w_ffb == 0) fhc->xab$l_ebk++;
|
||||
}
|
||||
fhc->xab$w_gbc = VMSWORD(head->fh2$w_recattr.fat$w_gbc);
|
||||
fhc->xab$l_hbk = VMSSWAP(head->fh2$w_recattr.fat$l_hiblk);
|
||||
fhc->xab$b_hsz = head->fh2$w_recattr.fat$b_vfcsize;
|
||||
fhc->xab$w_lrl = VMSWORD(head->fh2$w_recattr.fat$w_maxrec);
|
||||
fhc->xab$w_verlimit = VMSWORD(head->fh2$w_recattr.fat$w_versions);
|
||||
}
|
||||
break;
|
||||
case XAB$C_PRO:{
|
||||
struct XABPRO *pro = (struct XABPRO *) xab;
|
||||
pro->xab$w_pro = VMSWORD(head->fh2$w_fileprot);
|
||||
memcpy(&pro->xab$l_uic,&head->fh2$l_fileowner,4);
|
||||
for( list = itm->xab$l_itemlist; list->code != 0 || list->length != 0; list++ ) {
|
||||
list->retlen = sizeof(int);
|
||||
switch( list->code ) {
|
||||
case XAB$_UCHAR_NOBACKUP:
|
||||
*((int *)list->buffer) = (fch & FH2$M_NOBACKUP) != 0; break;
|
||||
case XAB$_UCHAR_CONTIGB:
|
||||
*((int *)list->buffer) = (fch & FH2$M_CONTIGB) != 0; break;
|
||||
case XAB$_UCHAR_CONTIG:
|
||||
*((int *)list->buffer) = (fch & FH2$M_CONTIG) != 0; break;
|
||||
case XAB$_UCHAR_DIRECTORY:
|
||||
*((int *)list->buffer) = (fch & FH2$M_DIRECTORY) != 0; break;
|
||||
case XAB$_UCHAR_MARKDEL:
|
||||
*((int *)list->buffer) = (fch & FH2$M_MARKDEL) != 0; break;
|
||||
default:
|
||||
list->retlen = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
xab = xab->xab$l_nxt;
|
||||
}
|
||||
@ -1061,13 +1169,15 @@ unsigned sys_close(struct FAB *fab)
|
||||
{
|
||||
int sts;
|
||||
int ifi_no = fab->fab$w_ifi;
|
||||
if (ifi_no < 1 || ifi_no >= IFI_MAX) return RMS$_IFI;
|
||||
if (ifi_no < 1 || ifi_no >= IFI_MAX)
|
||||
return RMS$_IFI;
|
||||
sts = deaccessfile(ifi_table[ifi_no]->wcf_fcb);
|
||||
if (sts & 1) {
|
||||
ifi_table[ifi_no]->wcf_fcb = NULL;
|
||||
if (ifi_table[ifi_no]->wcf_status & STATUS_TMPWCC) {
|
||||
cleanup_wcf(ifi_table[ifi_no]);
|
||||
if (fab->fab$l_nam != NULL) fab->fab$l_nam->nam$l_wcc = 0;
|
||||
cleanup_wcf(&ifi_table[ifi_no]);
|
||||
if (fab->fab$l_nam != NULL)
|
||||
fab->fab$l_nam->nam$l_wcc = 0;
|
||||
}
|
||||
fab->fab$w_ifi = 0;
|
||||
ifi_table[ifi_no] = NULL;
|
||||
@ -1085,9 +1195,15 @@ unsigned sys_open(struct FAB *fab)
|
||||
int wcc_flag = 0;
|
||||
struct WCCFILE *wccfile = NULL;
|
||||
struct NAM *nam = fab->fab$l_nam;
|
||||
|
||||
if (fab->fab$w_ifi != 0) return RMS$_IFI;
|
||||
while (ifi_table[ifi_no] != NULL && ifi_no < IFI_MAX) ifi_no++;
|
||||
if (ifi_no >= IFI_MAX) return RMS$_IFI;
|
||||
|
||||
while (ifi_table[ifi_no] != NULL && ifi_no < IFI_MAX)
|
||||
ifi_no++;
|
||||
|
||||
if (ifi_no >= IFI_MAX)
|
||||
return RMS$_IFI;
|
||||
|
||||
if (nam != NULL) {
|
||||
wccfile = (struct WCCFILE *) nam->nam$l_wcc;
|
||||
}
|
||||
@ -1099,6 +1215,8 @@ unsigned sys_open(struct FAB *fab)
|
||||
sts = RMS$_WLD;
|
||||
} else {
|
||||
sts = do_search(fab,wccfile);
|
||||
if ((sts & 1) == 0)
|
||||
wcc_flag = 0;
|
||||
}
|
||||
wccfile->wcf_status |= STATUS_TMPWCC;
|
||||
}
|
||||
@ -1115,7 +1233,7 @@ unsigned sys_open(struct FAB *fab)
|
||||
sys_display(fab);
|
||||
}
|
||||
if (wcc_flag && ((sts & 1) == 0)) {
|
||||
cleanup_wcf(wccfile);
|
||||
cleanup_wcf(&wccfile);
|
||||
if (nam != NULL) nam->nam$l_wcc = 0;
|
||||
}
|
||||
return sts;
|
||||
@ -1145,6 +1263,8 @@ unsigned sys_erase(struct FAB *fab)
|
||||
sts = RMS$_WLD;
|
||||
} else {
|
||||
sts = do_search(fab,wccfile);
|
||||
if ((sts & 1) == 0)
|
||||
wcc_flag = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1173,7 +1293,7 @@ unsigned sys_erase(struct FAB *fab)
|
||||
}
|
||||
}
|
||||
if (wcc_flag) {
|
||||
cleanup_wcf(wccfile);
|
||||
cleanup_wcf(&wccfile);
|
||||
if (nam != NULL) nam->nam$l_wcc = 0;
|
||||
}
|
||||
return sts;
|
||||
@ -1185,6 +1305,7 @@ unsigned sys_create(struct FAB *fab)
|
||||
unsigned sts;
|
||||
int ifi_no = 1;
|
||||
int wcc_flag = 0;
|
||||
|
||||
struct WCCFILE *wccfile = NULL;
|
||||
struct NAM *nam = fab->fab$l_nam;
|
||||
if (fab->fab$w_ifi != 0) return RMS$_IFI;
|
||||
@ -1201,6 +1322,8 @@ unsigned sys_create(struct FAB *fab)
|
||||
sts = RMS$_WLD;
|
||||
} else {
|
||||
sts = do_search(fab,wccfile);
|
||||
if ((sts & 1) == 0)
|
||||
wcc_flag = 0;
|
||||
if (sts == RMS$_FNF) sts = 1;
|
||||
}
|
||||
}
|
||||
@ -1209,11 +1332,13 @@ unsigned sys_create(struct FAB *fab)
|
||||
}
|
||||
if (sts & 1) {
|
||||
struct fibdef fibblk;
|
||||
struct dsc_descriptor fibdsc,serdsc;
|
||||
struct dsc_descriptor fibdsc; /* ,serdsc; */
|
||||
fibdsc.dsc_w_length = sizeof(struct fibdef);
|
||||
fibdsc.dsc_a_pointer = (char *) &fibblk;
|
||||
/* Unused
|
||||
serdsc.dsc_w_length = wccfile->wcf_wcd.wcd_reslen;
|
||||
serdsc.dsc_a_pointer = wccfile->wcf_result + wccfile->wcf_wcd.wcd_prelen;
|
||||
*/
|
||||
memcpy(&fibblk.fib$w_did_num,&wccfile->wcf_wcd.wcd_dirid,sizeof(struct fiddef));
|
||||
fibblk.fib$w_nmctl = 0;
|
||||
fibblk.fib$l_acctl = 0;
|
||||
@ -1233,8 +1358,10 @@ unsigned sys_create(struct FAB *fab)
|
||||
fab->fab$w_ifi = ifi_no;
|
||||
}
|
||||
}
|
||||
cleanup_wcf(wccfile);
|
||||
if (nam != NULL) nam->nam$l_wcc = 0;
|
||||
if( wcc_flag ) {
|
||||
cleanup_wcf(&wccfile);
|
||||
if (nam != NULL) nam->nam$l_wcc = 0;
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
@ -32,12 +32,11 @@
|
||||
|
||||
#define NAM$C_MAXRSS 255
|
||||
#define NAM$M_SYNCHK 1
|
||||
#define FAB$M_NAM 0x1000000
|
||||
|
||||
#define XAB$C_DAT 18
|
||||
#define XAB$C_FHC 29
|
||||
#define XAB$C_PRO 19
|
||||
|
||||
#define XAB$C_ITM 36
|
||||
|
||||
struct XABDAT {
|
||||
void *xab$l_nxt;
|
||||
@ -80,13 +79,56 @@ struct XABFHC cc$rms_xabfhc = {NULL,XAB$C_FHC,0,0,0,0,0,0,0,0,0,0};
|
||||
extern struct XABFHC cc$rms_xabfhc;
|
||||
#endif
|
||||
|
||||
#define XAB$K_SENSEMODE 1
|
||||
/* #define XAB$K_SETMODE 2 */
|
||||
#define XAB$_UCHAR 128
|
||||
#define XAB$_UCHAR_NOBACKUP 130 /* (set,sense) FCH$V_NOBACKUP */
|
||||
#define XAB$_UCHAR_WRITEBACK 131 /* (sense) FCH$V_WRITEBACK */
|
||||
#define XAB$_UCHAR_READCHECK 132 /* (set,sense) FCH$V_READCHECK */
|
||||
#define XAB$_UCHAR_WRITECHECK 133 /* (set,sense) FCH$V_WRITECHECK */
|
||||
#define XAB$_UCHAR_CONTIGB 134 /* (set,sense) FCH$V_CONTIGB */
|
||||
#define XAB$_UCHAR_LOCKED 135 /* (set,sense) FCH$V_LOCKED */
|
||||
#define XAB$_UCHAR_CONTIG 136 /* (sense) FCH$V_CONTIG */
|
||||
#define XAB$_UCHAR_SPOOL 138 /* (sense) FCH$V_SPOOL */
|
||||
#define XAB$_UCHAR_DIRECTORY 139 /* (sense) FCH$V_DIRECTORY */
|
||||
#define XAB$_UCHAR_BADBLOCK 140 /* (sense) FCH$V_BADBLOCK */
|
||||
#define XAB$_UCHAR_MARKDEL 141 /* (sense) FCH$V_BADBLOCK */
|
||||
|
||||
struct item_list {
|
||||
unsigned short int code;
|
||||
unsigned short int length;
|
||||
void *buffer;
|
||||
int retlen;
|
||||
};
|
||||
|
||||
struct XABITM {
|
||||
void *xab$l_nxt;
|
||||
int xab$b_cod;
|
||||
struct item_list *xab$l_itemlist;
|
||||
int xab$b_mode;
|
||||
};
|
||||
|
||||
#ifdef RMS$INITIALIZE
|
||||
struct XABITM cc$rms_xabitm = {NULL,XAB$C_ITM,NULL,0};
|
||||
#else
|
||||
extern struct XABITM cc$rms_xabitm;
|
||||
#endif
|
||||
|
||||
#define xab$m_noread 1
|
||||
#define xab$m_nowrite 2
|
||||
#define xab$m_noexe 4
|
||||
#define xab$m_nodel 8
|
||||
#define xab$m_prot (xab$m_noread|xab$m_nowrite|xab$m_noexe|xab$m_nodel)
|
||||
#define xab$v_system 0
|
||||
#define xab$v_owner 4
|
||||
#define xab$v_group 8
|
||||
#define xab$v_world 12
|
||||
|
||||
struct XABPRO {
|
||||
void *xab$l_nxt;
|
||||
int xab$b_cod;
|
||||
int xab$w_pro;
|
||||
int xab$l_uic;
|
||||
unsigned int xab$w_pro;
|
||||
unsigned int xab$l_uic;
|
||||
};
|
||||
|
||||
#ifdef RMS$INITIALIZE
|
||||
@ -185,6 +227,38 @@ extern struct RAB cc$rms_rab;
|
||||
#define FAB$C_STMLF 5
|
||||
#define FAB$C_STMCR 6
|
||||
|
||||
/* FAB$L_FOP */
|
||||
#define FAB$M_ASY 1
|
||||
#define FAB$M_MXV 2
|
||||
#define FAB$M_SUP 4
|
||||
#define FAB$M_TMP 8
|
||||
#define FAB$M_TMD 16
|
||||
#define FAB$M_DFW 32
|
||||
#define FAB$M_SQO 64
|
||||
#define FAB$M_RWO 128
|
||||
#define FAB$M_POS 256
|
||||
#define FAB$M_WCK 512
|
||||
#define FAB$M_NEF 1024
|
||||
#define FAB$M_RWC 2048
|
||||
#define FAB$M_DMO 4096
|
||||
#define FAB$M_SPL 8192
|
||||
#define FAB$M_SCF 16384
|
||||
#define FAB$M_DLT 32768
|
||||
#define FAB$M_NFS 65536
|
||||
#define FAB$M_UFO 131072
|
||||
#define FAB$M_PPF 262144
|
||||
#define FAB$M_INP 524288
|
||||
#define FAB$M_CTG 1048576
|
||||
#define FAB$M_CBT 2097152
|
||||
#define FAB$M_SYNCSTS 4194304
|
||||
#define FAB$M_RCK 8388608
|
||||
#define FAB$M_NAM 16777216
|
||||
#define FAB$M_CIF 33554432
|
||||
#define FAB$M_ESC 134217728
|
||||
#define FAB$M_TEF 268435456
|
||||
#define FAB$M_OFP 536870912
|
||||
#define FAB$M_KFO 1073741824
|
||||
|
||||
struct FAB {
|
||||
struct NAM *fab$l_nam;
|
||||
int fab$w_ifi;
|
||||
@ -195,9 +269,9 @@ struct FAB {
|
||||
int fab$l_alq;
|
||||
int fab$b_bks;
|
||||
int fab$w_deq;
|
||||
int fab$b_fsz;
|
||||
unsigned int fab$b_fsz;
|
||||
int fab$w_gbc;
|
||||
int fab$w_mrs;
|
||||
unsigned int fab$w_mrs;
|
||||
int fab$l_fop;
|
||||
int fab$b_org;
|
||||
int fab$b_rat;
|
||||
|
||||
88
extracters/ods2/sysmsg.c
Normal file
88
extracters/ods2/sysmsg.c
Normal file
@ -0,0 +1,88 @@
|
||||
/* Timothe Litt litt _at_ acm _ddot_ org */
|
||||
|
||||
/* Message code translations for non-VMS systems */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Should replace with lib$sys_getmsg under VMS
|
||||
|
||||
#ifndef VMS
|
||||
*/
|
||||
|
||||
#include "ssdef.h"
|
||||
#include "rms.h"
|
||||
#include "compat.h"
|
||||
|
||||
static
|
||||
const struct VMSMSG {
|
||||
unsigned int code;
|
||||
const char *const text;
|
||||
} *mp, vms2text[] = {
|
||||
{RMS$_BUG, "%RMS-F-BUG, fatal RMS condition detected, process deleted"},
|
||||
{RMS$_DIR, "%RMS-F-DIR, error in directory name"},
|
||||
{RMS$_DNF, "%RMS-E-DNF, directory not found"},
|
||||
{RMS$_EOF, "%RMS-E-EOF, end of file detected"},
|
||||
{RMS$_ESS, "%RMS-F-ESS, expanded string area too small"},
|
||||
{RMS$_FNF, "%RMS-E-FNF, file not found"},
|
||||
{RMS$_FNM, "%RMS-F-FNM, error in file name"},
|
||||
{RMS$_IFI, "%RMS-F-IFI, invalid internal file identifier (IFI) value"},
|
||||
{RMS$_NAM, "%RMS-F-NAM, invalid NAM block or NAM block not accessible"},
|
||||
{RMS$_NMF, "%RMS-E-NMF, no more files found"},
|
||||
{RMS$_RSS, "%RMS-F-RSS, invalid resultant string size"},
|
||||
{RMS$_RSZ, "%RMS-F-RSZ, invalid record size"},
|
||||
{RMS$_RTB, "%RMS-W-RTB, !UL byte record too large for user's buffer"},
|
||||
{RMS$_WCC, "%RMS-E-WCC, invalid wild card context (WCC) value"},
|
||||
{RMS$_WLD, "%RMS-F-WLD, invalid wildcard operation"},
|
||||
{SS$_ABORT, "%SYSTEM-F-ABORT, abort"},
|
||||
{SS$_BADFILENAME, "%SYSTEM-W-BADFILENAME, bad file name syntax"},
|
||||
{SS$_BADIRECTORY, "%SYSTEM-W-BADIRECTORY, bad directory file format"},
|
||||
{SS$_BADPARAM, "%SYSTEM-F-BADPARAM, bad parameter value"},
|
||||
{SS$_BUGCHECK, "%SYSTEM-F-BUGCHECK, internal consistency failure"},
|
||||
{SS$_DATACHECK, "%SYSTEM-F-DATACHECK, write check error"},
|
||||
{SS$_DEVICEFULL, "%SYSTEM-W-DEVICEFULL, device full - allocation failure"},
|
||||
{SS$_DEVMOUNT, "%SYSTEM-F-DEVMOUNT, device is already mounted"},
|
||||
{SS$_DEVNOTALLOC, "%SYSTEM-W-DEVNOTALLOC, device not allocated"},
|
||||
{SS$_DEVNOTDISM, "%SYSTEM-F-DEVNOTDISM, device not dismounted"},
|
||||
{SS$_DEVNOTMOUNT, "%SYSTEM-F-DEVNOTMOUNT, device is not mounted"},
|
||||
{SS$_DUPFILENAME, "%SYSTEM-W-DUPFILENAME, duplicate file name"},
|
||||
{SS$_DUPLICATE, "%SYSTEM-F-DUPLNAM, duplicate name"},
|
||||
{SS$_ENDOFFILE, "%SYSTEM-W-ENDOFFILE, end of file"},
|
||||
{SS$_FILELOCKED, "%SYSTEM-W-FILELOCKED, file is deaccess locked"},
|
||||
{SS$_FILESEQCHK, "%SYSTEM-W-FILESEQCHK, file identification sequence number check"},
|
||||
{SS$_ILLEFC, "%SYSTEM-F-ILLEFC, illegal event flag cluster"},
|
||||
{SS$_INSFMEM, "%SYSTEM-F-INSFMEM, insufficient dynamic memory"},
|
||||
{SS$_ITEMNOTFOUND, "%SYSTEM-W-ITEMNOTFOUND, requested item cannot be returned"},
|
||||
{SS$_IVCHAN, "%SYSTEM-F-IVCHAN, invalid I/O channel"},
|
||||
{SS$_IVDEVNAM, "%SYSTEM-F-IVDEVNAM, invalid device name"},
|
||||
{SS$_NOIOCHAN, "%SYSTEM-F-NOIOCHAN, no I/O channel available"},
|
||||
{SS$_NOMOREFILES, "%SYSTEM-W-NOMOREFILES, no more files"},
|
||||
{SS$_NORMAL, "%SYSTEM-S-NORMAL, normal successful completion"},
|
||||
{SS$_NOSUCHDEV, "%SYSTEM-W-NOSUCHDEV, no such device available"},
|
||||
{SS$_NOSUCHFILE, "%SYSTEM-W-NOSUCHFILE, no such file"},
|
||||
{SS$_NOSUCHVOL, "%SYSTEM-E-NOSUCHVOL, No such volume"},
|
||||
{SS$_NOTINSTALL, "%SYSTEM-F-NOTINSTALL, writable shareable images must be installed"},
|
||||
{SS$_PARITY, "%SYSTEM-F-PARITY, parity error"},
|
||||
{SS$_UNSUPVOLSET, "%SYSTEM-E-UNSUPVOLSET, Volume set not supported"},
|
||||
{SS$_WASCLR, "%SYSTEM-S-NORMAL, normal successful completion"},
|
||||
{SS$_WASSET, "%SYSTEM-S-WASSET, Event flag was set"},
|
||||
{SS$_WRITLCK, "%SYSTEM-F-WRITLCK, write lock error"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
const char *getmsg( unsigned int vmscode ) {
|
||||
char fmt[] = "%SYSTEM-E-NOSUCHMSG, Unknown message code %08X";
|
||||
static char buf[sizeof(fmt)+8+1];
|
||||
|
||||
for( mp = vms2text; mp->text; mp++ ) {
|
||||
if( vmscode == mp-> code ) {
|
||||
return mp->text;
|
||||
}
|
||||
}
|
||||
snprintf( buf, sizeof(buf), fmt, vmscode );
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
#endif
|
||||
*/
|
||||
6
extracters/ods2/sysmsg.h
Normal file
6
extracters/ods2/sysmsg.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef SYSMSG_H
|
||||
#define SYSMSG_H
|
||||
|
||||
const char *getmsg( unsigned int vmscode );
|
||||
|
||||
#endif
|
||||
@ -33,7 +33,7 @@ struct VCBDEV *rvn_to_dev(struct VCB *vcb,unsigned rvn);
|
||||
|
||||
unsigned update_freecount(struct VCBDEV *vcbdev,unsigned *retcount)
|
||||
{
|
||||
register unsigned sts;
|
||||
register unsigned sts = 1;
|
||||
register unsigned free_clusters = 0;
|
||||
register unsigned map_block, map_end = (vcbdev->max_cluster + 4095) / 4096 + 2;
|
||||
for (map_block = 2; map_block < map_end; ) {
|
||||
@ -270,7 +270,7 @@ unsigned update_findhead(struct VCBDEV *vcbdev,unsigned *rethead_no,
|
||||
*work_ptr |= 1 << bit_no;
|
||||
modify_flag = 1;
|
||||
if ((*headbuff)->fh2$w_checksum != 0 || (*headbuff)->fh2$w_fid.fid$w_num != 0 ||
|
||||
VMSLONG((*headbuff)->fh2$l_filechar) & FH2$M_MARKDEL == 0) {
|
||||
(VMSLONG((*headbuff)->fh2$l_filechar) & FH2$M_MARKDEL) == 0) {
|
||||
sts = deaccesschunk(*retvioc,0,0,0);
|
||||
} else {
|
||||
*rethead_no = head_no + 1;
|
||||
@ -302,6 +302,9 @@ unsigned update_addhead(struct VCB *vcb,char *filename,struct fiddef *back,
|
||||
struct IDENT *id;
|
||||
struct HEAD *head;
|
||||
struct VCBDEV *vcbdev = NULL;
|
||||
|
||||
if( rethead != NULL ) *rethead = NULL;
|
||||
|
||||
for (device = 0; device < vcb->devices; device++) {
|
||||
if (vcb->vcbdev[device].dev != NULL) {
|
||||
if (vcb->vcbdev[device].free_clusters > free_space) {
|
||||
@ -315,7 +318,7 @@ unsigned update_addhead(struct VCB *vcb,char *filename,struct fiddef *back,
|
||||
|
||||
sts = update_findhead(vcbdev,&head_no,vioc,&head,idxblk);
|
||||
if (!(sts & 1)) return sts;
|
||||
printf("Header %d index %d rvn %d\n",head_no,idxblk,rvn);
|
||||
printf("Header %d index %u rvn %u\n",head_no,*idxblk,rvn);
|
||||
fid->fid$w_num = head_no;
|
||||
fid->fid$w_seq = ++head->fh2$w_fid.fid$w_seq;
|
||||
if (fid->fid$w_seq == 0) fid->fid$w_seq = 1;
|
||||
@ -354,6 +357,7 @@ unsigned update_addhead(struct VCB *vcb,char *filename,struct fiddef *back,
|
||||
unsigned short check = checksum((vmsword *) head);
|
||||
head->fh2$w_checksum = VMSWORD(check);
|
||||
}
|
||||
if( rethead != NULL ) *rethead = head;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -424,7 +428,7 @@ unsigned update_extend(struct FCB *fcb,unsigned blocks,unsigned contig)
|
||||
sts = bitmap_search(vcbdev,&start_pos,&block_count);
|
||||
printf("Update_extend %d %d\n",start_pos,block_count);
|
||||
if (sts & 1) {
|
||||
if (block_count < 1 || contig && block_count * vcbdev->clustersize < blocks) {
|
||||
if (block_count < 1 || (contig && block_count * vcbdev->clustersize < blocks)) {
|
||||
sts = SS$_DEVICEFULL;
|
||||
} else {
|
||||
register unsigned short *mp;
|
||||
|
||||
10
extracters/ods2/version.h
Normal file
10
extracters/ods2/version.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
#ifdef DEBUG_BUILD
|
||||
#define MODULE_IDENT "Debug build"
|
||||
#else
|
||||
#define MODULE_IDENT "v1.4"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user