Merge "Omaha #3528 - removed unused versions of ldm from the baseline" into omaha_14.4.1
Former-commit-id:fffa5f5294
[formerly 61a982c8624ab6e433692255109119ab9f74655c] Former-commit-id:7331754776
This commit is contained in:
commit
5a35e873ac
367 changed files with 0 additions and 116004 deletions
411
ldm/.cproject
411
ldm/.cproject
|
@ -1,411 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?>
|
||||
|
||||
<cproject>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.511392745">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.511392745" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="ldm" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.511392745" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.511392745." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1507372032" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.1854026479" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
|
||||
<builder buildPath="${workspace_loc:/ldm/Debug}" id="cdt.managedbuild.target.gnu.builder.exe.debug.400911135" managedBuildOn="true" name="Gnu Make Builder.Debug" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.294982859" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1248516765" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1194121741" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1133258659" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.368884640" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.865956660" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1409256903" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1106099261" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.692421051" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1447774617" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.511392745;cdt.managedbuild.config.gnu.exe.debug.511392745.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.368884640;cdt.managedbuild.tool.gnu.c.compiler.input.99679941">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.1800080654">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.1800080654" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="ldm" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1800080654" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.1800080654." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1595536122" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1067435329" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
|
||||
<builder buildPath="${workspace_loc:/ldm/Release}" id="cdt.managedbuild.target.gnu.builder.exe.release.1596014357" managedBuildOn="true" name="Gnu Make Builder.Release" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1403019986" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.753397929" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
|
||||
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.2007606648" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.606066033" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.2050436167" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
|
||||
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1108424290" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.exe.release.option.debugging.level.440297915" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.1035986403" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.175364583" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.1312750372" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.511392745;cdt.managedbuild.config.gnu.exe.debug.511392745.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.368884640;cdt.managedbuild.tool.gnu.c.compiler.input.99679941">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="ldm.cdt.managedbuild.target.gnu.exe.130220916" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||
</storageModule>
|
||||
</cproject>
|
81
ldm/.project
81
ldm/.project
|
@ -1,81 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ldm</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/ldm/Debug}</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,5 +0,0 @@
|
|||
To compile the file in src, type the following at a command line in the src
|
||||
folder and copy the resulting executable to the decoders folder in the LDM
|
||||
install:
|
||||
|
||||
cc -D_GNU_SOURCE -o decrypt_file decrypt_file.c
|
|
@ -1,268 +0,0 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
|
||||
File name:
|
||||
decrypt_file.c
|
||||
|
||||
Compilation:
|
||||
cc -D_GNU_SOURCE -o decrypt_file decrypt_file.c
|
||||
|
||||
Requirements:
|
||||
- cruft must be installed
|
||||
- the decryption key must be in ~/.key
|
||||
|
||||
File description:
|
||||
This program attempts to decrypt a stream of data that has been encrypted
|
||||
with cruft.
|
||||
|
||||
This program reads data from stdin. It assumes that there is some kind of
|
||||
header before the start of the cruft header that must be stripped, though
|
||||
it will still work if there is no header.
|
||||
|
||||
If the cruft header is not found within the first 128 bytes, then the input
|
||||
data is simply copied to the output file since decryption is not needed. If
|
||||
a cruft header is found, then the data is piped to cruft for decryption and
|
||||
is written to the file name matching the template specified on the command line.
|
||||
|
||||
This program takes one argument: the output file name template that is used
|
||||
by the mkstemp system call to open a file with a unique file name. The
|
||||
string (".XXXXXX") is appended by this program as required by mkstemp.
|
||||
|
||||
Any program looking for files to process that are output by this program
|
||||
should look at the file permissions before attempting a read. When this
|
||||
program has finished writing the output file, it will change permissions to
|
||||
0666.
|
||||
|
||||
Command line:
|
||||
decrypt_file <output_file_name>
|
||||
|
||||
Author:
|
||||
Brian M. Rapp 03/19/2009
|
||||
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define MAX_BUF_SIZE 4096 // This must not be greater than PIPE_BUF
|
||||
// as defined in the kernel header file
|
||||
// /usr/src/linux/include/linux/limits.h
|
||||
|
||||
#define HDR_DEPTH 128 // The cruft header must occur within 128
|
||||
// bytes of the beginning of the file.
|
||||
|
||||
#define ENCRYPT_PROGRAM "cruft" // The code may require modification if
|
||||
// a different decryption tool is used.
|
||||
|
||||
#define INSERT_PROGRAM "pqinsert" // LDM tool to insert data into the product
|
||||
// queue
|
||||
|
||||
#define CRUFT_HDR_SIZE 9 // Cruft header length (see cruft_hdr below)
|
||||
#define SBN_HDR_SIZE 24 // Length of the SBN header
|
||||
#define WMO_HDR_SIZE 21 // Length of the WMO header (TTAAii CCCC DDHHMM\r\r\n)
|
||||
#define OPEN_FILE_PERMS (S_IRUSR | S_IWUSR)
|
||||
#define DONE_FILE_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
|
||||
#define DIR_PERMS 0777 // the permissions for the directories created
|
||||
#define DECRYPT_FLAG_OFFSET 5 // Offset to NWSTG CCB encryption flag
|
||||
|
||||
char *progname;
|
||||
char cruft_hdr[] = {253, 253, 253, 253, 253, 253, 253, 253, 253};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void usage (char *exename) {
|
||||
//fprintf (stderr, "Usage: %s output_file_path feed_type\n", exename); // no feed_type
|
||||
fprintf (stderr, "Usage: %s output_file_path \n", exename);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
char *out_template; // Input as the file name template from the command
|
||||
// line. This is modified by mkstemp to the output
|
||||
// file name.
|
||||
|
||||
int out_fd; // Output file descriptor returned by call to mkstemp
|
||||
FILE *out_pipe; // File pointer returned by call to popen for decryption
|
||||
size_t len; // Length of buffers read from STDIN
|
||||
size_t wlen; // Length of the write buffer
|
||||
size_t count; // Number of items written by calls to fwrite
|
||||
char file_buf[MAX_BUF_SIZE]; // Input buffer from STDIN
|
||||
char *hdr_ptr; // Pointer to start of cruft header within file_buf
|
||||
char command_line[128]; // Command line for starting cruft via popen
|
||||
char pqinsert_line[128]; // PQInsert Line
|
||||
char *sbn_hdr_ptr; // Pointer to the start of the 24-byte SBN header in each product
|
||||
char *slash_ptr; // pointer for the slashes in the path
|
||||
progname = argv[0]; // Get the program name
|
||||
|
||||
if (argc != 2) { // Only 1 parameter - the template for the output file name.
|
||||
usage (argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
len = (size_t) strlen (argv[1]) + 7 + 1; // Allocate 7 extra bytes for the ".XXXXXX"
|
||||
// plus 1 for the terminating nul
|
||||
if ((out_template = malloc (len)) == NULL) { // Try to malloc memory for output file name
|
||||
fprintf (stderr, "%s: Error \"%s\" while allocating memory for output template -- exiting\n",
|
||||
progname, strerror (errno));
|
||||
exit (errno);
|
||||
}
|
||||
|
||||
sprintf (out_template, "%s.XXXXXX", argv[1]); // Output file name template
|
||||
|
||||
// the reasons the DIR_PERMS are 777 is because of NFS permission issues with mkdir
|
||||
// make sure all of the intervening directories in out_template actually exist
|
||||
slash_ptr = strchr ( out_template, '/' );
|
||||
while ( slash_ptr != NULL )
|
||||
{
|
||||
*slash_ptr = '\0'; // truncate at the slash
|
||||
if ( strlen( out_template ) > 0 ) // corner case with a leading slash
|
||||
{
|
||||
if ( mkdir ( out_template, DIR_PERMS ) == - 1 && errno != EEXIST )
|
||||
{
|
||||
// it failed but not because the directory already exists
|
||||
fprintf ( stderr, "mkdir errno %d\n", errno );
|
||||
if ( errno == EPERM )
|
||||
{
|
||||
fprintf ( stderr, "mkdir permission error\n" );
|
||||
}
|
||||
exit (errno);
|
||||
}
|
||||
}
|
||||
*slash_ptr = '/'; // put the slash back
|
||||
++slash_ptr;
|
||||
slash_ptr = strchr ( slash_ptr, '/' ); // find the next slash
|
||||
}
|
||||
|
||||
if ((out_fd = mkstemp (out_template)) == -1) { // Create and open a unique temporary file for output
|
||||
fprintf (stderr, "%s: Error \"%s\" creating temporary file for template %s -- exiting\n",
|
||||
progname, strerror (errno), out_template);
|
||||
exit (errno);
|
||||
}
|
||||
|
||||
// Try to read some data from STDIN
|
||||
if ((len = read (STDIN_FILENO, file_buf, MAX_BUF_SIZE)) < 0) { // Error if read return negative value -- clean up
|
||||
fprintf (stderr, "%s: Error \"%s\" reading from STDIN -- exiting\n",
|
||||
progname, strerror (errno));
|
||||
close (out_fd);
|
||||
unlink (out_template);
|
||||
exit (errno);
|
||||
} else if (len == 0) { // Input data stream is empty -- clean up
|
||||
fprintf (stderr, "%s: File is empty -- ignoring\n", progname);
|
||||
close (out_fd);
|
||||
unlink (out_template);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
// If we're here, then we read some bytes from STDIN.
|
||||
// If the input buffer is less than 128 bytes, then only search through the number of bytes read
|
||||
if ((hdr_ptr = memmem (file_buf, (len < HDR_DEPTH) ? len : HDR_DEPTH, cruft_hdr, CRUFT_HDR_SIZE)) == NULL) {
|
||||
// then there is no cruft header within the first HDR_DEPTH bytes
|
||||
|
||||
if ((wlen = write (out_fd, file_buf, len)) != len) { // Try to write the input buffer to the output file
|
||||
fprintf (stderr, "%s: Error \"%s\" writing to %s -- exiting\n", progname, strerror (errno), out_template);
|
||||
close (out_fd);
|
||||
unlink (out_template);
|
||||
exit (errno);
|
||||
}
|
||||
|
||||
// Read the rest of the input data and write it to the output file, exit on error
|
||||
while ((len = read (STDIN_FILENO, file_buf, MAX_BUF_SIZE)) > 0) {
|
||||
if ((wlen = write (out_fd, file_buf, len)) != len) {
|
||||
fprintf (stderr, "%s: Error \"%s\" writing to %s -- exiting\n", progname, strerror (errno), out_template);
|
||||
close (out_fd);
|
||||
unlink (out_template);
|
||||
exit (errno);
|
||||
}
|
||||
}
|
||||
|
||||
if (len < 0) { // Uh oh, there was an error reading from STDIN
|
||||
fprintf (stderr, "%s: Error \"%s\" reading from STDIN -- exiting\n",
|
||||
progname, strerror (errno));
|
||||
close (out_fd);
|
||||
unlink (out_template);
|
||||
exit (errno);
|
||||
}
|
||||
|
||||
close (out_fd); // Close the output file
|
||||
} else { // Found a cruft header
|
||||
// Write the 24-byte SBN header to the output file before closing it. Cruft will append to this file.
|
||||
sbn_hdr_ptr = hdr_ptr - (WMO_HDR_SIZE + SBN_HDR_SIZE);
|
||||
|
||||
// Change compression flag from 'E' to 'U'
|
||||
if (file_buf[0] == 0x40) {
|
||||
if (file_buf[DECRYPT_FLAG_OFFSET] == 'E') {
|
||||
file_buf[DECRYPT_FLAG_OFFSET] = 'U';
|
||||
}
|
||||
}
|
||||
|
||||
if ((wlen = write (out_fd, sbn_hdr_ptr, SBN_HDR_SIZE)) != SBN_HDR_SIZE) {
|
||||
fprintf (stderr, "%s: Error \"%s\" writing SBN header to %s -- exiting\n", progname, strerror (errno), out_template);
|
||||
close (out_fd);
|
||||
unlink (out_template);
|
||||
exit (errno);
|
||||
}
|
||||
|
||||
close (out_fd);
|
||||
|
||||
if (chmod (out_template, OPEN_FILE_PERMS) < 0) { // Set file perms to 0600 so cruft can write to it.
|
||||
fprintf (stderr, "%s: Error \"%s\" changing file permissions on %s to %od\n",
|
||||
progname, strerror (errno), out_template, DONE_FILE_PERMS);
|
||||
}
|
||||
|
||||
sprintf (command_line, "%s >> %s", ENCRYPT_PROGRAM, out_template); // Create pipe command line
|
||||
if ((out_pipe = popen (command_line, "w")) == NULL) { // Try to open pipe for output to cruft
|
||||
fprintf (stderr, "%s: Error \"%s\" while attempting to open pipe to %s -- exiting\n",
|
||||
progname, strerror (errno), command_line);
|
||||
unlink (out_template); // Clean up mess
|
||||
exit (errno);
|
||||
}
|
||||
|
||||
wlen = file_buf + len - hdr_ptr; // Calculate the length of the output buffer from the start of the cruft header
|
||||
if ((count = fwrite (hdr_ptr, wlen, 1, out_pipe)) != 1) { // Try to pipe the output buffer to cruft
|
||||
fprintf (stderr, "%s: Error \"%s\" writing to output pipe -- only wrote %d items exiting\n",
|
||||
progname, strerror (errno), (int) count);
|
||||
fclose (out_pipe);
|
||||
unlink (out_template); // Clean up mess
|
||||
exit (errno);
|
||||
}
|
||||
|
||||
while ((len = read (STDIN_FILENO, file_buf, MAX_BUF_SIZE)) > 0) {
|
||||
if ((count = fwrite (file_buf, len, 1, out_pipe)) != 1) {
|
||||
fprintf (stderr, "%s: Error \"%s\" writing to output pipe -- only wrote %d items exiting\n",
|
||||
progname, strerror (errno), (int) count);
|
||||
fclose (out_pipe);
|
||||
unlink (out_template); // Clean up mess
|
||||
exit (errno);
|
||||
}
|
||||
}
|
||||
|
||||
if (len < 0) { // Uh oh, there was an error reading from STDIN
|
||||
fprintf (stderr, "%s: Error \"%s\" reading from STDIN -- exiting\n", progname, strerror (errno));
|
||||
fclose (out_pipe);
|
||||
unlink (out_template); // Clean up the mess
|
||||
exit (errno);
|
||||
}
|
||||
|
||||
fclose (out_pipe);
|
||||
|
||||
sprintf(pqinsert_line, "%s %s", INSERT_PROGRAM, out_template);
|
||||
if((system(pqinsert_line)) > 0) {
|
||||
fprintf (stderr, "%s: Error \"%s\" running pqinsert -- file not inserted into data stream\n", progname, strerror (errno));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Change file permissions on output file to 0666 as a signal to anyone watching that the file is available for access now
|
||||
if (chmod (out_template, DONE_FILE_PERMS) < 0) {
|
||||
fprintf (stderr, "%s: Error \"%s\" changing file permissions on %s to %od\n", progname, strerror (errno), out_template, DONE_FILE_PERMS);
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
1494
ldm/src/CHANGE_LOG
1494
ldm/src/CHANGE_LOG
File diff suppressed because it is too large
Load diff
|
@ -1,30 +0,0 @@
|
|||
Copyright 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 University Corporation for Atmospheric Research/Unidata
|
||||
|
||||
Portions of this software were developed by the Unidata Program at the
|
||||
University Corporation for Atmospheric Research.
|
||||
|
||||
Access and use of this software shall impose the following obligations
|
||||
and understandings on the user. The user is granted the right, without
|
||||
any fee or cost, to use, copy, modify, alter, enhance and distribute
|
||||
this software, and any derivative works thereof, and its supporting
|
||||
documentation for any purpose whatsoever, provided that this entire
|
||||
notice appears in all copies of the software, derivative works and
|
||||
supporting documentation. Further, UCAR requests that the user credit
|
||||
UCAR/Unidata in any publications that result from the use of this
|
||||
software or in any product that includes this software. The names UCAR
|
||||
and/or Unidata, however, may not be used in any advertising or publicity
|
||||
to endorse or promote any products or commercial entity unless specific
|
||||
written permission is obtained from UCAR/Unidata. The user also
|
||||
understands that UCAR/Unidata is not obligated to provide the user with
|
||||
any support, consulting, training or assistance of any kind with regard
|
||||
to the use, operation and performance of this software nor to provide
|
||||
the user with any updates, revisions, new versions or "bug fixes."
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "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 UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
|
||||
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||||
FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
|
403
ldm/src/Makefile
403
ldm/src/Makefile
|
@ -1,403 +0,0 @@
|
|||
# $Id: Makefile,v 1.6.2.6.4.4.2.23 2008/04/11 14:54:50 steve Exp $
|
||||
#
|
||||
# top level Makefile for ldm5
|
||||
#
|
||||
###
|
||||
|
||||
include macros.make
|
||||
|
||||
# Order is important here
|
||||
LIBSUBDIRS = \
|
||||
config \
|
||||
ulog \
|
||||
misc \
|
||||
protocol \
|
||||
pq \
|
||||
fauxPq
|
||||
|
||||
PROGSUBDIRS = \
|
||||
pqcheck \
|
||||
pqcreate \
|
||||
pqinsert \
|
||||
pqcat \
|
||||
pqexpire \
|
||||
pqmon \
|
||||
pqutil \
|
||||
pqsend \
|
||||
pqing \
|
||||
pqact \
|
||||
pqsurf \
|
||||
send \
|
||||
rtstats \
|
||||
feedme \
|
||||
notifyme \
|
||||
regex \
|
||||
server \
|
||||
ldmping \
|
||||
scripts \
|
||||
scour
|
||||
|
||||
ALL_TARGETS = \
|
||||
config/all \
|
||||
ulog/all \
|
||||
misc/all \
|
||||
protocol/all \
|
||||
$(pq_dir)/all \
|
||||
pqcheck/all \
|
||||
pqcreate/all \
|
||||
pqinsert/all \
|
||||
pqcat/all \
|
||||
pqexpire/all \
|
||||
pqmon/all \
|
||||
pqutil/all \
|
||||
pqsend/all \
|
||||
pqing/all \
|
||||
pqact/all \
|
||||
pqsurf/all \
|
||||
send/all \
|
||||
rtstats/all \
|
||||
feedme/all \
|
||||
notifyme/all \
|
||||
server/all \
|
||||
ldmping/all \
|
||||
scripts/all \
|
||||
scour/all \
|
||||
regex/all
|
||||
|
||||
TEST_TARGETS = \
|
||||
pqing/test
|
||||
|
||||
LIBRARY = libldm.a
|
||||
|
||||
LDM_VERSION = ldm_version
|
||||
|
||||
INSTALL_TARGETS = \
|
||||
config/install \
|
||||
ulog/install \
|
||||
misc/install \
|
||||
protocol/install \
|
||||
$(pq_dir)/install \
|
||||
pqcheck/install \
|
||||
pqcreate/install \
|
||||
pqinsert/install \
|
||||
pqcat/install \
|
||||
pqexpire/install \
|
||||
pqmon/install \
|
||||
pqutil/install \
|
||||
pqsend/install \
|
||||
pqing/install \
|
||||
pqact/install \
|
||||
pqsurf/install \
|
||||
send/install \
|
||||
rtstats/install \
|
||||
feedme/install \
|
||||
notifyme/install \
|
||||
server/install \
|
||||
ldmping/install \
|
||||
scripts/install \
|
||||
scour/install \
|
||||
regex/install
|
||||
|
||||
INSTALL_SETUIDS_TARGETS = \
|
||||
ulog/install_setuids \
|
||||
server/install_setuids
|
||||
|
||||
CLEAN_TARGETS = \
|
||||
config/clean \
|
||||
ulog/clean \
|
||||
misc/clean \
|
||||
protocol/clean \
|
||||
pq/clean \
|
||||
fauxPq/clean \
|
||||
pqcheck/clean \
|
||||
pqcreate/clean \
|
||||
pqinsert/clean \
|
||||
pqcat/clean \
|
||||
pqexpire/clean \
|
||||
pqmon/clean \
|
||||
pqutil/clean \
|
||||
pqsend/clean \
|
||||
pqing/clean \
|
||||
pqact/clean \
|
||||
pqsurf/clean \
|
||||
send/clean \
|
||||
rtstats/clean \
|
||||
feedme/clean \
|
||||
notifyme/clean \
|
||||
server/clean \
|
||||
ldmping/clean \
|
||||
scripts/clean \
|
||||
scour/clean \
|
||||
regex/clean \
|
||||
rpc/clean
|
||||
|
||||
DISTCLEAN_TARGETS = \
|
||||
config/distclean \
|
||||
ulog/distclean \
|
||||
misc/distclean \
|
||||
protocol/distclean \
|
||||
pq/distclean \
|
||||
fauxPq/distclean \
|
||||
pqcheck/distclean \
|
||||
pqcreate/distclean \
|
||||
pqinsert/distclean \
|
||||
pqcat/distclean \
|
||||
pqexpire/distclean \
|
||||
pqmon/distclean \
|
||||
pqutil/distclean \
|
||||
pqsend/distclean \
|
||||
pqing/distclean \
|
||||
pqact/distclean \
|
||||
pqsurf/distclean \
|
||||
send/distclean \
|
||||
rtstats/distclean \
|
||||
feedme/distclean \
|
||||
notifyme/distclean \
|
||||
server/distclean \
|
||||
ldmping/distclean \
|
||||
scripts/distclean \
|
||||
scour/distclean \
|
||||
regex/distclean \
|
||||
rpc/distclean
|
||||
|
||||
SUBDIRS = rpc config $(LIBSUBDIRS) $(PROGSUBDIRS)
|
||||
|
||||
TAG_SRCS = \
|
||||
ulog/*.h ulog/*.c \
|
||||
protocol/*.c protocol/*.h \
|
||||
server/*.c server/*.h \
|
||||
misc/*.c misc/*.h \
|
||||
pq/*.c pq/*.h
|
||||
|
||||
# inventory
|
||||
PACKING_LIST = \
|
||||
ANNOUNCEMENT \
|
||||
configure \
|
||||
COPYRIGHT \
|
||||
CHANGE_LOG \
|
||||
macros.make.in \
|
||||
Makefile \
|
||||
MANIFEST \
|
||||
README \
|
||||
RELEASE_NOTES \
|
||||
rules.make \
|
||||
simple_program.make \
|
||||
VERSION
|
||||
|
||||
# $(LIBRARY) must be made first because programs built
|
||||
# in subdirectories link against it.
|
||||
all: $(LIBRARY) rpc/all $(ALL_TARGETS)
|
||||
|
||||
$(LIBRARY): $(LDM_VERSION).o
|
||||
$(AR) $(ARFLAGS) $(LIBRARY) $(LDM_VERSION).o
|
||||
$(RANLIB) $(LIBRARY)
|
||||
|
||||
$(LDM_VERSION).o: $(LDM_VERSION).c
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(LDM_VERSION).c
|
||||
|
||||
test: $(TEST_TARGETS)
|
||||
|
||||
install: $(LIBDIR)/$(LIBRARY) $(INSTALL_TARGETS) whatis
|
||||
|
||||
whatis: $(MANDIR)/$(WHATIS)
|
||||
|
||||
$(MANDIR)/$(WHATIS): $(MANDIR)
|
||||
@if test "$(MAKEWHATIS_CMD)"; then \
|
||||
touch $@; \
|
||||
eval $(MAKEWHATIS_CMD) || \
|
||||
echo 1>&2 "Couldn't build manual-page database"; \
|
||||
fi
|
||||
|
||||
install_setuids: $(INSTALL_SETUIDS_TARGETS)
|
||||
|
||||
clean: $(CLEAN_TARGETS)
|
||||
rm -f *.a *.o *.ln *.i $(LIBRARY) $(LDM_VERSION).c
|
||||
|
||||
distclean: $(DISTCLEAN_TARGETS)
|
||||
rm -f *.a *.o *.ln *.i $(LIBRARY) $(LDM_VERSION).c
|
||||
rm -f config.cache config.status *.log MANIFEST *.Z macros.make
|
||||
|
||||
$(LDM_VERSION).c: VERSION
|
||||
echo 'const char* ldm_version = "'`cat VERSION`'";' >$@
|
||||
|
||||
$(ALL_TARGETS) \
|
||||
$(TEST_TARGETS) \
|
||||
$(INSTALL_TARGETS) \
|
||||
$(INSTALL_SETUIDS_TARGETS) \
|
||||
$(CLEAN_TARGETS) \
|
||||
$(DISTCLEAN_TARGETS):
|
||||
@subdir=`echo $@ | sed 's,/.*,,'`; \
|
||||
target=`echo $@ | sed 's,.*/,,'`; \
|
||||
$(MAKE) $(MFLAGS) SUBDIR=$$subdir TGET=$$target subdir_target
|
||||
|
||||
rpc/all:
|
||||
@echo ""
|
||||
@cd rpc && \
|
||||
echo "Making \`all' in directory `pwd`" && \
|
||||
echo "" && \
|
||||
$(MAKE) all LIBRARY=../$(LIBRARY) || exit 1
|
||||
@echo ""
|
||||
@echo "Returning to directory `pwd`"
|
||||
@echo ""
|
||||
|
||||
subdir_target:
|
||||
@echo ""
|
||||
@cd $(SUBDIR) && \
|
||||
echo "Making \`$(TGET)' in directory `pwd`" && \
|
||||
echo "" && \
|
||||
$(MAKE) $(TGET) || exit 1
|
||||
@echo ""
|
||||
@echo "Returning to directory `pwd`"
|
||||
@echo ""
|
||||
|
||||
$(LIBDIR)/$(LIBRARY) : $(LIBDIR) FORCE
|
||||
-@cmp -s $(LIBRARY) $@ || ($(INSTALL) $(LIBRARY) $@ && \
|
||||
echo 'updated $@')
|
||||
|
||||
$(LIBDIR):
|
||||
mkdir $@
|
||||
|
||||
configure: configure.in aclocal.m4
|
||||
autoconf
|
||||
|
||||
config.status: configure
|
||||
-@if [ -f "$@" ]; then \
|
||||
$(SHELL) config.status --recheck ; \
|
||||
else \
|
||||
echo 1>&1 "$@ must be created by the configure script"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
subdirs:
|
||||
@echo $(SUBDIRS)
|
||||
|
||||
# Ultimately depends on all the Makefiles, but...
|
||||
MANIFEST: Makefile FORCE
|
||||
@echo 1>&2 Creating MANIFEST
|
||||
@$(MAKE) -s $(LOCAL_MACROS) TOP_MANIFEST.echo | sort -o $@
|
||||
|
||||
TOP_MANIFEST.echo:
|
||||
@echo $(PACKING_LIST) | fmt -1
|
||||
@if [ -n "$(SUBDIRS)" ]; then \
|
||||
subdirs="$(SUBDIRS)"; \
|
||||
for subdir in $$subdirs; do \
|
||||
(cd $$subdir && \
|
||||
echo 1>&2 Creating MANIFEST.echo in `pwd` && \
|
||||
$(MAKE) $(MFLAGS) $(SUBDIR_MACROS) MANIFEST.echo | \
|
||||
sed "s|^|$$subdir/|") || exit 1; \
|
||||
done; \
|
||||
else \
|
||||
:; \
|
||||
fi
|
||||
|
||||
tag:
|
||||
@tag=ldm-`sed 's/\./_/g' VERSION`; \
|
||||
cvs tag -F $$tag . rpc
|
||||
|
||||
tar.gz:
|
||||
version=`cat VERSION`; \
|
||||
$(MAKE) $(MFLAGS) $(PACKAGE)-$$version.tar.gz VERSION=$$version
|
||||
|
||||
$(PACKAGE)-$(VERSION).tar.gz: FORCE
|
||||
tag=ldm-`echo "$(VERSION)" | sed 's/\./_/g'`; \
|
||||
dir=ldm-$(VERSION); \
|
||||
srcdir=$$dir/src; \
|
||||
if cvs export -N -d $$dir -r $$tag src && \
|
||||
(cd $$srcdir && \
|
||||
$(MAKE) -f ../../rpc/Makefile $(MFLAGS) export TAG=$$tag); \
|
||||
then \
|
||||
pax -x ustar -w $$srcdir | gzip -c >$@; \
|
||||
status=$$?; \
|
||||
else \
|
||||
status=1; \
|
||||
fi; \
|
||||
rm -rf $$dir; \
|
||||
exit $$status
|
||||
|
||||
$(PACKAGE)-$(VERSION).binary.tar.gz: install
|
||||
id=$(PACKAGE)-$(VERSION).binary \
|
||||
&& rm -rf $$id \
|
||||
&& mkdir $$id \
|
||||
&& cd $$id \
|
||||
&& cp ../[ABD-Z]* . \
|
||||
&& cp ../COPYRIGHT . \
|
||||
&& mkdir etc \
|
||||
&& cd etc \
|
||||
&& cp ../../server/*.conf . \
|
||||
&& cp ../../pqact/*.conf . \
|
||||
&& cp ../../scour/*.conf . \
|
||||
&& cp ../../scripts/*.conf . \
|
||||
&& cd .. \
|
||||
&& mkdir bin \
|
||||
&& cd bin \
|
||||
&& cp ../../../bin/* . \
|
||||
&& rm -f ldmadmin ldmcheck ldmfail ldmprods netcheck syscheck mailpqstats \
|
||||
&& rm -f ddplus dds hds feedtest hrs ids pps afos \
|
||||
&& cp ../../scripts/*.in . \
|
||||
&& cd .. \
|
||||
&& ln -s ../../lib . \
|
||||
&& ln -s ../../include . \
|
||||
&& ln -s ../../man . \
|
||||
&& rm -rf Makefile* */Makefile* \
|
||||
&& cd .. \
|
||||
&& pax -x ustar -w $$id | gzip -c > $@ \
|
||||
&& rm -r $$id
|
||||
|
||||
binary.tar.gz:
|
||||
version=`cat VERSION`; \
|
||||
$(MAKE) $(MFLAGS) $(PACKAGE)-$$version.binary.tar.gz VERSION=$$version
|
||||
|
||||
$(FTPDIR)/$(PACKAGE)-$(VERSION).tar.gz: $(PACKAGE)-$(VERSION).tar.gz
|
||||
scp $(PACKAGE)-$(VERSION).tar.gz ftp:$@
|
||||
ssh ftp chmod u+rw,g+rw,o=r $@
|
||||
|
||||
ftp:
|
||||
if cvs status . rpc 2>/dev/null | grep Status: \
|
||||
| grep -v Up-to-date >/dev/null; then \
|
||||
echo 1>&2 'Package or rpc/ needs "cvs commit"'; \
|
||||
exit 1; \
|
||||
else true; fi
|
||||
$(MAKE) tag
|
||||
version=`cat VERSION`; \
|
||||
$(MAKE) FTPDIR=$(FTPDIR) PACKAGE=$(PACKAGE) VERSION=$$version \
|
||||
$(FTPDIR)/$(PACKAGE)-$$version.tar.gz; \
|
||||
test ! -h $(FTPDIR)/$(PACKAGE).tar.gz && exit 0; \
|
||||
# cd $(FTPDIR) || exit 1; \
|
||||
# rm $(PACKAGE).tar.gz || exit 1; \
|
||||
# ln -s $(PACKAGE)-$$version.tar.gz $(PACKAGE).tar.gz;
|
||||
|
||||
beta:
|
||||
if cvs status . rpc 2>/dev/null | grep Status: \
|
||||
| grep -v Up-to-date >/dev/null; then \
|
||||
echo 1>&2 'Package or rpc/ needs "cvs commit"'; \
|
||||
exit 1; \
|
||||
else true; fi
|
||||
$(MAKE) tag
|
||||
version=`cat VERSION`; \
|
||||
$(MAKE) FTPDIR=$(FTPDIR)/beta PACKAGE=$(PACKAGE) VERSION=$$version \
|
||||
$(FTPDIR)/beta/$(PACKAGE)-$$version.tar.gz; \
|
||||
test ! -h $(FTPDIR)/beta/$(PACKAGE).tar.gz && exit 0; \
|
||||
|
||||
binftp:
|
||||
version=`cat VERSION`; \
|
||||
ftpbindir=/home/ftp/pub/binary/`system`; \
|
||||
$(MAKE) VERSION=$$version FTPBINDIR=$$ftpbindir \
|
||||
$$ftpbindir/$(PACKAGE)-$$version.tar.gz
|
||||
ftpbin: binftp
|
||||
|
||||
$(FTPBINDIR)/$(PACKAGE)-$(VERSION).tar.gz:
|
||||
id=$(PACKAGE)-$(VERSION); \
|
||||
&& rm -f $$id \
|
||||
&& ln -s $(prefix) $$id \
|
||||
&& pax -x ustar -w $$id/bin $$id/etc $$id/include $$id/lib \
|
||||
$$id/man | gzip -c > $@ \
|
||||
&& rm $$id
|
||||
chmod u+rw,g+rw,o=r $@
|
||||
test ! -h $(FTPBINDIR)/$(PACKAGE).tar.gz && exit 0; \
|
||||
cd $(FTPBINDIR) || exit 1; \
|
||||
rm $(PACKAGE).tar.gz || exit 1; \
|
||||
ln -s $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE).tar.gz;
|
||||
|
||||
FORCE:
|
||||
|
||||
ldm_version.o: ldm_version.c
|
|
@ -1,85 +0,0 @@
|
|||
LDM README FILE
|
||||
|
||||
INTRODUCTION:
|
||||
|
||||
This package contains the source-code for the Unidata Program
|
||||
Center's Local Data Manager (LDM).
|
||||
|
||||
RELEASE IDENTIFICATION:
|
||||
|
||||
The release identifier for this package is in the file VERSION and
|
||||
has the following form:
|
||||
|
||||
<major>.<minor>.<rev>
|
||||
|
||||
where:
|
||||
|
||||
<major> Is the major release-number (e.g., 6). Changes
|
||||
to this component indicate a major departure from
|
||||
previous releases (such as a change to the LDM
|
||||
protocol). Such changes are often not compatible
|
||||
with previous releases.
|
||||
|
||||
<minor> Is the minor release-number (e.g., 1). Changes
|
||||
to this component indicate the addition of
|
||||
new features. The package remains compatible
|
||||
with previous releases having the same major
|
||||
release-number.
|
||||
|
||||
<rev> Is the revision-level (e.g., 0). Changes to this
|
||||
component indicate bug-fixes and/or performance
|
||||
improvments that are functionally compatible with
|
||||
previous releases having the same major and minor
|
||||
release-numbers.
|
||||
|
||||
LEGAL:
|
||||
|
||||
Licensing and copyright information are contained in the file
|
||||
COPYRIGHT, which is in the top-level source directory.
|
||||
|
||||
INFORMATION:
|
||||
|
||||
HOMEPAGE -- INCLUDING INSTALLATION & CONFIGURATION INSTRUCTIONS:
|
||||
|
||||
The homepage of the LDM package is
|
||||
|
||||
http://www.unidata.ucar.edu/software/ldm/
|
||||
|
||||
Click on the appropriate release identifier to go the
|
||||
release-specific homepage, where you will find detailed LDM
|
||||
installation and configuration instructions as well as other useful
|
||||
information.
|
||||
|
||||
CHANGE LOG:
|
||||
|
||||
Changes to the package are documented in the file CHANGE_LOG,
|
||||
which is in the top-level source-directory.
|
||||
|
||||
RELEASE NOTES:
|
||||
|
||||
Release-specific aspects are documented in the file
|
||||
RELEASE_NOTES, which is in the top-level source-directory.
|
||||
|
||||
LDM DECODERS:
|
||||
|
||||
LDM-compatible decoders for local processing of received data
|
||||
products are available seperately from the Unidata Program
|
||||
Center. These include Unidata decoders, GEMPAK decoders and MCIDAS
|
||||
decoders. See
|
||||
|
||||
Unidata Decoders:
|
||||
http://www.unidata.ucar.edu/software/decoders/
|
||||
|
||||
GEMPAK Decoders:
|
||||
http://www.unidata.ucar.edu/software/gempak/
|
||||
|
||||
McIDAS Decoders:
|
||||
http://www.unidata.ucar.edu/software/mcidas/mcidd/
|
||||
|
||||
SUPPORT:
|
||||
|
||||
If you are a licensed Unidata member, then you may obtain support by
|
||||
sending an email inquiry to support-ldm@unidata.ucar.edu. Please
|
||||
include a description of the type of platform (hardware and
|
||||
operating system) and any relevant information that can help us
|
||||
answer your question (error messages, symptoms, etc.).
|
|
@ -1,7 +0,0 @@
|
|||
Added user-configurable checking of the accuracy of the system clock to almost
|
||||
every ldmadmin(1) command.
|
||||
|
||||
Add ability to accumulate LDM metrics and display them as time-series
|
||||
plots.
|
||||
|
||||
Improved the vetting procedure for new client connections.
|
|
@ -1 +0,0 @@
|
|||
6.8.0
|
1124
ldm/src/aclocal.m4
vendored
1124
ldm/src/aclocal.m4
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,90 +0,0 @@
|
|||
# $Id: complex_program.make,v 1.2 2003/02/27 22:07:11 steve Exp $
|
||||
|
||||
include ../macros.make
|
||||
|
||||
INCLUDES = -I../config -I../misc -I../ulog -I../protocol -I../pq
|
||||
TAG_SRCS = \
|
||||
../misc/*.c ../misc/*.h \
|
||||
../ulog/*.c ../ulog/*.h \
|
||||
../protocol/*.c ../protocol/*.h \
|
||||
../pq/*.c ../pq/*.h
|
||||
LDLIBS = -lm
|
||||
C_PROGRAMS = $(PROGRAM)
|
||||
PROG_CSRCS = \
|
||||
afos_message.c \
|
||||
do.c \
|
||||
dtime.c \
|
||||
faa604_message.c \
|
||||
feed.c \
|
||||
file.c \
|
||||
fxbuf.c \
|
||||
pqing.c \
|
||||
rawfile.c \
|
||||
tokens.c \
|
||||
tty.c \
|
||||
wmo_header.c \
|
||||
wmo_message.c \
|
||||
wmo_start.c \
|
||||
xbuf.c
|
||||
PROG_OBJS = \
|
||||
afos_message.o \
|
||||
do_check.o \
|
||||
do_nocheck.o \
|
||||
dtime.o \
|
||||
faa604_message.o \
|
||||
feed.o \
|
||||
file.o \
|
||||
fxbuf.o \
|
||||
pqing.o \
|
||||
rawfile.o \
|
||||
tokens.o \
|
||||
tty.o \
|
||||
wmo_header.o \
|
||||
wmo_message.o \
|
||||
wmo_start.o \
|
||||
xbuf.o
|
||||
MANUALS = pqing.1
|
||||
PACKING_LIST = \
|
||||
Makefile.in \
|
||||
$(PROG_CSRCS) \
|
||||
afos_message.h \
|
||||
crc_tab.h \
|
||||
dtime.h \
|
||||
faa604_message.h \
|
||||
faa604_message.c \
|
||||
feed.h \
|
||||
pqing.1 \
|
||||
rawfile.h \
|
||||
tokens.h \
|
||||
wmo_header.h \
|
||||
wmo_message.h \
|
||||
wmo_start.h \
|
||||
xbuf.h \
|
||||
test.wmo \
|
||||
pqcat.out.expect
|
||||
|
||||
all : $(C_PROGRAMS)
|
||||
|
||||
install : installed_programs installed_manuals links
|
||||
|
||||
$(C_PROGRAMS) : $(PROG_OBJS) $(LIBRARY)
|
||||
$(CC) -o $@ $(CFLAGS) $(PROG_OBJS) $(LIBS)
|
||||
|
||||
links: $(BINDIR)/$(C_PROGRAMS)
|
||||
cd $(BINDIR) ; rm -f dds ; ln -s $(PROG) dds
|
||||
cd $(BINDIR) ; rm -f pps ; ln -s $(PROG) pps
|
||||
cd $(BINDIR) ; rm -f ids ; ln -s $(PROG) ids
|
||||
cd $(BINDIR) ; rm -f hds ; ln -s $(PROG) hds
|
||||
cd $(BINDIR) ; rm -f hrs ; ln -s $(PROG) hrs
|
||||
cd $(BINDIR) ; rm -f ddplus ; ln -s $(PROG) ddplus
|
||||
cd $(BINDIR) ; rm -f feedtest ; ln -s $(PROG) feedtest
|
||||
cd $(BINDIR) ; rm -f afos ; ln -s $(PROG) afos
|
||||
|
||||
do_check.o : do.c crc_tab.h
|
||||
$(COMPILE.c) -DSCAN_CHECK do.c && mv do.o $@
|
||||
|
||||
do_nocheck.o : do.c crc_tab.h
|
||||
$(COMPILE.c) -USCAN_CHECK do.c && mv do.o $@
|
||||
|
||||
include ../rules.make
|
||||
include depends
|
File diff suppressed because it is too large
Load diff
|
@ -1,13 +0,0 @@
|
|||
# $Id: Makefile,v 1.4 2003/02/26 23:43:30 steve Exp $
|
||||
#
|
||||
# Makefile for configuration subdirectory (config/)
|
||||
#
|
||||
include ../macros.make
|
||||
|
||||
HEADERS = ldmconfig.h
|
||||
DISTCLEAN_GARBAGE = ldmconfig.h
|
||||
PACKING_LIST = Makefile ldmconfig.h.in
|
||||
|
||||
all:
|
||||
|
||||
include ../rules.make
|
|
@ -1,87 +0,0 @@
|
|||
/* config/ldmconfig.h. Generated from ldmconfig.h.in by configure. */
|
||||
#ifndef LDM_CONFIG_H
|
||||
#define LDM_CONFIG_H
|
||||
|
||||
#ifndef _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||
/* #undef _XOPEN_SOURCE_EXTENDED */
|
||||
#endif
|
||||
|
||||
/* AIX: */
|
||||
/* #undef _ALL_SOURCE */
|
||||
/* #undef BSD */
|
||||
/* Darwin: */
|
||||
/* #undef __DARWIN_UNIX03 */
|
||||
/* #undef _DARWIN_C_SOURCE */
|
||||
/* HP-UX: */
|
||||
/* #undef _HPUX_SOURCE */
|
||||
/* IRIX: */
|
||||
/* #undef _SGI_SOURCE */
|
||||
/* #undef _BSD_TYPES */
|
||||
/* FreeBSD: */
|
||||
/* Linux: */
|
||||
#define _BSD_SOURCE 1
|
||||
/* OSF1: */
|
||||
/* #undef _OSF_SOURCE */
|
||||
/* SunOS: */
|
||||
/* #undef __EXTENSIONS__ */
|
||||
|
||||
/* No database support in pqact/filel.c */
|
||||
#define NO_DB 1
|
||||
/* Concatenate products in pqact/filel.c. Mutually exclusive with DB_XPROD */
|
||||
#define DB_CONCAT 1
|
||||
/* XDR DB products in pqact/filel.c. Mutually exclusive with DB_CONCAT */
|
||||
#define DB_XPROD 0
|
||||
/* Use gdbm interface in pqact/filel.c; default is ndbm */
|
||||
/* #undef USE_GDBM */
|
||||
#define HAVE_ST_BLKSIZE 1
|
||||
#define HAVE_TIMEGM 1
|
||||
#define ULOGNAME "/dev/log"
|
||||
#define LOGNAME_ISSOCK 1
|
||||
/* #undef NO_ATEXIT */
|
||||
/* #undef NO_FSYNC */
|
||||
/* #undef NO_FTRUNCATE */
|
||||
/* #undef NO_MEMCMP */
|
||||
/* #undef NO_MEMMOVE */
|
||||
/* #undef NO_MMAP */
|
||||
/* #undef NO_POSIXSIGNALS */
|
||||
/* #undef NO_RENAME */
|
||||
#define NO_REPLACE_SYSLOG 1
|
||||
/* #undef NO_SETENV */
|
||||
/* #undef NO_SETEUID */
|
||||
/* #undef NO_STRDUP */
|
||||
/* #undef NO_STRERROR */
|
||||
#define SIZEOF_INT 4
|
||||
#define SIZEOF_LONG 4
|
||||
#define SYSLOG_PIDFILE "/var/run/syslogd.pid"
|
||||
/* #undef SYSLOG_RETURNS_INT */
|
||||
/* #undef TV_INT */
|
||||
/* #undef UD_SETPROCTITLE */
|
||||
/* #undef _DEV_CONSLOG */
|
||||
#define _MAPRGNS 1
|
||||
#define _NOGROW 1
|
||||
/* #undef _SYS_USER_INCLUDED */
|
||||
/* #undef const */
|
||||
/* #undef off_t */
|
||||
/* #undef ptrdiff_t */
|
||||
/* #undef sig_atomic_t */
|
||||
/* #undef ssize_t */
|
||||
/* #undef socklen_t */
|
||||
#define LDMHOME "/usr/local/ldm"
|
||||
#define LOG_LDM LOG_LOCAL0
|
||||
#define LDM_PORT 388
|
||||
#define LDM_PROG 300029
|
||||
|
||||
#define RESOLVER_TIME_THRESHOLD 10
|
||||
|
||||
/*
|
||||
* The following header-files are included here because on FreeBSD
|
||||
* 4.10-RELEASE-p2, at least, their order is important.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#endif
|
|
@ -1,86 +0,0 @@
|
|||
#ifndef LDM_CONFIG_H
|
||||
#define LDM_CONFIG_H
|
||||
|
||||
#ifndef _XOPEN_SOURCE
|
||||
#undef _XOPEN_SOURCE
|
||||
#endif
|
||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||
#undef _XOPEN_SOURCE_EXTENDED
|
||||
#endif
|
||||
|
||||
/* AIX: */
|
||||
#undef _ALL_SOURCE
|
||||
#undef BSD
|
||||
/* Darwin: */
|
||||
#undef __DARWIN_UNIX03
|
||||
#undef _DARWIN_C_SOURCE
|
||||
/* HP-UX: */
|
||||
#undef _HPUX_SOURCE
|
||||
/* IRIX: */
|
||||
#undef _SGI_SOURCE
|
||||
#undef _BSD_TYPES
|
||||
/* FreeBSD: */
|
||||
/* Linux: */
|
||||
#undef _BSD_SOURCE
|
||||
/* OSF1: */
|
||||
#undef _OSF_SOURCE
|
||||
/* SunOS: */
|
||||
#undef __EXTENSIONS__
|
||||
|
||||
/* No database support in pqact/filel.c */
|
||||
#undef NO_DB
|
||||
/* Concatenate products in pqact/filel.c. Mutually exclusive with DB_XPROD */
|
||||
#undef DB_CONCAT
|
||||
/* XDR DB products in pqact/filel.c. Mutually exclusive with DB_CONCAT */
|
||||
#undef DB_XPROD
|
||||
/* Use gdbm interface in pqact/filel.c; default is ndbm */
|
||||
#undef USE_GDBM
|
||||
#undef HAVE_ST_BLKSIZE
|
||||
#undef HAVE_TIMEGM
|
||||
#undef ULOGNAME
|
||||
#undef LOGNAME_ISSOCK
|
||||
#undef NO_ATEXIT
|
||||
#undef NO_FSYNC
|
||||
#undef NO_FTRUNCATE
|
||||
#undef NO_MEMCMP
|
||||
#undef NO_MEMMOVE
|
||||
#undef NO_MMAP
|
||||
#undef NO_POSIXSIGNALS
|
||||
#undef NO_RENAME
|
||||
#undef NO_REPLACE_SYSLOG
|
||||
#undef NO_SETENV
|
||||
#undef NO_SETEUID
|
||||
#undef NO_STRDUP
|
||||
#undef NO_STRERROR
|
||||
#undef SIZEOF_INT
|
||||
#undef SIZEOF_LONG
|
||||
#undef SYSLOG_PIDFILE
|
||||
#undef SYSLOG_RETURNS_INT
|
||||
#undef TV_INT
|
||||
#undef UD_SETPROCTITLE
|
||||
#undef _DEV_CONSLOG
|
||||
#undef _MAPRGNS
|
||||
#undef _NOGROW
|
||||
#undef _SYS_USER_INCLUDED
|
||||
#undef const
|
||||
#undef off_t
|
||||
#undef ptrdiff_t
|
||||
#undef sig_atomic_t
|
||||
#undef ssize_t
|
||||
#undef socklen_t
|
||||
#undef LDMHOME
|
||||
#undef LOG_LDM
|
||||
#undef LDM_PORT
|
||||
#undef LDM_PROG
|
||||
|
||||
#define RESOLVER_TIME_THRESHOLD 10
|
||||
|
||||
/*
|
||||
* The following header-files are included here because on FreeBSD
|
||||
* 4.10-RELEASE-p2, at least, their order is important.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#endif
|
8227
ldm/src/configure
vendored
8227
ldm/src/configure
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,220 +0,0 @@
|
|||
dnl
|
||||
dnl Process this file with autoconf 1.6 or later to produce a configure script
|
||||
dnl Requires ./aclocal.m4
|
||||
dnl
|
||||
AC_INIT(config/ldmconfig.h.in)
|
||||
|
||||
AC_ARG_ENABLE(faux-pq,
|
||||
AC_HELP_STRING([--enable-faux-pq],
|
||||
[use the faux product-queue [[default=disable]]]),
|
||||
[
|
||||
PQ_DIR=fauxPq
|
||||
PQ_PATH="\$etc_path/pq.xml"
|
||||
],
|
||||
[
|
||||
PQ_DIR=pq
|
||||
PQ_PATH="\$data_path/ldm.pq"
|
||||
])
|
||||
AC_SUBST(PQ_DIR)
|
||||
AC_SUBST(PQ_PATH)
|
||||
|
||||
AC_ARG_ENABLE(logging,
|
||||
AC_HELP_STRING([--enable-logging=facility],
|
||||
[use "facility" when logging [[default=local0]]]),
|
||||
[
|
||||
facility=`echo $enableval |
|
||||
tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
|
||||
AC_DEFINE_UNQUOTED([LOG_LDM], [LOG_$facility])
|
||||
AC_SUBST(LOG_LDM, $enableval)
|
||||
],
|
||||
[
|
||||
AC_DEFINE_UNQUOTED(LOG_LDM, LOG_LOCAL0)
|
||||
AC_SUBST(LOG_LDM, local0)
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(port,
|
||||
AC_HELP_STRING([--enable-port=port],
|
||||
[use "port" for LDM server [[default=388]]]),
|
||||
[
|
||||
LDM_PORT=$enableval
|
||||
ldm_prog=300029
|
||||
],
|
||||
[
|
||||
LDM_PORT=388
|
||||
ldm_prog=300029
|
||||
])
|
||||
AC_DEFINE_UNQUOTED(LDM_PORT, $LDM_PORT)
|
||||
AC_DEFINE_UNQUOTED(LDM_PROG, $ldm_prog)
|
||||
AC_SUBST(LDM_PORT)
|
||||
|
||||
AC_ARG_ENABLE(max-size,
|
||||
AC_HELP_STRING([--disable-max-size],
|
||||
[minimize the (long, void*, off_t) programming environment
|
||||
[[default=enable]]]),
|
||||
max_size=$enableval,
|
||||
max_size=yes)
|
||||
|
||||
AC_CONFIG_HEADER(config/ldmconfig.h)
|
||||
AC_SUBST(PATH)
|
||||
|
||||
VERSION=`cat VERSION`
|
||||
AC_SUBST(VERSION)
|
||||
|
||||
CFLAGS=${CFLAGS-"-O"}
|
||||
|
||||
AC_PROG_CC(c89 cc gcc)
|
||||
if test -z "$CC"; then
|
||||
AC_MSG_ERROR(no C compiler found)
|
||||
else
|
||||
AC_MSG_CHECKING(the C compiler)
|
||||
AC_COMPILE_IFELSE([int foo;],
|
||||
AC_MSG_RESULT(works),
|
||||
AC_MSG_FAILURE($CC failed to compile test code))
|
||||
fi
|
||||
|
||||
ARFLAGS=-cru
|
||||
if test "$max_size" = yes
|
||||
then
|
||||
AC_MSG_NOTICE(Checking how to maximize the (long, void*, off_t) programming environment)
|
||||
success=no
|
||||
AC_MSG_CHECKING([if the system supports _XBS5_LPBIG_OFFBIG])
|
||||
avail=`getconf _XBS5_LPBIG_OFFBIG 2>/dev/null`
|
||||
if test $? = 0 -a "$avail" \!= -1 -a "$avail" \!= "undefined"
|
||||
then
|
||||
if cflags=`getconf XBS5_LPBIG_OFFBIG_CFLAGS 2>/dev/null`
|
||||
then
|
||||
if ldflags=`getconf XBS5_LPBIG_OFFBIG_LDFLAGS 2>/dev/null`
|
||||
then
|
||||
if libs=`getconf XBS5_LPBIG_OFFBIG_LIBS 2>/dev/null`
|
||||
then
|
||||
maprgns=-U_MAPRGNS
|
||||
success=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($success)
|
||||
if test "$success" = no
|
||||
then
|
||||
AC_MSG_CHECKING([if the system supports _XBS5_LP64_OFF64])
|
||||
avail=`getconf _XBS5_LP64_OFF64 2>/dev/null`
|
||||
if test $? = 0 -a "$avail" \!= -1 -a "$avail" \!= "undefined"
|
||||
then
|
||||
if cflags=`getconf XBS5_LP64_OFF64_CFLAGS 2>/dev/null`
|
||||
then
|
||||
if ldflags=`getconf XBS5_LP64_OFF64_LDFLAGS 2>/dev/null`
|
||||
then
|
||||
if libs=`getconf XBS5_LP64_OFF64_LIBS 2>/dev/null`
|
||||
then
|
||||
maprgns=-U_MAPRGNS
|
||||
success=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($success)
|
||||
fi
|
||||
if test "$success" = no
|
||||
then
|
||||
AC_MSG_CHECKING([if the system supports _XBS5_ILP32_OFFBIG])
|
||||
avail=`getconf _XBS5_ILP32_OFFBIG 2>/dev/null`
|
||||
if test $? = 0 -a "$avail" \!= -1 -a "$avail" \!= "undefined"
|
||||
then
|
||||
if cflags=`getconf XBS5_ILP32_OFFBIG_CFLAGS 2>/dev/null`
|
||||
then
|
||||
if ldflags=`getconf XBS5_ILP32_OFFBIG_LDFLAGS 2>/dev/null`
|
||||
then
|
||||
if libs=`getconf XBS5_ILP32_OFFBIG_LIBS 2>/dev/null`
|
||||
then
|
||||
AC_DEFINE(_MAPRGNS, 1)
|
||||
maprgns=-D_MAPRGNS
|
||||
success=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($success)
|
||||
fi
|
||||
if test "$success" = yes
|
||||
then
|
||||
test -n "$cflags" && CFLAGS="$CFLAGS${CFLAGS+ }$cflags"
|
||||
test -n "$ldflags" && LDFLAGS="$LDFLAGS${LDFLAGS+ }$ldflags"
|
||||
test -n "$libs" && LIBS="$LIBS${LIBS+ }$libs"
|
||||
test `uname` = AIX && ARFLAGS='-cru -X 32_64'
|
||||
AC_MSG_NOTICE([$maprgns])
|
||||
AC_MSG_NOTICE([cflags=\"$cflags\"])
|
||||
AC_MSG_NOTICE([ldflags=\"$ldflags\"])
|
||||
AC_MSG_NOTICE([libs=\"$libs\"])
|
||||
AC_MSG_NOTICE([ARFLAGS=\"$ARFLAGS\"])
|
||||
AC_MSG_CHECKING([the C compiler (again)])
|
||||
AC_COMPILE_IFELSE([int foo;],
|
||||
AC_MSG_RESULT(works),
|
||||
AC_MSG_FAILURE($CC failed to compile test code))
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(ARFLAGS)
|
||||
|
||||
UD_CPPFLAGS
|
||||
UD_PREFIX(..)
|
||||
AC_REVISION ($Revision: 1.47.18.19 $)
|
||||
UD_DOMAINNAME
|
||||
UD_HPUX
|
||||
UD_PROG_CPP
|
||||
UD_PROG_AR
|
||||
UD_PROG_PERL
|
||||
UD_PROG_SH
|
||||
UD_PROG_YACC
|
||||
AC_PROG_RANLIB
|
||||
UD_LIB_YACC
|
||||
UD_MMAP
|
||||
UD_LDMHOME()
|
||||
AC_CHECK_SIZEOF(int, 4)
|
||||
AC_CHECK_SIZEOF(long, 4)
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_CHECK_TYPE(ssize_t, int)
|
||||
AC_CHECK_TYPE(ptrdiff_t, int)
|
||||
AC_CHECK_FUNCS(timegm)
|
||||
TYPE_SOCKLEN_T
|
||||
UD_NO_HEADERS(stdlib.h unistd.h)
|
||||
UD_NO_FUNCS(fsync ftruncate memmove memcmp rename strerror waitpid strdup seteuid setenv mmap)
|
||||
UD_SIG_ATOMIC_T
|
||||
AC_C_CONST
|
||||
AC_STRUCT_ST_BLKSIZE
|
||||
UD_NO_POSIXSIGNALS
|
||||
UD_SYSLOG_PIDFILE
|
||||
AC_SUBST(CFLAGS)
|
||||
UD_NETWORKING
|
||||
UD_ULOG
|
||||
UD_PROCTITLE
|
||||
UD_NEILLEY_COMPAT
|
||||
UD_DB
|
||||
UD_MAKEWHATIS
|
||||
libs=$LIBS
|
||||
LIBS=
|
||||
AC_SEARCH_LIBS(
|
||||
[dirname],
|
||||
[gen],
|
||||
[LD_GEN=$LIBS
|
||||
AC_SUBST([LD_GEN])
|
||||
LIBS=$libs],
|
||||
[AC_MSG_ERROR([Could not find required function dirname],[1])])
|
||||
|
||||
AC_CONFIG_SUBDIRS(rpc)
|
||||
#AC_MSG_NOTICE()
|
||||
#AC_MSG_NOTICE([Configuring in "rpc" subdirectory])
|
||||
#cmd="(cd rpc && CC=\"$CC\" CFLAGS=\"$CFLAGS\" ./configure --prefix=$prefix)"
|
||||
#AC_MSG_NOTICE([$cmd])
|
||||
#eval $cmd || exit
|
||||
#AC_MSG_NOTICE()
|
||||
|
||||
AC_OUTPUT( \
|
||||
macros.make \
|
||||
scour/scour \
|
||||
scripts/ldmadmin \
|
||||
scripts/writeConfiguration.pl \
|
||||
scripts/ldmfail \
|
||||
scripts/netcheck \
|
||||
scripts/syscheck \
|
||||
scripts/ldmcheck \
|
||||
)
|
|
@ -1,31 +0,0 @@
|
|||
# $Id: Makefile,v 1.1 2003/02/26 23:43:35 steve Exp $
|
||||
#
|
||||
# Development Makefile for the faux product queue implementation
|
||||
#
|
||||
include ../macros.make
|
||||
|
||||
XML_INC =
|
||||
INCLUDES = -I../config -I. -I../pq -I../misc -I../ulog -I../protocol \
|
||||
$(XML_INC)
|
||||
LDLIBS = -lm
|
||||
LIBRARY = ../libldm.a
|
||||
MANUAL = fauxPq.3
|
||||
LIB_CSRCS = \
|
||||
fauxPq.c \
|
||||
fauxPqConfigFile.c
|
||||
PACKING_LIST = \
|
||||
$(LIB_CSRCS) \
|
||||
depends \
|
||||
fauxPqConfigFile.h \
|
||||
Makefile \
|
||||
pq.xml
|
||||
|
||||
all: archived_files
|
||||
|
||||
install: $(ETCDIR)/pq.xml
|
||||
|
||||
$(ETCDIR)/pq.xml: $(ETCDIR) pq.xml
|
||||
-@test -f $@ || ($(INSTALL) pq.xml $@ && echo 'updated $@')
|
||||
|
||||
include ../rules.make
|
||||
include depends
|
|
@ -1,33 +0,0 @@
|
|||
fauxPq.o: fauxPq.c
|
||||
fauxPq.o: ../config/ldmconfig.h
|
||||
fauxPq.o: ../protocol/ldm_xlen.h
|
||||
fauxPq.o: ../protocol/ldm.h
|
||||
fauxPq.o: ../config/ldmconfig.h
|
||||
fauxPq.o: ../protocol/timestamp.h
|
||||
fauxPq.o: ../pq/pq.h
|
||||
fauxPq.o: ../protocol/ldm.h
|
||||
fauxPq.o: ../protocol/prod_class.h
|
||||
fauxPq.o: ../protocol/ldm.h
|
||||
fauxPq.o: ../ulog/ulog.h
|
||||
fauxPq.o: fauxPqConfigFile.h
|
||||
fauxPq.o: ../pq/pq.h
|
||||
fauxPqConfigFile.o: fauxPqConfigFile.c
|
||||
fauxPqConfigFile.o: ../config/ldmconfig.h
|
||||
fauxPqConfigFile.o: ../protocol/timestamp.h
|
||||
fauxPqConfigFile.o: ../protocol/atofeedt.h
|
||||
fauxPqConfigFile.o: ../protocol/ldm.h
|
||||
fauxPqConfigFile.o: ../config/ldmconfig.h
|
||||
fauxPqConfigFile.o: ../protocol/timestamp.h
|
||||
fauxPqConfigFile.o: ../misc/inetutil.h
|
||||
fauxPqConfigFile.o: ../protocol/ldm.h
|
||||
fauxPqConfigFile.o: ../protocol/ldm_xlen.h
|
||||
fauxPqConfigFile.o: ../protocol/ldm.h
|
||||
fauxPqConfigFile.o: ../protocol/ldmprint.h
|
||||
fauxPqConfigFile.o: ../protocol/ldm.h
|
||||
fauxPqConfigFile.o: ../protocol/md5.h
|
||||
fauxPqConfigFile.o: ../ulog/ulog.h
|
||||
fauxPqConfigFile.o: fauxPqConfigFile.h
|
||||
fauxPqConfigFile.o: ../pq/pq.h
|
||||
fauxPqConfigFile.o: ../protocol/ldm.h
|
||||
fauxPqConfigFile.o: ../protocol/prod_class.h
|
||||
fauxPqConfigFile.o: ../protocol/ldm.h
|
|
@ -1,729 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995, University Corporation for Atmospheric Research
|
||||
* See top level COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: fauxPq.c,v 1.7.18.1 2008/04/15 16:34:07 steve Exp $ */
|
||||
|
||||
|
||||
/*
|
||||
* A "faux" product queue. This module presents the public Product Queue API,
|
||||
* but it returns faux products and accepts everything. The products returned
|
||||
* by this implementation are configurable via the "product queue" file, which
|
||||
* is a configuration file that describes the behavior of this module.
|
||||
*/
|
||||
|
||||
|
||||
#include <ldmconfig.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ldm_xlen.h"
|
||||
#include "pq.h"
|
||||
#include "ulog.h"
|
||||
|
||||
#include "fauxPqConfigFile.h"
|
||||
|
||||
|
||||
/*
|
||||
* A value which is an invalid off_t
|
||||
*/
|
||||
#define OFF_NONE ((off_t)(-1))
|
||||
|
||||
|
||||
/*
|
||||
* The product queue structure (private to this module).
|
||||
*/
|
||||
struct pqueue {
|
||||
timestampt cursor; /* current position in queue */
|
||||
int isOpen;
|
||||
};
|
||||
|
||||
|
||||
const pqe_index _pqenone = {
|
||||
OFF_NONE,
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Creates a product queue.
|
||||
*
|
||||
* This implementation just checks the arguments and returns EACCES.
|
||||
*
|
||||
* path The pathname of the product queue. (in)
|
||||
* mode The mode in which to create the product queue. (in)
|
||||
* pflags Unknown. (in)
|
||||
* align The alignment of products in bytes or zero for the
|
||||
* default. (in)
|
||||
* initialsz The initial size of the product queue. (in)
|
||||
* nproducts The anticipated number of products for the queue. (in)
|
||||
* pqp The product queue. (out)
|
||||
*
|
||||
* Returns:
|
||||
* errno.h:EACCES if permission is denied.
|
||||
* errno.h:EINVAL if the pathname or queue argument is NULL.
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
int pq_create(
|
||||
const char* path,
|
||||
mode_t mode,
|
||||
int pflags,
|
||||
size_t align,
|
||||
off_t initialsz,
|
||||
size_t nproducts,
|
||||
pqueue** pqp)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (path == NULL || pqp == NULL) {
|
||||
status = EINVAL;
|
||||
}
|
||||
else {
|
||||
status = EACCES;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Opens an existing product queue. The pathname references a configuration
|
||||
* file that describes the behavior of this module regarding the virtual
|
||||
* product queue. The memory allocated to the returned queue stucture should
|
||||
* be freed via pq_close(pqueue*).
|
||||
*
|
||||
* path The pathname of the configuration file. (in)
|
||||
* pflags Unknown. (in)
|
||||
* pqp The product queue. (out)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if success.
|
||||
* errno.h:ENOMEM if out of memory.
|
||||
* errno.h:EINVAL if the pathname or queue argument is NULL.
|
||||
* errno.h:EBADF if the configuration file couldn't be opened.
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
int pq_open(
|
||||
const char* path,
|
||||
int pflags,
|
||||
pqueue** pqp)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (path == NULL || pqp == NULL) {
|
||||
status = EINVAL;
|
||||
}
|
||||
else {
|
||||
pqueue* pq = (pqueue*)malloc(sizeof(pqueue));
|
||||
|
||||
if (pq == NULL) {
|
||||
status = ENOMEM;
|
||||
}
|
||||
else {
|
||||
status = cfOpen(path);
|
||||
|
||||
if (status == ENOERR) {
|
||||
pq->isOpen = 1;
|
||||
*pqp = pq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Closes an open product queue and frees any allocated resources. Do not use
|
||||
* the product queue structure after this method.
|
||||
*
|
||||
* pq The product queue to be closed. (in/out)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if success.
|
||||
* errno.h:EINVAL if the queue argument is NULL or the queue has already been
|
||||
* closed.
|
||||
*/
|
||||
int pq_close(pqueue *pq)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (pq == NULL || !pq->isOpen) {
|
||||
status = EINVAL;
|
||||
}
|
||||
else {
|
||||
pq->isOpen = 0;
|
||||
free((void*)pq);
|
||||
cfClose();
|
||||
status = ENOERR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the page size of the product queue.
|
||||
*
|
||||
* This implementation always returns 4096.
|
||||
*
|
||||
* pq The product queue whose page size is to be returned.
|
||||
* (in)
|
||||
*
|
||||
* Returns The product queue page size.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
int pq_pagesize(const pqueue *pq)
|
||||
{
|
||||
return 4096;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ensures that a produce queue is open.
|
||||
*
|
||||
* pq The product queue.
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if the queue is open.
|
||||
* errno.h:EINVAL if the queue is NULL or not open.
|
||||
*/
|
||||
static int checkOpen(pqueue* pq)
|
||||
{
|
||||
return
|
||||
(pq == NULL)
|
||||
? EINVAL
|
||||
: ((pq->isOpen)
|
||||
? ENOERR
|
||||
: EINVAL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reserves space in the product queue for a product. This function is used
|
||||
* when a product is not yet assem- bled but we wish to allocate storage in
|
||||
* the queue for its assembly, such as upon the receipt of a COMINGSOON remote
|
||||
* procedure call in the server. It returns storage in *ptrp suitable for
|
||||
* placing the data of the product described by infop and product_size. The
|
||||
* value of *indexp should be retained for use in committing the product using
|
||||
* pqe_insert() or abandoning it using pqe_discard(). Calls to this function
|
||||
* for products whose signature is already in the queue fail with an error
|
||||
* indication of PQUEUE_DUP.
|
||||
*
|
||||
* This implementation just checks the arguments and returns allocated space
|
||||
* for the product.
|
||||
*
|
||||
* pq The product queue. (in)
|
||||
* infop Information on the product. (in)
|
||||
* ptrp Where to copy the data portion of the product. Managed by
|
||||
* this module. (out)
|
||||
* indexp The index of the product for use by pqe_insert() or
|
||||
* pqe_discard(). (out)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if success.
|
||||
* pq.h:PQUEUE_DUP if a product with same signature is already in the queue.
|
||||
* errno.h:ENOMEM if out of memory.
|
||||
* errno.h:EINVAL if any argument is NULL or the queue is not open.
|
||||
*/
|
||||
int pqe_new(
|
||||
pqueue* pq,
|
||||
const prod_info* infop,
|
||||
void** ptrp,
|
||||
pqe_index* indexp)
|
||||
{
|
||||
int status = checkOpen(pq);
|
||||
|
||||
if (status == ENOERR) {
|
||||
if (infop == NULL || ptrp == NULL || indexp == NULL) {
|
||||
status = EINVAL;
|
||||
}
|
||||
else {
|
||||
void* ptr = malloc(infop->sz);
|
||||
|
||||
if (ptr == NULL) {
|
||||
status = ENOMEM;
|
||||
}
|
||||
else {
|
||||
*ptrp = ptr;
|
||||
indexp->offset = (off_t)ptr;
|
||||
(void)memcpy(indexp->signature, infop->signature,
|
||||
sizeof(infop->signature));
|
||||
status = ENOERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Abandons the saving of a product which was begun using pqe_new() and
|
||||
* releases any allocated resources.
|
||||
*
|
||||
* pq The product queue. (in/out)
|
||||
* index The index of the product begun by pqe_new(...). (in)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if success.
|
||||
* errno.h:EINVAL if the queue is NULL or not open.
|
||||
*/
|
||||
int pqe_discard(
|
||||
pqueue* pq,
|
||||
pqe_index index)
|
||||
{
|
||||
int status = checkOpen(pq);
|
||||
|
||||
if (status == ENOERR) {
|
||||
if(!pqeIsNone(index))
|
||||
free((void*)index.offset);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Inserts a completed product which was begun using pqe_new() and releases
|
||||
* any allocated resources.
|
||||
*
|
||||
* pq The product queue. (in/out)
|
||||
* index The index of the product begun by pqe_new(...). (in)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if success.
|
||||
* errno.h:EINVAL if the queue is NULL or not open.
|
||||
*/
|
||||
int pqe_insert(
|
||||
pqueue* pq,
|
||||
pqe_index index)
|
||||
{
|
||||
return pqe_discard(pq, index);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Inserts a product into the queue.
|
||||
*
|
||||
* pq The product queue. (in/out)
|
||||
* prod The product. (in)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if success.
|
||||
* errno.h:EINVAL if the queue is NULL or not open.
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
int pq_insert(
|
||||
pqueue* pq,
|
||||
const product* prod)
|
||||
{
|
||||
assert(pq != NULL);
|
||||
|
||||
return checkOpen(pq);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns some useful statistics.
|
||||
*
|
||||
* pq The product queue. (in/out)
|
||||
* highwaterp Maximum size of data segment. Set to 0. (out)
|
||||
* maxproductsp Maximum number of products in queue. Set to 0. (out)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if success.
|
||||
* errno.h:EINVAL if the queue argument is NULL.
|
||||
*/
|
||||
int pq_highwater(
|
||||
pqueue* pq,
|
||||
off_t* highwaterp,
|
||||
size_t* maxproductsp)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (pq == NULL || highwaterp == NULL || maxproductsp == NULL) {
|
||||
status = EINVAL;
|
||||
}
|
||||
else {
|
||||
*highwaterp = 0;
|
||||
*maxproductsp = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Sets the cursor used by pq_sequence() or pq_seqdel().
|
||||
*
|
||||
* pq The product queue. (in/out)
|
||||
* tvp The time cursor. (in)
|
||||
*
|
||||
* Raises:
|
||||
* SIGSEGV If the queue argument is NULL.
|
||||
*/
|
||||
void pq_cset(
|
||||
pqueue* pq,
|
||||
const timestampt* tvp)
|
||||
{
|
||||
pq->cursor = *tvp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Gets the current cursor value used by pq_sequence() or pq_seqdel().
|
||||
*
|
||||
* pq The product queue. (in)
|
||||
* tvp The time cursor. (out)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if success.
|
||||
*
|
||||
* Raises
|
||||
* SIGSEGV if either argument is NULL.
|
||||
*/
|
||||
void pq_ctimestamp(
|
||||
const pqueue* pq,
|
||||
timestampt* tvp)
|
||||
{
|
||||
*tvp = pq->cursor;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Steps thru the time-sorted inventory of products according to 'mt', and
|
||||
* the current cursor value. If no product in the inventory matches the
|
||||
* specification, then PQUEUE_END is returned; otherwise, if a matching
|
||||
* product is found, then ifMatch(xprod, len, otherargs) is called and the
|
||||
* return value of that function is returned.
|
||||
*
|
||||
* Whether or not a matching product is found depends upon the configuration
|
||||
* file.
|
||||
*
|
||||
* pq The product queue. (in)
|
||||
* mt The time-matching criteria for finding a product. (in)
|
||||
* clss The class of products to find. (in)
|
||||
* ifMatch The function to call if a matching product is found. (in)
|
||||
* otherargs The last argument to (*ifMatch). (unknown)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:PQUEUE_END if no matching product was found.
|
||||
* errno.h:EINVAL if the queue is NULL or not open.
|
||||
* (else) <errno.h> error code.
|
||||
*/
|
||||
int pq_sequence(
|
||||
pqueue* pq,
|
||||
pq_match mt,
|
||||
const prod_class_t* clss,
|
||||
pq_seqfunc* ifMatch,
|
||||
void* otherargs)
|
||||
{
|
||||
int status = checkOpen(pq);
|
||||
|
||||
if (status == ENOERR) {
|
||||
prod_info info; /* the product metadata */
|
||||
void* datap; /* the XDR-decoded product-data */
|
||||
/* (excludes metadata) */
|
||||
void* xprodp; /* the corresponding, XDR-encoded product */
|
||||
/* (includes metadata) */
|
||||
size_t len; /* the size of xprodp in bytes */
|
||||
|
||||
status = cfGetProduct(mt, clss, &info, &datap, &xprodp, &len);
|
||||
|
||||
if (status == ENOERR) {
|
||||
status = (*ifMatch)(&info, datap, xprodp, len, otherargs);
|
||||
|
||||
cfFreeProduct(&info, &datap, &xprodp);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Like pq_sequence(), but the action is to remove the product from the product
|
||||
* queue. If no matching product is found, then PQUEUE_END is returned and
|
||||
* *extentp and *timestampp are unmodified.
|
||||
*
|
||||
* pq The product queue. (in/out)
|
||||
* mt The sequencing behavior for finding a product. (in)
|
||||
* clss The class of products to find. (in)
|
||||
* wait Unknown. (in)
|
||||
* extentp The amount of storage, in bytes, made available by the
|
||||
* removal. (out)
|
||||
* timestampp The insertion time of the removed product. (out)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:PQUEUE_END if no matching product was found.
|
||||
* errno.h:EINVAL if the queue is NULL or not open.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int pq_seqdel(
|
||||
pqueue* pq,
|
||||
pq_match mt,
|
||||
const prod_class_t* clss,
|
||||
int wait,
|
||||
size_t* extentp,
|
||||
timestampt* timestampp)
|
||||
{
|
||||
return checkOpen(pq);
|
||||
}
|
||||
|
||||
|
||||
static void hndlr_noop(int sig)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
switch(sig) {
|
||||
case SIGALRM :
|
||||
udebug("SIGALRM") ;
|
||||
return ;
|
||||
case SIGCONT :
|
||||
udebug("SIGCONT") ;
|
||||
return;
|
||||
}
|
||||
udebug("hndlr_noop: unhandled signal: %d", sig) ;
|
||||
#endif
|
||||
/* nothing to do, just wake up */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Suspends the current thread until one of the following events occurs:
|
||||
*
|
||||
* A signal is received that has a non-default handler.
|
||||
* A SIGCONT is received, indicating that new data is available in the queue.
|
||||
* The specified time elapses.
|
||||
*
|
||||
* maxsleep The amount of time to sleep in seconds. If zero, then
|
||||
* the sleep is indefinite.
|
||||
*
|
||||
* Returns:
|
||||
* 0 Success.
|
||||
*/
|
||||
int
|
||||
pq_suspend(unsigned int maxsleep)
|
||||
{
|
||||
struct sigaction sigact, csavact, asavact;
|
||||
sigset_t mask, savmask;
|
||||
|
||||
/* block CONT and ALRM while we set up */
|
||||
(void)sigemptyset(&mask);
|
||||
(void)sigaddset(&mask, SIGCONT);
|
||||
if(maxsleep)
|
||||
(void)sigaddset(&mask, SIGALRM);
|
||||
(void) sigprocmask(SIG_BLOCK, &mask, &savmask);
|
||||
|
||||
/*
|
||||
* Set up handlers for CONT and ALRM, stashing old
|
||||
*/
|
||||
(void)sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
sigact.sa_handler = hndlr_noop;
|
||||
(void) sigaction(SIGCONT, &sigact, &csavact);
|
||||
if(maxsleep)
|
||||
{
|
||||
/* set the alarm */
|
||||
(void) sigaction(SIGALRM, &sigact, &asavact);
|
||||
(void) alarm(maxsleep);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unblock the signals.
|
||||
*/
|
||||
mask = savmask;
|
||||
(void)sigdelset(&mask, SIGCONT);
|
||||
if(maxsleep)
|
||||
(void)sigdelset(&mask, SIGALRM);
|
||||
|
||||
/* Nighty night... */
|
||||
(void) sigsuspend(&mask);
|
||||
|
||||
/* Now we are back, restore state */
|
||||
if(maxsleep)
|
||||
{
|
||||
(void)alarm(0);
|
||||
(void) sigaction(SIGALRM, &asavact, NULL );
|
||||
}
|
||||
(void) sigaction(SIGCONT, &csavact, NULL );
|
||||
|
||||
(void) sigprocmask(SIG_SETMASK, &savmask, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get some detailed product queue statistics. These may be useful for
|
||||
* monitoring the internal state of the product queue:
|
||||
*
|
||||
* nprodsp
|
||||
* holds the current number of products in the queue.
|
||||
* nfreep
|
||||
* holds the current number of free regions. This should be small
|
||||
* and it's OK if it's zero, since new free regions are created
|
||||
* as needed by deleting oldest products. If this gets large,
|
||||
* insertion and deletion take longer.
|
||||
* nemptyp
|
||||
* holds the number of product slots left. This may decrease, but
|
||||
* should eventually stay above some positive value unless too
|
||||
* few product slots were allocated when the queue was
|
||||
* created. New product slots get created when adjacent free
|
||||
* regions are consolidated, and product slots get consumed
|
||||
* when larger free regions are split into smaller free
|
||||
* regions.
|
||||
* nbytesp
|
||||
* holds the current number of bytes in the queue used for data
|
||||
* products.
|
||||
* maxprodsp
|
||||
* holds the maximum number of products in the queue, so far.
|
||||
* maxfreep
|
||||
* holds the maximum number of free regions, so far.
|
||||
* minemptyp
|
||||
* holds the minimum number of empty product slots, so far.
|
||||
* maxbytesp
|
||||
* holds the maximum number of bytes used for data, so far.
|
||||
* age_oldestp
|
||||
* holds the age in seconds of the oldest product in the queue.
|
||||
* maxextentp
|
||||
* holds extent of largest free region
|
||||
*
|
||||
* Returns 0
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
int pq_stats(
|
||||
pqueue *pq,
|
||||
size_t *nprodsp,
|
||||
size_t *nfreep,
|
||||
size_t *nemptyp,
|
||||
size_t *nbytesp,
|
||||
size_t *maxprodsp,
|
||||
size_t *maxfreep,
|
||||
size_t *minemptyp,
|
||||
size_t *maxbytesp,
|
||||
double *age_oldestp,
|
||||
size_t *maxextentp)
|
||||
{
|
||||
if(nprodsp)
|
||||
*nprodsp = 0;
|
||||
if(nfreep)
|
||||
*nfreep = 0;
|
||||
if(maxextentp)
|
||||
*maxextentp = 0;
|
||||
if(nemptyp)
|
||||
*nemptyp = 0;
|
||||
if(nbytesp)
|
||||
*nbytesp = 0;
|
||||
if(maxprodsp)
|
||||
*maxprodsp = 0;
|
||||
if(maxfreep)
|
||||
*maxfreep = 0;
|
||||
if(minemptyp)
|
||||
*minemptyp = 0;
|
||||
if(maxbytesp)
|
||||
*maxbytesp = 0;
|
||||
if(age_oldestp) {
|
||||
*age_oldestp = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* For debugging: dump extents of regions on free list, in order by extent.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
int pq_fext_dump(pqueue *const pq)
|
||||
{
|
||||
return ENOERR;
|
||||
}
|
||||
|
||||
|
||||
/*ARGSUSED0*/
|
||||
int pq_last(
|
||||
pqueue* pq,
|
||||
const prod_class_t* clssp,
|
||||
timestampt* tsp) /* modified upon return */
|
||||
{
|
||||
int status = set_timestamp(tsp);
|
||||
|
||||
if (status != 0) {
|
||||
uerror("%s:%d: Couldn't set time: %s", __FILE__,
|
||||
__LINE__, strerror(errno));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Insert at rear of queue
|
||||
* (Don't signal process group.)
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
int pq_insertNoSig(pqueue *pq, const product *prod)
|
||||
{
|
||||
return ENOERR;
|
||||
}
|
||||
|
||||
|
||||
/*ARGSUSED0*/
|
||||
int pq_ctimeck(
|
||||
const pqueue* pq,
|
||||
pq_match mt,
|
||||
const prod_class_t* clssp,
|
||||
const timestampt* maxlatencyp)
|
||||
{
|
||||
return ENOERR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* LDM 4 convenience funct.
|
||||
* Change signature, Insert at rear of queue, send SIGCONT to process group
|
||||
*/
|
||||
/*ARGSUSED2*/
|
||||
int pqe_xinsert(
|
||||
pqueue* pq,
|
||||
pqe_index index,
|
||||
const signaturet realsignature)
|
||||
{
|
||||
return pqe_insert(pq, index);
|
||||
}
|
||||
|
||||
|
||||
int pq_clss_setfrom(
|
||||
pqueue* pq,
|
||||
prod_class_t *clssp) /* modified upon return */
|
||||
{
|
||||
timestampt ts = clssp->from;
|
||||
int status = pq_last(pq, clssp, &ts);
|
||||
|
||||
if(status == ENOERR)
|
||||
{
|
||||
if(tvEqual(ts, clssp->from))
|
||||
status = PQUEUE_END;
|
||||
else
|
||||
clssp->from = ts;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*ARGSUSED0*/
|
||||
int pq_cClassSet(
|
||||
pqueue* pq,
|
||||
pq_match* mtp,
|
||||
const prod_class_t* clssp)
|
||||
{
|
||||
return ENOERR;
|
||||
}
|
|
@ -1,515 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995, University Corporation for Atmospheric Research
|
||||
* See top level COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: fauxPqConfigFile.c,v 1.7.12.1 2008/04/15 16:34:07 steve Exp $ */
|
||||
|
||||
|
||||
/*
|
||||
* A module for controlling the behavior of the "faux" product queue from a
|
||||
* configuration file.
|
||||
*/
|
||||
|
||||
|
||||
#include "ldmconfig.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <parser.h> /* XML parser API */
|
||||
#include <rpc/xdr.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h> /* time(), difftime() */
|
||||
#include <timestamp.h>
|
||||
#include <unistd.h> /* sleep() */
|
||||
|
||||
#include "atofeedt.h"
|
||||
#include "inetutil.h" /* ghostname() */
|
||||
#include "ldm.h"
|
||||
#include "ldm_xlen.h" /* xlen_prod_i() */
|
||||
#include "ldmprint.h" /* s_signaturet() */
|
||||
#include "md5.h"
|
||||
#include "ulog.h"
|
||||
|
||||
#include "fauxPqConfigFile.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
CLOSED,
|
||||
START,
|
||||
IN_ROOT_ELT,
|
||||
UNKNOWN,
|
||||
READY,
|
||||
ERROR
|
||||
} State;
|
||||
|
||||
|
||||
static State currState = CLOSED;
|
||||
static State prevState;
|
||||
static int unknownLevel;
|
||||
static xmlSAXHandler saxer;
|
||||
static const xmlChar* rootEltName = (xmlChar*)"FauxProductQueue";
|
||||
static const xmlChar* feedEltName = (xmlChar*)"feed";
|
||||
static const xmlChar* typeAttName = (xmlChar*)"type";
|
||||
static const xmlChar* idAttName = (xmlChar*)"id";
|
||||
static const xmlChar* sizeAttName = (xmlChar*)"size";
|
||||
static const xmlChar* delayAttName = (xmlChar*)"delay";
|
||||
static feedtypet feedType = EXP;
|
||||
static char* prodId = "faux product";
|
||||
static unsigned int prodSize = 200000; /* bytes */
|
||||
static void* prodData = NULL;
|
||||
static prod_info prodInfo;
|
||||
static size_t prodXdrLen;
|
||||
static void* prodXdrBuf;
|
||||
static product prod;
|
||||
static unsigned int delay = 1; /* seconds */
|
||||
static MD5_CTX* md5;
|
||||
static unsigned int prodCount = 0;
|
||||
static time_t lastReturned = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Handles the start of the XML document.
|
||||
*
|
||||
* user_data User-supplied data. (in/out)
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void myStartDocument(void *user_data)
|
||||
{
|
||||
currState = START;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handles the start of an XML element.
|
||||
*
|
||||
* user_data User-supplied data. (in/out)
|
||||
* name The name of the element. (in)
|
||||
* attrs XML attributes associated with the element. (in)
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void myStartElement(
|
||||
void* user_data,
|
||||
const xmlChar* name,
|
||||
const xmlChar** attrs)
|
||||
{
|
||||
switch (currState) {
|
||||
|
||||
case START:
|
||||
if (xmlStrcmp(name, rootEltName) == 0) {
|
||||
currState = IN_ROOT_ELT;
|
||||
}
|
||||
else {
|
||||
uerror("%s:%d: Root element \"%s\" is not \"%s\"", __FILE__,
|
||||
__LINE__, name, rootEltName);
|
||||
currState = ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case IN_ROOT_ELT:
|
||||
if (xmlStrcmp(name, feedEltName) != 0) {
|
||||
prevState = currState;
|
||||
currState = UNKNOWN;
|
||||
unknownLevel = 1;
|
||||
}
|
||||
else {
|
||||
const xmlChar** nameValuePair = attrs;
|
||||
for (; *nameValuePair != NULL; nameValuePair += 2) {
|
||||
const xmlChar* attName = nameValuePair[0];
|
||||
|
||||
if (xmlStrcmp(attName, typeAttName) == 0) {
|
||||
if (strfeedtypet((const char*)nameValuePair[1], &feedType)
|
||||
!= FEEDTYPE_OK) {
|
||||
|
||||
uerror("%s:%d: Invalid feed type: \"%s\"",
|
||||
__FILE__, __LINE__, nameValuePair[1]);
|
||||
currState = ERROR;
|
||||
}
|
||||
}
|
||||
else if (xmlStrcmp(attName, idAttName) == 0) {
|
||||
prodId = strdup((char*)nameValuePair[1]);
|
||||
|
||||
if (prodId == NULL) {
|
||||
uerror(
|
||||
"%s:%d: Couldn't duplicate product ID: \"%s\"",
|
||||
__FILE__, __LINE__, nameValuePair[1]);
|
||||
currState = ERROR;
|
||||
}
|
||||
}
|
||||
else if (xmlStrcmp(attName, sizeAttName) == 0) {
|
||||
if (sscanf((const char*)nameValuePair[1], "%u", &prodSize)
|
||||
!= 1) {
|
||||
|
||||
uerror("%s:%d: Invalid product size: \"%s\"",
|
||||
__FILE__, __LINE__, nameValuePair[1]);
|
||||
currState = ERROR;
|
||||
}
|
||||
}
|
||||
else if (xmlStrcmp(attName, delayAttName) == 0) {
|
||||
if (sscanf((const char*)nameValuePair[1], "%u", &delay)
|
||||
!= 1) {
|
||||
|
||||
uerror("%s:%d: Invalid delay time: \"%s\"",
|
||||
__FILE__, __LINE__, nameValuePair[1]);
|
||||
currState = ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uerror("%s:%d: Invalid attribute: \"%s\"",
|
||||
__FILE__, __LINE__, attName);
|
||||
currState = ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case UNKNOWN:
|
||||
++unknownLevel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the character data associated with an XM entity.
|
||||
*
|
||||
* user_data User-supplied data. (in/out)
|
||||
* name The name of the XML entity. (in)
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static xmlEntityPtr myGetEntity(
|
||||
void* user_data,
|
||||
const xmlChar* name)
|
||||
{
|
||||
return xmlGetPredefinedEntity(name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handles character data in the body of an XM element.
|
||||
*
|
||||
* user_data User-supplied data. (in/out)
|
||||
* ch The character data. (in)
|
||||
* len The amount of data in characters. (in)
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void myCharacters(
|
||||
void* user_data,
|
||||
const xmlChar* ch,
|
||||
int len)
|
||||
{}
|
||||
|
||||
|
||||
/*
|
||||
* Handles the end of an XML element.
|
||||
*
|
||||
* user_data User-supplied data. (in/out)
|
||||
* name The name of the XML element. (in)
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void myEndElement(
|
||||
void* user_data,
|
||||
const xmlChar* name)
|
||||
{
|
||||
if (currState == UNKNOWN) {
|
||||
if (--unknownLevel == 0)
|
||||
currState = prevState;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handles the end of the XML document.
|
||||
*
|
||||
* user_data User-supplied data. (in/out)
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void myEndDocument(void *user_data)
|
||||
{
|
||||
if (currState != ERROR)
|
||||
currState = READY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handles an XML warning message.
|
||||
*
|
||||
* user_data User-supplied data. (in/out)
|
||||
* msg The warning message as a printf(3) format. (in)
|
||||
* ... Arguments referenced by the message.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void xmlWarning(
|
||||
void* user_data,
|
||||
const char* msg,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, msg);
|
||||
vulog(LOG_WARNING, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handles an XML error or fatal error message.
|
||||
*
|
||||
* user_data User-supplied data. (in/out)
|
||||
* msg The warning message as a printf(3) format. (in)
|
||||
* ... Arguments referenced by the message.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void xmlError(
|
||||
void* user_data,
|
||||
const char* msg,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, msg);
|
||||
vulog(LOG_ERR, msg, args);
|
||||
va_end(args);
|
||||
|
||||
currState = ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the next product signature (MD5 checksum).
|
||||
*
|
||||
* signature The buffer in which to put the MD5 checksum.
|
||||
*/
|
||||
static void nextSignature(signaturet* signature)
|
||||
{
|
||||
MD5Init(md5);
|
||||
MD5Update(md5, (const unsigned char*)&prodCount, sizeof(prodCount));
|
||||
MD5Final((unsigned char*)*signature, md5);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ensures that products aren't returned more often than the configured
|
||||
* delay.
|
||||
*/
|
||||
static void ensure_delay()
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (lastReturned != 0) {
|
||||
double diff = difftime(now, lastReturned);
|
||||
|
||||
if (diff < delay) {
|
||||
(void)sleep((int)(delay - diff + 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
lastReturned = now;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Public API:
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* Opens the configuration file. Any previously opened configuration file will
|
||||
* be closed. The ulog(3) facility will be used to log any problems.
|
||||
*
|
||||
* pathname The pathname of the file. (in)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if success.
|
||||
* errno.h:ENOMEM if out of memory.
|
||||
* errno.h:EINVAL if the pathname is NULL or if the configuration file was
|
||||
* invalid.
|
||||
* (else) <errno.h> error code.
|
||||
*/
|
||||
int cfOpen(const char* pathname)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (pathname == NULL) {
|
||||
uerror("%s:%d: NULL pathname", __FILE__, __LINE__);
|
||||
status = EINVAL;
|
||||
}
|
||||
else {
|
||||
if (currState != CLOSED)
|
||||
cfClose();
|
||||
|
||||
md5 = new_MD5_CTX();
|
||||
|
||||
if (saxer.startDocument != myStartDocument) {
|
||||
saxer.startDocument = myStartDocument;
|
||||
saxer.startElement = myStartElement;
|
||||
saxer.getEntity = myGetEntity;
|
||||
saxer.characters = myCharacters;
|
||||
saxer.endElement = myEndElement;
|
||||
saxer.endDocument = myEndDocument;
|
||||
saxer.warning = xmlWarning;
|
||||
saxer.error = xmlError;
|
||||
saxer.fatalError = xmlError;
|
||||
}
|
||||
|
||||
(void)xmlSAXUserParseFile(&saxer, NULL, pathname);
|
||||
|
||||
if (currState != READY) {
|
||||
cfClose();
|
||||
status = EINVAL;
|
||||
}
|
||||
else {
|
||||
prodData = realloc(prodData, prodSize);
|
||||
|
||||
if (prodData == NULL) {
|
||||
uerror("%s:%d: Couldn't allocate %u bytes for product data",
|
||||
__FILE__, __LINE__, prodSize);
|
||||
status = ENOMEM;
|
||||
}
|
||||
else {
|
||||
(void)memset(prodData, 'x', prodSize);
|
||||
|
||||
prodInfo.origin = (char*)ghostname();
|
||||
prodInfo.feedtype = feedType;
|
||||
prodInfo.ident = prodId;
|
||||
prodInfo.sz = prodSize;
|
||||
prodXdrLen = xlen_prod_i(&prodInfo);
|
||||
prodXdrBuf = realloc(prodXdrBuf, prodXdrLen);
|
||||
|
||||
if (prodXdrBuf == NULL) {
|
||||
uerror("%s:%d: Couldn't allocate %lu bytes for product "
|
||||
"XDR buffer", __FILE__, __LINE__, prodXdrLen);
|
||||
status = errno;
|
||||
}
|
||||
else {
|
||||
prod.data = prodData;
|
||||
status = ENOERR;
|
||||
}
|
||||
|
||||
if (status != ENOERR) {
|
||||
free(prodData);
|
||||
prodData = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns a matching product if appropriate. Successfully obtained products
|
||||
* should be freed using cfFreeProduct(...).
|
||||
*
|
||||
* mt The time-matching criteria for finding a product. (in)
|
||||
* clss The class of products to find. (in)
|
||||
* info The product metadata. (out)
|
||||
* data The product data (no metadata). (out)
|
||||
* encProd The entire, XDR-encoded product (including metadata). (out)
|
||||
* len The size of "encProd" in bytes. (out)
|
||||
*
|
||||
* Returns:
|
||||
* pq.h:ENOERR if matching product found.
|
||||
* pq.h:PQUEUE_END if no matching product.
|
||||
* errno.h:EINVAL if an argument is invalid.
|
||||
* errno.h:ENOENT if cfOpen(...) hasn't been called or cfClose() has been
|
||||
* called more recently.
|
||||
* (else) <errno.h> error code.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
int cfGetProduct(
|
||||
pq_match mt,
|
||||
const prod_class_t* clss,
|
||||
prod_info* info,
|
||||
void** data,
|
||||
void** encProd,
|
||||
size_t* len)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (currState != READY) {
|
||||
uerror("%s:%d: Configuration file not ready", __FILE__, __LINE__);
|
||||
|
||||
status = ENOENT;
|
||||
}
|
||||
else {
|
||||
ensure_delay();
|
||||
|
||||
*info = prodInfo;
|
||||
|
||||
status = set_timestamp(&info->arrival);
|
||||
|
||||
if (status != 0) {
|
||||
uerror("%s:%d: Couldn't set product arrival time: %s", __FILE__,
|
||||
__LINE__, strerror(errno));
|
||||
}
|
||||
else {
|
||||
XDR xdr;
|
||||
|
||||
info->seqno = ++prodCount;
|
||||
nextSignature(&info->signature);
|
||||
prod.info = *info;
|
||||
|
||||
*data = prodData;
|
||||
*len = prodXdrLen;
|
||||
*encProd = prodXdrBuf;
|
||||
|
||||
xdrmem_create(&xdr, *encProd, *len, XDR_ENCODE);
|
||||
|
||||
if(xdr_product(&xdr, &prod))
|
||||
{
|
||||
status = ENOERR;
|
||||
}
|
||||
else {
|
||||
uerror("%s:%d: Couldn't XDR_ENCODE product",
|
||||
__FILE__, __LINE__);
|
||||
status = EIO;
|
||||
}
|
||||
|
||||
xdr_destroy(&xdr);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Frees resources associated with a product obtained via cfGetProduct(...).
|
||||
*
|
||||
* info The product metadata. (in/out)
|
||||
* data The product data (no metadata). (in/out)
|
||||
* encProd The entire, XDR-encoded product (including metadata).
|
||||
* (in/out)
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
void cfFreeProduct(
|
||||
prod_info* info,
|
||||
void** data,
|
||||
void** encProd)
|
||||
{}
|
||||
|
||||
|
||||
/*
|
||||
* Closes the configuration file and releases any resources.
|
||||
*/
|
||||
void cfClose()
|
||||
{
|
||||
if (currState != CLOSED) {
|
||||
free_MD5_CTX(md5);
|
||||
|
||||
if (prodXdrBuf != NULL) {
|
||||
free(prodXdrBuf);
|
||||
prodXdrBuf = NULL;
|
||||
}
|
||||
|
||||
if (prodData != NULL) {
|
||||
free(prodData);
|
||||
prodData = NULL;
|
||||
}
|
||||
|
||||
currState = CLOSED;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright 1994, University Corporation for Atmospheric Research
|
||||
* See top level COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: fauxPqConfigFile.h,v 1.1.20.1 2008/04/15 16:34:07 steve Exp $ */
|
||||
|
||||
#ifndef _CONFIG_FILE_H
|
||||
#define _CONFIG_FILE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "pq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int cfOpen(const char* pathname);
|
||||
|
||||
int cfGetProduct(
|
||||
pq_match mt,
|
||||
const prod_class_t* clss,
|
||||
prod_info* info,
|
||||
void** data,
|
||||
void** prod,
|
||||
size_t* len);
|
||||
|
||||
void cfFreeProduct(
|
||||
prod_info* info,
|
||||
void** data,
|
||||
void** prod);
|
||||
|
||||
void cfDelay();
|
||||
|
||||
void cfClose();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_CONFIG_FILE_H */
|
|
@ -1,3 +0,0 @@
|
|||
<FauxProductQueue>
|
||||
<feed size="200000" delay="7"/>
|
||||
</FauxProductQueue>
|
|
@ -1,7 +0,0 @@
|
|||
# $Id: Makefile,v 1.1 2003/02/26 23:43:37 steve Exp $
|
||||
|
||||
include ../macros.make
|
||||
PROGRAM = feedme
|
||||
include ../simple_program.make
|
||||
include ../rules.make
|
||||
include depends
|
|
@ -1,11 +0,0 @@
|
|||
feedme.o: ../config/ldmconfig.h
|
||||
feedme.o: ../misc/inetutil.h
|
||||
feedme.o: ../protocol/atofeedt.h
|
||||
feedme.o: ../protocol/h_clnt.h
|
||||
feedme.o: ../protocol/ldm.h
|
||||
feedme.o: ../protocol/ldm5.h
|
||||
feedme.o: ../protocol/ldm5_clnt.h
|
||||
feedme.o: ../protocol/ldmprint.h
|
||||
feedme.o: ../protocol/timestamp.h
|
||||
feedme.o: ../ulog/ulog.h
|
||||
feedme.o: feedme.c
|
|
@ -1,71 +0,0 @@
|
|||
'\"
|
||||
'\" $Header: /cvsroot/ldm/src/feedme/feedme.1,v 1.10.22.1 2009/06/18 16:10:21 steve Exp $
|
||||
.TH FEEDME 1 "$Date: 2009/06/18 16:10:21 $"
|
||||
.SH NAME
|
||||
feedme - event driven data sink client for the Unidata LDM
|
||||
.SH "UNIX SYNOPSIS"
|
||||
\fBfeedme \fR[\fB\-vx\fR] [\fB\-l \fIlogfile\fR]
|
||||
.BI [\-h " remote" ]
|
||||
.BI [\-p " pattern" ]
|
||||
.BI [\-f " feedtype" ]
|
||||
.BI [\-t " timeout" ]
|
||||
.BI [\-T " TotalTimeo" ]
|
||||
.SH DESCRIPTION
|
||||
This program gets selected meteorological data as it becomes available.
|
||||
It is part of the Unidata Local Data Management system (LDM).
|
||||
It calls the LDM server at \fIremote\fR and requests
|
||||
that data whose identifying key matches \fIpattern\fR be sent.
|
||||
As data arrives at the server, qualifying data products are passed along
|
||||
to this program. On receipt, this program writes the data to standard output.
|
||||
If connection is lost to the server,
|
||||
the program repeats its request for data.
|
||||
.SH OPTIONS
|
||||
.TP 8
|
||||
.B \-v
|
||||
Verbose flag. If present, the log will contain a line for
|
||||
each product that was received.
|
||||
.TP 8
|
||||
.B \-x
|
||||
Requests that debugging information also be printed. Details about
|
||||
each FEEDME RPC.
|
||||
.TP
|
||||
.BI \-l " logfile"
|
||||
The path name of a file to be used as the log file for the process. The
|
||||
default is to use syslogd(8).
|
||||
.TP
|
||||
.BI \-h " remote"
|
||||
Requests that that the LDM server on \fIremote\fR send along data.
|
||||
Default is "localhost".
|
||||
.TP
|
||||
.BI \-p " pattern"
|
||||
Requests that data be sent along that matches \fIpattern\fP.
|
||||
The default is `\fB.*\fP'.
|
||||
.TP
|
||||
.BI \-f " feedtype"
|
||||
Requests that data that originates in a feed type of type
|
||||
\fIfeedtype\fP be sent along.
|
||||
The default is any feed type.
|
||||
.TP
|
||||
.BI \-t " timeout"
|
||||
Sets the RPC timeout on FEEDME requests to "\fItimeout\fR" seconds.
|
||||
.TP
|
||||
.BI \-T " TotalTimeo"
|
||||
Give up attempting to make a connection after
|
||||
\fITotalTimeo\fR seconds. Any partially built up client connnection
|
||||
is destroyed and we start over.
|
||||
.SH EXAMPLE
|
||||
Although this program was written as a coding example, it is useful in
|
||||
its own right.
|
||||
The command
|
||||
.RS +4
|
||||
.nf
|
||||
xterm -sb -title "Denver Warnings" -e ~ldm/bin/feedme -h myhost -f PPS -p "^W..... KDEN"
|
||||
.fi
|
||||
.RE
|
||||
Will create a scrolling window titled "Denver Warnings" to which warnings
|
||||
and watches from KDEN will be printed as they are received.
|
||||
.SH "SEE ALSO"
|
||||
ldmd(1), ldm(1)
|
||||
.SH DIAGNOSTICS
|
||||
Error messages and log messages are written to the
|
||||
log file.
|
|
@ -1,516 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: feedme.c,v 1.61.12.9 2007/02/22 19:43:15 steve Exp $ */
|
||||
|
||||
/*
|
||||
* listens for data
|
||||
*/
|
||||
|
||||
#include <ldmconfig.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include "ldm5.h"
|
||||
#include "globals.h"
|
||||
#include "ldmprint.h"
|
||||
#include "atofeedt.h"
|
||||
#include "ulog.h"
|
||||
#include "inetutil.h"
|
||||
#include "ldm5_clnt.h"
|
||||
#include "RegularExpressions.h"
|
||||
#include "xdr_data.h"
|
||||
|
||||
#ifdef NO_ATEXIT
|
||||
#include "atexit.h"
|
||||
#endif
|
||||
|
||||
#ifndef STDOUT_FILENO
|
||||
#define STDOUT_FILENO 1
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_REMOTE
|
||||
#define DEFAULT_REMOTE "localhost"
|
||||
#endif
|
||||
#ifndef DEFAULT_TIMEO
|
||||
#define DEFAULT_TIMEO 25
|
||||
#endif
|
||||
#ifndef DEFAULT_TOTALTIMEO
|
||||
#define DEFAULT_TOTALTIMEO (12*DEFAULT_TIMEO)
|
||||
#endif
|
||||
#ifndef DEFAULT_FEEDTYPE
|
||||
#define DEFAULT_FEEDTYPE ANY
|
||||
#endif
|
||||
#ifndef DEFAULT_PATTERN
|
||||
#define DEFAULT_PATTERN ".*"
|
||||
#endif
|
||||
|
||||
|
||||
static const char *remote = DEFAULT_REMOTE; /* hostname of data remote */
|
||||
static ldm_replyt reply = { OK };
|
||||
|
||||
|
||||
/*
|
||||
* Called at exit.
|
||||
* This callback routine registered by atexit().
|
||||
*/
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
unotice("exiting");
|
||||
|
||||
/* TODO: sign off */
|
||||
|
||||
(void) closeulog();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called upon receipt of signals.
|
||||
* This callback routine registered in set_sigactions() .
|
||||
*/
|
||||
static void
|
||||
signal_handler(int sig)
|
||||
{
|
||||
#ifdef SVR3SIGNALS
|
||||
/*
|
||||
* Some systems reset handler to SIG_DFL upon entry to handler.
|
||||
* In that case, we reregister our handler.
|
||||
*/
|
||||
(void) signal(sig, signal_handler);
|
||||
#endif
|
||||
switch(sig) {
|
||||
case SIGHUP :
|
||||
return;
|
||||
case SIGINT :
|
||||
/*FALLTHROUGH*/
|
||||
case SIGTERM :
|
||||
done = 1;
|
||||
return;
|
||||
case SIGUSR1 :
|
||||
return;
|
||||
case SIGUSR2 :
|
||||
toggleulogpri(LOG_INFO);
|
||||
return;
|
||||
case SIGPIPE :
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_sigactions(void)
|
||||
{
|
||||
#ifndef NO_POSIXSIGNALS
|
||||
struct sigaction sigact;
|
||||
|
||||
sigact.sa_handler = signal_handler;
|
||||
(void)sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
|
||||
(void) sigaction(SIGHUP, &sigact, NULL);
|
||||
(void) sigaction(SIGINT, &sigact, NULL);
|
||||
(void) sigaction(SIGTERM, &sigact, NULL);
|
||||
(void) sigaction(SIGUSR1, &sigact, NULL);
|
||||
(void) sigaction(SIGUSR2, &sigact, NULL);
|
||||
(void) sigaction(SIGPIPE, &sigact, NULL);
|
||||
#else
|
||||
(void) signal(SIGHUP, signal_handler);
|
||||
(void) signal(SIGINT, signal_handler);
|
||||
(void) signal(SIGTERM, signal_handler);
|
||||
(void) signal(SIGUSR1, signal_handler);
|
||||
(void) signal(SIGUSR2, signal_handler);
|
||||
(void) signal(SIGPIPE, signal_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
usage(
|
||||
char *av0 /* id string */
|
||||
)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"Usage: %s [options] \t\nOptions:\n", av0);
|
||||
(void)fprintf(stderr,
|
||||
"\t-v Verbose, report each notification\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-x Debug mode\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-l logfile Send log info to file (default uses syslogd)\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-h remote Have \"remote\" send us data (default \"%s\")\n",
|
||||
DEFAULT_REMOTE);
|
||||
(void)fprintf(stderr,
|
||||
"\t-f feedtype Interested in products from feed \"feedtype\" (default %s)\n", s_feedtypet(DEFAULT_FEEDTYPE));
|
||||
(void)fprintf(stderr,
|
||||
"\t-p pattern Interested in products matching \"pattern\" (default \"%s\")\n", DEFAULT_PATTERN);
|
||||
(void)fprintf(stderr,
|
||||
"\t-o offset Set the \"from\" time offset secs before now\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-t timeout Set RPC timeout to \"timeout\" seconds (default %d)\n",
|
||||
DEFAULT_TIMEO);
|
||||
(void)fprintf(stderr,
|
||||
"\t-T TotalTimeo Give up after this many secs (default %d)\n",
|
||||
DEFAULT_TOTALTIMEO);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
ldm_replyt *
|
||||
hiya_5_svc(prod_class *clssp, struct svc_req *rqstp)
|
||||
{
|
||||
|
||||
(void) memset((char*)&reply, 0, sizeof(reply));
|
||||
|
||||
if(ulogIsVerbose())
|
||||
{
|
||||
uinfo("hiya5: %s: %s",
|
||||
remote,
|
||||
s_prod_class(NULL, 0, clssp));
|
||||
}
|
||||
|
||||
return(&reply);
|
||||
}
|
||||
|
||||
|
||||
static prod_class clss;
|
||||
|
||||
|
||||
/*
|
||||
* Used by comingsoon_5_svc and blkdata_5_svc
|
||||
* to keep track of the product in progress.
|
||||
* N.B., this program only handles product in progress
|
||||
* at a time.
|
||||
*/
|
||||
static signaturet signature;
|
||||
static unsigned remaining;
|
||||
static timestampt arrival;
|
||||
static char infostr[50 + KEYSIZE]; /* only used for log messages */
|
||||
|
||||
/*ARGSUSED*/
|
||||
ldm_replyt *
|
||||
comingsoon_5_svc(comingsoon_args *argsp, struct svc_req *rqstp)
|
||||
{
|
||||
prod_info *infop = argsp->infop;
|
||||
(void) memset((char*)&reply, 0, sizeof(reply));
|
||||
|
||||
(void) s_prod_info(infostr, sizeof(infostr), infop, 0);
|
||||
if(ulogIsDebug())
|
||||
{
|
||||
udebug("comingsoon5: %s %s (pktsz %u)",
|
||||
s_signaturet(NULL, 0, infop->signature),
|
||||
infostr, argsp->pktsz);
|
||||
}
|
||||
|
||||
/* set up control structure */
|
||||
remaining = infop->sz;
|
||||
(void)memcpy(signature, infop->signature, sizeof(signature));
|
||||
arrival = infop->arrival;
|
||||
|
||||
return(&reply);
|
||||
}
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
ldm_replyt *
|
||||
blkdata_5_svc(datapkt *dpkp, struct svc_req *rqstp)
|
||||
{
|
||||
(void) memset((char*)&reply, 0, sizeof(reply));
|
||||
|
||||
if(ulogIsDebug())
|
||||
{
|
||||
udebug(" blkdata5: %s %8u %5u",
|
||||
s_signaturet(NULL, 0, *dpkp->signaturep),
|
||||
dpkp->data.dbuf_len,
|
||||
dpkp->pktnum);
|
||||
}
|
||||
|
||||
if(memcmp(*dpkp->signaturep, signature, sizeof(signaturet)) != 0)
|
||||
{
|
||||
uerror("signature mismatch\n");
|
||||
goto err;
|
||||
}
|
||||
/* else */
|
||||
|
||||
remaining -= dpkp->data.dbuf_len;
|
||||
|
||||
|
||||
/*
|
||||
* Update the request filter with the timestamp
|
||||
* we just recieved.
|
||||
* N.B.: There can still be duplicates after
|
||||
* a reconnect.
|
||||
*/
|
||||
if(remaining == 0)
|
||||
{
|
||||
clss.from = arrival;
|
||||
timestamp_incr(&clss.from);
|
||||
uinfo("%s", infostr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* your code here, example writes to stdout
|
||||
*/
|
||||
if( write(STDOUT_FILENO, dpkp->data.dbuf_val, dpkp->data.dbuf_len) !=
|
||||
dpkp->data.dbuf_len)
|
||||
{
|
||||
serror( "data write failed") ;
|
||||
exit(1) ;
|
||||
}
|
||||
|
||||
xd_reset(); /* reset XDR data-buffer */
|
||||
|
||||
return(&reply);
|
||||
err:
|
||||
svcerr_systemerr(rqstp->rq_xprt);
|
||||
xd_reset();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The RPC dispatch routine for this program.
|
||||
* Registered as a callback by svc_register() below.
|
||||
* Note that only NULLPROC, HIYA, COMINGSOON, and BLKDATA are
|
||||
* handled by this program.
|
||||
*/
|
||||
static void
|
||||
feedmeprog_5(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
{
|
||||
union {
|
||||
prod_class hiya_5_arg;
|
||||
comingsoon_args comingsoon_5_arg;
|
||||
datapkt blkdata_5_arg;
|
||||
} argument;
|
||||
char *result;
|
||||
xdrproc_t xdr_argument, xdr_result;
|
||||
char *(*local)(char *, struct svc_req *);
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
case NULLPROC:
|
||||
(void) svc_sendreply(transp, (xdrproc_t) xdr_void, (char *)NULL);
|
||||
return;
|
||||
|
||||
case HIYA:
|
||||
xdr_argument = (xdrproc_t) xdr_prod_class;
|
||||
xdr_result = (xdrproc_t) xdr_ldm_replyt;
|
||||
local = (char *(*)(char *, struct svc_req *)) hiya_5_svc;
|
||||
break;
|
||||
|
||||
case COMINGSOON:
|
||||
xdr_argument = (xdrproc_t) xdr_comingsoon_args;
|
||||
xdr_result = (xdrproc_t) xdr_ldm_replyt;
|
||||
local = (char *(*)(char *, struct svc_req *)) comingsoon_5_svc;
|
||||
break;
|
||||
|
||||
case BLKDATA:
|
||||
xdr_argument = (xdrproc_t) xdr_datapkt;
|
||||
xdr_result = (xdrproc_t) xdr_ldm_replyt;
|
||||
local = (char *(*)(char *, struct svc_req *)) blkdata_5_svc;
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc(transp);
|
||||
return;
|
||||
}
|
||||
(void) memset((char *)&argument, 0, sizeof (argument));
|
||||
if (!svc_getargs(transp, xdr_argument, (caddr_t) &argument)) {
|
||||
svcerr_decode(transp);
|
||||
return;
|
||||
}
|
||||
result = (*local)((char *)&argument, rqstp);
|
||||
|
||||
(void)exitIfDone(0);
|
||||
|
||||
if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
|
||||
svcerr_systemerr(transp);
|
||||
}
|
||||
if (!svc_freeargs(transp, xdr_argument, (caddr_t) &argument)) {
|
||||
uerror("unable to free arguments");
|
||||
exit(1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int main(int ac, char *av[])
|
||||
{
|
||||
char *logfname = 0;
|
||||
int TotalTimeo = DEFAULT_TOTALTIMEO;
|
||||
unsigned timeo = DEFAULT_TIMEO;
|
||||
unsigned interval = DEFAULT_TIMEO;
|
||||
prod_spec spec;
|
||||
int status;
|
||||
prod_class *clssp;
|
||||
|
||||
if(set_timestamp(&clss.from) != 0)
|
||||
{
|
||||
(void)fprintf(stderr, "Couldn't set timestamp\n");
|
||||
exit(1);
|
||||
}
|
||||
clss.to = TS_ENDT;
|
||||
clss.psa.psa_len = 1;
|
||||
clss.psa.psa_val = &spec;
|
||||
spec.feedtype = DEFAULT_FEEDTYPE;
|
||||
spec.pattern = DEFAULT_PATTERN;
|
||||
|
||||
{ /* Begin getopt block */
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
extern char *optarg;
|
||||
int ch;
|
||||
int logmask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) |
|
||||
LOG_MASK(LOG_NOTICE));
|
||||
int fterr;
|
||||
|
||||
opterr = 1;
|
||||
|
||||
while ((ch = getopt(ac, av, "vxl:f:o:t:h:p:T:")) != EOF)
|
||||
switch (ch) {
|
||||
case 'v':
|
||||
logmask |= LOG_MASK(LOG_INFO);
|
||||
break;
|
||||
case 'x':
|
||||
logmask |= LOG_MASK(LOG_DEBUG);
|
||||
break;
|
||||
case 'l':
|
||||
logfname = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
remote = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
spec.pattern = optarg;
|
||||
/* compiled below */
|
||||
break;
|
||||
case 'f':
|
||||
fterr = strfeedtypet(optarg, &spec.feedtype);
|
||||
if(fterr != FEEDTYPE_OK)
|
||||
{
|
||||
(void)fprintf(stderr, "Bad feedtype \"%s\", "
|
||||
"%s\n", optarg, strfeederr(fterr));
|
||||
usage(av[0]);
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
clss.from.tv_sec -= atoi(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
TotalTimeo = atoi(optarg);
|
||||
if(TotalTimeo <= 0)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"%s: invalid TotalTimeo %s", av[0], optarg);
|
||||
usage(av[0]);
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
timeo = (unsigned)atoi(optarg);
|
||||
if(timeo == 0 || timeo > 32767)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"%s: invalid timeout %s", av[0], optarg);
|
||||
usage(av[0]);
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
usage(av[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if(ac - optind > 0)
|
||||
usage(av[0]);
|
||||
|
||||
if (re_isPathological(spec.pattern))
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"Adjusting pathological regular-expression: "
|
||||
"\"%s\"\n", spec.pattern);
|
||||
re_vetSpec(spec.pattern);
|
||||
}
|
||||
status = regcomp(&spec.rgx,
|
||||
spec.pattern,
|
||||
REG_EXTENDED|REG_NOSUB);
|
||||
if(status != 0)
|
||||
{
|
||||
(void)fprintf(stderr, "Bad regular expression \"%s\"\n",
|
||||
spec.pattern);
|
||||
usage(av[0]);
|
||||
}
|
||||
|
||||
(void) setulogmask(logmask);
|
||||
|
||||
if(TotalTimeo < timeo)
|
||||
{
|
||||
(void)fprintf(stderr, "TotalTimeo %d < timeo %u\n",
|
||||
TotalTimeo, timeo);
|
||||
usage(av[0]);
|
||||
}
|
||||
|
||||
} /* End getopt block */
|
||||
|
||||
/*
|
||||
* initialize logger
|
||||
*/
|
||||
(void) openulog(ubasename(av[0]),
|
||||
(LOG_CONS|LOG_PID), LOG_LDM, logfname);
|
||||
unotice("Starting Up: %s: %s",
|
||||
remote,
|
||||
s_prod_class(NULL, 0, &clss));
|
||||
|
||||
/*
|
||||
* register exit handler
|
||||
*/
|
||||
if(atexit(cleanup) != 0)
|
||||
{
|
||||
serror("atexit");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* set up signal handlers
|
||||
*/
|
||||
set_sigactions();
|
||||
|
||||
|
||||
/*
|
||||
* Try forever.
|
||||
*/
|
||||
while (exitIfDone(0))
|
||||
{
|
||||
clssp = &clss;
|
||||
status = forn5(FEEDME, remote, &clssp,
|
||||
timeo, TotalTimeo, feedmeprog_5);
|
||||
|
||||
(void)exitIfDone(0);
|
||||
|
||||
switch(status) {
|
||||
/* problems with remote, retry */
|
||||
case ECONNABORTED:
|
||||
case ECONNRESET:
|
||||
case ETIMEDOUT:
|
||||
case ECONNREFUSED:
|
||||
(void)sleep(interval);
|
||||
break;
|
||||
case 0:
|
||||
/* assert(done); */
|
||||
break;
|
||||
default:
|
||||
/* some wierd error */
|
||||
done = 1;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
# $Id: Makefile,v 1.1.2.3 2003/06/23 18:44:16 steve Exp $
|
||||
|
||||
include ../macros.make
|
||||
PROGRAM = ldmping
|
||||
include ../simple_program.make
|
||||
include ../rules.make
|
||||
include depends
|
|
@ -1,7 +0,0 @@
|
|||
ldmping.o: ../config/ldmconfig.h
|
||||
ldmping.o: ../protocol/h_clnt.h
|
||||
ldmping.o: ../protocol/ldm5.h
|
||||
ldmping.o: ../protocol/ldm5_clnt.h
|
||||
ldmping.o: ../protocol/timestamp.h
|
||||
ldmping.o: ../ulog/ulog.h
|
||||
ldmping.o: ldmping.c
|
|
@ -1,88 +0,0 @@
|
|||
'\"
|
||||
'\" $Header: /cvsroot/ldm/src/ldmping/ldmping.1,v 1.4.24.1 2009/06/18 16:10:57 steve Exp $
|
||||
.TH LDMPING 1 "$Date: 2009/06/18 16:10:57 $"
|
||||
.SH NAME
|
||||
ldmping - check if ldm server is running
|
||||
.SH "UNIX SYNOPSIS"
|
||||
\fBldmping \fR[\fB\-x\fR] [\fB\-v\fR|\fB\-q\fR] [\fB\-l \fIlogfile\fR]
|
||||
.BI [\-t timeout]
|
||||
.BI [\-i interval]
|
||||
.BI [\-h remote]
|
||||
.BI [remote ...]
|
||||
.SH DESCRIPTION
|
||||
|
||||
This program sends a RPC NULLPROC request to a list of LDM servers
|
||||
\fIremote ...\fR. The default behavior of the program changes depending
|
||||
on whether the program is invoked interactively or not. (This is determined
|
||||
by whether STDERR "isatty".)
|
||||
.LP
|
||||
This program is used as a simple check that an LDM server is running
|
||||
on a given host and that the server is responding to RPC calls, or to
|
||||
perform this check on a group of hosts.
|
||||
|
||||
.LP
|
||||
.SH OPTIONS
|
||||
.TP 8
|
||||
.B \-v
|
||||
Verbose flag.
|
||||
If the verbose flag is on, a log message is emitted on success as well
|
||||
as failure. If the program is invoked interactively, this is the default.
|
||||
.TP 8
|
||||
.B \-q
|
||||
Quiet, turn off verbose flag. Useful to override the default.
|
||||
.TP
|
||||
.BI \-l " logfile"
|
||||
The path name of a file to be used as the log file for the process. The
|
||||
default is to use standard error when interactive and syslogd(8) otherwise.
|
||||
To use syslogd from the command line, enter "ldmping remote >& /dev/null".
|
||||
.TP
|
||||
.BI \-t " timeout"
|
||||
Set the RPC timeout to this many seconds. The default is 10 seconds.
|
||||
.TP
|
||||
.BI \-i " interval"
|
||||
Set the polling interval to this many seconds. If non zero, the program
|
||||
will loop forever (until interrupted). If zero, the program tries each remote
|
||||
once, exiting with status 0 if all check out okay, otherwise exiting with
|
||||
status one (failure) when an error is encountered. The default polling interval
|
||||
is 25 when interactive and 0 otherwise.
|
||||
.TP
|
||||
.BI \-h " remote"
|
||||
Requests that that the LDM server on \fIremote\fR be pinged. Multiple remotes
|
||||
may be specified. A list of remotes may be also specified without using "-h".
|
||||
If no remotes are specified, defaults to "localhost".
|
||||
.TP
|
||||
.B \-x
|
||||
Requests that debugging information also be printed. (None in this program.)
|
||||
.SH OUTPUT FORMAT
|
||||
The report consists of 5 fields.
|
||||
.LP
|
||||
The first field is the state of the connection. The connection may be
|
||||
seen as climbing through various states to complete a transaction.
|
||||
The lowest state is NAMED, we have defined a service we wish to contact
|
||||
(the ldm via TCP at a given \fIremotehost\fR).
|
||||
The next state is ADDRESSED, meaning we were able to translate the
|
||||
hostname into an IP address. (Sometimes RPC problems are really nameservice
|
||||
problems.)
|
||||
The third state, PMAP_CLNTED, indicates that the RPC portmapper is up on
|
||||
the remote and the fourth, MAPPED, indicates that there is ldm service
|
||||
(program 300029) registered.
|
||||
The fifth state is H_CLNTED, indicating that we were able to make a
|
||||
TCP connection to the port handed us by the RPC portmapper. Presumably this
|
||||
is a connection to an ldm server.
|
||||
Finally, if the remote service responds to the RPC NULLPROC within the
|
||||
\fItimeout\fR interval, we mark it as RESPONDING.
|
||||
.LP
|
||||
The second field is the time elapsed in completing the call.
|
||||
Expect that the Elapsed is greater during the initial connection than
|
||||
during subsequent calls, since this time includes all the time taken
|
||||
to climb thru the states.
|
||||
.LP
|
||||
The third field is the TCP port number (returned by the RPC portmapper).
|
||||
.LP
|
||||
The fourth field is the remote host you specified.
|
||||
.LP
|
||||
If there is an RPC problem, the RPC status will be printed at the end of
|
||||
the line. Note that this status may apply to the RPC portmapper if the
|
||||
state is lower than CONNECTED.
|
||||
.SH "SEE ALSO"
|
||||
ldmd(1), ingestd(1), ulog(3), rpcinfo(1)
|
|
@ -1,263 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: ldmping.c,v 1.20.18.3 2007/04/05 21:41:58 steve Exp $ */
|
||||
|
||||
/*
|
||||
* pings remote host
|
||||
*/
|
||||
|
||||
#include "ldmconfig.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "h_clnt.h"
|
||||
#include "ldm5.h"
|
||||
#include "ldm5_clnt.h"
|
||||
#include "ulog.h"
|
||||
|
||||
|
||||
#define DEFAULT_INTERVAL 25
|
||||
#define DEFAULT_TIMEO 10
|
||||
|
||||
|
||||
/*
|
||||
* ping the remote
|
||||
*/
|
||||
static enum clnt_stat
|
||||
check_hstat(hcp, timeout)
|
||||
h_clnt *hcp ;
|
||||
int timeout ;
|
||||
{
|
||||
return nullproc5(hcp, timeout) ;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_label()
|
||||
{
|
||||
uinfo("%10s %10s %4s %-21s %s\n",
|
||||
"State",
|
||||
"Elapsed",
|
||||
"Port",
|
||||
"Remote_Host",
|
||||
"rpc_stat"
|
||||
) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_hstat(hcp)
|
||||
h_clnt *hcp ;
|
||||
{
|
||||
if(hcp->state == RESPONDING)
|
||||
uinfo("%10s %3ld.%06ld %4d %-11s %s\n",
|
||||
s_remote_state(hcp->state),
|
||||
hcp->elapsed.tv_sec, hcp->elapsed.tv_usec,
|
||||
hcp->port,
|
||||
hcp->remote,
|
||||
s_hclnt_sperrno(hcp)
|
||||
) ;
|
||||
else
|
||||
uerror("%10s %3ld.%06ld %4d %-11s %s\n",
|
||||
s_remote_state(hcp->state),
|
||||
hcp->elapsed.tv_sec, hcp->elapsed.tv_usec,
|
||||
hcp->port,
|
||||
hcp->remote,
|
||||
s_hclnt_sperrno(hcp)
|
||||
) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
usage(av0)
|
||||
char *av0 ; /* id string */
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"Usage: %s [options] [remote ...] \t\nOptions:\n", av0);
|
||||
(void)fprintf(stderr,
|
||||
"\t-v Verbose (default if interactive)\n") ;
|
||||
(void)fprintf(stderr,
|
||||
"\t-q Quiet (to shut up when interactive)\n") ;
|
||||
(void)fprintf(stderr,
|
||||
"\t-x Debug mode\n") ;
|
||||
(void)fprintf(stderr,
|
||||
"\t-l logfile Send log info to file (default stderr if interactive,\n") ;
|
||||
(void)fprintf(stderr,
|
||||
"\t else uses syslogd)\n") ;
|
||||
(void)fprintf(stderr,
|
||||
"\t-t timeout set RPC timeout to \"timeout\" seconds (default %d)\n",
|
||||
DEFAULT_TIMEO) ;
|
||||
fprintf(stderr,
|
||||
"\t-i interval Poll after \"interval\" secs (default %d when interactive,\n",
|
||||
DEFAULT_INTERVAL) ;
|
||||
(void)fprintf(stderr,
|
||||
"\t 0 => one trip otherwise)\n") ;
|
||||
(void)fprintf(stderr,
|
||||
"\t-h remote \"remote\" host to ping (default is localhost)\n") ;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(ac,av)
|
||||
int ac ;
|
||||
char *av[] ;
|
||||
{
|
||||
int verbose = 0 ;
|
||||
char *logfname = 0 ;
|
||||
int interval = 0 ;
|
||||
int timeo = DEFAULT_TIMEO ;
|
||||
const char *logident = ubasename(av[0]) ;
|
||||
int logoptions = (LOG_CONS|LOG_PID) ;
|
||||
int nremotes = 0 ;
|
||||
#define MAX_REMOTES 14 /* 2 * MAX_REMOTES + 3 < max_open_file_descriptors */
|
||||
h_clnt stats[MAX_REMOTES + 1] ;
|
||||
h_clnt *sp ;
|
||||
unsigned remotePort = LDM_PORT;
|
||||
|
||||
if(isatty(fileno(stderr)))
|
||||
{
|
||||
/* set interactive defaults */
|
||||
verbose = !0 ;
|
||||
logfname = "-" ;
|
||||
interval = DEFAULT_INTERVAL ;
|
||||
logident = "" ;
|
||||
logoptions = 0 ;
|
||||
}
|
||||
|
||||
{
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
extern char *optarg;
|
||||
int ch;
|
||||
int logmask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) |
|
||||
LOG_MASK(LOG_NOTICE)) ;
|
||||
|
||||
opterr = 1;
|
||||
|
||||
while ((ch = getopt(ac, av, "vxl:t:h:P:qi:")) != EOF)
|
||||
switch (ch) {
|
||||
case 'v':
|
||||
verbose = !0 ;
|
||||
break;
|
||||
case 'q':
|
||||
verbose = 0 ;
|
||||
break ;
|
||||
case 'x':
|
||||
logmask |= LOG_MASK(LOG_DEBUG) ;
|
||||
break;
|
||||
case 'l':
|
||||
logfname = optarg ;
|
||||
break;
|
||||
case 'h':
|
||||
if(nremotes > MAX_REMOTES)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Can't handle more than %d remotes\n", MAX_REMOTES) ;
|
||||
break ;
|
||||
}
|
||||
init_h_clnt(&stats[nremotes++], optarg,
|
||||
LDMPROG, FIVE, IPPROTO_TCP) ;
|
||||
break ;
|
||||
case 'P': {
|
||||
char* suffix = "";
|
||||
long port;
|
||||
|
||||
errno = 0;
|
||||
port = strtol(optarg, &suffix, 0);
|
||||
|
||||
if (0 != errno || 0 != *suffix ||
|
||||
0 >= port || 0xffff < port) {
|
||||
|
||||
(void)fprintf(stderr, "%s: invalid port %s\n",
|
||||
av[0], optarg);
|
||||
usage(av[0]);
|
||||
}
|
||||
|
||||
remotePort = (unsigned)port;
|
||||
|
||||
break;
|
||||
}
|
||||
case 't':
|
||||
timeo = atoi(optarg) ;
|
||||
if(timeo == 0 && *optarg != '0')
|
||||
{
|
||||
fprintf(stderr, "%s: invalid timeout %s", av[0], optarg) ;
|
||||
usage(av[0]) ;
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
interval = atoi(optarg) ;
|
||||
if(interval == 0 && *optarg != '0')
|
||||
{
|
||||
fprintf(stderr, "%s: invalid interval %s", av[0], optarg) ;
|
||||
usage(av[0]) ;
|
||||
}
|
||||
break ;
|
||||
case '?':
|
||||
usage(av[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
for(; nremotes < MAX_REMOTES && optind < ac ; nremotes++, optind++)
|
||||
{
|
||||
init_h_clnt(&stats[nremotes], av[optind],
|
||||
LDMPROG, FIVE, IPPROTO_TCP) ;
|
||||
}
|
||||
if(ac - optind > 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Can't handle more than %d remotes\n", MAX_REMOTES) ;
|
||||
}
|
||||
if(nremotes == 0)
|
||||
{
|
||||
init_h_clnt(&stats[nremotes++], "localhost",
|
||||
LDMPROG, FIVE, IPPROTO_TCP) ;
|
||||
}
|
||||
stats[nremotes].state = H_NONE ; /* terminator */
|
||||
|
||||
if(verbose)
|
||||
logmask |= LOG_MASK(LOG_INFO) ;
|
||||
(void) setulogmask(logmask) ;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize logger
|
||||
*/
|
||||
(void)openulog(logident, logoptions, LOG_LDM, logfname) ;
|
||||
|
||||
/*
|
||||
* set up signal handlers
|
||||
*/
|
||||
(void) signal(SIGPIPE, SIG_IGN) ;
|
||||
|
||||
if(verbose)
|
||||
print_label() ;
|
||||
|
||||
while(1)
|
||||
{
|
||||
for(sp = stats ; sp->state != H_NONE ; sp++)
|
||||
{
|
||||
check_hstat(sp, timeo) ;
|
||||
/* if not verbose, only report "significant" stuff */
|
||||
if(verbose || sp->elapsed.tv_sec > 1 || sp->state != RESPONDING)
|
||||
print_hstat(sp) ;
|
||||
if(interval == 0 && sp->state != RESPONDING)
|
||||
exit(1) ;
|
||||
}
|
||||
if(interval == 0)
|
||||
break ;
|
||||
sleep(interval) ;
|
||||
}
|
||||
|
||||
exit(0) ;
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
# This file contains make(1) macro definitions.
|
||||
|
||||
SHELL = /bin/sh
|
||||
INSTALL = cp
|
||||
YACC = yacc
|
||||
CC = c89
|
||||
RPCGEN = rpcgen
|
||||
AR = ar
|
||||
ARFLAGS = -cru
|
||||
RANLIB = ranlib
|
||||
|
||||
CFLAGS = -O -m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
|
||||
CONFIGURE_CPPFLAGS = -DNDEBUG
|
||||
GDBMLIB =
|
||||
CONFIGURE_LIBS =
|
||||
|
||||
LD_YACC =
|
||||
LD_GEN =
|
||||
|
||||
PACKAGE = ldm
|
||||
|
||||
prefix = /usr/local/ldm/ldm-6.8.0
|
||||
exec_prefix = $(prefix)
|
||||
ldmhome = /usr/local/ldm
|
||||
pq_dir = pq
|
||||
|
||||
PROGRAM = dummy_program
|
||||
HEADER = dummy_header
|
||||
ETC_FILE = dummy_etc_file
|
||||
MANUAL = dummy_manual
|
||||
|
||||
INCDIR = $(prefix)/include
|
||||
LIBDIR = $(exec_prefix)/lib
|
||||
BINDIR = $(exec_prefix)/bin
|
||||
ETCDIR = $(ldmhome)/etc
|
||||
MANDIR = $(prefix)/man
|
||||
# only used to update the release at the source site
|
||||
FTPDIR = /home/ftp/pub/ldm
|
||||
|
||||
# Manual pages:
|
||||
WHATIS = whatis
|
||||
# The following macro should be empty on systems that don't
|
||||
# allow users to create their own manual-page indexes.
|
||||
MAKEWHATIS_CMD =
|
||||
|
||||
LIBRARY = ../libldm.a
|
|
@ -1,46 +0,0 @@
|
|||
# This file contains make(1) macro definitions.
|
||||
|
||||
SHELL = /bin/sh
|
||||
INSTALL = cp
|
||||
YACC = @YACC@
|
||||
CC = @CC@
|
||||
RPCGEN = rpcgen
|
||||
AR = ar
|
||||
ARFLAGS = @ARFLAGS@
|
||||
RANLIB = @RANLIB@
|
||||
|
||||
CFLAGS = @CFLAGS@
|
||||
CONFIGURE_CPPFLAGS = @CPPFLAGS@
|
||||
GDBMLIB = @GDBMLIB@
|
||||
CONFIGURE_LIBS = @LIBS@
|
||||
|
||||
LD_YACC = @LD_YACC@
|
||||
LD_GEN = @LD_GEN@
|
||||
|
||||
PACKAGE = ldm
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = $(prefix)
|
||||
ldmhome = @LDMHOME@
|
||||
pq_dir = @PQ_DIR@
|
||||
|
||||
PROGRAM = dummy_program
|
||||
HEADER = dummy_header
|
||||
ETC_FILE = dummy_etc_file
|
||||
MANUAL = dummy_manual
|
||||
|
||||
INCDIR = $(prefix)/include
|
||||
LIBDIR = $(exec_prefix)/lib
|
||||
BINDIR = $(exec_prefix)/bin
|
||||
ETCDIR = $(ldmhome)/etc
|
||||
MANDIR = $(prefix)/man
|
||||
# only used to update the release at the source site
|
||||
FTPDIR = /home/ftp/pub/ldm
|
||||
|
||||
# Manual pages:
|
||||
WHATIS = @WHATIS@
|
||||
# The following macro should be empty on systems that don't
|
||||
# allow users to create their own manual-page indexes.
|
||||
MAKEWHATIS_CMD = @MAKEWHATIS_CMD@
|
||||
|
||||
LIBRARY = ../libldm.a
|
|
@ -1,72 +0,0 @@
|
|||
# $Id: Makefile,v 1.1.18.4 2005/06/24 21:05:18 steve Exp $
|
||||
#
|
||||
# Development Makefile for ldm library misc routines
|
||||
#
|
||||
include ../macros.make
|
||||
|
||||
INCLUDES = -I../config -I../ulog
|
||||
LIBRARY = ../libldm.a
|
||||
LINT_LIBRARY = misc
|
||||
HEADERS = \
|
||||
ldmalloc.h \
|
||||
alrm.h \
|
||||
error.h \
|
||||
fdnb.h \
|
||||
fsStats.h \
|
||||
inetutil.h \
|
||||
mkdirs_open.h \
|
||||
paths.h \
|
||||
pattern.h \
|
||||
RegularExpressions.h \
|
||||
rpcutil.h \
|
||||
setenv.h \
|
||||
statsMath.h
|
||||
LIB_CSRCS = \
|
||||
error.c \
|
||||
fdnb.c \
|
||||
fsStats.c \
|
||||
inetutil.c \
|
||||
mkdirs_open.c \
|
||||
pattern.c \
|
||||
RegularExpressions.c \
|
||||
rpcutil.c \
|
||||
setenv.c \
|
||||
statsMath.c \
|
||||
StringBuf.c
|
||||
TAG_SRCS = ../ulog/*.c ../ulog/*.h
|
||||
PACKING_LIST = \
|
||||
depends \
|
||||
Makefile \
|
||||
ldmalloc.h \
|
||||
alrm.h \
|
||||
depends \
|
||||
error.c \
|
||||
error.h \
|
||||
fdnb.c \
|
||||
fdnb.h \
|
||||
fsStats.c \
|
||||
fsStats.h \
|
||||
inetutil.c \
|
||||
inetutil.h \
|
||||
mkdirs_open.c \
|
||||
mkdirs_open.h \
|
||||
paths.h \
|
||||
pattern.h \
|
||||
pattern.c \
|
||||
RegularExpressions.c \
|
||||
RegularExpressions.h \
|
||||
rpcutil.c \
|
||||
rpcutil.h \
|
||||
setenv.c \
|
||||
setenv.h \
|
||||
statsMath.c \
|
||||
statsMath.h \
|
||||
StringBuf.c \
|
||||
StringBuf.h
|
||||
|
||||
all: archived_files
|
||||
|
||||
lint: llib-l$(LINT_LIBRARY).ln
|
||||
|
||||
include ../rules.make
|
||||
include depends
|
|
@ -1,57 +0,0 @@
|
|||
/* $Id: RegularExpressions.c,v 1.1.2.1 2005/01/26 21:38:35 steve Exp $ */
|
||||
|
||||
#include "ldmconfig.h"
|
||||
|
||||
#include "RegularExpressions.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* Indicates if a regular-expression specification is pathological or not.
|
||||
* Pathological specifications are longer than two characters and have
|
||||
* a ".*" prefix.
|
||||
*
|
||||
* Arguments:
|
||||
* spec Pointer to 0-terminated regular expression specification.
|
||||
*
|
||||
* Returns:
|
||||
* 0 Specification is not pathological.
|
||||
* 1 Specification is pathological.
|
||||
*/
|
||||
int
|
||||
re_isPathological(
|
||||
const char* const spec)
|
||||
{
|
||||
return strlen(spec) > 2 && (0 == strncmp(".*", spec, 2));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Vets a regular-expression specification. Converts pathological
|
||||
* specifications (ones with a ".*" prefix) to non-pathological ones.
|
||||
*
|
||||
* Arguments:
|
||||
* spec Pointer to 0-terminated regular expression specification.
|
||||
* Must not be NULL.
|
||||
*
|
||||
* Returns:
|
||||
* 0 Specification was not adjusted.
|
||||
* 1 Specification was adjusted.
|
||||
*/
|
||||
int
|
||||
re_vetSpec(
|
||||
char* const spec)
|
||||
{
|
||||
int wasConverted = 0;
|
||||
size_t len = strlen(spec);
|
||||
|
||||
while (len > 2 && (0 == strncmp(".*", spec, 2))) {
|
||||
(void)memmove(spec, spec+2, len-1);
|
||||
|
||||
len -= 2;
|
||||
wasConverted = 1;
|
||||
}
|
||||
|
||||
return wasConverted;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef REGULAR_EXPRESSIONS_H
|
||||
#define REGULAR_EXPRESSIONS_H
|
||||
|
||||
|
||||
/*
|
||||
* Indicates if a regular-expression specification is pathological or not.
|
||||
* Pathological specifications are longer than two characters and have
|
||||
* a ".*" prefix.
|
||||
*
|
||||
* Arguments:
|
||||
* spec Pointer to 0-terminated regular expression specification.
|
||||
*
|
||||
* Returns:
|
||||
* 0 Specification is not pathological.
|
||||
* 1 Specification is pathological.
|
||||
*/
|
||||
int
|
||||
re_isPathological(
|
||||
const char* const spec);
|
||||
|
||||
|
||||
/*
|
||||
* Vets a regular-expression specification. Converts pathological
|
||||
* specifications (ones with a ".*" prefix) to non-pathological ones.
|
||||
*
|
||||
* Arguments:
|
||||
* spec Pointer to 0-terminated regular expression specification.
|
||||
* Must not be NULL.
|
||||
*
|
||||
* Returns:
|
||||
* 0 Specification was not adjusted.
|
||||
* 1 Specification was adjusted.
|
||||
*/
|
||||
int
|
||||
re_vetSpec(
|
||||
char* const spec);
|
||||
|
||||
#endif
|
|
@ -1,221 +0,0 @@
|
|||
#include "ldmconfig.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "StringBuf.h"
|
||||
|
||||
|
||||
struct StringBuf {
|
||||
char* buf;
|
||||
size_t len;
|
||||
size_t max;
|
||||
int errCode;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Returns an allocated StringBuf.
|
||||
*
|
||||
* Arguments:
|
||||
* initMax Initial capacity of the StringBuf, in characters,
|
||||
* excluding any terminating NUL.
|
||||
* Returns:
|
||||
* NULL Failure.
|
||||
* else Pointer to an allocated StringBuf.
|
||||
*/
|
||||
StringBuf*
|
||||
strBuf_new(
|
||||
size_t initMax )
|
||||
{
|
||||
StringBuf* strBuf = (StringBuf*)malloc(sizeof(StringBuf));
|
||||
|
||||
if (NULL != strBuf) {
|
||||
char* buf = (char*)malloc(initMax+1);
|
||||
|
||||
if (NULL == buf) {
|
||||
free(strBuf);
|
||||
strBuf = NULL;
|
||||
}
|
||||
else {
|
||||
*buf = 0;
|
||||
strBuf->buf = buf;
|
||||
strBuf->len = 0;
|
||||
strBuf->max = initMax;
|
||||
strBuf->errCode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return strBuf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Appends a string to the contents of a StringBuf. If the StringBuf is valid
|
||||
* and the string cannot be appended, then the StringBuf is rendered invalid.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf Pointer to the StringBuf or NULL.
|
||||
* string String to be appended. Caller may free upon return.
|
||||
* Returns:
|
||||
* 0 Success.
|
||||
* EINVAL "strBuf" is NULL or "*strBuf" is invalid.
|
||||
* ENOMEM Out-of-memory.
|
||||
*/
|
||||
int
|
||||
strBuf_appendString(
|
||||
StringBuf* const strBuf,
|
||||
const char* const string)
|
||||
{
|
||||
int errCode = 0; /* success */
|
||||
|
||||
if (NULL == strBuf) {
|
||||
errCode = EINVAL;
|
||||
}
|
||||
else {
|
||||
if (0 != strBuf->errCode) {
|
||||
errCode = EINVAL;
|
||||
}
|
||||
else {
|
||||
size_t len = strlen(string);
|
||||
size_t newLen = strBuf->len + len;
|
||||
|
||||
if (newLen > strBuf->max) {
|
||||
size_t newMax = (size_t)(1.618034*newLen + 0.5);
|
||||
char* newBuf = (char*)realloc(strBuf->buf, newMax+1);
|
||||
|
||||
if (NULL == newBuf) {
|
||||
strBuf->errCode = errno;
|
||||
errCode = ENOMEM;
|
||||
}
|
||||
else {
|
||||
strBuf->buf = newBuf;
|
||||
strBuf->max = newMax;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == errCode) {
|
||||
(void)strcpy(strBuf->buf+strBuf->len, string);
|
||||
|
||||
strBuf->len += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errCode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clears a StringBuf. On success, a subsequent strBuf_toString() will return
|
||||
* the empty string.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf Pointer to the StringBuf to be cleared.
|
||||
* Returns:
|
||||
* 0 Success.
|
||||
* EINVAL "strBuf" is NULL or "*strBuf" is invalid.
|
||||
*/
|
||||
int
|
||||
strBuf_clear(
|
||||
StringBuf* const strBuf)
|
||||
{
|
||||
int errCode;
|
||||
|
||||
if (NULL == strBuf || 0 != strBuf->errCode) {
|
||||
errCode = EINVAL;
|
||||
}
|
||||
else {
|
||||
strBuf->buf[0] = 0;
|
||||
strBuf->len = 0;
|
||||
errCode = 0;
|
||||
}
|
||||
|
||||
return errCode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sets a StringBuf to a string.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf Pointer to the StringBuf.
|
||||
* string Pointer to the string to which "strBuf" will be set.
|
||||
* Caller may free upon return.
|
||||
* Returns:
|
||||
* 0 Success.
|
||||
* EINVAL "strBuf" is NULL or "*strBuf" is invalid.
|
||||
* ENOMEM Out-of-memory.
|
||||
*/
|
||||
int
|
||||
strBuf_setToString(
|
||||
StringBuf* const strBuf,
|
||||
const char* const string)
|
||||
{
|
||||
int errCode = strBuf_clear(strBuf);
|
||||
|
||||
if (0 == errCode)
|
||||
errCode = strBuf_appendString(strBuf, string);
|
||||
|
||||
return errCode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the contents of a StringBuf as a NUL-terminated string.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf Pointer to the StringBuf.
|
||||
* Returns:
|
||||
* NULL "strBuf" is NULL or "*strbuf" is invalid.
|
||||
* else The contents of "strBuf" as a NUL-terminated string.
|
||||
*/
|
||||
const char*
|
||||
strBuf_toString(
|
||||
const StringBuf* const strBuf)
|
||||
{
|
||||
return
|
||||
NULL == strBuf || 0 != strBuf->errCode
|
||||
? NULL
|
||||
: strBuf->buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns an error-message string corresponding to the state of a StringBuf.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf Pointer to the StringBuf. It must have been returned by
|
||||
* strBuf_new().
|
||||
* Returns:
|
||||
* Pointer to a string describing the state of "strBuf".
|
||||
*/
|
||||
const char*
|
||||
strBuf_strerror(
|
||||
const StringBuf* const strBuf)
|
||||
{
|
||||
return
|
||||
NULL == strBuf
|
||||
? "The StringBuf couldn't be allocated: out-of-memory"
|
||||
: 0 == strBuf->errCode
|
||||
? "No error"
|
||||
: strerror(strBuf->errCode);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Releases any resouces associated with a StringBuf.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf Pointer to the StringBuf or NULL.
|
||||
*/
|
||||
void
|
||||
strBuf_free(
|
||||
StringBuf* const strBuf)
|
||||
{
|
||||
if (NULL != strBuf) {
|
||||
free(strBuf->buf);
|
||||
free(strBuf);
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
#ifndef STRING_BUF_H
|
||||
#define STRING_BUF_H
|
||||
|
||||
|
||||
typedef struct StringBuf StringBuf;
|
||||
|
||||
|
||||
/*
|
||||
* Returns an allocated StringBuf.
|
||||
*
|
||||
* Arguments:
|
||||
* initMax Initial capacity of the StringBuf, in characters,
|
||||
* excluding any terminating NUL.
|
||||
* Returns:
|
||||
* NULL Failure.
|
||||
* else Pointer to an allocated StringBuf.
|
||||
*/
|
||||
StringBuf*
|
||||
strBuf_new(
|
||||
size_t initMax );
|
||||
|
||||
|
||||
/*
|
||||
* Appends a string to the contents of a StringBuf. If the StringBuf is valid
|
||||
* and the string cannot be appended, then the StringBuf is rendered invalid.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf Pointer to a StringBuf or NULL.
|
||||
* string String to be appended.
|
||||
* Returns:
|
||||
* 0 Success.
|
||||
* EINVAL "strBuf" is NULL or "*strBuf" is invalid.
|
||||
* ENOMEM Out-of-memory.
|
||||
*/
|
||||
int
|
||||
strBuf_appendString(
|
||||
StringBuf* const strBuf,
|
||||
const char* const string);
|
||||
|
||||
|
||||
/*
|
||||
* Clears a StringBuf. On success, a subsequent strBuf_toString() will return
|
||||
* the empty string.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf Pointer to the StringBuf to be cleared.
|
||||
* Returns:
|
||||
* 0 Success.
|
||||
* EINVAL "strBuf" is NULL or "*strBuf" is invalid.
|
||||
*/
|
||||
int
|
||||
strBuf_clear(
|
||||
StringBuf* const strBuf);
|
||||
|
||||
|
||||
/*
|
||||
* Sets a StringBuf to a string.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf Pointer to the StringBuf.
|
||||
* string Pointer to the string to which "strBuf" will be set.
|
||||
* Caller may free upon return.
|
||||
* Returns:
|
||||
* 0 Success.
|
||||
* EINVAL "strBuf" is NULL or "*strBuf" is invalid.
|
||||
* ENOMEM Out-of-memory.
|
||||
*/
|
||||
int
|
||||
strBuf_setToString(
|
||||
StringBuf* const strBuf,
|
||||
const char* const string);
|
||||
|
||||
|
||||
/*
|
||||
* Returns the contents of a StringBuf as a NUL-terminated string.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf The StringBuf.
|
||||
* Returns:
|
||||
* NULL "strBuf" is NULL or "*strbuf" is invalid.
|
||||
* else The contents of "strBuf" as a NUL-terminated string.
|
||||
*/
|
||||
const char*
|
||||
strBuf_toString(
|
||||
const StringBuf* const strBuf);
|
||||
|
||||
|
||||
/*
|
||||
* Returns an error-message string corresponding to the state of a StringBuf.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf The StringBuf. It must have been returned by a
|
||||
* previous call to strBuf_new().
|
||||
* Returns:
|
||||
* Pointer to a string describing the state of "strBuf".
|
||||
*/
|
||||
const char*
|
||||
strBuf_strerror(
|
||||
const StringBuf* const strBuf);
|
||||
|
||||
|
||||
/*
|
||||
* Releases any resouces associated with a StringBuf.
|
||||
*
|
||||
* Arguments:
|
||||
* strBuf Point to the SringBuf or NULL.
|
||||
*/
|
||||
void
|
||||
strBuf_free(
|
||||
StringBuf* const strBuf);
|
||||
|
||||
|
||||
#endif
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: alrm.h,v 1.10.18.2 2005/06/24 21:05:18 steve Exp $ */
|
||||
|
||||
#ifndef ALRM_H
|
||||
#define ALRM_H
|
||||
|
||||
/*
|
||||
* Careful alarm interface
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
/*
|
||||
* implement a signal function with known,
|
||||
* desired characteristics. -Stevens
|
||||
*/
|
||||
#if defined(__STDC__)
|
||||
typedef void Sigfunc(int) ;
|
||||
#else
|
||||
typedef void Sigfunc() ;
|
||||
#endif
|
||||
|
||||
static Sigfunc *
|
||||
mysignal(int signo, Sigfunc *handler)
|
||||
{
|
||||
struct sigaction sigact, oact ;
|
||||
|
||||
sigact.sa_handler = handler ;
|
||||
sigemptyset(&sigact.sa_mask) ;
|
||||
sigact.sa_flags = 0 ;
|
||||
|
||||
/* Don't restart after alarms */
|
||||
#ifdef SA_INTERRUPT /* SunOS 4.x */
|
||||
sigact.sa_flags |= SA_INTERRUPT ;
|
||||
#endif
|
||||
|
||||
if(sigaction(signo, &sigact, &oact) == -1)
|
||||
return(SIG_ERR) ;
|
||||
/* else */
|
||||
return (oact.sa_handler) ;
|
||||
}
|
||||
|
||||
|
||||
/* set when the jmp_buf is valid */
|
||||
static volatile sig_atomic_t validJmpbuf = 0 ;
|
||||
static sigjmp_buf env ;
|
||||
static Sigfunc *sav_handler = SIG_ERR ;
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
alrm_handler(int sig)
|
||||
{
|
||||
if(!validJmpbuf)
|
||||
{
|
||||
/* TODO: something rational */
|
||||
return ;
|
||||
}
|
||||
/* else, safe to do the jump */
|
||||
validJmpbuf = 0 ;
|
||||
(void) siglongjmp(env, 1) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Safe to call even when set_alarm()
|
||||
* has not been called
|
||||
*/
|
||||
#define CLR_ALRM() \
|
||||
{ \
|
||||
(void) alarm(0) ; \
|
||||
if(sav_handler != SIG_ERR) \
|
||||
{ \
|
||||
(void) mysignal(SIGALRM, sav_handler) ; \
|
||||
sav_handler = SIG_ERR ; \
|
||||
} \
|
||||
validJmpbuf = 0 ; \
|
||||
}
|
||||
|
||||
|
||||
#define SET_ALARM(seconds, jumplabel) \
|
||||
{ \
|
||||
if( sigsetjmp(env, 1) ) \
|
||||
{ \
|
||||
/* \
|
||||
* Result of a signal_handler call to siglongjmp(). \
|
||||
*/ \
|
||||
if(sav_handler != SIG_ERR) \
|
||||
{ \
|
||||
(void) mysignal(SIGALRM, sav_handler) ; \
|
||||
sav_handler = SIG_ERR ; \
|
||||
} \
|
||||
goto jumplabel ; \
|
||||
} \
|
||||
/* else, first time, we set the jmp env */ \
|
||||
validJmpbuf = 1 ; \
|
||||
\
|
||||
sav_handler = mysignal(SIGALRM, alrm_handler) ; \
|
||||
if(sav_handler == SIG_ERR) \
|
||||
{ \
|
||||
validJmpbuf = 0 ; \
|
||||
} else { \
|
||||
(void) alarm((unsigned)(seconds)) ; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* ALRM_H */
|
|
@ -1,56 +0,0 @@
|
|||
RegularExpressions.o: ../config/ldmconfig.h
|
||||
RegularExpressions.o: RegularExpressions.c
|
||||
RegularExpressions.o: RegularExpressions.h
|
||||
SkipList..o: SkipList..c
|
||||
SkipList..o: SkipList.h
|
||||
StringBuf.o: StringBuf.c
|
||||
StringBuf.o: StringBuf.h
|
||||
error.o: ../config/ldmconfig.h
|
||||
error.o: ../ulog/ulog.h
|
||||
error.o: error.c
|
||||
error.o: error.h
|
||||
errorTest.o: ../ulog/ulog.h
|
||||
errorTest.o: error.h
|
||||
errorTest.o: errorTest.c
|
||||
fdnb.o: ../config/ldmconfig.h
|
||||
fdnb.o: ../ulog/ulog.h
|
||||
fdnb.o: fdnb.c
|
||||
fdnb.o: fdnb.h
|
||||
foo.o: foo.c
|
||||
fsStats.o: ../config/ldmconfig.h
|
||||
fsStats.o: fsStats.c
|
||||
fsStats.o: fsStats.h
|
||||
inetutil.o: ../config/ldmconfig.h
|
||||
inetutil.o: ../ulog/ulog.h
|
||||
inetutil.o: inetutil.c
|
||||
inetutil.o: inetutil.h
|
||||
mkdirs_open.o: ../config/ldmconfig.h
|
||||
mkdirs_open.o: mkdirs_open.c
|
||||
mkdirs_open.o: mkdirs_open.h
|
||||
mysem.o: mysem.c
|
||||
pattern.o: ../config/ldmconfig.h
|
||||
pattern.o: RegularExpressions.h
|
||||
pattern.o: error.h
|
||||
pattern.o: pattern.c
|
||||
pattern.o: pattern.h
|
||||
rpcutil.o: ../config/ldmconfig.h
|
||||
rpcutil.o: ../rpc/auth.h
|
||||
rpcutil.o: ../rpc/auth_unix.h
|
||||
rpcutil.o: ../rpc/clnt.h
|
||||
rpcutil.o: ../rpc/pmap_clnt.h
|
||||
rpcutil.o: ../rpc/pmap_prot.h
|
||||
rpcutil.o: ../rpc/rpc.h
|
||||
rpcutil.o: ../rpc/rpc_msg.h
|
||||
rpcutil.o: ../rpc/svc.h
|
||||
rpcutil.o: ../rpc/svc_auth.h
|
||||
rpcutil.o: ../rpc/types.h
|
||||
rpcutil.o: ../rpc/xdr.h
|
||||
rpcutil.o: ../ulog/ulog.h
|
||||
rpcutil.o: inetutil.h
|
||||
rpcutil.o: rpcutil.c
|
||||
rpcutil.o: rpcutil.h
|
||||
setenv.o: ../config/ldmconfig.h
|
||||
setenv.o: setenv.c
|
||||
setenv.o: setenv.h
|
||||
statsMath.o: statsMath.c
|
||||
statsMath.o: statsMath.h
|
|
@ -1,265 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: error.c,v 1.10.2.3.6.6 2006/12/17 22:06:26 steve Exp $ */
|
||||
|
||||
#include <ldmconfig.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h> /* NULL */
|
||||
#include <stdio.h> /* vsnprintf(), snprintf() */
|
||||
#include <stdlib.h> /* malloc(), free(), abort() */
|
||||
#include <string.h>
|
||||
#include <strings.h> /* strdup() */
|
||||
|
||||
#include "ulog.h"
|
||||
|
||||
#include "error.h"
|
||||
|
||||
|
||||
struct error {
|
||||
char msg[512];
|
||||
ErrorObj* cause;
|
||||
const char* file;
|
||||
size_t msglen;
|
||||
int code;
|
||||
unsigned line;
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Public API:
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
ErrorObj* err_new(
|
||||
const int code,
|
||||
ErrorObj *const cause,
|
||||
const char *const file,
|
||||
const unsigned line,
|
||||
const char *const fmt,
|
||||
...)
|
||||
{
|
||||
ErrorObj *err;
|
||||
|
||||
assert(file != NULL);
|
||||
|
||||
err = (ErrorObj*)malloc(sizeof(ErrorObj));
|
||||
|
||||
if (NULL == err) {
|
||||
serror("err_new(): malloc(%lu) failure",
|
||||
(unsigned long)sizeof(ErrorObj));
|
||||
}
|
||||
else {
|
||||
char *cp = err->msg;
|
||||
int len = 0;
|
||||
|
||||
err->line = line;
|
||||
err->file = file;
|
||||
|
||||
if (NULL == fmt) {
|
||||
err->msg[0] = 0;
|
||||
err->msglen = 0;
|
||||
err->code = code;
|
||||
err->cause = cause;
|
||||
}
|
||||
else {
|
||||
va_list args;
|
||||
int nbytes;
|
||||
|
||||
va_start(args, fmt);
|
||||
|
||||
nbytes = vsnprintf(err->msg, sizeof(err->msg)-1, fmt, args);
|
||||
if (nbytes < 0) {
|
||||
nbytes = snprintf(err->msg, sizeof(err->msg)-1,
|
||||
"err_new(): vsnprintf() failure: \"%s\"", fmt);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
err->msg[sizeof(err->msg)-1] = 0;
|
||||
err->msglen = (size_t)nbytes;
|
||||
|
||||
assert(err->msglen < sizeof(err->msg));
|
||||
|
||||
err->code = code;
|
||||
err->cause = cause;
|
||||
}
|
||||
} /* "err" allocated */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
err_code(const ErrorObj* err)
|
||||
{
|
||||
assert(err != NULL);
|
||||
|
||||
return err->code;
|
||||
}
|
||||
|
||||
|
||||
ErrorObj*
|
||||
err_cause(const ErrorObj *err)
|
||||
{
|
||||
assert(err != NULL);
|
||||
|
||||
return err->cause;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
err_message(const ErrorObj *err)
|
||||
{
|
||||
return err->msg;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is not re-entrant because it contains static variables that are
|
||||
* potentially modified on every invocation.
|
||||
*/
|
||||
void err_log(
|
||||
const ErrorObj *const err,
|
||||
const enum err_level level)
|
||||
{
|
||||
static const unsigned logMasks[] = {
|
||||
LOG_MASK(LOG_ERR),
|
||||
LOG_MASK(LOG_WARNING),
|
||||
LOG_MASK(LOG_NOTICE),
|
||||
LOG_MASK(LOG_INFO),
|
||||
LOG_MASK(LOG_DEBUG)
|
||||
};
|
||||
|
||||
if (getulogmask() & logMasks[level]) {
|
||||
const ErrorObj* e;
|
||||
const char* const stdErrSep = "; ";
|
||||
const char* const stdLocSep = ": ";
|
||||
const char* errSep;
|
||||
const char* locSep;
|
||||
|
||||
static char initialBuf[1024];
|
||||
static char* buf = initialBuf;
|
||||
static size_t buflen = sizeof(initialBuf);
|
||||
static const int pris[] =
|
||||
{LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG};
|
||||
|
||||
assert(err != NULL);
|
||||
|
||||
{
|
||||
size_t totlen = 0;
|
||||
|
||||
errSep = "";
|
||||
|
||||
for (e = err; e != NULL; e = e->cause) {
|
||||
totlen += strlen(errSep);
|
||||
|
||||
errSep = "";
|
||||
|
||||
if (ERR_DEBUG != level) {
|
||||
locSep = "";
|
||||
}
|
||||
else {
|
||||
totlen += sprintf(buf, "%s@%u", e->file, e->line);
|
||||
locSep = stdLocSep;
|
||||
errSep = stdErrSep;
|
||||
}
|
||||
|
||||
if (0 < e->msglen) {
|
||||
totlen += strlen(locSep) + e->msglen;
|
||||
errSep = stdErrSep;
|
||||
}
|
||||
}
|
||||
|
||||
totlen++; /* + '\0' */
|
||||
|
||||
if (NULL == buf) {
|
||||
buf = (char*)malloc(totlen);
|
||||
buflen = totlen;
|
||||
}
|
||||
else if (totlen > buflen) {
|
||||
if (buf != initialBuf)
|
||||
free(buf);
|
||||
|
||||
buf = (char*)malloc(totlen);
|
||||
buflen = totlen;
|
||||
}
|
||||
|
||||
assert(NULL != buf);
|
||||
}
|
||||
|
||||
{
|
||||
char *cp = buf;
|
||||
|
||||
errSep = "";
|
||||
|
||||
for (e = err; e != NULL; e = e->cause) {
|
||||
(void)strcpy(cp, errSep);
|
||||
cp += strlen(errSep);
|
||||
|
||||
errSep = "";
|
||||
|
||||
if (ERR_DEBUG != level) {
|
||||
locSep = "";
|
||||
}
|
||||
else {
|
||||
cp += sprintf(cp, "%s@%u", e->file, e->line);
|
||||
locSep = stdLocSep;
|
||||
errSep = stdErrSep;
|
||||
}
|
||||
|
||||
if (0 < e->msglen) {
|
||||
(void)strcpy(cp, locSep);
|
||||
cp += strlen(locSep);
|
||||
|
||||
(void)memcpy(cp, e->msg, e->msglen);
|
||||
cp += e->msglen;
|
||||
|
||||
errSep = stdErrSep;
|
||||
}
|
||||
}
|
||||
|
||||
*cp = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NB: The message is not printed using "ulog(pris[level], buf)"
|
||||
* because "buf" might have formatting characters in it (e.g., "%")
|
||||
* from, for example, a call to "s_prod_info()" with a dangerous
|
||||
* product-identifier.
|
||||
*/
|
||||
ulog(pris[level], "%s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void err_free(ErrorObj *const err)
|
||||
{
|
||||
if (err != NULL) {
|
||||
if (err->cause != NULL)
|
||||
err_free(err->cause);
|
||||
|
||||
free((void*)err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Logs the error and then frees it. This function is equivalent to
|
||||
* err_log(err);
|
||||
* err_free(err);
|
||||
*
|
||||
* Arguments:
|
||||
* err The error.
|
||||
* level The logging level.
|
||||
*/
|
||||
void err_log_and_free(
|
||||
ErrorObj *const err,
|
||||
const enum err_level level)
|
||||
{
|
||||
err_log(err, level);
|
||||
err_free(err);
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: error.h,v 1.2.2.3.6.5 2006/10/19 19:27:04 steve Exp $ */
|
||||
|
||||
#ifndef ERROR_H
|
||||
#define ERROR_H
|
||||
|
||||
typedef struct error ErrorObj; /* defined in error.c */
|
||||
|
||||
|
||||
enum err_level {
|
||||
ERR_FAILURE,
|
||||
ERR_ERROR = ERR_FAILURE,
|
||||
ERR_WARNING,
|
||||
ERR_NOTICE,
|
||||
ERR_INFO,
|
||||
ERR_DEBUG
|
||||
};
|
||||
|
||||
|
||||
#define ERR_NEW(code, cause, msg) err_new(code, cause, __FILE__, __LINE__, msg)
|
||||
#define ERR_NEW0 ERR_NEW
|
||||
#define ERR_NEW1(code, cause, fmt, a1) \
|
||||
err_new(code, cause, __FILE__, __LINE__, fmt, a1)
|
||||
#define ERR_NEW2(code, cause, fmt, a1, a2) \
|
||||
err_new(code, cause, __FILE__, __LINE__, fmt, a1, a2)
|
||||
#define ERR_NEW3(code, cause, fmt, a1, a2, a3) \
|
||||
err_new(code, cause, __FILE__, __LINE__, fmt, a1, a2, a3)
|
||||
#define ERR_NEW4(code, cause, fmt, a1, a2, a3, a4) \
|
||||
err_new(code, cause, __FILE__, __LINE__, fmt, a1, a2, a3, a4)
|
||||
#define ERR_NEW5(code, cause, fmt, a1, a2, a3, a4, a5) \
|
||||
err_new(code, cause, __FILE__, __LINE__, fmt, a1, a2, a3, a4, a5)
|
||||
|
||||
|
||||
ErrorObj*
|
||||
err_new(
|
||||
const int code,
|
||||
ErrorObj* cause,
|
||||
const char* file,
|
||||
const unsigned line,
|
||||
const char* fmt,
|
||||
...);
|
||||
|
||||
int
|
||||
err_code(
|
||||
const ErrorObj *err);
|
||||
|
||||
ErrorObj*
|
||||
err_cause(
|
||||
const ErrorObj *err);
|
||||
|
||||
const char*
|
||||
err_message(
|
||||
const ErrorObj *err);
|
||||
|
||||
void
|
||||
err_log(
|
||||
const ErrorObj *err,
|
||||
enum err_level level);
|
||||
|
||||
void
|
||||
err_free(
|
||||
ErrorObj *err);
|
||||
|
||||
void
|
||||
err_log_and_free(
|
||||
ErrorObj *err,
|
||||
enum err_level level);
|
||||
|
||||
#endif
|
|
@ -1,51 +0,0 @@
|
|||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "ulog.h"
|
||||
|
||||
int
|
||||
main(int argc, char* args[])
|
||||
{
|
||||
int status;
|
||||
if (openulog("errorTest", LOG_PID, 0, "-") == -1) {
|
||||
perror("openulog()");
|
||||
|
||||
status = 1;
|
||||
}
|
||||
else {
|
||||
ErrorObj* err;
|
||||
|
||||
(void)setulogmask(LOG_UPTO(LOG_DEBUG));
|
||||
|
||||
err = ERR_NEW(0, NULL, "Simple message");
|
||||
err_log(err, ERR_ERROR);
|
||||
err_free(err);
|
||||
|
||||
err = ERR_NEW(
|
||||
0,
|
||||
ERR_NEW(1, NULL, "Nested message 2"),
|
||||
"Nested message 1");
|
||||
err_log(err, ERR_ERROR);
|
||||
err_free(err);
|
||||
|
||||
err =
|
||||
ERR_NEW(
|
||||
0,
|
||||
ERR_NEW1(
|
||||
1,
|
||||
ERR_NEW1(2, NULL, "Nested message 3: %s",
|
||||
strerror(ENOMEM)),
|
||||
"Nested message 2: %d",
|
||||
INT_MAX),
|
||||
"Nested message 1");
|
||||
err_log(err, ERR_DEBUG);
|
||||
err_free(err);
|
||||
|
||||
status = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: fdnb.c,v 1.5 2002/12/09 18:23:56 steve Exp $ */
|
||||
|
||||
#include <ldmconfig.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include "ulog.h"
|
||||
#include "fdnb.h"
|
||||
|
||||
/* some systems have FNDELAY (== O_NDELAY) different from O_NONBLOCK */
|
||||
#if defined(__ultrix) || defined(ultrix)
|
||||
/* ultrix 4.3 (and before?) */
|
||||
/* #define NB_O_NONBLOCK (FNDELAY | O_NONBLOCK) */
|
||||
#define NB_O_NONBLOCK FNDELAY
|
||||
#endif
|
||||
/* default do like posix sez */
|
||||
#ifndef NB_O_NONBLOCK
|
||||
#define NB_O_NONBLOCK O_NONBLOCK
|
||||
#endif
|
||||
/*
|
||||
* Set descriptor for non blocking
|
||||
* return 1 if changed, 0 otherwise.
|
||||
*/
|
||||
int
|
||||
set_fd_nonblock(int fd)
|
||||
{
|
||||
unsigned flags = (unsigned)fcntl(fd, F_GETFL, 0);
|
||||
|
||||
if(flags == (unsigned)-1)
|
||||
{
|
||||
serror("fcntl(..., F_GETFL,)");
|
||||
return 0;
|
||||
}
|
||||
/* else */
|
||||
|
||||
if(flags & NB_O_NONBLOCK)
|
||||
return 0; /* no change required */
|
||||
/* else */
|
||||
|
||||
flags |= NB_O_NONBLOCK;
|
||||
if(fcntl(fd, F_SETFL, (int)flags) == -1)
|
||||
{
|
||||
serror("fcntl(..., F_SETFL, O_NONBLOCK)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* clear descriptor for non blocking
|
||||
* (EG, set to blocking)
|
||||
* return 1 if changed, 0 otherwise.
|
||||
*/
|
||||
int
|
||||
clr_fd_nonblock(int fd)
|
||||
{
|
||||
int flags = fcntl(fd, F_GETFL, 0);
|
||||
|
||||
if(flags == -1)
|
||||
{
|
||||
serror("fcntl(..., F_GETFL,)");
|
||||
return 0;
|
||||
}
|
||||
/* else */
|
||||
|
||||
if(!((unsigned int)flags & NB_O_NONBLOCK))
|
||||
return 0; /* no change required */
|
||||
/* else */
|
||||
|
||||
flags &= ~NB_O_NONBLOCK;
|
||||
if(fcntl(fd, F_SETFL, flags) == -1)
|
||||
{
|
||||
serror("fcntl(..., F_SETFL, &= ~O_NONBLOCK)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: fdnb.h,v 1.2 1995/10/19 00:34:28 davis Exp $ */
|
||||
#ifndef _FDNB_H_
|
||||
#define _FDNB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" int set_fd_nonblock( int fd );
|
||||
extern "C" int clr_fd_nonblock( int fd );
|
||||
#elif defined(__STDC__)
|
||||
extern int set_fd_nonblock( int fd );
|
||||
extern int clr_fd_nonblock( int fd );
|
||||
#else
|
||||
extern int set_fd_nonblock();
|
||||
extern int clr_fd_nonblock();
|
||||
#endif
|
||||
|
||||
#endif /* !_FDNB_H_ */
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: fsStats.c,v 1.11.18.3 2005/06/24 21:05:18 steve Exp $ */
|
||||
|
||||
#include "ldmconfig.h"
|
||||
|
||||
#include "fsStats.h"
|
||||
|
||||
#if __ultrix
|
||||
/* ULTRIX 4.4 (MIPS), 4.3 (VAX), blatant kludge */
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
typedef struct fs_data STRUCT_STATFS;
|
||||
#if 1
|
||||
#define FSTATFS(fd, sbp) (errno = ENOSYS, -1)
|
||||
#else
|
||||
#define FSTATFS(fd, sbp) (statfs(".", (sbp)))
|
||||
#endif
|
||||
#define f_blocks fd_btot
|
||||
#define f_bavail fd_bfreen
|
||||
#endif
|
||||
|
||||
#if __bsdi__ || __bsdi || __FreeBSD__ || (__APPLE__ && __MACH__)
|
||||
/* BSDI, ... */
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
typedef struct statfs STRUCT_STATFS;
|
||||
#define FSTATFS(fd, sbp) (fstatfs((fd), (sbp)))
|
||||
#define f_frsize f_bsize
|
||||
#endif
|
||||
|
||||
#if defined(CRAY)
|
||||
/* UNICOS */
|
||||
#include <sys/statfs.h>
|
||||
typedef struct statfs STRUCT_STATFS;
|
||||
#define FSTATFS(fd, sbp) (fstatfs((fd), (sbp), (sizeof(struct statfs)), (0)))
|
||||
#define f_frsize f_bsize
|
||||
#define f_bavail f_bfree
|
||||
#endif
|
||||
|
||||
#if (__sun && !__SVR4) || __hpux || __linux
|
||||
/* SunOS 4, HPUX, Linux */
|
||||
#include <sys/vfs.h>
|
||||
typedef struct statfs STRUCT_STATFS;
|
||||
#define FSTATFS(fd, sbp) (fstatfs((fd), (sbp)))
|
||||
#define f_frsize f_bsize
|
||||
/* On HP the f_bavail member seems to be wrong, and f_bfree
|
||||
* agrees with others f_bavail... */
|
||||
#endif
|
||||
|
||||
#if _SYSTYPE_SVR4 || __SVR4 || _AIX || __osf__ || __sgi
|
||||
/* irix 5.3, SunOS 5, AIX, OSF1 */
|
||||
#include <sys/statvfs.h>
|
||||
typedef struct statvfs STRUCT_STATFS;
|
||||
#define FSTATFS(fd, sbp) (fstatvfs((fd), (sbp)))
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
fsStats(int fd, off_t *fs_szp, off_t *remp)
|
||||
{
|
||||
STRUCT_STATFS sbuf;
|
||||
off_t frsize; /* multiplier */
|
||||
|
||||
if(FSTATFS(fd, &sbuf) == -1)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
/* else */
|
||||
#if __ultrix
|
||||
frsize = 1024;
|
||||
#else
|
||||
frsize = sbuf.f_frsize;
|
||||
if(frsize <= 0)
|
||||
{
|
||||
/* f_frsize not supported ? */
|
||||
frsize = sbuf.f_bsize;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(fs_szp != 0)
|
||||
*fs_szp = frsize * sbuf.f_blocks;
|
||||
if(remp != 0)
|
||||
*remp = frsize * sbuf.f_bavail;
|
||||
|
||||
return ENOERR;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_FSSTATS /* test driver */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
static void
|
||||
usage(const char *const av0)
|
||||
{
|
||||
(void)fprintf(stderr, "Usage: %s filename\n",
|
||||
av0);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
main(int ac, char *av[])
|
||||
{
|
||||
int status = ENOERR;
|
||||
int fd;
|
||||
const char *const path = av[ac-1];
|
||||
off_t total;
|
||||
off_t avail;
|
||||
|
||||
if(ac != 2)
|
||||
usage(av[0]);
|
||||
|
||||
fd = open(path, O_RDONLY, 0);
|
||||
if(fd == -1)
|
||||
{
|
||||
status = errno;
|
||||
(void)fprintf(stderr, "open %s failed: %s\n",
|
||||
path, strerror(status));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
status = fsStats(fd, &total, &avail);
|
||||
if(status != ENOERR)
|
||||
{
|
||||
(void)fprintf(stderr, "fsStats %s failed: %s\n",
|
||||
path, strerror(status));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("File system size: %10ld (%7ld k)\n",
|
||||
(long)total, (long)total/1024);
|
||||
printf(" space available: %10ld (%7ld k)\n",
|
||||
(long)avail, (long)avail/1024);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
#endif /* TEST_FSSTATS */
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef _FSSTATS_H_
|
||||
#define _FSSTATS_H_
|
||||
/*
|
||||
* Copyright 1995, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: fsStats.h,v 1.1 1995/05/31 17:20:31 davis Exp $ */
|
||||
|
||||
#include <sys/types.h> /* off_t */
|
||||
#include <errno.h>
|
||||
#ifndef ENOERR
|
||||
#define ENOERR 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wrapper around fstatvfs or fstatfs.
|
||||
*
|
||||
* On failure, return errno value indicating cause of
|
||||
* failure.
|
||||
*
|
||||
* On success, returns ENOERR and sets '*fs_szp' to
|
||||
* size in bytes of the unix partition
|
||||
* where the file corresponding to 'fd' resides,
|
||||
* And sets '*remp' to the number of bytes available to
|
||||
* a non-super-user on the partition.
|
||||
*/
|
||||
int
|
||||
fsStats(int fd, off_t *fs_szp, off_t *remp);
|
||||
|
||||
#endif /*!_FSSTATS_H_*/
|
|
@ -1,900 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: inetutil.c,v 1.41.2.1.6.10 2009/07/23 23:18:31 steve Exp $ */
|
||||
|
||||
/*
|
||||
* Miscellaneous functions to make dealing with internet addresses easier.
|
||||
*/
|
||||
|
||||
#include <ldmconfig.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
/*
|
||||
* On FreeBSD 4.10-RELEASE-p2 the following order is necessary.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "error.h"
|
||||
#include "ulog.h"
|
||||
#include "inetutil.h"
|
||||
#include "../protocol/timestamp.h"
|
||||
|
||||
/*
|
||||
* Host names are limited to 255 bytes by the The Single UNIX®
|
||||
* Specification, Version 2, for the function gethostname(). MAXHOSTNAMELEN
|
||||
* is not required by that specification to be defined.
|
||||
*/
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
#ifndef h_errno /* AIX 4.3 */
|
||||
extern int h_errno; /* error number for gethostby...() functions */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return a string indicating the problem with one of the gethostby...()
|
||||
* functions.
|
||||
*/
|
||||
static const char*
|
||||
host_err_str(void)
|
||||
{
|
||||
static char msgstr[200];
|
||||
|
||||
switch (h_errno)
|
||||
{
|
||||
case 0:
|
||||
msgstr[0] = 0;
|
||||
break;
|
||||
#ifdef HOST_NOT_FOUND
|
||||
case HOST_NOT_FOUND:
|
||||
(void) strcpy(msgstr, "no such host is known");
|
||||
break;
|
||||
#endif
|
||||
#ifdef TRY_AGAIN
|
||||
case TRY_AGAIN:
|
||||
(void) strcpy(msgstr,
|
||||
"local server did not receive authoritative response");
|
||||
break;
|
||||
#endif
|
||||
#ifdef NO_RECOVERY
|
||||
case NO_RECOVERY:
|
||||
(void) strcpy(msgstr, "nonrecoverable error");
|
||||
break;
|
||||
#endif
|
||||
#ifdef NO_ADDRESS
|
||||
case NO_ADDRESS:
|
||||
(void) strcpy(msgstr, "valid name has no IP address");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void)sprintf(msgstr, "h_errno = %d", h_errno);
|
||||
}
|
||||
|
||||
return msgstr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* convenience wrapper around gethostname(2)
|
||||
* !NO_INET_FQ_KLUDGE ==> try to make sure it is "fully qualified"
|
||||
*/
|
||||
char *
|
||||
ghostname(void)
|
||||
{
|
||||
|
||||
static char hostname[MAXHOSTNAMELEN+1];
|
||||
|
||||
if (hostname[0])
|
||||
return hostname;
|
||||
|
||||
/*
|
||||
* Since the ldm programs require fully qualified
|
||||
* hostnames in an internet environment AND users
|
||||
* often don't have control over the system admin
|
||||
* conventions, we allow override of the
|
||||
* hostname with an environment variable.
|
||||
* This is meant to be the fully qualified
|
||||
* hostname of the current host.
|
||||
*/
|
||||
{
|
||||
char *cp;
|
||||
cp = getenv("LDMHOSTNAME");
|
||||
if(cp != NULL)
|
||||
{
|
||||
(void)strncpy(hostname, cp, MAXHOSTNAMELEN);
|
||||
return hostname;
|
||||
}
|
||||
}
|
||||
|
||||
if(gethostname(hostname, MAXHOSTNAMELEN) < 0)
|
||||
return NULL;
|
||||
#ifndef NO_INET_FQ_KLUDGE
|
||||
if(strchr(hostname, '.') == NULL)
|
||||
{
|
||||
/* gethostname return not fully qualified */
|
||||
struct hostent *hp;
|
||||
hp = gethostbyname(hostname);
|
||||
if(hp != NULL && hp->h_addrtype == AF_INET)
|
||||
{
|
||||
/* hopefully hp->h_name is fully qualified */
|
||||
(void)strncpy(hostname, hp->h_name, MAXHOSTNAMELEN);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* On some systems, neither gethostname() nor
|
||||
* the hp->h_name is fully qualified.
|
||||
* If you can't shoot the Systems Administrator and fix it,
|
||||
* hardwire the trailing path here.
|
||||
* (Uncomment and replace ".unversity.edu" with your domain.)
|
||||
*/
|
||||
/* #define HARDWIRED_LOCAL_DOMAIN ".unversity.edu" */
|
||||
#ifdef HARDWIRED_LOCAL_DOMAIN
|
||||
if(strchr(hostname, '.') == NULL)
|
||||
{
|
||||
strcat(hostname, HARDWIRED_LOCAL_DOMAIN);
|
||||
}
|
||||
#endif /* HARDWIRED_LOCAL_DOMAIN */
|
||||
#endif
|
||||
return hostname;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns a string identifying the Internet host referred to by an Internet
|
||||
* address. If the hostname lookup fails, then the "dotted quad" form of the
|
||||
* address is returned.
|
||||
* Arguments:
|
||||
* paddr Pointer to the Internet address structure.
|
||||
* Returns:
|
||||
* Pointer to static buffer containing the identifying string.
|
||||
*/
|
||||
const char*
|
||||
hostbyaddr(
|
||||
const struct sockaddr_in* const paddr)
|
||||
{
|
||||
struct hostent* hp;
|
||||
const char* identifier;
|
||||
struct in_addr addr;
|
||||
timestampt start;
|
||||
timestampt stop;
|
||||
double elapsed;
|
||||
ErrorObj* error;
|
||||
|
||||
addr.s_addr = paddr->sin_addr.s_addr;
|
||||
|
||||
(void)set_timestamp(&start);
|
||||
hp = gethostbyaddr((char *)&addr, sizeof (addr), AF_INET);
|
||||
(void)set_timestamp(&stop);
|
||||
|
||||
elapsed = d_diff_timestamp(&stop, &start);
|
||||
|
||||
if(hp == NULL) {
|
||||
identifier = inet_ntoa(paddr->sin_addr);
|
||||
error = ERR_NEW2(0, NULL,
|
||||
"Couldn't resolve \"%s\" to a hostname in %g seconds",
|
||||
identifier, elapsed);
|
||||
}
|
||||
else {
|
||||
identifier = hp->h_name;
|
||||
|
||||
if (elapsed < RESOLVER_TIME_THRESHOLD && !ulogIsVerbose()) {
|
||||
error = NULL;
|
||||
}
|
||||
else {
|
||||
error = ERR_NEW3(0, NULL,
|
||||
"Resolving %s to %s took %g seconds",
|
||||
inet_ntoa(paddr->sin_addr), identifier, elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
err_log_and_free(error,
|
||||
elapsed >= RESOLVER_TIME_THRESHOLD ? ERR_WARNING : ERR_INFO);
|
||||
}
|
||||
|
||||
return identifier;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Gets the IP address corresponding to a host identifier.
|
||||
*
|
||||
* Arguments:
|
||||
* id The host identifier as either a name or an IP address in
|
||||
* dotted-quad form (NNN.NNN.NNN.NNN).
|
||||
* paddr Pointer to structure to be set to the IP address of the given
|
||||
* host. Modified on and only on success. The port is set to
|
||||
* zero, the address family to AF_INET, and the rest is cleared.
|
||||
* Returns:
|
||||
* 0 Success.
|
||||
* -1 Failure. No IP address could be found for the given host
|
||||
* identifier.
|
||||
*/
|
||||
int
|
||||
addrbyhost(
|
||||
const char* const id,
|
||||
struct sockaddr_in* const paddr)
|
||||
{
|
||||
int errCode = 0; /* success */
|
||||
in_addr_t ipAddr;
|
||||
|
||||
ipAddr = inet_addr(id);
|
||||
|
||||
if (ipAddr != (in_addr_t)-1) {
|
||||
/*
|
||||
* The identifier is a dotted-quad IP address.
|
||||
*/
|
||||
paddr->sin_addr.s_addr = ipAddr;
|
||||
}
|
||||
else {
|
||||
timestampt start;
|
||||
timestampt stop;
|
||||
double elapsed;
|
||||
ErrorObj* error;
|
||||
struct hostent* hp;
|
||||
|
||||
(void)set_timestamp(&start);
|
||||
hp = gethostbyname(id);
|
||||
(void)set_timestamp(&stop);
|
||||
|
||||
elapsed = d_diff_timestamp(&stop, &start);
|
||||
|
||||
if (hp == NULL) {
|
||||
error = ERR_NEW2(0, NULL,
|
||||
"Couldn't resolve \"%s\" to an Internet address in %g seconds",
|
||||
id, elapsed);
|
||||
errCode = -1; /* failure */
|
||||
}
|
||||
else if (hp->h_addrtype != AF_INET) {
|
||||
err_log_and_free(
|
||||
ERR_NEW1(0, NULL, "\"%s\" isn't an Internet host identifier",
|
||||
id),
|
||||
ERR_WARNING);
|
||||
error = NULL;
|
||||
errCode = -1; /* failure */
|
||||
} else {
|
||||
(void) memcpy((char *)&paddr->sin_addr, hp->h_addr_list[0],
|
||||
(size_t)hp->h_length);
|
||||
|
||||
if (elapsed < RESOLVER_TIME_THRESHOLD && !ulogIsVerbose()) {
|
||||
error = NULL;
|
||||
}
|
||||
else {
|
||||
error = ERR_NEW3(0, NULL, "Resolving %s to %s took %g seconds",
|
||||
id, inet_ntoa(paddr->sin_addr), elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
err_log_and_free(error,
|
||||
elapsed >= RESOLVER_TIME_THRESHOLD ? ERR_WARNING : ERR_INFO);
|
||||
}
|
||||
|
||||
if (errCode == 0) {
|
||||
paddr->sin_family= AF_INET;
|
||||
paddr->sin_port= 0;
|
||||
|
||||
(void) memset(paddr->sin_zero, 0, sizeof (paddr->sin_zero));
|
||||
}
|
||||
|
||||
return errCode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Indicates if a host identifier has a given IP address.
|
||||
* Potentially lengthy operation.
|
||||
* Arguments:
|
||||
* id Name of the host or dotted-quad IP address.
|
||||
* targetAddr Target IP address.
|
||||
* hasAddress Pointer to result. Set on and only on success. Set to 0
|
||||
* if and only if the given host has the given IP address.
|
||||
* Returns:
|
||||
* NULL Success. See *hasAddress for the result.
|
||||
* else An error occurred. *hasAddress is not set. Error codes:
|
||||
* 1 gethostbyname() failure
|
||||
* 2 "id" isn't an Internet host identifier
|
||||
*/
|
||||
ErrorObj*
|
||||
hostHasIpAddress(
|
||||
const char* const id,
|
||||
const in_addr_t targetAddr,
|
||||
int* const hasAddress)
|
||||
{
|
||||
ErrorObj* error = NULL; /* success */
|
||||
const in_addr_t ipAddr = inet_addr(id);
|
||||
|
||||
if (ipAddr != (in_addr_t)-1) {
|
||||
*hasAddress = targetAddr == ipAddr;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* The identifier is not a dotted-quad IP address.
|
||||
*/
|
||||
timestampt start;
|
||||
timestampt stop;
|
||||
double elapsed;
|
||||
const struct hostent* hp;
|
||||
|
||||
(void)set_timestamp(&start);
|
||||
hp = gethostbyname(id);
|
||||
(void)set_timestamp(&stop);
|
||||
|
||||
elapsed = d_diff_timestamp(&stop, &start);
|
||||
|
||||
if (hp == NULL) {
|
||||
error = ERR_NEW2(1,
|
||||
ERR_NEW(h_errno, NULL,
|
||||
h_errno == HOST_NOT_FOUND ? "host not found" :
|
||||
h_errno == NO_DATA ? "no data on host" :
|
||||
h_errno == NO_RECOVERY ? "unrecoverable server error" :
|
||||
h_errno == TRY_AGAIN ? "hostname lookup timeout" :
|
||||
"unknown error"),
|
||||
"Couldn't resolve \"%s\" to an Internet address in %g seconds",
|
||||
id, elapsed);
|
||||
}
|
||||
else if (hp->h_addrtype != AF_INET) {
|
||||
error = ERR_NEW1(2, NULL,
|
||||
"\"%s\" isn't an Internet host identifier", id);
|
||||
} else {
|
||||
const struct in_addr* const* in_addr_pp;
|
||||
|
||||
for (in_addr_pp = (const struct in_addr* const*)hp->h_addr_list;
|
||||
*in_addr_pp != NULL;
|
||||
in_addr_pp++) {
|
||||
if ((*in_addr_pp)->s_addr == targetAddr)
|
||||
break;
|
||||
}
|
||||
|
||||
*hasAddress = *in_addr_pp != NULL;
|
||||
|
||||
if (elapsed >= RESOLVER_TIME_THRESHOLD || ulogIsVerbose()) {
|
||||
err_log_and_free(
|
||||
ERR_NEW2(0, NULL,
|
||||
"Resolving %s to an IP address took %g seconds",
|
||||
id, elapsed),
|
||||
elapsed >= RESOLVER_TIME_THRESHOLD
|
||||
? ERR_WARNING : ERR_INFO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
s_sockaddr_in(
|
||||
struct sockaddr_in *paddr
|
||||
)
|
||||
{
|
||||
static char buf[64];
|
||||
(void) sprintf(buf,
|
||||
"sin_port %5d, sin_addr %s",
|
||||
paddr->sin_port,
|
||||
inet_ntoa(paddr->sin_addr));
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Puts the address of the current host into *paddr
|
||||
* Returns 0 on success, -1 failure
|
||||
*/
|
||||
int
|
||||
gethostaddr_in(
|
||||
struct sockaddr_in *paddr
|
||||
)
|
||||
{
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
struct hostent *hp;
|
||||
|
||||
if(gethostname(hostname,MAXHOSTNAMELEN) == -1)
|
||||
return -1;
|
||||
|
||||
return addrbyhost(hostname, paddr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the well known port for (servicename, proto)
|
||||
* or -1 on failure.
|
||||
*/
|
||||
int
|
||||
getservport(
|
||||
const char *servicename,
|
||||
const char *proto
|
||||
)
|
||||
{
|
||||
struct servent *se;
|
||||
se = getservbyname(servicename, proto);
|
||||
if(se == NULL)
|
||||
return -1;
|
||||
/* else */
|
||||
return se->s_port;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Attempt to connect to a unix domain socket.
|
||||
* Create & connect.
|
||||
* Returns (socket) descriptor or -1 on error.
|
||||
*/
|
||||
int
|
||||
usopen(
|
||||
const char *name /* name of socket */
|
||||
)
|
||||
{
|
||||
int sock = -1;
|
||||
struct sockaddr addr; /* AF_UNIX address */
|
||||
int logType = SOCK_DGRAM;
|
||||
|
||||
|
||||
while(sock == -1)
|
||||
{
|
||||
sock = socket(AF_UNIX, logType, 0);
|
||||
if(sock == -1)
|
||||
return -1;
|
||||
/* else */
|
||||
|
||||
addr.sa_family = AF_UNIX;
|
||||
(void) strncpy(addr.sa_data, name,
|
||||
sizeof(addr.sa_data));
|
||||
if (connect(sock, &addr, sizeof(addr)) == -1)
|
||||
{
|
||||
const int errnum = errno;
|
||||
(void) close(sock);
|
||||
sock = -1;
|
||||
#ifdef EPROTOTYPE /* Linux ulog */
|
||||
if(logType == SOCK_DGRAM && errnum == EPROTOTYPE)
|
||||
{
|
||||
/* retry with stream socket type */
|
||||
logType = SOCK_STREAM;
|
||||
errno = 0;
|
||||
continue;
|
||||
}
|
||||
/* else */
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
break; /* normal loop exit */
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Attempt to connect to a internet domain udp socket.
|
||||
* Create & connect.
|
||||
* Returns (socket) descriptor or -1 on error.
|
||||
*/
|
||||
int
|
||||
udpopen(
|
||||
const char *hostname,
|
||||
const char *servicename
|
||||
)
|
||||
{
|
||||
int sock;
|
||||
int port;
|
||||
struct sockaddr_in addr; /* AF_INET address */
|
||||
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(sock == -1)
|
||||
return -1;
|
||||
/* else */
|
||||
|
||||
if(addrbyhost(hostname, &addr) == -1)
|
||||
{
|
||||
(void) close(sock);
|
||||
return -1;
|
||||
}
|
||||
/* else */
|
||||
|
||||
if((port = getservport(servicename, "udp")) == -1)
|
||||
{
|
||||
(void) close(sock);
|
||||
return -1;
|
||||
}
|
||||
/* else */
|
||||
addr.sin_port = (unsigned short) port;
|
||||
|
||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
|
||||
{
|
||||
(void) close(sock);
|
||||
return -1;
|
||||
}
|
||||
/* else */
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Macro for rounding-up the positive value x to the nearest multiple of n:
|
||||
*/
|
||||
#undef ROUNDUP
|
||||
#define ROUNDUP(x,n) ((x % n) ? (x + (n - (x % n))) : x)
|
||||
|
||||
|
||||
/*
|
||||
* Return a new (allocated) host entry.
|
||||
*/
|
||||
static
|
||||
struct hostent*
|
||||
hostent_new(
|
||||
const char *name
|
||||
)
|
||||
{
|
||||
struct hostent *new = NULL;
|
||||
struct hostent *entry;
|
||||
|
||||
/*
|
||||
* Retrieve the host's entry.
|
||||
*/
|
||||
entry = gethostbyname(name);
|
||||
if (NULL == entry)
|
||||
uerror("Couldn't get information on host %s: %s", name, host_err_str());
|
||||
else
|
||||
{
|
||||
int num_aliases;
|
||||
int num_addr;
|
||||
char **from_alias;
|
||||
char **to_alias;
|
||||
char *cp;
|
||||
size_t nbytes;
|
||||
size_t h_name_off;
|
||||
size_t h_aliases_off;
|
||||
size_t addrs_off;
|
||||
size_t h_addr_list_off;
|
||||
struct in_addr **from_addr;
|
||||
struct in_addr **to_addr;
|
||||
struct in_addr *addrp;
|
||||
|
||||
/*
|
||||
* Compute the size requirements and offsets for the new host entry.
|
||||
*/
|
||||
|
||||
/* Basic size of host entry structure: */
|
||||
nbytes = sizeof(struct hostent);
|
||||
|
||||
/* Offset and size of official name string: */
|
||||
h_name_off = nbytes;
|
||||
nbytes += strlen(entry->h_name) + 1;
|
||||
|
||||
/* Offset and length of aliases: */
|
||||
nbytes = (size_t)ROUNDUP(nbytes, sizeof(char*));
|
||||
h_aliases_off = nbytes;
|
||||
for (from_alias = entry->h_aliases; NULL != *from_alias; from_alias++)
|
||||
nbytes += strlen(*from_alias) + 1;
|
||||
num_aliases = (int)(from_alias - entry->h_aliases);
|
||||
nbytes += sizeof(char*) * (num_aliases + 1);
|
||||
|
||||
/* Offset and length of addresses: */
|
||||
nbytes = (size_t)ROUNDUP(nbytes, sizeof(struct in_addr*));
|
||||
h_addr_list_off = nbytes;
|
||||
for (from_addr = (struct in_addr**)entry->h_addr_list;
|
||||
NULL != *from_addr; )
|
||||
from_addr++;
|
||||
num_addr = (int)(from_addr - (struct in_addr**)entry->h_addr_list);
|
||||
nbytes += sizeof(struct in_addr*) * (num_addr + 1);
|
||||
nbytes = (size_t)ROUNDUP(nbytes, sizeof(struct in_addr));
|
||||
addrs_off = nbytes;
|
||||
nbytes += sizeof(struct in_addr) * num_addr;
|
||||
|
||||
/*
|
||||
* Allocate the new host entry.
|
||||
*/
|
||||
new = (struct hostent *) malloc(nbytes);
|
||||
if (NULL == new)
|
||||
serror(
|
||||
"Couldn't allocate %lu bytes for information on host \"%s\"",
|
||||
(unsigned long) nbytes, name);
|
||||
else
|
||||
{
|
||||
/* Copy non-pointer members. */
|
||||
new->h_addrtype = entry->h_addrtype;
|
||||
new->h_length = entry->h_length;
|
||||
|
||||
/* Copy official host name. */
|
||||
new->h_name = (char *) new + h_name_off;
|
||||
(void) strcpy(new->h_name, entry->h_name);
|
||||
|
||||
/* Copy aliases. */
|
||||
new->h_aliases = (char**)((char*)new + h_aliases_off);
|
||||
cp = (char *) (new->h_aliases + num_aliases);
|
||||
for (from_alias = entry->h_aliases, to_alias = new->h_aliases;
|
||||
NULL != *from_alias;
|
||||
from_alias++, to_alias++)
|
||||
{
|
||||
*to_alias = cp;
|
||||
(void) strcpy(*to_alias, *from_alias);
|
||||
cp += strlen(*to_alias) + 1;
|
||||
}
|
||||
*to_alias = NULL;
|
||||
|
||||
/* Copy addresses. */
|
||||
new->h_addr_list = (char**)((char*)new + h_addr_list_off);
|
||||
addrp = (struct in_addr*)((char*)new + addrs_off);
|
||||
for (from_addr = (struct in_addr**)entry->h_addr_list,
|
||||
to_addr = (struct in_addr**)new->h_addr_list;
|
||||
NULL != *from_addr;
|
||||
from_addr++, to_addr++)
|
||||
{
|
||||
*to_addr = addrp++;
|
||||
**to_addr = **from_addr;
|
||||
}
|
||||
*to_addr = NULL;
|
||||
} /* new host entry allocated */
|
||||
} /* host entry retrieved */
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compare two (possibly fully-qualified) hostnames. Indicate if they
|
||||
* refer to the same host. If one of them isn't fully-qualified, then
|
||||
* assume it's in the same domain as the other.
|
||||
*
|
||||
* Returns:
|
||||
* 0 Different hosts
|
||||
* 1 Same host
|
||||
*/
|
||||
static int
|
||||
same_host(
|
||||
const char *name1,
|
||||
const char *name2
|
||||
)
|
||||
{
|
||||
return (name1 == name2) ||
|
||||
(strcmp(name1, name2) == 0) ||
|
||||
(strstr(name1, name2) == name1 && name1[strlen(name2)] == '.') ||
|
||||
(strstr(name2, name1) == name2 && name2[strlen(name1)] == '.');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Attempt to determine if "remote" is the same as this host.
|
||||
* Could be lots smarter...
|
||||
*/
|
||||
int
|
||||
isMe(
|
||||
const char *remote
|
||||
)
|
||||
{
|
||||
static char *names[] = {
|
||||
"localhost",
|
||||
"loopback",
|
||||
NULL /* necessary terminator */
|
||||
};
|
||||
char *me;
|
||||
char **npp;
|
||||
static struct hostent *hp;
|
||||
|
||||
/* Check `local host' aliases. */
|
||||
for (npp = names; *npp != NULL; npp++)
|
||||
if (same_host(remote, *npp))
|
||||
return 1;
|
||||
|
||||
me = ghostname();
|
||||
if (me == NULL)
|
||||
return 0;
|
||||
|
||||
/* Check my nominal hostname. */
|
||||
if (same_host(me, remote))
|
||||
return 1;
|
||||
|
||||
/* Cache host information on myself. */
|
||||
if (NULL == hp)
|
||||
hp = hostent_new(me);
|
||||
|
||||
/* Check my aliases. */
|
||||
if (hp != NULL)
|
||||
{
|
||||
for(npp = hp->h_aliases; *npp != NULL; npp++)
|
||||
if (same_host(*npp, remote))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sets the socket Internet address of the local host.
|
||||
*
|
||||
* Returns:
|
||||
* 0 Success
|
||||
* !0 Failure. errno set.
|
||||
*/
|
||||
int
|
||||
local_sockaddr_in(struct sockaddr_in* addr)
|
||||
{
|
||||
int error;
|
||||
static int cached = 0;
|
||||
struct sockaddr_in cachedAddr;
|
||||
|
||||
if (cached) {
|
||||
(void)memcpy(addr, &cachedAddr, sizeof(cachedAddr));
|
||||
|
||||
error = 0;
|
||||
}
|
||||
else {
|
||||
char name[256];
|
||||
|
||||
(void)memset(&cachedAddr, 0, sizeof(cachedAddr));
|
||||
|
||||
if (gethostname(name, sizeof(name))) {
|
||||
serror("gethostname()");
|
||||
|
||||
error = errno;
|
||||
}
|
||||
else {
|
||||
error = 0;
|
||||
|
||||
if (addrbyhost(name, &cachedAddr)) {
|
||||
if (addrbyhost("localhost", &cachedAddr)) {
|
||||
if (addrbyhost("0.0.0.0", &cachedAddr)) {
|
||||
serror("addrbyhost()");
|
||||
|
||||
error = errno;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!error)
|
||||
(void)memcpy(addr, &cachedAddr, sizeof(cachedAddr));
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#ifndef TIRPC
|
||||
/*
|
||||
* Create a socket of type "udp" or "tcp" and bind it
|
||||
* to port.
|
||||
* Return the socket or -1 on error.
|
||||
*/
|
||||
int
|
||||
sockbind(
|
||||
const char *type,
|
||||
unsigned short port
|
||||
)
|
||||
{
|
||||
int sock = -1;
|
||||
struct sockaddr_in addr;
|
||||
size_t len = sizeof(struct sockaddr_in);
|
||||
|
||||
if(type == NULL)
|
||||
return -1;
|
||||
|
||||
if(*type == 't')
|
||||
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
else if(*type == 'u')
|
||||
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if(sock == -1)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Eliminate problem with EADDRINUSE for reserved socket.
|
||||
* We get this if an upstream data source hasn't tried to
|
||||
* write on the other and we are in FIN_WAIT_2
|
||||
*/
|
||||
if(*type == 't')
|
||||
{
|
||||
int on = 1;
|
||||
(void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *)&on, sizeof(on));
|
||||
}
|
||||
|
||||
(void) memset((char *)&addr, 0, len);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
addr.sin_port = (short)htons((short)port);
|
||||
|
||||
if(bind(sock, (struct sockaddr *)&addr, len) < 0)
|
||||
{
|
||||
(void) close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* TLI version of above function.
|
||||
* Create a TLI transport endpoint of type "udp" or "tcp"
|
||||
* and bind it to port.
|
||||
* Return the descriptor or -1 on error.
|
||||
* Only tested on SunOS 5.x
|
||||
*/
|
||||
#include <tiuser.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int
|
||||
sockbind(
|
||||
const char *type,
|
||||
unsigned short port
|
||||
)
|
||||
{
|
||||
int sock = -1;
|
||||
struct sockaddr_in sin_req;
|
||||
struct t_bind *req, *ret;
|
||||
extern void terror();
|
||||
|
||||
if(type == NULL)
|
||||
return -1;
|
||||
|
||||
if(*type == 't')
|
||||
sock = t_open("/dev/tcp", O_RDWR, NULL);
|
||||
else if(*type == 'u')
|
||||
sock = t_open("/dev/udp", O_RDWR, NULL);
|
||||
|
||||
if((sock == -1) || ( t_getstate(sock) != T_UNBND) )
|
||||
{
|
||||
terror("sockbind: t_open");
|
||||
goto err0;
|
||||
}
|
||||
|
||||
req = (struct t_bind *)t_alloc(sock, T_BIND, T_ADDR);
|
||||
if(req == NULL)
|
||||
{
|
||||
terror("sockbind: t_alloc req");
|
||||
goto err1;
|
||||
}
|
||||
ret = (struct t_bind *)t_alloc(sock, T_BIND, T_ADDR);
|
||||
if(ret == NULL)
|
||||
{
|
||||
terror("sockbind: t_alloc ret");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
(void) memset((char *)&sin_req, 0, sizeof(sin_req));
|
||||
sin_req.sin_family = AF_INET;
|
||||
sin_req.sin_addr.s_addr = INADDR_ANY;
|
||||
sin_req.sin_port = htons(port);
|
||||
|
||||
(void) memcpy(req->addr.buf, (char *)&sin_req, sizeof(sin_req));
|
||||
req->addr.len = sizeof(sin_req);
|
||||
req->qlen = 32; /* rpc_soc.c uses 8 */
|
||||
|
||||
if(t_bind(sock, req, ret) < 0)
|
||||
{
|
||||
terror("sockbind: t_bind");
|
||||
goto err3;
|
||||
}
|
||||
if(memcmp(req->addr.buf, ret->addr.buf, ret->addr.len) != 0)
|
||||
{
|
||||
uerror("sockbind: memcmp: t_bind changed address");
|
||||
}
|
||||
|
||||
(void) t_free((char *)req, T_BIND);
|
||||
(void) t_free((char *)ret, T_BIND);
|
||||
return sock;
|
||||
|
||||
err3 :
|
||||
(void) t_free((char *)ret, T_BIND);
|
||||
err2 :
|
||||
(void) t_free((char *)req, T_BIND);
|
||||
err1 :
|
||||
(void) close(sock);
|
||||
err0 :
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* !TIRPC */
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: inetutil.h,v 1.12.18.3 2006/10/19 19:28:08 steve Exp $ */
|
||||
|
||||
/*
|
||||
* Miscellaneous functions to make dealing with internet addresses easier.
|
||||
*/
|
||||
|
||||
#ifndef _INETUTIL_H_
|
||||
#define _INETUTIL_H_
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include "error.h"
|
||||
|
||||
#ifdef IPPROTO_IP /* we included netinet/in.h, so struct sockaddr_in is */
|
||||
extern const char* hostbyaddr(
|
||||
const struct sockaddr_in* const paddr);
|
||||
extern int addrbyhost(const char *hostname, struct sockaddr_in *paddr);
|
||||
extern ErrorObj* hostHasIpAddress(
|
||||
const char* const hostname,
|
||||
const in_addr_t targetAddr,
|
||||
int* const hasAddress);
|
||||
extern char *s_sockaddr_in(struct sockaddr_in *paddr);
|
||||
extern int gethostaddr_in(struct sockaddr_in *paddr);
|
||||
#endif
|
||||
extern int getservport(const char *servicename, const char *proto);
|
||||
extern char *ghostname(void);
|
||||
extern int usopen(const char *name);
|
||||
extern int udpopen(const char *hostname, const char *servicename);
|
||||
extern int isMe(const char *remote);
|
||||
extern int local_sockaddr_in(struct sockaddr_in* addr);
|
||||
extern int sockbind(const char *type, unsigned short port);
|
||||
|
||||
#endif /* !_INETUTIL_H_ */
|
|
@ -1,29 +0,0 @@
|
|||
/* $Id: ldmalloc.h,v 1.1.22.1 2005/09/21 18:37:12 steve Exp $ */
|
||||
#ifndef _ALLOC_H_
|
||||
#define _ALLOC_H_
|
||||
|
||||
#ifndef NO_STDLIB_H
|
||||
/* assume __STDC__ */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#else
|
||||
/* old style declarations */
|
||||
|
||||
extern char *malloc();
|
||||
extern char *realloc();
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif /* !NULL */
|
||||
|
||||
#endif /* !NO_STDLIB_H */
|
||||
|
||||
|
||||
#define Alloc(theNum, theType) \
|
||||
(theType *)malloc((size_t)(sizeof(theType) * (theNum)))
|
||||
|
||||
|
||||
#define ARRAYLEN(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
|
||||
#endif /* !_ALLOC_H_ */
|
|
@ -1,207 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: mkdirs_open.c,v 1.14.18.4 2006/01/23 22:12:26 steve Exp $ */
|
||||
|
||||
#include "ldmconfig.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h> /* O_RDONLY et al */
|
||||
#include "mkdirs_open.h"
|
||||
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 255
|
||||
#endif /* !PATH_MAX */
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef ENAMETOOLONG
|
||||
#define ENAMETOOLONG E2BIG /* punt */
|
||||
#endif /* !ENAMETOOLONG */
|
||||
|
||||
#include <string.h>
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#include <unistd.h> /* access */
|
||||
|
||||
/*
|
||||
* Ensures that a directory exists. Will create all necessary parent
|
||||
* directories.
|
||||
*
|
||||
* Arguments:
|
||||
* path Pointer to directory pathname.
|
||||
* mode File creation mode for directory and any parent directories.
|
||||
* Returns:
|
||||
* -1 Failure. errno is set.
|
||||
* 0 Success.
|
||||
*/
|
||||
int
|
||||
mkdirs(
|
||||
const char* const path,
|
||||
const mode_t mode)
|
||||
{
|
||||
int retCode = mkdir(path, mode);
|
||||
|
||||
if (retCode != 0) {
|
||||
if (errno == EEXIST) {
|
||||
/*
|
||||
* The directory already exists (another process might just have
|
||||
* created it). This is still a "success".
|
||||
*/
|
||||
retCode = 0;
|
||||
}
|
||||
else if (errno == ENOENT) {
|
||||
/*
|
||||
* A necessary parent directory doesn't exist.
|
||||
*
|
||||
* Strip off the last parent directory in the path.
|
||||
*/
|
||||
char* ep = strrchr(path, '/');
|
||||
size_t len = (size_t)(ep - path);
|
||||
char stripped[PATH_MAX+1];
|
||||
|
||||
assert(ep != NULL && ep != path);
|
||||
assert(len < PATH_MAX);
|
||||
|
||||
/*
|
||||
* Copy up-to the last component in the path.
|
||||
*/
|
||||
(void)memcpy(stripped, path, len);
|
||||
stripped[len] = 0;
|
||||
|
||||
/*
|
||||
* Ensure that the parent directory exists.
|
||||
*/
|
||||
retCode = mkdirs(stripped, mode);
|
||||
|
||||
if (retCode == 0)
|
||||
retCode = mkdir(path, mode);
|
||||
} /* a parent directory doesn't exist */
|
||||
} /* couldn't create directory */
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Like open(2), but will create components as necessary.
|
||||
* Returns valid file descriptor if successful, -1 on failure.
|
||||
*/
|
||||
int
|
||||
mkdirs_open(
|
||||
const char *path,
|
||||
int flags,
|
||||
mode_t mode)
|
||||
{
|
||||
int fd;
|
||||
fd = open(path, flags, mode);
|
||||
if(fd != -1) /* open suceeded */
|
||||
return fd;
|
||||
/* else */
|
||||
if(errno != ENOENT) /* not a problem we will fix here */
|
||||
return -1;
|
||||
/* else */
|
||||
if(!((unsigned int)flags & O_CREAT))
|
||||
return -1;
|
||||
|
||||
/* else, a component of the path prefix does not exist */
|
||||
{
|
||||
char *ep;
|
||||
size_t len;
|
||||
char stripped[PATH_MAX+1];
|
||||
|
||||
ep = strrchr(path, '/');
|
||||
if(ep == NULL || ep == path)
|
||||
return -1; /* can't happen ? */
|
||||
/* else */
|
||||
|
||||
/* strip off last component in path */
|
||||
len = (size_t)(ep - path);
|
||||
if(len >= PATH_MAX)
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
(void)memcpy(stripped, path, len);
|
||||
stripped[len] = 0;
|
||||
|
||||
if(mkdirs(stripped, (mode | 0111)) == -1)
|
||||
return -1;
|
||||
/* else */
|
||||
}
|
||||
return open(path, flags, mode);
|
||||
}
|
||||
|
||||
|
||||
#if TEST_FIXTURE
|
||||
main(ac,av)
|
||||
int ac;
|
||||
char *av[];
|
||||
{
|
||||
int fd;
|
||||
|
||||
if(ac < 2) exit(1);
|
||||
|
||||
fd = mkdirs_open(av[1] , O_WRONLY | O_CREAT | O_TRUNC, 0664);
|
||||
if(fd == -1)
|
||||
{
|
||||
perror(av[1]);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Check to see if we have access to all components of 'path'
|
||||
* up to the last component. (Doesn't check the access of the full path)
|
||||
* If 'create' is no zero, attempt to create path components (directories)
|
||||
* as necessary.
|
||||
* Returns 0 if access is ok, -1 on error.
|
||||
*/
|
||||
int
|
||||
diraccess(
|
||||
const char *path,
|
||||
int access_m,
|
||||
int create)
|
||||
{
|
||||
char *ep;
|
||||
size_t len;
|
||||
char stripped[PATH_MAX+1];
|
||||
|
||||
ep = strrchr(path, '/');
|
||||
if(ep == NULL || ep == path)
|
||||
return (0);
|
||||
|
||||
/* else */
|
||||
/* strip off last component in path */
|
||||
len = (size_t)(ep - path);
|
||||
if(len >= PATH_MAX)
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
(void)memcpy(stripped, path, len);
|
||||
stripped[len] = 0;
|
||||
|
||||
/* Now we have something that looks like a directory */
|
||||
if(access(stripped, (unsigned int)access_m | X_OK) == 0)
|
||||
return(0);
|
||||
/* else */
|
||||
|
||||
if(create && errno == ENOENT)
|
||||
{
|
||||
if(mkdirs(stripped, 0777) == 0) /* let the umask fix it */
|
||||
return 0;
|
||||
}
|
||||
/* else */
|
||||
|
||||
return -1;
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: mkdirs_open.h,v 1.8 1999/04/03 00:26:12 davis Exp $ */
|
||||
#ifndef _MKDIRS_H_
|
||||
#define _MKDIRS_H_
|
||||
|
||||
/*
|
||||
* Like mkdir(2), but will create components as necessary.
|
||||
* The specified mode is used to create the directories.
|
||||
* Returns 0 if successful, -1 on failure.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" int mkdirs(const char *path, mode_t mode);
|
||||
#elif defined(__STDC__)
|
||||
extern int mkdirs(const char *path, mode_t mode);
|
||||
#else /* Old Style C */
|
||||
extern int mkdirs();
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Like open(2), but will create components as necessary.
|
||||
* Returns valid file descriptor if successful, -1 on failure.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" int mkdirs_open(const char *path, int flags, mode_t mode);
|
||||
#elif defined(__STDC__)
|
||||
extern int mkdirs_open(const char *path, int flags, mode_t mode);
|
||||
#else /* Old Style C */
|
||||
extern int mkdirs_open();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check to see if we have access to all components of 'path'
|
||||
* up to the last component. (Doesn't check the access of the full path)
|
||||
* If 'create' is no zero, attempt to create path components (directories)
|
||||
* as necessary.
|
||||
* Returns 0 if access is ok, -1 on error.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" int diraccess(const char *path, int access_m, int create);
|
||||
#elif defined(__STDC__)
|
||||
extern int diraccess(const char *path, int access_m, int create);
|
||||
#else /* Old Style C */
|
||||
extern int diraccess();
|
||||
#endif
|
||||
|
||||
#endif /* !_MKDIRS_H_ */
|
|
@ -1,14 +0,0 @@
|
|||
/* $Id: paths.h,v 1.3.20.1 2007/02/26 17:28:07 steve Exp $ */
|
||||
/*
|
||||
* Set up default paths for ldm system.
|
||||
* Can be overridden on the command line.
|
||||
*/
|
||||
#define DEFAULT_ETCDIR LDMHOME "/etc"
|
||||
#define DEFAULT_ACLPATHNAME DEFAULT_ETCDIR "/ldmd.conf"
|
||||
#define DEFAULT_CONFFILENAME DEFAULT_ETCDIR "/pqact.conf"
|
||||
#define DEFAULT_DATADIR LDMHOME
|
||||
#define DEFAULT_LOGDIR LDMHOME "/logs"
|
||||
#define DEFAULT_QUEUE LDMHOME "/data/ldm.pq"
|
||||
#define DEFAULT_SURF_OUTQUEUE LDMHOME "/data/pqsurf.pq"
|
||||
#define DEFAULT_SURF_CONFFILE DEFAULT_ETCDIR "/pqsurf.conf"
|
||||
#define DEFAULT_SURF_DATADIR LDMHOME
|
|
@ -1,175 +0,0 @@
|
|||
#include "ldmconfig.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "pattern.h"
|
||||
#include "RegularExpressions.h"
|
||||
|
||||
|
||||
struct Pattern {
|
||||
char* string;
|
||||
regex_t reg;
|
||||
int ignoreCase;
|
||||
};
|
||||
|
||||
static Pattern* matchAll;
|
||||
|
||||
|
||||
/*
|
||||
* Arguments:
|
||||
* pat Pointer to memory that will be set to point to an
|
||||
* allocated Pattern. Set on and only on success.
|
||||
* ere The extended regular expression. Caller may free upon
|
||||
* return. If the expression is a pathological
|
||||
* regular-expression, then it will be repaired.
|
||||
* ignoreCase Whether or not to ignore case in matches.
|
||||
*
|
||||
* Returns:
|
||||
* NULL Success. *pat is set.
|
||||
* else Error object. err_code() values:
|
||||
* 1 System error. *pat not set.
|
||||
* 2 Invalid ERE. *pat not set.
|
||||
*/
|
||||
ErrorObj*
|
||||
pat_new(
|
||||
Pattern** const pat,
|
||||
const char* const ere,
|
||||
const int ignoreCase)
|
||||
{
|
||||
ErrorObj* errObj = NULL; /* success */
|
||||
int isTrivial = 0 == strcmp(".*", ere);
|
||||
|
||||
if (isTrivial && NULL != matchAll) {
|
||||
*pat = matchAll;
|
||||
}
|
||||
else {
|
||||
Pattern* const ptr = (Pattern*)malloc(sizeof(Pattern));
|
||||
|
||||
if (NULL == ptr) {
|
||||
errObj = ERR_NEW2(1, NULL, "Couldn't allocate %lu bytes: %s",
|
||||
(unsigned long)sizeof(Pattern), strerror(errno));
|
||||
}
|
||||
else {
|
||||
ptr->string = strdup(ere);
|
||||
|
||||
if (NULL == ptr->string) {
|
||||
errObj = ERR_NEW2(1, NULL, "Couldn't copy string \"%s\": %s",
|
||||
ere, strerror(errno));
|
||||
}
|
||||
else {
|
||||
int err;
|
||||
|
||||
(void)re_vetSpec(ptr->string);
|
||||
|
||||
if (err = regcomp(&ptr->reg, ptr->string,
|
||||
REG_EXTENDED | REG_NOSUB | (ignoreCase ? REG_ICASE : 0))) {
|
||||
|
||||
char buf[512];
|
||||
|
||||
(void)regerror(err, &ptr->reg, buf, sizeof(buf));
|
||||
|
||||
errObj = ERR_NEW2((REG_ESPACE == err) ? 1 : 2, NULL,
|
||||
"Couldn't compile ERE \"%s\": %s", ptr->string, buf);
|
||||
}
|
||||
else {
|
||||
ptr->ignoreCase = ignoreCase;
|
||||
*pat = ptr;
|
||||
|
||||
if (isTrivial && NULL == matchAll)
|
||||
matchAll = ptr;
|
||||
} /* ERE compiled */
|
||||
|
||||
if (errObj)
|
||||
free(ptr->string);
|
||||
} /* ptr->string allocated */
|
||||
|
||||
if (errObj)
|
||||
free(ptr);
|
||||
} /* "ptr" allocated */
|
||||
} /* non-trivial ERE or matchAll==NULL */
|
||||
|
||||
return errObj;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clones a pattern.
|
||||
*
|
||||
* Arguments:
|
||||
* dst Pointer to pointer to be set to the clone. Set on and
|
||||
* only on success.
|
||||
* src The pattern to be cloned.
|
||||
* Returns:
|
||||
* NULL Success.
|
||||
* else Error object.
|
||||
*/
|
||||
ErrorObj*
|
||||
pat_clone(
|
||||
Pattern** const dst,
|
||||
const Pattern* const src)
|
||||
{
|
||||
return pat_new(dst, src->string, src->ignoreCase);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Arguments:
|
||||
* pat Pointer to Pattern set by pat_new().
|
||||
* Returns:
|
||||
* 0 String doesn't match pattern
|
||||
* 1 String matches pattern
|
||||
*/
|
||||
int
|
||||
pat_isMatch(
|
||||
const Pattern* const pat,
|
||||
const char* const string)
|
||||
{
|
||||
return
|
||||
matchAll == pat
|
||||
? 1
|
||||
: 0 == regexec(&pat->reg, string, 0, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Arguments:
|
||||
* pat Pointer to Pattern set by pat_new().
|
||||
*
|
||||
* Returns:
|
||||
* Pointer to the extended regular expression of this pattern. If the
|
||||
* initializing expression was pathological, then then returned string is
|
||||
* the repaired form of the expression.
|
||||
*/
|
||||
const char*
|
||||
pat_getEre(
|
||||
const Pattern* const pat)
|
||||
{
|
||||
return
|
||||
matchAll == pat
|
||||
? ".*"
|
||||
: pat->string;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Releases the resources of a Pattern.
|
||||
*
|
||||
* Arguments:
|
||||
* pat Pointer to Pattern. May be NULL.
|
||||
*/
|
||||
void
|
||||
pat_free(
|
||||
Pattern* const pat)
|
||||
{
|
||||
if (pat && matchAll != pat) {
|
||||
Pattern* p = (Pattern*)pat;
|
||||
|
||||
regfree(&p->reg);
|
||||
free(p->string);
|
||||
free(p);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef PATTERN_H
|
||||
#define PATTERN_H
|
||||
|
||||
#include "error.h"
|
||||
|
||||
typedef struct Pattern Pattern;
|
||||
|
||||
ErrorObj*
|
||||
pat_new(
|
||||
Pattern** pat,
|
||||
const char* re,
|
||||
const int ignoreCase);
|
||||
|
||||
ErrorObj*
|
||||
pat_clone(
|
||||
Pattern** dst,
|
||||
const Pattern* src);
|
||||
|
||||
int
|
||||
pat_isMatch(
|
||||
const Pattern* pat,
|
||||
const char* string);
|
||||
|
||||
const char*
|
||||
pat_getEre(
|
||||
const Pattern* pat);
|
||||
|
||||
void
|
||||
pat_free(
|
||||
Pattern* pat);
|
||||
|
||||
#endif
|
|
@ -1,141 +0,0 @@
|
|||
/*
|
||||
* This module contains RPC helper functions.
|
||||
*/
|
||||
|
||||
#include "ldmconfig.h"
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "rpcutil.h"
|
||||
#include "inetutil.h"
|
||||
#include "ulog.h"
|
||||
|
||||
|
||||
/*
|
||||
* Print reply error info
|
||||
*
|
||||
* This is derived from RPC 4.0 source. It's here because at least one
|
||||
* implementation of the RPC function clnt_sperror() results in a segmentation
|
||||
* violation (SunOS 5.8).
|
||||
*/
|
||||
char*
|
||||
clnt_errmsg(CLIENT* clnt)
|
||||
{
|
||||
struct rpc_err e;
|
||||
static char buf[512];
|
||||
char *str = buf;
|
||||
|
||||
clnt_geterr(clnt, &e);
|
||||
|
||||
(void) strcpy(str, clnt_sperrno(e.re_status));
|
||||
str += strlen(str);
|
||||
|
||||
switch (e.re_status) {
|
||||
case RPC_SUCCESS:
|
||||
case RPC_CANTENCODEARGS:
|
||||
case RPC_CANTDECODERES:
|
||||
case RPC_TIMEDOUT:
|
||||
case RPC_PROGUNAVAIL:
|
||||
case RPC_PROCUNAVAIL:
|
||||
case RPC_CANTDECODEARGS:
|
||||
case RPC_SYSTEMERROR:
|
||||
case RPC_UNKNOWNHOST:
|
||||
case RPC_UNKNOWNPROTO:
|
||||
case RPC_PMAPFAILURE:
|
||||
case RPC_PROGNOTREGISTERED:
|
||||
case RPC_FAILED:
|
||||
break;
|
||||
|
||||
case RPC_CANTSEND:
|
||||
case RPC_CANTRECV:
|
||||
(void) sprintf(str, "; errno = %s", strerror(e.re_errno));
|
||||
str += strlen(str);
|
||||
break;
|
||||
|
||||
case RPC_VERSMISMATCH:
|
||||
(void) sprintf(str, "; low version = %lu, high version = %lu",
|
||||
e.re_vers.low, e.re_vers.high);
|
||||
str += strlen(str);
|
||||
break;
|
||||
|
||||
case RPC_AUTHERROR:
|
||||
(void) sprintf(str,"; why = ");
|
||||
str += strlen(str);
|
||||
(void) sprintf(str, "(authentication error %d)",
|
||||
(int) e.re_why);
|
||||
str += strlen(str);
|
||||
break;
|
||||
|
||||
case RPC_PROGVERSMISMATCH:
|
||||
(void) sprintf(str, "; low version = %lu, high version = %lu",
|
||||
e.re_vers.low, e.re_vers.high);
|
||||
str += strlen(str);
|
||||
break;
|
||||
|
||||
default: /* unknown */
|
||||
(void) sprintf(str, "; s1 = %lu, s2 = %lu",
|
||||
e.re_lb.s1, e.re_lb.s2);
|
||||
str += strlen(str);
|
||||
break;
|
||||
}
|
||||
|
||||
(void) sprintf(str, "\n");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Indicate whether or not the portmapper daemon is running on the local host.
|
||||
*
|
||||
* Returns:
|
||||
* -1 Error. errno set.
|
||||
* 0 Portmapper daemon is NOT running on the local host.
|
||||
* 1 Portmapper daemon is running on the local host.
|
||||
*/
|
||||
int
|
||||
local_portmapper_running()
|
||||
{
|
||||
static int status;
|
||||
static int cached = 0;
|
||||
|
||||
if (!cached) {
|
||||
struct sockaddr_in addr;
|
||||
|
||||
if (local_sockaddr_in(&addr)) {
|
||||
status = -1;
|
||||
}
|
||||
else {
|
||||
CLIENT* client;
|
||||
int socket = RPC_ANYSOCK;
|
||||
|
||||
addr.sin_port = (short)htons((short)PMAPPORT);
|
||||
|
||||
if ((client = clnttcp_create(&addr, PMAPPROG,
|
||||
PMAPVERS, &socket, 50, 500)) == NULL) {
|
||||
status = 0;
|
||||
|
||||
unotice("local_portmapper_running(): clnttcp_create() "
|
||||
"failure: %s", clnt_spcreateerror(""));
|
||||
uinfo("Portmapper daemon is not running on local host");
|
||||
}
|
||||
else {
|
||||
status = 1;
|
||||
|
||||
auth_destroy(client->cl_auth);
|
||||
clnt_destroy(client);
|
||||
(void)close(socket);
|
||||
}
|
||||
}
|
||||
|
||||
cached = 1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef RPCUTIL_H
|
||||
#define RPCUTIL_H
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
char *clnt_errmsg(CLIENT* clnt);
|
||||
int local_portmapper_running();
|
||||
|
||||
#endif
|
|
@ -1,148 +0,0 @@
|
|||
#include <ldmconfig.h>
|
||||
#ifdef NO_SETENV
|
||||
/*
|
||||
* Copyright (c) 1987 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "setenv.h"
|
||||
|
||||
/*
|
||||
* _findenv --
|
||||
* Returns pointer to value associated with name, if any, else NULL.
|
||||
* Sets offset to be the offset of the name/value combination in the
|
||||
* environmental array, for use by setenv(3) and unsetenv(3).
|
||||
* Explicitly removes '=' in argument name.
|
||||
*
|
||||
* This routine *should* be a static; don't use it.
|
||||
*/
|
||||
static char *
|
||||
_findenv(const char *name, size_t *offset)
|
||||
{
|
||||
extern char **environ;
|
||||
size_t len;
|
||||
const char *cC;
|
||||
char *C;
|
||||
char **P;
|
||||
|
||||
for (cC = name, len = 0; *cC && *cC != '='; ) {
|
||||
++cC;
|
||||
++len;
|
||||
}
|
||||
for (P = environ; *P; ++P)
|
||||
if (!strncmp(*P, name, len))
|
||||
if (*(C = *P + len) == '=') {
|
||||
*offset = (size_t)(P - environ);
|
||||
return(++C);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* setenv --
|
||||
* Set the value of the environmental variable "name" to be
|
||||
* "value". If rewrite is set, replace any current value.
|
||||
*/
|
||||
int
|
||||
setenv(const char *name, const char *value, int rewrite)
|
||||
{
|
||||
extern char **environ;
|
||||
static int alloced; /* if allocated space before */
|
||||
char *C;
|
||||
size_t l_value, offset;
|
||||
|
||||
if (*value == '=') /* no `=' in value */
|
||||
++value;
|
||||
l_value = strlen(value);
|
||||
if ((C = _findenv(name, &offset))) { /* find if already exists */
|
||||
if (!rewrite)
|
||||
return (0);
|
||||
if (strlen(C) >= l_value) { /* old larger; copy over */
|
||||
while (*C++ = *value++)
|
||||
; /* empty */
|
||||
return (0);
|
||||
}
|
||||
} else { /* create new slot */
|
||||
size_t cnt;
|
||||
char **P;
|
||||
|
||||
for (P = environ, cnt = 0; *P; ) {
|
||||
++P;
|
||||
++cnt;
|
||||
}
|
||||
if (alloced) { /* just increase size */
|
||||
environ = (char **)realloc((char *)environ,
|
||||
(size_t)(sizeof(char *) * (cnt + 2)));
|
||||
if (!environ)
|
||||
return (-1);
|
||||
}
|
||||
else { /* get new space */
|
||||
alloced = 1; /* copy old entries into it */
|
||||
P = (char **)malloc((size_t)(sizeof(char *) *
|
||||
(cnt + 2)));
|
||||
if (!P)
|
||||
return (-1);
|
||||
(void)memcpy(P, environ,
|
||||
(size_t)(cnt * sizeof(char *)));
|
||||
environ = P;
|
||||
}
|
||||
environ[cnt + 1] = NULL;
|
||||
offset = cnt;
|
||||
}
|
||||
{
|
||||
const char *C;
|
||||
for (C = name; *C && *C != '='; )
|
||||
++C; /* no `=' in name */
|
||||
if (!(environ[offset] = /* name + `=' + value */
|
||||
malloc((size_t)(C - name) + l_value + 2))) /* no overflow */
|
||||
return (-1);
|
||||
}
|
||||
for (C = environ[offset]; (*C = *name++) && *C != '='; ) /* "=" is OK */
|
||||
++C;
|
||||
;
|
||||
for (*C++ = '='; *C++ = *value++; )
|
||||
; /* empty */
|
||||
return (0);
|
||||
}
|
||||
#else /* NO_SETENV *//* End of BSD copywrited inclusion */
|
||||
void
|
||||
_nada_setenv(void)
|
||||
{
|
||||
/* Do nothing
|
||||
* except declare a function which does nothing
|
||||
* except shut up compilers and archivers
|
||||
* that complain about empty files.
|
||||
*/
|
||||
}
|
||||
#endif /* NO_SETENV */
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef LDM_SETENV_H
|
||||
#define LDM_SETENV_H
|
||||
|
||||
#ifdef NO_SETENV
|
||||
extern int
|
||||
setenv(const char *name, const char *value, int rewrite);
|
||||
#else /* NO_SETENV */
|
||||
void
|
||||
_nada_setenv(void);
|
||||
#endif /* NO_SETENV */
|
||||
|
||||
#endif /* !LDM_SETENV_H */
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* This module contains statistical mathematical functions.
|
||||
*
|
||||
* $Id: statsMath.c,v 1.1.2.3 2005/07/05 18:24:00 steve Exp $
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "statsMath.h"
|
||||
|
||||
|
||||
/*
|
||||
* Returns the sum of binomial coefficients, nCi, where i goes from 0 through
|
||||
* k, inclusive.
|
||||
*
|
||||
* Arguments:
|
||||
* n The number of possibilities.
|
||||
* k The maximum number of unordered outcomes.
|
||||
* Returns:
|
||||
* NaN The value could not be computed.
|
||||
* HUGE_VAL The value is too large to be represented.
|
||||
* else the sum of the binomial coefficients, nCi, where i goes
|
||||
* from 0 through k, inclusive.
|
||||
*/
|
||||
double
|
||||
sumBinomCoeff(
|
||||
unsigned n,
|
||||
unsigned k)
|
||||
{
|
||||
double sum = 1; /* nC0 coefficient */
|
||||
int i;
|
||||
|
||||
for (i = 0; i < k; i++)
|
||||
sum += ((double)(n - i) / (i + 1)) * sum; /* += nC(i+1) */
|
||||
|
||||
return floor(sum + 0.5);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef STATS_MATH_H
|
||||
#define STATS_MATH_H
|
||||
|
||||
extern double sumBinomCoeff(
|
||||
unsigned n,
|
||||
unsigned k);
|
||||
|
||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||
# $Id: Makefile,v 1.1.18.1 2005/06/22 22:52:30 steve Exp $
|
||||
|
||||
include ../macros.make
|
||||
|
||||
TAG_SRCS = *.c *.h \
|
||||
../misc/*.c ../misc/*.h \
|
||||
../ulog/*.c ../ulog/*.h \
|
||||
../protocol/*.c ../protocol/*.h \
|
||||
../server/*.c ../server/*.h \
|
||||
../pq/*.c ../pq/*.h
|
||||
PROGRAM = notifyme
|
||||
include ../simple_program.make
|
||||
include ../rules.make
|
||||
include depends
|
|
@ -1,11 +0,0 @@
|
|||
notifyme.o: ../config/ldmconfig.h
|
||||
notifyme.o: ../misc/inetutil.h
|
||||
notifyme.o: ../protocol/atofeedt.h
|
||||
notifyme.o: ../protocol/h_clnt.h
|
||||
notifyme.o: ../protocol/ldm.h
|
||||
notifyme.o: ../protocol/ldm5.h
|
||||
notifyme.o: ../protocol/ldm5_clnt.h
|
||||
notifyme.o: ../protocol/ldmprint.h
|
||||
notifyme.o: ../protocol/timestamp.h
|
||||
notifyme.o: ../ulog/ulog.h
|
||||
notifyme.o: notifyme.c
|
|
@ -1,80 +0,0 @@
|
|||
'\"
|
||||
'\" $Header: /cvsroot/ldm/src/notifyme/notifyme.1,v 1.11.22.1 2009/06/18 16:14:42 steve Exp $
|
||||
.TH NOTIFYME 1 "$Date: 2009/06/18 16:14:42 $"
|
||||
.SH NAME
|
||||
notifyme - ldm NOTIFYME example client
|
||||
.SH "UNIX SYNOPSIS"
|
||||
\fBnotifyme \fR[\fB\-x -v\fR] [\fB\-l \fIlogfile\fR]
|
||||
.BI [\-h " remote" ]
|
||||
.BI [\-p " pattern" ]
|
||||
.BI [\-f " feedtype" ]
|
||||
.BI [\-o " offset" ]
|
||||
.BI [\-t " timeout" ]
|
||||
.BI [\-T " TotalTimeo" ]
|
||||
.SH DESCRIPTION
|
||||
This program receives notification messages from the
|
||||
Unidata Local Data Management system (ldm) and optionally
|
||||
prints the notification information with timestamps.
|
||||
It establishes a connection with the LDM server at \fIremote\fR and requests
|
||||
notification of the arrival data whose identifier matches \fIpattern\fR.
|
||||
As data arrives at the server, notification is sent to this program.
|
||||
.LP
|
||||
This program is an example of how to use ldm4 notification.
|
||||
.SH OPTIONS
|
||||
.TP 8
|
||||
.BI \-f " feedtype"
|
||||
Requests that notification of data that originates in a feed type of type
|
||||
\fIfeedtype\fP be sent along.
|
||||
The default is `ANY'.
|
||||
.TP
|
||||
.BI \-h " remote"
|
||||
Requests notification from the ldm server on \fIremote\fR. Default
|
||||
is "localhost".
|
||||
.TP
|
||||
.BI \-l " logfile"
|
||||
the path name of a file to be used as the log file for the process. By
|
||||
default messages are sent to syslogd(8). If a HUP signal is received, the
|
||||
log file is closed and then reopened.
|
||||
.TP
|
||||
.BI \-o " offset"
|
||||
Requests notification for data that arrived \fIoffset\fP seconds before NOW.
|
||||
.TP
|
||||
.BI \-p " pattern"
|
||||
Requests that notification of data be sent along that matches \fIpattern\fP.
|
||||
The default is `\fB.*\fP'.
|
||||
.TP
|
||||
.BI \-T " TotalTimeo"
|
||||
Give up attempting to make a connection after
|
||||
\fITotalTimeo\fR seconds. Any partially built up client connnection
|
||||
is destroyed and we start over.
|
||||
.TP
|
||||
.BI \-t " timeout"
|
||||
Sets the RPC timeout on FEEDME requests to \fItimeout\fR seconds.
|
||||
.TP
|
||||
.B \-v
|
||||
Verbose flag. If present, the log will contain a line for
|
||||
each product that was received. Each line reports (1) the current system time,
|
||||
(2) the string 'notifyme', (3) the product size, (4) the time the product
|
||||
was injected into the IDD, (5) the feed type, (6) a sequence number, and
|
||||
(7) the product ID with the actual product time. (If you take the difference
|
||||
between the first and fourth fields, you can see how long it took the product
|
||||
to arrive at the host.)
|
||||
.TP
|
||||
.BI \-x
|
||||
Requests that debugging information also be printed.
|
||||
.SH EXAMPLE
|
||||
The command
|
||||
.RS +4
|
||||
.nf
|
||||
notifyme -v -l - -h localhost
|
||||
.fi
|
||||
.RE
|
||||
will let you watch the data come in on `localhost'.
|
||||
.SH "SEE ALSO"
|
||||
ldmd(1), ldmd.conf(5), feedme(1)
|
||||
.SH DIAGNOSTICS
|
||||
Error messages and log messages are written to the
|
||||
log file.
|
||||
.SH BUGS and LIMITATIONS
|
||||
Doesn't do anything particularly useful. If you leave off the -v
|
||||
flag, it doesn't do anything useful.
|
|
@ -1,417 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: notifyme.c,v 1.63.12.8 2008/04/15 16:34:07 steve Exp $ */
|
||||
|
||||
/*
|
||||
* get notification
|
||||
*/
|
||||
|
||||
#include <ldmconfig.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include "ldm5.h"
|
||||
#include "globals.h"
|
||||
#include "ldmprint.h"
|
||||
#include "atofeedt.h"
|
||||
#include "ulog.h"
|
||||
#include "inetutil.h"
|
||||
#include "ldm5_clnt.h"
|
||||
#include "RegularExpressions.h"
|
||||
|
||||
#ifdef NO_ATEXIT
|
||||
#include "atexit.h"
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_REMOTE
|
||||
#define DEFAULT_REMOTE "localhost"
|
||||
#endif
|
||||
#ifndef DEFAULT_TIMEO
|
||||
#define DEFAULT_TIMEO 25
|
||||
#endif
|
||||
#ifndef DEFAULT_TOTALTIMEO
|
||||
#define DEFAULT_TOTALTIMEO (12*DEFAULT_TIMEO)
|
||||
#endif
|
||||
#ifndef DEFAULT_FEEDTYPE
|
||||
#define DEFAULT_FEEDTYPE ANY
|
||||
#endif
|
||||
#ifndef DEFAULT_PATTERN
|
||||
#define DEFAULT_PATTERN ".*"
|
||||
#endif
|
||||
|
||||
|
||||
static const char *remote = DEFAULT_REMOTE; /* hostname of data remote */
|
||||
static ldm_replyt reply = { OK };
|
||||
|
||||
|
||||
/*
|
||||
* Called at exit.
|
||||
* This callback routine registered by atexit().
|
||||
*/
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
unotice("exiting");
|
||||
|
||||
/* TODO: sign off */
|
||||
|
||||
(void) closeulog();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called upon receipt of signals.
|
||||
* This callback routine registered in set_sigactions() .
|
||||
*/
|
||||
static void
|
||||
signal_handler(int sig)
|
||||
{
|
||||
#ifdef SVR3SIGNALS
|
||||
/*
|
||||
* Some systems reset handler to SIG_DFL upon entry to handler.
|
||||
* In that case, we reregister our handler.
|
||||
*/
|
||||
(void) signal(sig, signal_handler);
|
||||
#endif
|
||||
switch(sig) {
|
||||
case SIGHUP :
|
||||
return;
|
||||
case SIGINT :
|
||||
/*FALLTHROUGH*/
|
||||
case SIGTERM :
|
||||
done = !0;
|
||||
return;
|
||||
case SIGUSR1 :
|
||||
return;
|
||||
case SIGUSR2 :
|
||||
toggleulogpri(LOG_INFO);
|
||||
return;
|
||||
case SIGPIPE :
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_sigactions(void)
|
||||
{
|
||||
#ifndef NO_POSIXSIGNALS
|
||||
struct sigaction sigact;
|
||||
|
||||
sigact.sa_handler = signal_handler;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
|
||||
(void) sigaction(SIGHUP, &sigact, NULL);
|
||||
(void) sigaction(SIGINT, &sigact, NULL);
|
||||
(void) sigaction(SIGTERM, &sigact, NULL);
|
||||
(void) sigaction(SIGUSR1, &sigact, NULL);
|
||||
(void) sigaction(SIGUSR2, &sigact, NULL);
|
||||
(void) sigaction(SIGPIPE, &sigact, NULL);
|
||||
#else
|
||||
(void) signal(SIGHUP, signal_handler);
|
||||
(void) signal(SIGINT, signal_handler);
|
||||
(void) signal(SIGTERM, signal_handler);
|
||||
(void) signal(SIGUSR1, signal_handler);
|
||||
(void) signal(SIGUSR2, signal_handler);
|
||||
(void) signal(SIGPIPE, signal_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
usage(
|
||||
char *av0 /* id string */
|
||||
)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"Usage: %s [options] \t\nOptions:\n", av0);
|
||||
(void)fprintf(stderr,
|
||||
"\t-v Verbose, report each notification\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-x Debug mode\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-l logfile Send log info to file (default uses syslogd)\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-h remote Have \"remote\" send us data (default \"%s\")\n",
|
||||
DEFAULT_REMOTE);
|
||||
(void)fprintf(stderr,
|
||||
"\t-f feedtype Interested in products from feed \"feedtype\" (default %s)\n", s_feedtypet(DEFAULT_FEEDTYPE));
|
||||
(void)fprintf(stderr,
|
||||
"\t-p pattern Interested in products matching \"pattern\" (default \"%s\")\n", DEFAULT_PATTERN);
|
||||
(void)fprintf(stderr,
|
||||
"\t-o offset Set the \"from\" time offset secs before now\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-t timeout Set RPC timeout to \"timeout\" seconds (default %d)\n",
|
||||
DEFAULT_TIMEO);
|
||||
(void)fprintf(stderr,
|
||||
"\t-T TotalTimeo Give up after this many secs (default %d)\n",
|
||||
DEFAULT_TOTALTIMEO);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
static prod_class clss;
|
||||
|
||||
/*
|
||||
* The RPC dispatch routine for this program.
|
||||
* Registered as a callback by svc_register() below.
|
||||
* Note that only NULLPROC and NOTIFICATION rpc procs are
|
||||
* handled by this program.
|
||||
*/
|
||||
static void
|
||||
notifymeprog_5(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
{
|
||||
prod_info notice;
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
|
||||
case NULLPROC:
|
||||
svc_sendreply(transp, (xdrproc_t)xdr_void, (caddr_t)NULL);
|
||||
return;
|
||||
|
||||
case NOTIFICATION:
|
||||
(void) memset((char*)¬ice, 0, sizeof(notice));
|
||||
if (!svc_getargs(transp, (xdrproc_t)xdr_prod_info,
|
||||
(caddr_t)¬ice))
|
||||
{
|
||||
svcerr_decode(transp);
|
||||
return;
|
||||
}
|
||||
|
||||
(void)exitIfDone(0);
|
||||
|
||||
/*
|
||||
* Update the request filter with the timestamp
|
||||
* we just recieved.
|
||||
* N.B.: There can still be duplicates after
|
||||
* a reconnect.
|
||||
*/
|
||||
clss.from = notice.arrival;
|
||||
timestamp_incr(&clss.from);
|
||||
|
||||
|
||||
/*
|
||||
* your code here, example just logs it
|
||||
*/
|
||||
uinfo("%s", s_prod_info(NULL, 0, ¬ice, ulogIsDebug()));
|
||||
|
||||
|
||||
if(!svc_sendreply(transp, (xdrproc_t)xdr_ldm_replyt,
|
||||
(caddr_t) &reply))
|
||||
{
|
||||
svcerr_systemerr(transp);
|
||||
}
|
||||
|
||||
(void)exitIfDone(0);
|
||||
|
||||
if(!svc_freeargs(transp, xdr_prod_info, (caddr_t) ¬ice)) {
|
||||
uerror("unable to free arguments");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
svcerr_noproc(transp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int ac, char *av[])
|
||||
{
|
||||
char *logfname = 0;
|
||||
unsigned timeo = DEFAULT_TIMEO;
|
||||
unsigned interval = DEFAULT_TIMEO;
|
||||
unsigned TotalTimeo = DEFAULT_TOTALTIMEO;
|
||||
prod_spec spec;
|
||||
int status;
|
||||
prod_class_t *clssp;
|
||||
unsigned remotePort = LDM_PORT;
|
||||
|
||||
if(set_timestamp(&clss.from) != 0)
|
||||
{
|
||||
fprintf(stderr, "Couldn't set timestamp\n");
|
||||
exit(1);
|
||||
}
|
||||
clss.to = TS_ENDT;
|
||||
clss.psa.psa_len = 1;
|
||||
clss.psa.psa_val = &spec;
|
||||
spec.feedtype = DEFAULT_FEEDTYPE;
|
||||
spec.pattern = DEFAULT_PATTERN;
|
||||
|
||||
{ /* Begin getopt block */
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
extern char *optarg;
|
||||
int ch;
|
||||
int logmask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) |
|
||||
LOG_MASK(LOG_NOTICE));
|
||||
int fterr;
|
||||
|
||||
opterr = 1;
|
||||
|
||||
while ((ch = getopt(ac, av, "vxl:f:o:t:h:P:p:T:")) != EOF)
|
||||
switch (ch) {
|
||||
case 'v':
|
||||
logmask |= LOG_MASK(LOG_INFO);
|
||||
break;
|
||||
case 'x':
|
||||
logmask |= LOG_MASK(LOG_DEBUG);
|
||||
break;
|
||||
case 'l':
|
||||
logfname = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
remote = optarg;
|
||||
break;
|
||||
case 'P': {
|
||||
char* suffix = "";
|
||||
long port;
|
||||
|
||||
errno = 0;
|
||||
port = strtol(optarg, &suffix, 0);
|
||||
|
||||
if (0 != errno || 0 != *suffix ||
|
||||
0 >= port || 0xffff < port) {
|
||||
|
||||
(void)fprintf(stderr, "%s: invalid port %s\n",
|
||||
av[0], optarg);
|
||||
usage(av[0]);
|
||||
}
|
||||
|
||||
remotePort = (unsigned)port;
|
||||
|
||||
break;
|
||||
}
|
||||
case 'p':
|
||||
spec.pattern = optarg;
|
||||
/* compiled below */
|
||||
break;
|
||||
case 'f':
|
||||
fterr = strfeedtypet(optarg, &spec.feedtype);
|
||||
if(fterr != FEEDTYPE_OK)
|
||||
{
|
||||
fprintf(stderr, "Bad feedtype \"%s\", %s\n",
|
||||
optarg, strfeederr(fterr));
|
||||
usage(av[0]);
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
clss.from.tv_sec -= atoi(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
TotalTimeo = atoi(optarg);
|
||||
if(TotalTimeo == 0)
|
||||
{
|
||||
fprintf(stderr, "%s: invalid TotalTimeo %s", av[0], optarg);
|
||||
usage(av[0]);
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
timeo = (unsigned)atoi(optarg);
|
||||
if(timeo == 0 || timeo > 32767)
|
||||
{
|
||||
fprintf(stderr, "%s: invalid timeout %s", av[0], optarg);
|
||||
usage(av[0]);
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
usage(av[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if(ac - optind > 0)
|
||||
usage(av[0]);
|
||||
|
||||
if (re_isPathological(spec.pattern))
|
||||
{
|
||||
fprintf(stderr, "Adjusting pathological regular-expression: "
|
||||
"\"%s\"\n", spec.pattern);
|
||||
re_vetSpec(spec.pattern);
|
||||
}
|
||||
status = regcomp(&spec.rgx,
|
||||
spec.pattern,
|
||||
REG_EXTENDED|REG_NOSUB);
|
||||
if(status != 0)
|
||||
{
|
||||
fprintf(stderr, "Bad regular expression \"%s\"\n",
|
||||
spec.pattern);
|
||||
usage(av[0]);
|
||||
}
|
||||
|
||||
(void) setulogmask(logmask);
|
||||
|
||||
if(TotalTimeo < timeo)
|
||||
{
|
||||
fprintf(stderr, "TotalTimeo %u < timeo %u\n",
|
||||
TotalTimeo, timeo);
|
||||
usage(av[0]);
|
||||
}
|
||||
|
||||
} /* End getopt block */
|
||||
|
||||
/*
|
||||
* initialize logger
|
||||
*/
|
||||
(void) openulog(ubasename(av[0]),
|
||||
(LOG_CONS|LOG_PID), LOG_LDM, logfname);
|
||||
unotice("Starting Up: %s: %s",
|
||||
remote,
|
||||
s_prod_class(NULL, 0, &clss));
|
||||
|
||||
/*
|
||||
* register exit handler
|
||||
*/
|
||||
if(atexit(cleanup) != 0)
|
||||
{
|
||||
serror("atexit");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* set up signal handlers
|
||||
*/
|
||||
set_sigactions();
|
||||
|
||||
|
||||
/*
|
||||
* Try forever.
|
||||
*/
|
||||
while (exitIfDone(0))
|
||||
{
|
||||
clssp = &clss;
|
||||
status = forn5(NOTIFYME, remote, &clssp,
|
||||
timeo, TotalTimeo, notifymeprog_5);
|
||||
|
||||
(void)exitIfDone(0);
|
||||
|
||||
switch(status) {
|
||||
/* problems with remote, retry */
|
||||
case ECONNABORTED:
|
||||
case ECONNRESET:
|
||||
case ETIMEDOUT:
|
||||
case ECONNREFUSED:
|
||||
sleep(interval);
|
||||
break;
|
||||
case 0:
|
||||
/* assert(done); */
|
||||
break;
|
||||
default:
|
||||
/* some wierd error */
|
||||
done = 1;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
/*NOTREACHED*/
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
# $Id: Makefile,v 3.1 2003/02/26 23:43:48 steve Exp $
|
||||
#
|
||||
# Development Makefile for pq
|
||||
#
|
||||
include ../macros.make
|
||||
|
||||
INCLUDES = -I../config -I../misc -I../ulog -I../protocol
|
||||
TAG_SRCS = \
|
||||
../misc/*.c ../misc/*.h \
|
||||
../ulog/*.c ../ulog/*.h \
|
||||
../protocol/*.c ../protocol/*.h
|
||||
LDLIBS = -lm
|
||||
LIBRARY = ../libldm.a
|
||||
LINT_LIBRARY = pq
|
||||
HEADERS = fbits.h lcm.h pq.h
|
||||
MANUALS = pq.3
|
||||
LIB_CSRCS = pq.c lcm.c
|
||||
GARBAGE = pqt
|
||||
|
||||
# inventory
|
||||
PACKING_LIST = \
|
||||
depends \
|
||||
fbits.h \
|
||||
lcm.h \
|
||||
pq.h \
|
||||
$(LIB_CSRCS) \
|
||||
Makefile \
|
||||
pq.3
|
||||
|
||||
all: archived_files
|
||||
|
||||
test: pqt
|
||||
|
||||
include ../rules.make
|
||||
include depends
|
|
@ -1,28 +0,0 @@
|
|||
lcm.o: ../config/ldmconfig.h
|
||||
lcm.o: lcm.c
|
||||
lcm.o: lcm.h
|
||||
pq.o: ../config/ldmconfig.h
|
||||
pq.o: ../misc/fsStats.h
|
||||
pq.o: ../protocol/ldm.h
|
||||
pq.o: ../protocol/ldm_xlen.h
|
||||
pq.o: ../protocol/ldmprint.h
|
||||
pq.o: ../protocol/prod_class.h
|
||||
pq.o: ../protocol/prod_info.h
|
||||
pq.o: ../protocol/timestamp.h
|
||||
pq.o: ../rpc/auth.h
|
||||
pq.o: ../rpc/auth_unix.h
|
||||
pq.o: ../rpc/clnt.h
|
||||
pq.o: ../rpc/pmap_clnt.h
|
||||
pq.o: ../rpc/pmap_prot.h
|
||||
pq.o: ../rpc/rpc.h
|
||||
pq.o: ../rpc/rpc_msg.h
|
||||
pq.o: ../rpc/svc.h
|
||||
pq.o: ../rpc/svc_auth.h
|
||||
pq.o: ../rpc/types.h
|
||||
pq.o: ../rpc/xdr.h
|
||||
pq.o: ../ulog/ulog.h
|
||||
pq.o: fbits.h
|
||||
pq.o: lcm.h
|
||||
pq.o: pq.c
|
||||
pq.o: pq.h
|
||||
randomTest.o: randomTest.c
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995, University Corporation for Atmospheric Research
|
||||
* See top level COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: fbits.h,v 1.2.22.1 2004/10/28 19:24:38 steve Exp $ */
|
||||
|
||||
#ifndef _FBITS_H_
|
||||
#define _FBITS_H_
|
||||
|
||||
/*
|
||||
* Macros for dealing with flag bits.
|
||||
*/
|
||||
#define fSet(t, f) ((t) |= (f))
|
||||
#define fClr(t, f) ((t) &= ~(unsigned long)(f))
|
||||
#define fIsSet(t, f) ((t) & (f))
|
||||
#define fMask(t, f) ((t) & ~(unsigned long)(f))
|
||||
|
||||
/*
|
||||
* Propositions
|
||||
*/
|
||||
/* a implies b */
|
||||
#define pIf(a,b) (!(a) || (b))
|
||||
/* a if and only if b, use == when it makes sense */
|
||||
#define pIff(a,b) (((a) && (b)) || (!(a) && !(b)))
|
||||
|
||||
#endif /*!FBITS_H_*/
|
164
ldm/src/pq/lcm.c
164
ldm/src/pq/lcm.c
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995, University Corporation for Atmospheric Research
|
||||
* See top level COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: lcm.c,v 1.3 1998/10/16 19:28:13 steve Exp $ */
|
||||
|
||||
#include <ldmconfig.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#ifndef NDEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include "lcm.h"
|
||||
|
||||
/*
|
||||
* Compute the Greatest Common Divisor
|
||||
* of mm and nn using modified Euclid's algorithm
|
||||
*/
|
||||
static unsigned long
|
||||
gcd0(unsigned long mm, unsigned long nn)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
assert(nn <= mm);
|
||||
|
||||
while(nn > 1)
|
||||
{
|
||||
tmp = nn;
|
||||
nn = mm % nn;
|
||||
mm = tmp;
|
||||
}
|
||||
if(nn == 0)
|
||||
return mm;
|
||||
/* else */
|
||||
assert(nn == 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Public driver for above
|
||||
*/
|
||||
unsigned long
|
||||
gcd(unsigned long mm, unsigned long nn)
|
||||
{
|
||||
if(mm < nn)
|
||||
{
|
||||
/* swap */
|
||||
unsigned long tmp = mm;
|
||||
mm = nn;
|
||||
nn = tmp;
|
||||
}
|
||||
return gcd0(mm, nn);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compute the Least Common Multiple
|
||||
* of mm and nn.
|
||||
* If the result would overflow, return
|
||||
* ULONG_MAX and set errno to ERANGE.
|
||||
* (ERANGE chosen because strtoul uses this.
|
||||
* I personally think EDOM would be a better choice.)
|
||||
*/
|
||||
unsigned long
|
||||
lcm(unsigned long mm, unsigned long nn)
|
||||
{
|
||||
unsigned long gg;
|
||||
|
||||
if(mm == nn)
|
||||
return mm;
|
||||
|
||||
if(mm < nn)
|
||||
{
|
||||
/* swap */
|
||||
gg = mm;
|
||||
mm = nn;
|
||||
nn = gg;
|
||||
}
|
||||
|
||||
if(nn == 0)
|
||||
return 0;
|
||||
|
||||
if(nn == 1)
|
||||
return mm;
|
||||
|
||||
gg = gcd0(mm, nn);
|
||||
assert(gg != 0); /* covered by (nn == 0) case above */
|
||||
mm /= gg;
|
||||
|
||||
/* bounds check */
|
||||
gg = ULONG_MAX/nn;
|
||||
if(mm < gg || (mm == gg && ((ULONG_MAX % nn) != 0)))
|
||||
return (mm * nn);
|
||||
/* else, overflow */
|
||||
errno = ERANGE;
|
||||
return ULONG_MAX;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_LCM /** Test driver **/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef ENOERR
|
||||
#define ENOERR 0
|
||||
#endif
|
||||
|
||||
static int
|
||||
ul_arg(const char *const optarg, unsigned long *result)
|
||||
{
|
||||
char *cp;
|
||||
unsigned long ul = strtoul(optarg, &cp, 10);
|
||||
if(ul == ULONG_MAX && errno == ERANGE)
|
||||
return ERANGE;
|
||||
if(ul == 0 && cp == optarg)
|
||||
return EDOM;
|
||||
*result = ul;
|
||||
return ENOERR;
|
||||
}
|
||||
|
||||
|
||||
main(int ac, char *av[])
|
||||
{
|
||||
unsigned long mm = 0;
|
||||
unsigned long nn = 0;
|
||||
unsigned long gg = 0;
|
||||
|
||||
if(ac != 3)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s mm nn\n",
|
||||
av[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(ul_arg(av[1], &mm) != ENOERR)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Illegal operand \"%s\"\n",
|
||||
av[1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(ul_arg(av[2], &nn) != ENOERR)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Illegal operand \"%s\"\n",
|
||||
av[2]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
gg = gcd(mm,nn);
|
||||
|
||||
printf("gcd of %lu, %lu is %lu\n", mm, nn, gg);
|
||||
|
||||
gg = lcm(mm,nn);
|
||||
if(gg == ULONG_MAX && errno == ERANGE)
|
||||
fprintf(stderr,"Overflow\n");
|
||||
|
||||
printf("lcm of %lu, %lu is %lu\n", mm, nn, gg);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
#endif /* TEST_LCM */
|
|
@ -1,12 +0,0 @@
|
|||
/* $Id: lcm.h,v 1.1 1995/04/06 00:07:10 davis Exp $ */
|
||||
|
||||
#ifndef _LCM_H_
|
||||
#define _LCM_H_
|
||||
|
||||
extern unsigned long
|
||||
gcd(unsigned long mm, unsigned long nn);
|
||||
|
||||
extern unsigned long
|
||||
lcm(unsigned long mm, unsigned long nn);
|
||||
|
||||
#endif /*!_LCM_H_*/
|
384
ldm/src/pq/pq.3
384
ldm/src/pq/pq.3
|
@ -1,384 +0,0 @@
|
|||
." $Id: pq.3,v 2.5.14.2.2.1 2008/04/15 16:34:07 steve Exp $
|
||||
." $__Header$
|
||||
.TH PQ 3 "$Date: 2008/04/15 16:34:07 $" "Printed: \n(yr.\n(mo.\n(dy" "UNIDATA LIBRARY FUNCTIONS"
|
||||
.SH NAME
|
||||
pq,
|
||||
pq_create, pq_open, pq_close,
|
||||
pq_insert,
|
||||
pqe_new, pqe_discard, pqe_insert,
|
||||
pq_cset, pq_ctimestamp, pq_sequence, pq_seqdel,
|
||||
pq_pagesize, pq_higwater,
|
||||
pq_suspend - LDM product queue inteface
|
||||
.SH SYNOPSIS
|
||||
#include "pq.h"
|
||||
.na
|
||||
.nh
|
||||
.HP
|
||||
int\ pq_create(const\ char\ *\fIpath\fP, mode_t\ \fImode\fP, int\ \fIpflags\fP, size_t\ \fIalign\fP, off_t\ \fIinitialsz\fP, size_t\ \fInproducts\fP, pqueue\ **\fIpqp\fP);
|
||||
.HP
|
||||
\fRint\ pq_open(const\ char\ *\fIpath\fP, int\ \fIpflags\fP, pqueue\ **\fIpqp\fP);
|
||||
.HP
|
||||
int\ pq_close(pqueue\ *\fIpq\fP);
|
||||
.HP
|
||||
int\ pq_insert(pqueue\ *\fIpq\fP, const\ product\ *\fIprod\fP);
|
||||
.HP
|
||||
void\ pq_cset(pqueue\ *\fIpq\fP, const\ struct\ timeval\ *\fItvp\fP);
|
||||
.HP
|
||||
void\ pq_ctimestamp(const\ pqueue\ *\fIpq\fP, struct\ timeval\ *\fItvp\fP);
|
||||
.HP
|
||||
int\ pq_sequence(pqueue\ *\fIpq\fP, pq_match\ \fImt\fP, const\ prod_class_t\ *\fIclass\fP, pq_seqfunc\ *\fIifMatch\fP, void\ *\fIotherargs\fP);
|
||||
.HP
|
||||
int\ pq_seqdel(pqueue\ *\fIpq\fP, pq_match\ \fImt\fP, const\ prod_class_t\ *\fIclss\fP, size_t\ *\fIextentp\fP, time_t\ *\fItimestampp\fP);
|
||||
.HP
|
||||
int\ pq_pagesize(const\ pqueue\ *\fIpq\fP);
|
||||
.HP
|
||||
int\ pq_highwater(pqueue\ *\fIpq\fP, off_t\ *\fIhighwaterp\fP, size_t\ *\fImaxproductsp\fP);
|
||||
.HP
|
||||
int\ pq_suspend(unsigned\ int\ \fImaxsleep\fP);
|
||||
.HP
|
||||
int\ pq_get_write_count(const\ char*\ \fIpath\fP, unsigned*\ \fIcount\fP);
|
||||
.HP
|
||||
int pq_clear_write_count(const\ char*\ \fIpath\fP);
|
||||
.ad
|
||||
.hy
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
The Product Queue interface, \fBPQ\fP, provides access to a persistent and
|
||||
sharable queue of LDM data products. This implementation is a
|
||||
database, a collection of LDM products keyed by the time a product was
|
||||
inserted in the database, by the product offset in the queue, by the
|
||||
product signature (to ensure uniqueness), and by the product size (for
|
||||
efficiently recycling memory).
|
||||
.LP
|
||||
By "shared" we mean the queue may be accessed by multiple processes.
|
||||
Contention control is handled below the level of this interface by use of
|
||||
POSIX fnctl() file region locking.
|
||||
.LP
|
||||
By "persistent" we mean the queue outlasts any particular process
|
||||
which might access it. The queue appears as an object in the file system.
|
||||
Products in the queue will not disappear due to a program
|
||||
or system crash.
|
||||
.LP
|
||||
The library maintains a cursor value for each queue and process which is
|
||||
simply a timestamp (struct timeval). This is used by the scanning functions
|
||||
\fIpq_sequence\fP() and \fIpq_seqdel\fP(). The value of the cursor is set
|
||||
or changed by calls to \fIpq_cset\fP(), \fIpq_sequence\fP(),
|
||||
or \fIpq_seqdel\fP(). It may be queried by a call to \fIpq_ctimestamp\fP().
|
||||
.LP
|
||||
The ldm product "signature" is used by the package to detect duplicate
|
||||
products. Attempts to insert products whose signature is already in the queue
|
||||
will fail.
|
||||
.LP
|
||||
Requests for storage when the queue is full
|
||||
will cause the library to delete the oldest products, combining
|
||||
adjacent deleted products when possible, until enough
|
||||
space is available.
|
||||
.LP
|
||||
All of the functions return ENOERR (0) if successful.
|
||||
If a system call made in the library fails, causing failure of one of
|
||||
these functions, the system errno value is returned.
|
||||
Most internal errors are mapped into system errors as well,
|
||||
particularly \fBEINVAL\fP for invalid argument and \fBEIO\fP for xdr
|
||||
encoding problems.
|
||||
The ulog(3) package is used for error reporting below the interface,
|
||||
logging descriptive information about problems at the point where they
|
||||
occur.
|
||||
.SS Routines
|
||||
.nf
|
||||
#include "pq.h"
|
||||
.fi
|
||||
.nf
|
||||
cc -I/usr/local/ldm/include ... -L/usr/local/ldm/lib -lldm
|
||||
.fi
|
||||
.na
|
||||
.HP
|
||||
int pq_create(const\ char\ *\fIpath\fP,\ mode_t\ \fImode\fP,\ int\ \fIpflags\fP, size_t\ \fIalign\fP,\ off_t\ \fIinitialsz\fP,\ size_t\ \fInproducts\fP, pqueue\ **\fIpqp\fP);
|
||||
.ad
|
||||
.IP
|
||||
Creates a new product queue and sets \fI*pqp\fP to reference it.
|
||||
|
||||
\fIpath\fP is the pathname of the new product queue.
|
||||
|
||||
As the third parameter to the \fIopen\fP() system call,
|
||||
the access permission bits of the file mode are set to
|
||||
the value of \fImode\fP.
|
||||
|
||||
The \fIpflags\fP parameter may contain the bitwise OR of flag bits
|
||||
which alter the default behavior. These are defined in pq.h.
|
||||
When \fIPQ_NOCLOBBER\fP is set, \fIpqcreate\fP will return \fBEEXIST\fP
|
||||
when attempting to create a file which already exists. The default behavior
|
||||
is to silently overwrite any existing file.
|
||||
When \fIPQ_READONLY\fP is set, the file is opened read-only; the default is read-write.
|
||||
The \fIPQ_NOMAP\fP flag causes the library to use an i/o strategy
|
||||
which uses \fIread\fP(), \fIwrite\fP() and \fImalloc\fP().
|
||||
The \fIPQ_MAPRGNS\fP flag causes the library to use an i/o strategy
|
||||
which uses \fImmap\fP(), but maps regions as as they are needed and
|
||||
unmaps them when no longer needed. The default strategy is to map the
|
||||
whole file. Only one of \fIPQ_NOMAP\fP and \fIPQ_MAPRGNS\fP should be
|
||||
specified.
|
||||
When \fIPQ_NOLOCK\fP is set,
|
||||
locking is disabled. When \fIPQ_PRIVATE\fP is set and mmap() is being used,
|
||||
the mapping is \fIMAP_PRIVATE\fP instead of the default \fIMAP_SHARED\fP.
|
||||
|
||||
The \fIalign\fP parameter sets the access alignment. Requests for storage in the
|
||||
queue are rounded up to a multiple of this value. A value of zero for this
|
||||
allows the library to set a suitable default.
|
||||
|
||||
The parameter \fIinitialsz\fP is the amount of storage to initially
|
||||
allocate for data in the queue.
|
||||
|
||||
The parameter \fInproducts\fP sets the initial product capacity of
|
||||
the queue.
|
||||
The size of the file created is a function of this and the
|
||||
\fIinitialsz\fP parameter.
|
||||
|
||||
If the product queue is opened for writing, then the writer-count in the
|
||||
product queue is incremented and the product queue \fBmust\fP be closed by
|
||||
\fIpq_close\fP in order to decrement the writer-count.
|
||||
|
||||
.na
|
||||
.HP
|
||||
int pq_open(const\ char\ *\fIpath\fP, int\ \fIpflags\fP, pqueue\ **\fIpqp\fP);
|
||||
.ad
|
||||
.IP
|
||||
Opens an existing product queue and sets \fI*pqp\fP to reference it.
|
||||
|
||||
\fIpath\fP is a pathname of the product queue.
|
||||
|
||||
The \fIpflags\fP parameter contains flags as described under \fIpqcreate\fP(),
|
||||
except that \fIPQ_NOCLOBBER\fP is meaningless in this context.
|
||||
|
||||
If the product queue is opened for writing, then the writer-count in the
|
||||
product queue is incremented and the product queue \fBmust\fP be closed by
|
||||
\fIpq_close\fP in order to decrement the writer-count.
|
||||
|
||||
This function will not create a new product queue, but will instead
|
||||
return \fBENOENT\fP when the queue does not exist. If the file
|
||||
exists but is not a product queue, the open fails and \fBEINVAL\fP is
|
||||
returned. If the product queue is inconsistent, then the open fails and
|
||||
\fBPQ_CORRUPT\fP is returned.
|
||||
|
||||
.na
|
||||
.HP
|
||||
int pq_close(pqueue\ *\fIpq\fP);
|
||||
.ad
|
||||
.IP
|
||||
Closes an open product queue \fIpq\fP and frees any associated resources.
|
||||
|
||||
If the product queue was opened for writing, then the writer-count in the
|
||||
product queue is decremented.
|
||||
.na
|
||||
.HP
|
||||
int pq_insert(pqueue\ *\fIpq\fP, const\ product\ *\fIprod\fP);
|
||||
.ad
|
||||
.IP
|
||||
Inserts the LDM data product \fIprod\fP into the queue and sends SIGCONT
|
||||
to the process group.
|
||||
Calls to this function for products whose signature is already in the queue
|
||||
fail with an error indication of \fBPQUEUE_DUP\fB.
|
||||
.na
|
||||
.HP
|
||||
int pqe_new(pqueue\ *\fIpq\fP, const\ prod_info\ *\fIinfop\fP, size_t\ \fIproduct_size\fP, void\ **\fIptrp\fP, pqe_index\ *\fIindexp\fP);
|
||||
.ad
|
||||
.IP
|
||||
This function is used when a product is not yet assembled but we wish to
|
||||
allocate storage in the queue for its assembly, such as upon the receipt
|
||||
of a COMINGSOON remote procedure call in the server.
|
||||
It returns storage in \fI*ptrp\fP suitable for placing the data of the product
|
||||
described by \fIinfop\fP and \fIproduct_size\fP.
|
||||
The value of \fI*indexp\fP should be retained for use in committing the product
|
||||
using \fIpqe_insert\fP() or abandoning it using \fIpqe_discard\fP().
|
||||
Calls to this function for products whose signature is already in the queue
|
||||
fail with an error indication of \fBPQUEUE_DUP\fB.
|
||||
.na
|
||||
.HP
|
||||
int pqe_discard(pqueue\ *\fIpq\fP, pqe_index\ \fIindex\fP);
|
||||
.ad
|
||||
.IP
|
||||
Abandon construction of a product which was begun using \fIpqe_new\fP(),
|
||||
freeing up any queue resources allocated to it.
|
||||
.na
|
||||
.HP
|
||||
int pqe_insert(pqueue\ *\fIpq\fP, pqe_index\ \fIindex\fP);
|
||||
.ad
|
||||
.IP
|
||||
Commit (insert) a completed product which was begun using \fIpqe_new\fP(),
|
||||
sending SIGCONT to the process group. The insertion timestamp of the product
|
||||
will be the time of the call to this function, not \fIpqe_new\fP().
|
||||
.na
|
||||
.HP
|
||||
void pq_cset(pqueue\ *\fIpq\fP, const\ struct\ timeval\ *\fItvp\fP);
|
||||
.ad
|
||||
.IP
|
||||
Sets the cursor value to \fI*tvp\fP. Cheap to call.
|
||||
.na
|
||||
.HP
|
||||
void pq_ctimestamp(const pqueue\ *\fIpq\fP, struct\ timeval\ *\fItvp\fP);
|
||||
.ad
|
||||
.IP
|
||||
Retrives the cursor value as \fI*tvp\fP. Cheap to call.
|
||||
.na
|
||||
.HP
|
||||
int pq_sequence(pqueue\ *\fIpq\fP, pq_match\ \fImt\fP, const\ prod_class_t\ *\fIclass\fP, pq_seqfunc\ *\fIifMatch\fP, void\ *\fIotherargs\fP);
|
||||
.ad
|
||||
.IP
|
||||
Step thru the queue in the direction specified by \fImt\fP,
|
||||
relative to the current cursor value,
|
||||
and execute the user supplied function \fIifMatch\fP
|
||||
if the product in next position "matches"
|
||||
the specification defined by \fIclss\fP.
|
||||
The queue cursor value is set to the insertion time of the product sampled.
|
||||
The interface file prod_class.h (included by pq.h) provides a definition of
|
||||
prod_class_t and pq.h provides a prototype for pq_seqfunc.
|
||||
The product class PQ_CLASS_ALL matches everything.
|
||||
|
||||
The \fImt\fP argument controls the sequencing behavior.
|
||||
|
||||
If(mt == TV_LT), \fIpq_sequence\fP() will get a product
|
||||
whose queue insertion timestamp is strictly less than
|
||||
the current cursor value. If the cursor is not set,
|
||||
it is set to TV_ENDT early in the call, so that
|
||||
most recently inserted product in queue is tested.
|
||||
If multiple products have the same queue insertion timestamp, the
|
||||
user-supplied function will be applied to each of them on successive
|
||||
calls to \fIpq_sequence\fP().
|
||||
|
||||
If(mt == TV_GT), \fIpq_sequence\fP() will get a product
|
||||
whose queue insertion timestamp is strictly greater than
|
||||
the current cursor value. If the cursor is not set,
|
||||
it is set to TV_ZERO early in the call, so that
|
||||
oldest product in queue is tested.
|
||||
|
||||
If(mt == TV_EQ), \fIpq_sequence\fP() will get a product
|
||||
whose queue insertion timestamp is equal to
|
||||
the current cursor value. If the cursor is not set,
|
||||
you will fail an assertion and dump core.
|
||||
|
||||
If no product is in the inventory which which meets the
|
||||
above spec, \fIpq_sequence\fP() returns \fBPQUEUE_END\fP.
|
||||
|
||||
This function waits for locks it needs.
|
||||
|
||||
Using this function is easier than it explaining or understanding it.
|
||||
See pqcat.c in the source distribution.
|
||||
|
||||
.na
|
||||
.HP
|
||||
int pq_seqdel(pqueue\ *\fIpq\fP, pq_match\ \fImt\fP, const\ prod_class_t\ *\fIclss\fP, size_t\ *\fIextentp\fP, time_t\ *\fItimestampp\fP);
|
||||
.ad
|
||||
.IP
|
||||
Similar to \fIpq_sequence\fP(), except that the action is to
|
||||
delete any matching product.
|
||||
Upon return, \fI*timestampp\fP is set to creation time of the tested product.
|
||||
When deletion occurs,
|
||||
\fI*extentp\fP is set to the amount of storage made available.
|
||||
|
||||
This function does not wait on region lock. It may return \fBEAGAIN\fP
|
||||
or \fBEACCESS\fP.
|
||||
.na
|
||||
.HP
|
||||
int pq_pagesize(const\ pqueue\ *\fIpq\fP);
|
||||
.ad
|
||||
.IP
|
||||
If pq is NULL, returns the system page size. Otherwise, returns the
|
||||
queue page size, typically the least common multiple of the system page size
|
||||
and the \fIalign\fP parameter to \fIpq_create\fP(). This function might
|
||||
be used for optimizations such as the choice of an \fIalign\fP value.
|
||||
.na
|
||||
.HP
|
||||
int pq_highwater(pqueue\ *\fIpq\fP, off_t\ *\fIhighwaterp\fP, size_t\ *\fImaxproductsp\fP);
|
||||
.ad
|
||||
.IP
|
||||
Upon success, returns the maximum data segment utilization in bytes as
|
||||
\fI*highwaterp\fP and maximum number of products held in the queue as
|
||||
\fI*maxproductsp\fP. These are suitable for use as the \fIinitialsz\fP
|
||||
and \fInproducts\fP parameters to \fIpq_create\fP(), respectively.
|
||||
Since this information is part of the shared queue state, calling this
|
||||
function is more expensive than one would hope.
|
||||
.na
|
||||
.HP
|
||||
int pq_suspend(unsigned\ int\ \fImaxsleep\fP);
|
||||
.ad
|
||||
.IP
|
||||
This function is used in conjunction with the scanning function
|
||||
\fIpq_sequence\fP() when it reaches the end of queue.
|
||||
\fIpq_suspend\fP() is called and the program sleeps until either
|
||||
\fImaxsleep\fP() seconds have elapsed or the process receives the
|
||||
signal SIGCONT, presumably signaling that a product has been inserted
|
||||
by some other process.
|
||||
.na
|
||||
.HP
|
||||
int\ pq_get_write_count(const\ char*\ \fIpath\fP\fP, unsigned*\ \fIcount\fP\fP);
|
||||
.ad
|
||||
.IP
|
||||
Returns the number of \fBpq_open()\fPs for writing outstanding on an existing
|
||||
product queue, i.e., this function returns the current value of the
|
||||
\fIwriter-counter\fP. If a writing process terminates without calling
|
||||
\fBpq_close()\fP,
|
||||
then the actual number will be less than this number. This function opens
|
||||
the product-queue read-only, so if there are no outstanding product-queue
|
||||
writers, then the returned count will be zero.
|
||||
.IP
|
||||
.I path
|
||||
is the pathname of the product-queue.
|
||||
.I count
|
||||
is the memory to receive the number of writers.
|
||||
.IP
|
||||
On and only on success, this function returns 0 and *\fIcount\fP is set
|
||||
to the number of writers.
|
||||
Other return values are \fBEINVAL\fP, which means that
|
||||
\fIpath\fP is NULL or \fIcount\fP is NULL;
|
||||
\fBENOSYS\fP, which means that this function is not supported because the
|
||||
product-queue doesn't have a writer-counter;
|
||||
\fBPQ_CORRUPT\fP, which means the product-queue is internally inconsistent;
|
||||
and any of the \fB<errno.h>\fP error-codes associated with opening and
|
||||
reading from a file.
|
||||
.na
|
||||
.HP
|
||||
int\ pq_clear_write_count(const\ char*\ \fIpath\fP\fP);
|
||||
.ad
|
||||
.IP
|
||||
Sets to zero the number of pq_open()s for writing outstanding on the
|
||||
product-queue, i.e., this function clears the \fIwriter-counter\fP in the
|
||||
product-queue. This is a dangerous function and should only be used when
|
||||
it is known that there are no outstanding \fBpq_open()\fPs for writing on the
|
||||
product-queue.
|
||||
.IP
|
||||
\fIpath\fP is the pathname of the product-queue.
|
||||
.IP
|
||||
On and only on success, this function returns 0. Other return-values are
|
||||
\fBEINVAL\fP, which means that \fIpath\fP is NULL;
|
||||
\fBPQ_CORRUPT\fP, which means that the product-queue is internally
|
||||
inconsistent; and any of the \fB<errno.h>\fP error-codes associated with
|
||||
opening and reading from a file.
|
||||
.fi
|
||||
.ad
|
||||
.LP
|
||||
.SH "EXAMPLES"
|
||||
.LP
|
||||
There are numerous examples in ldm source code distribution.
|
||||
.sp
|
||||
.RS +4
|
||||
.nf
|
||||
.ta 4m +\w'utUnit 'u +\w'double 'u +4m +4m
|
||||
.fi
|
||||
.RE
|
||||
.SH DIAGNOSTICS
|
||||
.LP
|
||||
This package uses the \fBulog\fP(3) library to print
|
||||
(hopefully) self-explanatory error-messages.
|
||||
.SH "SEE ALSO"
|
||||
.LP
|
||||
.BR ldm (1),
|
||||
.BR open (2),
|
||||
.BR fnctl (2),
|
||||
.BR mmap (2)
|
||||
.SH "BUGS AND RESTRICTIONS"
|
||||
.LP
|
||||
Chaos will result if time runs backwards.
|
||||
.LP
|
||||
On many systems, it is an error to mmap a file when that file is not
|
||||
on a local file system. In such a case, the package emits a message
|
||||
and reverts to the \fIPQ_NOMAP\fP strategy. Since locking over the
|
||||
network is _extremely_ slow, use of this feature is strongly
|
||||
discouraged.
|
6826
ldm/src/pq/pq.c
6826
ldm/src/pq/pq.c
File diff suppressed because it is too large
Load diff
388
ldm/src/pq/pq.h
388
ldm/src/pq/pq.h
|
@ -1,388 +0,0 @@
|
|||
/*
|
||||
* Copyright 1994, University Corporation for Atmospheric Research
|
||||
* See top level COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: pq.h,v 3.20.8.2.2.1.2.7 2009/05/21 20:30:44 steve Exp $ */
|
||||
|
||||
#ifndef _PQ_H
|
||||
#define _PQ_H
|
||||
|
||||
#include <sys/types.h> /* off_t, mode_t */
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
#include "prod_class.h"
|
||||
|
||||
|
||||
/*
|
||||
* The functions below return ENOERR upon success.
|
||||
* Upon failure, the return something else :-).
|
||||
* (Usually, that something else will be the a system
|
||||
* error (errno.h), don't count on it making sense.)
|
||||
*/
|
||||
#ifndef ENOERR
|
||||
#define ENOERR 0
|
||||
#endif /*!ENOERR */
|
||||
|
||||
#define PQ_END -1 /* at end of product-queue */
|
||||
#define PQ_CORRUPT -2 /* the product-queue is corrupt */
|
||||
#define PQ_NOTFOUND -3 /* no such data-product */
|
||||
|
||||
typedef struct pqueue pqueue; /* private, implemented in pq.c */
|
||||
|
||||
|
||||
/*
|
||||
* pflags arg to pq_open() and pq_create()
|
||||
*/
|
||||
#define PQ_DEFAULT 0x00
|
||||
#define PQ_NOCLOBBER 0x01 /* Don't destroy existing file on create */
|
||||
#define PQ_READONLY 0x02 /* Default is read/write */
|
||||
#define PQ_NOLOCK 0x04 /* Disable locking */
|
||||
#define PQ_PRIVATE 0x08 /* mmap() the file MAP_PRIVATE, default MAP_SHARED */
|
||||
#define PQ_NOGROW 0x10 /* If pq_create(), must have intialsz */
|
||||
#define PQ_NOMAP 0x20 /* Use malloc/read/write/free instead of mmap() */
|
||||
#define PQ_MAPRGNS 0x40 /* Map region by region, default whole file */
|
||||
#define PQ_SPARSE 0x80 /* Created as sparse file, zero blocks unallocated */
|
||||
/* N.B.: bits 0x1000 (and above) in use internally */
|
||||
|
||||
extern int
|
||||
pq_create(const char *path, mode_t mode, int pflags,
|
||||
size_t align, off_t initialsz, size_t nproducts,
|
||||
pqueue **pqp);
|
||||
|
||||
extern int
|
||||
pq_open(const char *path,
|
||||
int pflags,
|
||||
pqueue **pqp);
|
||||
|
||||
extern int
|
||||
pq_close(pqueue *pq);
|
||||
|
||||
|
||||
/*
|
||||
* Let the user find out the pagesize.
|
||||
*/
|
||||
extern int pq_pagesize(const pqueue *pq);
|
||||
|
||||
|
||||
struct pqe_index {
|
||||
off_t offset;
|
||||
signaturet signature;
|
||||
};
|
||||
typedef struct pqe_index pqe_index;
|
||||
#define pqeOffset(pqe) ((pqe).offset)
|
||||
#define pqeEqual(left, rght) (pqeOffset(left) == pqeOffset(rght))
|
||||
|
||||
extern const pqe_index _pqenone;
|
||||
#define PQE_NONE (_pqenone)
|
||||
#define pqeIsNone(pqe) (pqeEqual(pqe, PQE_NONE))
|
||||
|
||||
#define PQUEUE_DUP (-2) /* return value indicating attempt to insert
|
||||
duplicate product */
|
||||
#define PQUEUE_BIG (-3) /* return value indicating attempt to insert
|
||||
product that's too large */
|
||||
extern int
|
||||
pqe_new(pqueue *pq, const prod_info *infop,
|
||||
void **ptrp, pqe_index *indexp);
|
||||
|
||||
extern int
|
||||
pqe_discard(pqueue *pq, pqe_index index);
|
||||
|
||||
/* Insert at rear of queue, send SIGCONT to process group */
|
||||
extern int
|
||||
pqe_insert(pqueue *pq, pqe_index index);
|
||||
|
||||
/*
|
||||
* LDM 4 convenience funct.
|
||||
* Change signature, Insert at rear of queue, send SIGCONT to process group
|
||||
*/
|
||||
extern int
|
||||
pqe_xinsert(pqueue *pq, pqe_index index, const signaturet realsignature);
|
||||
|
||||
/*
|
||||
* pq_insertNoSig() is a special purpose function that only
|
||||
* needs to be in the public interface for 'pqsurf'.
|
||||
*/
|
||||
/* Insert at rear of queue (Don't signal process group.) */
|
||||
extern int
|
||||
pq_insertNoSig(pqueue *pq, const product *prod);
|
||||
|
||||
/* Insert at rear of queue, send SIGCONT to process group */
|
||||
extern int
|
||||
pq_insert(pqueue *pq, const product *prod);
|
||||
|
||||
|
||||
/*
|
||||
* Get some useful statistics.
|
||||
* 'highwater' is the max number of bytes used for data storage,
|
||||
* suitable as the 'initialsz' parameter to pq_create().
|
||||
* 'maxproductsp' is the max number of products in the inventory,
|
||||
* suitable as the 'nproducts' parameter to pq_create().
|
||||
*/
|
||||
extern int
|
||||
pq_highwater(pqueue *pq, off_t *highwaterp, size_t *maxproductsp);
|
||||
|
||||
|
||||
/* prototype for 4th arg to pq_sequence() */
|
||||
typedef int pq_seqfunc(const prod_info *infop, const void *datap,
|
||||
void *xprod, size_t len,
|
||||
void *otherargs);
|
||||
|
||||
/*
|
||||
* Set cursor used by pq_sequence() or pq_seqdel().
|
||||
*/
|
||||
extern void
|
||||
pq_cset(pqueue *pq, const timestampt *tsp);
|
||||
|
||||
|
||||
/*
|
||||
* Get current cursor value used by pq_sequence() or pq_seqdel().
|
||||
*/
|
||||
extern void
|
||||
pq_ctimestamp(const pqueue *pq, timestampt *tsp);
|
||||
|
||||
|
||||
/*
|
||||
* Which direction the cursor moves in pq_sequence().
|
||||
*/
|
||||
typedef enum {
|
||||
TV_LT = -1,
|
||||
TV_EQ = 0,
|
||||
TV_GT = 1
|
||||
} pq_match;
|
||||
|
||||
|
||||
/*
|
||||
* Step thru the time sorted inventory according to 'mt',
|
||||
* and the current cursor value.
|
||||
*
|
||||
* If(mt == TV_LT), pq_sequence() will get a product
|
||||
* whose queue insertion timestamp is strictly less than
|
||||
* the current cursor value.
|
||||
*
|
||||
* If(mt == TV_GT), pq_sequence() will get a product
|
||||
* whose queue insertion timestamp is strictly greater than
|
||||
* the current cursor value.
|
||||
*
|
||||
* If(mt == TV_EQ), pq_sequence() will get a product
|
||||
* whose queue insertion timestamp is equal to
|
||||
* the current cursor value.
|
||||
*
|
||||
* If no product is in the inventory which which meets the
|
||||
* above spec, return PQUEUE_END.
|
||||
*
|
||||
* Otherwise, if the product info matches class,
|
||||
* execute ifMatch(xprod, len, otherargs) and return the
|
||||
* return value from ifMatch().
|
||||
*/
|
||||
#define PQUEUE_END PQ_END /* return value indicating end of queue */
|
||||
extern int
|
||||
pq_sequence(pqueue *pq, pq_match mt,
|
||||
const prod_class *clssp, pq_seqfunc *ifMatch, void *otherargs);
|
||||
|
||||
/*
|
||||
* Boolean function to
|
||||
* check that the cursor timestime is
|
||||
* in the time range specified by clssp.
|
||||
* Returns non-zero if this is the case, zero if not.
|
||||
*/
|
||||
extern int
|
||||
pq_ctimeck(const pqueue *pq, pq_match mt, const prod_class *clssp,
|
||||
const timestampt *maxlatencyp);
|
||||
|
||||
/*
|
||||
* Figure out the direction of scan of clssp, and set *mtp to it.
|
||||
* Set the cursor to include all of clssp time range in the queue.
|
||||
* (N.B.: For "reverse" scans, this range may not include all
|
||||
* the arrival times.)
|
||||
*/
|
||||
extern int
|
||||
pq_cClassSet(pqueue *pq, pq_match *mtp, const prod_class *clssp);
|
||||
|
||||
/*
|
||||
* Like pq_sequence(), but the ifmatch action is to remove the
|
||||
* product from inventory.
|
||||
* If wait is nonzero, then wait for locks.
|
||||
*/
|
||||
extern int
|
||||
pq_seqdel(pqueue *pq, pq_match mt,
|
||||
const prod_class *clssp, int wait, size_t *nrp, timestampt *tp);
|
||||
|
||||
/*
|
||||
* Find the most recent match and set the timestamp *tsp
|
||||
* to info->arrival (product creation time).
|
||||
* clss->from should be less than clssp->to ("forward scan").
|
||||
* Leaves cursor set as side effect, ready for a forward scan.
|
||||
*/
|
||||
extern int
|
||||
pq_last(pqueue *pq,
|
||||
const prod_class *clssp,
|
||||
timestampt *tsp); /* modified upon return */
|
||||
|
||||
/*
|
||||
* Find the most recent match and set clssp->from to it.
|
||||
* clss->from should be less than clssp->to ("forward scan").
|
||||
*/
|
||||
extern int
|
||||
pq_clss_setfrom(pqueue *pq, prod_class_t *clssp);
|
||||
|
||||
|
||||
/*
|
||||
* Suspend yourself (sleep) until
|
||||
* one of the following events occurs:
|
||||
* You recieve a signal that you handle.
|
||||
* You recieve SIGCONT (as send from an insert proc indicating
|
||||
* data is available).
|
||||
* "maxsleep" seconds elapse.
|
||||
* If "maxsleep" is zero, you could sleep forever.
|
||||
*/
|
||||
extern unsigned
|
||||
pq_suspend(unsigned int maxsleep);
|
||||
|
||||
/*
|
||||
* Get some detailed product queue statistics. These may be useful for
|
||||
* monitoring the internal state of the product queue:
|
||||
* nprodsp
|
||||
* holds the current number of products in the queue.
|
||||
* nfreep
|
||||
* holds the current number of free regions. This should be small
|
||||
* and it's OK if it's zero, since new free regions are created
|
||||
* as needed by deleting oldest products. If this gets large,
|
||||
* insertion and deletion take longer.
|
||||
* nemptyp
|
||||
* holds the number of product slots left. This may decrease, but
|
||||
* should eventually stay above some positive value unless too
|
||||
* few product slots were allocated when the queue was
|
||||
* created. New product slots get created when adjacent free
|
||||
* regions are consolidated, and product slots get consumed
|
||||
* when larger free regions are split into smaller free
|
||||
* regions.
|
||||
* nbytesp
|
||||
* holds the current number of bytes in the queue used for data
|
||||
* products.
|
||||
* maxprodsp
|
||||
* holds the maximum number of products in the queue, so far.
|
||||
* maxfreep
|
||||
* holds the maximum number of free regions, so far.
|
||||
* minemptyp
|
||||
* holds the minimum number of empty product slots, so far.
|
||||
* maxbytesp
|
||||
* holds the maximum number of bytes used for data, so far.
|
||||
* age_oldestp
|
||||
* holds the age in seconds of the oldest product in the queue.
|
||||
* maxextentp
|
||||
* holds extent of largest free region
|
||||
*
|
||||
* Note: the fixed number of slots allocated for products when the
|
||||
* queue was created is nalloc = (nprods + nfree + nempty).
|
||||
*/
|
||||
extern int
|
||||
pq_stats(pqueue *pq,
|
||||
size_t *nprodsp,
|
||||
size_t *nfreep,
|
||||
size_t *nemptyp,
|
||||
size_t *nbytesp,
|
||||
size_t *maxprodsp,
|
||||
size_t *maxfreep,
|
||||
size_t *minemptyp,
|
||||
size_t *maxbytesp,
|
||||
double *age_oldestp,
|
||||
size_t *maxextentp);
|
||||
|
||||
/*
|
||||
* Returns the insertion-timestamp of the oldest data-product in the
|
||||
* product-queue.
|
||||
*
|
||||
* Arguments:
|
||||
* oldestCursor Pointer to structure to received the insertion-time
|
||||
* of the oldest data-product.
|
||||
* Returns:
|
||||
* ENOERR Success.
|
||||
* else Failure.
|
||||
*/
|
||||
int
|
||||
pq_getOldestCursor(
|
||||
pqueue* pq,
|
||||
timestampt* const oldestCursor);
|
||||
|
||||
extern int pq_del_oldest(pqueue *pq);
|
||||
extern int pq_fext_dump(pqueue *const pq);
|
||||
extern void pq_coffset(pqueue *pq, off_t c_offset);
|
||||
extern void pq_reset_random(void);
|
||||
extern int pq_clear_write_count(const char* path);
|
||||
extern int pq_get_write_count(const char* path, unsigned* count);
|
||||
extern const char* pq_strerror(const pqueue* pq, int error);
|
||||
|
||||
|
||||
/*
|
||||
* Set the cursor based on the insertion-time of the product with the given
|
||||
* signature if and only if the associated data-product is found in the
|
||||
* product-queue.
|
||||
*
|
||||
* Arguments:
|
||||
* pq Pointer to the product-queue.
|
||||
* signature The given signature.
|
||||
* Returns:
|
||||
* 0 Success. The cursor is set to reference the data-product with
|
||||
* the same signature as the given one.
|
||||
* EACCES "pq->fd" is not open for read or "pq->fd" is not open for write
|
||||
* and PROT_WRITE was specified for a MAP_SHARED type mapping.
|
||||
* EAGAIN The mapping could not be locked in memory, if required by
|
||||
* mlockall(), due to a lack of resources.
|
||||
* EBADF "pq->fd" is not a valid file descriptor open for reading.
|
||||
* EDEADLK The necessary lock is blocked by some lock from another process
|
||||
* and putting the calling process to sleep, waiting for that lock
|
||||
* to become free would cause a deadlock.
|
||||
* EFBIG or EINVAL
|
||||
* The extent of the region is greater than the maximum file size.
|
||||
* EFBIG The file is a regular file and the extent of the region is
|
||||
* greater than the offset maximum established in the open file
|
||||
* description associated with "pq->fd".
|
||||
* EINTR A signal was caught during execution.
|
||||
* EINVAL The region's offset or extent is not valid, or "pq->fd" refers
|
||||
* to a file that does not support locking.
|
||||
* EINVAL The region's offset is not a multiple of the page size as
|
||||
* returned by sysconf(), or is considered invalid by the
|
||||
* implementation.
|
||||
* EIO An I/O error occurred while reading from the file system.
|
||||
* EIO The metadata of a data-product in the product-queue could not be
|
||||
* decoded.
|
||||
* EMFILE The number of mapped regions would exceed an
|
||||
* implementation-dependent limit (per process or per system).
|
||||
* ENODEV "pq->fd" refers to a file whose type is not supported by mmap().
|
||||
* ENOLCK Satisfying the request would result in the number of locked
|
||||
* regions in the system exceeding a system-imposed limit.
|
||||
* ENOMEM There is insufficient room in the address space to effect the
|
||||
* necessary mapping.
|
||||
* ENOMEM The region's mapping could not be locked in memory, if required
|
||||
* by mlockall(), because it would require more space than the
|
||||
* system is able to supply.
|
||||
* ENOMEM Insufficient memory is available.
|
||||
* ENOTSUP The implementation does not support the access requested in
|
||||
* "pq->pflags".
|
||||
* ENXIO The region's location is invalid for the object specified by
|
||||
* "pq->fd".
|
||||
* EOVERFLOW
|
||||
* The smallest or, if the region's extent is non-zero, the
|
||||
* largest offset of any byte in the requested segment cannot be
|
||||
* represented correctly in an object of type off_t.
|
||||
* EOVERFLOW
|
||||
* The file size in bytes or the number of blocks allocated to the
|
||||
* file or the file serial number cannot be represented correctly.
|
||||
* EOVERFLOW
|
||||
* The file is a regular file and the region's offset plus
|
||||
* extent exceeds the offset maximum established in the open file
|
||||
* description associated with "fd".
|
||||
* EROFS The file resides on a read-only file system.
|
||||
*
|
||||
* PQ_CORRUPT
|
||||
* The product-queue is corrupt.
|
||||
* PQ_NOTFOUND
|
||||
* A data-product with the given signature was not found in the
|
||||
* product-queue.
|
||||
*/
|
||||
int
|
||||
pq_setCursorFromSignature(
|
||||
pqueue* const pq,
|
||||
const signaturet signature);
|
||||
|
||||
#endif /* !_PQ_H */
|
|
@ -1,55 +0,0 @@
|
|||
# $Id: Makefile,v 1.1.16.1.2.3 2007/05/04 16:54:09 steve Exp $
|
||||
#
|
||||
# Makefile for "pqact"
|
||||
#
|
||||
include ../macros.make
|
||||
|
||||
INCLUDES = -I../config -I../misc -I../ulog -I../protocol -I../pq
|
||||
TAG_SRCS = \
|
||||
../misc/*.c ../misc/*.h \
|
||||
../ulog/*.c ../ulog/*.h \
|
||||
../protocol/*.c ../protocol/*.h \
|
||||
../pq/*.c ../pq/*.h \
|
||||
../gdbm/*.c ../gdbm/*.h
|
||||
LDLIBS = -lm $(GDBMLIB)
|
||||
C_PROGRAMS = pqact
|
||||
LIBRARY = ../libldm.a
|
||||
LIB_CSRCS = \
|
||||
action.c \
|
||||
filel.c \
|
||||
palt.c \
|
||||
pbuf.c \
|
||||
state.c
|
||||
PROG_CSRCS = $(LIB_CSRCS) pqact.c
|
||||
PROG_OBJS = $(PROG_CSRCS:.c=.o)
|
||||
MANUALS = pqact.1
|
||||
ETC_FILES = pqact.conf
|
||||
PACKING_LIST = \
|
||||
depends \
|
||||
Makefile \
|
||||
$(PROG_CSRCS) \
|
||||
action.h \
|
||||
filel.h \
|
||||
palt.h \
|
||||
pbuf.h \
|
||||
state.h \
|
||||
pqact.1 \
|
||||
pqact.conf
|
||||
|
||||
all: pqact
|
||||
|
||||
pqact: $(PROG_OBJS) $(LIBRARY)
|
||||
$(CC) -o $@ $(CFLAGS) $(PROG_OBJS) $(LIBS)
|
||||
|
||||
include ../rules.make
|
||||
|
||||
lint: $(PROG_CSRCS:.c=.ln)
|
||||
$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(PROG_CSRCS:.c=.ln)
|
||||
|
||||
check:
|
||||
$(CC) -o date_sub $(CFLAGS) $(CPPFLAGS) -UNDEBUG -DTEST_DATE_SUB \
|
||||
palt.c $(LIBRARY)
|
||||
./date_sub
|
||||
rm date_sub
|
||||
|
||||
include depends
|
|
@ -1,209 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: action.c,v 1.78.16.4.2.3 2005/09/21 18:37:12 steve Exp $ */
|
||||
|
||||
#include "ldmconfig.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "ldm.h"
|
||||
#include "ldmalloc.h"
|
||||
#include "action.h"
|
||||
#include "error.h"
|
||||
#include "filel.h"
|
||||
#include "globals.h"
|
||||
#include "pq.h"
|
||||
#include "ulog.h"
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
prod_noop(
|
||||
const product *prod,
|
||||
int argc, char **argv,
|
||||
const void *xprod, size_t xlen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Execute a program.
|
||||
*
|
||||
* Arguments:
|
||||
* prod Pointer to the data-product that caused this action.
|
||||
* argc Number of arguments in the command-line.
|
||||
* argv Pointer to pointers to command-line arguments.
|
||||
* xprod Pointer to XDR-ed data-product.
|
||||
* xlen Size of "xprod" in bytes.
|
||||
* Returns:
|
||||
* -1 Failure. An error--message is logged.
|
||||
* else PID of the child process.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
exec_prodput(
|
||||
const product* prod,
|
||||
int argc,
|
||||
char** argv,
|
||||
const void* xprod,
|
||||
size_t xlen)
|
||||
{
|
||||
pid_t pid;
|
||||
int waitOnChild = 0; /* default is not to wait */
|
||||
|
||||
if (strcmp(argv[0], "-wait") == 0)
|
||||
{
|
||||
waitOnChild = 1; /* => wait for child */
|
||||
argc--; argv++;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (-1 == pid)
|
||||
{
|
||||
err_log_and_free(
|
||||
ERR_NEW1(0, NULL,
|
||||
"Couldn't fork() child-process: %s", strerror(errno)),
|
||||
ERR_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 == pid)
|
||||
{
|
||||
/*
|
||||
* Child process.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Detach the child process from the parents process group??
|
||||
(void) setpgid(0,0);
|
||||
*/
|
||||
|
||||
(void)signal(SIGTERM, SIG_DFL);
|
||||
(void)pq_close(pq);
|
||||
|
||||
/*
|
||||
* It is assumed that the standard input, output, and error streams
|
||||
* are correctly established and should not be modified.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Don't let the child process get any inappropriate privileges.
|
||||
*/
|
||||
endpriv();
|
||||
|
||||
(void) execvp(argv[0], &argv[0]);
|
||||
err_log_and_free(
|
||||
ERR_NEW2(0, NULL, "Couldn't exec(%s): %s",
|
||||
argv[0], strerror(errno)),
|
||||
ERR_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Parent process.
|
||||
*/
|
||||
|
||||
if (!waitOnChild)
|
||||
{
|
||||
udebug(" exec %s[%d]", argv[0], pid);
|
||||
}
|
||||
else
|
||||
{
|
||||
udebug(" exec -wait %s[%d]", argv[0], pid);
|
||||
(void)reap(pid, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1 == pid ? -1 : 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
atoaction(
|
||||
const char *str,
|
||||
actiont *resultp)
|
||||
{
|
||||
#define MAXACTIONLEN 12
|
||||
char buf[MAXACTIONLEN];
|
||||
const char *in;
|
||||
char *cp;
|
||||
actiont *ap;
|
||||
|
||||
static actiont assoc[] = {
|
||||
{"noop",
|
||||
0,
|
||||
prod_noop},
|
||||
{"file",
|
||||
0,
|
||||
unio_prodput},
|
||||
{"stdiofile",
|
||||
0,
|
||||
stdio_prodput},
|
||||
{"dbfile",
|
||||
0,
|
||||
#ifndef NO_DB
|
||||
ldmdb_prodput},
|
||||
#else
|
||||
prod_noop},
|
||||
#endif
|
||||
{"pipe",
|
||||
0,
|
||||
pipe_prodput},
|
||||
{"spipe",
|
||||
0,
|
||||
spipe_prodput},
|
||||
{"xpipe",
|
||||
0,
|
||||
xpipe_prodput},
|
||||
{"exec",
|
||||
0,
|
||||
exec_prodput},
|
||||
|
||||
};
|
||||
|
||||
if(str == NULL || *str == 0)
|
||||
{
|
||||
udebug("atoaction: Invalid string argument");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(in = str, cp = buf; *in != 0 && cp < &buf[MAXACTIONLEN] ; cp++, in++)
|
||||
{
|
||||
*cp = (char)(isupper(*in) ? tolower((*in)) : (*in));
|
||||
}
|
||||
*cp = 0;
|
||||
|
||||
for(ap = &assoc[0]; ap < &assoc[sizeof(assoc)/sizeof(assoc[0])] ; ap ++)
|
||||
{
|
||||
if(strcmp(ap->name, buf) == 0)
|
||||
{
|
||||
(void) memcpy((char *)resultp, (char *)ap,
|
||||
sizeof(actiont));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* uerror("Unknown action \"%s\"", str); */
|
||||
return -1; /* noop */
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
s_actiont(actiont *act)
|
||||
{
|
||||
if(act == NULL || act->name == NULL)
|
||||
return "";
|
||||
/* else */
|
||||
return act->name;
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: action.h,v 1.67.16.2 2004/08/09 14:46:28 steve Exp $ */
|
||||
#ifndef _ACTION_H_
|
||||
#define _ACTION_H_
|
||||
|
||||
#include "ldm.h"
|
||||
#include "filel.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct actiont {
|
||||
char *name;
|
||||
#define LDM_ACT_TRANSIENT 1
|
||||
int flags;
|
||||
/* executed in "processProduct" */
|
||||
int (*prod_action)(product *prod, int argc, char **argv);
|
||||
};
|
||||
typedef struct actiont actiont;
|
||||
extern "C" int close_all(void);
|
||||
extern "C" int atoaction(const char *str, actiont *result);
|
||||
extern "C" char * s_actiont(actiont *act);
|
||||
#elif defined(__STDC__)
|
||||
struct actiont {
|
||||
char *name;
|
||||
#define LDM_ACT_TRANSIENT 1
|
||||
int flags;
|
||||
/* executed in "processProduct" */
|
||||
int (*prod_action)(const product *prod, int argc, char **argv,
|
||||
const void *xprod, size_t xlen);
|
||||
|
||||
};
|
||||
typedef struct actiont actiont;
|
||||
extern int close_all(void);
|
||||
extern int atoaction(const char *str, actiont *result);
|
||||
extern char * s_actiont(actiont *act);
|
||||
#else /* Old Style C */
|
||||
struct actiont {
|
||||
char *name;
|
||||
#define LDM_ACT_TRANSIENT 1
|
||||
int flags;
|
||||
/* executed in "processProduct" */
|
||||
int (*prod_action)();
|
||||
};
|
||||
typedef struct actiont actiont;
|
||||
extern int close_all();
|
||||
extern int atoaction();
|
||||
extern char * s_actiont();
|
||||
#endif
|
||||
|
||||
#endif /* !_ACTION_H_ */
|
|
@ -1,48 +0,0 @@
|
|||
action.o: ../config/ldmconfig.h
|
||||
action.o: ../misc/ldmalloc.h
|
||||
action.o: ../protocol/ldm.h
|
||||
action.o: ../protocol/timestamp.h
|
||||
action.o: ../ulog/ulog.h
|
||||
action.o: action.c
|
||||
action.o: action.h
|
||||
action.o: filel.h
|
||||
filel.o: ../config/ldmconfig.h
|
||||
filel.o: ../misc/ldmalloc.h
|
||||
filel.o: ../misc/mkdirs_open.h
|
||||
filel.o: ../protocol/ldm.h
|
||||
filel.o: ../protocol/timestamp.h
|
||||
filel.o: ../ulog/ulog.h
|
||||
filel.o: action.h
|
||||
filel.o: filel.c
|
||||
filel.o: filel.h
|
||||
filel.o: pbuf.h
|
||||
palt.o: ../config/ldmconfig.h
|
||||
palt.o: ../misc/ldmalloc.h
|
||||
palt.o: ../protocol/atofeedt.h
|
||||
palt.o: ../protocol/ldm.h
|
||||
palt.o: ../protocol/ldmprint.h
|
||||
palt.o: ../protocol/timestamp.h
|
||||
palt.o: ../ulog/ulog.h
|
||||
palt.o: action.h
|
||||
palt.o: filel.h
|
||||
palt.o: palt.c
|
||||
palt.o: palt.h
|
||||
pbuf.o: ../config/ldmconfig.h
|
||||
pbuf.o: ../misc/alrm.h
|
||||
pbuf.o: ../misc/fdnb.h
|
||||
pbuf.o: ../misc/ldmalloc.h
|
||||
pbuf.o: ../ulog/ulog.h
|
||||
pbuf.o: pbuf.c
|
||||
pbuf.o: pbuf.h
|
||||
pqact.o: ../config/ldmconfig.h
|
||||
pqact.o: ../misc/paths.h
|
||||
pqact.o: ../pq/pq.h
|
||||
pqact.o: ../protocol/atofeedt.h
|
||||
pqact.o: ../protocol/ldm.h
|
||||
pqact.o: ../protocol/ldmprint.h
|
||||
pqact.o: ../protocol/prod_class.h
|
||||
pqact.o: ../protocol/timestamp.h
|
||||
pqact.o: ../ulog/ulog.h
|
||||
pqact.o: filel.h
|
||||
pqact.o: palt.h
|
||||
pqact.o: pqact.c
|
File diff suppressed because it is too large
Load diff
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: filel.h,v 1.144.16.2.2.5 2008/09/17 16:35:45 steve Exp $ */
|
||||
#ifndef _FILEL_H_
|
||||
#define _FILEL_H_
|
||||
|
||||
#include <sys/types.h> /* pid_t */
|
||||
#include "ldm.h"
|
||||
|
||||
/*
|
||||
* fl_entry.flags, args to close_lru()
|
||||
*/
|
||||
#define FL_NEEDS_SYNC 1
|
||||
#define FL_OVERWRITE 2
|
||||
#define FL_NOTRANSIENT 16
|
||||
#define FL_STRIP 32
|
||||
#define FL_LOG 64
|
||||
#define FL_METADATA 128 /* write data-product metadata */
|
||||
#define FL_NODATA 256 /* don't write data */
|
||||
#define FL_EDEX 512 /* send message to memory segment */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int unio_prodput( const product *prod, int argc, char **argv,
|
||||
const void *xprod, size_t xlen);
|
||||
extern int stdio_prodput( const product *prod, int argc, char **argv,
|
||||
const void *xprod, size_t xlen);
|
||||
extern int pipe_prodput( const product *prod, int argc, char **argv,
|
||||
const void *xprod, size_t xlen);
|
||||
extern int spipe_prodput( const product *prod, int argc, char **argv,
|
||||
const void *xprod, size_t xlen);
|
||||
extern int xpipe_prodput( const product *prod, int argc, char **argv,
|
||||
const void *xprod, size_t xlen);
|
||||
#ifndef NO_DB
|
||||
extern int ldmdb_prodput( const product *prod, int argc, char **argv,
|
||||
const void *xprod, size_t xlen);
|
||||
#endif /* !NO_DB */
|
||||
extern pid_t reap(pid_t pid, int options);
|
||||
extern void fl_sync(int nentries, int block);
|
||||
extern void close_lru(int skipflags);
|
||||
extern void fl_close_all(void);
|
||||
extern void endpriv(void);
|
||||
extern int set_avail_fd_count(unsigned fdCount);
|
||||
extern int set_shared_space(int shid, int semid, unsigned size);
|
||||
extern long openMax();
|
||||
|
||||
struct edex_message {
|
||||
char filename[4096];
|
||||
char ident[256];
|
||||
};
|
||||
typedef struct edex_message edex_message;
|
||||
|
||||
union semun {
|
||||
int val; /* Value for SETVAL */
|
||||
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
|
||||
unsigned short *array; /* Array for GETALL, SETALL */
|
||||
struct seminfo *__buf; /* Buffer for IPC_INFO
|
||||
(Linux specific) */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_FILEL_H_ */
|
1265
ldm/src/pqact/palt.c
1265
ldm/src/pqact/palt.c
File diff suppressed because it is too large
Load diff
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: palt.h,v 1.59 1997/03/12 00:56:11 davis Exp $ */
|
||||
#ifndef _PALT_H_
|
||||
#define _PALT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" int readPatFile(char *path);
|
||||
extern "C" int processProduct(const prod_info *infop, const void *datap,
|
||||
const void *xprod, size_t len,
|
||||
void *otherargs);
|
||||
extern "C" void dummyprod(char *ident);
|
||||
#elif defined(__STDC__)
|
||||
extern int readPatFile(char *path);
|
||||
extern int processProduct(const prod_info *infop, const void *datap,
|
||||
void *xprod, size_t len,
|
||||
void *otherargs);
|
||||
extern void dummyprod(char *ident);
|
||||
#else /* Old Style C */
|
||||
extern int readPatFile();
|
||||
extern int processProduct();
|
||||
extern void dummyprod();
|
||||
#endif
|
||||
|
||||
#endif /* !_PALT_H_ */
|
|
@ -1,232 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: pbuf.c,v 1.21.16.2.2.8 2009/05/21 20:30:44 steve Exp $ */
|
||||
|
||||
/* #define _POSIX_SOURCE */
|
||||
|
||||
#include <ldmconfig.h>
|
||||
#include "pbuf.h"
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "ulog.h"
|
||||
#include "ldmalloc.h"
|
||||
#include "alrm.h"
|
||||
#include "error.h"
|
||||
#include "fdnb.h"
|
||||
|
||||
#ifdef NO_MEMMOVE
|
||||
/* define memmove in terms of bcopy - recividist */
|
||||
#define memmove(d1, d2, n) bcopy((d2), (d1), (n))
|
||||
#endif /* NO_MEMMOVE */
|
||||
|
||||
#define INSTRUMENT
|
||||
|
||||
#ifdef INSTRUMENT
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
* take the difference between two timevals
|
||||
*
|
||||
* N.B. Meaningful only if "afta" is later than "b4",
|
||||
* negative differences map to 0.0
|
||||
*/
|
||||
static struct timeval
|
||||
diff_timeval(struct timeval *afta, struct timeval *b4)
|
||||
{
|
||||
struct timeval diff;
|
||||
|
||||
diff.tv_sec = afta->tv_sec - b4->tv_sec;
|
||||
diff.tv_usec = afta->tv_usec - b4->tv_usec;
|
||||
|
||||
if(diff.tv_usec < 0)
|
||||
{
|
||||
if(diff.tv_sec > 0)
|
||||
{
|
||||
/* borrow */
|
||||
diff.tv_sec--;
|
||||
diff.tv_usec += 1000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* truncate to zero */
|
||||
diff.tv_sec = 0;
|
||||
diff.tv_usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
free_pbuf(pbuf *buf)
|
||||
{
|
||||
if(buf == NULL)
|
||||
return;
|
||||
free(buf->base);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
pbuf *
|
||||
new_pbuf(
|
||||
int pfd,
|
||||
size_t bufsize)
|
||||
{
|
||||
long pipe_buf = 512; /* _POSIX_PIPE_BUF */
|
||||
pbuf *buf = NULL;
|
||||
buf = Alloc(1, pbuf);
|
||||
if(buf == NULL)
|
||||
return NULL;
|
||||
#ifdef _PC_PIPE_BUF
|
||||
pipe_buf = fpathconf(pfd, _PC_PIPE_BUF);
|
||||
if(pipe_buf == -1L)
|
||||
{
|
||||
serror("fpathconf %d, _PC_PIPE_BUF", pfd);
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
set_fd_nonblock(pfd);
|
||||
buf->pfd = pfd;
|
||||
if(bufsize < (size_t)pipe_buf)
|
||||
bufsize = (size_t)pipe_buf;
|
||||
buf->base = Alloc(bufsize, char);
|
||||
if(buf->base == NULL)
|
||||
goto err;
|
||||
buf->ptr = buf->base;
|
||||
buf->upperbound = buf->base + bufsize;
|
||||
return buf;
|
||||
err:
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* returns 0 or errno on error */
|
||||
int
|
||||
pbuf_flush(
|
||||
pbuf* buf,
|
||||
int block, /* bool_t */
|
||||
unsigned int timeo, /* N.B. Not a struct timeval */
|
||||
const char* const id)
|
||||
{
|
||||
size_t len = (size_t)(buf->ptr - buf->base);
|
||||
int changed = 0;
|
||||
int nwrote = 0;
|
||||
int status = ENOERR; /* success */
|
||||
int tmpErrno;
|
||||
time_t start;
|
||||
time_t stop;
|
||||
time_t duration;
|
||||
|
||||
udebug(" pbuf_flush fd %d %6d %s",
|
||||
buf->pfd, len, block ? "block" : "" );
|
||||
|
||||
if(len == 0)
|
||||
return 0; /* nothing to do */
|
||||
/* else */
|
||||
|
||||
(void)time(&start);
|
||||
|
||||
if(block)
|
||||
changed = clr_fd_nonblock(buf->pfd);
|
||||
|
||||
if(block && timeo != 0) /* (timeo == 0) => don't set alarm */
|
||||
SET_ALARM(timeo, flush_timeo);
|
||||
|
||||
nwrote = (int) write(buf->pfd, buf->base, len);
|
||||
tmpErrno = errno; /* CLR_ALRM() can change "errno" */
|
||||
|
||||
if(block && timeo != 0)
|
||||
CLR_ALRM();
|
||||
|
||||
if(nwrote == -1) {
|
||||
if((tmpErrno == EAGAIN) && (!block)) {
|
||||
udebug(" pbuf_flush: EAGAIN on %d bytes", len);
|
||||
|
||||
nwrote = 0;
|
||||
}
|
||||
else {
|
||||
status = tmpErrno;
|
||||
|
||||
serror("pbuf_flush (%d) write", buf->pfd);
|
||||
}
|
||||
}
|
||||
else if(nwrote == len) {
|
||||
/* wrote the whole buffer */
|
||||
udebug(" pbuf_flush: wrote %d bytes", nwrote);
|
||||
|
||||
buf->ptr = buf->base;
|
||||
len = 0;
|
||||
}
|
||||
else if(nwrote > 0) {
|
||||
/* partial write, just shift the amount wrote */
|
||||
udebug(" pbuf_flush: partial write %d of %d bytes",
|
||||
nwrote, len);
|
||||
|
||||
len -= nwrote;
|
||||
|
||||
/* could be an overlapping copy */
|
||||
memmove(buf->base, buf->base + nwrote, len);
|
||||
|
||||
buf->ptr = buf->base +len;
|
||||
}
|
||||
|
||||
if(changed)
|
||||
set_fd_nonblock(buf->pfd);
|
||||
|
||||
duration = time(NULL) - start;
|
||||
|
||||
if(duration > 5)
|
||||
uwarn(id == NULL
|
||||
? "write(%d,,%d) to decoder took %lu s"
|
||||
: "write(%d,,%d) to decoder took %lu s: %s",
|
||||
buf->pfd, nwrote, (unsigned long)duration, id);
|
||||
|
||||
return status;
|
||||
|
||||
flush_timeo:
|
||||
if(changed)
|
||||
set_fd_nonblock(buf->pfd);
|
||||
|
||||
uerror(id == NULL
|
||||
? "write(%d,,%lu) to decoder timed-out (%lu s)"
|
||||
: "write(%d,,%lu) to decoder timed-out (%lu s): %s",
|
||||
buf->pfd, (unsigned long)len, (unsigned long)(time(NULL) - start), id);
|
||||
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
int
|
||||
pbuf_write(
|
||||
pbuf* buf,
|
||||
const char* ptr,
|
||||
size_t nbytes,
|
||||
unsigned int timeo, /* N.B. Not a struct timeval */
|
||||
const char* const id)
|
||||
{
|
||||
size_t tlen;
|
||||
|
||||
while (nbytes > 0) {
|
||||
tlen = (size_t)(buf->upperbound - buf->ptr);
|
||||
tlen = (nbytes < tlen) ? nbytes : tlen;
|
||||
|
||||
memcpy(buf->ptr, ptr, tlen);
|
||||
|
||||
buf->ptr += tlen;
|
||||
|
||||
if(buf->ptr == buf->upperbound) {
|
||||
const int status = pbuf_flush(buf, 1, timeo, id);
|
||||
|
||||
if(status != ENOERR)
|
||||
return status;
|
||||
}
|
||||
|
||||
ptr += tlen;
|
||||
nbytes -= tlen;
|
||||
}
|
||||
|
||||
/* write what we can */
|
||||
return pbuf_flush(buf, 0, 0, id);
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: pbuf.h,v 1.7.22.1 2007/01/19 20:47:04 steve Exp $ */
|
||||
|
||||
#ifndef _PBUF_H_
|
||||
#define _PBUF_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#ifndef ENOERR
|
||||
#define ENOERR 0
|
||||
#endif /*!ENOERR */
|
||||
|
||||
typedef struct {
|
||||
int pfd;
|
||||
char *base; /* actual storage */
|
||||
char *ptr; /* current position */
|
||||
char *upperbound; /* base + bufsize */
|
||||
} pbuf;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" void free_pbuf(pbuf *buf);
|
||||
extern "C" pbuf * new_pbuf(int pfd, size_t bufsize);
|
||||
extern "C" int pbuf_flush(pbuf *buf, int /*bool_t*/ block, unsigned int timeo,
|
||||
const char* id);
|
||||
extern "C" int pbuf_write(pbuf *buf, const char *ptr, size_t nbytes,
|
||||
unsigned int timeo, const char* id);
|
||||
#elif defined(__STDC__)
|
||||
extern void free_pbuf(pbuf *buf);
|
||||
extern pbuf * new_pbuf(int pfd, size_t bufsize);
|
||||
extern int pbuf_flush(pbuf *buf, int /*bool_t*/ block, unsigned int timeo,
|
||||
const char* id);
|
||||
extern int pbuf_write(pbuf *buf, const char *ptr, size_t nbytes,
|
||||
unsigned int timeo, const char* id);
|
||||
#else /* Old Style C */
|
||||
extern void free_pbuf();
|
||||
extern pbuf * new_pbuf();
|
||||
extern int pbuf_flush();
|
||||
extern int pbuf_write();
|
||||
#endif
|
||||
|
||||
#endif /* !_PBUF_H_ */
|
|
@ -1,367 +0,0 @@
|
|||
." $Id: pqact.1,v 1.9.20.1.2.6 2009/06/18 16:14:52 steve Exp $
|
||||
.TH PQACT 1 "$Date: 2009/06/18 16:14:52 $"
|
||||
.SH NAME
|
||||
pqact - program to process products in a Unidata LDM product queue
|
||||
.SH SYNOPSIS
|
||||
.HP
|
||||
.ft B
|
||||
pqact
|
||||
.nh
|
||||
\%[-v]
|
||||
\%[-x]
|
||||
\%[-l\ \fIlogpath\fP]
|
||||
\%[-d\ \fIdatadir\fP]
|
||||
\%[-q\ \fIpqfname\fP]
|
||||
\%[-f\ \fIfeedtype\fP]
|
||||
\%[-p\ \fIpattern\fP]
|
||||
\%[-i\ \fIinterval\fP]
|
||||
\%[-t\ \fItime\fP]
|
||||
\%[-o\ \fItime\fP]
|
||||
\%[\fIconf_file\fP]
|
||||
.hy
|
||||
.ft R
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
This program processes ldm data products from a local product queue (see
|
||||
\fBpq\fP(3)). Pattern matching is used to specify what actions are
|
||||
performed on each product.
|
||||
.LP
|
||||
A product's feed type is used for coarse product discrimination, and pattern
|
||||
matching on product identifiers determines which of a set of general actions
|
||||
are applied to the product. A product identifier may match multiple
|
||||
patterns, and hence multiple actions may be applied to it. A pattern may be
|
||||
used to mark parts of a product identifier for use in the associated action.
|
||||
The actions supported include filing products for later scheduled decoding
|
||||
or for direct use, decoding products as they arrive, adding products to a
|
||||
database for quick retrieval by applications, or executing arbitrary
|
||||
programs on the arrival of selected products, e.g., mailing local severe
|
||||
weather warnings to users.
|
||||
.LP
|
||||
.B pqact
|
||||
uses a configuration file
|
||||
.IR conf_file ,
|
||||
(default pqact.conf) to set up the table of patterns and associated actions
|
||||
for products. This file is human-readable and editable. It contains a list
|
||||
of pattern-action entries, where a pattern is a (feed type, regular
|
||||
expression) pair. The available actions are described in the ``USAGE''
|
||||
section, below.
|
||||
.LP
|
||||
Although it can be run manually, this program
|
||||
is typically started as subprocess of the ldm server, \fBrpc.ldmd(1)\fP,
|
||||
at system startup, from an \fBexec\fP line in the configuration file.
|
||||
This ensures that \fBpqact\fP is in the same process group as other
|
||||
programs sharing the queue.
|
||||
.LP
|
||||
When a \fBpqact\fP process terminates, it writes the insertion-time of
|
||||
the last successfully-processed data-product into a file. The pathname
|
||||
of the file is that of the configuration-file with ".state" appended.
|
||||
This allows a subsequent \fBpqact\fP process that executes the same
|
||||
configuration-file to start processing where the previous process stopped.
|
||||
It also means that a configuration-file should have at most one \fBpqact\fPr
|
||||
process executing it as a time.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -v
|
||||
Verbose logging.
|
||||
Informative messages (level \fBLOG_INFO\fP) are logged, including a line for
|
||||
each product read out of the product queue and a line for each action
|
||||
invoked on a product.
|
||||
By default, only messages of severity \fBLOG_NOTICE\fP and greater are
|
||||
logged.
|
||||
.TP
|
||||
.B -x
|
||||
Debug logging.
|
||||
Debugging messages (level \fBLOG_DEBUG\fP) are logged.
|
||||
.TP
|
||||
.BI "-l " logpath
|
||||
Log file pathname.
|
||||
The program uses Unidata's \fBulog\fP(3) package to write error and log
|
||||
messages.
|
||||
The default is to write to the \fBsyslogd\fP(8) daemon. If this option is
|
||||
specified, however, then messages will be written to the file
|
||||
\fIlogpath\fP unless that pathname is "-", in which case all messages will be
|
||||
written to standard error and the program will not put itself into the
|
||||
background.
|
||||
.TP
|
||||
.BI \-d " datadir"
|
||||
The directory relative to
|
||||
which file names are specified in the configuration file.
|
||||
The default is set at compile time, typically /usr/local/ldm.
|
||||
.TP
|
||||
.BI "-q " pqfname
|
||||
The name of the product queue file.
|
||||
The default is \fBdata/ldm.pq\fP relative to the installation point,
|
||||
which is typically \fB/usr/local/ldm\fP. The compiled in default can
|
||||
be overridden by setting the environment variable \fBLDMPQFNAME\fP.
|
||||
You can specify a null product queue
|
||||
\fB/dev/null\fP to just check the syntax of a configuration file for
|
||||
\fBpqact\fP, as in
|
||||
.RS +12
|
||||
pqact -v -l- -q /dev/null pqact.conf
|
||||
.RE
|
||||
.TP
|
||||
.BI \-f " feedtype"
|
||||
Reads from the product queue only products that have a feedtype that is a
|
||||
member of the \fIfeedtype\fP set. The default is `ANY', specifying all
|
||||
feedtypes. See the ``Usage'' section below for a list of basic feedtypes
|
||||
and the use of feedtype expressions to specify combinations of basic
|
||||
feedtypes.
|
||||
.TP
|
||||
.BI \-p " pattern"
|
||||
Reads from the product queue only products whose identifier
|
||||
matches \fIpattern\fP.
|
||||
The default is `\fB.*\fP', specifying all products. A pattern that is
|
||||
longer than two characters and that has a ".*" prefix is deemed
|
||||
pathological and causes the program to log a warning message.
|
||||
.TP
|
||||
.BI \-i " time"
|
||||
Polling interval, in seconds.
|
||||
Check for new products in the product queue every \fItime\fP seconds.
|
||||
When
|
||||
.B pqact
|
||||
is run in the same process group as the programs that insert products into
|
||||
the product queue, a signal informs
|
||||
.B pqact
|
||||
and all other interested processes in the process group
|
||||
whenever a new product is available, so polling is not necessary in this
|
||||
case. The default
|
||||
interval is 15 seconds.
|
||||
.TP
|
||||
.BI \-o " time"
|
||||
Offset time, in seconds.
|
||||
Begin scan with products created \fItime\fP
|
||||
seconds earlier than the current time.
|
||||
The default is to begin just after the time stamp of the oldest product
|
||||
in the queue at startup.
|
||||
This option might be used when manually processing data from an old queue.
|
||||
.TP
|
||||
.I conf_file
|
||||
Configuration file. This is the pattern-action file that specifies what to
|
||||
do with each product whose feed type and product identifier match a
|
||||
specified pattern. The format of this file is described in the ``Usage''
|
||||
section, below. The default is \fBetc/pqact.conf\fP relative to the
|
||||
installation point, which is typically \fB/usr/local/ldm\fP.
|
||||
.SH SIGNALS
|
||||
.TP
|
||||
.BR SIGTERM
|
||||
Graceful termination after finishing actions on current product.
|
||||
.TP
|
||||
.BR SIGHUP
|
||||
Rereads configuration file.
|
||||
.TP
|
||||
.BR SIGINT
|
||||
Immediate termination.
|
||||
.TP
|
||||
.B SIGUSR1
|
||||
A no-op. (This program currently keeps no internal statistics.)
|
||||
.TP
|
||||
.B SIGUSR2
|
||||
Cyclically increment the verbosity of the program. Assumming the program was
|
||||
started without the \fB-v\fP or \fB-x\fP switches, the first \fBSIGUSR2\fP will
|
||||
make it verbose and \fBLOG_INFO\fP priority messages will appear.
|
||||
The second will turn on the \fBLOG_DEBUG\fP priority messages as well.
|
||||
A third will take it back to the normal state.
|
||||
.TP
|
||||
.B SIGCONT
|
||||
Wake up if sleeping, because there is a new product in the queue.
|
||||
|
||||
.SH USAGE
|
||||
.LP
|
||||
Each pattern-action rule in the configuration file begins with a
|
||||
non-white-space character and consists of three fields, separated by one or
|
||||
more tab characters: a feedtype field, a pattern field, and an action field
|
||||
that may include one or more action arguments. An initial `#' character
|
||||
indicates a comment line. An initial sequence of one or more blank or tab
|
||||
characters indicates a new field of the previous pattern-action line. This
|
||||
allows multiline pattern-action rules.
|
||||
|
||||
|
||||
.SS Feedtypes
|
||||
.LP
|
||||
Each data product has an associated feedtype and product identifier. The
|
||||
feedtype names the data stream from which the product originated and the
|
||||
product identifier distinguishes different products within a data stream.
|
||||
The feedtype field provides coarse discrimination among various data
|
||||
sources. It helps determine how the product identifiers should be
|
||||
interpreted, since each data source may use a different scheme for product
|
||||
identifiers. The feedtypes currently recognized are:
|
||||
|
||||
.TP 10
|
||||
.B NONE
|
||||
matches no feed
|
||||
.TP 10
|
||||
.B PPS
|
||||
Public Products Service
|
||||
.TP 10
|
||||
.B DDS
|
||||
Domestic Data Service
|
||||
.TP 10
|
||||
.B DDPLUS
|
||||
Domestic Data Plus, a union of DDS and PPS.
|
||||
.TP 10
|
||||
.B IDS
|
||||
International Product Service
|
||||
.TP 10
|
||||
.B HRS
|
||||
High-Resolution Data Service, consisting of forecast model outputs from the
|
||||
U.S. National Meteorological Center and the European Center for Medium-Range
|
||||
Weather Forecasts.
|
||||
.TP 10
|
||||
.B WMO
|
||||
any of the above WMO format products, so named because they use World
|
||||
Meteorological Organization standard headers for product identifiers.
|
||||
.TP 10
|
||||
.B MCIDAS
|
||||
Unidata/Wisconsin broadcast
|
||||
.TP 10
|
||||
.B PCWS
|
||||
Forecast Systems Lab PC DARE feed
|
||||
.TP 10
|
||||
.B FSL
|
||||
Other FSL feeds
|
||||
.TP 10
|
||||
.B NMC
|
||||
NMC feeds
|
||||
.TP 10
|
||||
.B NLDN
|
||||
National Lighting Data Network
|
||||
.TP 10
|
||||
.B EXP
|
||||
experimental data feed
|
||||
.TP 10
|
||||
.B ANY
|
||||
wild card, matches any product feedtype
|
||||
.LP
|
||||
The feedtype field may also contain a feedtype expression specifying a
|
||||
combination of the above named feedtypes, using the union operator `|', the
|
||||
difference operator `-', and parentheses for grouping. For example, to
|
||||
specify products from either the IDS feed or the HRS feed, use
|
||||
.RS +4
|
||||
IDS|HRS
|
||||
.RE
|
||||
.LP
|
||||
To specify any products from the WMO feeds except HRS products, use
|
||||
.RS +4
|
||||
WMO-HRS
|
||||
.RE
|
||||
|
||||
.SS Product Identifiers
|
||||
.LP
|
||||
A product identifier is typically extracted from characters at the beginning
|
||||
of a product in the data stream. When a product is first processed or
|
||||
created, the feedtype and product identifier are assigned. For each product
|
||||
it reads out of the product queue,
|
||||
.B pqact
|
||||
attempts to match the
|
||||
feedtype and identifier against entries in the configuration file. Whether a
|
||||
product is captured or processed further is determined by whether its
|
||||
feedtype and identifier match any of the pattern-action rules specified in
|
||||
the configuration file.
|
||||
.LP
|
||||
The identifier of a product is successively matched against each pattern
|
||||
in the configuration file that has a matching feedtype; whenever a match is
|
||||
found with such a pattern, the associated action is invoked.
|
||||
|
||||
.SS Patterns
|
||||
.LP
|
||||
A pattern is an extended regular expression (see \fBregex\fP(5)) that matches
|
||||
product identifiers in the data stream. Since the end of the pattern field
|
||||
is delimited by a tab or newline character, the pattern cannot contain a
|
||||
literal tab or newline character but may contain blanks. Patterns longer
|
||||
than two characters and that start with a ".*" prefix are deemed pathological
|
||||
and cause the program to log warning messages.
|
||||
|
||||
|
||||
.SS Actions
|
||||
.LP
|
||||
The action field consists of an action command followed by a tab and one or
|
||||
more arguments separated by blanks or tabs. Valid actions in the LDM are:
|
||||
|
||||
.TP 10
|
||||
.B FILE
|
||||
Write a product into a file.
|
||||
.TP 10
|
||||
.B STDIOFILE
|
||||
Buffered write of a product into a file.
|
||||
.TP 10
|
||||
.B PIPE
|
||||
Run another process with the product as input.
|
||||
.TP 10
|
||||
.B EXEC
|
||||
Run another process (no connection).
|
||||
.TP 10
|
||||
.B DBFILE
|
||||
Store a product in a database.
|
||||
.TP 10
|
||||
.B ALLOW
|
||||
Obsolete action to specify which hosts may request which products. This is
|
||||
now handled by the \fBldmd.access\fP configuration file of \fBrpc.ldmd\fP(1)
|
||||
instead.
|
||||
.TP 10
|
||||
.B ACCEPT
|
||||
Obsolete action to specify which hosts may feed which products. This is
|
||||
now handled by the \fBldmd.access\fP configuration file of \fBrpc.ldmd\fP(1)
|
||||
instead.
|
||||
.LP
|
||||
For more information on these actions and their arguments, see the LDM Site
|
||||
Manager's Guide.
|
||||
|
||||
.SS Pattern-Action Rules
|
||||
.LP
|
||||
A product may match multiple pattern-action lines. In that case the
|
||||
specified actions are invoked for that product in the same order they appear
|
||||
in the configuration file.
|
||||
.LP
|
||||
Parts of a matching product identifier and components of the date of the
|
||||
data or the current date and time may be substituted into action arguments
|
||||
before the action is invoked. For more information about the notations for
|
||||
this, consult the section on the pqact(1) configuration-file in the
|
||||
``LDM Basics'' webpages for your particular release at
|
||||
\fBhttp://www.unidata.ucar.edu/software/ldm\fP.
|
||||
|
||||
.SH EXAMPLE
|
||||
|
||||
The following pattern-action rule will append all products from the DDS data
|
||||
stream that have product identifiers (in this case WMO headers) beginning
|
||||
with the characters `SAUS' to hourly files named saus_\fImmdd\fP.wmo
|
||||
(extracting the appropriate month and day fields from the product
|
||||
identifiers):
|
||||
.RS +4
|
||||
DDS ^SAUS.. ... (..)(..) FILE saus_\1\2.wmo
|
||||
.RE
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
.B pqact.conf
|
||||
Default configuration-file.
|
||||
.TP
|
||||
.B pqact.conf.state
|
||||
Default persistent-state file. Used to hold the insertion-time of
|
||||
the last, successfully-processed data-product.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.LP
|
||||
.BR runpg (1),
|
||||
.BR ldmd (1),
|
||||
.BR ulog (3),
|
||||
.BR pq (3),
|
||||
.BR syslogd (8),
|
||||
WWW URL \fBhttp://www.unidata.ucar.edu/software/ldm/\fP.
|
||||
|
||||
.SH SUPPORT
|
||||
.LP
|
||||
If you have problems with this program, then you should first examine the
|
||||
LDM email archive for similar problems and how they were solved.
|
||||
The email archive is available via the following World Wide Web URL:
|
||||
.sp
|
||||
.RS
|
||||
\fBhttp://www.unidata.ucar.edu/software/ldm\fP
|
||||
.RE
|
||||
.sp
|
||||
If this does not suffice and your site is a member of the Unidata
|
||||
program, then send an inquiry via email -- together will all relevant
|
||||
information -- to
|
||||
.sp
|
||||
.RS
|
||||
\fBsupport@unidata.ucar.edu\fP
|
||||
.RE
|
|
@ -1,698 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: pqact.c,v 1.40.10.6.2.14 2008/09/04 20:09:52 steve Exp $ */
|
||||
|
||||
/*
|
||||
* ldm server mainline program module
|
||||
*/
|
||||
|
||||
#include <ldmconfig.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
#ifndef NO_WAITPID
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#include "ldm.h"
|
||||
#include "error.h"
|
||||
#include "globals.h"
|
||||
#include "paths.h" /* built by configure from paths.h.in */
|
||||
#include "atofeedt.h"
|
||||
#include "pq.h"
|
||||
#include "palt.h"
|
||||
#include "ldmprint.h"
|
||||
#include "filel.h" /* pipe_timeo */
|
||||
#include "state.h"
|
||||
#include "timestamp.h"
|
||||
#include "ulog.h"
|
||||
#include "log.h"
|
||||
#include "RegularExpressions.h"
|
||||
|
||||
#ifdef NO_ATEXIT
|
||||
#include "atexit.h"
|
||||
#endif
|
||||
|
||||
static volatile int hupped = 0;
|
||||
static char* conffilename = 0;
|
||||
static int shmid = -1;
|
||||
static int semid = -1;
|
||||
static key_t key;
|
||||
static key_t semkey;
|
||||
timestampt oldestCursor;
|
||||
timestampt currentCursor;
|
||||
int currentCursorSet = 0;
|
||||
|
||||
#ifndef DEFAULT_INTERVAL
|
||||
#define DEFAULT_INTERVAL 15
|
||||
#endif
|
||||
#ifndef DEFAULT_FEEDTYPE
|
||||
#define DEFAULT_FEEDTYPE ANY
|
||||
#endif
|
||||
#ifndef DEFAULT_PATTERN
|
||||
#define DEFAULT_PATTERN ".*"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Timeout used for PIPE actions,
|
||||
* referenced in filel.c
|
||||
*/
|
||||
#ifndef DEFAULT_PIPE_TIMEO
|
||||
#define DEFAULT_PIPE_TIMEO 60
|
||||
#endif /* !DEFAULT_PIPE_TIMEO */
|
||||
int pipe_timeo = DEFAULT_PIPE_TIMEO;
|
||||
|
||||
|
||||
/*
|
||||
* called at exit
|
||||
*/
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
unotice("Exiting");
|
||||
|
||||
if (done) {
|
||||
/*
|
||||
* We are not in the interrupt context, so these can
|
||||
* be performed safely.
|
||||
*/
|
||||
fl_close_all();
|
||||
|
||||
if (pq)
|
||||
(void)pq_close(pq);
|
||||
|
||||
if (currentCursorSet) {
|
||||
timestampt now;
|
||||
|
||||
(void)set_timestamp(&now);
|
||||
unotice("Behind by %g s", d_diff_timestamp(&now, ¤tCursor));
|
||||
|
||||
if (stateWrite(¤tCursor) < 0) {
|
||||
log_add("Couldn't save insertion-time of last processed "
|
||||
"data-product");
|
||||
log_log(LOG_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
while (reap(-1, WNOHANG) > 0)
|
||||
/*EMPTY*/;
|
||||
}
|
||||
|
||||
if(shmid != -1) {
|
||||
unotice("Deleting shared segment.");
|
||||
shmctl(shmid, IPC_RMID, NULL);
|
||||
}
|
||||
if(semid != -1) {
|
||||
semctl(semid, 0, IPC_RMID);
|
||||
}
|
||||
|
||||
(void)closeulog();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* called upon receipt of signals
|
||||
*/
|
||||
static void
|
||||
signal_handler(int sig)
|
||||
{
|
||||
#ifdef SVR3SIGNALS
|
||||
/*
|
||||
* Some systems reset handler to SIG_DFL upon entry to handler.
|
||||
* In that case, we reregister our handler.
|
||||
*/
|
||||
(void) signal(sig, signal_handler);
|
||||
#endif
|
||||
switch(sig) {
|
||||
case SIGHUP :
|
||||
hupped = 1;
|
||||
return;
|
||||
case SIGINT :
|
||||
exit(0);
|
||||
/*NOTREACHED*/
|
||||
case SIGTERM :
|
||||
done = 1;
|
||||
return;
|
||||
case SIGUSR1 :
|
||||
/* TODO? stats */
|
||||
return;
|
||||
case SIGUSR2 :
|
||||
rollulogpri();
|
||||
return;
|
||||
case SIGALRM :
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* register the signal_handler
|
||||
*/
|
||||
static void
|
||||
set_sigactions(void)
|
||||
{
|
||||
struct sigaction sigact;
|
||||
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
|
||||
/* Ignore these */
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
(void) sigaction(SIGPIPE, &sigact, NULL);
|
||||
|
||||
/* Handle these */
|
||||
#ifdef SA_RESTART /* SVR4, 4.3+ BSD */
|
||||
/* usually, restart system calls */
|
||||
sigact.sa_flags |= SA_RESTART;
|
||||
/*
|
||||
* NOTE: The OSF/1 operating system doesn't conform to the UNIX standard
|
||||
* in this regard: the SA_RESTART flag does not affect writes to regular
|
||||
* files or, apparently, pipes. Consequently, interrupted writes must
|
||||
* be handled explicitly. See the discussion of the SA_RESTART option
|
||||
* at http://www.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
|
||||
*/
|
||||
#endif
|
||||
sigact.sa_handler = signal_handler;
|
||||
(void) sigaction(SIGHUP, &sigact, NULL);
|
||||
(void) sigaction(SIGTERM, &sigact, NULL);
|
||||
(void) sigaction(SIGUSR1, &sigact, NULL);
|
||||
(void) sigaction(SIGUSR2, &sigact, NULL);
|
||||
(void) sigaction(SIGALRM, &sigact, NULL);
|
||||
|
||||
/* Don't restart after interrupt */
|
||||
sigact.sa_flags = 0;
|
||||
#ifdef SA_INTERRUPT /* SunOS 4.x */
|
||||
sigact.sa_flags |= SA_INTERRUPT;
|
||||
#endif
|
||||
(void) sigaction(SIGINT, &sigact, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
usage(
|
||||
char *av0 /* id string */
|
||||
)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"Usage: %s [options] [confilename]\t\nOptions:\n",
|
||||
av0);
|
||||
(void)fprintf(stderr,
|
||||
"\t-v Verbose, log each match (SIGUSR2 cycles)\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-x Debug mode (SIGUSR2 cycles)\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-l logfile Send log info to file (default uses syslogd)\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-d datadir cd to \"datadir\" before interpreting filenames in\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t conffile (default %s)\n",
|
||||
DEFAULT_DATADIR);
|
||||
(void)fprintf(stderr,
|
||||
"\t-q queue default \"%s\"\n", DEFAULT_QUEUE);
|
||||
(void)fprintf(stderr,
|
||||
"\t-p pattern Interested in products matching \"pattern\" (default \"%s\")\n", DEFAULT_PATTERN);
|
||||
(void)fprintf(stderr,
|
||||
"\t-f feedtype Interested in products from feed \"feedtype\" (default %s)\n", s_feedtypet(DEFAULT_FEEDTYPE));
|
||||
(void)fprintf(stderr,
|
||||
"\t-i interval loop, polling each \"interval\" seconds (default %d)\n", DEFAULT_INTERVAL);
|
||||
(void)fprintf(stderr,
|
||||
"\t-t timeo set write timeo for PIPE subprocs to \"timeo\" secs (default %d)\n", DEFAULT_PIPE_TIMEO);
|
||||
(void)fprintf(stderr,
|
||||
"\t-o offset the oldest product we will consider is \"offset\" secs before now (default: most recent in queue)\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t(default conffilename is %s)\n",
|
||||
DEFAULT_CONFFILENAME);
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int ac, char *av[])
|
||||
{
|
||||
int status = 0;
|
||||
char *logfname = 0;
|
||||
/* data directory, conffile paths may be relative */
|
||||
char *datadir = DEFAULT_DATADIR;
|
||||
int interval = DEFAULT_INTERVAL;
|
||||
prod_spec spec;
|
||||
prod_class_t clss;
|
||||
int toffset = TOFFSET_NONE;
|
||||
int loggingToStdErr = 0;
|
||||
unsigned queue_size = 5000;
|
||||
|
||||
conffilename = DEFAULT_CONFFILENAME;
|
||||
|
||||
spec.feedtype = DEFAULT_FEEDTYPE;
|
||||
spec.pattern = DEFAULT_PATTERN;
|
||||
|
||||
if(set_timestamp(&clss.from) != ENOERR) /* corrected by toffset below */
|
||||
{
|
||||
int errnum = errno;
|
||||
fprintf(stderr, "Couldn't set timestamp: %s",
|
||||
strerror(errnum));
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
clss.to = TS_ENDT;
|
||||
clss.psa.psa_len = 1;
|
||||
clss.psa.psa_val = &spec;
|
||||
|
||||
/*
|
||||
* Check the environment for some options.
|
||||
* May be overridden by command line switches below.
|
||||
*/
|
||||
{
|
||||
const char *ldmpqfname = getenv("LDMPQFNAME");
|
||||
if(ldmpqfname != NULL)
|
||||
pqfname = ldmpqfname;
|
||||
}
|
||||
/*
|
||||
* deal with the command line, set options
|
||||
*/
|
||||
{
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
extern char *optarg;
|
||||
|
||||
int ch;
|
||||
int logmask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) |
|
||||
LOG_MASK(LOG_NOTICE));
|
||||
int fterr;
|
||||
|
||||
opterr = 1;
|
||||
|
||||
while ((ch = getopt(ac, av, "vxel:d:f:q:o:p:i:t:")) != EOF)
|
||||
switch (ch) {
|
||||
case 'v':
|
||||
logmask |= LOG_UPTO(LOG_INFO);
|
||||
break;
|
||||
case 'x':
|
||||
logmask |= LOG_MASK(LOG_DEBUG);
|
||||
break;
|
||||
case 'e':
|
||||
key = ftok("/etc/rc.d/rc.local",'R');
|
||||
semkey = ftok("/etc/rc.d/rc.local",'e');
|
||||
shmid = shmget(key, sizeof(edex_message) * queue_size, 0666 | IPC_CREAT);
|
||||
semid = semget(semkey, 2, 0666 | IPC_CREAT);
|
||||
break;
|
||||
case 'l':
|
||||
logfname = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
datadir = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
fterr = strfeedtypet(optarg, &spec.feedtype);
|
||||
if(fterr != FEEDTYPE_OK)
|
||||
{
|
||||
fprintf(stderr, "Bad feedtype \"%s\", %s\n",
|
||||
optarg, strfeederr(fterr));
|
||||
usage(av[0]);
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
pqfname = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
toffset = atoi(optarg);
|
||||
if(toffset == 0 && *optarg != '0')
|
||||
{
|
||||
fprintf(stderr, "%s: invalid offset %s\n",
|
||||
av[0], optarg);
|
||||
usage(av[0]);
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
interval = atoi(optarg);
|
||||
if(interval == 0 && *optarg != '0')
|
||||
{
|
||||
fprintf(stderr, "%s: invalid interval %s\n", av[0], optarg);
|
||||
usage(av[0]);
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
pipe_timeo = atoi(optarg);
|
||||
if(pipe_timeo == 0 && *optarg != 0)
|
||||
{
|
||||
fprintf(stderr, "%s: invalid pipe_timeo %s", av[0], optarg);
|
||||
usage(av[0]);
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
spec.pattern = optarg;
|
||||
break;
|
||||
case '?':
|
||||
usage(av[0]);
|
||||
break;
|
||||
}
|
||||
if(ac - optind == 1)
|
||||
conffilename = av[optind];
|
||||
(void) setulogmask(logmask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize logging.
|
||||
*/
|
||||
loggingToStdErr = STDERR_FILENO == openulog(
|
||||
ubasename(av[0]), (LOG_CONS|LOG_PID), LOG_LDM, logfname);
|
||||
|
||||
unotice("Starting Up");
|
||||
|
||||
/*
|
||||
* Initialze the previous-state module for this process.
|
||||
*/
|
||||
if (stateInit(conffilename) < 0) {
|
||||
log_add("Couldn't initialize previous-state module");
|
||||
log_log(LOG_ERR);
|
||||
exit(EXIT_FAILURE);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* The standard input stream is redirected to /dev/null because this
|
||||
* program doesn't use it and doing so prevents child processes
|
||||
* that mistakenly read from it from terminating abnormally.
|
||||
*/
|
||||
if (NULL == freopen("/dev/null", "r", stdin))
|
||||
{
|
||||
err_log_and_free(
|
||||
ERR_NEW1(0, NULL,
|
||||
"Couldn't redirect stdin to /dev/null: %s",
|
||||
strerror(errno)),
|
||||
ERR_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* The standard output stream is redirected to /dev/null because this
|
||||
* program doesn't use it and doing so prevents child processes
|
||||
* that mistakenly write to it from terminating abnormally.
|
||||
*/
|
||||
if (NULL == freopen("/dev/null", "w", stdout))
|
||||
{
|
||||
err_log_and_free(
|
||||
ERR_NEW1(0, NULL,
|
||||
"Couldn't redirect stdout to /dev/null: %s",
|
||||
strerror(errno)),
|
||||
ERR_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* If the standard error stream isn't being used for logging, then it's
|
||||
* redirected to /dev/null to prevent child processes that mistakenly
|
||||
* write to it from terminating abnormally.
|
||||
*/
|
||||
if (!loggingToStdErr && NULL == freopen("/dev/null", "w", stderr))
|
||||
{
|
||||
err_log_and_free(
|
||||
ERR_NEW1(0, NULL, "Couldn't redirect stderr to /dev/null: %s",
|
||||
strerror(errno)),
|
||||
ERR_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Inform the "filel" module about the number of available file
|
||||
* descriptors. File descriptors are reserved for stdin, stdout,
|
||||
* stderr, the product-queue, the configuration-file, and (possibly)
|
||||
* logging.
|
||||
*/
|
||||
if (0 != set_avail_fd_count(openMax() - (5 + (!loggingToStdErr))))
|
||||
{
|
||||
uerror("Couldn't set number of available file-descriptors");
|
||||
unotice("Exiting");
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Inform the "filel" module of the shared memory segment
|
||||
*/
|
||||
if (shmid != -1 && semid != -1)
|
||||
{
|
||||
set_shared_space(shmid, semid, queue_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile the pattern.
|
||||
*/
|
||||
if (re_isPathological(spec.pattern))
|
||||
{
|
||||
uerror("Adjusting pathological regular-expression: \"%s\"",
|
||||
spec.pattern);
|
||||
re_vetSpec(spec.pattern);
|
||||
}
|
||||
status = regcomp(&spec.rgx, spec.pattern, REG_EXTENDED|REG_NOSUB);
|
||||
if(status != 0)
|
||||
{
|
||||
uerror("Can't compile regular expression \"%s\"",
|
||||
spec.pattern);
|
||||
unotice("Exiting");
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* register exit handler
|
||||
*/
|
||||
if(atexit(cleanup) != 0)
|
||||
{
|
||||
serror("atexit");
|
||||
unotice("Exiting");
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* set up signal handlers
|
||||
*/
|
||||
set_sigactions();
|
||||
|
||||
/*
|
||||
* Read in (compile) the configuration file. We do this first so
|
||||
* its syntax may be checked without opening a product queue.
|
||||
*/
|
||||
if ((status = readPatFile(conffilename)) < 0) {
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
else if (status == 0) {
|
||||
unotice("Configuration-file \"%s\" has no entries. "
|
||||
"You should probably not start this program instead.",
|
||||
conffilename);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the product queue
|
||||
*/
|
||||
status = pq_open(pqfname, PQ_READONLY, &pq);
|
||||
if(status)
|
||||
{
|
||||
if (PQ_CORRUPT == status) {
|
||||
uerror("The product-queue \"%s\" is inconsistent\n",
|
||||
pqfname);
|
||||
}
|
||||
else {
|
||||
uerror("pq_open failed: %s: %s\n",
|
||||
pqfname, strerror(status));
|
||||
}
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if(toffset != TOFFSET_NONE)
|
||||
{
|
||||
/*
|
||||
* Filter and queue position set by "toffset".
|
||||
*/
|
||||
clss.from.tv_sec -= toffset;
|
||||
pq_cset(pq, &clss.from);
|
||||
} /* no time-offset specified */
|
||||
else
|
||||
{
|
||||
int needFromTime = 1;
|
||||
|
||||
/*
|
||||
* Try getting the time of the last, successfully-processed
|
||||
* data-product from the previous invocation.
|
||||
*/
|
||||
status = stateRead(&clss.from);
|
||||
|
||||
if (status == 0) {
|
||||
timestampt now;
|
||||
|
||||
(void)set_timestamp(&now);
|
||||
|
||||
if (tvCmp(now, clss.from, <)) {
|
||||
log_start("Time of last processed data-product from "
|
||||
"previous execution is in future. Adjusting...");
|
||||
log_log(LOG_WARNING);
|
||||
}
|
||||
else {
|
||||
char buf[80];
|
||||
|
||||
(void)strftime(buf, sizeof(buf), "%Y-%m-%d %T",
|
||||
gmtime(&clss.from.tv_sec));
|
||||
unotice("Starting from insertion-time %s.%06lu UTC", buf,
|
||||
(unsigned long)clss.from.tv_usec);
|
||||
pq_cset(pq, &clss.from);
|
||||
|
||||
needFromTime = 0;
|
||||
}
|
||||
}
|
||||
else if (status == -2) {
|
||||
/*
|
||||
* Previous-state information doesn't exist.
|
||||
*/
|
||||
log_add(
|
||||
"Previous-state information doesn't exist. Continuing...");
|
||||
log_log(LOG_WARNING);
|
||||
}
|
||||
else if (status == -3) {
|
||||
/*
|
||||
* Previous-state I/O error.
|
||||
*/
|
||||
log_add("Previous-state I/O error. Continuing...");
|
||||
log_log(LOG_WARNING);
|
||||
}
|
||||
|
||||
if (needFromTime) {
|
||||
/*
|
||||
* Be permissive with the time filter,
|
||||
* jump now to the end of the queue.
|
||||
*/
|
||||
clss.from = TS_ZERO;
|
||||
(void)pq_last(pq, &clss, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if(ulogIsVerbose())
|
||||
{
|
||||
char buf[1984];
|
||||
uinfo("%s", s_prod_class(buf, sizeof(buf), &clss));
|
||||
}
|
||||
|
||||
/*
|
||||
* Change directories if datadir was specified
|
||||
*/
|
||||
if(datadir != NULL && *datadir != 0)
|
||||
{
|
||||
/* change to data directory */
|
||||
if (chdir(datadir) == -1)
|
||||
{
|
||||
serror("cannot chdir to %s", datadir);
|
||||
exit(4);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Do special pre main loop actions in pattern/action file
|
||||
* N.B. Deprecate.
|
||||
*/
|
||||
dummyprod("_BEGIN_");
|
||||
|
||||
|
||||
/*
|
||||
* Main loop
|
||||
*/
|
||||
for (;;) {
|
||||
if (hupped) {
|
||||
unotice("Rereading configuration file %s", conffilename);
|
||||
(void) readPatFile(conffilename);
|
||||
hupped = 0;
|
||||
}
|
||||
|
||||
status = pq_sequence(pq, TV_GT, &clss, processProduct, 0);
|
||||
|
||||
if (status == 0) {
|
||||
/*
|
||||
* A data-product was processed.
|
||||
*/
|
||||
timestampt oldestCursor;
|
||||
|
||||
pq_ctimestamp(pq, ¤tCursor);
|
||||
currentCursorSet = 1;
|
||||
|
||||
if (pq_getOldestCursor(pq, &oldestCursor) == 0 &&
|
||||
tvEqual(oldestCursor, currentCursor)) {
|
||||
timestampt now;
|
||||
|
||||
(void)set_timestamp(&now);
|
||||
uwarn("Processed oldest product in queue: %g s",
|
||||
d_diff_timestamp(&now, ¤tCursor));
|
||||
}
|
||||
|
||||
(void)exitIfDone(0);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* No data-product was processed.
|
||||
*/
|
||||
if (status == PQUEUE_END) {
|
||||
udebug("End of Queue");
|
||||
|
||||
if (interval == 0)
|
||||
break;
|
||||
}
|
||||
else if (status == EAGAIN || status == EACCES) {
|
||||
udebug("Hit a lock");
|
||||
/*
|
||||
* Close the least recently used file descriptor.
|
||||
*/
|
||||
close_lru(FL_NOTRANSIENT);
|
||||
}
|
||||
else if (status == EDEADLK
|
||||
#if defined(EDEADLOCK) && EDEADLOCK != EDEADLK
|
||||
|| status == EDEADLOCK
|
||||
#endif
|
||||
) {
|
||||
uerror("%s", strerror(status));
|
||||
/*
|
||||
* Close the least recently used file descriptor.
|
||||
*/
|
||||
close_lru(FL_NOTRANSIENT);
|
||||
}
|
||||
else {
|
||||
uerror("pq_sequence failed: %s (errno = %d)",
|
||||
strerror(status), status);
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
(void)pq_suspend(interval);
|
||||
(void)exitIfDone(0);
|
||||
} /* data-product not processed */
|
||||
|
||||
/*
|
||||
* Perform a non-blocking sync on all open file descriptors.
|
||||
*/
|
||||
fl_sync(-1, FALSE);
|
||||
|
||||
/*
|
||||
* Wait on any children which might have terminated.
|
||||
*/
|
||||
while (reap(-1, WNOHANG) > 0)
|
||||
/*EMPTY*/;
|
||||
} /* main loop */
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
####
|
||||
# $Id: pqact.conf,v 1.11.6.1.4.2.2.4 2008/09/17 16:36:09 steve Exp $
|
||||
#
|
||||
# This is an example pqact.conf file,
|
||||
# with some example entries commented out.
|
||||
#
|
||||
# The entries in this file control the disposition of data-products on
|
||||
# the local computer. More information on this file can be found at
|
||||
#
|
||||
# http://www.unidata.ucar.edu/software/ldm/
|
||||
#
|
||||
# under the "LDM Basics" webpages of a specific LDM release.
|
||||
#
|
||||
# The various display and analysis packages each have their own
|
||||
# conventions on data disposition. When you install a package such as
|
||||
# GEMPAK or McIdas, you should find with that package a collection of
|
||||
# entries to add to this file.
|
||||
#
|
||||
##
|
||||
# The format of an entry is
|
||||
#
|
||||
# feedtype tab pattern tab action [tab options] [tab action_args]
|
||||
#
|
||||
# where tab is \t or \n\t.
|
||||
#
|
||||
# Actions, options, and arguments are
|
||||
#
|
||||
# NOOP
|
||||
# Do nothing
|
||||
#
|
||||
# FILE [tab (-overwrite|-flush|-close|-strip)] tab filename
|
||||
# write(2) to unix file (flush calls fsync(2))
|
||||
#
|
||||
# STDIOFILE [tab (-overwrite|-flush|-close|-strip)] tab filename
|
||||
# fwrite(3) (buffered io) to file (flush calls fflush(3))
|
||||
#
|
||||
# DBFILE tab dbfilename [tab dbkey]
|
||||
# Put to gdbmfile.
|
||||
#
|
||||
# PIPE [tab (-close|-strip|-metadata|-nodata)] tab commandname [args]
|
||||
# Put data on stdin of a subprocess specified by
|
||||
# commandname [args].
|
||||
# Uses the execvp(2) library call, so if commandname is not fully
|
||||
# qualified, the PATH environment variable will be used.
|
||||
#
|
||||
# "-metadata" causes the metadata of the data-product to be
|
||||
# written to the pipe before any data. The metadata is written
|
||||
# in the following order using the indicated data-types:
|
||||
# metadata-length in bytes uint32_t
|
||||
# data-product signature (MD5 checksum) uchar[16]
|
||||
# data-product size in bytes uint32_t
|
||||
# product creation-time in seconds since the epoch:
|
||||
# integer portion uint64_t
|
||||
# microseconds portion int32_t
|
||||
# data-product feedtype uint32_t
|
||||
# data-product sequence number uint32_t
|
||||
# product-identifier:
|
||||
# length in bytes (excluding NUL) uint32_t
|
||||
# non-NUL-terminated string char[]
|
||||
# product-origin:
|
||||
# length in bytes (excluding NUL) uint32_t
|
||||
# non-NUL-terminated string char[]
|
||||
#
|
||||
# "-nodata" causes the data portion of the data-product to
|
||||
# *not* be written to the pipe. It also turns on the
|
||||
# "-metadata" option.
|
||||
#
|
||||
# EXEC [tab -wait] tab commandname [args ...]
|
||||
# Run a program. No io channel between this process and it.
|
||||
# Like PIPE above, uses execvp.
|
||||
#
|
||||
# The '-strip' option to FILE, STDIOFILE, & PIPE removes control characters
|
||||
# (other than the '\n') from the data before output. This is useful for
|
||||
# cleaning up WMO format text bulletins.
|
||||
#
|
||||
# The "-overwrite" option to FILE and STDIOFILE will cause the output
|
||||
# file to be truncated when it is opened but not when a data-product is
|
||||
# written; consequently, you should probably always use the "-close"
|
||||
# option in conjunction with "-overwrite".
|
||||
#
|
||||
# To check the syntax of the pqact.conf file, execute pqact with the product
|
||||
# queue specified as /dev/null:
|
||||
#
|
||||
# pqact -vxl- -q /dev/null pqact.conf
|
||||
#
|
||||
# or
|
||||
#
|
||||
# ldmadmin pqactcheck
|
||||
#
|
||||
# To send an HUP signal to pqact
|
||||
#
|
||||
# ldmadmin pqactHUP
|
||||
# ldmadmin tail (used to check HUP, look for ReRead msg)
|
||||
#
|
||||
# When creating actions for pqact be sure to also consider when and
|
||||
# how the data will ultimately be removed, otherwise you may fill up
|
||||
# your disk. The LDM 'scour' program is one possibility for removing files.
|
||||
#
|
||||
# By default, the FILE action appends to the file. Note that scour
|
||||
# won't remove files less than 1 day old. Files to which products are
|
||||
# frequently appended will generally be less than one day old, in which
|
||||
# case they will not be scoured and will have to be tidied up in some other way.
|
||||
# ------------------------------------------------------------------------
|
||||
# Examples
|
||||
#
|
||||
# Metars
|
||||
# Append all US metars.
|
||||
# This action will slowly consume disk space.
|
||||
#IDS|DDPLUS ^SAUS(..) (....)
|
||||
# FILE data/ldm/surface/US/\2/\1
|
||||
|
||||
# Watches, warnings, advisories
|
||||
# Append all special weather stmts to those of the same type and source.
|
||||
# This action will slowly consume disk space.
|
||||
#IDS|DDPLUS ^(WW....) (....)
|
||||
# FILE data/ldm/WWA/special/\1_\2
|
||||
|
||||
# Keep only the most recent nowcast for each forcast office
|
||||
#IDS|DDPLUS /pNOW(...)
|
||||
# FILE -overwrite -close data/ldm/nowcast/\1
|
||||
|
||||
# Keep only the most recent SIGMET.
|
||||
#IDS|DDPLUS ^WS
|
||||
# FILE -overwrite -close data/ldm/WWA/lastSIGMET
|
||||
|
||||
#
|
||||
# Bin all the (Non-GRIB) WMO format data, using elements from the
|
||||
# identifier as path components. The minutes portion of the timestamp,
|
||||
# and the retransmit code is ignored. The day of the month portion
|
||||
# of the timestamp is not used as a path component, so it would be
|
||||
# a good idea to run 'scour' on a less than 24 hour basis. This
|
||||
# action uses a lot of disk space.
|
||||
#
|
||||
# "ASUS42 KRDU 012259" gets filed as
|
||||
# data/US/KRDU/22/AS42.wmo
|
||||
#
|
||||
#WMO ^([^H][A-Z])([A-Z][A-Z])([0-9][0-9]) (....) ([0-3][0-9])([0-2][0-9])
|
||||
# FILE data/\2/\4/\6/\1\3.wmo
|
||||
#
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: state.c,v 1.1.2.4 2008/09/04 20:12:13 steve Exp $ */
|
||||
|
||||
/*
|
||||
* Persists state (e.g., time of last-processed data-product) of pqact(1)
|
||||
* processes between invocations.
|
||||
*/
|
||||
|
||||
#include <ldmconfig.h>
|
||||
#include <assert.h>
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "timestamp.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "state.h"
|
||||
|
||||
static char* statePathname = NULL;
|
||||
static char* tmpStatePathname = NULL;
|
||||
|
||||
|
||||
int
|
||||
stateInit(
|
||||
const char* const configPathname)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (configPathname == NULL) {
|
||||
log_start("stateInit(): Pathname is NULL");
|
||||
status = -1;
|
||||
}
|
||||
else {
|
||||
static const char* const extension = ".state";
|
||||
size_t pathlen =
|
||||
strlen(configPathname) + strlen(extension) + 1;
|
||||
char* newPath = malloc(pathlen);
|
||||
|
||||
if (newPath == NULL) {
|
||||
log_errno();
|
||||
log_add("stateInit(): Couldn't allocate %lu-byte pathname",
|
||||
(unsigned long)pathlen);
|
||||
status = -2;
|
||||
}
|
||||
else {
|
||||
static const char* const tmpExt = ".tmp";
|
||||
char* newTmpPath;
|
||||
|
||||
pathlen += strlen(tmpExt);
|
||||
newTmpPath = malloc(pathlen);
|
||||
|
||||
if (newTmpPath == NULL) {
|
||||
log_errno();
|
||||
log_add("stateInit(): Couldn't allocate %lu-byte pathname",
|
||||
(unsigned long)pathlen);
|
||||
status = -2;
|
||||
}
|
||||
else {
|
||||
(void)strcpy(newPath, configPathname);
|
||||
(void)strcat(newPath, extension);
|
||||
free(statePathname);
|
||||
statePathname = newPath;
|
||||
|
||||
(void)strcpy(newTmpPath, newPath);
|
||||
(void)strcat(newTmpPath, tmpExt);
|
||||
free(tmpStatePathname);
|
||||
tmpStatePathname = newTmpPath;
|
||||
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
} /* configPathname != NULL */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
stateRead(
|
||||
timestampt* const pqCursor)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (statePathname == NULL) {
|
||||
log_start("stateRead(): stateInit() not successfully called");
|
||||
status = -1; /* module not initialized */
|
||||
}
|
||||
else {
|
||||
FILE* file = fopen(statePathname, "r");
|
||||
|
||||
if (file == NULL) {
|
||||
log_errno();
|
||||
log_add("stateRead(): Couldn't open \"%s\"", statePathname);
|
||||
status = -2; /* couldn't open state-file */
|
||||
}
|
||||
else {
|
||||
int c;
|
||||
char comment[1];
|
||||
|
||||
status = -3; /* state-file is corrupt */
|
||||
|
||||
while ((c = fgetc(file)) == '#')
|
||||
(void)fscanf(file, "%*[^\n]\n", comment);
|
||||
|
||||
if (ferror(file)) {
|
||||
log_errno();
|
||||
log_add("stateRead(): Couldn't read comments from \"%s\"",
|
||||
statePathname);
|
||||
}
|
||||
else {
|
||||
unsigned long seconds;
|
||||
long microseconds;
|
||||
|
||||
ungetc(c, file);
|
||||
|
||||
if (fscanf(file, "%lu.%ld", &seconds, µseconds) != 2) {
|
||||
log_errno();
|
||||
log_add("stateRead(): Couldn't read time from \"%s\"",
|
||||
statePathname);
|
||||
}
|
||||
else {
|
||||
pqCursor->tv_sec = seconds;
|
||||
pqCursor->tv_usec = microseconds;
|
||||
status = 0; /* success */
|
||||
} /* read time */
|
||||
} /* read comments */
|
||||
|
||||
(void)fclose(file);
|
||||
} /* file open */
|
||||
} /* module initialized */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
stateWrite(
|
||||
const timestampt* const pqCursor)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (statePathname == NULL) {
|
||||
log_start("stateWrite(): stateInit() not successfully called");
|
||||
status = -1;
|
||||
}
|
||||
else {
|
||||
FILE* file = fopen(tmpStatePathname, "w");
|
||||
|
||||
if (file == NULL) {
|
||||
log_errno();
|
||||
log_add("stateWrite(): Couldn't open \"%s\"", tmpStatePathname);
|
||||
status = -2;
|
||||
}
|
||||
else {
|
||||
status = -3;
|
||||
|
||||
if (fputs(
|
||||
"# The following line contains the insertion-time of the last, successfully-\n"
|
||||
"# processed data-product. Do not modify it unless you know exactly what\n"
|
||||
"# you're doing!\n", file) < 0) {
|
||||
log_errno();
|
||||
log_add("stateWrite(): Couldn't write comment to \"%s\"",
|
||||
tmpStatePathname);
|
||||
}
|
||||
else {
|
||||
if (fprintf(file, "%lu.%06lu\n",
|
||||
(unsigned long)pqCursor->tv_sec,
|
||||
(unsigned long)pqCursor->tv_usec) < 0) {
|
||||
log_errno();
|
||||
log_add("stateWrite(): Couldn't write time to \"%s\"",
|
||||
tmpStatePathname);
|
||||
}
|
||||
else {
|
||||
if (rename(tmpStatePathname, statePathname) == -1) {
|
||||
log_errno();
|
||||
log_add("stateWrite(): "
|
||||
"Couldn't rename \"%s\" to \"%s\"",
|
||||
tmpStatePathname, statePathname);
|
||||
}
|
||||
else {
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(void)fclose(file);
|
||||
} /* output file open */
|
||||
} /* module initialized */
|
||||
|
||||
return status;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: state.h,v 1.1.2.1 2007/01/30 22:19:05 steve Exp $ */
|
||||
|
||||
#ifndef STATE_H_INCLUDED
|
||||
#define STATE_H_INCLUDED
|
||||
|
||||
#include "timestamp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int
|
||||
stateInit(
|
||||
const char* const configPathname);
|
||||
|
||||
int
|
||||
stateRead(
|
||||
timestampt* const pqCursor);
|
||||
|
||||
int
|
||||
stateWrite(
|
||||
const timestampt* const pqCursor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,4 +0,0 @@
|
|||
Oct 14 19:07:10 pqact[2121] NOTE: Starting Up
|
||||
Oct 14 19:07:10 pqact[2121] NOTE: Starting from insertion-time 2009-10-14 16:02:21.124572 UTC
|
||||
Oct 14 19:07:18 pqact[2121] NOTE: Exiting
|
||||
Oct 14 19:07:18 pqact[2121] NOTE: Deleting shared segment.
|
|
@ -1,7 +0,0 @@
|
|||
# $Id: Makefile,v 1.1 2003/02/26 23:43:48 steve Exp $
|
||||
|
||||
include ../macros.make
|
||||
PROGRAM = pqcat
|
||||
include ../simple_program.make
|
||||
include ../rules.make
|
||||
include depends
|
|
@ -1,11 +0,0 @@
|
|||
pqcat.o: ../config/ldmconfig.h
|
||||
pqcat.o: ../misc/paths.h
|
||||
pqcat.o: ../pq/pq.h
|
||||
pqcat.o: ../protocol/atofeedt.h
|
||||
pqcat.o: ../protocol/ldm.h
|
||||
pqcat.o: ../protocol/ldmprint.h
|
||||
pqcat.o: ../protocol/md5.h
|
||||
pqcat.o: ../protocol/prod_class.h
|
||||
pqcat.o: ../protocol/timestamp.h
|
||||
pqcat.o: ../ulog/ulog.h
|
||||
pqcat.o: pqcat.c
|
|
@ -1,183 +0,0 @@
|
|||
." $Id: pqcat.1,v 1.14.16.1.2.2 2009/06/18 16:15:03 steve Exp $
|
||||
.TH PQCAT 1 "$Date: 2009/06/18 16:15:03 $"
|
||||
.SH NAME
|
||||
pqcat - program to print products from an LDM product queue
|
||||
.SH SYNOPSIS
|
||||
.HP
|
||||
.ft B
|
||||
pqcat
|
||||
.nh
|
||||
\%[-v]
|
||||
\%[-O]
|
||||
\%[-x]
|
||||
\%[-l\ \fIlogfile\fP]
|
||||
\%[-f\ \fIfeedtype\fP]
|
||||
\%[-p\ \fIpattern\fP]
|
||||
\%[-q\ \fIpqfname\fP]
|
||||
\%[-i\ \fIinterval\fP]
|
||||
\%[-o\ \fIoffset\fP]
|
||||
\%[-c]
|
||||
\%[-s]
|
||||
\%[\fIoutputfile\fP]
|
||||
.hy
|
||||
.ft
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
This program writes to \fIoutputfile\fP selected data products from a local
|
||||
LDM product queue (see \fBpq\fP(3)). If no \fIoutputfile\fP is specified,
|
||||
the data is written to standard output. The program may also be used to log
|
||||
product information about the products in a product queue whose identifiers
|
||||
match a specified feedtype and pattern. By default,
|
||||
.B pqcat
|
||||
starts at the front of the product queue (the oldest products) and iterates
|
||||
through products in order until it reaches the end of the queue (the most
|
||||
recently inserted products). On reaching the end of the queue it exits,
|
||||
unless a non zero \fIinterval\fP is specified.
|
||||
.LP
|
||||
.B pqcat
|
||||
is typically used to see what is in the product queue or to select
|
||||
particular products out of the product queue.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -v
|
||||
Verbose logging. A line is emitted for every product in the queue whose
|
||||
feed type and identifier match the specified feedtype and pattern. The
|
||||
emitted line contains the UTC date and time, the program name, the product
|
||||
ingest time, feedtype, sequence number, size in bytes, and the product
|
||||
identifier.
|
||||
.TP
|
||||
.B -O
|
||||
Show product origin. Adds originating site of product to each line of
|
||||
verbose output. Valid only with -v option.
|
||||
.TP
|
||||
.B -x
|
||||
Debugging information is also emitted.
|
||||
.TP
|
||||
.BI "-l " logfile
|
||||
The path name of a file to be used as the log file for the process. The
|
||||
default is to use standard error when interactive and syslogd(8) otherwise.
|
||||
To use syslogd from the command line, enter ``pqcat ... >& /dev/null''.
|
||||
|
||||
.TP
|
||||
.BI \-f " feedtype"
|
||||
Reads from the product queue only products that have a feedtype that is a
|
||||
member of the \fIfeedtype\fP set. The default is `ANY', specifying all
|
||||
feed types. See \fBpqact\fP(1) for a list of basic feed types
|
||||
and the use of feedtype expressions to specify combinations of basic
|
||||
feed types.
|
||||
.TP
|
||||
.BI \-p " pattern"
|
||||
Reads from the product queue only products whose identifier
|
||||
matches the regular expression \fIpattern\fP.
|
||||
The default is `\fB.*\fP', specifying all products.
|
||||
.TP
|
||||
.BI "-q " pqfname
|
||||
The filename of the product queue.
|
||||
The default is \fBdata/ldm.pq\fP relative to the installation point,
|
||||
which is typically \fB/usr/local/ldm\fP.
|
||||
.TP
|
||||
.BI \-i " interval"
|
||||
Polling interval, in seconds. When the end of the queue is reached, the
|
||||
program sleeps and
|
||||
checks for new products in the product queue every \fIinterval\fP seconds.
|
||||
If the \fIinterval\fP is 0, the program exits after one pass through the queue.
|
||||
When
|
||||
.B pqcat
|
||||
is run in the same process group as the programs that insert products into
|
||||
the product queue, a signal informs
|
||||
.B pqcat
|
||||
and all other interested processes in the process group
|
||||
whenever a new product is available. This may wake up the process sooner than
|
||||
\fIinterval\fP.
|
||||
.TP
|
||||
.BI \-o " offset"
|
||||
Offset time, in seconds.
|
||||
Begin reading products inserted into the product queue \fIoffset\fP
|
||||
seconds earlier than the current time.
|
||||
The default is to read all products
|
||||
in the queue.
|
||||
.TP
|
||||
.B -c
|
||||
Check each product.
|
||||
Recompute the MD5 checksum of product data and compare it against the
|
||||
the signature in product description. If the comparison fails,
|
||||
a message is emitted.
|
||||
|
||||
.TP
|
||||
.B -s
|
||||
Queue "sanity" check.
|
||||
Scans entire queue, tallies number of products encountered, and
|
||||
compares the result with the number of products the queue thinks it should
|
||||
have. If the LDM is not running and no product subsets are specified
|
||||
on the command line, the
|
||||
results should agree. This is a simplistic way to determine
|
||||
whether the queue is corrupted. Although it may be possible for the
|
||||
queue to be in a bad state for some other reason, it is expected that
|
||||
this test will catch most ways in which queue corruption can occur. Note
|
||||
that if the LDM is running or if a subset of products is specified on
|
||||
the command line with the -f or -p options,
|
||||
the two results will not agree and pqcat will exit with a nonzero
|
||||
value. It is intended that pqcat -s be run before starting the LDM in
|
||||
order to determine whether or not to rebuild the queue before starting.
|
||||
|
||||
.SH SIGNALS
|
||||
.TP
|
||||
.BR SIGTERM
|
||||
Normal termination.
|
||||
.TP
|
||||
.BR SIGINT
|
||||
Immediate termination.
|
||||
.TP
|
||||
.B SIGUSR1
|
||||
Write status and product statistics to log output.
|
||||
.TP
|
||||
.B SIGUSR2
|
||||
Cyclically increment the verbosity of the program. Assumming the program was
|
||||
started without the \fB-v\fP or \fB-x\fP switches, the first \fBSIGUSR2\fP will
|
||||
make it verbose and \fBLOG_INFO\fP priority messages will appear.
|
||||
The second will turn on the \fBLOG_DEBUG\fP priority messages as well.
|
||||
A third will take it back to the normal state.
|
||||
|
||||
.SH EXAMPLE
|
||||
|
||||
The following invocation will capture into the file /tmp/pq.contents
|
||||
information about all the products currently in the default product queue:
|
||||
.RS +4
|
||||
pqcat -vl /tmp/pq.contents > /dev/null
|
||||
.RE
|
||||
The following example will emit to stderr information about each product as
|
||||
it is inserted into a product queue in /tmp/ldm.pq, starting at the
|
||||
current time:
|
||||
.RS +4
|
||||
pqcat -v -q /tmp/ldm.pq -o 0 -i 15 > /dev/null
|
||||
.RE
|
||||
|
||||
.SH FILES
|
||||
.LP
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.LP
|
||||
.BR ldmd (1),
|
||||
.BR pqact(1),
|
||||
.BR ulog (3),
|
||||
.BR pq (3),
|
||||
.BR syslogd (8),
|
||||
WWW URL \fBhttp://www.unidata.ucar.edu/software/ldm/\fP.
|
||||
|
||||
.SH SUPPORT
|
||||
.LP
|
||||
If you have problems with this program, then you should first examine the
|
||||
LDM email archive for similar problems and how they were solved.
|
||||
The email archive is available via the following World Wide Web URL:
|
||||
.sp
|
||||
.RS
|
||||
\fBhttp://www.unidata.ucar.edu/software/ldm/\fP
|
||||
.RE
|
||||
.sp
|
||||
If this does not suffice and your site is a member of the Unidata
|
||||
program, then send an inquiry via email -- together will all relevant
|
||||
information -- to
|
||||
.sp
|
||||
.RS
|
||||
\fBsupport@unidata.ucar.edu\fP
|
||||
.RE
|
|
@ -1,482 +0,0 @@
|
|||
/*
|
||||
* Copyright 1993, University Corporation for Atmospheric Research
|
||||
* See ../COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
/* $Id: pqcat.c,v 1.40.10.1.2.4 2008/04/15 16:34:09 steve Exp $ */
|
||||
|
||||
/*
|
||||
* dump a pq
|
||||
*/
|
||||
|
||||
#include <ldmconfig.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <regex.h>
|
||||
#include "ldm.h"
|
||||
#include "atofeedt.h"
|
||||
#include "ldmprint.h"
|
||||
#include "ulog.h"
|
||||
#include "pq.h"
|
||||
#include "paths.h"
|
||||
#include "md5.h"
|
||||
#include "RegularExpressions.h"
|
||||
|
||||
#ifdef NO_ATEXIT
|
||||
#include "atexit.h"
|
||||
#endif
|
||||
|
||||
/* default "one trip" */
|
||||
#ifndef DEFAULT_INTERVAL
|
||||
#define DEFAULT_INTERVAL 0
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_FEEDTYPE
|
||||
#define DEFAULT_FEEDTYPE ANY
|
||||
#endif
|
||||
|
||||
static volatile int done = 0;
|
||||
static volatile int intr = 0;
|
||||
static volatile int stats_req = 0;
|
||||
static int showProdOrigin = 0;
|
||||
|
||||
static const char *pqfname = DEFAULT_QUEUE;
|
||||
static pqueue *pq = NULL;
|
||||
|
||||
static int nprods = 0;
|
||||
|
||||
static MD5_CTX *md5ctxp = NULL;
|
||||
|
||||
static void
|
||||
dump_stats(void)
|
||||
{
|
||||
unotice("Number of products %d", nprods);
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
writeprod(const prod_info *infop, const void *datap,
|
||||
void *xprod, size_t size, void *notused)
|
||||
{
|
||||
if(ulogIsVerbose())
|
||||
{
|
||||
if (showProdOrigin)
|
||||
{
|
||||
uinfo("%s %s", s_prod_info(NULL, 0, infop, ulogIsDebug()), infop->origin);
|
||||
} else
|
||||
{
|
||||
uinfo("%s", s_prod_info(NULL, 0, infop, ulogIsDebug()));
|
||||
}
|
||||
}
|
||||
|
||||
if(md5ctxp != NULL) /* -c option */
|
||||
{
|
||||
signaturet check;
|
||||
MD5Init(md5ctxp);
|
||||
MD5Update(md5ctxp, datap, infop->sz);
|
||||
MD5Final((unsigned char*)check, md5ctxp);
|
||||
if(memcmp(infop->signature, check, sizeof(signaturet)) != 0)
|
||||
{
|
||||
char sb[33]; char cb[33];
|
||||
uerror("signature mismatch: %s != %s",
|
||||
s_signaturet(sb, sizeof(sb), infop->signature),
|
||||
s_signaturet(cb, sizeof(cb), check));
|
||||
}
|
||||
}
|
||||
|
||||
if( write(STDOUT_FILENO, datap, infop->sz) !=
|
||||
infop->sz)
|
||||
{
|
||||
int errnum = errno;
|
||||
serror( "data write failed") ;
|
||||
return errnum;
|
||||
}
|
||||
|
||||
nprods++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tallyProds(const prod_info *infop, const void *datap,
|
||||
void *xprod, size_t size, void *notused)
|
||||
{
|
||||
nprods++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(const char *av0) /* id string */
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"Usage: %s [options] [outputfile]\n\tOptions:\n", av0);
|
||||
(void)fprintf(stderr,
|
||||
"\t-v Verbose, tell me about each product\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-l logfile Log to a file rather than stderr\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-f feedtype Scan for data of type \"feedtype\" (default \"%s\")\n", s_feedtypet(DEFAULT_FEEDTYPE));
|
||||
(void)fprintf(stderr,
|
||||
"\t-p pattern Interested in products matching \"pattern\" (default \".*\")\n") ;
|
||||
(void)fprintf(stderr,
|
||||
"\t-q pqfname (default \"%s\")\n", DEFAULT_QUEUE);
|
||||
(void)fprintf(stderr,
|
||||
"\t-o offset Set the \"from\" time \"offset\" secs before now\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t (default \"from\" the beginning of the epoch)\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-i interval Poll queue after \"interval\" secs (default %d)\n",
|
||||
DEFAULT_INTERVAL);
|
||||
(void)fprintf(stderr,
|
||||
"\t (\"interval\" of 0 means exit at end of queue)\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-c Check, verify MD5 signature\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-O Include product origin in verbose output\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t (valid only with -v option)\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t-s Check queue for sanity/non-corruption\n");
|
||||
(void)fprintf(stderr,
|
||||
"Output defaults to standard output\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
unotice("Exiting");
|
||||
|
||||
if(!intr)
|
||||
{
|
||||
if(md5ctxp != NULL)
|
||||
free_MD5_CTX(md5ctxp);
|
||||
|
||||
if(pq != NULL)
|
||||
(void)pq_close(pq);
|
||||
}
|
||||
|
||||
dump_stats();
|
||||
|
||||
(void) closeulog();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
signal_handler(int sig)
|
||||
{
|
||||
#ifdef SVR3SIGNALS
|
||||
/*
|
||||
* Some systems reset handler to SIG_DFL upon entry to handler.
|
||||
* In that case, we reregister our handler.
|
||||
*/
|
||||
(void) signal(sig, signal_handler);
|
||||
#endif
|
||||
switch(sig) {
|
||||
case SIGINT :
|
||||
intr = !0;
|
||||
exit(0);
|
||||
case SIGTERM :
|
||||
done = !0;
|
||||
return;
|
||||
case SIGUSR1 :
|
||||
stats_req = !0;
|
||||
return;
|
||||
case SIGUSR2 :
|
||||
rollulogpri();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* register the signal_handler
|
||||
*/
|
||||
static void
|
||||
set_sigactions(void)
|
||||
{
|
||||
struct sigaction sigact;
|
||||
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
|
||||
/* Ignore these */
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
(void) sigaction(SIGHUP, &sigact, NULL);
|
||||
(void) sigaction(SIGPIPE, &sigact, NULL);
|
||||
(void) sigaction(SIGALRM, &sigact, NULL);
|
||||
(void) sigaction(SIGCHLD, &sigact, NULL);
|
||||
|
||||
/* Handle these */
|
||||
#ifdef SA_RESTART /* SVR4, 4.3+ BSD */
|
||||
/* usually, restart system calls */
|
||||
sigact.sa_flags |= SA_RESTART;
|
||||
#endif
|
||||
sigact.sa_handler = signal_handler;
|
||||
(void) sigaction(SIGTERM, &sigact, NULL);
|
||||
(void) sigaction(SIGUSR1, &sigact, NULL);
|
||||
(void) sigaction(SIGUSR2, &sigact, NULL);
|
||||
|
||||
/* Don't restart after interrupt */
|
||||
sigact.sa_flags = 0;
|
||||
#ifdef SA_INTERRUPT /* SunOS 4.x */
|
||||
sigact.sa_flags |= SA_INTERRUPT;
|
||||
#endif
|
||||
(void) sigaction(SIGINT, &sigact, NULL);
|
||||
}
|
||||
|
||||
|
||||
int main(int ac, char *av[])
|
||||
{
|
||||
const char *progname = ubasename(av[0]);
|
||||
char *logfname;
|
||||
prod_class_t clss;
|
||||
prod_spec spec;
|
||||
int status = 0;
|
||||
int interval = DEFAULT_INTERVAL;
|
||||
int logoptions = (LOG_CONS|LOG_PID) ;
|
||||
int queueSanityCheck = FALSE;
|
||||
|
||||
logfname = "";
|
||||
|
||||
if(isatty(fileno(stderr)))
|
||||
{
|
||||
/* set interactive defaults */
|
||||
logfname = "-" ;
|
||||
logoptions = 0 ;
|
||||
}
|
||||
|
||||
clss.from = TS_ZERO; /* default dump the whole file */
|
||||
clss.to = TS_ENDT;
|
||||
clss.psa.psa_len = 1;
|
||||
clss.psa.psa_val = &spec;
|
||||
spec.feedtype = ANY;
|
||||
spec.pattern = ".*";
|
||||
|
||||
/*
|
||||
* Check the environment for some options.
|
||||
* May be overridden by command line switches below.
|
||||
*/
|
||||
{
|
||||
const char *ldmpqfname = getenv("LDMPQFNAME");
|
||||
if(ldmpqfname != NULL)
|
||||
pqfname = ldmpqfname;
|
||||
}
|
||||
|
||||
{
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
extern char *optarg;
|
||||
int ch;
|
||||
int logmask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) |
|
||||
LOG_MASK(LOG_NOTICE));
|
||||
int fterr;
|
||||
|
||||
opterr = 1;
|
||||
|
||||
while ((ch = getopt(ac, av, "cvxOsl:p:f:q:o:i:")) != EOF)
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
md5ctxp = new_MD5_CTX();
|
||||
if(md5ctxp == NULL)
|
||||
serror("new_md5_CTX failed");
|
||||
break;
|
||||
case 'v':
|
||||
logmask |= LOG_MASK(LOG_INFO);
|
||||
break;
|
||||
case 'x':
|
||||
logmask |= LOG_MASK(LOG_DEBUG);
|
||||
break;
|
||||
case 'l':
|
||||
logfname = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
spec.pattern = optarg;
|
||||
/* compiled below */
|
||||
break;
|
||||
case 'f':
|
||||
fterr = strfeedtypet(optarg, &spec.feedtype) ;
|
||||
if(fterr != FEEDTYPE_OK)
|
||||
{
|
||||
fprintf(stderr, "Bad feedtype \"%s\", %s\n",
|
||||
optarg, strfeederr(fterr)) ;
|
||||
usage(progname);
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
pqfname = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
(void) set_timestamp(&clss.from);
|
||||
clss.from.tv_sec -= atoi(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
interval = atoi(optarg);
|
||||
if(interval == 0 && *optarg != '0')
|
||||
{
|
||||
fprintf(stderr, "%s: invalid interval %s",
|
||||
progname, optarg);
|
||||
usage(progname);
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
showProdOrigin = TRUE;
|
||||
break;
|
||||
case 's':
|
||||
queueSanityCheck = TRUE;
|
||||
break;
|
||||
case '?':
|
||||
usage(progname);
|
||||
break;
|
||||
}
|
||||
|
||||
(void) setulogmask(logmask);
|
||||
|
||||
if (re_isPathological(spec.pattern))
|
||||
{
|
||||
fprintf(stderr, "Adjusting pathological regular-expression: "
|
||||
"\"%s\"\n", spec.pattern);
|
||||
re_vetSpec(spec.pattern);
|
||||
}
|
||||
status = regcomp(&spec.rgx,
|
||||
spec.pattern,
|
||||
REG_EXTENDED|REG_NOSUB);
|
||||
if(status != 0)
|
||||
{
|
||||
fprintf(stderr, "Bad regular expression \"%s\"\n",
|
||||
spec.pattern);
|
||||
usage(av[0]);
|
||||
}
|
||||
|
||||
|
||||
/* last arg, outputfname, is optional */
|
||||
if(ac - optind > 0)
|
||||
{
|
||||
const char *const outputfname = av[optind];
|
||||
if(freopen(outputfname, "a+b", stdout) == NULL)
|
||||
{
|
||||
status = errno;
|
||||
fprintf(stderr, "%s: Couldn't open \"%s\": %s\n",
|
||||
progname, outputfname, strerror(status));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up error logging.
|
||||
*/
|
||||
(void) openulog(progname,
|
||||
logoptions, LOG_LDM, logfname);
|
||||
unotice("Starting Up (%d)", getpgrp());
|
||||
|
||||
/*
|
||||
* register exit handler
|
||||
*/
|
||||
if(atexit(cleanup) != 0)
|
||||
{
|
||||
serror("atexit");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* set up signal handlers
|
||||
*/
|
||||
set_sigactions();
|
||||
|
||||
|
||||
/*
|
||||
* Open the product que
|
||||
*/
|
||||
status = pq_open(pqfname, PQ_READONLY, &pq);
|
||||
if(status)
|
||||
{
|
||||
if (PQ_CORRUPT == status) {
|
||||
uerror("The product-queue \"%s\" is inconsistent\n",
|
||||
pqfname);
|
||||
}
|
||||
else {
|
||||
uerror("pq_open failed: %s: %s\n",
|
||||
pqfname, strerror(status));
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the cursor position to starting time
|
||||
*/
|
||||
pq_cset(pq, &clss.from );
|
||||
|
||||
while(!done)
|
||||
{
|
||||
if(stats_req)
|
||||
{
|
||||
dump_stats();
|
||||
stats_req = 0;
|
||||
}
|
||||
|
||||
if (queueSanityCheck)
|
||||
status = pq_sequence(pq, TV_GT, &clss, tallyProds, 0);
|
||||
else
|
||||
status = pq_sequence(pq, TV_GT, &clss, writeprod, 0);
|
||||
|
||||
switch(status) {
|
||||
case 0: /* no error */
|
||||
continue; /* N.B., other cases sleep */
|
||||
case PQUEUE_END:
|
||||
udebug("End of Queue");
|
||||
break;
|
||||
case EAGAIN:
|
||||
case EACCES:
|
||||
udebug("Hit a lock");
|
||||
break;
|
||||
default:
|
||||
uerror("pq_sequence failed: %s (errno = %d)",
|
||||
strerror(status), status);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
|
||||
if(interval == 0)
|
||||
break;
|
||||
pq_suspend(interval);
|
||||
|
||||
}
|
||||
|
||||
if (queueSanityCheck)
|
||||
{
|
||||
size_t queueProdCnt;
|
||||
size_t dummy1, dummy2, dummy3, dummy4, dummy5, dummy6, dummy7, dummy9;
|
||||
double dummy8;
|
||||
status = pq_stats(pq, &queueProdCnt, &dummy1, &dummy2, &dummy3, &dummy4,
|
||||
&dummy5, &dummy6, &dummy7, &dummy8, &dummy9);
|
||||
if (status) {
|
||||
uerror("pq_stats failed: %s (errno = %d)",
|
||||
strerror(status), status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (nprods == queueProdCnt)
|
||||
{
|
||||
unotice("pqcat queueSanityCheck: Number of products tallied consistent with value in queue");
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uerror("pqcat queueSanityCheck: Product count doesn't match");
|
||||
uerror("products tallied: %d Value in queue: %d", nprods, queueProdCnt); exit(1);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
/*NOTREACHED*/
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
# $Id: Makefile,v 1.1.4.1 2003/06/20 18:42:49 steve Exp $
|
||||
|
||||
include ../macros.make
|
||||
PROGRAM = pqcheck
|
||||
include ../simple_program.make
|
||||
include ../rules.make
|
||||
include depends
|
|
@ -1,11 +0,0 @@
|
|||
pqcheck.o: ../config/ldmconfig.h
|
||||
pqcheck.o: ../misc/paths.h
|
||||
pqcheck.o: ../pq/pq.h
|
||||
pqcheck.o: ../protocol/atofeedt.h
|
||||
pqcheck.o: ../protocol/ldm.h
|
||||
pqcheck.o: ../protocol/ldmprint.h
|
||||
pqcheck.o: ../protocol/md5.h
|
||||
pqcheck.o: ../protocol/prod_class.h
|
||||
pqcheck.o: ../protocol/timestamp.h
|
||||
pqcheck.o: ../ulog/ulog.h
|
||||
pqcheck.o: pqcheck.c
|
|
@ -1,152 +0,0 @@
|
|||
." $Id: pqcheck.1,v 1.1.4.1.4.4.2.2 2009/06/18 16:15:11 steve Exp $
|
||||
.TH PQCHECK 1 "$Date: 2009/06/18 16:15:11 $"
|
||||
.SH NAME
|
||||
pqcheck - program to check that an LDM product queue was successfully closed
|
||||
.SH SYNOPSIS
|
||||
.HP
|
||||
.ft B
|
||||
pqcheck
|
||||
.nh
|
||||
\%[-F]
|
||||
\%[-v]
|
||||
\%[-l\ \fIlogfile\fP]
|
||||
\%[-q\ \fIpqfname\fP]
|
||||
.hy
|
||||
.ft
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
This program checks that a product-queue is not open for writing by any
|
||||
process. Beginning with this version of the LDM, a product-queue contains
|
||||
a persistent "write count". Every time
|
||||
\fBpq_open\fP(3) is invoked on a product-queue with the
|
||||
\fBPQ_READONLY\fP flag unset, the write-count is incremented.
|
||||
Every time
|
||||
\fBpq_close\fP(3) is invoked on a product-queue opened in this way,
|
||||
the write-count is decremented.
|
||||
.LP
|
||||
If it is known that no process holds the product-queue open for writing
|
||||
and this utility indicates that the product-queue write-count is zero, then the
|
||||
product-queue was successfully closed by all processes that had it open for
|
||||
writing and the product-queue is guaranteed to be in a consistent state
|
||||
(i.e., the product-queue will not be corrupt).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -F
|
||||
Force. Support for a write-count will be added to the product-queue,
|
||||
if necessary, and the write-count will be set to zero.
|
||||
.TP
|
||||
.BI "-l " logfile
|
||||
The path name of a file to be used as the log file for the process. The
|
||||
default is to use standard error when that stream goes to the terminal
|
||||
and syslogd(8) otherwise.
|
||||
To use syslogd(8) from the command line, execute "pqcheck ... 2> /dev/null".
|
||||
.TP
|
||||
.BI "-q " pqfname
|
||||
The filename of the product queue.
|
||||
The default is \fBdata/ldm.pq\fP relative to the installation point,
|
||||
which is typically \fB/usr/local/ldm\fP.
|
||||
.TP
|
||||
.B -v
|
||||
Verbose logging. The write-count for the product-queue will be printed.
|
||||
.SH SIGNALS
|
||||
.TP
|
||||
.BR SIGTERM
|
||||
Normal termination.
|
||||
.TP
|
||||
.BR SIGINT
|
||||
Immediate termination.
|
||||
|
||||
.SH EXIT STATUS
|
||||
.TP
|
||||
0
|
||||
Success. The product-queue was opened and the write-count is zero.
|
||||
.TP
|
||||
1
|
||||
A system-error occurred.
|
||||
.TP
|
||||
2
|
||||
The product-queue doesn't have a write-count. If you know that no process
|
||||
has the product-queue open for writing, then you can use the \fB-F\fP option
|
||||
to add write-count capability to the product-queue.
|
||||
.TP
|
||||
3
|
||||
The product-queue was opened but the write-count is positive.
|
||||
.TP
|
||||
4
|
||||
The product-queue could not be opened because it is internally inconsistent.
|
||||
It will have to be deleted and recreated.
|
||||
|
||||
.SH EXAMPLE
|
||||
.LP
|
||||
The following shell-script fragment checks the product-queue:
|
||||
.RS +4
|
||||
.nf
|
||||
#
|
||||
# The product-queue exists. Test for corruption.
|
||||
#
|
||||
if pqcheck -q $LDMHOME/data/ldm.pq; then
|
||||
echo "Using existing queue."
|
||||
else
|
||||
case $? in
|
||||
1) echo "Aborting..."
|
||||
;;
|
||||
2) echo "Adding write-count capability to product-queue"
|
||||
if ! pqcheck -F -q $LDMHOME/data/ldm.pq; then
|
||||
echo "Aborting..."
|
||||
fi
|
||||
;;
|
||||
3) echo "Product-queue incorrectly closed. Checking..."
|
||||
if pqcat -s -l /dev/null; then
|
||||
echo "Product-queue appears OK. Clearing write-count."
|
||||
if ! pqcheck -F -q $LDMHOME/data/ldm.pq; then
|
||||
echo "Aborting..."
|
||||
fi
|
||||
else
|
||||
echo "Product-queue appears corrupt. Recreating..."
|
||||
/bin/mv -f $LDMHOME/data/ldm.pq $LDMHOME/data/ldm.pq.save
|
||||
/bin/su - ldm -c "$LDMBIN/ldmadmin delqueue"
|
||||
/bin/su - ldm -c "$LDMBIN/ldmadmin mkqueue"
|
||||
fi
|
||||
;;
|
||||
4) echo "Product-queue is corrupt. Recreating..."
|
||||
/bin/mv -f $LDMHOME/data/ldm.pq $LDMHOME/data/ldm.pq.save
|
||||
/bin/su - ldm -c "$LDMBIN/ldmadmin delqueue"
|
||||
/bin/su - ldm -c "$LDMBIN/ldmadmin mkqueue"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
.fi
|
||||
.RE
|
||||
This fragment
|
||||
is appropriate for a shell-script that starts the LDM system at boot-time.
|
||||
|
||||
.SH FILES
|
||||
.LP
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.LP
|
||||
.BR ldmd (1),
|
||||
.BR pqcat(1),
|
||||
.BR ulog (3),
|
||||
.BR pq (3),
|
||||
.BR syslogd (8),
|
||||
WWW URL \fBhttp://www.unidata.ucar.edu/software/ldm\fP.
|
||||
|
||||
.SH SUPPORT
|
||||
.LP
|
||||
If you have problems with this program, then you should first examine the
|
||||
LDM email archive for similar problems and how they were solved.
|
||||
The email archive is available via the following World Wide Web URL:
|
||||
.sp
|
||||
.RS
|
||||
\fBhttp://www.unidata.ucar.edu/software/ldm\fP
|
||||
.RE
|
||||
.sp
|
||||
If this does not suffice and your site is a member of the Unidata
|
||||
program, then send an inquiry via email -- together will all relevant
|
||||
information -- to
|
||||
.sp
|
||||
.RS
|
||||
\fBsupport@unidata.ucar.edu\fP
|
||||
.RE
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue