mirror of
https://github.com/open-simh/simtools.git
synced 2026-04-14 23:58:30 +00:00
Backlog of work since 2016
Too much to list all, but includes (in no particular order): - Cleanup for 64-bit builds, MSVC warnings. - Structured help - Help file compiler. - Supports volsets, writes/create work. - Support for I18n in messages, help. - Makefiles. - Initialize volume/volset - Command line editing/history Builds and works on Linux and Windows (VS). Not recently built or tested on other platforms, but not intentinonally broken.
This commit is contained in:
9
.gitignore
vendored
9
.gitignore
vendored
@@ -3,6 +3,13 @@
|
||||
*.bak
|
||||
*.o
|
||||
*.orig
|
||||
*.vhd
|
||||
*.iso
|
||||
pc/*
|
||||
*.simh_dsk
|
||||
*.swp
|
||||
*.exe
|
||||
*.lst
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
@@ -33,6 +40,8 @@ bld/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
\~AutoRecover.*
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
117
extracters/genmsg-en/genmsg-en.vcxproj
Executable file
117
extracters/genmsg-en/genmsg-en.vcxproj
Executable file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.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>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{50B74AC8-ED54-475B-BA94-6CAABA45F6A5}</ProjectGuid>
|
||||
<RootNamespace>genmsgen</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</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>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<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|x64'">
|
||||
<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>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
17
extracters/genmsg-en/genmsg-en.vcxproj.filters
Executable file
17
extracters/genmsg-en/genmsg-en.vcxproj.filters
Executable file
@@ -0,0 +1,17 @@
|
||||
<?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;hh;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>
|
||||
</Project>
|
||||
3
extracters/libvhd/.gitignore
vendored
Normal file
3
extracters/libvhd/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*.so
|
||||
*.so.*
|
||||
|
||||
@@ -1,200 +1,200 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifndef __BLKTAP2_UUID_H__
|
||||
#define __BLKTAP2_UUID_H__
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
typedef struct {
|
||||
uuid_t uuid;
|
||||
} blk_uuid_t;
|
||||
|
||||
static inline int blk_uuid_is_nil(blk_uuid_t *uuid)
|
||||
{
|
||||
return uuid_is_null(uuid->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_generate(blk_uuid_t *uuid)
|
||||
{
|
||||
uuid_generate(uuid->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_to_string(blk_uuid_t *uuid, char *out, size_t size)
|
||||
{
|
||||
(void) size;
|
||||
uuid_unparse(uuid->uuid, out);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_from_string(blk_uuid_t *uuid, const char *in)
|
||||
{
|
||||
uuid_parse(in, uuid->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_copy(blk_uuid_t *dst, blk_uuid_t *src)
|
||||
{
|
||||
uuid_copy(dst->uuid, src->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_clear(blk_uuid_t *uuid)
|
||||
{
|
||||
uuid_clear(uuid->uuid);
|
||||
}
|
||||
|
||||
static inline int blk_uuid_compare(blk_uuid_t *uuid1, blk_uuid_t *uuid2)
|
||||
{
|
||||
return uuid_compare(uuid1->uuid, uuid2->uuid);
|
||||
}
|
||||
|
||||
#elif defined(__NetBSD__)
|
||||
|
||||
#include <uuid.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef uuid_t blk_uuid_t;
|
||||
|
||||
static inline int blk_uuid_is_nil(blk_uuid_t *uuid)
|
||||
{
|
||||
uint32_t status;
|
||||
return uuid_is_nil((uuid_t *)uuid, &status);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_generate(blk_uuid_t *uuid)
|
||||
{
|
||||
uint32_t status;
|
||||
uuid_create((uuid_t *)uuid, &status);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_to_string(blk_uuid_t *uuid, char *out, size_t size)
|
||||
{
|
||||
uint32_t status;
|
||||
char *_out = NULL;
|
||||
uuid_to_string((uuid_t *)uuid, &_out, &status);
|
||||
strlcpy(out, _out, size);
|
||||
free(_out);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_from_string(blk_uuid_t *uuid, const char *in)
|
||||
{
|
||||
uint32_t status;
|
||||
uuid_from_string(in, (uuid_t *)uuid, &status);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_copy(blk_uuid_t *dst, blk_uuid_t *src)
|
||||
{
|
||||
memcpy((uuid_t *)dst, (uuid_t *)src, sizeof(uuid_t));
|
||||
}
|
||||
|
||||
static inline void blk_uuid_clear(blk_uuid_t *uuid)
|
||||
{
|
||||
memset((uuid_t *)uuid, 0, sizeof(uuid_t));
|
||||
}
|
||||
|
||||
static inline int blk_uuid_compare(blk_uuid_t *uuid1, blk_uuid_t *uuid2)
|
||||
{
|
||||
uint32_t status;
|
||||
return uuid_compare((uuid_t *)uuid1, (uuid_t *)uuid2, &status);
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#include <Rpc.h>
|
||||
typedef UUID blk_uuid_t;
|
||||
|
||||
static size_t strlcpy( char *dst, const char *src, size_t size ) {
|
||||
size_t srclen;
|
||||
|
||||
size--;
|
||||
srclen = strlen( src );
|
||||
|
||||
if( srclen > size )
|
||||
srclen = size;
|
||||
|
||||
memcpy( dst, src, srclen );
|
||||
dst[srclen] = '\0';
|
||||
|
||||
return (srclen);
|
||||
}
|
||||
static inline int blk_uuid_is_nil( blk_uuid_t *uuid )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
return UuidIsNil( (uuid_t *)uuid, &status );
|
||||
}
|
||||
|
||||
static inline void blk_uuid_generate( blk_uuid_t *uuid )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
status = UuidCreate( (uuid_t *)uuid );
|
||||
if( status == RPC_S_OK || status == RPC_S_UUID_LOCAL_ONLY )
|
||||
return;
|
||||
abort();
|
||||
}
|
||||
|
||||
static inline void blk_uuid_to_string( blk_uuid_t *uuid, char *out, size_t size )
|
||||
{
|
||||
RPC_CSTR _out = NULL;
|
||||
if( UuidToString( (uuid_t *)uuid, &_out ) != RPC_S_OK )
|
||||
return;
|
||||
strlcpy( out, (const char *)_out, size );
|
||||
RpcStringFree( &_out );
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void blk_uuid_from_string( blk_uuid_t *uuid, const char *in )
|
||||
{
|
||||
UuidFromString( (RPC_CSTR)in, (uuid_t *)uuid );
|
||||
}
|
||||
|
||||
static inline void blk_uuid_copy( blk_uuid_t *dst, blk_uuid_t *src )
|
||||
{
|
||||
memcpy( (uuid_t *)dst, (uuid_t *)src, sizeof( uuid_t ) );
|
||||
}
|
||||
|
||||
static inline void blk_uuid_clear( blk_uuid_t *uuid )
|
||||
{
|
||||
memset( (uuid_t *)uuid, 0, sizeof( uuid_t ) );
|
||||
}
|
||||
|
||||
static inline int blk_uuid_compare( blk_uuid_t *uuid1, blk_uuid_t *uuid2 )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
return UuidCompare( (uuid_t *)uuid1, (uuid_t *)uuid2, &status );
|
||||
}
|
||||
#else
|
||||
|
||||
#error "Please update blk_uuid.h for your OS"
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __BLKTAP2_UUID_H__ */
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifndef __BLKTAP2_UUID_H__
|
||||
#define __BLKTAP2_UUID_H__
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
typedef struct {
|
||||
uuid_t uuid;
|
||||
} blk_uuid_t;
|
||||
|
||||
static inline int blk_uuid_is_nil(blk_uuid_t *uuid)
|
||||
{
|
||||
return uuid_is_null(uuid->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_generate(blk_uuid_t *uuid)
|
||||
{
|
||||
uuid_generate(uuid->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_to_string(blk_uuid_t *uuid, char *out, size_t size)
|
||||
{
|
||||
(void) size;
|
||||
uuid_unparse(uuid->uuid, out);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_from_string(blk_uuid_t *uuid, const char *in)
|
||||
{
|
||||
uuid_parse(in, uuid->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_copy(blk_uuid_t *dst, blk_uuid_t *src)
|
||||
{
|
||||
uuid_copy(dst->uuid, src->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_clear(blk_uuid_t *uuid)
|
||||
{
|
||||
uuid_clear(uuid->uuid);
|
||||
}
|
||||
|
||||
static inline int blk_uuid_compare(blk_uuid_t *uuid1, blk_uuid_t *uuid2)
|
||||
{
|
||||
return uuid_compare(uuid1->uuid, uuid2->uuid);
|
||||
}
|
||||
|
||||
#elif defined(__NetBSD__)
|
||||
|
||||
#include <uuid.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef uuid_t blk_uuid_t;
|
||||
|
||||
static inline int blk_uuid_is_nil(blk_uuid_t *uuid)
|
||||
{
|
||||
uint32_t status;
|
||||
return uuid_is_nil((uuid_t *)uuid, &status);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_generate(blk_uuid_t *uuid)
|
||||
{
|
||||
uint32_t status;
|
||||
uuid_create((uuid_t *)uuid, &status);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_to_string(blk_uuid_t *uuid, char *out, size_t size)
|
||||
{
|
||||
uint32_t status;
|
||||
char *_out = NULL;
|
||||
uuid_to_string((uuid_t *)uuid, &_out, &status);
|
||||
strlcpy(out, _out, size);
|
||||
free(_out);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_from_string(blk_uuid_t *uuid, const char *in)
|
||||
{
|
||||
uint32_t status;
|
||||
uuid_from_string(in, (uuid_t *)uuid, &status);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_copy(blk_uuid_t *dst, blk_uuid_t *src)
|
||||
{
|
||||
memcpy((uuid_t *)dst, (uuid_t *)src, sizeof(uuid_t));
|
||||
}
|
||||
|
||||
static inline void blk_uuid_clear(blk_uuid_t *uuid)
|
||||
{
|
||||
memset((uuid_t *)uuid, 0, sizeof(uuid_t));
|
||||
}
|
||||
|
||||
static inline int blk_uuid_compare(blk_uuid_t *uuid1, blk_uuid_t *uuid2)
|
||||
{
|
||||
uint32_t status;
|
||||
return uuid_compare((uuid_t *)uuid1, (uuid_t *)uuid2, &status);
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#include <Rpc.h>
|
||||
typedef UUID blk_uuid_t;
|
||||
|
||||
static size_t strlcpy( char *dst, const char *src, size_t size ) {
|
||||
size_t srclen;
|
||||
|
||||
size--;
|
||||
srclen = strlen( src );
|
||||
|
||||
if( srclen > size )
|
||||
srclen = size;
|
||||
|
||||
memcpy( dst, src, srclen );
|
||||
dst[srclen] = '\0';
|
||||
|
||||
return (srclen);
|
||||
}
|
||||
static inline int blk_uuid_is_nil( blk_uuid_t *uuid )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
return UuidIsNil( (uuid_t *)uuid, &status );
|
||||
}
|
||||
|
||||
static inline void blk_uuid_generate( blk_uuid_t *uuid )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
status = UuidCreate( (uuid_t *)uuid );
|
||||
if( status == RPC_S_OK || status == RPC_S_UUID_LOCAL_ONLY )
|
||||
return;
|
||||
abort();
|
||||
}
|
||||
|
||||
static inline void blk_uuid_to_string( blk_uuid_t *uuid, char *out, size_t size )
|
||||
{
|
||||
RPC_CSTR _out = NULL;
|
||||
if( UuidToString( (uuid_t *)uuid, &_out ) != RPC_S_OK )
|
||||
return;
|
||||
strlcpy( out, (const char *)_out, size );
|
||||
RpcStringFree( &_out );
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void blk_uuid_from_string( blk_uuid_t *uuid, const char *in )
|
||||
{
|
||||
UuidFromString( (RPC_CSTR)in, (uuid_t *)uuid );
|
||||
}
|
||||
|
||||
static inline void blk_uuid_copy( blk_uuid_t *dst, blk_uuid_t *src )
|
||||
{
|
||||
memcpy( (uuid_t *)dst, (uuid_t *)src, sizeof( uuid_t ) );
|
||||
}
|
||||
|
||||
static inline void blk_uuid_clear( blk_uuid_t *uuid )
|
||||
{
|
||||
memset( (uuid_t *)uuid, 0, sizeof( uuid_t ) );
|
||||
}
|
||||
|
||||
static inline int blk_uuid_compare( blk_uuid_t *uuid1, blk_uuid_t *uuid2 )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
return UuidCompare( (uuid_t *)uuid1, (uuid_t *)uuid2, &status );
|
||||
}
|
||||
#else
|
||||
|
||||
#error "Please update blk_uuid.h for your OS"
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __BLKTAP2_UUID_H__ */
|
||||
|
||||
@@ -1,363 +1,363 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifndef _VHD_LIB_H_
|
||||
#define _VHD_LIB_H_
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
|
||||
#include <string.h>
|
||||
#if defined(__linux__)
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#elif defined(__NetBSD__)
|
||||
#include <sys/endian.h>
|
||||
#include <sys/bswap.h>
|
||||
#elif defined(_WIN32)
|
||||
#undef BYTE_ORDER
|
||||
#undef LITTLE_ENDIAN
|
||||
#define BYTE_ORDER 1234
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#define bswap_16(val) _byteswap_ushort(val)
|
||||
#define bswap_32(val) _byteswap_ulong(val)
|
||||
#define bswap_64(val) _byteswap_uint64(val)
|
||||
#endif
|
||||
|
||||
#include "blk_uuid.h"
|
||||
#include "vhd.h"
|
||||
|
||||
#ifndef O_LARGEFILE
|
||||
#define O_LARGEFILE 0
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(LIBVHD_DLL)
|
||||
#ifdef LIBVHD_EXPORTS
|
||||
#define LIBVHD_API __declspec(dllexport)
|
||||
#else
|
||||
#define LIBVHD_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define LIBVHD_API
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if defined(__linux__) || defined(_WIN32)
|
||||
#define BE16_IN(foo) (*(foo)) = bswap_16(*(foo))
|
||||
#define BE32_IN(foo) (*(foo)) = bswap_32(*(foo))
|
||||
#define BE64_IN(foo) (*(foo)) = bswap_64(*(foo))
|
||||
#define BE16_OUT(foo) (*(foo)) = bswap_16(*(foo))
|
||||
#define BE32_OUT(foo) (*(foo)) = bswap_32(*(foo))
|
||||
#define BE64_OUT(foo) (*(foo)) = bswap_64(*(foo))
|
||||
#elif defined(__NetBSD__)
|
||||
#define BE16_IN(foo) (*(foo)) = bswap16(*(foo))
|
||||
#define BE32_IN(foo) (*(foo)) = bswap32(*(foo))
|
||||
#define BE64_IN(foo) (*(foo)) = bswap64(*(foo))
|
||||
#define BE16_OUT(foo) (*(foo)) = bswap16(*(foo))
|
||||
#define BE32_OUT(foo) (*(foo)) = bswap32(*(foo))
|
||||
#define BE64_OUT(foo) (*(foo)) = bswap64(*(foo))
|
||||
#endif
|
||||
#else
|
||||
#define BE16_IN(foo)
|
||||
#define BE32_IN(foo)
|
||||
#define BE64_IN(foo)
|
||||
#define BE32_OUT(foo)
|
||||
#define BE32_OUT(foo)
|
||||
#define BE64_OUT(foo)
|
||||
#endif
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#define VHD_MAX_NAME_LEN 1024
|
||||
|
||||
#define VHD_BLOCK_SHIFT 21
|
||||
#define VHD_BLOCK_SIZE (1ULL << VHD_BLOCK_SHIFT)
|
||||
|
||||
#define UTF_16 "UTF-16"
|
||||
#define UTF_16LE "UTF-16LE"
|
||||
#define UTF_16BE "UTF-16BE"
|
||||
|
||||
#define VHD_OPEN_RDONLY 0x00001
|
||||
#define VHD_OPEN_RDWR 0x00002
|
||||
#define VHD_OPEN_FAST 0x00004
|
||||
#define VHD_OPEN_STRICT 0x00008
|
||||
#define VHD_OPEN_IGNORE_DISABLED 0x00010
|
||||
|
||||
#define VHD_FLAG_CREAT_PARENT_RAW 0x00001
|
||||
|
||||
#define vhd_flag_set(word, flag) ((word) |= (flag))
|
||||
#define vhd_flag_clear(word, flag) ((word) &= ~(flag))
|
||||
#define vhd_flag_test(word, flag) ((word) & (flag))
|
||||
|
||||
|
||||
#ifndef _WIN32x
|
||||
#define ENABLE_FAILURE_TESTING 1
|
||||
#endif
|
||||
#define FAIL_REPARENT_BEGIN 0
|
||||
#define FAIL_REPARENT_LOCATOR 1
|
||||
#define FAIL_REPARENT_END 2
|
||||
#define FAIL_RESIZE_BEGIN 3
|
||||
#define FAIL_RESIZE_DATA_MOVED 4
|
||||
#define FAIL_RESIZE_METADATA_MOVED 5
|
||||
#define FAIL_RESIZE_END 6
|
||||
#define NUM_FAIL_TESTS 7
|
||||
|
||||
#ifdef ENABLE_FAILURE_TESTING
|
||||
#define TEST_FAIL_AT(point) \
|
||||
if (TEST_FAIL[point]) { \
|
||||
printf("Failing at %s\n", ENV_VAR_FAIL[point]); exit(EINVAL); }
|
||||
#ifdef _WIN32
|
||||
#define TEST_FAIL_EXTERN_VARS \
|
||||
LIBVHD_API extern const char* ENV_VAR_FAIL[]; \
|
||||
LIBVHD_API extern int TEST_FAIL[];
|
||||
#else
|
||||
#define TEST_FAIL_EXTERN_VARS \
|
||||
extern const char* ENV_VAR_FAIL[]; \
|
||||
extern int TEST_FAIL[];
|
||||
#endif
|
||||
#else
|
||||
#define TEST_FAIL_AT(point)
|
||||
#define TEST_FAIL_EXTERN_VARS
|
||||
#endif /* ENABLE_FAILURE_TESTING */
|
||||
|
||||
|
||||
static const char VHD_POISON_COOKIE[] = "v_poison";
|
||||
|
||||
typedef struct hd_ftr vhd_footer_t;
|
||||
typedef struct dd_hdr vhd_header_t;
|
||||
typedef struct vhd_bat vhd_bat_t;
|
||||
typedef struct vhd_batmap vhd_batmap_t;
|
||||
typedef struct dd_batmap_hdr vhd_batmap_header_t;
|
||||
typedef struct prt_loc vhd_parent_locator_t;
|
||||
typedef struct vhd_context vhd_context_t;
|
||||
typedef uint32_t vhd_flag_creat_t;
|
||||
|
||||
struct vhd_bat {
|
||||
uint32_t spb;
|
||||
uint32_t entries;
|
||||
uint32_t *bat;
|
||||
};
|
||||
|
||||
struct vhd_batmap {
|
||||
vhd_batmap_header_t header;
|
||||
char *map;
|
||||
};
|
||||
|
||||
struct vhd_context {
|
||||
int fd;
|
||||
char *file;
|
||||
int oflags;
|
||||
int is_block;
|
||||
|
||||
uint32_t spb;
|
||||
uint32_t bm_secs;
|
||||
|
||||
vhd_header_t header;
|
||||
vhd_footer_t footer;
|
||||
vhd_bat_t bat;
|
||||
vhd_batmap_t batmap;
|
||||
};
|
||||
|
||||
static inline uint32_t
|
||||
secs_round_up(uint64_t bytes)
|
||||
{
|
||||
return (uint32_t)((bytes + (VHD_SECTOR_SIZE - 1)) >> VHD_SECTOR_SHIFT);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
secs_round_up_no_zero(uint64_t bytes)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = secs_round_up(bytes);
|
||||
return ( result? result : 1);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
vhd_sectors_to_bytes(uint64_t sectors)
|
||||
{
|
||||
return sectors << VHD_SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
vhd_bytes_padded(uint64_t bytes)
|
||||
{
|
||||
return vhd_sectors_to_bytes(secs_round_up_no_zero(bytes));
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_type_dynamic(vhd_context_t *ctx)
|
||||
{
|
||||
return (ctx->footer.type == HD_TYPE_DYNAMIC ||
|
||||
ctx->footer.type == HD_TYPE_DIFF);
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_creator_tapdisk(vhd_context_t *ctx)
|
||||
{
|
||||
return !strncmp(ctx->footer.crtr_app, "tap", 3);
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_disabled(vhd_context_t *ctx)
|
||||
{
|
||||
return (!memcmp(ctx->footer.cookie,
|
||||
VHD_POISON_COOKIE, sizeof(ctx->footer.cookie)));
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
vhd_parent_locator_size(vhd_parent_locator_t *loc)
|
||||
{
|
||||
/*
|
||||
* MICROSOFT_COMPAT
|
||||
* data_space *should* be in sectors,
|
||||
* but sometimes we find it in bytes
|
||||
*/
|
||||
if (loc->data_space < 512)
|
||||
return (size_t)vhd_sectors_to_bytes(loc->data_space);
|
||||
else if (loc->data_space % 512 == 0)
|
||||
return loc->data_space;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_parent_raw(vhd_context_t *ctx)
|
||||
{
|
||||
return blk_uuid_is_nil(&ctx->header.prt_uuid);
|
||||
}
|
||||
|
||||
LIBVHD_API void libvhd_set_log_level(int);
|
||||
|
||||
LIBVHD_API int vhd_test_file_fixed(const char *, int *);
|
||||
|
||||
LIBVHD_API uint32_t vhd_time(time_t time);
|
||||
LIBVHD_API size_t vhd_time_to_string(uint32_t timestamp, char *target);
|
||||
LIBVHD_API uint32_t vhd_chs(uint64_t size);
|
||||
|
||||
LIBVHD_API uint32_t vhd_checksum_footer(vhd_footer_t *);
|
||||
LIBVHD_API uint32_t vhd_checksum_header(vhd_header_t *);
|
||||
LIBVHD_API uint32_t vhd_checksum_batmap(vhd_batmap_t *);
|
||||
|
||||
LIBVHD_API void vhd_footer_in(vhd_footer_t *);
|
||||
LIBVHD_API void vhd_footer_out(vhd_footer_t *);
|
||||
LIBVHD_API void vhd_header_in(vhd_header_t *);
|
||||
LIBVHD_API void vhd_header_out(vhd_header_t *);
|
||||
LIBVHD_API void vhd_bat_in(vhd_bat_t *);
|
||||
LIBVHD_API void vhd_bat_out(vhd_bat_t *);
|
||||
LIBVHD_API void vhd_batmap_header_in(vhd_batmap_t *);
|
||||
LIBVHD_API void vhd_batmap_header_out(vhd_batmap_t *);
|
||||
|
||||
LIBVHD_API int vhd_validate_footer(vhd_footer_t *footer);
|
||||
LIBVHD_API int vhd_validate_header(vhd_header_t *header);
|
||||
LIBVHD_API int vhd_validate_batmap_header(vhd_batmap_t *batmap);
|
||||
LIBVHD_API int vhd_validate_batmap(vhd_batmap_t *batmap);
|
||||
LIBVHD_API int vhd_validate_platform_code(uint32_t code);
|
||||
|
||||
LIBVHD_API int vhd_open(vhd_context_t *, const char *file, int flags);
|
||||
LIBVHD_API void vhd_close(vhd_context_t *);
|
||||
LIBVHD_API int vhd_create(const char *name, uint64_t bytes, int type, vhd_flag_creat_t);
|
||||
/* vhd_snapshot: the bytes parameter is optional and can be 0 if the snapshot
|
||||
* is to have the same size as the (first non-empty) parent */
|
||||
LIBVHD_API int vhd_snapshot(const char *snapshot, uint64_t bytes, const char *parent,
|
||||
vhd_flag_creat_t);
|
||||
|
||||
LIBVHD_API int vhd_hidden(vhd_context_t *, int *);
|
||||
LIBVHD_API int vhd_chain_depth(vhd_context_t *, int *);
|
||||
|
||||
LIBVHD_API off_t vhd_position(vhd_context_t *);
|
||||
LIBVHD_API int vhd_seek(vhd_context_t *, off_t, int);
|
||||
LIBVHD_API int vhd_read(vhd_context_t *, void *, size_t);
|
||||
LIBVHD_API int vhd_write(vhd_context_t *, void *, size_t);
|
||||
|
||||
LIBVHD_API int vhd_offset(vhd_context_t *, uint32_t, uint32_t *);
|
||||
|
||||
LIBVHD_API int vhd_end_of_headers(vhd_context_t *ctx, off_t *off);
|
||||
LIBVHD_API int vhd_end_of_data(vhd_context_t *ctx, off_t *off);
|
||||
LIBVHD_API int vhd_batmap_header_offset(vhd_context_t *ctx, off_t *off);
|
||||
|
||||
LIBVHD_API int vhd_get_header(vhd_context_t *);
|
||||
LIBVHD_API int vhd_get_footer(vhd_context_t *);
|
||||
LIBVHD_API int vhd_get_bat(vhd_context_t *);
|
||||
LIBVHD_API int vhd_get_batmap(vhd_context_t *);
|
||||
|
||||
LIBVHD_API void vhd_put_header(vhd_context_t *);
|
||||
LIBVHD_API void vhd_put_footer(vhd_context_t *);
|
||||
LIBVHD_API void vhd_put_bat(vhd_context_t *);
|
||||
LIBVHD_API void vhd_put_batmap(vhd_context_t *);
|
||||
|
||||
LIBVHD_API int vhd_has_batmap(vhd_context_t *);
|
||||
LIBVHD_API int vhd_batmap_test(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
LIBVHD_API void vhd_batmap_set(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
LIBVHD_API void vhd_batmap_clear(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
|
||||
LIBVHD_API int vhd_get_phys_size(vhd_context_t *, off_t *);
|
||||
LIBVHD_API int vhd_set_phys_size(vhd_context_t *, off_t);
|
||||
|
||||
LIBVHD_API int vhd_bitmap_test(vhd_context_t *, char *, uint32_t);
|
||||
LIBVHD_API void vhd_bitmap_set(vhd_context_t *, char *, uint32_t);
|
||||
LIBVHD_API void vhd_bitmap_clear(vhd_context_t *, char *, uint32_t);
|
||||
|
||||
LIBVHD_API int vhd_parent_locator_count(vhd_context_t *);
|
||||
LIBVHD_API int vhd_parent_locator_get(vhd_context_t *, char **);
|
||||
LIBVHD_API int vhd_parent_locator_read(vhd_context_t *, vhd_parent_locator_t *, char **);
|
||||
LIBVHD_API int vhd_find_parent(vhd_context_t *, const char *, char **);
|
||||
LIBVHD_API int vhd_parent_locator_write_at(vhd_context_t *, const char *,
|
||||
off_t, uint32_t, size_t,
|
||||
vhd_parent_locator_t *);
|
||||
|
||||
LIBVHD_API int vhd_header_decode_parent(vhd_context_t *, vhd_header_t *, char **);
|
||||
LIBVHD_API int vhd_change_parent(vhd_context_t *, char *parent_path, int raw);
|
||||
|
||||
LIBVHD_API int vhd_read_footer(vhd_context_t *, vhd_footer_t *);
|
||||
LIBVHD_API int vhd_read_footer_at(vhd_context_t *, vhd_footer_t *, off_t);
|
||||
LIBVHD_API int vhd_read_footer_strict(vhd_context_t *, vhd_footer_t *);
|
||||
LIBVHD_API int vhd_read_header(vhd_context_t *, vhd_header_t *);
|
||||
LIBVHD_API int vhd_read_header_at(vhd_context_t *, vhd_header_t *, off_t);
|
||||
LIBVHD_API int vhd_read_bat(vhd_context_t *, vhd_bat_t *);
|
||||
LIBVHD_API int vhd_read_batmap(vhd_context_t *, vhd_batmap_t *);
|
||||
LIBVHD_API int vhd_read_bitmap(vhd_context_t *, uint32_t block, char **bufp);
|
||||
LIBVHD_API int vhd_read_block(vhd_context_t *, uint32_t block, char **bufp);
|
||||
|
||||
LIBVHD_API int vhd_write_footer(vhd_context_t *, vhd_footer_t *);
|
||||
LIBVHD_API int vhd_write_footer_at(vhd_context_t *, vhd_footer_t *, off_t);
|
||||
LIBVHD_API int vhd_write_header(vhd_context_t *, vhd_header_t *);
|
||||
LIBVHD_API int vhd_write_header_at(vhd_context_t *, vhd_header_t *, off_t);
|
||||
LIBVHD_API int vhd_write_bat(vhd_context_t *, vhd_bat_t *);
|
||||
LIBVHD_API int vhd_write_batmap(vhd_context_t *, vhd_batmap_t *);
|
||||
LIBVHD_API int vhd_write_bitmap(vhd_context_t *, uint32_t block, char *bitmap);
|
||||
LIBVHD_API int vhd_write_block(vhd_context_t *, uint32_t block, char *data);
|
||||
|
||||
LIBVHD_API int vhd_io_read(vhd_context_t *, char *, uint64_t, uint32_t);
|
||||
LIBVHD_API int vhd_io_write(vhd_context_t *, char *, uint64_t, uint32_t);
|
||||
|
||||
#endif
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifndef _VHD_LIB_H_
|
||||
#define _VHD_LIB_H_
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
|
||||
#include <string.h>
|
||||
#if defined(__linux__)
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#elif defined(__NetBSD__)
|
||||
#include <sys/endian.h>
|
||||
#include <sys/bswap.h>
|
||||
#elif defined(_WIN32)
|
||||
#undef BYTE_ORDER
|
||||
#undef LITTLE_ENDIAN
|
||||
#define BYTE_ORDER 1234
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#define bswap_16(val) _byteswap_ushort(val)
|
||||
#define bswap_32(val) _byteswap_ulong(val)
|
||||
#define bswap_64(val) _byteswap_uint64(val)
|
||||
#endif
|
||||
|
||||
#include "blk_uuid.h"
|
||||
#include "vhd.h"
|
||||
|
||||
#ifndef O_LARGEFILE
|
||||
#define O_LARGEFILE 0
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(LIBVHD_DLL)
|
||||
#ifdef LIBVHD_EXPORTS
|
||||
#define LIBVHD_API __declspec(dllexport)
|
||||
#else
|
||||
#define LIBVHD_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define LIBVHD_API
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if defined(__linux__) || defined(_WIN32)
|
||||
#define BE16_IN(foo) (*(foo)) = bswap_16(*(foo))
|
||||
#define BE32_IN(foo) (*(foo)) = bswap_32(*(foo))
|
||||
#define BE64_IN(foo) (*(foo)) = bswap_64(*(foo))
|
||||
#define BE16_OUT(foo) (*(foo)) = bswap_16(*(foo))
|
||||
#define BE32_OUT(foo) (*(foo)) = bswap_32(*(foo))
|
||||
#define BE64_OUT(foo) (*(foo)) = bswap_64(*(foo))
|
||||
#elif defined(__NetBSD__)
|
||||
#define BE16_IN(foo) (*(foo)) = bswap16(*(foo))
|
||||
#define BE32_IN(foo) (*(foo)) = bswap32(*(foo))
|
||||
#define BE64_IN(foo) (*(foo)) = bswap64(*(foo))
|
||||
#define BE16_OUT(foo) (*(foo)) = bswap16(*(foo))
|
||||
#define BE32_OUT(foo) (*(foo)) = bswap32(*(foo))
|
||||
#define BE64_OUT(foo) (*(foo)) = bswap64(*(foo))
|
||||
#endif
|
||||
#else
|
||||
#define BE16_IN(foo)
|
||||
#define BE32_IN(foo)
|
||||
#define BE64_IN(foo)
|
||||
#define BE32_OUT(foo)
|
||||
#define BE32_OUT(foo)
|
||||
#define BE64_OUT(foo)
|
||||
#endif
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#define VHD_MAX_NAME_LEN 1024
|
||||
|
||||
#define VHD_BLOCK_SHIFT 21
|
||||
#define VHD_BLOCK_SIZE (1ULL << VHD_BLOCK_SHIFT)
|
||||
|
||||
#define UTF_16 "UTF-16"
|
||||
#define UTF_16LE "UTF-16LE"
|
||||
#define UTF_16BE "UTF-16BE"
|
||||
|
||||
#define VHD_OPEN_RDONLY 0x00001
|
||||
#define VHD_OPEN_RDWR 0x00002
|
||||
#define VHD_OPEN_FAST 0x00004
|
||||
#define VHD_OPEN_STRICT 0x00008
|
||||
#define VHD_OPEN_IGNORE_DISABLED 0x00010
|
||||
|
||||
#define VHD_FLAG_CREAT_PARENT_RAW 0x00001
|
||||
|
||||
#define vhd_flag_set(word, flag) ((word) |= (flag))
|
||||
#define vhd_flag_clear(word, flag) ((word) &= ~(flag))
|
||||
#define vhd_flag_test(word, flag) ((word) & (flag))
|
||||
|
||||
|
||||
#ifndef _WIN32x
|
||||
#define ENABLE_FAILURE_TESTING 1
|
||||
#endif
|
||||
#define FAIL_REPARENT_BEGIN 0
|
||||
#define FAIL_REPARENT_LOCATOR 1
|
||||
#define FAIL_REPARENT_END 2
|
||||
#define FAIL_RESIZE_BEGIN 3
|
||||
#define FAIL_RESIZE_DATA_MOVED 4
|
||||
#define FAIL_RESIZE_METADATA_MOVED 5
|
||||
#define FAIL_RESIZE_END 6
|
||||
#define NUM_FAIL_TESTS 7
|
||||
|
||||
#ifdef ENABLE_FAILURE_TESTING
|
||||
#define TEST_FAIL_AT(point) \
|
||||
if (TEST_FAIL[point]) { \
|
||||
printf("Failing at %s\n", ENV_VAR_FAIL[point]); exit(EINVAL); }
|
||||
#ifdef _WIN32
|
||||
#define TEST_FAIL_EXTERN_VARS \
|
||||
LIBVHD_API extern const char* ENV_VAR_FAIL[]; \
|
||||
LIBVHD_API extern int TEST_FAIL[];
|
||||
#else
|
||||
#define TEST_FAIL_EXTERN_VARS \
|
||||
extern const char* ENV_VAR_FAIL[]; \
|
||||
extern int TEST_FAIL[];
|
||||
#endif
|
||||
#else
|
||||
#define TEST_FAIL_AT(point)
|
||||
#define TEST_FAIL_EXTERN_VARS
|
||||
#endif /* ENABLE_FAILURE_TESTING */
|
||||
|
||||
|
||||
static const char VHD_POISON_COOKIE[] = "v_poison";
|
||||
|
||||
typedef struct hd_ftr vhd_footer_t;
|
||||
typedef struct dd_hdr vhd_header_t;
|
||||
typedef struct vhd_bat vhd_bat_t;
|
||||
typedef struct vhd_batmap vhd_batmap_t;
|
||||
typedef struct dd_batmap_hdr vhd_batmap_header_t;
|
||||
typedef struct prt_loc vhd_parent_locator_t;
|
||||
typedef struct vhd_context vhd_context_t;
|
||||
typedef uint32_t vhd_flag_creat_t;
|
||||
|
||||
struct vhd_bat {
|
||||
uint32_t spb;
|
||||
uint32_t entries;
|
||||
uint32_t *bat;
|
||||
};
|
||||
|
||||
struct vhd_batmap {
|
||||
vhd_batmap_header_t header;
|
||||
char *map;
|
||||
};
|
||||
|
||||
struct vhd_context {
|
||||
int fd;
|
||||
char *file;
|
||||
int oflags;
|
||||
int is_block;
|
||||
|
||||
uint32_t spb;
|
||||
uint32_t bm_secs;
|
||||
|
||||
vhd_header_t header;
|
||||
vhd_footer_t footer;
|
||||
vhd_bat_t bat;
|
||||
vhd_batmap_t batmap;
|
||||
};
|
||||
|
||||
static inline uint32_t
|
||||
secs_round_up(uint64_t bytes)
|
||||
{
|
||||
return (uint32_t)((bytes + (VHD_SECTOR_SIZE - 1)) >> VHD_SECTOR_SHIFT);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
secs_round_up_no_zero(uint64_t bytes)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = secs_round_up(bytes);
|
||||
return ( result? result : 1);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
vhd_sectors_to_bytes(uint64_t sectors)
|
||||
{
|
||||
return sectors << VHD_SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
vhd_bytes_padded(uint64_t bytes)
|
||||
{
|
||||
return vhd_sectors_to_bytes(secs_round_up_no_zero(bytes));
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_type_dynamic(vhd_context_t *ctx)
|
||||
{
|
||||
return (ctx->footer.type == HD_TYPE_DYNAMIC ||
|
||||
ctx->footer.type == HD_TYPE_DIFF);
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_creator_tapdisk(vhd_context_t *ctx)
|
||||
{
|
||||
return !strncmp(ctx->footer.crtr_app, "tap", 3);
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_disabled(vhd_context_t *ctx)
|
||||
{
|
||||
return (!memcmp(ctx->footer.cookie,
|
||||
VHD_POISON_COOKIE, sizeof(ctx->footer.cookie)));
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
vhd_parent_locator_size(vhd_parent_locator_t *loc)
|
||||
{
|
||||
/*
|
||||
* MICROSOFT_COMPAT
|
||||
* data_space *should* be in sectors,
|
||||
* but sometimes we find it in bytes
|
||||
*/
|
||||
if (loc->data_space < 512)
|
||||
return (size_t)vhd_sectors_to_bytes(loc->data_space);
|
||||
else if (loc->data_space % 512 == 0)
|
||||
return loc->data_space;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_parent_raw(vhd_context_t *ctx)
|
||||
{
|
||||
return blk_uuid_is_nil(&ctx->header.prt_uuid);
|
||||
}
|
||||
|
||||
LIBVHD_API void libvhd_set_log_level(int);
|
||||
|
||||
LIBVHD_API int vhd_test_file_fixed(const char *, int *);
|
||||
|
||||
LIBVHD_API uint32_t vhd_time(time_t time);
|
||||
LIBVHD_API size_t vhd_time_to_string(uint32_t timestamp, char *target);
|
||||
LIBVHD_API uint32_t vhd_chs(uint64_t size);
|
||||
|
||||
LIBVHD_API uint32_t vhd_checksum_footer(vhd_footer_t *);
|
||||
LIBVHD_API uint32_t vhd_checksum_header(vhd_header_t *);
|
||||
LIBVHD_API uint32_t vhd_checksum_batmap(vhd_batmap_t *);
|
||||
|
||||
LIBVHD_API void vhd_footer_in(vhd_footer_t *);
|
||||
LIBVHD_API void vhd_footer_out(vhd_footer_t *);
|
||||
LIBVHD_API void vhd_header_in(vhd_header_t *);
|
||||
LIBVHD_API void vhd_header_out(vhd_header_t *);
|
||||
LIBVHD_API void vhd_bat_in(vhd_bat_t *);
|
||||
LIBVHD_API void vhd_bat_out(vhd_bat_t *);
|
||||
LIBVHD_API void vhd_batmap_header_in(vhd_batmap_t *);
|
||||
LIBVHD_API void vhd_batmap_header_out(vhd_batmap_t *);
|
||||
|
||||
LIBVHD_API int vhd_validate_footer(vhd_footer_t *footer);
|
||||
LIBVHD_API int vhd_validate_header(vhd_header_t *header);
|
||||
LIBVHD_API int vhd_validate_batmap_header(vhd_batmap_t *batmap);
|
||||
LIBVHD_API int vhd_validate_batmap(vhd_batmap_t *batmap);
|
||||
LIBVHD_API int vhd_validate_platform_code(uint32_t code);
|
||||
|
||||
LIBVHD_API int vhd_open(vhd_context_t *, const char *file, int flags);
|
||||
LIBVHD_API void vhd_close(vhd_context_t *);
|
||||
LIBVHD_API int vhd_create(const char *name, uint64_t bytes, int type, vhd_flag_creat_t);
|
||||
/* vhd_snapshot: the bytes parameter is optional and can be 0 if the snapshot
|
||||
* is to have the same size as the (first non-empty) parent */
|
||||
LIBVHD_API int vhd_snapshot(const char *snapshot, uint64_t bytes, const char *parent,
|
||||
vhd_flag_creat_t);
|
||||
|
||||
LIBVHD_API int vhd_hidden(vhd_context_t *, int *);
|
||||
LIBVHD_API int vhd_chain_depth(vhd_context_t *, int *);
|
||||
|
||||
LIBVHD_API off_t vhd_position(vhd_context_t *);
|
||||
LIBVHD_API int vhd_seek(vhd_context_t *, off_t, int);
|
||||
LIBVHD_API int vhd_read(vhd_context_t *, void *, size_t);
|
||||
LIBVHD_API int vhd_write(vhd_context_t *, void *, size_t);
|
||||
|
||||
LIBVHD_API int vhd_offset(vhd_context_t *, uint32_t, uint32_t *);
|
||||
|
||||
LIBVHD_API int vhd_end_of_headers(vhd_context_t *ctx, off_t *off);
|
||||
LIBVHD_API int vhd_end_of_data(vhd_context_t *ctx, off_t *off);
|
||||
LIBVHD_API int vhd_batmap_header_offset(vhd_context_t *ctx, off_t *off);
|
||||
|
||||
LIBVHD_API int vhd_get_header(vhd_context_t *);
|
||||
LIBVHD_API int vhd_get_footer(vhd_context_t *);
|
||||
LIBVHD_API int vhd_get_bat(vhd_context_t *);
|
||||
LIBVHD_API int vhd_get_batmap(vhd_context_t *);
|
||||
|
||||
LIBVHD_API void vhd_put_header(vhd_context_t *);
|
||||
LIBVHD_API void vhd_put_footer(vhd_context_t *);
|
||||
LIBVHD_API void vhd_put_bat(vhd_context_t *);
|
||||
LIBVHD_API void vhd_put_batmap(vhd_context_t *);
|
||||
|
||||
LIBVHD_API int vhd_has_batmap(vhd_context_t *);
|
||||
LIBVHD_API int vhd_batmap_test(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
LIBVHD_API void vhd_batmap_set(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
LIBVHD_API void vhd_batmap_clear(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
|
||||
LIBVHD_API int vhd_get_phys_size(vhd_context_t *, off_t *);
|
||||
LIBVHD_API int vhd_set_phys_size(vhd_context_t *, off_t);
|
||||
|
||||
LIBVHD_API int vhd_bitmap_test(vhd_context_t *, char *, uint32_t);
|
||||
LIBVHD_API void vhd_bitmap_set(vhd_context_t *, char *, uint32_t);
|
||||
LIBVHD_API void vhd_bitmap_clear(vhd_context_t *, char *, uint32_t);
|
||||
|
||||
LIBVHD_API int vhd_parent_locator_count(vhd_context_t *);
|
||||
LIBVHD_API int vhd_parent_locator_get(vhd_context_t *, char **);
|
||||
LIBVHD_API int vhd_parent_locator_read(vhd_context_t *, vhd_parent_locator_t *, char **);
|
||||
LIBVHD_API int vhd_find_parent(vhd_context_t *, const char *, char **);
|
||||
LIBVHD_API int vhd_parent_locator_write_at(vhd_context_t *, const char *,
|
||||
off_t, uint32_t, size_t,
|
||||
vhd_parent_locator_t *);
|
||||
|
||||
LIBVHD_API int vhd_header_decode_parent(vhd_context_t *, vhd_header_t *, char **);
|
||||
LIBVHD_API int vhd_change_parent(vhd_context_t *, char *parent_path, int raw);
|
||||
|
||||
LIBVHD_API int vhd_read_footer(vhd_context_t *, vhd_footer_t *);
|
||||
LIBVHD_API int vhd_read_footer_at(vhd_context_t *, vhd_footer_t *, off_t);
|
||||
LIBVHD_API int vhd_read_footer_strict(vhd_context_t *, vhd_footer_t *);
|
||||
LIBVHD_API int vhd_read_header(vhd_context_t *, vhd_header_t *);
|
||||
LIBVHD_API int vhd_read_header_at(vhd_context_t *, vhd_header_t *, off_t);
|
||||
LIBVHD_API int vhd_read_bat(vhd_context_t *, vhd_bat_t *);
|
||||
LIBVHD_API int vhd_read_batmap(vhd_context_t *, vhd_batmap_t *);
|
||||
LIBVHD_API int vhd_read_bitmap(vhd_context_t *, uint32_t block, char **bufp);
|
||||
LIBVHD_API int vhd_read_block(vhd_context_t *, uint32_t block, char **bufp);
|
||||
|
||||
LIBVHD_API int vhd_write_footer(vhd_context_t *, vhd_footer_t *);
|
||||
LIBVHD_API int vhd_write_footer_at(vhd_context_t *, vhd_footer_t *, off_t);
|
||||
LIBVHD_API int vhd_write_header(vhd_context_t *, vhd_header_t *);
|
||||
LIBVHD_API int vhd_write_header_at(vhd_context_t *, vhd_header_t *, off_t);
|
||||
LIBVHD_API int vhd_write_bat(vhd_context_t *, vhd_bat_t *);
|
||||
LIBVHD_API int vhd_write_batmap(vhd_context_t *, vhd_batmap_t *);
|
||||
LIBVHD_API int vhd_write_bitmap(vhd_context_t *, uint32_t block, char *bitmap);
|
||||
LIBVHD_API int vhd_write_block(vhd_context_t *, uint32_t block, char *data);
|
||||
|
||||
LIBVHD_API int vhd_io_read(vhd_context_t *, char *, uint64_t, uint32_t);
|
||||
LIBVHD_API int vhd_io_write(vhd_context_t *, char *, uint64_t, uint32_t);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifndef _RELATIVE_PATH_H_
|
||||
#define _RELATIVE_PATH_H_
|
||||
|
||||
#define MAX_NAME_LEN 1000
|
||||
|
||||
#if defined(_WIN32) && defined(LIBVHD_DLL)
|
||||
#ifdef LIBVHD_EXPORTS
|
||||
#define LIBVHD_API __declspec(dllexport)
|
||||
#else
|
||||
#define LIBVHD_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define LIBVHD_API
|
||||
#endif
|
||||
|
||||
/*
|
||||
* returns a relative path from @src to @dest
|
||||
* result should be freed
|
||||
*/
|
||||
LIBVHD_API char *relative_path_to(char *src, char *dest, int *err);
|
||||
|
||||
#ifdef _WIN32
|
||||
LIBVHD_API char *realpath( const char *path, char *resolved );
|
||||
LIBVHD_API int asprintf( char **result, const char *fmt, ... );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifndef _RELATIVE_PATH_H_
|
||||
#define _RELATIVE_PATH_H_
|
||||
|
||||
#define MAX_NAME_LEN 1000
|
||||
|
||||
#if defined(_WIN32) && defined(LIBVHD_DLL)
|
||||
#ifdef LIBVHD_EXPORTS
|
||||
#define LIBVHD_API __declspec(dllexport)
|
||||
#else
|
||||
#define LIBVHD_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define LIBVHD_API
|
||||
#endif
|
||||
|
||||
/*
|
||||
* returns a relative path from @src to @dest
|
||||
* result should be freed
|
||||
*/
|
||||
LIBVHD_API char *relative_path_to(char *src, char *dest, int *err);
|
||||
|
||||
#ifdef _WIN32
|
||||
LIBVHD_API char *realpath( const char *path, char *resolved );
|
||||
LIBVHD_API int asprintf( char **result, const char *fmt, ... );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,228 +1,228 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
#ifndef __VHD_H__
|
||||
#define __VHD_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
/* #define DEBUG 1 */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* General definitions. */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#define VHD_SECTOR_SIZE 512
|
||||
#define VHD_SECTOR_SHIFT 9
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* This is the generic disk footer, used by all disks. */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct hd_ftr {
|
||||
char cookie[8]; /* Identifies original creator of the disk */
|
||||
u32 features; /* Feature Support -- see below */
|
||||
u32 ff_version; /* (major,minor) version of disk file */
|
||||
u64 data_offset; /* Abs. offset from SOF to next structure */
|
||||
u32 timestamp; /* Creation time. secs since 1/1/2000GMT */
|
||||
char crtr_app[4]; /* Creator application */
|
||||
u32 crtr_ver; /* Creator version (major,minor) */
|
||||
u32 crtr_os; /* Creator host OS */
|
||||
u64 orig_size; /* Size at creation (bytes) */
|
||||
u64 curr_size; /* Current size of disk (bytes) */
|
||||
u32 geometry; /* Disk geometry */
|
||||
u32 type; /* Disk type */
|
||||
u32 checksum; /* 1's comp sum of this struct. */
|
||||
blk_uuid_t uuid; /* Unique disk ID, used for naming parents */
|
||||
char saved; /* one-bit -- is this disk/VM in a saved state? */
|
||||
char hidden; /* tapdisk-specific field: is this vdi hidden? */
|
||||
char reserved[426]; /* padding */
|
||||
};
|
||||
|
||||
/* VHD cookie string. */
|
||||
static const char HD_COOKIE[9] = "conectix";
|
||||
|
||||
/* Feature fields in hd_ftr */
|
||||
#define HD_NO_FEATURES 0x00000000
|
||||
#define HD_TEMPORARY 0x00000001 /* disk can be deleted on shutdown */
|
||||
#define HD_RESERVED 0x00000002 /* NOTE: must always be set */
|
||||
|
||||
/* Version field in hd_ftr */
|
||||
#define HD_FF_VERSION 0x00010000
|
||||
|
||||
/* Known creator OS type fields in hd_ftr.crtr_os */
|
||||
#define HD_CR_OS_WINDOWS 0x5769326B /* (Wi2k) */
|
||||
#define HD_CR_OS_MACINTOSH 0x4D616320 /* (Mac ) */
|
||||
#define HD_CR_OS_UNIX 0x556E6978 /* (Unix) */
|
||||
#define HD_CR_OS_VMS 0x4F564D53 /* (OVMS) */
|
||||
/*
|
||||
* version 0.1: little endian bitmaps
|
||||
* version 1.1: big endian bitmaps; batmap
|
||||
* version 1.2: libvhd
|
||||
* version 1.3: batmap version bump to 1.2
|
||||
*/
|
||||
#define VHD_VERSION(major, minor) (((major) << 16) | ((minor) & 0x0000FFFF))
|
||||
#define VHD_CURRENT_VERSION VHD_VERSION(1, 3)
|
||||
|
||||
/* Disk geometry accessor macros. */
|
||||
/* Geometry is a triple of (cylinders (2 bytes), tracks (1 byte), and
|
||||
* secotrs-per-track (1 byte))
|
||||
*/
|
||||
#define GEOM_GET_CYLS(_g) (((_g) >> 16) & 0xffff)
|
||||
#define GEOM_GET_HEADS(_g) (((_g) >> 8) & 0xff)
|
||||
#define GEOM_GET_SPT(_g) ((_g) & 0xff)
|
||||
|
||||
#define GEOM_ENCODE(_c, _h, _s) (((_c) << 16) | ((_h) << 8) | (_s))
|
||||
|
||||
/* type field in hd_ftr */
|
||||
#define HD_TYPE_NONE 0
|
||||
#define HD_TYPE_FIXED 2 /* fixed-allocation disk */
|
||||
#define HD_TYPE_DYNAMIC 3 /* dynamic disk */
|
||||
#define HD_TYPE_DIFF 4 /* differencing disk */
|
||||
|
||||
/* String table for hd.type */
|
||||
#ifdef __GNUC__
|
||||
__attribute__((unused))
|
||||
#endif
|
||||
static const char *HD_TYPE_STR[7] = {
|
||||
"None", /* 0 */
|
||||
"Reserved (deprecated)", /* 1 */
|
||||
"Fixed hard disk", /* 2 */
|
||||
"Dynamic hard disk", /* 3 */
|
||||
"Differencing hard disk", /* 4 */
|
||||
"Reserved (deprecated)", /* 5 */
|
||||
"Reserved (deprecated)" /* 6 */
|
||||
};
|
||||
|
||||
#define HD_TYPE_MAX 6
|
||||
|
||||
struct prt_loc {
|
||||
u32 code; /* Platform code -- see defines below. */
|
||||
u32 data_space; /* Number of 512-byte sectors to store locator */
|
||||
u32 data_len; /* Actual length of parent locator in bytes */
|
||||
u32 res; /* Must be zero */
|
||||
u64 data_offset; /* Absolute offset of locator data (bytes) */
|
||||
};
|
||||
|
||||
/* Platform Codes */
|
||||
#define PLAT_CODE_NONE 0x0
|
||||
#define PLAT_CODE_WI2R 0x57693272 /* deprecated */
|
||||
#define PLAT_CODE_WI2K 0x5769326B /* deprecated */
|
||||
#define PLAT_CODE_W2RU 0x57327275 /* Windows relative path (UTF-16) */
|
||||
#define PLAT_CODE_W2KU 0x57326B75 /* Windows absolute path (UTF-16) */
|
||||
#define PLAT_CODE_MAC 0x4D616320 /* MacOS alias stored as a blob. */
|
||||
#define PLAT_CODE_MACX 0x4D616358 /* File URL (UTF-8), see RFC 2396. */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* This is the dynamic disk header. */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct dd_hdr {
|
||||
char cookie[8]; /* Should contain "cxsparse" */
|
||||
u64 data_offset; /* Byte offset of next record. (Unused) 0xffs */
|
||||
u64 table_offset; /* Absolute offset to the BAT. */
|
||||
u32 hdr_ver; /* Version of the dd_hdr (major,minor) */
|
||||
u32 max_bat_size; /* Maximum number of entries in the BAT */
|
||||
u32 block_size; /* Block size in bytes. Must be power of 2. */
|
||||
u32 checksum; /* Header checksum. 1's comp of all fields. */
|
||||
blk_uuid_t prt_uuid; /* ID of the parent disk. */
|
||||
u32 prt_ts; /* Modification time of the parent disk */
|
||||
u32 res1; /* Reserved. */
|
||||
char prt_name[512]; /* Parent unicode name. */
|
||||
struct prt_loc loc[8]; /* Parent locator entries. */
|
||||
char res2[256]; /* Reserved. */
|
||||
};
|
||||
|
||||
/* VHD cookie string. */
|
||||
static const char DD_COOKIE[9] = "cxsparse";
|
||||
|
||||
/* Version field in hd_ftr */
|
||||
#define DD_VERSION 0x00010000
|
||||
|
||||
/* Default blocksize is 2 meg. */
|
||||
#define DD_BLOCKSIZE_DEFAULT 0x00200000
|
||||
|
||||
#define DD_BLK_UNUSED 0xFFFFFFFF
|
||||
|
||||
struct dd_batmap_hdr {
|
||||
char cookie[8]; /* should contain "tdbatmap" */
|
||||
u64 batmap_offset; /* byte offset to batmap */
|
||||
u32 batmap_size; /* batmap size in sectors */
|
||||
u32 batmap_version; /* version of batmap */
|
||||
u32 checksum; /* batmap checksum -- 1's complement of batmap */
|
||||
};
|
||||
|
||||
static const char VHD_BATMAP_COOKIE[9] = "tdbatmap";
|
||||
|
||||
/*
|
||||
* version 1.1: signed char checksum
|
||||
*/
|
||||
#define VHD_BATMAP_VERSION(major, minor) (((major) << 16) | ((minor) & 0x0000FFFF))
|
||||
#define VHD_BATMAP_CURRENT_VERSION VHD_BATMAP_VERSION(1, 2)
|
||||
|
||||
/* Layout of a dynamic disk:
|
||||
*
|
||||
* +-------------------------------------------------+
|
||||
* | Mirror image of HD footer (hd_ftr) (512 bytes) |
|
||||
* +-------------------------------------------------+
|
||||
* | Sparse drive header (dd_hdr) (1024 bytes) |
|
||||
* +-------------------------------------------------+
|
||||
* | BAT (Block allocation table) |
|
||||
* | - Array of absolute sector offsets into the |
|
||||
* | file (u32). |
|
||||
* | - Rounded up to a sector boundary. |
|
||||
* | - Unused entries are marked as 0xFFFFFFFF |
|
||||
* | - max entries in dd_hdr->max_bat_size |
|
||||
* +-------------------------------------------------+
|
||||
* | Data Block 0 |
|
||||
* | Bitmap (padded to 512 byte sector boundary) |
|
||||
* | - each bit indicates whether the associated |
|
||||
* | sector within this block is used. |
|
||||
* | Data |
|
||||
* | - power-of-two multiple of sectors. |
|
||||
* | - default 2MB (4096 * 512) |
|
||||
* | - Any entries with zero in bitmap should be |
|
||||
* | zero on disk |
|
||||
* +-------------------------------------------------+
|
||||
* | Data Block 1 |
|
||||
* +-------------------------------------------------+
|
||||
* | ... |
|
||||
* +-------------------------------------------------+
|
||||
* | Data Block n |
|
||||
* +-------------------------------------------------+
|
||||
* | HD Footer (511 bytes) |
|
||||
* +-------------------------------------------------+
|
||||
*/
|
||||
|
||||
#endif
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
#ifndef __VHD_H__
|
||||
#define __VHD_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
/* #define DEBUG 1 */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* General definitions. */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#define VHD_SECTOR_SIZE 512
|
||||
#define VHD_SECTOR_SHIFT 9
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* This is the generic disk footer, used by all disks. */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct hd_ftr {
|
||||
char cookie[8]; /* Identifies original creator of the disk */
|
||||
u32 features; /* Feature Support -- see below */
|
||||
u32 ff_version; /* (major,minor) version of disk file */
|
||||
u64 data_offset; /* Abs. offset from SOF to next structure */
|
||||
u32 timestamp; /* Creation time. secs since 1/1/2000GMT */
|
||||
char crtr_app[4]; /* Creator application */
|
||||
u32 crtr_ver; /* Creator version (major,minor) */
|
||||
u32 crtr_os; /* Creator host OS */
|
||||
u64 orig_size; /* Size at creation (bytes) */
|
||||
u64 curr_size; /* Current size of disk (bytes) */
|
||||
u32 geometry; /* Disk geometry */
|
||||
u32 type; /* Disk type */
|
||||
u32 checksum; /* 1's comp sum of this struct. */
|
||||
blk_uuid_t uuid; /* Unique disk ID, used for naming parents */
|
||||
char saved; /* one-bit -- is this disk/VM in a saved state? */
|
||||
char hidden; /* tapdisk-specific field: is this vdi hidden? */
|
||||
char reserved[426]; /* padding */
|
||||
};
|
||||
|
||||
/* VHD cookie string. */
|
||||
static const char HD_COOKIE[9] = "conectix";
|
||||
|
||||
/* Feature fields in hd_ftr */
|
||||
#define HD_NO_FEATURES 0x00000000
|
||||
#define HD_TEMPORARY 0x00000001 /* disk can be deleted on shutdown */
|
||||
#define HD_RESERVED 0x00000002 /* NOTE: must always be set */
|
||||
|
||||
/* Version field in hd_ftr */
|
||||
#define HD_FF_VERSION 0x00010000
|
||||
|
||||
/* Known creator OS type fields in hd_ftr.crtr_os */
|
||||
#define HD_CR_OS_WINDOWS 0x5769326B /* (Wi2k) */
|
||||
#define HD_CR_OS_MACINTOSH 0x4D616320 /* (Mac ) */
|
||||
#define HD_CR_OS_UNIX 0x556E6978 /* (Unix) */
|
||||
#define HD_CR_OS_VMS 0x4F564D53 /* (OVMS) */
|
||||
/*
|
||||
* version 0.1: little endian bitmaps
|
||||
* version 1.1: big endian bitmaps; batmap
|
||||
* version 1.2: libvhd
|
||||
* version 1.3: batmap version bump to 1.2
|
||||
*/
|
||||
#define VHD_VERSION(major, minor) (((major) << 16) | ((minor) & 0x0000FFFF))
|
||||
#define VHD_CURRENT_VERSION VHD_VERSION(1, 3)
|
||||
|
||||
/* Disk geometry accessor macros. */
|
||||
/* Geometry is a triple of (cylinders (2 bytes), tracks (1 byte), and
|
||||
* secotrs-per-track (1 byte))
|
||||
*/
|
||||
#define GEOM_GET_CYLS(_g) (((_g) >> 16) & 0xffff)
|
||||
#define GEOM_GET_HEADS(_g) (((_g) >> 8) & 0xff)
|
||||
#define GEOM_GET_SPT(_g) ((_g) & 0xff)
|
||||
|
||||
#define GEOM_ENCODE(_c, _h, _s) (((_c) << 16) | ((_h) << 8) | (_s))
|
||||
|
||||
/* type field in hd_ftr */
|
||||
#define HD_TYPE_NONE 0
|
||||
#define HD_TYPE_FIXED 2 /* fixed-allocation disk */
|
||||
#define HD_TYPE_DYNAMIC 3 /* dynamic disk */
|
||||
#define HD_TYPE_DIFF 4 /* differencing disk */
|
||||
|
||||
/* String table for hd.type */
|
||||
#ifdef __GNUC__
|
||||
__attribute__((unused))
|
||||
#endif
|
||||
static const char *HD_TYPE_STR[7] = {
|
||||
"None", /* 0 */
|
||||
"Reserved (deprecated)", /* 1 */
|
||||
"Fixed hard disk", /* 2 */
|
||||
"Dynamic hard disk", /* 3 */
|
||||
"Differencing hard disk", /* 4 */
|
||||
"Reserved (deprecated)", /* 5 */
|
||||
"Reserved (deprecated)" /* 6 */
|
||||
};
|
||||
|
||||
#define HD_TYPE_MAX 6
|
||||
|
||||
struct prt_loc {
|
||||
u32 code; /* Platform code -- see defines below. */
|
||||
u32 data_space; /* Number of 512-byte sectors to store locator */
|
||||
u32 data_len; /* Actual length of parent locator in bytes */
|
||||
u32 res; /* Must be zero */
|
||||
u64 data_offset; /* Absolute offset of locator data (bytes) */
|
||||
};
|
||||
|
||||
/* Platform Codes */
|
||||
#define PLAT_CODE_NONE 0x0
|
||||
#define PLAT_CODE_WI2R 0x57693272 /* deprecated */
|
||||
#define PLAT_CODE_WI2K 0x5769326B /* deprecated */
|
||||
#define PLAT_CODE_W2RU 0x57327275 /* Windows relative path (UTF-16) */
|
||||
#define PLAT_CODE_W2KU 0x57326B75 /* Windows absolute path (UTF-16) */
|
||||
#define PLAT_CODE_MAC 0x4D616320 /* MacOS alias stored as a blob. */
|
||||
#define PLAT_CODE_MACX 0x4D616358 /* File URL (UTF-8), see RFC 2396. */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* This is the dynamic disk header. */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct dd_hdr {
|
||||
char cookie[8]; /* Should contain "cxsparse" */
|
||||
u64 data_offset; /* Byte offset of next record. (Unused) 0xffs */
|
||||
u64 table_offset; /* Absolute offset to the BAT. */
|
||||
u32 hdr_ver; /* Version of the dd_hdr (major,minor) */
|
||||
u32 max_bat_size; /* Maximum number of entries in the BAT */
|
||||
u32 block_size; /* Block size in bytes. Must be power of 2. */
|
||||
u32 checksum; /* Header checksum. 1's comp of all fields. */
|
||||
blk_uuid_t prt_uuid; /* ID of the parent disk. */
|
||||
u32 prt_ts; /* Modification time of the parent disk */
|
||||
u32 res1; /* Reserved. */
|
||||
char prt_name[512]; /* Parent unicode name. */
|
||||
struct prt_loc loc[8]; /* Parent locator entries. */
|
||||
char res2[256]; /* Reserved. */
|
||||
};
|
||||
|
||||
/* VHD cookie string. */
|
||||
static const char DD_COOKIE[9] = "cxsparse";
|
||||
|
||||
/* Version field in hd_ftr */
|
||||
#define DD_VERSION 0x00010000
|
||||
|
||||
/* Default blocksize is 2 meg. */
|
||||
#define DD_BLOCKSIZE_DEFAULT 0x00200000
|
||||
|
||||
#define DD_BLK_UNUSED 0xFFFFFFFF
|
||||
|
||||
struct dd_batmap_hdr {
|
||||
char cookie[8]; /* should contain "tdbatmap" */
|
||||
u64 batmap_offset; /* byte offset to batmap */
|
||||
u32 batmap_size; /* batmap size in sectors */
|
||||
u32 batmap_version; /* version of batmap */
|
||||
u32 checksum; /* batmap checksum -- 1's complement of batmap */
|
||||
};
|
||||
|
||||
static const char VHD_BATMAP_COOKIE[9] = "tdbatmap";
|
||||
|
||||
/*
|
||||
* version 1.1: signed char checksum
|
||||
*/
|
||||
#define VHD_BATMAP_VERSION(major, minor) (((major) << 16) | ((minor) & 0x0000FFFF))
|
||||
#define VHD_BATMAP_CURRENT_VERSION VHD_BATMAP_VERSION(1, 2)
|
||||
|
||||
/* Layout of a dynamic disk:
|
||||
*
|
||||
* +-------------------------------------------------+
|
||||
* | Mirror image of HD footer (hd_ftr) (512 bytes) |
|
||||
* +-------------------------------------------------+
|
||||
* | Sparse drive header (dd_hdr) (1024 bytes) |
|
||||
* +-------------------------------------------------+
|
||||
* | BAT (Block allocation table) |
|
||||
* | - Array of absolute sector offsets into the |
|
||||
* | file (u32). |
|
||||
* | - Rounded up to a sector boundary. |
|
||||
* | - Unused entries are marked as 0xFFFFFFFF |
|
||||
* | - max entries in dd_hdr->max_bat_size |
|
||||
* +-------------------------------------------------+
|
||||
* | Data Block 0 |
|
||||
* | Bitmap (padded to 512 byte sector boundary) |
|
||||
* | - each bit indicates whether the associated |
|
||||
* | sector within this block is used. |
|
||||
* | Data |
|
||||
* | - power-of-two multiple of sectors. |
|
||||
* | - default 2MB (4096 * 512) |
|
||||
* | - Any entries with zero in bitmap should be |
|
||||
* | zero on disk |
|
||||
* +-------------------------------------------------+
|
||||
* | Data Block 1 |
|
||||
* +-------------------------------------------------+
|
||||
* | ... |
|
||||
* +-------------------------------------------------+
|
||||
* | Data Block n |
|
||||
* +-------------------------------------------------+
|
||||
* | HD Footer (511 bytes) |
|
||||
* +-------------------------------------------------+
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,442 +1,442 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "relative-path.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <Shlwapi.h>
|
||||
#define strdup _strdup
|
||||
#else
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
#define DELIMITER '/'
|
||||
|
||||
#define FN __func__
|
||||
|
||||
#define EPRINTF(a) rpath_log_error a
|
||||
|
||||
static void rpath_log_error( const char *func, const char *fmt, ... )
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf,2,3)));
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
#ifndef LIBVHD_HAS_SYSLOG
|
||||
#ifdef _WIN32
|
||||
#define LIBVHD_HAS_SYSLOG 0
|
||||
#else
|
||||
#define LIBVHD_HAS_SYSLOG 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define sfree(ptr) \
|
||||
do { \
|
||||
free(ptr); \
|
||||
ptr = NULL; \
|
||||
} while (0)
|
||||
|
||||
#ifdef _WIN32
|
||||
LIBVHD_API char *realpath( const char *path, char *resolved ) {
|
||||
char *p;
|
||||
DWORD len;
|
||||
|
||||
p = resolved;
|
||||
if( resolved == NULL ) {
|
||||
resolved = malloc( 1+ MAX_PATH + 1 );
|
||||
if( resolved == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if( (len = GetFullPathName( path[0] == '/'? path+1:path, MAX_PATH + 1, resolved, NULL )) == 0 ) {
|
||||
if( p == NULL )
|
||||
free( resolved );
|
||||
return NULL;
|
||||
}
|
||||
if( len > MAX_PATH ) {
|
||||
if( p != NULL )
|
||||
return NULL;
|
||||
if( (p = realloc( resolved, len )) == NULL ) {
|
||||
free( resolved );
|
||||
return NULL;
|
||||
}
|
||||
resolved = p;
|
||||
len = GetFullPathName( path, MAX_PATH + 1, resolved, NULL );
|
||||
if( len > MAX_PATH || len == 0 ) {
|
||||
free( resolved );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for( p = resolved; *p; p++ ) {
|
||||
if( *p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
for( p = resolved; isalpha( *p ); p++ )
|
||||
;
|
||||
if( *p == ':' ) { /* Hide drive under '/' for callers. */
|
||||
memmove( resolved + 1, resolved, strlen( resolved ) +1 );
|
||||
resolved[0] = '/'; /* Callers must skip '/' when touching filesystem. */
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
LIBVHD_API int asprintf( char **result, const char *fmt, ... ) {
|
||||
int len;
|
||||
va_list ap;
|
||||
char *np;
|
||||
|
||||
/* It would be better to va_copy() the list and do a prescan,
|
||||
* but va_copy apparently has issues with versions of MS C
|
||||
* still in the field. This approach is ugly and wasteful, but
|
||||
* should work. (A KB just isn't what it used to be...)
|
||||
*/
|
||||
if( (*result = malloc( 1 * 100 * 1000 + 1 )) == NULL )
|
||||
return -1;
|
||||
va_start( ap, fmt );
|
||||
len = vsprintf( *result, fmt, ap );
|
||||
np = realloc( *result, len + 1 );
|
||||
if( np != NULL )
|
||||
*result = np;
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* count number of tokens between DELIMITER characters
|
||||
*/
|
||||
|
||||
int count_nodes(char *path)
|
||||
{
|
||||
int i;
|
||||
char *tmp;
|
||||
|
||||
if (!path)
|
||||
return 0;
|
||||
|
||||
for (i = 0, tmp = path; *tmp != '\0'; tmp++)
|
||||
if (*tmp == DELIMITER)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* return copy of next node in @path, or NULL
|
||||
* @path is moved to the end of the next node
|
||||
* @err is set to -errno on failure
|
||||
* copy should be freed
|
||||
*/
|
||||
static char *
|
||||
next_node(char **path, int *err)
|
||||
{
|
||||
int ret;
|
||||
char *tmp, *start;
|
||||
|
||||
if (!path || !*path) {
|
||||
*err = -EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*err = 0;
|
||||
start = *path;
|
||||
|
||||
for (tmp = *path; *tmp != '\0'; tmp++)
|
||||
if (*tmp == DELIMITER) {
|
||||
int size;
|
||||
char *node;
|
||||
|
||||
size = tmp - start + 1;
|
||||
node = malloc(size);
|
||||
if (!node) {
|
||||
*err = -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = snprintf(node, size, "%s", start);
|
||||
if (ret < 0) {
|
||||
free(node);
|
||||
*err = -EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*path = tmp;
|
||||
return node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* count number of nodes in common betwee @to and @from
|
||||
* returns number of common nodes, or -errno on failure
|
||||
*/
|
||||
static int
|
||||
count_common_nodes(char *to, char *from)
|
||||
{
|
||||
int err, common;
|
||||
char *to_node, *from_node;
|
||||
|
||||
if (!to || !from)
|
||||
return -EINVAL;
|
||||
|
||||
err = 0;
|
||||
common = 0;
|
||||
to_node = NULL;
|
||||
from_node = NULL;
|
||||
|
||||
do {
|
||||
to_node = next_node(&to, &err);
|
||||
if (err || !to_node)
|
||||
break;
|
||||
|
||||
from_node = next_node(&from, &err);
|
||||
if (err || !from_node)
|
||||
break;
|
||||
|
||||
if (strncmp(to_node, from_node, MAX_NAME_LEN))
|
||||
break;
|
||||
|
||||
++to;
|
||||
++from;
|
||||
++common;
|
||||
sfree(to_node);
|
||||
sfree(from_node);
|
||||
|
||||
} while (1);
|
||||
|
||||
sfree(to_node);
|
||||
sfree(from_node);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return common;
|
||||
}
|
||||
|
||||
/*
|
||||
* construct path of @count '../', './' if @count is zero, or NULL on error
|
||||
* result should be freed
|
||||
*/
|
||||
static char *
|
||||
up_nodes(int count)
|
||||
{
|
||||
char *path, *tmp;
|
||||
int i, ret, len, size;
|
||||
|
||||
if (!count)
|
||||
return strdup("./");
|
||||
|
||||
len = strlen("../");
|
||||
size = len * count;
|
||||
if (size >= MAX_NAME_LEN)
|
||||
return NULL;
|
||||
|
||||
path = malloc(size + 1);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
tmp = path;
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = sprintf(tmp, "../");
|
||||
if (ret < 0 || ret != len) {
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
tmp += ret;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/*
|
||||
* return pointer to @offset'th node of path or NULL on error
|
||||
*/
|
||||
static char *
|
||||
node_offset(char *from, int offset)
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (!from || !offset)
|
||||
return NULL;
|
||||
|
||||
for (path = from; *path != '\0'; path++) {
|
||||
if (*path == DELIMITER)
|
||||
if (--offset == 0)
|
||||
return path + 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* return a relative path from @from to @to
|
||||
* result should be freed
|
||||
*/
|
||||
LIBVHD_API
|
||||
char *
|
||||
relative_path_to(char *from, char *to, int *err)
|
||||
{
|
||||
int from_nodes, common;
|
||||
char *to_absolute, *from_absolute;
|
||||
char *up, *common_target_path, *relative_path;
|
||||
|
||||
*err = 0;
|
||||
up = NULL;
|
||||
to_absolute = NULL;
|
||||
from_absolute = NULL;
|
||||
relative_path = NULL;
|
||||
|
||||
if (strnlen(to, MAX_NAME_LEN) == MAX_NAME_LEN ||
|
||||
strnlen(from, MAX_NAME_LEN) == MAX_NAME_LEN) {
|
||||
EPRINTF((FN,"invalid input; max path length is %d\n",
|
||||
MAX_NAME_LEN));
|
||||
*err = -ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
to_absolute = realpath(to, NULL);
|
||||
if (!to_absolute) {
|
||||
EPRINTF((FN,"failed to get absolute path of %s\n", to));
|
||||
*err = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
from_absolute = realpath(from, NULL);
|
||||
if (!from_absolute) {
|
||||
EPRINTF((FN,"failed to get absolute path of %s\n", from));
|
||||
*err = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strnlen(to_absolute, MAX_NAME_LEN) == MAX_NAME_LEN ||
|
||||
strnlen(from_absolute, MAX_NAME_LEN) == MAX_NAME_LEN) {
|
||||
EPRINTF((FN,"invalid input; max path length is %d\n",
|
||||
MAX_NAME_LEN));
|
||||
*err = -ENAMETOOLONG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* count nodes in source path */
|
||||
from_nodes = count_nodes(from_absolute);
|
||||
|
||||
/* count nodes in common */
|
||||
common = count_common_nodes(to_absolute + 1, from_absolute + 1);
|
||||
if (common < 0) {
|
||||
EPRINTF((FN,"failed to count common nodes of %s and %s: %d\n",
|
||||
to_absolute, from_absolute, common));
|
||||
*err = common;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* move up to common node */
|
||||
up = up_nodes(from_nodes - common - 1);
|
||||
if (!up) {
|
||||
EPRINTF((FN,"failed to allocate relative path for %s: %d\n",
|
||||
from_absolute, -ENOMEM));
|
||||
*err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get path from common node to target */
|
||||
common_target_path = node_offset(to_absolute, common + 1);
|
||||
if (!common_target_path) {
|
||||
EPRINTF((FN,"failed to find common target path to %s: %d\n",
|
||||
to_absolute, -EINVAL));
|
||||
*err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get relative path */
|
||||
if (asprintf(&relative_path, "%s%s", up, common_target_path) == -1) {
|
||||
EPRINTF((FN,"failed to construct final path %s%s: %d\n",
|
||||
up, common_target_path, -ENOMEM));
|
||||
relative_path = NULL;
|
||||
*err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
sfree(up);
|
||||
sfree(to_absolute);
|
||||
sfree(from_absolute);
|
||||
|
||||
return relative_path;
|
||||
}
|
||||
static void rpath_log_error( const char *func, const char *fmt, ... )
|
||||
{
|
||||
char *buf, nilbuf;
|
||||
size_t ilen, len;
|
||||
va_list ap;
|
||||
|
||||
ilen = sizeof( "tap-err:%s: " ) + strlen( func ) -2;
|
||||
va_start(ap, fmt );
|
||||
len = vsnprintf( &nilbuf, 1, fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
if( (buf = malloc( ilen + len + 1 )) == NULL ) {
|
||||
#if LIBVHD_HAS_SYSLOG
|
||||
syslog( LOG_INFO, "tap-err:%s: Out of memory", func );
|
||||
#else
|
||||
fprintf( stderr, "tap-err%s: Out of memory for %s\n", func, fmt );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
(void) snprintf( buf, ilen, "tap-err:%s: ", func );
|
||||
(void) vsnprintf( buf + ilen -1, len+1, fmt, ap );
|
||||
va_end( ap );
|
||||
len += ilen -1;
|
||||
if( buf[ len -1 ] != '\n' )
|
||||
buf[len++] = '\n';
|
||||
buf[len] = '\0';
|
||||
#if LIBVHD_HAS_SYSLOG
|
||||
syslog(LOG_INFO, buf);
|
||||
#else
|
||||
fputs( buf, stderr );
|
||||
#endif
|
||||
free( buf );
|
||||
|
||||
return;
|
||||
}
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "relative-path.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <Shlwapi.h>
|
||||
#define strdup _strdup
|
||||
#else
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
#define DELIMITER '/'
|
||||
|
||||
#define FN __func__
|
||||
|
||||
#define EPRINTF(a) rpath_log_error a
|
||||
|
||||
static void rpath_log_error( const char *func, const char *fmt, ... )
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf,2,3)));
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
#ifndef LIBVHD_HAS_SYSLOG
|
||||
#ifdef _WIN32
|
||||
#define LIBVHD_HAS_SYSLOG 0
|
||||
#else
|
||||
#define LIBVHD_HAS_SYSLOG 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define sfree(ptr) \
|
||||
do { \
|
||||
free(ptr); \
|
||||
ptr = NULL; \
|
||||
} while (0)
|
||||
|
||||
#ifdef _WIN32
|
||||
LIBVHD_API char *realpath( const char *path, char *resolved ) {
|
||||
char *p;
|
||||
DWORD len;
|
||||
|
||||
p = resolved;
|
||||
if( resolved == NULL ) {
|
||||
resolved = malloc( 1+ MAX_PATH + 1 );
|
||||
if( resolved == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if( (len = GetFullPathName( path[0] == '/'? path+1:path, MAX_PATH + 1, resolved, NULL )) == 0 ) {
|
||||
if( p == NULL )
|
||||
free( resolved );
|
||||
return NULL;
|
||||
}
|
||||
if( len > MAX_PATH ) {
|
||||
if( p != NULL )
|
||||
return NULL;
|
||||
if( (p = realloc( resolved, len )) == NULL ) {
|
||||
free( resolved );
|
||||
return NULL;
|
||||
}
|
||||
resolved = p;
|
||||
len = GetFullPathName( path, MAX_PATH + 1, resolved, NULL );
|
||||
if( len > MAX_PATH || len == 0 ) {
|
||||
free( resolved );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for( p = resolved; *p; p++ ) {
|
||||
if( *p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
for( p = resolved; isalpha( *p ); p++ )
|
||||
;
|
||||
if( *p == ':' ) { /* Hide drive under '/' for callers. */
|
||||
memmove( resolved + 1, resolved, strlen( resolved ) +1 );
|
||||
resolved[0] = '/'; /* Callers must skip '/' when touching filesystem. */
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
LIBVHD_API int asprintf( char **result, const char *fmt, ... ) {
|
||||
int len;
|
||||
va_list ap;
|
||||
char *np;
|
||||
|
||||
/* It would be better to va_copy() the list and do a prescan,
|
||||
* but va_copy apparently has issues with versions of MS C
|
||||
* still in the field. This approach is ugly and wasteful, but
|
||||
* should work. (A KB just isn't what it used to be...)
|
||||
*/
|
||||
if( (*result = malloc( 1 * 100 * 1000 + 1 )) == NULL )
|
||||
return -1;
|
||||
va_start( ap, fmt );
|
||||
len = vsprintf( *result, fmt, ap );
|
||||
np = realloc( *result, len + 1 );
|
||||
if( np != NULL )
|
||||
*result = np;
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* count number of tokens between DELIMITER characters
|
||||
*/
|
||||
|
||||
int count_nodes(char *path)
|
||||
{
|
||||
int i;
|
||||
char *tmp;
|
||||
|
||||
if (!path)
|
||||
return 0;
|
||||
|
||||
for (i = 0, tmp = path; *tmp != '\0'; tmp++)
|
||||
if (*tmp == DELIMITER)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* return copy of next node in @path, or NULL
|
||||
* @path is moved to the end of the next node
|
||||
* @err is set to -errno on failure
|
||||
* copy should be freed
|
||||
*/
|
||||
static char *
|
||||
next_node(char **path, int *err)
|
||||
{
|
||||
int ret;
|
||||
char *tmp, *start;
|
||||
|
||||
if (!path || !*path) {
|
||||
*err = -EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*err = 0;
|
||||
start = *path;
|
||||
|
||||
for (tmp = *path; *tmp != '\0'; tmp++)
|
||||
if (*tmp == DELIMITER) {
|
||||
int size;
|
||||
char *node;
|
||||
|
||||
size = tmp - start + 1;
|
||||
node = malloc(size);
|
||||
if (!node) {
|
||||
*err = -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = snprintf(node, size, "%s", start);
|
||||
if (ret < 0) {
|
||||
free(node);
|
||||
*err = -EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*path = tmp;
|
||||
return node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* count number of nodes in common betwee @to and @from
|
||||
* returns number of common nodes, or -errno on failure
|
||||
*/
|
||||
static int
|
||||
count_common_nodes(char *to, char *from)
|
||||
{
|
||||
int err, common;
|
||||
char *to_node, *from_node;
|
||||
|
||||
if (!to || !from)
|
||||
return -EINVAL;
|
||||
|
||||
err = 0;
|
||||
common = 0;
|
||||
to_node = NULL;
|
||||
from_node = NULL;
|
||||
|
||||
do {
|
||||
to_node = next_node(&to, &err);
|
||||
if (err || !to_node)
|
||||
break;
|
||||
|
||||
from_node = next_node(&from, &err);
|
||||
if (err || !from_node)
|
||||
break;
|
||||
|
||||
if (strncmp(to_node, from_node, MAX_NAME_LEN))
|
||||
break;
|
||||
|
||||
++to;
|
||||
++from;
|
||||
++common;
|
||||
sfree(to_node);
|
||||
sfree(from_node);
|
||||
|
||||
} while (1);
|
||||
|
||||
sfree(to_node);
|
||||
sfree(from_node);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return common;
|
||||
}
|
||||
|
||||
/*
|
||||
* construct path of @count '../', './' if @count is zero, or NULL on error
|
||||
* result should be freed
|
||||
*/
|
||||
static char *
|
||||
up_nodes(int count)
|
||||
{
|
||||
char *path, *tmp;
|
||||
int i, ret, len, size;
|
||||
|
||||
if (!count)
|
||||
return strdup("./");
|
||||
|
||||
len = strlen("../");
|
||||
size = len * count;
|
||||
if (size >= MAX_NAME_LEN)
|
||||
return NULL;
|
||||
|
||||
path = malloc(size + 1);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
tmp = path;
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = sprintf(tmp, "../");
|
||||
if (ret < 0 || ret != len) {
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
tmp += ret;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/*
|
||||
* return pointer to @offset'th node of path or NULL on error
|
||||
*/
|
||||
static char *
|
||||
node_offset(char *from, int offset)
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (!from || !offset)
|
||||
return NULL;
|
||||
|
||||
for (path = from; *path != '\0'; path++) {
|
||||
if (*path == DELIMITER)
|
||||
if (--offset == 0)
|
||||
return path + 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* return a relative path from @from to @to
|
||||
* result should be freed
|
||||
*/
|
||||
LIBVHD_API
|
||||
char *
|
||||
relative_path_to(char *from, char *to, int *err)
|
||||
{
|
||||
int from_nodes, common;
|
||||
char *to_absolute, *from_absolute;
|
||||
char *up, *common_target_path, *relative_path;
|
||||
|
||||
*err = 0;
|
||||
up = NULL;
|
||||
to_absolute = NULL;
|
||||
from_absolute = NULL;
|
||||
relative_path = NULL;
|
||||
|
||||
if (strnlen(to, MAX_NAME_LEN) == MAX_NAME_LEN ||
|
||||
strnlen(from, MAX_NAME_LEN) == MAX_NAME_LEN) {
|
||||
EPRINTF((FN,"invalid input; max path length is %d\n",
|
||||
MAX_NAME_LEN));
|
||||
*err = -ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
to_absolute = realpath(to, NULL);
|
||||
if (!to_absolute) {
|
||||
EPRINTF((FN,"failed to get absolute path of %s\n", to));
|
||||
*err = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
from_absolute = realpath(from, NULL);
|
||||
if (!from_absolute) {
|
||||
EPRINTF((FN,"failed to get absolute path of %s\n", from));
|
||||
*err = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strnlen(to_absolute, MAX_NAME_LEN) == MAX_NAME_LEN ||
|
||||
strnlen(from_absolute, MAX_NAME_LEN) == MAX_NAME_LEN) {
|
||||
EPRINTF((FN,"invalid input; max path length is %d\n",
|
||||
MAX_NAME_LEN));
|
||||
*err = -ENAMETOOLONG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* count nodes in source path */
|
||||
from_nodes = count_nodes(from_absolute);
|
||||
|
||||
/* count nodes in common */
|
||||
common = count_common_nodes(to_absolute + 1, from_absolute + 1);
|
||||
if (common < 0) {
|
||||
EPRINTF((FN,"failed to count common nodes of %s and %s: %d\n",
|
||||
to_absolute, from_absolute, common));
|
||||
*err = common;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* move up to common node */
|
||||
up = up_nodes(from_nodes - common - 1);
|
||||
if (!up) {
|
||||
EPRINTF((FN,"failed to allocate relative path for %s: %d\n",
|
||||
from_absolute, -ENOMEM));
|
||||
*err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get path from common node to target */
|
||||
common_target_path = node_offset(to_absolute, common + 1);
|
||||
if (!common_target_path) {
|
||||
EPRINTF((FN,"failed to find common target path to %s: %d\n",
|
||||
to_absolute, -EINVAL));
|
||||
*err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get relative path */
|
||||
if (asprintf(&relative_path, "%s%s", up, common_target_path) == -1) {
|
||||
EPRINTF((FN,"failed to construct final path %s%s: %d\n",
|
||||
up, common_target_path, -ENOMEM));
|
||||
relative_path = NULL;
|
||||
*err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
sfree(up);
|
||||
sfree(to_absolute);
|
||||
sfree(from_absolute);
|
||||
|
||||
return relative_path;
|
||||
}
|
||||
static void rpath_log_error( const char *func, const char *fmt, ... )
|
||||
{
|
||||
char *buf, nilbuf;
|
||||
size_t ilen, len;
|
||||
va_list ap;
|
||||
|
||||
ilen = sizeof( "tap-err:%s: " ) + strlen( func ) -2;
|
||||
va_start(ap, fmt );
|
||||
len = vsnprintf( &nilbuf, 1, fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
if( (buf = malloc( ilen + len + 1 )) == NULL ) {
|
||||
#if LIBVHD_HAS_SYSLOG
|
||||
syslog( LOG_INFO, "tap-err:%s: Out of memory", func );
|
||||
#else
|
||||
fprintf( stderr, "tap-err%s: Out of memory for %s\n", func, fmt );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
(void) snprintf( buf, ilen, "tap-err:%s: ", func );
|
||||
(void) vsnprintf( buf + ilen -1, len+1, fmt, ap );
|
||||
va_end( ap );
|
||||
len += ilen -1;
|
||||
if( buf[ len -1 ] != '\n' )
|
||||
buf[len++] = '\n';
|
||||
buf[len] = '\0';
|
||||
#if LIBVHD_HAS_SYSLOG
|
||||
syslog(LOG_INFO, buf);
|
||||
#else
|
||||
fputs( buf, stderr );
|
||||
#endif
|
||||
free( buf );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
135
extracters/makehelp/makehelp.vcxproj
Executable file
135
extracters/makehelp/makehelp.vcxproj
Executable file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{0b040f93-b411-4ceb-b55b-5aae6c27347d}</ProjectGuid>
|
||||
<RootNamespace>makehelp</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</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>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<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|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;DEBUG_BUILD;USE_VLD</PreprocessorDefinitions>
|
||||
<ConformanceMode>Default</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>$(CoreLibraryDependencies);Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>$(CoreLibraryDependencies);Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;DEBUG_BUILD;USE_VLD</PreprocessorDefinitions>
|
||||
<ConformanceMode>Default</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>$(CoreLibraryDependencies);Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>$(CoreLibraryDependencies);Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\ods2\compat.c" />
|
||||
<ClCompile Include="..\ods2\makehelp.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
25
extracters/makehelp/makehelp.vcxproj.filters
Executable file
25
extracters/makehelp/makehelp.vcxproj.filters
Executable file
@@ -0,0 +1,25 @@
|
||||
<?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;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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>
|
||||
<ClCompile Include="..\ods2\makehelp.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ods2\compat.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
5
extracters/ods2/.gitignore
vendored
Normal file
5
extracters/ods2/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
ods2
|
||||
makehelp
|
||||
genmsg
|
||||
testdata
|
||||
attic
|
||||
@@ -1,3 +1,2 @@
|
||||
--memcheck:leak-check=yes
|
||||
--suppressions=valgrind_suppressions_readline
|
||||
--suppressions=valgrind_suppressions_ods2
|
||||
|
||||
@@ -11,6 +11,8 @@ The platform-specific files are:
|
||||
|
||||
Select the appropriate platform file & review the definitions.
|
||||
|
||||
For Unix-like OSs, defaults are set in makefile.unixdefs.
|
||||
|
||||
The easiest way to build ODS-2 is to softlink Makefile to
|
||||
the platform file. For example:
|
||||
ln -s makefile.unix Makefile
|
||||
@@ -19,16 +21,51 @@ the platform file. For example:
|
||||
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,
|
||||
Copy the resulting object file, the .HLB, and .MDF files 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.
|
||||
|
||||
The .HLB files contain the (compiled) help text. The MDF files contain
|
||||
message strings. Both are binary files, may be architecture-specific,
|
||||
and can be localized.
|
||||
|
||||
Building from source requires Perl and uses data from VMS message and header files.
|
||||
Unless you are localizing messages, the included files suffice. The procedure
|
||||
for extracting localized messages from VMS is documented in the message script..
|
||||
|
||||
VHD support requires the libvhd in simtools/extracters/libvhd and
|
||||
simtools/extracters/vhd-tools. Note that these are different from the
|
||||
vhd support in simH.
|
||||
|
||||
ods2 includes RMS emulation that is fairly complete (except for indexed organization).
|
||||
Messages use a VMS getmsg emulation; .msg files are localizable.
|
||||
|
||||
If you have an alternate message file (e.g. for I18n), it will be a
|
||||
.mdf file (e.g. ods2_en_us.mdf), which should also be placed in a convenient
|
||||
place.
|
||||
|
||||
The help source is in .hlp files, which are structured text. They are compiled
|
||||
into .hlb files by makehelp. en_us.hlp is the base file; any translations should
|
||||
use the same naming convention. The makefiles generate ods2_en_us.hlb. The
|
||||
helpfile can be selected by the ODS2HELP environment variable, and/or the
|
||||
set helpfile command.
|
||||
|
||||
The default help library filename is "ods2.hlb", in the same directory as
|
||||
the ods2 executable. This file is made a symlink or copy of the default
|
||||
language by the makefile. If another available language is desired,
|
||||
softlink (or copy) the desired language file to it (or set the ODS2HELP
|
||||
environment variable.)
|
||||
E.g. for US English help: ln -s ods2_en_us.hlb ods2.hlb
|
||||
|
||||
If you need different definitions for another platform, please
|
||||
add a new platform-specific file rather than changing makefile.generic.
|
||||
|
||||
For development, I use a wrapper on make called "strictmake" to keep the sources
|
||||
as clean as possible; it enables extra warnings from gcc (and filters a few). I
|
||||
also use "grind" to run with valgrind to keep the code leak free. Currently,
|
||||
the only exception is that libedit doesn't completely clean up on exit.
|
||||
|
||||
On VMS, you can use the DCL command procedure build.com to build
|
||||
with DECC or GCC, with
|
||||
$ @build
|
||||
@@ -40,4 +77,15 @@ If you have MMS/mmk, use descrip.mms, with
|
||||
To build with VAXC
|
||||
$ mmk/macro=vaxc=1
|
||||
|
||||
For Microsoft Windows, use Visual Studio - the free Community Edition works.
|
||||
A solution file is included in ODS2's git repository. x64, x86 builds are
|
||||
supported. Debug builds include Visual Leak Detector (a free tool), but
|
||||
that can be turned off. VLD indicates that ODS2 is leak-free on Windows.
|
||||
|
||||
I build for Windows with the sources on a Linux share. This makes it easy
|
||||
to test changes with one copy of the source. The object files do not overlap;
|
||||
the VS directories are excluded from git. For convenience, the windows .EXEs
|
||||
are copied to the git working directory.
|
||||
|
||||
Bug reports, contributions, and feature requests are welcome
|
||||
at https://github.com/open-simh/simtools/issues.
|
||||
|
||||
175
extracters/ods2/00README.txt
Normal file
175
extracters/ods2/00README.txt
Normal file
@@ -0,0 +1,175 @@
|
||||
ODS2 provides access to DEC Files-11 On-Disk Structure Level 2 volumes from
|
||||
Unix, VMS & Windows hosts.
|
||||
|
||||
It is capable of reading and writing physical volumes, such as SCSI disks and
|
||||
CDROMs, as well as SimH simulator files (native, and optionally VHD).
|
||||
|
||||
The original code was developed by Paul Nankervis, email address: Paulnank@au1.ibm.com.
|
||||
|
||||
This version has been extensively re-worked - debugged, completed and enhanced - by
|
||||
Timothe Litt - litt@acm.org. It also contains contributions from Larry Baker of
|
||||
the USGS and from Hunter Goatley. The VHD support is open-source from the Xen
|
||||
project - with some minor changes on Unix & some significant changes for Windows.
|
||||
|
||||
This version provides full read and write support for ODS2 volumes - physical and
|
||||
virtual. It can initialize volumes, create, read, write, and extend files. It
|
||||
allows files to be copied between the host filesystem and the Files-11 volume(s),
|
||||
converting all RMS formats except indexed. Volume sets and multiple independent volumes
|
||||
can be accessed simultaneously.
|
||||
|
||||
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 contributions
|
||||
of the original author and subsequent contributors. This is free software; no warranty
|
||||
is offered, and while we believe it to be useful, you use it at your own risk.
|
||||
|
||||
There are opportunities for additional contributions, among them:
|
||||
- message file translations
|
||||
- help file completion and translations
|
||||
- testing on other host platforms
|
||||
Please use the https://github.com/open-simh/simtools repository for pull
|
||||
requests and issues.
|
||||
|
||||
ODS2 starts by executing a command file, which it looks for in the following order:
|
||||
The environment variable (or logical name) ODS2INIT
|
||||
The user's home directory
|
||||
Windows: %HOMEDRIVE%%HOMEPATH%\.ods2.ini
|
||||
VMS: SYS$LOGIN:_ODS2.INI
|
||||
Unix: $HOME/.ods2.ini
|
||||
This can be used to specify defaults, mount a favorite device...
|
||||
No error is reported if the file does not exist.
|
||||
|
||||
Next, ODS2 executes any commands specified on the command line.
|
||||
Multiple command are separated by '$' (most shells require $ to be quoted).
|
||||
|
||||
Finally, ODS2 enters interactive mode. Under Unix, with READLINE support, command
|
||||
history is preserved in $HOME/.ods2.
|
||||
|
||||
The HELP command provides full command syntax, which is very similar to DCL.
|
||||
The help text is located in ods2.hlb, in the same directory as ODS2. You can
|
||||
set the environment variable ODS2HELP to an alternate helpfile or use the
|
||||
set helpfile command. Note that helpfiles are binary - see 00INSTALL.TXT..
|
||||
|
||||
N.B. The default help library filename is "ods2.hlb", in the same directory as
|
||||
the ods2 executable. This file is made a symlink or copy of the default
|
||||
language by the makefile. If another available language is desired,
|
||||
softlink (or copy) the desired language file to it (or set the ODS2HELP
|
||||
environment variable.)
|
||||
E.g. for US English help: ln -s ods2_en_us.hlb ods2.hlb
|
||||
|
||||
The following is a brief summary of commonly-used command sequences.
|
||||
Abbreviations can be used. Full VMS filenames (device:[dir.sfd...]name.ext;gen)
|
||||
can be used for files on the FILES-11 volume. Wildcards are supported for most
|
||||
commands. Wildcards can be used on the host filesystem, e.g. when copying files
|
||||
to the volume.
|
||||
|
||||
The most important command for any program:
|
||||
ODS2$> EXIT
|
||||
|
||||
(QUIT also works.)
|
||||
|
||||
Create a new Files-11 volume:
|
||||
|
||||
ODS2$> INITIALIZE /medium:RM02/LOG rm02.vhd myvolume
|
||||
|
||||
N.B. The .vhd file type will create a dynamic (sparse) VHD-format simulator file.
|
||||
It is important to specify the medium type, as FILES-11 is sensitve to volume
|
||||
size and geometry.
|
||||
|
||||
Create a directory:
|
||||
ODS2$> CREATE/DIRECTORY/LOG [FRED.PAKS]
|
||||
|
||||
Copy files to the volume:
|
||||
ODS2$> COPY /TO_FILES-11/ASCII *.txt *.doc [FRED.PAKS]*.*
|
||||
|
||||
Set default directory on the volume:
|
||||
ODS2$> SET DEFAULT [FRED.PAKS]
|
||||
|
||||
See what's there:
|
||||
ODS2$> DIR /DATE/SIZE
|
||||
|
||||
Copy files from the volume:
|
||||
ODS2$> COPY /FROM_FILES-11/ASCII *.txt *.*
|
||||
|
||||
Mount an existing volume:
|
||||
ODS2$> MOUNT /medium:RM02 /WRITE rmo2.vhd myvolume
|
||||
|
||||
N.B. The volume name is optional, but if specified must match.
|
||||
|
||||
Dismount the volume:
|
||||
ODS2$> DISMOUNT A:
|
||||
(The drive letter will vary - it's reported by INITIALIZE/MOUNT)
|
||||
|
||||
N.B. It's VERY important to dismount the volume, especially if it's mounted
|
||||
for write. ODS2 makes heavy use of caching, and any interruption will
|
||||
leave it in an inconsistent state.
|
||||
|
||||
Inspect a file on the volume:
|
||||
ODS2$> TYPE/PAGE *.TXT
|
||||
|
||||
Obtain information:
|
||||
ODS2$> SHOW DEVICES
|
||||
ODS2$> SHOW VOLUMES
|
||||
|
||||
Interactively create a file:
|
||||
ODS2$> CREATE FILE.TXT
|
||||
mumble
|
||||
gobble
|
||||
^D
|
||||
(or ^Z on Windows/VMS)
|
||||
|
||||
Delete a file
|
||||
ODS2$> DELETE FILE.TXT;2
|
||||
|
||||
More advanced usage:
|
||||
|
||||
When asked for confirmation, the VMS DCL responses are accepted:
|
||||
0, no, false : Don't do this action, ask again for additional items
|
||||
1, yes, true : Proceed with this action, ask again for additional items
|
||||
quit : Don't do this action, and don't consider any more items
|
||||
all : Proceed with this action, and do all other items without asking
|
||||
|
||||
Lines beginning with ';' or '!' are considered comments, and ignored. This
|
||||
may be used for commenting command files.
|
||||
|
||||
With editline (libedit) support, a comment entry is made in the command history
|
||||
when an initialization file is opened. This can be used to trace initialization
|
||||
issues. editlline also uses ~/.editrc and can be customized using the
|
||||
'ods2' tag. editline is a Unix command history editor that can be compiled
|
||||
with ods2. 'man 7 editline' and 'man 5 editrc' for usage details. editline
|
||||
is available on most Linux distributions; building ods2 requires the corresponding
|
||||
-dev(el) package.
|
||||
|
||||
It may be necessary to quote command arguments, e.g. when specifying a
|
||||
file name on a Unix system that includes '/'. Use '"' or "'"; double
|
||||
the quote character to include it in the string. e.g. """hello""" produces
|
||||
"hello"
|
||||
|
||||
Alternatively, you can switch to unix-style options with SET QUALIFIER_STYLE UNIX.
|
||||
|
||||
A heuristic is used to distinguish physical devices from simulator disk image
|
||||
files in the mount and initialize commands. Use /device or /image if it
|
||||
guesses wrong.
|
||||
|
||||
It is possible to mount multiple volumes simultaneously, though not
|
||||
(currently) to move files directly from one Files-11 volume to another.
|
||||
|
||||
It is possible to mount volumesets, though this hasn't been completely debugged.
|
||||
|
||||
Command files can be executed with @filename. They can be nested.
|
||||
|
||||
Favorite directory and/or copy qualifiers can be set in the .ini file, e.g.
|
||||
SET DIRECTORY /DATE/SIZE
|
||||
|
||||
With VHD support, you can write to a snapshot of the volume:
|
||||
ODS2$> MOUNT /SNAPSHOTS_OF=myvolume.vhd testvolume.vhd /write
|
||||
|
||||
For more details on these and other capabilities, use the HELP command.
|
||||
|
||||
For build/installation information, see 00INSTALL.TXT
|
||||
|
||||
Bug reports, contributions, and feature requests are welcome
|
||||
at https://github.com/open-simh/simtools/issues.
|
||||
|
||||
|
||||
-- Timothe Litt
|
||||
April 2016, October 2022
|
||||
1
extracters/ods2/Makefile
Symbolic link
1
extracters/ods2/Makefile
Symbolic link
@@ -0,0 +1 @@
|
||||
makefile.unix
|
||||
Binary file not shown.
35
extracters/ods2/ODS2.sln
Normal file → Executable file
35
extracters/ods2/ODS2.sln
Normal file → Executable file
@@ -1,20 +1,51 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C++ Express 2010
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.3.32922.545
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ODS2", "ODS2.vcxproj", "{BCCEAED2-1732-D796-1F70-040DE5DA42AD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genmsg-en", "genmsg-en\genmsg-en.vcxproj", "{5AC343A4-5F8B-47F1-982B-7E44B3208748}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makehelp", "..\makehelp\makehelp.vcxproj", "{0B040F93-B411-4CEB-B55B-5AAE6C27347D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
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}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BCCEAED2-1732-D796-1F70-040DE5DA42AD}.Debug|x64.Build.0 = Debug|x64
|
||||
{BCCEAED2-1732-D796-1F70-040DE5DA42AD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BCCEAED2-1732-D796-1F70-040DE5DA42AD}.Release|Win32.Build.0 = Release|Win32
|
||||
{BCCEAED2-1732-D796-1F70-040DE5DA42AD}.Release|x64.ActiveCfg = Release|x64
|
||||
{BCCEAED2-1732-D796-1F70-040DE5DA42AD}.Release|x64.Build.0 = Release|x64
|
||||
{5AC343A4-5F8B-47F1-982B-7E44B3208748}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{5AC343A4-5F8B-47F1-982B-7E44B3208748}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{5AC343A4-5F8B-47F1-982B-7E44B3208748}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5AC343A4-5F8B-47F1-982B-7E44B3208748}.Debug|x64.Build.0 = Debug|x64
|
||||
{5AC343A4-5F8B-47F1-982B-7E44B3208748}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{5AC343A4-5F8B-47F1-982B-7E44B3208748}.Release|Win32.Build.0 = Release|Win32
|
||||
{5AC343A4-5F8B-47F1-982B-7E44B3208748}.Release|x64.ActiveCfg = Release|x64
|
||||
{5AC343A4-5F8B-47F1-982B-7E44B3208748}.Release|x64.Build.0 = Release|x64
|
||||
{0B040F93-B411-4CEB-B55B-5AAE6C27347D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{0B040F93-B411-4CEB-B55B-5AAE6C27347D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0B040F93-B411-4CEB-B55B-5AAE6C27347D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0B040F93-B411-4CEB-B55B-5AAE6C27347D}.Debug|x64.Build.0 = Debug|x64
|
||||
{0B040F93-B411-4CEB-B55B-5AAE6C27347D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{0B040F93-B411-4CEB-B55B-5AAE6C27347D}.Release|Win32.Build.0 = Release|Win32
|
||||
{0B040F93-B411-4CEB-B55B-5AAE6C27347D}.Release|x64.ActiveCfg = Release|x64
|
||||
{0B040F93-B411-4CEB-B55B-5AAE6C27347D}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E61B3FE9-F8F6-44C6-AF2F-E3CEDB9B04B7}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
119
extracters/ods2/ODS2.vcxproj
Normal file → Executable file
119
extracters/ods2/ODS2.vcxproj
Normal file → Executable file
@@ -5,25 +5,44 @@
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{BCCEAED2-1732-D796-1F70-040DE5DA42AD}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -31,19 +50,33 @@
|
||||
<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 Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<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>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<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>
|
||||
<CustomBuildAfterTargets>
|
||||
</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<CustomBuildAfterTargets />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Link</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Link</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>USE_VLD;DEBUG_BUILD;USE_VHD;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
@@ -52,6 +85,7 @@
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>vhd\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
@@ -66,14 +100,41 @@
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>copy $(OutDir)$(TargetName)$(TargetExt) $(SolutionDir)$(TargetName)_$(PlatformShortName)_debug$(TargetExt) </Command>
|
||||
<Outputs>$(SolutionDir)$(TargetName)_$(PlatformShortName)_debug$(TargetExt)</Outputs>
|
||||
<Message>Copying $(TargetName)$(TargetExt)</Message>
|
||||
<Inputs>$(OutDir)$(TargetName)$(TargetExt) </Inputs>
|
||||
</CustomBuildStep>
|
||||
<PreBuildEvent>
|
||||
<Command>del $(SolutionDir)$(TargetName)$(TargetExt) >nil.bak 2>&1 || exit /b 0</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>USE_VLD;DEBUG_BUILD;USE_VHD;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>vhd\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>Rpcrt4.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>
|
||||
</DelayLoadDLLs>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Outputs>
|
||||
</Outputs>
|
||||
<Inputs>
|
||||
</Inputs>
|
||||
<Message>
|
||||
</Message>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>copy $(OutDir)$(TargetName)$(TargetExt) $(SolutionDir)$(TargetName)_$(PlatformShortName)_debug$(TargetExt) </Command>
|
||||
<Outputs>$(SolutionDir)$(TargetName)_$(PlatformShortName)_debug$(TargetExt)</Outputs>
|
||||
<Message>Copying $(TargetName)$(TargetExt)</Message>
|
||||
<Inputs>$(OutDir)$(TargetName)$(TargetExt) </Inputs>
|
||||
</CustomBuildStep>
|
||||
<PreBuildEvent>
|
||||
<Command>del $(SolutionDir)$(TargetName)$(TargetExt) >nil.bak 2>&1 || exit /b 0</Command>
|
||||
@@ -100,8 +161,34 @@
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>copy $(OutDir)$(TargetName)$(TargetExt) $(SolutionDir)$(TargetName)$(TargetExt) </Command>
|
||||
<Outputs>$(SolutionDir)$(TargetName)$(TargetExt)</Outputs>
|
||||
<Command>copy $(OutDir)$(TargetName)$(TargetExt) $(SolutionDir)$(TargetName)_$(PlatformShortName)$(TargetExt) </Command>
|
||||
<Outputs>$(SolutionDir)$(TargetName)_$(PlatformShortName)$(TargetExt)</Outputs>
|
||||
<Message>Copying $(TargetName)$(TargetExt)</Message>
|
||||
<Inputs>$(OutDir)$(TargetName)$(TargetExt) </Inputs>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>USE_VHD;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>vhd\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>Rpcrt4.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>copy $(OutDir)$(TargetName)$(TargetExt) $(SolutionDir)$(TargetName)_$(PlatformShortName)$(TargetExt) </Command>
|
||||
<Outputs>$(SolutionDir)$(TargetName)_$(PlatformShortName)$(TargetExt)</Outputs>
|
||||
<Message>Copying $(TargetName)$(TargetExt)</Message>
|
||||
<Inputs>$(OutDir)$(TargetName)$(TargetExt) </Inputs>
|
||||
</CustomBuildStep>
|
||||
@@ -114,6 +201,7 @@
|
||||
<ClCompile Include="createcmd.c" />
|
||||
<ClCompile Include="debug.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="deletecmd.c" />
|
||||
<ClCompile Include="device.c" />
|
||||
@@ -123,7 +211,6 @@
|
||||
<ClCompile Include="dismountcmd.c" />
|
||||
<ClCompile Include="extendcmd.c" />
|
||||
<ClCompile Include="helpcmd.c" />
|
||||
<ClCompile Include="importcmd.c" />
|
||||
<ClCompile Include="initialcmd.c" />
|
||||
<ClCompile Include="initvol.c" />
|
||||
<ClCompile Include="mountcmd.c" />
|
||||
@@ -131,17 +218,19 @@
|
||||
<ClCompile Include="phynt.c" />
|
||||
<ClCompile Include="phyvhd.c" />
|
||||
<ClCompile Include="phyvirt.c" />
|
||||
<ClCompile Include="renamecmd.c" />
|
||||
<ClCompile Include="rms.c" />
|
||||
<ClCompile Include="searchcmd.c" />
|
||||
<ClCompile Include="setcmd.c" />
|
||||
<ClCompile Include="showcmd.c" />
|
||||
<ClCompile Include="spawncmd.c" />
|
||||
<ClCompile Include="sysmsg.c" />
|
||||
<ClCompile Include="typecmd.c" />
|
||||
<ClCompile Include="termio.c" />
|
||||
<ClCompile Include="update.c" />
|
||||
<ClCompile Include="vhd\libvhd.c" />
|
||||
<ClCompile Include="vhd\relative-path.c" />
|
||||
<ClCompile Include="vmstime.c" />
|
||||
<ClCompile Include="winfile.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="access.h" />
|
||||
@@ -170,11 +259,17 @@
|
||||
<ClInclude Include="vhd\relative-path.h" />
|
||||
<ClInclude Include="vhd\vhd.h" />
|
||||
<ClInclude Include="vmstime.h" />
|
||||
<ClInclude Include="winfile.h" />
|
||||
<ClInclude Include="wnaspi32.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ods2.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="default.mt">
|
||||
<FileType>Document</FileType>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
15
extracters/ods2/ODS2.vcxproj.filters
Normal file → Executable file
15
extracters/ods2/ODS2.vcxproj.filters
Normal file → Executable file
@@ -90,9 +90,6 @@
|
||||
<ClCompile Include="helpcmd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="importcmd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="initialcmd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -111,7 +108,13 @@
|
||||
<ClCompile Include="spawncmd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="typecmd.c">
|
||||
<ClCompile Include="winfile.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="termio.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="renamecmd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -197,6 +200,10 @@
|
||||
<ClInclude Include="cmddef.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="winfile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="default.mt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ods2.rc">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,22 @@
|
||||
/* Access.h 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.
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _ACCESS_H
|
||||
#define _ACCESS_H
|
||||
|
||||
#include "ods2.h"
|
||||
#include "cache.h"
|
||||
#include "f11def.h"
|
||||
#include "vmstime.h"
|
||||
@@ -21,14 +25,14 @@
|
||||
|
||||
struct WCB {
|
||||
struct CACHE cache;
|
||||
unsigned loblk,hiblk; /* Range of window */
|
||||
unsigned hd_basevbn; /* File blocks prior to header */
|
||||
uint32_t loblk, hiblk; /* Range of window */
|
||||
uint32_t hd_basevbn; /* File blocks prior to header */
|
||||
unsigned hd_seg_num; /* Header segment number */
|
||||
struct fiddef hd_fid; /* Header FID */
|
||||
unsigned short extcount; /* Extents in use */
|
||||
unsigned phylen[EXTMAX];
|
||||
unsigned phyblk[EXTMAX];
|
||||
unsigned char rvn[EXTMAX];
|
||||
uint32_t phylen[EXTMAX];
|
||||
uint32_t phyblk[EXTMAX];
|
||||
uint8_t rvn[EXTMAX];
|
||||
}; /* Window control block */
|
||||
|
||||
#define VIOC_CHUNKSIZE 4
|
||||
@@ -48,29 +52,32 @@ struct FCB {
|
||||
struct HEAD *head; /* Pointer to header block */
|
||||
struct WCB *wcb; /* Window control block tree */
|
||||
struct VIOC *vioc; /* Virtual I/O chunk tree */
|
||||
unsigned headvbn; /* vbn for file header */
|
||||
unsigned hiblock; /* Highest block mapped */
|
||||
unsigned highwater; /* First high water block */
|
||||
uint32_t headvbn; /* vbn for file header */
|
||||
uint32_t hiblock; /* Highest block mapped */
|
||||
uint32_t highwater; /* First high water block */
|
||||
unsigned char status; /* FCB status bits */
|
||||
#define FCB_WRITE 1 /* FCB open for write... */
|
||||
unsigned char rvn; /* Initial file relative volume */
|
||||
#define FCB_WRITTEN 2 /* Modified */
|
||||
#define FCB_RDTSET 4 /* Revision date set by create */
|
||||
|
||||
uint8_t 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 */
|
||||
struct fiddef parent;
|
||||
struct dir$r_ent entry;
|
||||
struct dir$r_rec record;
|
||||
};
|
||||
|
||||
#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 */
|
||||
uint32_t clustersize; /* Cluster size of the device */
|
||||
uint32_t max_cluster; /* Total clusters on the device */
|
||||
uint32_t free_clusters; /* Free clusters on disk volume */
|
||||
struct HOME home; /* Volume home block */
|
||||
};
|
||||
struct VCB {
|
||||
@@ -89,35 +96,66 @@ void show_volumes( void );
|
||||
|
||||
/* returns NULL if RVN illegal or device not mounted */
|
||||
|
||||
#define RVN_TO_DEV( vcb, rvn ) ( ( rvn < 2 ) ? \
|
||||
vcb->vcbdev : \
|
||||
( ( rvn <= vcb->devices ) ? \
|
||||
&vcb->vcbdev[rvn - 1] : \
|
||||
NULL \
|
||||
) \
|
||||
)
|
||||
#define RVN_TO_DEV( vcb, rvn ) ( ( rvn < 2 ) ? \
|
||||
vcb->vcbdev : \
|
||||
( ( rvn <= vcb->devices ) ? \
|
||||
&vcb->vcbdev[rvn - 1] : \
|
||||
NULL \
|
||||
) \
|
||||
)
|
||||
|
||||
void fid_copy(struct fiddef *dst,struct fiddef *src,unsigned rvn);
|
||||
struct NEWFILE {
|
||||
struct RECATTR recattr;
|
||||
VMSTIME credate;
|
||||
VMSTIME revdate;
|
||||
VMSTIME expdate;
|
||||
VMSTIME bakdate;
|
||||
f11word verlimit;
|
||||
f11word revision;
|
||||
uint32_t fileprot;
|
||||
f11long filechar;
|
||||
struct UIC fileowner;
|
||||
};
|
||||
|
||||
unsigned dismount(struct VCB *vcb);
|
||||
unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[] );
|
||||
void fid_copy( struct fiddef *dst, struct fiddef *src, unsigned rvn );
|
||||
|
||||
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);
|
||||
vmscond_t dismount( struct VCB *vcb, options_t options);
|
||||
vmscond_t mount( options_t flags, unsigned devices, char *devnam[], char *label[] );
|
||||
|
||||
vmscond_t accesserase( struct VCB *vcb, struct fiddef *fid );
|
||||
vmscond_t deaccessfile( struct FCB *fcb );
|
||||
vmscond_t accessfile( struct VCB *vcb, struct fiddef *fid,
|
||||
struct FCB **fcb, unsigned wrtflg );
|
||||
|
||||
vmscond_t deaccesschunk( struct VIOC *vioc, uint32_t wrtvbn, int wrtblks, int reuse );
|
||||
vmscond_t accesschunk( struct FCB *fcb, uint32_t vbn, struct VIOC **retvioc,
|
||||
char **retbuff, uint32_t *retblocks, uint32_t wrtblks );
|
||||
vmscond_t access_extend( struct FCB *fcb, uint32_t blocks, unsigned contig );
|
||||
|
||||
vmscond_t deallocfile(struct FCB *fcb);
|
||||
|
||||
unsigned deaccesschunk(struct VIOC *vioc,unsigned wrtvbn,int wrtblks,int reuse);
|
||||
unsigned accesschunk(struct FCB *fcb,unsigned vbn,struct VIOC **retvioc,
|
||||
char **retbuff,unsigned *retblocks,unsigned wrtblks);
|
||||
unsigned access_extend(struct FCB *fcb,unsigned blocks,unsigned contig);
|
||||
unsigned update_freecount(struct VCBDEV *vcbdev,unsigned *retcount);
|
||||
unsigned update_create(struct VCB *vcb,struct fiddef *did,char *filename,
|
||||
struct fiddef *fid,struct FCB **fcb);
|
||||
unsigned update_extend(struct FCB *fcb,unsigned blocks,unsigned contig);
|
||||
f11word checksumn( f11word *block, int count );
|
||||
f11word checksum( f11word *block );
|
||||
|
||||
void access_rundown( void );
|
||||
|
||||
/* These live in update.c, which contains the write part of access */
|
||||
|
||||
vmscond_t update_freecount( struct VCBDEV *vcbdev, uint32_t *retcount );
|
||||
vmscond_t update_create( struct VCB *vcb, struct fiddef *did, char *filename,
|
||||
struct fiddef *fid, struct NEWFILE *attrs, struct FCB **fcb );
|
||||
vmscond_t update_extend( struct FCB *fcb, uint32_t blocks, unsigned contig );
|
||||
|
||||
vmscond_t update_truncate( struct FCB *fcb, uint32_t newsize );
|
||||
|
||||
/* These are used by update.c */
|
||||
|
||||
vmscond_t deaccesshead( struct VIOC *vioc, struct HEAD *head, uint32_t idxblk );
|
||||
vmscond_t accesshead( struct VCB *vcb, struct fiddef *fid, uint32_t seg_num,
|
||||
struct VIOC **vioc, struct HEAD **headbuff,
|
||||
uint32_t *retidxblk, unsigned wrtflg );
|
||||
vmscond_t getwindow( struct FCB * fcb, uint32_t vbn, struct VCBDEV **devptr,
|
||||
uint32_t *phyblk, uint32_t *phylen, struct fiddef *hdrfid,
|
||||
uint32_t *hdrseq );
|
||||
|
||||
#endif /* # ifndef _ACCESS_H */
|
||||
|
||||
@@ -4,7 +4,7 @@ $
|
||||
$ default = F$Environment( "DEFAULT" )
|
||||
$ this = F$Environment( "PROCEDURE" )
|
||||
$ src = F$Parse( this, , , "DEVICE", "SYNTAX_ONLY" ) + -
|
||||
F$Parse( this, , , "DIRECTORY", "SYNTAX_ONLY" )
|
||||
F$Parse( this, , , "DIRECTORY", "SYNTAX_ONLY" )
|
||||
$
|
||||
$ If ( P1 .eqs. "CLEAN" )
|
||||
$ Then
|
||||
|
||||
@@ -1,50 +1,53 @@
|
||||
/* Cache.c 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.
|
||||
*/
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
/*
|
||||
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, file windows, file chunks
|
||||
(segments) 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).
|
||||
|
||||
The main routines is cache_find() which is used to search for and
|
||||
place objects in a binary tree which is located by a tree pointer.
|
||||
cache_touch() and cache_untouch() are used to bump and decrement
|
||||
reference counts. Any object with a reference count of zero is a
|
||||
candidate for destruction - but if it requires special action
|
||||
before it is destroyed, such as deleting a subtree, flushing data
|
||||
to disk, etc, then it should have an 'object manager' function
|
||||
assigned which will be called at deletion time to take care of these
|
||||
needs.
|
||||
|
||||
This version of the cache routines attempts to maintain binary tree
|
||||
balance by dynamically changing tree shape during search functions.
|
||||
All objects remain in the binary tree until destruction so that they
|
||||
can be re-used at any time. Objects with a zero reference count are
|
||||
special in that they are kept in a 'least recently used' linked list.
|
||||
When the reference count is decemented a flag is used to indicate
|
||||
whether the object is likely to be referenced again so that the object
|
||||
can be put in the 'correct' end of this list.
|
||||
|
||||
Note: These routines are 'general' in that do not know anything
|
||||
about ODS2 objects or structures....
|
||||
*/
|
||||
* 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, file windows, file chunks
|
||||
* (segments) 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).
|
||||
*
|
||||
* The main routines is cache_find() which is used to search for and
|
||||
* place objects in a binary tree which is located by a tree pointer.
|
||||
* cache_touch() and cache_untouch() are used to bump and decrement
|
||||
* reference counts. Any object with a reference count of zero is a
|
||||
* candidate for destruction - but if it requires special action
|
||||
* before it is destroyed, such as deleting a subtree, flushing data
|
||||
* to disk, etc, then it should have an 'object manager' function
|
||||
* assigned which will be called at deletion time to take care of these
|
||||
* needs.
|
||||
*
|
||||
* This version of the cache routines attempts to maintain binary tree
|
||||
* balance by dynamically changing tree shape during search functions.
|
||||
* All objects remain in the binary tree until destruction so that they
|
||||
* can be re-used at any time. Objects with a zero reference count are
|
||||
* special in that they are kept in a 'least recently used' linked list.
|
||||
* When the reference count is decemented a flag is used to indicate
|
||||
* whether the object is likely to be referenced again so that the object
|
||||
* can be put in the 'correct' end of this list.
|
||||
*
|
||||
* Note: These routines are 'general' in that do not know anything
|
||||
* about ODS2 objects or structures....
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_CACHE )
|
||||
#define DEBUG DEBUG_CACHE
|
||||
@@ -80,7 +83,7 @@ static int cachedeletes = 0;
|
||||
|
||||
static int cachedeleteing = FALSE; /* Cache deletion in progress... */
|
||||
|
||||
struct CACHE lrulist = {&lrulist,&lrulist,NULL,NULL,NULL,NULL,0,0,1,0};
|
||||
struct CACHE lrulist = {&lrulist, &lrulist, NULL, NULL, NULL, NULL, 0, 0, 1, 0};
|
||||
|
||||
static void cache_deleter( struct CACHE *cacheobj, struct CACHE **actualobj );
|
||||
|
||||
@@ -91,10 +94,10 @@ static void cache_deleter( struct CACHE *cacheobj, struct CACHE **actualobj );
|
||||
void cache_show(void)
|
||||
{
|
||||
printf("CACHE_SHOW Find %d Create %d Purge %d Peak %d Count %d Free %d\n",
|
||||
cachefinds,cachecreated,cachepurges,cachepeak,cachecount,
|
||||
cachefinds, cachecreated, cachepurges, cachepeak, cachecount,
|
||||
cachefreecount);
|
||||
if (cachecreated - cachedeletes != cachecount) {
|
||||
printf(" - Deleted %d\n",cachedeletes);
|
||||
printf(" - Deleted %d\n", cachedeletes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,10 +105,10 @@ void cache_show(void)
|
||||
|
||||
/* cache_refcount() - compute reference count for cache subtree... */
|
||||
|
||||
int cache_refcount(struct CACHE *cacheobj)
|
||||
{
|
||||
int cache_refcount( struct CACHE *cacheobj ) {
|
||||
register int refcount = 0;
|
||||
if (cacheobj != NULL) {
|
||||
|
||||
if( cacheobj != NULL ) {
|
||||
refcount = cacheobj->refcount;
|
||||
if (cacheobj->left != NULL) {
|
||||
refcount += cache_refcount(cacheobj->left);
|
||||
@@ -134,7 +137,7 @@ static void cache_deleter( struct CACHE *cacheobj, struct CACHE **actualobj ) {
|
||||
while (cacheobj->objmanager != NULL) {
|
||||
register struct CACHE *proxyobj;
|
||||
cachedeleteing = TRUE;
|
||||
proxyobj = (*cacheobj->objmanager) (cacheobj,FALSE);
|
||||
proxyobj = (*cacheobj->objmanager) (cacheobj, FALSE);
|
||||
cachedeleteing = FALSE;
|
||||
if( proxyobj == NULL ) {
|
||||
if( actualobj != NULL )
|
||||
@@ -145,12 +148,13 @@ static void cache_deleter( struct CACHE *cacheobj, struct CACHE **actualobj ) {
|
||||
cacheobj = proxyobj;
|
||||
}
|
||||
#if DEBUG
|
||||
if (cachedeleteing) printf("CACHE deletion while delete in progress\n");
|
||||
if (cachedeleteing)
|
||||
printf("CACHE deletion while delete in progress\n");
|
||||
#endif
|
||||
if (cacheobj->refcount != 0) {
|
||||
#if DEBUG
|
||||
printf("CACHE attempt to delete referenced object %d:%d\n",
|
||||
cacheobj->objtype,cacheobj->hashval);
|
||||
cacheobj->objtype, cacheobj->hashval);
|
||||
#endif
|
||||
abort();
|
||||
if( actualobj != NULL )
|
||||
@@ -206,20 +210,24 @@ static void cache_deleter( struct CACHE *cacheobj, struct CACHE **actualobj ) {
|
||||
*actualobj = cacheobj;
|
||||
|
||||
free(cacheobj); /* This may be the supplied object, or it may have been replaced by a proxy. */
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************** cache_purge() */
|
||||
|
||||
/* cache_purge() - trim size of free list */
|
||||
|
||||
void cache_purge(int all)
|
||||
{
|
||||
void cache_purge( int all ) {
|
||||
if (!cachedeleteing) {
|
||||
register struct CACHE *cacheobj = lrulist.lastlru;
|
||||
register struct CACHE *cacheobj;
|
||||
|
||||
cacheobj = lrulist.lastlru;
|
||||
cachepurges++;
|
||||
while ( (all || cachefreecount > CACHEGOAL) && cacheobj != &lrulist) {
|
||||
register struct CACHE *lastobj = cacheobj->lastlru;
|
||||
|
||||
while( (all || cachefreecount > CACHEGOAL) && cacheobj != &lrulist ) {
|
||||
register struct CACHE *lastobj;
|
||||
|
||||
lastobj = cacheobj->lastlru;
|
||||
#if DEBUG
|
||||
if (cacheobj->lastlru->nextlru != cacheobj ||
|
||||
cacheobj->nextlru->lastlru != cacheobj ||
|
||||
@@ -242,14 +250,16 @@ void cache_purge(int all)
|
||||
|
||||
/* cache_flush() - flush modified entries in cache */
|
||||
|
||||
void cache_flush(void)
|
||||
{
|
||||
register struct CACHE *cacheobj = lrulist.lastlru;
|
||||
while (cacheobj != &lrulist) {
|
||||
void cache_flush(void) {
|
||||
register struct CACHE *cacheobj;
|
||||
|
||||
for( cacheobj = lrulist.lastlru;
|
||||
cacheobj != &lrulist;
|
||||
cacheobj = cacheobj->lastlru ) {
|
||||
|
||||
if (cacheobj->objmanager != NULL) {
|
||||
(*cacheobj->objmanager) (cacheobj,TRUE);
|
||||
(*cacheobj->objmanager) (cacheobj, TRUE);
|
||||
}
|
||||
cacheobj = cacheobj->lastlru;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,11 +267,12 @@ void cache_flush(void)
|
||||
|
||||
/* cache_remove() - delete all possible objects from cache subtree */
|
||||
|
||||
void cache_remove(struct CACHE *cacheobj)
|
||||
{
|
||||
void cache_remove( struct CACHE *cacheobj ) {
|
||||
if (cacheobj != NULL) {
|
||||
if (cacheobj->left != NULL) cache_remove(cacheobj->left);
|
||||
if (cacheobj->right != NULL) cache_remove(cacheobj->right);
|
||||
if (cacheobj->left != NULL)
|
||||
cache_remove(cacheobj->left);
|
||||
if (cacheobj->right != NULL)
|
||||
cache_remove(cacheobj->right);
|
||||
if (cacheobj->refcount == 0) {
|
||||
struct CACHE *delobj;
|
||||
do {
|
||||
@@ -275,8 +286,7 @@ void cache_remove(struct CACHE *cacheobj)
|
||||
|
||||
/* cache_touch() - to increase the access count on an object... */
|
||||
|
||||
void cache_touch(struct CACHE *cacheobj)
|
||||
{
|
||||
void cache_touch(struct CACHE *cacheobj) {
|
||||
if (cacheobj->refcount++ == 0) {
|
||||
#if DEBUG
|
||||
if (cacheobj->nextlru == NULL || cacheobj->lastlru == NULL) {
|
||||
@@ -294,19 +304,23 @@ void cache_touch(struct CACHE *cacheobj)
|
||||
|
||||
/************************************************************ cache_untouch() */
|
||||
|
||||
/* cache_untouch() - to deaccess an object... */
|
||||
/* Deaccess an object.
|
||||
* Recycle => TRUE puts object at front of LRU list, indicating that
|
||||
* it's likely to be reused soon. Note that untouch() can
|
||||
* trigger a purge, so the object can be deleted on return.
|
||||
* This won't happen if recycle is TRUE because purge will maintain
|
||||
* CACHEGOAL LRU entries, which must be non-zero.
|
||||
*/
|
||||
|
||||
void cache_untouch(struct CACHE *cacheobj,int recycle)
|
||||
{
|
||||
if (cacheobj->refcount > 0) {
|
||||
if (--cacheobj->refcount == 0) {
|
||||
if (++cachefreecount >= CACHELIM) cache_purge(FALSE);
|
||||
void cache_untouch( struct CACHE *cacheobj, int recycle ) {
|
||||
if( cacheobj->refcount > 0 ) {
|
||||
if( --cacheobj->refcount == 0 ) {
|
||||
#if DEBUG
|
||||
if (cacheobj->nextlru != NULL || cacheobj->lastlru != NULL) {
|
||||
if( cacheobj->nextlru != NULL || cacheobj->lastlru != NULL ) {
|
||||
printf("CACHE LRU pointers corrupt\n");
|
||||
}
|
||||
#endif
|
||||
if (recycle) {
|
||||
if( recycle ) {
|
||||
cacheobj->nextlru = lrulist.nextlru;
|
||||
cacheobj->lastlru = &lrulist;
|
||||
cacheobj->nextlru->lastlru = cacheobj;
|
||||
@@ -317,6 +331,8 @@ void cache_untouch(struct CACHE *cacheobj,int recycle)
|
||||
cacheobj->lastlru->nextlru = cacheobj;
|
||||
lrulist.lastlru = cacheobj;
|
||||
}
|
||||
if( ++cachefreecount >= CACHELIM )
|
||||
cache_purge(FALSE);
|
||||
}
|
||||
} else {
|
||||
#if DEBUG
|
||||
@@ -329,43 +345,51 @@ void cache_untouch(struct CACHE *cacheobj,int recycle)
|
||||
/*************************************************************** cache_find() */
|
||||
|
||||
/* cache_find() - 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! :-)
|
||||
*
|
||||
* This version will call a creation function to allocate and
|
||||
* initialize an object if it is not found.
|
||||
*/
|
||||
|
||||
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! :-)
|
||||
|
||||
This version will call a creation function to allocate and
|
||||
initialize an object if it is not found.
|
||||
*/
|
||||
|
||||
void *cache_find( void **root, unsigned hashval, void *keyval, unsigned *retsts,
|
||||
int (*compare_func) ( unsigned hashval, void *keyval,
|
||||
void *cache_find( void **root, uint32_t hashval, void *keyval, vmscond_t *retsts,
|
||||
int (*compare_func) ( uint32_t hashval, void *keyval,
|
||||
void *node ),
|
||||
void *(*create_func) ( unsigned hashval, void *keyval,
|
||||
unsigned *retsts ) ) {
|
||||
void *(*create_func) ( uint32_t hashval, void *keyval,
|
||||
vmscond_t *retsts ) ) {
|
||||
|
||||
register struct CACHE *cacheobj,**parent = (struct CACHE **) root;
|
||||
register struct CACHE *cacheobj, **parent;
|
||||
|
||||
parent = (struct CACHE **) root;
|
||||
cachefinds++;
|
||||
while ((cacheobj = *parent) != NULL) {
|
||||
register int cmp = hashval - cacheobj->hashval;
|
||||
|
||||
while( (cacheobj = *parent) != NULL ) {
|
||||
register int cmp;
|
||||
|
||||
cmp = hashval - cacheobj->hashval;
|
||||
#if DEBUG
|
||||
if (cacheobj->parent != parent) {
|
||||
printf("CACHE Parent pointer is corrupt\n");
|
||||
}
|
||||
#endif
|
||||
if (cmp == 0 && compare_func != NULL) {
|
||||
cmp = (*compare_func) (hashval,keyval,cacheobj);
|
||||
cmp = (*compare_func) (hashval, keyval, cacheobj);
|
||||
}
|
||||
if (cmp == 0) {
|
||||
cache_touch(cacheobj);
|
||||
if (retsts != NULL) *retsts = SS$_NORMAL;
|
||||
if (retsts != NULL)
|
||||
*retsts = SS$_NORMAL;
|
||||
return cacheobj;
|
||||
}
|
||||
if (cmp < 0) {
|
||||
#ifdef IMBALANCE
|
||||
register struct CACHE *left_path = cacheobj->left;
|
||||
register struct CACHE *left_path;
|
||||
|
||||
left_path = cacheobj->left;
|
||||
if (left_path != NULL && cacheobj->balance-- < -IMBALANCE) {
|
||||
cacheobj->left = left_path->right;
|
||||
if (cacheobj->left != NULL) {
|
||||
@@ -380,7 +404,9 @@ void *cache_find( void **root, unsigned hashval, void *keyval, unsigned *retsts,
|
||||
parent = &cacheobj->left;
|
||||
}
|
||||
} else {
|
||||
register struct CACHE *right_path = cacheobj->right;
|
||||
register struct CACHE *right_path;
|
||||
|
||||
right_path = cacheobj->right;
|
||||
if (right_path != NULL && cacheobj->balance++ > IMBALANCE) {
|
||||
cacheobj->right = right_path->left;
|
||||
if (cacheobj->right != NULL) {
|
||||
@@ -402,9 +428,10 @@ void *cache_find( void **root, unsigned hashval, void *keyval, unsigned *retsts,
|
||||
}
|
||||
}
|
||||
if (create_func == NULL) {
|
||||
if (retsts != NULL) *retsts = SS$_ITEMNOTFOUND;
|
||||
if (retsts != NULL)
|
||||
*retsts = SS$_ITEMNOTFOUND;
|
||||
} else {
|
||||
cacheobj = (*create_func) (hashval,keyval,retsts);
|
||||
cacheobj = (*create_func) (hashval, keyval, retsts);
|
||||
if (cacheobj != NULL) {
|
||||
cacheobj->nextlru = NULL;
|
||||
cacheobj->lastlru = NULL;
|
||||
@@ -416,7 +443,8 @@ void *cache_find( void **root, unsigned hashval, void *keyval, unsigned *retsts,
|
||||
cacheobj->balance = 0;
|
||||
*parent = cacheobj;
|
||||
cachecreated++;
|
||||
if (cachecount++ >= cachepeak) cachepeak = cachecount;
|
||||
if (cachecount++ >= cachepeak)
|
||||
cachepeak = cachecount;
|
||||
}
|
||||
}
|
||||
return cacheobj;
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
/* Cache.h Definitions for cache 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.
|
||||
*/
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _CACHE_H
|
||||
#define _CACHE_H
|
||||
@@ -19,21 +22,24 @@
|
||||
#define signed signed
|
||||
#endif
|
||||
|
||||
#include "ods2.h"
|
||||
|
||||
struct CACHE {
|
||||
struct CACHE *nextlru; /* next object on least recently used list */
|
||||
struct CACHE *lastlru; /* last object on least recently used list */
|
||||
struct CACHE *left; /* left branch of binary tree */
|
||||
struct CACHE *right; /* right branch of binary tree */
|
||||
struct CACHE **parent; /* address of pointer to this object */
|
||||
void *(*objmanager) (struct CACHE * cacheobj,int flushonly);
|
||||
unsigned hashval; /* object hash value */
|
||||
void *(*objmanager) ( struct CACHE * cacheobj, int flushonly );
|
||||
uint32_t hashval; /* object hash value */
|
||||
short refcount; /* object reference count */
|
||||
signed char balance; /* object tree imbalance factor */
|
||||
signed char objtype; /* object type (for debugging) */
|
||||
#define OBJTYPE_DEV 1
|
||||
#define OBJTYPE_FCB 2
|
||||
#define OBJTYPE_WCB 3
|
||||
#define OBJTYPE_DEV 1
|
||||
#define OBJTYPE_FCB 2
|
||||
#define OBJTYPE_WCB 3
|
||||
#define OBJTYPE_VIOC 7
|
||||
#define OBJTYPE_DIR 8
|
||||
};
|
||||
|
||||
void cache_show(void);
|
||||
@@ -44,10 +50,10 @@ void cache_flush(void);
|
||||
void cache_remove(struct CACHE *cacheobj);
|
||||
void cache_touch(struct CACHE * cacheobj);
|
||||
void cache_untouch(struct CACHE * cacheobj,int recycle);
|
||||
void *cache_find( void **root, unsigned hashval, void *keyval, unsigned *retsts,
|
||||
int (*compare_func) ( unsigned hashval, void *keyval,
|
||||
void *cache_find( void **root, uint32_t hashval, void *keyval, vmscond_t *retsts,
|
||||
int (*compare_func) ( uint32_t hashval, void *keyval,
|
||||
void *node ),
|
||||
void *(*create_func) ( unsigned hashval, void *keyval,
|
||||
unsigned *retsts ) );
|
||||
void *(*create_func) ( uint32_t hashval, void *keyval,
|
||||
vmscond_t *retsts ) );
|
||||
|
||||
#endif /* #ifndef _CACHE_H */
|
||||
|
||||
@@ -2,21 +2,31 @@
|
||||
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CMDDEF_H
|
||||
#define _CMDDEF_H
|
||||
|
||||
#ifndef _BSD_SOURCE
|
||||
#define _BSD_SOURCE
|
||||
#endif
|
||||
#ifndef _DEFAULT_SOURCE
|
||||
#define _DEFAULT_SOURCE
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -38,11 +48,10 @@
|
||||
#include "sysmsg.h"
|
||||
|
||||
#define MAXREC 32767
|
||||
#define PRINT_ATTR ( FAB$M_CR | FAB$M_PRN | FAB$M_FTN )
|
||||
|
||||
#define DT_NAME "drive_type"
|
||||
#define DT_NAME "medium_type"
|
||||
|
||||
#define DECL_CMD(x) unsigned do ## x(int argc,char **argv,int qualc,char **qualv)
|
||||
#define DECL_CMD(x) vmscond_t do ## x(int argc,char **argv,int qualc,char **qualv)
|
||||
|
||||
typedef struct CMDSET CMDSET_t;
|
||||
typedef struct param param_t;
|
||||
@@ -52,11 +61,13 @@ typedef CMDSET_t *CMDSETp_t;
|
||||
typedef param_t *paramp_t;
|
||||
typedef qual_t *qualp_t;
|
||||
|
||||
typedef vmscond_t (*cmdproc_t) (int argc,char *argv[],int qualc,char *qualv[]);
|
||||
|
||||
/* Command table entry */
|
||||
|
||||
struct CMDSET {
|
||||
char *name;
|
||||
unsigned (*proc) (int argc,char *argv[],int qualc,char *qualv[]);
|
||||
cmdproc_t proc;
|
||||
int uniq;
|
||||
qualp_t validquals;
|
||||
paramp_t params;
|
||||
@@ -64,45 +75,132 @@ struct CMDSET {
|
||||
};
|
||||
|
||||
/* set, clear: bits specified are cleared, then set in value
|
||||
* qtype = qualifier's value type. + => value required, - optional, 0 none
|
||||
* Following macros simplify setting up the tables.
|
||||
* helpstr: if null, switch not listed in help. If starts with -,
|
||||
* listed as negatable in help
|
||||
* listed as negatable in help. If null string (""), listed
|
||||
* as value table. Otherwise, .hlp file lookup key.
|
||||
*/
|
||||
#define NV NOVAL, NULL
|
||||
#define KV(list) KEYVAL, list
|
||||
#define CV(list) KEYCOL, list
|
||||
#define DV(val) DECVAL, val
|
||||
#define SV(val) STRVAL, ((void *)val)
|
||||
#define PV(val) PROT, ((void *)val)
|
||||
#define UV(val) UIC, ((void *)val)
|
||||
|
||||
/* Use VOPT(XX()) for optional value */
|
||||
#define VOPT(def) -def
|
||||
|
||||
struct qual {
|
||||
const char *name;
|
||||
int set;
|
||||
int clear;
|
||||
enum qualtype { NOVAL, KEYVAL, KEYCOL, DECVAL, STRVAL } qtype;
|
||||
options_t set;
|
||||
options_t clear;
|
||||
enum qualtype { opt_optional = -1, NOVAL = 0, /* enum must be signed */
|
||||
KEYVAL, KEYCOL, DECVAL, STRVAL, PROT, UIC } qtype;
|
||||
void *arg;
|
||||
const char *helpstr;
|
||||
char *helpstr;
|
||||
};
|
||||
|
||||
typedef const char *(hlpfunc_t)( CMDSET_t *cmd, param_t *p, int argc, char **argv );
|
||||
|
||||
struct param {
|
||||
const char *name;
|
||||
enum parflags { REQ, OPT, CND } flags;
|
||||
enum partype { VMSFS, LCLFS, LIST, KEYWD, STRING, CMDNAM, NONE } ptype;
|
||||
enum parflags { REQ = 1, OPT = 2, CND = 4, NOLIM = 8 } flags;
|
||||
enum partype { NONE = 0, FSPEC, LIST, KEYWD, QUALS, STRING } ptype;
|
||||
#define PA(arg) NULL, (arg)
|
||||
#define NOPA PA(NULL)
|
||||
hlpfunc_t *hlpfnc;
|
||||
void *arg;
|
||||
const char *helpstr;
|
||||
char *helpstr;
|
||||
};
|
||||
|
||||
extern int vms_qual;
|
||||
/* Default qualifer sets */
|
||||
|
||||
struct defquals {
|
||||
struct defquals *next;
|
||||
int qualc;
|
||||
char **qualv;
|
||||
char *data[1];
|
||||
};
|
||||
|
||||
typedef struct defquals defquals_t;
|
||||
typedef defquals_t *defqualsp_t;
|
||||
|
||||
extern const char *qstyle_s;
|
||||
#define qstyle_c (qstyle_s[0])
|
||||
|
||||
extern int verify_cmd;
|
||||
extern int error_exit;
|
||||
|
||||
vmscond_t parselist( int *nret, char ***items, size_t min, char *arg );
|
||||
vmscond_t checkquals( options_t *result, options_t defval,
|
||||
qualp_t qualset, int qualc,char **qualv );
|
||||
|
||||
int parselist( char ***items, size_t min, char *arg, const char *label );
|
||||
int checkquals( int result, qual_t qualset[],int qualc,char *qualv[] );
|
||||
int keycomp(const char *param, const char *keywrd);
|
||||
char *fgetline( FILE *stream, int keepnl );
|
||||
vmscond_t confirm_cmd( vmscond_t status, ... );
|
||||
|
||||
int prvmstime(VMSTIME vtime, const char *sfx);
|
||||
void pwrap( int *pos, const char *fmt, ... );
|
||||
vmscond_t sethelpfile( char *filename, char *env, char *pname );
|
||||
vmscond_t showhelpfile( void );
|
||||
|
||||
vmscond_t helptopic( options_t options, char *topic, ... );
|
||||
#define HLP_OPTIONAL 0x00000001
|
||||
#define HLP_WRAP 0x00000002
|
||||
#define HLP_RELOAD 0x00000004
|
||||
#define HLP_ABBREV 0x00000008
|
||||
|
||||
typedef struct pause {
|
||||
size_t interval;
|
||||
size_t lineno;
|
||||
vmscond_t prompt;
|
||||
} pause_t;
|
||||
|
||||
vmscond_t put_c( int c, FILE *outf, pause_t *pause );
|
||||
vmscond_t put_str( const char *buf, FILE *outf, pause_t *pause );
|
||||
vmscond_t put_strn( const char *buf, size_t len, FILE *outf, pause_t *pause );
|
||||
void termchar( int *width, int *height );
|
||||
|
||||
vmscond_t prvmstime(FILE *of, VMSTIME vtime, const char *sfx);
|
||||
void pwrap( FILE *of, int *pos, const char *fmt, ... );
|
||||
|
||||
#ifdef HELPFILEDEFS
|
||||
/* File and index structures private to helpcmd and makehelp. */
|
||||
|
||||
/* Helpfile magic cookie, version & header */
|
||||
|
||||
#define HLP_MAGIC "ODS2HLP"
|
||||
#define HLP_VERSION 1
|
||||
|
||||
typedef struct hlphdr {
|
||||
char magic[ sizeof(HLP_MAGIC) ];
|
||||
uint32_t version;
|
||||
uint32_t psize, ssize, tsize;
|
||||
time_t ddate;
|
||||
size_t size;
|
||||
} hlphdr_t;
|
||||
|
||||
/* In-memory pointer / file offsets */
|
||||
|
||||
typedef union ptr {
|
||||
void *ptr;
|
||||
ptrdiff_t ofs;
|
||||
} ptr_t;
|
||||
|
||||
/* Help tree topic nodes (including root) */
|
||||
|
||||
typedef struct hlproot {
|
||||
ptr_t topics; /*struct hlptopic * */
|
||||
size_t ntopics;
|
||||
} hlproot_t;
|
||||
|
||||
/* Help topic data under each node */
|
||||
|
||||
typedef struct hlptopic {
|
||||
ptr_t key; /* char * */
|
||||
ptr_t text; /* char * */
|
||||
hlproot_t subtopics;
|
||||
uint32_t keylen;
|
||||
} hlptopic_t;
|
||||
|
||||
#endif /* HELPFILEDEFS */
|
||||
#endif
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
/* This module contains compatibility code, currently just
|
||||
@@ -35,6 +38,7 @@
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -48,6 +52,7 @@
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <shlwapi.h> /* PathSearchAndQualify() */
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@@ -119,21 +124,20 @@ const char *ods2_strerror( int errn ) {
|
||||
|
||||
TCHAR *w32_errstr( DWORD eno, ... ) {
|
||||
va_list ap;
|
||||
TCHAR *msg;
|
||||
TCHAR *msg = NULL;
|
||||
|
||||
if( eno == NO_ERROR )
|
||||
eno = GetLastError();
|
||||
va_start(ap,eno);
|
||||
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 );
|
||||
msg = (TCHAR *)malloc( 64 );
|
||||
if( msg == NULL ) {
|
||||
perror( "malloc" );
|
||||
printf( "Original error number (%u)\n", eno );
|
||||
printf( "Out of memory reporting Windows error(%u\n", eno );
|
||||
} else
|
||||
(void) snprintf( msg, 32, "(%u)", eno );
|
||||
(void) snprintf( msg, 64, "(%u)", eno );
|
||||
}
|
||||
va_end(ap);
|
||||
return msg;
|
||||
@@ -143,7 +147,7 @@ TCHAR *w32_errstr( DWORD eno, ... ) {
|
||||
|
||||
char *driveFromLetter( const char *letter ) {
|
||||
DWORD rv = ERROR_INSUFFICIENT_BUFFER;
|
||||
size_t cs = 16;
|
||||
DWORD cs = 16;
|
||||
TCHAR *bufp = NULL;
|
||||
|
||||
do {
|
||||
@@ -180,7 +184,7 @@ char *get_env( const char *name ) {
|
||||
return NULL;
|
||||
if ((r = malloc( i )) == NULL )
|
||||
return NULL;
|
||||
(void)getenv_s( &i, r, i, "USERNAME" );
|
||||
(void)getenv_s( &i, r, i, name );
|
||||
return r;
|
||||
#else
|
||||
char *t;
|
||||
@@ -207,10 +211,12 @@ char *get_username( void ) {
|
||||
size_t i;
|
||||
#ifdef VMS
|
||||
char uame[12 + 1] = "UNKNOWN ";
|
||||
struct dsc$descriptor_s userdsc = { sizeof( uname ) - 1, DSC$K_DTYPE_T, DSC$K_CLASS_S, uname };
|
||||
struct dsc$descriptor_s userdsc = { sizeof( uname ) - 1,
|
||||
DSC$K_DTYPE_T,
|
||||
DSC$K_CLASS_S, uname };
|
||||
|
||||
r = "UNKNOWN";
|
||||
if( lib$getjpi( &JPI$_USERNAME, 0, 0, 0, &userdsc, 0 ) & STS$M_SUCCESS ) {
|
||||
if( $SUCCESSFUL(lib$getjpi( &JPI$_USERNAME, 0, 0, 0, &userdsc, 0 )) ) {
|
||||
for( i = sizeof( uname ) - 1; i >= 0; i-- ) {
|
||||
if( uname[i] == ' ' )
|
||||
uname[i] = '\0';
|
||||
@@ -251,3 +257,194 @@ char *get_username( void ) {
|
||||
memcpy( username, r, i + 1 );
|
||||
return username;
|
||||
}
|
||||
|
||||
/******************************************************************* homefile () */
|
||||
|
||||
char *homefile( int dotfile, const char *filename, const char *ext ) {
|
||||
char * prefix, *delim, *name;
|
||||
size_t pfxlen, dellen, namlen, extlen;
|
||||
|
||||
#ifdef _WIN32
|
||||
char *drive;
|
||||
|
||||
prefix = drive = get_env( "HOMEDRIVE" );
|
||||
if( drive != NULL ) {
|
||||
prefix = get_env( "HOMEPATH" );
|
||||
if( prefix != NULL ) {
|
||||
dellen = strlen( drive );
|
||||
pfxlen = strlen( prefix );
|
||||
if( (name = malloc( dellen + pfxlen + 1 )) == NULL ) {
|
||||
free( prefix );
|
||||
free( drive );
|
||||
return NULL;
|
||||
}
|
||||
memcpy( name, drive, dellen );
|
||||
memcpy( name+dellen, prefix, pfxlen +1 );
|
||||
free( prefix );
|
||||
prefix = name;
|
||||
}
|
||||
free( drive );
|
||||
}
|
||||
delim = dotfile? "\\.": "\\";
|
||||
#elif defined( VMS )
|
||||
prefix = get_env( "SYS$LOGIN" );
|
||||
delim = dotfile? "_": "";
|
||||
#else
|
||||
prefix = get_env( "HOME" );
|
||||
delim = dotfile? "/." : "/";
|
||||
#endif
|
||||
pfxlen = prefix? strlen( prefix ) : 0;
|
||||
dellen = strlen( delim );
|
||||
namlen = strlen( filename );
|
||||
extlen = ext? strlen( ext ) : 0;
|
||||
|
||||
if( (name = malloc( pfxlen+dellen+namlen+extlen+1)) == NULL )
|
||||
return NULL;
|
||||
/* N.B. There is no buffer overrun here */
|
||||
if( pfxlen )
|
||||
memcpy( name, prefix, pfxlen );
|
||||
memcpy( name+pfxlen, delim, dellen );
|
||||
memcpy( name+pfxlen+dellen, filename, namlen+1 );
|
||||
if( ext )
|
||||
memcpy( name+pfxlen+dellen+namlen, ext, extlen+1 );
|
||||
free( prefix );
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/************************************************************* get_realpath() */
|
||||
|
||||
char *get_realpath( const char *filnam ) {
|
||||
#ifdef _WIN32
|
||||
size_t n;
|
||||
char *path, resultant_path[MAX_PATH];
|
||||
|
||||
if ( filnam == NULL || strpbrk( filnam, "*?" ) != NULL ||
|
||||
!PathSearchAndQualify( filnam, /* pcszPath */
|
||||
resultant_path, /* pszFullyQualifiedPath */
|
||||
/* cchFullyQualifiedPath */
|
||||
sizeof( resultant_path )
|
||||
) ) {
|
||||
return NULL;
|
||||
}
|
||||
n = strlen( resultant_path );
|
||||
path = (char *) malloc( n + 1 );
|
||||
if ( path != NULL ) {
|
||||
memcpy( path, resultant_path, n + 1 );
|
||||
}
|
||||
return path;
|
||||
#elif defined VMS
|
||||
#define MAXPATH 255
|
||||
size_t n;
|
||||
unsigned short resultant_path[1 + ( ( MAXPATH + 1 ) / 2)];
|
||||
char *path;
|
||||
unsigned long context, sts, flags;
|
||||
struct dsc$descriptor filespec = {
|
||||
0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL
|
||||
};
|
||||
struct dsc$descriptor resultant_filespec = {
|
||||
MAXPATH, DSC$K_DTYPE_T, DSC$K_CLASS_VS, (char *) resultant_path
|
||||
};
|
||||
|
||||
path = NULL;
|
||||
if ( filnam != NULL ) {
|
||||
filespec.dsc$w_length = strlen( filnam );
|
||||
filespec.dsc$a_pointer = (char *) filnam;
|
||||
*resultant_path = 0;
|
||||
context = 0;
|
||||
flags = LIB$M_FIL_NOWILD;
|
||||
sts = lib$find_file( &filespec, &resultant_filespec, &context,
|
||||
NULL, NULL, &sts, &flags );
|
||||
lib$find_file_end( &context );
|
||||
if( $SUCCESSFUL(sts) ) {
|
||||
n = *resultant_path;
|
||||
path = (char *) malloc( n + 1 );
|
||||
if ( path != NULL ) {
|
||||
memcpy( path, resultant_path + 1, n );
|
||||
path[n] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
return path;
|
||||
#elif defined unix || 1
|
||||
size_t n;
|
||||
char *path, resolved_path[PATH_MAX+1];
|
||||
|
||||
if ( filnam == NULL || realpath( filnam, resolved_path ) == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
n = strlen( resolved_path );
|
||||
path = (char *) malloc( n + 1 );
|
||||
if ( path != NULL ) {
|
||||
memcpy( path, resolved_path, n + 1 );
|
||||
}
|
||||
return path;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************** Ctime() */
|
||||
|
||||
char *Ctime( time_t *tval ) {
|
||||
char *buf;
|
||||
|
||||
#ifdef _WIN32
|
||||
if( (buf = malloc( 26 )) == NULL ) return NULL;
|
||||
if( ctime_s( buf, 26, tval ) != 0 ) {
|
||||
free( buf );
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
char *cbuf;
|
||||
|
||||
if( (buf = malloc( 25 )) == NULL ) return NULL;
|
||||
if( (cbuf = ctime( tval )) == NULL ) {
|
||||
free( buf );
|
||||
return NULL;
|
||||
}
|
||||
memcpy( buf, cbuf, 24 );
|
||||
#endif
|
||||
buf[24] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
/******************************************************************* fgetline() */
|
||||
/* Read a line of input - unlimited length
|
||||
* Removes \n, returns NULL at EOF
|
||||
* If *buf is NULL, one is allocated of size *bufsize.
|
||||
* Thereafter, it is reused. Expanded if necessary.
|
||||
* Caller responsible for free()
|
||||
*/
|
||||
char *fgetline( FILE *stream, int keepnl, char **buf, size_t *bufsize ) {
|
||||
int c;
|
||||
size_t idx = 0;
|
||||
|
||||
if( *buf == NULL && (*buf = malloc( *bufsize )) == NULL ) {
|
||||
perror( "malloc" );
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
while( (c = getc( stream )) != EOF && c != '\n' ) {
|
||||
if( idx + (keepnl != 0) +2 > *bufsize ) { /* Now + char + (? \n) + \0 */
|
||||
char *nbuf;
|
||||
*bufsize += 32;
|
||||
nbuf = (char *) realloc( *buf, *bufsize );
|
||||
if( nbuf == NULL ) {
|
||||
perror( "realloc" );
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
*buf = nbuf;
|
||||
}
|
||||
buf[0][idx++] = c;
|
||||
}
|
||||
if( c == '\n' ) {
|
||||
if( keepnl )
|
||||
buf[0][idx++] = '\n';
|
||||
} else {
|
||||
if( c == EOF && idx == 0 ) {
|
||||
buf[0][0] = '\0';
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
buf[0][idx] = '\0';
|
||||
return *buf;
|
||||
}
|
||||
|
||||
@@ -12,19 +12,22 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors.
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_H
|
||||
#define COMPAT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.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, ...);
|
||||
|
||||
@@ -43,7 +46,7 @@ FILE *openf( const char *filename, const char *mode );
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#undef getcwd
|
||||
#define getcwd _getcwd
|
||||
#define getcwd(_buf,_siz) _getcwd((_buf), (int)(_siz))
|
||||
#undef chdir
|
||||
#define chdir _chdir
|
||||
#undef tzset
|
||||
@@ -52,8 +55,15 @@ FILE *openf( const char *filename, const char *mode );
|
||||
#define setenv(name, value, overwrite) _putenv_s(name, value)
|
||||
#undef unsetenv
|
||||
#define unsetenv(name) _putenv_s(name,"")
|
||||
#undef unlink
|
||||
#define unlink _unlink
|
||||
#define Unlink _unlink
|
||||
#define Fileno(x) _fileno(x)
|
||||
#include <io.h>
|
||||
#include <sys/stat.h>
|
||||
#define Chmod _chmod
|
||||
#ifndef S_IREAD
|
||||
#define S_IREAD _S_IREAD
|
||||
#define S_IWRITE _S_IWRITE
|
||||
#endif
|
||||
|
||||
#undef strerror
|
||||
#define strerror(n) ods2_strerror(n)
|
||||
@@ -64,10 +74,17 @@ char *driveFromLetter( const char *letter );
|
||||
|
||||
#else /* Not WIN32 */
|
||||
#include <unistd.h>
|
||||
#define Unlink unlink
|
||||
#define Fileno(x) fileno(x)
|
||||
#define Chmod chmod
|
||||
#endif
|
||||
|
||||
char *get_username( void );
|
||||
char *get_env( const char *name );
|
||||
char *homefile( int dotfile, const char *filename, const char *ext );
|
||||
char *get_realpath( const char *filnam );
|
||||
char *Ctime( time_t *tval );
|
||||
char *fgetline( FILE *stream, int keepnl, char **buf, size_t *bufsize );
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,13 @@
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_CREATECMD )
|
||||
@@ -17,36 +20,654 @@
|
||||
|
||||
#include "cmddef.h"
|
||||
|
||||
#include "f11def.h"
|
||||
static vmscond_t create_directory( options_t options, int argc, char** argv );
|
||||
static vmscond_t create_file( options_t options, int argc, char** argv );
|
||||
|
||||
/******************************************************************* dotest() */
|
||||
|
||||
param_t createpars[] = { {"parameter", REQ, STRING, NOPA, "for create."},
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
/******************************************************************* docreate() */
|
||||
|
||||
#define create_log OPT_GENERIC_1
|
||||
#define create_dir OPT_GENERIC_2
|
||||
|
||||
#define create_owner OPT_GENERIC_3
|
||||
#define create_protect OPT_GENERIC_4
|
||||
#define create_volume OPT_GENERIC_5
|
||||
#define create_verlim OPT_GENERIC_6
|
||||
|
||||
#define create_recfmt (OPT_GENERIC_10|OPT_GENERIC_9|OPT_GENERIC_8)
|
||||
#define create_v_recfmt (OPT_V_GENERIC + 7)
|
||||
|
||||
#define create_b4 (OPT_SHARED_2|OPT_SHARED_1)
|
||||
#define create_v_b4 0
|
||||
|
||||
#define create_after (OPT_SHARED_4|OPT_SHARED_3)
|
||||
#define create_v_after 2
|
||||
|
||||
#define create_prn_none 0
|
||||
#define create_prn_nl 1
|
||||
#define create_prn_c0 2
|
||||
#define create_prn_vfu 3
|
||||
|
||||
#define create_prn OPT_SHARED_17
|
||||
#define create_ftn OPT_SHARED_18
|
||||
#define create_cr OPT_SHARED_19
|
||||
#define create_span OPT_SHARED_20
|
||||
|
||||
static uint32_t b4n, aftn;
|
||||
static uint32_t vfclen;
|
||||
static uint32_t reclen;
|
||||
static uint32_t verlimit;
|
||||
static uint32_t volume;
|
||||
static uint32_t protection;
|
||||
static uint32_t ownuic;
|
||||
|
||||
static qual_t
|
||||
prnb4[] = { {"none", create_prn_none << create_v_b4,
|
||||
create_b4, NV, "commands create qual_cc print b4 none"},
|
||||
{"nl", create_prn_nl << create_v_b4,
|
||||
create_b4, DV(&b4n), "commands create qual_cc print b4 nl"},
|
||||
{"ctl", create_prn_c0, create_b4, DV(&b4n), "commands create qual_cc print b4 ctl"},
|
||||
{"vfu", create_prn_vfu << create_v_b4,
|
||||
create_b4, DV(&b4n), "commands create qual_cc print b4 vfu"},
|
||||
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
static qual_t
|
||||
prnafter[] = { {"none", create_prn_none << create_v_after,
|
||||
create_after, NV, "commands create qual_cc print b4 none"},
|
||||
{"nl", create_prn_nl << create_v_after,
|
||||
create_after, DV(&aftn), "commands create qual_cc print b4 nl"},
|
||||
{"ctl", create_prn_c0, create_b4, DV(&aftn), "commands create qual_cc print b4 ctl"},
|
||||
{"vfu", create_prn_vfu << create_v_after,
|
||||
create_after, DV(&aftn), "commands create qual_cc print b4 vfu"},
|
||||
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
|
||||
#if 0
|
||||
extern struct VCB *test_vcb;
|
||||
#endif
|
||||
static qual_t
|
||||
prnkwds[] = { {"before", 0, create_b4, KV(prnb4), "commands create qual_cc print b4"},
|
||||
{"after", 0, create_after, KV(prnafter), "commands create qual_cc print after"},
|
||||
|
||||
/* docreate: you don't want to know! */
|
||||
{NULL, OPT_NOSORT, 0, NV, NULL}
|
||||
};
|
||||
|
||||
static qual_t
|
||||
cckwds[] = { {"fortran", create_ftn, create_cr|create_prn, NV,
|
||||
"commands create qual_cc fortran"},
|
||||
{"carriage_return", create_cr, create_ftn|create_prn, NV,
|
||||
"commands create qual_cc cr"},
|
||||
{"print", create_prn|(FAB$C_VFC<<create_v_recfmt),
|
||||
create_ftn|create_cr|create_recfmt, KV(prnkwds),
|
||||
"commands create qual_cc print"},
|
||||
{"none", 0, create_ftn|create_cr|create_prn, NV,
|
||||
"commands create qual_cc none"},
|
||||
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
|
||||
static qual_t
|
||||
fmtkwds[] = { {"fixed", (FAB$C_FIX +1) << create_v_recfmt,
|
||||
create_recfmt, DV(&reclen),
|
||||
"commands create qual_recfmt fixed"},
|
||||
{"variable", (FAB$C_VAR +1) << create_v_recfmt,
|
||||
create_recfmt, NV,
|
||||
"commands create qual_recfmt variable"},
|
||||
{"vfc", (FAB$C_VFC +1) << create_v_recfmt,
|
||||
create_recfmt, VOPT(DV(&vfclen)),
|
||||
"commands create qual_recfmt vfc"},
|
||||
{"stream", (FAB$C_STM +1) << create_v_recfmt,
|
||||
create_recfmt, NV,
|
||||
"commands create qual_recfmt stream"},
|
||||
{"streamlf", (FAB$C_STMLF +1) << create_v_recfmt,
|
||||
create_recfmt, NV,
|
||||
"commands create qual_recfmt streamlf"},
|
||||
{"streamcr", (FAB$C_STMCR +1) << create_v_recfmt,
|
||||
create_recfmt, NV,
|
||||
"commands create qual_recfmt streamcr"},
|
||||
{"undefined", (FAB$C_UDF +1) << create_v_recfmt,
|
||||
create_recfmt, NV,
|
||||
"commands create qual_recfmt undefined"},
|
||||
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
|
||||
qual_t
|
||||
createquals[] = { {"log", create_log, 0, NV,
|
||||
"-commands create qual_log"},
|
||||
{"nolog", 0, create_log, NV, NULL },
|
||||
{"directory", create_dir, 0, NV,
|
||||
"commands create qual_directory"},
|
||||
{"version_limit", create_verlim, 0, DV(&verlimit),
|
||||
"commands create qual_verlim"},
|
||||
#if 0
|
||||
{"volume", create_volume, 0, DV(&volume),
|
||||
"commands create qual_volume"},
|
||||
#endif
|
||||
{"owner_uic", create_owner, 0, UV(&ownuic),
|
||||
"commands create qual_owner" },
|
||||
{"protection", create_protect, 0, PV(&protection),
|
||||
"commands create qual_protection"},
|
||||
{"record_format", 0, 0, KV(fmtkwds),
|
||||
"commands create qual_recfmt"},
|
||||
{"carriage_control", 0, 0, KV(cckwds),
|
||||
"commands create qual_cc"},
|
||||
{"span", create_span, 0, NV, "commands create qual_span"},
|
||||
{"nospan", 0, create_span,NV, NULL},
|
||||
|
||||
{ NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
|
||||
param_t
|
||||
createpars[] = { {"parameter", REQ, STRING, NOPA, "commands create filespec"},
|
||||
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
};
|
||||
|
||||
DECL_CMD(create) {
|
||||
unsigned sts = 0;
|
||||
struct fiddef fid;
|
||||
vmscond_t sts;
|
||||
options_t options;
|
||||
|
||||
vfclen = 0;
|
||||
reclen = 0;
|
||||
|
||||
if( $FAILS(sts = checkquals( &options, create_span, createquals, qualc, qualv )) ) {
|
||||
return sts;
|
||||
}
|
||||
|
||||
if( options & create_dir )
|
||||
return create_directory( options, argc, argv );
|
||||
|
||||
return create_file( options, argc, argv );
|
||||
}
|
||||
|
||||
/******************************************************************* create_directory() */
|
||||
|
||||
static vmscond_t create_directory( options_t options, int argc, char **argv ) {
|
||||
vmscond_t sts;
|
||||
char tdir[NAM$C_MAXRSS+1],
|
||||
rsname[NAM$C_MAXRSS+1];
|
||||
struct FAB fab = cc$rms_fab;
|
||||
struct NAM nam = cc$rms_nam;
|
||||
|
||||
UNUSED(argc);
|
||||
UNUSED(qualc);
|
||||
UNUSED(qualv);
|
||||
|
||||
#if 0 /* Needs to call RMS, etc */
|
||||
sts = update_create( test_vcb, NULL, "Test.File", &fid, NULL );
|
||||
#else
|
||||
memset( &fid, 0, sizeof( struct fiddef ) );
|
||||
#endif
|
||||
printf( "Create status of %d (%s)\n", sts, argv[1] );
|
||||
do {
|
||||
int level;
|
||||
char newdir[NAM$C_MAXRSS + 1], *p;
|
||||
uint8_t newlen, devlen, newdirlen, tmplen, sfdlen;
|
||||
struct XABPRO parpro;
|
||||
struct XABFHC parfhc;
|
||||
|
||||
parpro = cc$rms_xabpro;
|
||||
parfhc = cc$rms_xabfhc;
|
||||
|
||||
nam.nam$b_ess = sizeof( newdir ) -1;
|
||||
nam.nam$l_esa = newdir;
|
||||
|
||||
nam.nam$b_rss = sizeof( rsname ) -1;
|
||||
nam.nam$l_rsa = rsname;
|
||||
|
||||
fab.fab$l_nam = &nam;
|
||||
|
||||
fab.fab$b_fac = 0;
|
||||
fab.fab$l_fop = FAB$M_OFP;
|
||||
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = (uint8_t)strlen(fab.fab$l_fna);
|
||||
|
||||
/* Check syntax & see if specified directory exists */
|
||||
|
||||
sts = sys_parse( &fab );
|
||||
|
||||
tdir[nam.nam$b_rsl] = '\0';
|
||||
newdir[nam.nam$b_esl] = '\0';
|
||||
|
||||
devlen = nam.nam$b_dev;
|
||||
newdirlen = nam.nam$b_dir;
|
||||
newlen = devlen + newdirlen;
|
||||
|
||||
if( $SUCCESSFUL(sts) &&
|
||||
!(nam.nam$l_fnb & (NAM$M_EXP_NAME | NAM$M_EXP_TYPE |
|
||||
NAM$M_EXP_VER | NAM$M_WILDCARD)) ) {
|
||||
rsname[newlen] = '\0';
|
||||
sts = printmsg( CREATE_EXISTS, 0, rsname );
|
||||
break;
|
||||
}
|
||||
if( $FAILED(sts) && !$MATCHCOND(sts, RMS$_DNF) ) {
|
||||
sts = printmsg( sts, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
if( nam.nam$l_fnb & (NAM$M_EXP_NAME | NAM$M_EXP_TYPE |
|
||||
NAM$M_EXP_VER | NAM$M_WILDCARD) ) {
|
||||
sts = printmsg( RMS$_DIR, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
/* Scan from MFD down to apply defaults and fill in missing
|
||||
* SFDs.
|
||||
*/
|
||||
p = newdir+devlen+1;
|
||||
memcpy( tdir, newdir, devlen );
|
||||
memcpy( tdir+devlen, "[000000]000000.DIR;1",
|
||||
sizeof( "[000000]000000.DIR;1" ) -1 );
|
||||
tmplen = sizeof( "[000000]" ) -1;
|
||||
sfdlen = sizeof( "000000" ) -1;
|
||||
level = 0;
|
||||
|
||||
fab.fab$b_fns =
|
||||
nam.nam$b_ess =
|
||||
fab.fab$b_dns = 0;
|
||||
nam.nam$l_rlf = NULL;
|
||||
nam.nam$b_nop = NAM$M_SYNCHK;
|
||||
(void) sys_parse( &fab ); /* Release context */
|
||||
fab.fab$l_nam = NULL;
|
||||
|
||||
fab.fab$l_fna = tdir;
|
||||
|
||||
sts = SS$_NORMAL;
|
||||
|
||||
while( TRUE ) {
|
||||
uint32_t directory;
|
||||
uint16_t retlen;
|
||||
struct XABFHC fhc;
|
||||
struct XABPRO pro;
|
||||
struct XABITM itm;
|
||||
struct item_list xitems[] = {
|
||||
{ XAB$_UCHAR_DIRECTORY, sizeof(int), NULL, 0 },
|
||||
{ 0, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
fhc = cc$rms_xabfhc;
|
||||
pro = cc$rms_xabpro;
|
||||
itm = cc$rms_xabitm;
|
||||
|
||||
itm.xab$l_nxt = &fhc;
|
||||
xitems[0].buffer = &directory; xitems[0].retlen = &retlen;
|
||||
|
||||
itm.xab$b_mode = XAB$K_SENSEMODE;
|
||||
itm.xab$l_itemlist = xitems;
|
||||
|
||||
pro.xab$l_nxt = &itm;
|
||||
fab.fab$l_xab = &pro;
|
||||
|
||||
fab.fab$b_fns = devlen+tmplen+sfdlen+6;
|
||||
|
||||
tdir[fab.fab$b_fns] = '\0';
|
||||
if( $SUCCESSFUL(sys_open(&fab)) ) {
|
||||
fab.fab$l_xab = NULL;
|
||||
sys_close( &fab );
|
||||
if( !directory ) {
|
||||
sts = printmsg( CREATE_NOTDIR, 0, tdir );
|
||||
break;
|
||||
}
|
||||
parpro = pro;
|
||||
parfhc = fhc;
|
||||
} else {
|
||||
struct FAB nfab = cc$rms_fab;
|
||||
struct NAM nam = cc$rms_nam;
|
||||
struct XABALL all = cc$rms_xaball;
|
||||
|
||||
all.xab$l_alq = 1;
|
||||
if( options & create_volume )
|
||||
all.xab$w_vol = (uint16_t)volume;
|
||||
|
||||
fhc = parfhc;
|
||||
if( options & create_verlim )
|
||||
fhc.xab$w_verlimit = verlimit;
|
||||
|
||||
fhc.xab$l_nxt = &all;
|
||||
|
||||
pro = parpro;
|
||||
pro.xab$w_pro |= ( ((xab$m_nodel) << xab$v_system) |
|
||||
((xab$m_nodel) << xab$v_owner) |
|
||||
((xab$m_nodel) << xab$v_group) |
|
||||
((xab$m_nodel) << xab$v_world) );
|
||||
|
||||
if( options & create_protect ) {
|
||||
pro.xab$w_pro = (uint16_t)
|
||||
((pro.xab$w_pro & ~(protection >> 16)) |
|
||||
(uint16_t)protection);
|
||||
}
|
||||
|
||||
if( options & create_owner ) {
|
||||
pro.xab$l_uic = ownuic;
|
||||
}
|
||||
|
||||
itm.xab$l_nxt = &fhc;
|
||||
|
||||
directory = 1;
|
||||
itm.xab$b_mode = XAB$K_SETMODE;
|
||||
pro.xab$l_nxt = &itm;
|
||||
nfab.fab$l_xab = &pro;
|
||||
|
||||
nam.nam$b_rss = sizeof( rsname ) -1;
|
||||
nam.nam$l_rsa = rsname;
|
||||
nfab.fab$l_nam = &nam;
|
||||
|
||||
nfab.fab$b_fac = 0;
|
||||
nfab.fab$l_fop = FAB$M_OFP;
|
||||
nfab.fab$b_org = FAB$C_SEQ;
|
||||
nfab.fab$b_rat = FAB$M_BLK;
|
||||
nfab.fab$b_rfm = FAB$C_VAR;
|
||||
fhc.xab$w_lrl =
|
||||
nfab.fab$w_mrs = 512;
|
||||
|
||||
nfab.fab$b_fns = fab.fab$b_fns;
|
||||
nfab.fab$l_fna = fab.fab$l_fna;
|
||||
|
||||
sts = sys_create( &nfab );
|
||||
|
||||
rsname[nam.nam$b_rsl] = '\0';
|
||||
if( $FAILED(sts) ) {
|
||||
printmsg( CREATE_CREDIRFAIL, 0, rsname );
|
||||
sts = printmsg( sts, MSG_CONTINUE, CREATE_CREDIRFAIL );
|
||||
} else {
|
||||
if( $FAILS(sts = sys_close(&nfab)) ) {
|
||||
printmsg(CREATE_CLOSEOUT, 0, rsname);
|
||||
sts = printmsg(sts, MSG_CONTINUE, CREATE_CLOSEOUT);
|
||||
}
|
||||
}
|
||||
nfab.fab$b_fns =
|
||||
nam.nam$b_ess = 0;
|
||||
nfab.fab$b_dns = 0;
|
||||
nam.nam$b_nop = NAM$M_SYNCHK;
|
||||
(void) sys_parse( &nfab );
|
||||
|
||||
if( $FAILED(sts) )
|
||||
break;
|
||||
|
||||
if( options & create_log )
|
||||
sts = printmsg( CREATE_CREATED, 0, rsname );
|
||||
}
|
||||
|
||||
if( *p == ']' )
|
||||
break;
|
||||
|
||||
switch( level++ ) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
memmove( tdir+devlen+1, tdir+devlen+tmplen, sfdlen );
|
||||
tmplen = 1+ sfdlen +1;
|
||||
tdir[devlen+tmplen-1] = ']';
|
||||
break;
|
||||
default:
|
||||
tdir[devlen+tmplen -1] = '.';
|
||||
tmplen += 1 + sfdlen;
|
||||
tdir[devlen+tmplen -1] = ']';
|
||||
break;
|
||||
}
|
||||
|
||||
for( sfdlen = 0; *p != '.' && *p != ']'; sfdlen++ )
|
||||
tdir[devlen+tmplen+sfdlen] = *p++;
|
||||
|
||||
memcpy( tdir+devlen+tmplen+sfdlen, ".DIR;1", 6 );
|
||||
if( *p == '.' )
|
||||
++p;
|
||||
}
|
||||
|
||||
} while( 0 );
|
||||
|
||||
if( nam.nam$l_fnb & (NAM$M_EXP_NAME | NAM$M_EXP_TYPE |
|
||||
NAM$M_EXP_VER | NAM$M_WILDCARD) ) {
|
||||
sts = printmsg( RMS$_DIR, 0 );
|
||||
}
|
||||
|
||||
fab.fab$b_fns =
|
||||
nam.nam$b_ess =
|
||||
fab.fab$b_dns = 0;
|
||||
nam.nam$b_nop = NAM$M_SYNCHK;
|
||||
(void) sys_parse( &fab );
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
/******************************************************************* create_file() */
|
||||
|
||||
static vmscond_t create_file( options_t options, int argc, char** argv ) {
|
||||
vmscond_t sts;
|
||||
char *buf = NULL;
|
||||
size_t bufsize = 80;
|
||||
char vfc[2], rsbuf[NAM$C_MAXRSS + 1];
|
||||
struct NAM nam;
|
||||
struct FAB fab;
|
||||
struct RAB rab;
|
||||
struct XABPRO pro;
|
||||
|
||||
UNUSED( argc );
|
||||
|
||||
nam = cc$rms_nam;
|
||||
fab = cc$rms_fab;
|
||||
rab = cc$rms_rab;
|
||||
pro = cc$rms_xabpro;
|
||||
|
||||
nam.nam$l_esa = NULL;
|
||||
nam.nam$b_ess = 0;
|
||||
|
||||
nam.nam$b_rss = sizeof( rsbuf ) -1;
|
||||
nam.nam$l_rsa = rsbuf;
|
||||
|
||||
if( options & (create_protect|create_owner) ) {
|
||||
fab.fab$l_xab = &pro;
|
||||
|
||||
if( options & create_protect ) {
|
||||
pro.xab$w_pro = (uint16_t)
|
||||
((pro.xab$w_pro & ~(protection >> 16)) |
|
||||
(uint16_t)protection);
|
||||
}
|
||||
|
||||
if( options & create_owner ) {
|
||||
pro.xab$l_uic = ownuic;
|
||||
}
|
||||
}
|
||||
|
||||
fab.fab$l_nam = &nam;
|
||||
|
||||
fab.fab$b_fac = FAB$M_PUT;
|
||||
fab.fab$l_fop = FAB$M_OFP | FAB$M_TEF;
|
||||
fab.fab$b_org = FAB$C_SEQ;
|
||||
|
||||
if( !(options & create_recfmt) ) {
|
||||
options |= (FAB$C_VAR +1) << create_v_recfmt;
|
||||
if( !(options & (create_prn|create_ftn|create_cr)) )
|
||||
options |= create_cr;
|
||||
}
|
||||
|
||||
fab.fab$b_rfm = ((options & create_recfmt) >> create_v_recfmt) -1;
|
||||
|
||||
switch( fab.fab$b_rfm ) {
|
||||
case FAB$C_STM:
|
||||
case FAB$C_STMLF:
|
||||
case FAB$C_STMCR:
|
||||
fab.fab$b_rat |= FAB$M_CR;
|
||||
break;
|
||||
case FAB$C_VFC:
|
||||
fab.fab$b_fsz = vfclen;
|
||||
break;
|
||||
}
|
||||
|
||||
if( !(options & create_span) )
|
||||
fab.fab$b_rat |= FAB$M_BLK;
|
||||
if( options & create_ftn )
|
||||
fab.fab$b_rat |= FAB$M_FTN;
|
||||
if( options & create_cr )
|
||||
fab.fab$b_rat |= FAB$M_CR;
|
||||
if( options & create_prn ) {
|
||||
fab.fab$b_rat |= FAB$M_PRN;
|
||||
fab.fab$b_fsz = 2;
|
||||
fab.fab$b_rfm = FAB$C_VFC;
|
||||
|
||||
switch( (options & create_b4) >> create_v_b4 ) {
|
||||
case create_prn_none:
|
||||
vfc[0] = 0;
|
||||
break;
|
||||
case create_prn_nl:
|
||||
if( b4n < 1 || b4n > 127 )
|
||||
return printmsg( CREATE_INVALIDNL, 0 );
|
||||
vfc[0] = b4n & 0x7f;
|
||||
break;
|
||||
case create_prn_c0:
|
||||
if( b4n > 31 )
|
||||
return printmsg( CREATE_INVALIDC0, 0 );
|
||||
vfc[0] = 0x80 | b4n;
|
||||
break;
|
||||
case create_prn_vfu:
|
||||
if( b4n < 1 || b4n > 16 )
|
||||
return printmsg( CREATE_INVALIDVFU, 0 );
|
||||
vfc[0] = (0xC0 | (b4n -1)) & 0xff;
|
||||
}
|
||||
switch( (options & create_after) >> create_v_after ) {
|
||||
case create_prn_none:
|
||||
vfc[1] = 0;
|
||||
break;
|
||||
case create_prn_nl:
|
||||
if( aftn < 1 || aftn > 127 )
|
||||
return printmsg( CREATE_INVALIDNL, 0 );
|
||||
vfc[1] = aftn & 0x7f;
|
||||
break;
|
||||
case create_prn_c0:
|
||||
if( aftn > 31 )
|
||||
return printmsg( CREATE_INVALIDC0, 0 );
|
||||
vfc[1] = 0x80 | aftn;
|
||||
break;
|
||||
case create_prn_vfu:
|
||||
if( aftn < 1 || aftn > 16 )
|
||||
return printmsg( CREATE_INVALIDVFU, 0 );
|
||||
vfc[1] = (0xC0 | (aftn -1)) & 0xff;
|
||||
}
|
||||
} /* prn */
|
||||
|
||||
/*
|
||||
fab.fab$w_deq = 5;
|
||||
fab.fab$l_alq = 100;
|
||||
*/
|
||||
fab.fab$w_mrs = (uint16_t)reclen;
|
||||
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = (uint8_t)strlen(fab.fab$l_fna);
|
||||
|
||||
do {
|
||||
char *input;
|
||||
|
||||
sts = sys_create( &fab );
|
||||
rsbuf[nam.nam$b_rsl] = '\0';
|
||||
|
||||
if( $FAILED(sts) )
|
||||
break;
|
||||
|
||||
rab.rab$l_fab = &fab;
|
||||
if( $FAILS(sts = sys_connect( &rab )) )
|
||||
break;
|
||||
if( options & create_prn )
|
||||
rab.rab$l_rhb = vfc;
|
||||
if( options & create_log ) {
|
||||
printmsg( CREATE_READY, 0, rsbuf );
|
||||
printmsg( CREATE_TERMEOF, MSG_CONTINUE, CREATE_READY,
|
||||
#if defined( VMS ) || defined( _WIN32 )
|
||||
"Control-Z"
|
||||
#ifdef _WIN32
|
||||
" Enter"
|
||||
#endif
|
||||
#else
|
||||
"Control-D"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
while( (input = fgetline( stdin, FALSE, &buf, &bufsize )) != NULL ) {
|
||||
size_t len;
|
||||
|
||||
len = strlen( input );
|
||||
sts = SS$_NORMAL;
|
||||
|
||||
#if 0
|
||||
if( len && input[len -1] == '\r' )
|
||||
len--;
|
||||
#endif
|
||||
rab.rab$l_rbf = input;
|
||||
|
||||
switch( fab.fab$b_rfm ) {
|
||||
case FAB$C_FIX:
|
||||
if( len > (size_t)fab.fab$w_mrs )
|
||||
len = fab.fab$w_mrs;
|
||||
else if( len < (size_t)fab.fab$w_mrs ) {
|
||||
char *p = input;
|
||||
|
||||
if( bufsize < fab.fab$w_mrs ) {
|
||||
p = realloc( buf, fab.fab$w_mrs );
|
||||
if( p == NULL ) {
|
||||
sts = SS$_INSFMEM;
|
||||
break;
|
||||
}
|
||||
bufsize = fab.fab$w_mrs;
|
||||
rab.rab$l_rbf =
|
||||
buf =
|
||||
input = p;
|
||||
}
|
||||
p += len;
|
||||
len = fab.fab$w_mrs - len;
|
||||
while( len-- )
|
||||
*p++ = ' ';
|
||||
len = fab.fab$w_mrs;
|
||||
}
|
||||
break;
|
||||
case FAB$C_VFC:
|
||||
if( !(options & create_prn) ) {
|
||||
if( len < fab.fab$b_fsz ) {
|
||||
sts = RMS$_RFM;
|
||||
break;
|
||||
}
|
||||
rab.rab$l_rhb = input;
|
||||
rab.rab$l_rbf = input + fab.fab$b_fsz;
|
||||
len -= fab.fab$b_fsz;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( $SUCCESSFUL(sts) ) {
|
||||
rab.rab$w_rsz = (uint16_t)len;
|
||||
|
||||
sts = sys_put(&rab);
|
||||
}
|
||||
|
||||
if( $FAILED(sts) )
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} while( 0 );
|
||||
|
||||
if( buf != NULL ) free( buf );
|
||||
|
||||
if( $FAILED(sts) ) {
|
||||
vmscond_t rsts;
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
rsts = printmsg( sts, 0, nam.nam$b_rsl? rsbuf: argv[1] );
|
||||
if( err )
|
||||
printmsg( ODS2_OSERROR, MSG_CONTINUE, sts, strerror( err ) );
|
||||
sts = rsts;
|
||||
}
|
||||
sys_disconnect( &rab );
|
||||
if( $SUCCESSFUL( sts ) ) {
|
||||
if( $FAILS(sts = sys_close( &fab )) ) {
|
||||
vmscond_t rsts;
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
rsts = printmsg( CREATE_CLOSEOUT, 0,
|
||||
nam.nam$b_rsl? rsbuf: argv[1] );
|
||||
printmsg( sts, MSG_CONTINUE, rsts, nam.nam$b_rsl? rsbuf: argv[1] );
|
||||
if( err )
|
||||
printmsg( ODS2_OSERROR, MSG_CONTINUE, sts, strerror( err ) );
|
||||
sts = rsts;
|
||||
}
|
||||
} else {
|
||||
sys_close( &fab );
|
||||
}
|
||||
|
||||
if( $SUCCESSFUL( sts ) && (options & create_log) )
|
||||
sts = printmsg( CREATE_CREATED, 0, rsbuf );
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
1419
extracters/ods2/default.md
Normal file
1419
extracters/ods2/default.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,10 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_DELETECMD )
|
||||
@@ -17,69 +20,160 @@
|
||||
|
||||
#include "cmddef.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef DELETE
|
||||
#endif
|
||||
|
||||
/***************************************************************** dodelete() */
|
||||
|
||||
#define delete_log OPT_GENERIC_1
|
||||
#define delete_log OPT_GENERIC_1
|
||||
#define delete_confirm OPT_GENERIC_2
|
||||
|
||||
qual_t delquals[] = { {"log", delete_log, 0, NV, "-List name of each file deleted. (Default)"},
|
||||
{"nolog", 0, delete_log, NV, NULL },
|
||||
{ NULL, 0, 0, NV, NULL }
|
||||
qual_t delquals[] = { {"log", delete_log, 0, NV,
|
||||
"-commands delete qual_log"},
|
||||
{"nolog", 0, delete_log, NV, NULL },
|
||||
{"confirm", delete_confirm, 0, NV,
|
||||
"-commands delete qual_confirm"},
|
||||
{"noconfirm", 0, delete_confirm, NV, NULL},
|
||||
{ NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
param_t delpars[] = { {"filespec", REQ, VMSFS, NOPA,
|
||||
"for files to be deleted from ODS-2 volume. Wildcards are permitted.."},
|
||||
param_t delpars[] = { {"filespec", REQ | NOLIM, FSPEC, NOPA,
|
||||
"commands delete filespec"},
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
};
|
||||
|
||||
DECL_CMD(delete) {
|
||||
int sts = 0;
|
||||
char res[NAM$C_MAXRSS + 1], rsa[NAM$C_MAXRSS + 1];
|
||||
vmscond_t sts = 0;
|
||||
char esa[NAM$C_MAXRSS + 1], rsa[NAM$C_MAXRSS + 1];
|
||||
struct NAM nam = cc$rms_nam;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
int options, filecount = 0;
|
||||
options_t options, filecount = 0;
|
||||
vmscond_t confirm = ODS2_CONFIRM_ALL;
|
||||
|
||||
UNUSED(argc);
|
||||
if( $FAILS(sts = checkquals( &options, delete_log, delquals, qualc, qualv )) ) {
|
||||
return sts;
|
||||
}
|
||||
|
||||
options = checkquals( delete_log, delquals, qualc, qualv );
|
||||
if( options == -1 )
|
||||
return SS$_BADPARAM;
|
||||
if( options & delete_confirm )
|
||||
confirm = DELETE_CONFIRM;
|
||||
|
||||
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 & STS$M_SUCCESS ) {
|
||||
if (nam.nam$b_ver < 2) {
|
||||
printf( "%s\n", getmsg( DELETE$_DELVER, MSG_FULL) );
|
||||
return SS$_BADPARAM;
|
||||
--argc;
|
||||
++argv;
|
||||
while( ($SUCCESSFUL(sts) ||
|
||||
$VMS_STATUS_SEVERITY(sts) <= STS$K_WARNING ) && argc-- ) {
|
||||
nam.nam$l_esa = esa;
|
||||
nam.nam$b_ess = sizeof(esa) -1;
|
||||
fab.fab$l_nam = &nam;
|
||||
fab.fab$l_fna = argv++[0];
|
||||
fab.fab$b_fns = (uint8_t)strlen(fab.fab$l_fna);
|
||||
|
||||
if( $FAILS(sts = sys_parse( &fab )) ) {
|
||||
printmsg( DELETE_NOTDELETED, 0, fab.fab$l_fna );
|
||||
sts = printmsg( sts,MSG_CONTINUE, DELETE_NOTDELETED );
|
||||
break;
|
||||
}
|
||||
esa[nam.nam$b_esl] = '\0';
|
||||
if( !(nam.nam$l_fnb & NAM$M_EXP_VER) ) {
|
||||
sts = printmsg( $SETFAC(SHR$_DELVER,DELETE), 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
nam.nam$l_rsa = rsa;
|
||||
nam.nam$b_rss = NAM$C_MAXRSS;
|
||||
fab.fab$l_fop = FAB$M_NAM;
|
||||
while ( ( sts = sys_search( &fab ) ) & STS$M_SUCCESS ) {
|
||||
sts = sys_erase(&fab);
|
||||
if ( !( sts & STS$M_SUCCESS ) ) {
|
||||
printf("%%DELETE-F-DELERR, Delete error: %s\n",getmsg(sts, MSG_TEXT));
|
||||
nam.nam$b_rss = sizeof(rsa) -1;
|
||||
fab.fab$l_fop = 0;
|
||||
|
||||
while( TRUE ) {
|
||||
uint32_t directory;
|
||||
uint16_t retlen;
|
||||
struct FAB ffab = cc$rms_fab;
|
||||
struct RAB rab = cc$rms_rab;
|
||||
struct XABITM itm = cc$rms_xabitm;
|
||||
struct item_list xitems[] = {
|
||||
{ XAB$_UCHAR_DIRECTORY, sizeof(directory), NULL, 0 },
|
||||
{ 0, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
if( $FAILS(sts = sys_search( &fab )) ) {
|
||||
if( $MATCHCOND(sts, RMS$_NMF) )
|
||||
break;
|
||||
printmsg( DELETE_NOTDELETED, 0,
|
||||
(nam.nam$b_esl? esa: fab.fab$l_fna) );
|
||||
sts = printmsg( sts, MSG_CONTINUE, DELETE_NOTDELETED );
|
||||
break;
|
||||
} else {
|
||||
filecount++;
|
||||
if( options & delete_log ) {
|
||||
rsa[nam.nam$b_rsl] = '\0';
|
||||
printf("%%DELETE-I-DELETED, Deleted %s\n",rsa);
|
||||
}
|
||||
rsa[nam.nam$b_rsl] = '\0';
|
||||
|
||||
if( $MATCHCOND( confirm, DELETE_CONFIRM) )
|
||||
confirm = confirm_cmd( confirm, rsa );
|
||||
|
||||
if( !$MATCHCOND( confirm, ODS2_CONFIRM_ALL ) ) {
|
||||
if( $MATCHCOND( confirm, ODS2_CONFIRM_YES ) ) {
|
||||
confirm = DELETE_CONFIRM;
|
||||
} else if( $MATCHCOND( confirm, ODS2_CONFIRM_NO ) ) {
|
||||
confirm = DELETE_CONFIRM;
|
||||
continue;
|
||||
} else { /* ODS2_CONFIRM_QUIT */
|
||||
sts = confirm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( sts == RMS$_NMF ) sts = SS$_NORMAL;
|
||||
}
|
||||
if( sts & STS$M_SUCCESS ) {
|
||||
if( filecount < 1 ) {
|
||||
printf( "%%DELETE-W-NOFILES, no files deleted\n" );
|
||||
}
|
||||
} else {
|
||||
printf( "%%DELETE-F-ERROR Status: %s\n", getmsg(sts, MSG_TEXT) );
|
||||
|
||||
xitems[0].buffer = &directory; xitems[0].retlen = &retlen;
|
||||
itm.xab$b_mode = XAB$K_SENSEMODE;
|
||||
itm.xab$l_itemlist = xitems;
|
||||
ffab.fab$l_xab = &itm;
|
||||
ffab.fab$l_fna = rsa;
|
||||
ffab.fab$b_fns = nam.nam$b_rsl;
|
||||
ffab.fab$b_fac = FAB$M_GET;
|
||||
|
||||
if( $FAILS(sys_open( &ffab )) ) {
|
||||
sts = printmsg( DELETE_OPENIN, 0, rsa );
|
||||
continue;
|
||||
}
|
||||
if( directory ) {
|
||||
rab.rab$l_fab = &ffab;
|
||||
if( $FAILS(sts = sys_connect( &rab )) ) {
|
||||
printmsg( DELETE_OPENIN, 0, rsa );
|
||||
sts = printmsg( sts, MSG_CONTINUE, DELETE_OPENIN );
|
||||
} else {
|
||||
sts = sys_get( &rab );
|
||||
if( $MATCHCOND( sts, RMS$_EOF ) ) {
|
||||
sts = SS$_NORMAL;
|
||||
} else { /* RMS$_RTB if a record exists */
|
||||
printmsg( DELETE_NOTDELETED, 0, rsa );
|
||||
sts = printmsg( DELETE_DIRNOTEMPTY, MSG_CONTINUE, DELETE_NOTDELETED );
|
||||
}
|
||||
sys_disconnect( &rab );
|
||||
}
|
||||
}
|
||||
sys_close( &ffab );
|
||||
if( $FAILED(sts) ) {
|
||||
continue;
|
||||
}
|
||||
if( $FAILS(sts = sys_erase(&ffab)) ) {
|
||||
printmsg( DELETE_NOTDELETED, 0, rsa );
|
||||
sts = printmsg( sts, MSG_CONTINUE, DELETE_NOTDELETED );
|
||||
continue;
|
||||
}
|
||||
filecount++;
|
||||
if( options & delete_log )
|
||||
sts = printmsg( DELETE_DELETED, 0, rsa);
|
||||
} /* search */
|
||||
if( $MATCHCOND( sts, ODS2_CONFIRM_QUIT ) )
|
||||
break;
|
||||
if( $MATCHCOND(sts, RMS$_NMF) )
|
||||
sts = SS$_NORMAL;
|
||||
} /* arg */
|
||||
|
||||
if( $SUCCESSFUL(sts) || $MATCHCOND( sts, ODS2_CONFIRM_QUIT ) ) {
|
||||
if( filecount < 1 )
|
||||
sts = printmsg( DELETE_NOFILES, 0 );
|
||||
else if( filecount != 1 )
|
||||
sts = printmsg( DELETE_NFILES, 0, filecount );
|
||||
}
|
||||
fab.fab$b_fns =
|
||||
fab.fab$b_dns = 0;
|
||||
nam.nam$b_nop = NAM$M_SYNCHK;
|
||||
(void) sys_parse( &fab ); /* Discard context */
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
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 contributions of the original author and
|
||||
* subsequent contributors.
|
||||
|
||||
1.4 Changed declarations NOT to define DOLLAR identifiers
|
||||
unless DOLLAR is defined (some compilers can't handle $'s!)
|
||||
|
||||
@@ -30,7 +30,7 @@ OPTIONS =
|
||||
.ENDIF
|
||||
|
||||
# The next line is automatically generated. Do not change the format or split into multiple lines
|
||||
OBJS = ODS2 ACCESS CACHE COMPAT COPYCMD CREATECMD DEBUG DELETECMD DEVICE DIFFCMD DIRCMD DIRECT DISMOUNTCMD EXTENDCMD HELPCMD IMPORTCMD INITIALCMD INITVOL MOUNTCMD PHYVMS PHYVIRT RMS SEARCHCMD SETCMD SHOWCMD SPAWNCMD SYSMSG TYPECMD UPDATE VMSTIME
|
||||
OBJS = ODS2 ACCESS CACHE COMPAT COPYCMD CREATECMD DEBUG DELETECMD DEVICE DIFFCMD DIRCMD DIRECT DISMOUNTCMD EXTENDCMD HELPCMD INITIALCMD INITVOL MOUNTCMD PHYVMS PHYVIRT RMS SEARCHCMD SETCMD SHOWCMD SPAWNCMD SYSMSG UPDATE VMSTIME
|
||||
|
||||
ODS2$(EXE) : ODS2$(OLB)($(OBJS))$(OPTFILE)
|
||||
$(LINK)$(LINKFLAGS) ODS2$(OLB)/INCLUDE=($(OBJS))$(OPTIONS)
|
||||
@@ -45,118 +45,110 @@ VAXCRTL.OPT :
|
||||
|
||||
# ### BEGIN RULES ###
|
||||
|
||||
ODS2$(OBJ): VERSION.H
|
||||
ODS2$(OBJ): CMDDEF.H
|
||||
ODS2$(OBJ): COMPAT.H
|
||||
ODS2$(OBJ): ODS2.H RMS.H
|
||||
ODS2$(OBJ): VMSTIME.H DESCRIP.H SSDEF.H STSDEF.H SYSMSG.H CACHE.H PHYVIRT.H
|
||||
ODS2$(OBJ): VERSION.H CMDDEF.H
|
||||
ODS2$(OBJ): COMPAT.H
|
||||
ODS2$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H DESCRIP.H
|
||||
ODS2$(OBJ): SSDEF.H STSDEF.H SYSMSG.H CACHE.H PHYVIRT.H
|
||||
ACCESS$(OBJ): SSDEF.H ACCESS.H CACHE.H F11DEF.H
|
||||
ACCESS$(OBJ): VMSTIME.H
|
||||
ACCESS$(OBJ): DESCRIP.H STSDEF.H DEVICE.H PHYIO.H INITVOL.H ODS2.H PHYVIRT.H
|
||||
ACCESS$(OBJ): COMPAT.H
|
||||
ACCESS$(OBJ): DESCRIP.H STSDEF.H DEVICE.H ODS2.H PHYIO.H INITVOL.H PHYVIRT.H
|
||||
ACCESS$(OBJ): COMPAT.H
|
||||
ACCESS$(OBJ): SYSMSG.H
|
||||
CACHE$(OBJ): CACHE.H ODS2.H SSDEF.H
|
||||
CACHE$(OBJ): CACHE.H ODS2.H
|
||||
CACHE$(OBJ): SSDEF.H
|
||||
COMPAT$(OBJ): COMPAT.H
|
||||
COMPAT$(OBJ): DESCRIP.H STSDEF.H
|
||||
COPYCMD$(OBJ): CMDDEF.H
|
||||
COPYCMD$(OBJ): COMPAT.H
|
||||
COPYCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
COPYCMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
CREATECMD$(OBJ): CMDDEF.H
|
||||
COMPAT$(OBJ): DESCRIP.H STSDEF.H
|
||||
COPYCMD$(OBJ): CMDDEF.H
|
||||
COPYCMD$(OBJ): COMPAT.H ODS2.H
|
||||
COPYCMD$(OBJ): RMS.H F11DEF.H VMSTIME.H DESCRIP.H SSDEF.H STSDEF.H SYSMSG.H
|
||||
CREATECMD$(OBJ): CMDDEF.H
|
||||
CREATECMD$(OBJ): COMPAT.H
|
||||
CREATECMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
CREATECMD$(OBJ): STSDEF.H SYSMSG.H F11DEF.H
|
||||
CREATECMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H
|
||||
CREATECMD$(OBJ): DESCRIP.H SSDEF.H STSDEF.H SYSMSG.H
|
||||
DEBUG$(OBJ): DEBUG.H
|
||||
DELETECMD$(OBJ): CMDDEF.H
|
||||
DELETECMD$(OBJ): CMDDEF.H
|
||||
DELETECMD$(OBJ): COMPAT.H
|
||||
DELETECMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
DELETECMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
DEVICE$(OBJ): ODS2.H ACCESS.H CACHE.H F11DEF.H
|
||||
DEVICE$(OBJ): VMSTIME.H
|
||||
DELETECMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H
|
||||
DELETECMD$(OBJ): DESCRIP.H SSDEF.H STSDEF.H SYSMSG.H
|
||||
DEVICE$(OBJ): ODS2.H
|
||||
DEVICE$(OBJ): ACCESS.H CACHE.H F11DEF.H VMSTIME.H
|
||||
DEVICE$(OBJ): DESCRIP.H SSDEF.H STSDEF.H DEVICE.H PHYIO.H
|
||||
DIFFCMD$(OBJ): CMDDEF.H
|
||||
DIFFCMD$(OBJ): CMDDEF.H
|
||||
DIFFCMD$(OBJ): COMPAT.H
|
||||
DIFFCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
DIFFCMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
DIRCMD$(OBJ): CMDDEF.H
|
||||
DIFFCMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H DESCRIP.H
|
||||
DIFFCMD$(OBJ): SSDEF.H STSDEF.H SYSMSG.H
|
||||
DIRCMD$(OBJ): CMDDEF.H
|
||||
DIRCMD$(OBJ): COMPAT.H
|
||||
DIRCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
DIRCMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
DIRCMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H DESCRIP.H
|
||||
DIRCMD$(OBJ): SSDEF.H STSDEF.H SYSMSG.H
|
||||
DIRECT$(OBJ): ACCESS.H CACHE.H F11DEF.H
|
||||
DIRECT$(OBJ): VMSTIME.H
|
||||
DIRECT$(OBJ): DESCRIP.H SSDEF.H STSDEF.H DIRECT.H FIBDEF.H ODS2.H
|
||||
DISMOUNTCMD$(OBJ): CMDDEF.H
|
||||
DISMOUNTCMD$(OBJ): COMPAT.H
|
||||
DIRECT$(OBJ): DESCRIP.H SSDEF.H STSDEF.H DIRECT.H FIBDEF.H ODS2.H SYSMSG.H
|
||||
DISMOUNTCMD$(OBJ): CMDDEF.H
|
||||
DISMOUNTCMD$(OBJ): COMPAT.H
|
||||
DISMOUNTCMD$(OBJ): ODS2.H
|
||||
DISMOUNTCMD$(OBJ): RMS.H VMSTIME.H DESCRIP.H SSDEF.H STSDEF.H SYSMSG.H ACCESS.H
|
||||
DISMOUNTCMD$(OBJ): CACHE.H F11DEF.H
|
||||
DISMOUNTCMD$(OBJ): DEVICE.H PHYIO.H
|
||||
EXTENDCMD$(OBJ): CMDDEF.H
|
||||
DISMOUNTCMD$(OBJ): RMS.H F11DEF.H VMSTIME.H DESCRIP.H SSDEF.H STSDEF.H SYSMSG.H
|
||||
DISMOUNTCMD$(OBJ): ACCESS.H CACHE.H DEVICE.H PHYIO.H
|
||||
EXTENDCMD$(OBJ): CMDDEF.H
|
||||
EXTENDCMD$(OBJ): COMPAT.H
|
||||
EXTENDCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
EXTENDCMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
HELPCMD$(OBJ): CMDDEF.H
|
||||
EXTENDCMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H
|
||||
EXTENDCMD$(OBJ): DESCRIP.H SSDEF.H STSDEF.H SYSMSG.H
|
||||
HELPCMD$(OBJ): CMDDEF.H
|
||||
HELPCMD$(OBJ): COMPAT.H
|
||||
HELPCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
HELPCMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
IMPORTCMD$(OBJ): CMDDEF.H
|
||||
IMPORTCMD$(OBJ): COMPAT.H
|
||||
IMPORTCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
IMPORTCMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
INITIALCMD$(OBJ): CMDDEF.H
|
||||
HELPCMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H DESCRIP.H
|
||||
HELPCMD$(OBJ): SSDEF.H STSDEF.H SYSMSG.H VERSION.H
|
||||
INITIALCMD$(OBJ): CMDDEF.H
|
||||
INITIALCMD$(OBJ): COMPAT.H
|
||||
INITIALCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H
|
||||
INITIALCMD$(OBJ): SSDEF.H STSDEF.H SYSMSG.H ACCESS.H CACHE.H F11DEF.H
|
||||
INITIALCMD$(OBJ): DEVICE.H
|
||||
INITIALCMD$(OBJ): PHYIO.H INITVOL.H PHYVIRT.H
|
||||
INITVOL$(OBJ): COMPAT.H
|
||||
INITIALCMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H
|
||||
INITIALCMD$(OBJ): DESCRIP.H SSDEF.H STSDEF.H SYSMSG.H
|
||||
INITIALCMD$(OBJ): ACCESS.H CACHE.H DEVICE.H PHYIO.H INITVOL.H PHYVIRT.H
|
||||
INITVOL$(OBJ): COMPAT.H
|
||||
INITVOL$(OBJ): F11DEF.H
|
||||
INITVOL$(OBJ): VMSTIME.H
|
||||
INITVOL$(OBJ): DESCRIP.H SSDEF.H STSDEF.H INITVOL.H ODS2.H PHYVIRT.H RMS.H
|
||||
MOUNTCMD$(OBJ): CMDDEF.H
|
||||
INITVOL$(OBJ): SYSMSG.H
|
||||
MOUNTCMD$(OBJ): CMDDEF.H
|
||||
MOUNTCMD$(OBJ): COMPAT.H
|
||||
MOUNTCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
MOUNTCMD$(OBJ): STSDEF.H SYSMSG.H ACCESS.H CACHE.H F11DEF.H
|
||||
MOUNTCMD$(OBJ): DEVICE.H
|
||||
MOUNTCMD$(OBJ): PHYIO.H PHYVIRT.H
|
||||
PHYVMS$(OBJ): DESCRIP.H RMS.H VMSTIME.H SSDEF.H STSDEF.H
|
||||
MOUNTCMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H DESCRIP.H
|
||||
MOUNTCMD$(OBJ): SSDEF.H STSDEF.H SYSMSG.H ACCESS.H
|
||||
MOUNTCMD$(OBJ): CACHE.H DEVICE.H PHYIO.H PHYVIRT.H
|
||||
PHYVMS$(OBJ): DESCRIP.H RMS.H F11DEF.H
|
||||
PHYVMS$(OBJ): VMSTIME.H
|
||||
PHYVMS$(OBJ): SSDEF.H STSDEF.H
|
||||
PHYVMS$(OBJ): ODS2.H PHYIO.H PHYVIRT.H
|
||||
PHYVIRT$(OBJ): COMPAT.H
|
||||
PHYVIRT$(OBJ): COMPAT.H
|
||||
PHYVIRT$(OBJ): DEVICE.H
|
||||
PHYVIRT$(OBJ): ACCESS.H CACHE.H F11DEF.H
|
||||
PHYVIRT$(OBJ): ACCESS.H CACHE.H F11DEF.H
|
||||
PHYVIRT$(OBJ): VMSTIME.H DESCRIP.H SSDEF.H STSDEF.H
|
||||
PHYVIRT$(OBJ): PHYIO.H ODS2.H PHYVIRT.H
|
||||
RMS$(OBJ): ACCESS.H CACHE.H
|
||||
RMS$(OBJ): F11DEF.H VMSTIME.H
|
||||
RMS$(OBJ): DESCRIP.H SSDEF.H STSDEF.H DEVICE.H PHYIO.H DIRECT.H FIBDEF.H ODS2.H
|
||||
RMS$(OBJ): RMS.H COMPAT.H
|
||||
PHYVIRT$(OBJ): ODS2.H PHYIO.H PHYVIRT.H
|
||||
RMS$(OBJ): ACCESS.H CACHE.H F11DEF.H
|
||||
RMS$(OBJ): VMSTIME.H DESCRIP.H
|
||||
RMS$(OBJ): SSDEF.H STSDEF.H DEVICE.H ODS2.H PHYIO.H DIRECT.H FIBDEF.H RMS.H
|
||||
RMS$(OBJ): COMPAT.H
|
||||
RMS$(OBJ): SYSMSG.H
|
||||
SEARCHCMD$(OBJ): CMDDEF.H
|
||||
SEARCHCMD$(OBJ): CMDDEF.H
|
||||
SEARCHCMD$(OBJ): COMPAT.H
|
||||
SEARCHCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
SEARCHCMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
SETCMD$(OBJ): CMDDEF.H
|
||||
SEARCHCMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H
|
||||
SEARCHCMD$(OBJ): DESCRIP.H SSDEF.H STSDEF.H SYSMSG.H
|
||||
SETCMD$(OBJ): CMDDEF.H
|
||||
SETCMD$(OBJ): COMPAT.H
|
||||
SETCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
SETCMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
SHOWCMD$(OBJ): CMDDEF.H
|
||||
SETCMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H DESCRIP.H
|
||||
SETCMD$(OBJ): SSDEF.H STSDEF.H SYSMSG.H
|
||||
SHOWCMD$(OBJ): CMDDEF.H
|
||||
SHOWCMD$(OBJ): COMPAT.H
|
||||
SHOWCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
SHOWCMD$(OBJ): STSDEF.H SYSMSG.H ACCESS.H CACHE.H F11DEF.H
|
||||
SHOWCMD$(OBJ): DIRECT.H PHYIO.H
|
||||
SHOWCMD$(OBJ): PHYVIRT.H VERSION.H
|
||||
SPAWNCMD$(OBJ): CMDDEF.H
|
||||
SHOWCMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H DESCRIP.H
|
||||
SHOWCMD$(OBJ): SSDEF.H STSDEF.H SYSMSG.H ACCESS.H
|
||||
SHOWCMD$(OBJ): CACHE.H DIRECT.H PHYIO.H PHYVIRT.H VERSION.H
|
||||
SPAWNCMD$(OBJ): CMDDEF.H
|
||||
SPAWNCMD$(OBJ): COMPAT.H
|
||||
SPAWNCMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
SPAWNCMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
SYSMSG$(OBJ): SSDEF.H RMS.H
|
||||
SYSMSG$(OBJ): VMSTIME.H DESCRIP.H STSDEF.H COMPAT.H
|
||||
SPAWNCMD$(OBJ): ODS2.H RMS.H F11DEF.H VMSTIME.H DESCRIP.H
|
||||
SPAWNCMD$(OBJ): SSDEF.H STSDEF.H SYSMSG.H
|
||||
SYSMSG$(OBJ): ODS2.H SSDEF.H RMS.H F11DEF.H VMSTIME.H
|
||||
SYSMSG$(OBJ): DESCRIP.H STSDEF.H COMPAT.H
|
||||
SYSMSG$(OBJ): SYSMSG.H
|
||||
TYPECMD$(OBJ): CMDDEF.H
|
||||
TYPECMD$(OBJ): COMPAT.H
|
||||
TYPECMD$(OBJ): ODS2.H RMS.H VMSTIME.H DESCRIP.H SSDEF.H
|
||||
TYPECMD$(OBJ): STSDEF.H SYSMSG.H
|
||||
SYSMSG$(OBJ): DEFAULT.MT
|
||||
UPDATE$(OBJ): ACCESS.H CACHE.H
|
||||
UPDATE$(OBJ): F11DEF.H
|
||||
UPDATE$(OBJ): VMSTIME.H DESCRIP.H SSDEF.H STSDEF.H DEVICE.H PHYIO.H ODS2.H
|
||||
UPDATE$(OBJ): F11DEF.H VMSTIME.H DESCRIP.H SSDEF.H STSDEF.H DEVICE.H ODS2.H
|
||||
UPDATE$(OBJ): PHYIO.H INITVOL.H
|
||||
VMSTIME$(OBJ): VMSTIME.H DESCRIP.H SSDEF.H STSDEF.H
|
||||
VMSTIME$(OBJ): ODS2.H
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
/* Device.c Module to remember and find devices...*/
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
/* Should have mechanism to return actual device name... */
|
||||
|
||||
/* This module is simple enough - it just keeps track of
|
||||
device names and initialization... */
|
||||
* device names and initialization...
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -34,32 +39,30 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void *device_create( unsigned devsiz, void *keyval, unsigned *retsts );
|
||||
static int device_compare( unsigned keylen, void *keyval, void *node );
|
||||
static void *device_create( uint32_t devsiz, void *keyval, vmscond_t *retsts );
|
||||
static int device_compare( uint32_t keylen, void *keyval, void *node );
|
||||
|
||||
static struct DEV *dev_root = NULL;
|
||||
|
||||
|
||||
/************************************************************ device_create() */
|
||||
|
||||
/* device_create() creates a device object... */
|
||||
/* device_create() creates a device object...
|
||||
*/
|
||||
|
||||
static void *device_create( unsigned devsiz, void *keyval, unsigned *retsts ) {
|
||||
static void *device_create( uint32_t devsiz, void *keyval, vmscond_t *retsts ) {
|
||||
|
||||
register struct DEV *dev;
|
||||
|
||||
dev = (struct DEV *) malloc( sizeof( struct DEV ) + devsiz + 1 );
|
||||
dev = (struct DEV *) calloc( 1, offsetof( struct DEV, devnam ) + devsiz + 2 );
|
||||
if ( dev == NULL ) {
|
||||
*retsts = SS$_INSFMEM;
|
||||
return NULL;
|
||||
}
|
||||
dev->cache.objmanager = NULL;
|
||||
dev->cache.objtype = OBJTYPE_DEV;
|
||||
dev->vcb = NULL;
|
||||
dev->access = 0;
|
||||
dev->context = NULL;
|
||||
memcpy( dev->devnam, keyval, devsiz );
|
||||
memcpy( dev->devnam + devsiz, ":", 2 );
|
||||
|
||||
*retsts = SS$_NORMAL;
|
||||
return dev;
|
||||
}
|
||||
@@ -77,7 +80,7 @@ void device_done( struct DEV *dev ) {
|
||||
#endif
|
||||
abort();
|
||||
}
|
||||
cache_untouch( &dev->cache, FALSE );
|
||||
cache_untouch( &dev->cache, TRUE );
|
||||
if( dev->cache.refcount == 0 ) /* Safe because on LRU list */
|
||||
cache_delete( &dev->cache );
|
||||
return;
|
||||
@@ -87,11 +90,14 @@ void device_done( struct DEV *dev ) {
|
||||
|
||||
/* device_compare() compares a device name to that of a device object... */
|
||||
|
||||
static int device_compare( unsigned keylen, void *keyval, void *node ) {
|
||||
static int device_compare( uint32_t keylen, void *keyval, void *node ) {
|
||||
|
||||
register int cmp;
|
||||
register const char *keynam = (const char *) keyval;
|
||||
register const char *devnam = ((const struct DEV *) node)->devnam;
|
||||
register const char *keynam;
|
||||
register const char *devnam;
|
||||
|
||||
keynam = (const char *) keyval;
|
||||
devnam = ((const struct DEV *) node)->devnam;
|
||||
|
||||
cmp = 0;
|
||||
while ( keylen-- > 0 ) {
|
||||
@@ -110,10 +116,11 @@ static int device_compare( unsigned keylen, void *keyval, void *node ) {
|
||||
|
||||
/* device_lookup() is to to find devices... */
|
||||
|
||||
unsigned device_lookup( unsigned devlen, char *devnam, int create,
|
||||
vmscond_t device_lookup( size_t devlen, char *devnam, int create,
|
||||
struct DEV **retdev ) {
|
||||
|
||||
unsigned sts, devsiz;
|
||||
vmscond_t sts;
|
||||
size_t devsiz;
|
||||
register struct DEV *dev;
|
||||
|
||||
for ( devsiz = 0; devsiz < devlen; devsiz++ ) {
|
||||
@@ -121,15 +128,18 @@ unsigned device_lookup( unsigned devlen, char *devnam, int create,
|
||||
break;
|
||||
}
|
||||
}
|
||||
dev = (struct DEV *) cache_find( (void *) &dev_root, devsiz, devnam, &sts,
|
||||
dev = (struct DEV *) cache_find( (void *) &dev_root, (uint32_t)devsiz, devnam, &sts,
|
||||
device_compare,
|
||||
create ? device_create : NULL );
|
||||
if ( dev == NULL ) {
|
||||
if ( sts == SS$_ITEMNOTFOUND ) {
|
||||
if ( $MATCHCOND(sts, SS$_ITEMNOTFOUND) ) {
|
||||
sts = SS$_NOSUCHDEV;
|
||||
}
|
||||
} else {
|
||||
*retdev = dev;
|
||||
if( retdev == NULL )
|
||||
device_done( dev );
|
||||
else
|
||||
*retdev = dev;
|
||||
sts = SS$_NORMAL;
|
||||
}
|
||||
return sts;
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
/* Device.h Definitions for device routines */
|
||||
|
||||
/*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
email address: Paulnank@au1.ibm.com
|
||||
* 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.
|
||||
*/
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _DEVICE_H
|
||||
#define _DEVICE_H
|
||||
@@ -21,12 +24,13 @@
|
||||
#include <sys/types.h>
|
||||
#include "access.h"
|
||||
#include "cache.h"
|
||||
#include "ods2.h"
|
||||
#include "phyio.h"
|
||||
|
||||
struct DEV { /* Device information */
|
||||
struct CACHE cache;
|
||||
struct VCB *vcb; /* Pointer to volume (if mounted) */
|
||||
int access; /* Device mount options (e.g., /Write) */
|
||||
options_t access; /* Device mount options (e.g., /Write) */
|
||||
void *context; /* Context for implementation */
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -57,7 +61,7 @@ struct DEV { /* Device information */
|
||||
char devnam[1]; /* Device name */
|
||||
};
|
||||
|
||||
unsigned device_lookup( unsigned devlen, char *devnam, int create,
|
||||
vmscond_t device_lookup( size_t devlen, char *devnam, int create,
|
||||
struct DEV **retdev );
|
||||
void device_done( struct DEV *dev );
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_DIFFCMD )
|
||||
@@ -16,81 +19,136 @@
|
||||
#endif
|
||||
|
||||
#include "cmddef.h"
|
||||
#include "phyio.h"
|
||||
|
||||
/******************************************************************* dodiff() */
|
||||
|
||||
/* dodiff: a simple file difference routine */
|
||||
|
||||
param_t diffpars[] = { {"ods-2_filespec", REQ, VMSFS, NOPA, "for file on ODS-2 volume."},
|
||||
{"local_filespec", REQ, LCLFS, NOPA, "for file on local filesystem."},
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
static uint32_t maxdiffs;
|
||||
|
||||
#define diff_maxdiff OPT_GENERIC_1
|
||||
#define diff_binary OPT_GENERIC_2
|
||||
qual_t
|
||||
diffquals[] = {{"maximum_differences", diff_maxdiff, 0, DV(&maxdiffs), "commands difference qual_maxdiff"},
|
||||
{"nomaximum_differences", 0, diff_maxdiff, NV, NULL },
|
||||
{"binary", diff_binary, 0, NV, "commands difference qual_binary"},
|
||||
|
||||
{ NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
|
||||
param_t
|
||||
diffpars[] = { {"Files-11_filespec", REQ, FSPEC, NOPA, "commands difference Files-11_spec"},
|
||||
{"local_filespec", REQ, FSPEC, NOPA, "commands difference local_spec"},
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
};
|
||||
|
||||
DECL_CMD(diff) {
|
||||
int sts, records = 0;
|
||||
char *rec, *cpy = NULL;
|
||||
vmscond_t sts;
|
||||
options_t options;
|
||||
uint32_t records, diffs = 0;
|
||||
char *rec, *cpy = NULL, *buf = NULL;
|
||||
size_t bufsize = 80;
|
||||
char *name;
|
||||
FILE *tof;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
struct RAB rab = cc$rms_rab;
|
||||
struct NAM nam = cc$rms_nam;
|
||||
char rsname[NAM$C_MAXRSS+1];
|
||||
|
||||
UNUSED(argc);
|
||||
UNUSED(qualc);
|
||||
UNUSED(qualv);
|
||||
|
||||
name = argv[1];
|
||||
sts = SS$_BADFILENAME;
|
||||
if ( *name == '\0' ) {
|
||||
if( $FAILS(sts = checkquals( &options, 0, diffquals, qualc, qualv )) )
|
||||
return sts;
|
||||
|
||||
name = get_realpath( argv[2] );
|
||||
records = 0;
|
||||
|
||||
nam.nam$l_rsa = rsname;
|
||||
nam.nam$b_rss = (uint8_t)(sizeof( rsname) - 1);
|
||||
|
||||
fab.fab$l_nam = &nam;
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = (uint8_t)strlen( fab.fab$l_fna );
|
||||
|
||||
if ( (tof = openf( name? name: argv[2], "r" )) == NULL ) {
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( DIFF_OPENIN, 0, name? name: argv[2] );
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE, DIFF_OPENIN, strerror(err) );
|
||||
free( name );
|
||||
return sts;
|
||||
}
|
||||
records = 0;
|
||||
fab.fab$l_fna = name;
|
||||
fab.fab$b_fns = strlen( fab.fab$l_fna );
|
||||
tof = openf( argv[2], "r" );
|
||||
if ( tof == NULL ) {
|
||||
printf("%%ODS2-E-OPENERR, Could not open file %s\n",name);
|
||||
perror( " - " );
|
||||
return SS$_NOSUCHFILE;
|
||||
}
|
||||
sts = sys_open( &fab );
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
|
||||
if( $SUCCESSFUL(sts = sys_open( &fab )) ) {
|
||||
rab.rab$l_fab = &fab;
|
||||
sts = sys_connect( &rab );
|
||||
if( sts & STS$M_SUCCESS ) {
|
||||
nam.nam$l_rsa[nam.nam$b_rsl] = '\0';
|
||||
if( $SUCCESSFUL(sts = sys_connect( &rab )) ) {
|
||||
if( (rec = malloc( MAXREC + 2 )) == NULL ) {
|
||||
perror( "malloc" );
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
sts = SS$_INSFMEM;
|
||||
printmsg( sts, 0 );
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE, sts, strerror(err) );
|
||||
} else {
|
||||
rab.rab$l_ubf = rec;
|
||||
rab.rab$w_usz = MAXREC;
|
||||
while( (sts = sys_get( &rab )) & STS$M_SUCCESS ) {
|
||||
while( $SUCCESSFUL(sts = sys_get( &rab )) ) {
|
||||
rec[rab.rab$w_rsz] = '\0';
|
||||
cpy = fgetline( tof, FALSE );
|
||||
++records;
|
||||
cpy = fgetline( tof, FALSE, &buf, &bufsize );
|
||||
if( cpy == NULL ||
|
||||
rab.rab$w_rsz != strlen( cpy ) ||
|
||||
memcmp( rec, cpy, rab.rab$w_rsz ) != 0 ) {
|
||||
|
||||
printf( "%%DIFF-F-DIFFERENT Files are different!\n" );
|
||||
sts = 4;
|
||||
break;
|
||||
if( options & diff_binary )
|
||||
sts = printmsg( DIFF_DIFFER, 0, records );
|
||||
else
|
||||
printf( "************\n"
|
||||
"File %s\n"
|
||||
"%5u %.*s\n"
|
||||
"******\n"
|
||||
"File %s\n"
|
||||
"%5u %s\n"
|
||||
"************\n",
|
||||
rsname,
|
||||
records, rab.rab$w_rsz, rec,
|
||||
name,
|
||||
records, cpy? cpy: "<EOF>" );
|
||||
if( (++diffs > maxdiffs && (options & diff_maxdiff)) || cpy == NULL )
|
||||
break;
|
||||
}
|
||||
free( cpy );
|
||||
cpy = NULL;
|
||||
records++;
|
||||
}
|
||||
if( cpy != NULL ) free( cpy );
|
||||
free( rec );
|
||||
rec = cpy = NULL;
|
||||
}
|
||||
sys_disconnect(&rab);
|
||||
}
|
||||
sys_close(&fab);
|
||||
} else {
|
||||
printmsg( DIFF_OPENIN, 0, argv[1] );
|
||||
sts = printmsg( sts, MSG_CONTINUE, DIFF_OPENIN );
|
||||
}
|
||||
if( sts == RMS$_EOF ) {
|
||||
if( (cpy = fgetline( tof, FALSE, &buf, &bufsize )) == NULL )
|
||||
sts = SS$_NORMAL;
|
||||
else {
|
||||
if( diffs < maxdiffs )
|
||||
sts = printmsg( DIFF_DIFFER, 0, records );
|
||||
}
|
||||
}
|
||||
|
||||
if( buf != NULL ) free( buf );
|
||||
fclose(tof);
|
||||
if (sts == RMS$_EOF) sts = SS$_NORMAL;
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
printf( "%%DIFF-I-Compared %d records\n", records );
|
||||
} else if ( sts != 4 ) {
|
||||
printf("%%DIFF-F-Error %s in difference\n",getmsg(sts, MSG_TEXT));
|
||||
|
||||
if( $SUCCESSFUL(sts) ) {
|
||||
sts = printmsg( DIFF_COMPARED, 0, records );
|
||||
} else if( !$MATCHCOND(sts, DIFF_DIFFER) ) {
|
||||
sts = printmsg( sts, 0, rab.rab$l_stv );
|
||||
}
|
||||
free( name );
|
||||
return sts;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,26 +1,31 @@
|
||||
/* Direct.h Definitions for directory 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.
|
||||
*/
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _DIRECT_H
|
||||
#define _DIRECT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "access.h"
|
||||
#include "descrip.h"
|
||||
#include "f11def.h"
|
||||
#include "ods2.h"
|
||||
|
||||
void direct_show( void );
|
||||
unsigned direct(struct VCB *vcb,struct dsc_descriptor *fibdsc,
|
||||
struct dsc_descriptor *filedsc,unsigned short *reslen,
|
||||
struct dsc_descriptor *resdsc,unsigned action);
|
||||
vmscond_t direct( struct VCB *vcb, struct dsc_descriptor *fibdsc,
|
||||
struct dsc_descriptor *filedsc, uint16_t *reslen,
|
||||
struct dsc_descriptor *resdsc, unsigned action );
|
||||
|
||||
#define DIRECT_FIND 0
|
||||
#define DIRECT_DELETE 1
|
||||
@@ -28,4 +33,7 @@ unsigned direct(struct VCB *vcb,struct dsc_descriptor *fibdsc,
|
||||
|
||||
#define MODIFIES(action) (action != DIRECT_FIND)
|
||||
|
||||
vmscond_t direct_dirid( struct VCB *vcb, struct dsc$descriptor *dirdsc,
|
||||
struct fiddef *dirid, struct fiddef *fid );
|
||||
|
||||
#endif /* #ifndef _DIRECT_H */
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_DISMOUNTCMD )
|
||||
@@ -22,28 +25,40 @@
|
||||
|
||||
/******************************************************************* dodismount() */
|
||||
|
||||
param_t dmopars[] = { {"drive_letter", REQ, STRING, NOPA, "Drive containing volume to dismount", },
|
||||
{NULL, 0, 0, NOPA, NULL }
|
||||
qual_t
|
||||
dmoquals[] = { {"log", MOU_LOG, 0, NV,
|
||||
"-commands dismount qual_log"},
|
||||
{"nolog", 0, MOU_LOG, NV, NULL },
|
||||
|
||||
{NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
|
||||
param_t
|
||||
dmopars[] = { {"drive_name", REQ, STRING, NOPA,
|
||||
"commands dismount drive"},
|
||||
|
||||
{NULL, 0, 0, NOPA, NULL}
|
||||
};
|
||||
|
||||
DECL_CMD(dismount) {
|
||||
vmscond_t sts;
|
||||
options_t options;
|
||||
struct DEV *dev;
|
||||
int sts;
|
||||
|
||||
UNUSED(argc);
|
||||
UNUSED(qualc);
|
||||
UNUSED(qualv);
|
||||
|
||||
sts = device_lookup( strlen(argv[1]), argv[1], FALSE, &dev );
|
||||
if( sts & STS$M_SUCCESS ) {
|
||||
if( $FAILS(sts = checkquals( &options, MOU_LOG, dmoquals, qualc, qualv )) ) {
|
||||
return sts;
|
||||
}
|
||||
if( $SUCCESSFUL(sts = device_lookup( (uint32_t)strlen(argv[1]),
|
||||
argv[1], FALSE, &dev )) ) {
|
||||
device_done( dev );
|
||||
if( dev->vcb != NULL ) {
|
||||
sts = dismount( dev->vcb );
|
||||
sts = dismount( dev->vcb, options );
|
||||
} else {
|
||||
sts = SS$_DEVNOTMOUNT;
|
||||
}
|
||||
}
|
||||
if( !(sts & STS$M_SUCCESS) )
|
||||
printf("%%DISMOUNT-E-STATUS Error: %s\n",getmsg(sts, MSG_TEXT));
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
912
extracters/ods2/en_us.hlp
Normal file
912
extracters/ods2/en_us.hlp
Normal file
@@ -0,0 +1,912 @@
|
||||
! Help file for ODS2
|
||||
! Contains help text for topics that don't need a condition code, or are too long
|
||||
! for condition code messages, which are limited to 255 bytes.
|
||||
!
|
||||
! Format:
|
||||
! Lines beginning with a digit + space + TOPIC are search keys.
|
||||
! Similar to the VMS HELP librarian, there are 9 hierarchical levels
|
||||
! of keys. However, unlike the VMS HELP librarian, browsing is controlled
|
||||
! by the command tables & the text allows printf() substitutions.
|
||||
!
|
||||
! The key names are not case-sensitive. Most key names are
|
||||
! coded in the command tables of ODS2 and can not be changed
|
||||
! unless a corresponding change is made to the tables.
|
||||
!
|
||||
! All other lines contain topic text.
|
||||
!
|
||||
! If a line ends in '$' newline, the newline will not be displayed.
|
||||
!
|
||||
! A topic consists of all lines following the search key until
|
||||
! another search key or EOF is encountered.
|
||||
!
|
||||
1 CREDITS
|
||||
The orginal version of ods2 was developed by Paul Nankervis
|
||||
<Paulnank@au1.ibm.com>
|
||||
|
||||
This modified version was developed by Timothe Litt, and
|
||||
incorporates significant previous modifications by Larry
|
||||
Baker of the USGS and by Hunter Goatley
|
||||
|
||||
This code may be freely distributed within the VMS community
|
||||
providing that the contributions of the original author and
|
||||
subsequent contributors are acknowledged in the help text and
|
||||
source files. This is free software; no warranty is offered,
|
||||
and while we believe it to be useful, you use it at your own risk.
|
||||
|
||||
Please send problem reports/comments to litt@acm.org
|
||||
|
||||
!
|
||||
1 COMMANDS
|
||||
ODS2 has the following commands:
|
||||
2 copy
|
||||
Copy one or more files from a Files-11 volume to the local filesystem
|
||||
or from the local filesystem to a Files-11 volume.
|
||||
3 fromspec
|
||||
One or more file specifications to copy.
|
||||
|
||||
The syntax of each filespec depends on the direction of the copy.
|
||||
Files on the Files-11 volume use Files-11 syntax. Files on the
|
||||
local filesystem use the local filespec syntax.
|
||||
|
||||
Wildcards may be used.
|
||||
3 tospec
|
||||
File specification for the destination file. The syntax of each
|
||||
filespec depends on the direction of the copy. Files on the
|
||||
Files-11 volume use Files-11 syntax. Files on the local
|
||||
filesystem use the local filespec syntax.
|
||||
|
||||
Wildcards are replaced from the source file name.
|
||||
3 qual_ascii
|
||||
Copy file in ASCII mode (default).
|
||||
|
||||
ASCII mode converts local files to/from Files-11 records.
|
||||
3 qual_binary
|
||||
Copy file in binary mode.
|
||||
|
||||
Binary mode ...
|
||||
3 qual_append
|
||||
Append data to existing file.
|
||||
Default is to create, create a new version or supersede per the output
|
||||
filesystem's conventions.
|
||||
3 qual_from
|
||||
Copy file from files-11 volume to local file.
|
||||
3 qual_to
|
||||
Copy file(s) from local filesystem to files-11 volume.
|
||||
3 qual_log
|
||||
Log files copied.
|
||||
3 qual_confirm
|
||||
Prompt for confirmation of each file copied.
|
||||
See HELP SYNTAX CONFIRM for details.
|
||||
3 qual_cc
|
||||
Carriage control for file records copied TO files-11 volume.
|
||||
Does not apply to files copied FROM files-11 volumes.
|
||||
4 none
|
||||
No carriage control (default).
|
||||
4 fortran
|
||||
FORTRAN carriage control in column 1.
|
||||
4 cr
|
||||
Records are preceded by <LF> and followed by <CR>.
|
||||
4 print
|
||||
Records are VFC format with 2 bytes of encoded carriage control.
|
||||
One of the following can be used for each carriage-control qualifier.
|
||||
To specify both BEFORE and AFTER, use
|
||||
/carriage=print=before=specifier /carriage=print=after=specifier.
|
||||
Do not specify the record_format qualifier.
|
||||
! Following group is used for print=before AND =after as the text would be identical
|
||||
5 b4
|
||||
Carriage control applied before record is printed.
|
||||
6 none
|
||||
No paper motion.
|
||||
6 nl
|
||||
Advance n lines (1-127).
|
||||
6 ctl
|
||||
Output ASCII C0 control character n (0 - 31).
|
||||
6 vfu
|
||||
Advance to VFU channel n (1-16).
|
||||
5 after
|
||||
Carriage control applied after record is printed.
|
||||
3 qual_recfmt
|
||||
Record format for files copied TO files-11 volume.
|
||||
Default is variable with carriage_return carriage control.
|
||||
Does not apply to files copied FROM files-11 volume.
|
||||
4 fixed
|
||||
Fixed length records, n bytes.
|
||||
Input will be padded or truncated to this length.
|
||||
4 variable
|
||||
Variable length records.
|
||||
4 vfc
|
||||
Variable length records with fixed length header.
|
||||
Header is first n characters of input.
|
||||
4 stream
|
||||
Stream format with <CR><LF> record delimiters.
|
||||
4 streamlf
|
||||
Stream format with <LF> record delimiters.
|
||||
4 streamcr
|
||||
Stream format with <CR> record delimiters.
|
||||
4 undefined
|
||||
Stream format with no record delimiters.
|
||||
3 qual_span
|
||||
Allow records to cross block boundaries. (default)
|
||||
Does not apply to stream files.
|
||||
3 qual_verlim
|
||||
Specify the version limit for a file.
|
||||
3 qual_volume
|
||||
Specify the volume (of a volume set) on which the file will
|
||||
be placed.
|
||||
3 qual_owner
|
||||
Specifies the UIC of the owner of files copied TO a files-11 volume.
|
||||
Default is parent directory's owner.
|
||||
3 qual_protection
|
||||
Specifies the protection of files copied TO a files-11 volume.
|
||||
The default file protection is set when the volume is initialized.
|
||||
2 create
|
||||
Create Files-11 files or directories.
|
||||
3 filespec
|
||||
Filespec of the file or directory to be created.
|
||||
Wildcards are not permitted.
|
||||
3 qual_directory
|
||||
Create a new Files-11 directory or subdirectory.
|
||||
Note that it is possible to create a series of nested
|
||||
subdirectories with a single CREATE/DIRECTORY command.
|
||||
3 qual_log
|
||||
List name of each file or directory created.
|
||||
3 qual_cc
|
||||
Carriage control for file records.
|
||||
Does not apply to directories.
|
||||
4 none
|
||||
No carriage control (default).
|
||||
4 fortran
|
||||
FORTRAN carriage control in column 1.
|
||||
4 cr
|
||||
Records are preceded by <LF> and followed by <CR>.
|
||||
4 print
|
||||
Records are VFC format with 2 bytes of encoded carriage control.
|
||||
One of the following can be used for each carriage-control qualifier.
|
||||
To specify both BEFORE and AFTER, use
|
||||
/carriage=print=before=specifier /carriage=print=after=specifier.
|
||||
Do not specify the record_format qualifier.
|
||||
! Following group is used for print=before AND =after as the text would be identical
|
||||
5 b4
|
||||
Carriage control applied before record is printed.
|
||||
6 none
|
||||
No paper motion.
|
||||
6 nl
|
||||
Advance n lines (1-127).
|
||||
6 ctl
|
||||
Output ASCII C0 control character n (0 - 31).
|
||||
6 vfu
|
||||
Advance to VFU channel n (1-16).
|
||||
5 after
|
||||
Carriage control applied after record is printed.
|
||||
3 qual_recfmt
|
||||
Record format when creating file.
|
||||
Default is variable with carriage_return carriage control.
|
||||
Does not apply to directories.
|
||||
4 fixed
|
||||
Fixed length records, n bytes.
|
||||
Input will be padded or truncated to this length.
|
||||
4 variable
|
||||
Variable length records.
|
||||
4 vfc
|
||||
Variable length records with fixed length header.
|
||||
Header is first n characters of input.
|
||||
4 stream
|
||||
Stream format with <CR><LF> record delimiters.
|
||||
4 streamlf
|
||||
Stream format with <LF> record delimiters.
|
||||
4 streamcr
|
||||
Stream format with <CR> record delimiters.
|
||||
4 undefined
|
||||
Stream format with no record delimiters.
|
||||
3 qual_span
|
||||
Allow records to cross block boundaries. (default)
|
||||
Does not apply to stream files or directories.
|
||||
3 qual_verlim
|
||||
Specify the version limit for a file, or the default version limit
|
||||
for a directory.
|
||||
3 qual_volume
|
||||
Specify the volume (of a volume set) on which the file or directory will
|
||||
be placed.
|
||||
3 qual_owner
|
||||
Specifies the UIC of the owner of the file or directory.
|
||||
Default is parent directory's owner.
|
||||
3 qual_protection
|
||||
Specifies the protection of the file or directory.
|
||||
The default file protection is set when the volume is initialized.
|
||||
The default directory protection is inherited from the
|
||||
directory's parent, with all delete permissions removed.
|
||||
3 qual_vfc
|
||||
Include fixed header of VFC records copied as data.
|
||||
Ignored for PRINT format files.
|
||||
2 delete
|
||||
Delete Files-11 files or directories.
|
||||
3 filespec
|
||||
File specification(s) for Files-11 file(s) to be deleted.
|
||||
Wildcards are permitted.
|
||||
3 qual_log
|
||||
List name of each file deleted. (Default)
|
||||
3 qual_confirm
|
||||
Prompt for confirmation of each file deleted.
|
||||
See HELP SYNTAX CONFIRM for details.
|
||||
2 difference
|
||||
Compare a file on the Files-11 volume to a file on the local filesystem and
|
||||
report the differences.
|
||||
3 Files-11_spec
|
||||
File specification for a file on a Files-11 volume.
|
||||
3 local_spec
|
||||
File specification for a file on the local filesystem.
|
||||
3 qual_binary
|
||||
Compares the file as binary; does not output difference records.
|
||||
3 qual_maxdiff
|
||||
Maximum number of differences to report.
|
||||
2 directory
|
||||
List files on a Files-11 volume.
|
||||
3 filespec
|
||||
Specification of files to list. Files-11 wildcards are supported.
|
||||
Default is *.*;*
|
||||
3 qual_brief
|
||||
Brief display - names with header/trailer (default)
|
||||
3 qual_fileid
|
||||
Include file ID
|
||||
3 qual_full
|
||||
Include all details
|
||||
3 qual_grand
|
||||
Include only grand total
|
||||
3 qual_heading
|
||||
Include heading
|
||||
3 qual_owner
|
||||
Include file owner
|
||||
3 qual_output
|
||||
Write ouput to a local file
|
||||
3 qual_protection
|
||||
Include file protection
|
||||
3 qual_total
|
||||
Include only directory name and summary
|
||||
3 qual_trailing
|
||||
Include trailing summary line
|
||||
3 qual_map
|
||||
Include map area of file header.
|
||||
3 qual_pack
|
||||
Normal packing of fields. Negated,
|
||||
outputs format for automation.
|
||||
3 qual_size
|
||||
Size of file.
|
||||
4 size_both
|
||||
Number of blocks allocated and used.
|
||||
4 size_alloc
|
||||
Number of blocks allocated to file.
|
||||
4 size_used
|
||||
Number of blocks used for data. (default)
|
||||
3 qual_date
|
||||
File date(s). Multiple dates are displayed in the order:
|
||||
Date created, date modified, date expired and date of backup.
|
||||
4 date_created
|
||||
Date file created (default)
|
||||
4 date_modified
|
||||
Date file modified
|
||||
4 date_expired
|
||||
Date file expired
|
||||
4 date_backup
|
||||
Date of last backup
|
||||
2 dismount
|
||||
Dismount a Files-11 volume. If the volume is a member
|
||||
of a mounted volumeset, the entire volumeset is dismounted.
|
||||
3 drive
|
||||
Drive containing volume to dismount.
|
||||
3 qual_log
|
||||
Display the name of the volume(s) dismounted.
|
||||
2 echo
|
||||
Print a string.
|
||||
2 exit
|
||||
Dismount all Files-11 volumes and exit ODS2
|
||||
2 extend
|
||||
Extend or truncate a Files-11 file.
|
||||
This changes the number of blocks allocated to a file, but does
|
||||
not change the data contained in the file.
|
||||
|
||||
Note that allocation is always a multiple of the volume's cluster size.
|
||||
3 filespec
|
||||
Specifies the name of the file on the File-11 volume to extend or truncate.
|
||||
Wildcards are not permitted.
|
||||
3 qual_allocate
|
||||
The number of blocks to add to the file's allocation.
|
||||
3 qual_truncate
|
||||
Truncate allocation to the current end-of-file.
|
||||
2 help
|
||||
The HELP command describes ODS2 comands and functions.
|
||||
|
||||
Help is available for each command, and for general topics.
|
||||
|
||||
Without parameters, HELP lists the commands and topics for which
|
||||
help is available.
|
||||
|
||||
HELP TOPIC displays the help for the named topic.
|
||||
|
||||
Additional levels of help are available for some topics and
|
||||
commands.
|
||||
|
||||
HELP COMMAND PARAMETER displays the help for the parameters of a
|
||||
command. The word 'parameter' lists all parameters; use the name
|
||||
of a parameter (shown by the topic help) for details of just one.
|
||||
|
||||
For some complex commands, another level of help is available
|
||||
with HELP COMMAND PARAMETER ARGUMENT.
|
||||
|
||||
To learn about common command elements, see the SYNTAX topic.
|
||||
3 topic
|
||||
Topic or command for which you want help.
|
||||
For a list, type HELP<CR>
|
||||
3 subtopic
|
||||
Subtopic - parameter, value, or item
|
||||
2 initialize
|
||||
Create a new filesystem.
|
||||
|
||||
ALL EXISTING DATA ON THE MEDIA WILL BE LOST.
|
||||
3 devspec
|
||||
Local file specification for device or disk image to be initialized.
|
||||
|
||||
ALL EXISTING DATA ON THE MEDIA WILL BE LOST.
|
||||
3 volspec
|
||||
Volume label for new volume, which must be unique within a volumeset.
|
||||
Volume labels are no more than 12 characters long.
|
||||
Only alphanumeric characters, '$', '-', and '_' are legal.
|
||||
3 qual_media
|
||||
Media type (DEC model name). This determines the media size, geometry
|
||||
and (in some cases) interleave.
|
||||
3 qual_bootblock
|
||||
Places boot block in non-standard location, which is inadvisable.
|
||||
3 qual_clustersize
|
||||
Cluster size (blocks) is the unit of storage allocation.
|
||||
3 qual_confirm
|
||||
Prompt for confirmation (default).
|
||||
See HELP SYNTAX CONFIRM for details.
|
||||
3 qual_create
|
||||
Create a new disk image file of the specified type. Default.
|
||||
Will not overwrite existing file.
|
||||
3 qual_directories
|
||||
Number of directory entries to pre-allocate in the MFD.
|
||||
3 qual_fileprot
|
||||
Default file protection for volume, default (S:RWED,O:RWED,G:RE,W:)
|
||||
3 qual_headers
|
||||
Number of file headers to pre-allocate.
|
||||
3 qual_extension
|
||||
Default extension size (blocks) for files on volume.
|
||||
3 qual_windows
|
||||
Default number of mapping pointers per file window.
|
||||
3 qual_index
|
||||
Placement hint for index file. One of:
|
||||
4 begin
|
||||
Place index file in lowest available LBNs.
|
||||
4 block
|
||||
Place index file near specific LBN.
|
||||
4 middle
|
||||
Place index file near middle of volume. (default)
|
||||
3 qual_image
|
||||
Initialize a disk image file.
|
||||
3 qual_device
|
||||
Initialize a physical device.
|
||||
3 qual_log
|
||||
Show progress and details of file structure.
|
||||
3 qual_replace
|
||||
Replace filesystem in existing image file. Will not change
|
||||
media type.
|
||||
3 qual_mount
|
||||
Mount volume after initialization completes.
|
||||
3 qual_maxfiles
|
||||
Maximum number of files volume can (ever) contain.
|
||||
3 qual_owneruic
|
||||
Volume owner's UIC. Default is [1,1].
|
||||
3 qual_protection
|
||||
Volume protection. The default is (S:RWED,O:RWED,G:RWED,W:RWED).
|
||||
3 qual_username
|
||||
Volume owner's username. The default your username on the local system.
|
||||
2 mount
|
||||
Mount a Files-11 volume or volumeset. Mounting a volume makes the files
|
||||
that it contains accessible to ods2. The volume must be initialized to be mounted.
|
||||
|
||||
While a volume is mounted, ods2 caches data creating a potentially inconsistent
|
||||
state. It must not be accessed by any other means until dismounted.
|
||||
|
||||
See HELP INITIALIZE for information on initializing a volume.
|
||||
See HELP DISMOUNT for information on dismounting a volume.
|
||||
3 volumes
|
||||
List of devices or files containing volumes to mount.
|
||||
Multiple containers must comprise a volumeset and must be specified
|
||||
in ascending order of relative volume number.
|
||||
Separate list items with comma.
|
||||
3 labels
|
||||
List of volume labels corresponding to each container.
|
||||
Separate list items with comma.
|
||||
If specified, must match label(s) in the Files-11 metadata.
|
||||
3 qual_media
|
||||
Media type (DEC model name). This determines the media size, geometry
|
||||
and (in some cases) interleave.
|
||||
A mount can fail if the wrong media type is specified.
|
||||
3 qual_image
|
||||
The containers are disk image files.
|
||||
3 qual_log
|
||||
Show progress
|
||||
3 qual_readonly
|
||||
Only permit reading from the volume.
|
||||
3 qual_snapshot
|
||||
Create snapshot(s) of the (existing) VHD disk(s) specified by this qualifier.
|
||||
See HELP SPECIFY_MOUNT for more information.
|
||||
3 qual_device
|
||||
The containers are raw devices.
|
||||
3 qual_write
|
||||
Allow both reading from and writing to the volume.
|
||||
2 quit
|
||||
Dismount all Files-11 volumes and exit ODS2.
|
||||
2 rename
|
||||
Rename files on Files-11 volume.
|
||||
3 fromspec
|
||||
Filespec of existing file on Files-11 volume.
|
||||
|
||||
Wildcards can be used.
|
||||
3 tospec
|
||||
New filespec for file.
|
||||
|
||||
The '*' wildcard can be used to copy components from the original filename(s).
|
||||
(Currently only [*] and [*...] are supported for the directory.)
|
||||
|
||||
Can change directory, name, type, version, but not device.
|
||||
3 qual_confirm
|
||||
Prompt for confirmation.
|
||||
See HELP SYNTAX CONFIRM for details.
|
||||
3 qual_log
|
||||
Show progress
|
||||
2 search
|
||||
Search Files-11 file(s) for one or more strings.
|
||||
3 filespec
|
||||
File on Files-11 volume to search.
|
||||
|
||||
Wildcards are permitted.
|
||||
3 string
|
||||
One or more strings to earch for in the file(s).
|
||||
|
||||
Multiple strings are compared with each record as specified by
|
||||
the MATCH qualifier.
|
||||
3 qual_confirm
|
||||
Prompt for confirmation before searching each file.
|
||||
See HELP SYNTAX CONFIRM for details.
|
||||
3 qual_exact
|
||||
Strings are compared matching the string to the record exactly.
|
||||
By default, uppercase and lowercase are treated as equivalent.
|
||||
3 qual_heading
|
||||
Print a heading with the name of each file that matches.
|
||||
By default, a heading is only printed if the filespec contained a wildcard.
|
||||
3 qual_highlight
|
||||
Highlight text that matches specified string(s), using one or more of
|
||||
the following renderings:
|
||||
4 highlight_blink
|
||||
Blink matching text
|
||||
4 highlight_bold
|
||||
Render matching text as bold (default)
|
||||
4 highlight_hardcopy
|
||||
Render matching text for a non-ANSI device
|
||||
4 highlight_reverse
|
||||
Render matching text in reverse video
|
||||
4 highlight_underline
|
||||
Underline matching text
|
||||
3 qual_log
|
||||
Display summary results for each file examined
|
||||
3 qual_match
|
||||
Match requirement for string(s)
|
||||
4 match_and
|
||||
Record must match all specified strings.
|
||||
4 match_or
|
||||
Record must match at least one specfied string. (default)
|
||||
4 match_nand
|
||||
Record must not contain all specified strings, but may contain some.
|
||||
4 match_nor
|
||||
Record must not contain any specified string.
|
||||
3 qual_nowindow
|
||||
Do not display records that match search critera.
|
||||
3 qual_numbers
|
||||
Display line number with matching records.
|
||||
3 qual_page
|
||||
Paginate output; pause every n lines. Default: terminal height.
|
||||
See HELP SYNTAX PAGINATE for details.
|
||||
2 set
|
||||
Set a parameter or default.
|
||||
3 item_name
|
||||
The following items can be set:
|
||||
4 type_cwd
|
||||
Working (default) directory for local files.
|
||||
4 type_dirquals
|
||||
Directory$
|
||||
4 type_copyquals
|
||||
Copy$
|
||||
4 type_setdef
|
||||
Default device and directory for Files-11 volume.
|
||||
4 type_setmsg
|
||||
Message definition file name and/or message display option qualifiers.
|
||||
4 type_searchquals
|
||||
Search$
|
||||
4 type_qualstyle
|
||||
Style$
|
||||
4 item_cwd
|
||||
Working directory on local system.
|
||||
4 item_dirquals
|
||||
Default qualifiers for DIRECTORY command.
|
||||
4 item_copyquals
|
||||
Default qualifiers for COPY command.
|
||||
4 item_setdef
|
||||
Default directory on Files-11 volume.
|
||||
4 item_history_limit
|
||||
Maximum number of lines of command history to retain.
|
||||
4 item_key_bindings
|
||||
Manipulate libedit key bindings using its 'bind' command
|
||||
4 item_setmsg
|
||||
Message definition file or display option qualifiers.
|
||||
4 item_helpfile
|
||||
Help library file
|
||||
4 item_seterrxit
|
||||
Cause exit when a command results in an error.
|
||||
4 item_searchquals
|
||||
Default qualifiers for SEARCH command.
|
||||
4 item_qualstyle
|
||||
Qualifer style.
|
||||
4 item_verify
|
||||
Display commands in indirect files.
|
||||
4 item_msgfac
|
||||
Display facility name
|
||||
4 item_msgsev
|
||||
Display severity code
|
||||
4 item_msgid
|
||||
Display identification
|
||||
4 item_msgtext
|
||||
Display message text
|
||||
4 item_default
|
||||
Use default (built-in) messages
|
||||
3 value
|
||||
xxx
|
||||
4 value_unix
|
||||
Unix style options, '-option'
|
||||
4 value_dcl
|
||||
DCL style qualifiers, '/qualifier'
|
||||
2 show
|
||||
Display a parameter or default.
|
||||
3 copy
|
||||
Default qualifiers for COPY command
|
||||
3 cwd
|
||||
Working directory on local system
|
||||
3 default
|
||||
Default Files-11 device & directory
|
||||
3 devices
|
||||
Raw devices for mounting Files-11 volumes and virtual devices
|
||||
mapped to mounted disk image files.
|
||||
3 directory
|
||||
Default qualifiers set for DIRECTORY command
|
||||
3 qstyle
|
||||
Qualifier style (DCL, Unix)
|
||||
3 search
|
||||
Default qualifiers set for SEARCH command
|
||||
3 statistics
|
||||
Debugging statistics
|
||||
3 terminal
|
||||
Terminal dimensions used for paged output.
|
||||
3 time
|
||||
Time of day
|
||||
3 verify
|
||||
Command file echo state
|
||||
3 history
|
||||
Command history
|
||||
Qualifier:
|
||||
/max-entries=n - Maximum number of history entries to display
|
||||
3 helpfile
|
||||
Name of current help library file
|
||||
3 version
|
||||
Version and configuration of ODS2
|
||||
3 volumes
|
||||
Mounted volumes' attributes
|
||||
3 message
|
||||
Name of current message definition file
|
||||
2 spawnnt
|
||||
Open a command subprocess, cmd.
|
||||
|
||||
Return to ods2 with the EXIT command to the cmd interpreter.
|
||||
2 spawnunix
|
||||
Open a command shell subprocess. The SHELL environment variable determines
|
||||
which shell is run. If SHELL is not defined, /bin/sh is run.
|
||||
|
||||
Return to ODS2 with the exit command to the shell.
|
||||
2 spawnvms
|
||||
Open an interactive DCL command subprocess.
|
||||
|
||||
Return to ODS2 with the LOGOUT command to DCL.
|
||||
2 type
|
||||
Display one or more Files-11 files on the terminal.
|
||||
3 filespec
|
||||
One or more Files-11 file specifications to display.
|
||||
|
||||
Wildcards may be used.
|
||||
3 qual_page
|
||||
Paginate output; pause every n lines. Default: terminal height.
|
||||
See HELP SYNTAX PAGINATE for details.
|
||||
3 qual_vfc
|
||||
Include fixed header of VFC records.
|
||||
Ignored for PRINT format files.
|
||||
1 INVOCATION
|
||||
INVOKING ODS2
|
||||
Invoke %s from your shell's command line. %s commands
|
||||
may be specified on the invocation line. Separate multiple
|
||||
commands on the invocation line with '$'.
|
||||
|
||||
If present, an initialization file is executed automatically
|
||||
before any other commands, including commands on the invocation line.
|
||||
|
||||
2 NT
|
||||
The environment variable ODS2INIT specifies the initialization file.
|
||||
If ODS2INIT is not defined, %s%s\.%s.INI is used.
|
||||
2 VMS
|
||||
The logical name ODS2INIT specifies the initialization file.
|
||||
If ODS2INIT is not defined, SYS$LOGIN:_%s.INI is used.
|
||||
2 UNIX
|
||||
The environment variable ODS2INIT specifies the initialization file.
|
||||
If ODS2INIT is not defined, ~/.%s.ini is used.
|
||||
2 LIBEDIT
|
||||
|
||||
%s uses the libedit command history editor. libedit reads the editrc
|
||||
file for configuration data. See 'man 5 editrc' and 'man 7 editline' for usage details.
|
||||
|
||||
!
|
||||
1 MOUNT
|
||||
You can mount a volume(-set) from either physical devices
|
||||
such a CDROM or hard disk drive, or files containing an
|
||||
image of a volume, such as a .ISO file or simulator disk image.
|
||||
|
||||
To mount a disk image, use the %simage qualifier and
|
||||
specify the filename as the parameter.
|
||||
If the filename contains %s, specify it in double quotes
|
||||
|
||||
Mount will assign a virtual device name to each volume.
|
||||
|
||||
You can select a virtual device name using the format
|
||||
dka100=my_files.iso
|
||||
|
||||
To mount a physical device, use the format:
|
||||
!
|
||||
2 NT
|
||||
|
||||
mount D:
|
||||
|
||||
Any drive letter mapped to a physical drive can be used.
|
||||
|
||||
The drive is accessed as a physical device, which may require privileges.
|
||||
Use SHOW DEVICES for a list of available devices.
|
||||
!
|
||||
2 NTASPI
|
||||
|
||||
mount D:
|
||||
|
||||
Any drive letter mapped to a physical drive can be used.
|
||||
|
||||
If the drive letter is C: or higher, commands are
|
||||
sent directly to the drive, bypassing system drivers.
|
||||
The drive must be a SCSI device.
|
||||
|
||||
The drive is accessed as a physical device, which may require privileges.
|
||||
Use SHOW DEVICES for a list of available devices.
|
||||
!
|
||||
2 OS2
|
||||
Specify the device to be mounted as a drive letter.
|
||||
E.g. mount D:
|
||||
The drive letter must be between A: and Z:
|
||||
The drive is accessed as a physical device.
|
||||
!
|
||||
2 UNIX
|
||||
|
||||
mount device
|
||||
|
||||
The device must be in %s.
|
||||
|
||||
For example, if you are using %s
|
||||
ODS2$> mount cdrom0
|
||||
|
||||
Use SHOW DEVICES for a list of available devices.
|
||||
!
|
||||
2 VMS
|
||||
mount DUB0:
|
||||
The device can be specified as a physical device or logical name.
|
||||
|
||||
You will need the LOGIO privilege.
|
||||
|
||||
Use SHOW DEVICES for a list of available devices.
|
||||
|
||||
2 VHD
|
||||
To create and mount a snapshot of a VHD-based volume set, use the
|
||||
%ssnapshot_of qualifier.
|
||||
Specify the existing volumes' filenames as an argument to %ssnapshot, and
|
||||
list the corresponding filenames to be created as the mount parameter.
|
||||
|
||||
See the VHD_IMAGE_FILES topic for more information.
|
||||
!
|
||||
2 VOLSET
|
||||
To mount a volume set, specify all the members in RVN order
|
||||
as a comma-separated list.
|
||||
|
||||
If you specify a list of volume labels, they must be in
|
||||
the same order as the volumes, and each must match the label
|
||||
stored in the data
|
||||
!
|
||||
1 SYNTAX
|
||||
SYNTAX
|
||||
%s commands roughly follow DCL/VMS syntax, which has the
|
||||
general form
|
||||
VERB /Qualifier(s) parameter parameter ...
|
||||
|
||||
If you prefer Unix-style options to DCL qualifiers, use
|
||||
SET QUALIFIER_STYLE UNIX
|
||||
No logical names or symbols are supported.
|
||||
|
||||
Command arguments can be quoted. If parameters (e.g. filenames)
|
||||
contain '%s', you can either quote them or indicate the end of
|
||||
of qualifers with with '%s%s'.
|
||||
2 COMMAND_FILES
|
||||
COMMAND FILES
|
||||
Command files allow you to automate operations, especially those
|
||||
that you do more than once. A command file consists of ods2
|
||||
commands exactly as you would type them, one per line.
|
||||
|
||||
We recommend that you do not abbreviate commands or command
|
||||
elements in command files.
|
||||
|
||||
Command files are executed with @filespec.
|
||||
|
||||
They can be nested up to %u levels deep.
|
||||
|
||||
A command file can be automatically executed each time ods2 is
|
||||
invoked. See the description of initialization files in
|
||||
HELP INVOCATION
|
||||
2 CONFIRM
|
||||
Several command provide the CONFIRM qualifier, which causes a prompt
|
||||
for confirmation of the operation. This is especially useful for
|
||||
destructive and/or wildcarded operations.
|
||||
|
||||
The following responses are valid:
|
||||
|
||||
YES NO QUIT
|
||||
|
||||
TRUE FALSE Ctrl/Z
|
||||
|
||||
1 0 ALL
|
||||
<Return>
|
||||
|
||||
You can use any combination of uppercase and lowercase letters
|
||||
for word responses. Word responses can be abbreviated to one or
|
||||
more letters (for example, T, TR, or TRU for TRUE), but these
|
||||
abbreviations must be unique. Affirmative answers are YES, TRUE,
|
||||
and 1. Negative answers include: NO, FALSE, 0, and pressing
|
||||
the Return key. Entering QUIT or pressing Ctrl/Z indicates that
|
||||
you want to stop processing the command at that point. When you
|
||||
respond by entering ALL, the command continues to process, but no
|
||||
further prompts are given. If you type a response other than one
|
||||
of those in the list, ODS2 issues an error message and redisplays
|
||||
the prompt.
|
||||
2 PAGINATE
|
||||
Commands with the /PAGE qualifier allow you to request that output
|
||||
be paginated; that is, pause every 'n' lines. This prevents
|
||||
large amounts of output from scrolling off the screen.
|
||||
|
||||
N defaults to the height of the terminal window.
|
||||
|
||||
When the output pauses, you are prompted and to make one of the
|
||||
following choices:
|
||||
<CR> Continue processing and display the next 'n' lines of output.
|
||||
F<CR> Finish processing without any further pauses.
|
||||
Q<CR> Stop processing the command.
|
||||
|
||||
End-of-file (Ctrl/Z or Ctrl/D (Unix) has the same effect as Q.
|
||||
2 QUALIFIERS
|
||||
Qualifiers provide additional direction to a a command. In other
|
||||
environments, they may be known as "switches" or "options."
|
||||
|
||||
Qualifiers consist of a "/" followed by a keyword, which may
|
||||
be abbreviated. (SET QUALIFIER_STYLE UNIX replaces the "/" with "-".)
|
||||
|
||||
Some qualifiers have a complement; e.g. /LOG and /NOLOG. These
|
||||
are identifed in the help as /[NO]qualname, and the affirmative
|
||||
sense is the one documented.
|
||||
|
||||
Some qualifiers accept a value; e.g. /DATE=CREATE. The value
|
||||
is separated from the qualifier by '=' (':' is also accepted).
|
||||
|
||||
Qualifier values can be a a list, in which case the list members
|
||||
are separated by comma. The list may be enclosed in parentheses.
|
||||
|
||||
2 UIC
|
||||
A UIC is a "User Identification Code", which identifies the ownershipe
|
||||
of a file or volume when applying file protection rules.
|
||||
|
||||
File and volume protections are not enforced by ODS-2, but are enforced
|
||||
by other operating environments. ODS-2 allows you to specify and
|
||||
display protections for interoperability with those environments.
|
||||
|
||||
Under some operating systems, the UIC can be specified as an alphanumeric
|
||||
name, e.g. [SYSTEM]. ODS-2 does not support this format.
|
||||
|
||||
ODS-2 supports the numeric form of UICs, which is [group,member],
|
||||
where group and member are up-to 6 digit octal numbers. Each has a
|
||||
maximum value of 177777. The square brackets and comma are required.
|
||||
2 PROTECTION
|
||||
Files-11 protection divides accessors into four groups: SYSTEM, OWNER,
|
||||
GROUP, and WORLD.
|
||||
|
||||
SYSTEM refers to system-privileged utilities, such as BACKUP.
|
||||
OWNER refers to accesses from processes running under the OWNER UIC.
|
||||
GROUP refers to accesses from processes running under a UIC which matches the [group,] field of the owner.
|
||||
WORLD encompasses any other access.
|
||||
|
||||
Protection controls 4 access types: Read, Write, Execute and Delete.
|
||||
(Execute is also known as Create when the protection is applied to
|
||||
a directory or volume.)
|
||||
|
||||
Protection is specifed as a 4-tuple in the form
|
||||
(SYSTEM:RWED,OWNER:RWED,GROUP:RWED,WORLD:RWED)
|
||||
The group name can be abbreviated to one character.
|
||||
To specify no access, specify the group name but omit the value.
|
||||
If the group name is omitted entirely, that group's access is not
|
||||
modified.
|
||||
2 FILE_SPECS
|
||||
A Files-11 file specification is comprised of 5 fields, each of
|
||||
which is optional. The full form is:
|
||||
device:[directory]name.type;version
|
||||
|
||||
Device is the name of device containing a volume.
|
||||
|
||||
Directory is the name of a directory (or "folder") containing
|
||||
one or more files. Directories are hierarchical; a directory can
|
||||
contain sub-directories up to a depth of 8 levels. Subdirectories
|
||||
are delimited by '.'; e.g. [outer.inner.middle] The highest level
|
||||
directory is called the Master File Directory, or MFD. It has the
|
||||
name '[000000]', and is implicit.
|
||||
|
||||
Name is the name of a file.
|
||||
|
||||
Type (or "extension") indicates the type of data in the file (by convention).
|
||||
|
||||
Version (or "generation") allows multiple copies of a file with the same
|
||||
device, directory, name and type to be retained. Version numbers
|
||||
have a range of 1 through 32767;
|
||||
|
||||
Some commands allow groups of files to be refered to with wildcards.
|
||||
The wildcard '%' matches exactly one character. '*' matches any
|
||||
number of characters including zero. '...' in a directory matches
|
||||
'and all lower directories'. Wildcards are not permitted for device names.
|
||||
|
||||
Version ';' (no number) means 'the highest generation' for an input file.
|
||||
For an output file, it means 'the next higher' generation.
|
||||
|
||||
When fields are omitted from a file specification, they are replaced
|
||||
by an application-specific default, or absent that, from the
|
||||
'default' file specification specified by SET DEFAULT. The latter
|
||||
can include a device and directory, but no file name, type or version.
|
||||
|
||||
Each file specification component is limited to 39 characters.
|
||||
!
|
||||
1 VHD_IMAGE_FILES
|
||||
Virtual Hard Disk (VHD) is a disk image format published by Microsoft as an
|
||||
"open specification". It is used by many simulators, including SimH.
|
||||
|
||||
VHD covers three kinds of disk images:
|
||||
Fixed - A fixed size disk image
|
||||
Dynamic - A sparse disk image; space in the container is allocated
|
||||
as the OS uses it.
|
||||
Difference - A sparse disk image containing only changes to a Dynamic
|
||||
image. Also called a "snapshot".
|
||||
|
||||
ODS2 can read and write all three VHD formats, which must
|
||||
have a file type of .vhd (or .VHD) to be recognized.
|
||||
|
||||
ODS2 currently only initializes Dynamic disks. Mount can create a
|
||||
snapshot of a dynamic disk. This can be useful for experimentation
|
||||
when you might want to roll-back changes.
|
||||
|
||||
Note that once a snapshot has been taken of a Dynamic disk, the
|
||||
original (parent) disk must not be modified, as this would invalidate
|
||||
the snapshot. You can take snapshots of snapshots.
|
||||
|
||||
The vhdtools collection provides a utility that can merge snapshots
|
||||
into their parent disk. It also supports other maintenance functions.
|
||||
!
|
||||
748
extracters/ods2/en_us.msg
Normal file
748
extracters/ods2/en_us.msg
Normal file
@@ -0,0 +1,748 @@
|
||||
! All facilities defined here must be listed in the message compiler.
|
||||
!
|
||||
! This file defines all the ODS2-specific messages. The message compiler
|
||||
! (a perl script, not the VMS utility) compiles this into a .h and mdf files for
|
||||
! ODS2. Note that none of the facility codes chosen are registered with
|
||||
! DEC :-). Also note that these are all customer facilites; they will not
|
||||
! conflict with VMS facilities of the same name. Reconstructed messages from
|
||||
! the VMS facilities are merged with this file when it is compiled.
|
||||
! The comments in the (auto-generated) ssdef.h explain how to generate
|
||||
! those sources. Only necessary if you are translating (I18n)...
|
||||
!
|
||||
! Copyright (C) 2016, 2022 Timothe Litt - litt at acm .org
|
||||
!
|
||||
! Provided as part of the ODS2 utility, originally 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 contributions of the original author and
|
||||
! subsequent contributors. This is free software; no
|
||||
! warranty is offered, and while we believe it to be useful,
|
||||
! you use it at your own risk. This is free software; no
|
||||
! warranty is offered, and while we believe it to be useful,
|
||||
! you use it at your own risk.
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY ODS2,84
|
||||
.LITERAL ODS2_OFFSET = ODS2_FACILITY - ^X800
|
||||
|
||||
|
||||
.SEVERITY WARNING
|
||||
|
||||
.LITERAL ODS2_NORMAL = (ODS2_OFFSET@16) + SHR_NORMAL + SHR_SUCCESS
|
||||
.LITERAL ODS2_OPENIN = (ODS2_OFFSET@16) + SHR_OPENIN + SHR_WARN
|
||||
|
||||
.SEVERITY SUCCESS
|
||||
.BASE 200
|
||||
|
||||
CONFIRM_ALL </CONFIRM ALL response>
|
||||
CONFIRM_YES </CONFIRM YES response>
|
||||
CONFIRM_NO </CONFIRM NO response> /WARNING
|
||||
CONFIRM_QUIT </CONFIRM QUIT response> /WARNING
|
||||
|
||||
EXIT <exiting>
|
||||
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
MSGFILE <Message definition file: !AZ> /FAO=1
|
||||
INVDEF <!AZ does not exist> /FAO=1
|
||||
HELPFILE <Help library file: !AZ> /FAO=1
|
||||
HELPFILEVER1 <Version !UL !UL-bit created !AZ> /FAO=3 /IDENT=HELPFILEVER
|
||||
HELPFILEVER2 <Version !UL !UL/!UL-bit created !AZ> /FAO=4 /IDENT=HELPFILEVER
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
FILHDRACC <unable to read file header>
|
||||
SETCWD <failed to set cwd>
|
||||
LOCALE <unable to set locale>
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
AMBIGUOUS <!AZ '!AZ' is ambiguous> /FAO=2
|
||||
UNKNOWN <unrecognized !AZ '!AZ'> /FAO=2
|
||||
NOVALUE <no value allowed for !AZ !AZ> /FAO=2
|
||||
VALUEREQ <value required for !AZ !AZ> /FAO=2
|
||||
NOPAREN <value is missng ')' for !AZ '!AZ'> /FAO=2
|
||||
TOOMANY <too many !AZ specified> /FAO=1
|
||||
TOOFEW <too few !AZ specified> /FAO=1
|
||||
|
||||
MAXIND <maximum indirect command file nesting limit (!UL) exceeded> /FAO=1
|
||||
UNTERMSTR <unterminated quoted string>
|
||||
INVNUMBER <!AZ is not a valid number> /FAO=1
|
||||
NOQUALS <no qualifiers specified>
|
||||
NOQUALSOK <no qualifiers permitted> /IDENT=NOQUALS
|
||||
NOPAROK <no parameters permitted>
|
||||
INCONQUAL <inconsistent use of qualifiers>
|
||||
BADPRO <invalid syntax for file or directory protection>
|
||||
BADUIC <invalid syntax for UIC. [group,member] must be numeric>
|
||||
BADVALUE <invalid value>
|
||||
|
||||
OPENIND <failed to open indirect command file !AZ> /FAO=1
|
||||
NOSHELL <failed to run !AZ> /FAO=1
|
||||
OSERROR <the last host OS error was: !AZ> /FAO=1
|
||||
OSERRORNO <the last host OS error was !UL.> /FAO=1 /IDENT=OSERROR
|
||||
|
||||
VMSTIME <failed to convert VMS time quadword>
|
||||
|
||||
FCS2DV <rename operation failed--different devices specified>
|
||||
BADORG <unsupported file organization>
|
||||
ILLDIRWRT <directories may not be written as files>
|
||||
|
||||
FILESTRUCT <unsupported file structure level !UL.!UL> /FAO=2
|
||||
|
||||
.SEVERITY SEVERE
|
||||
.BASE 1000
|
||||
|
||||
INITIALFAIL <initialization failed>
|
||||
|
||||
BADMSGFILE <invalid message file format>
|
||||
NOMSG <message number !8XL> /FAO_COUNT=1
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY COPY,85
|
||||
.LITERAL COPY_OFFSET = COPY_FACILITY - ^X800
|
||||
|
||||
.SEVERITY SUCCESS
|
||||
.BASE 200
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
.LITERAL COPY_COPIEDB = (COPY_OFFSET@16) + SHR_COPIEDB + SHR_INFO
|
||||
.LITERAL COPY_COPIEDR = (COPY_OFFSET@16) + SHR_COPIEDR + SHR_INFO
|
||||
|
||||
COPIEDU <!AZ copied to !AZ (!UL byte!%S)> /IDENT=COPIED /FAO=3
|
||||
|
||||
CONFIRM <copy !AZ to !AZ? > /FAO=2
|
||||
COPIED <!UL file(s) copied> /FAO=1
|
||||
NOFILES <no files found>
|
||||
DIRNOTCOPIED <!AZ is a directory, not copied> /FAO=1
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
.LITERAL COPY_OPENIN = (COPY_OFFSET@16) + SHR_OPENIN + SHR_WARN
|
||||
|
||||
PROTERR <failed to set protection for !AZ> /FAO=1
|
||||
NOMATCH <no local files match !AZ> /FAO=1
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
.LITERAL COPY_CLOSEOUT = (COPY_OFFSET@16) + SHR_CLOSEOUT + SHR_ERROR
|
||||
.LITERAL COPY_OPENIN = (COPY_OFFSET@16) + SHR_OPENIN + SHR_ERROR
|
||||
.LITERAL COPY_OPENOUT = (COPY_OFFSET@16) + SHR_OPENOUT + SHR_ERROR
|
||||
.LITERAL COPY_PARSEFAIL = (COPY_OFFSET@16) + SHR_PARSEFAIL + SHR_ERROR
|
||||
.LITERAL COPY_SEARCHFAIL = (COPY_OFFSET@16) + SHR_SEARCHFAIL + SHR_ERROR
|
||||
.LITERAL COPY_READERR = (COPY_OFFSET@16) + SHR_READERR + SHR_ERROR
|
||||
.LITERAL COPY_WRITEERR = (COPY_OFFSET@16) + SHR_WRITEERR + SHR_ERROR
|
||||
.LITERAL COPY_INVALIDNL = (COPY_OFFSET@16) + SHR_INVALIDNL + SHR_ERROR
|
||||
.LITERAL COPY_INVALIDVFU = (COPY_OFFSET@16) + SHR_INVALIDVFU + SHR_ERROR
|
||||
.LITERAL COPY_INVALIDC0 = (COPY_OFFSET@16) + SHR_INVALIDC0 + SHR_ERROR
|
||||
|
||||
NONAME <no file name specified for output>
|
||||
|
||||
.SEVERITY SEVERE
|
||||
.BASE 1000
|
||||
|
||||
NOMEM <out of memory expanding !AZ> /GAO=1
|
||||
GLOBABT <read error expanding !AZ> /FAO=1
|
||||
GLOBERR <unknown error !UL processing !AZ> /FAO=2
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY CREATE,86
|
||||
.LITERAL CREATE_OFFSET = CREATE_FACILITY - ^X800
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
.LITERAL CREATE_EXISTS = (CREATE_OFFSET@16) + SHR_EXISTS + SHR_INFO
|
||||
.LITERAL CREATE_CREATED = (CREATE_OFFSET@16) + SHR_CREATED + SHR_INFO
|
||||
|
||||
READY <!AZ is open for output. Type lines of text ending with Enter> /FAO=1
|
||||
TERMEOF <terminate input with !AZ> /FAO=1
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
CREDIRFAIL <failed to create directory !AZ> /FAO=1
|
||||
.LITERAL CREATE_NOTDIR = (CREATE_OFFSET@16) + SHR_NOTDIR + SHR_ERROR
|
||||
.LITERAL CREATE_CLOSEOUT = (CREATE_OFFSET@16) + SHR_CLOSEOUT + SHR_ERROR
|
||||
.LITERAL CREATE_INVALIDNL = (CREATE_OFFSET@16) + SHR_INVALIDNL + SHR_ERROR
|
||||
.LITERAL CREATE_INVALIDVFU = (CREATE_OFFSET@16) + SHR_INVALIDVFU + SHR_ERROR
|
||||
.LITERAL CREATE_INVALIDC0 = (CREATE_OFFSET@16) + SHR_INVALIDC0 + SHR_ERROR
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY DELETE,87
|
||||
.LITERAL DELETE_OFFSET = DELETE_FACILITY - ^X800
|
||||
|
||||
.SEVERITY SUCCESS
|
||||
.BASE 200
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
CONFIRM <delete !AZ? > /FAO:1
|
||||
DELETED <deleted !AZ> /FAO=1
|
||||
NFILES <!UL files deleted> /FAO=1 /IDENT=DELETED
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
.LITERAL DELETE_OPENIN = (DELETE_OFFSET@16) + SHR_OPENIN + SHR_WARN
|
||||
|
||||
NOFILES <no files deleted>
|
||||
NOTDELETED <error deleting !AZ> /FAO=1
|
||||
DIRNOTEMPTY <directory is not empty>
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
|
||||
.SEVERITY SEVERE
|
||||
.BASE 1000
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY DIFF,88
|
||||
.LITERAL DIFF_OFFSET = DIFF_FACILITY - ^X800
|
||||
|
||||
.SEVERITY SUCCESS
|
||||
.BASE 200
|
||||
|
||||
NODIFF <no differences encountered>
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
COMPARED <compared !UL record(s)> /FAO=1
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
.LITERAL DIFF_OPENIN = (DIFF_OFFSET@16) + SHR_OPENIN + SHR_ERROR
|
||||
|
||||
DIFFER <files differ at record !UL>
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY DIRECT,89
|
||||
.LITERAL DIRECT_OFFSET = DIRECT_FACILITY - ^X800
|
||||
|
||||
.SEVERITY WARNING
|
||||
|
||||
.SEVERITY SUCCESS
|
||||
.BASE 200
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
DIRHEAD <!/Directory !AZ!/!/> /FAO=1
|
||||
FULLSIZE <!/Size: !9UL> /FAO=1
|
||||
GRANDTOT <!/Grand total of !UL directory!%S, !UL file!%S> /FAO=2
|
||||
FILETOTAL <!/Total of !UL file!%S> /FAO=1
|
||||
USEDTOT <!UL block!%S> /FAO=1
|
||||
ALLOCTOT <!UL block!%S> /FAO=1
|
||||
BOTHSIZE <!UL/!UL block!%S> /FAO=2
|
||||
OWNER <owner: [!OW,!OW]> /FAO=2
|
||||
CREATED <created: >
|
||||
REVISED <revised: >
|
||||
EXPIRES <expires: >
|
||||
BACKUP <backup: >
|
||||
FILEORG <file organization: >
|
||||
SEQORG <sequential>
|
||||
RELORG <relative>
|
||||
IDXORG <indexed>
|
||||
UNKORG <unknown (!UL)> /FAO=1
|
||||
FILEATT <!/File attributes: >
|
||||
ALLOC <allocation: !UL> /FAO=1
|
||||
EXTEND <, Extend: !UW> /FAO=1
|
||||
GBC <, Global buffer count: !UW> /FAO=1
|
||||
VERLIMIT <, Version limit: !UW> /FAO=1
|
||||
DIRLIMIT <, Default version limit: !UW> /FAO=1
|
||||
NOVERLIMIT <, No version limit>
|
||||
NODIRLIMIT <, No default version limit>
|
||||
|
||||
CONTIG <, Contiguous>
|
||||
CONTIGB <, Contiguous best try>
|
||||
NOBACKUP <, Backups disabled>
|
||||
DIRECTORY <, Directory file>
|
||||
WRITEBACK <, Writeback>
|
||||
READCHECK <, Read verification>
|
||||
WRITECHECK <, Write verification>
|
||||
LOCKED <, File locked>
|
||||
SPOOL <, Spool file>
|
||||
MARKDEL <, Marked for deletion>
|
||||
BADBLOCK <, Contains bad block>
|
||||
|
||||
EOFPOS <end of file: Block !UL, byte !UW!/> /FAO=2
|
||||
|
||||
RECFMT <record format: >
|
||||
RECUDF <undefined>
|
||||
RECFIX <fixed length !UW byte records> /FAO=1
|
||||
RECVAR <variable length, maximum !UW bytes> /FAO=1
|
||||
RECVFC <VFC, !UB byte header, maximum !UW bytes> /FAO=2
|
||||
RECSTM <stream>
|
||||
RECSTMLF <stream-LF>
|
||||
RECSTMCR <stream-CR>
|
||||
|
||||
RECATT <Record attributes: >
|
||||
RECATT_NONE <none>
|
||||
RECATT_FTN <!AZFortran carriage control> /FAO=1
|
||||
RECATT_CR <!AZCarriage return carriage control> /FAO=1
|
||||
RECATT_PRN <!AZPrint file carriage control> /FAO=1
|
||||
RECATT_BLK <!AZNon-spanned> /FAO=1
|
||||
|
||||
PROT_SYS <File protection: System:>
|
||||
PROT_OWNER <, Owner:>
|
||||
PROT_GROUP <, Group:>
|
||||
PROT_WORLD <, World:>
|
||||
|
||||
UIC < [!OW,!OW]> /FAO=2
|
||||
|
||||
IDNAME <!/Header filename: !AZ> /FAO=1
|
||||
EXTNHDR <extension header: !UW, Extension FID (!UL,!UW,!UB)> /FAO=4
|
||||
HDROFFSETS <ID area offset (words):!UB!/Map area offset: !UB!/ACL area offset: !UB!/Reserved area offset: !UB> /FAO=4
|
||||
STRUCLEVEL <structure level: !UB.!UB> /FAO=2
|
||||
MAPSIZE <map area size: !UL, in use: !UL!/Cluster size: !UL!/Highest VBN allocated: !UL> /FAO=4
|
||||
MAPHIGHWATER <highest VBN written: !UL> /FAO=1
|
||||
MAPHEADER <!/Retrieval pointers:!/ VBN F Count Start LBN End LBN!/--------- - --------- --------- --------->
|
||||
MAPFMT0 <format 0: !XW> /FAO=1
|
||||
MAPENTRY <!9UL !UW !9UL !9UL !9UL> /FAO=5
|
||||
MAPFREE "!9UL <= First free" /FAO=1
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
.LITERAL DIRECT_NOFILES = (DIRECT_OFFSET@16) + SHR_NOFILES + SHR_WARN
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
.LITERAL DIRECT_OPENOUT = (DIRECT_OFFSET@16) + SHR_OPENOUT + SHR_ERROR
|
||||
|
||||
.SEVERITY SEVERE
|
||||
.BASE 1000
|
||||
|
||||
.END
|
||||
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY DISM,90
|
||||
.LITERAL DISM_OFFSET = DISM_FACILITY - ^X800
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
DISMOUNTD <volume !12AD of volume set !12AD dismounted> /FAO=4 /IDENT=DISMOUNTED
|
||||
DISMOUNTDV <volume !12AD dismounted> /FAO=2 /IDENT=DISMOUNTED
|
||||
|
||||
DISMAL <all members of !12AD have been dismounted>
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
CANNOTDMT <!12AD cannot be dismounted> /FAO=2
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
.SEVERITY SEVERE
|
||||
.BASE 1000
|
||||
|
||||
DEVNOTDISM <device not dismounted>
|
||||
USERFILES <!SL user file(s) open on volume> /FAO=1
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY EXTEND,91
|
||||
.LITERAL EXTEND_OFFSET = EXTEND_FACILITY - ^X800
|
||||
|
||||
.SEVERITY SUCCESS
|
||||
.BASE 200
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
NEWSIZE <new allocated size is !UL block!%S> /FAO=1
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
CONFLQUAL <can not specify both !AZallocate and !AZtruncate> /FAO=2
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY HELP,92
|
||||
.LITERAL HELP_OFFSET = HELP_FACILITY - ^X800
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
TERMWID <A minimum terminal window width of !UL is recommended for correct formatting of HELP> /FAO=1
|
||||
TERMSIZE <Terminal width is !UL, height is !UL> /FAO:2
|
||||
KEYWORD < keyword, one of the following:>
|
||||
KEYWORDS < keywords, one or more of the following:>
|
||||
QUALIFIER < qualifier, one of the following>
|
||||
QUALIFIERS < qualifiers, one or more of the following>
|
||||
LIST <list, !AZ> /FAO=1
|
||||
LISTS <lists, !AZ> /FAO=1
|
||||
HEAD < Commands are:>
|
||||
MORE < Additional information:>
|
||||
EXPLAIN < Type HELP COMMAND or HELP TOPIC for information on any command or topic.!/ Type HELP HELP for information on the help system.>
|
||||
NOCMDHELP <!AZ: No help available> /FAO=1
|
||||
NOPARHELP <no parameter '!AZ' found> /FAO=1
|
||||
PARNOTACT <parameter is not used for this command>
|
||||
NOPARAMS <!AZ has no parameters> /FAO=1
|
||||
PARHEADING <!/ Parameters:!/ >
|
||||
PARNOLIMIT < "*" indicates that a parameter can be used more than once.>
|
||||
PAREXPLAIN < Type help !AZ PARAMETER for more about each parameter.> /FAO=1
|
||||
QUALHEAD <qualifiers>
|
||||
|
||||
SETVALUE <type 'help set value ITEM' for item details>
|
||||
|
||||
SHOWCWD < Current working directory is !AZ> /FAO=1
|
||||
SHOWDEFQ < Default qualifiers for !AZ command> /FAO=1
|
||||
SHOWNODEFQ < None set>
|
||||
SHOWQSTYLE < Qualifier style: !AZ> /FAO=1
|
||||
SHOWSTATS <Statistics:>
|
||||
SHOWVERON <Command file verification is on>
|
||||
SHOWVEROFF <Command file verification is off>
|
||||
SHOWVERS < !AZ !AZ built !AZ !AZ> /FAO=4
|
||||
SHOWVERSRL < !AZ !AZ built !AZ !AZ with libedit version !UL.!UL> /FAO=6
|
||||
SHOWVERSCSI < Direct SCSI access is supported>
|
||||
SHOWVERNOVHD < VHD format image file support is not configured>
|
||||
SHOWVERPLATFM < Platform: !AZ> /FAO=1
|
||||
SHOWVERCOMPLR < Compiler: !AZ, version !AZ> /FAO=2
|
||||
SHOWVLD < Visual Leak Detector is configured>
|
||||
SHOWCMDHISTLN <!5UL: !AZ> /FAO=2
|
||||
SHOWMSGPRINTED <(printed): >
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
OPENHLP <failed to open help file !AZ> /FAO=1
|
||||
NOHELP <can't locate help topic "!AZ" in !AZ> /FAO=2
|
||||
HELPFMT <help file !AZ has invalid format or is empty> /FAO=1 /IDENT=NOHELP
|
||||
HELPLEVEL <help level error at line !UL> /FAO=1
|
||||
NOTEXT <no text for topic !AZ at line !UL> /FAO=2
|
||||
NOTEXT2 <no text for topic !AZ> /FAO=1 /IDENT=HELPNOTEXT
|
||||
SHOWNOCMDHIST <No command history exists>
|
||||
SETCMDHISTVAL <Command history limit must be greater than zero>
|
||||
|
||||
.END
|
||||
! ********************************************************************************
|
||||
.FACILITY INIT,93
|
||||
.LITERAL INIT_OFFSET = INIT_FACILITY - ^X800
|
||||
|
||||
.SEVERITY SUCCESS
|
||||
.BASE 200
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
CONFIRM_PHY <this will delete all data on the physical device !AZ. Proceed? > /FAO:1 /IDENT=CONFIRM
|
||||
CONFIRM_VIRT <this will delete all data in !AZ and initialize a !AZ image file. Proceed? > /FAO:2 /IDENT=CONFIRM
|
||||
|
||||
START_PHY <initializing !AZ on device !AZ as !AZ> /FAO=3 /IDENT=STARTING
|
||||
START_VIRT <initializing !AZ on disk image !AZ as !AZ> /FAO=3 /IDENT=STARTNG
|
||||
|
||||
VOLINIT <!AZ initialized successfully> /FAO=1
|
||||
SIZING1 <volume size !UL blocks, cluster size !UL, maximum files !UL> /IDENT=SIZING /FAO=3
|
||||
SIZING2 <preallocated !UL file headers !UL directory entries> /IDENT=SIZING /FAO=2
|
||||
PLACED1 <boot block at LBN !UL, HOM blocks at LBNs !UL and !UL> /IDENT=SIZING /FAO=3
|
||||
PLACED2 < MFD at LBN !UL, index file at LBNs !UL thru !UL> /IDENT=SIZING /FAO=3
|
||||
|
||||
MFGBAD <writing manufacturer's bad block index>
|
||||
SWBAD <writing software bad block descriptor>
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
INVOPT <!AZcreate and !AZreplace only apply to disk image files> /FAO=2
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
BADVOLLABEL <volume label must be 1-12 alphanumeric charactes>
|
||||
BADUSERNAME <username must be 1-12 alphanumeric characters>
|
||||
BADMEDIUM <unknown medium '!AZ'; HELP INITIALIZE for list> /FAO=1
|
||||
|
||||
.SEVERITY SEVERE
|
||||
.BASE 1000
|
||||
|
||||
TOOSMALL <device is too small to hold a useful Files-11 volume>
|
||||
NOHOMLOC <no good block found for primary HOM block>
|
||||
NOHOM2LOC <no good block found for secondary HOM block> /IDENT=NOHOMLOC
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY IO,94
|
||||
.LITERAL IO_OFFSET = IO_FACILITY - ^X800
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
STATS <initializations: !UL Reads: !UL Writes: !UL> /FAO=3
|
||||
LARGEFILE "large files and devices (>2GB) are supported"
|
||||
NOLARGEFILE "large files and devices (>2GB) are NOT supported"
|
||||
UNXDEVHDR < Physical devices>
|
||||
NODEVS <no devices found>
|
||||
|
||||
NTDEVHEADER < Physical devices!/ Drv Type Physical Name!/ --- --------- ------------->
|
||||
NTDEVREMOVABLE < !AZ Removable !AZ> /FAO=2
|
||||
NTDEVFIXED < !AZ Fixed !AZ> /FAO=2
|
||||
NTDEVREMOTE < !AZ Network> /FAO=1
|
||||
NTDEVCDROM < !AZ CDROM !AZ> /FAO=2
|
||||
NTDEVRAMDISK < !AZ RAMdisk !AZ> /FAO=2
|
||||
NTDEVOTHER < !AZ Other> /FAO=1
|
||||
|
||||
VNODEVS < No virtual devices are assigned>
|
||||
VDEVHEADER < Virtual devices>
|
||||
|
||||
VHDAVAIL <VHD format image files are supported>
|
||||
VHDNOTAVAIL <VHD format image file support is configured, but not available>
|
||||
VHDFMTSTART <formatting !AZ> /FAO=1
|
||||
VHDFMTEND <VHD volume formatting completed>
|
||||
VMSMOUNT <device !AZ mounted /FOREIGN> /FAO=1
|
||||
VMSDMT <device !AZ dismounted> /FAO=1
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
VHDSAVED <!AZ contains a suspended system and should not be modified> /FAO=1
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
NOVHD <VHD disk support is not available in this version>
|
||||
ISVIRTDEV <!AD is a virtual device> /FAO=2
|
||||
VIRTDEVINUSE <!AZ is in use by !AZ> /FAO=2
|
||||
VIRTFILEINUSE <!AZ is in use on virtual drive !AZ> /FAO=2
|
||||
BADPATH <invalid path: !AZ> /FAO=1
|
||||
DIRRDERR <error reading directory !AZ> /FAO=1
|
||||
LOCKVOL <error locking volume on !AZ> /FAO=1
|
||||
NOGEO <unable to obtain geometry for !AZ> /FAO=1
|
||||
OPENDEV <error opening !AZ> /FAO=1
|
||||
READERR <read error at sector !UL> /FAO=1
|
||||
READLEN <read error at lbn !UL, got !UL, expected !UL> /FAO=3
|
||||
WRITELEN <read error at lbn !UL, got !UL, expected !UL> /FAO=3
|
||||
SEEKERR <seek failure at sector !UL> /FAO=1
|
||||
WRITEERR <write error at sector !UL> /FAO=1
|
||||
UNXNOTREG <!AZ is not a regular file> /FAO=1
|
||||
UNXNOTBLK <!AZ is not a block device> /FAO=1
|
||||
EXISTS <file !AZ already exists, not superseded> /FAO=1
|
||||
RDBLK2BIG <read from non-existent LBN !UL> /FAO=1 /IDENT=BLK2BIG
|
||||
WRBLK2BIG <write to non-existent LBN !UL> /FAO=1 /IDENT=BLK2BIG
|
||||
VHDONLY <!AZ Snapshots can only be taken of VHD format image files> /FAO=1
|
||||
VHDSNAPFAIL <snapshot of !AZ failed> /FAO=1
|
||||
VHDMEM <failed to allocate memory for VHD>
|
||||
VHDCREATEERR <error creating VHD volume !AZ> /FAO=1
|
||||
VMSDEVSCAN <error scanning devices>
|
||||
VMSNOMOUNT <unable to mount device !AZ /FOREIGN> /FAO=1
|
||||
VMSNODMT <unable to dismount device !AZ> /FAO=1
|
||||
|
||||
.SEVERITY SEVERE
|
||||
.BASE 1000
|
||||
|
||||
OFFSET_TOO_BIG <Volume is too large for local file system: needs 64-bit I/O>
|
||||
|
||||
VHDNOLIB <VHD library !AZ could not be loaded> /FAO=1
|
||||
VHDNOSYM <symbol !AZ not present in !AZ> /FAO=2
|
||||
VHDNOTVALID <the VHD library !AZ is not usable> /FAO=1
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY MOUNT,95
|
||||
.LITERAL MOUNT_OFFSET = MOUNT_FACILITY - ^X800
|
||||
|
||||
.SEVERITY WARNING
|
||||
|
||||
.SEVERITY SUCCESS
|
||||
.BASE 200
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
MOUNTED <!12AD mounted on !AZ> /FAO=3
|
||||
SNAPOK <!AZ created from !AZ> /FAO=2
|
||||
VSMOUNTED <volume set !12AD mounted> /FAO=1
|
||||
WRITELCK <!AZ can not be written, mounted read-only> /FAO=1
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
BADSCB <invalid storage control block on !AZ> /FAO=1
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
BADLABEL <label !AZ is too long> /FAO=1
|
||||
FAILED <mount failed>
|
||||
HOMBLKCHK <!UL home block software consistency error!%S> /FAO=1
|
||||
BITMAPSYS <unable to access BITMAP.SYS on !AZ> /FAO=1
|
||||
BITUPDFAIL <unable to compute disk usage for !AZ> /FAO=1
|
||||
INCONVOL <volume '!12AD' on !AZ is a member of '!12AD', not a member of '!12AD'> /FAO=7
|
||||
NOTSAME <you must specify the same number of existing files (!UL) with !AZSNAPSHOT as filenames to create (!UL)> /FAO=3
|
||||
RVN1NOTMNT <volume 1 of the volume set must be mounted>
|
||||
VOLOOO <RVN !UL of '!12AD' is '!12AD'. !AZ contains '!AD'> /FAO=8
|
||||
VOLSETSYS <unable to access VOLSET.SYS on !AZ> /FAO=1
|
||||
WRONGRVN <device !AZ contains !12AD, which is RVN !UW of !12AD. !UL of !12AD expected> /FAO=9 /IDENT=WRONGVOL
|
||||
NOTVSMEM <device !AZ contains !12AD, which is not part of a volume set. RVN !UL of !12AD expected> /FAO=6
|
||||
WRONGVOL <device !AZ contains volume '!12AD', '!12AD' expected> /FAO=5
|
||||
WRONGVOLCNT <volume set !12AD has !UL members, but !UL specified> /FAO=3
|
||||
WRONGVOLMEM <volume set name on !AZ is '!12AD', but VOLSET.SYS is for '!12AD'> /FAO=5
|
||||
|
||||
.SEVERITY SEVERE
|
||||
.BASE 1000
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY RENAME,96
|
||||
.LITERAL RENAME_OFFSET = RENAME_FACILITY - ^X800
|
||||
|
||||
.SEVERITY SUCCESS
|
||||
.BASE 200
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
|
||||
RENAMED <!AZ renamed to !AZ> /FAO=2
|
||||
|
||||
CONFIRM <rename !AZ to !AZ? > /FAO=2
|
||||
NRENAMED <!UL file(s) renamed> /FAO=1 /IDENT=RENAMED
|
||||
NOFILES <no files renamed>
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
FAILED <rename !AZ to !AZ failed> /FAO=2
|
||||
|
||||
.LITERAL RENAME_PARSEFAIL = (RENAME_OFFSET@16) + SHR_PARSEFAIL + SHR_ERROR
|
||||
.LITERAL RENAME_SEARCHFAIL = (RENAME_OFFSET@16) + SHR_SEARCHFAIL + SHR_ERROR
|
||||
|
||||
.SEVERITY SEVERE
|
||||
.BASE 1000
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY SEARCH,97
|
||||
.LITERAL SEARCH_OFFSET = SEARCH_FACILITY - ^X800
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
CONFIRM <search !AZ? > /FAO=1
|
||||
NOMATCH <no strings matched>
|
||||
MATCHED <!AZ searched, !UL record!%S, !UL match!%S> /FAO=3
|
||||
FILE <!AZ searched, !UL record!%S, no matches> /FAO=2
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
.LITERAL SEARCH_OPENIN = (SEARCH_OFFSET@16) + SHR_OPENIN + SHR_WARN
|
||||
.LITERAL SEARCH_NOFILES = (SEARCH_OFFSET@16) + SHR_NOFILES + SHR_WARN
|
||||
.LITERAL SEARCH_CONTINUE = (SEARCH_OFFSET@16) + SHR_CONTINUE + SHR_INFO
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
.LITERAL SEARCH_PARSEFAIL = (SEARCH_OFFSET@16) + SHR_PARSEFAIL + SHR_ERROR
|
||||
.LITERAL SEARCH_SEARCHFAIL = (SEARCH_OFFSET@16) + SHR_SEARCHFAIL + SHR_ERROR
|
||||
|
||||
BADSTRING <search string !UL too short> /FAO=1
|
||||
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY TYPE,98
|
||||
.LITERAL TYPE_OFFSET = TYPE_FACILITY - ^X800
|
||||
|
||||
.SEVERITY INFO
|
||||
.BASE 400
|
||||
|
||||
.LITERAL TYPE_CONTINUE = (TYPE_OFFSET@16) + SHR_CONTINUE + SHR_INFO
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 600
|
||||
|
||||
.LITERAL TYPE_OPENIN = (TYPE_OFFSET@16) + SHR_OPENIN + SHR_WARN
|
||||
|
||||
.SEVERITY ERROR
|
||||
.BASE 800
|
||||
|
||||
.LITERAL TYPE_PARSEFAIL = (TYPE_OFFSET@16) + SHR_PARSEFAIL + SHR_ERROR
|
||||
.LITERAL TYPE_SEARCHFAIL = (TYPE_OFFSET@16) + SHR_SEARCHFAIL + SHR_ERROR
|
||||
|
||||
|
||||
.END
|
||||
|
||||
! ********************************************************************************
|
||||
.FACILITY SHR,0 /SHARED
|
||||
|
||||
.LITERAL SHR_WARN = 0
|
||||
.LITERAL SHR_SUCCESS = 1
|
||||
.LITERAL SHR_ERROR = 2
|
||||
.LITERAL SHR_INFO = 3
|
||||
.LITERAL SHR_SEVERE = 4
|
||||
|
||||
! Convention shared with DEC:
|
||||
! All shared messaged defined as WARNING so that user can
|
||||
! add one of the severity codes above
|
||||
|
||||
.SEVERITY WARNING
|
||||
.BASE 0
|
||||
NORMAL <normal successful completion>
|
||||
|
||||
.BASE 600
|
||||
|
||||
CONTINUE " Type <CR> to continue, f<CR> to finish, q<cr> to abort "
|
||||
|
||||
CLOSEIN <error closing !AZ as input> /FAO=1
|
||||
CLOSEOUT <error closing !AZ as output> /FAO=1
|
||||
COPIEDB <!AZ copied to !AZ (!UL block!%S)> /IDENT=COPIED /FAO=3
|
||||
COPIEDR <!AZ copied to !AZ (!UL record!%S)> /IDENT=COPIED /FAO=3
|
||||
CREATED <!AZ created> /FAO=1
|
||||
EXISTS <!AZ already exists> /FAO=1
|
||||
|
||||
INVALIDNL <VFC newline count must be between 1 and 128>
|
||||
INVALIDVFU <VFU channel must be between 1 an 16>
|
||||
INVALIDC0 <VFC ASCII control must be between 0 and 31>
|
||||
|
||||
NOFILES <no files found>
|
||||
NOTDIR <!AZ is not a directory> /FAO=1
|
||||
|
||||
OPENIN <error opening !AZ as input> /FAO=1
|
||||
OPENOUT <error opening !AZ for output> /FAO=1
|
||||
|
||||
PARSEFAIL <error parsing !AZ> /FAO=1
|
||||
READERR <error reading !AZ> /FAO=1
|
||||
SEARCHFAIL <error searching for !AZ> /FAO=1
|
||||
|
||||
WRITEERR <error writing !AZ> /FAO=1
|
||||
|
||||
.END
|
||||
@@ -1,10 +1,13 @@
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_EXTENDCMD )
|
||||
@@ -19,32 +22,67 @@
|
||||
|
||||
|
||||
/***************************************************************** doextend() */
|
||||
static uint32_t alq;
|
||||
|
||||
/* more test code... */
|
||||
#define xtnd_truncate OPT_GENERIC_1
|
||||
#define xtnd_allocate OPT_GENERIC_2
|
||||
|
||||
param_t extendpars[] = { {"ods-2_filespec", REQ, VMSFS, NOPA, "for file on ODS-2 volume."},
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
qual_t
|
||||
extendquals[] = { {"allocate", xtnd_allocate, 0, DV(&alq),
|
||||
"commands extend qual_allocate"},
|
||||
{"truncate", xtnd_truncate, 0, NV,
|
||||
"commands extend qual_truncate"},
|
||||
|
||||
{NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
|
||||
param_t
|
||||
extendpars[] = { {"filespec", REQ, FSPEC, NOPA, "commands extend filespec"},
|
||||
|
||||
{NULL, 0, 0, NOPA, NULL}
|
||||
};
|
||||
|
||||
DECL_CMD(extend) {
|
||||
int sts;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
vmscond_t sts;
|
||||
options_t options;
|
||||
struct FAB fab;
|
||||
|
||||
UNUSED(argc);
|
||||
UNUSED(qualc);
|
||||
UNUSED(qualv);
|
||||
|
||||
fab = cc$rms_fab;
|
||||
|
||||
alq = 0;
|
||||
if( $FAILS(sts = checkquals( &options, 0, extendquals, qualc, qualv )) ) {
|
||||
return sts;
|
||||
}
|
||||
|
||||
if( !(~options & (xtnd_allocate|xtnd_truncate)) )
|
||||
return printmsg( EXTEND_CONFLQUAL, 0, qstyle_s, qstyle_s );
|
||||
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = strlen(fab.fab$l_fna);
|
||||
fab.fab$b_fns = (uint8_t)strlen(fab.fab$l_fna);
|
||||
fab.fab$b_fac = FAB$M_UPD;
|
||||
sts = sys_open( &fab );
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
fab.fab$l_alq = 32;
|
||||
sts = sys_extend(&fab);
|
||||
sys_close(&fab);
|
||||
|
||||
if( options & xtnd_truncate )
|
||||
fab.fab$l_fop |= FAB$M_TEF;
|
||||
|
||||
if( $SUCCESSFUL(sts = sys_open( &fab )) ) {
|
||||
if( alq ) {
|
||||
fab.fab$l_alq = alq;
|
||||
sts = sys_extend(&fab);
|
||||
}
|
||||
sys_close( &fab );
|
||||
fab.fab$l_alq = 0;
|
||||
if( $SUCCESSFUL(sts) ) {
|
||||
sts = sys_open( &fab );
|
||||
sys_close( &fab );
|
||||
}
|
||||
}
|
||||
if ( !( sts & STS$M_SUCCESS ) ) {
|
||||
printf("%%EXTEND-F-ERROR Status: %s\n",getmsg(sts, MSG_TEXT));
|
||||
if( $FAILED(sts) ) {
|
||||
sts = printmsg(sts, 0);
|
||||
} else {
|
||||
sts = printmsg( EXTEND_NEWSIZE, 0, fab.fab$l_alq );
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
/* Access.h Definitions for file access routines */
|
||||
|
||||
/*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
email address: Paulnank@au1.ibm.com
|
||||
* 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.
|
||||
*/
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _F11DEF_H
|
||||
#define _F11DEF_H
|
||||
@@ -17,53 +20,75 @@
|
||||
|
||||
#include "vmstime.h"
|
||||
|
||||
|
||||
#ifndef ODS2_BIG_ENDIAN
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define ODS2_BIG_ENDIAN 1
|
||||
#endif
|
||||
#else
|
||||
#define ODS2_BIG_ENDIAN 0
|
||||
#endif
|
||||
#elif !defined(__GNUC__) /* GLIB can define some of these with older GCC */
|
||||
#if defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)
|
||||
#define ODS2_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ODS2_BIG_ENDIAN
|
||||
#define F11LONG( l ) ( ( (l) & 0x000000ff ) << 24 | \
|
||||
( (l) & 0x0000ff00 ) << 8 | \
|
||||
( (l) & 0x00ff0000 ) >> 8 | \
|
||||
(l) >> 24 )
|
||||
#define F11WORD( w ) ( ( (w) & 0x00ff ) << 8 | \
|
||||
(w) >> 8 )
|
||||
#define F11SWAP( l ) ( ( (l) & 0x00ff0000 ) << 8 | \
|
||||
( (l) & 0xff000000 ) >> 8 | \
|
||||
( (l) & 0x000000ff ) << 8 | \
|
||||
( (l) & 0x0000ff00 ) >> 8 )
|
||||
#else
|
||||
#define F11LONG( l ) (l)
|
||||
#define F11WORD( w ) (w)
|
||||
#define F11SWAP( l ) ( ( (l) & 0x0000ffff ) << 16 | \
|
||||
(l) >> 16 )
|
||||
#define ODS2_BIG_ENDIAN 0
|
||||
#endif
|
||||
#else
|
||||
#define ODS2_BIG_ENDIAN 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef uint8_t f11byte;
|
||||
#if ODS2_BIG_ENDIAN
|
||||
#define F11LONG( l ) ((f11long)( ( (l) & 0x000000ff ) << 24 | \
|
||||
( (l) & 0x0000ff00 ) << 8 | \
|
||||
( (l) & 0x00ff0000 ) >> 8 | \
|
||||
(l) >> 24 ))
|
||||
#define F11WORD( w ) ((f11word)( ( (w) & 0x00ff ) << 8 | \
|
||||
(w) >> 8 ))
|
||||
#define F11SWAP( l ) ((f11long)( ( (l) & 0x00ff0000 ) << 8 | \
|
||||
( (l) & 0xff000000 ) >> 8 | \
|
||||
( (l) & 0x000000ff ) << 8 | \
|
||||
( (l) & 0x0000ff00 ) >> 8 ))
|
||||
#else
|
||||
#define F11LONG( l ) ((f11long)(l))
|
||||
#define F11WORD( w ) ((f11word)(w))
|
||||
#define F11SWAP( l ) ((f11long)( ( (l) & 0x0000ffff ) << 16 | \
|
||||
(l) >> 16 ))
|
||||
#endif
|
||||
|
||||
typedef uint8_t f11byte;
|
||||
typedef uint16_t f11word;
|
||||
typedef uint32_t f11swap;
|
||||
typedef uint32_t f11long;
|
||||
|
||||
#define FH2$M_WASCONTIG 0x00001
|
||||
#define FH2$M_NOBACKUP 0x00002
|
||||
#define FH2$M_WRITEBACK 0x00004
|
||||
#define FH2$M_READCHECK 0x00008
|
||||
#define FH2$M_WRITECHECK 0x00010
|
||||
#define FH2$M_CONTIGB 0x00020
|
||||
#define FH2$M_LOCKED 0x00040
|
||||
#define FH2$M_CONTIG 0x00080
|
||||
#define FH2$M_DIRECTORY 0x02000
|
||||
#define FH2$M_MARKDEL 0x08000
|
||||
#define FH2$M_ERASE 0x20000
|
||||
|
||||
#define FH2$M_BADACL 0x000800
|
||||
#define FH2$M_SPOOL 0x001000
|
||||
#define FH2$M_DIRECTORY 0x002000
|
||||
#define FH2$M_BADBLOCK 0x004000
|
||||
#define FH2$M_MARKDEL 0x008000
|
||||
#define FH2$M_NOCHARGE 0x010000
|
||||
#define FH2$M_ERASE 0x020000
|
||||
#define FH2$M_NOMOVE 0x200000
|
||||
|
||||
#ifdef __ALPHA
|
||||
#pragma member_alignment save
|
||||
#pragma nomember_alignment
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma pack(push,1)
|
||||
#endif
|
||||
|
||||
struct UIC {
|
||||
f11word uic$w_mem;
|
||||
f11word uic$w_grp;
|
||||
@@ -75,6 +100,48 @@ struct fiddef {
|
||||
f11byte fid$b_rvn;
|
||||
f11byte fid$b_nmx;
|
||||
};
|
||||
#define NULL_FID(fidadr) ((fidadr)->fid$w_num == 0 && \
|
||||
(fidadr)->fid$w_seq == 0 && \
|
||||
(fidadr)->fid$b_rvn ==0 && \
|
||||
(fidadr)->fid$b_nmx == 0 )
|
||||
|
||||
#define FID_MATCH(fid1,fid2,rvn) ((fid1)->fid$w_num == (fid2)->fid$w_num && \
|
||||
(fid1)->fid$w_seq == (fid2)->fid$w_seq && \
|
||||
((fid1)->fid$b_rvn? (fid1)->fid$b_rvn: rvn) == \
|
||||
((fid2)->fid$b_rvn? (fid2)->fid$b_rvn: rvn) && \
|
||||
(fid1)->fid$b_nmx == (fid1)->fid$b_nmx )
|
||||
|
||||
#define FID$C_INDEXF 1
|
||||
#define FID$C_BITMAP 2
|
||||
#define FID$C_BADBLK 3
|
||||
#define FID$C_MFD 4
|
||||
#define FID$C_CORIMG 5
|
||||
#define FID$C_VOLSET 6
|
||||
#define FID$C_CONTIN 7
|
||||
#define FID$C_BACKUP 8
|
||||
#define FID$C_BADLOG 9
|
||||
#define FID$C_FREFIL 10
|
||||
|
||||
#define FID$C_MAXRES 10
|
||||
|
||||
#define prot$m_system 0x000F
|
||||
#define prot$v_system 0
|
||||
#define prot$m_owner 0x00F0
|
||||
#define prot$v_owner 4
|
||||
#define prot$m_group 0x0F00
|
||||
#define prot$v_group 8
|
||||
#define prot$m_world 0xF000
|
||||
#define prot$v_world 12
|
||||
|
||||
#define prot$m_noread 0x1
|
||||
#define prot$m_nowrite 0x2
|
||||
#define prot$m_noexe 0x4
|
||||
#define prot$m_nodel 0x8
|
||||
#define prot$m_none (prot$m_noread|prot$m_nowrite|prot$m_noexe|prot$m_nodel)
|
||||
#define prot$m_norestrict 0x0
|
||||
#define SETPROT( sys, own, grp, wld ) \
|
||||
( ((sys) << prot$v_system) | ((own) << prot$v_owner) | \
|
||||
((grp) << prot$v_group) | ((wld) << prot$v_world) )
|
||||
|
||||
struct RECATTR {
|
||||
f11byte fat$b_rtype;
|
||||
@@ -166,12 +233,32 @@ struct HEAD {
|
||||
f11byte fh2$b_ru_active;
|
||||
f11word fh2$w_reserved2;
|
||||
f11long fh2$l_highwater;
|
||||
#define FH2$C_LENGTH 80 /* (offsetof( struct HEAD, fh2$l_highwater) +
|
||||
sizeof( f11long ))
|
||||
*/
|
||||
f11byte fh2$b_reserved3[8];
|
||||
f11byte fh2$r_class_prot[20];
|
||||
f11byte fh2$r_restofit[402];
|
||||
struct fh2$r_class_prot {
|
||||
f11byte cls$b_secur_lev;
|
||||
f11byte cls$b_integ_lev;
|
||||
f11word reserved4;
|
||||
f11byte cls$q_secur_cat[8];
|
||||
f11byte cls$q_integ_cat[8];
|
||||
} fh2$r_class_prot;
|
||||
f11byte fh2$r_vardata[402];
|
||||
f11word fh2$w_checksum;
|
||||
};
|
||||
|
||||
#define STRUCLEV (0x0201)
|
||||
#define FM2$M_FORMAT1 (1 << 14)
|
||||
#define FM2$M_FORMAT2 (2 << 14)
|
||||
#define FM2$M_FORMAT3 (3 << 14)
|
||||
#define FM2$C_FMT1_MAXLBN ((1 << 22) - 1)
|
||||
#define FM2$C_FMT1_MAXCNT (256)
|
||||
#define FM2$C_FMT2_MAXLBN (0xFFFFFFFF)
|
||||
#define FM2$C_FMT2_MAXCNT (1 << 14)
|
||||
#define FM2$C_FMT3_MAXLBN (0xFFFFFFFF)
|
||||
#define FM2$C_FMT3_MAXCNT (1 << 30)
|
||||
|
||||
struct SCB {
|
||||
f11word scb$w_struclev;
|
||||
f11word scb$w_cluster;
|
||||
@@ -209,6 +296,9 @@ struct dir$r_ent {
|
||||
struct fiddef dir$w_fid;
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#ifdef __ALPHA
|
||||
#pragma member_alignment restore
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
/* Fibdef.h Definition of 'struct fibdef' */
|
||||
|
||||
/*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
email address: Paulnank@au1.ibm.com
|
||||
* 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.
|
||||
*/
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _FIBDEF_H
|
||||
#define _FIBDEF_H
|
||||
|
||||
189
extracters/ods2/genmsg-en/genmsg-en.vcxproj
Executable file
189
extracters/ods2/genmsg-en/genmsg-en.vcxproj
Executable file
@@ -0,0 +1,189 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.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>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{5AC343A4-5F8B-47F1-982B-7E44B3208748}</ProjectGuid>
|
||||
<RootNamespace>genmsgen</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</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>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<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|x64'">
|
||||
<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)'=='Release|Win32'">
|
||||
<CustomBuildAfterTargets>Link</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<CustomBuildAfterTargets>Link</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<CustomBuildBeforeTargets>
|
||||
</CustomBuildBeforeTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<CustomBuildBeforeTargets>
|
||||
</CustomBuildBeforeTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<PreBuildEvent>
|
||||
<Command>del $(SolutionDir)$(TargetName)$(TargetExt) >nil-en.bak 2>&1 || exit /b 0</Command>
|
||||
</PreBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>
|
||||
</Command>
|
||||
<Message>
|
||||
</Message>
|
||||
<Outputs>
|
||||
</Outputs>
|
||||
<Inputs>
|
||||
</Inputs>
|
||||
</CustomBuildStep>
|
||||
<Link>
|
||||
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<PreBuildEvent>
|
||||
<Command>del $(SolutionDir)$(TargetName)$(TargetExt) >nil-en.bak 2>&1 || exit /b 0</Command>
|
||||
</PreBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>
|
||||
</Command>
|
||||
<Message>
|
||||
</Message>
|
||||
<Outputs>
|
||||
</Outputs>
|
||||
<Inputs>
|
||||
</Inputs>
|
||||
</CustomBuildStep>
|
||||
<Link>
|
||||
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
<CustomBuildStep>
|
||||
<Command>copy $(OutDir)$(TargetName)$(TargetExt) $(SolutionDir)$(TargetName)$(TargetExt) </Command>
|
||||
<Outputs>$(SolutionDir)$(TargetName)$(TargetExt)</Outputs>
|
||||
<Message>Copying $(TargetName)$(TargetExt)</Message>
|
||||
<Inputs>$(OutDir)$(TargetName)$(TargetExt) </Inputs>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<CustomBuildStep>
|
||||
<Command>copy $(OutDir)$(TargetName)$(TargetExt) $(SolutionDir)$(TargetName)$(TargetExt) </Command>
|
||||
<Message>Copying $(TargetName)$(TargetExt)</Message>
|
||||
<Outputs>$(SolutionDir)$(TargetName)$(TargetExt)</Outputs>
|
||||
<Inputs>$(OutDir)$(TargetName)$(TargetExt) </Inputs>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\genmsg.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\sysmsg.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
27
extracters/ods2/genmsg-en/genmsg-en.vcxproj.filters
Executable file
27
extracters/ods2/genmsg-en/genmsg-en.vcxproj.filters
Executable file
@@ -0,0 +1,27 @@
|
||||
<?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;hh;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>
|
||||
<ClCompile Include="..\genmsg.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\sysmsg.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
363
extracters/ods2/genmsg.c
Normal file
363
extracters/ods2/genmsg.c
Normal file
@@ -0,0 +1,363 @@
|
||||
/* Timothe Litt March 2016
|
||||
* Copyright (C) 2016 Timothe litt
|
||||
* litt at acm dot org
|
||||
*
|
||||
* Free for use with the ODS2 package. All other rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is distributed as part of ODS2, originally 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
/* Write a message data file.
|
||||
*
|
||||
* Update/translate messages in cc.msg (en_us.msg)
|
||||
* The makefiles handle this:
|
||||
*
|
||||
* message -bt vms_messages.msg en_us.msg en_us.mt
|
||||
* cc genmsg '-DTABLEFILE="en_us.mt"' -o genmsg
|
||||
* genmsg en_us.mdf
|
||||
* rm -f genmsg
|
||||
* ods2 set message en_us
|
||||
*
|
||||
* For translations:
|
||||
* message -br vms_messages_fr.msg fr_ca.msg fr_ca.mt
|
||||
* cc genmsg '-DTABLEFILE="fr_ca.mt"' -o genmsg
|
||||
* genmsg fr_ca.mdf
|
||||
* rm -f genmsg
|
||||
* ods2 set message fr_ca
|
||||
*/
|
||||
|
||||
#ifndef TABLEFILE
|
||||
#define TABLEFILE "default.md"
|
||||
#endif
|
||||
|
||||
#define _XOPEN_SOURCE
|
||||
|
||||
#ifdef _MSC_VER /* fopen*/
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define SYSMSG_INTERNAL
|
||||
#include "sysmsg.h"
|
||||
|
||||
#include "ssdef.h"
|
||||
#include "stsdef.h"
|
||||
|
||||
static const char
|
||||
hdrrec[] = { MSG_HEADER_REC },
|
||||
facrec[] = { MSG_FAC_REC },
|
||||
msgrec[] = { MSG_MSG_REC },
|
||||
summary1[] = { "%s: %"PRIu32 " facilities, %"PRIu32 " messages" },
|
||||
summary2[] = { ", file size %"PRIuMAX " writtten to " };
|
||||
|
||||
static const char facdatafmt[] = { "{ \"%s\", UINT32_C(%"PRIu32")},\n" };
|
||||
static const char msgdatafmt[] = { "{ \"%s\", \"%s\", UINT32_C(0x%08"PRIX32"), UINT32_C(%"PRIu32") },\n" };
|
||||
|
||||
/* For portability of .mdf files, need fixed length encodings for host-specific
|
||||
* format descriptors... This re-encodes them without source changes:
|
||||
*/
|
||||
|
||||
#undef PRIo8
|
||||
#undef PRIo16
|
||||
#undef PRIo32
|
||||
#undef PRIo64
|
||||
#define PRIo8 "\001A"
|
||||
#define PRIo16 "\001B"
|
||||
#define PRIo32 "\001C"
|
||||
#define PRIo64 "\001D"
|
||||
|
||||
#undef PRIu8
|
||||
#undef PRIu16
|
||||
#undef PRIu32
|
||||
#undef PRIu64
|
||||
#define PRIu8 "\001E"
|
||||
#define PRIu16 "\001F"
|
||||
#define PRIu32 "\001G"
|
||||
#define PRIu64 "\001H"
|
||||
|
||||
#undef PRIX8
|
||||
#undef PRIX16
|
||||
#undef PRIX32
|
||||
#undef PRIX64
|
||||
#define PRIX8 "\001I"
|
||||
#define PRIX16 "\001J"
|
||||
#define PRIX32 "\001K"
|
||||
#define PRIX64 "\001L"
|
||||
|
||||
#undef PRId8
|
||||
#undef PRId16
|
||||
#undef PRId32
|
||||
#undef PRId64
|
||||
#define PRId8 "\001M"
|
||||
#define PRId16 "\001N"
|
||||
#define PRId32 "\001O"
|
||||
#define PRId64 "\001P"
|
||||
|
||||
/* Instantiate the tables from ssdef.h (whatever language; it's essentially an object file)
|
||||
*/
|
||||
|
||||
static
|
||||
struct VMSFAC fac2text[] = {
|
||||
#define GENERATE_FACTAB
|
||||
#include TABLEFILE
|
||||
};
|
||||
|
||||
static
|
||||
struct VMSMSG vms2text[] = {
|
||||
#define GENERATE_MSGTAB
|
||||
#include TABLEFILE
|
||||
};
|
||||
|
||||
static void putbyte( char c, size_t idx, char **buf, size_t *size );
|
||||
|
||||
/******************************************************************* main() */
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
struct VMSFAC *fp;
|
||||
struct VMSMSG *mp;
|
||||
FILE *ofp;
|
||||
int ac, quiet = 0, help = 0, newh = 0;
|
||||
char **av, *pname, *outname = NULL;
|
||||
|
||||
ac = argc; av = argv;
|
||||
pname = argv[0];
|
||||
if( argc <= 1 ) help = 1;
|
||||
for( ; argc > 1; --argc, ++argv ) {
|
||||
if( !strcmp( argv[1], "--" ) ) break;
|
||||
if( *argv[1] == '-' && argv[1][1] ) {
|
||||
char *p;
|
||||
|
||||
for( p = argv[1]+1; *p; p++ ) {
|
||||
switch( *p ) {
|
||||
case 'h':
|
||||
help = 1;
|
||||
break;
|
||||
case 'd':
|
||||
newh = 1;
|
||||
break;
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unknown option %c\n", argv[1][1] );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( help ) {
|
||||
fprintf( stderr, "%s - Generate ODS2 message file\n\n"
|
||||
" Options: -q -- suppress informational messages\n"
|
||||
" -d -- generate a data file for built-in table\n"
|
||||
"./message -bt vms_messages.msg ods2_en.msg en_us.mt\n"
|
||||
"cc genmsg '-DTABLEFILE=\"en_us.mt\"'\n"
|
||||
"./genmsg en_us.mdf\n"
|
||||
"./ods2 set message en_us\n"
|
||||
" ./genmsg -d default.md\n", pname
|
||||
);
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
if( argc > 1 ) {
|
||||
if( strcmp( argv[1], "-" ) ) {
|
||||
outname = argv[1];
|
||||
}
|
||||
--argc; ++argv;
|
||||
}
|
||||
|
||||
qsort( fac2text, (uint32_t)(sizeof(fac2text)/sizeof(fac2text[0]))-1,
|
||||
sizeof(fac2text[0]), &faccmp );
|
||||
qsort( vms2text, (uint32_t)(sizeof(vms2text)/sizeof(vms2text[0])),
|
||||
sizeof(vms2text[0]), &msgcmp );
|
||||
|
||||
if( outname == NULL )
|
||||
ofp = stdout;
|
||||
else if( (ofp = fopen( outname, "wb" )) == NULL ) {
|
||||
perror( outname );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
if( !quiet ) {
|
||||
fprintf( stderr, summary1, TABLEFILE,
|
||||
(uint32_t)(sizeof(fac2text)/sizeof(fac2text[0])) -1,
|
||||
(uint32_t)(sizeof(vms2text)/sizeof(vms2text[0])) );
|
||||
}
|
||||
|
||||
if( newh ) { /* Generate a new .h file for built-in defaults */
|
||||
size_t i, bufsize = 80;
|
||||
char *buf = NULL;
|
||||
|
||||
fprintf( ofp,
|
||||
"/* This is an automatically-generated file.\n"
|
||||
" * Command:" );
|
||||
for( ; ac > 0; --ac, ++av )
|
||||
fprintf( ofp, " %s", *av );
|
||||
fprintf( ofp,
|
||||
"\n"
|
||||
" * Compiled-in version of a message table\n"
|
||||
" * This technlology was developed by Timothe Litt, and is\n"
|
||||
" * free to use with the ODS2 package, originally developed by\n"
|
||||
" * Paul Nankervis <Paulnank@au1.ibm.com>.\n"
|
||||
" * ODS2 may be freely distributed within the VMS community\n"
|
||||
" * providing that the contributions of the original author and\n"
|
||||
" * subsequent contributors are acknowledged in the help text and\n"
|
||||
" * source files. This is free software; no warranty is offered,\n"
|
||||
" * and while we believe it to be useful, you use it at your own risk.\n"
|
||||
" */\n\n" );
|
||||
|
||||
fprintf( ofp,
|
||||
"#ifdef GENERATE_FACTAB\n"
|
||||
"#undef GENERATE_FACTAB\n" );
|
||||
for( i = 0; i < (uint32_t)(sizeof(fac2text)/sizeof(fac2text[0]))-1; i++ ) {
|
||||
fprintf( ofp, facdatafmt, fac2text[i].text, fac2text[i].code );
|
||||
}
|
||||
fprintf( ofp,
|
||||
"#endif\n"
|
||||
"#ifdef GENERATE_MSGTAB\n"
|
||||
"#undef GENERATE_MSGTAB\n" );
|
||||
for( i = 0; i < (uint32_t)(sizeof(vms2text)/sizeof(vms2text[0])); i++ ) {
|
||||
char *p;
|
||||
size_t idx;
|
||||
|
||||
p = vms2text[i].text;
|
||||
|
||||
for( idx = 0; *p; p++ ) {
|
||||
char c = *p;
|
||||
switch( c ) {
|
||||
case '"':
|
||||
case '\\':
|
||||
putbyte( '\\', idx++, &buf, &bufsize );
|
||||
break;
|
||||
case '\n':
|
||||
putbyte( '\\', idx++, &buf, &bufsize );
|
||||
c = 'n';
|
||||
break;
|
||||
case '\001': {
|
||||
const char *xpn;
|
||||
|
||||
putbyte( '"', idx++, &buf, &bufsize );
|
||||
c = *++p;
|
||||
xpn = prisym[ c - PRI_CODEBASE ];
|
||||
while( *xpn ) {
|
||||
putbyte( *xpn++, idx++, &buf, &bufsize );
|
||||
}
|
||||
putbyte( '"', idx++, &buf, &bufsize );
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
putbyte( c, idx++, &buf, &bufsize );
|
||||
}
|
||||
putbyte( '\0', idx++, &buf, &bufsize );
|
||||
|
||||
|
||||
fprintf( ofp, msgdatafmt,
|
||||
vms2text[i].ident, buf,
|
||||
vms2text[i].code, vms2text[i].nargs );
|
||||
}
|
||||
fprintf( ofp,
|
||||
"#endif\n" );
|
||||
if( ofp != stdout )
|
||||
fclose( ofp );
|
||||
|
||||
if( !quiet ) {
|
||||
if( ofp == stdout )
|
||||
fputc( '\n', stderr );
|
||||
else
|
||||
fprintf( stderr, ", written to %s\n", outname );
|
||||
}
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
/* File header record. Version + number of facilities + number of message definitions
|
||||
*/
|
||||
|
||||
fprintf( ofp, hdrrec,
|
||||
(uint32_t)(sizeof(fac2text)/sizeof(fac2text[0])) -1,
|
||||
(uint32_t)(sizeof(vms2text)/sizeof(vms2text[0])) );
|
||||
fputc( '\0', ofp );
|
||||
|
||||
/* Output each facility with its associated string.
|
||||
* Always produce an end-marker for the string.
|
||||
*/
|
||||
|
||||
for( fp = fac2text; fp < fac2text + sizeof(fac2text)/sizeof(fac2text[0]) -1; fp++ ) {
|
||||
fprintf( ofp, facrec, fp->code );
|
||||
if( fp->text )
|
||||
fprintf( ofp, "%s", fp->text );
|
||||
fputc( '\0', ofp );
|
||||
}
|
||||
|
||||
/* Same for each message definition, but two strings.
|
||||
*/
|
||||
|
||||
for( mp = vms2text; mp < vms2text + sizeof(vms2text)/sizeof(vms2text[0]); mp++ ) {
|
||||
fprintf( ofp, msgrec,
|
||||
mp->code, mp->nargs );
|
||||
if( mp->ident )
|
||||
fprintf( ofp, "%s", mp->ident );
|
||||
fputc( '\0', ofp );
|
||||
if( mp->text )
|
||||
fprintf( ofp, "%s", mp->text );
|
||||
fputc( '\0', ofp );
|
||||
}
|
||||
|
||||
/* wrap up */
|
||||
|
||||
fprintf( ofp, MSG_EOF_REC );
|
||||
fputc( '\0', ofp );
|
||||
|
||||
if( ferror(ofp) ) {
|
||||
perror( "write" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
if( !quiet && ofp != stdout )
|
||||
fprintf( stderr, summary2, (uintmax_t)ftell(ofp) );
|
||||
|
||||
if( ofp != stdout )
|
||||
fclose( ofp );
|
||||
|
||||
if( !quiet ) {
|
||||
if( ofp == stdout )
|
||||
fputc( '\n', stderr );
|
||||
else
|
||||
fprintf( stderr, "%s\n", outname );
|
||||
}
|
||||
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
static void putbyte( char c, size_t idx, char **buf, size_t *size ) {
|
||||
if( *buf == NULL || idx+1 > *size ) {
|
||||
*buf = realloc( *buf, *size += 32 );
|
||||
if( *buf == NULL ) {
|
||||
perror( "realloc" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
buf[0][idx++] = c;
|
||||
return;
|
||||
}
|
||||
18
extracters/ods2/grind
Executable file
18
extracters/ods2/grind
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Run ods2 with listed arguments
|
||||
PROG=./ods2
|
||||
#
|
||||
# Save valgrind output in grind.txt~ for analysis
|
||||
# Display full output on TTY
|
||||
# Merge rules in suppress.txt~ with output, creating newsuppress.txt~
|
||||
|
||||
touch suppress.txt~
|
||||
valgrind --gen-suppressions=all \
|
||||
--show-leak-kinds=all \
|
||||
--leak-check=full \
|
||||
--num-callers=30 \
|
||||
$PROG "$@" \
|
||||
3>&1 1>&2 2>&3 | tee /dev/stderr grind.txt~ | \
|
||||
grindmerge -f suppress.txt~ >newsuppress.txt~
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,119 +0,0 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_IMPORTCMD )
|
||||
#define DEBUG DEBUG_IMPORTCMD
|
||||
#else
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "cmddef.h"
|
||||
|
||||
|
||||
/***************************************************************** doimport() */
|
||||
|
||||
#define import_binary OPT_GENERIC_1
|
||||
#define import_log OPT_GENERIC_2
|
||||
|
||||
qual_t importquals[] = { {"ascii", 0, import_binary, NV,
|
||||
"Transfer file in ascii mode (default)"},
|
||||
{"binary", import_binary, 0, NV, "Transfer file in binary mode", },
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
param_t importpars[] = { {"from_filespec", REQ, LCLFS, NOPA, "for source file."},
|
||||
{"to_filespec", REQ, VMSFS, NOPA, "for destination file."},
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
};
|
||||
|
||||
DECL_CMD(import) {
|
||||
int options;
|
||||
unsigned sts;
|
||||
char *name;
|
||||
FILE *fromf;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
struct RAB rab = cc$rms_rab;
|
||||
|
||||
UNUSED(argc);
|
||||
|
||||
options = checkquals( 0, importquals, qualc, qualv );
|
||||
if( options == -1 )
|
||||
return SS$_BADPARAM;
|
||||
|
||||
sts = SS$_BADFILENAME;
|
||||
name = argv[1]; /*unquote( argv[1] );*/
|
||||
if ( *name == '\0' ) {
|
||||
return sts;
|
||||
}
|
||||
fromf = openf( name, (options & import_binary)? "rb": "r" );
|
||||
if( fromf == NULL ) {
|
||||
printf( "%%ODS2-E-OPENERR, Can't open %s\n", name );
|
||||
perror( " - " );
|
||||
return sts;
|
||||
}
|
||||
fab.fab$b_fac = FAB$M_PUT;
|
||||
fab.fab$l_fop = FAB$M_OFP | FAB$M_TEF;
|
||||
fab.fab$b_org = FAB$C_SEQ;
|
||||
if( options & import_binary ) {
|
||||
fab.fab$w_mrs = 512;
|
||||
fab.fab$b_rfm = FAB$C_FIX;
|
||||
} else {
|
||||
fab.fab$b_rat = 0;
|
||||
fab.fab$b_rfm = FAB$C_STM;
|
||||
}
|
||||
|
||||
fab.fab$l_fna = argv[2];
|
||||
fab.fab$b_fns = strlen( fab.fab$l_fna );
|
||||
sts = sys_create( &fab );
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
rab.rab$l_fab = &fab;
|
||||
sts = sys_connect( &rab );
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
if( options & import_binary ) {
|
||||
char *buf;
|
||||
size_t len;
|
||||
|
||||
if( (buf = malloc( 512 )) == NULL )
|
||||
sts = SS$_INSFMEM;
|
||||
else {
|
||||
rab.rab$l_rbf = buf;
|
||||
while( (len = fread( buf, 1, 512, fromf )) > 0 ) {
|
||||
if( len != 512 )
|
||||
memset( buf + len, 0, 512 - len );
|
||||
rab.rab$w_rsz = len;
|
||||
sts = sys_put( &rab );
|
||||
if( !(sts & STS$M_SUCCESS) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
free( buf );
|
||||
buf = NULL;
|
||||
}
|
||||
} else {
|
||||
while ( (rab.rab$l_rbf = fgetline( fromf, TRUE )) != NULL ) {
|
||||
rab.rab$w_rsz = strlen( rab.rab$l_rbf );
|
||||
sts = sys_put( &rab );
|
||||
free( rab.rab$l_rbf );
|
||||
if ( !( sts & STS$M_SUCCESS ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sys_disconnect( &rab );
|
||||
}
|
||||
sys_close( &fab );
|
||||
}
|
||||
fclose( fromf );
|
||||
if ( !(sts & STS$M_SUCCESS) ) {
|
||||
printf("%%IMPORT-F-ERROR Status: %s\n",getmsg(sts, MSG_TEXT));
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
@@ -1,10 +1,15 @@
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_INITIALCMD )
|
||||
@@ -15,6 +20,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include "cmddef.h"
|
||||
|
||||
#include "access.h"
|
||||
@@ -26,76 +32,127 @@
|
||||
|
||||
static struct NEWVOL initpars;
|
||||
|
||||
#define init_beg OPT_GENERIC_1
|
||||
#define init_mid OPT_GENERIC_2
|
||||
#define init_blk OPT_GENERIC_3
|
||||
#define init_mount OPT_GENERIC_4
|
||||
#define init_beg OPT_GENERIC_1
|
||||
#define init_mid OPT_GENERIC_2
|
||||
#define init_blk OPT_GENERIC_3
|
||||
#define init_mount OPT_GENERIC_4
|
||||
#define init_disp OPT_GENERIC_5
|
||||
#define init_confirm OPT_GENERIC_6
|
||||
#define init_uic OPT_GENERIC_7
|
||||
#define init_dtype OPT_GENERIC_8
|
||||
|
||||
qual_t idxkwds[] = { {"beginning", init_beg, init_mid|init_blk, NV,
|
||||
"Place index file in lowest available LBNs"},
|
||||
{"block", init_blk, init_beg|init_mid, DV(&initpars.indexlbn),
|
||||
"Place index file near specific LBN"},
|
||||
{"middle", init_mid, init_beg|init_blk, NV,
|
||||
"Place index file near middle of volume (default)"},
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
static qual_t
|
||||
idxkwds[] =
|
||||
{ {"beginning", init_beg, init_mid|init_blk, NV,
|
||||
"commands initialize qual_index begin"},
|
||||
{"block", init_blk, init_beg|init_mid, DV(&initpars.indexlbn),
|
||||
"commands initialize qual_index block"},
|
||||
{"middle", init_mid, init_beg|init_blk, NV,
|
||||
"commands initialize qual_index middle"},
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
|
||||
qual_t iniquals[] = { {DT_NAME, 0, MOU_DEVTYPE, CV(NULL), "Drive type (DEC model name) "},
|
||||
{"cluster_size", 0, 0, DV(&initpars.clustersize),
|
||||
"Cluster size (blocks)" },
|
||||
{"create", PHY_CREATE|MOU_VIRTUAL, 0, NV, "Create a new image file" },
|
||||
{"directories", 0, 0, DV(&initpars.directories),
|
||||
"Directory entries to pre-allocate" },
|
||||
{"headers", 0, 0, DV(&initpars.headers),
|
||||
"File headers to pre-allocate" },
|
||||
{"index", 0, init_beg|init_mid|init_blk, KV(idxkwds),
|
||||
"Index file placement hint"},
|
||||
{"image", PHY_CREATE|MOU_VIRTUAL, 0, NV,
|
||||
"Initialize a disk image file", },
|
||||
{"log", MOU_LOG, 0, NV, "-Show progress"},
|
||||
{"nolog", 0, MOU_LOG, NV, NULL},
|
||||
{"replace", MOU_VIRTUAL, PHY_CREATE, NV,
|
||||
"Replace filesystem in existing image file" },
|
||||
{"mount", init_mount, 0, NV, "-Mount volume after initializing it"},
|
||||
{"nomount", 0, init_mount, NV, NULL },
|
||||
{"virtual", PHY_CREATE|MOU_VIRTUAL, 0, NV, NULL, },
|
||||
{"maximum_files", 0, 0, DV(&initpars.maxfiles),
|
||||
"Maximum number of files volume can (ever) contain" },
|
||||
{"owner_uic", 0, 0, SV(&initpars.useruic),
|
||||
"Volume owner's UIC, default [1,1]"},
|
||||
{"user_name", 0, 0, SV(&initpars.username),
|
||||
"Volume owner's username, default yours"},
|
||||
{NULL, 0, 0, NV, NULL } };
|
||||
qual_t
|
||||
iniquals[] =
|
||||
{ {DT_NAME, 0, MOU_DEVTYPE, CV(NULL),
|
||||
"commands initialize qual_media"},
|
||||
{"bootblock", 0, 0, DV(&initpars.bootlbn),
|
||||
"commands initialize qual_bootblock"},
|
||||
{"cluster_size", 0, 0, DV(&initpars.clustersize),
|
||||
"commands initialize qual_clustersize" },
|
||||
{"confirm", init_confirm, 0, NV,
|
||||
"-commands initialize qual_confirm"},
|
||||
{"noconfirm", 0, init_confirm,
|
||||
NV, NULL},
|
||||
{"create", init_disp|PHY_CREATE,
|
||||
0, NV,
|
||||
"commands initialize qual_create" },
|
||||
{"directories", 0, 0, DV(&initpars.directories),
|
||||
"commands initialize qual_directories" },
|
||||
{"file_protection", 0, 0, PV(&initpars.fileprot),
|
||||
"commands initialize qual_fileprot"},
|
||||
{"headers", 0, 0, DV(&initpars.headers),
|
||||
"commands initialize qual_headers" },
|
||||
{"extension", 0, 0, DV(&initpars.extension),
|
||||
"commands initialize qual_extension" },
|
||||
{"windows", 0, 0, DV(&initpars.windows),
|
||||
"commands initialize qual_windows" },
|
||||
{"index", 0, init_beg|init_mid|init_blk, KV(idxkwds),
|
||||
"commands initialize qual_index"},
|
||||
{"image", init_dtype | MOU_VIRTUAL,
|
||||
0, NV,
|
||||
"commands initialize qual_image", },
|
||||
{"device", init_dtype, MOU_VIRTUAL, NV,
|
||||
"commands initialize qual_device", },
|
||||
{"log", MOU_LOG, 0, NV, "-commands initialize qual_log"},
|
||||
{"nolog", 0, MOU_LOG, NV, NULL},
|
||||
{"replace", init_disp, PHY_CREATE,
|
||||
NV,
|
||||
"commands initialize qual_replace" },
|
||||
{"mount", init_mount, 0, NV,
|
||||
"-commands initialize qual_mount"},
|
||||
{"nomount", 0, init_mount, NV, NULL },
|
||||
{"virtual", init_dtype | MOU_VIRTUAL, 0, NV, NULL, },
|
||||
{"maximum_files", 0, 0, DV(&initpars.maxfiles),
|
||||
"commands initialize qual_maxfiles" },
|
||||
{"owner_uic", init_uic, 0, UV(&initpars.useruic),
|
||||
"commands initialize qual_owneruic"},
|
||||
{"protection", 0, 0, PV(&initpars.volprot),
|
||||
"commands initialize qual_protection"},
|
||||
{"user_name", 0, 0, SV(&initpars.username),
|
||||
"commands initialize qual_username"},
|
||||
|
||||
param_t inipars[] = { {"device", REQ, LCLFS, NOPA,
|
||||
"for device or disk image to be initialized.\n "
|
||||
"ALL EXISTING DATA WILL BE LOST."
|
||||
},
|
||||
{"labels", REQ, LCLFS, NOPA, "volume label for new volume" },
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
};
|
||||
{ NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
|
||||
param_t
|
||||
inipars[] =
|
||||
{ {"device", REQ, FSPEC, NOPA, "commands initialize devspec" },
|
||||
{"labels", REQ, STRING, NOPA, "commands initialize volspec" },
|
||||
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
};
|
||||
|
||||
DECL_CMD(initial) {
|
||||
int sts = SS$_NORMAL;
|
||||
vmscond_t sts = SS$_NORMAL;
|
||||
options_t options;
|
||||
char *devname = NULL;
|
||||
size_t len;
|
||||
struct DEV *dev;
|
||||
int options;
|
||||
|
||||
UNUSED(argc);
|
||||
|
||||
devname = argv[1];
|
||||
|
||||
options = checkquals( PHY_CREATE | init_mid | init_mount, iniquals, qualc, qualv );
|
||||
do {
|
||||
memset( &initpars, 0, sizeof( initpars ) );
|
||||
initpars.extension = 5;
|
||||
initpars.windows = 7;
|
||||
|
||||
if( options == -1 ) {
|
||||
sts = SS$_BADPARAM;
|
||||
sts = checkquals( &options, init_confirm | init_mid | init_mount,
|
||||
iniquals, qualc, qualv );
|
||||
|
||||
do {
|
||||
size_t len;
|
||||
struct DEV *dev;
|
||||
char *p;
|
||||
|
||||
if( $FAILED( sts ) ) {
|
||||
break;
|
||||
}
|
||||
options |= MOU_WRITE;
|
||||
if( !(options & MOU_VIRTUAL) )
|
||||
options &= ~PHY_CREATE;
|
||||
if( !(options & init_dtype) && (p = strchr( devname, '.' )) ) {
|
||||
len = strlen( p+1 );
|
||||
if( len >= 1 && len == strspn( p+1, "0123456789" ".;-_"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz" ) )
|
||||
options |= MOU_VIRTUAL;
|
||||
}
|
||||
if( options & MOU_VIRTUAL ) {
|
||||
if( !(options & init_disp) ) /* Disposition (/create/replace)? */
|
||||
options |= PHY_CREATE;
|
||||
} else {
|
||||
if( options & init_disp ) {
|
||||
printmsg( INIT_INVOPT, 0, qstyle_s, qstyle_s );
|
||||
}
|
||||
}
|
||||
|
||||
if( options & init_mid )
|
||||
initpars.indexlbn = INIT_INDEX_MIDDLE;
|
||||
@@ -104,24 +161,30 @@ DECL_CMD(initial) {
|
||||
if( (options & init_blk) && initpars.indexlbn == INIT_INDEX_MIDDLE )
|
||||
initpars.indexlbn--;
|
||||
|
||||
initpars.options = 0;
|
||||
if( options & MOU_LOG )
|
||||
initpars.options |= INIT_LOG;
|
||||
if( options & MOU_VIRTUAL )
|
||||
initpars.options |= INIT_VIRTUAL;
|
||||
if( options & init_uic )
|
||||
initpars.options |= INIT_OWNUIC;
|
||||
|
||||
initpars.devtype = disktype[(options & MOU_DEVTYPE) >> MOU_V_DEVTYPE].name;
|
||||
|
||||
len = strlen( argv[2] );
|
||||
if( len > 12 || !*argv[2] ||
|
||||
strspn( argv[2], VOL_ALPHABET ) != len ) {
|
||||
printf( "Volume label must be between 1 and 12 alphanumeric characters long\n" );
|
||||
sts = SS$_BADPARAM;
|
||||
sts = printmsg( INIT_BADVOLLABEL, 0 );
|
||||
break;
|
||||
}
|
||||
initpars.label = argv[2];
|
||||
|
||||
if( !((sts = virt_open( &devname, options, &dev )) & STS$M_SUCCESS) )
|
||||
if( (options & init_confirm) &&
|
||||
$FAILS(sts = confirm_cmd( (options & MOU_VIRTUAL)?
|
||||
INIT_CONFIRM_VIRT: INIT_CONFIRM_PHY,
|
||||
devname, initpars.devtype )) )
|
||||
break;
|
||||
|
||||
if( $FAILS(sts = virt_open( &devname, options, &dev )) )
|
||||
break;
|
||||
|
||||
if( !(dev->access & MOU_WRITE) ) {
|
||||
@@ -130,11 +193,11 @@ DECL_CMD(initial) {
|
||||
break;
|
||||
}
|
||||
initpars.devnam = devname;
|
||||
if( !((sts = initvol( dev, &initpars )) & STS$M_SUCCESS) ) {
|
||||
if( $FAILS(sts = initvol( dev, &initpars )) ) {
|
||||
virt_close( dev );
|
||||
break;
|
||||
}
|
||||
if( !((sts = virt_close( dev )) & STS$M_SUCCESS) )
|
||||
if( $FAILS(sts = virt_close( dev )) )
|
||||
break;
|
||||
|
||||
if( options & init_mount ) {
|
||||
@@ -143,18 +206,15 @@ DECL_CMD(initial) {
|
||||
}
|
||||
} while( 0 );
|
||||
|
||||
initpars.username =
|
||||
initpars.useruic = NULL;
|
||||
|
||||
if( sts & STS$M_SUCCESS )
|
||||
if( $SUCCESSFUL( sts ) )
|
||||
return sts;
|
||||
|
||||
printf( "%%ODS2-E-FAILED, Initialize failed: %s\n", getmsg( sts, MSG_TEXT ) );
|
||||
sts = printmsg( sts, 0 );
|
||||
|
||||
if( (options & (MOU_VIRTUAL|PHY_CREATE)) == (MOU_VIRTUAL|PHY_CREATE) &&
|
||||
!( (sts & STS$M_COND_ID) == (SS$_DUPFILENAME & STS$M_COND_ID) ||
|
||||
(sts & STS$M_COND_ID) == (SS$_IVDEVNAM & STS$M_COND_ID) ) ) {
|
||||
(void) unlink( argv[1] );
|
||||
!( $MATCHCOND(sts, SS$_DUPFILENAME) ||
|
||||
$MATCHCOND(sts, SS$_IVDEVNAM) ) ) {
|
||||
(void) Unlink( argv[1] );
|
||||
}
|
||||
|
||||
return sts;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,30 +12,42 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _INITVOL_H
|
||||
#define _INITVOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ods2.h"
|
||||
|
||||
struct NEWVOL {
|
||||
const char *label;
|
||||
const char *devtype;
|
||||
const char *devnam;
|
||||
const char *username;
|
||||
const char *useruic;
|
||||
uint32_t useruic;
|
||||
unsigned options;
|
||||
unsigned clustersize;
|
||||
unsigned maxfiles;
|
||||
unsigned headers;
|
||||
unsigned indexlbn;
|
||||
unsigned directories;
|
||||
uint32_t clustersize;
|
||||
uint32_t maxfiles;
|
||||
uint32_t headers;
|
||||
uint32_t indexlbn;
|
||||
uint32_t directories;
|
||||
uint32_t bootlbn;
|
||||
uint32_t volprot;
|
||||
uint32_t fileprot;
|
||||
uint32_t extension;
|
||||
uint32_t windows;
|
||||
};
|
||||
#define INIT_INDEX_MIDDLE (~0U)
|
||||
#define INIT_LOG (1 << 0)
|
||||
#define INIT_VIRTUAL (1 << 1)
|
||||
#define INIT_LOG (1 << 0)
|
||||
#define INIT_VIRTUAL (1 << 1)
|
||||
#define INIT_OWNUIC (1 << 2)
|
||||
#define INIT_VOLPROT (1 << 3)
|
||||
#define INIT_FILEPROT (1 << 4)
|
||||
|
||||
#define VOL_ALPHABET "abcdefghijklmnopqrstuvwxyz$-_" \
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
@@ -78,7 +90,10 @@ struct SWBAD {
|
||||
#pragma member_alignment restore
|
||||
#endif
|
||||
|
||||
unsigned initvol( void *dev, struct NEWVOL *params );
|
||||
unsigned int delta_from_index( size_t index );
|
||||
vmscond_t initvol( void *dev, struct NEWVOL *params );
|
||||
uint32_t delta_from_index( size_t index );
|
||||
|
||||
vmscond_t addmappointers( struct HEAD *fhd,
|
||||
uint32_t *start, uint32_t *n, int sparse );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,123 +1,132 @@
|
||||
# DO NOT DELETE
|
||||
|
||||
ods2.o: version.h cmddef.h
|
||||
ods2.o: version.h
|
||||
ods2.o: cmddef.h
|
||||
ods2.o: compat.h
|
||||
ods2.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
ods2.o: stsdef.h sysmsg.h cache.h phyvirt.h
|
||||
ods2.o: ods2.h
|
||||
ods2.o: rms.h f11def.h vmstime.h descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
ods2.o: cache.h phyvirt.h
|
||||
access.o: ssdef.h access.h
|
||||
access.o: cache.h f11def.h
|
||||
access.o: vmstime.h descrip.h stsdef.h device.h phyio.h initvol.h ods2.h
|
||||
access.o: phyvirt.h compat.h
|
||||
access.o: sysmsg.h
|
||||
cache.o: cache.h ods2.h ssdef.h
|
||||
access.o: ods2.h
|
||||
access.o: cache.h f11def.h vmstime.h
|
||||
access.o: descrip.h stsdef.h device.h phyio.h initvol.h phyvirt.h compat.h
|
||||
access.o: sysmsg.h
|
||||
cache.o: cache.h
|
||||
cache.o: ods2.h
|
||||
cache.o: ssdef.h
|
||||
compat.o: compat.h
|
||||
compat.o: descrip.h stsdef.h
|
||||
copycmd.o: cmddef.h
|
||||
copycmd.o: compat.h
|
||||
copycmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
copycmd.o: stsdef.h sysmsg.h
|
||||
copycmd.o: compat.h ods2.h rms.h
|
||||
copycmd.o: f11def.h vmstime.h descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
createcmd.o: cmddef.h
|
||||
createcmd.o: compat.h
|
||||
createcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
createcmd.o: stsdef.h sysmsg.h f11def.h
|
||||
createcmd.o: ods2.h rms.h f11def.h vmstime.h
|
||||
createcmd.o: descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
debug.o: debug.h
|
||||
deletecmd.o: cmddef.h
|
||||
deletecmd.o: compat.h
|
||||
deletecmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
deletecmd.o: stsdef.h sysmsg.h
|
||||
device.o: ods2.h access.h cache.h
|
||||
device.o: f11def.h vmstime.h
|
||||
device.o: descrip.h ssdef.h stsdef.h device.h phyio.h
|
||||
deletecmd.o: ods2.h rms.h f11def.h vmstime.h
|
||||
deletecmd.o: descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
device.o: ods2.h
|
||||
device.o: access.h cache.h f11def.h
|
||||
device.o: vmstime.h descrip.h ssdef.h stsdef.h device.h phyio.h
|
||||
diffcmd.o: cmddef.h
|
||||
diffcmd.o: compat.h
|
||||
diffcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
diffcmd.o: stsdef.h sysmsg.h
|
||||
diffcmd.o: compat.h
|
||||
diffcmd.o: ods2.h rms.h f11def.h vmstime.h
|
||||
diffcmd.o: descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
diffcmd.o: phyio.h
|
||||
dircmd.o: cmddef.h
|
||||
dircmd.o: compat.h
|
||||
dircmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
dircmd.o: stsdef.h sysmsg.h
|
||||
direct.o: access.h cache.h
|
||||
direct.o: f11def.h vmstime.h
|
||||
direct.o: descrip.h ssdef.h stsdef.h direct.h fibdef.h ods2.h
|
||||
dircmd.o: ods2.h rms.h f11def.h vmstime.h descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
direct.o: access.h ods2.h
|
||||
direct.o: cache.h f11def.h vmstime.h descrip.h ssdef.h stsdef.h direct.h
|
||||
direct.o: fibdef.h sysmsg.h
|
||||
dismountcmd.o: cmddef.h
|
||||
dismountcmd.o: compat.h
|
||||
dismountcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
dismountcmd.o: stsdef.h sysmsg.h access.h cache.h f11def.h
|
||||
dismountcmd.o: device.h
|
||||
dismountcmd.o: ods2.h rms.h f11def.h vmstime.h descrip.h ssdef.h stsdef.h
|
||||
dismountcmd.o: sysmsg.h access.h cache.h device.h
|
||||
dismountcmd.o: phyio.h
|
||||
extendcmd.o: cmddef.h
|
||||
extendcmd.o: compat.h
|
||||
extendcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
extendcmd.o: stsdef.h sysmsg.h
|
||||
extendcmd.o: ods2.h rms.h f11def.h vmstime.h
|
||||
extendcmd.o: descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
helpcmd.o: ods2.h
|
||||
helpcmd.o: cmddef.h
|
||||
helpcmd.o: compat.h
|
||||
helpcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
helpcmd.o: stsdef.h sysmsg.h
|
||||
importcmd.o: cmddef.h
|
||||
importcmd.o: compat.h
|
||||
importcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
importcmd.o: stsdef.h sysmsg.h
|
||||
helpcmd.o: compat.h
|
||||
helpcmd.o: rms.h f11def.h vmstime.h descrip.h
|
||||
helpcmd.o: ssdef.h stsdef.h sysmsg.h version.h
|
||||
initialcmd.o: compat.h
|
||||
initialcmd.o: cmddef.h
|
||||
initialcmd.o: compat.h
|
||||
initialcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
initialcmd.o: stsdef.h sysmsg.h access.h cache.h f11def.h
|
||||
initialcmd.o: device.h
|
||||
initialcmd.o: phyio.h initvol.h phyvirt.h
|
||||
initialcmd.o: ods2.h rms.h f11def.h vmstime.h descrip.h
|
||||
initialcmd.o: ssdef.h stsdef.h sysmsg.h access.h
|
||||
initialcmd.o: cache.h device.h phyio.h initvol.h phyvirt.h
|
||||
initvol.o: compat.h
|
||||
initvol.o: f11def.h
|
||||
initvol.o: vmstime.h descrip.h ssdef.h stsdef.h
|
||||
initvol.o: initvol.h ods2.h phyvirt.h rms.h
|
||||
initvol.o: f11def.h vmstime.h descrip.h
|
||||
initvol.o: ssdef.h stsdef.h initvol.h ods2.h phyvirt.h rms.h sysmsg.h
|
||||
mountcmd.o: compat.h
|
||||
mountcmd.o: cmddef.h
|
||||
mountcmd.o: compat.h
|
||||
mountcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
mountcmd.o: stsdef.h sysmsg.h access.h cache.h f11def.h
|
||||
mountcmd.o: device.h phyio.h phyvirt.h phyvhd.h
|
||||
phyunix.o: device.h
|
||||
phyunix.o: access.h cache.h f11def.h vmstime.h descrip.h ssdef.h stsdef.h
|
||||
phyunix.o: phyio.h ods2.h phyvirt.h compat.h
|
||||
mountcmd.o: ods2.h rms.h f11def.h vmstime.h descrip.h
|
||||
mountcmd.o: ssdef.h stsdef.h sysmsg.h access.h
|
||||
mountcmd.o: cache.h device.h phyio.h phyvirt.h phyvhd.h
|
||||
phyunix.o: cmddef.h
|
||||
phyunix.o: compat.h ods2.h rms.h
|
||||
phyunix.o: f11def.h vmstime.h descrip.h ssdef.h stsdef.h sysmsg.h device.h
|
||||
phyunix.o: access.h cache.h phyio.h phyvirt.h
|
||||
phyvirt.o: compat.h
|
||||
phyvirt.o: device.h access.h cache.h f11def.h
|
||||
phyvirt.o: vmstime.h
|
||||
phyvirt.o: descrip.h ssdef.h stsdef.h phyio.h ods2.h phyvirt.h phyvhd.h
|
||||
rms.o: access.h cache.h f11def.h
|
||||
rms.o: vmstime.h descrip.h ssdef.h stsdef.h
|
||||
rms.o: device.h phyio.h direct.h fibdef.h ods2.h rms.h compat.h
|
||||
rms.o: sysmsg.h
|
||||
phyvirt.o: device.h access.h ods2.h cache.h f11def.h vmstime.h descrip.h
|
||||
phyvirt.o: ssdef.h stsdef.h phyio.h phyvirt.h sysmsg.h phyvhd.h
|
||||
renamecmd.o: cmddef.h
|
||||
renamecmd.o: compat.h
|
||||
renamecmd.o: ods2.h rms.h f11def.h vmstime.h
|
||||
renamecmd.o: descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
rms.o: access.h ods2.h
|
||||
rms.o: cache.h
|
||||
rms.o: f11def.h vmstime.h descrip.h ssdef.h stsdef.h device.h phyio.h
|
||||
rms.o: direct.h fibdef.h rms.h compat.h
|
||||
rms.o: sysmsg.h
|
||||
searchcmd.o: cmddef.h
|
||||
searchcmd.o: compat.h
|
||||
searchcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
searchcmd.o: stsdef.h sysmsg.h
|
||||
searchcmd.o: ods2.h rms.h f11def.h vmstime.h
|
||||
searchcmd.o: descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
setcmd.o: cmddef.h
|
||||
setcmd.o: compat.h
|
||||
setcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
setcmd.o: stsdef.h sysmsg.h
|
||||
setcmd.o: ods2.h rms.h f11def.h vmstime.h descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
showcmd.o: cmddef.h
|
||||
showcmd.o: compat.h
|
||||
showcmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
showcmd.o: stsdef.h sysmsg.h
|
||||
showcmd.o: access.h cache.h f11def.h
|
||||
showcmd.o: direct.h phyio.h
|
||||
showcmd.o: phyvhd.h phyvirt.h version.h
|
||||
showcmd.o: compat.h
|
||||
showcmd.o: ods2.h rms.h f11def.h vmstime.h
|
||||
showcmd.o: descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
showcmd.o: access.h cache.h direct.h phyio.h
|
||||
showcmd.o: phyvhd.h phyvirt.h version.h
|
||||
spawncmd.o: cmddef.h
|
||||
spawncmd.o: compat.h
|
||||
spawncmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
spawncmd.o: stsdef.h sysmsg.h
|
||||
sysmsg.o: ssdef.h rms.h vmstime.h
|
||||
sysmsg.o: descrip.h stsdef.h compat.h
|
||||
spawncmd.o: ods2.h rms.h f11def.h vmstime.h
|
||||
spawncmd.o: descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
sysmsg.o: ods2.h ssdef.h rms.h
|
||||
sysmsg.o: f11def.h vmstime.h descrip.h stsdef.h compat.h
|
||||
sysmsg.o: sysmsg.h
|
||||
typecmd.o: cmddef.h
|
||||
typecmd.o: compat.h
|
||||
typecmd.o: ods2.h rms.h vmstime.h descrip.h ssdef.h
|
||||
typecmd.o: stsdef.h sysmsg.h
|
||||
update.o: access.h cache.h
|
||||
update.o: f11def.h vmstime.h
|
||||
update.o: descrip.h ssdef.h stsdef.h device.h phyio.h ods2.h
|
||||
vmstime.o: vmstime.h descrip.h ssdef.h stsdef.h
|
||||
phyvhd.o: device.h
|
||||
phyvhd.o: access.h cache.h f11def.h
|
||||
phyvhd.o: vmstime.h descrip.h ssdef.h stsdef.h
|
||||
phyvhd.o: phyio.h ods2.h phyvirt.h vhd/libvhd.h
|
||||
phyvhd.o: vhd/blk_uuid.h vhd/vhd.h
|
||||
termio.o: cmddef.h
|
||||
termio.o: compat.h ods2.h rms.h f11def.h vmstime.h
|
||||
termio.o: descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
update.o: access.h ods2.h
|
||||
update.o: cache.h f11def.h vmstime.h descrip.h ssdef.h stsdef.h device.h
|
||||
update.o: phyio.h initvol.h
|
||||
vmstime.o: vmstime.h descrip.h ssdef.h
|
||||
vmstime.o: stsdef.h ods2.h
|
||||
phyvhd.o: compat.h
|
||||
phyvhd.o: device.h access.h
|
||||
phyvhd.o: ods2.h
|
||||
phyvhd.o: cache.h f11def.h vmstime.h
|
||||
phyvhd.o: descrip.h ssdef.h stsdef.h phyio.h phyvirt.h sysmsg.h
|
||||
phyvhd.o: vhd/libvhd.h
|
||||
phyvhd.o: vhd/blk_uuid.h vhd/vhd.h phyvhd.h
|
||||
vhd/libvhd.o: vhd/libvhd.h
|
||||
vhd/libvhd.o: vhd/blk_uuid.h vhd/vhd.h vhd/relative-path.h
|
||||
vhd/relative-path.o: vhd/relative-path.h
|
||||
genmsg.o: sysmsg.h
|
||||
genmsg.o: ods2.h
|
||||
genmsg.o: ssdef.h stsdef.h
|
||||
makehelp.o: compat.h
|
||||
makehelp.o: cmddef.h
|
||||
makehelp.o: ods2.h rms.h
|
||||
makehelp.o: f11def.h vmstime.h descrip.h ssdef.h stsdef.h sysmsg.h
|
||||
|
||||
@@ -6,41 +6,20 @@
|
||||
# otherwise, every little change means updating all
|
||||
# the os-specific makefiles.
|
||||
#
|
||||
# See makefile.<osname>, which normally includes it
|
||||
# For Unix and Unix-ish OSs, variables are defaulted
|
||||
# in makefile.unixdefs, which is included by
|
||||
# makefile.<osname>. Per-OS customizations are set
|
||||
# by makefile.<osname>, which then includes this file.
|
||||
#
|
||||
# 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
|
||||
# If your make doesn't support include (are any left?),
|
||||
# combine the files with an editor.
|
||||
#
|
||||
# or just combine the files you need with an editor.
|
||||
# Life will be simpler if you softlink Makefile to makefile.<osname>
|
||||
# e.g. ln -s makefile.unix Makefile
|
||||
#
|
||||
# ###
|
||||
|
||||
# OS-Specific defines
|
||||
# These variables are available
|
||||
|
||||
# Other defines = "-DDEBUG_BUILD" "-D_FILE_OFFSET_BITS=32"
|
||||
#DEFS =
|
||||
|
||||
# Libraries, e.g. -lreadline
|
||||
#LDLIBS =
|
||||
|
||||
# Linker flags
|
||||
#LDFLAGS =
|
||||
|
||||
# Object file suffix
|
||||
#OBJ = .o
|
||||
|
||||
# Executable file suffix
|
||||
|
||||
#EXE =
|
||||
|
||||
# Physical IO module
|
||||
#PHYSIO = phyunix
|
||||
|
||||
# Extra physical IO headers
|
||||
#PHYSIOH =
|
||||
# See makefile.unixdefs for a list of the available variables.
|
||||
|
||||
# VHD format options
|
||||
|
||||
@@ -48,11 +27,26 @@ include $(VHDOPTS)
|
||||
|
||||
# #####################################################
|
||||
|
||||
DEPENDS = makefile.depends
|
||||
MAKEDEPEND = makedepend
|
||||
SED = sed
|
||||
# Language files are of the form LL_CC.{msg, hlp}
|
||||
# Where: LL is a language code (e.g. en), and
|
||||
# CC is a country code (e.g. us)
|
||||
# .msg files are the message definitions
|
||||
# .hlp file are the helpfile text
|
||||
#
|
||||
# The base language is en_us, but translations are welcome.
|
||||
|
||||
all : ods2$(EXE)
|
||||
# Filenames of these forms will automatically generate the
|
||||
# runtime-loadable help (.hlb) and message (.mdf) files.
|
||||
|
||||
# Note that translated messages from a VMS system are required
|
||||
# for each language; these are generated with the (DECUS)
|
||||
# unmessage utility, are are named "vms_msgdump.<lang>.msg.
|
||||
# Output from the message utility has more details.
|
||||
|
||||
MSGLANGS = $(wildcard ??_??.msg)
|
||||
HLPLANGS = $(wildcard ??_??.hlp)
|
||||
|
||||
all : ods2$(EXE) helpfiles msgfiles
|
||||
|
||||
SRCS = ods2.c \
|
||||
access.c \
|
||||
@@ -69,19 +63,19 @@ direct.c \
|
||||
dismountcmd.c \
|
||||
extendcmd.c \
|
||||
helpcmd.c \
|
||||
importcmd.c \
|
||||
initialcmd.c \
|
||||
initvol.c \
|
||||
mountcmd.c \
|
||||
$(PHYSIO).c \
|
||||
phyvirt.c \
|
||||
renamecmd.c \
|
||||
rms.c \
|
||||
searchcmd.c \
|
||||
setcmd.c \
|
||||
showcmd.c \
|
||||
spawncmd.c \
|
||||
sysmsg.c \
|
||||
typecmd.c \
|
||||
termio.c \
|
||||
update.c \
|
||||
vmstime.c \
|
||||
$(VHDLIB)
|
||||
@@ -107,15 +101,19 @@ vclist:
|
||||
@echo $(SRCS) | sed -e's/ */\n/g' | sort | uniq
|
||||
|
||||
# This processing is so the kit can contain a generic, up-to-date depends file
|
||||
# I don't want to require makedepend for people to build from source.
|
||||
# I do want the file to be accurate when shipped, so auto-maintained.
|
||||
# makedepend will include all the system library includes, which is not
|
||||
# without requiring makedepend when rebuilding from source.
|
||||
#
|
||||
# Raw makedepend will include all the system library includes, which is not
|
||||
# helpful for this case. So the sed processing removes dependencies that
|
||||
# start with "/" - e.g. /usr/include and friends.
|
||||
#
|
||||
# The sleep is because make uses high-precision timing; the output can appear
|
||||
# to be in the future by a few msec.
|
||||
|
||||
$(DEPENDS): $(MAKEFILE_LIST)
|
||||
touch $(DEPENDS)
|
||||
2>/dev/null $(MAKEDEPEND) -o$(OBJ) -I. -f- -- $(CFLAGS) $(CPPFLAGS) $(DEFS) -- $(SRCS) | $(SED) -e's/ \/[^ ]*\.h/ /g' -e'/^[^:]*: *$$/d' -e's/ */ /g' >$(DEPENDS)
|
||||
2>/dev/null $(MAKEDEPEND) -o$(OBJ) -I. -f- -- $(CFLAGS) $(CPPFLAGS) $(DEFS) -- $(SRCS) genmsg.c makehelp.c | $(SED) -e's/ \/[^ ]*\.h/ /g' -e'/^[^:]*: *$$/d' -e's/ */ /g' >$(DEPENDS)
|
||||
@sleep 2
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
@@ -133,3 +131,63 @@ descrip.mms : $(SRCS) $(DEPENDS)
|
||||
|
||||
ods2$(EXE) : $(OBJS) $(LIBS)
|
||||
$(CC) $(LDFLAGS) -o ods2$(EXE) $(OBJS) $(LDLIBS)
|
||||
|
||||
# Message definition files: These provide the text for every condition (message) code.
|
||||
#
|
||||
# For a new translation:
|
||||
# create a new <lang>.msg file, based on an existing one (e.g. en_us.msg)
|
||||
# make does the rest
|
||||
# To test, ods2 set message ods2_<lang>.mdf
|
||||
|
||||
# Runtime-loadable message file for I18n supports:
|
||||
|
||||
msgfiles : $(foreach LANG,$(MSGLANGS),ods2_$(basename $(LANG)).mdf)
|
||||
|
||||
ods2_%.mdf : %.mt genmsg.c
|
||||
$(CC) $(CCFLAGS) $(CPPFLAGS) $(DEFS) $(LDFLAGS) '-DTABLEFILE="$<"' -o genmsg$(EXE) genmsg.c $(LDLIBS)
|
||||
$(RUN)genmsg$(EXE) -q $@
|
||||
@$(DELETE) genmsg$(EXE)
|
||||
|
||||
# Build ssdef (condition code definitions) from .msg files.
|
||||
# Requires Perl. Generate ssdef.msg for documentatation.
|
||||
# The output is not language-specific (aside from the documention file)
|
||||
# It's merely the #defines for the facility numbers and condition codes.
|
||||
|
||||
ssdef.h : $(ODS2LANG).msg vms_messages_$(ODS2LANG).msg message
|
||||
$(MESSAGE) -q vms_messages_$(ODS2LANG).msg $(ODS2LANG).msg ssdef.h
|
||||
$(MESSAGE) -m -q vms_messages_$(ODS2LANG).msg $(ODS2LANG).msg ssdef.msg
|
||||
|
||||
# Compile-time message definition data file: #included in sysmsg to
|
||||
# compile default/fallback definitions.
|
||||
|
||||
default.md : $(ODS2LANG).mt genmsg.c
|
||||
$(CC) $(CCFLAGS) $(CPPFLAGS) $(DEFS) $(LDFLAGS) '-DTABLEFILE="$<"' -o genmsg$(EXE) genmsg.c $(LDLIBS)
|
||||
$(RUN)genmsg$(EXE) -dq $@
|
||||
@$(DELETE) genmsg$(EXE)
|
||||
|
||||
sysmsg$(OBJ) : default.md
|
||||
|
||||
|
||||
# Build message table from .msg file.
|
||||
# Requires Perl.
|
||||
|
||||
%.mt : %.msg vms_messages_$(basename %).msg message
|
||||
$(MESSAGE) -q -t $(filter-out message,$^) $@
|
||||
|
||||
# VMS messages for each language
|
||||
|
||||
vms_messages_%.msg : vms_msgdump.%.msg message vms_msgdefs.h
|
||||
$(MESSAGE) -m -q vms_msgdefs.h $< $@
|
||||
|
||||
# Help files
|
||||
|
||||
helpfiles : ods2.hlb $(foreach LANG,$(HLPLANGS),ods2_$(basename $(LANG)).hlb)
|
||||
|
||||
ods2_%.hlb : %.hlp makehelp$(EXE)
|
||||
$(RUN)makehelp$(EXE) -q $< $@
|
||||
|
||||
makehelp$(EXE) : makehelp.o compat.o
|
||||
$(CC) $(CCFLAGS) $(CPPFLAGS) $(DEFS) $(LDFLAGS) -o makehelp$(EXE) makehelp.o compat.o $(LDLIBS)
|
||||
|
||||
ods2.hlb : ods2_$(ODS2LANG).hlb
|
||||
$(LN) $< $@
|
||||
|
||||
@@ -2,33 +2,14 @@
|
||||
|
||||
# Makefile for solaris OS
|
||||
|
||||
# Start with generic unix
|
||||
|
||||
include makefile.unixdefs
|
||||
|
||||
# Use gcc
|
||||
|
||||
CC=gcc
|
||||
|
||||
CCFLAGS = -O4 -g
|
||||
|
||||
DEFS = -DUSE_READLINE
|
||||
LDFLAGS = -lreadline -ltermcap
|
||||
|
||||
# Include VHD format image file support
|
||||
|
||||
VHDOPTS = makefile-vhd.unix
|
||||
|
||||
# Object file extension
|
||||
OBJ = .o
|
||||
|
||||
DELETE = "rm -f"
|
||||
|
||||
# Physical I/O module
|
||||
PHYSIO = phyunix
|
||||
PHYSIOH =
|
||||
|
||||
TOPMAKE = makefile.solaris
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
rm -f ods2 $(OBJS)
|
||||
|
||||
include makefile.generic
|
||||
|
||||
@@ -3,29 +3,25 @@
|
||||
# Makefile for Tru64 (DEC/OSF1)
|
||||
#
|
||||
|
||||
# Start with generic unix
|
||||
|
||||
include makefile.unixdefs
|
||||
|
||||
# Use gcc
|
||||
|
||||
CC=gcc
|
||||
|
||||
TOPMAKE = makefile.solaris
|
||||
|
||||
include makefile.generic
|
||||
|
||||
CCFLAGS = -O4 -g
|
||||
|
||||
# DEFS = -DUSE_READLINE
|
||||
# LDFLAGS = -lreadline -ltermcap
|
||||
# I don't think we have libedit
|
||||
|
||||
# Include VHD format image file support
|
||||
|
||||
VHDOPTS = makefile-vhd.unix
|
||||
|
||||
# Object file extension
|
||||
OBJ = .o
|
||||
|
||||
DELETE = rm -f
|
||||
|
||||
# Physical I/O module
|
||||
PHYSIO = phyunix
|
||||
PHYSIOH =
|
||||
DEFS =
|
||||
LDLIBS =
|
||||
|
||||
TOPMAKE = makefile.tru64
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
rm -f ods2 $(OBJS)
|
||||
|
||||
include makefile.generic
|
||||
|
||||
@@ -3,39 +3,9 @@
|
||||
# Makefile for most Unix distributions
|
||||
#
|
||||
|
||||
# Special defines, e.g.
|
||||
# DEFS="-DDEBUG_RMS -DDEBUG_BUILD -D_FILE_OFFSET_BITS=32"
|
||||
|
||||
CCFLAGS = -O4 -g
|
||||
#-O0 -g -DUSE_READLINE -Wall -pedantic
|
||||
# Extra warns about $ in identifiers...
|
||||
# -Wextra
|
||||
|
||||
# Include readline support
|
||||
|
||||
DEFS = -DUSE_READLINE
|
||||
LDLIBS = -lreadline -ltermcap
|
||||
|
||||
# Include VHD format image file support
|
||||
|
||||
VHDOPTS = makefile-vhd.unix
|
||||
|
||||
# Object file extension
|
||||
OBJ = .o
|
||||
|
||||
EXE =
|
||||
|
||||
DELETE = rm -f
|
||||
|
||||
# Physical I/O module
|
||||
PHYSIO = phyunix
|
||||
include makefile.unixdefs
|
||||
|
||||
TOPMAKE = makefile.unix
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
rm -f ods2$(EXE) $(OBJS)
|
||||
|
||||
include makefile.generic
|
||||
|
||||
|
||||
78
extracters/ods2/makefile.unixdefs
Normal file
78
extracters/ods2/makefile.unixdefs
Normal file
@@ -0,0 +1,78 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
# Basic variable definitions for Unix & Unix-like OSs
|
||||
#
|
||||
# OS-specific file can redefine selectively
|
||||
|
||||
# Special defines, e.g.
|
||||
# DEFS="-DDEBUG_RMS -DDEBUG_BUILD -D_FILE_OFFSET_BITS=32"
|
||||
|
||||
CCFLAGS = -O4 -g
|
||||
#-O0 -g -DUSE_LIBEDIT -Wall -pedantic
|
||||
# Extra warns about $ in identifiers...
|
||||
# -Wextra
|
||||
|
||||
# Large file support
|
||||
DEFS += "-D_FILE_OFFSET_BITS=64"
|
||||
|
||||
# Include editline support
|
||||
|
||||
DEFS += -DUSE_LIBEDIT
|
||||
LDLIBS = -ledit -ltermcap
|
||||
|
||||
# Include VHD format image file support
|
||||
|
||||
VHDOPTS = makefile-vhd.unix
|
||||
|
||||
# Default language
|
||||
|
||||
ODS2LANG = en_us
|
||||
|
||||
# Object file extension
|
||||
OBJ = .o
|
||||
|
||||
# Executable file extension
|
||||
|
||||
EXE =
|
||||
|
||||
# Delete file - must be one file spec, as VMS needs commas
|
||||
|
||||
DELETE = rm -f
|
||||
|
||||
# How to run a program
|
||||
RUN = ./
|
||||
|
||||
# Copy a file
|
||||
COPY = cp -p
|
||||
|
||||
# Softlink a file
|
||||
LN = ln -sf
|
||||
|
||||
# Physical I/O module
|
||||
PHYSIO = phyunix
|
||||
|
||||
# The top level makefile (used for recursive make)
|
||||
#TOPMAKE = makefile.unix
|
||||
|
||||
# Files to clean
|
||||
|
||||
CLEANFILES = ods2$(EXE) genmsg$(EXE) makehelp$(EXE) $(OBJS) *.mt *.md *.mdf *.hlb vms_messages_*.msg ssdef.h ssdef.msg
|
||||
|
||||
# How to run Perl
|
||||
PERL = LC_ALL="C" perl
|
||||
|
||||
# Name of dependencies file & how to build
|
||||
DEPENDS = makefile.depends
|
||||
MAKEDEPEND = makedepend
|
||||
|
||||
# How to run sed
|
||||
SED = sed
|
||||
|
||||
# How to run message
|
||||
|
||||
MESSAGE = $(PERL) message
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
rm -f $(CLEANFILES)
|
||||
@@ -9,7 +9,11 @@
|
||||
|
||||
CCFLAGS = -O4 -g
|
||||
|
||||
#LDLIBS = -lreadline -ltermcap
|
||||
#LDLIBS = -ledit -ltermcap
|
||||
|
||||
# Default language
|
||||
|
||||
ODS2LANG = en_us
|
||||
|
||||
# Object file extension
|
||||
OBJ = .OBJ
|
||||
@@ -19,14 +23,24 @@ EXE = .EXE
|
||||
DELETE = DELETE
|
||||
GEN = ";*"
|
||||
|
||||
RUN = mcr sys$disk:[]
|
||||
|
||||
COPY = COPY
|
||||
|
||||
LN = COPY
|
||||
|
||||
# Physical I/O module
|
||||
PHYSIO = phyvms
|
||||
|
||||
TOPMAKE = makefile.vms
|
||||
|
||||
SED = sed
|
||||
DEPENDS = makefile.depends
|
||||
MAKEDEPEND = makedepend
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
$(DELETE) *.$(OBJ)$(GEN),*.$(EXE)$(GEN)
|
||||
$(DELETE) *.$(OBJ)$(GEN),*.$(EXE)$(GEN), $.mt$(GEN), *.mdf$(GEN)
|
||||
|
||||
include makefile.generic
|
||||
|
||||
649
extracters/ods2/makehelp.c
Normal file
649
extracters/ods2/makehelp.c
Normal file
@@ -0,0 +1,649 @@
|
||||
/* Copyright (c) Timothe Litt <litt@acm.org>
|
||||
*/
|
||||
|
||||
/* Help file compiler
|
||||
*/
|
||||
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#define HELPFILEDEFS
|
||||
#include "cmddef.h"
|
||||
|
||||
#define INEXT ".hlp"
|
||||
#define OUTEXT ".hlb"
|
||||
#define LSTEXT ".lst"
|
||||
|
||||
#ifdef _WIN64
|
||||
#define OUTPFX "win64-ods2_"
|
||||
#define DDLIM '\\'
|
||||
#elif defined( _WIN32 )
|
||||
#define OUTPFX "win-ods2_"
|
||||
#define DDLIM '\\'
|
||||
#elif defined( VMS )
|
||||
#define OUTPFX "ods2_"
|
||||
#define DDLIM ']'
|
||||
#else
|
||||
#define OUTPFX "ods2_"
|
||||
#define DDLIM '/'
|
||||
#endif
|
||||
|
||||
/* Leaks are not an issue since this program exits after every command.
|
||||
* However, the leak detector is handy for debugging other issues.
|
||||
*/
|
||||
#if defined( _WIN32 ) && defined(_MSC_VER) && defined( DEBUG_BUILD ) && defined( USE_VLD )
|
||||
/* Normally done in the project file, but VLD is optional and I'd rather not provide
|
||||
* instructions as they vary by IDE version. See http://vld.codeplex.com/ if interested.
|
||||
*/
|
||||
#include "C:\\Program Files (x86)\\Visual Leak Detector\\include\\vld.h"
|
||||
#pragma comment (lib,"C:\\Program Files (x86)\\Visual Leak Detector\\lib\\Win32\\vld.lib")
|
||||
#endif
|
||||
|
||||
typedef struct hlpstat {
|
||||
size_t topics[9];
|
||||
size_t keymem[9];
|
||||
size_t txtmem[9];
|
||||
size_t ntopics;
|
||||
size_t keymemtot;
|
||||
size_t txtmemtot;
|
||||
} hlpstat_t;
|
||||
|
||||
static void pstats( FILE *of, char *outname, hlpstat_t *stats, size_t memsize );
|
||||
static size_t hlpsize( hlproot_t *root );
|
||||
static int rdhelp( hlproot_t *root, const char *filename );
|
||||
static void helpsort( hlproot_t *root );
|
||||
static int hlpcmp( const void *qa, const void *qb );
|
||||
static void savehlp( hlproot_t *oroot, hlproot_t *iroot,
|
||||
char *base, char **sp, char **pp,
|
||||
unsigned lvl, hlpstat_t *stats );
|
||||
static int printdata( FILE *of, unsigned level, hlproot_t *root,
|
||||
int text, hlpstat_t *stats );
|
||||
|
||||
/* ******************************************************************* main() */
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
int opth = 0, optd = 0, optD = 0, optq = 0;
|
||||
char *inname = NULL, *outname = NULL, *pname;
|
||||
int outmalloced = FALSE;
|
||||
size_t memsize = 0;
|
||||
hlproot_t inroot;
|
||||
hlphdr_t *hdr;
|
||||
hlpstat_t stats;
|
||||
struct stat instat;
|
||||
char *base, *pp, *sp;
|
||||
FILE *of = NULL;
|
||||
|
||||
memset( &inroot, 0, sizeof( inroot ) );
|
||||
inroot.topics.ptr = NULL;
|
||||
inroot.ntopics = 0;
|
||||
|
||||
pname = argv[0];
|
||||
if( argc <= 1 ) opth = TRUE;
|
||||
for( ; argc > 1; --argc, ++argv ) {
|
||||
if( !strcmp( argv[1], "--" ) ) break;
|
||||
if( *argv[1] == '-' && argv[1][1] ) {
|
||||
char *p;
|
||||
|
||||
for( p = argv[1]+1; *p; p++ ) {
|
||||
switch( *p ) {
|
||||
case 'h':
|
||||
opth = TRUE;
|
||||
break;
|
||||
case 'd':
|
||||
optd = TRUE;
|
||||
break;
|
||||
case 'D':
|
||||
optD = TRUE;
|
||||
break;
|
||||
case 'q':
|
||||
optq = TRUE;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unknown option %c\n", argv[1][1] );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( opth ) {
|
||||
printf( "%s [opts] [in" INEXT " [out" OUTEXT "]]\n"
|
||||
" -h This help\n"
|
||||
" -d Dump structure of input\n"
|
||||
" -D Dump structure of input with topic text\n"
|
||||
" -q Suppress statistics report\n"
|
||||
" -- End of options\n"
|
||||
" - is stdin/out\n"
|
||||
"If an output file is not specified, the input filename\n"
|
||||
"prefixed by " OUTPFX " is used. " OUTEXT " replaces the "
|
||||
"input name's extension.\n"
|
||||
"With -d or -D, " LSTEXT " replaces the input name's extension.\n"
|
||||
"The " OUTEXT " files are architecture-dependent.\n"
|
||||
"Under Windows, the default output file is prefixed\n"
|
||||
"with 'win-' or 'win64-'.\n", pname? pname : "makehelp" );
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
if( argc > 1 ) {
|
||||
if( strcmp( argv[1], "-" ) ) {
|
||||
inname = argv[1];
|
||||
}
|
||||
--argc; ++argv;
|
||||
}
|
||||
if( argc > 1 ) {
|
||||
if( strcmp( argv[1], "-" ) ) {
|
||||
outname = argv[1];
|
||||
}
|
||||
--argc; ++argv;
|
||||
} else {
|
||||
if( inname != NULL ) {
|
||||
char *p, *outext;
|
||||
size_t inlen, extsiz, addlen;
|
||||
ptrdiff_t plen = 0;
|
||||
|
||||
inlen = strlen( inname );
|
||||
outext = ( optd || optD )? LSTEXT : OUTEXT;
|
||||
addlen =
|
||||
extsiz = strlen( outext ) +1;
|
||||
#ifdef OUTPFX
|
||||
addlen += sizeof( OUTPFX ) -1;
|
||||
#endif
|
||||
outname = malloc( inlen + addlen );
|
||||
if( outname == NULL ) {
|
||||
perror( "malloc" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
outmalloced = TRUE;
|
||||
#ifdef OUTPFX
|
||||
if( (p = strrchr( inname, DDLIM )) != NULL ) {
|
||||
plen = (p - inname) +1;
|
||||
p = outname + plen;
|
||||
memcpy( outname, inname, plen );
|
||||
} else
|
||||
p = outname;
|
||||
memcpy( p, OUTPFX, sizeof( OUTPFX ) -1 );
|
||||
memcpy( p + sizeof( OUTPFX ) -1,
|
||||
inname + plen, strlen( inname + plen ) +1 );
|
||||
#else
|
||||
memcpy( outname, inname + plen, inlen +1 ); /* plen == 0, ensures it's used */
|
||||
#endif
|
||||
if( (p = strrchr( outname, '.' )) != NULL && strchr( p, DDLIM ) == NULL ) {
|
||||
*p = '\0';
|
||||
}
|
||||
memcpy( outname + strlen(outname), outext, extsiz );
|
||||
}
|
||||
}
|
||||
if( argc >1 ) {
|
||||
fprintf( stderr, "Too many command arguments\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
if( optd || optD ) {
|
||||
if( outname == NULL )
|
||||
of = stdout;
|
||||
else {
|
||||
of = openf( outname, "w" );
|
||||
if( !of ) {
|
||||
perror( outname );
|
||||
if( outmalloced) free( outname );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
}
|
||||
memset( &stats, 0, sizeof( stats ) );
|
||||
memset( &instat, 0, sizeof( instat ) );
|
||||
if( inname == NULL || stat( inname, &instat ) != 0 )
|
||||
instat.st_mtime = 0;
|
||||
|
||||
if( !optq ) {
|
||||
time_t now;
|
||||
FILE *pf;
|
||||
char *rpi = NULL;
|
||||
|
||||
if( inname != NULL )
|
||||
rpi = get_realpath( inname );
|
||||
pf = (optd || optD)? of : stderr;
|
||||
fprintf( pf, "Topic structure of %s\n",
|
||||
inname? (rpi? rpi : inname) : "<stdin>" );
|
||||
if( rpi ) free( rpi );
|
||||
if( instat.st_mtime != 0 ) {
|
||||
char *mt;
|
||||
mt = Ctime( &instat.st_mtime );
|
||||
if( mt != NULL ) {
|
||||
now = time( &now );
|
||||
fprintf( pf, "File: %s ", mt );
|
||||
free( mt );
|
||||
mt = Ctime( &now );
|
||||
if( mt != NULL ) {
|
||||
fprintf( pf, "as of %s", mt );
|
||||
free( mt );
|
||||
}
|
||||
fprintf( pf, "\n" );
|
||||
}
|
||||
}
|
||||
fprintf( pf,
|
||||
"---------------------------------------------------------------\n" );
|
||||
}
|
||||
|
||||
if( rdhelp( &inroot, inname ) ) {
|
||||
if( outmalloced) free( outname );
|
||||
perror( inname );
|
||||
if( of && of != stdout && of != stderr ) fclose( of );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
memsize = sizeof( inroot) + hlpsize( &inroot );
|
||||
|
||||
if( optd || optD ) {
|
||||
printdata( of, 1, &inroot, optD, &stats );
|
||||
if( !optq ) pstats( of, outname, &stats, memsize );
|
||||
if( of && of != stdout && of != stderr ) fclose( of );
|
||||
if( outmalloced) free( outname );
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
base = malloc( sizeof( hlphdr_t ) + memsize );
|
||||
if( !base ) {
|
||||
perror("malloc");
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
hdr = (hlphdr_t *)base;
|
||||
sp = base + sizeof( hlphdr_t );
|
||||
pp = sp + memsize;
|
||||
|
||||
memset( hdr, 0, sizeof( *hdr ) );
|
||||
memcpy( hdr->magic, HLP_MAGIC, sizeof( HLP_MAGIC ) );
|
||||
hdr->version = HLP_VERSION;
|
||||
hdr->psize = sizeof( void * );
|
||||
hdr->ssize = sizeof( size_t );
|
||||
hdr->tsize = sizeof( time_t );
|
||||
hdr->ddate = instat.st_mtime;
|
||||
hdr->size = memsize;
|
||||
|
||||
savehlp( NULL, &inroot, base, &sp, &pp, 1, &stats );
|
||||
|
||||
if( outname == NULL )
|
||||
of = stdout;
|
||||
else {
|
||||
of = openf( outname, "wb" );
|
||||
if( !of ) {
|
||||
perror( outname );
|
||||
if( outmalloced) free( outname );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
if( !optq) pstats( stderr, outname, &stats, memsize );
|
||||
fwrite( base, 1, memsize + sizeof( hlphdr_t ), of );
|
||||
if( of && of != stdout && of != stderr ) fclose( of );
|
||||
free( base );
|
||||
if( outmalloced) free( outname );
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
/* ***************************************************************** pstats() */
|
||||
static void pstats( FILE *of, char *outname, hlpstat_t *stats, size_t memsize ) {
|
||||
size_t i;
|
||||
char *p = NULL;
|
||||
|
||||
if( outname != NULL && (p = get_realpath( outname )) != NULL )
|
||||
outname = p;
|
||||
fprintf( of,
|
||||
"\n---------------------------------------------------------------\n"
|
||||
"Summary of: %s\n", outname == NULL? "<stdout>" : outname );
|
||||
if( p != NULL ) free( p );
|
||||
for( i = 0; i < 9; i++ ) {
|
||||
if( stats->topics[i] ) {
|
||||
fprintf( of,
|
||||
"Level %u topics: %4u Key memory: %5u bytes Text memory: %5u\n",
|
||||
(unsigned)i+1, (unsigned)stats->topics[i],
|
||||
(unsigned)stats->keymem[i],
|
||||
(unsigned)stats->txtmem[i] );
|
||||
stats->ntopics++;
|
||||
stats->keymemtot += stats->keymem[i];
|
||||
stats->txtmemtot += stats->txtmem[i];
|
||||
}
|
||||
}
|
||||
fprintf( of, " Total topics: %4u Key memory: %5u bytes Text memory: %5u\n",
|
||||
(unsigned)stats->ntopics, (unsigned)stats->keymemtot,
|
||||
(unsigned)stats->txtmemtot );
|
||||
fprintf( of, " Index memory: %5u bytes Data memory: %5u\n",
|
||||
(unsigned)(memsize - (stats->keymemtot + stats->txtmemtot)),
|
||||
(unsigned)(stats->keymemtot + stats->txtmemtot));
|
||||
return;
|
||||
}
|
||||
|
||||
/* **************************************************************** hlpsize() */
|
||||
|
||||
static size_t hlpsize( hlproot_t *root ) {
|
||||
hlptopic_t *hlp;
|
||||
size_t size = 0;
|
||||
|
||||
if( root->ntopics == 0 ) {
|
||||
fprintf( stderr, "Encountered an empty root\n" );
|
||||
return size;
|
||||
}
|
||||
for( hlp = root->topics.ptr;
|
||||
hlp < (hlptopic_t *)root->topics.ptr + root->ntopics; hlp++ ) {
|
||||
size += strlen( hlp->key.ptr ) +1;
|
||||
size += strlen( hlp->text.ptr ) +1;
|
||||
if( hlp->subtopics.ntopics )
|
||||
size += hlpsize( &hlp->subtopics );
|
||||
}
|
||||
size += root->ntopics * sizeof( hlptopic_t );
|
||||
return size;
|
||||
}
|
||||
|
||||
/*************************************************************** rdhelp() */
|
||||
static
|
||||
int rdhelp( hlproot_t *toproot, const char *filename ) {
|
||||
FILE *fp;
|
||||
size_t bufsize = 80;
|
||||
char *buf = NULL, *rec;
|
||||
hlproot_t *root = NULL;
|
||||
hlptopic_t *hlp = NULL,
|
||||
*tpath[9];
|
||||
unsigned int level = 0, n, lineno = 0;
|
||||
|
||||
if( filename == NULL )
|
||||
fp = stdin;
|
||||
else {
|
||||
if( (fp = openf( filename, "r" )) == NULL )
|
||||
return errno;
|
||||
}
|
||||
memset( tpath, 0, sizeof( tpath ) );
|
||||
|
||||
for( rec = NULL; ; ) {
|
||||
char *p, *t;
|
||||
size_t txtlen = 0, len;
|
||||
|
||||
/* Read initial search key */
|
||||
if( rec == NULL ) {
|
||||
++lineno;
|
||||
if( (rec = fgetline( fp, FALSE, &buf, &bufsize )) == NULL )
|
||||
break; /* EOF */
|
||||
}
|
||||
if( (p = strchr( rec, '\r' )) != NULL ) {
|
||||
*p = '\0';
|
||||
}
|
||||
p = rec + 2;
|
||||
if( rec[0] == '!' ||
|
||||
!(strlen(rec) >= 3 &&
|
||||
rec[0] >= '1' && rec[0] <= '9' &&
|
||||
rec[1] == ' ' && isprint( p[ (len = strspn( p, " " )) ]) ) ) {
|
||||
rec = NULL;
|
||||
continue; /* Comment or not a search key record */
|
||||
}
|
||||
p += len; /* Search key starts after level + 1 or more spaces */
|
||||
|
||||
/* Start new topic */
|
||||
|
||||
n = rec[0] - '1';
|
||||
if( n <= level ) {
|
||||
if( n )
|
||||
root = &tpath[n-1]->subtopics;
|
||||
else
|
||||
root = toproot;
|
||||
} else if( n != level +1 ) {
|
||||
free( buf );
|
||||
if( filename != NULL) fclose( fp );
|
||||
fprintf( stderr, "Level error at line %u\n", lineno );
|
||||
exit( EXIT_FAILURE );
|
||||
} else { /* hlp can't be NULL, for code analyzer */
|
||||
if( hlp ) root = &hlp->subtopics;
|
||||
}
|
||||
level = n;
|
||||
|
||||
if( !root ) exit(EXIT_FAILURE); /* More code analyzer */
|
||||
if( (hlp = realloc( root->topics.ptr,
|
||||
(root->ntopics + 1) * sizeof( hlptopic_t ) )) == NULL ) {
|
||||
free( buf );
|
||||
if( filename != NULL) fclose( fp );
|
||||
return errno;
|
||||
}
|
||||
root->topics.ptr = hlp;
|
||||
hlp += root->ntopics++;
|
||||
tpath[level] = hlp;
|
||||
len = strlen( p ) + 1;
|
||||
if( (hlp->key.ptr = malloc( len )) == NULL ) {
|
||||
free( buf );
|
||||
if( filename != NULL) fclose( fp );
|
||||
return errno;
|
||||
}
|
||||
memcpy( hlp->key.ptr, p, len );
|
||||
hlp->keylen = (uint32_t)(len -1);
|
||||
hlp->text.ptr = NULL;
|
||||
hlp->subtopics.topics.ptr = NULL;
|
||||
hlp->subtopics.ntopics = 0;
|
||||
|
||||
/* Add text */
|
||||
|
||||
while( (rec = fgetline( fp, TRUE, &buf, &bufsize )) != NULL ) {
|
||||
++lineno;
|
||||
if( (p = strchr( rec, '\r' )) != NULL ) {
|
||||
*p++ = '\n';
|
||||
*p = '\0';
|
||||
}
|
||||
if( rec[0] == '!' ) { /* Comment */
|
||||
continue;
|
||||
}
|
||||
p = rec;
|
||||
if( strlen(p) >= 3 &&
|
||||
(rec[0] >= '1' && rec[0] <= '9') &&
|
||||
rec[1] == ' ' && isprint( p[ strspn( p + 2, " " ) ] ) ) {
|
||||
if( (p = strchr( p, '\n' )) )
|
||||
*p = '\0';
|
||||
break; /* New search key, rescan this record */
|
||||
}
|
||||
|
||||
len = strlen( p );
|
||||
if( len >= 2 && p[len-2] == '$' && p[len-1] == '\n' ) {
|
||||
p[len-2] = '\0'; /* Strip \n for lines ending in $ */
|
||||
--len;
|
||||
}
|
||||
++len;
|
||||
if( hlp->text.ptr ) {
|
||||
if(txtlen != strlen(hlp->text.ptr)) printf( "len mismatch\n");
|
||||
} else if( txtlen ) printf( "Missing text\n");
|
||||
if( (t = realloc( hlp->text.ptr, txtlen + len)) == NULL ) {
|
||||
free( buf );
|
||||
if( filename != NULL) fclose( fp );
|
||||
return errno;
|
||||
}
|
||||
hlp->text.ptr = t;
|
||||
memcpy( (char *)hlp->text.ptr + txtlen, p, len );
|
||||
txtlen += --len;
|
||||
rec = NULL;
|
||||
} /* Add topic text */
|
||||
if( hlp->text.ptr == NULL ) {
|
||||
fprintf( stderr, "No text for %s at line %u\n",
|
||||
(char *)hlp->key.ptr, lineno );
|
||||
free( rec );
|
||||
if( filename != NULL) fclose( fp );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
} /* Add topic */
|
||||
free( buf );
|
||||
if( filename != NULL) fclose( fp );
|
||||
if( toproot->ntopics == 0 ) {
|
||||
fprintf( stderr, "No topics found at line %u\n", lineno );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
helpsort( toproot );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************** helpsort() */
|
||||
|
||||
static void helpsort( hlproot_t *root ) {
|
||||
hlptopic_t *hlp;
|
||||
|
||||
if( root->topics.ptr == NULL ) {
|
||||
fprintf( stderr, "Node has no topics\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
for( hlp = root->topics.ptr;
|
||||
hlp < (hlptopic_t *)root->topics.ptr + root->ntopics; hlp++ ) {
|
||||
if( hlp->text.ptr == NULL ) {
|
||||
fprintf( stderr, "No text for %s\n", (char *)hlp->key.ptr );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
if( hlp->subtopics.topics.ptr )
|
||||
helpsort( &hlp->subtopics );
|
||||
}
|
||||
|
||||
qsort( root->topics.ptr, root->ntopics, sizeof( hlptopic_t ), &hlpcmp );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/***************************************************************** hlpcmp() */
|
||||
|
||||
static int hlpcmp( const void *ta, const void *tb ) {
|
||||
const char *a, *b;
|
||||
size_t alen, blen;
|
||||
|
||||
a = ((hlptopic_t *)ta)->key.ptr;
|
||||
b = ((hlptopic_t *)tb)->key.ptr;
|
||||
alen = ((hlptopic_t *)ta)->keylen;
|
||||
blen = ((hlptopic_t *)tb)->keylen;
|
||||
|
||||
while( alen && blen ) {
|
||||
int c;
|
||||
|
||||
c = tolower( (unsigned char)*a ) - tolower( (unsigned char)*b );
|
||||
if( c != 0 )
|
||||
return c;
|
||||
++a; ++b; --alen; --blen;
|
||||
}
|
||||
|
||||
return (int)(alen - blen);
|
||||
}
|
||||
|
||||
/* **************************************************************** savehlp() */
|
||||
|
||||
static void savehlp( hlproot_t *oroot, hlproot_t *iroot,
|
||||
char *base,char **sp, char **pp,
|
||||
unsigned lvl, hlpstat_t *stats ) {
|
||||
size_t t;
|
||||
hlptopic_t *ihlp, *ohlp;
|
||||
hlproot_t *rp;
|
||||
|
||||
/* sp allocates structures toward increasing addresses.
|
||||
* pp allocates strings toward decreasing addresses.
|
||||
* This ensures that alignment is accounted for.
|
||||
* All pointers in the input tree are offsets in the output.
|
||||
*/
|
||||
if( oroot == NULL ) { /* Top root */
|
||||
rp = (hlproot_t *)*sp;
|
||||
*sp = (char *)(rp + 1);
|
||||
memset( rp, 0, sizeof( *rp ) );
|
||||
} else
|
||||
rp = oroot; /* Subtopic root */
|
||||
|
||||
ohlp = (hlptopic_t *)*sp; /* Topic list for this root */
|
||||
rp->topics.ofs = (char *)ohlp - base;
|
||||
t =
|
||||
rp->ntopics = iroot->ntopics;
|
||||
t *= sizeof( hlptopic_t );
|
||||
*sp += t;
|
||||
memset( ohlp, 0, t );
|
||||
|
||||
for( ihlp = iroot->topics.ptr, t = 0; t < iroot->ntopics; ihlp++, t++ ) {
|
||||
size_t len;
|
||||
|
||||
stats->topics[lvl-1]++;
|
||||
|
||||
memset( ohlp, 0, sizeof( *ohlp ) );
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning (disable: 6001)
|
||||
#endif
|
||||
/* N.B. Pointers ARE initialized */
|
||||
len = strlen( ihlp->key.ptr ) +1;
|
||||
stats->keymem[lvl-1] += len;
|
||||
*pp = (char *)*pp - len;
|
||||
memcpy( *pp, ihlp->key.ptr, len );
|
||||
free( (void *)ihlp->key.ptr );
|
||||
ohlp->key.ofs = *pp - base;
|
||||
ohlp->keylen = (uint32_t)len -1;
|
||||
|
||||
len = strlen( ihlp->text.ptr ) +1;
|
||||
stats->txtmem[lvl-1] += len;
|
||||
*pp = (char *)*pp - len;
|
||||
memcpy( *pp, ihlp->text.ptr, len );
|
||||
free( (void *)ihlp->text.ptr );
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
ohlp->text.ofs = *pp - base;
|
||||
|
||||
ohlp->subtopics.ntopics = ihlp->subtopics.ntopics;
|
||||
if( ihlp->subtopics.ntopics ) {
|
||||
ohlp->subtopics.topics.ofs = *sp - base;
|
||||
savehlp( &ohlp->subtopics, &ihlp->subtopics, base, sp, pp,
|
||||
lvl+1, stats );
|
||||
} else {
|
||||
ohlp->subtopics.topics.ofs = 0;
|
||||
}
|
||||
++ohlp;
|
||||
}
|
||||
free( (void *)iroot->topics.ptr );
|
||||
return;
|
||||
}
|
||||
|
||||
/*************************************************************** printdata() */
|
||||
|
||||
static int printdata( FILE *of, unsigned level, hlproot_t *root,
|
||||
int text, hlpstat_t *stats ) {
|
||||
int sts;
|
||||
hlptopic_t *hlp;
|
||||
|
||||
if( root->topics.ptr == NULL )
|
||||
return 1;
|
||||
|
||||
for( hlp = root->topics.ptr;
|
||||
hlp < (hlptopic_t *)root->topics.ptr + root->ntopics; hlp++ ) {
|
||||
stats->topics[level-1]++;
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning (disable: 6001)
|
||||
#endif
|
||||
/* N.B. Pointers ARE initialized */
|
||||
fprintf( of, "%*s %u %s\n", level, "", level, (char *)hlp->key.ptr );
|
||||
free( hlp->key.ptr );
|
||||
if( hlp->text.ptr == NULL )
|
||||
return 0;
|
||||
stats->keymem[level-1] += (size_t)hlp->keylen+1;
|
||||
stats->txtmem[level-1] += strlen( (char *)hlp->text.ptr ) +1;
|
||||
if( text )
|
||||
printf( "%s\n", (char *)hlp->text.ptr );
|
||||
free( hlp->text.ptr );
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
if( hlp->subtopics.topics.ptr != NULL &&
|
||||
!(sts = printdata( of, level +1, &hlp->subtopics, text, stats )) )
|
||||
return sts;
|
||||
}
|
||||
free( root->topics.ptr );
|
||||
root->topics.ptr = NULL;
|
||||
root->ntopics = 0;
|
||||
return 1;
|
||||
}
|
||||
1188
extracters/ods2/message
Executable file
1188
extracters/ods2/message
Executable file
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,10 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_MOUNTCMD )
|
||||
@@ -15,6 +18,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include "cmddef.h"
|
||||
|
||||
#include "access.h"
|
||||
@@ -31,80 +35,117 @@ static char *parents = NULL;
|
||||
void mounthelp(void);
|
||||
|
||||
#define mou_snapshot OPT_GENERIC_1
|
||||
#define mou_dtype OPT_GENERIC_2
|
||||
|
||||
|
||||
qual_t mouquals[] = { {DT_NAME, 0, MOU_DEVTYPE, CV(NULL), "Drive type (DEC model name) "},
|
||||
{"image", MOU_VIRTUAL, 0, NV, "Mount a disk image file", },
|
||||
{"log", MOU_LOG, 0, NV, "-Show progress"},
|
||||
{"nolog", 0, MOU_LOG, NV, NULL},
|
||||
{"readonly", 0, MOU_WRITE, NV, "Only allow reading from volume"},
|
||||
qual_t
|
||||
mouquals[] = { {DT_NAME, 0, MOU_DEVTYPE, CV(NULL),
|
||||
"commands mount qual_media"},
|
||||
{"image", mou_dtype | MOU_VIRTUAL,
|
||||
0, NV,
|
||||
"commands mount qual_image"},
|
||||
{"log", MOU_LOG, 0, NV,
|
||||
"-commands mount qual_log"},
|
||||
{"nolog", 0, MOU_LOG, NV, NULL},
|
||||
{"readonly", 0, MOU_WRITE, NV,
|
||||
"commands mount qual_readonly"},
|
||||
#ifdef USE_VHD
|
||||
{"snapshots_of", MOU_VIRTUAL | MOU_WRITE | mou_snapshot, PHY_CREATE, SV(&parents),
|
||||
"Create snapshot(s) of the (existing) VHD disk(s) specified by this qualifier." },
|
||||
{"snapshots_of",
|
||||
MOU_VIRTUAL | MOU_WRITE | mou_snapshot,
|
||||
PHY_CREATE, SV(&parents),
|
||||
"commands mount qual_snapshot"},
|
||||
#endif
|
||||
{"virtual", MOU_VIRTUAL, 0, NV, NULL, },
|
||||
{"write", MOU_WRITE, 0, NV, "Allow writing to volume", },
|
||||
{NULL, 0, 0, NV, NULL } };
|
||||
{"device", mou_dtype, MOU_VIRTUAL, NV,
|
||||
"commands mount qual_device"},
|
||||
{"virtual", mou_dtype | MOU_VIRTUAL, 0,
|
||||
NV, NULL},
|
||||
{"write", MOU_WRITE, 0, NV,
|
||||
"-commands mount qual_write"},
|
||||
{"nowrite" , 0, MOU_WRITE, NV, NULL},
|
||||
|
||||
param_t moupars[] = { {"volumes", REQ, LIST, NOPA,
|
||||
"devices or disk image(s) of volume set in RVN order separated by comma"
|
||||
},
|
||||
{"labels", OPT, LIST, NOPA, "volume labels in RVN order separated by comma" },
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
{NULL, 0, 0, NV, NULL} };
|
||||
|
||||
param_t
|
||||
moupars[] = { {"volumes", REQ, LIST, NOPA, "commands mount volumes"},
|
||||
{"labels", OPT, LIST, NOPA, "commands mount labels"},
|
||||
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
};
|
||||
|
||||
/******************************************************************* domount() */
|
||||
|
||||
DECL_CMD(mount) {
|
||||
int sts = 1, devices = 0;
|
||||
vmscond_t sts = 1;
|
||||
int devices = 0;
|
||||
size_t i;
|
||||
char **devs = NULL, **labs = NULL;
|
||||
int options;
|
||||
options_t options;
|
||||
|
||||
#ifdef USE_VHD
|
||||
int nparents = 0;
|
||||
size_t i;
|
||||
char **parfiles = NULL;
|
||||
#endif
|
||||
|
||||
options = checkquals( 0, mouquals, qualc, qualv );
|
||||
if( options == -1 )
|
||||
return SS$_BADPARAM;
|
||||
|
||||
UNUSED(argc);
|
||||
|
||||
if( (devices = parselist( &devs, 0, argv[1], "devices")) < 0 )
|
||||
return SS$_BADPARAM;
|
||||
if( parselist( &labs, devices, argv[2], "labels") < 0 ) {
|
||||
free( devs );
|
||||
return SS$_BADPARAM;
|
||||
if( $FAILS(sts = checkquals( &options, MOU_LOG, mouquals, qualc, qualv )) ) {
|
||||
return sts;
|
||||
}
|
||||
|
||||
if( $FAILS(sts = parselist( &devices, &devs, 0, argv[1])) )
|
||||
return sts;
|
||||
if( $FAILS(sts = parselist( NULL, &labs, devices, argv[2])) ) {
|
||||
free( devs );
|
||||
return sts;
|
||||
}
|
||||
|
||||
if( !(options & mou_dtype) ) {
|
||||
for( i = 0; i < (unsigned)devices; i++ ) {
|
||||
size_t len;
|
||||
char *p;
|
||||
|
||||
if( (p = strchr( devs[i], '.' )) != NULL ) {
|
||||
len = strlen( p+1 );
|
||||
if( len >= 1 && len == strspn( p+1, "0123456789" ".;-_"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz" ) )
|
||||
options |= MOU_VIRTUAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_VHD
|
||||
if( options & mou_snapshot ) {
|
||||
nparents = parselist( &parfiles, devices, parents, "parent VHD files " );
|
||||
if( $FAILS(sts = parselist( &nparents, &parfiles, devices, parents )) ) {
|
||||
free( devs );
|
||||
free( labs );
|
||||
return sts;
|
||||
}
|
||||
if( nparents != devices ) {
|
||||
printf( "%%ODS2-E-NOTSAME, You must specify the same number of existing files (%u) with %cSNAPSHOT as filenames to create (%u)\n",
|
||||
nparents, vms_qual? '/': '-', devices );
|
||||
sts = printmsg( MOUNT_NOTSAME, 0, nparents, qstyle_c, devices );
|
||||
free( parfiles );
|
||||
return SS$_BADPARAM;
|
||||
free( devs );
|
||||
free( labs );
|
||||
return sts;
|
||||
}
|
||||
for( i = 0; i < (size_t)nparents; i++ ) {
|
||||
sts = phyvhd_snapshot( devs[i], parfiles[i] );
|
||||
if( !(sts & STS$M_SUCCESS) ) {
|
||||
if( (sts & STS$M_COND_ID) != (SS$_DUPFILENAME & STS$M_COND_ID) ) {
|
||||
(void) unlink( devs[i] );
|
||||
if( $FAILS(sts = phyvhd_snapshot( devs[i], parfiles[i] )) ) {
|
||||
if( !$MATCHCOND(sts, SS$_DUPFILENAME) ) {
|
||||
(void) Unlink( devs[i] );
|
||||
}
|
||||
while( i > 0 ) {
|
||||
--i;
|
||||
(void) unlink( devs[i] );
|
||||
(void) Unlink( devs[i] );
|
||||
}
|
||||
free( parfiles );
|
||||
return SS$_BADPARAM;
|
||||
free( devs );
|
||||
free( labs );
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
if( options & MOU_LOG ) {
|
||||
for( i = 0; i < (size_t)nparents; i++ )
|
||||
printf( "%%ODS2-I-SNAPOK, %s created from %s\n",
|
||||
devs[i], parfiles[i] );
|
||||
sts = printmsg( MOUNT_SNAPOK, 0, devs[i], parfiles[i] );
|
||||
}
|
||||
options |= MOU_WRITE;
|
||||
free( parfiles );
|
||||
@@ -112,42 +153,31 @@ DECL_CMD(mount) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (devices > 0) {
|
||||
sts = mount( options | MOU_LOG, devices, devs, labs );
|
||||
if( !(sts & STS$M_SUCCESS) )
|
||||
printf("%%ODS2-E-MOUNTERR, Mount failed with %s\n", getmsg(sts, MSG_TEXT));
|
||||
}
|
||||
if( devices > 0 )
|
||||
sts = mount( options, devices, devs, labs );
|
||||
|
||||
free( devs );
|
||||
free( labs );
|
||||
return sts;
|
||||
}
|
||||
|
||||
void mounthelp(void) {
|
||||
printf( "\n" );
|
||||
printf( "You can mount a volume(-set) from either physical devices\n" );
|
||||
printf( "such a CDROM or hard disk drive, or files containing an\n" );
|
||||
printf( "image of a volume, such as a .ISO file or simulator disk\n\n" );
|
||||
printf( "To mount a disk image, use the %cimage qualifier and\n",
|
||||
(vms_qual? '/': '-') );
|
||||
printf( "specify the filename as the parameter.\n\n" );
|
||||
printf( "If the filename contains %c, specify it in double quotes\n\n",
|
||||
(vms_qual? '/': '-') );
|
||||
printf( "Mount will assign a virtual device name to each volume.\n" );
|
||||
printf( "You can select a virtual device name using the format\n" );
|
||||
printf( " dka100=my_files.iso\n\n" );
|
||||
printf( "To mount a physical device, use the format:\n" );
|
||||
phyio_help(stdout);
|
||||
printf( "To mount a volume set, specify all the members in RVN order\n" );
|
||||
printf( "as a comma-separated list.\n\n" );
|
||||
printf( "If you specify a list of volume labels, they must be in\n" );
|
||||
printf( "the same order as the volumes, and each must match the label\n" );
|
||||
printf( "stored in the data\n" );
|
||||
/*************************************************************** domounthelp() */
|
||||
|
||||
DECL_CMD(mounthelp) {
|
||||
UNUSED( argc );
|
||||
UNUSED( argv );
|
||||
UNUSED( qualc );
|
||||
UNUSED( qualv );
|
||||
|
||||
(void) helptopic( 0, "MOUNT", qstyle_s, qstyle_s );
|
||||
|
||||
phyio_help();
|
||||
|
||||
(void) helptopic( 0, "MOUNT VOLSET" );
|
||||
|
||||
#ifdef USE_VHD
|
||||
printf( "\nTo create and mount a snapshot of a VHD-based volume set, use the %csnapshot_of qualifier.\n", vms_qual? '/': '-' );
|
||||
printf( "Specify the existing volumes' filenames as an argument to %csnapshot, and\n", vms_qual? '/': '-' );
|
||||
printf( "list the corresponding filenames to be created as the mount parameter.\n" );
|
||||
(void) helptopic( 0, "MOUNT VHD", qstyle_s, qstyle_s );
|
||||
#endif
|
||||
|
||||
return;
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,18 @@
|
||||
* ods2.h
|
||||
*/
|
||||
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _ODS2_H
|
||||
#define _ODS2_H
|
||||
|
||||
@@ -16,29 +28,91 @@
|
||||
#include "debug.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t vmscond_t;
|
||||
|
||||
#define $MATCHCOND( c1, c2 ) ( ((c1) & STS$M_FAC_SP)? \
|
||||
((c1) & STS$M_COND_ID) == ((c2) & STS$M_COND_ID): \
|
||||
((c1) & STS$M_MSG_NO) == ((c2) & STS$M_MSG_NO) )
|
||||
|
||||
#define $SETLEVEL(cond, LEVEL) (((cond) & ~STS$M_SEVERITY) | STS$K_ ## LEVEL)
|
||||
#define $SETFAC(cond,fac) (((cond) & ~STS$M_FAC_NO) | (fac ## _FACILITY << STS$V_FAC_NO))
|
||||
#define $SHRMSG(cond,fac,LEVEL) $SETLEVEL((((cond) & STS$M_FAC_SP)? (cond): $SETFAC(cond,fac)),LEVEL)
|
||||
|
||||
#define $FAILED(cond) !((cond) & STS$M_SUCCESS)
|
||||
#define $FAILS(cond) !((cond) & STS$M_SUCCESS)
|
||||
#define $SUCCESSFUL(cond) (((cond) & STS$M_SUCCESS))
|
||||
#define $PRINTED(cond) (((cond) & STS$M_INHIB_MSG) != 0)
|
||||
|
||||
/* Option bits common to I/O, access, visible outside the ODS-2 parser */
|
||||
|
||||
#define MOU_WRITE (1 << 0)
|
||||
#define MOU_VIRTUAL (1 << 1)
|
||||
#define MOU_LOG (1 << 2)
|
||||
#define PHY_CREATE (1 << 3)
|
||||
#define PHY_VHDDSK (1 << 4)
|
||||
#define MOU_WRITE OPT_SHARED_1
|
||||
#define MOU_VIRTUAL OPT_SHARED_2
|
||||
#define MOU_LOG OPT_SHARED_3
|
||||
#define PHY_CREATE OPT_SHARED_4
|
||||
#define PHY_VHDDSK OPT_SHARED_5
|
||||
#define OS_MOUNTED OPT_SHARED_6
|
||||
|
||||
/* OPT_SHARED_7 is free */
|
||||
|
||||
/* DEVTYPE can probably be shrunk by several bits */
|
||||
#define MOU_V_DEVTYPE (OPT_V_SHARED + 8)
|
||||
#define MOU_DEVTYPE ((((options_t)(1u) << MOU_S_DEVTYPE) -1) << MOU_V_DEVTYPE)
|
||||
#define MOU_S_DEVTYPE (12)
|
||||
|
||||
/* I/O option bits overlaid for use by non-I/O commands */
|
||||
|
||||
#define OPT_V_SHARED (0)
|
||||
#define OPT_SHARED_1 (((options_t)1u) << (OPT_V_SHARED + 0))
|
||||
#define OPT_SHARED_2 (((options_t)1u) << (OPT_V_SHARED + 1))
|
||||
#define OPT_SHARED_3 (((options_t)1u) << (OPT_V_SHARED + 2))
|
||||
#define OPT_SHARED_4 (((options_t)1u) << (OPT_V_SHARED + 3))
|
||||
#define OPT_SHARED_5 (((options_t)1u) << (OPT_V_SHARED + 4))
|
||||
#define OPT_SHARED_6 (((options_t)1u) << (OPT_V_SHARED + 5))
|
||||
#define OPT_SHARED_7 (((options_t)1u) << (OPT_V_SHARED + 6))
|
||||
#define OPT_SHARED_8 (((options_t)1u) << (OPT_V_SHARED + 7))
|
||||
#define OPT_SHARED_9 (((options_t)1u) << (OPT_V_SHARED + 8))
|
||||
#define OPT_SHARED_10 (((options_t)1u) << (OPT_V_SHARED + 9))
|
||||
#define OPT_SHARED_11 (((options_t)1u) << (OPT_V_SHARED + 10))
|
||||
#define OPT_SHARED_12 (((options_t)1u) << (OPT_V_SHARED + 11))
|
||||
#define OPT_SHARED_13 (((options_t)1u) << (OPT_V_SHARED + 12))
|
||||
#define OPT_SHARED_14 (((options_t)1u) << (OPT_V_SHARED + 13))
|
||||
#define OPT_SHARED_15 (((options_t)1u) << (OPT_V_SHARED + 14))
|
||||
#define OPT_SHARED_16 (((options_t)1u) << (OPT_V_SHARED + 15))
|
||||
#define OPT_SHARED_17 (((options_t)1u) << (OPT_V_SHARED + 16))
|
||||
#define OPT_SHARED_18 (((options_t)1u) << (OPT_V_SHARED + 17))
|
||||
#define OPT_SHARED_19 (((options_t)1u) << (OPT_V_SHARED + 18))
|
||||
#define OPT_SHARED_20 (((options_t)1u) << (OPT_V_SHARED + 19))
|
||||
|
||||
#define MOU_V_DEVTYPE (8)
|
||||
#define MOU_DEVTYPE (0xffff << MOU_V_DEVTYPE)
|
||||
#define MOU_S_DEVTYPE (16)
|
||||
|
||||
/* Option bits that will not conflict with I/O */
|
||||
|
||||
#define OPT_GENERIC_1 (1 << (MOU_V_DEVTYPE + MOU_S_DEVTYPE + 0) )
|
||||
#define OPT_GENERIC_2 (1 << (MOU_V_DEVTYPE + MOU_S_DEVTYPE + 1) )
|
||||
#define OPT_GENERIC_3 (1 << (MOU_V_DEVTYPE + MOU_S_DEVTYPE + 2) )
|
||||
#define OPT_GENERIC_4 (1 << (MOU_V_DEVTYPE + MOU_S_DEVTYPE + 3) )
|
||||
#define OPT_GENERIC_5 (1 << (MOU_V_DEVTYPE + MOU_S_DEVTYPE + 4) )
|
||||
#define OPT_GENERIC_6 (1 << (MOU_V_DEVTYPE + MOU_S_DEVTYPE + 5) )
|
||||
#define OPT_GENERIC_7 (1 << (MOU_V_DEVTYPE + MOU_S_DEVTYPE + 6) )
|
||||
#define OPT_GENERIC_8 (1 << (MOU_V_DEVTYPE + MOU_S_DEVTYPE + 7) )
|
||||
#define OPT_V_GENERIC (MOU_V_DEVTYPE + MOU_S_DEVTYPE)
|
||||
#define OPT_GENERIC_1 ((options_t)(1u << (OPT_V_GENERIC + 0)))
|
||||
#define OPT_GENERIC_2 ((options_t)(1u << (OPT_V_GENERIC + 1)))
|
||||
#define OPT_GENERIC_3 ((options_t)(1u << (OPT_V_GENERIC + 2)))
|
||||
#define OPT_GENERIC_4 ((options_t)(1u << (OPT_V_GENERIC + 3)))
|
||||
#define OPT_GENERIC_5 ((options_t)(1u << (OPT_V_GENERIC + 4)))
|
||||
#define OPT_GENERIC_6 ((options_t)(1u << (OPT_V_GENERIC + 5)))
|
||||
#define OPT_GENERIC_7 ((options_t)(1u << (OPT_V_GENERIC + 6)))
|
||||
#define OPT_GENERIC_8 ((options_t)(1u << (OPT_V_GENERIC + 7)))
|
||||
#define OPT_GENERIC_9 ((options_t)(1u << (OPT_V_GENERIC + 8)))
|
||||
#define OPT_GENERIC_10 ((options_t)(1u << (OPT_V_GENERIC + 9)))
|
||||
#define OPT_GENERIC_11 ((options_t)(1u << (OPT_V_GENERIC + 10)))
|
||||
#define OPT_GENERIC_12 ((options_t)(1u << (OPT_V_GENERIC + 11)))
|
||||
|
||||
#define OPT_NOSORT (1 << 31)
|
||||
#if (OPT_V_GENERIC+11 > 31)
|
||||
#error options_t overflow, change size or definitions in ods2.h
|
||||
#endif
|
||||
|
||||
/* This bit is set in the table end marker and does not overlap the
|
||||
* data bits. The decision to sort is made after a scan of the entire
|
||||
* table that computes some statistics that do not depend on order.
|
||||
*/
|
||||
|
||||
#define OPT_NOSORT ((options_t)(1u << 31))
|
||||
|
||||
typedef int32_t options_t;
|
||||
|
||||
#endif /* #ifndef _ODS2_H */
|
||||
|
||||
@@ -28,8 +28,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,0,0,1
|
||||
PRODUCTVERSION 2,0,0,1
|
||||
FILEVERSION 3,0,0,0
|
||||
PRODUCTVERSION 3,0,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -44,17 +44,17 @@ BEGIN
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
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 (Modified)\0"
|
||||
VALUE "FileVersion", "V2.1\0"
|
||||
VALUE "Comments", "ODS-2 (VMS) disk reader/writer for Windows NT-based OS\0"
|
||||
VALUE "CompanyName", "Paul Nankervis <paulnank@au1.ibm.com>, Timothe Litt <litt@acm.org>\0"
|
||||
VALUE "FileDescription", "ODS-2 Reader/Writer for Windows (Modified)\0"
|
||||
VALUE "FileVersion", "V3.0\0"
|
||||
VALUE "InternalName", "ODS2\0"
|
||||
VALUE "LegalCopyright", "Copyright <EFBFBD> 2001, 2016\0"
|
||||
VALUE "LegalCopyright", "Copyright \251 2001, 2016, 2022\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "ODS2.EXE\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "ODS2\0"
|
||||
VALUE "ProductVersion", "V2.1\0"
|
||||
VALUE "ProductVersion", "V3.0.0.0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,44 +1,49 @@
|
||||
/* Phyio.h Definition of Physical I/O 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.
|
||||
*/
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
/* 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_path() returns the full path of the supplied filnam.a The
|
||||
returned character string must be deallocated by the
|
||||
caller.
|
||||
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_done() makes a device unavailable.
|
||||
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.
|
||||
|
||||
*/
|
||||
* 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_path() returns the full path of the supplied filnam.a The
|
||||
* returned character string must be deallocated by the
|
||||
* caller.
|
||||
* 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_done() makes a device unavailable.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _PHYIO_H
|
||||
#define _PHYIO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ods2.h"
|
||||
|
||||
#define PHYIO_READONLY 1
|
||||
|
||||
typedef enum showtype {
|
||||
@@ -50,15 +55,14 @@ typedef enum showtype {
|
||||
struct DEV;
|
||||
|
||||
void phyio_show( showtype_t type );
|
||||
char *phyio_path( const char *filnam );
|
||||
unsigned phyio_init( struct DEV *dev );
|
||||
unsigned phyio_done( struct DEV *dev );
|
||||
vmscond_t phyio_init( struct DEV *dev );
|
||||
vmscond_t phyio_done( struct DEV *dev );
|
||||
|
||||
typedef unsigned (*phy_iord_t)( struct DEV *dev, unsigned block, unsigned length,
|
||||
char *buffer );
|
||||
typedef unsigned (*phy_iowr_t)( struct DEV *dev, unsigned block, unsigned length,
|
||||
const char *buffer );
|
||||
typedef vmscond_t( *phy_iord_t )( struct DEV *dev, uint32_t block,
|
||||
uint32_t length, char *buffer );
|
||||
typedef vmscond_t( *phy_iowr_t )( struct DEV *dev, uint32_t block,
|
||||
uint32_t length, const char *buffer );
|
||||
|
||||
void phyio_help(FILE *fp );
|
||||
void phyio_help( void );
|
||||
|
||||
#endif /* #ifndef _PHYIO_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,28 @@
|
||||
/* PHYOS2.C v1.2 Physical I/O module for OS2 */
|
||||
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
/* This version implemented to read from Floppy or CD by
|
||||
guessing that A: or B: will be a floppy and anything
|
||||
else is probably a CD? */
|
||||
* guessing that A: or B: will be a floppy and anything
|
||||
* else is probably a CD?
|
||||
*/
|
||||
|
||||
/* This module has not been compiled in quite some time, and
|
||||
* while some effort has been made to keep up with API changes,
|
||||
* it requires quite a bit of work to bring it up to date.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
@@ -12,22 +30,33 @@
|
||||
#define INCL_DOSDEVIOCTL
|
||||
#define INCL_NOPMAPI
|
||||
#include <os2.h>
|
||||
#include "ods2.h"
|
||||
#include "phyio.h"
|
||||
#include "ssdef.h"
|
||||
#include "sysmsg.h"
|
||||
|
||||
static unsigned phyio_read( struct DEV *dev, unsigned block, unsigned length,
|
||||
char *buffer );
|
||||
static unsigned phyio_write( struct DEV *dev, unsigned block, unsigned length,
|
||||
const char *buffer );
|
||||
static vmscond_t phyio_read( struct DEV *dev, uint32_t block, uint32_t length,
|
||||
char *buffer );
|
||||
static vmscond_t phyio_write( struct DEV *dev, uint32_t block, uint32_t length,
|
||||
const char *buffer );
|
||||
|
||||
unsigned init_count = 0;
|
||||
unsigned read_count = 0;
|
||||
unsigned write_count = 0;
|
||||
|
||||
void phyio_show(void)
|
||||
{
|
||||
printf("PHYIO_SHOW Initializations: %d Reads: %d Writes: %d\n",
|
||||
init_count,read_count,write_count);
|
||||
void phyio_show( showtype_t type ) {
|
||||
switch( type ) {
|
||||
case SHOW_STATS:
|
||||
printmsg( IO_STATS, MSG_TEXT, init_count, read_count, write_count );
|
||||
return;
|
||||
case SHOW_FILE64:
|
||||
printmsg( IO_NOLARGEFILE, MSG_TEXT );
|
||||
return;
|
||||
case SHOW_DEVICES:
|
||||
return;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,23 +93,19 @@ 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" );
|
||||
void phyio_help( void ) {
|
||||
(void) helptopic( 0, "MOUNT OS2" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NOTE: This will not compile. The API for phyio_init has changed to
|
||||
taking a DEV struct. I'm leaving it this way becauses I don't have the
|
||||
ability to test under OS2. This was left undone when the API was changed...
|
||||
before my time.
|
||||
before my time. /TL
|
||||
|
||||
|
||||
unsigned phyio_init(int devlen,char *devnam,unsigned *hand,struct phyio_info *info)
|
||||
{
|
||||
vmscond_t phyio_init(int devlen,char *devnam,unsigned *hand,struct phyio_info *info) {
|
||||
dev->devread = phyio_read;
|
||||
dev->devwrite = phyio_write;
|
||||
|
||||
@@ -149,9 +174,7 @@ unsigned phyio_init(int devlen,char *devnam,unsigned *hand,struct phyio_info *in
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned phy_getsect(HFILE hfile,unsigned sector,char *buffer)
|
||||
{
|
||||
static vmscond_t phy_getsect(HFILE hfile, uint32_t sector,char *buffer) {
|
||||
ULONG ulPinout,ulDinout;
|
||||
ULONG stat;
|
||||
char rawsect[SECTORSIZE + 304];
|
||||
@@ -171,13 +194,8 @@ unsigned phy_getsect(HFILE hfile,unsigned sector,char *buffer)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static unsigned phyio_read(unsigned handno,unsigned block,unsigned length,char *buffer)
|
||||
{
|
||||
register unsigned sts = 1;
|
||||
static vmscond_t phyio_read(unsigned handno, uint32_t block, uint32_t length, char *buffer) {
|
||||
register vmscond_t sts = SS$_NORMAL;
|
||||
#if DEBUG
|
||||
printf("PHYIO_READ block %d length %d\n",block,length);
|
||||
#endif
|
||||
@@ -215,7 +233,7 @@ static unsigned phyio_read(unsigned handno,unsigned block,unsigned length,char *
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sts & 1) {
|
||||
if( $SUCCESSFUL(sts) ) {
|
||||
read_count++;
|
||||
} else {
|
||||
printf("PHYOS2 Error %d Block %d Length %d\n",sts,block,length);
|
||||
@@ -223,9 +241,7 @@ static unsigned phyio_read(unsigned handno,unsigned block,unsigned length,char *
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
static unsigned phyio_write(unsigned handle,unsigned block,unsigned length,char *buffer)
|
||||
{
|
||||
static vmscond_t phyio_write(unsigned handle, uint32_t block, uint32_t length, char *buffer) {
|
||||
write_count++;
|
||||
return SS$_WRITLCK;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
/* PHYUNIX.c Physical I/O module for Unix */
|
||||
|
||||
/*
|
||||
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.
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -21,7 +24,8 @@
|
||||
/* DO NOT MOVE THIS DEFINITION */
|
||||
/* */
|
||||
#ifndef _FILE_OFFSET_BITS /* */
|
||||
#define _FILE_OFFSET_BITS 64 /* 64-bit off_t (glibc V2.2.x and later) */
|
||||
#error _FILE_OFFSET_BITS must be defined in the makefile */
|
||||
/* It MUST be consistent across all modules. */
|
||||
#endif /* */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
@@ -47,6 +51,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cmddef.h"
|
||||
#include "device.h"
|
||||
#include "ods2.h"
|
||||
#include "phyio.h"
|
||||
@@ -74,17 +79,243 @@ struct devdat {
|
||||
unsigned high;
|
||||
};
|
||||
|
||||
static unsigned phyio_read( struct DEV *dev, unsigned block, unsigned length,
|
||||
char *buffer );
|
||||
static unsigned phyio_write( struct DEV *dev, unsigned block, unsigned length,
|
||||
const char *buffer );
|
||||
static vmscond_t phyio_read( struct DEV *dev, uint32_t block, uint32_t length,
|
||||
char *buffer );
|
||||
static vmscond_t phyio_write( struct DEV *dev, uint32_t block, uint32_t length,
|
||||
const char *buffer );
|
||||
static void showdevs( void );
|
||||
static int devcmp( const void *d1, const void *d2 );
|
||||
|
||||
/*************************************************************** showdevs() */
|
||||
/*************************************************************** phyio_init() */
|
||||
|
||||
static int devcmp( const void *d1, const void *d2 ) {
|
||||
return strcmp( ((struct devdat *)d1)->name, ((struct devdat *)d2)->name );
|
||||
unsigned phyio_init( struct DEV *dev ) {
|
||||
vmscond_t sts = SS$_NORMAL;
|
||||
size_t n;
|
||||
int fd, oflags, saverr = 0;
|
||||
char *device;
|
||||
struct stat statbuf;
|
||||
|
||||
init_count++;
|
||||
|
||||
dev->handle = -1;
|
||||
dev->devread = phyio_read;
|
||||
dev->devwrite = phyio_write;
|
||||
|
||||
if( dev->access & MOU_VIRTUAL ) {
|
||||
const char *virtual;
|
||||
|
||||
virtual = virt_lookup( dev->devnam );
|
||||
if ( virtual == NULL ) {
|
||||
return SS$_NOSUCHDEV;
|
||||
}
|
||||
n = strlen( virtual );
|
||||
device = (char *) malloc( n + 1 );
|
||||
if( device == NULL )
|
||||
return SS$_INSFMEM;
|
||||
|
||||
memcpy( device, virtual, n + 1 );
|
||||
} else {
|
||||
n = sizeof( DEV_PREFIX ) + strlen( dev->devnam );
|
||||
device = (char *) malloc( n );
|
||||
if ( device == NULL )
|
||||
return SS$_INSFMEM;
|
||||
|
||||
memcpy( device, DEV_PREFIX, sizeof( DEV_PREFIX ) -1 );
|
||||
memcpy( device+sizeof( DEV_PREFIX ) -1, dev->devnam, n +1 - sizeof( DEV_PREFIX ) );
|
||||
device[n - 2] = '\0'; /* Remove ':' from device name */
|
||||
}
|
||||
|
||||
oflags = (dev->access & MOU_WRITE )? O_RDWR : O_RDONLY;
|
||||
if( (dev->access & (MOU_VIRTUAL|PHY_CREATE)) == (MOU_VIRTUAL|PHY_CREATE) )
|
||||
oflags |= O_CREAT | O_EXCL;
|
||||
|
||||
fd = open( device, oflags, 0644 );
|
||||
if( fd < 0 )
|
||||
saverr = errno;
|
||||
#if DEBUG
|
||||
printf( "%d = open( \"%s\", %s%s )\n", fd, device,
|
||||
(dev->access & MOU_WRITE )? "O_RDWR" : "O_RDONLY",
|
||||
(dev->access & PHY_CREATE)? "|O_CREAT|O_EXCL, 0666" : "" );
|
||||
#endif
|
||||
if ( fd < 0 && (dev->access & (MOU_WRITE|PHY_CREATE)) == MOU_WRITE ) {
|
||||
dev->access &= ~MOU_WRITE;
|
||||
fd = open( device, O_RDONLY );
|
||||
#if DEBUG
|
||||
printf( "%d = open( \"%s\", O_RDONLY )\n", fd, device );
|
||||
#endif
|
||||
}
|
||||
dev->handle = fd;
|
||||
|
||||
if( fd >= 0 ) {
|
||||
if( fstat( fd, &statbuf ) == 0 ) {
|
||||
if( dev->access & MOU_VIRTUAL ) {
|
||||
if( !S_ISREG(statbuf.st_mode) ) {
|
||||
sts = printmsg( IO_UNXNOTREG, 0, device );
|
||||
close( fd );
|
||||
dev->handle = -1;
|
||||
} else
|
||||
dev->eofptr = statbuf.st_size;
|
||||
} else {
|
||||
if( !S_ISBLK(statbuf.st_mode ) ) {
|
||||
sts = printmsg( IO_UNXNOTBLK, 0, device );
|
||||
close( fd );
|
||||
dev->handle = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if( !saverr )
|
||||
saverr = errno;
|
||||
close( fd );
|
||||
dev->handle = -1;
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fd < 0 ) {
|
||||
switch( saverr ) {
|
||||
case EEXIST:
|
||||
printmsg( IO_EXISTS, 0, device );
|
||||
sts = SS$_DUPFILENAME | STS$M_INHIB_MSG;
|
||||
break;
|
||||
default:
|
||||
printmsg( IO_OPENDEV, 0, device );
|
||||
printmsg( ODS2_OSERROR, MSG_CONTINUE, IO_OPENDEV, strerror( saverr ) );
|
||||
sts = ((dev->access & MOU_VIRTUAL) ? SS$_NOSUCHFILE : SS$_NOSUCHDEV) |
|
||||
STS$M_INHIB_MSG;
|
||||
}
|
||||
}
|
||||
free( device );
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_done() */
|
||||
|
||||
vmscond_t phyio_done( struct DEV *dev ) {
|
||||
if( dev->handle != -1 )
|
||||
close( dev->handle );
|
||||
dev->handle = -1;
|
||||
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_read() */
|
||||
|
||||
static vmscond_t phyio_read( struct DEV *dev, uint32_t block,
|
||||
uint32_t length, char *buffer ) {
|
||||
vmscond_t sts;
|
||||
ssize_t res;
|
||||
off_t pos;
|
||||
|
||||
#if DEBUG
|
||||
printf("Phyio read block: %d into %p (%d bytes)\n",
|
||||
block, buffer, length );
|
||||
#endif
|
||||
|
||||
read_count++;
|
||||
pos = (off_t) block * (off_t) 512;
|
||||
if( (pos = lseek( dev->handle, pos, SEEK_SET )) < 0 ) {
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( IO_SEEKERR, block );
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE,
|
||||
IO_SEEKERR, strerror(err) );
|
||||
return sts;
|
||||
}
|
||||
if( (res = read( dev->handle, buffer, length )) != (ssize_t)length ) {
|
||||
int err;
|
||||
|
||||
if( res == 0 ) {
|
||||
return SS$_ENDOFFILE;
|
||||
}
|
||||
err = errno;
|
||||
printmsg( IO_READERR, 0, block );
|
||||
if( res == (off_t)-1 ) {
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE,
|
||||
IO_READERR, strerror(err) );
|
||||
} else {
|
||||
sts = printmsg( IO_READLEN, MSG_CONTINUE, IO_READERR,
|
||||
block, (uint32_t)res, length );
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/************************************************************** phyio_write() */
|
||||
|
||||
static vmscond_t phyio_write( struct DEV *dev, uint32_t block,
|
||||
uint32_t length, const char *buffer ) {
|
||||
vmscond_t sts;
|
||||
off_t pos;
|
||||
ssize_t res;
|
||||
|
||||
#if DEBUG
|
||||
printf("Phyio write block: %d from %p (%d bytes)\n",
|
||||
block, buffer, length );
|
||||
#endif
|
||||
|
||||
write_count++;
|
||||
pos = (off_t) block * (off_t) 512;
|
||||
if( ( pos = lseek( dev->handle, pos, SEEK_SET ) ) < 0 ) {
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( IO_SEEKERR, block );
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE,
|
||||
IO_SEEKERR, strerror(err) );
|
||||
return sts;
|
||||
}
|
||||
if( ( res = write( dev->handle, buffer, length ) ) != (ssize_t)length ) {
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( IO_WRITEERR, 0, block );
|
||||
if( res == (off_t)-1 ) {
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE,
|
||||
IO_WRITEERR, strerror(err) );
|
||||
} else {
|
||||
sts = printmsg( IO_WRITELEN, MSG_CONTINUE, IO_WRITEERR,
|
||||
block, (uint32_t)res, length );
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_help() */
|
||||
|
||||
void phyio_help( void ) {
|
||||
char devpfx[] = { DEV_PREFIX };
|
||||
|
||||
devpfx[ sizeof( devpfx ) -2 ] = '\0'; /* Remove trailing '/' */
|
||||
|
||||
(void) helptopic( 0, "MOUNT UNIX", devpfx, DEV_PREFIX "cdrom0" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_show() */
|
||||
|
||||
void phyio_show( showtype_t type ) {
|
||||
switch( type ) {
|
||||
case SHOW_STATS:
|
||||
printmsg( IO_STATS, MSG_TEXT, init_count, read_count, write_count );
|
||||
return;
|
||||
case SHOW_FILE64:
|
||||
printmsg( (sizeof( off_t ) < 8)? IO_NOLARGEFILE: IO_LARGEFILE, MSG_TEXT );
|
||||
return;
|
||||
case SHOW_DEVICES:
|
||||
printmsg( IO_UNXDEVHDR, MSG_TEXT );
|
||||
showdevs();
|
||||
return;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************** showdevs() */
|
||||
static void showdevs( void ) {
|
||||
DIR *dirp;
|
||||
size_t i, cpl, n = 0, max = 0;
|
||||
@@ -106,14 +337,17 @@ static void showdevs( void ) {
|
||||
break;
|
||||
|
||||
len = strlen( dp->d_name );
|
||||
fs = malloc( sizeof( DEV_PREFIX ) + len );
|
||||
if( fs == NULL )
|
||||
if( (fs = malloc( sizeof( DEV_PREFIX ) + len )) == NULL )
|
||||
break;
|
||||
memcpy( fs, DEV_PREFIX, sizeof( DEV_PREFIX ) -1 );
|
||||
memcpy( fs + sizeof( DEV_PREFIX ) -1, dp->d_name, len +1 );
|
||||
|
||||
if( stat( fs, &stb ) == -1 ) {
|
||||
perror( fs );
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( IO_DIRRDERR, 0, fs );
|
||||
printmsg( ODS2_OSERROR, MSG_CONTINUE, IO_DIRRDERR, strerror( err ) );
|
||||
free( fs );
|
||||
continue;
|
||||
}
|
||||
@@ -154,8 +388,11 @@ static void showdevs( void ) {
|
||||
(void) closedir(dirp);
|
||||
}
|
||||
if( errno != 0 ) {
|
||||
printf( "%%ODS2-W-DIRERR, Error reading %s\n", DEV_PREFIX );
|
||||
perror( " - " );
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( IO_DIRRDERR, 0, DEV_PREFIX );
|
||||
printmsg( ODS2_OSERROR, MSG_CONTINUE, IO_DIRRDERR, strerror( err ) );
|
||||
for( i = 0; i < n; i++ )
|
||||
free( (*list)[i].name );
|
||||
free( list );
|
||||
@@ -163,7 +400,7 @@ static void showdevs( void ) {
|
||||
}
|
||||
|
||||
if( n == 0 ) {
|
||||
printf( "%%ODS2-I-NODEV, No devices found\n" );
|
||||
printmsg( IO_NODEVS, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -208,236 +445,8 @@ static void showdevs( void ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_show() */
|
||||
/*************************************************************** devcmp() */
|
||||
|
||||
void phyio_show( showtype_t type ) {
|
||||
switch( type ) {
|
||||
case SHOW_STATS:
|
||||
printf( "PHYIO_SHOW Initializations: %d Reads: %d Writes: %d\n",
|
||||
init_count, read_count, write_count );
|
||||
return;
|
||||
case SHOW_FILE64:
|
||||
printf( "Large ODS-2 image files (>2GB) are %ssupported.\n",
|
||||
(sizeof( off_t ) < 8)? "NOT ": "" );
|
||||
return;
|
||||
case SHOW_DEVICES:
|
||||
printf( " Physical devices\n" );
|
||||
showdevs();
|
||||
return;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void phyio_help(FILE *fp ) {
|
||||
fprintf( fp, " mount device\nThe device must be in %.*s.\n\n",
|
||||
(int)(sizeof( DEV_PREFIX ) -2), DEV_PREFIX );
|
||||
fprintf( fp, "For example, if you are using " DEV_PREFIX "%s\n", "cdrom0" );
|
||||
fprintf( fp, " ODS2$> mount cdrom0\n" );
|
||||
fprintf( fp, "For a list of devices, see SHOW DEVICES\n\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_path() */
|
||||
|
||||
char *phyio_path( const char *filnam ) {
|
||||
|
||||
size_t n;
|
||||
char *path, resolved_path[PATH_MAX+1];
|
||||
|
||||
if ( filnam == NULL || realpath( filnam, resolved_path ) == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
n = strlen( resolved_path );
|
||||
path = (char *) malloc( n + 1 );
|
||||
if ( path != NULL ) {
|
||||
memcpy( path, resolved_path, n + 1 );
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_init() */
|
||||
|
||||
unsigned phyio_init( struct DEV *dev ) {
|
||||
int sts = SS$_NORMAL;
|
||||
size_t n;
|
||||
int fd, saverr = 0;
|
||||
char *device;
|
||||
const char *virtual;
|
||||
struct stat statbuf;
|
||||
|
||||
init_count++;
|
||||
|
||||
dev->handle = -1;
|
||||
dev->devread = phyio_read;
|
||||
dev->devwrite = phyio_write;
|
||||
|
||||
if( dev->access & MOU_VIRTUAL ) {
|
||||
virtual = virt_lookup( dev->devnam );
|
||||
if ( virtual == NULL ) {
|
||||
return SS$_NOSUCHDEV;
|
||||
}
|
||||
n = strlen( virtual );
|
||||
device = (char *) malloc( n + 1 );
|
||||
if( device == NULL )
|
||||
return SS$_INSFMEM;
|
||||
|
||||
memcpy( device, virtual, n + 1 );
|
||||
} else {
|
||||
n = sizeof( DEV_PREFIX ) + strlen( dev->devnam );
|
||||
device = (char *) malloc( n );
|
||||
if ( device == NULL )
|
||||
return SS$_INSFMEM;
|
||||
|
||||
memcpy( device, DEV_PREFIX, sizeof( DEV_PREFIX ) -1 );
|
||||
memcpy( device+sizeof( DEV_PREFIX ) -1, dev->devnam, n +1 - sizeof( DEV_PREFIX ) );
|
||||
device[n - 2] = '\0'; /* Remove : from device name */
|
||||
}
|
||||
|
||||
fd = open( device,
|
||||
((dev->access & MOU_WRITE )? O_RDWR : O_RDONLY) |
|
||||
((dev->access & (MOU_VIRTUAL|PHY_CREATE)) == (MOU_VIRTUAL|PHY_CREATE)?
|
||||
O_CREAT | O_EXCL : 0),
|
||||
0644 );
|
||||
if( fd < 0 )
|
||||
saverr = errno;
|
||||
#if DEBUG
|
||||
printf( "%d = open( \"%s\", %s%s )\n", fd, device,
|
||||
(dev->access & MOU_WRITE )? "O_RDWR" : "O_RDONLY",
|
||||
(dev->access & PHY_CREATE)? "|O_CREAT|O_EXCL, 0666" : "" );
|
||||
#endif
|
||||
if ( fd < 0 && (dev->access & (MOU_WRITE|PHY_CREATE)) == MOU_WRITE ) {
|
||||
dev->access &= ~MOU_WRITE;
|
||||
fd = open( device, O_RDONLY );
|
||||
#if DEBUG
|
||||
printf( "%d = open( \"%s\", O_RDONLY )\n", fd, device );
|
||||
#endif
|
||||
}
|
||||
dev->handle = fd;
|
||||
|
||||
if( fd >= 0 ) {
|
||||
if( fstat( fd, &statbuf ) == 0 ) {
|
||||
if( dev->access & MOU_VIRTUAL ) {
|
||||
if( !S_ISREG(statbuf.st_mode) ) {
|
||||
printf( "%%ODS2-E-NOTFILE, %s is not a regular file\n", device );
|
||||
close( fd );
|
||||
dev->handle = -1;
|
||||
sts = SS$_IVDEVNAM;
|
||||
} else
|
||||
dev->eofptr = statbuf.st_size;
|
||||
} else {
|
||||
if( !S_ISBLK(statbuf.st_mode ) ) {
|
||||
printf( "%%ODS2-E-NOTFILE, %s is not a block device\n", device );
|
||||
close( fd );
|
||||
dev->handle = -1;
|
||||
sts = SS$_IVDEVNAM;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if( !saverr )
|
||||
saverr = errno;
|
||||
close( fd );
|
||||
dev->handle = -1;
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fd < 0 ) {
|
||||
#if DEBUG
|
||||
errno = saverr;
|
||||
perror( "open" );
|
||||
#endif
|
||||
|
||||
errno = saverr;
|
||||
switch( errno ) {
|
||||
case EEXIST:
|
||||
printf( "%%ODS2-E-EXISTS, File %s already exists, not superseded\n", device );
|
||||
sts = SS$_DUPFILENAME;
|
||||
break;
|
||||
default:
|
||||
printf( "%%ODS2-E-OPENERR, Open %s: %s\n", device, strerror( errno ) );
|
||||
sts = (dev->access & MOU_VIRTUAL) ? SS$_NOSUCHFILE : SS$_NOSUCHDEV;
|
||||
}
|
||||
}
|
||||
free( device );
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_done() */
|
||||
|
||||
unsigned phyio_done( struct DEV *dev ) {
|
||||
|
||||
if( dev->handle != -1 )
|
||||
close( dev->handle );
|
||||
dev->handle = -1;
|
||||
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_read() */
|
||||
|
||||
static unsigned phyio_read( struct DEV *dev, unsigned block, unsigned length,
|
||||
char *buffer ) {
|
||||
|
||||
ssize_t res;
|
||||
off_t pos;
|
||||
|
||||
#if DEBUG
|
||||
printf("Phyio read block: %d into %p (%d bytes)\n",
|
||||
block, buffer, length );
|
||||
#endif
|
||||
|
||||
read_count++;
|
||||
pos = (off_t) block * (off_t) 512;
|
||||
if ( ( pos = lseek( dev->handle, pos, SEEK_SET ) ) < 0 ) {
|
||||
perror( "lseek " );
|
||||
printf("lseek failed %" PRIuMAX "\n",(uintmax_t)pos);
|
||||
return SS$_PARITY;
|
||||
}
|
||||
if ( ( res = read( dev->handle, buffer, length ) ) != length ) {
|
||||
if( res == 0 ) {
|
||||
return SS$_ENDOFFILE;
|
||||
}
|
||||
if( res == (off_t)-1 ) {
|
||||
perror( "%%ODS2-F-READERR, read failed" );
|
||||
} else {
|
||||
printf( "%%ODS2-F-READERR, read failed with bc = %" PRIuMAX " for length %u, lbn %u\n",
|
||||
(uintmax_t)res, length, block );
|
||||
}
|
||||
return SS$_PARITY;
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/************************************************************** phyio_write() */
|
||||
|
||||
static unsigned phyio_write( struct DEV *dev, unsigned block, unsigned length,
|
||||
const char *buffer ) {
|
||||
|
||||
off_t pos;
|
||||
ssize_t res;
|
||||
|
||||
#if DEBUG
|
||||
printf("Phyio write block: %d from %p (%d bytes)\n",
|
||||
block, buffer, length );
|
||||
#endif
|
||||
|
||||
write_count++;
|
||||
pos = (off_t) block * (off_t) 512;
|
||||
if ( ( pos = lseek( dev->handle, pos, SEEK_SET ) ) < 0 ) {
|
||||
perror( "lseek " );
|
||||
printf( "lseek failed %" PRIuMAX "\n", (uintmax_t)pos );
|
||||
return SS$_PARITY;
|
||||
}
|
||||
if ( ( res = write( dev->handle, buffer, length ) ) != length ) {
|
||||
if( res == (off_t)-1 ) {
|
||||
perror( "%%ODS2-F-WRITEERR, write failed" );
|
||||
} else {
|
||||
printf( "%%ODS2-F-WRITEERR, write failed with bc = %" PRIuMAX " for length %u, lbn %u\n",
|
||||
(uintmax_t)res, length, block );
|
||||
}
|
||||
return SS$_PARITY;
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
static int devcmp( const void *d1, const void *d2 ) {
|
||||
return strcmp( ((struct devdat *)d1)->name, ((struct devdat *)d2)->name );
|
||||
}
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_PHYVHD )
|
||||
@@ -30,7 +33,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef phyvhd_MINSIZE
|
||||
#define phyvhd_MINSIZE (20 * 1000 * 1000)
|
||||
#define phyvhd_MINSIZE (0)
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
@@ -48,13 +51,16 @@
|
||||
#define _aligned_free free
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include "device.h"
|
||||
#include "ods2.h"
|
||||
#include "phyvirt.h"
|
||||
#include "ssdef.h"
|
||||
#include "stsdef.h"
|
||||
#include "sysmsg.h"
|
||||
|
||||
#include "libvhd.h"
|
||||
#include "phyvhd.h"
|
||||
|
||||
typedef vhd_context_t *vhd_contextp;
|
||||
typedef vhd_context_t vhd_context;
|
||||
@@ -98,12 +104,11 @@ static void *libvhd = NULL;
|
||||
#define vhdresolve(s) do { \
|
||||
if( libvhd != NULL && \
|
||||
(s ## _fcn = (s ## _p)dlsym( libvhd, #s )) == NULL ) { \
|
||||
printf( "VHD format image files can not be used\n" ); \
|
||||
printf( "%%ODS2-F-NOSYM, Missing symbol %s in " LIBVHDSO(USE_LIBVHD) "\n", #s ); \
|
||||
printmsg( IO_VHDNOSYM, 0, #s, LIBVHDSO(USE_LIBVHD) ); \
|
||||
dlclose( libvhd ); \
|
||||
libvhd = NULL; \
|
||||
} \
|
||||
} while( 0 )
|
||||
} while( 0 )
|
||||
#else
|
||||
|
||||
#define vhd_open_fcn vhd_open
|
||||
@@ -120,10 +125,10 @@ static void *libvhd = NULL;
|
||||
|
||||
#endif
|
||||
|
||||
static unsigned phyvhd_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
char *buffer );
|
||||
static unsigned phyvhd_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
const char *buffer );
|
||||
static vmscond_t phyvhd_read( struct DEV *dev, uint32_t lbn, uint32_t length,
|
||||
char *buffer );
|
||||
static vmscond_t phyvhd_write( struct DEV *dev, uint32_t lbn, uint32_t length,
|
||||
const char *buffer );
|
||||
|
||||
/*********************************************************** phyvhd_available() */
|
||||
int phyvhd_available( int query ) {
|
||||
@@ -136,13 +141,11 @@ int phyvhd_available( int query ) {
|
||||
const char *err;
|
||||
|
||||
if( query )
|
||||
printf( "VHD format image file support is configud, but not available\n" );
|
||||
printmsg( IO_VHDNOTAVAIL, MSG_TEXT );
|
||||
|
||||
printf( "%%ODS2-F-NOLIB, " LIBVHDSO(USE_LIBVHD) " not could not be loaded (see vhdtools or XEN libraries)" );
|
||||
printmsg( IO_VHDNOLIB, 0, LIBVHDSO(USE_LIBVHD) );
|
||||
if( (err = dlerror()) != NULL )
|
||||
printf( ": %s\n", err );
|
||||
else
|
||||
putchar( '\n' );
|
||||
printmsg( ODS2_OSERROR, MSG_CONTINUE, O_VHDNOLIB, err );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -157,14 +160,15 @@ int phyvhd_available( int query ) {
|
||||
vhdresolve( vhd_io_write );
|
||||
|
||||
if( libvhd == NULL ) {
|
||||
printf( "%%ODS2-F-BADLIB, the " LIBVHDSO(USE_LIBVHD) " library is not valid\n" );
|
||||
printmsg( IO_VHDNOTVALID, MSG_CONTINUE,
|
||||
IO_VHDNOSYM, LIBVHDSO(USE_LIBVHD) );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( query )
|
||||
printf( "VHD format image files can be used\n" );
|
||||
printmsg( IO_VHDAVAIL, MSG_TEXT );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -174,29 +178,35 @@ int phyvhd_available( int query ) {
|
||||
#pragma warning(disable: 4996) /* MS complains about _open, which is open() */
|
||||
#endif
|
||||
/*********************************************************** phyvhd_snapshot() */
|
||||
unsigned phyvhd_snapshot( const char *filename, const char *parent ) {
|
||||
vmscond_t phyvhd_snapshot( const char *filename, const char *parent ) {
|
||||
int fd, err;
|
||||
char *p;
|
||||
|
||||
if( !( (p = strrchr( filename, '.')) != NULL && ( !strcmp( p, ".vhd" ) ||
|
||||
!strcmp( p, ".VHD" ) ) ) ) {
|
||||
printf( "%%ODS2-E-NOTVHD, %s: Snapshots can only be taken of VHD format image files\n", filename );
|
||||
return SS$_DUPFILENAME;
|
||||
return printmsg( IO_VHDONLY, 0, filename );
|
||||
}
|
||||
|
||||
#ifdef USE_LIBVHD
|
||||
if( libvhd == NULL && !phyvhd_available( FALSE ) )
|
||||
return SS$_NOTINSTALL;
|
||||
return IO_VHDNOTVALID | STS$M_INHIB_MSG;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
fd = _open( filename, _O_RDWR | _O_CREAT | _O_EXCL, 0644 );
|
||||
fd = _open( filename, _O_BINARY | _O_RDWR | _O_CREAT | _O_EXCL, 0644 );
|
||||
#else
|
||||
fd = open( filename, O_RDWR | O_CREAT | O_EXCL, 0644 );
|
||||
#endif
|
||||
if( fd == -1 ) {
|
||||
printf( "%%ODS2-E-EXISTS, %s already exists\n", filename );
|
||||
return SS$_DUPFILENAME;
|
||||
int err;
|
||||
|
||||
if( errno == EEXIST ) {
|
||||
printmsg( IO_EXISTS, 0, filename );
|
||||
return SS$_DUPFILENAME | STS$M_INHIB_MSG;
|
||||
}
|
||||
err = errno;
|
||||
printmsg( IO_OPENDEV, 0, filename );
|
||||
return printmsg( ODS2_OSERROR, MSG_CONTINUE, IO_OPENDEV, strerror( err ) );
|
||||
}
|
||||
err = vhd_snapshot_fcn( filename, 0, parent, 0 );
|
||||
close( fd );
|
||||
@@ -204,14 +214,12 @@ unsigned phyvhd_snapshot( const char *filename, const char *parent ) {
|
||||
if( err == 0 )
|
||||
return SS$_NORMAL;
|
||||
|
||||
printf( "%%ODS2-E-NOSNAP, snapshot failed\n" );
|
||||
errno = -err;
|
||||
perror( " - " );
|
||||
return SS$_DEVOFFLINE;
|
||||
printmsg( IO_VHDSNAPFAIL, 0, parent );
|
||||
return printmsg( ODS2_OSERROR, MSG_CONTINUE, IO_VHDSNAPFAIL, strerror( -err ) );
|
||||
}
|
||||
|
||||
/*********************************************************** phyvhd_init() */
|
||||
unsigned phyvhd_init( struct DEV *dev ) {
|
||||
vmscond_t phyvhd_init( struct DEV *dev ) {
|
||||
int err;
|
||||
char *fname;
|
||||
unsigned status;
|
||||
@@ -229,7 +237,7 @@ unsigned phyvhd_init( struct DEV *dev ) {
|
||||
|
||||
#ifdef USE_LIBVHD
|
||||
if( libvhd == NULL && !phyvhd_available( FALSE ) )
|
||||
return SS$_NOTINSTALL;
|
||||
return IO_VHDNOTVALID | STS$M_INHIB_MSG;
|
||||
#endif
|
||||
libvhd_set_log_level_fcn( -1 );
|
||||
|
||||
@@ -242,27 +250,23 @@ unsigned phyvhd_init( struct DEV *dev ) {
|
||||
|
||||
#ifdef _WIN32
|
||||
if( (dev->IoBuffer = _aligned_malloc( phyvhd_BUFSIZE, align )) == NULL ) {
|
||||
printf( "Unable to allocate memory for bufer\n" );
|
||||
return SS$_INSFMEM;
|
||||
return printmsg( IO_VHDMEM, 0 );
|
||||
}
|
||||
|
||||
if( (dev->context = _aligned_malloc( sizeof( vhd_context ), align )) == NULL ) {
|
||||
printf( "Unable to allocate memory for context\n" );
|
||||
_aligned_free(dev->IoBuffer);
|
||||
dev->IoBuffer = NULL;
|
||||
return SS$_INSFMEM;
|
||||
return printmsg( IO_VHDMEM, 0 );
|
||||
}
|
||||
#else
|
||||
if( posix_memalign( (void**)&dev->IoBuffer, align, phyvhd_BUFSIZE ) != 0 ) {
|
||||
printf( "Unable to allocate memory for bufer\n" );
|
||||
return SS$_INSFMEM;
|
||||
return printmsg( IO_VHDMEM, 0 );
|
||||
}
|
||||
if( posix_memalign( (void**)&dev->context, align,
|
||||
sizeof( vhd_context ) ) != 0 ) {
|
||||
printf( "Unable to allocate memory for context\n" );
|
||||
free(dev->IoBuffer);
|
||||
dev->IoBuffer = NULL;
|
||||
return SS$_INSFMEM;
|
||||
return printmsg( IO_VHDMEM, 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -272,38 +276,41 @@ unsigned phyvhd_init( struct DEV *dev ) {
|
||||
if( dev->access & PHY_CREATE ) {
|
||||
disktypep_t dp;
|
||||
uint64_t size;
|
||||
int fd;
|
||||
int fd;
|
||||
|
||||
#ifdef _WIN32
|
||||
fd = _open( fname, _O_RDWR | _O_CREAT | _O_EXCL, 0644 );
|
||||
fd = _open( fname, _O_BINARY | _O_RDWR | _O_CREAT | _O_EXCL, 0644 );
|
||||
#else
|
||||
fd = open( fname, O_RDWR | O_CREAT | O_EXCL, 0644 );
|
||||
#endif
|
||||
if( fd == -1 ) {
|
||||
close( fd );
|
||||
status = SS$_DUPFILENAME;
|
||||
break;
|
||||
}
|
||||
if( dev->access & MOU_LOG )
|
||||
printf( "%%ODS2-I-VHDINIT, Formatting %s\n", fname );
|
||||
printmsg( IO_VHDFMTSTART, 0, fname );
|
||||
|
||||
dp = dev->disktype;
|
||||
size = ((uint64_t)dp->sectors) * dp->tracks * dp->cylinders * dp->sectorsize;
|
||||
size = (size + 511) / 512;
|
||||
size *= 512;
|
||||
|
||||
#if phyvhd_MINSIZE == 0
|
||||
err = vhd_create_fcn( fname, size, HD_TYPE_DYNAMIC, 0 );
|
||||
#else
|
||||
err = vhd_create_fcn( fname, size, (size >= phyvhd_MINSIZE?
|
||||
HD_TYPE_DYNAMIC: HD_TYPE_FIXED),
|
||||
0 );
|
||||
#endif
|
||||
close( fd );
|
||||
if( err != 0 ) {
|
||||
errno = -err;
|
||||
perror( "vhd create" );
|
||||
status = SS$_NOSUCHDEV;
|
||||
printmsg( IO_VHDCREATEERR, 0, fname );
|
||||
status = printmsg( ODS2_OSERROR, MSG_CONTINUE, IO_VHDCREATEERR,
|
||||
strerror( -err ) );
|
||||
break;
|
||||
}
|
||||
if( dev->access & MOU_LOG )
|
||||
printf( "%%ODS2-I-VHDDONE, VHD volume formatting completed\n" );
|
||||
printmsg( IO_VHDFMTEND, 0 );
|
||||
}
|
||||
err = vhd_open_fcn( dev->context, fname,
|
||||
(dev->access & MOU_WRITE)?
|
||||
@@ -314,18 +321,18 @@ unsigned phyvhd_init( struct DEV *dev ) {
|
||||
err = vhd_open_fcn( dev->context, fname, VHD_OPEN_RDONLY | VHD_OPEN_STRICT );
|
||||
}
|
||||
if( err != 0 ) {
|
||||
errno = -err;
|
||||
perror( "vhd open" );
|
||||
status = SS$_NOSUCHDEV;
|
||||
printmsg( IO_OPENDEV, 0, fname );
|
||||
status = printmsg( ODS2_OSERROR, MSG_CONTINUE, IO_OPENDEV,
|
||||
strerror( -err ) );
|
||||
break;
|
||||
}
|
||||
if( (dev->access & MOU_WRITE) && ((vhd_contextp)dev->context)->footer.saved ) {
|
||||
printf( "%%ODS2-W-VHDSAVED, %s contains a suspended system and should not be modified\n", fname );
|
||||
printmsg( IO_VHDSAVED, 0, fname );
|
||||
}
|
||||
dev->eofptr = (off_t)(((vhd_contextp)dev->context)->footer.curr_size);
|
||||
} while( 0 );
|
||||
|
||||
if( !(status & STS$M_SUCCESS) ) {
|
||||
if( $FAILED(status) ) {
|
||||
_aligned_free( dev->context );
|
||||
_aligned_free( dev->IoBuffer );
|
||||
dev->context =
|
||||
@@ -371,14 +378,14 @@ void phyvhd_show( struct DEV *dev, size_t column ) {
|
||||
return;
|
||||
}
|
||||
/*********************************************************** phyvhd_read() */
|
||||
static unsigned phyvhd_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
char *buffer ) {
|
||||
unsigned status;
|
||||
static vmscond_t phyvhd_read( struct DEV *dev, uint32_t lbn,
|
||||
uint32_t length, char *buffer ) {
|
||||
vmscond_t status;
|
||||
int err;
|
||||
|
||||
status = SS$_NORMAL;
|
||||
while( length > 0 ) {
|
||||
unsigned rdsize;
|
||||
uint32_t rdsize;
|
||||
|
||||
rdsize = (length + 511) / 512;
|
||||
rdsize = ( (rdsize > phyvhd_BUFSIZE/512)?
|
||||
@@ -386,8 +393,10 @@ static unsigned phyvhd_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
|
||||
if( (err = vhd_io_read_fcn(dev->context, dev->IoBuffer, lbn, rdsize)) != 0 ) {
|
||||
if( err == -ERANGE )
|
||||
return SS$_ILLBLKNUM;
|
||||
return SS$_PARITY;
|
||||
return printmsg( IO_RDBLK2BIG, 0, lbn );
|
||||
printmsg( IO_READERR, 0, lbn );
|
||||
return printmsg( ODS2_OSERROR, MSG_CONTINUE, IO_READERR,
|
||||
strerror( -err ) );
|
||||
}
|
||||
lbn += rdsize;
|
||||
rdsize *= 512;
|
||||
@@ -403,14 +412,14 @@ static unsigned phyvhd_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
|
||||
/*********************************************************** phyvhd_write() */
|
||||
|
||||
static unsigned phyvhd_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
const char *buffer ) {
|
||||
unsigned status;
|
||||
static vmscond_t phyvhd_write( struct DEV *dev, uint32_t lbn,
|
||||
uint32_t length, const char *buffer ) {
|
||||
vmscond_t status;
|
||||
int err;
|
||||
|
||||
status = SS$_NORMAL;
|
||||
while( length > 0 ) {
|
||||
unsigned wrsize, iosize;
|
||||
uint32_t wrsize, iosize;
|
||||
|
||||
iosize = (length + 511) / 512;
|
||||
iosize = ( (iosize > phyvhd_BUFSIZE/512)?
|
||||
@@ -425,8 +434,10 @@ static unsigned phyvhd_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
|
||||
if( (err = vhd_io_write_fcn(dev->context, dev->IoBuffer, lbn, iosize)) != 0 ) {
|
||||
if( err == -ERANGE )
|
||||
return SS$_ILLBLKNUM;
|
||||
return SS$_PARITY;
|
||||
return printmsg( IO_WRBLK2BIG, 0, lbn );
|
||||
printmsg( IO_WRITEERR, 0, lbn );
|
||||
return printmsg( ODS2_OSERROR, MSG_CONTINUE, IO_WRITEERR,
|
||||
strerror( -err ) );
|
||||
}
|
||||
lbn += iosize;
|
||||
}
|
||||
@@ -434,7 +445,7 @@ static unsigned phyvhd_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
}
|
||||
|
||||
/*********************************************************** phyvhd_close() */
|
||||
unsigned phyvhd_close( struct DEV *dev ) {
|
||||
vmscond_t phyvhd_close( struct DEV *dev ) {
|
||||
if( dev->context != NULL ) {
|
||||
vhd_close_fcn( dev->context );
|
||||
_aligned_free( dev->context );
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
/*
|
||||
* This is distributed as part of ODS2, originally 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _PHYVHD_H
|
||||
#define _PHYVHD_H 1
|
||||
|
||||
#include "ods2.h"
|
||||
|
||||
struct DEV;
|
||||
|
||||
unsigned phyvhd_snapshot( const char *filename, const char *parent );
|
||||
unsigned phyvhd_init( struct DEV *dev );
|
||||
unsigned phyvhd_close( struct DEV *dev );
|
||||
vmscond_t phyvhd_snapshot( const char *filename, const char *parent );
|
||||
vmscond_t phyvhd_init( struct DEV *dev );
|
||||
vmscond_t phyvhd_close( struct DEV *dev );
|
||||
void phyvhd_show( struct DEV *dev, size_t column );
|
||||
|
||||
int phyvhd_available( int query );
|
||||
|
||||
@@ -18,14 +18,17 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
/* A virtual device is used when normal file I/O is desired, e.g. to
|
||||
* a disk image (simulator, .iso).
|
||||
*
|
||||
* A virtual device is established on the command line by specifying
|
||||
* /virtual to the mount command.
|
||||
* /image to the mount or initialize command, or by defaulting.
|
||||
* If the device name is of the form dev:file, dev: becomes the
|
||||
* virtual device name. Otherwise, a suitable name is created.
|
||||
*
|
||||
@@ -34,7 +37,7 @@
|
||||
* device specific transformations, such as interleave and skew.
|
||||
*
|
||||
* It also provides an access layer for VHD format image files, on
|
||||
* platforms where libvhd is available.
|
||||
* platforms where libvhd is available.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_PHYVIRT )
|
||||
@@ -46,6 +49,7 @@
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -57,6 +61,7 @@
|
||||
#include "phyio.h"
|
||||
#include "phyvirt.h"
|
||||
#include "ssdef.h"
|
||||
#include "sysmsg.h"
|
||||
|
||||
static struct VDEV {
|
||||
struct VDEV *next;
|
||||
@@ -69,96 +74,66 @@ static struct VDEV {
|
||||
#include "phyvhd.h"
|
||||
#endif
|
||||
|
||||
static int virt_compare( unsigned keylen, const char *keynam,
|
||||
static int virt_compare( uint32_t keylen, const char *keynam,
|
||||
const char *devnam );
|
||||
static struct VDEV *virt_insert( const char *devnam, unsigned devsiz,
|
||||
static struct VDEV *virt_insert( const char *devnam, uint32_t devsiz,
|
||||
const char *path );
|
||||
static void virt_remove( const char *devnam, unsigned devsiz );
|
||||
|
||||
|
||||
unsigned virt_open( char **devname, unsigned flags, struct DEV **dev );
|
||||
static unsigned virt_makedev( char *devnam, char **vname );
|
||||
static void virt_remove( const char *devnam, uint32_t devsiz );
|
||||
static vmscond_t virt_makedev( char *devnam, char **vname );
|
||||
static char *autodev( void );
|
||||
static unsigned virt_assign( char *devnam, struct DEV *dev );
|
||||
unsigned virt_close( struct DEV *dev );
|
||||
|
||||
static unsigned maplbn( unsigned lbn, disktypep_t dp, unsigned sect );
|
||||
|
||||
unsigned virt_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
char *buffer ) ;
|
||||
unsigned virt_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
const char *buffer );
|
||||
unsigned virt_readp( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
char *buffer );
|
||||
unsigned virt_writep( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
char *buffer );
|
||||
static vmscond_t virt_assign( char *devnam, struct DEV *dev );
|
||||
static vmscond_t maplbn( uint32_t lbn, disktypep_t dp, uint32_t sect );
|
||||
static size_t get_devsiz( const char *devnam );
|
||||
|
||||
|
||||
/************************************************************* virt_show() */
|
||||
|
||||
void virt_show( const char *devnam ) {
|
||||
|
||||
unsigned devsiz;
|
||||
void virt_show( void ) {
|
||||
struct VDEV *vp;
|
||||
size_t maxd = sizeof( "Device" ) -1,
|
||||
maxp = sizeof( "File" ) -1,
|
||||
n;
|
||||
|
||||
if( devnam == NULL ) {
|
||||
size_t maxd = sizeof( "Device" ) -1,
|
||||
maxp = sizeof( "File" ) -1,
|
||||
n;
|
||||
|
||||
if( virt_device_list == NULL ) {
|
||||
printf( " No virtual devices are assigned\n" );
|
||||
return;
|
||||
}
|
||||
for( vp = virt_device_list; vp != NULL; vp = vp->next ) {
|
||||
n = strlen( vp->devnam );
|
||||
if( n > maxd )
|
||||
maxd = n;
|
||||
n = strlen( vp->path );
|
||||
if( n > maxp )
|
||||
maxp =n;
|
||||
}
|
||||
if( maxp > 64 )
|
||||
maxp = 64;
|
||||
|
||||
printf( " Virtual devices\n" );
|
||||
printf( " %-*s %s\n ", (int)maxd, "Device", "File" );
|
||||
for( n = 0; n < maxd; n++ ) putchar( '-' );
|
||||
putchar( ' ');
|
||||
for( n = 0; n < maxp; n++ ) putchar( '-' );
|
||||
putchar( '\n' );
|
||||
|
||||
for( vp = virt_device_list; vp != NULL; vp = vp->next ) {
|
||||
n = strlen( vp->path );
|
||||
printf( " %-*s %-*.*s", (int)maxd, vp->devnam, (int)maxp,
|
||||
(int)maxp, (n > maxp)? vp->path+(n-maxp): vp->path );
|
||||
#ifdef USE_VHD
|
||||
if( vp->dev->access & PHY_VHDDSK )
|
||||
phyvhd_show( vp->dev, 2 + maxd + 1 + maxp + 1 );
|
||||
#endif
|
||||
putchar( '\n' );
|
||||
}
|
||||
} else {
|
||||
devsiz = get_devsiz( devnam );
|
||||
|
||||
if( devsiz == 0 ) {
|
||||
return;
|
||||
}
|
||||
for( vp = virt_device_list; vp != NULL; vp = vp->next ) {
|
||||
if( virt_compare( devsiz, (char *) devnam, vp->devnam ) == 0 ) {
|
||||
printf( " %s => %s\n", vp->devnam, vp->path );
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( virt_device_list == NULL ) {
|
||||
printmsg( IO_VNODEVS, MSG_TEXT );
|
||||
return;
|
||||
}
|
||||
for( vp = virt_device_list; vp != NULL; vp = vp->next ) {
|
||||
n = strlen( vp->devnam );
|
||||
if( n > maxd )
|
||||
maxd = n;
|
||||
n = strlen( vp->path );
|
||||
if( n > maxp )
|
||||
maxp =n;
|
||||
}
|
||||
if( maxp > 64 )
|
||||
maxp = 64;
|
||||
|
||||
printmsg( IO_VDEVHEADER, MSG_TEXT );
|
||||
printf( " %-*s %s\n ", (int)maxd, "Device", "File" );
|
||||
for( n = 0; n < maxd; n++ ) putchar( '-' );
|
||||
putchar( ' ');
|
||||
for( n = 0; n < maxp; n++ ) putchar( '-' );
|
||||
putchar( '\n' );
|
||||
|
||||
for( vp = virt_device_list; vp != NULL; vp = vp->next ) {
|
||||
n = strlen( vp->path );
|
||||
printf( " %-*s %-*.*s", (int)maxd, vp->devnam, (int)maxp,
|
||||
(int)maxp, (n > maxp)? vp->path+(n-maxp): vp->path );
|
||||
#ifdef USE_VHD
|
||||
if( vp->dev->access & PHY_VHDDSK )
|
||||
phyvhd_show( vp->dev, 2 + maxd + 1 + maxp + 1 );
|
||||
#endif
|
||||
putchar( '\n' );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/********************************************************** virt_compare() */
|
||||
|
||||
static int virt_compare( unsigned keylen, const char *keynam,
|
||||
const char *devnam ) {
|
||||
|
||||
static int virt_compare( uint32_t keylen, const char *keynam,
|
||||
const char *devnam ) {
|
||||
register int cmp;
|
||||
|
||||
cmp = 0;
|
||||
@@ -179,11 +154,10 @@ static int virt_compare( unsigned keylen, const char *keynam,
|
||||
/* virt_lookup() finds virtual devices... */
|
||||
|
||||
char *virt_lookup( const char *devnam ) {
|
||||
|
||||
unsigned devsiz;
|
||||
uint32_t devsiz;
|
||||
struct VDEV *vp;
|
||||
|
||||
devsiz = get_devsiz( devnam );
|
||||
devsiz = (uint32_t)get_devsiz( devnam );
|
||||
if( devsiz == 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -197,9 +171,9 @@ char *virt_lookup( const char *devnam ) {
|
||||
|
||||
/*********************************************************** virt_insert() */
|
||||
|
||||
static struct VDEV *virt_insert( const char *devnam, unsigned devsiz,
|
||||
static struct VDEV *virt_insert( const char *devnam, uint32_t devsiz,
|
||||
const char *path ) {
|
||||
unsigned pathsiz;
|
||||
size_t pathsiz;
|
||||
struct VDEV *vp, **vpp, **here;
|
||||
|
||||
here = NULL;
|
||||
@@ -215,7 +189,8 @@ static struct VDEV *virt_insert( const char *devnam, unsigned devsiz,
|
||||
if( vp == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
vp->devnam = (char *) malloc( devsiz + 1 );
|
||||
vp->devnam = (char *) malloc( (size_t)devsiz + 1 );
|
||||
|
||||
vp->path = (char *) malloc( (pathsiz = strlen( path )) + 1 );
|
||||
|
||||
if( vp->devnam == NULL || vp->path == NULL ) {
|
||||
@@ -236,7 +211,7 @@ static struct VDEV *virt_insert( const char *devnam, unsigned devsiz,
|
||||
|
||||
/*********************************************************** virt_remove() */
|
||||
|
||||
static void virt_remove( const char *devnam, unsigned devsiz ) {
|
||||
static void virt_remove( const char *devnam, uint32_t devsiz ) {
|
||||
|
||||
struct VDEV *vp, **vpp;
|
||||
|
||||
@@ -257,8 +232,8 @@ static void virt_remove( const char *devnam, unsigned devsiz ) {
|
||||
* devices. Calls phyio_init with everything straightend out.
|
||||
*/
|
||||
|
||||
unsigned virt_open( char **devname, unsigned flags, struct DEV **dev ) {
|
||||
unsigned sts;
|
||||
vmscond_t virt_open( char **devname, uint32_t flags, struct DEV **dev ) {
|
||||
vmscond_t sts;
|
||||
|
||||
flags &= ~PHY_VHDDSK;
|
||||
|
||||
@@ -269,28 +244,22 @@ unsigned virt_open( char **devname, unsigned flags, struct DEV **dev ) {
|
||||
#ifdef USE_VHD
|
||||
flags |= PHY_VHDDSK;
|
||||
#else
|
||||
printf( "%%ODS2-W-NOVHD, VHD disk support is not available in this version\n" );
|
||||
return SS$_IVDEVNAM;
|
||||
return printmsg( IO_NOVHD, 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
sts = virt_makedev( *devname, devname );
|
||||
if( !(sts & STS$M_SUCCESS) )
|
||||
if( $FAILS( sts = virt_makedev( *devname, devname )) )
|
||||
return sts;
|
||||
} else {
|
||||
if( virt_lookup( *devname ) != NULL ) {
|
||||
int devsiz;
|
||||
|
||||
devsiz = get_devsiz( *devname );
|
||||
printf( "%%ODS2-E-VIRTDEV, %.*s is a virtual device\n",
|
||||
(int)devsiz, *devname );
|
||||
return SS$_DEVMOUNT;
|
||||
devsiz = (int)get_devsiz( *devname );
|
||||
return printmsg( IO_ISVIRTDEV, 0, devsiz, *devname );
|
||||
}
|
||||
}
|
||||
sts = device_lookup( strlen( *devname ), *devname, TRUE, dev );
|
||||
if( !(sts & STS$M_SUCCESS) ) {
|
||||
if( $FAILS(sts = device_lookup( strlen( *devname ), *devname, TRUE, dev )) ) {
|
||||
if( flags & MOU_VIRTUAL )
|
||||
virt_remove( *devname, get_devsiz( *devname ) );
|
||||
virt_remove( *devname, (uint32_t)get_devsiz( *devname ) );
|
||||
return sts;
|
||||
}
|
||||
(*dev)->access = flags; /* Requested mount options */
|
||||
@@ -301,15 +270,16 @@ unsigned virt_open( char **devname, unsigned flags, struct DEV **dev ) {
|
||||
#ifdef USE_VHD
|
||||
sts = phyvhd_init( *dev );
|
||||
#else
|
||||
return SS$_IVDEVNAM;
|
||||
device_done( *dev );
|
||||
return printmsg( IO_NOVHD, 0 );
|
||||
#endif
|
||||
} else {
|
||||
sts = phyio_init( *dev );
|
||||
}
|
||||
|
||||
if( (flags & MOU_VIRTUAL) ) {
|
||||
if( sts & STS$M_SUCCESS ) {
|
||||
if( !((sts = virt_assign( *devname, *dev )) & STS$M_SUCCESS) ) {
|
||||
if( $SUCCESSFUL(sts) ) {
|
||||
if( $FAILS(sts = virt_assign( *devname, *dev )) ) {
|
||||
#ifdef USE_VHD
|
||||
if( flags & PHY_VHDDSK )
|
||||
phyvhd_close( *dev );
|
||||
@@ -318,8 +288,10 @@ unsigned virt_open( char **devname, unsigned flags, struct DEV **dev ) {
|
||||
phyio_done( *dev );
|
||||
device_done( *dev );
|
||||
}
|
||||
} else
|
||||
virt_remove( *devname, get_devsiz( *devname ) );
|
||||
} else {
|
||||
virt_remove( *devname, (uint32_t)get_devsiz( *devname ) );
|
||||
device_done( *dev );
|
||||
}
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
@@ -332,9 +304,9 @@ unsigned virt_open( char **devname, unsigned flags, struct DEV **dev ) {
|
||||
* file might not exist yet. (initialize)
|
||||
*/
|
||||
|
||||
static unsigned virt_makedev( char *devnam, char **vname ) {
|
||||
static vmscond_t virt_makedev( char *devnam, char **vname ) {
|
||||
struct VDEV *vp;
|
||||
unsigned devsiz;
|
||||
uint32_t devsiz;
|
||||
char *path = NULL;
|
||||
char *p;
|
||||
|
||||
@@ -342,15 +314,14 @@ static unsigned virt_makedev( char *devnam, char **vname ) {
|
||||
*p = '\0';
|
||||
path = ++p;
|
||||
if( (p = virt_lookup( devnam)) != NULL ) {
|
||||
printf( "%%ODS2-E-INUSE, %s is in use by %s\n", devnam, p );
|
||||
return SS$_DEVALLOC;
|
||||
return printmsg( IO_VIRTDEVINUSE, 0, devnam, p );
|
||||
}
|
||||
} else {
|
||||
path = devnam;
|
||||
devnam = autodev();
|
||||
}
|
||||
|
||||
devsiz = get_devsiz( devnam );
|
||||
devsiz = (uint32_t)get_devsiz( devnam );
|
||||
if( devsiz == 0 ) {
|
||||
return SS$_BADPARAM;
|
||||
}
|
||||
@@ -414,6 +385,7 @@ char *autodev( void ) {
|
||||
int i = 0;
|
||||
char t[ sizeof(devnam) ];
|
||||
|
||||
memset( t, 0, sizeof(t) );
|
||||
n = d;
|
||||
do {
|
||||
ldiv_t r;
|
||||
@@ -440,12 +412,13 @@ char *autodev( void ) {
|
||||
* virt_open will close the physical device if we have problems.
|
||||
*/
|
||||
|
||||
static unsigned virt_assign( char *devnam, struct DEV *dev ) {
|
||||
unsigned devsiz;
|
||||
static vmscond_t virt_assign( char *devnam, struct DEV *dev ) {
|
||||
vmscond_t sts;
|
||||
uint32_t devsiz;
|
||||
char *p;
|
||||
struct VDEV *vp, **vpp;
|
||||
|
||||
devsiz = get_devsiz( devnam );
|
||||
devsiz = (uint32_t)get_devsiz( devnam );
|
||||
if( devsiz == 0 ) {
|
||||
return SS$_BADPARAM;
|
||||
}
|
||||
@@ -457,19 +430,19 @@ static unsigned virt_assign( char *devnam, struct DEV *dev ) {
|
||||
if( vp == NULL )
|
||||
return SS$_BADPARAM;
|
||||
|
||||
if( (p = phyio_path( vp->path )) == NULL || strlen( p ) == 0 ) {
|
||||
printf( "%%ODS2-E-BADPATH, Invalid path: %s\n", vp->path );
|
||||
if( (p = get_realpath( vp->path )) == NULL || strlen( p ) == 0 ) {
|
||||
sts = printmsg( IO_BADPATH, 0, vp->path );
|
||||
free( p );
|
||||
virt_remove( devnam, devsiz );
|
||||
return SS$_BADPARAM;
|
||||
return sts;
|
||||
}
|
||||
|
||||
for( vpp = &virt_device_list; *vpp != NULL; vpp = &(*vpp)->next ) {
|
||||
if( (*vpp != vp) && strcmp( (*vpp)->path, p ) == 0 ) {
|
||||
printf( "%%ODS2-E-MAPPED, %s is in use on virtual drive %s\n", p, (*vpp)->devnam );
|
||||
sts = printmsg( IO_VIRTFILEINUSE, 0, p, (*vpp)->devnam );
|
||||
free( p );
|
||||
virt_remove( devnam, devsiz );
|
||||
return SS$_DEVALLOC;
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,14 +459,14 @@ static unsigned virt_assign( char *devnam, struct DEV *dev ) {
|
||||
* Wraps phyio_done;
|
||||
*/
|
||||
|
||||
unsigned virt_close( struct DEV *dev ) {
|
||||
unsigned devsiz;
|
||||
unsigned sts;
|
||||
vmscond_t virt_close( struct DEV *dev ) {
|
||||
uint32_t devsiz;
|
||||
vmscond_t sts;
|
||||
|
||||
cache_flush();
|
||||
|
||||
if( dev->access & MOU_VIRTUAL ) {
|
||||
devsiz = get_devsiz( dev->devnam );
|
||||
devsiz = (uint32_t)get_devsiz( dev->devnam );
|
||||
virt_remove( dev->devnam, devsiz );
|
||||
}
|
||||
#ifdef USE_VHD
|
||||
@@ -510,8 +483,8 @@ unsigned virt_close( struct DEV *dev ) {
|
||||
/* Map an LBN as viewed by the OS to each of its physical sectors.
|
||||
*/
|
||||
|
||||
static unsigned maplbn( unsigned lbn, disktypep_t dp, unsigned sect ) {
|
||||
unsigned c, t, s;
|
||||
static vmscond_t maplbn( uint32_t lbn, disktypep_t dp, uint32_t sect ) {
|
||||
uint32_t c, t, s;
|
||||
ldiv_t r;
|
||||
|
||||
lbn = (lbn * (512 / dp->sectorsize)) + sect;
|
||||
@@ -534,14 +507,15 @@ static unsigned maplbn( unsigned lbn, disktypep_t dp, unsigned sect ) {
|
||||
|
||||
/*********************************************************** virt_read() */
|
||||
|
||||
unsigned virt_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
vmscond_t virt_read( struct DEV *dev, uint32_t lbn, uint32_t length,
|
||||
char *buffer ) {
|
||||
disktypep_t dp;
|
||||
char *lbnbuf = NULL;
|
||||
unsigned status, secblk;
|
||||
vmscond_t status;
|
||||
uint32_t secblk;
|
||||
off_t devlimit, end, eofptr;
|
||||
#ifdef DEBUG_DISKIO
|
||||
unsigned inlbn = lbn, inlen = length;
|
||||
uint32_t inlbn = lbn, inlen = length;
|
||||
char *inbuf = buffer;
|
||||
#endif
|
||||
|
||||
@@ -577,21 +551,19 @@ unsigned virt_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
if( dp->reserved == 0 && dp->interleave == 0 && dp->skew == 0 ) {
|
||||
if( (dev->access & MOU_VIRTUAL) &&
|
||||
(end = ((off_t)lbn * 512 + length)) > eofptr ) {
|
||||
unsigned avail;
|
||||
uint32_t avail;
|
||||
off_t start;
|
||||
|
||||
if( end > devlimit ) {
|
||||
printf( "%%ODS2-E-BLK2BIG, Read from non-existent block %lu\n",
|
||||
((end + dp->sectorsize -1)/dp->sectorsize) );
|
||||
return SS$_ILLBLKNUM;
|
||||
return printmsg( IO_RDBLK2BIG, 0,
|
||||
((end + dp->sectorsize -1)/dp->sectorsize) );
|
||||
}
|
||||
start = (off_t)lbn * 512;
|
||||
|
||||
if( start < eofptr ) {
|
||||
avail = (unsigned)( eofptr - start );
|
||||
avail = (uint32_t)( eofptr - start );
|
||||
|
||||
status = dev->devread( dev, lbn, avail, buffer );
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILS(status = dev->devread( dev, lbn, avail, buffer )) )
|
||||
return status;
|
||||
|
||||
length -= avail;
|
||||
@@ -617,15 +589,15 @@ unsigned virt_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
abort(); /* TODO *** Handle large sectors, e.g. CDROM 2K where multiple LBNs fit into one. */
|
||||
|
||||
secblk = 512 / dp->sectorsize;
|
||||
if( (lbnbuf = malloc( 512 * 2 )) == NULL )
|
||||
if( (lbnbuf = malloc( (size_t)512 * 2 )) == NULL )
|
||||
return SS$_INSFMEM;
|
||||
|
||||
while( length > 0 && (status & STS$M_SUCCESS) ) {
|
||||
unsigned pbn;
|
||||
unsigned s;
|
||||
while( length > 0 && $SUCCESSFUL(status) ) {
|
||||
uint32_t pbn;
|
||||
uint32_t s;
|
||||
|
||||
for( s = 0; s < secblk && length > 0; s++ ) {
|
||||
unsigned n;
|
||||
uint32_t n;
|
||||
ldiv_t r;
|
||||
|
||||
pbn = maplbn( lbn, dp, s );
|
||||
@@ -636,32 +608,29 @@ unsigned virt_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
|
||||
if( (dev->access & MOU_VIRTUAL) &&
|
||||
(end = ((off_t)r.quot * 512 + n)) > eofptr ) {
|
||||
unsigned avail;
|
||||
uint32_t avail;
|
||||
off_t start;
|
||||
|
||||
if( ((off_t)pbn * (long)dp->sectorsize) + (long)n - r.rem > devlimit ) {
|
||||
printf( "%%ODS2-E-BLK2BIG, Read from non-existent block %lu\n",
|
||||
status = printmsg( IO_RDBLK2BIG, 0,
|
||||
(((pbn * dp->sectorsize + n) + dp->sectorsize -1) /
|
||||
dp->sectorsize) -1 );
|
||||
status = SS$_ILLBLKNUM;
|
||||
break;
|
||||
}
|
||||
|
||||
start = (off_t)r.quot * 512;
|
||||
|
||||
if( start < eofptr ) {
|
||||
avail = (unsigned)( eofptr - start );
|
||||
avail = (uint32_t)( eofptr - start );
|
||||
|
||||
status = dev->devread( dev, r.quot, avail, lbnbuf );
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILS(status = dev->devread( dev, r.quot, avail, lbnbuf )) )
|
||||
return status;
|
||||
|
||||
memset( lbnbuf+avail, 0, n - avail );
|
||||
memset( lbnbuf+avail, 0, (size_t)n - avail );
|
||||
} else
|
||||
memset( lbnbuf, 0, n );
|
||||
} else {
|
||||
status = dev->devread( dev, r.quot, n, lbnbuf );
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILS(status = dev->devread( dev, r.quot, n, lbnbuf )) )
|
||||
break;
|
||||
}
|
||||
n = (dp->sectorsize > length)? length: dp->sectorsize;
|
||||
@@ -680,14 +649,15 @@ unsigned virt_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
|
||||
/*********************************************************** virt_write() */
|
||||
|
||||
unsigned virt_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
vmscond_t virt_write( struct DEV *dev, uint32_t lbn, uint32_t length,
|
||||
const char *buffer ) {
|
||||
disktypep_t dp;
|
||||
char *lbnbuf = NULL;
|
||||
unsigned status, secblk;
|
||||
vmscond_t status;
|
||||
uint32_t secblk;
|
||||
off_t devlimit, start, end;
|
||||
#ifdef DEBUG_DISKIO
|
||||
unsigned inlbn = lbn, inlen = length;
|
||||
uint32_t inlbn = lbn, inlen = length;
|
||||
const char *inbuf = buffer;
|
||||
#endif
|
||||
|
||||
@@ -701,18 +671,16 @@ unsigned virt_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
|
||||
if( dp->reserved == 0 && dp->interleave == 0 && dp->skew == 0 ) {
|
||||
if( (end + 511)/512 > devlimit ) {
|
||||
printf( "%%ODS2-E-BLK2BIG, Write to non-existent block %lu\n",
|
||||
((end + dp->sectorsize -1)/dp->sectorsize) );
|
||||
return SS$_ILLBLKNUM;
|
||||
return printmsg( IO_WRBLK2BIG, 0,
|
||||
((end + dp->sectorsize -1)/dp->sectorsize) );
|
||||
}
|
||||
status = dev->devwrite( dev, lbn, length, buffer );
|
||||
#ifdef DEBUG_DISKIO
|
||||
dumpblock( inlbn, inlen, inbuf, "Virt Write, status %08X", status );
|
||||
#endif
|
||||
if( (status & STS$M_SUCCESS) && (dev->access & MOU_VIRTUAL) ) {
|
||||
if( end > dev->eofptr ) {
|
||||
dev->eofptr = end;
|
||||
}
|
||||
if( $SUCCESSFUL(status) &&
|
||||
(dev->access & MOU_VIRTUAL) && (end > dev->eofptr) ) {
|
||||
dev->eofptr = end;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -723,15 +691,15 @@ unsigned virt_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
abort(); /* TODO *** Handle large sectors, e.g. CDROM 2K where multiple LBNs fit into one. */
|
||||
|
||||
secblk = 512 / dp->sectorsize;
|
||||
if( (lbnbuf = malloc( 512 * 2 )) == NULL )
|
||||
if( (lbnbuf = malloc( (size_t)512 * 2 )) == NULL )
|
||||
return SS$_INSFMEM;
|
||||
|
||||
while( length > 0 && (status & STS$M_SUCCESS) ) {
|
||||
unsigned pbn;
|
||||
unsigned s;
|
||||
while( length > 0 && $SUCCESSFUL(status) ) {
|
||||
uint32_t pbn;
|
||||
uint32_t s;
|
||||
|
||||
for( s = 0; s < secblk && length > 0; s++ ) {
|
||||
unsigned n, m;
|
||||
uint32_t n, m;
|
||||
ldiv_t r;
|
||||
|
||||
pbn = maplbn( lbn, dp, s );
|
||||
@@ -743,26 +711,24 @@ unsigned virt_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
start = (off_t)r.quot * 512;
|
||||
m = ((n + 511) / 512) * 512;
|
||||
if( start < dev->eofptr && (off_t)(start + m) > dev->eofptr )
|
||||
m = (unsigned)(dev->eofptr - start);
|
||||
m = (uint32_t)(dev->eofptr - start);
|
||||
|
||||
if( dev->access & MOU_VIRTUAL ) {
|
||||
if( ((off_t)pbn * (long)dp->sectorsize) + ((long)n - r.rem) > devlimit ) {
|
||||
printf( "%%ODS2-E-BLK2BIG, Write to non-existent block %lu\n",
|
||||
(((pbn * dp->sectorsize) + (n - r.rem) +
|
||||
dp->sectorsize -1) / dp->sectorsize ) -1 );
|
||||
status = SS$_ILLBLKNUM;
|
||||
status = printmsg( IO_WRBLK2BIG, 0,
|
||||
(((pbn * dp->sectorsize) + (n - r.rem) +
|
||||
dp->sectorsize -1) / dp->sectorsize ) -1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
memset( lbnbuf, 0, 512 * 2 );
|
||||
memset( lbnbuf, 0, (size_t)512 * 2 );
|
||||
if( start < dev->eofptr ) {
|
||||
status = dev->devread( dev, r.quot, m, lbnbuf );
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILS(status = dev->devread( dev, r.quot, m, lbnbuf )) )
|
||||
break;
|
||||
if( m < n )
|
||||
memset( lbnbuf+m, 0, n - m );
|
||||
memset( lbnbuf+m, 0, (size_t)n - m );
|
||||
}
|
||||
memcpy( lbnbuf+r.rem, buffer, n - r.rem );
|
||||
memcpy( lbnbuf+r.rem, buffer, (size_t)n - r.rem );
|
||||
end = start + n;
|
||||
if( end > dev->eofptr ) {
|
||||
status = dev->devwrite( dev, r.quot, n, lbnbuf );
|
||||
@@ -770,7 +736,7 @@ unsigned virt_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
} else
|
||||
status = dev->devwrite( dev, r.quot, m, lbnbuf );
|
||||
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILED(status) )
|
||||
break;
|
||||
n -= r.rem;
|
||||
buffer += n;
|
||||
@@ -788,14 +754,14 @@ unsigned virt_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
|
||||
/*********************************************************** virt_readp() */
|
||||
|
||||
unsigned virt_readp( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
vmscond_t virt_readp( struct DEV *dev, uint32_t pbn, uint32_t length,
|
||||
char *buffer ) {
|
||||
disktypep_t dp;
|
||||
unsigned status;
|
||||
vmscond_t status;
|
||||
off_t devlimit, eofptr;
|
||||
off_t fp, offset;
|
||||
char *buf;
|
||||
unsigned avail;
|
||||
uint32_t avail;
|
||||
|
||||
dp = dev->disktype;
|
||||
|
||||
@@ -807,9 +773,8 @@ unsigned virt_readp( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
fp = ((off_t)pbn) * dp->sectorsize;
|
||||
|
||||
if( fp + (off_t)length > devlimit ) {
|
||||
printf( "%%ODS2-E-BLK2BIG, Read from non-existent block %lu\n",
|
||||
return printmsg( IO_RDBLK2BIG, 0,
|
||||
((fp + length + dp->sectorsize -1)/dp->sectorsize) );
|
||||
return SS$_ILLBLKNUM;
|
||||
}
|
||||
|
||||
if( dev->access & MOU_VIRTUAL ) {
|
||||
@@ -829,13 +794,12 @@ unsigned virt_readp( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
|
||||
offset = fp % 512;
|
||||
|
||||
avail = (unsigned)(eofptr - fp);
|
||||
avail = (uint32_t)(eofptr - fp);
|
||||
if( avail > length )
|
||||
avail = length;
|
||||
|
||||
if( offset == 0 ) {
|
||||
status = dev->devread( dev, (unsigned) (fp / 512), avail, buffer );
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILS(status = dev->devread( dev, (uint32_t) (fp / 512), avail, buffer )) )
|
||||
return status;
|
||||
|
||||
length -= avail;
|
||||
@@ -849,9 +813,10 @@ unsigned virt_readp( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
if( (buf = malloc( (size_t) (offset + avail) )) == NULL )
|
||||
if( (buf = malloc( ((size_t)offset + avail) )) == NULL )
|
||||
return SS$_INSFMEM;
|
||||
status = dev->devread( dev, (unsigned) (fp / 512), (unsigned) (offset + avail), buf );
|
||||
status = dev->devread( dev, (uint32_t) (fp / 512),
|
||||
(uint32_t) (offset + avail), buf );
|
||||
|
||||
memcpy( buffer, buf+offset, avail );
|
||||
free( buf );
|
||||
@@ -868,16 +833,16 @@ unsigned virt_readp( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
|
||||
/*********************************************************** virt_writep() */
|
||||
|
||||
unsigned virt_writep( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
vmscond_t virt_writep( struct DEV *dev, uint32_t pbn, uint32_t length,
|
||||
char *buffer ) {
|
||||
disktypep_t dp;
|
||||
unsigned status;
|
||||
vmscond_t status;
|
||||
off_t devlimit;
|
||||
off_t fp, offset;
|
||||
char *buf = NULL;
|
||||
unsigned avail, n, m;
|
||||
uint32_t avail, n, m;
|
||||
#ifdef DEBUG_DISKIO
|
||||
unsigned inpbn = pbn, inlen = length;
|
||||
uint32_t inpbn = pbn, inlen = length;
|
||||
const char *inbuf = buffer;
|
||||
#endif
|
||||
|
||||
@@ -891,15 +856,14 @@ unsigned virt_writep( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
fp = ((off_t)pbn) * dp->sectorsize;
|
||||
|
||||
if( fp + (off_t)length > devlimit ) {
|
||||
printf( "%%ODS2-E-BLK2BIG, Write to non-existent block %lu\n",
|
||||
return printmsg( IO_WRBLK2BIG, 0,
|
||||
((fp + length + dp->sectorsize -1)/dp->sectorsize) );
|
||||
return SS$_ILLBLKNUM;
|
||||
}
|
||||
|
||||
offset = fp % 512;
|
||||
|
||||
if( offset == 0 && length % 512 == 0 ) {
|
||||
status = dev->devwrite( dev, (unsigned)(fp / 512), length, buffer );
|
||||
status = dev->devwrite( dev, (uint32_t)(fp / 512), length, buffer );
|
||||
#ifdef DEBUG_DISKIO
|
||||
dumpblock( inpbn, inlen, inbuf, "Phys Write, status %08X", status );
|
||||
#endif
|
||||
@@ -916,12 +880,11 @@ unsigned virt_writep( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
|
||||
do {
|
||||
if( offset != 0 ) {
|
||||
avail = (unsigned) ( devlimit - (fp -offset) );
|
||||
avail = (uint32_t) ( devlimit - (fp -offset) );
|
||||
|
||||
n = (avail > 512)? 512: avail;
|
||||
|
||||
status = dev->devread( dev, (unsigned) (fp / 512), n, buf );
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILS(status = dev->devread( dev, (uint32_t) (fp / 512), n, buf )) )
|
||||
break;
|
||||
|
||||
m = (n > length)? length: n;
|
||||
@@ -930,16 +893,14 @@ unsigned virt_writep( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
buffer += m;
|
||||
length -= m;
|
||||
|
||||
status = dev->devwrite( dev, (unsigned) (fp / 512), n, buf );
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILS(status = dev->devwrite( dev, (uint32_t) (fp / 512), n, buf )) )
|
||||
break;
|
||||
fp += n;
|
||||
}
|
||||
|
||||
if( (n = length / 512) > 0 ) {
|
||||
n *= 512;
|
||||
status = dev->devwrite( dev, (unsigned) (fp / 512), n, buffer );
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILS(status = dev->devwrite( dev, (uint32_t) (fp / 512), n, buffer )) )
|
||||
break;
|
||||
|
||||
buffer += n;
|
||||
@@ -948,12 +909,11 @@ unsigned virt_writep( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
}
|
||||
|
||||
if( length > 0 ) {
|
||||
avail = (unsigned) ( devlimit - fp );
|
||||
avail = (uint32_t) ( devlimit - fp );
|
||||
|
||||
n = (avail > 512)? 512: avail;
|
||||
|
||||
status = dev->devread( dev, (unsigned) (fp / 512), n, buf );
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILS(status = dev->devread( dev, (uint32_t) (fp / 512), n, buf )) )
|
||||
break;
|
||||
|
||||
m = (n > length)? length: n;
|
||||
@@ -962,8 +922,7 @@ unsigned virt_writep( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
buffer += m;
|
||||
length -= m;
|
||||
|
||||
status = dev->devwrite( dev, (unsigned) (fp / 512), n, buf );
|
||||
if( !(status & STS$M_SUCCESS) )
|
||||
if( $FAILS(status = dev->devwrite( dev, (uint32_t) (fp / 512), n, buf )) )
|
||||
break;
|
||||
|
||||
fp += n;
|
||||
@@ -1024,6 +983,8 @@ disktype_t disktype[] = {
|
||||
|
||||
DISK(RM02, 32, 5, 823, DISK_BAD144)
|
||||
DISK(RM03, 32, 5, 823, DISK_BAD144)
|
||||
DISK(RP02, 10, 20, 203, DISK_BAD144)
|
||||
DISK(RP03, 10, 20, 406, DISK_BAD144)
|
||||
DISK(RP04, 22, 19, 411, DISK_BAD144)
|
||||
DISK(RP05, 22, 19, 411, DISK_BAD144)
|
||||
DISK(RM80, 31, 14, 559, DISK_BAD144)
|
||||
@@ -1031,6 +992,9 @@ disktype_t disktype[] = {
|
||||
DISK(RM05, 32, 19, 823, DISK_BAD144)
|
||||
DISK(RP07, 50, 32, 630, DISK_BAD144)
|
||||
|
||||
DISKS(RS03, 128, 64, 1, 64, 0, DISK_BAD144)
|
||||
DISKS(RS04, 256, 64, 1, 64, 0, DISK_BAD144)
|
||||
|
||||
#if 0 /* Not useful now as RSX20-F used ODS-1 */
|
||||
DISKS(RM02-T, 576, 30, 5, 823, 0, DISK_BAD144)
|
||||
DISKS(RM03-T, 576, 30, 5, 823, 0, DISK_BAD144)
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _PHYVIRT_H
|
||||
@@ -27,9 +30,9 @@ typedef disktype_t *disktypep_t;
|
||||
|
||||
struct disktype {
|
||||
const char *name;
|
||||
unsigned long sectorsize, sectors, tracks, cylinders;
|
||||
unsigned long reserved, interleave, skew;
|
||||
unsigned int flags;
|
||||
uint32_t sectorsize, sectors, tracks, cylinders;
|
||||
uint32_t reserved, interleave, skew;
|
||||
uint32_t flags;
|
||||
#define DISK_BAD144 1
|
||||
#define DISK_BADSW 2
|
||||
};
|
||||
@@ -39,19 +42,19 @@ extern size_t max_disktype;
|
||||
|
||||
struct DEV;
|
||||
|
||||
void virt_show( const char *devnam );
|
||||
unsigned virt_open( char **devname, unsigned flags, struct DEV **dev );
|
||||
void virt_show( void );
|
||||
vmscond_t virt_open( char **devname, uint32_t flags, struct DEV **dev );
|
||||
char *virt_lookup( const char *devnam );
|
||||
unsigned virt_close( struct DEV *dev );
|
||||
vmscond_t virt_close( struct DEV *dev );
|
||||
|
||||
unsigned virt_read( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
vmscond_t virt_read( struct DEV *dev, uint32_t lbn, uint32_t length,
|
||||
char *buffer );
|
||||
unsigned virt_write( struct DEV *dev, unsigned lbn, unsigned length,
|
||||
vmscond_t virt_write( struct DEV *dev, uint32_t lbn, uint32_t length,
|
||||
const char *buffer );
|
||||
|
||||
unsigned virt_readp( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
vmscond_t virt_readp( struct DEV *dev, uint32_t pbn, uint32_t length,
|
||||
char *buffer );
|
||||
unsigned virt_writep( struct DEV *dev, unsigned pbn, unsigned length,
|
||||
vmscond_t virt_writep( struct DEV *dev, uint32_t pbn, uint32_t length,
|
||||
char *buffer );
|
||||
|
||||
#ifdef USE_VHD
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
/* PHYVMS.c Physical I/O module for VMS */
|
||||
|
||||
/*
|
||||
This is part of ODS2 written by Paul Nankervis,
|
||||
email address: Paulnank@au1.ibm.com
|
||||
* 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.
|
||||
*/
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
/* How come VMS is so much easier to do physical I/O on than
|
||||
those other ^%$@*! systems? I can't believe that they have
|
||||
different command sets for different device types, and can
|
||||
even have different command sets depending on what mode they
|
||||
are called from! Sigh. */
|
||||
* those other ^%$@*! systems? I can't believe that they have
|
||||
* different command sets for different device types, and can
|
||||
* even have different command sets depending on what mode they
|
||||
* are called from! Sigh. */
|
||||
|
||||
/* Modified by:
|
||||
*
|
||||
@@ -88,10 +91,10 @@ unsigned sys$dassgn();
|
||||
#include "phyio.h"
|
||||
#include "phyvirt.h"
|
||||
|
||||
static unsigned phyio_read( struct DEV *dev, unsigned block, unsigned length,
|
||||
char *buffer );
|
||||
static unsigned phyio_write( struct DEV *dev, unsigned block, unsigned length,
|
||||
const char *buffer );
|
||||
static vmscond_t phyio_read( struct DEV *dev, uint32_t block,
|
||||
uint32_t length, char *buffer );
|
||||
static vmscond_t phyio_write( struct DEV *dev, uint32_t block,
|
||||
uint32_t length, const char *buffer );
|
||||
|
||||
struct ITMLST {
|
||||
unsigned short length;
|
||||
@@ -100,11 +103,6 @@ struct ITMLST {
|
||||
unsigned short *retlen;
|
||||
};
|
||||
|
||||
#define chk( sts ) { register chksts; \
|
||||
if ( !( ( chksts = sts ) & STS$M_SUCCESS ) ) \
|
||||
lib$stop( chksts ); \
|
||||
}
|
||||
|
||||
#define MSGID(sts) ((sts) & (STS$M_COND_ID|STS$M_SEVERITY))
|
||||
|
||||
static unsigned init_count = 0;
|
||||
@@ -113,7 +111,7 @@ static unsigned write_count = 0;
|
||||
|
||||
/*************************************************************** showdevs() */
|
||||
static void showdevs( void ) {
|
||||
unsigned long status;
|
||||
vmscond_t status;
|
||||
size_t max = 0;
|
||||
int pass;
|
||||
|
||||
@@ -174,12 +172,13 @@ static void showdevs( void ) {
|
||||
case SS$_NOMOREDEV:
|
||||
break;
|
||||
case SS$_NOSUCHDEV:
|
||||
printf( "No devices found\n" );
|
||||
printmsg( IO_NODEVS, MSG_TEXT );
|
||||
break;
|
||||
case SS$_NORMAL:
|
||||
break;
|
||||
default:
|
||||
printf( "%%ODS2-W-ERRDEV, Error scanning devices: %s\n",
|
||||
getmsg( status, MSG_TEXT ) );
|
||||
printmsg( IO_VMSDEVSCAN, 0 );
|
||||
printmsg( status, MSG_CONTINUE, IO_VMSDEVSCAN );
|
||||
break;
|
||||
}
|
||||
return;
|
||||
@@ -190,12 +189,10 @@ static void showdevs( void ) {
|
||||
void phyio_show( showtype_t type ) {
|
||||
switch( type ) {
|
||||
case SHOW_STATS:
|
||||
printf( "PHYIO_SHOW Initializations: %d Reads: %d Writes: %d\n",
|
||||
init_count, read_count, write_count );
|
||||
printmsg( IO_STATS, MSG_TEXT, init_count, read_count, write_count );
|
||||
return;
|
||||
case SHOW_FILE64:
|
||||
printf( "Large ODS-2 image files (>2GB) are %ssupported.\n",
|
||||
(sizeof( off_t ) < 8)? "NOT ": "" );
|
||||
printmsg( (sizeof( off_t ) < 8)? IO_NOLARGEFILE: IO_LARGEFILE, MSG_TEXT );
|
||||
return;
|
||||
case SHOW_DEVICES:
|
||||
printf( " Physical devices\n" );
|
||||
@@ -206,61 +203,19 @@ void phyio_show( showtype_t type ) {
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_help() */
|
||||
|
||||
void phyio_help(FILE *fp ) {
|
||||
fprintf( fp, "mount DUB0:\n" );
|
||||
fprintf( fp, "The device can be specified as a physical device or logical name\n" );
|
||||
fprintf( fp, "You will need the LOGIO privilege\n" );
|
||||
fprintf( fp, "Use show DEVICES for a list of available devices.\n" );
|
||||
fprintf( fp, "For a list of devices, use the DCL SHOW DEVICE command.\n\n" );
|
||||
(void) helptopic( 0, "MOUNT VMS" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************** phyio_path() */
|
||||
|
||||
#define MAXPATH 255
|
||||
|
||||
char *phyio_path( const char *filnam ) {
|
||||
|
||||
size_t n;
|
||||
unsigned short resultant_path[1 + ( ( MAXPATH + 1 ) / 2)];
|
||||
char *path;
|
||||
unsigned long context, sts, flags;
|
||||
struct dsc$descriptor filespec = {
|
||||
0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL
|
||||
};
|
||||
struct dsc$descriptor resultant_filespec = {
|
||||
MAXPATH, DSC$K_DTYPE_T, DSC$K_CLASS_VS, (char *) resultant_path
|
||||
};
|
||||
|
||||
path = NULL;
|
||||
if ( filnam != NULL ) {
|
||||
filespec.dsc$w_length = strlen( filnam );
|
||||
filespec.dsc$a_pointer = (char *) filnam;
|
||||
*resultant_path = 0;
|
||||
context = 0;
|
||||
flags = LIB$M_FIL_NOWILD;
|
||||
sts = lib$find_file( &filespec, &resultant_filespec, &context,
|
||||
NULL, NULL, &sts, &flags );
|
||||
lib$find_file_end( &context );
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
n = *resultant_path;
|
||||
path = (char *) malloc( n + 1 );
|
||||
if ( path != NULL ) {
|
||||
memcpy( path, resultant_path + 1, n );
|
||||
path[n] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_init() */
|
||||
|
||||
unsigned phyio_init( struct DEV *dev ) {
|
||||
vmscond_t phyio_init( struct DEV *dev ) {
|
||||
|
||||
unsigned long sts;
|
||||
vmscond_t sts;
|
||||
const char *virtual;
|
||||
|
||||
init_count++;
|
||||
@@ -290,17 +245,18 @@ unsigned phyio_init( struct DEV *dev ) {
|
||||
vmsfd = open( virtual, O_RDONLY, 0444, opnopts );
|
||||
}
|
||||
if ( vmsfd < 0 ) {
|
||||
int err;
|
||||
|
||||
switch( errno ) {
|
||||
case EEXIST:
|
||||
printf( "%%ODS2-E-EXISTS, File %s already exists, not superseded\n",
|
||||
virtual );
|
||||
sts = SS$_DUPFILENAME;
|
||||
break;
|
||||
printmsg( IO_EXISTS, 0, virtual );
|
||||
return SS$_DUPFILENAME | STS$M_INHIB_MSG;
|
||||
default:
|
||||
printf( "%%ODS2-E-OPENERR, Open %s: %s\n",
|
||||
virtual, strerror( errno ) );
|
||||
err = errno;
|
||||
printmsg( IO_OPENDEV, 0, virtual );
|
||||
return printmsg( ODS2_OSERROR, MSG_CONTINUE, IO_OPENDEV,
|
||||
strerror( err ) );
|
||||
}
|
||||
return SS$_NOSUCHFILE;
|
||||
}
|
||||
|
||||
dev->handle = vmsfd;
|
||||
@@ -308,14 +264,13 @@ unsigned phyio_init( struct DEV *dev ) {
|
||||
fab = cc$rms_fab; /* Make this a real FAB (bid and bln) */
|
||||
fab.fab$l_fna = (char *) virtual;
|
||||
fab.fab$b_fns = strlen( virtual );
|
||||
sts = sys$open( &fab ); /* Lookup file, get file size */
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
if( $SUCCESSFUL(sts = sys$open( &fab )) {/* Lookup file, get file size */
|
||||
dev->sectors = fab.fab$l_alq;
|
||||
sys$close( &fab );
|
||||
if ( sizeof( off_t ) < 8 && dev->sectors > 0x3FFFFF ) {
|
||||
close( vmsfd );
|
||||
dev->handle = -1;
|
||||
return SS$_OFFSET_TOO_BIG; /* Sorry, need 64-bit off_t */
|
||||
return printmsg( IO_OFFSET_TOO_BIG, 0 ); /* Need 64-bit off_t */
|
||||
}
|
||||
}
|
||||
} else { /* Physical */
|
||||
@@ -335,24 +290,23 @@ unsigned phyio_init( struct DEV *dev ) {
|
||||
};
|
||||
|
||||
/* Get some device information: device name, class, and mount status */
|
||||
memset( devname, 0, sizeof( devname ) );
|
||||
devdsc.dsc$w_length = strlen( dev->devnam );
|
||||
devdsc.dsc$a_pointer = dev->devnam;
|
||||
sts = sys$getdviw( EFN$C_ENF, 0, &devdsc, &dvi_itmlst, iosb, 0, 0, 0 );
|
||||
if ( !( sts & STS$M_SUCCESS ) ) {
|
||||
if( $FAILS(sts = sys$getdviw( EFN$C_ENF, 0, &devdsc, &dvi_itmlst,
|
||||
iosb, 0, 0, 0 )) ) {
|
||||
return sts;
|
||||
}
|
||||
if ( devclass != DC$_DISK ) { /* If not a disk, return an error */
|
||||
if( devclass != DC$_DISK ) { /* If not a disk, return an error */
|
||||
return SS$_IVDEVNAM;
|
||||
}
|
||||
dev->sectors = cylinders * tracks * sectors;
|
||||
if ( !( devchar & DEV$M_MNT ) ) {
|
||||
#if 0
|
||||
if( !(devchar & DEV$M_MNT) ) {
|
||||
#if 1
|
||||
/*
|
||||
* This code will mount the disk if it's not already mounted. However,
|
||||
* there's no good way to ensure we dismount a disk we mounted (no
|
||||
* easy way to walk the list of devices at exit), so it's been #ifdefed
|
||||
* out. If you enable it, the "mount" command will mount the disk, but
|
||||
* it'll stay mounted by the process running ODS2, even after image exit.
|
||||
* This code will mount the disk if it's not already mounted.
|
||||
* If you enable it, the "mount" command will mount the disk, but
|
||||
* it'll stay mounted by the process running ODS2 if ODS2 exits abnormally.
|
||||
*/
|
||||
unsigned long mntflags[2];
|
||||
struct ITMLST mnt_itmlst[3] = {
|
||||
@@ -362,21 +316,27 @@ unsigned phyio_init( struct DEV *dev ) {
|
||||
};
|
||||
mnt_itmlst[0].length = strlen( devname );
|
||||
mntflags[0] = MNT$M_FOREIGN | MNT$M_NOASSIST | MNT$M_NOMNTVER;
|
||||
if ( !( dev->access & MOU_WRITE ) ) {
|
||||
if( !(dev->access & MOU_WRITE) ) {
|
||||
mntflags[0] |= MNT$M_NOWRITE;
|
||||
}
|
||||
mntflags[1] = 0;
|
||||
sts = sys$mount( &mnt_itmlst );
|
||||
if ( !( sts & STS$M_SUCCESS ) && ( dev->access & MOU_WRITE ) ) {
|
||||
if( $FAILED(sts) && (dev->access & MOU_WRITE) ) {
|
||||
dev->access &= ~MOU_WRITE;
|
||||
mntflags[0] |= MNT$M_NOWRITE;
|
||||
sts = sys$mount( &mnt_itmlst );
|
||||
}
|
||||
if( $SUCCESSFUL(sts) ) {
|
||||
dev->access |= OS_MOUNTED;
|
||||
printmsg( IO_VMSMOUNT, 0, devname );
|
||||
} else {
|
||||
printmsg( IO_VMSNOMOUNT, 0, devname );
|
||||
}
|
||||
#else
|
||||
sts = SS$_DEVNOTMOUNT;
|
||||
#endif
|
||||
}
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
if( $SUCCESSFUL(sts) ) {
|
||||
sts = sys$assign( &devdsc, &dev->handle, 0, 0, 0, 0 );
|
||||
}
|
||||
}
|
||||
@@ -386,73 +346,129 @@ unsigned phyio_init( struct DEV *dev ) {
|
||||
|
||||
/*************************************************************** phyio_done() */
|
||||
|
||||
unsigned phyio_done( struct DEV *dev ) {
|
||||
vmscond_t phyio_done( struct DEV *dev ) {
|
||||
vmscond_t status;
|
||||
|
||||
status = SS$_NORMAL;
|
||||
|
||||
if ( dev->access & MOU_VIRTUAL ) {
|
||||
close( dev->handle );
|
||||
virt_device( dev->devnam, NULL );
|
||||
} else {
|
||||
#if 1
|
||||
if( dev->access & OS_MOUNTED ) {
|
||||
struct dsc$descriptor devdsc;
|
||||
|
||||
devdsc.dsc$b_dtype = DSC$K_DTYPE_T;
|
||||
devdsc.dsc$b_class = DSC$K_CLASS_S;
|
||||
devdsc.dsc$w_length = strlen( dev->devnam );
|
||||
devdsc.dsc$a_pointer = dev->devnam;
|
||||
|
||||
if( $SUCCESSFUL(status = sys$dismou( &devdsc, 0 )) ) {
|
||||
printmsg( IO_VMSDMT, 0, dev->devnam );
|
||||
} else {
|
||||
printmsg( IO_VMSNODMT, 0, dev->devnam );
|
||||
}
|
||||
|
||||
dev->access &= ~OS_MOUNTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
sys$dassgn( dev->handle );
|
||||
}
|
||||
dev->handle = 0;
|
||||
return SS$_NORMAL;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*************************************************************** phyio_read() */
|
||||
|
||||
static unsigned phyio_read( struct DEV *dev, unsigned block, unsigned length,
|
||||
char *buffer ) {
|
||||
static vmscond_t phyio_read( struct DEV *dev, uint32_t block, uint32_t length,
|
||||
char *buffer ) {
|
||||
vmscond_t sts;
|
||||
|
||||
#if DEBUG
|
||||
printf("Phyio read block: %d into %x (%d bytes)\n",block,buffer,length);
|
||||
#endif
|
||||
read_count++;
|
||||
if ( dev->access & MOU_VIRTUAL ) {
|
||||
if( dev->access & MOU_VIRTUAL ) {
|
||||
int res;
|
||||
if ( ( res = lseek( dev->handle, block * 512, SEEK_SET ) ) < 0 ) {
|
||||
perror( "lseek " );
|
||||
printf( "lseek failed %d\n", res );
|
||||
return SS$_PARITY;
|
||||
if( (res = lseek( dev->handle, block * 512, SEEK_SET )) < 0 ) {
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( IO_SEEKERR, block );
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE,
|
||||
IO_SEEKERR, strerror(err) );
|
||||
return sts;
|
||||
}
|
||||
if ( ( res = read( dev->handle, buffer, length ) ) != length ) {
|
||||
if( (res = read( dev->handle, buffer, length )) != length ) {
|
||||
int err;
|
||||
|
||||
if( res == 0 ) {
|
||||
return SS$_ENDOFFILE;
|
||||
}
|
||||
perror( "read " );
|
||||
printf( "read failed %d\n", res );
|
||||
return SS$_PARITY;
|
||||
err = errno;
|
||||
printmsg( IO_READERR, 0, block );
|
||||
if( res == (off_t)-1 ) {
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE,
|
||||
IO_READERR, strerror(err) );
|
||||
} else {
|
||||
sts = printmsg( IO_READLEN, MSG_CONTINUE, IO_READERR,
|
||||
block, (uint32_t)res, length );
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
} else {
|
||||
return sys$qiow( 1, dev->handle, IO$_READLBLK, NULL, 0, 0,
|
||||
unsigned short int iosb[4];
|
||||
|
||||
return sys$qiow( EFN$C_ENF, dev->handle, IO$_READLBLK, iosb, 0, 0,
|
||||
buffer, length, block, 0, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************** phyio_write() */
|
||||
|
||||
static unsigned phyio_write( struct DEV *dev, unsigned block, unsigned length,
|
||||
const char *buffer ) {
|
||||
static vmscond_t phyio_write( struct DEV *dev, uint32_t block, uint32_t length,
|
||||
const char *buffer ) {
|
||||
|
||||
vmscond_t sts;
|
||||
|
||||
#if DEBUG
|
||||
printf("Phyio write block: %d from %x (%d bytes)\n",block,buffer,length);
|
||||
#endif
|
||||
write_count++;
|
||||
if ( dev->access & MOU_VIRTUAL ) {
|
||||
if( dev->access & MOU_VIRTUAL ) {
|
||||
int res;
|
||||
if ( ( res = lseek( dev->handle, block * 512, 0 ) ) < 0 ) {
|
||||
perror( "lseek " );
|
||||
printf( "lseek failed %d\n", res );
|
||||
return SS$_PARITY;
|
||||
if( (res = lseek( dev->handle, block * 512, 0 )) < 0 ) {
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( IO_SEEKERR, block );
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE,
|
||||
IO_SEEKERR, strerror(err) );
|
||||
return sts;
|
||||
}
|
||||
if ( ( res = write( dev->handle, buffer, length ) ) != length ) {
|
||||
perror( "write " );
|
||||
printf( "write failed %d\n", res );
|
||||
return SS$_PARITY;
|
||||
if( (res = write( dev->handle, buffer, length )) != length ) {
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( IO_WRITEERR, 0, block );
|
||||
if( res == (off_t)-1 ) {
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE,
|
||||
IO_WRITEERR, strerror(err) );
|
||||
} else {
|
||||
sts = printmsg( IO_WRITELEN, MSG_CONTINUE, IO_WRITEERR,
|
||||
block, (uint32_t)res, length );
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
} else {
|
||||
return sys$qiow( 1, dev->handle, IO$_WRITELBLK, NULL, 0, 0,
|
||||
unsigned short int iosb[4];
|
||||
|
||||
return sys$qiow( EFN$C_ENF, dev->handle, IO$_WRITELBLK, iosb, 0, 0,
|
||||
buffer, length, block, 0, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
214
extracters/ods2/renamecmd.c
Normal file
214
extracters/ods2/renamecmd.c
Normal file
@@ -0,0 +1,214 @@
|
||||
|
||||
/* This is part of ODS2, originally 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_RENAMECMD )
|
||||
#define DEBUG DEBUG_RENAMECMD
|
||||
#else
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "cmddef.h"
|
||||
|
||||
|
||||
/******************************************************************* dorename() */
|
||||
|
||||
/* rename a file */
|
||||
|
||||
#define rename_log OPT_GENERIC_1
|
||||
#define rename_confirm OPT_GENERIC_2
|
||||
|
||||
|
||||
qual_t
|
||||
renamequals[] = { {"log", rename_log, 0, NV,
|
||||
"-commands rename qual_log"},
|
||||
{"nolog", 0, rename_log, NV, NULL},
|
||||
{"confirm", rename_confirm, 0, NV,
|
||||
"-commands rename qual_confirm"},
|
||||
{"noconfirm", 0, rename_confirm, NV, NULL},
|
||||
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
|
||||
param_t
|
||||
renamepars[] = { {"from_filespec", REQ, FSPEC, NOPA,
|
||||
"commands rename fromspec"},
|
||||
{"to_filespec", REQ, FSPEC, NOPA,
|
||||
"commands rename tospec"},
|
||||
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
};
|
||||
|
||||
DECL_CMD(rename) {
|
||||
options_t options;
|
||||
vmscond_t sts = 0;
|
||||
vmscond_t confirm = ODS2_CONFIRM_ALL;
|
||||
uint32_t renamecnt = 0;
|
||||
struct FAB ofab, nfab;
|
||||
struct NAM onam, nnam;
|
||||
char oes[NAM$C_MAXRSS+1], nes[NAM$C_MAXRSS+1],
|
||||
ors[NAM$C_MAXRSS+1], nrs[NAM$C_MAXRSS+1];
|
||||
|
||||
UNUSED(argc);
|
||||
|
||||
if( $FAILS(sts = checkquals( &options, 0, renamequals, qualc, qualv )) ) {
|
||||
return sts;
|
||||
}
|
||||
|
||||
if( options & rename_confirm )
|
||||
confirm = RENAME_CONFIRM;
|
||||
|
||||
/* Old spec, possibly wild */
|
||||
|
||||
onam = cc$rms_nam;
|
||||
onam.nam$l_esa = oes;
|
||||
onam.nam$b_ess = sizeof( oes ) -1;
|
||||
onam.nam$l_rsa = ors;
|
||||
onam.nam$b_rss = sizeof( ors ) -1;
|
||||
|
||||
ofab = cc$rms_fab;
|
||||
ofab.fab$l_nam = &onam;
|
||||
ofab.fab$l_fna = argv[1];
|
||||
ofab.fab$b_fns = (uint8_t)strlen(ofab.fab$l_fna);
|
||||
|
||||
do {
|
||||
if( $FAILS(sts = sys_parse(&ofab)) ) {
|
||||
printmsg( RENAME_PARSEFAIL, 0, ofab.fab$l_fna );
|
||||
sts = printmsg( sts, MSG_CONTINUE, RENAME_PARSEFAIL );
|
||||
break;
|
||||
}
|
||||
|
||||
oes[onam.nam$b_esl] = '\0';
|
||||
|
||||
while( $SUCCESSFUL(sts) ) {
|
||||
struct FAB rfab;
|
||||
struct NAM rnam;
|
||||
char res[NAM$C_MAXRSS+1], rrs[NAM$C_MAXRSS+1];
|
||||
|
||||
if( $FAILS(sts = sys_search( &ofab )) ) {
|
||||
if( $MATCHCOND(sts, RMS$_NMF) ) {
|
||||
sts = SS$_NORMAL;
|
||||
break;
|
||||
}
|
||||
printmsg( RENAME_SEARCHFAIL, 0, onam.nam$l_esa );
|
||||
sts = printmsg( sts, MSG_CONTINUE, RENAME_SEARCHFAIL );
|
||||
break;
|
||||
}
|
||||
ors[onam.nam$b_rsl] = '\0';
|
||||
|
||||
/* New spec */
|
||||
|
||||
nnam = cc$rms_nam;
|
||||
nnam.nam$l_esa = nes;
|
||||
nnam.nam$b_ess = sizeof( nes ) -1;
|
||||
nnam.nam$l_rsa = nrs;
|
||||
nnam.nam$b_rss = sizeof( nrs ) -1;
|
||||
nnam.nam$l_rlf = &onam;
|
||||
|
||||
nfab = cc$rms_fab;
|
||||
nfab.fab$l_nam = &nnam;
|
||||
nfab.fab$l_fna = argv[2];
|
||||
nfab.fab$b_fns = (uint8_t)strlen(nfab.fab$l_fna);
|
||||
nfab.fab$l_fop = FAB$M_OFP;
|
||||
|
||||
if( $FAILS(sts = sys_parse(&nfab)) ) {
|
||||
printmsg( RENAME_PARSEFAIL, 0, nfab.fab$l_fna );
|
||||
sts = printmsg( sts, MSG_CONTINUE, RENAME_PARSEFAIL );
|
||||
break;
|
||||
}
|
||||
nes[nnam.nam$b_esl] = '\0';
|
||||
|
||||
/* Old resultant spec for rename */
|
||||
|
||||
rnam = cc$rms_nam;
|
||||
rnam.nam$l_esa = res;
|
||||
rnam.nam$b_ess = sizeof( res ) -1;
|
||||
rnam.nam$l_rsa = rrs;
|
||||
rnam.nam$b_rss = sizeof( rrs ) -1;
|
||||
|
||||
rfab = cc$rms_fab;
|
||||
rfab.fab$l_nam = &rnam;
|
||||
rfab.fab$l_fna = onam.nam$l_rsa;
|
||||
rfab.fab$b_fns = onam.nam$b_rsl;
|
||||
|
||||
if( $MATCHCOND( confirm, RENAME_CONFIRM) )
|
||||
confirm = confirm_cmd( confirm, ors, nes );
|
||||
|
||||
if( !$MATCHCOND( confirm, ODS2_CONFIRM_ALL ) ) {
|
||||
if( $MATCHCOND( confirm, ODS2_CONFIRM_YES ) ) {
|
||||
confirm = RENAME_CONFIRM;
|
||||
} else if( $MATCHCOND( confirm, ODS2_CONFIRM_NO ) ) {
|
||||
confirm = RENAME_CONFIRM;
|
||||
continue;
|
||||
} else { /* ODS2_CONFIRM_QUIT */
|
||||
sts = confirm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sts = sys_rename( &rfab, NULL, NULL, &nfab );
|
||||
res[rnam.nam$b_esl] = '\0';
|
||||
rrs[rnam.nam$b_rsl] = '\0';
|
||||
nes[nnam.nam$b_esl] = '\0';
|
||||
nrs[nnam.nam$b_rsl] = '\0';
|
||||
|
||||
if( $SUCCESSFUL(sts) ) {
|
||||
renamecnt++;
|
||||
if( options & rename_log )
|
||||
sts = printmsg( RENAME_RENAMED, 0, rrs, nrs );
|
||||
} else {
|
||||
printmsg( RENAME_FAILED, 0,
|
||||
rnam.nam$b_rsl? rrs: rnam.nam$b_esl? res: rfab.fab$l_fna,
|
||||
nnam.nam$b_rsl? nrs: nnam.nam$b_rsl? nes: nfab.fab$l_fna );
|
||||
sts = printmsg( sts, MSG_CONTINUE, RENAME_FAILED );
|
||||
}
|
||||
|
||||
rfab.fab$b_fns =
|
||||
rnam.nam$b_ess =
|
||||
rfab.fab$b_dns = 0;
|
||||
rnam.nam$b_nop = NAM$M_SYNCHK;
|
||||
(void) sys_parse( &rfab );
|
||||
|
||||
if( $FAILED(sts) && $VMS_STATUS_SEVERITY(sts) > STS$K_WARNING )
|
||||
break;
|
||||
} /* search old files */
|
||||
} while( 0 );
|
||||
|
||||
if( options & rename_log ) {
|
||||
vmscond_t st2 = 0;
|
||||
|
||||
if( renamecnt > 1 ) {
|
||||
st2 = printmsg( RENAME_NRENAMED, 0, renamecnt );
|
||||
} else if( renamecnt == 0 && $SUCCESSFUL(sts) )
|
||||
st2 = printmsg( RENAME_NOFILES, 0 );
|
||||
if( $SUCCESSFUL(sts) )
|
||||
sts = st2;
|
||||
}
|
||||
|
||||
ofab.fab$b_fns =
|
||||
onam.nam$b_ess =
|
||||
ofab.fab$b_dns = 0;
|
||||
onam.nam$l_rlf = NULL;
|
||||
onam.nam$b_nop = NAM$M_SYNCHK;
|
||||
(void) sys_parse( &ofab );
|
||||
|
||||
nfab.fab$b_fns =
|
||||
nnam.nam$b_ess =
|
||||
nfab.fab$b_dns = 0;
|
||||
nnam.nam$l_rlf = NULL;
|
||||
nnam.nam$b_nop = NAM$M_SYNCHK;
|
||||
(void) sys_parse( &nfab );
|
||||
|
||||
return sts;
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by ODS2.rc
|
||||
//
|
||||
/* {{NO_DEPENDENCIES}}
|
||||
* Microsoft Developer Studio generated include file.
|
||||
* Used by ODS2.rc
|
||||
*/
|
||||
|
||||
/* Next default values for new objects
|
||||
*/
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +1,72 @@
|
||||
/* RMS.h RMS routine definitions */
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#ifndef _RMS_H
|
||||
#define _RMS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ods2.h"
|
||||
#include "f11def.h"
|
||||
#include "vmstime.h"
|
||||
|
||||
#define RMS$_FACILITY 1
|
||||
#define NAM$C_MAXRSS 255u
|
||||
#define NAM$M_SYNCHK 0x8u
|
||||
#define NAM$S_DVI 32u
|
||||
|
||||
#define RMS$_RTB 98728
|
||||
#define RMS$_EOF 98938
|
||||
#define RMS$_FNF 98962
|
||||
#define RMS$_NMF 99018
|
||||
#define RMS$_WCC 99050
|
||||
#define RMS$_BUG 99380
|
||||
#define RMS$_DIR 99532
|
||||
#define RMS$_ESS 99588
|
||||
#define RMS$_FNM 99628
|
||||
#define RMS$_IFI 99684
|
||||
#define RMS$_NAM 99804
|
||||
#define RMS$_RSS 99988
|
||||
#define RMS$_RSZ 100004
|
||||
#define RMS$_WLD 100164
|
||||
#define RMS$_DNF 114762
|
||||
#define XAB$C_DAT 18u
|
||||
#define XAB$C_ALL 20u
|
||||
#define XAB$C_FHC 29u
|
||||
#define XAB$C_PRO 19u
|
||||
#define XAB$C_RDT 30u
|
||||
#define XAB$C_ITM 36u
|
||||
|
||||
#define NAM$C_MAXRSS 255
|
||||
#define NAM$M_SYNCHK 0x8
|
||||
/* N.B. xab$l_nxt and xab$b_cod MUST have the same offsets in all XABs */
|
||||
|
||||
#define XAB$C_DAT 18
|
||||
#define XAB$C_FHC 29
|
||||
#define XAB$C_PRO 19
|
||||
#define XAB$C_ITM 36
|
||||
struct XABALL {
|
||||
void *xab$l_nxt;
|
||||
uint8_t xab$b_cod;
|
||||
uint16_t xab$w_vol;
|
||||
uint32_t xab$l_alq;
|
||||
uint16_t xab$w_deq;
|
||||
uint8_t xab$b_bkz;
|
||||
};
|
||||
|
||||
#ifdef RMS$INITIALIZE
|
||||
struct XABALL cc$rms_xaball = { NULL, XAB$C_ALL, 0,
|
||||
0, 0, 0 };
|
||||
#else
|
||||
extern struct XABALL cc$rms_xaball;
|
||||
#endif
|
||||
|
||||
struct XABRDT {
|
||||
void *xab$l_nxt;
|
||||
uint8_t xab$b_cod;
|
||||
uint16_t xab$w_rvn;
|
||||
VMSTIME xab$q_rdt;
|
||||
};
|
||||
#ifdef RMS$INITIALIZE
|
||||
struct XABRDT cc$rms_xabrdt = { NULL, XAB$C_RDT, 0, VMSTIME_ZERO };
|
||||
#else
|
||||
extern struct XABRDT cc$rms_xabrdt;
|
||||
#endif
|
||||
|
||||
struct XABDAT {
|
||||
void *xab$l_nxt;
|
||||
int xab$b_cod;
|
||||
int xab$w_rvn;
|
||||
uint8_t xab$b_cod;
|
||||
uint16_t xab$w_rvn;
|
||||
VMSTIME xab$q_bdt;
|
||||
VMSTIME xab$q_cdt;
|
||||
VMSTIME xab$q_edt;
|
||||
@@ -52,241 +74,288 @@ struct XABDAT {
|
||||
};
|
||||
|
||||
#ifdef RMS$INITIALIZE
|
||||
struct XABDAT cc$rms_xabdat = {NULL,XAB$C_DAT,0,
|
||||
VMSTIME_ZERO, VMSTIME_ZERO,
|
||||
VMSTIME_ZERO, VMSTIME_ZERO};
|
||||
struct XABDAT cc$rms_xabdat = { NULL, XAB$C_DAT, 0,
|
||||
VMSTIME_ZERO, VMSTIME_ZERO,
|
||||
VMSTIME_ZERO, VMSTIME_ZERO };
|
||||
#else
|
||||
extern struct XABDAT cc$rms_xabdat;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
struct XABFHC {
|
||||
void *xab$l_nxt;
|
||||
int xab$b_cod;
|
||||
int xab$b_atr;
|
||||
int xab$b_bkz;
|
||||
int xab$w_dxq;
|
||||
int xab$l_ebk;
|
||||
int xab$w_ffb;
|
||||
int xab$w_gbc;
|
||||
int xab$l_hbk;
|
||||
int xab$b_hsz;
|
||||
int xab$w_lrl;
|
||||
int xab$w_verlimit;
|
||||
uint8_t xab$b_cod;
|
||||
uint8_t xab$b_atr;
|
||||
uint16_t xab$w_ffb;
|
||||
uint32_t xab$l_ebk;
|
||||
uint32_t xab$l_hbk;
|
||||
uint16_t xab$w_lrl;
|
||||
uint16_t xab$w_dxq;
|
||||
uint16_t xab$w_gbc;
|
||||
uint16_t xab$w_verlimit;
|
||||
uint8_t xab$b_bkz;
|
||||
uint8_t xab$b_hsz;
|
||||
};
|
||||
|
||||
#ifdef RMS$INITIALIZE
|
||||
struct XABFHC cc$rms_xabfhc = {NULL,XAB$C_FHC,0,0,0,0,0,0,0,0,0,0};
|
||||
struct XABFHC cc$rms_xabfhc = { NULL, XAB$C_FHC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
#else
|
||||
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 */
|
||||
#define XAB$K_SENSEMODE 1u
|
||||
#define XAB$K_SETMODE 2u
|
||||
#define XAB$_UCHAR 128u
|
||||
#define XAB$_UCHAR_NOBACKUP 130u /* (set, sense) FCH$V_NOBACKUP */
|
||||
#define XAB$_UCHAR_WRITEBACK 131u /* (sense) FCH$V_WRITEBACK */
|
||||
#define XAB$_UCHAR_READCHECK 132u /* (set, sense) FCH$V_READCHECK */
|
||||
#define XAB$_UCHAR_WRITECHECK 133u /* (set, sense) FCH$V_WRITECHECK */
|
||||
#define XAB$_UCHAR_CONTIGB 134u /* (set, sense) FCH$V_CONTIGB */
|
||||
#define XAB$_UCHAR_LOCKED 135u /* (set, sense) FCH$V_LOCKED */
|
||||
#define XAB$_UCHAR_CONTIG 136u /* (sense) FCH$V_CONTIG */
|
||||
#define XAB$_UCHAR_SPOOL 138u /* (sense) FCH$V_SPOOL */
|
||||
#define XAB$_UCHAR_DIRECTORY 139u /* (sense) FCH$V_DIRECTORY */
|
||||
#define XAB$_UCHAR_BADBLOCK 140u /* (sense) FCH$V_BADBLOCK */
|
||||
#define XAB$_UCHAR_MARKDEL 141u /* (sense) FCH$V_BADBLOCK */
|
||||
|
||||
struct item_list {
|
||||
unsigned short int code;
|
||||
unsigned short int length;
|
||||
void *buffer;
|
||||
int retlen;
|
||||
uint16_t code;
|
||||
uint16_t length;
|
||||
void *buffer;
|
||||
uint16_t *retlen;
|
||||
};
|
||||
|
||||
struct XABITM {
|
||||
void *xab$l_nxt;
|
||||
int xab$b_cod;
|
||||
void *xab$l_nxt;
|
||||
uint8_t xab$b_cod;
|
||||
uint8_t xab$b_mode;
|
||||
struct item_list *xab$l_itemlist;
|
||||
int xab$b_mode;
|
||||
};
|
||||
|
||||
#ifdef RMS$INITIALIZE
|
||||
struct XABITM cc$rms_xabitm = {NULL,XAB$C_ITM,NULL,0};
|
||||
struct XABITM cc$rms_xabitm = {NULL, XAB$C_ITM, 0, NULL};
|
||||
#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
|
||||
#define xab$m_noread 1u
|
||||
#define xab$m_nowrite 2u
|
||||
#define xab$m_noexe 4u
|
||||
#define xab$m_nodel 8u
|
||||
#define xab$m_prot (xab$m_noread|xab$m_nowrite|xab$m_noexe|xab$m_nodel)
|
||||
#define xab$v_system 0u
|
||||
#define xab$v_owner 4u
|
||||
#define xab$v_group 8u
|
||||
#define xab$v_world 12u
|
||||
|
||||
struct XABPRO {
|
||||
void *xab$l_nxt;
|
||||
int xab$b_cod;
|
||||
unsigned int xab$w_pro;
|
||||
unsigned int xab$l_uic;
|
||||
void *xab$l_nxt;
|
||||
uint8_t xab$b_cod;
|
||||
uint16_t xab$w_pro;
|
||||
uint32_t xab$l_uic;
|
||||
};
|
||||
|
||||
#ifdef RMS$INITIALIZE
|
||||
struct XABPRO cc$rms_xabpro = {NULL,XAB$C_PRO,0,0};
|
||||
struct XABPRO cc$rms_xabpro = { NULL, XAB$C_PRO, 0, 0 };
|
||||
#else
|
||||
extern struct XABPRO cc$rms_xabpro;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define NAM$M_WILDCARD 0x100
|
||||
#define NAM$M_EXP_VER UINT32_C(0x00000001)
|
||||
#define NAM$M_EXP_TYPE UINT32_C(0x00000002)
|
||||
#define NAM$M_EXP_NAME UINT32_C(0x00000004)
|
||||
#define NAM$M_WILD_VER UINT32_C(0x00000008)
|
||||
#define NAM$M_WILD_TYPE UINT32_C(0x00000010)
|
||||
#define NAM$M_WILD_NAME UINT32_C(0x00000020)
|
||||
#define NAM$M_EXP_DIR UINT32_C(0x00000040)
|
||||
#define NAM$M_EXP_DEV UINT32_C(0x00000080)
|
||||
#define NAM$M_WILDCARD UINT32_C(0x00000100)
|
||||
#define NAM$M_SEARCH_LIST UINT32_C(0x00000800)
|
||||
#define NAM$M_CNCL_DEV UINT32_C(0x00001000)
|
||||
#define NAM$M_ROOT_DIR UINT32_C(0x00002000)
|
||||
#define NAM$M_LOWVER UINT32_C(0x00004000)
|
||||
#define NAM$M_HIGHVER UINT32_C(0x00008000)
|
||||
#define NAM$M_PPF UINT32_C(0x00010000)
|
||||
#define NAM$M_NODE UINT32_C(0x00020000)
|
||||
#define NAM$M_QUOTED UINT32_C(0x00040000)
|
||||
#define NAM$M_GRP_MBR UINT32_C(0x00080000)
|
||||
#define NAM$M_WILD_DIR UINT32_C(0x00100000)
|
||||
#define NAM$M_DIR_LVLS UINT32_C(0x00e00000)
|
||||
#define NAM$V_DIR_LVLS 20u
|
||||
#define NAM$M_WILD_UFD UINT32_C(0x01000000)
|
||||
#define NAM$M_WILD_SFD1 UINT32_C(0x02000000)
|
||||
#define NAM$M_WILD_SFD2 UINT32_C(0x04000000)
|
||||
#define NAM$M_WILD_SFD3 UINT32_C(0x08000000)
|
||||
#define NAM$M_WILD_SFD4 UINT32_C(0x10000000)
|
||||
#define NAM$M_WILD_SFD5 UINT32_C(0x20000000)
|
||||
#define NAM$M_WILD_SFD6 UINT32_C(0x40000000)
|
||||
#define NAM$M_WILD_SFD7 UINT32_C(0x80000000)
|
||||
/* The following are aliased to WILD_UFD, WILD_SFD1 */
|
||||
#define NAM$M_WILD_GRP UINT32_C(0x01000000)
|
||||
#define NAM$M_WILD_MBR UINT32_C(0x02000000)
|
||||
|
||||
struct NAM {
|
||||
unsigned short nam$w_did_num;
|
||||
unsigned short nam$w_did_seq;
|
||||
unsigned char nam$b_did_rvn;
|
||||
unsigned char nam$b_did_nmx;
|
||||
unsigned short nam$w_fid_num;
|
||||
unsigned short nam$w_fid_seq;
|
||||
unsigned char nam$b_fid_rvn;
|
||||
unsigned char nam$b_fid_nmx;
|
||||
int nam$b_ess;
|
||||
int nam$b_rss;
|
||||
int nam$b_esl;
|
||||
char *nam$l_esa;
|
||||
int nam$b_rsl;
|
||||
char *nam$l_rsa;
|
||||
int nam$b_dev;
|
||||
char *nam$l_dev;
|
||||
int nam$b_dir;
|
||||
char *nam$l_dir;
|
||||
int nam$b_name;
|
||||
char *nam$l_name;
|
||||
int nam$b_type;
|
||||
char *nam$l_type;
|
||||
int nam$b_ver;
|
||||
char *nam$l_ver;
|
||||
void *nam$l_wcc;
|
||||
int nam$b_nop;
|
||||
int nam$l_fnb;
|
||||
char *nam$l_esa;
|
||||
char *nam$l_rsa;
|
||||
char *nam$l_dev;
|
||||
char *nam$l_dir;
|
||||
char *nam$l_name;
|
||||
char *nam$l_type;
|
||||
char *nam$l_ver;
|
||||
struct NAM *nam$l_rlf;
|
||||
void *nam$l_wcc;
|
||||
struct fiddef nam$w_fid;
|
||||
struct fiddef nam$w_did;
|
||||
uint32_t nam$l_fnb;
|
||||
char nam$t_dvi[1+NAM$S_DVI];
|
||||
uint8_t nam$b_ess;
|
||||
uint8_t nam$b_esl;
|
||||
uint8_t nam$b_rss;
|
||||
uint8_t nam$b_rsl;
|
||||
uint8_t nam$b_dev;
|
||||
uint8_t nam$b_dir;
|
||||
uint8_t nam$b_name;
|
||||
uint8_t nam$b_type;
|
||||
uint8_t nam$b_ver;
|
||||
uint8_t nam$b_nop;
|
||||
};
|
||||
|
||||
#ifdef RMS$INITIALIZE
|
||||
struct NAM cc$rms_nam = {0,0,0,0,0,0,0,0,0,0,0,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0,0,0,NULL};
|
||||
struct NAM cc$rms_nam = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, {0, 0, 0, 0}, {0, 0, 0, 0}, 0,
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
|
||||
#else
|
||||
extern struct NAM cc$rms_nam;
|
||||
#endif
|
||||
|
||||
|
||||
#define RAB$C_SEQ 0
|
||||
#define RAB$C_RFA 2
|
||||
/* rab$b_rac */
|
||||
#define RAB$C_SEQ 0u
|
||||
#define RAB$C_RFA 2u
|
||||
|
||||
/* rab$l_rop */
|
||||
#define RAB$M_TPT 2
|
||||
#define RAB$M_EOF 256u
|
||||
|
||||
struct RAB {
|
||||
struct RAB *rab$a__next;
|
||||
struct FAB *rab$l_fab;
|
||||
char *rab$l_ubf;
|
||||
char *rab$l_rhb;
|
||||
char *rab$l_rbf;
|
||||
unsigned rab$w_usz;
|
||||
unsigned rab$w_rsz;
|
||||
int rab$b_rac;
|
||||
unsigned short rab$w_rfa[3];
|
||||
char *rab$l_ubf;
|
||||
char *rab$l_rhb;
|
||||
char *rab$l_rbf;
|
||||
uint32_t rab$l_stv;
|
||||
uint32_t rab$l_rop;
|
||||
uint32_t rab$w_isi;
|
||||
uint16_t rab$w_usz;
|
||||
uint16_t rab$w_rsz;
|
||||
uint8_t rab$b_rac;
|
||||
uint16_t rab$w_rfa[3];
|
||||
};
|
||||
|
||||
#ifdef RMS$INITIALIZE
|
||||
struct RAB cc$rms_rab = {NULL,NULL,NULL,NULL,0,0,0,{0,0,0}};
|
||||
struct RAB cc$rms_rab = { NULL, NULL, NULL, NULL, NULL,
|
||||
0, 0, 0, 0, 0, 0, {0, 0, 0} };
|
||||
#else
|
||||
extern struct RAB cc$rms_rab;
|
||||
#endif
|
||||
|
||||
|
||||
/* FAB$B_ORG : N.B. These are all high nibble values for fat$b_rtype */
|
||||
#define FAB$C_SEQ 0u
|
||||
#define FAB$C_REL 16u
|
||||
#define FAB$C_IDX 32u
|
||||
#define FAB$C_HSH 48u
|
||||
|
||||
#define FAB$C_SEQ 0
|
||||
#define FAB$C_REL 16
|
||||
#define FAB$C_IDX 32
|
||||
#define FAB$C_HSH 48
|
||||
/* FAB$B_RAT : N.B. These are all low nibble values for fat$b_rtype */
|
||||
#define FAB$M_FTN 0x1u
|
||||
#define FAB$M_CR 0x2u
|
||||
#define FAB$M_PRN 0x4u
|
||||
#define FAB$M_BLK 0x8u
|
||||
|
||||
#define FAB$M_FTN 0x1
|
||||
#define FAB$M_CR 0x2
|
||||
#define FAB$M_PRN 0x4
|
||||
#define FAB$M_BLK 0x8
|
||||
/* FAB$B_FAC */
|
||||
#define FAB$M_PUT 0x1u
|
||||
#define FAB$M_GET 0x2u
|
||||
#define FAB$M_DEL 0x4u
|
||||
#define FAB$M_UPD 0x8u
|
||||
#define FAB$M_TRN 0x10u
|
||||
#define FAB$M_BIO 0x20u
|
||||
#define FAB$M_BRO 0x40u
|
||||
#define FAB$M_EXE 0x80u
|
||||
|
||||
#define FAB$M_PUT 0x1
|
||||
#define FAB$M_GET 0x2
|
||||
#define FAB$M_DEL 0x4
|
||||
#define FAB$M_UPD 0x8
|
||||
#define FAB$M_TRN 0x10
|
||||
#define FAB$M_BIO 0x20
|
||||
#define FAB$M_BRO 0x40
|
||||
#define FAB$M_EXE 0x80
|
||||
|
||||
#define FAB$C_UDF 0
|
||||
#define FAB$C_FIX 1
|
||||
#define FAB$C_VAR 2
|
||||
#define FAB$C_VFC 3
|
||||
#define FAB$C_STM 4
|
||||
#define FAB$C_STMLF 5
|
||||
#define FAB$C_STMCR 6
|
||||
/* FAB$B_RFM */
|
||||
#define FAB$C_UDF 0u
|
||||
#define FAB$C_FIX 1u
|
||||
#define FAB$C_VAR 2u
|
||||
#define FAB$C_VFC 3u
|
||||
#define FAB$C_STM 4u
|
||||
#define FAB$C_STMLF 5u
|
||||
#define FAB$C_STMCR 6u
|
||||
|
||||
/* 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
|
||||
#define FAB$M_ASY UINT32_C(1)
|
||||
#define FAB$M_MXV UINT32_C(2)
|
||||
#define FAB$M_SUP UINT32_C(4)
|
||||
#define FAB$M_TMP UINT32_C(8)
|
||||
#define FAB$M_TMD UINT32_C(16)
|
||||
#define FAB$M_DFW UINT32_C(32)
|
||||
#define FAB$M_SQO UINT32_C(64)
|
||||
#define FAB$M_RWO UINT32_C(128)
|
||||
#define FAB$M_POS UINT32_C(256)
|
||||
#define FAB$M_WCK UINT32_C(512)
|
||||
#define FAB$M_NEF UINT32_C(1024)
|
||||
#define FAB$M_RWC UINT32_C(2048)
|
||||
#define FAB$M_DMO UINT32_C(4096)
|
||||
#define FAB$M_SPL UINT32_C(8192)
|
||||
#define FAB$M_SCF UINT32_C(16384)
|
||||
#define FAB$M_DLT UINT32_C(32768)
|
||||
#define FAB$M_NFS UINT32_C(65536)
|
||||
#define FAB$M_UFO UINT32_C(131072)
|
||||
#define FAB$M_PPF UINT32_C(262144)
|
||||
#define FAB$M_INP UINT32_C(524288)
|
||||
#define FAB$M_CTG UINT32_C(1048576)
|
||||
#define FAB$M_CBT UINT32_C(2097152)
|
||||
#define FAB$M_SYNCSTS UINT32_C(4194304)
|
||||
#define FAB$M_RCK UINT32_C(8388608)
|
||||
#define FAB$M_NAM UINT32_C(16777216)
|
||||
#define FAB$M_CIF UINT32_C(33554432)
|
||||
#define FAB$M_ESC UINT32_C(134217728)
|
||||
#define FAB$M_TEF UINT32_C(268435456)
|
||||
#define FAB$M_OFP UINT32_C(536870912)
|
||||
#define FAB$M_KFO UINT32_C(1073741824)
|
||||
|
||||
struct FAB {
|
||||
char *fab$l_fna;
|
||||
char *fab$l_dna;
|
||||
struct NAM *fab$l_nam;
|
||||
int fab$w_ifi;
|
||||
char *fab$l_fna;
|
||||
char *fab$l_dna;
|
||||
int fab$b_fns;
|
||||
int fab$b_dns;
|
||||
int fab$l_alq;
|
||||
int fab$b_bks;
|
||||
int fab$w_deq;
|
||||
unsigned int fab$b_fsz;
|
||||
int fab$w_gbc;
|
||||
unsigned int fab$w_mrs;
|
||||
int fab$l_fop;
|
||||
int fab$b_org;
|
||||
int fab$b_rat;
|
||||
int fab$b_rfm;
|
||||
int fab$b_fac;
|
||||
void *fab$l_xab;
|
||||
unsigned short fab__w_verlimit;
|
||||
void *fab$l_xab;
|
||||
struct RAB *fab$a__rab;
|
||||
uint32_t fab$l_isi;
|
||||
uint32_t fab$l_alq;
|
||||
uint32_t fab$l_fop;
|
||||
uint32_t fab$l_openfop;
|
||||
uint16_t fab$w_deq;
|
||||
uint16_t fab$w_ifi;
|
||||
uint16_t fab$w_gbc;
|
||||
uint16_t fab$w_mrs;
|
||||
uint8_t fab$b_fns;
|
||||
uint8_t fab$b_dns;
|
||||
uint8_t fab$b_bks;
|
||||
uint8_t fab$b_fsz;
|
||||
uint8_t fab$b_org;
|
||||
uint8_t fab$b_rat;
|
||||
uint8_t fab$b_rfm;
|
||||
uint8_t fab$b_fac;
|
||||
uint16_t fab__w_verlimit;
|
||||
};
|
||||
|
||||
#ifdef RMS$INITIALIZE
|
||||
struct FAB cc$rms_fab = {NULL,0,NULL,NULL,0,0,0,0,0,0,0,0,0,0,0,0,0,NULL,0};
|
||||
struct FAB cc$rms_fab = {NULL, NULL, NULL, NULL, NULL,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
#else
|
||||
extern struct FAB cc$rms_fab;
|
||||
#endif
|
||||
@@ -304,23 +373,26 @@ extern struct FAB cc$rms_fab;
|
||||
#define sys$open sys_open
|
||||
#define sys$create sys_create
|
||||
#define sys$erase sys_erase
|
||||
#define sys$rename sys_rename
|
||||
#define sys$extend sys_extend
|
||||
#endif
|
||||
|
||||
unsigned sys_search(struct FAB *fab);
|
||||
unsigned sys_parse(struct FAB *fab);
|
||||
unsigned sys_connect(struct RAB *rab);
|
||||
unsigned sys_disconnect(struct RAB *rab);
|
||||
unsigned sys_get(struct RAB *rab);
|
||||
unsigned sys_put(struct RAB *rab);
|
||||
unsigned sys_display(struct FAB *fab);
|
||||
unsigned sys_close(struct FAB *fab);
|
||||
unsigned sys_open(struct FAB *fab);
|
||||
unsigned sys_create(struct FAB *fab);
|
||||
unsigned sys_erase(struct FAB *fab);
|
||||
unsigned sys_extend(struct FAB *fab);
|
||||
unsigned sys_setddir(struct dsc_descriptor *newdir,unsigned short *oldlen,
|
||||
struct dsc_descriptor *olddir);
|
||||
|
||||
unsigned sys_initialize(void);
|
||||
vmscond_t sys_close( struct FAB *fab );
|
||||
vmscond_t sys_connect( struct RAB *rab );
|
||||
vmscond_t sys_create( struct FAB *fab );
|
||||
vmscond_t sys_disconnect( struct RAB *rab );
|
||||
vmscond_t sys_display( struct FAB *fab );
|
||||
vmscond_t sys_erase( struct FAB *fab );
|
||||
vmscond_t sys_extend( struct FAB *fab );
|
||||
vmscond_t sys_get( struct RAB *rab );
|
||||
vmscond_t sys_initialize(void);
|
||||
vmscond_t sys_open( struct FAB *fab );
|
||||
vmscond_t sys_parse( struct FAB *fab );
|
||||
vmscond_t sys_put( struct RAB *rab );
|
||||
vmscond_t sys_rename( struct FAB *oldfab,
|
||||
void *astrtn, void *astprm, struct FAB *newfab );
|
||||
vmscond_t sys_search( struct FAB *fab );
|
||||
vmscond_t sys_setddir( struct dsc_descriptor *newdir, uint16_t *oldlen,
|
||||
struct dsc_descriptor *olddir );
|
||||
|
||||
#endif /* #ifndef _RMS_H */
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
/*
|
||||
* This is distributed as part of ODS2, originally 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
//***************************************************************************
|
||||
//
|
||||
// Name: SCSIDEFS.H
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_SEARCHCMD )
|
||||
@@ -15,139 +18,621 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cmddef.h"
|
||||
|
||||
#define CSI "\033["
|
||||
|
||||
static const char *const C0[32] = {
|
||||
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
|
||||
"BS" , "TAB", "LF" , "VT" , "FF" , "CR" , "SO" , "SI" ,
|
||||
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
|
||||
"CAN", "EM" , "SUB", "ESC", "FS" , "GS" , "RS" , "US" };
|
||||
static const char *const C1[33] = { /* 0x80 - 0xA0 */
|
||||
"80" , "81" , "BPH", "NBH", "IND", "NEL", "SSA", "ESA",
|
||||
"HTS", "HTJ", "VTS", "PLD", "PLU", "RI" , "SS2", "SS3",
|
||||
"DCS", "PU1", "PU2", "STS", "CCH", "MW" , "SPA", "EPA",
|
||||
"SOS", "SGCI","DECID","CSI", "ST" , "OSC", "PM" , "APC",
|
||||
"NSP" };
|
||||
static uint8_t CW[256], CWS;
|
||||
|
||||
#if MAXREC <= INT8_MAX
|
||||
typedef int8_t mpos_t;
|
||||
#elif MAXREC <= INT16_MAX
|
||||
typedef int16_t mpos_t;
|
||||
#else /* MAXREC <= INT32_MAX */
|
||||
typedef int32_t mpos_t;
|
||||
#endif
|
||||
|
||||
static int prep( int fc, char *pattern, int plen, void **ctx );
|
||||
static int match( int fc, char *pattern, int plen,
|
||||
char *data, int dlen, mpos_t *mpos, void *ctx );
|
||||
|
||||
/***************************************************************** dosearch() */
|
||||
|
||||
/* dosearch: a simple file search routine */
|
||||
#define search_exact OPT_GENERIC_1
|
||||
#define search_number OPT_GENERIC_2
|
||||
#define search_confirm OPT_GENERIC_3
|
||||
#define search_heading OPT_GENERIC_4
|
||||
#define search_nohead OPT_GENERIC_5
|
||||
#define search_log OPT_GENERIC_6
|
||||
#define search_highlight OPT_GENERIC_7
|
||||
#define search_nowindow OPT_GENERIC_8
|
||||
#define search_page OPT_GENERIC_9
|
||||
#define search_blink OPT_SHARED_1
|
||||
#define search_bold OPT_SHARED_2
|
||||
#define search_reverse OPT_SHARED_3
|
||||
#define search_underline OPT_SHARED_4
|
||||
#define search_hardcopy OPT_SHARED_5
|
||||
|
||||
param_t searchpars[] = { {"filespec", REQ, VMSFS, NOPA, "for file to search. Wildcards are allowed."},
|
||||
{"string", REQ, STRING, NOPA, "string to search for."},
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
#define search_match (OPT_SHARED_7|OPT_SHARED_6)
|
||||
#define search_v_match (OPT_V_SHARED + 5)
|
||||
|
||||
#define MAT_AND 0
|
||||
#define MAT_OR 1
|
||||
#define MAT_NAND 2
|
||||
#define MAT_NOR 3
|
||||
|
||||
#define search_mat_and (MAT_AND << search_v_match)
|
||||
#define search_mat_or (MAT_OR << search_v_match)
|
||||
#define search_mat_nand (MAT_NAND << search_v_match)
|
||||
#define search_mat_nor (MAT_NOR << search_v_match)
|
||||
|
||||
static qual_t
|
||||
matchkwds[] = { {"and", search_mat_and, search_match, NV,
|
||||
"commands search qual_match match_and"},
|
||||
{"or", search_mat_or, search_match, NV,
|
||||
"commands search qual_match match_or"},
|
||||
{"nand", search_mat_nand, search_match, NV,
|
||||
"commands search qual_match match_nand"},
|
||||
{"nor", search_mat_nor, search_match, NV,
|
||||
"commands search qual_match match_nor"},
|
||||
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
|
||||
static qual_t
|
||||
highkwds[] = { {"blink", search_blink, 0, NV,
|
||||
"commands search qual_highlight highlight_blink"},
|
||||
{"bold", search_bold, 0, NV,
|
||||
"commands search qual_highlight highlight_bold"},
|
||||
{"hardcopy", search_hardcopy, 0, NV,
|
||||
"commands search qual_highlight highlight_hardcopy"},
|
||||
{"reverse", search_reverse, 0, NV,
|
||||
"commands search qual_highlight highlight_reverse"},
|
||||
{"underline", search_underline, 0, NV,
|
||||
"commands search qual_highlight highlight_underline"},
|
||||
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
|
||||
static uint32_t height;
|
||||
|
||||
const int search_defaults = search_highlight | search_mat_or;
|
||||
defqualsp_t search_defopt = NULL;
|
||||
|
||||
qual_t
|
||||
searchquals[] = { {"confirm", search_confirm, 0, NV,
|
||||
"-commands search qual_confirm"},
|
||||
{"noconfirm", 0, search_confirm, NV, NULL},
|
||||
{"exact", search_exact, 0, NV,
|
||||
"-commands search qual_exact"},
|
||||
{"noexact", 0, search_exact, NV, NULL},
|
||||
{"log", search_log, 0, NV,
|
||||
"-commands search qual_log"},
|
||||
{"nolog", 0, search_log, NV, NULL},
|
||||
{"heading", search_heading, search_nohead, NV,
|
||||
"-commands search qual_heading"},
|
||||
{"noheading", search_nohead, search_heading, NV, NULL},
|
||||
{"highlight", search_highlight, 0, VOPT(KV(highkwds)),
|
||||
"-commands search qual_highlight"},
|
||||
{"nohighlight", 0, search_highlight, NV, NULL},
|
||||
{"match_type", 0, 0, KV(&matchkwds),
|
||||
"commands search qual_match"},
|
||||
{"nowindow", search_nowindow|search_heading, /* ~~/WINDOW=0 */
|
||||
search_nohead, NV,
|
||||
"commands search qual_nowindow"},
|
||||
{"numbers", search_number, 0, NV,
|
||||
"-commands search qual_numbers"},
|
||||
|
||||
{"nonumbers", 0, search_number, NV, NULL},
|
||||
{"page", search_page, 0, VOPT(DV(&height)),
|
||||
"-commands search qual_page"},
|
||||
{"nopage", 0, search_page, NV, NULL},
|
||||
{NULL, 0, 0, NV, NULL}
|
||||
};
|
||||
|
||||
param_t
|
||||
searchpars[] = { {"filespec", REQ, FSPEC, NOPA, "commands search filespec"},
|
||||
{"string", REQ|NOLIM, STRING, NOPA, "commands search string"},
|
||||
{ NULL, 0, 0, NOPA, NULL }
|
||||
};
|
||||
|
||||
DECL_CMD(search) {
|
||||
int sts = 0;
|
||||
int filecount = 0;
|
||||
int findcount = 0;
|
||||
vmscond_t sts = 0;
|
||||
vmscond_t confirm = ODS2_CONFIRM_ALL;
|
||||
options_t options;
|
||||
uint32_t filecount = 0;
|
||||
uint32_t findcount = 0;
|
||||
char res[NAM$C_MAXRSS + 1],rsa[NAM$C_MAXRSS + 1];
|
||||
register char firstch, *searstr, *searend, *s;
|
||||
struct NAM nam = cc$rms_nam;
|
||||
struct FAB fab = cc$rms_fab;
|
||||
struct RAB rab = cc$rms_rab;
|
||||
char *rec = NULL;
|
||||
mpos_t *mpos = NULL;
|
||||
uint32_t *mind = NULL;
|
||||
int theight;
|
||||
pause_t *pause = NULL, pausectl;
|
||||
char highlight[sizeof(CSI ";1;4;5;7m")];
|
||||
struct sstr {
|
||||
void *ctx;
|
||||
int slen;
|
||||
char *string;
|
||||
} *sstr, *ss;
|
||||
int nstrings;
|
||||
uint32_t match_type;
|
||||
struct NAM nam;
|
||||
struct FAB fab;
|
||||
struct RAB rab;
|
||||
|
||||
UNUSED(argc);
|
||||
UNUSED(qualc);
|
||||
UNUSED(qualv);
|
||||
memset( res, 0, sizeof(res) );
|
||||
memset( rsa, 0, sizeof(rsa) );
|
||||
memset( &pausectl, 0, sizeof(pausectl) );
|
||||
|
||||
searstr = argv[2]; /* unquote( argv[2] ); */
|
||||
if( !CWS ) {
|
||||
unsigned int i;
|
||||
|
||||
searend = searstr + strlen( searstr );
|
||||
for ( s = searstr; s < searend; s++ ) {
|
||||
*s = tolower( *s );
|
||||
for( i = 0; i < 256; i++ ) {
|
||||
if( isprint( i ) )
|
||||
CW[i] = 1;
|
||||
else if( i < 32 )
|
||||
CW[i] = 2 + (unsigned char)strlen( C0[i] );
|
||||
else if( i == '\177' )
|
||||
CW[i] = sizeof( "<DEL>" ) -1;
|
||||
else if( i >= 0x80ul && i <= 0xA0ul )
|
||||
CW[i] = 2 + (unsigned char)strlen( C1[i - 0x80ul] );
|
||||
else
|
||||
CW[i] = sizeof( "<xx>" ) -1;
|
||||
}
|
||||
CWS = TRUE;
|
||||
}
|
||||
firstch = *searstr++;
|
||||
filecount = 0;
|
||||
findcount = 0;
|
||||
|
||||
(void) termchar( NULL, &theight );
|
||||
height = theight-1;
|
||||
|
||||
if( search_defopt != NULL ) {
|
||||
if( $FAILS(sts = checkquals( &options, search_defaults, searchquals,
|
||||
search_defopt->qualc, search_defopt->qualv )) ) {
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
else
|
||||
options = search_defaults;
|
||||
|
||||
if( $FAILS(sts = checkquals( &options, options,
|
||||
searchquals, qualc, qualv )) )
|
||||
return sts;
|
||||
|
||||
match_type = (options & search_match) >> search_v_match;
|
||||
|
||||
if( options & search_page ) {
|
||||
pausectl.interval = height;
|
||||
pausectl.lineno = 0;
|
||||
pausectl.prompt = SEARCH_CONTINUE;
|
||||
pause = &pausectl;
|
||||
}
|
||||
|
||||
if( options & search_highlight ) {
|
||||
if( !(options &
|
||||
(search_bold|search_blink|search_underline|search_reverse|search_hardcopy)) )
|
||||
memcpy( highlight, CSI "1m", sizeof( CSI "1m" ) );
|
||||
else if( options & (search_bold|search_blink|search_underline|search_reverse) ) {
|
||||
memcpy( highlight, CSI, sizeof( CSI ) );
|
||||
if( options & search_bold )
|
||||
memcpy( highlight+strlen(highlight), ";1", sizeof( ";1" ) );
|
||||
if( options & search_blink )
|
||||
memcpy( highlight+strlen(highlight), ";5", sizeof( ";5" ) );
|
||||
if( options & search_reverse )
|
||||
memcpy( highlight+strlen(highlight), ";7", sizeof( ";7" ) );
|
||||
if( options & search_underline )
|
||||
memcpy( highlight+strlen(highlight), ";4", sizeof( ";4" ) );
|
||||
memcpy( highlight+strlen(highlight), "m", sizeof( "m" ) );
|
||||
} else
|
||||
highlight[0] = '\0';
|
||||
}
|
||||
|
||||
nstrings = argc - 2;
|
||||
if( (sstr = calloc( nstrings, sizeof( struct sstr ) )) == NULL ) {
|
||||
return printmsg( SS$_INSFMEM, 0 );
|
||||
}
|
||||
|
||||
if( options & search_confirm )
|
||||
confirm = SEARCH_CONFIRM;
|
||||
|
||||
nam = cc$rms_nam;
|
||||
fab = cc$rms_fab;
|
||||
rab = cc$rms_rab;
|
||||
rab.rab$l_fab = &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 & STS$M_SUCCESS ) {
|
||||
nam.nam$l_rsa = rsa;
|
||||
nam.nam$b_rss = NAM$C_MAXRSS;
|
||||
fab.fab$l_fop = FAB$M_NAM;
|
||||
while ( ( sts = sys_search( &fab ) ) & STS$M_SUCCESS ) {
|
||||
sts = sys_open(&fab);
|
||||
if ( !( sts & STS$M_SUCCESS ) ) {
|
||||
printf("%%SEARCH-F-OPENFAIL, Open error: %s\n",getmsg(sts, MSG_TEXT));
|
||||
} else {
|
||||
rab.rab$l_fab = &fab;
|
||||
sts = sys_connect( &rab );
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
int printname = 1;
|
||||
char *rec;
|
||||
|
||||
if( (rec = malloc( MAXREC + 2 )) == NULL )
|
||||
sts = SS$_INSFMEM;
|
||||
else {
|
||||
filecount++;
|
||||
rab.rab$l_ubf = rec;
|
||||
rab.rab$w_usz = MAXREC;
|
||||
while( (sts = sys_get( &rab )) & STS$M_SUCCESS ) {
|
||||
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"
|
||||
);
|
||||
printf( "%s\n\n", rsa );
|
||||
printname = 0;
|
||||
}
|
||||
fputs( rec, stdout );
|
||||
if( fab.fab$b_rat & PRINT_ATTR ) {
|
||||
fputc( '\n', stdout );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free( rec );
|
||||
rec = NULL;
|
||||
}
|
||||
sys_disconnect(&rab);
|
||||
}
|
||||
if (sts == SS$_NOTINSTALL) {
|
||||
printf(
|
||||
"%%SEARCH-W-NOIMPLEM, file operation not implemented\n"
|
||||
);
|
||||
sts = SS$_NORMAL;
|
||||
}
|
||||
sys_close(&fab);
|
||||
fab.fab$l_nam = &nam;
|
||||
fab.fab$b_fac = FAB$M_GET;
|
||||
fab.fab$l_fna = argv[1];
|
||||
fab.fab$b_fns = (uint8_t)strlen(fab.fab$l_fna);
|
||||
|
||||
do {
|
||||
int i;
|
||||
|
||||
if( (mind = malloc( (size_t)4u * ((MAXREC + 2u + 31u) / 32u) )) == NULL ) {
|
||||
sts = printmsg( SS$_INSFMEM, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
for( ss = sstr, i = 0; i < nstrings; ss++, i++ ) {
|
||||
ss->string = argv[2 + i];
|
||||
ss->slen = (int)strlen( ss->string);
|
||||
if( ss->slen < 1 ) {
|
||||
sts = printmsg( SEARCH_BADSTRING, 0, i + 1 );
|
||||
break;
|
||||
}
|
||||
if( !prep( !(options & search_exact),
|
||||
ss->string, ss->slen, &ss->ctx ) ) {
|
||||
sts = printmsg( SS$_INSFMEM, 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sts == RMS$_NMF || sts == RMS$_FNF) sts = SS$_NORMAL;
|
||||
}
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
if (filecount < 1) {
|
||||
printf("%%SEARCH-W-NOFILES, no files found\n");
|
||||
|
||||
if( $FAILS(sts = sys_parse(&fab)) ) {
|
||||
printmsg( SEARCH_PARSEFAIL, 0, fab.fab$l_fna );
|
||||
sts = printmsg( sts, MSG_CONTINUE, SEARCH_PARSEFAIL );
|
||||
break;
|
||||
}
|
||||
nam.nam$l_esa[nam.nam$b_esl] = '\0';
|
||||
nam.nam$l_rsa = rsa;
|
||||
nam.nam$b_rss = NAM$C_MAXRSS;
|
||||
fab.fab$l_fop = 0;
|
||||
|
||||
if( (rec = malloc( MAXREC + 2 )) == NULL ) {
|
||||
sts = printmsg( SS$_INSFMEM, 0 );
|
||||
break;
|
||||
}
|
||||
if( (mpos = malloc( MAXREC * sizeof( mpos_t ) )) == NULL ) {
|
||||
sts = printmsg( SS$_INSFMEM, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
while( TRUE ) {
|
||||
int32_t lineno, filefind;
|
||||
int first = TRUE;
|
||||
|
||||
if( $FAILS(sts = sys_search( &fab )) ) {
|
||||
if( $MATCHCOND(sts, RMS$_NMF) ) {
|
||||
sts = SS$_NORMAL;
|
||||
break;
|
||||
}
|
||||
printmsg( SEARCH_SEARCHFAIL, 0, nam.nam$l_esa );
|
||||
sts = printmsg( sts, MSG_CONTINUE, SEARCH_SEARCHFAIL );
|
||||
break;
|
||||
}
|
||||
nam.nam$l_rsa[ nam.nam$b_rsl ] = '\0';
|
||||
|
||||
if( $FAILS(sts = sys_open(&fab)) ) {
|
||||
printmsg( SEARCH_OPENIN, 0, nam.nam$l_rsa );
|
||||
sts = printmsg( sts, MSG_CONTINUE, SEARCH_OPENIN );
|
||||
continue;
|
||||
}
|
||||
if( $MATCHCOND( confirm, SEARCH_CONFIRM) )
|
||||
confirm = confirm_cmd( confirm, nam.nam$l_rsa);
|
||||
|
||||
if( !$MATCHCOND( confirm, ODS2_CONFIRM_ALL ) ) {
|
||||
if( $MATCHCOND( confirm, ODS2_CONFIRM_YES ) ) {
|
||||
confirm = SEARCH_CONFIRM;
|
||||
} else if( $MATCHCOND( confirm, ODS2_CONFIRM_NO ) ) {
|
||||
confirm = SEARCH_CONFIRM;
|
||||
sys_close( &fab );
|
||||
continue;
|
||||
} else { /* ODS2_CONFIRM_QUIT */
|
||||
sys_close( &fab );
|
||||
sts = confirm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( $FAILS(sts = sys_connect( &rab )) ) {
|
||||
printmsg( sts, 0 );
|
||||
sys_close( &fab );
|
||||
continue;
|
||||
}
|
||||
|
||||
filecount++;
|
||||
lineno = 0;
|
||||
filefind = 0;
|
||||
rab.rab$l_ubf = rec;
|
||||
rab.rab$w_usz = MAXREC;
|
||||
while( $SUCCESSFUL(sts = sys_get( &rab )) ) {
|
||||
int indent = 0, matched = 0, hl = FALSE;
|
||||
unsigned m;
|
||||
char *p;
|
||||
|
||||
++lineno;
|
||||
for( ss = sstr; ss < sstr + nstrings; ss++ ) {
|
||||
int nmat;
|
||||
|
||||
nmat = match( !(options & search_exact),
|
||||
ss->string, ss->slen,
|
||||
rec, rab.rab$w_rsz, mpos, ss->ctx );
|
||||
if( nmat <= 0 )
|
||||
continue;
|
||||
if( !matched++ )
|
||||
memset( mind, 0, 4u * (((size_t)rab.rab$w_rsz + 31u) / 32u) );
|
||||
for( i = 0; i < nmat; i++ )
|
||||
for( m = mpos[i]; m < (unsigned)(mpos[i] + ss->slen); m++ )
|
||||
mind[ m >> 5 ] |= UINT32_C(1) << (m & 31u);
|
||||
}
|
||||
if( match_type == MAT_OR ) {
|
||||
if( !(matched > 0) )
|
||||
continue;
|
||||
} else if( match_type == MAT_AND ) {
|
||||
if( !(matched == nstrings) )
|
||||
continue;
|
||||
} else if( match_type == MAT_NOR ) {
|
||||
if( !!(matched > 0) )
|
||||
continue;
|
||||
} else { /* MAT_NAND */
|
||||
if( !!(matched == nstrings) )
|
||||
continue;
|
||||
}
|
||||
findcount++;
|
||||
filefind++;
|
||||
if( first && !(options & search_nohead) &&
|
||||
((options & search_heading) ||
|
||||
(nam.nam$l_fnb & NAM$M_WILDCARD)) ) {
|
||||
first = FALSE;
|
||||
if( options & search_nowindow ) {
|
||||
printf( "%.*s", nam.nam$b_rsl, nam.nam$l_rsa );
|
||||
if( $FAILS(sts = put_c( '\n', stdout, pause )) )
|
||||
break;
|
||||
continue;
|
||||
} else {
|
||||
if( $FAILS(sts = put_str( "\n******************************\n",
|
||||
stdout, pause )) )
|
||||
break;
|
||||
printf( "%.*s", nam.nam$b_rsl, nam.nam$l_rsa );
|
||||
if( $FAILS(sts = put_strn( "\n\n", 2, stdout, pause )) )
|
||||
break;
|
||||
}
|
||||
} else if( options & search_nowindow )
|
||||
continue;
|
||||
|
||||
if( options & search_number )
|
||||
indent = printf( "%u: ", lineno );
|
||||
|
||||
for( m = 0, p = rec; p < rec + rab.rab$w_rsz; m++, p++ ) {
|
||||
if( matched && (options & search_highlight) ) {
|
||||
if( mind[ m >> 5 ] & (UINT32_C(1) << (m & 31u)) ) {
|
||||
if( !hl && highlight[0] )
|
||||
fputs( highlight, stdout );
|
||||
hl = TRUE;
|
||||
} else {
|
||||
if( hl && highlight[0] )
|
||||
fputs( CSI "m", stdout );
|
||||
hl = FALSE;
|
||||
}
|
||||
}
|
||||
if( isprint( *p & 0xFFul ) ) {
|
||||
putc( (*p & 0xFFul), stdout );
|
||||
} else if( (*p & 0xFFul) < 32 ) {
|
||||
printf( "<%s>", C0[*p & 0x1Ful] );
|
||||
} else if( *p == '\177' ) {
|
||||
printf( "<DEL>" );
|
||||
} else if( (*p & 0xFFul) >= 0x80ul &&
|
||||
(*p & 0xFFul) <= 0xA0ul ) { /* Special case A0 for code analysis */
|
||||
printf( "<%s>", C1[ ((*p & 0xFFul) == 0xA0ul)? 0x20ul :
|
||||
(((*p & 0xFFul) - 0x80ul) & 0x1Ful) ] );
|
||||
} else
|
||||
printf( "<%02lX>", (*p & 0xFFul) );
|
||||
}
|
||||
if( hl && highlight[0] )
|
||||
fputs( CSI "m", stdout );
|
||||
hl = FALSE;
|
||||
|
||||
if( $FAILS(sts = put_c( '\n', stdout, pause )) )
|
||||
break;
|
||||
|
||||
if( matched && (options & search_hardcopy) ) {
|
||||
unsigned e;
|
||||
|
||||
for( e = rab.rab$w_rsz; e > 0; --e )
|
||||
if( mind[ (e - 1) >> 5 ] & (UINT32_C(1) << ((e -1) & 31u)) )
|
||||
break;
|
||||
if( e > 0 ) {
|
||||
printf( "%*s", indent, "" );
|
||||
for( m = 0, p = rec; m < e; m++, p++ ) {
|
||||
int i;
|
||||
|
||||
for( i = 0; i < CW[*p & 0xFFul]; i++ )
|
||||
fputc( (mind[ m >> 5] & (UINT32_C(1) << (m & 31u)))?
|
||||
'^': ' ', stdout );
|
||||
}
|
||||
if( $FAILS(sts = put_c( '\n', stdout, pause)) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sys_disconnect( &rab );
|
||||
sys_close( &fab );
|
||||
if( options & search_log ) {
|
||||
if( filefind > 0 ) {
|
||||
printmsg( SEARCH_MATCHED, 0,
|
||||
nam.nam$l_rsa, lineno, filefind );
|
||||
} else {
|
||||
printmsg( SEARCH_FILE, 0, nam.nam$l_rsa, lineno );
|
||||
}
|
||||
}
|
||||
if( $MATCHCOND(sts, SS$_ABORT) )
|
||||
break;
|
||||
}
|
||||
} while( 0 );
|
||||
|
||||
for( ss = sstr; ss < sstr + nstrings; ss++ )
|
||||
free( ss->ctx );
|
||||
free( sstr );
|
||||
free( mind );
|
||||
free( rec );
|
||||
free( mpos );
|
||||
|
||||
fab.fab$b_fns =
|
||||
nam.nam$b_ess =
|
||||
fab.fab$b_dns = 0;
|
||||
nam.nam$l_rlf = NULL;
|
||||
nam.nam$b_nop = NAM$M_SYNCHK;
|
||||
(void) sys_parse( &fab ); /* Release context */
|
||||
|
||||
if( $SUCCESSFUL(sts) ||
|
||||
$MATCHCOND(sts, SS$_ABORT) || $MATCHCOND(sts, ODS2_CONFIRM_QUIT) ) {
|
||||
if( filecount < 1 ) {
|
||||
sts = printmsg( SEARCH_NOFILES, 0 );
|
||||
} else {
|
||||
if (findcount < 1) {
|
||||
printf("%%SEARCH-I-NOMATCHES, no strings matched\n");
|
||||
if( findcount < 1 ) {
|
||||
sts = printmsg( SEARCH_NOMATCH, 0 );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("%%SEARCH-F-ERROR Status: %s\n",getmsg(sts, MSG_TEXT));
|
||||
sts = printmsg(sts, 0 );
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
/***************************************************************** prep() */
|
||||
|
||||
static int prep( int fc, char *pattern, int plen, void **ctx ) {
|
||||
int i, j, k = 0;
|
||||
int *bm, *gm, *sx;
|
||||
|
||||
/* BM1977 */
|
||||
|
||||
*ctx = NULL;
|
||||
|
||||
#define AS (UCHAR_MAX+1)
|
||||
#define ALLOC(plen) ( (AS + plen) * sizeof( int ) )
|
||||
|
||||
if( (bm = (int *)malloc( ALLOC((size_t)plen) )) == NULL ) {
|
||||
return FALSE;
|
||||
}
|
||||
if( (sx = (int *)malloc( plen * sizeof( int ) )) == NULL ) {
|
||||
free( bm );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*ctx = bm;
|
||||
gm = bm + AS;
|
||||
|
||||
for( i = 0; i < AS; i++ ) {
|
||||
bm[i] = (int)plen;
|
||||
}
|
||||
j = plen - 1;
|
||||
if( fc ) {
|
||||
for( i = 0; i < j; i++ ) {
|
||||
pattern[i] = tolower( pattern[i] );
|
||||
bm[ (unsigned)(pattern[i] & 0xFFul) ] = j - i;
|
||||
}
|
||||
pattern[i] = tolower( pattern[i] & 0xFFul );
|
||||
} else
|
||||
for( i = 0; i < j; i++ ) {
|
||||
bm[ (unsigned)(pattern[i] & 0xFFul) ] = j - i;
|
||||
}
|
||||
sx[j] = plen;
|
||||
for( i = plen - 2; i >= 0; i-- ) {
|
||||
if( i > j && sx[ i + plen -1 - k ] < i - j ) {
|
||||
sx[i] = sx[ i + plen - 1 -k ];
|
||||
} else {
|
||||
if( i < j ) {
|
||||
j = i;
|
||||
}
|
||||
k = i;
|
||||
while( j >= 0 && pattern[j] == pattern[ j + plen - 1 - k ] ) {
|
||||
--j;
|
||||
}
|
||||
sx[i] = k - j;
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < plen; i++ ) {
|
||||
gm[i] = plen;
|
||||
}
|
||||
|
||||
k = plen - 1;
|
||||
for( j = 0, i = k; i >= 0; i-- ) {
|
||||
if( sx[i] == i + 1 ) {
|
||||
for( ; j < k - i; j++ ) {
|
||||
if( gm[j] == plen ) {
|
||||
gm[j] = k - i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i = 0; i <= plen - 2; i++ ) {
|
||||
gm[ k - sx[i] ] = k - i;
|
||||
}
|
||||
free( sx );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***************************************************************** match() */
|
||||
|
||||
static int match( int fc, char *pattern, int plen,
|
||||
char *data, int dlen, mpos_t *mpos, void *ctx ) {
|
||||
int i, j, n = 0;
|
||||
int *bm, *gm;
|
||||
|
||||
bm = ctx;
|
||||
gm = bm + AS;
|
||||
|
||||
if( fc ) {
|
||||
for( j = 0; j <= dlen - plen; ) {
|
||||
for( i = plen -1;
|
||||
i >= 0 && pattern[i] == tolower( data[i + j] & 0xFFul ); i-- )
|
||||
;
|
||||
if( i < 0 ) {
|
||||
if( mpos != NULL )
|
||||
mpos[ n ] = j;
|
||||
++n;
|
||||
j += gm[0];
|
||||
} else {
|
||||
int g, b;
|
||||
|
||||
g = gm[i];
|
||||
b = bm[ (unsigned)(tolower( data[i + j] & 0xFFul )
|
||||
& 0xFFul) ] - plen + 1 + i;
|
||||
j += (g > b)? g: b;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
for( j = 0; j <= dlen - plen; ) {
|
||||
for( i = plen -1; i >= 0 && pattern[i] == data[i + j]; i-- )
|
||||
;
|
||||
if( i < 0 ) {
|
||||
if( mpos != NULL )
|
||||
mpos[ n ] = j;
|
||||
++n;
|
||||
j += gm[0];
|
||||
} else {
|
||||
int g, b;
|
||||
|
||||
g = gm[i];
|
||||
b = bm[ (unsigned)(data[i + j] & 0xFFul) ] - plen + 1 + i;
|
||||
j += (g > b)? g: b;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_SETCMD )
|
||||
@@ -17,89 +20,271 @@
|
||||
|
||||
#include "cmddef.h"
|
||||
|
||||
#ifdef USE_LIBEDIT
|
||||
#include <histedit.h>
|
||||
extern EditLine *editline;
|
||||
extern History *edithist;
|
||||
#endif
|
||||
|
||||
static hlpfunc_t sethelp;
|
||||
|
||||
static unsigned setcwd( char *newdef );
|
||||
static unsigned setdef( char *newdef );
|
||||
static vmscond_t setcwd( char *newdef );
|
||||
static vmscond_t setdef( char *newdef );
|
||||
|
||||
static vmscond_t savequals( options_t defval, qual_t *qp,
|
||||
int qualc, char **qualv,
|
||||
defqualsp_t *saveloc );
|
||||
static void set_exit( void );
|
||||
|
||||
|
||||
/******************************************************************* doset() */
|
||||
|
||||
static qual_t setkwds[] = { {"cwd", 0, 0, NV, "Working directory on local system"},
|
||||
{"directory_qualifiers", 1, 0, NV, "Default qualifiers for DIRECTORY command" },
|
||||
{"default", 2, 0, NV, "Default directory on VMS volume"},
|
||||
{"qualifier_style", 3, 0, NV, "Qualifier style (Unix, VMS)"},
|
||||
{"verify", 4, 0, NV, "-Display commands in indirect files"},
|
||||
{"noverify", 5, 0, NV, NULL },
|
||||
{NULL, 0, 0, NV, NULL }
|
||||
#define set_msgdef OPT_GENERIC_1
|
||||
|
||||
/* Indexes must match in doset() & sethelp() */
|
||||
|
||||
static uint32_t histmax;
|
||||
|
||||
static
|
||||
qual_t setkwds[] = { {"cwd", 0, 0, NV,
|
||||
"commands set item_name item_cwd"},
|
||||
{"directory_qualifiers", 1, 0, NV,
|
||||
"commands set item_name item_dirquals"},
|
||||
{"copy_qualifiers", 2, 0, NV,
|
||||
"commands set item_name item_copyquals" },
|
||||
{"default", 3, 0, NV,
|
||||
"commands set item_name item_setdef"},
|
||||
{"error_exit", 4, 0, NV,
|
||||
"-commands set item_name item_seterrxit"},
|
||||
{"noerror_exit", 5, 0, NV, NULL },
|
||||
{"message", 6, 0, NV,
|
||||
"commands set item_name item_setmsg"},
|
||||
{"qualifier_style", 7, 0, NV,
|
||||
"commands set item_name item_qualstyle"},
|
||||
{"search_qualifiers", 8, 0, NV,
|
||||
"commands set item_name item_searchquals"},
|
||||
{"verify", 9, 0, NV,
|
||||
"-commands set item_name item_verify"},
|
||||
{"noverify", 10, 0, NV, NULL },
|
||||
#ifdef USE_LIBEDIT
|
||||
{"key_bindings", 11, 0, NV,
|
||||
"commands set item_name item_key_bindings"},
|
||||
#endif
|
||||
{"history_limit", 12, 0, DV(&histmax),
|
||||
"commands set item_name item_history_limit"},
|
||||
{"help_file", 13, 0, NV,
|
||||
"commands set item_name item_helpfile"},
|
||||
|
||||
{NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
static qual_t setqskwds[] = {{"unix", 1, 0, NV, "Unix style options, '-option'"},
|
||||
{"vms", 2, 0, NV, "VMS style qualifiers, '/qualifier'"},
|
||||
{NULL, 0, 0, NV, NULL }
|
||||
|
||||
static
|
||||
qual_t setmsgkwdsp[] = {{"facility", MSG_FACILITY, 0, NV,
|
||||
"commands set item_name item_msgfac"},
|
||||
{"nofacility", 0, MSG_FACILITY, NV, NULL},
|
||||
{"severity", MSG_SEVERITY, 0, NV,
|
||||
"commands set item_name item_msgsev"},
|
||||
{"noseverity", 0, MSG_SEVERITY, NV, NULL},
|
||||
{"identification", MSG_NAME, 0, NV,
|
||||
"commands set item_name item_msgid"},
|
||||
{"noidentification", 0, MSG_NAME, NV, NULL},
|
||||
{"text", MSG_TEXT, 0, NV,
|
||||
"commands set item_name item_msgtext"},
|
||||
{"notext", 0, MSG_TEXT, NV, NULL},
|
||||
{"default", set_msgdef, 0, NV,
|
||||
"commands set item_name item_default"},
|
||||
|
||||
{NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
|
||||
static
|
||||
qual_t setqskwds[] = {{"unix", 1, 0, NV, "commands set value value_unix"},
|
||||
{"dcl", 2, 0, NV, "commands set value value_dcl"},
|
||||
{"vms", 2, 0, NV, NULL },
|
||||
|
||||
{NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
param_t setpars[] = { {"item_name", REQ, KEYWD, PA(setkwds), "" },
|
||||
{"value" , CND, KEYWD, sethelp, setqskwds, "" },
|
||||
|
||||
{NULL, 0, 0, NOPA, NULL },
|
||||
};
|
||||
|
||||
/*********************************************************** doset() */
|
||||
|
||||
extern qual_t copyquals[];
|
||||
extern const int copy_defaults;
|
||||
extern defqualsp_t copy_defopt;
|
||||
|
||||
extern qual_t dirquals[];
|
||||
extern const int dir_defaults;
|
||||
extern int dir_defopt;
|
||||
extern defqualsp_t dir_defopt;
|
||||
|
||||
extern qual_t searchquals[];
|
||||
extern const int search_defaults;
|
||||
extern defqualsp_t search_defopt;
|
||||
|
||||
extern uint32_t cmd_histsize;
|
||||
|
||||
DECL_CMD(set) {
|
||||
int parnum;
|
||||
options_t parnum;
|
||||
vmscond_t sts;
|
||||
|
||||
UNUSED(argc);
|
||||
|
||||
parnum = checkquals( 0, setkwds, -1, argv+1 );
|
||||
if( $FAILS(sts = checkquals( &parnum, 0, setkwds, -1, argv+1 )) ) {
|
||||
return sts;
|
||||
}
|
||||
switch( parnum ) {
|
||||
default:
|
||||
return SS$_BADPARAM;
|
||||
case 0: /* default */
|
||||
case 2: /* current working directory */
|
||||
if( qualc ) {
|
||||
printf( "%%ODS2-E-NOQUAL, No qualifiers are permitted\n" );
|
||||
return 0;
|
||||
}
|
||||
case 3: /* current working directory */
|
||||
if( qualc )
|
||||
return printmsg( ODS2_NOQUALSOK, 0 );
|
||||
return (parnum == 0)? setcwd( argv[2] ) : setdef( argv[2] );
|
||||
case 1:{ /* directory_qualifiers */
|
||||
int options = checkquals(dir_defaults,dirquals,qualc,qualv);
|
||||
if( options == -1 )
|
||||
return SS$_BADPARAM;
|
||||
dir_defopt = options;
|
||||
return 1;
|
||||
if( qualc == 0 )
|
||||
return printmsg( ODS2_NOQUALS, 0 );
|
||||
return savequals( dir_defaults, dirquals,
|
||||
qualc, qualv, &dir_defopt );
|
||||
}
|
||||
case 3: { /* qualifier_style */
|
||||
int par = checkquals (0,setqskwds,1,argv+2);
|
||||
if( par == -1 )
|
||||
return SS$_BADPARAM;
|
||||
case 2:{ /* copy_qualifiers */
|
||||
if( qualc == 0 )
|
||||
return printmsg( ODS2_NOQUALS, 0 );
|
||||
return savequals( copy_defaults, copyquals,
|
||||
qualc, qualv, ©_defopt );
|
||||
}
|
||||
case 4:
|
||||
if( qualc )
|
||||
return printmsg( ODS2_NOQUALSOK, 0 );
|
||||
error_exit = TRUE;
|
||||
return SS$_NORMAL;
|
||||
case 5:
|
||||
if( qualc )
|
||||
return printmsg( ODS2_NOQUALSOK, 0 );
|
||||
error_exit = FALSE;
|
||||
return SS$_NORMAL;
|
||||
case 6: { /* message file */
|
||||
options_t options;
|
||||
|
||||
if( qualc != 0 ) {
|
||||
if( $FAILS(sts = checkquals( &options, get_message_format(),
|
||||
setmsgkwdsp, qualc, qualv )) )
|
||||
return sts;
|
||||
if( argc > 2 )
|
||||
return printmsg( ODS2_NOPAROK, 0 );
|
||||
if( options & set_msgdef ) {
|
||||
if( (options & ~set_msgdef) != get_message_format() )
|
||||
return printmsg( ODS2_INCONQUAL, 0 );
|
||||
return set_message_file( NULL );
|
||||
}
|
||||
if( $FAILS(sts = set_message_format( options )) )
|
||||
return printmsg( sts, 0 );
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
if( argc > 3 )
|
||||
return printmsg( ODS2_TOOMANY, 0, "parameters" );
|
||||
if( argc < 3 )
|
||||
return printmsg( ODS2_TOOFEW, 0, "parameters" );
|
||||
if( $FAILS(sts = set_message_file( argv[2] )) )
|
||||
return printmsg(sts, 0 );
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
case 7: { /* qualifier_style */
|
||||
options_t par;
|
||||
|
||||
if( qualc )
|
||||
return printmsg( ODS2_NOQUALSOK, 0 );
|
||||
if( $FAILS(sts = checkquals( &par, 0, setqskwds, 1, argv+2 )) ) {
|
||||
return sts;
|
||||
}
|
||||
switch(par) {
|
||||
default:
|
||||
abort();
|
||||
case 2:
|
||||
vms_qual = 1;
|
||||
qstyle_s = "/";
|
||||
break;
|
||||
case 1:
|
||||
vms_qual = 0;
|
||||
qstyle_s = "-";
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
case 4:
|
||||
verify_cmd = 1;
|
||||
return 1;
|
||||
case 5:
|
||||
verify_cmd = 0;
|
||||
return 1;
|
||||
case 8:{ /* search_qualifiers */
|
||||
if( qualc == 0 )
|
||||
return printmsg( ODS2_NOQUALS, 0 );
|
||||
return savequals( search_defaults, searchquals,
|
||||
qualc, qualv, &search_defopt );
|
||||
}
|
||||
case 9:
|
||||
if( qualc )
|
||||
return printmsg( ODS2_NOQUALSOK, 0 );
|
||||
verify_cmd = TRUE;
|
||||
return SS$_NORMAL;
|
||||
case 10:
|
||||
if( qualc )
|
||||
return printmsg( ODS2_NOQUALSOK, 0 );
|
||||
verify_cmd = FALSE;
|
||||
return SS$_NORMAL;
|
||||
#ifdef USE_LIBEDIT
|
||||
case 11: {
|
||||
char *av[20];
|
||||
int i, ac;
|
||||
|
||||
ac = argc -2;
|
||||
for( i = 0; i < 20; i++ ) {
|
||||
if( i < ac )
|
||||
av[i] = argv[i+2];
|
||||
else
|
||||
av[i] = NULL;
|
||||
}
|
||||
|
||||
el_set( editline, EL_BIND,
|
||||
av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7],
|
||||
av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15],
|
||||
av[16], av[17], av[18], NULL );
|
||||
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
#endif
|
||||
case 12: {
|
||||
#ifdef USE_LIBEDIT
|
||||
HistEvent ev;
|
||||
|
||||
if( qualc )
|
||||
return printmsg( ODS2_NOQUALSOK, 0 );
|
||||
if( histmax < 1 )
|
||||
return printmsg( HELP_SETCMDHISTVAL, 0 );
|
||||
if( history( edithist, &ev, H_SETSIZE, histmax ) >= 0 ) {
|
||||
cmd_histsize = histmax;
|
||||
}
|
||||
#else
|
||||
if( qualc )
|
||||
return printmsg( ODS2_NOQUALSOK, 0 );
|
||||
if( histmax < 1 )
|
||||
return printmsg( HELP_SETCMDHISTVAL, 0 );
|
||||
cmd_histsize = histmax;
|
||||
#endif
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
case 13:
|
||||
if( qualc )
|
||||
return printmsg( ODS2_NOQUALSOK, 0 );
|
||||
if( argc > 3 )
|
||||
return printmsg( ODS2_TOOMANY, 0, "parameters" );
|
||||
if( argc < 3 )
|
||||
return printmsg( ODS2_TOOFEW, 0, "parameters" );
|
||||
if( $FAILS(sts = sethelpfile( argv[2], NULL, NULL )) )
|
||||
return printmsg( sts, 0 );
|
||||
return sts;
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
/************************************************************ sethelp() */
|
||||
|
||||
static const char * sethelp( CMDSETp_t cmd, paramp_t p, int argc, char **argv ) {
|
||||
int par;
|
||||
static const char *sethelp( CMDSETp_t cmd, paramp_t p,
|
||||
int argc, char **argv ) {
|
||||
options_t par;
|
||||
vmscond_t sts;
|
||||
|
||||
UNUSED( cmd );
|
||||
UNUSED( argc );
|
||||
@@ -108,37 +293,73 @@ static const char * sethelp( CMDSETp_t cmd, paramp_t p, int argc, char **argv )
|
||||
p->helpstr = "";
|
||||
p->ptype = KEYWD;
|
||||
p->arg = setkwds;
|
||||
return "Type 'help set value ITEM' for item details\n";
|
||||
return getmsg( HELP_SETVALUE, MSG_TEXT );
|
||||
}
|
||||
|
||||
par = checkquals( 0, setkwds, -1, argv+1 );
|
||||
if( par == -1 )
|
||||
if( $FAILS(sts = checkquals( &par, 0, setkwds, -1, argv+1 )) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch( par ) {
|
||||
case 0:
|
||||
p->helpstr = "working directory for local files";
|
||||
p->helpstr = "commands set item_name type_cwd";
|
||||
p->ptype = STRING;
|
||||
break;
|
||||
case 1:
|
||||
p->helpstr = "default directory on volume";
|
||||
p->ptype = VMSFS;
|
||||
break;
|
||||
case 2:
|
||||
p->helpstr = "directory qualifier name ";
|
||||
p->ptype = KEYWD;
|
||||
p->helpstr = "commands set item_name type_dirquals";
|
||||
p->ptype = QUALS;
|
||||
p->arg = dirquals;
|
||||
break;
|
||||
case 2:
|
||||
p->helpstr = "commands set item_name type_copyquals";
|
||||
p->ptype = QUALS;
|
||||
p->arg = copyquals;
|
||||
break;
|
||||
case 3:
|
||||
p->helpstr = "style ";
|
||||
p->ptype = KEYWD;
|
||||
p->arg = setqskwds;
|
||||
p->helpstr = "commands set item_name type_setdef";
|
||||
p->ptype = FSPEC;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
p->helpstr = "commands set item_name type_seterrxit";
|
||||
p->ptype = NONE;
|
||||
break;
|
||||
case 6:
|
||||
p->helpstr = "commands set item_name type_setmsg";
|
||||
p->ptype = QUALS;
|
||||
p->arg = setmsgkwdsp;
|
||||
break;
|
||||
case 7:
|
||||
p->helpstr = "commands set item_name type_qualstyle";
|
||||
p->ptype = KEYWD;
|
||||
p->arg = setqskwds;
|
||||
break;
|
||||
case 8:
|
||||
p->helpstr = "commands set item_name type_searchquals";
|
||||
p->ptype = QUALS;
|
||||
p->arg = searchquals;
|
||||
break;
|
||||
case 9:
|
||||
case 10:
|
||||
p->helpstr = "commands set item_name item_verify";
|
||||
p->ptype = NONE;
|
||||
break;
|
||||
#ifdef USE_LIBEDIT
|
||||
case 11:
|
||||
p->helpstr = "commands set item_name item_key_bindings";
|
||||
p->ptype = STRING;
|
||||
break;
|
||||
#endif
|
||||
case 12:
|
||||
p->helpstr = "commands set item_name item_history_limit";
|
||||
p->ptype = STRING;
|
||||
break;
|
||||
case 13:
|
||||
p->helpstr = "commands set item_name item_helpfile";
|
||||
p->ptype = NONE;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf( stderr, "Missing help key for param %d\n", par );
|
||||
abort();
|
||||
}
|
||||
return NULL;
|
||||
@@ -146,37 +367,39 @@ static const char * sethelp( CMDSETp_t cmd, paramp_t p, int argc, char **argv )
|
||||
|
||||
/*********************************************************** setcwd() */
|
||||
|
||||
static unsigned setcwd( char *newdef ) {
|
||||
static vmscond_t setcwd( char *newdef ) {
|
||||
if( chdir( newdef ) != 0 ) {
|
||||
printf( "%%ODS2-W-SETDEF, Error %s setting cwd to %s\n",
|
||||
strerror( errno ), newdef );
|
||||
return SS$_BADPARAM;
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( ODS2_SETCWD, 0 );
|
||||
return printmsg( ODS2_OSERROR, MSG_CONTINUE, ODS2_SETCWD,
|
||||
strerror( err ) );
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/*********************************************************** setdef() */
|
||||
|
||||
static int default_set = FALSE;
|
||||
|
||||
static unsigned setdef( char *newdef ) {
|
||||
register unsigned sts;
|
||||
struct dsc_descriptor defdsc;
|
||||
static vmscond_t setdef( char *newdef ) {
|
||||
register vmscond_t sts;
|
||||
struct dsc_descriptor defdsc = { 0, 0, 0, NULL };
|
||||
|
||||
defdsc.dsc_a_pointer = (char *) newdef;
|
||||
defdsc.dsc_w_length = (unsigned short)strlen( defdsc.dsc_a_pointer );
|
||||
sts = sys_setddir( &defdsc, NULL, NULL );
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
if( $SUCCESSFUL(sts = sys_setddir( &defdsc, NULL, NULL )) ) {
|
||||
default_set = TRUE;
|
||||
} else {
|
||||
printf( "%%ODS2-E-SETDEF, Error %s setting default to %s\n", getmsg(sts, MSG_TEXT), newdef );
|
||||
sts = printmsg( sts, 0 );
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
/*********************************************************** mountdef() */
|
||||
|
||||
int mountdef( const char *devnam ) {
|
||||
vmscond_t mountdef( const char *devnam ) {
|
||||
char *colon, *buf;
|
||||
size_t len;
|
||||
|
||||
@@ -184,10 +407,9 @@ int mountdef( const char *devnam ) {
|
||||
return SS$_NORMAL;
|
||||
|
||||
len = strlen( devnam );
|
||||
buf = (char *) malloc( len + sizeof( ":[000000]" ));
|
||||
buf = (char *) malloc( len + sizeof( ":[000000]" ) );
|
||||
if( buf == NULL ) {
|
||||
perror( "malloc" );
|
||||
return SS$_INSFMEM;
|
||||
return printmsg( ODS2_OSERROR, 0, strerror( errno ) );
|
||||
}
|
||||
|
||||
colon = strchr( devnam, ':' );
|
||||
@@ -195,8 +417,82 @@ int mountdef( const char *devnam ) {
|
||||
len = (size_t)(colon - devnam);
|
||||
memcpy( buf, devnam, len );
|
||||
memcpy( buf+len, ":[000000]", sizeof( ":[000000]" ) );
|
||||
setdef(buf);
|
||||
setdef( buf );
|
||||
free( buf );
|
||||
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/************************************************************ savequals() */
|
||||
|
||||
static defqualsp_t savedquals = NULL;
|
||||
|
||||
static vmscond_t savequals( options_t defval, qual_t *qp,
|
||||
int qualc, char **qualv,
|
||||
defqualsp_t *saveloc ) {
|
||||
vmscond_t sts;
|
||||
int i;
|
||||
size_t len;
|
||||
defqualsp_t newq, *old;
|
||||
char *dp;
|
||||
|
||||
len = ( offsetof( defquals_t, data ) +
|
||||
( sizeof( char** ) * ((size_t)qualc +1) ) );
|
||||
|
||||
for( i = 0; i < qualc; i++ )
|
||||
len += strlen( qualv[i] ) + 1;
|
||||
|
||||
if( (newq = (defqualsp_t) malloc( len )) == NULL )
|
||||
return SS$_INSFMEM;
|
||||
|
||||
newq->qualc = qualc;
|
||||
newq->qualv = newq->data;
|
||||
|
||||
dp = (char *)(newq->data + qualc + 1);
|
||||
|
||||
for( i = 0; i < qualc; i++ ) {
|
||||
newq->qualv[i] = dp;
|
||||
len = strlen( qualv[i] ) +1;
|
||||
memcpy( dp, qualv[i], len );
|
||||
dp += len;
|
||||
}
|
||||
newq->qualv[i] = NULL;
|
||||
|
||||
if( $FAILS(sts = checkquals( &defval, defval, qp, qualc, qualv )) ) {
|
||||
free( newq );
|
||||
return sts;
|
||||
}
|
||||
|
||||
for( old = &savedquals; *old != NULL; old = &(*old)->next ) {
|
||||
defqualsp_t t;
|
||||
|
||||
if( (t = *old) == *saveloc ) {
|
||||
*old = t->next;
|
||||
free( t );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
newq->next = savedquals;
|
||||
|
||||
if( savedquals == NULL )
|
||||
atexit( set_exit );
|
||||
|
||||
*saveloc =
|
||||
savedquals = newq;
|
||||
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/************************************************************ set_exit() */
|
||||
static void set_exit( void ) {
|
||||
defqualsp_t sq;
|
||||
|
||||
while( (sq = savedquals) != NULL ) {
|
||||
savedquals = sq->next;
|
||||
free( sq );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_SHOWCMD )
|
||||
@@ -17,16 +20,16 @@
|
||||
|
||||
#include "cmddef.h"
|
||||
|
||||
#ifdef USE_READLINE
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _XOPEN_SOURCE
|
||||
#endif
|
||||
#include <readline/readline.h>
|
||||
#ifdef USE_LIBEDIT
|
||||
#include <histedit.h>
|
||||
#else
|
||||
extern FILE *histfile;
|
||||
#endif
|
||||
|
||||
#include "access.h"
|
||||
#include "cache.h"
|
||||
#include "direct.h"
|
||||
#include "f11def.h"
|
||||
#include "phyio.h"
|
||||
#ifdef USE_VHD
|
||||
#include "phyvhd.h"
|
||||
@@ -34,40 +37,95 @@
|
||||
#include "phyvirt.h"
|
||||
#include "version.h"
|
||||
|
||||
extern defqualsp_t copy_defopt;
|
||||
extern qual_t copyquals[];
|
||||
|
||||
extern defqualsp_t dir_defopt;
|
||||
extern qual_t dirquals[];
|
||||
|
||||
extern defqualsp_t search_defopt;
|
||||
extern qual_t searchquals[];
|
||||
|
||||
static unsigned show_defq( defqualsp_t defs,
|
||||
qualp_t qualset, const char *name );
|
||||
|
||||
static unsigned show_stats( void );
|
||||
|
||||
void show_version( void );
|
||||
static vmscond_t show_history( int qualc, char **qualv );
|
||||
|
||||
void show_version( int full );
|
||||
|
||||
static char *get_cwd( void );
|
||||
|
||||
|
||||
/******************************************************************* doshow() */
|
||||
|
||||
static qual_t showkwds[] = { {"cwd", 0, 0, NV, "Working directory on local system"},
|
||||
{"default", 1, 0, NV, "Default directory on VMS volume"},
|
||||
{"devices", 2, 0, NV, "Devices"},
|
||||
{"qualifier_style", 3, 0, NV, "Qualifier style (Unix, VMS)" },
|
||||
{"statistics", 4, 0, NV, "Debugging statistics"},
|
||||
{"time", 5, 0, NV, "Time"},
|
||||
{"verify", 6, 0, NV, "Command file echo" },
|
||||
{"version", 7, 0, NV, "Version"},
|
||||
{"volumes", 8, 0, NV, "Mounted volume information" },
|
||||
{NULL, 0, 0, NV, NULL }
|
||||
#define hist_max OPT_SHARED_20
|
||||
static uint32_t histmax;
|
||||
static
|
||||
qual_t histquals[] = { {"max-entries", hist_max, 0, DV(&histmax),
|
||||
"commands history qual_maxent"},
|
||||
{NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
|
||||
static
|
||||
qual_t showkwds[] = { {"cwd", 0, ~0u, NV,
|
||||
"commands show copy"},
|
||||
{"default", 1, ~0u, NV,
|
||||
"commands show default"},
|
||||
{"devices", 2, ~0u, NV,
|
||||
"commands show devices"},
|
||||
{"qualifier_style", 3, ~0u, NV,
|
||||
"commands show qstyle" },
|
||||
{"statistics", 4, ~0u, NV,
|
||||
"commands show statistics"},
|
||||
{"terminal", 5, ~0u, NV,
|
||||
"commands show terminal"},
|
||||
{"time", 6, ~0u, NV,
|
||||
"commands show time"},
|
||||
{"verify", 7, ~0u, NV,
|
||||
"commands show verify" },
|
||||
{"version", 8, ~0u, NV,
|
||||
"commands show version"},
|
||||
{"volumes", 9, ~0u, NV,
|
||||
"commands show volumes"},
|
||||
{"directory_qualifiers",
|
||||
10, ~0u, NV,
|
||||
"commands show directory"},
|
||||
{"copy_qualifiers",
|
||||
11, ~0u, NV,
|
||||
"commands show copy"},
|
||||
{"message", 12, ~0u, NV,
|
||||
"commands show message"},
|
||||
{"search_qualifiers",
|
||||
13, ~0u, NV,
|
||||
"commands show search"},
|
||||
{"history", 14, ~0u, NV,
|
||||
"commands show history"},
|
||||
{"help_file", 15, ~0u, NV,
|
||||
"commands show helpfile"},
|
||||
|
||||
{NULL, 0, 0, NV, NULL }
|
||||
};
|
||||
param_t showpars[] = { {"item_name", REQ, KEYWD, PA(showkwds), "" },
|
||||
{"selector", OPT|NOLIM, STRING, NOPA, NULL},
|
||||
|
||||
{NULL, 0, 0, NOPA, NULL }
|
||||
};
|
||||
|
||||
/*********************************************************** doshow() */
|
||||
|
||||
DECL_CMD(show) {
|
||||
int parnum;
|
||||
options_t parnum;
|
||||
vmscond_t sts;
|
||||
|
||||
UNUSED(argc);
|
||||
UNUSED(qualc);
|
||||
UNUSED(qualv);
|
||||
|
||||
parnum = checkquals( 0, showkwds, -1, argv+1 );
|
||||
if( $FAILS(sts = checkquals( &parnum, 0, showkwds, -1, argv+1 )) ) {
|
||||
return sts;
|
||||
}
|
||||
|
||||
switch( parnum ) {
|
||||
default:
|
||||
return SS$_BADPARAM;
|
||||
@@ -78,72 +136,151 @@ DECL_CMD(show) {
|
||||
if( cwd == NULL ) {
|
||||
return SS$_BADPARAM;
|
||||
}
|
||||
printf( " Current working directory is %s\n", cwd );
|
||||
printmsg( HELP_SHOWCWD, MSG_TEXT, cwd );
|
||||
free( cwd );
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
case 1: {
|
||||
int sts;
|
||||
unsigned short curlen;
|
||||
char curdir[NAM$C_MAXRSS + 1];
|
||||
char curdir[NAM$C_MAXRSS + 1] = { "" };
|
||||
struct dsc_descriptor curdsc;
|
||||
struct FAB fab;
|
||||
struct NAM nam;
|
||||
|
||||
memset( &curdsc, 0, sizeof( curdsc ) );
|
||||
curdsc.dsc_w_length = NAM$C_MAXRSS;
|
||||
curdsc.dsc_a_pointer = curdir;
|
||||
sts = sys_setddir( NULL, &curlen, &curdsc );
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
curdir[curlen] = '\0';
|
||||
puts( curdir );
|
||||
} else {
|
||||
printf("%%ODS2-E-GETDEF, Error %s getting default\n",getmsg(sts, MSG_TEXT));
|
||||
|
||||
if( $FAILS(sts = sys_setddir( NULL, &curlen, &curdsc )) ) {
|
||||
return printmsg( sts, 0 );
|
||||
}
|
||||
|
||||
fab = cc$rms_fab;
|
||||
nam = cc$rms_nam;
|
||||
|
||||
nam.nam$b_ess = sizeof(curdir) -1;
|
||||
nam.nam$l_esa = curdir;
|
||||
fab.fab$l_nam = &nam;
|
||||
fab.fab$l_fna = curdir;
|
||||
fab.fab$b_fns = (uint8_t)curlen;
|
||||
|
||||
if( $FAILS(sts = sys_parse(&fab)) ) {
|
||||
curdir[curlen] = '\0';
|
||||
sts = printmsg( ODS2_INVDEF, 0, curdir );
|
||||
} else {
|
||||
curdir[nam.nam$b_dev+nam.nam$b_dir] = '\0';
|
||||
printf( "%s\n", curdir );
|
||||
}
|
||||
fab.fab$b_fns =
|
||||
nam.nam$b_ess =
|
||||
fab.fab$b_dns = 0;
|
||||
nam.nam$b_nop = NAM$M_SYNCHK;
|
||||
nam.nam$l_rlf = NULL;
|
||||
(void) sys_parse( &fab ); /* Release context */
|
||||
return sts;
|
||||
}
|
||||
case 2:
|
||||
phyio_show( SHOW_DEVICES );
|
||||
virt_show( NULL );
|
||||
virt_show();
|
||||
return SS$_NORMAL;
|
||||
case 3:
|
||||
printf ( " Qualifier style: %s\n", vms_qual? "/VMS": "-unix" );
|
||||
return SS$_NORMAL;
|
||||
return printmsg( HELP_SHOWQSTYLE, MSG_TEXT, (qstyle_c == '/')? "/DCL": "-unix" );
|
||||
case 4:
|
||||
return show_stats();
|
||||
case 5: {
|
||||
unsigned sts;
|
||||
char timstr[24];
|
||||
int twid, th;
|
||||
termchar( &twid, &th );
|
||||
return printmsg( HELP_TERMSIZE, MSG_TEXT, twid, th );
|
||||
}
|
||||
case 6: {
|
||||
char timstr[24] = { "" };
|
||||
unsigned short timlen;
|
||||
struct dsc_descriptor timdsc;
|
||||
|
||||
memset( &timdsc, 0, sizeof( timdsc ) );
|
||||
timdsc.dsc_w_length = 20;
|
||||
timdsc.dsc_a_pointer = timstr;
|
||||
sts = sys$asctim( &timlen, &timdsc, NULL, 0 );
|
||||
if ( sts & STS$M_SUCCESS ) {
|
||||
timstr[timlen] = '\0';
|
||||
printf(" %s\n",timstr);
|
||||
} else {
|
||||
printf("%%SHOW-W-TIMERR error %s\n",getmsg(sts, MSG_TEXT));
|
||||
if( $FAILS(sts = sys_asctim( &timlen, &timdsc, NULL, 0 )) ) {
|
||||
printmsg(ODS2_VMSTIME, 0 );
|
||||
return printmsg( sts, MSG_CONTINUE, ODS2_VMSTIME );
|
||||
}
|
||||
timstr[timlen] = '\0';
|
||||
printf(" %s\n",timstr);
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
case 6:
|
||||
printf( "Command file verification is %s\n", (verify_cmd? "on": "off") );
|
||||
return SS$_NORMAL;
|
||||
case 7:
|
||||
show_version();
|
||||
return SS$_NORMAL;
|
||||
return printmsg( verify_cmd? HELP_SHOWVERON: HELP_SHOWVEROFF, MSG_TEXT );
|
||||
case 8:
|
||||
show_version( 1 );
|
||||
return SS$_NORMAL;
|
||||
case 9:
|
||||
show_volumes();
|
||||
return SS$_NORMAL;
|
||||
case 10:
|
||||
return show_defq( dir_defopt, dirquals,
|
||||
"directory" );
|
||||
case 11:
|
||||
return show_defq( copy_defopt, copyquals, "copy" );
|
||||
case 12:
|
||||
return show_message( argc, argv );
|
||||
case 13:
|
||||
return show_defq( search_defopt, searchquals, "search" );
|
||||
case 14:
|
||||
return show_history( qualc, qualv );
|
||||
case 15:
|
||||
return showhelpfile();
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/************************************************************ show_defq() */
|
||||
|
||||
static unsigned show_defq( defqualsp_t defs,
|
||||
qualp_t qualset, const char *name ) {
|
||||
int i;
|
||||
|
||||
printmsg( HELP_SHOWDEFQ, MSG_TEXT, name );
|
||||
|
||||
if( defs == NULL || defs->qualc == 0 ) {
|
||||
printmsg( HELP_SHOWNODEFQ, MSG_TEXT );
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
for( i = 0; i < defs->qualc; i++ ) {
|
||||
qualp_t qp;
|
||||
char *qk, *qv;
|
||||
size_t len;
|
||||
|
||||
len = strlen( defs->qualv[i] ) +1;
|
||||
if( (qk = malloc( len )) == NULL )
|
||||
return SS$_INSFMEM;
|
||||
memcpy( qk, defs->qualv[i], len );
|
||||
if( (qv = strchr( qk, '=' )) == NULL )
|
||||
qv = strchr( qk, ':');
|
||||
if( qv != NULL )
|
||||
*qv++ = '\0';
|
||||
|
||||
for( qp = qualset; qp->name != NULL; qp++ ) {
|
||||
if( keycomp( qk, qp->name ) ) {
|
||||
printf( " %c%s", qstyle_c, qp->name );
|
||||
if( qp->qtype != NOVAL && qv != NULL && *qv )
|
||||
printf( "=%s", qv );
|
||||
putchar( '\n' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
free( qk );
|
||||
}
|
||||
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/****************************************************************** show_stats() */
|
||||
|
||||
/* dostats: print some simple statistics */
|
||||
|
||||
static unsigned show_stats( void ) {
|
||||
printf("Statistics:-\n");
|
||||
printmsg( HELP_SHOWSTATS, MSG_TEXT );
|
||||
direct_show();
|
||||
cache_show();
|
||||
phyio_show(SHOW_STATS);
|
||||
@@ -151,33 +288,489 @@ static unsigned show_stats( void ) {
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/*********************************************************** show_history() */
|
||||
static vmscond_t show_history( int qualc, char **qualv ) {
|
||||
vmscond_t sts;
|
||||
options_t options;
|
||||
#ifdef USE_LIBEDIT
|
||||
extern History *edithist;
|
||||
HistEvent ev;
|
||||
#else
|
||||
extern uint32_t cmd_histsize;
|
||||
uint32_t excess = 0;
|
||||
char *buf = NULL;
|
||||
size_t bufsize = 80;
|
||||
#endif
|
||||
int nent;
|
||||
|
||||
if( $FAILS(sts = checkquals( &options, 0, histquals, qualc, qualv )) ) {
|
||||
return sts;
|
||||
}
|
||||
sts = SS$_NORMAL;
|
||||
|
||||
#ifdef USE_LIBEDIT
|
||||
history( edithist, &ev, H_GETSIZE );
|
||||
nent = ev.num;
|
||||
if( nent < 0 ) {
|
||||
fprintf( stderr, "GETSIZE error (%d) %s\n", ev.num, ev.str );
|
||||
return sts;
|
||||
}
|
||||
if( !(options & hist_max) || histmax > (uint32_t)nent ) {
|
||||
histmax = nent;
|
||||
}
|
||||
if( histmax == 0 )
|
||||
return printmsg( HELP_SHOWNOCMDHIST, 0 );
|
||||
if( history( edithist, &ev, H_FIRST ) < 0 ) { /* Most recent cmd */
|
||||
fprintf( stderr, "FIRST error (%d) %s\n", ev.num, ev.str );
|
||||
return sts;
|
||||
}
|
||||
for( nent = 1; (uint32_t)nent < histmax; nent++ ) { /* Find MAXth older cmd */
|
||||
if( history( edithist, &ev, H_NEXT ) < 0 ) {
|
||||
fprintf( stderr, "NEXT error (%d) %s\n", ev.num, ev.str );
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
for( nent = 0; (uint32_t)nent < histmax; nent++ ) {
|
||||
printmsg( HELP_SHOWCMDHISTLN, MSG_TEXT, ev.num, ev.str );
|
||||
history( edithist, &ev, H_PREV );
|
||||
}
|
||||
return sts;
|
||||
#else
|
||||
if( histfile == NULL ) {
|
||||
printmsg( HELP_SHOWNOCMDHIST, 0 );
|
||||
return sts;
|
||||
}
|
||||
fseek( histfile, 0, SEEK_SET );
|
||||
for( nent = 0; ; ) { /* Count history lines */
|
||||
int c;
|
||||
|
||||
c = getc( histfile );
|
||||
if( c == EOF ) break;
|
||||
if( c == '\n' ) ++nent;
|
||||
}
|
||||
if( !(options & hist_max) || histmax > (uint32_t)nent ) {
|
||||
histmax = nent;
|
||||
}
|
||||
if( histmax == 0 )
|
||||
return printmsg( HELP_SHOWNOCMDHIST, 0 );
|
||||
if( (uint32_t)nent > cmd_histsize ) /* Hide excess file lines if size reduced */
|
||||
excess = nent - cmd_histsize;
|
||||
if( histmax > (uint32_t)nent - excess )
|
||||
histmax = (uint32_t)nent - excess; /* Reduce request to visible window */
|
||||
histmax = nent - histmax;
|
||||
fseek( histfile, 0, SEEK_SET );
|
||||
for( nent = 0; (uint32_t)nent < histmax; ) { /* Skip old lines */
|
||||
int c;
|
||||
|
||||
c = getc( histfile );
|
||||
if( c == EOF ) break;
|
||||
if( c == '\n' ) ++nent;
|
||||
}
|
||||
for( ; ; nent++ ) { /* Get full lines for display */
|
||||
char *line;
|
||||
|
||||
if( (line = fgetline( histfile, FALSE, &buf, &bufsize )) == NULL )
|
||||
break;
|
||||
printmsg( HELP_SHOWCMDHISTLN, MSG_TEXT, nent + 1 - excess, line );
|
||||
}
|
||||
if( buf != NULL ) free( buf );
|
||||
fseek( histfile, 0, SEEK_END );
|
||||
return sts;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************** show_version() */
|
||||
|
||||
void show_version( int full ) {
|
||||
char *detail, *version;
|
||||
#ifdef DEBUG_BUILD
|
||||
extern int vld_present;
|
||||
#endif
|
||||
|
||||
void show_version( void ) {
|
||||
printf(" %s %s", MNAME(MODULE_NAME), MODULE_IDENT );
|
||||
printf( " built %s %s", __DATE__, __TIME__ );
|
||||
#ifdef USE_READLINE
|
||||
printf(" with readline version %s", rl_library_version );
|
||||
#ifdef USE_LIBEDIT
|
||||
printmsg( HELP_SHOWVERSRL, MSG_TEXT, MNAME(MODULE_NAME), MODULE_IDENT,
|
||||
__DATE__, __TIME__, LIBEDIT_MAJOR, LIBEDIT_MINOR );
|
||||
#else
|
||||
printmsg( HELP_SHOWVERS, MSG_TEXT, MNAME(MODULE_NAME), MODULE_IDENT,
|
||||
__DATE__, __TIME__ );
|
||||
#endif
|
||||
|
||||
if( !full ) return;
|
||||
|
||||
/* Determine what platform and compiler were targeted for this image */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define strcat( _dst, _src ) strcat_s( (_dst), MAXSTRL, (_src) )
|
||||
#endif
|
||||
#define MAXSTRL 512
|
||||
|
||||
if( (detail = malloc( MAXSTRL * 2 )) == NULL ) {
|
||||
return;
|
||||
}
|
||||
detail[0] = '\0';
|
||||
version = detail + MAXSTRL;
|
||||
version[0] = '\0';
|
||||
|
||||
/* N.B. The order of detection is intended to deal with ambiguities,
|
||||
* and does not inidcate any particular preference or judgement.
|
||||
*
|
||||
* The detection scheme is an amalgam of tests from various sources.
|
||||
* It has not been run in all these environments by the author,
|
||||
* (or perhaps by anyone), so errors may exist and should be reported.
|
||||
* Additions are also welcome.
|
||||
*/
|
||||
|
||||
#if defined __ANDROID__
|
||||
strcat( detail, "Android" );
|
||||
#elif defined __linux__
|
||||
strcat( detail, "Linux" );
|
||||
#elif defined __APPLE__
|
||||
#include "TargetConditionals.h"
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
strcat( detail, "iOS Simulator" );
|
||||
#elif TARGET_OS_IPHONE
|
||||
strcat( detail, "iOS device" );
|
||||
#elif TARGET_OS_MAC
|
||||
strcat( detail, "OS X" );
|
||||
#else
|
||||
strcat( detail, "Unknown Apple platform" );
|
||||
#endif
|
||||
#elif defined __CYGWIN__ && !defined _WIN32
|
||||
strcat( detail, "Cygwin" );
|
||||
#elif defined _WIN64
|
||||
strcat( detail, "Windows (64-bit)" );
|
||||
#elif defined _WIN32
|
||||
strcat( detail, "Windows (32-bit)" );
|
||||
#elif defined VMS || defined __VMS
|
||||
#if defined __ia64__ || defined __ia64 || defined _M_IA64
|
||||
strcat( detail, "VMS (Itanium)" );
|
||||
#elif defined __ALPHA || defined __ALPHA_AXP
|
||||
strcat( detail, "VMS (Alpha)" );
|
||||
#elif defined VAX || defined __VAX
|
||||
strcat( detail, "VMS (VAX)" );
|
||||
#else
|
||||
strcat( detail, "VMS" );
|
||||
#endif
|
||||
#if defined __VMS_VER
|
||||
snprintf( detail + strlen( detail ), MAXSTRL - strlen( detail ),
|
||||
"%c%u.%u-%u%c",
|
||||
(__VMS_VER % 100u),
|
||||
(__VMS_VER / 10000000u),
|
||||
(__VMS_VER / 100000u) % 100u,
|
||||
(__VMS_VER / 10000u) % 10u,
|
||||
(__VMS_VER / 100u) % 100u );
|
||||
#endif
|
||||
#elif defined __osf__
|
||||
strcat( detail, "DEC OSF/1 (Tru64)" );
|
||||
#elif defined ultrix || defined __ultrix || defined __ultrix__
|
||||
strcat( detail, "Ultrix" );
|
||||
#elif defined UNICOS
|
||||
strcat( detail, "UNICOS" );
|
||||
#elif defined _CRAY || defined __crayx1
|
||||
strcat( detail, "UNICOSD/mp" );
|
||||
#elif defined _AIX
|
||||
#if defined __64BIT__
|
||||
strcat( detail, "AIX (64-bit)" );
|
||||
#else
|
||||
strcat( detail, "AIX" );
|
||||
#endif
|
||||
#elif defined(__sun) && defined(__SVR4)
|
||||
strcat( detail, "Solaris" );
|
||||
#elif defined __hpux
|
||||
strcat( detail, "HP-UX" );
|
||||
#elif defined __NetBSD__
|
||||
strcat( detail, "NetBSD" );
|
||||
#elif defined __OpenBSD__
|
||||
strcat( detail, "OpenBSD" );
|
||||
|
||||
/* Generic */
|
||||
#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <sys/param.h>
|
||||
#if defined(BSD)
|
||||
strcat( detail, "BSD Unix" );
|
||||
#endif
|
||||
#elif defined_POSIX_VERSION
|
||||
strcat( detail, "POSIX" );
|
||||
#if( _POSIX_VERSION >= 200809L )
|
||||
strcat( detail, ".1-2008" );
|
||||
#elif( _POSIX_VERSION >= 200112L )
|
||||
strcat( detail, ".1-2001" );
|
||||
#elif( _POSIX_VERSION >= 199506L )
|
||||
strcat( detail, ".1-1995" );
|
||||
#elif( _POSIX_VERSION >= 199309L )
|
||||
strcat( detail, ".1-1993" );
|
||||
#elif( _POSIX_VERSION >= 199009L )
|
||||
strcat( detail,".1-1990" );
|
||||
#elif( _POSIX_VERSION >= 198808L )
|
||||
strcat( detail,".1-1988" );
|
||||
#endif
|
||||
#else
|
||||
strcat( detail, "Unknown platform" );
|
||||
#endif
|
||||
|
||||
/* Hardware */
|
||||
|
||||
#if defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)
|
||||
#if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \
|
||||
defined(__64BIT__) || defined(_LP64) || defined(__LP64__)
|
||||
strcat( detail, " PowerPC (64-bit)" );
|
||||
#else
|
||||
strcat( detail, " PowerPC (32-bit)" );
|
||||
#endif
|
||||
#elif defined(__ia64) || defined(__itanium__) || defined(_M_IA64)
|
||||
#if !defined VMS && !defined __VMS
|
||||
strcat( detail, " Itanium " );
|
||||
#endif
|
||||
#elif defined(__sparc)
|
||||
strcat( detail, " SPARC" );
|
||||
#elif defined(__x86_64__) || defined(_M_X64)
|
||||
strcat( detail, " x86-64" );
|
||||
#elif defined(__i386) || defined(_M_IX86)
|
||||
strcat( detail, " x86-32" );
|
||||
#elif defined __alpha || defined __alpha || defined _M_ALPHA
|
||||
#if !defined VMS
|
||||
strcat( detail, " Alpha" );
|
||||
#endif
|
||||
#elif defined VAX || defined __VAX
|
||||
strcat( detail, " VAX" );
|
||||
#elif defined __aarch64__
|
||||
strcat( detail, " ARM64" );
|
||||
#elif defined __thumb__
|
||||
strcat( detail, " ARM (Thumb)" );
|
||||
#elif defined __arm__
|
||||
strcat( detail, " ARM " )
|
||||
#elif defined __hppa__ || defined __HPPA__ || defined _hppa
|
||||
strcat( detail, " HP/PA RISC" );
|
||||
#elif defined __m68k__ || defined M68000 || defined __MC68K__
|
||||
strcat( detail, " Motorola 68000" );
|
||||
#elif defined __mips__ || defined __mips
|
||||
strcat( detail, " MIPS" );
|
||||
#elif defined __THW_RS6000__
|
||||
strcat( detail, " RS6000" );
|
||||
#elif defined __370__ || defined __THW_370__ || defined __s390__ || defined __s390x || \
|
||||
defined __zarch__ || defined __SYSC_ZARCH__
|
||||
strcat( detail, " System Z (370)" );
|
||||
#endif
|
||||
|
||||
#if defined __STDC_VERSION__
|
||||
#if( __STDC_VERSION__ >= 201112L )
|
||||
strcat( detail, " C11" );
|
||||
#elif( __STDC_VERSION__ >= 199901L )
|
||||
strcat( detail, " C99" );
|
||||
#elif( __STDC_VERSION__ >= 199409L )
|
||||
strcat( detail, " C94" );
|
||||
#else
|
||||
strcat( detail, " C89/90" );
|
||||
#endif
|
||||
#elif defined __STDC__
|
||||
strcat( detail, " C89/90" );
|
||||
#else
|
||||
strcat( detail, " C" );
|
||||
#endif
|
||||
|
||||
#if defined __LSB_VERSION__
|
||||
snprintf( detail + strlen( detail ), MAXSTRL - strlen( detail ),
|
||||
" LSB V%u.%u",
|
||||
(__LSB_VERSION__ / 10), (__LSB_VERSION__%10) );
|
||||
#endif
|
||||
|
||||
#if ODS2_BIG_ENDIAN
|
||||
strcat( detail, " Big-Endian" );
|
||||
#endif
|
||||
printmsg( HELP_SHOWVERPLATFM, MSG_TEXT, detail );
|
||||
|
||||
/* Compiler */
|
||||
|
||||
detail[0] = '\0';
|
||||
#if defined __clang__
|
||||
strcat( detail, "Clang/LLVM" );
|
||||
snprintf( version, MAXSTRL, "%d.%d.%d",
|
||||
__clang_major__, __clang_minor__, __clang_patchlevel__ );
|
||||
#elif defined(__ICC) || defined(__INTEL_COMPILER)
|
||||
strcat( detail, "ICC" );
|
||||
#if defined __VERSION__
|
||||
strcat( version, __VERSION__ );
|
||||
#endif
|
||||
#elif defined(__HP_cc) || defined(__HP_aCC)
|
||||
strcat( detail, "HP C" );
|
||||
#if defined __HP_aCC && __HP_aCC > 1
|
||||
snprintf( version, MAXSTRL, "%02u.%02u.%02u",
|
||||
(__HP_aCC / 10000u ),
|
||||
(__HP_aCC / 100u ) % 100u,
|
||||
(__HP_aCC % 100u ) % 100u );
|
||||
#elif defined __HP_cc && __HP_cc > 1
|
||||
snprintf( version, MAXSTRL, "%02u.%02u.%02u",
|
||||
(__HP_cc / 10000u ),
|
||||
(__HP_cc / 100u ) % 100u,
|
||||
(__HP_cc % 100u ) % 100u );
|
||||
#endif
|
||||
#elif defined(__IBMC__) || defined(__IBMCPP__)
|
||||
strcat( detail, "IBM XL C" );
|
||||
#if defined __COMPILER_VER__
|
||||
strcat( version, __COMPILER_VER__ );
|
||||
#elif defined __xlxc__
|
||||
strcat( version, __xlc__ );
|
||||
#else
|
||||
strcat( version, __IBMC__ );
|
||||
#endif
|
||||
#elif defined __LCC__
|
||||
strcat( detail, "LCC" );
|
||||
#elif defined ___llvm
|
||||
strcat( detail, "LLVM" );
|
||||
#elif defined __MINGW64__
|
||||
strcat( detail, "MinGW-w64" );
|
||||
#if defined __MINGW64_VERSION_MAJOR
|
||||
snprintf( version, MAXSTRL, "%u.%u",
|
||||
__MINGW64_VERSION_MAJOR, __MINGW64_VERSION_MINOR );
|
||||
#endif
|
||||
#elif defined __MINGW32__
|
||||
strcat( detail, "MinGW" );
|
||||
#if defined __MINGW32_MAJOR_VERSIONR
|
||||
snprintf( version, MAXSTRL, "%u.%u",
|
||||
__MINGW32_MAJOR_VERSION, __MINGW32_MINOR_VERSION );
|
||||
#endif
|
||||
#elif defined(__PGI)
|
||||
strcat( detail, "PGCC" );
|
||||
snprintf( version, MAXSTRL, "%u.%u.%u",
|
||||
__PGIC__, __PGIC_MINOR, __PGIC_PATCHLEVEL__ );
|
||||
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
strcat( detail, "Solaris Studio" );
|
||||
#if defined __SUNPRO_C
|
||||
snprintf( version, MAXSTRL, "%u.%u.%u",
|
||||
(__SUNPRO_C / 0x100 ),
|
||||
(__SUNPRO_C / 0x10 ) % 0x100,
|
||||
(__SUNPRO_C % 0x10 ) );
|
||||
#elif defined __SUNPRO_CC
|
||||
snprintf( version, MAXSTRL, "%u.%u.%u",
|
||||
(__SUNPRO_CC / 0x100 ),
|
||||
(__SUNPRO_CC / 0x10 ) % 0x100,
|
||||
(__SUNPRO_CC % 0x10 ) );
|
||||
#endif
|
||||
#elif defined __sgi || defined sgi
|
||||
strcat( detail, "MIPSpro" );
|
||||
#if defined _SGI_COMPILER_VERSION
|
||||
snprintf( version, MAXSTRL, "%u.%u.%u",
|
||||
(_SGI_COMPILER_VERSION / 100u),
|
||||
(_SGI_COMPILER_VERSION / 10u) % 10u,
|
||||
(_SGI_COMPILER_VERSION % 10u) );
|
||||
#elif defined _COMPILER_VERSION
|
||||
snprintf( version, MAXSTRL, "%u.%u.%u",
|
||||
(_COMPILER_VERSION / 100u),
|
||||
(_COMPILER_VERSION / 10u) % 10u,
|
||||
(_COMPILER_VERSION % 10u) );
|
||||
#endif
|
||||
#elif defined _MSC_FULL_VER
|
||||
strcat( detail, "Visual C++" );
|
||||
snprintf( version, MAXSTRL, "%d.%02d.%05d.%02d",
|
||||
(_MSC_FULL_VER / 10000000u),
|
||||
(_MSC_FULL_VER / 100000u ) % 100u,
|
||||
(_MSC_FULL_VER % 100000u ),
|
||||
_MSC_BUILD);
|
||||
#ifdef _MSC_VER
|
||||
{ /* https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros */
|
||||
struct {
|
||||
char *ide; unsigned ver; } ides[] = {
|
||||
{"Visual Studio 6.0", 1200},
|
||||
{"Visual Studio .NET 2002 (7.0)", 1300},
|
||||
{"Visual Studio .NET 2003 (7.1)", 1310},
|
||||
{"Visual Studio 2005 (8.0)", 1400},
|
||||
{"Visual Studio 2008 (9.0)", 1500},
|
||||
{"Visual Studio 2010 (10.0)", 1600},
|
||||
{"Visual Studio 2012 (11.0)", 1700},
|
||||
{"Visual Studio 2013 (12.0)", 1800},
|
||||
{"Visual Studio 2015 (14.0)", 1900},
|
||||
{"Visual Studio 2017 RTW (15.0)", 1910},
|
||||
{"Visual Studio 2017 version 15.3", 1911},
|
||||
{"Visual Studio 2017 version 15.5", 1912},
|
||||
{"Visual Studio 2017 version 15.6", 1913},
|
||||
{"Visual Studio 2017 version 15.7", 1914},
|
||||
{"Visual Studio 2017 version 15.8", 1915},
|
||||
{"Visual Studio 2017 version 15.9", 1916},
|
||||
{"Visual Studio 2019 RTW (16.0)", 1920},
|
||||
{"Visual Studio 2019 version 16.1", 1921},
|
||||
{"Visual Studio 2019 version 16.2", 1922},
|
||||
{"Visual Studio 2019 version 16.3", 1923},
|
||||
{"Visual Studio 2019 version 16.4", 1924},
|
||||
{"Visual Studio 2019 version 16.5", 1925},
|
||||
{"Visual Studio 2019 version 16.6", 1926},
|
||||
{"Visual Studio 2019 version 16.7", 1927},
|
||||
{"Visual Studio 2019 version 16.8, 16.9", 1928},
|
||||
{"Visual Studio 2019 version 16.10, 16.11", 1929},
|
||||
{"Visual Studio 2022 RTW (17.0)", 1930},
|
||||
{"Visual Studio 2022 version 17.1", 1931},
|
||||
{"Visual Studio 2022 version 17.2", 1932},
|
||||
{"Visual Studio 2022 version 17.3", 1933},
|
||||
{"Visual Studio 2022+", 100000}, }, *ip;
|
||||
for( ip = ides; ip->ver < _MSC_VER; ip++ )
|
||||
;
|
||||
strcat( version, ", " );
|
||||
strcat( version, ip->ide );
|
||||
}
|
||||
#endif
|
||||
#elif defined _MSC_VER
|
||||
strcat( detail, "Visual Studio" );
|
||||
snprintf( version, MAXSTRL, "%d", _MSC_VER );
|
||||
#elif defined __CC_ARM
|
||||
strcat( version, "ARM Compiler" );
|
||||
snprintf( version, MAXSTRL, "%u.%u.%u build %u",
|
||||
(__ARMCC_VERSION / 100000u ),
|
||||
(__ARMCC_VERSION / 10000u ) % 10u,
|
||||
(__ARMCC_VERSION / 1000u ) % 10u,
|
||||
(__ARMCC_VERSION % 1000u ) );
|
||||
#elif defined __GNUC__
|
||||
strcat( detail, "gcc" );
|
||||
#if defined __VERSION__
|
||||
strcat( version, __VERSION__ );
|
||||
#else
|
||||
snprintf( version, MAXSTRL, "%d.%d", __GNUC__, __GNUC_MINOR__ );
|
||||
#endif
|
||||
#elif defined __DECC__ || defined _DECC
|
||||
strcat( detail, "DEC C" );
|
||||
{
|
||||
char ct;
|
||||
switch( (__DECC_VER / 10000u) % 10u ) {
|
||||
case 6:
|
||||
ct = 'T'; break;
|
||||
case 8:
|
||||
ct = 'S'; break;
|
||||
case 9:
|
||||
ct = 'V'; break;
|
||||
default:
|
||||
ct = 'X'; break;
|
||||
}
|
||||
snprintf( version, MAXSTRL, "%c%u.%u-%03u", ct,
|
||||
(__DECC_VER / 10000000u),
|
||||
(__DECC_VER / 100000u) % 100u,
|
||||
(__DECC_VER % 10000u) );
|
||||
}
|
||||
#elif defined VAXC || defined VAX11C || defined __VAXC || defined __VAX11C
|
||||
strcat( detail, "VAX C" );
|
||||
#endif
|
||||
if( !version[0] )
|
||||
strcat( version, "unknown" );
|
||||
#undef strcat
|
||||
#undef MAXSTRL
|
||||
|
||||
printmsg( HELP_SHOWVERCOMPLR, MSG_TEXT, detail, version );
|
||||
|
||||
free( detail ); /* includes version */
|
||||
detail = version = NULL;
|
||||
|
||||
#ifdef DEBUG_BUILD
|
||||
if( vld_present )
|
||||
printmsg( HELP_SHOWVLD, MSG_TEXT );
|
||||
#endif
|
||||
#ifdef USE_WNASPI32
|
||||
# ifdef USE_READLINE
|
||||
printf( " and" );
|
||||
# else
|
||||
printf( " with" );
|
||||
# endif
|
||||
printf( " direct SCSI access support");
|
||||
printmsg( HELP_SHOWVERSCSI, MSG_TEXT );
|
||||
#endif
|
||||
printf( "\n " );
|
||||
putchar( ' ');
|
||||
phyio_show( SHOW_FILE64 );
|
||||
#ifdef USE_VHD
|
||||
putchar( ' ');
|
||||
(void) phyvhd_available( TRUE );
|
||||
#else
|
||||
printf( " VHD format image files are not supported\n" );
|
||||
printmsg( HELP_SHOWVERNOVHD, MSG_TEXT );
|
||||
#endif
|
||||
|
||||
putchar( '\n' );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -197,7 +790,7 @@ static char *get_cwd( void ) {
|
||||
if( getcwd( buf, size ) != NULL )
|
||||
break;
|
||||
if( errno != ERANGE ) {
|
||||
perror( "getcwd" );
|
||||
printmsg( ODS2_OSERROR, 0, strerror( errno ) );
|
||||
return NULL;
|
||||
}
|
||||
size *= 2;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_SPAWNCMD )
|
||||
@@ -31,30 +34,48 @@
|
||||
|
||||
/******************************************************************* dospawn() */
|
||||
|
||||
DECL_CMD(spawn) {
|
||||
#ifdef VMS
|
||||
unsigned sts;
|
||||
char spawnhelp[] = { "commands spawnvms" };
|
||||
|
||||
DECL_CMD(spawn) {
|
||||
vmscond_t sts;
|
||||
|
||||
UNUSED( argc );
|
||||
UNUSED( argv );
|
||||
UNUSED( qualc );
|
||||
UNUSED( qualv );
|
||||
|
||||
sts = lib$spawn( 0,0,0,0,0,0,0,0,0,0,0,0,0 );
|
||||
/* command, input, output, flags, process_name, pid, exit_sts, efn,
|
||||
* astaddr, astprm, prompt, cli, table
|
||||
*/
|
||||
if( $FAILS(sts = lib$spawn( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 )) ) {
|
||||
printmsg( ODS2_NOSHELL, 0, "command interpreter" );
|
||||
sts = printmsg( sts, MSG_CONTINUE, ODS2_NOSHELL );
|
||||
}
|
||||
return sts;
|
||||
#else
|
||||
# ifdef _WIN32
|
||||
}
|
||||
#elif defined( _WIN32 )
|
||||
char spawnhelp[] = { "commands spawnnt" };
|
||||
|
||||
DECL_CMD(spawn) {
|
||||
UNUSED( argc );
|
||||
UNUSED( argv );
|
||||
UNUSED( qualc );
|
||||
UNUSED( qualv );
|
||||
|
||||
if( system( "cmd" ) == -1 ) {
|
||||
perror( "cmd" );
|
||||
return SS$_NOSUCHFILE;
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( ODS2_NOSHELL, 0, "cmd" );
|
||||
return printmsg( ODS2_OSERROR, MSG_CONTINUE, strerror( err ) );
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
# else
|
||||
}
|
||||
#else
|
||||
char spawnhelp[] = { "commands spawnunix" };
|
||||
|
||||
DECL_CMD(spawn) {
|
||||
char *shell, *p;
|
||||
pid_t pid;
|
||||
|
||||
@@ -71,19 +92,24 @@ DECL_CMD(spawn) {
|
||||
p++;
|
||||
|
||||
if( (pid = fork()) == 0 ) {
|
||||
int err;
|
||||
|
||||
execlp( shell, p, (char *)NULL );
|
||||
perror( "%s" );
|
||||
|
||||
err = errno;
|
||||
printmsg( ODS2_NOSHELL, 0, shell );
|
||||
printmsg( ODS2_OSERROR, MSG_CONTINUE, strerror( err ) );
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if( pid == -1 ) {
|
||||
perror( shell );
|
||||
return SS$_NOSUCHFILE;
|
||||
int err = errno;
|
||||
|
||||
printmsg( ODS2_NOSHELL, 0, shell );
|
||||
return printmsg( ODS2_OSERROR, MSG_CONTINUE, strerror( err ) );
|
||||
}
|
||||
waitpid( pid, NULL, 0 );
|
||||
|
||||
return SS$_NORMAL;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1806
extracters/ods2/ssdef.msg
Normal file
1806
extracters/ods2/ssdef.msg
Normal file
File diff suppressed because it is too large
Load Diff
18
extracters/ods2/strictmake
Executable file
18
extracters/ods2/strictmake
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
# This is how I validate that everything compiles with GCC warnings enabled.
|
||||
# ./strictmake -g -DDEBUG (or any other CCFLAGS)
|
||||
# If the first argument does not begin with '-', it's the target of the build
|
||||
#
|
||||
# Exception reasons:
|
||||
# $ in identifier - VMS compatible code
|
||||
# object to function pointer - dlsym requires this to work; it's in the
|
||||
# OpenGroup standard's notes on this (standard) function.
|
||||
# VHD uses long long - but is optional
|
||||
|
||||
if [[ "$1" =~ ^- ]]; then
|
||||
TGT=
|
||||
else
|
||||
TGT="$1"
|
||||
shift
|
||||
fi
|
||||
LANG=C 2>&1 make -f makefile.unix $TGT "CCFLAGS=-O4 $* -DUSE_LIBEDIT -Wall -pedantic -Wextra" | grep -vP "(warning: '\\\$' in identifier or number)|\`arg[cv]|(In file included from)|(phyvhd.c:\\d+:\\d+: warning: ISO C forbids conversion of object pointer to function pointer)|(use of C99 long long integer constant)"
|
||||
@@ -12,10 +12,13 @@
|
||||
* 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 contributions of the original author and
|
||||
* subsequent contributors. This is free software; no
|
||||
* warranty is offered, and while we believe it to be useful,
|
||||
* you use it at your own risk.
|
||||
*/
|
||||
|
||||
/* Message code translations for non-VMS systems */
|
||||
/* VMS-ish message code translations */
|
||||
|
||||
#if !defined( DEBUG ) && defined( DEBUG_SYSMSG )
|
||||
#define DEBUG DEBUG_SYSMSG
|
||||
@@ -25,147 +28,245 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Should replace with lib$sys_getmsg under VMS
|
||||
|
||||
#ifndef VMS
|
||||
*/
|
||||
/* This is similar to, but not quite $PUTMSG. We don't have VMS signals...
|
||||
*/
|
||||
|
||||
#define SYSMSG_INTERNAL
|
||||
#include "ods2.h"
|
||||
#include "ssdef.h"
|
||||
#include "rms.h"
|
||||
#include "compat.h"
|
||||
#include "stsdef.h"
|
||||
|
||||
#include "sysmsg.h"
|
||||
|
||||
#define MSG(code,text) { $VMS_STATUS_COND_ID(code), #code, text },
|
||||
|
||||
static
|
||||
const struct VMSFAC {
|
||||
unsigned int code;
|
||||
const char *const text;
|
||||
} fac2text[] = {
|
||||
{ SYSTEM$_FACILITY, "SYSTEM" },
|
||||
{ RMS$_FACILITY, "RMS" },
|
||||
{ COPY$_FACILITY, "COPY" },
|
||||
{ DELETE$_FACILITY, "DELETE" },
|
||||
{ 0, NULL },
|
||||
{ 0, "NONAME" }
|
||||
};
|
||||
|
||||
static const char sev2text[(STS$M_SEVERITY>>STS$V_SEVERITY)+1] =
|
||||
{ 'W', 'S', 'E', 'I', 'F', '?', '?', '?', };
|
||||
|
||||
/* Unknown facility or message code */
|
||||
|
||||
#ifndef SS$_NOMSG
|
||||
#define SS$_NOMSG 0xFFFFFFFF
|
||||
#ifdef _WIN32
|
||||
#undef sscanf
|
||||
#define sscanf sscanf_s
|
||||
#undef fscanf
|
||||
#define fscanf fscanf_s
|
||||
#endif
|
||||
|
||||
static const char nofmt[] = "Message number %08X";
|
||||
static char notext[sizeof(nofmt)+8];
|
||||
/* Facility name to text translations
|
||||
*/
|
||||
|
||||
static
|
||||
const struct VMSMSG {
|
||||
unsigned int code;
|
||||
const char *const txtcode;
|
||||
char *text;
|
||||
} vms2text[] = {
|
||||
MSG(DELETE$_DELVER, "explicit version number or wild card required")
|
||||
struct VMSFAC fac2textdef[] = {
|
||||
#define GENERATE_FACTAB
|
||||
#include "default.md"
|
||||
}, /* Entry for unknown facility */
|
||||
nofac = { "NONAME", 0 };
|
||||
|
||||
MSG(COPY$_OPENIN, " error opening %s as input")
|
||||
/* Number of entries to search */
|
||||
static size_t faclen = (sizeof(fac2textdef)/sizeof(fac2textdef[0]));
|
||||
|
||||
MSG(RMS$_BUG, "fatal RMS condition detected, process deleted")
|
||||
MSG(RMS$_DIR, "error in directory name")
|
||||
MSG(RMS$_DNF, "directory not found")
|
||||
MSG(RMS$_EOF, "end of file detected")
|
||||
MSG(RMS$_ESS, "expanded string area too small")
|
||||
MSG(RMS$_FNF, "file not found")
|
||||
MSG(RMS$_FNM, "error in file name")
|
||||
MSG(RMS$_IFI, "invalid internal file identifier (IFI) value")
|
||||
MSG(RMS$_NAM, "invalid NAM block or NAM block not accessible")
|
||||
MSG(RMS$_NMF, "no more files found")
|
||||
MSG(RMS$_RSS, "invalid resultant string size")
|
||||
MSG(RMS$_RSZ, "invalid record size")
|
||||
MSG(RMS$_RTB, "%u byte record too large for user's buffer") /* !UL byte */
|
||||
MSG(RMS$_WCC, "invalid wild card context (WCC) value")
|
||||
MSG(RMS$_WLD, "invalid wildcard operation")
|
||||
MSG(SS$_ABORT, "abort")
|
||||
MSG(SS$_BADFILENAME, "bad file name syntax")
|
||||
MSG(SS$_BADIRECTORY, "bad directory file format")
|
||||
MSG(SS$_BADPARAM, "bad parameter value")
|
||||
MSG(SS$_BUGCHECK, "internal consistency failure")
|
||||
MSG(SS$_DATACHECK, "write check error")
|
||||
MSG(SS$_DEVALLOC, "device already allocated to another user")
|
||||
MSG(SS$_DEVASSIGN, "device has channels assigned" )
|
||||
MSG(SS$_DEVICEFULL, "device full - allocation failure")
|
||||
MSG(SS$_DEVMOUNT, "device is already mounted")
|
||||
MSG(SS$_DEVNOTALLOC, "device not allocated")
|
||||
MSG(SS$_DEVNOTDISM, "device not dismounted")
|
||||
MSG(SS$_DEVNOTMOUNT, "device is not mounted")
|
||||
MSG(SS$_DUPFILENAME, "duplicate file name")
|
||||
MSG(SS$_DUPLICATE, "duplicate name")
|
||||
MSG(SS$_ENDOFFILE, "end of file")
|
||||
MSG(SS$_ILLBLKNUM, "illegal logical block number")
|
||||
MSG(SS$_FILELOCKED, "file is deaccess locked")
|
||||
MSG(SS$_FILESEQCHK, "file identification sequence number check")
|
||||
MSG(SS$_ILLEFC, "illegal event flag cluster")
|
||||
MSG(SS$_INSFMEM, "insufficient dynamic memory")
|
||||
MSG(SS$_ITEMNOTFOUND, "requested item cannot be returned")
|
||||
MSG(SS$_NOMOREDEV, "no more devices")
|
||||
MSG(SS$_IVCHAN, "invalid I/O channel")
|
||||
MSG(SS$_DEVOFFLINE, "device is not in configuration or not available")
|
||||
MSG(SS$_IVDEVNAM, "invalid device name")
|
||||
MSG(SS$_NOIOCHAN, "no I/O channel available")
|
||||
MSG(SS$_NOMOREFILES, "no more files")
|
||||
MSG(SS$_NORMAL, "normal successful completion")
|
||||
MSG(SS$_NOSUCHDEV, "no such device available")
|
||||
MSG(SS$_NOSUCHFILE, "no such file")
|
||||
MSG(SS$_NOSUCHVOL, "No such volume")
|
||||
MSG(SS$_NOTINSTALL, "writable shareable images must be installed")
|
||||
MSG(SS$_PARITY, "parity error")
|
||||
MSG(SS$_UNSUPVOLSET, "Volume set not supported")
|
||||
MSG(SS$_WASCLR, "normal successful completion")
|
||||
MSG(SS$_WASSET, "Event flag was set")
|
||||
MSG(SS$_WRITLCK, "write lock error")
|
||||
MSG(SS$_OFFSET_TOO_BIG, "Volume is too large for local file system: needs 64-bit I/O" )
|
||||
{0, NULL, NULL},
|
||||
{ SS$_NOMSG, "SS$_NOMSG", notext }
|
||||
};
|
||||
/* Pointer to active table.
|
||||
* Special labels for facility code 0.
|
||||
*/
|
||||
|
||||
static
|
||||
struct VMSFAC *fac2text = fac2textdef,
|
||||
sysfac = { "SYSTEM", 0 },
|
||||
shrfac = { "SHR" , 0 };
|
||||
|
||||
/* Pointer to memory containing dynamically-loaded message file data.
|
||||
*/
|
||||
static char *msgfile;
|
||||
static char *msgfilename;
|
||||
|
||||
static const char sev2text[(STS$M_SEVERITY >> STS$V_SEVERITY)+1] =
|
||||
{ 'W', 'S', 'E', 'I', 'F', '?', '?', '?', };
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
|
||||
/* Unknown facility or message code
|
||||
*/
|
||||
static char notext[256];
|
||||
|
||||
/* Message data
|
||||
*/
|
||||
|
||||
static
|
||||
struct VMSMSG vms2textdef[] = {
|
||||
#define GENERATE_MSGTAB
|
||||
#include "default.md"
|
||||
}, /* Special item for Unknown message response */
|
||||
nomsg = { "NOMSG", notext, ODS2_NOMSG, 1 };
|
||||
/* Number of messages */
|
||||
static size_t msglen = sizeof(vms2textdef)/sizeof(vms2textdef[0]);
|
||||
|
||||
/* Pointer to active message table */
|
||||
struct VMSMSG *vms2text = vms2textdef;
|
||||
|
||||
/* Default message display options
|
||||
*/
|
||||
static options_t message_format = MSG_FULL;
|
||||
|
||||
/* Expandable buffer for formatted messages */
|
||||
|
||||
static char *buf = NULL;
|
||||
static size_t bufsize = 0;
|
||||
|
||||
/******************************************************************* xpand() */
|
||||
/* Last few formatted messages for callers that hold
|
||||
* pointers across calls.
|
||||
*/
|
||||
static char *retbuf[10];
|
||||
static size_t retidx = 0, lastidx = 0;
|
||||
|
||||
static int xpand( size_t used, size_t add ) {
|
||||
char *nbuf;
|
||||
size_t need;
|
||||
static int argcount( vmscond_t vmscond );
|
||||
|
||||
need = used + add + 1; /* Always allow for \0 */
|
||||
if( need < bufsize ) {
|
||||
return 1;
|
||||
static int xpand( size_t used, size_t add );
|
||||
static const char *returnbuf( void );
|
||||
static int decstr( FILE *mf, size_t *len, char **pp, char **sp );
|
||||
|
||||
/******************************************************************* printmsg() */
|
||||
|
||||
vmscond_t printmsg( vmscond_t vmscond, unsigned int flags, ... ) {
|
||||
va_list ap;
|
||||
vmscond_t status;
|
||||
|
||||
va_start( ap, flags );
|
||||
status = vprintmsg( vmscond, flags, ap );
|
||||
va_end( ap );
|
||||
|
||||
return status;
|
||||
}
|
||||
/******************************************************************* vprintmsg() */
|
||||
|
||||
vmscond_t vprintmsg( vmscond_t vmscond, unsigned int flags, va_list ap ) {
|
||||
const char *msg, *pfxe;
|
||||
FILE *of = stdout;
|
||||
int nargs;
|
||||
vmscond_t primary;
|
||||
|
||||
if( flags & MSG_TOFILE )
|
||||
of = va_arg( ap, FILE * );
|
||||
|
||||
if( flags & MSG_CONTINUE ) {
|
||||
primary = va_arg( ap, vmscond_t );
|
||||
vmscond |= primary & STS$M_INHIB_MSG;
|
||||
} else
|
||||
primary = vmscond;
|
||||
|
||||
if( (vmscond & STS$M_INHIB_MSG) && !(flags & MSG_ALWAYS) )
|
||||
return primary;
|
||||
|
||||
if( (flags & (MSG_WITHARGS | MSG_NOARGS)) == 0 ) {
|
||||
nargs = argcount( vmscond );
|
||||
if( nargs > 0 )
|
||||
flags |= MSG_WITHARGS;
|
||||
}
|
||||
nbuf = realloc( buf, need + 16 + 1); /* 16 minimizes reallocs */
|
||||
if( nbuf == NULL ) {
|
||||
return 0;
|
||||
|
||||
if( !(flags & MSG_FULL) ) {
|
||||
flags = (flags & ~MSG_FULL) | message_format;
|
||||
}
|
||||
buf = nbuf;
|
||||
bufsize = need + 16 + 1;
|
||||
return 1;
|
||||
|
||||
if( (flags & (MSG_WITHARGS | MSG_TEXT)) != (MSG_WITHARGS | MSG_TEXT) ) {
|
||||
fprintf( of, "%s", getmsg_string( vmscond, flags ) );
|
||||
if( !(flags & MSG_NOCRLF) )
|
||||
fputc( '\n', of );
|
||||
return primary | STS$M_INHIB_MSG;
|
||||
}
|
||||
|
||||
msg = getmsg_string( vmscond, flags );
|
||||
|
||||
if( flags & (MSG_FACILITY | MSG_SEVERITY | MSG_NAME) ) {
|
||||
pfxe = strchr( msg, ',' );
|
||||
if( pfxe == NULL ) {
|
||||
abort();
|
||||
}
|
||||
pfxe += 2;
|
||||
fprintf( of, "%.*s", (int)(pfxe - msg), msg );
|
||||
} else {
|
||||
pfxe = msg;
|
||||
}
|
||||
|
||||
vfprintf( of, pfxe, ap );
|
||||
|
||||
if( !(flags & MSG_NOCRLF) )
|
||||
fputc( '\n', of );
|
||||
|
||||
return primary | STS$M_INHIB_MSG;
|
||||
}
|
||||
|
||||
/******************************************************************* getmsg() */
|
||||
|
||||
const char *getmsg( unsigned int vmscode, unsigned int flags, ... ) {
|
||||
const struct VMSMSG *mp = NULL;
|
||||
const char *getmsg( vmscond_t vmscond, unsigned int flags, ... ) {
|
||||
char *buf, *msg;
|
||||
va_list ap;
|
||||
size_t prelen, len, fmtlen;
|
||||
|
||||
if( !(flags & MSG_WITHARGS) ) {
|
||||
return getmsg_string( vmscond, flags );
|
||||
}
|
||||
|
||||
buf = retbuf[ lastidx ];
|
||||
|
||||
prelen = 0;
|
||||
errno = 0;
|
||||
(void) getmsg_string( vmscond, flags );
|
||||
if( errno )
|
||||
return strerror( errno );
|
||||
|
||||
fmtlen = strlen( buf );
|
||||
|
||||
if( (msg = strchr( buf, ',')) != NULL ) {
|
||||
prelen = 2 + (size_t)( msg -buf );
|
||||
}
|
||||
|
||||
va_start( ap, flags );
|
||||
len = vsnprintf( buf+fmtlen+1, 1, buf, ap );
|
||||
va_end( ap );
|
||||
|
||||
if( (buf = realloc( buf, fmtlen + 1 + len + 1 )) == NULL )
|
||||
return strerror( errno );
|
||||
retbuf[lastidx] = buf;
|
||||
|
||||
va_start( ap, flags );
|
||||
(void) vsnprintf( buf+fmtlen + 1, len+1, buf + prelen, ap );
|
||||
va_end( ap );
|
||||
|
||||
memmove( buf, buf+fmtlen+1, len + 1 );
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/******************************************************************* argcount() */
|
||||
static int argcount( vmscond_t vmscond ) {
|
||||
struct VMSMSG *mp, key;
|
||||
|
||||
memset( &key, 0, sizeof( key ) );
|
||||
key.code = vmscond;
|
||||
mp = bsearch( &key, vms2text, msglen,
|
||||
sizeof(vms2text[0]), msgcmp );
|
||||
if( mp == NULL )
|
||||
return -1;
|
||||
|
||||
return mp->nargs;
|
||||
}
|
||||
|
||||
/******************************************************************* getmsg_string() */
|
||||
|
||||
const char *getmsg_string( vmscond_t vmscond, unsigned int flags ) {
|
||||
const struct VMSFAC *fp = NULL;
|
||||
const struct VMSMSG *mp = NULL;
|
||||
struct VMSFAC fackey;
|
||||
struct VMSMSG msgkey;
|
||||
|
||||
memset( &fackey, 0, sizeof( fackey ) );
|
||||
memset( &msgkey, 0, sizeof( msgkey ) );
|
||||
|
||||
if( !(flags & MSG_FULL) )
|
||||
flags = (flags & ~MSG_FULL) | MSG_FULL;
|
||||
flags = (flags & ~MSG_FULL) | message_format;
|
||||
|
||||
while( 1 ) {
|
||||
size_t i = 0, len;
|
||||
@@ -174,14 +275,30 @@ const char *getmsg( unsigned int vmscode, unsigned int flags, ... ) {
|
||||
if( flags & (MSG_FACILITY|MSG_SEVERITY|MSG_NAME) ) {
|
||||
if( !xpand( i, 1 ) )
|
||||
return strerror( errno );
|
||||
buf[i++] = '%';
|
||||
buf[i++] = (flags & MSG_CONTINUE)? '-': '%';
|
||||
|
||||
if( fp == NULL ) {
|
||||
for( fp = fac2text; fp->text != NULL; fp++ ) {
|
||||
if( fp->code == $VMS_STATUS_FAC_NO(vmscode) )
|
||||
break;
|
||||
uint32_t facno;
|
||||
|
||||
facno = $VMS_STATUS_FAC_NO(vmscond);
|
||||
|
||||
if( facno == 0 ) {
|
||||
fp = &sysfac;
|
||||
if( !$VMS_STATUS_FAC_SP(vmscond) ) {
|
||||
uint32_t msgno;
|
||||
|
||||
msgno = $VMS_STATUS_CODE(vmscond);
|
||||
if( msgno >= 4096 && msgno < 8192 )
|
||||
fp = &shrfac;
|
||||
}
|
||||
} else {
|
||||
fackey.code = facno;
|
||||
fp = bsearch( &fackey, fac2text, faclen,
|
||||
sizeof(fac2text[0]), faccmp );
|
||||
if( fp == NULL ) fp = &nofac;
|
||||
}
|
||||
}
|
||||
|
||||
if( fp->text == NULL )
|
||||
break;
|
||||
if( flags & MSG_FACILITY ) {
|
||||
@@ -197,28 +314,22 @@ const char *getmsg( unsigned int vmscode, unsigned int flags, ... ) {
|
||||
if( flags & MSG_SEVERITY ) {
|
||||
if( !xpand( i, 2 ) )
|
||||
return strerror( errno );
|
||||
buf[i++] = sev2text[$VMS_STATUS_SEVERITY(vmscode)];
|
||||
buf[i++] = sev2text[$VMS_STATUS_SEVERITY(vmscond)];
|
||||
if( flags & MSG_NAME )
|
||||
buf[i++] = '-';
|
||||
}
|
||||
if( flags & MSG_NAME ) {
|
||||
char *p;
|
||||
|
||||
if( mp == NULL ) {
|
||||
for( mp = vms2text; mp->text != NULL; mp++ ) {
|
||||
if( $VMS_STATUS_COND_ID(vmscode) == mp-> code )
|
||||
break;
|
||||
}
|
||||
msgkey.code = vmscond;
|
||||
mp = bsearch( &msgkey, vms2text, msglen,
|
||||
sizeof(vms2text[0]), msgcmp );
|
||||
}
|
||||
if( mp->text == NULL )
|
||||
if( mp == NULL )
|
||||
break;
|
||||
p = strchr( mp->txtcode, '_' );
|
||||
if( p == NULL )
|
||||
abort();
|
||||
len = strlen( ++p );
|
||||
len = strlen( mp->ident );
|
||||
if( !xpand( i, len ) )
|
||||
return strerror( errno );
|
||||
memcpy( buf+i, p, len );
|
||||
memcpy( buf+i, mp->ident, len );
|
||||
i += len;
|
||||
}
|
||||
if( flags & MSG_TEXT ) {
|
||||
@@ -229,50 +340,398 @@ const char *getmsg( unsigned int vmscode, unsigned int flags, ... ) {
|
||||
}
|
||||
}
|
||||
if( flags & MSG_TEXT ) {
|
||||
va_list ap;
|
||||
if( mp == NULL ) {
|
||||
for( mp = vms2text; mp->text; mp++ ) {
|
||||
if( $VMS_STATUS_COND_ID(vmscode) == mp-> code )
|
||||
break;
|
||||
}
|
||||
if( mp->text == NULL )
|
||||
msgkey.code = vmscond;
|
||||
mp = bsearch( &msgkey, vms2text, msglen,
|
||||
sizeof(vms2text[0]), msgcmp );
|
||||
if( mp == NULL )
|
||||
break;
|
||||
}
|
||||
if( flags & MSG_WITHARGS ) {
|
||||
va_start( ap, flags );
|
||||
len = vsnprintf( buf+i, 1, mp->text, ap );
|
||||
va_end( ap );
|
||||
} else
|
||||
len = strlen( mp->text );
|
||||
len = strlen( mp->text );
|
||||
if( !xpand( i, len ) )
|
||||
return strerror( errno );
|
||||
if( flags & MSG_WITHARGS ) {
|
||||
va_start( ap, flags );
|
||||
(void) vsnprintf( buf+i, len+1, mp->text, ap );
|
||||
va_end( ap );
|
||||
} else
|
||||
memcpy( buf+i, mp->text, len );
|
||||
|
||||
memcpy( buf+i, mp->text, len );
|
||||
if( !(flags & (MSG_FACILITY|MSG_SEVERITY|MSG_NAME|MSG_NOUC)) )
|
||||
buf[i] = toupper( buf[i] );
|
||||
|
||||
i += len;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
return buf;
|
||||
return returnbuf();
|
||||
} while( 0 );
|
||||
|
||||
if( fp == NULL || fp->text == NULL )
|
||||
fp = fac2text + (sizeof(fac2text)/sizeof(fac2text[0])) -1;
|
||||
fp = &nofac;
|
||||
|
||||
mp = vms2text + (sizeof(vms2text)/sizeof(vms2text[0])) -1;
|
||||
(void) snprintf( notext, sizeof(notext), nofmt, vmscode );
|
||||
if( mp == NULL || mp->text == NULL ) {
|
||||
msgkey.code = vmscond;
|
||||
mp = bsearch( &msgkey, vms2text, msglen,
|
||||
sizeof(vms2text[0]), msgcmp );
|
||||
if( mp == NULL || mp->text == NULL ) {
|
||||
msgkey.code = ODS2_NOMSG;
|
||||
mp = bsearch( &msgkey, vms2text, msglen,
|
||||
sizeof(vms2text[0]), msgcmp );
|
||||
if( mp == NULL || mp->text == NULL ) {
|
||||
(void) snprintf( notext, sizeof(notext),
|
||||
"message number %08X", vmscond );
|
||||
} else {
|
||||
(void) snprintf( notext, sizeof(notext),
|
||||
mp->text, vmscond );
|
||||
notext[sizeof(notext) -1] = '\0';
|
||||
}
|
||||
mp = &nomsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************* xpand() */
|
||||
|
||||
static int xpand( size_t used, size_t add ) {
|
||||
char *nbuf;
|
||||
size_t need;
|
||||
|
||||
need = used + add + 1; /* Always allow for \0 */
|
||||
if( need < bufsize ) {
|
||||
return 1;
|
||||
}
|
||||
nbuf = realloc( buf, need + 32 + 1); /* 32 minimizes reallocs */
|
||||
if( nbuf == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
buf = nbuf;
|
||||
bufsize = need + 32 + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************* returnbuf() */
|
||||
|
||||
static const char *returnbuf( void ) {
|
||||
const char *rbuf;
|
||||
|
||||
lastidx = retidx;
|
||||
free( retbuf[retidx] );
|
||||
retbuf[retidx++] = buf;
|
||||
retidx %= sizeof( retbuf ) / sizeof( retbuf[0] );
|
||||
rbuf = buf;
|
||||
buf = NULL;
|
||||
bufsize = 0;
|
||||
return rbuf;
|
||||
}
|
||||
|
||||
/***************************************************************** set_message_format */
|
||||
vmscond_t set_message_format( options_t new ) {
|
||||
|
||||
message_format = new & (MSG_FACILITY|MSG_SEVERITY|MSG_NAME|MSG_TEXT);
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/***************************************************************** set_message_format */
|
||||
options_t get_message_format( void ) {
|
||||
|
||||
return message_format;
|
||||
}
|
||||
|
||||
/******************************************************************* set_message_file */
|
||||
|
||||
vmscond_t set_message_file( const char *filename ) {
|
||||
vmscond_t sts;
|
||||
char *newmsg = NULL;
|
||||
char *newfilename = NULL;
|
||||
FILE *mf = NULL;
|
||||
|
||||
if( filename == NULL ) { /* Reset to built-in default tables */
|
||||
fac2text = fac2textdef;
|
||||
vms2text = vms2textdef;
|
||||
faclen = (sizeof(fac2textdef)/sizeof(fac2textdef[0]));
|
||||
msglen = sizeof(vms2textdef)/sizeof(vms2textdef[0]);
|
||||
|
||||
if( msgfile != NULL ) {
|
||||
free( msgfile );
|
||||
msgfile = NULL;
|
||||
}
|
||||
if( msgfilename ) {
|
||||
free( msgfilename );
|
||||
msgfilename = NULL;
|
||||
}
|
||||
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
/* Load a file (built by genmsg.c) */
|
||||
|
||||
sts = ODS2_OPENIN;
|
||||
errno = 0;
|
||||
do {
|
||||
size_t size, i;
|
||||
uint32_t facn, msgn;
|
||||
uint32_t code, nargs;
|
||||
int c, n;
|
||||
char *np, *sp;
|
||||
off_t pos;
|
||||
|
||||
if( (newfilename = get_realpath( filename )) == NULL ) {
|
||||
size = strlen( filename ) +1;
|
||||
if( (newfilename = malloc( size)) == NULL ) {
|
||||
sts = SS$_INSFMEM;
|
||||
break;
|
||||
}
|
||||
memcpy( newfilename, filename, size );
|
||||
}
|
||||
|
||||
if( (mf = openf( newfilename, "rb" )) == NULL ) {
|
||||
break;
|
||||
}
|
||||
|
||||
sts = ODS2_BADMSGFILE;
|
||||
|
||||
/* File header record */
|
||||
|
||||
n = 0;
|
||||
if( (c = fscanf( mf, MSG_HEADER_DEC, &facn, &msgn, &n )) == EOF ||
|
||||
c < 2 ||
|
||||
n != MSG_HEADER_DECN )
|
||||
break;
|
||||
|
||||
size = ( (facn * sizeof( struct VMSFAC ) ) +
|
||||
(msgn * sizeof( struct VMSMSG ) ) );
|
||||
|
||||
if( (c = getc( mf )) != '\0' )
|
||||
break;
|
||||
|
||||
pos = ftell( mf );
|
||||
|
||||
/* Compute string pool size */
|
||||
|
||||
/* Facility records */
|
||||
|
||||
for( i = 0; i < facn; i++ ) {
|
||||
n = 0;
|
||||
if( (c = fscanf( mf, MSG_FAC_DEC, &code, &n )) == EOF ||
|
||||
c < 1 ||
|
||||
n != MSG_FAC_DECN )
|
||||
break;
|
||||
|
||||
if( (c = decstr( mf, &size, NULL, NULL )) == EOF )
|
||||
break;
|
||||
}
|
||||
if( c == EOF || i < facn )
|
||||
break;
|
||||
|
||||
/* Message description records */
|
||||
|
||||
for( i = 0; i < msgn; i++ ) {
|
||||
n = 0;
|
||||
if( (c = fscanf( mf, MSG_MSG_DEC, &code, &nargs, &n )) == EOF ||
|
||||
c < 2 ||
|
||||
n != MSG_MSG_DECN )
|
||||
break;
|
||||
|
||||
if( (c = decstr( mf, &size, NULL, NULL )) == EOF )
|
||||
break;
|
||||
if( (c = decstr( mf, &size, NULL, NULL )) == EOF )
|
||||
break;
|
||||
}
|
||||
if( c == EOF || i < msgn )
|
||||
break;
|
||||
|
||||
/* Allocate enough memory for the tables and the string pool */
|
||||
|
||||
if( fseek( mf, pos, SEEK_SET ) == -1 )
|
||||
break;
|
||||
|
||||
if( (newmsg = malloc( size )) == NULL ) {
|
||||
sts = SS$_INSFMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
np = newmsg;
|
||||
sp = np + ((facn * sizeof( struct VMSFAC )) +
|
||||
(msgn * sizeof( struct VMSMSG )));
|
||||
|
||||
/* Create each structure along with any strings. */
|
||||
|
||||
/* Facility records */
|
||||
|
||||
for( i = 0; i < facn; i++ ) {
|
||||
struct VMSFAC *fp = (struct VMSFAC *)np;
|
||||
|
||||
np += sizeof( struct VMSFAC );
|
||||
|
||||
n = 0;
|
||||
if( (c = fscanf( mf, MSG_FAC_DEC, &code, &n )) == EOF ||
|
||||
c < 1 ||
|
||||
n != MSG_FAC_DECN )
|
||||
break;
|
||||
|
||||
fp->code = code;
|
||||
if( (c = decstr( mf, &size, &sp, &fp->text )) == EOF )
|
||||
break;
|
||||
}
|
||||
if( c == EOF || i < facn )
|
||||
break;
|
||||
|
||||
/* Message description records */
|
||||
|
||||
for( i = 0; i < msgn; i++ ) {
|
||||
struct VMSMSG *mp = (struct VMSMSG *)np;
|
||||
|
||||
np += sizeof( struct VMSMSG );
|
||||
|
||||
n = 0;
|
||||
if( (c = fscanf( mf, MSG_MSG_DEC, &code, &nargs, &n )) == EOF ||
|
||||
c < 2 ||
|
||||
n != MSG_MSG_DECN )
|
||||
break;
|
||||
|
||||
mp->code = code;
|
||||
mp->nargs = nargs;
|
||||
|
||||
if( (c = decstr( mf, &size, &sp, &mp->ident )) == EOF )
|
||||
break;
|
||||
if( (c = decstr( mf, &size, &sp, &mp->text )) == EOF )
|
||||
break;
|
||||
}
|
||||
if( c == EOF || i < msgn )
|
||||
break;
|
||||
|
||||
/* EOF */
|
||||
n = 0;
|
||||
if( (c = fscanf( mf, MSG_EOF_DEC, &n )) == EOF ||
|
||||
c < 0 ||
|
||||
n != MSG_EOF_DECN || (c = getc( mf )) != 0 )
|
||||
break;
|
||||
|
||||
/* Success. Install new file. */
|
||||
|
||||
free( msgfile );
|
||||
msgfile = newmsg;
|
||||
|
||||
free( msgfilename );
|
||||
msgfilename = newfilename;
|
||||
newfilename = NULL;
|
||||
|
||||
fac2text = (struct VMSFAC *)newmsg;
|
||||
vms2text = (struct VMSMSG *)(newmsg +
|
||||
(facn * sizeof( struct VMSFAC )));
|
||||
msglen = msgn;
|
||||
faclen = (size_t)facn;
|
||||
|
||||
newmsg = NULL;
|
||||
|
||||
sts = SS$_NORMAL;
|
||||
} while( 0 );
|
||||
|
||||
if( mf != NULL ) {
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
fclose( mf );
|
||||
if( err )
|
||||
errno = err;
|
||||
}
|
||||
|
||||
if( $FAILED(sts) ) {
|
||||
if( errno ) {
|
||||
int err;
|
||||
|
||||
err = errno;
|
||||
printmsg( sts, 0, newfilename );
|
||||
sts = printmsg( ODS2_OSERROR, MSG_CONTINUE, sts,
|
||||
strerror( err ) );
|
||||
} else
|
||||
sts = printmsg( sts, 0, newfilename );
|
||||
|
||||
if( newmsg != NULL ) free( newmsg );
|
||||
if( newfilename != NULL ) free( newfilename );
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
/********************************************************** showmessagefile() */
|
||||
vmscond_t show_message( int argc, char **argv ) {
|
||||
unsigned long n;
|
||||
|
||||
if( argc > 2 ) { /* SHOW MESSAGE numeric [numeric...] */
|
||||
for( ; argc > 2; --argc, ++argv ) {
|
||||
n = strtoul( argv[2], NULL, 0 );
|
||||
if( $PRINTED((vmscond_t)n) ){
|
||||
printmsg( HELP_SHOWMSGPRINTED, MSG_TEXT | MSG_NOCRLF );
|
||||
printmsg( (vmscond_t)n, MSG_CONTINUE | MSG_ALWAYS, HELP_SHOWMSGPRINTED );
|
||||
} else
|
||||
printmsg( (vmscond_t)n, MSG_NOARGS | MSG_ALWAYS );
|
||||
}
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
return printmsg( ODS2_MSGFILE, 0, (msgfilename? msgfilename: "/DEFAULT") );
|
||||
}
|
||||
|
||||
/******************************************************************* decstr() */
|
||||
|
||||
static int decstr( FILE *mf, size_t *size, char **pp, char **sp ) {
|
||||
int c;
|
||||
size_t len = 0;
|
||||
|
||||
if( sp != NULL )
|
||||
*sp = NULL;
|
||||
|
||||
while( (c = getc( mf )) != EOF && c != '\0' ) {
|
||||
if( len == 0 ) {
|
||||
len = 1;
|
||||
if( sp != NULL )
|
||||
*sp = *pp;
|
||||
}
|
||||
if( c == '\001' ) {
|
||||
const char *s;
|
||||
size_t slen;
|
||||
|
||||
c = getc( mf );
|
||||
if( c == EOF )
|
||||
return c;
|
||||
|
||||
if( c < PRI_CODEBASE || c > PRI_CODEEND )
|
||||
return EOF;
|
||||
|
||||
s = pristr[ c - PRI_CODEBASE ];
|
||||
len +=
|
||||
slen = strlen( s );
|
||||
if( sp != NULL ) {
|
||||
memcpy( *pp, s, slen );
|
||||
*pp += slen;
|
||||
}
|
||||
} else {
|
||||
if( sp != NULL )
|
||||
*(*pp)++ = c;
|
||||
++len;
|
||||
}
|
||||
}
|
||||
if( c == EOF )
|
||||
return c;
|
||||
|
||||
*size += len;
|
||||
if( sp != NULL && len != 0 )
|
||||
*(*pp)++ = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************* sysmsg_rundown() */
|
||||
|
||||
void sysmsg_rundown( void ) {
|
||||
size_t i;
|
||||
|
||||
for( i = 0; i < sizeof( retbuf ) / sizeof( retbuf[0] ); i++ )
|
||||
if( retbuf[i] != buf ) {
|
||||
free( retbuf[i] );
|
||||
retbuf[i] = NULL;
|
||||
}
|
||||
free( buf );
|
||||
buf = NULL;
|
||||
free( msgfile );
|
||||
msgfile = NULL;
|
||||
free( msgfilename );
|
||||
msgfilename = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user