From d6fa96b4cd67cf4fa18b5b9b6739f9bc2494a9f4 Mon Sep 17 00:00:00 2001 From: guest Date: Tue, 23 Sep 2008 21:29:27 +0000 Subject: initial import git-svn-id: http://manut.eu/svn/yalp/trunk@1 f059d3a0-6783-47b7-97ff-1fe0bbf25129 --- ClientConfiguration.xml | 7 + ServerSettings.xml | 6 + auth.sh | 1 + build.xml | 189 ++ client.policy | 20 + client.sh | 1 + idlj.sh | 3 + img/folder.gif | Bin 0 -> 1658 bytes img/forward.gif | Bin 0 -> 548 bytes img/pause.gif | Bin 0 -> 84 bytes img/play.gif | Bin 0 -> 486 bytes img/stop.gif | Bin 0 -> 474 bytes img/yalp.bmp | Bin 0 -> 3338 bytes img/yalp.gif | Bin 0 -> 5665 bytes img/yalp.ico | Bin 0 -> 3262 bytes img/yalpLogo.gif | Bin 0 -> 1602 bytes img/yalpV2.gif | Bin 0 -> 4744 bytes img/yalpV2_klein.gif | Bin 0 -> 1094 bytes img/yalpV2_mittel.gif | Bin 0 -> 1472 bytes img/yalpV2_original.gif | Bin 0 -> 12384 bytes img/yalp_klein.gif | Bin 0 -> 1071 bytes input.sh | 1 + lib/commons-net-1.4.1.jar | Bin 0 -> 180792 bytes lib/id3-1.6.0d9.jar | Bin 0 -> 140949 bytes lib/jarbundler-1.4.jar | Bin 0 -> 13141 bytes lib/libswt-carbon-3139.jnilib | Bin 0 -> 240676 bytes lib/libswt-pi-carbon-3139.jnilib | Bin 0 -> 369744 bytes lib/libswt-webkit-carbon-3139.jnilib | Bin 0 -> 24352 bytes lib/log4j-1.2.15.jar | Bin 0 -> 391834 bytes lib/postgresql-8.1-404.jdbc3.jar | Bin 0 -> 401336 bytes lib/swt-win32-3139.dll | Bin 0 -> 315392 bytes lib/swt.jar | Bin 0 -> 1216222 bytes lib/yajil-0.3.3.jar | Bin 0 -> 15381 bytes log4j_server.conf | 8 + output.sh | 1 + postgresql_autodoc/Makefile | 103 + postgresql_autodoc/config.log | 164 ++ postgresql_autodoc/config.mk | 13 + postgresql_autodoc/config.mk.in | 13 + postgresql_autodoc/config.status | 761 +++++ postgresql_autodoc/configure | 2907 ++++++++++++++++++++ postgresql_autodoc/configure.ac | 56 + postgresql_autodoc/dia.tmpl | 212 ++ postgresql_autodoc/dot.tmpl | 19 + postgresql_autodoc/html.tmpl | 308 +++ postgresql_autodoc/install-sh | 251 ++ postgresql_autodoc/neato.tmpl | 22 + postgresql_autodoc/postgresql_autodoc | 1907 +++++++++++++ postgresql_autodoc/postgresql_autodoc.pl | 1907 +++++++++++++ postgresql_autodoc/xml.tmpl | 204 ++ postgresql_autodoc/zigzag.dia.tmpl | 224 ++ removed-code/Browser.java | 157 ++ removed-code/Client.java | 48 + server.policy | 8 + server.sh | 4 + src/YalpAuth/YalpPGSqlAuth/DatabaseDefines.java | 65 + .../YalpPGSqlAuth/YalpAuthInterfaceImpl.java | 137 + src/YalpAuth/YalpPGSqlAuth/YalpPGSqlAuth.java | 32 + src/YalpClients/ClientConfiguration.java | 113 + src/YalpClients/SwtClient/GUI/GUI.java | 2101 ++++++++++++++ src/YalpClients/SwtClient/GUI/InitGUI.java | 58 + src/YalpClients/SwtClient/GUI/LoadDialog.java | 110 + .../SwtClient/GUI/SWTResourceManager.java | 145 + src/YalpClients/SwtClient/GUI/SortListener.java | 63 + src/YalpClients/SwtClient/GUI/StartDialog.java | 236 ++ src/YalpClients/SwtClient/Model.java | 744 +++++ src/YalpClients/SwtClient/SwtClient.java | 61 + src/YalpInputs/YalpPGSqlInput/DatabaseDefines.java | 65 + src/YalpInputs/YalpPGSqlInput/PGSqlInput.java | 123 + .../YalpPGSqlInput/YalpInputPluginImpl.java | 189 ++ src/YalpInputs/YalpPGSqlInput/YalpPGSqlInput.java | 33 + src/YalpInputs/YalpPGSqlInput/db-design-backup.sql | 321 +++ .../YalpVlcTelnetOutput/TelnetInterface.java | 147 + .../YalpVlcTelnetOutput/VlcStreamer.java | 145 + .../YalpVlcTelnetOutput/YalpOutputPluginImpl.java | 371 +++ .../YalpVlcTelnetOutput/YalpVlcTelnetOutput.java | 20 + src/YalpServer/FileBrowser.java | 175 ++ src/YalpServer/FileFinder.java | 110 + src/YalpServer/FileInfoManager.java | 126 + src/YalpServer/InitServer.java | 283 ++ src/YalpServer/ServerControlImpl.java | 385 +++ src/YalpServer/ServerSettings.java | 68 + src/YalpServer/YalpServer.java | 40 + src/yalp.idl | 265 ++ svn-commit.tmp | 4 + 85 files changed, 16260 insertions(+) create mode 100644 ClientConfiguration.xml create mode 100644 ServerSettings.xml create mode 100755 auth.sh create mode 100644 build.xml create mode 100644 client.policy create mode 100755 client.sh create mode 100755 idlj.sh create mode 100755 img/folder.gif create mode 100755 img/forward.gif create mode 100755 img/pause.gif create mode 100755 img/play.gif create mode 100755 img/stop.gif create mode 100755 img/yalp.bmp create mode 100755 img/yalp.gif create mode 100755 img/yalp.ico create mode 100755 img/yalpLogo.gif create mode 100755 img/yalpV2.gif create mode 100755 img/yalpV2_klein.gif create mode 100755 img/yalpV2_mittel.gif create mode 100755 img/yalpV2_original.gif create mode 100755 img/yalp_klein.gif create mode 100755 input.sh create mode 100755 lib/commons-net-1.4.1.jar create mode 100755 lib/id3-1.6.0d9.jar create mode 100755 lib/jarbundler-1.4.jar create mode 100755 lib/libswt-carbon-3139.jnilib create mode 100755 lib/libswt-pi-carbon-3139.jnilib create mode 100755 lib/libswt-webkit-carbon-3139.jnilib create mode 100755 lib/log4j-1.2.15.jar create mode 100755 lib/postgresql-8.1-404.jdbc3.jar create mode 100755 lib/swt-win32-3139.dll create mode 100755 lib/swt.jar create mode 100755 lib/yajil-0.3.3.jar create mode 100644 log4j_server.conf create mode 100755 output.sh create mode 100644 postgresql_autodoc/Makefile create mode 100644 postgresql_autodoc/config.log create mode 100644 postgresql_autodoc/config.mk create mode 100644 postgresql_autodoc/config.mk.in create mode 100755 postgresql_autodoc/config.status create mode 100755 postgresql_autodoc/configure create mode 100644 postgresql_autodoc/configure.ac create mode 100644 postgresql_autodoc/dia.tmpl create mode 100644 postgresql_autodoc/dot.tmpl create mode 100644 postgresql_autodoc/html.tmpl create mode 100755 postgresql_autodoc/install-sh create mode 100644 postgresql_autodoc/neato.tmpl create mode 100755 postgresql_autodoc/postgresql_autodoc create mode 100755 postgresql_autodoc/postgresql_autodoc.pl create mode 100644 postgresql_autodoc/xml.tmpl create mode 100644 postgresql_autodoc/zigzag.dia.tmpl create mode 100644 removed-code/Browser.java create mode 100755 removed-code/Client.java create mode 100644 server.policy create mode 100755 server.sh create mode 100644 src/YalpAuth/YalpPGSqlAuth/DatabaseDefines.java create mode 100644 src/YalpAuth/YalpPGSqlAuth/YalpAuthInterfaceImpl.java create mode 100644 src/YalpAuth/YalpPGSqlAuth/YalpPGSqlAuth.java create mode 100755 src/YalpClients/ClientConfiguration.java create mode 100644 src/YalpClients/SwtClient/GUI/GUI.java create mode 100644 src/YalpClients/SwtClient/GUI/InitGUI.java create mode 100644 src/YalpClients/SwtClient/GUI/LoadDialog.java create mode 100644 src/YalpClients/SwtClient/GUI/SWTResourceManager.java create mode 100644 src/YalpClients/SwtClient/GUI/SortListener.java create mode 100644 src/YalpClients/SwtClient/GUI/StartDialog.java create mode 100755 src/YalpClients/SwtClient/Model.java create mode 100755 src/YalpClients/SwtClient/SwtClient.java create mode 100644 src/YalpInputs/YalpPGSqlInput/DatabaseDefines.java create mode 100644 src/YalpInputs/YalpPGSqlInput/PGSqlInput.java create mode 100644 src/YalpInputs/YalpPGSqlInput/YalpInputPluginImpl.java create mode 100644 src/YalpInputs/YalpPGSqlInput/YalpPGSqlInput.java create mode 100644 src/YalpInputs/YalpPGSqlInput/db-design-backup.sql create mode 100644 src/YalpOutputs/YalpVlcTelnetOutput/TelnetInterface.java create mode 100644 src/YalpOutputs/YalpVlcTelnetOutput/VlcStreamer.java create mode 100644 src/YalpOutputs/YalpVlcTelnetOutput/YalpOutputPluginImpl.java create mode 100644 src/YalpOutputs/YalpVlcTelnetOutput/YalpVlcTelnetOutput.java create mode 100755 src/YalpServer/FileBrowser.java create mode 100755 src/YalpServer/FileFinder.java create mode 100755 src/YalpServer/FileInfoManager.java create mode 100755 src/YalpServer/InitServer.java create mode 100755 src/YalpServer/ServerControlImpl.java create mode 100755 src/YalpServer/ServerSettings.java create mode 100755 src/YalpServer/YalpServer.java create mode 100644 src/yalp.idl create mode 100644 svn-commit.tmp diff --git a/ClientConfiguration.xml b/ClientConfiguration.xml new file mode 100644 index 0000000..7eff5e7 --- /dev/null +++ b/ClientConfiguration.xml @@ -0,0 +1,7 @@ + + + 127.0.0.1 + 5002 + 5001 + "/usr/bin/vlc" + diff --git a/ServerSettings.xml b/ServerSettings.xml new file mode 100644 index 0000000..fd0f623 --- /dev/null +++ b/ServerSettings.xml @@ -0,0 +1,6 @@ + + + jdbc:postgresql://localhost:5432/yalp + huhu + yalp + diff --git a/auth.sh b/auth.sh new file mode 100755 index 0000000..dd0fe2f --- /dev/null +++ b/auth.sh @@ -0,0 +1 @@ +java -Djava.library.path=./lib -jar yalpPGSqlAuth.jar -ORBInitialPort 1050 -ORBInitialHost localhost diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..149a99f --- /dev/null +++ b/build.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Doing all + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client.policy b/client.policy new file mode 100644 index 0000000..9b5a629 --- /dev/null +++ b/client.policy @@ -0,0 +1,20 @@ +grant { + permission java.net.SocketPermission "*:80","connect,resolve"; + permission java.util.PropertyPermission "swt.version", "read"; + permission java.util.PropertyPermission "user.dir", "read"; + permission java.util.PropertyPermission "os.name", "read"; + + permission java.util.PropertyPermission "org.eclipse.swt.internal.carbon.smallFonts", "read"; + permission java.util.PropertyPermission "org.eclipse.swt.internal.carbon.noFocusRing", "read"; + permission java.lang.RuntimePermission "loadLibrary.swt-gtk-3139", "read"; + permission java.lang.RuntimePermission "loadLibrary.swt-pi-gtk-3139", "read"; + permission java.lang.RuntimePermission "loadLibrary.swt-pi-gtk", "read"; + permission java.lang.RuntimePermission "loadLibrary.swt-pi-carbon","read"; + permission java.lang.RuntimePermission "loadLibrary.swt-pi-carbon-3139" ,"read"; + permission java.lang.RuntimePermission "loadLibrary.swt-win32-3139" ,"read"; + permission java.lang.RuntimePermission "loadLibrary.swt-carbon-3139" ,"read"; + permission java.io.FilePermission "<>","read,write,execute"; + permission java.io.FilePermission "C:\\Programme\\VideoLAN\\VLC\\vlc","execute"; + permission java.io.FilePermission "/Applications/VLC.app/Contents/MacOS/VLC","execute"; + permission java.net.SocketPermission "*:1024-","connect,resolve"; +}; diff --git a/client.sh b/client.sh new file mode 100755 index 0000000..e1d2711 --- /dev/null +++ b/client.sh @@ -0,0 +1 @@ +java -Djava.library.path=./lib -jar yalpSWTClient.jar -ORBInitialPort 1050 -ORBInitialHost localhost diff --git a/idlj.sh b/idlj.sh new file mode 100755 index 0000000..f85e7b2 --- /dev/null +++ b/idlj.sh @@ -0,0 +1,3 @@ +#!/bin/bash +#/opt/sun-jdk-1.6.0.07/bin/idlj -fall $@ +/opt/ibm-java-i386-60/bin/idlj -fall $@ diff --git a/img/folder.gif b/img/folder.gif new file mode 100755 index 0000000..411fe64 Binary files /dev/null and b/img/folder.gif differ diff --git a/img/forward.gif b/img/forward.gif new file mode 100755 index 0000000..17cfe1d Binary files /dev/null and b/img/forward.gif differ diff --git a/img/pause.gif b/img/pause.gif new file mode 100755 index 0000000..28f71b5 Binary files /dev/null and b/img/pause.gif differ diff --git a/img/play.gif b/img/play.gif new file mode 100755 index 0000000..9cdf8a2 Binary files /dev/null and b/img/play.gif differ diff --git a/img/stop.gif b/img/stop.gif new file mode 100755 index 0000000..75e4ff7 Binary files /dev/null and b/img/stop.gif differ diff --git a/img/yalp.bmp b/img/yalp.bmp new file mode 100755 index 0000000..a9465d1 Binary files /dev/null and b/img/yalp.bmp differ diff --git a/img/yalp.gif b/img/yalp.gif new file mode 100755 index 0000000..b8c23fe Binary files /dev/null and b/img/yalp.gif differ diff --git a/img/yalp.ico b/img/yalp.ico new file mode 100755 index 0000000..414efa3 Binary files /dev/null and b/img/yalp.ico differ diff --git a/img/yalpLogo.gif b/img/yalpLogo.gif new file mode 100755 index 0000000..57ed766 Binary files /dev/null and b/img/yalpLogo.gif differ diff --git a/img/yalpV2.gif b/img/yalpV2.gif new file mode 100755 index 0000000..4640702 Binary files /dev/null and b/img/yalpV2.gif differ diff --git a/img/yalpV2_klein.gif b/img/yalpV2_klein.gif new file mode 100755 index 0000000..a9845d4 Binary files /dev/null and b/img/yalpV2_klein.gif differ diff --git a/img/yalpV2_mittel.gif b/img/yalpV2_mittel.gif new file mode 100755 index 0000000..9be65b7 Binary files /dev/null and b/img/yalpV2_mittel.gif differ diff --git a/img/yalpV2_original.gif b/img/yalpV2_original.gif new file mode 100755 index 0000000..3dcb582 Binary files /dev/null and b/img/yalpV2_original.gif differ diff --git a/img/yalp_klein.gif b/img/yalp_klein.gif new file mode 100755 index 0000000..e0fe9ab Binary files /dev/null and b/img/yalp_klein.gif differ diff --git a/input.sh b/input.sh new file mode 100755 index 0000000..b77419f --- /dev/null +++ b/input.sh @@ -0,0 +1 @@ +java -Djava.library.path=./lib -jar yalpPGSqlInput.jar -ORBInitialPort 1050 -ORBInitialHost localhost diff --git a/lib/commons-net-1.4.1.jar b/lib/commons-net-1.4.1.jar new file mode 100755 index 0000000..9666a92 Binary files /dev/null and b/lib/commons-net-1.4.1.jar differ diff --git a/lib/id3-1.6.0d9.jar b/lib/id3-1.6.0d9.jar new file mode 100755 index 0000000..7da41c5 Binary files /dev/null and b/lib/id3-1.6.0d9.jar differ diff --git a/lib/jarbundler-1.4.jar b/lib/jarbundler-1.4.jar new file mode 100755 index 0000000..b74baa6 Binary files /dev/null and b/lib/jarbundler-1.4.jar differ diff --git a/lib/libswt-carbon-3139.jnilib b/lib/libswt-carbon-3139.jnilib new file mode 100755 index 0000000..cc04ee4 Binary files /dev/null and b/lib/libswt-carbon-3139.jnilib differ diff --git a/lib/libswt-pi-carbon-3139.jnilib b/lib/libswt-pi-carbon-3139.jnilib new file mode 100755 index 0000000..307d8eb Binary files /dev/null and b/lib/libswt-pi-carbon-3139.jnilib differ diff --git a/lib/libswt-webkit-carbon-3139.jnilib b/lib/libswt-webkit-carbon-3139.jnilib new file mode 100755 index 0000000..e95b2fd Binary files /dev/null and b/lib/libswt-webkit-carbon-3139.jnilib differ diff --git a/lib/log4j-1.2.15.jar b/lib/log4j-1.2.15.jar new file mode 100755 index 0000000..c930a6a Binary files /dev/null and b/lib/log4j-1.2.15.jar differ diff --git a/lib/postgresql-8.1-404.jdbc3.jar b/lib/postgresql-8.1-404.jdbc3.jar new file mode 100755 index 0000000..01c43bb Binary files /dev/null and b/lib/postgresql-8.1-404.jdbc3.jar differ diff --git a/lib/swt-win32-3139.dll b/lib/swt-win32-3139.dll new file mode 100755 index 0000000..720fa74 Binary files /dev/null and b/lib/swt-win32-3139.dll differ diff --git a/lib/swt.jar b/lib/swt.jar new file mode 100755 index 0000000..253f82f Binary files /dev/null and b/lib/swt.jar differ diff --git a/lib/yajil-0.3.3.jar b/lib/yajil-0.3.3.jar new file mode 100755 index 0000000..8dd5834 Binary files /dev/null and b/lib/yajil-0.3.3.jar differ diff --git a/log4j_server.conf b/log4j_server.conf new file mode 100644 index 0000000..79c355b --- /dev/null +++ b/log4j_server.conf @@ -0,0 +1,8 @@ +log4j.rootLogger=debug, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Pattern to output the caller's file name and line number. +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n + diff --git a/output.sh b/output.sh new file mode 100755 index 0000000..cdad4fd --- /dev/null +++ b/output.sh @@ -0,0 +1 @@ +java -Djava.library.path=./lib -jar yalpVlcTelnetOutput.jar -ORBInitialPort 1050 -ORBInitialHost localhost diff --git a/postgresql_autodoc/Makefile b/postgresql_autodoc/Makefile new file mode 100644 index 0000000..fdddc1a --- /dev/null +++ b/postgresql_autodoc/Makefile @@ -0,0 +1,103 @@ +# $Header: /cvsroot/autodoc/autodoc/Makefile,v 1.3 2006/05/16 18:57:24 rbt Exp $ + +TEMPLATES = dia.tmpl dot.tmpl html.tmpl neato.tmpl xml.tmpl zigzag.dia.tmpl +BINARY = postgresql_autodoc +CONFIGFILE = config.mk + +RELEASE_FILES = Makefile config.mk.in configure \ + configure.ac $(TEMPLATES) install-sh \ + postgresql_autodoc.pl + +cur-dir := $(shell basename ${PWD}) +REAL_RELEASE_FILES = $(addprefix $(cur-dir)/,$(RELEASE_FILES)) + +# Global dependencies +ALWAYS_DEPEND = Makefile configure $(CONFIGFILE) + + +#### +# Test to see if $(CONFIGFILE) has been generated. If so, include it. Otherwise we assume +# it will be created for us. +has_configmk := $(wildcard $(CONFIGFILE)) + +ifeq ($(has_configmk),$(CONFIGFILE)) +include $(CONFIGFILE) +endif + +#### +# ALL +.PHONY: all +all: $(ALWAYS_DEPEND) $(BINARY) + +#### +# Replace the /usr/bin/env perl with the supplied path +# chmod to make testing easier +$(BINARY): postgresql_autodoc.pl $(CONFIGFILE) + $(SED) -e "s,/usr/bin/env perl,$(PERL)," \ + -e "s,@@TEMPLATE-DIR@@,$(datadir)," \ + postgresql_autodoc.pl > $(BINARY) + -chmod +x $(BINARY) + +#### +# INSTALL Target +.PHONY: install uninstall +install: all $(ALWAYS_DEPEND) + $(INSTALL_SCRIPT) -d $(bindir) + $(INSTALL_SCRIPT) -d $(datadir) + $(INSTALL_SCRIPT) -m 755 $(BINARY) $(bindir) + for entry in $(TEMPLATES) ; \ + do $(INSTALL_SCRIPT) -m 644 $${entry} $(datadir) ; \ + done + +uninstall: + -$(RM) $(bindir)/$(BINARY) + for entry in $(TEMPLATES) ; \ + do $(RM) $(datadir)/$${entry} ; \ + done + -rmdir $(datadir) + -rmdir $(bindir) + +#### +# CLEAN / DISTRIBUTION-CLEAN / MAINTAINER-CLEAN Targets +.PHONY: clean +clean: $(ALWAYS_DEPEND) + $(RM) $(BINARY) + +.PHONY: distribution-clean distclean +distribution-clean distclean: clean + $(RM) $(CONFIGFILE) config.log config.status + $(RM) -r autom4te.cache + $(RM) $(patsubst %.tmpl,*.%,$(wildcard *.tmpl)) + +.PHONY: maintainer-clean +maintainer-clean: distribution-clean + $(RM) configure + +#### +# Build a release +# +# Clean +# Ensure configure is up to date +# Commit any pending elements +# Tar up the results +.PHONY: release +release: distribution-clean configure $(RELEASE_FILES) + @if [ -z ${VERSION} ] ; then \ + echo "-------------------------------------------"; \ + echo "VERSION needs to be specified for a release"; \ + echo "-------------------------------------------"; \ + false; \ + fi + cvs2cl + -cvs commit + cd ../ && tar -czvf postgresql_autodoc-${VERSION}.tar.gz $(REAL_RELEASE_FILES) + +#### +# Build and Run configure files when configure or a template is updated. +configure: configure.ac + autoconf + +# Fix my makefile, then execute myself +$(CONFIGFILE) : config.mk.in configure + ./configure + $(MAKE) $(MAKEFLAGS) diff --git a/postgresql_autodoc/config.log b/postgresql_autodoc/config.log new file mode 100644 index 0000000..5ac7ad9 --- /dev/null +++ b/postgresql_autodoc/config.log @@ -0,0 +1,164 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by configure, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ ./configure + +## --------- ## +## Platform. ## +## --------- ## + +hostname = tc4200 +uname -m = i686 +uname -r = 2.6.26 +uname -s = Linux +uname -v = #30 PREEMPT Mon Jul 14 10:58:29 CEST 2008 + +/usr/bin/uname -p = Intel(R) Pentium(R) M processor 1.73GHz +/bin/uname -X = unknown + +/bin/arch = unknown +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /usr/local/bin +PATH: /usr/bin +PATH: /bin +PATH: /opt/bin +PATH: /usr/i686-pc-linux-gnu/arm-gentoo-linux-uclibc/gcc-bin/4.1.2 +PATH: /usr/i686-pc-linux-gnu/arm-linux-uclibc/gcc-bin/4.1.2 +PATH: /usr/i686-pc-linux-gnu/gcc-bin/4.3.1 +PATH: /usr/i686-pc-linux-gnu/powerpc-fendt-linux-gnu/gcc-bin/4.2.2 +PATH: /opt/e17/bin +PATH: /usr/kde/3.5/bin +PATH: /usr/qt/3/bin +PATH: /usr/games/bin +PATH: /opt/bin +PATH: /opt/ACE_wrappers/bin +PATH: /opt/ACE_wrappers/TAO/orbsvcs/Naming_Service +PATH: /home/linutronix/scripts +PATH: /home/linutronix/scripts + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:1665: checking for a BSD-compatible install +configure:1721: result: /usr/bin/install -c +configure:1737: checking for sed +configure:1756: found /bin/sed +configure:1768: result: /bin/sed +configure:1824: checking for perl +configure:1843: found /usr/bin/perl +configure:1855: result: /usr/bin/perl +configure:1884: checking DBI +configure:1893: result: yes +configure:1884: checking DBD::Pg +configure:1893: result: yes +configure:1884: checking Fcntl +configure:1893: result: yes +configure:1884: checking HTML::Template +configure:1893: result: yes +configure:1884: checking Term::ReadKey +configure:1893: result: yes +configure:2031: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by config.status, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on tc4200 + +config.status:570: creating config.mk +config.status:705: WARNING: config.mk.in seems to ignore the --datarootdir setting + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_path_PERL=/usr/bin/perl +ac_cv_path_SED=/bin/sed +ac_cv_path_install='/usr/bin/install -c' + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +DEFS='-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\"' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +LIBOBJS='' +LIBS='' +LTLIBOBJS='' +PACKAGE_BUGREPORT='' +PACKAGE_NAME='' +PACKAGE_STRING='' +PACKAGE_TARNAME='' +PACKAGE_VERSION='' +PATH_SEPARATOR=':' +PERL='/usr/bin/perl' +SED='/bin/sed' +SHELL='/bin/sh' +bindir='${exec_prefix}/bin' +build_alias='' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +docdir='${datarootdir}/doc/${PACKAGE}' +dvidir='${docdir}' +exec_prefix='${prefix}' +host_alias='' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +mandir='${datarootdir}/man' +oldincludedir='/usr/include' +pdfdir='${docdir}' +prefix='/usr/local' +program_transform_name='s,x,x,' +psdir='${docdir}' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +#define PACKAGE_NAME "" +#define PACKAGE_TARNAME "" +#define PACKAGE_VERSION "" +#define PACKAGE_STRING "" +#define PACKAGE_BUGREPORT "" + +configure: exit 0 diff --git a/postgresql_autodoc/config.mk b/postgresql_autodoc/config.mk new file mode 100644 index 0000000..73bd570 --- /dev/null +++ b/postgresql_autodoc/config.mk @@ -0,0 +1,13 @@ +SHELL = /bin/sh + + +# Configure replacements +INSTALL_SCRIPT = /usr/bin/install -c +PERL = /usr/bin/perl +SED = /bin/sed + +# installation directories +prefix = /usr/local +exec_prefix= ${prefix} +bindir = ${exec_prefix}/bin +datadir = ${prefix}/share/postgresql_autodoc diff --git a/postgresql_autodoc/config.mk.in b/postgresql_autodoc/config.mk.in new file mode 100644 index 0000000..ddcee1a --- /dev/null +++ b/postgresql_autodoc/config.mk.in @@ -0,0 +1,13 @@ +SHELL = /bin/sh +VPATH = @srcdir@ + +# Configure replacements +INSTALL_SCRIPT = @INSTALL@ +PERL = @PERL@ +SED = @SED@ + +# installation directories +prefix = @prefix@ +exec_prefix= @exec_prefix@ +bindir = @bindir@ +datadir = @datadir@/postgresql_autodoc diff --git a/postgresql_autodoc/config.status b/postgresql_autodoc/config.status new file mode 100755 index 0000000..5f5e3a1 --- /dev/null +++ b/postgresql_autodoc/config.status @@ -0,0 +1,761 @@ +#! /bin/sh +# Generated by configure. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=${CONFIG_SHELL-/bin/sh} +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +# Files that config.status was made for. +config_files=" config.mk" + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." + +ac_cs_version="\ +config.status +configured by ./configure, generated by GNU Autoconf 2.61, + with options \"\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='/home/manut/postgresql_autodoc' +srcdir='.' +INSTALL='/usr/bin/install -c' +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +if $ac_cs_recheck; then + echo "running CONFIG_SHELL=/bin/sh /bin/sh ./configure " $ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=/bin/sh + export CONFIG_SHELL + exec /bin/sh "./configure" $ac_configure_extra_args --no-create --no-recursion +fi + +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +cat >"$tmp/subs-1.sed" <<\CEOF +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +s,@SHELL@,|#_!!_#|/bin/sh,g +s,@PATH_SEPARATOR@,|#_!!_#|:,g +s,@PACKAGE_NAME@,|#_!!_#|,g +s,@PACKAGE_TARNAME@,|#_!!_#|,g +s,@PACKAGE_VERSION@,|#_!!_#|,g +s,@PACKAGE_STRING@,|#_!!_#|,g +s,@PACKAGE_BUGREPORT@,|#_!!_#|,g +s,@exec_prefix@,|#_!!_#|${prefix},g +s,@prefix@,|#_!!_#|/usr/local,g +s,@program_transform_name@,|#_!!_#|s\,x\,x\,,g +s,@bindir@,|#_!!_#|${exec_prefix}/bin,g +s,@sbindir@,|#_!!_#|${exec_prefix}/sbin,g +s,@libexecdir@,|#_!!_#|${exec_prefix}/libexec,g +s,@datarootdir@,|#_!!_#|${prefix}/share,g +s,@datadir@,|#_!!_#|${datarootdir},g +s,@sysconfdir@,|#_!!_#|${prefix}/etc,g +s,@sharedstatedir@,|#_!!_#|${prefix}/com,g +s,@localstatedir@,|#_!!_#|${prefix}/var,g +s,@includedir@,|#_!!_#|${prefix}/include,g +s,@oldincludedir@,|#_!!_#|/usr/include,g +s,@docdir@,|#_!!_#|${datarootdir}/doc/${PACKAGE},g +s,@infodir@,|#_!!_#|${datarootdir}/info,g +s,@htmldir@,|#_!!_#|${docdir},g +s,@dvidir@,|#_!!_#|${docdir},g +s,@pdfdir@,|#_!!_#|${docdir},g +s,@psdir@,|#_!!_#|${docdir},g +s,@libdir@,|#_!!_#|${exec_prefix}/lib,g +s,@localedir@,|#_!!_#|${datarootdir}/locale,g +s,@mandir@,|#_!!_#|${datarootdir}/man,g +s,@DEFS@,|#_!!_#|-DPACKAGE_NAME=\\"\\" -DPACKAGE_TARNAME=\\"\\" -DPACKAGE_VERSION=\\"\\" -DPACKAGE_STRING=\\"\\" -DPACKAGE_BUGREPORT=\\"\\",g +s,@ECHO_C@,|#_!!_#|,g +s,@ECHO_N@,|#_!!_#|-n,g +s,@ECHO_T@,|#_!!_#|,g +s,@LIBS@,|#_!!_#|,g +s,@build_alias@,|#_!!_#|,g +s,@host_alias@,|#_!!_#|,g +s,@target_alias@,|#_!!_#|,g +s,@INSTALL_PROGRAM@,|#_!!_#|${INSTALL},g +s,@INSTALL_SCRIPT@,|#_!!_#|${INSTALL},g +s,@INSTALL_DATA@,|#_!!_#|${INSTALL} -m 644,g +s,@SED@,|#_!!_#|/bin/sed,g +s,@PERL@,|#_!!_#|/usr/bin/perl,g +s,@LIBOBJS@,|#_!!_#|,g +s,@LTLIBOBJS@,|#_!!_#|,g +:end +s/|#_!!_#|//g +CEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + ac_datarootdir_hack=' + s&@datadir@&${datarootdir}&g + s&@docdir@&${datarootdir}/doc/${PACKAGE}&g + s&@infodir@&${datarootdir}/info&g + s&@localedir@&${datarootdir}/locale&g + s&@mandir@&${datarootdir}/man&g + s&\${datarootdir}&${prefix}/share&g' ;; +esac + sed "/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } diff --git a/postgresql_autodoc/configure b/postgresql_autodoc/configure new file mode 100755 index 0000000..776cb9d --- /dev/null +++ b/postgresql_autodoc/configure @@ -0,0 +1,2907 @@ +#! /bin/sh +# From configure.ac Header: /cvsroot/autodoc/autodoc/configure.ac. +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="postgresql_autodoc.pl" +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +SED +PERL +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-perl-prefix Location of Perl + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +# Programs +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +for ac_prog in sed +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $SED in + [\\/]* | ?:[\\/]*) + ac_cv_path_SED="$SED" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/bin:/usr/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +SED=$ac_cv_path_SED +if test -n "$SED"; then + { echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$SED" && break +done + + +# Check for Perl + +# Check whether --with-perl-prefix was given. +if test "${with_perl_prefix+set}" = set; then + withval=$with_perl_prefix; PERLPATH=$withval +else + PERLPATH="" +fi + + +if ( test -n "$PERLPATH" -a "`echo $PERLPATH | cut -c-3`" = "../" ); then + PERLPATH="$PWD/$PERLPATH" +fi + +PERL="" +if ( test -n "$PERLPATH" ); then + as_ac_File=`echo "ac_cv_file_"$PERLPATH/bin/perl"" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for \"$PERLPATH/bin/perl\"" >&5 +echo $ECHO_N "checking for \"$PERLPATH/bin/perl\"... $ECHO_C" >&6; } +if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + test "$cross_compiling" = yes && + { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 +echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} + { (exit 1); exit 1; }; } +if test -r ""$PERLPATH/bin/perl""; then + eval "$as_ac_File=yes" +else + eval "$as_ac_File=no" +fi +fi +ac_res=`eval echo '${'$as_ac_File'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_File'}'` = yes; then + PERL="$PERLPATH/bin/perl" +fi + +else + for ac_prog in perl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_PERL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/bin:/usr/local/bin:/usr/pkg/bin:/usr/local/perl/bin:/opt/sfw/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +PERL=$ac_cv_path_PERL +if test -n "$PERL"; then + { echo "$as_me:$LINENO: result: $PERL" >&5 +echo "${ECHO_T}$PERL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$PERL" && break +done + +fi +if ( test -z "$PERL" ); then + { { echo "$as_me:$LINENO: error: \"Perl is required\"" >&5 +echo "$as_me: error: \"Perl is required\"" >&2;} + { (exit 1); exit 1; }; } +fi + + + +# Check that Perl Libraries are available: +# DBI +# DBD::Pg +# Fcntl +# HTML::Template +# Term::ReadKey +# +# Output of if test redirected to /dev/null to keep quiet +for module in DBI DBD::Pg Fcntl HTML::Template Term::ReadKey ; do + { echo "$as_me:$LINENO: checking ${module}" >&5 +echo $ECHO_N "checking ${module}... $ECHO_C" >&6; } + if ! (${PERL} -e "use ${module}" 2>&1 /dev/null ) ; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + { { echo "$as_me:$LINENO: error: Perl module ${module} is required" >&5 +echo "$as_me: error: Perl module ${module} is required" >&2;} + { (exit 1); exit 1; }; } + else + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + fi +done + + +ac_config_files="$ac_config_files config.mk" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +SED!$SED$ac_delim +PERL!$PERL$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 44; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/postgresql_autodoc/configure.ac b/postgresql_autodoc/configure.ac new file mode 100644 index 0000000..128a044 --- /dev/null +++ b/postgresql_autodoc/configure.ac @@ -0,0 +1,56 @@ +AC_PREREQ(2.53) +AC_REVISION($Header: /cvsroot/autodoc/autodoc/configure.ac,v 1.2 2007/01/02 13:53:19 rbt Exp $) +AC_INIT(postgresql_autodoc.pl) + + +# Programs +AC_PROG_INSTALL + +AC_PATH_PROGS([SED], [sed], , + [$PATH:/bin:/usr/bin]) + +# Check for Perl +AC_ARG_WITH(perl-prefix, + [ --with-perl-prefix Location of Perl], + PERLPATH=$withval, + PERLPATH="") + +if ( test -n "$PERLPATH" -a "`echo $PERLPATH | cut -c-3`" = "../" ); then + PERLPATH="$PWD/$PERLPATH" +fi + +PERL="" +if ( test -n "$PERLPATH" ); then + AC_CHECK_FILE("$PERLPATH/bin/perl",PERL="$PERLPATH/bin/perl") +else + AC_PATH_PROGS([PERL], [perl], , + [$PATH:/usr/bin:/usr/local/bin:/usr/pkg/bin:/usr/local/perl/bin:/opt/sfw/bin]) +fi +if ( test -z "$PERL" ); then + AC_MSG_ERROR("Perl is required") +fi +AC_SUBST(PERL) + + +# Check that Perl Libraries are available: +# DBI +# DBD::Pg +# Fcntl +# HTML::Template +# Term::ReadKey +# +# Output of if test redirected to /dev/null to keep quiet +for module in DBI DBD::Pg Fcntl HTML::Template Term::ReadKey ; do + AC_MSG_CHECKING(${module}) + if [ ! (${PERL} -e "use ${module}" 2>&1 /dev/null ) ]; then + AC_MSG_RESULT(no) + AC_MSG_ERROR(Perl module ${module} is required) + else + AC_MSG_RESULT(yes) + fi +done + + +AC_OUTPUT([ +config.mk +]) diff --git a/postgresql_autodoc/dia.tmpl b/postgresql_autodoc/dia.tmpl new file mode 100644 index 0000000..88143e9 --- /dev/null +++ b/postgresql_autodoc/dia.tmpl @@ -0,0 +1,212 @@ + + + + + + + + + "> + + + + + + + + + + + + + + + + + ## + + + + ## + + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #PK # + + + ## + + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + + + + + + + + + + + + ## + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "> + + + + + + + + + + + + ## + + + + + + + + + " connection=""/> + " connection=""/> + + + + + diff --git a/postgresql_autodoc/dot.tmpl b/postgresql_autodoc/dot.tmpl new file mode 100644 index 0000000..1cb9ca6 --- /dev/null +++ b/postgresql_autodoc/dot.tmpl @@ -0,0 +1,19 @@ +digraph g { +graph [ +rankdir = "LR", +concentrate = true, +ratio = auto +]; +node [ +fontsize = "10", +shape = record +]; +edge [ +]; + +"." [shape = plaintext, label = <
\N
" > PK FK ">
> ]; +
+ + +".":rtcol -> ".":ltcol [label=""]; +} diff --git a/postgresql_autodoc/html.tmpl b/postgresql_autodoc/html.tmpl new file mode 100644 index 0000000..4830b15 --- /dev/null +++ b/postgresql_autodoc/html.tmpl @@ -0,0 +1,308 @@ + + + + + + Index for <!-- TMPL_VAR ESCAPE="HTML" name="database" --> + + + + + + + + + + +



Dumped on

+

Index of database -

+ + + + --> + + +
+

Schema

+ +

+ + + + +
+

View:Table: + + ">."> +

+ +

+ + + + + + + + + + + + + tr0tr1"> + + + + + + +
. Structure
F-KeyNameTypeDescription
+ + + ">..# + + + + + PRIMARY KEY + + + + UNIQUE# + + + + NOT NULL + DEFAULT + +

+
+ + + +

Table . Inherits + + + ">., + +

+ + + + +

 

+ + + + + + + + + + + + + + + + +
Statistics
Total Space (disk usage)Tuple CountActive SpaceDead SpaceFree Space
+ + + + + +

 

+ + + + + + + + tr0tr1"> + + + + +
. Constraints
NameConstraint
+ + + + +

Tables referencing this one via Foreign Key Constraints:

+ + + + + + + + + + + + +
+ + + + +

 

+ + + + + + + + + + + + + + tr0tr1"> + + + + + + + + + + +
Permissions which apply to .
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
+ + +

+ Index - + ">Schema +

+ + + + +
+

Function: + ">."> +

+

Returns:

+

Language:

+

+
+ + + +

Generated by PostgreSQL Autodoc

+

W3C HTML 4.01 Strict

+ diff --git a/postgresql_autodoc/install-sh b/postgresql_autodoc/install-sh new file mode 100755 index 0000000..398a88e --- /dev/null +++ b/postgresql_autodoc/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + : +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + : + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + : + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + : + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + : + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/postgresql_autodoc/neato.tmpl b/postgresql_autodoc/neato.tmpl new file mode 100644 index 0000000..b21e067 --- /dev/null +++ b/postgresql_autodoc/neato.tmpl @@ -0,0 +1,22 @@ +digraph g { +node [ fontsize = "10", shape = record ]; +edge []; + +"." [shape = record, label = "{ \N| : \l}" ]; + + +"." -> "." [label=""]; +} + + diff --git a/postgresql_autodoc/postgresql_autodoc b/postgresql_autodoc/postgresql_autodoc new file mode 100755 index 0000000..503a8c5 --- /dev/null +++ b/postgresql_autodoc/postgresql_autodoc @@ -0,0 +1,1907 @@ +#!/usr/bin/perl +# -- # -*- Perl -*-w +# $Header: /cvsroot/autodoc/autodoc/postgresql_autodoc.pl,v 1.21 2008/03/12 19:00:56 rbt Exp $ +# Imported 1.22 2002/02/08 17:09:48 into sourceforge + +# Postgres Auto-Doc Version 1.31 + +# License +# ------- +# Copyright (c) 2001-2007, Rod Taylor +# 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. Neither the name of the InQuent Technologies Inc. nor the names +# of its contributors may be used to endorse or promote products +# derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD +# PROJECT 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. + +# About Project +# ------------- +# Various details about the project and related items can be found at +# the website +# +# http://www.rbt.ca/autodoc/ + +use strict; +use warnings; + +use DBI; +use Fcntl; + +# Allows file templates +use HTML::Template; + +# Allow reading a password from stdin +use Term::ReadKey; + +sub main($) { + my ($ARGV) = @_; + + my %db; + + # The templates path + # /usr/local/share/postgresql_autodoc will be replaced by make in the build phase + my $template_path = '/usr/local/share/postgresql_autodoc'; + + # Setup the default connection variables based on the environment + my $dbuser = $ENV{'PGUSER'}; + $dbuser ||= $ENV{'USER'}; + + my $database = $ENV{'PGDATABASE'}; + $database ||= $dbuser; + + my $dbhost = $ENV{'PGHOST'}; + $dbhost ||= ""; + + my $dbport = $ENV{'PGPORT'}; + $dbport ||= ""; + + # Determine whether we need a password to connect + my $needpass = 0; + + my $dbpass = ""; + my $output_filename_base = $database; + + # Tracking variables + my $dbisset = 0; + my $fileisset = 0; + + my $only_schema; + + my $table_out; + + my $wanted_output = undef; # means all types + + my $statistics = 0; + + # Fetch base and dirnames. Useful for Usage() + my $basename = $0; + my $dirname = $0; + $basename =~ s|^.*/([^/]+)$|$1|; + $dirname =~ s|^(.*)/[^/]+$|$1|; + + # If template_path isn't defined, lets set it ourselves + $template_path = $dirname if ( !defined($template_path) ); + + for ( my $i = 0 ; $i <= $#ARGV ; $i++ ) { + ARGPARSE: for ( $ARGV[$i] ) { + + # Set the database + /^-d$/ && do { + $database = $ARGV[ ++$i ]; + $dbisset = 1; + if ( !$fileisset ) { + $output_filename_base = $database; + } + last; + }; + + # Set the user + /^-[uU]$/ && do { + $dbuser = $ARGV[ ++$i ]; + if ( !$dbisset ) { + $database = $dbuser; + if ( !$fileisset ) { + $output_filename_base = $database; + } + } + last; + }; + + # Set the hostname + /^-h$/ && do { $dbhost = $ARGV[ ++$i ]; last; }; + + # Set the Port + /^-p$/ && do { $dbport = $ARGV[ ++$i ]; last; }; + + # Set the users password + /^--password=/ && do { + $dbpass = $ARGV[$i]; + $dbpass =~ s/^--password=//g; + last; + }; + + # Make sure we get a password before attempting to conenct + /^--password$/ && do { + $needpass = 1; + last; + }; + + # Set the base of the filename. The extensions pulled + # from the templates will be appended to this name + /^-f$/ && do { + $output_filename_base = $ARGV[ ++$i ]; + $fileisset = 1; + last; + }; + + # Set the template directory explicitly + /^(-l|--library)$/ && do { + $template_path = $ARGV[ ++$i ]; + last; + }; + + # Set the output type + /^(-t|--type)$/ && do { + $wanted_output = $ARGV[ ++$i ]; + last; + }; + + # User has requested a single schema dump and provided a pattern + /^(-s|--schema)$/ && do { + $only_schema = $ARGV[ ++$i ]; + last; + }; + + # One might dump a table's set (comma-separated) or just one + # If dumping a set of specific tables do NOT dump out the functions + # in this database. Generates noise in the output + # that most likely isn't wanted. Check for $table_out around the + # function gathering location. + /^--table=/ && do { + my $some_table = $ARGV[$i]; + $some_table =~ s/^--table=//g; + + my @tables_in = split( ',', $some_table ); + sub single_quote; + $table_out = join( ',', map( single_quote, @tables_in ) ); + + last; + }; + + # Check to see if Statistics have been requested + /^--statistics$/ && do { + $statistics = 1; + last; + }; + + # Help is wanted, redirect user to usage() + /^-\?$/ && do { usage( $basename, $database, $dbuser ); last; }; + /^--help$/ && do { usage( $basename, $database, $dbuser ); last; }; + } + } + + # If no arguments have been provided, connect to the database anyway but + # inform the user of what we're doing. + if ( $#ARGV <= 0 ) { + print <connect( @{$dbConnect} ) + or triggerError("Unable to connect due to: $DBI::errstr"); + + $dbh->do("set client_encoding to 'UTF-8'") + or triggerError("could not set client_encoding to UTF-8: $DBI::errstr"); + + my %struct; + $db->{$database}{'STRUCT'} = \%struct; + my $struct = $db->{$database}{'STRUCT'}; + + # PostgreSQL's version is used to determine what queries are required + # to retrieve a given information set. + if ( $dbh->{pg_server_version} < 70300 ) { + die("PostgreSQL 7.3 and later are supported"); + } + + # Ensure we only retrieve information for the requested schemas. + # + # system_schema -> The primary system schema for a database. + # Public is used for verions prior to 7.3 + # + # system_schema_list -> The list of schemas which we are not supposed + # to gather information for. + # TODO: Merge with system_schema in array form. + # + # schemapattern -> The schema the user provided as a command + # line option. + my $schemapattern = '^'; + my $system_schema = 'pg_catalog'; + my $system_schema_list = + 'pg_catalog|pg_toast|pg_temp_[0-9]+|information_schema'; + if ( defined($only_schema) ) { + $schemapattern = '^' . $only_schema . '$'; + } + + # + # List of queries which are used to gather information from the + # database. The queries differ based on version but should + # provide similar output. At some point it should be safe to remove + # support for older database versions. + # + + # Fetch the description of the database + my $sql_Database = q{ + SELECT pg_catalog.obj_description(oid, 'pg_database') as comment + FROM pg_catalog.pg_database + WHERE datname = '$database'; + }; + + # Pull out a list of tables, views and special structures. + my $sql_Tables = qq{ + SELECT nspname as namespace + , relname as tablename + , pg_catalog.pg_get_userbyid(relowner) AS tableowner + , relhasindex as hasindexes + , relhasrules as hasrules + , reltriggers as hastriggers + , pg_class.oid + , pg_catalog.obj_description(pg_class.oid, 'pg_class') as table_description + , relacl + , CASE + WHEN relkind = 'r' THEN + 'table' + WHEN relkind = 's' THEN + 'special' + ELSE + 'view' + END as reltype + , CASE + WHEN relkind = 'v' THEN + pg_get_viewdef(pg_class.oid) + ELSE + NULL + END as view_definition + FROM pg_catalog.pg_class + JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid) + WHERE relkind IN ('r', 's', 'v') + AND nspname !~ '$system_schema_list' + AND nspname ~ '$schemapattern' + }; + $sql_Tables .= qq{ AND relname IN ($table_out)} if defined($table_out); + + # - uses pg_class.oid + my $sql_Columns = q{ + SELECT attname as column_name + , attlen as column_length + , CASE + WHEN pg_type.typname = 'int4' + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + 'serial' + WHEN pg_type.typname = 'int8' + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + 'bigserial' + ELSE + pg_catalog.format_type(atttypid, atttypmod) + END as column_type + , CASE + WHEN attnotnull THEN + cast('NOT NULL' as text) + ELSE + cast('' as text) + END as column_null + , CASE + WHEN pg_type.typname IN ('int4', 'int8') + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + NULL + ELSE + adsrc + END as column_default + , pg_catalog.col_description(attrelid, attnum) as column_description + , attnum + FROM pg_catalog.pg_attribute + JOIN pg_catalog.pg_type ON (pg_type.oid = atttypid) + LEFT JOIN pg_catalog.pg_attrdef ON ( attrelid = adrelid + AND attnum = adnum) + WHERE attnum > 0 + AND attisdropped IS FALSE + AND attrelid = ?; + }; + + my $sql_Table_Statistics; + if ( $statistics == 1 ) { + if ( $dbh->{pg_server_version} <= 70300 ) { + triggerError( + "Table statistics supported on PostgreSQL 7.4 and later.\n" + . "Remove --statistics flag and try again." ); + } + + $sql_Table_Statistics = q{ + SELECT table_len + , tuple_count + , tuple_len + , CAST(tuple_percent AS numeric(20,2)) AS tuple_percent + , dead_tuple_count + , dead_tuple_len + , CAST(dead_tuple_percent AS numeric(20,2)) AS dead_tuple_percent + , CAST(free_space AS numeric(20,2)) AS free_space + , CAST(free_percent AS numeric(20,2)) AS free_percent + FROM pgstattuple(CAST(? AS oid)); + }; + } + + my $sql_Indexes = q{ + SELECT schemaname + , tablename + , indexname + , substring( indexdef + FROM position('(' IN indexdef) + 1 + FOR length(indexdef) - position('(' IN indexdef) - 1 + ) AS indexdef + FROM pg_catalog.pg_indexes + WHERE substring(indexdef FROM 8 FOR 6) != 'UNIQUE' + AND schemaname = ? + AND tablename = ?; + }; + + my $sql_Inheritance = qq{ + SELECT parnsp.nspname AS par_schemaname + , parcla.relname AS par_tablename + , chlnsp.nspname AS chl_schemaname + , chlcla.relname AS chl_tablename + FROM pg_catalog.pg_inherits + JOIN pg_catalog.pg_class AS chlcla ON (chlcla.oid = inhrelid) + JOIN pg_catalog.pg_namespace AS chlnsp ON (chlnsp.oid = chlcla.relnamespace) + JOIN pg_catalog.pg_class AS parcla ON (parcla.oid = inhparent) + JOIN pg_catalog.pg_namespace AS parnsp ON (parnsp.oid = parcla.relnamespace) + WHERE chlnsp.nspname = ? + AND chlcla.relname = ? + AND chlnsp.nspname ~ '$schemapattern' + AND parnsp.nspname ~ '$schemapattern'; + }; + + # Fetch the list of PRIMARY and UNIQUE keys + my $sql_Primary_Keys = q{ + SELECT conname AS constraint_name + , pg_catalog.pg_get_indexdef(d.objid) AS constraint_definition + , CASE + WHEN contype = 'p' THEN + 'PRIMARY KEY' + ELSE + 'UNIQUE' + END as constraint_type + FROM pg_catalog.pg_constraint AS c + JOIN pg_catalog.pg_depend AS d ON (d.refobjid = c.oid) + WHERE contype IN ('p', 'u') + AND deptype = 'i' + AND conrelid = ?; + }; + + # FOREIGN KEY fetch + # + # Don't return the constraint name if it was automatically generated by + # PostgreSQL. The $N (where N is an integer) is not a descriptive enough + # piece of information to be worth while including in the various outputs. + my $sql_Foreign_Keys = qq{ + SELECT pg_constraint.oid + , pg_namespace.nspname AS namespace + , CASE WHEN substring(pg_constraint.conname FROM 1 FOR 1) = '\$' THEN '' + ELSE pg_constraint.conname + END AS constraint_name + , conkey AS constraint_key + , confkey AS constraint_fkey + , confrelid AS foreignrelid + FROM pg_catalog.pg_constraint + JOIN pg_catalog.pg_class ON (pg_class.oid = conrelid) + JOIN pg_catalog.pg_class AS pc ON (pc.oid = confrelid) + JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid) + JOIN pg_catalog.pg_namespace AS pn ON (pn.oid = pc.relnamespace) + WHERE contype = 'f' + AND conrelid = ? + AND pg_namespace.nspname ~ '$schemapattern' + AND pn.nspname ~ '$schemapattern'; + }; + + my $sql_Foreign_Key_Arg = q{ + SELECT attname AS attribute_name + , relname AS relation_name + , nspname AS namespace + FROM pg_catalog.pg_attribute + JOIN pg_catalog.pg_class ON (pg_class.oid = attrelid) + JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid) + WHERE attrelid = ? + AND attnum = ?; + }; + + # Fetch CHECK constraints + my $sql_Constraint; + if ( $dbh->{pg_server_version} >= 70400 ) { + $sql_Constraint = q{ + SELECT pg_get_constraintdef(oid) AS constraint_source + , conname AS constraint_name + FROM pg_constraint + WHERE conrelid = ? + AND contype = 'c'; + }; + } + else { + $sql_Constraint = q{ + SELECT 'CHECK ' || pg_catalog.substr(consrc, 2, length(consrc) - 2) AS constraint_source + , conname AS constraint_name + FROM pg_constraint + WHERE conrelid = ? + AND contype = 'c'; + }; + } + + # Query for function information + my $sql_Function; + my $sql_FunctionArg; + if ( $dbh->{pg_server_version} >= 80000 ) { + $sql_Function = qq{ + SELECT proname AS function_name + , nspname AS namespace + , lanname AS language_name + , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment + , proargtypes AS function_args + , proargnames AS function_arg_names + , prosrc AS source_code + , proretset AS returns_set + , prorettype AS return_type + FROM pg_catalog.pg_proc + JOIN pg_catalog.pg_language ON (pg_language.oid = prolang) + JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid) + JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid) + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern' + AND proname != 'plpgsql_call_handler'; + }; + + $sql_FunctionArg = q{ + SELECT nspname AS namespace + , replace(pg_catalog.format_type(pg_type.oid, typtypmod) + , nspname ||'.' + , '') AS type_name + FROM pg_catalog.pg_type + JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace) + WHERE pg_type.oid = ?; + }; + } + else { + $sql_Function = qq{ + SELECT proname AS function_name + , nspname AS namespace + , lanname AS language_name + , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment + , proargtypes AS function_args + , NULL AS function_arg_names + , prosrc AS source_code + , proretset AS returns_set + , prorettype AS return_type + FROM pg_catalog.pg_proc + JOIN pg_catalog.pg_language ON (pg_language.oid = prolang) + JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid) + JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid) + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern' + AND proname != 'plpgsql_call_handler'; + }; + + $sql_FunctionArg = q{ + SELECT nspname AS namespace + , replace(pg_catalog.format_type(pg_type.oid, typtypmod) + , nspname ||'.' + , '') AS type_name + FROM pg_catalog.pg_type + JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace) + WHERE pg_type.oid = ?; + }; + } + + # Fetch schema information. + my $sql_Schema = qq{ + SELECT pg_catalog.obj_description(oid, 'pg_namespace') AS comment + , nspname as namespace + FROM pg_catalog.pg_namespace + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern'; + }; + + my $sth_Columns = $dbh->prepare($sql_Columns); + my $sth_Constraint = $dbh->prepare($sql_Constraint); + my $sth_Database = $dbh->prepare($sql_Database); + my $sth_Foreign_Keys = $dbh->prepare($sql_Foreign_Keys); + my $sth_Foreign_Key_Arg = $dbh->prepare($sql_Foreign_Key_Arg); + my $sth_Function = $dbh->prepare($sql_Function); + my $sth_FunctionArg = $dbh->prepare($sql_FunctionArg); + my $sth_Indexes = $dbh->prepare($sql_Indexes); + my $sth_Inheritance = $dbh->prepare($sql_Inheritance); + my $sth_Primary_Keys = $dbh->prepare($sql_Primary_Keys); + my $sth_Schema = $dbh->prepare($sql_Schema); + my $sth_Tables = $dbh->prepare($sql_Tables); + my $sth_Table_Statistics = $dbh->prepare($sql_Table_Statistics) + if ( $statistics == 1 ); + + # Fetch Database info + $sth_Database->execute(); + my $dbinfo = $sth_Database->fetchrow_hashref; + if ( defined($dbinfo) ) { + $db->{$database}{'COMMENT'} = $dbinfo->{'comment'}; + } + + # Fetch tables and all things bound to tables + $sth_Tables->execute(); + while ( my $tables = $sth_Tables->fetchrow_hashref ) { + my $reloid = $tables->{'oid'}; + my $relname = $tables->{'tablename'}; + + my $schema = $tables->{'namespace'}; + + EXPRESSIONFOUND: + + # Store permissions + my $acl = $tables->{'relacl'}; + + # Empty acl groups cause serious issues. + $acl ||= ''; + + # Strip array forming 'junk'. + $acl =~ s/^{//g; + $acl =~ s/}$//g; + $acl =~ s/"//g; + + # Foreach acl + foreach ( split( /\,/, $acl ) ) { + my ( $user, $raw_permissions ) = split( /=/, $_ ); + + if ( defined($raw_permissions) ) { + if ( $user eq '' ) { + $user = 'PUBLIC'; + } + + # The section after the / is the user who granted the permissions + my ( $permissions, $granting_user ) = + split( /\//, $raw_permissions ); + + # Break down permissions to individual flags + if ( $permissions =~ /a/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'INSERT'} = 1; + } + + if ( $permissions =~ /r/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'SELECT'} = 1; + } + + if ( $permissions =~ /w/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'UPDATE'} = 1; + } + + if ( $permissions =~ /d/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'DELETE'} = 1; + } + + if ( $permissions =~ /R/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'RULE'} = 1; + } + + if ( $permissions =~ /x/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'REFERENCES'} = 1; + } + + if ( $permissions =~ /t/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'TRIGGER'} = 1; + } + } + } + + # Primitive Stats, but only if requested + if ( $statistics == 1 and $tables->{'reltype'} eq 'table' ) { + $sth_Table_Statistics->execute($reloid); + + my $stats = $sth_Table_Statistics->fetchrow_hashref; + + $struct->{$schema}{'TABLE'}{$relname}{'TABLELEN'} = + $stats->{'table_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'TUPLECOUNT'} = + $stats->{'tuple_count'}; + $struct->{$schema}{'TABLE'}{$relname}{'TUPLELEN'} = + $stats->{'tuple_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'DEADTUPLELEN'} = + $stats->{'dead_tuple_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'FREELEN'} = + $stats->{'free_space'}; + } + + # Store the relation type + $struct->{$schema}{'TABLE'}{$relname}{'TYPE'} = $tables->{'reltype'}; + + # Store table description + $struct->{$schema}{'TABLE'}{$relname}{'DESCRIPTION'} = + $tables->{'table_description'}; + + # Store the view definition + $struct->{$schema}{'TABLE'}{$relname}{'VIEW_DEF'} = + $tables->{'view_definition'}; + + # Store constraints + $sth_Constraint->execute($reloid); + while ( my $cols = $sth_Constraint->fetchrow_hashref ) { + my $constraint_name = $cols->{'constraint_name'}; + $struct->{$schema}{'TABLE'}{$relname}{'CONSTRAINT'} + {$constraint_name} = $cols->{'constraint_source'}; + } + + $sth_Columns->execute($reloid); + my $i = 1; + while ( my $cols = $sth_Columns->fetchrow_hashref ) { + my $column_name = $cols->{'column_name'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'ORDER'} = $cols->{'attnum'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'PRIMARY KEY'} = 0; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'FKTABLE'} = ''; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'TYPE'} = $cols->{'column_type'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'NULL'} = $cols->{'column_null'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'DESCRIPTION'} = $cols->{'column_description'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'DEFAULT'} = $cols->{'column_default'}; + } + + # Pull out both PRIMARY and UNIQUE keys based on the supplied query + # and the relation OID. + # + # Since there may be multiple UNIQUE indexes on a table, we append a + # number to the end of the the UNIQUE keyword which shows that they + # are a part of a related definition. I.e UNIQUE_1 goes with UNIQUE_1 + # + $sth_Primary_Keys->execute($reloid); + my $unqgroup = 0; + while ( my $pricols = $sth_Primary_Keys->fetchrow_hashref ) { + my $index_type = $pricols->{'constraint_type'}; + my $con = $pricols->{'constraint_name'}; + my $indexdef = $pricols->{'constraint_definition'}; + + # Fetch the column list + my $column_list = $indexdef; + $column_list =~ s/.*\(([^)]+)\).*/$1/g; + + # Split our column list and deal with all PRIMARY KEY fields + my @collist = split( ',', $column_list ); + + # Store the column number in the indextype field. Anything > 0 + # indicates the column has this type of constraint applied to it. + my $column; + my $currentcol = $#collist + 1; + my $numcols = $#collist + 1; + + # Bump group number if there are two or more columns + if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) { + $unqgroup++; + } + + # Record the data to the structure. + while ( $column = pop(@collist) ) { + $column =~ s/\s$//; + $column =~ s/^\s//; + $column =~ s/^"//; + $column =~ s/"$//; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'TYPE'} = $index_type; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'COLNUM'} = $currentcol--; + + # Record group number only when a multi-column + # constraint is involved + if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'} = $unqgroup; + } + } + } + + # FOREIGN KEYS like UNIQUE indexes can appear several times in + # a table in multi-column format. We use the same trick to + # record a numeric association to the foreign key reference. + $sth_Foreign_Keys->execute($reloid); + my $fkgroup = 0; + while ( my $forcols = $sth_Foreign_Keys->fetchrow_hashref ) { + my $column_oid = $forcols->{'oid'}; + my $con = $forcols->{'constraint_name'}; + + # Declare variables for dataload + my @keylist; + my @fkeylist; + my $fschema; + my $ftable; + + my $fkey = $forcols->{'constraint_fkey'}; + my $keys = $forcols->{'constraint_key'}; + my $frelid = $forcols->{'foreignrelid'}; + + # Since decent array support was not added until 7.4, and + # we want to support 7.3 as well, we parse the text version + # of the array by hand rather than combining this and + # Foreign_Key_Arg query into a single query. + + my @fkeyset; + if ( ref $fkey eq 'ARRAY' ) { + @fkeyset = @{$fkey}; + } + else { # DEPRECATED: DBD::Pg 1.49 and earlier + $fkey =~ s/^{//g; + $fkey =~ s/}$//g; + $fkey =~ s/"//g; + @fkeyset = split( /,/, $fkey ); + } + + my @keyset; + if ( ref $keys eq 'ARRAY' ) { + @keyset = @{$keys}; + } + else { # DEPRECATED: DBD::Pg 1.49 and earlier + $keys =~ s/^{//g; + $keys =~ s/}$//g; + $keys =~ s/"//g; + @keyset = split( /,/, $keys ); + } + + # Convert the list of column numbers into column names for the + # local side. + foreach my $k (@keyset) { + $sth_Foreign_Key_Arg->execute( $reloid, $k ); + + my $row = $sth_Foreign_Key_Arg->fetchrow_hashref; + + push( @keylist, $row->{'attribute_name'} ); + } + + # Convert the list of columns numbers into column names + # for the referenced side. Grab the table and namespace + # while we're here. + foreach my $k (@fkeyset) { + $sth_Foreign_Key_Arg->execute( $frelid, $k ); + + my $row = $sth_Foreign_Key_Arg->fetchrow_hashref; + + push( @fkeylist, $row->{'attribute_name'} ); + $fschema = $row->{'namespace'}; + $ftable = $row->{'relation_name'}; + } + + # Deal with common catalog issues. + die "FKEY $con Broken -- fix your PostgreSQL installation" + if $#keylist != $#fkeylist; + + # Load up the array based on the information discovered + # using the information retrieval methods above. + my $numcols = $#keylist + 1; + my $currentcol = $#keylist + 1; + + # Bump group number if there are two or more columns involved + if ( $numcols >= 2 ) { + $fkgroup++; + } + + # Record the foreign key to structure + while ( my $column = pop(@keylist) + and my $fkey = pop(@fkeylist) ) + { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'TYPE'} = 'FOREIGN KEY'; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'COLNUM'} = $currentcol--; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FKTABLE'} = $ftable; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FKSCHEMA'} = $fschema; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FK-COL NAME'} = $fkey; + + # Record group number only when a multi-column + # constraint is involved + if ( $numcols >= 2 ) { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'} = $fkgroup; + } + } + } + + # Pull out index information + $sth_Indexes->execute( $schema, $relname ); + while ( my $idx = $sth_Indexes->fetchrow_hashref ) { + $struct->{$schema}{'TABLE'}{$relname}{'INDEX'} + { $idx->{'indexname'} } = $idx->{'indexdef'}; + } + + # Extract Inheritance information + $sth_Inheritance->execute( $schema, $relname ); + while ( my $inherit = $sth_Inheritance->fetchrow_hashref ) { + my $parSch = $inherit->{'par_schemaname'}; + my $parTab = $inherit->{'par_tablename'}; + $struct->{$schema}{'TABLE'}{$relname}{'INHERIT'}{$parSch}{$parTab} = + 1; + } + } + + # Function Handling + $sth_Function->execute(); + while ( my $functions = $sth_Function->fetchrow_hashref and not $table_out ) + { + my $functionname = $functions->{'function_name'} . '( '; + my $schema = $functions->{'namespace'}; + my $comment = $functions->{'comment'}; + my $functionargs = $functions->{'function_args'}; + my @types = split( ' ', $functionargs ); + my $count = 0; + + # Pre-setup argument names when available. + my $argnames = $functions->{'function_arg_names'}; + my @names; + + if ( defined($argnames) ) { + $argnames =~ s/{(.*)}/$1/; + @names = split( ',', $argnames ); + } + + # Setup full argument types -- including the name prefix + foreach my $type (@types) { + $sth_FunctionArg->execute($type); + + my $hash = $sth_FunctionArg->fetchrow_hashref; + + if ( $count > 0 ) { + $functionname .= ', '; + } + + if ( scalar(@names) > 0 ) { + $functionname .= $names[$count] . ' '; + } + + if ( $hash->{'namespace'} ne $system_schema ) { + $functionname .= $hash->{'namespace'} . '.'; + } + $functionname .= $hash->{'type_name'}; + + $count++; + } + $functionname .= ' )'; + + my $ret_type = $functions->{'returns_set'} ? 'SET OF ' : ''; + $sth_FunctionArg->execute( $functions->{'return_type'} ); + my $rhash = $sth_FunctionArg->fetchrow_hashref; + $ret_type .= $rhash->{'type_name'}; + + $struct->{$schema}{'FUNCTION'}{$functionname}{'COMMENT'} = $comment; + $struct->{$schema}{'FUNCTION'}{$functionname}{'SOURCE'} = + $functions->{'source_code'}; + $struct->{$schema}{'FUNCTION'}{$functionname}{'LANGUAGE'} = + $functions->{'language_name'}; + $struct->{$schema}{'FUNCTION'}{$functionname}{'RETURNS'} = $ret_type; + } + + # Deal with the Schema + $sth_Schema->execute(); + while ( my $schema = $sth_Schema->fetchrow_hashref ) { + my $comment = $schema->{'comment'}; + my $namespace = $schema->{'namespace'}; + + $struct->{$namespace}{'SCHEMA'}{'COMMENT'} = $comment; + } + + $sth_Columns->finish(); + $sth_Constraint->finish(); + $sth_Database->finish(); + $sth_Foreign_Keys->finish(); + $sth_Foreign_Key_Arg->finish(); + $sth_Function->finish(); + $sth_FunctionArg->finish(); + $sth_Indexes->finish(); + $sth_Inheritance->finish(); + $sth_Primary_Keys->finish(); + $sth_Schema->finish(); + $sth_Tables->finish(); + $sth_Table_Statistics->finish() + if ( $statistics == 1 ); + + $dbh->disconnect; + +} ## end sub info_collect($$$$$) + +##### +# write_using_templates +# +# Generate structure that HTML::Template requires out of the +# $struct for table related information, and $struct for +# the schema and function information +sub write_using_templates($$$$$) { + my ( $db, $database, $statistics, $template_path, $output_filename_base, + $wanted_output ) + = @_; + my $struct = $db->{$database}{'STRUCT'}; + + my @schemas; + + # Start at 0, increment to 1 prior to use. + my $object_id = 0; + my %tableids; + foreach my $schema ( sort keys %{$struct} ) { + my @tables; + foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) { + + # Column List + my @columns; + foreach my $column ( + sort { + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a} + {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table} + {'COLUMN'}{$b}{'ORDER'} + } keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} } + ) + { + my $inferrednotnull = 0; + + # Have a shorter default for places that require it + my $shortdefault = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'}; + $shortdefault =~ s/^(.{17}).{5,}(.{5})$/$1 ... $2/g + if ( defined($shortdefault) ); + + # Deal with column constraints + my @colconstraints; + foreach my $con ( + sort keys %{ + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'} + } + ) + { + if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'UNIQUE' ) + { + my $unq = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'}; + my $unqcol = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'COLNUM'}; + my $unqgroup = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'}; + + push @colconstraints, + { + column_unique => $unq, + column_unique_colnum => $unqcol, + column_unique_keygroup => $unqgroup, + }; + } + elsif ( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'PRIMARY KEY' ) + { + $inferrednotnull = 1; + push @colconstraints, + { column_primary_key => 'PRIMARY KEY', }; + } + elsif ( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' ) + { + my $fksgmlid = sgml_safe_id( + join( '.', + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'FKSCHEMA'}, + $struct->{$schema}{'TABLE'}{$table}{'TYPE'}, + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'FKTABLE'} ) + ); + + my $fkgroup = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'}; + my $fktable = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKTABLE'}; + my $fkcol = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FK-COL NAME'}; + my $fkschema = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKSCHEMA'}; + + push @colconstraints, + { + column_fk => 'FOREIGN KEY', + column_fk_colnum => $fkcol, + column_fk_keygroup => $fkgroup, + column_fk_schema => $fkschema, + column_fk_schema_dbk => docbook($fkschema), + column_fk_schema_dot => graphviz($fkschema), + column_fk_sgmlid => $fksgmlid, + column_fk_table => $fktable, + column_fk_table_dbk => docbook($fktable), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $colconstraints[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + } + } + + # Generate the Column array + push @columns, { + column => $column, + column_dbk => docbook($column), + column_dot => graphviz($column), + column_default => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'}, + column_default_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'} + ), + column_default_short => $shortdefault, + column_default_short_dbk => docbook($shortdefault), + + column_comment => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DESCRIPTION'}, + column_comment_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DESCRIPTION'} + ), + + column_number => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'ORDER'}, + + column_type => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'}, + column_type_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'} + ), + column_type_dot => graphviz( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'} + ), + + column_constraints => \@colconstraints, + }; + + if ( $inferrednotnull == 0 ) { + $columns[-1]{"column_constraint_notnull"} = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'NULL'}; + } + } + + # Constraint List + my @constraints; + foreach my $constraint ( + sort + keys %{ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} } + ) + { + my $shortcon = + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint}; + $shortcon =~ s/^(.{30}).{5,}(.{5})$/$1 ... $2/g; + push @constraints, + { + constraint => + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint}, + constraint_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint} + ), + constraint_name => $constraint, + constraint_name_dbk => docbook($constraint), + constraint_short => $shortcon, + constraint_short_dbk => docbook($shortcon), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + }; + } + + # Index List + my @indexes; + foreach my $index ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INDEX'} } ) + { + push @indexes, + { + index_definition => + $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index}, + index_definition_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index} + ), + index_name => $index, + index_name_dbk => docbook($index), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + }; + } + + my @inherits; + foreach my $inhSch ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'} } ) + { + foreach my $inhTab ( + sort keys + %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'}{$inhSch} } + ) + { + push @inherits, + { + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + sgmlid => + sgml_safe_id( join( '.', $schema, 'table', $table ) ), + parent_sgmlid => sgml_safe_id( + join( '.', $inhSch, 'table', $inhTab ) + ), + parent_table => $inhTab, + parent_table_dbk => docbook($inhTab), + parent_table_dot => graphviz($inhTab), + parent_schema => $inhSch, + parent_schema_dbk => docbook($inhSch), + parent_schema_dot => graphviz($inhSch), + }; + } + } + + # Foreign Key Discovery + # + # $lastmatch is used to ensure that we only supply a result a + # single time and not once for each link found. Since the + # loops are sorted, we only need to track the last element, and + # not all supplied elements. + my @fk_schemas; + my $lastmatch = ''; + foreach my $fk_schema ( sort keys %{$struct} ) { + foreach + my $fk_table ( sort keys %{ $struct->{$fk_schema}{'TABLE'} } ) + { + foreach my $fk_column ( + sort keys + %{ $struct->{$fk_schema}{'TABLE'}{$fk_table}{'COLUMN'} } + ) + { + foreach my $fk_con ( + sort keys %{ + $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'} + } + ) + { + if ( $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con}{'TYPE'} + eq 'FOREIGN KEY' + and $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con} + {'FKTABLE'} eq $table + and $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con} + {'FKSCHEMA'} eq $schema + and $lastmatch ne "$fk_schema$fk_table" ) + { + my $fksgmlid = sgml_safe_id( + join( '.', + $fk_schema, + $struct->{$fk_schema}{'TABLE'} + {$fk_table}{'TYPE'}, + $fk_table ) + ); + push @fk_schemas, + { + fk_column_number => + $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'ORDER'}, + fk_sgmlid => $fksgmlid, + fk_schema => $fk_schema, + fk_schema_dbk => docbook($fk_schema), + fk_schema_dot => graphviz($fk_schema), + fk_table => $fk_table, + fk_table_dbk => docbook($fk_table), + fk_table_dot => graphviz($fk_table), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $fk_schemas[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + + $lastmatch = "$fk_schema$fk_table"; + } + } + } + } + } + + # List off permissions + my @permissions; + foreach my $user ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'} } ) + { + push @permissions, + { + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + user => $user, + user_dbk => docbook($user), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $permissions[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + + foreach my $perm ( + keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} } + ) + { + if ( $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} + {$perm} == 1 ) + { + $permissions[-1]{ lower($perm) } = 1; + } + } + + } + + # Increment and record the object ID + $tableids{"$schema$table"} = ++$object_id; + my $viewdef = sql_prettyprint( + $struct->{$schema}{'TABLE'}{$table}{'VIEW_DEF'} ); + + # Truncate comment for Dia + my $comment_dia = + $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'}; + $comment_dia =~ s/^(.{35}).{5,}(.{5})$/$1 ... $2/g + if ( defined($comment_dia) ); + + push @tables, { + object_id => $object_id, + object_id_dbk => docbook($object_id), + + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + + # Statistics + stats_enabled => $statistics, + stats_dead_bytes => useUnits( + $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'} + ), + stats_dead_bytes_dbk => docbook( + useUnits( + $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'} + ) + ), + stats_free_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ), + stats_free_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ) + ), + stats_table_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ), + stats_table_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ) + ), + stats_tuple_count => + $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'}, + stats_tuple_count_dbk => + docbook( $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'} ), + stats_tuple_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ), + stats_tuple_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ) + ), + + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + table_sgmlid => sgml_safe_id( + join( '.', + $schema, $struct->{$schema}{'TABLE'}{$table}{'TYPE'}, + $table ) + ), + table_comment => + $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'}, + table_comment_dbk => + docbook( $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'} ), + table_comment_dia => $comment_dia, + view_definition => $viewdef, + view_definition_dbk => docbook($viewdef), + columns => \@columns, + constraints => \@constraints, + fk_schemas => \@fk_schemas, + indexes => \@indexes, + inherits => \@inherits, + permissions => \@permissions, + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $tables[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + # Dump out list of functions + my @functions; + foreach my $function ( sort keys %{ $struct->{$schema}{'FUNCTION'} } ) { + push @functions, + { + function => $function, + function_dbk => docbook($function), + function_sgmlid => + sgml_safe_id( join( '.', $schema, 'function', $function ) ), + function_comment => + $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'}, + function_comment_dbk => docbook( + $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'} + ), + function_language => + uc( $struct->{$schema}{'FUNCTION'}{$function}{'LANGUAGE'} ), + function_returns => + $struct->{$schema}{'FUNCTION'}{$function}{'RETURNS'}, + function_source => + $struct->{$schema}{'FUNCTION'}{$function}{'SOURCE'}, + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $functions[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + push @schemas, + { + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + schema_comment => $struct->{$schema}{'SCHEMA'}{'COMMENT'}, + schema_comment_dbk => + docbook( $struct->{$schema}{'SCHEMA'}{'COMMENT'} ), + functions => \@functions, + tables => \@tables, + }; + + # Build the array of schemas + if ( scalar( keys %{$struct} ) > 1 ) { + $schemas[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + # Link the various components together via the template. + my @fk_links; + my @fkeys; + foreach my $schema ( sort keys %{$struct} ) { + foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) { + foreach my $column ( + sort { + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a} + {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table} + {'COLUMN'}{$b}{'ORDER'} + } + keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} } + ) + { + foreach my $con ( + sort keys %{ + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'} + } + ) + { + + # To prevent a multi-column foreign key from appearing + # several times, we've opted + # to simply display the first column of any given key. + # Since column numbering always starts at 1 + # for foreign keys. + if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' + && $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'COLNUM'} == 1 ) + { + + # Pull out some of the longer keys + my $ref_table = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKTABLE'}; + my $ref_schema = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKSCHEMA'}; + my $ref_column = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FK-COL NAME'}; + + # Default values cause these elements to attach + # to the bottom in Dia + # If a KEYGROUP is not defined, it's a single column. + # Modify the ref_con and key_con variables to attach + # the to the columns connection point directly. + my $ref_con = 0; + my $key_con = 0; + my $keycon_offset = 0; + if ( + !defined( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'KEYGROUP'} + ) + ) + { + $ref_con = + $struct->{$ref_schema}{'TABLE'}{$ref_table} + {'COLUMN'}{$ref_column}{'ORDER'} || 0; + $key_con = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'ORDER'} || 0; + $keycon_offset = 1; + } + + # Bump object_id + $object_id++; + + push @fk_links, + { + fk_link_name => $con, + fk_link_name_dbk => docbook($con), + fk_link_name_dot => graphviz($con), + handle0_connection => $key_con, + handle0_connection_dbk => docbook($key_con), + handle0_connection_dia => 6 + ( $key_con * 2 ), + handle0_name => $table, + handle0_name_dbk => docbook($table), + handle0_schema => $schema, + handle0_to => $tableids{"$schema$table"}, + handle0_to_dbk => + docbook( $tableids{"$schema$table"} ), + handle1_connection => $ref_con, + handle1_connection_dbk => docbook($ref_con), + handle1_connection_dia => 6 + + ( $ref_con * 2 ) + + $keycon_offset, + handle1_name => $ref_table, + handle1_name_dbk => docbook($ref_table), + handle1_schema => $ref_schema, + handle1_to => $tableids{"$ref_schema$ref_table"}, + handle1_to_dbk => + docbook( $tableids{"$ref_schema$ref_table"} ), + object_id => $object_id, + object_id_dbk => docbook($object_id), + }; + + # Build the array of schemas + if ( scalar( keys %{$struct} ) > 1 ) { + $fk_links[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + } + } + } + } + } + + # Make database level comment information + my @timestamp = localtime(); + my $dumped_on = sprintf( "%04d-%02d-%02d", + $timestamp[5] + 1900, + $timestamp[4] + 1, + $timestamp[3] ); + my $database_comment = $db->{$database}{'COMMENT'}; + + # Loop through each template found in the supplied path. + # Output the results of the template as . + # into the current working directory. + my @template_files = glob( $template_path . '/*.tmpl' ); + + # Ensure we've told the user if we don't find any files. + triggerError("Templates files not found in $template_path") + if ( $#template_files < 0 ); + + # Process all found templates. + foreach my $template_file (@template_files) { + ( my $file_extension = $template_file ) =~ + s/^(?:.*\/|)([^\/]+)\.tmpl$/$1/; + next + if ( defined($wanted_output) && $file_extension ne $wanted_output ); + my $output_filename = "$output_filename_base.$file_extension"; + print "Producing $output_filename from $template_file\n"; + + my $template = HTML::Template->new( + filename => $template_file, + die_on_bad_params => 0, + global_vars => 0, + strict => 1, + loop_context_vars => 1 + ); + + $template->param( + database => $database, + database_dbk => docbook($database), + database_sgmlid => sgml_safe_id($database), + database_comment => $database_comment, + database_comment_dbk => docbook($database_comment), + dumped_on => $dumped_on, + dumped_on_dbk => docbook($dumped_on), + fk_links => \@fk_links, + schemas => \@schemas, + ); + + sysopen( FH, $output_filename, O_WRONLY | O_TRUNC | O_CREAT, 0644 ) + or die "Can't open $output_filename: $!"; + print FH $template->output(); + } +} ## end sub write_using_templates($$$$$) + +###### +# sgml_safe_id +# Safe SGML ID Character replacement +sub sgml_safe_id($) { + my $string = shift; + + # Lets use the keyword ARRAY in place of the square brackets + # to prevent duplicating a non-array equivelent + $string =~ s/\[\]/ARRAY-/g; + + # Brackets, spaces, commads, underscores are not valid 'id' characters + # replace with as few -'s as possible. + $string =~ s/[ "',)(_-]+/-/g; + + # Don't want a - at the end either. It looks silly. + $string =~ s/-$//g; + + return ($string); +} + +##### +# lower +# LowerCase the string +sub lower($) { + my $string = shift; + + $string =~ tr/A-Z/a-z/; + + return ($string); +} + +##### +# useUnits +# Tack on base 2 metric units +sub useUnits($) { + my ($value) = @_; + + return '' if ( !defined($value) ); + + my @units = ( 'Bytes', 'KiBytes', 'MiBytes', 'GiBytes', 'TiBytes' ); + my $loop = 0; + + while ( $value >= 1024 ) { + $loop++; + + $value = $value / 1024; + } + + return ( sprintf( "%.2f %s", $value, $units[$loop] ) ); +} + +##### +# docbook +# Docbook output is special in that we may or may not want to escape +# the characters inside the string depending on a string prefix. +sub docbook($) { + my $string = shift; + + if ( defined($string) ) { + if ( $string =~ /^\@DOCBOOK/ ) { + $string =~ s/^\@DOCBOOK//; + } + else { + $string =~ s/&(?!(amp|lt|gr|apos|quot);)/&/g; + $string =~ s//>/g; + $string =~ s/'/'/g; + $string =~ s/"/"/g; + } + } + else { + + # Return an empty string when all else fails + $string = ''; + } + + return ($string); +} + +##### +# graphviz +# GraphViz output requires that special characters (like " and whitespace) must be preceeded +# by a \ when a part of a lable. +sub graphviz($) { + my $string = shift; + + # Ensure we don't return an least a empty string + $string = '' if ( !defined($string) ); + + $string =~ s/([\s"'])/\\$1/g; + + return ($string); +} + +##### +# sql_prettyprint +# Clean up SQL into something presentable +sub sql_prettyprint($) { + my $string = shift; + + # If nothing has been sent in, return an empty string + if ( !defined($string) ) { + return ''; + } + + # Initialize Result string + my $result = ''; + + # List of tokens to split on + my $tok = + "SELECT|FROM|WHERE|HAVING|GROUP BY|ORDER BY|OR|AND|LEFT JOIN|RIGHT JOIN" + . "|LEFT OUTER JOIN|LEFT INNER JOIN|INNER JOIN|RIGHT OUTER JOIN|RIGHT INNER JOIN" + . "|JOIN|UNION ALL|UNION|EXCEPT|USING|ON|CAST|[\(\),]"; + + my $key = 0; + my $bracket = 0; + my $depth = 0; + my $indent = 6; + + # XXX: Split is wrong -- match would do + foreach my $elem ( split( /(\"[^\"]*\"|'[^']*'|$tok)/, $string ) ) { + my $format; + + # Skip junk tokens + if ( $elem =~ /^[\s]?$/ ) { + next; + } + + # NOTE: Should we drop leading spaces? + # $elem =~ s/^\s//; + + # Close brackets are special + # Bring depth in a level + if ( $elem =~ /\)/ ) { + $depth = $depth - $indent; + if ( $key == 1 or $bracket == 1 ) { + $format = "%s%s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + + $key = 0; + $bracket = 0; + } + + # Open brackets are special + # Bump depth out a level + elsif ( $elem =~ /\(/ ) { + if ( $key == 1 ) { + $format = "%s %s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + $depth = $depth + $indent; + $bracket = 1; + $key = 0; + } + + # Key element + # Token from our list -- format on left hand side of the equation + # when appropriate. + elsif ( $elem =~ /$tok/ ) { + if ( $key == 1 ) { + $format = "%s%s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + + $key = 1; + $bracket = 0; + } + + # Value + # Format for right hand side of the equation + else { + $format = "%s%s"; + + $key = 0; + } + + # Add the new format string to the result + $result = sprintf( $format, $result, $elem ); + } + + return $result; +} ## end sub sql_prettyprint($) + +## +# triggerError +# Print out a supplied error message and exit the script. +sub triggerError($) { + my ($error) = @_; + + # Test error + if ( !defined($error) || $error eq '' ) { + + # Suppress prototype checking in call to self + &triggerError("triggerError: Unknown error"); + } + printf( "\n\n%s\n", $error ); + + exit 2; +} + +##### +# usage +sub usage($$$) { + my ( $basename, $database, $dbuser ) = @_; + print < Specify database name to connect to (default: $database) + -f Specify output file prefix (default: $database) + -h Specify database server host (default: localhost) + -p Specify database server port (default: 5432) + -u Specify database username (default: $dbuser) + --password= Specify database password (default: blank) + --password Have $basename prompt for a password + + -l Path to the templates (default: /usr/local/share/postgresql_autodoc) + -t Type of output wanted (default: All in template library) + + -s Specify a specific schema to match. Technically this is a regular + expression but anything other than a specific name may have unusual + results. + --table= Tables to export. Multiple tables may be provided using a + comma-separated list. + + --statistics In 7.4 and later, with the contrib module pgstattuple installed we + can gather statistics on the tables in the database + (average size, free space, disk space used, dead tuple counts, etc.) + This is disk intensive on large databases as all pages must be visited. +USAGE + ; + exit 1; +} + +sub single_quote { + my $attr = $_; + $attr =~ s/^\s+|\s+$//g; + return qq{'$attr'}; +} + +## +# Kick off execution of main() +main($ARGV); + diff --git a/postgresql_autodoc/postgresql_autodoc.pl b/postgresql_autodoc/postgresql_autodoc.pl new file mode 100755 index 0000000..fa8ac96 --- /dev/null +++ b/postgresql_autodoc/postgresql_autodoc.pl @@ -0,0 +1,1907 @@ +#!/usr/bin/env perl +# -- # -*- Perl -*-w +# $Header: /cvsroot/autodoc/autodoc/postgresql_autodoc.pl,v 1.21 2008/03/12 19:00:56 rbt Exp $ +# Imported 1.22 2002/02/08 17:09:48 into sourceforge + +# Postgres Auto-Doc Version 1.31 + +# License +# ------- +# Copyright (c) 2001-2007, Rod Taylor +# 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. Neither the name of the InQuent Technologies Inc. nor the names +# of its contributors may be used to endorse or promote products +# derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD +# PROJECT 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. + +# About Project +# ------------- +# Various details about the project and related items can be found at +# the website +# +# http://www.rbt.ca/autodoc/ + +use strict; +use warnings; + +use DBI; +use Fcntl; + +# Allows file templates +use HTML::Template; + +# Allow reading a password from stdin +use Term::ReadKey; + +sub main($) { + my ($ARGV) = @_; + + my %db; + + # The templates path + # @@TEMPLATE-DIR@@ will be replaced by make in the build phase + my $template_path = '@@TEMPLATE-DIR@@'; + + # Setup the default connection variables based on the environment + my $dbuser = $ENV{'PGUSER'}; + $dbuser ||= $ENV{'USER'}; + + my $database = $ENV{'PGDATABASE'}; + $database ||= $dbuser; + + my $dbhost = $ENV{'PGHOST'}; + $dbhost ||= ""; + + my $dbport = $ENV{'PGPORT'}; + $dbport ||= ""; + + # Determine whether we need a password to connect + my $needpass = 0; + + my $dbpass = ""; + my $output_filename_base = $database; + + # Tracking variables + my $dbisset = 0; + my $fileisset = 0; + + my $only_schema; + + my $table_out; + + my $wanted_output = undef; # means all types + + my $statistics = 0; + + # Fetch base and dirnames. Useful for Usage() + my $basename = $0; + my $dirname = $0; + $basename =~ s|^.*/([^/]+)$|$1|; + $dirname =~ s|^(.*)/[^/]+$|$1|; + + # If template_path isn't defined, lets set it ourselves + $template_path = $dirname if ( !defined($template_path) ); + + for ( my $i = 0 ; $i <= $#ARGV ; $i++ ) { + ARGPARSE: for ( $ARGV[$i] ) { + + # Set the database + /^-d$/ && do { + $database = $ARGV[ ++$i ]; + $dbisset = 1; + if ( !$fileisset ) { + $output_filename_base = $database; + } + last; + }; + + # Set the user + /^-[uU]$/ && do { + $dbuser = $ARGV[ ++$i ]; + if ( !$dbisset ) { + $database = $dbuser; + if ( !$fileisset ) { + $output_filename_base = $database; + } + } + last; + }; + + # Set the hostname + /^-h$/ && do { $dbhost = $ARGV[ ++$i ]; last; }; + + # Set the Port + /^-p$/ && do { $dbport = $ARGV[ ++$i ]; last; }; + + # Set the users password + /^--password=/ && do { + $dbpass = $ARGV[$i]; + $dbpass =~ s/^--password=//g; + last; + }; + + # Make sure we get a password before attempting to conenct + /^--password$/ && do { + $needpass = 1; + last; + }; + + # Set the base of the filename. The extensions pulled + # from the templates will be appended to this name + /^-f$/ && do { + $output_filename_base = $ARGV[ ++$i ]; + $fileisset = 1; + last; + }; + + # Set the template directory explicitly + /^(-l|--library)$/ && do { + $template_path = $ARGV[ ++$i ]; + last; + }; + + # Set the output type + /^(-t|--type)$/ && do { + $wanted_output = $ARGV[ ++$i ]; + last; + }; + + # User has requested a single schema dump and provided a pattern + /^(-s|--schema)$/ && do { + $only_schema = $ARGV[ ++$i ]; + last; + }; + + # One might dump a table's set (comma-separated) or just one + # If dumping a set of specific tables do NOT dump out the functions + # in this database. Generates noise in the output + # that most likely isn't wanted. Check for $table_out around the + # function gathering location. + /^--table=/ && do { + my $some_table = $ARGV[$i]; + $some_table =~ s/^--table=//g; + + my @tables_in = split( ',', $some_table ); + sub single_quote; + $table_out = join( ',', map( single_quote, @tables_in ) ); + + last; + }; + + # Check to see if Statistics have been requested + /^--statistics$/ && do { + $statistics = 1; + last; + }; + + # Help is wanted, redirect user to usage() + /^-\?$/ && do { usage( $basename, $database, $dbuser ); last; }; + /^--help$/ && do { usage( $basename, $database, $dbuser ); last; }; + } + } + + # If no arguments have been provided, connect to the database anyway but + # inform the user of what we're doing. + if ( $#ARGV <= 0 ) { + print <connect( @{$dbConnect} ) + or triggerError("Unable to connect due to: $DBI::errstr"); + + $dbh->do("set client_encoding to 'UTF-8'") + or triggerError("could not set client_encoding to UTF-8: $DBI::errstr"); + + my %struct; + $db->{$database}{'STRUCT'} = \%struct; + my $struct = $db->{$database}{'STRUCT'}; + + # PostgreSQL's version is used to determine what queries are required + # to retrieve a given information set. + if ( $dbh->{pg_server_version} < 70300 ) { + die("PostgreSQL 7.3 and later are supported"); + } + + # Ensure we only retrieve information for the requested schemas. + # + # system_schema -> The primary system schema for a database. + # Public is used for verions prior to 7.3 + # + # system_schema_list -> The list of schemas which we are not supposed + # to gather information for. + # TODO: Merge with system_schema in array form. + # + # schemapattern -> The schema the user provided as a command + # line option. + my $schemapattern = '^'; + my $system_schema = 'pg_catalog'; + my $system_schema_list = + 'pg_catalog|pg_toast|pg_temp_[0-9]+|information_schema'; + if ( defined($only_schema) ) { + $schemapattern = '^' . $only_schema . '$'; + } + + # + # List of queries which are used to gather information from the + # database. The queries differ based on version but should + # provide similar output. At some point it should be safe to remove + # support for older database versions. + # + + # Fetch the description of the database + my $sql_Database = q{ + SELECT pg_catalog.obj_description(oid, 'pg_database') as comment + FROM pg_catalog.pg_database + WHERE datname = '$database'; + }; + + # Pull out a list of tables, views and special structures. + my $sql_Tables = qq{ + SELECT nspname as namespace + , relname as tablename + , pg_catalog.pg_get_userbyid(relowner) AS tableowner + , relhasindex as hasindexes + , relhasrules as hasrules + , reltriggers as hastriggers + , pg_class.oid + , pg_catalog.obj_description(pg_class.oid, 'pg_class') as table_description + , relacl + , CASE + WHEN relkind = 'r' THEN + 'table' + WHEN relkind = 's' THEN + 'special' + ELSE + 'view' + END as reltype + , CASE + WHEN relkind = 'v' THEN + pg_get_viewdef(pg_class.oid) + ELSE + NULL + END as view_definition + FROM pg_catalog.pg_class + JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid) + WHERE relkind IN ('r', 's', 'v') + AND nspname !~ '$system_schema_list' + AND nspname ~ '$schemapattern' + }; + $sql_Tables .= qq{ AND relname IN ($table_out)} if defined($table_out); + + # - uses pg_class.oid + my $sql_Columns = q{ + SELECT attname as column_name + , attlen as column_length + , CASE + WHEN pg_type.typname = 'int4' + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + 'serial' + WHEN pg_type.typname = 'int8' + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + 'bigserial' + ELSE + pg_catalog.format_type(atttypid, atttypmod) + END as column_type + , CASE + WHEN attnotnull THEN + cast('NOT NULL' as text) + ELSE + cast('' as text) + END as column_null + , CASE + WHEN pg_type.typname IN ('int4', 'int8') + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + NULL + ELSE + adsrc + END as column_default + , pg_catalog.col_description(attrelid, attnum) as column_description + , attnum + FROM pg_catalog.pg_attribute + JOIN pg_catalog.pg_type ON (pg_type.oid = atttypid) + LEFT JOIN pg_catalog.pg_attrdef ON ( attrelid = adrelid + AND attnum = adnum) + WHERE attnum > 0 + AND attisdropped IS FALSE + AND attrelid = ?; + }; + + my $sql_Table_Statistics; + if ( $statistics == 1 ) { + if ( $dbh->{pg_server_version} <= 70300 ) { + triggerError( + "Table statistics supported on PostgreSQL 7.4 and later.\n" + . "Remove --statistics flag and try again." ); + } + + $sql_Table_Statistics = q{ + SELECT table_len + , tuple_count + , tuple_len + , CAST(tuple_percent AS numeric(20,2)) AS tuple_percent + , dead_tuple_count + , dead_tuple_len + , CAST(dead_tuple_percent AS numeric(20,2)) AS dead_tuple_percent + , CAST(free_space AS numeric(20,2)) AS free_space + , CAST(free_percent AS numeric(20,2)) AS free_percent + FROM pgstattuple(CAST(? AS oid)); + }; + } + + my $sql_Indexes = q{ + SELECT schemaname + , tablename + , indexname + , substring( indexdef + FROM position('(' IN indexdef) + 1 + FOR length(indexdef) - position('(' IN indexdef) - 1 + ) AS indexdef + FROM pg_catalog.pg_indexes + WHERE substring(indexdef FROM 8 FOR 6) != 'UNIQUE' + AND schemaname = ? + AND tablename = ?; + }; + + my $sql_Inheritance = qq{ + SELECT parnsp.nspname AS par_schemaname + , parcla.relname AS par_tablename + , chlnsp.nspname AS chl_schemaname + , chlcla.relname AS chl_tablename + FROM pg_catalog.pg_inherits + JOIN pg_catalog.pg_class AS chlcla ON (chlcla.oid = inhrelid) + JOIN pg_catalog.pg_namespace AS chlnsp ON (chlnsp.oid = chlcla.relnamespace) + JOIN pg_catalog.pg_class AS parcla ON (parcla.oid = inhparent) + JOIN pg_catalog.pg_namespace AS parnsp ON (parnsp.oid = parcla.relnamespace) + WHERE chlnsp.nspname = ? + AND chlcla.relname = ? + AND chlnsp.nspname ~ '$schemapattern' + AND parnsp.nspname ~ '$schemapattern'; + }; + + # Fetch the list of PRIMARY and UNIQUE keys + my $sql_Primary_Keys = q{ + SELECT conname AS constraint_name + , pg_catalog.pg_get_indexdef(d.objid) AS constraint_definition + , CASE + WHEN contype = 'p' THEN + 'PRIMARY KEY' + ELSE + 'UNIQUE' + END as constraint_type + FROM pg_catalog.pg_constraint AS c + JOIN pg_catalog.pg_depend AS d ON (d.refobjid = c.oid) + WHERE contype IN ('p', 'u') + AND deptype = 'i' + AND conrelid = ?; + }; + + # FOREIGN KEY fetch + # + # Don't return the constraint name if it was automatically generated by + # PostgreSQL. The $N (where N is an integer) is not a descriptive enough + # piece of information to be worth while including in the various outputs. + my $sql_Foreign_Keys = qq{ + SELECT pg_constraint.oid + , pg_namespace.nspname AS namespace + , CASE WHEN substring(pg_constraint.conname FROM 1 FOR 1) = '\$' THEN '' + ELSE pg_constraint.conname + END AS constraint_name + , conkey AS constraint_key + , confkey AS constraint_fkey + , confrelid AS foreignrelid + FROM pg_catalog.pg_constraint + JOIN pg_catalog.pg_class ON (pg_class.oid = conrelid) + JOIN pg_catalog.pg_class AS pc ON (pc.oid = confrelid) + JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid) + JOIN pg_catalog.pg_namespace AS pn ON (pn.oid = pc.relnamespace) + WHERE contype = 'f' + AND conrelid = ? + AND pg_namespace.nspname ~ '$schemapattern' + AND pn.nspname ~ '$schemapattern'; + }; + + my $sql_Foreign_Key_Arg = q{ + SELECT attname AS attribute_name + , relname AS relation_name + , nspname AS namespace + FROM pg_catalog.pg_attribute + JOIN pg_catalog.pg_class ON (pg_class.oid = attrelid) + JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid) + WHERE attrelid = ? + AND attnum = ?; + }; + + # Fetch CHECK constraints + my $sql_Constraint; + if ( $dbh->{pg_server_version} >= 70400 ) { + $sql_Constraint = q{ + SELECT pg_get_constraintdef(oid) AS constraint_source + , conname AS constraint_name + FROM pg_constraint + WHERE conrelid = ? + AND contype = 'c'; + }; + } + else { + $sql_Constraint = q{ + SELECT 'CHECK ' || pg_catalog.substr(consrc, 2, length(consrc) - 2) AS constraint_source + , conname AS constraint_name + FROM pg_constraint + WHERE conrelid = ? + AND contype = 'c'; + }; + } + + # Query for function information + my $sql_Function; + my $sql_FunctionArg; + if ( $dbh->{pg_server_version} >= 80000 ) { + $sql_Function = qq{ + SELECT proname AS function_name + , nspname AS namespace + , lanname AS language_name + , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment + , proargtypes AS function_args + , proargnames AS function_arg_names + , prosrc AS source_code + , proretset AS returns_set + , prorettype AS return_type + FROM pg_catalog.pg_proc + JOIN pg_catalog.pg_language ON (pg_language.oid = prolang) + JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid) + JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid) + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern' + AND proname != 'plpgsql_call_handler'; + }; + + $sql_FunctionArg = q{ + SELECT nspname AS namespace + , replace(pg_catalog.format_type(pg_type.oid, typtypmod) + , nspname ||'.' + , '') AS type_name + FROM pg_catalog.pg_type + JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace) + WHERE pg_type.oid = ?; + }; + } + else { + $sql_Function = qq{ + SELECT proname AS function_name + , nspname AS namespace + , lanname AS language_name + , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment + , proargtypes AS function_args + , NULL AS function_arg_names + , prosrc AS source_code + , proretset AS returns_set + , prorettype AS return_type + FROM pg_catalog.pg_proc + JOIN pg_catalog.pg_language ON (pg_language.oid = prolang) + JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid) + JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid) + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern' + AND proname != 'plpgsql_call_handler'; + }; + + $sql_FunctionArg = q{ + SELECT nspname AS namespace + , replace(pg_catalog.format_type(pg_type.oid, typtypmod) + , nspname ||'.' + , '') AS type_name + FROM pg_catalog.pg_type + JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace) + WHERE pg_type.oid = ?; + }; + } + + # Fetch schema information. + my $sql_Schema = qq{ + SELECT pg_catalog.obj_description(oid, 'pg_namespace') AS comment + , nspname as namespace + FROM pg_catalog.pg_namespace + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern'; + }; + + my $sth_Columns = $dbh->prepare($sql_Columns); + my $sth_Constraint = $dbh->prepare($sql_Constraint); + my $sth_Database = $dbh->prepare($sql_Database); + my $sth_Foreign_Keys = $dbh->prepare($sql_Foreign_Keys); + my $sth_Foreign_Key_Arg = $dbh->prepare($sql_Foreign_Key_Arg); + my $sth_Function = $dbh->prepare($sql_Function); + my $sth_FunctionArg = $dbh->prepare($sql_FunctionArg); + my $sth_Indexes = $dbh->prepare($sql_Indexes); + my $sth_Inheritance = $dbh->prepare($sql_Inheritance); + my $sth_Primary_Keys = $dbh->prepare($sql_Primary_Keys); + my $sth_Schema = $dbh->prepare($sql_Schema); + my $sth_Tables = $dbh->prepare($sql_Tables); + my $sth_Table_Statistics = $dbh->prepare($sql_Table_Statistics) + if ( $statistics == 1 ); + + # Fetch Database info + $sth_Database->execute(); + my $dbinfo = $sth_Database->fetchrow_hashref; + if ( defined($dbinfo) ) { + $db->{$database}{'COMMENT'} = $dbinfo->{'comment'}; + } + + # Fetch tables and all things bound to tables + $sth_Tables->execute(); + while ( my $tables = $sth_Tables->fetchrow_hashref ) { + my $reloid = $tables->{'oid'}; + my $relname = $tables->{'tablename'}; + + my $schema = $tables->{'namespace'}; + + EXPRESSIONFOUND: + + # Store permissions + my $acl = $tables->{'relacl'}; + + # Empty acl groups cause serious issues. + $acl ||= ''; + + # Strip array forming 'junk'. + $acl =~ s/^{//g; + $acl =~ s/}$//g; + $acl =~ s/"//g; + + # Foreach acl + foreach ( split( /\,/, $acl ) ) { + my ( $user, $raw_permissions ) = split( /=/, $_ ); + + if ( defined($raw_permissions) ) { + if ( $user eq '' ) { + $user = 'PUBLIC'; + } + + # The section after the / is the user who granted the permissions + my ( $permissions, $granting_user ) = + split( /\//, $raw_permissions ); + + # Break down permissions to individual flags + if ( $permissions =~ /a/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'INSERT'} = 1; + } + + if ( $permissions =~ /r/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'SELECT'} = 1; + } + + if ( $permissions =~ /w/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'UPDATE'} = 1; + } + + if ( $permissions =~ /d/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'DELETE'} = 1; + } + + if ( $permissions =~ /R/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'RULE'} = 1; + } + + if ( $permissions =~ /x/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'REFERENCES'} = 1; + } + + if ( $permissions =~ /t/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'TRIGGER'} = 1; + } + } + } + + # Primitive Stats, but only if requested + if ( $statistics == 1 and $tables->{'reltype'} eq 'table' ) { + $sth_Table_Statistics->execute($reloid); + + my $stats = $sth_Table_Statistics->fetchrow_hashref; + + $struct->{$schema}{'TABLE'}{$relname}{'TABLELEN'} = + $stats->{'table_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'TUPLECOUNT'} = + $stats->{'tuple_count'}; + $struct->{$schema}{'TABLE'}{$relname}{'TUPLELEN'} = + $stats->{'tuple_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'DEADTUPLELEN'} = + $stats->{'dead_tuple_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'FREELEN'} = + $stats->{'free_space'}; + } + + # Store the relation type + $struct->{$schema}{'TABLE'}{$relname}{'TYPE'} = $tables->{'reltype'}; + + # Store table description + $struct->{$schema}{'TABLE'}{$relname}{'DESCRIPTION'} = + $tables->{'table_description'}; + + # Store the view definition + $struct->{$schema}{'TABLE'}{$relname}{'VIEW_DEF'} = + $tables->{'view_definition'}; + + # Store constraints + $sth_Constraint->execute($reloid); + while ( my $cols = $sth_Constraint->fetchrow_hashref ) { + my $constraint_name = $cols->{'constraint_name'}; + $struct->{$schema}{'TABLE'}{$relname}{'CONSTRAINT'} + {$constraint_name} = $cols->{'constraint_source'}; + } + + $sth_Columns->execute($reloid); + my $i = 1; + while ( my $cols = $sth_Columns->fetchrow_hashref ) { + my $column_name = $cols->{'column_name'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'ORDER'} = $cols->{'attnum'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'PRIMARY KEY'} = 0; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'FKTABLE'} = ''; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'TYPE'} = $cols->{'column_type'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'NULL'} = $cols->{'column_null'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'DESCRIPTION'} = $cols->{'column_description'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'DEFAULT'} = $cols->{'column_default'}; + } + + # Pull out both PRIMARY and UNIQUE keys based on the supplied query + # and the relation OID. + # + # Since there may be multiple UNIQUE indexes on a table, we append a + # number to the end of the the UNIQUE keyword which shows that they + # are a part of a related definition. I.e UNIQUE_1 goes with UNIQUE_1 + # + $sth_Primary_Keys->execute($reloid); + my $unqgroup = 0; + while ( my $pricols = $sth_Primary_Keys->fetchrow_hashref ) { + my $index_type = $pricols->{'constraint_type'}; + my $con = $pricols->{'constraint_name'}; + my $indexdef = $pricols->{'constraint_definition'}; + + # Fetch the column list + my $column_list = $indexdef; + $column_list =~ s/.*\(([^)]+)\).*/$1/g; + + # Split our column list and deal with all PRIMARY KEY fields + my @collist = split( ',', $column_list ); + + # Store the column number in the indextype field. Anything > 0 + # indicates the column has this type of constraint applied to it. + my $column; + my $currentcol = $#collist + 1; + my $numcols = $#collist + 1; + + # Bump group number if there are two or more columns + if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) { + $unqgroup++; + } + + # Record the data to the structure. + while ( $column = pop(@collist) ) { + $column =~ s/\s$//; + $column =~ s/^\s//; + $column =~ s/^"//; + $column =~ s/"$//; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'TYPE'} = $index_type; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'COLNUM'} = $currentcol--; + + # Record group number only when a multi-column + # constraint is involved + if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'} = $unqgroup; + } + } + } + + # FOREIGN KEYS like UNIQUE indexes can appear several times in + # a table in multi-column format. We use the same trick to + # record a numeric association to the foreign key reference. + $sth_Foreign_Keys->execute($reloid); + my $fkgroup = 0; + while ( my $forcols = $sth_Foreign_Keys->fetchrow_hashref ) { + my $column_oid = $forcols->{'oid'}; + my $con = $forcols->{'constraint_name'}; + + # Declare variables for dataload + my @keylist; + my @fkeylist; + my $fschema; + my $ftable; + + my $fkey = $forcols->{'constraint_fkey'}; + my $keys = $forcols->{'constraint_key'}; + my $frelid = $forcols->{'foreignrelid'}; + + # Since decent array support was not added until 7.4, and + # we want to support 7.3 as well, we parse the text version + # of the array by hand rather than combining this and + # Foreign_Key_Arg query into a single query. + + my @fkeyset; + if ( ref $fkey eq 'ARRAY' ) { + @fkeyset = @{$fkey}; + } + else { # DEPRECATED: DBD::Pg 1.49 and earlier + $fkey =~ s/^{//g; + $fkey =~ s/}$//g; + $fkey =~ s/"//g; + @fkeyset = split( /,/, $fkey ); + } + + my @keyset; + if ( ref $keys eq 'ARRAY' ) { + @keyset = @{$keys}; + } + else { # DEPRECATED: DBD::Pg 1.49 and earlier + $keys =~ s/^{//g; + $keys =~ s/}$//g; + $keys =~ s/"//g; + @keyset = split( /,/, $keys ); + } + + # Convert the list of column numbers into column names for the + # local side. + foreach my $k (@keyset) { + $sth_Foreign_Key_Arg->execute( $reloid, $k ); + + my $row = $sth_Foreign_Key_Arg->fetchrow_hashref; + + push( @keylist, $row->{'attribute_name'} ); + } + + # Convert the list of columns numbers into column names + # for the referenced side. Grab the table and namespace + # while we're here. + foreach my $k (@fkeyset) { + $sth_Foreign_Key_Arg->execute( $frelid, $k ); + + my $row = $sth_Foreign_Key_Arg->fetchrow_hashref; + + push( @fkeylist, $row->{'attribute_name'} ); + $fschema = $row->{'namespace'}; + $ftable = $row->{'relation_name'}; + } + + # Deal with common catalog issues. + die "FKEY $con Broken -- fix your PostgreSQL installation" + if $#keylist != $#fkeylist; + + # Load up the array based on the information discovered + # using the information retrieval methods above. + my $numcols = $#keylist + 1; + my $currentcol = $#keylist + 1; + + # Bump group number if there are two or more columns involved + if ( $numcols >= 2 ) { + $fkgroup++; + } + + # Record the foreign key to structure + while ( my $column = pop(@keylist) + and my $fkey = pop(@fkeylist) ) + { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'TYPE'} = 'FOREIGN KEY'; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'COLNUM'} = $currentcol--; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FKTABLE'} = $ftable; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FKSCHEMA'} = $fschema; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FK-COL NAME'} = $fkey; + + # Record group number only when a multi-column + # constraint is involved + if ( $numcols >= 2 ) { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'} = $fkgroup; + } + } + } + + # Pull out index information + $sth_Indexes->execute( $schema, $relname ); + while ( my $idx = $sth_Indexes->fetchrow_hashref ) { + $struct->{$schema}{'TABLE'}{$relname}{'INDEX'} + { $idx->{'indexname'} } = $idx->{'indexdef'}; + } + + # Extract Inheritance information + $sth_Inheritance->execute( $schema, $relname ); + while ( my $inherit = $sth_Inheritance->fetchrow_hashref ) { + my $parSch = $inherit->{'par_schemaname'}; + my $parTab = $inherit->{'par_tablename'}; + $struct->{$schema}{'TABLE'}{$relname}{'INHERIT'}{$parSch}{$parTab} = + 1; + } + } + + # Function Handling + $sth_Function->execute(); + while ( my $functions = $sth_Function->fetchrow_hashref and not $table_out ) + { + my $functionname = $functions->{'function_name'} . '( '; + my $schema = $functions->{'namespace'}; + my $comment = $functions->{'comment'}; + my $functionargs = $functions->{'function_args'}; + my @types = split( ' ', $functionargs ); + my $count = 0; + + # Pre-setup argument names when available. + my $argnames = $functions->{'function_arg_names'}; + my @names; + + if ( defined($argnames) ) { + $argnames =~ s/{(.*)}/$1/; + @names = split( ',', $argnames ); + } + + # Setup full argument types -- including the name prefix + foreach my $type (@types) { + $sth_FunctionArg->execute($type); + + my $hash = $sth_FunctionArg->fetchrow_hashref; + + if ( $count > 0 ) { + $functionname .= ', '; + } + + if ( scalar(@names) > 0 ) { + $functionname .= $names[$count] . ' '; + } + + if ( $hash->{'namespace'} ne $system_schema ) { + $functionname .= $hash->{'namespace'} . '.'; + } + $functionname .= $hash->{'type_name'}; + + $count++; + } + $functionname .= ' )'; + + my $ret_type = $functions->{'returns_set'} ? 'SET OF ' : ''; + $sth_FunctionArg->execute( $functions->{'return_type'} ); + my $rhash = $sth_FunctionArg->fetchrow_hashref; + $ret_type .= $rhash->{'type_name'}; + + $struct->{$schema}{'FUNCTION'}{$functionname}{'COMMENT'} = $comment; + $struct->{$schema}{'FUNCTION'}{$functionname}{'SOURCE'} = + $functions->{'source_code'}; + $struct->{$schema}{'FUNCTION'}{$functionname}{'LANGUAGE'} = + $functions->{'language_name'}; + $struct->{$schema}{'FUNCTION'}{$functionname}{'RETURNS'} = $ret_type; + } + + # Deal with the Schema + $sth_Schema->execute(); + while ( my $schema = $sth_Schema->fetchrow_hashref ) { + my $comment = $schema->{'comment'}; + my $namespace = $schema->{'namespace'}; + + $struct->{$namespace}{'SCHEMA'}{'COMMENT'} = $comment; + } + + $sth_Columns->finish(); + $sth_Constraint->finish(); + $sth_Database->finish(); + $sth_Foreign_Keys->finish(); + $sth_Foreign_Key_Arg->finish(); + $sth_Function->finish(); + $sth_FunctionArg->finish(); + $sth_Indexes->finish(); + $sth_Inheritance->finish(); + $sth_Primary_Keys->finish(); + $sth_Schema->finish(); + $sth_Tables->finish(); + $sth_Table_Statistics->finish() + if ( $statistics == 1 ); + + $dbh->disconnect; + +} ## end sub info_collect($$$$$) + +##### +# write_using_templates +# +# Generate structure that HTML::Template requires out of the +# $struct for table related information, and $struct for +# the schema and function information +sub write_using_templates($$$$$) { + my ( $db, $database, $statistics, $template_path, $output_filename_base, + $wanted_output ) + = @_; + my $struct = $db->{$database}{'STRUCT'}; + + my @schemas; + + # Start at 0, increment to 1 prior to use. + my $object_id = 0; + my %tableids; + foreach my $schema ( sort keys %{$struct} ) { + my @tables; + foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) { + + # Column List + my @columns; + foreach my $column ( + sort { + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a} + {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table} + {'COLUMN'}{$b}{'ORDER'} + } keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} } + ) + { + my $inferrednotnull = 0; + + # Have a shorter default for places that require it + my $shortdefault = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'}; + $shortdefault =~ s/^(.{17}).{5,}(.{5})$/$1 ... $2/g + if ( defined($shortdefault) ); + + # Deal with column constraints + my @colconstraints; + foreach my $con ( + sort keys %{ + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'} + } + ) + { + if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'UNIQUE' ) + { + my $unq = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'}; + my $unqcol = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'COLNUM'}; + my $unqgroup = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'}; + + push @colconstraints, + { + column_unique => $unq, + column_unique_colnum => $unqcol, + column_unique_keygroup => $unqgroup, + }; + } + elsif ( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'PRIMARY KEY' ) + { + $inferrednotnull = 1; + push @colconstraints, + { column_primary_key => 'PRIMARY KEY', }; + } + elsif ( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' ) + { + my $fksgmlid = sgml_safe_id( + join( '.', + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'FKSCHEMA'}, + $struct->{$schema}{'TABLE'}{$table}{'TYPE'}, + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'FKTABLE'} ) + ); + + my $fkgroup = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'}; + my $fktable = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKTABLE'}; + my $fkcol = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FK-COL NAME'}; + my $fkschema = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKSCHEMA'}; + + push @colconstraints, + { + column_fk => 'FOREIGN KEY', + column_fk_colnum => $fkcol, + column_fk_keygroup => $fkgroup, + column_fk_schema => $fkschema, + column_fk_schema_dbk => docbook($fkschema), + column_fk_schema_dot => graphviz($fkschema), + column_fk_sgmlid => $fksgmlid, + column_fk_table => $fktable, + column_fk_table_dbk => docbook($fktable), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $colconstraints[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + } + } + + # Generate the Column array + push @columns, { + column => $column, + column_dbk => docbook($column), + column_dot => graphviz($column), + column_default => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'}, + column_default_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'} + ), + column_default_short => $shortdefault, + column_default_short_dbk => docbook($shortdefault), + + column_comment => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DESCRIPTION'}, + column_comment_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DESCRIPTION'} + ), + + column_number => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'ORDER'}, + + column_type => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'}, + column_type_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'} + ), + column_type_dot => graphviz( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'} + ), + + column_constraints => \@colconstraints, + }; + + if ( $inferrednotnull == 0 ) { + $columns[-1]{"column_constraint_notnull"} = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'NULL'}; + } + } + + # Constraint List + my @constraints; + foreach my $constraint ( + sort + keys %{ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} } + ) + { + my $shortcon = + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint}; + $shortcon =~ s/^(.{30}).{5,}(.{5})$/$1 ... $2/g; + push @constraints, + { + constraint => + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint}, + constraint_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint} + ), + constraint_name => $constraint, + constraint_name_dbk => docbook($constraint), + constraint_short => $shortcon, + constraint_short_dbk => docbook($shortcon), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + }; + } + + # Index List + my @indexes; + foreach my $index ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INDEX'} } ) + { + push @indexes, + { + index_definition => + $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index}, + index_definition_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index} + ), + index_name => $index, + index_name_dbk => docbook($index), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + }; + } + + my @inherits; + foreach my $inhSch ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'} } ) + { + foreach my $inhTab ( + sort keys + %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'}{$inhSch} } + ) + { + push @inherits, + { + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + sgmlid => + sgml_safe_id( join( '.', $schema, 'table', $table ) ), + parent_sgmlid => sgml_safe_id( + join( '.', $inhSch, 'table', $inhTab ) + ), + parent_table => $inhTab, + parent_table_dbk => docbook($inhTab), + parent_table_dot => graphviz($inhTab), + parent_schema => $inhSch, + parent_schema_dbk => docbook($inhSch), + parent_schema_dot => graphviz($inhSch), + }; + } + } + + # Foreign Key Discovery + # + # $lastmatch is used to ensure that we only supply a result a + # single time and not once for each link found. Since the + # loops are sorted, we only need to track the last element, and + # not all supplied elements. + my @fk_schemas; + my $lastmatch = ''; + foreach my $fk_schema ( sort keys %{$struct} ) { + foreach + my $fk_table ( sort keys %{ $struct->{$fk_schema}{'TABLE'} } ) + { + foreach my $fk_column ( + sort keys + %{ $struct->{$fk_schema}{'TABLE'}{$fk_table}{'COLUMN'} } + ) + { + foreach my $fk_con ( + sort keys %{ + $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'} + } + ) + { + if ( $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con}{'TYPE'} + eq 'FOREIGN KEY' + and $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con} + {'FKTABLE'} eq $table + and $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con} + {'FKSCHEMA'} eq $schema + and $lastmatch ne "$fk_schema$fk_table" ) + { + my $fksgmlid = sgml_safe_id( + join( '.', + $fk_schema, + $struct->{$fk_schema}{'TABLE'} + {$fk_table}{'TYPE'}, + $fk_table ) + ); + push @fk_schemas, + { + fk_column_number => + $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'ORDER'}, + fk_sgmlid => $fksgmlid, + fk_schema => $fk_schema, + fk_schema_dbk => docbook($fk_schema), + fk_schema_dot => graphviz($fk_schema), + fk_table => $fk_table, + fk_table_dbk => docbook($fk_table), + fk_table_dot => graphviz($fk_table), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $fk_schemas[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + + $lastmatch = "$fk_schema$fk_table"; + } + } + } + } + } + + # List off permissions + my @permissions; + foreach my $user ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'} } ) + { + push @permissions, + { + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + user => $user, + user_dbk => docbook($user), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $permissions[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + + foreach my $perm ( + keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} } + ) + { + if ( $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} + {$perm} == 1 ) + { + $permissions[-1]{ lower($perm) } = 1; + } + } + + } + + # Increment and record the object ID + $tableids{"$schema$table"} = ++$object_id; + my $viewdef = sql_prettyprint( + $struct->{$schema}{'TABLE'}{$table}{'VIEW_DEF'} ); + + # Truncate comment for Dia + my $comment_dia = + $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'}; + $comment_dia =~ s/^(.{35}).{5,}(.{5})$/$1 ... $2/g + if ( defined($comment_dia) ); + + push @tables, { + object_id => $object_id, + object_id_dbk => docbook($object_id), + + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + + # Statistics + stats_enabled => $statistics, + stats_dead_bytes => useUnits( + $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'} + ), + stats_dead_bytes_dbk => docbook( + useUnits( + $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'} + ) + ), + stats_free_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ), + stats_free_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ) + ), + stats_table_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ), + stats_table_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ) + ), + stats_tuple_count => + $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'}, + stats_tuple_count_dbk => + docbook( $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'} ), + stats_tuple_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ), + stats_tuple_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ) + ), + + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + table_sgmlid => sgml_safe_id( + join( '.', + $schema, $struct->{$schema}{'TABLE'}{$table}{'TYPE'}, + $table ) + ), + table_comment => + $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'}, + table_comment_dbk => + docbook( $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'} ), + table_comment_dia => $comment_dia, + view_definition => $viewdef, + view_definition_dbk => docbook($viewdef), + columns => \@columns, + constraints => \@constraints, + fk_schemas => \@fk_schemas, + indexes => \@indexes, + inherits => \@inherits, + permissions => \@permissions, + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $tables[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + # Dump out list of functions + my @functions; + foreach my $function ( sort keys %{ $struct->{$schema}{'FUNCTION'} } ) { + push @functions, + { + function => $function, + function_dbk => docbook($function), + function_sgmlid => + sgml_safe_id( join( '.', $schema, 'function', $function ) ), + function_comment => + $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'}, + function_comment_dbk => docbook( + $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'} + ), + function_language => + uc( $struct->{$schema}{'FUNCTION'}{$function}{'LANGUAGE'} ), + function_returns => + $struct->{$schema}{'FUNCTION'}{$function}{'RETURNS'}, + function_source => + $struct->{$schema}{'FUNCTION'}{$function}{'SOURCE'}, + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $functions[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + push @schemas, + { + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + schema_comment => $struct->{$schema}{'SCHEMA'}{'COMMENT'}, + schema_comment_dbk => + docbook( $struct->{$schema}{'SCHEMA'}{'COMMENT'} ), + functions => \@functions, + tables => \@tables, + }; + + # Build the array of schemas + if ( scalar( keys %{$struct} ) > 1 ) { + $schemas[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + # Link the various components together via the template. + my @fk_links; + my @fkeys; + foreach my $schema ( sort keys %{$struct} ) { + foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) { + foreach my $column ( + sort { + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a} + {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table} + {'COLUMN'}{$b}{'ORDER'} + } + keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} } + ) + { + foreach my $con ( + sort keys %{ + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'} + } + ) + { + + # To prevent a multi-column foreign key from appearing + # several times, we've opted + # to simply display the first column of any given key. + # Since column numbering always starts at 1 + # for foreign keys. + if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' + && $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'COLNUM'} == 1 ) + { + + # Pull out some of the longer keys + my $ref_table = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKTABLE'}; + my $ref_schema = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKSCHEMA'}; + my $ref_column = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FK-COL NAME'}; + + # Default values cause these elements to attach + # to the bottom in Dia + # If a KEYGROUP is not defined, it's a single column. + # Modify the ref_con and key_con variables to attach + # the to the columns connection point directly. + my $ref_con = 0; + my $key_con = 0; + my $keycon_offset = 0; + if ( + !defined( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'KEYGROUP'} + ) + ) + { + $ref_con = + $struct->{$ref_schema}{'TABLE'}{$ref_table} + {'COLUMN'}{$ref_column}{'ORDER'} || 0; + $key_con = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'ORDER'} || 0; + $keycon_offset = 1; + } + + # Bump object_id + $object_id++; + + push @fk_links, + { + fk_link_name => $con, + fk_link_name_dbk => docbook($con), + fk_link_name_dot => graphviz($con), + handle0_connection => $key_con, + handle0_connection_dbk => docbook($key_con), + handle0_connection_dia => 6 + ( $key_con * 2 ), + handle0_name => $table, + handle0_name_dbk => docbook($table), + handle0_schema => $schema, + handle0_to => $tableids{"$schema$table"}, + handle0_to_dbk => + docbook( $tableids{"$schema$table"} ), + handle1_connection => $ref_con, + handle1_connection_dbk => docbook($ref_con), + handle1_connection_dia => 6 + + ( $ref_con * 2 ) + + $keycon_offset, + handle1_name => $ref_table, + handle1_name_dbk => docbook($ref_table), + handle1_schema => $ref_schema, + handle1_to => $tableids{"$ref_schema$ref_table"}, + handle1_to_dbk => + docbook( $tableids{"$ref_schema$ref_table"} ), + object_id => $object_id, + object_id_dbk => docbook($object_id), + }; + + # Build the array of schemas + if ( scalar( keys %{$struct} ) > 1 ) { + $fk_links[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + } + } + } + } + } + + # Make database level comment information + my @timestamp = localtime(); + my $dumped_on = sprintf( "%04d-%02d-%02d", + $timestamp[5] + 1900, + $timestamp[4] + 1, + $timestamp[3] ); + my $database_comment = $db->{$database}{'COMMENT'}; + + # Loop through each template found in the supplied path. + # Output the results of the template as . + # into the current working directory. + my @template_files = glob( $template_path . '/*.tmpl' ); + + # Ensure we've told the user if we don't find any files. + triggerError("Templates files not found in $template_path") + if ( $#template_files < 0 ); + + # Process all found templates. + foreach my $template_file (@template_files) { + ( my $file_extension = $template_file ) =~ + s/^(?:.*\/|)([^\/]+)\.tmpl$/$1/; + next + if ( defined($wanted_output) && $file_extension ne $wanted_output ); + my $output_filename = "$output_filename_base.$file_extension"; + print "Producing $output_filename from $template_file\n"; + + my $template = HTML::Template->new( + filename => $template_file, + die_on_bad_params => 0, + global_vars => 0, + strict => 1, + loop_context_vars => 1 + ); + + $template->param( + database => $database, + database_dbk => docbook($database), + database_sgmlid => sgml_safe_id($database), + database_comment => $database_comment, + database_comment_dbk => docbook($database_comment), + dumped_on => $dumped_on, + dumped_on_dbk => docbook($dumped_on), + fk_links => \@fk_links, + schemas => \@schemas, + ); + + sysopen( FH, $output_filename, O_WRONLY | O_TRUNC | O_CREAT, 0644 ) + or die "Can't open $output_filename: $!"; + print FH $template->output(); + } +} ## end sub write_using_templates($$$$$) + +###### +# sgml_safe_id +# Safe SGML ID Character replacement +sub sgml_safe_id($) { + my $string = shift; + + # Lets use the keyword ARRAY in place of the square brackets + # to prevent duplicating a non-array equivelent + $string =~ s/\[\]/ARRAY-/g; + + # Brackets, spaces, commads, underscores are not valid 'id' characters + # replace with as few -'s as possible. + $string =~ s/[ "',)(_-]+/-/g; + + # Don't want a - at the end either. It looks silly. + $string =~ s/-$//g; + + return ($string); +} + +##### +# lower +# LowerCase the string +sub lower($) { + my $string = shift; + + $string =~ tr/A-Z/a-z/; + + return ($string); +} + +##### +# useUnits +# Tack on base 2 metric units +sub useUnits($) { + my ($value) = @_; + + return '' if ( !defined($value) ); + + my @units = ( 'Bytes', 'KiBytes', 'MiBytes', 'GiBytes', 'TiBytes' ); + my $loop = 0; + + while ( $value >= 1024 ) { + $loop++; + + $value = $value / 1024; + } + + return ( sprintf( "%.2f %s", $value, $units[$loop] ) ); +} + +##### +# docbook +# Docbook output is special in that we may or may not want to escape +# the characters inside the string depending on a string prefix. +sub docbook($) { + my $string = shift; + + if ( defined($string) ) { + if ( $string =~ /^\@DOCBOOK/ ) { + $string =~ s/^\@DOCBOOK//; + } + else { + $string =~ s/&(?!(amp|lt|gr|apos|quot);)/&/g; + $string =~ s//>/g; + $string =~ s/'/'/g; + $string =~ s/"/"/g; + } + } + else { + + # Return an empty string when all else fails + $string = ''; + } + + return ($string); +} + +##### +# graphviz +# GraphViz output requires that special characters (like " and whitespace) must be preceeded +# by a \ when a part of a lable. +sub graphviz($) { + my $string = shift; + + # Ensure we don't return an least a empty string + $string = '' if ( !defined($string) ); + + $string =~ s/([\s"'])/\\$1/g; + + return ($string); +} + +##### +# sql_prettyprint +# Clean up SQL into something presentable +sub sql_prettyprint($) { + my $string = shift; + + # If nothing has been sent in, return an empty string + if ( !defined($string) ) { + return ''; + } + + # Initialize Result string + my $result = ''; + + # List of tokens to split on + my $tok = + "SELECT|FROM|WHERE|HAVING|GROUP BY|ORDER BY|OR|AND|LEFT JOIN|RIGHT JOIN" + . "|LEFT OUTER JOIN|LEFT INNER JOIN|INNER JOIN|RIGHT OUTER JOIN|RIGHT INNER JOIN" + . "|JOIN|UNION ALL|UNION|EXCEPT|USING|ON|CAST|[\(\),]"; + + my $key = 0; + my $bracket = 0; + my $depth = 0; + my $indent = 6; + + # XXX: Split is wrong -- match would do + foreach my $elem ( split( /(\"[^\"]*\"|'[^']*'|$tok)/, $string ) ) { + my $format; + + # Skip junk tokens + if ( $elem =~ /^[\s]?$/ ) { + next; + } + + # NOTE: Should we drop leading spaces? + # $elem =~ s/^\s//; + + # Close brackets are special + # Bring depth in a level + if ( $elem =~ /\)/ ) { + $depth = $depth - $indent; + if ( $key == 1 or $bracket == 1 ) { + $format = "%s%s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + + $key = 0; + $bracket = 0; + } + + # Open brackets are special + # Bump depth out a level + elsif ( $elem =~ /\(/ ) { + if ( $key == 1 ) { + $format = "%s %s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + $depth = $depth + $indent; + $bracket = 1; + $key = 0; + } + + # Key element + # Token from our list -- format on left hand side of the equation + # when appropriate. + elsif ( $elem =~ /$tok/ ) { + if ( $key == 1 ) { + $format = "%s%s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + + $key = 1; + $bracket = 0; + } + + # Value + # Format for right hand side of the equation + else { + $format = "%s%s"; + + $key = 0; + } + + # Add the new format string to the result + $result = sprintf( $format, $result, $elem ); + } + + return $result; +} ## end sub sql_prettyprint($) + +## +# triggerError +# Print out a supplied error message and exit the script. +sub triggerError($) { + my ($error) = @_; + + # Test error + if ( !defined($error) || $error eq '' ) { + + # Suppress prototype checking in call to self + &triggerError("triggerError: Unknown error"); + } + printf( "\n\n%s\n", $error ); + + exit 2; +} + +##### +# usage +sub usage($$$) { + my ( $basename, $database, $dbuser ) = @_; + print < Specify database name to connect to (default: $database) + -f Specify output file prefix (default: $database) + -h Specify database server host (default: localhost) + -p Specify database server port (default: 5432) + -u Specify database username (default: $dbuser) + --password= Specify database password (default: blank) + --password Have $basename prompt for a password + + -l Path to the templates (default: @@TEMPLATE-DIR@@) + -t Type of output wanted (default: All in template library) + + -s Specify a specific schema to match. Technically this is a regular + expression but anything other than a specific name may have unusual + results. + --table= Tables to export. Multiple tables may be provided using a + comma-separated list. + + --statistics In 7.4 and later, with the contrib module pgstattuple installed we + can gather statistics on the tables in the database + (average size, free space, disk space used, dead tuple counts, etc.) + This is disk intensive on large databases as all pages must be visited. +USAGE + ; + exit 1; +} + +sub single_quote { + my $attr = $_; + $attr =~ s/^\s+|\s+$//g; + return qq{'$attr'}; +} + +## +# Kick off execution of main() +main($ARGV); + diff --git a/postgresql_autodoc/xml.tmpl b/postgresql_autodoc/xml.tmpl new file mode 100644 index 0000000..d589930 --- /dev/null +++ b/postgresql_autodoc/xml.tmpl @@ -0,0 +1,204 @@ + + + +" xreflabel=" database schema"><!-- TMPL_VAR name="database_dbk" --> Model + + + + + + + " + xreflabel=""> + Schema <!-- TMPL_VAR name="schema_dbk" --> + + + +
" + xreflabel="."> + -title"> + <!-- TMPL_IF name="view_definition" -->View: + <!-- TMPL_ELSE -->Table: + <!-- /TMPL_IF name="view_definition" --> + <structname><!-- TMPL_VAR name="table_dbk" --></structname> + + + + + + + + + + + + Structure of <structname><!-- TMPL_VAR name="table_dbk" --></structname> + + + + + + + + + + PRIMARY KEY + + + + + UNIQUE# + + + + + NOT NULL + + + + DEFAULT + + + + + REFERENCES "/> + + + + + + + + + + + + + + + + + Constraints on <!-- TMPL_VAR name="table_dbk" --> + + + + + + + + + + + + + + Indexes on <!-- TMPL_VAR name="table_dbk" --> + + + + + + + + + + + + + + + Tables referencing <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_schema_dbk" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_table_dbk" --> via Foreign Key Constraints + + + + + "/> + + + + + + + + +
+ Definition of view <!-- TMPL_VAR name="table_dbk" --> + +
+ + + + + Permissions on <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR name="table_dbk" --> + + + + + + + + Select + + + Insert + + + Update + + + Delete + + + Rule + + + References + + + Trigger + + + + + + + + + + +
+
+ + + + --> +
" + xreflabel=""> + -title"> + <!-- TMPL_VAR name="function_dbk" --> + + -titleabbrev"> + + + + + + Function Properties + + Language + Return Type + + + + + + + + + +
+ +
+ +
+ diff --git a/postgresql_autodoc/zigzag.dia.tmpl b/postgresql_autodoc/zigzag.dia.tmpl new file mode 100644 index 0000000..2b9f952 --- /dev/null +++ b/postgresql_autodoc/zigzag.dia.tmpl @@ -0,0 +1,224 @@ + + + + + + + + + "> + + + + + + + + + + + + + + + + + ## + + + + ## + + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #PK # + + + ## + + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + + + + + + + + + + + + ## + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "> + + + + + + + + + + + + + + + + + + + + + + + + ## + + + ## + + + + + + " connection=""/> + " connection=""/> + + + + + diff --git a/removed-code/Browser.java b/removed-code/Browser.java new file mode 100644 index 0000000..daafa05 --- /dev/null +++ b/removed-code/Browser.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpClients.SwtClient.GUI; + +import YalpClients.*; +import YalpClients.SwtClient.*; + +import YalpInterfaces.*; + +import org.eclipse.swt.*; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.layout.*; +import org.eclipse.swt.widgets.*; + +import java.util.LinkedList; + +/* + * Class Browser + * + * + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006
+ */ +public class Browser extends Composite{ + private Composite parentComposite; + private Display display1; + private Shell shell; + private Model model; + private LinkedList alreadyBrowsed; + private Tree tree; + private Button add; + private Button cancel; + + Browser( Composite parent, + final Model model, + Display display, + Composite parentComposite, + int style ) + { + super(parent, style); + this.parentComposite=parentComposite; + this.alreadyBrowsed = new LinkedList(); + this.model = model; + this.display1 = display; + this.shell = new Shell(this.display1,SWT.NONE); + this.setSize(300,400); + GridLayout gridLayout = new GridLayout(); + this.shell.setLayout(gridLayout); + gridLayout.numColumns = 2; + + GridData treeGrid = new GridData(); + treeGrid.horizontalSpan = 2; + treeGrid.widthHint = 300; + treeGrid.heightHint = 400; + treeGrid.grabExcessHorizontalSpace = true; + treeGrid.grabExcessVerticalSpace = true; + treeGrid.horizontalAlignment = SWT.FILL; + treeGrid.verticalAlignment = SWT.FILL; + + this.tree = new Tree(this.shell, SWT.SINGLE); + this.tree.setLayoutData(treeGrid); + + TreeItem tmp; + for(YalpFile aFile : model.getDir("/")){ + tmp = new TreeItem(this.tree, SWT.NULL); + tmp.setText(aFile.name); + if(aFile.isDir) tmp.setImage(new Image(display1, "folder.gif")); + else tmp.setImage(new Image(display1, "yalpV2_klein.gif")); + } + + this.tree.addSelectionListener ( + new SelectionAdapter() { + + public void widgetSelected(SelectionEvent e) { + String path = getPath(); + if(!alreadyBrowsed.contains(path)){ + alreadyBrowsed.add(path); + TreeItem tmp; + for(YalpFile aFile : model.getDir(path)){ + tmp = new TreeItem(tree.getSelection()[0],SWT.NULL); + tmp.setText(aFile.name); + if(aFile.isDir) tmp.setImage(new Image(display1, "folder.gif")); + else tmp.setImage(new Image(display1, "yalpV2_klein.gif")); + tmp.getParentItem().setExpanded(true); + } + } + } + } + ); + + GridData buttonGrid1 = new GridData(); + buttonGrid1.horizontalSpan = 1; + + this.add = new Button(this.shell, SWT.PUSH); + this.add.setText("Indicate"); + this.add.setLayoutData(buttonGrid1); + this.add.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e){ + model.addDir(getPath()); + parentEnable(true); + shell.setVisible(false); + } + }); + + GridData buttonGrid2 = new GridData(); + buttonGrid2.horizontalSpan = 1; + buttonGrid2.horizontalAlignment = SWT.END; + + this.cancel = new Button(this.shell, SWT.PUSH); + this.cancel.setText("Cancel"); + this.cancel.setLayoutData(buttonGrid2); + this.cancel.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e){ + parentEnable(true); + shell.setVisible(false); + } + }); + } + + public void show(){ + parentEnable(false); + Point size=this.getSize(); + Rectangle parentRec=((Shell)this.parentComposite).getBounds(); + Rectangle thisRec=this.shell.computeTrim(parentRec.x+(parentRec.width/2)-(size.x/2),parentRec.y+(parentRec.height/2)-(size.y/2),size.x,size.y); + shell.setBounds(thisRec); + shell.open(); + while(!shell.isDisposed()){ + if(!this.display1.readAndDispatch()) this.display1.sleep(); + } + this.display1.dispose(); + } + + private String getPath(){ + TreeItem actualItem = tree.getSelection()[0]; + String path = "/"+tree.getSelection()[0].getText(); + while(actualItem.getParentItem() != null){ + actualItem = actualItem.getParentItem(); + path = "/" + actualItem.getText() + path; + } + return path; + } + private void parentEnable(boolean bool){ + parentComposite.setEnabled(bool); + } +} diff --git a/removed-code/Client.java b/removed-code/Client.java new file mode 100755 index 0000000..a945f48 --- /dev/null +++ b/removed-code/Client.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpClients.SwtClient; +import YalpClients.SwtClient.GUI.*; + +import org.eclipse.swt.*; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/* + * Class Client + * + * Instances Model, LoadDialog and StartDialog + * + * @author Volker Dahnke + * + * @version 1 02-04-2006
+ */ + public class Client implements Runnable{ + +/* + * enables the Class to be loaded dynamicly. + * Instances Model, LoadDialog and StartDialog. + */ + + public void run () { + + LoadDialog load = new LoadDialog( + new Shell(Display.getDefault(),SWT.NONE), SWT.NONE); + + load.show(); + final Model model = new Model(); + load.close(); + + StartDialog start = + new StartDialog(new Shell(Display.getDefault(),SWT.MIN),model, SWT.NONE); + + start.show(); + } +} diff --git a/server.policy b/server.policy new file mode 100644 index 0000000..e07e45d --- /dev/null +++ b/server.policy @@ -0,0 +1,8 @@ +grant { + permission java.io.FilePermission "<>","execute, read, write"; + permission java.io.FilePermission "C:\\Programme\\VideoLAN\\VLC\\vlc","execute"; + permission java.io.FilePermission "/Applications/VLC.app/Contents/MacOS/VLC","execute"; + permission java.net.SocketPermission "*:1024-","connect,accept,resolve"; + permission java.util.PropertyPermission "id3.default_language", "read"; + permission java.util.PropertyPermission "id3.default_encoding", "read"; +}; diff --git a/server.sh b/server.sh new file mode 100755 index 0000000..585302a --- /dev/null +++ b/server.sh @@ -0,0 +1,4 @@ +/opt/sun-jdk-1.6.0.07/bin/orbd -ORBInitialPort 1050 & +sleep 2 +java -Djava.library.path=./lib -jar yalpServer.jar -ORBInitialPort 1050 -ORBInitialHost localhost +killall -9 orbd diff --git a/src/YalpAuth/YalpPGSqlAuth/DatabaseDefines.java b/src/YalpAuth/YalpPGSqlAuth/DatabaseDefines.java new file mode 100644 index 0000000..5ff92c7 --- /dev/null +++ b/src/YalpAuth/YalpPGSqlAuth/DatabaseDefines.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ +package YalpAuth.YalpPGSqlAuth; + +/* + * Class DatabaseDefines + * + * + * + * @author Manuel Traut + * + * @version 0.1 28-08-2008
+ * + */ + +public class DatabaseDefines { + + public String dbConnection="jdbc:postgresql://10.0.3.20:5432/yalp_user"; + public String dbUser="yalp"; + public String dbPasswd="huhu"; + +/* + * set string for dbConnection + * @param dbConnection + * "jdbc:postgresql://:/"; + */ + public void setDBConnection(String dbConnection){ + this.dbConnection = dbConnection; + } + +/* + * set userName for db Edit + * @param dbUser + */ + public void setDBUser(String dbUser){ + this.dbUser = dbUser; + } + +/* + * set string for db Password + * @param DBPasswd + */ + public void setDBPasswd(String DBPasswd){ + this.dbPasswd = DBPasswd; + } + + public String getDBConnection(){ + return this.dbConnection; + } + + public String getDBUser(){ + return this.dbUser; + } + + public String getDBPasswd(){ + return this.dbPasswd; + } +} diff --git a/src/YalpAuth/YalpPGSqlAuth/YalpAuthInterfaceImpl.java b/src/YalpAuth/YalpPGSqlAuth/YalpAuthInterfaceImpl.java new file mode 100644 index 0000000..b87bce3 --- /dev/null +++ b/src/YalpAuth/YalpPGSqlAuth/YalpAuthInterfaceImpl.java @@ -0,0 +1,137 @@ +package YalpAuth.YalpPGSqlAuth; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.*; +import java.sql.*; + +import YalpInterfaces.*; + +public class YalpAuthInterfaceImpl { + private String db; + private String dbuser; + private String dbpasswd; + private Statement stat; + private Connection con; + +/* + * Constructor establishes connection to Database Server + * + * @param db + * jdbc Connection to database + * @param dbYalpUser + * userName for database + * @param dbPasswd + * password for database + */ + public YalpAuthInterfaceImpl(String db, String dbYalpUser, String dbPasswd) { + try{ + this.dbuser = dbYalpUser; + this.dbpasswd = dbPasswd; + Class.forName("org.postgresql.Driver"); + con = DriverManager.getConnection(db,dbuser,dbpasswd); + System.out.println("YalpAuth: PGSQL connection established"); + this.stat= con.createStatement(); + } catch (SQLException e) { + System.out.println("Exception in DbConnection Constructor: "+e); + } catch (ClassNotFoundException e) { + System.out.println("Exception in DbConnection Constructor: "+e); + } + } + +/* + * checks if user exists in yalpYalpUser Database and what rights he has + * + * @param username + * username to check + * @param passwd + * password to check + * + * @return enum privilege level + */ + public int userVerify(String username,String passwd) { + try{ + ResultSet result=stat.executeQuery("select * from \"user\" where \"username\" = '"+username+"' and \"passwd\" = '"+passwd+"';"); + + if (result.next()){ + if (result.getBoolean(5)==true){ + return 2; + }else return 1; + }else return 0; + }catch (SQLException e){ + System.out.println("Exception in DbConnection.userVerify: "+e); + return 0; + } + } + +/* + * returns an ArrayList with all yalpYalpUsers and Admins + * + * @return ArrayList + * list with all YalpYalpUsers and Admins + */ + public void getUser(UsersHolder list, YalpErrorHolder err) { + try { + ArrayList resultList =new ArrayList(); + YalpUser actUser = new YalpUser(); + String query = "select * from \"user\"order by \"id\";"; + Statement stat= con.createStatement(); + ResultSet result=stat.executeQuery(query); + + while(result.next()) + { + /* t.b.d. - create YalpUser according to new database design */ + // result.getInt(1),result.getString(2),result.getString(3),result.getString(4),result.getBoolean(5))) + resultList.add( actUser ); + } + YalpUser[] u = new YalpUser[1]; + list = new UsersHolder(resultList.toArray(u)); + } catch (SQLException e) { + YalpError error = new YalpError(); + error.code = YalpErrorCode.ERROR_SQL; + error.descr = e.toString(); + error.level = YalpErrorLevel.ERROR_LEVEL_ERROR; + err = new YalpErrorHolder(error); + } + } + +/* + * submits changes to yalpYalpUserDatabase + * + * @param change + * describes the change to commit + * @return int + * -1 if failed + */ + public void changeUser(YalpUser usr, String passwd, Action todo, + YalpError err) { + + /* t.b.d. alter to new db design + try{ + String sql; + switch (todo.type){ + // if updateType is UPDATE + case Action._UPDATE: + sql="update \"user\" set \"username\"='"+usr.name+"', \"passwd\"='"+change.passwd+"', \"realname\"='"+change.realname+"', \"admin\"="+change.admin+" where \"id\"= "+change.id+" ;"; + break; + // if updateType is INSERT INTO + case Action._INSERT: + sql="insert into \"user\" values(nextval('userId'), '"+usr+"','"+change.passwd+"','"+change.realname+"',"+change.admin+");"; + break; + // if updateType is DELETE + case Action._DELETE: + sql="delete from \"user\" where \"id\"= "+change.id+" ;"; + break; + default: + //errorhandling + } + // perform operation on table an return number of updated rows + System.out.println(sql); + return stat.executeUpdate(sql); + }catch(SQLException e){ + System.out.println("Exception in DbConnection.changeYalpUser: "+e); + } + */ + } +} diff --git a/src/YalpAuth/YalpPGSqlAuth/YalpPGSqlAuth.java b/src/YalpAuth/YalpPGSqlAuth/YalpPGSqlAuth.java new file mode 100644 index 0000000..53ddde1 --- /dev/null +++ b/src/YalpAuth/YalpPGSqlAuth/YalpPGSqlAuth.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ +package YalpAuth.YalpPGSqlAuth; + +import YalpInterfaces.*; + +/* + * Class YalpPGSqlAuth + * + * Implements functionality of the DBConnectionInterface + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006
+ */ + +public class YalpPGSqlAuth { + private YalpAuthInterfaceImpl con; + private DatabaseDefines config; + + public static void main(String[] args) + { + System.out.println("YalpPGSqlAuth\n"); + } +} diff --git a/src/YalpClients/ClientConfiguration.java b/src/YalpClients/ClientConfiguration.java new file mode 100755 index 0000000..7e39e78 --- /dev/null +++ b/src/YalpClients/ClientConfiguration.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ +package YalpClients; + +/* + * Class ClientSettings + * + * handles Settings of the yalpClient + * + * @author Manuel Traut, Volker Dahnke + * + * @version 0.1 18-03-2006
+ * + * @see client + */ + +public class ClientConfiguration{ + static final long serialVersionUID = 0; + public String serverIP = "localhost"; + public Integer classServerPort = 5002; + public Integer registryPort = 5001; + public String vlcCommand = "vlc"; + +/* + * sets IP of yalp Server to connect to + * + * @param serverIP + * ip of yalpServer + */ + public void setserverIP(String serverIP){ + this.serverIP = serverIP; + } + +/* + * sets Port of yalp ClassServer to get Client-classFiles from + * + * @param classServerPort + * port of classServer + */ + public void setclassServerPort(int classServerPort){ + this.classServerPort = classServerPort; + } + +/* + * sets Port where RMI Registry can be found + * + * @param registryPort + * port of RMI Registry + */ + public void setregistryPort(int registryPort){ + this.registryPort = registryPort; + } + +/* + * sets Command how vlcPlayer on Client can be started + * on some hardware it can be useful, to commit not only: + * / + * but also path, executable and like --alsadev hw0,0 + * @param vlcCommand + * for a perfectly running vlc on the client + */ + public void setvlcCommand(String vlcCommand){ + this.vlcCommand = vlcCommand; + } + +/* + * returns the ip of the yalpServer + * + * @return String + * ip of yalpServer + */ + public String getserverIP(){ + return this.serverIP; + } + +/* + * returns port of the yalpClassServer + * + * @return int + * port of yalpClassServer + */ + public int getclassServerPort(){ + return this.classServerPort; + } + +/* + * returns port of RMI Registry + * + * @return int + * Port of RMI Registry + */ + public int getregistryPort(){ + return this.registryPort; + } + +/* + * returns command to start vlc Player on client + * + * @return String + * Command + */ + public String getvlcCommand(){ + return this.vlcCommand; + } + +} diff --git a/src/YalpClients/SwtClient/GUI/GUI.java b/src/YalpClients/SwtClient/GUI/GUI.java new file mode 100644 index 0000000..4c0e474 --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/GUI.java @@ -0,0 +1,2101 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpClients.SwtClient.GUI; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.layout.*; +import org.eclipse.swt.widgets.*; +import org.eclipse.swt.events.*; +import java.util.*; + +import YalpInterfaces.*; +import YalpClients.SwtClient.*; + +/* + * + * Class GUI + * + * + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006
+ * + */ +public class GUI extends org.eclipse.swt.widgets.Composite { + + public Model model; + public Composite resultComposite; + public Composite playlistComposite; + public Composite bottemComposite; + public Table resultTable1; + public Table resultTable2; + public Composite composite1; + public Composite changeComposite; + public Table UserTable; + public Composite composite3; + + private AccessRights userKind; + private StyledText styledText1; + private CTabFolder cTabFolder1; + private CTabItem tab1; + private Composite container1; + private Composite topComposite; + private Group find; + private Group logo; + private CTabItem tab2; + private Composite container2; + private Group group1; + private Group group2; + private CLabel authorLabel; + private CLabel titleLabel; + private CLabel streamLabel2; + private CLabel actualStreamLabel2; + private CLabel actualStreamLabel1; + private CLabel streamLabel1; + private CLabel data2; + private CLabel data1; + private Button shutdown; + private TableColumn ip; + private TableColumn userName; + public Table iptable; + private Composite composite4; + + private Button submitButton; + private CLabel adminAddLabel; + private CLabel passwdAddLable; + private CLabel usernameAddLable; + private CLabel realnameAddLabel; + private CCombo adminAdd; + private Text realnameAdd; + private Text passwdAdd; + private Text usernameAdd; + private Group tab3group5; + private Button next; + private Button stop; + private Button play; + private CLabel cLabel2; + private Button save; + private Text userTableId; + private Text passwd; + private Text username; + private Text userTableName; + private CLabel adminLabel; + private CCombo adminCombo; + private CLabel nameLable; + private CLabel passwdLable; + private CLabel usernameLable; + private CLabel idLable; + private Group tab3group4; + private Button delete; + private Button add1; + private Group tab3Group3; + private Group tab3Group2; + private Group tab3Group1; + private Composite container3; + private Button deleteButton; + private Button addButton; + private StyledText status; + private Button saveButton; + private Text id; + private CLabel idLabel; + private CLabel cLabel1; + private CLabel nameLabel; + private CLabel pathLabel; + private CLabel lastEditLable; + private CLabel ownerIdLabel; + private CLabel resolutionLabel; + private CLabel vBitrateLabel; + private CLabel aBitrateLabel; + private CLabel durationLabel; + private CLabel yearLabel; + private CLabel categoryLabel; + private CLabel albumLabel; + private CCombo type; + private Text name; + private Text path; + private Text lastEdit; + private Text ownerId; + private Text resolution; + private Text vBitrate; + private Text aBitrate; + private Text duration; + private Text year; + private Text category; + private Text album; + private Text author; + private Text title; + private Composite composite2; + private Table playlistTable; + private Button add2; + private Button del; + private Boolean isNotPlaying=true; + private Boolean paused =true; + private CTabItem tab3; + private Composite parent; + private Display display; + final Image pauseImage=new Image(this.getDisplay(),"img/pause.gif"); + final Image playImage=new Image(this.getDisplay(),"img/play.gif"); + final Image forwardImage=new Image(this.getDisplay(),"img/forward.gif"); + { + //Register as a resource user - SWTResourceManager will + //handle the obtaining and disposing of resources + SWTResourceManager.registerResourceUser(this); + } + + public GUI( Composite parent, Display display, Model model, + AccessRights userKind, int style ) { + + super(parent, style); + + this.parent = parent; + this.display = display; + this.model = model; + this.userKind = userKind; + + initGUI(); + } + + private void initGUI() { + try { + this.setSize(800, 600); + this.setBackground(SWTResourceManager.getColor(192, 192, 192)); + GridLayout thisLayout = new GridLayout(1, true); + thisLayout.marginWidth = 5; + thisLayout.marginHeight = 5; + thisLayout.numColumns = 1; + thisLayout.makeColumnsEqualWidth = true; + thisLayout.horizontalSpacing = 5; + thisLayout.verticalSpacing = 5; + this.setLayout(thisLayout); + + { + if (this.userKind.value() == AccessRights._USER){ + cTabFolder1 = new CTabFolder(this, SWT.NONE); + GridData cTabFolder1LData = new GridData(); + cTabFolder1LData.widthHint = 787; + cTabFolder1LData.heightHint = 568; + cTabFolder1.setLayoutData(cTabFolder1LData); + { + tab1 = new CTabItem(cTabFolder1,SWT.NONE); + tab1.setText("Find"); + { + container1 = new Composite(cTabFolder1,SWT.NONE); + tab1.setControl(container1); + RowLayout container1Layout = new RowLayout(org.eclipse.swt.SWT.HORIZONTAL); + container1.setLayout(container1Layout); + { + topComposite = new Composite(container1,SWT.NONE); + GridLayout topCompositeLayout = new GridLayout(); + topCompositeLayout.makeColumnsEqualWidth = true; + topCompositeLayout.numColumns = 2; + topCompositeLayout.verticalSpacing = 2; + topCompositeLayout.horizontalSpacing = 5; + topComposite.setLayout(topCompositeLayout); + RowData topCompositeLData = new RowData(); + topCompositeLData.width = 783; + topCompositeLData.height = 566; + topComposite.setLayoutData(topCompositeLData); + { + find = new Group(topComposite,SWT.NONE); + this.find(find,resultComposite,playlistComposite,bottemComposite,1); + } + { + logo = new Group(topComposite,SWT.NONE); + this.logo(logo); + } + { + resultComposite = new Composite(topComposite,SWT.NONE); + resultTable1 = new Table(resultComposite,SWT.MULTI|SWT.FULL_SELECTION); + resultTable1.setToolTipText("Medias"); + resultTable1.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + add2.setEnabled(true); + } + }); + this.resultTable(resultComposite,resultTable1,1); + } + { + playlistComposite = new Composite(topComposite,SWT.NONE); + FormLayout playlistCompositeLayout = new FormLayout(); + playlistComposite.setLayout(playlistCompositeLayout); + GridData playlistCompositeLData = new GridData(); + playlistCompositeLData.heightHint = 390; + playlistCompositeLData.horizontalAlignment = GridData.FILL; + playlistComposite.setLayoutData(playlistCompositeLData); + playlistComposite.setVisible(false); + playlistComposite.setSize(238, 390); + { + next = new Button(playlistComposite,SWT.PUSH | SWT.CENTER); + FormData nextLData = new FormData(); + nextLData.width = 45; + nextLData.height = 21; + nextLData.left = new FormAttachment(0, 1000, 185); + nextLData.top = new FormAttachment(0, 1000, 365); + next.setLayoutData(nextLData); + next.setEnabled(false); + next.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false)); + next.setToolTipText("play next Title"); + next.setImage(forwardImage); + next.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + model.next(); + } + }); + } + { + stop = new Button(playlistComposite,SWT.PUSH | SWT.CENTER); + FormData stopLData = new FormData(); + stopLData.width = 35; + stopLData.height = 21; + stopLData.left = new FormAttachment(0, 1000, 91); + stopLData.top = new FormAttachment(0, 1000, 365); + stop.setLayoutData(stopLData); + stop.setImage(new Image(this.getDisplay(),"img/stop.gif")); + stop.setEnabled(false); + stop.setToolTipText("stop"); + stop.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + if (model.stop()){ + play.setEnabled(true); + next.setEnabled(false); + stop.setEnabled(false); + play.setImage(playImage); + play.setToolTipText("play"); + isNotPlaying=true; + } + + } + }); + } + { + play = new Button(playlistComposite,SWT.PUSH | SWT.CENTER); + FormData playLData = new FormData(); + playLData.width = 35; + playLData.height = 21; + playLData.left = new FormAttachment(0, 1000, 50); + playLData.top = new FormAttachment(0, 1000, 365); + play.setLayoutData(playLData); + play.setImage(playImage); + play.setEnabled(false); + play.setToolTipText("play"); + play.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + stop.setEnabled(true); + if (playlistTable.getItemCount()>1)next.setEnabled(true); + del.setEnabled(false); + //add2.setEnabled(false); + if (isNotPlaying){ + play.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_WAIT)); + if(model.play()){ + play.setImage(pauseImage); + play.setToolTipText("pause"); + play.setCursor(SWTResourceManager.getCursor(SWT.NONE)); + isNotPlaying= false; + }else; + }else{ + if(model.pause()){ + if (paused){ + play.setImage(playImage); + play.setToolTipText("play"); + paused=false; + }else{ + play.setImage(pauseImage); + play.setToolTipText("pause"); + paused=true; + } + }else; + } + + } + }); + } + { + add2 = new Button(playlistComposite,SWT.PUSH | SWT.CENTER); + FormData addLData = new FormData(); + addLData.width = 25; + addLData.height = 21; + addLData.left = new FormAttachment(0, 1000, 2); + addLData.top = new FormAttachment(0, 1000, 160); + add2.setLayoutData(addLData); + add2.setText(">>"); + add2.setEnabled(false); + add2.setToolTipText("add to Playlist"); + add2.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false)); + add2.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + if (System.getProperty("os.name")== "Mac OS X"){ + for (int i=resultTable1.getSelectionCount()-1;i>=0;i--){ + int id=new Integer(resultTable1.getSelection()[i].getText(0)).intValue(); + System.out.println(resultTable1.getSelection()[i].getText(1)); + model.add2PlayList(id); + } + }else{ + for (int i=0;i playlist=model.getToPlaylist(); + for(int i=0;i1&& !isNotPlaying)next.setEnabled(true); + } + }); + } + { + del = new Button(playlistComposite,SWT.PUSH | SWT.CENTER); + FormData delLData = new FormData(); + delLData.width = 25; + delLData.height = 21; + delLData.left = new FormAttachment(0, 1000, 2); + delLData.top = new FormAttachment(0, 1000, 200); + del.setLayoutData(delLData); + del.setEnabled(false); + del.setToolTipText("del from Playlist"); + del.setText("<<"); + del.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false)); + del.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + for (int i=playlistTable.getSelectionCount()-1;i>=0;i--){ + int pos = playlistTable.getSelectionIndices()[i]; + model.removeFromPlayList(pos); + } + + del.setEnabled(false); + while(playlistTable.getItemCount()!=0){ + playlistTable.remove(0); + } + ArrayList playlist=model.getToPlaylist(); + for(int i=0;i resultList = model.getUser(); + for (int i = 0; i < resultList.size(); i++) { + TableItem item; + YalpUser result = resultList.get(i); + item = new TableItem(UserTable,SWT.NONE); + item.setText(0,new Integer(result.id).toString()); + item.setText(1,result.name); + // item.setText(2,result.password); + item.setText(3,result.realName); + item.setText(4,model.accessRightsName(result.level)); + } + tab3group4.setVisible(false); + } + }); + } + { + add1 = new Button(tab3Group3,SWT.PUSH | SWT.CENTER); + add1.setText("Add"); + FormData addLData = new FormData(); + addLData.width = 45; + addLData.height = 21; + addLData.left = new FormAttachment(0, 1000, 7); + addLData.top = new FormAttachment(0, 1000, 254); + add1.setLayoutData(addLData); + add1.setToolTipText("add new User "); + add1.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + tab3group5.setVisible(true); + } + }); + } + { + UserTable = new Table(tab3Group3,SWT.SINGLE|SWT.FULL_SELECTION); + FormData UserTableLData = new FormData(); + UserTableLData.width = 467; + UserTableLData.height = 224; + UserTableLData.left = new FormAttachment(11, 1000, 0); + UserTableLData.right = new FormAttachment(988, 1000, 0); + UserTableLData.top = new FormAttachment(19, 1000, 0); + UserTableLData.bottom = new FormAttachment(864, 1000, 0); + UserTable.setLayoutData(UserTableLData); + UserTable.setHeaderVisible(true); + UserTable.setToolTipText("registrated User"); + UserTable.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + userTableId.setText(UserTable.getSelection()[0].getText(0)); + username.setText(UserTable.getSelection()[0].getText(1)); + passwd.setText(UserTable.getSelection()[0].getText(2)); + userTableName.setText(UserTable.getSelection()[0].getText(3)); + adminCombo.setText(UserTable.getSelection()[0].getText(4)); + tab3group4.setVisible(true); + } + }); + { + TableColumn id = new TableColumn(UserTable,SWT.BEGINNING); + id.setText("ID"); + id.setWidth(45); + id.setMoveable(true); + id.addListener(SWT.Selection, new SortListener(this,UserTable,0,5)); + TableColumn userName = new TableColumn(UserTable,SWT.BEGINNING); + userName.setMoveable(true); + userName.setText("Username"); + userName.setWidth(120); + userName.addListener(SWT.Selection, new SortListener(this,UserTable,1,5)); + TableColumn passwd = new TableColumn(UserTable,SWT.BEGINNING); + passwd.setMoveable(true); + passwd.setText("Password"); + passwd.setWidth(120); + passwd.addListener(SWT.Selection, new SortListener(this,UserTable,2,5)); + TableColumn name = new TableColumn(UserTable,SWT.BEGINNING); + name.setMoveable(true); + name.setText("Name"); + name.setWidth(130); + name.addListener(SWT.Selection, new SortListener(this,UserTable,3,5)); + TableColumn admin = new TableColumn(UserTable,SWT.BEGINNING); + admin.setMoveable(true); + admin.setText("Admin"); + admin.setWidth(74); + admin.addListener(SWT.Selection, new SortListener(this,UserTable,4,5)); + //TableColumn huhu=new TableColumn(UserTable,SWT.BEGINNING); + //huhu.dispose(); + ArrayList resultList = model.getUser(); + for (int i = 0; i < resultList.size(); i++) { + TableItem item; + YalpUser result = resultList.get(i); + item = new TableItem(UserTable,SWT.NONE); + item.setText(0,new Integer(result.id).toString()); + item.setText(1,result.name); + //item.setText(2,result.passwd); + item.setText(3,result.realName); + item.setText(4,model.accessRightsName(result.level)); + } + } + } + } + { + tab3group4 = new Group(container3,SWT.NONE); + FormLayout tab3group4Layout = new FormLayout(); + tab3group4.setLayout(tab3group4Layout); + tab3group4.setText("Edit User"); + GridData tab3group4LData = new GridData(); + tab3group4LData.widthHint = 256; + tab3group4LData.heightHint = 284; + tab3group4.setLayoutData(tab3group4LData); + tab3group4.setVisible(false); + { + save = new Button(tab3group4,SWT.PUSH | SWT.CENTER); + save.setText("save"); + FormData saveLData = new FormData(); + saveLData.width = 45; + saveLData.height = 21; + saveLData.left = new FormAttachment(0, 1000, 42); + saveLData.top = new FormAttachment(0, 1000, 157); + save.setLayoutData(saveLData); + save.setToolTipText("save Changes"); + save.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + YalpUser toChange = new YalpUser(); + toChange.id = new Integer(userTableId.getText()).intValue(); + toChange.name = username.getText(); + model.changeUser(toChange, passwd.getText(), Action.EDIT); + while(UserTable.getItemCount()!=0){ + UserTable.remove(0); + } + ArrayList resultList = model.getUser(); + for (int i = 0; i < resultList.size(); i++) { + TableItem item; + YalpUser result = resultList.get(i); + item = new TableItem(UserTable,SWT.NONE); + item.setText(0,new Integer(result.id).toString()); + item.setText(1,result.name); + //item.setText(2,result.passwd); + item.setText(3,result.realName); + item.setText(4,model.accessRightsName(result.level)); + } + tab3group4.setVisible(false); + } + }); + } + { + userTableName = new Text(tab3group4,SWT.NONE); + FormData text2LData = new FormData(); + text2LData.width = 94; + text2LData.height = 14; + text2LData.left = new FormAttachment(0, 1000, 117); + text2LData.top = new FormAttachment(0, 1000, 112); + userTableName .setLayoutData(text2LData); + } + { + passwd = new Text(tab3group4,SWT.NONE); + FormData passwdLData = new FormData(); + passwdLData.width = 94; + passwdLData.height = 14; + passwdLData.left = new FormAttachment(0, 1000, 117); + passwdLData.top = new FormAttachment(0, 1000, 92); + passwd.setLayoutData(passwdLData); + } + { + username = new Text(tab3group4,SWT.NONE); + FormData usernameLData = new FormData(); + usernameLData.width = 94; + usernameLData.height = 14; + usernameLData.left = new FormAttachment(0, 1000, 117); + usernameLData.top = new FormAttachment(0, 1000, 72); + username.setLayoutData(usernameLData); + } + { + userTableId = new Text(tab3group4,SWT.NONE); + FormData text1LData = new FormData(); + text1LData.width = 94; + text1LData.height = 14; + text1LData.left = new FormAttachment(0, 1000, 117); + text1LData.top = new FormAttachment(0, 1000, 52); + userTableId.setLayoutData(text1LData); + userTableId.setEditable(false); + } + { + adminLabel = new CLabel(tab3group4,SWT.NONE); + adminLabel.setText("Admin:"); + FormData adminLabelLData = new FormData(); + adminLabelLData.width = 42; + adminLabelLData.height = 21; + adminLabelLData.left = new FormAttachment(0, 1000, 27); + adminLabelLData.top = new FormAttachment(0, 1000, 127); + adminLabel.setLayoutData(adminLabelLData); + } + { + idLable = new CLabel(tab3group4,SWT.NONE); + idLable.setText("Id:"); + FormData idLableLData = new FormData(); + idLableLData.width = 20; + idLableLData.height = 21; + idLableLData.left = new FormAttachment(107, 1000, 0); + idLableLData.right = new FormAttachment(185, 1000, 0); + idLableLData.top = new FormAttachment(167, 1000, 0); + idLableLData.bottom = new FormAttachment(241, 1000, 0); + idLable.setLayoutData(idLableLData); + } + { + usernameLable = new CLabel(tab3group4,SWT.NONE); + usernameLable.setText("Username:"); + FormData usernameLableLData = new FormData(); + usernameLableLData.width = 58; + usernameLableLData.height = 21; + usernameLableLData.left = new FormAttachment(107, 1000, 0); + usernameLableLData.right = new FormAttachment(333, 1000, 0); + usernameLableLData.top = new FormAttachment(237, 1000, 0); + usernameLableLData.bottom = new FormAttachment(311, 1000, 0); + usernameLable.setLayoutData(usernameLableLData); + } + { + passwdLable = new CLabel(tab3group4,SWT.NONE); + passwdLable.setText("Password:"); + FormData passwdLableLData = new FormData(); + passwdLableLData.width = 56; + passwdLableLData.height = 21; + passwdLableLData.left = new FormAttachment(107, 1000, 0); + passwdLableLData.right = new FormAttachment(326, 1000, 0); + passwdLableLData.top = new FormAttachment(308, 1000, 0); + passwdLableLData.bottom = new FormAttachment(382, 1000, 0); + passwdLable.setLayoutData(passwdLableLData); + } + { + nameLable = new CLabel(tab3group4,SWT.NONE); + nameLable.setText("Name:"); + FormData nameLableLData = new FormData(); + nameLableLData.width = 37; + nameLableLData.height = 21; + nameLableLData.left = new FormAttachment(107, 1000, 0); + nameLableLData.right = new FormAttachment(251, 1000, 0); + nameLableLData.top = new FormAttachment(378, 1000, 0); + nameLableLData.bottom = new FormAttachment(452, 1000, 0); + nameLable.setLayoutData(nameLableLData); + } + { + adminCombo = new CCombo(tab3group4,SWT.NONE); + FormData adminComboLData = new FormData(); + adminComboLData.width = 81; + adminComboLData.height = 16; + adminComboLData.left = new FormAttachment(458, 1000, 0); + adminComboLData.right = new FormAttachment(849, 1000, 0); + adminComboLData.top = new FormAttachment(466, 1000, 0); + adminComboLData.bottom = new FormAttachment(522, 1000, 0); + adminCombo.setLayoutData(adminComboLData); + { + adminCombo.add("true"); + adminCombo.add("false"); + } + } + } + tab3group5 = new Group(container3,SWT.NONE); + FormLayout tab3group5Layout = new FormLayout(); + tab3group5.setLayout(tab3group5Layout); + GridData tab3group5LData = new GridData(); + tab3group5LData.widthHint = 500; + tab3group5LData.heightHint = 99; + tab3group5.setLayoutData(tab3group5LData); + tab3group5.setText("Add User"); + tab3group5.setVisible(false); + { + submitButton = new Button(tab3group5,SWT.PUSH | SWT.CENTER); + submitButton.setText("Submit"); + FormData submitButtonLData = new FormData(); + submitButtonLData.width = 50; + submitButtonLData.height = 21; + submitButtonLData.left = new FormAttachment(0, 1000, 382); + submitButtonLData.top = new FormAttachment(0, 1000, 52); + submitButton.setLayoutData(submitButtonLData); + submitButton.setToolTipText("add User"); + submitButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + System.out.println("submit"); + YalpUser toChange = new YalpUser(); + toChange.id = 100; + toChange.name = usernameAdd.getText(); + toChange.realName = realnameAdd.getText(); + model.changeUser(toChange, passwdAdd.getText(), Action.CREATE); + while(UserTable.getItemCount()!=0){ + UserTable.remove(0); + } + ArrayList resultList = model.getUser(); + for (int i = 0; i < resultList.size(); i++) { + TableItem item; + YalpUser result = resultList.get(i); + item = new TableItem(UserTable,SWT.NONE); + item.setText(0,new Integer(result.id).toString()); + item.setText(1,result.name); + //item.setText(2,result.passwd); + item.setText(3,result.realName); + item.setText(4,model.accessRightsName(result.level)); + } + } + }); + } + { + adminAddLabel = new CLabel(tab3group5,SWT.NONE); + adminAddLabel.setText("Admin:"); + FormData adminAddLabelLData = new FormData(); + adminAddLabelLData.width = 40; + adminAddLabelLData.height = 21; + adminAddLabelLData.left = new FormAttachment(0, 1000, 291); + adminAddLabelLData.top = new FormAttachment(0, 1000, 17); + adminAddLabel.setLayoutData(adminAddLabelLData); + } + { + passwdAddLable = new CLabel(tab3group5,SWT.NONE); + passwdAddLable.setText("Password:"); + FormData passwdAddLableLData = new FormData(); + passwdAddLableLData.width = 60; + passwdAddLableLData.height = 21; + passwdAddLableLData.left = new FormAttachment(0, 1000, 17); + passwdAddLableLData.top = new FormAttachment(0, 1000, 57); + passwdAddLable.setLayoutData(passwdAddLableLData); + } + { + usernameAddLable = new CLabel(tab3group5,SWT.NONE); + usernameAddLable.setText("Username:"); + FormData usernameAddLableLData = new FormData(); + usernameAddLableLData.width = 60; + usernameAddLableLData.height = 21; + usernameAddLableLData.left = new FormAttachment(0, 1000, 17); + usernameAddLableLData.top = new FormAttachment(0, 1000, 37); + usernameAddLable.setLayoutData(usernameAddLableLData); + } + { + realnameAddLabel = new CLabel(tab3group5,SWT.NONE); + realnameAddLabel.setText("Name:"); + FormData realnameAddLabelLData = new FormData(); + realnameAddLabelLData.width = 60; + realnameAddLabelLData.height = 21; + realnameAddLabelLData.left = new FormAttachment(0, 1000, 17); + realnameAddLabelLData.top = new FormAttachment(0, 1000, 17); + realnameAddLabel.setLayoutData(realnameAddLabelLData); + } + { + adminAdd = new CCombo(tab3group5,SWT.NONE); + FormData adminAddLData = new FormData(); + adminAddLData.width = 65; + adminAddLData.height = 12; + adminAddLData.left = new FormAttachment(0, 1000, 347); + adminAddLData.top = new FormAttachment(0, 1000, 22); + adminAdd.setLayoutData(adminAddLData); + adminAdd.setText("false"); + { + adminAdd.add("false"); + adminAdd.add("true"); + } + } + { + realnameAdd = new Text(tab3group5,SWT.NONE); + FormData realnameAddLData = new FormData(); + realnameAddLData.width = 174; + realnameAddLData.height = 14; + realnameAddLData.left = new FormAttachment(0, 1000, 82); + realnameAddLData.top = new FormAttachment(0, 1000, 22); + realnameAdd.setLayoutData(realnameAddLData); + } + { + usernameAdd = new Text(tab3group5,SWT.NONE); + FormData usernameAddLData = new FormData(); + usernameAddLData.width = 174; + usernameAddLData.height = 13; + usernameAddLData.left = new FormAttachment(165, 1000, 0); + usernameAddLData.right = new FormAttachment(525, 1000, 0); + usernameAddLData.top = new FormAttachment(429, 1000, 0); + usernameAddLData.bottom = new FormAttachment(560, 1000, 0); + usernameAdd.setLayoutData(usernameAddLData); + } + { + FormData PasswdAddLData = new FormData(); + PasswdAddLData.width = 174; + PasswdAddLData.height = 13; + PasswdAddLData.left = new FormAttachment(165, 1000, 0); + PasswdAddLData.right = new FormAttachment(525, 1000, 0); + PasswdAddLData.top = new FormAttachment(631, 1000, 0); + PasswdAddLData.bottom = new FormAttachment(762, 1000, 0); + passwdAdd = new Text(tab3group5,SWT.NONE); + passwdAdd.setLayoutData(PasswdAddLData); + } + } + } + cTabFolder1.setSelection(0); + } + else{ + GridData testLData = new GridData(); + testLData.widthHint = 792; + testLData.heightHint = 590; + Composite simpelUser = new Composite(this, SWT.NONE); + RowLayout testLayout = new RowLayout(org.eclipse.swt.SWT.HORIZONTAL); + simpelUser.setLayout(testLayout); + simpelUser.setLayoutData(testLData); + { + topComposite = new Composite(simpelUser,SWT.NONE); + GridLayout topCompositeLayout = new GridLayout(); + topCompositeLayout.makeColumnsEqualWidth = true; + topCompositeLayout.numColumns = 2; + topCompositeLayout.verticalSpacing = 2; + topCompositeLayout.horizontalSpacing = 5; + topComposite.setLayout(topCompositeLayout); + RowData topCompositeLData = new RowData(); + topCompositeLData.width = 783; + topCompositeLData.height = 566; + topComposite.setLayoutData(topCompositeLData); + { + find = new Group(topComposite,SWT.NONE); + this.find(find,resultComposite,playlistComposite,bottemComposite,1); + } + { + logo = new Group(topComposite,SWT.NONE); + this.logo(logo); + } + { + resultComposite = new Composite(topComposite,SWT.NONE); + resultTable1 = new Table(resultComposite,SWT.MULTI|SWT.FULL_SELECTION); + resultTable1.setToolTipText("Medias"); + resultTable1.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + add2.setEnabled(true); + } + }); + this.resultTable(resultComposite,resultTable1,1); + } + { + playlistComposite = new Composite(topComposite,SWT.NONE); + FormLayout playlistCompositeLayout = new FormLayout(); + playlistComposite.setLayout(playlistCompositeLayout); + GridData playlistCompositeLData = new GridData(); + playlistCompositeLData.heightHint = 390; + playlistCompositeLData.horizontalAlignment = GridData.FILL; + playlistComposite.setLayoutData(playlistCompositeLData); + playlistComposite.setVisible(false); + playlistComposite.setSize(238, 390); + { + next = new Button(playlistComposite,SWT.PUSH | SWT.CENTER); + FormData nextLData = new FormData(); + nextLData.width = 45; + nextLData.height = 21; + nextLData.left = new FormAttachment(0, 1000, 185); + nextLData.top = new FormAttachment(0, 1000, 365); + next.setLayoutData(nextLData); + next.setEnabled(false); + next.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false)); + next.setToolTipText("play next Title"); + next.setImage(forwardImage); + next.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + model.next(); + } + }); + } + { + stop = new Button(playlistComposite,SWT.PUSH | SWT.CENTER); + FormData stopLData = new FormData(); + stopLData.width = 35; + stopLData.height = 21; + stopLData.left = new FormAttachment(0, 1000, 91); + stopLData.top = new FormAttachment(0, 1000, 365); + stop.setLayoutData(stopLData); + stop.setImage(new Image(this.getDisplay(),"img/stop.gif")); + stop.setEnabled(false); + stop.setToolTipText("stop"); + stop.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + if (model.stop()){ + play.setEnabled(true); + next.setEnabled(false); + stop.setEnabled(false); + play.setImage(playImage); + play.setToolTipText("play"); + isNotPlaying=true; + } + + } + }); + } + { + play = new Button(playlistComposite,SWT.PUSH | SWT.CENTER); + FormData playLData = new FormData(); + playLData.width = 35; + playLData.height = 21; + playLData.left = new FormAttachment(0, 1000, 50); + playLData.top = new FormAttachment(0, 1000, 365); + play.setLayoutData(playLData); + play.setImage(playImage); + play.setEnabled(false); + play.setToolTipText("play"); + play.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + stop.setEnabled(true); + if (playlistTable.getItemCount()>1)next.setEnabled(true); + del.setEnabled(false); + //add2.setEnabled(false); + if (isNotPlaying){ + play.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_WAIT)); + if(model.play()){ + play.setImage(pauseImage); + play.setToolTipText("pause"); + play.setCursor(SWTResourceManager.getCursor(SWT.NONE)); + isNotPlaying= false; + }else; + }else{ + if(model.pause()){ + if (paused){ + play.setImage(playImage); + play.setToolTipText("play"); + paused=false; + }else{ + play.setImage(pauseImage); + play.setToolTipText("pause"); + paused=true; + } + }else; + } + + } + }); + } + { + add2 = new Button(playlistComposite,SWT.PUSH | SWT.CENTER); + FormData addLData = new FormData(); + addLData.width = 25; + addLData.height = 21; + addLData.left = new FormAttachment(0, 1000, 2); + addLData.top = new FormAttachment(0, 1000, 160); + add2.setLayoutData(addLData); + add2.setText(">>"); + add2.setEnabled(false); + add2.setToolTipText("add to Playlist"); + add2.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false)); + add2.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + if (System.getProperty("os.name")== "Mac OS X"){ + for (int i=resultTable1.getSelectionCount()-1;i>=0;i--){ + int id=new Integer(resultTable1.getSelection()[i].getText(0)).intValue(); + System.out.println(resultTable1.getSelection()[i].getText(1)); + model.add2PlayList(id); + } + }else{ + for (int i=0;i playlist=model.getToPlaylist(); + for(int i=0;i1&& !isNotPlaying)next.setEnabled(true); + } + }); + } + { + del = new Button(playlistComposite,SWT.PUSH | SWT.CENTER); + FormData delLData = new FormData(); + delLData.width = 25; + delLData.height = 21; + delLData.left = new FormAttachment(0, 1000, 2); + delLData.top = new FormAttachment(0, 1000, 200); + del.setLayoutData(delLData); + del.setEnabled(false); + del.setToolTipText("del from Playlist"); + del.setText("<<"); + del.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false)); + del.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + for (int i=playlistTable.getSelectionCount()-1;i>=0;i--){ + int pos = playlistTable.getSelectionIndices()[i]; + model.removeFromPlayList(pos); + } + + del.setEnabled(false); + while(playlistTable.getItemCount()!=0){ + playlistTable.remove(0); + } + ArrayList playlist=model.getToPlaylist(); + for(int i=0;i types = new ArrayList(); + + if( videoCheckBox.getSelection() ) + types.add(MediaType.VIDEO); + + if( audioCheckBox.getSelection() ) + types.add(MediaType.SOUND); + /* t.b.d. add IMAGE support */ + + if (tab==1){ + while(resultTable1.getItemCount()!=0){ + resultTable1.remove(0); + } + }else{ + while(resultTable2.getItemCount()!=0){ + resultTable2.remove(0); + } + } + returnVal= model.search(search, types, tab); + ArrayListresultList=model.getMedia(tab); + for(int i=0;i=0;i--){ + + Media result = model.getMediaWithId( + new Integer(resultTable2.getSelection()[i].getText(0)).intValue(),2 ); + + changeComposite.setVisible(false); + deleteButton.setVisible(false); + model.changeMedia(result, Action.DELETE); + resultTable2.remove(resultTable2.getSelectionIndices()[i]); + } + }catch (Exception e){ + System.out.println("Exception in DeleteButton "+e); + } + } + private void addButtonWidgetSelected(SelectionEvent evt) { + System.out.println("browser not implemented in yalp v2"); + } + + + public void refillIpTable(){ + /* t.b.d. replace by session viewer + try{ + ArrayList list=model.srvCon.getClientInfo(); + while(iptable.getItemCount()!=0){ + iptable.remove(0); + } + for(ClientInfo info : list){ + TableItem item = new TableItem(iptable,SWT.NONE); + item.setText(0,info.getUserName()); + item.setText(1,info.getIp()); + } + }catch(Exception e){System.out.println("geht nicht "+e);} + */ + } + + public void show(){ + ((Shell)this.parent).setImage(new Image(display,"img/yalpV2_klein.gif")); + ((Shell)this.parent).setText("yalp"); + this.parent.addListener(SWT.Dispose,new org.eclipse.swt.widgets.Listener(){ + public void handleEvent(org.eclipse.swt.widgets.Event e) { + ShellClose(); + } + }); + Point size = this.getSize(); + java.awt.Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle shellBounds = this.parent.computeTrim((screen.width-size.x)/2,(screen.height-size.y)/2,size.x,size.y); + this.parent.setLayout(new FillLayout()); + this.parent.layout(); + this.parent.setBounds(shellBounds); + ((Shell)this.parent).open(); + while (!this.parent.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + } + public void ShellClose(){ + this.model.logoff(); + System.exit(0); + } + +} + diff --git a/src/YalpClients/SwtClient/GUI/InitGUI.java b/src/YalpClients/SwtClient/GUI/InitGUI.java new file mode 100644 index 0000000..6b1fa51 --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/InitGUI.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpClients.SwtClient.GUI; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import YalpClients.SwtClient.*; +import YalpInterfaces.AccessRights; + +/* + * Class InitGUI + * + * + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006
+ * + */ + +public class InitGUI { + private Model model; + private Display display; + private int time = 1000; + + public InitGUI(Model model,AccessRights kind){ + this.model=model; + this.display = Display.getDefault(); + final Runnable timer = new Runnable() { + public void run() { + serverStillAlive(this); + } + }; + display.timerExec(time, timer); + + GUI gui= new GUI( + new Shell(display ,SWT.MIN), display, model, kind, SWT.NULL ); + gui.show(); + } + + public void serverStillAlive(Runnable timer){ + model.serverStillAlive(); + if (!this.model.getLogoff()){ + this.display.timerExec(time, timer); + } + } + +} diff --git a/src/YalpClients/SwtClient/GUI/LoadDialog.java b/src/YalpClients/SwtClient/GUI/LoadDialog.java new file mode 100644 index 0000000..dcdc4a8 --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/LoadDialog.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpClients.SwtClient.GUI; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.layout.*; +import org.eclipse.swt.widgets.*; + +/* + * Class LoadDialog + * + * + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006
+ */ +public class LoadDialog extends Composite{ + + { + //Register as a resource user - SWTResourceManager will + //handle the obtaining and disposing of resources + SWTResourceManager.registerResourceUser(this); + } + + private CLabel cLabel1; + private CLabel cLabel2; + private CLabel cLabel3; + private Shell parent; + + public LoadDialog(Composite parent, int style) { + super(parent, style); + this.parent=(Shell)parent; + initDialog(); + } + + private void initDialog(){ + GridLayout thisLayout = new GridLayout(); + thisLayout.makeColumnsEqualWidth = true; + this.setLayout(thisLayout); + this.setSize(300,170); + { + Composite composite = new Composite(this, SWT.NONE); + FormLayout compositeLayout = new FormLayout(); + composite.setLayout(compositeLayout); + GridData compositeLData = new GridData(); + compositeLData.widthHint = 287; + compositeLData.heightHint = 165; + composite.setLayoutData(compositeLData); + composite.setVisible(true); + { + cLabel3 = new CLabel(composite, SWT.LEFT); + cLabel3.setText("Copyright (c) 2006 Manuel Traut and Volker Dahnke"); + FormData cLabel3LData = new FormData(); + cLabel3LData.width = 300; + cLabel3LData.height = 20; + cLabel3LData.left = new FormAttachment(0, 1000, 0); + cLabel3LData.top = new FormAttachment(0, 1000, 145); + cLabel3.setLayoutData(cLabel3LData); + cLabel3.setFont(SWTResourceManager.getFont("Times", 7, 0, false, false)); + } + { + cLabel2 = new CLabel(composite, SWT.CENTER); + cLabel2.setText("Loading..."); + FormData cLabel2LData = new FormData(); + cLabel2LData.width = 105; + cLabel2LData.height = 25; + cLabel2LData.left = new FormAttachment(0, 1000, 91); + cLabel2LData.top = new FormAttachment(0, 1000, 123); + cLabel2.setLayoutData(cLabel2LData); + cLabel2.setFont(SWTResourceManager.getFont("Times", 12, 1, false, false)); + } + { + cLabel1 = new CLabel(composite, SWT.CENTER); + FormData cLabel1LData = new FormData(); + cLabel1LData.width = 200; + cLabel1LData.height = 120; + cLabel1LData.left = new FormAttachment(0, 1000, 40); + cLabel1LData.top = new FormAttachment(0, 1000, 0); + cLabel1.setLayoutData(cLabel1LData); + cLabel1.setImage(new Image(this.getDisplay(),"img/yalpV2.gif")); + } + + } + } + + public void show(){ + Point size = this.getSize(); + java.awt.Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle shellBounds = this.parent.computeTrim((screen.width-size.x)/2,(screen.height-size.y)/2,size.x,size.y); + this.parent.setLayout(new FillLayout()); + this.parent.layout(); + this.parent.setBounds(shellBounds); + this.parent.open(); + } + + public void close(){ + this.parent.close(); + } +} diff --git a/src/YalpClients/SwtClient/GUI/SWTResourceManager.java b/src/YalpClients/SwtClient/GUI/SWTResourceManager.java new file mode 100644 index 0000000..87dffc3 --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/SWTResourceManager.java @@ -0,0 +1,145 @@ +package YalpClients.SwtClient.GUI; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Vector; + +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Widget; + +/* + * Class to manage SWT resources (Font, Color, Image and Cursor) + * There are no restrictions on the use of this code. + * + * You may change this code and your changes will not be overwritten, + * but if you change the version number below then this class will be + * completely overwritten by Jigloo. + * #SWTResourceManager:version4.0.0# + */ +public class SWTResourceManager { + + private static HashMap resources = new HashMap(); + private static Vector users = new Vector(); + private static SWTResourceManager instance = new SWTResourceManager(); + + private static DisposeListener disposeListener = new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + users.remove(e.getSource()); + if (users.size() == 0) + dispose(); + } + }; + + /* + * This method should be called by *all* Widgets which use resources + * provided by this SWTResourceManager. When widgets are disposed, + * they are removed from the "users" Vector, and when no more + * registered Widgets are left, all resources are disposed. + *

+ * If this method is not called for all Widgets then it should not be called + * at all, and the "dispose" method should be explicitly called after all + * resources are no longer being used. + */ + public static void registerResourceUser(Widget widget) { + if (users.contains(widget)) + return; + users.add(widget); + widget.addDisposeListener(disposeListener); + } + + public static void dispose() { + Iterator it = resources.keySet().iterator(); + while (it.hasNext()) { + Object resource = resources.get(it.next()); + if (resource instanceof Font) + ((Font) resource).dispose(); + else if (resource instanceof Color) + ((Color) resource).dispose(); + else if (resource instanceof Image) + ((Image) resource).dispose(); + else if (resource instanceof Cursor) + ((Cursor) resource).dispose(); + } + resources.clear(); + } + + public static Font getFont(String name, int size, int style) { + return getFont(name, size, style, false, false); + } + + public static Font getFont(String name, int size, int style, boolean strikeout, boolean underline) { + String fontName = name + "|" + size + "|" + style + "|" + strikeout + "|" + underline; + if (resources.containsKey(fontName)) + return (Font) resources.get(fontName); + FontData fd = new FontData(name, size, style); + if (strikeout || underline) { + try { + Class lfCls = Class.forName("org.eclipse.swt.internal.win32.LOGFONT"); + Object lf = FontData.class.getField("data").get(fd); + if (lf != null && lfCls != null) { + if (strikeout) + lfCls.getField("lfStrikeOut").set(lf, new Byte((byte) 1)); + if (underline) + lfCls.getField("lfUnderline").set(lf, new Byte((byte) 1)); + } + } catch (Throwable e) { + System.err.println( + "Unable to set underline or strikeout" + " (probably on a non-Windows platform). " + e); + } + } + Font font = new Font(Display.getDefault(), fd); + resources.put(fontName, font); + return font; + } + + public static Image getImage(String url, Control widget) { + Image img = getImage(url); + if(img != null && widget != null) + img.setBackground(widget.getBackground()); + return img; + } + + public static Image getImage(String url) { + try { + url = url.replace('\\', '/'); + if (url.startsWith("/")) + url = url.substring(1); + if (resources.containsKey(url)) + return (Image) resources.get(url); + Image img = new Image(Display.getDefault(), instance.getClass().getClassLoader().getResourceAsStream(url)); + if (img != null) + resources.put(url, img); + return img; + } catch (Exception e) { + System.err.println("SWTResourceManager.getImage: Error getting image "+url+", "+e); + return null; + } + } + + public static Color getColor(int red, int green, int blue) { + String name = "COLOR:" + red + "," + green + "," + blue; + if (resources.containsKey(name)) + return (Color) resources.get(name); + Color color = new Color(Display.getDefault(), red, green, blue); + resources.put(name, color); + return color; + } + + public static Cursor getCursor(int type) { + String name = "CURSOR:" + type; + if (resources.containsKey(name)) + return (Cursor) resources.get(name); + Cursor cursor = new Cursor(Display.getDefault(), type); + resources.put(name, cursor); + return cursor; + } + +} diff --git a/src/YalpClients/SwtClient/GUI/SortListener.java b/src/YalpClients/SwtClient/GUI/SortListener.java new file mode 100644 index 0000000..a2ff35a --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/SortListener.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpClients.SwtClient.GUI; + +import java.text.Collator; +import java.util.Locale; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.*; + +/* + * Class SortListener + * + * + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006
+ */ +public class SortListener implements Listener{ + private Table table; + private int colum,numColum; + private GUI gui; + + public SortListener(GUI gui,Table table,int colum,int numColum){ + this.colum=colum; + this.numColum=numColum; + this.table=table; + this.gui=gui; + } + + public void handleEvent(Event e) { + TableItem[] items = table.getItems(); + Collator collator = Collator.getInstance(Locale.getDefault()); + for (int i = 1; i < items.length; i++) { + String value1 = items[i].getText(colum); + for (int j = 0; j < i; j++) { + String value2 = items[j].getText(colum); + if (collator.compare(value1, value2) < 0) { + String[] values= new String[numColum]; + for(int g=0;g + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006
+ */ +public class StartDialog extends Composite { + + { + //Register as a resource user - SWTResourceManager will + //handle the obtaining and disposing of resources + SWTResourceManager.registerResourceUser(this); + } + private Display display; + private CLabel cLabel1; + private CLabel LogoLabel; + private Model model; + private Composite parent; + private Composite composite; + private CLabel logonLable; + private Button ok; + private Text passwd; + private Text username; + private CLabel passwdLable; + private CLabel usernameLable; + + + public StartDialog(Composite parent,Model model, int style) { + super(parent, style); + + this.parent=parent; + this.model=model; + this.display=Display.getDefault(); + initStartDialog(); + } + + private void initStartDialog(){ + GridLayout thisLayout = new GridLayout(); + thisLayout.makeColumnsEqualWidth = true; + this.setLayout(thisLayout); + this.setSize(300,150); + Listener listener =new Listener() { + public void handleEvent(org.eclipse.swt.widgets.Event evt) { + if (evt.character==SWT.CR){ + OkPressed(); + } + } + }; + addListener(SWT.KeyDown,listener); + { + composite = new Composite(this, SWT.NONE); + FormLayout compositeLayout = new FormLayout(); + composite.setLayout(compositeLayout); + GridData compositeLData = new GridData(); + compositeLData.widthHint = 287; + compositeLData.heightHint = 140; + composite.setLayoutData(compositeLData); + composite.setVisible(true); + composite.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + if (evt.character==SWT.CR){ + OkPressed(); + } + } + }); + { + cLabel1 = new CLabel(composite, SWT.NONE); + FormData cLabel1LData = new FormData(); + cLabel1LData.width = 120; + cLabel1LData.height = 20; + cLabel1LData.left = new FormAttachment(0, 1000, 93); + cLabel1LData.top = new FormAttachment(0, 1000, 40); + cLabel1.setLayoutData(cLabel1LData); + Color col =display.getSystemColor(SWT.COLOR_RED); + cLabel1.setForeground(col); + cLabel1.setFont(SWTResourceManager.getFont("Times", 10, 1, false, false)); + } + { + LogoLabel = new CLabel(composite, SWT.NONE); + FormData LogoLabelLData = new FormData(); + LogoLabelLData.width = 70; + LogoLabelLData.height = 42; + LogoLabelLData.left = new FormAttachment(0, 1000, 77); + LogoLabelLData.top = new FormAttachment(0, 1000, 0); + LogoLabelLData.right = new FormAttachment(1000, 1000, -140); + LogoLabelLData.bottom = new FormAttachment(1000, 1000, -98); + LogoLabel.setLayoutData(LogoLabelLData); + LogoLabel.setImage(new Image(this.getDisplay(),"img/yalpV2_mittel.gif")); + } + { + logonLable = new CLabel(composite, SWT.BEGINNING); + logonLable.setText("Login"); + FormData logonLableLData = new FormData(); + logonLableLData.width = 70; + logonLableLData.height = 28; + logonLableLData.left = new FormAttachment(0, 1000, 147); + logonLableLData.top = new FormAttachment(0, 1000, 5); + logonLable.setLayoutData(logonLableLData); + logonLable.setFont(SWTResourceManager.getFont("Times", 14, 1, false, false)); + } + { + username = new Text(composite, SWT.NONE); + FormData usernameLData = new FormData(); + usernameLData.width = 117; + usernameLData.height = 15; + usernameLData.left = new FormAttachment(0, 1000, 120); + usernameLData.top = new FormAttachment(0, 1000, 65); + username.setLayoutData(usernameLData); + username.setFocus(); + username.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + if (evt.character==SWT.CR){ + OkPressed(); + } + } + }); + } + { + passwd = new Text(composite, SWT.PASSWORD); + FormData passwdLData = new FormData(); + passwdLData.width = 117; + passwdLData.height = 15; + passwdLData.left = new FormAttachment(0, 1000, 120); + passwdLData.top = new FormAttachment(0, 1000, 88); + passwd.setLayoutData(passwdLData); + passwd.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + if (evt.character==SWT.CR){ + OkPressed(); + } + } + }); + } + { + ok = new Button(composite, SWT.PUSH | SWT.CENTER); + ok.setText("OK"); + FormData okLData = new FormData(); + okLData.width = 65; + okLData.height = 21; + okLData.left = new FormAttachment(0, 1000, 110); + okLData.top = new FormAttachment(0, 1000, 115); + ok.setLayoutData(okLData); + ok.setFont(SWTResourceManager.getFont("Times", 10, 1, false, false)); + ok.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + OkPressed(); + } + }); + } + { + passwdLable = new CLabel(composite, SWT.NONE); + passwdLable.setText("Password:"); + FormData passwdLableLData = new FormData(); + passwdLableLData.width = 70; + passwdLableLData.height = 20; + passwdLableLData.left = new FormAttachment(0, 1000, 35); + passwdLableLData.top = new FormAttachment(0, 1000, 83); + passwdLable.setLayoutData(passwdLableLData); + passwdLable.setFont(SWTResourceManager.getFont("Times", 10, 0, false, false)); + } + { + usernameLable = new CLabel(composite, SWT.NONE); + usernameLable.setText("Username:"); + FormData usernameLableLData = new FormData(); + usernameLableLData.width = 70; + usernameLableLData.height = 20; + usernameLableLData.left = new FormAttachment(0, 1000, 35); + usernameLableLData.top = new FormAttachment(0, 1000, 60); + usernameLable.setLayoutData(usernameLableLData); + usernameLable.setFont(SWTResourceManager.getFont("Times", 10, 0, false, false)); + } + } + this.layout(); + + } + private void OkPressed(){ + AccessRights kind; + kind = model.userVerify(username.getText(), passwd.getText()); + + if (kind.value() == AccessRights._NO_YALP_SERVER ) { + cLabel1.setText("Server offline"); + } else if (kind.value() == AccessRights._DENY ){ + cLabel1.setText("Access Denied"); + username.setText(""); + passwd.setText(""); + username.setFocus(); + } else { + display.close(); + InitGUI gui = new InitGUI(model, kind); + } + + } + + public void show(){ + ((Shell)this.parent).setImage(new Image(display,"img/yalpV2_klein.gif")); + ((Shell)this.parent).setText("yalp"); + Point size = this.getSize(); + java.awt.Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle shellBounds = this.parent.computeTrim((screen.width-size.x)/2,(screen.height-size.y)/2,size.x,size.y); + this.parent.setLayout(new FillLayout()); + this.parent.layout(); + this.parent.setBounds(shellBounds); + ((Shell)this.parent).open(); + while (!this.parent.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + } + + +} diff --git a/src/YalpClients/SwtClient/Model.java b/src/YalpClients/SwtClient/Model.java new file mode 100755 index 0000000..3c48615 --- /dev/null +++ b/src/YalpClients/SwtClient/Model.java @@ -0,0 +1,744 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpClients.SwtClient; + +import YalpInterfaces.*; +import YalpClients.*; + +import java.beans.XMLDecoder; +import java.beans.XMLEncoder; +import java.io.*; +import java.net.Inet4Address; +import java.net.MalformedURLException; +import java.net.UnknownHostException; +import java.sql.SQLException; +import java.util.ArrayList; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; + +/* + * Class Model + * + * Implementiert die Schnittstellenfunktionen zur Steuerung des Servers + * (Datenbankinhalte schreiben, lesen; Streaming steuern + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.6 14-12-2005
+ * + * @see client.GUI + */ + +public class Model { + + public ServerControlInterface srvCon; + private Process vlcPlayer; + private Output actualStream; + private Output streamInfo; + private ArrayList findMedia; + private ArrayList editMedia; + private ArrayList toPlaylist; + private ArrayList playList; + private ArrayList userList; + private ClientConfiguration settings; + private String clientIP; + private String curPasswd; + private AccessRights userGroup=AccessRights.DENY; + private String userName; + private Boolean playback = false; + private Boolean logoff= false; + private Session session; +/* + * Instances srvConnection to Registry, DbConnection, ServerControl + * and VlcStreamer. Also instances Class variables + */ + public Model(String[] argv) { + + this.settings=new ClientConfiguration(); + loadConfig("ClientConfiguration.xml"); + writeConfig("ClientConfiguration.xml"); + + try { + ORB orb = ORB.init(argv, null); + + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + + String name = "YALP_Server"; + srvCon = ServerControlInterfaceHelper.narrow(ncRef.resolve_str(name)); + } catch (Exception e) {// DEBUG + String errorStr="couldn't connect to YALP Server"; + + MessageBox messageBox = new MessageBox( + new Shell(Display.getDefault(),SWT.MIN), SWT.OK ); + + System.out.println(e); + messageBox.setMessage(errorStr); + messageBox.open(); + System.exit(0); + } + + // determine client IP Adress + try { + this.clientIP = Inet4Address.getLocalHost().getHostAddress(); + System.out.println(this.clientIP); + } catch (UnknownHostException e) { + String errorStr = "Model.model: determine IP failed"; + + MessageBox messageBox = new MessageBox( + new Shell(Display.getDefault(),SWT.MIN), SWT.OK ); + + System.out.println(errorStr); + messageBox.setMessage(errorStr); + messageBox.open(); + System.exit(0); + } + this.userList = new ArrayList(); + this.playList = new ArrayList(); + this.toPlaylist = new ArrayList(); + } + +/* + * write Configuration to XML File + * + * @param fileName + * @return boolean: true if succesful + */ + public boolean writeConfig(String fileName) { + try { + FileOutputStream srvConfigFile = new FileOutputStream(fileName); + XMLEncoder srvConfigWriter = new XMLEncoder(srvConfigFile); + srvConfigWriter.writeObject(settings.serverIP); + srvConfigWriter.writeObject(settings.classServerPort); + srvConfigWriter.writeObject(settings.registryPort); + srvConfigWriter.writeObject(settings.vlcCommand); + srvConfigWriter.close(); + } catch (FileNotFoundException fnfe) { + return false; + } + return true; + } + +/* + * load Configuration from XML File if possible + * + * @param fileName + * @return boolean: true if succesful + */ + public boolean loadConfig(String fileName){ + try{ + FileInputStream srvConfigFile = new FileInputStream(fileName); + XMLDecoder srvConfigLoader = new XMLDecoder(srvConfigFile); + System.out.println(srvConfigFile); + settings.serverIP = (String)srvConfigLoader.readObject(); + settings.classServerPort= (Integer)srvConfigLoader.readObject(); + settings.registryPort = (Integer)srvConfigLoader.readObject(); + settings.vlcCommand = (String)srvConfigLoader.readObject(); + srvConfigLoader.close(); + } catch(FileNotFoundException fnfe) { + System.out.println("Configuration not found, loading defaults..."); + return false; + } catch(ClassCastException cce) { + System.out.println("Errors in Configuration, loading defaults..."); + return false; + } + return true; + } + +/* + * get acutal srvConfig object + * + * @return ClientConfiguration: aktuelle Konfiguration + */ + public ClientConfiguration getConfig(){ + return this.settings; + } + +/* + * setzen und speichern eines ClientConfiguration Files + * + * @param set + * ClientConfiguration.xml + * @return boolean: true if succesful written Configuration + */ + public boolean setConfig(ClientConfiguration set){ + this.settings = set; + return this.writeConfig("ClientConfiguration.xml"); + } + +/* + * Sends YalpUsername and passwd to Server and returns YalpUsergroup + * + * @param username + * @param passwd + * @return AccessRights + */ + public AccessRights userVerify(String username,String passwd){ + this.userName=username; + this.curPasswd = passwd; + YalpErrorHolder err = new YalpErrorHolder(); + SessionHolder sess = new SessionHolder(); + try{ + // log on server + this.srvCon.clientLogon(this.userName,passwd,this.clientIP,sess,err); + this.session = sess.value; + this.userGroup = sess.value.me.level; + /* + } catch (RemoteException e) { + System.out.println("client.Model: Logon on Server failed 1"+ e); + e.printStackTrace(); + System.out.println("client.Model: Logon on Server failed 1"); + } catch (MalformedURLException e) { + System.out.println("client.Model: Logon on Server failed 2"); + } catch (SQLException e) { + System.out.println("client.Model: Logon on Server failed 3"); + } catch (NotBoundException e) { + System.out.println("client.Model: Logon on Server failed 4"); + */ + }catch(NullPointerException e){ + System.out.println("YALP Server couldn't be reached"); + this.userGroup = AccessRights.NO_YALP_SERVER; + } + return this.userGroup; + } + +/* + * Gets a list with all YalpUsers from the server + * + * @return ArrayList all registered YalpUsers + */ + public ArrayList getUser(){ + YalpErrorHolder err = new YalpErrorHolder(); + try{ + UsersHolder usr = new UsersHolder(); + this.srvCon.getUser(usr, err); + this.userList = new ArrayList(usr.value.length); + for(int i = 0; i < usr.value.length; i++) + this.userList.add(usr.value[i]); + }catch(Exception e){ + System.out.println("Exceoption in Model userList "+ e); + } + return userList; + } + +/* + * Sends User change request to server + * + * @param user + * Configuration with changes on specific YalpUser + */ + public void changeUser(YalpUser user, String passwd, Action action) { + YalpErrorHolder err = new YalpErrorHolder(); + try{ + this.srvCon.changeUser( user, + passwd, + action, + err ); + System.out.println(err.value.descr); + }catch(Exception e){ + System.out.println("Exceoption in Model changeUser "+ e); + } + } + +/* + * Sends Media change request to server and refreshes Model data + * + * @param media + * to change + * @return boolean: succesful changed media + */ + public Boolean changeMedia(Media media, Action action){ + YalpErrorHolder err = new YalpErrorHolder(); + try{ + this.srvCon.changeMedia(media, action, err); + if(err.value.code == YalpErrorCode.OK){ + Media result; + for (int i=0;i: ArrayList to create Playlist from + */ + public ArrayList getToPlaylist(){ + return this.toPlaylist; + } + +/* + * Creates new Stream with actual playlist + * + * @return Streaminfo: about new created Stream, Client should use this, + * information to get the Information howto receive the stream + */ + public Output createOutput(){ + /* t.b.d. former createStream */ + this.streamInfo.outputAction = Action.CREATE; + Media[] a = {}; + this.streamInfo.playlist = this.playList.toArray(a); + return this.streamInfo; + } + +/* + * Sends search request to server and refreshes Model data + * + * @param request + * Search Request + * @param kind + * 1 - search in first Window; other ints: search in other window + * (admins edit view) + * @return int: number of results + */ + public int search(String request, ArrayList types, int kind){ + YalpErrorHolder err = new YalpErrorHolder(); + MediasHolder result = new MediasHolder(); + try{ + MediaType[] a = {}; + if (kind == 1){ + srvCon.search(request, types.toArray(a), result, err); + for(int i = 0; i < result.value.length; i++) + this.findMedia.add(result.value[i]); + return this.findMedia.size(); + } else { + srvCon.search(request, types.toArray(a), result, err); + for(int i = 0; i < result.value.length; i++) + this.editMedia.add(result.value[i]); + return this.editMedia.size(); + } + } catch(Exception e){ + System.out.println("Exceoption in Model search "+ e); + return 0; + } + } + +/* + * Returns the search result + * + * @param kind + * 1 - for searchMedia of mainwindow; 2 - for searchMedia of editView + * @return ArrayList: last found medias + */ + + public ArrayList getMedia(int kind){ + if (kind==1) return this.findMedia; + else return this.editMedia; + } + +/* + * Retuns search result with given id + * + * @param id + * of the result + * @param kind + * 1 - for mainWindow, 2 for admins editView + * @return Media: searchMedia, with specified ID + */ + public Media getMediaWithId(int id,int kind){ + ArrayList resultList; + if (kind==1)resultList= this.findMedia; + else resultList=this.editMedia; + for (int i=0;(i ownerList =this.userList; + for (YalpUser owner:ownerList){ + if (owner.name.equals(username)){ + return owner.id; + } + } + return 0; + } + +/* + * Returns MediaType as string + * + * @param mediatype + * @return string + */ + public String getTypeName(MediaType type) + { + switch(type.value()) + { + case MediaType._IMAGE: + return "image"; + case MediaType._SOUND: + return "sound"; + case MediaType._VIDEO: + return "video"; + default: + return "unknown"; + } + } + +/* + * Returns AccessRights as string + * + * @param mediatype + * @return string + */ + public String accessRightsName(AccessRights type) + { + switch(type.value()) + { + case AccessRights._USER: + return "user"; + case AccessRights._ADMIN: + return "admin"; + case AccessRights._DENY: + return "no login"; + default: + return "unknown"; + } + } + + +/* + * Sets class variable actualStream to given value + * + * @param aStream + * stream to srvControl via play, pause, etc + */ + public void setActualStream(Output aStream){ + this.actualStream = aStream; + } + +/* + * Starts Video Lan Player + * + * @return boolean: true if vlc can be started and a stream is actualStream + */ + private boolean startVLC(){ + + String vlcCmd = settings.vlcCommand + + " --reset-srvConfig --video-on-top -I telnet --telnet-port 12345 "; +/* + switch (this.actualStream.getAccess()){ + case UDP: + vlcCmd += "udp:@"; + break; + case HTTP: + vlcCmd += "http://"; + break; + default: + System.out.println( + "client.Model.startVLC: playback this type is not supported" ); + } +*/ + vlcCmd += this.actualStream.info.params; + System.out.println(vlcCmd); + + try { + this.vlcPlayer = Runtime.getRuntime().exec(vlcCmd); + } catch (IOException e) { + System.out.println("client.Model.startVLC: starting vlcPlayer failed"); + return false; + } + return true; + } + +/* + * Stops Video Lan Player + * + */ + private void stopVLC(){ + this.playback = false; + this.vlcPlayer.destroy(); + } + +/* + * Starts playback of actual playlist + * + * @return void + */ + public boolean play(){ + + this.playback = true; + + this.actualStream = this.createOutput(); + this.actualStream.destIp = this.clientIP; + + YalpErrorHolder err = new YalpErrorHolder(); + + OutputHolder tmp = new OutputHolder(this.actualStream); + this.srvCon.control(tmp, err); + this.actualStream = tmp.value; + + this.actualStream.outputAction = Action.START; + OutputHolder tmp2 = new OutputHolder(this.actualStream); + this.srvCon.control(tmp2, err); + this.actualStream = tmp2.value; + this.startVLC(); + return true; + } + +/* + * Adds a new Media to Playlist. Only during playback + * + * @param name + * @param path + * @return boolean: true if succesful added + */ + public boolean add2Stream(String name, String path){ + + YalpErrorHolder err = new YalpErrorHolder(); + Media[] empty = {}; + this.actualStream.playlist = empty; + + Media media = new Media(); + media.path = path; + media.fileName = name; + + this.actualStream.playlist[this.actualStream.playlist.length] = media; + this.actualStream.outputAction = Action.CREATE; + + OutputHolder tmp = new OutputHolder(this.actualStream); + this.srvCon.control(tmp, err); + this.actualStream = tmp.value; + return true; + } + +/* + * Stops playback + * + * @return boolean: false - if srvConnection to streamer failed + */ + public boolean stop(){ + YalpErrorHolder err = new YalpErrorHolder(); + this.actualStream.outputAction = Action.STOP; + OutputHolder tmp = new OutputHolder(this.actualStream); + this.srvCon.control(tmp,err); + this.actualStream = tmp.value; + this.stopVLC(); + return true; + } + +/* + * jumps to next media in playlist + * + * @return boolean: false - if srvConnection to streamer failed + */ + public boolean next(){ + YalpErrorHolder err = new YalpErrorHolder(); + this.actualStream.outputAction = Action.FORWARD; + OutputHolder tmp = new OutputHolder(this.actualStream); + this.srvCon.control(tmp,err); + this.actualStream = tmp.value; + return true; + } + +/* + * Pauses playback + * + * @return boolean: false - if srvConnection to streamer failed + */ + public boolean pause(){ + YalpErrorHolder err = new YalpErrorHolder(); + this.actualStream.outputAction = Action.PAUSE; + OutputHolder tmp = new OutputHolder(this.actualStream); + this.srvCon.control(tmp,err); + this.actualStream = tmp.value; + return true; + } + +/* + * Causes the server to clean up and shutdown + * + */ + public void serverShutdown(){ + if (this.playback) + this.stop(); + this.srvCon.serverShutdown(); + } + +/* + * Checks if the server is still alive if not Client shutdown + * + */ + public void serverStillAlive(){ + // try{ + // srvCon.ping(); + /* }catch (RemoteException e){ + if (this.playback) + this.stopVLC(); + String errorStr="Server shutdown - Client is going down too"; + + MessageBox messageBox = new MessageBox( + new Shell(Display.getDefault(),SWT.MIN), SWT.OK); + + System.out.println(errorStr); + messageBox.setMessage(errorStr); + messageBox.open(); + System.exit(0); + } */ + } + +/* + * Returns client IP address + * + * @return String: ipAddress + */ + public String getClientIp(){ + return this.clientIP; + } + +/* + * Returns username of logged in user + * + * @return String: username + */ + public String getYalpUserName(){ + return this.userName; + } + +/* + * Returns indication if playback is runing + * + * @return boolean: true - if is play'in + */ + public Boolean getPlayback(){ + return this.playback; + } + +/* + * Get Total amount of streams played + * + * @return int: number of Streams totally played + * + public int getAllStreamNum(){ + try{ + return this.srvCon.getStreamCounter().getAllStreams(); + }catch (Exception e){ + System.out.println("Exception in Model.getAllStreamNum"+e); + } + return -1; + } + */ + +/* + * Gets amount of Streams actual playing + * + * @return int: number of Streams play'in at the moment + * + public int getActualStreamNum(){ + try{ + return this.srvCon.getStreamCounter().getActualStreams(); + }catch (Exception e){ + System.out.println("Exception in Model.getActualStreamNum"+e); + } + return -1; + } + */ + +/* + * Sets class variable logoff to true and logs off from server + */ + public void logoff(){ + YalpErrorHolder err = new YalpErrorHolder(); + try{ + this.logoff=true; + this.srvCon.clientLogoff(this.session, err); + }catch(Exception e) {// DEBUG + System.out.println("Model Exeptions in logoff"); + e.printStackTrace(); + } + } + +/* + * Returns indication if client is logging of + * + * @return Boolean: true - if is logging of + */ + public Boolean getLogoff(){ + return this.logoff; + } +} diff --git a/src/YalpClients/SwtClient/SwtClient.java b/src/YalpClients/SwtClient/SwtClient.java new file mode 100755 index 0000000..513d4ff --- /dev/null +++ b/src/YalpClients/SwtClient/SwtClient.java @@ -0,0 +1,61 @@ +/* + * + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + * + */ +package YalpClients.SwtClient; + +import YalpClients.SwtClient.GUI.*; + +import org.eclipse.swt.*; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + + +/* + * Class SwtClient + * + * static main method + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.1 20-11-2005
+ */ +public class SwtClient{ + +/* + * Client initialization + * + * @param argv + * arguments which are not used + */ + public static void main (String[] argv) { + try{ + System.setProperty("java.security.policy","client.policy"); + } + catch (Exception e) {//DEBUG + System.out.println ("Server SecurityManagerExeptions not caught jet " + e); + System.exit(0); + } + + LoadDialog load = new LoadDialog( + new Shell(Display.getDefault(),SWT.NONE), SWT.NONE); + + load.show(); + final Model model = new Model(argv); + load.close(); + + StartDialog start = + new StartDialog(new Shell(Display.getDefault(),SWT.MIN),model, SWT.NONE); + + start.show(); + + return; + } +} diff --git a/src/YalpInputs/YalpPGSqlInput/DatabaseDefines.java b/src/YalpInputs/YalpPGSqlInput/DatabaseDefines.java new file mode 100644 index 0000000..b6ee2ce --- /dev/null +++ b/src/YalpInputs/YalpPGSqlInput/DatabaseDefines.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ +package YalpInputs.YalpPGSqlInput; + +/* + * Class DatabaseDefines + * + * + * + * @author Manuel Traut + * + * @version 0.1 28-08-2008
+ * + */ + +public class DatabaseDefines { + + public String dbConnection="jdbc:postgresql://10.0.3.20:5432/yalp_media"; + public String dbUser="yalp"; + public String dbPasswd="huhu"; + +/* + * set string for dbConnection + * @param dbConnection + * "jdbc:postgresql://:/"; + */ + public void setDBConnection(String dbConnection){ + this.dbConnection = dbConnection; + } + +/* + * set userName for db Edit + * @param dbUser + */ + public void setDBUser(String dbUser){ + this.dbUser = dbUser; + } + +/* + * set string for db Password + * @param DBPasswd + */ + public void setDBPasswd(String DBPasswd){ + this.dbPasswd = DBPasswd; + } + + public String getDBConnection(){ + return this.dbConnection; + } + + public String getDBUser(){ + return this.dbUser; + } + + public String getDBPasswd(){ + return this.dbPasswd; + } +} diff --git a/src/YalpInputs/YalpPGSqlInput/PGSqlInput.java b/src/YalpInputs/YalpPGSqlInput/PGSqlInput.java new file mode 100644 index 0000000..531f53d --- /dev/null +++ b/src/YalpInputs/YalpPGSqlInput/PGSqlInput.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpInputs.YalpPGSqlInput; + +import YalpInterfaces.*; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; +import org.omg.PortableServer.*; +import org.omg.PortableServer.POA; + +/* + * Class PGSqlInput + * + * Postgre SQL database connection + * + * @author Volker Dahnke / Manuel Traut + * + * @version 2.0 2008-09-23
+ */ +public class PGSqlInput { + + private static ORB orb; + private static POA poa; + private static YalpInputPluginImpl psql; + private static InputPluginInterface inputPlugin; + private static ServerControlInterface srvCon; + private static PluginInfo pluginInfo; + + public PGSqlInput(String[] argv) { + + pluginInfo = new PluginInfo(); + pluginInfo.name = "Postgre SQL Input Plugin"; + pluginInfo.description = "provides information about files, which are stored on a harddisk and have been indicated to the YALP Postgre SQL database"; + pluginInfo.type = PluginType.INPUT_PLUGIN; + pluginInfo.supportedTypes = new MediaType[3]; + pluginInfo.supportedTypes[0] = MediaType.IMAGE; + pluginInfo.supportedTypes[1] = MediaType.VIDEO; + pluginInfo.supportedTypes[2] = MediaType.SOUND; + pluginInfo.access = new AccessInfo(); + pluginInfo.access.name = "local files"; + pluginInfo.access.description = ""; + pluginInfo.access.executable = ""; + pluginInfo.access.params = ""; + pluginInfo.access.type = AccessType.FILES; + + try { + this.orb = ORB.init(argv, null); + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); + } catch(Exception e) { + /* t.b.d. error handling */ + System.out.println("couldn't host plugin implementation"); + } + + try { + poa.the_POAManager().activate(); + } catch(org.omg.PortableServer.POAManagerPackage.AdapterInactive e) { + /* t.b.d. error handling */ + System.out.println("poa inactive"); + } + + YalpErrorHolder err = new YalpErrorHolder(); + + try { + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + String name = "YALP_Server"; + srvCon = ServerControlInterfaceHelper.narrow(ncRef.resolve_str(name)); + } catch (Exception e) { + System.out.println("Couldn't connect to YALP Server"); + System.exit(0); + } + + psql = new YalpInputPluginImpl(); + psql.setORB(orb); + + try { + poa.activate_object(psql); + org.omg.CORBA.Object ref = poa.servant_to_reference(psql); + inputPlugin = InputPluginInterfaceHelper.narrow(ref); + + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + String name = "YALP_Postgre_SQL_Input"; + NameComponent path[] = ncRef.to_name(name); + ncRef.rebind(path, inputPlugin); + + PluginInfoHolder tmp = new PluginInfoHolder(pluginInfo); + srvCon.ping(err); + System.out.println(err.value.descr); + srvCon.registerInputPlugin(inputPlugin, tmp, err ); + pluginInfo = tmp.value; + + if(err.value.code != YalpErrorCode.OK) + System.out.println("registring inputplugin failed"); + else + System.out.println("input plugin registered"); + + orb.run(); + + } catch (Exception e) { + System.out.println("binding plugin failed 1"); + e.printStackTrace(); + System.exit(0); + } + } +} diff --git a/src/YalpInputs/YalpPGSqlInput/YalpInputPluginImpl.java b/src/YalpInputs/YalpPGSqlInput/YalpInputPluginImpl.java new file mode 100644 index 0000000..7f599be --- /dev/null +++ b/src/YalpInputs/YalpPGSqlInput/YalpInputPluginImpl.java @@ -0,0 +1,189 @@ +package YalpInputs.YalpPGSqlInput; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.*; +import java.sql.*; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; + +import YalpInterfaces.*; + +public class YalpInputPluginImpl extends InputPluginInterfacePOA { + + private String db; + private String dbuser; + private String dbpasswd; + private Statement stat; + private Connection con; + private PluginInfo pluginInfo; + private ORB orb; + + public YalpInputPluginImpl() + { + System.out.println("YalpInputPluginImpl()"); + } + + public void setORB(ORB _orb) + { + orb = _orb; + String db = "jdbc:postgresql://localhost:5432/yalp"; + String dbYalpUser = "yalp"; + String dbPasswd = "yalp"; + + try{ + dbuser = dbYalpUser; + dbpasswd = dbPasswd; + Class.forName("org.postgresql.Driver"); + con = DriverManager.getConnection(db,dbuser,dbpasswd); + System.out.println("YalpPGSqlInput: db connection established"); + stat= con.createStatement(); + } catch (SQLException e) { + System.out.println("Exception in PGSqlInput Constructor: "+e); + } catch (ClassNotFoundException e) { + System.out.println("Exception in PGSqlInput Constructor: "+e); + } + } + +/* + * submits changes to yalpMediaDatabase + * + * @param change + * describes the change to commit + * @return int + * -1 if failed + */ + public void changeMedia (Media toChange, Action todo, YalpErrorHolder err) { + /* t.b.d. alter this to new database design + try{ + String sql1,sql2,sql3; + int Return; + switch (change.updateType){ + // if updateType is UPDATE + case UPDATE: + sql1="update \"medien\" set \"type\"='"+change.type+"', \"title\"='"+change.title+"', \"author\"='"+change.author+"', \"album\"='"+change.album+"', \"category\"='"+change.category+"', \"year\"='"+change.year+"', \"duration\"='"+change.duration+"', \"aBitrate\"="+change.aBitrate+", \"vBitrate\"="+change.vBitrate+", \"resolution\"='"+change.resolution+"', \"lastEdit\"='"+new java.util.Date(System.currentTimeMillis()).toString()+"' where \"id\"= "+change.id+" ;"; + System.out.println(sql1); + Return=stat.executeUpdate(sql1); + break; + // if updateType is INSERT INTO + case INSERT: + sql1="insert into \"medien\" values(nextval('medienId'),'"+change.type+"','"+change.title+"','"+change.author+"','"+change.album+"','"+change.category+"','"+change.year+"','"+change.duration+"',"+change.aBitrate+","+change.vBitrate+",'"+change.resolution+"',"+change.ownerId+",'"+new java.util.Date(System.currentTimeMillis()).toString()+"','"+change.path+"','"+change.name+"');"; + System.out.println(sql1); + Return=stat.executeUpdate(sql1); + break; + // if updateType is DELETE + case DELETE: + sql1="delete from \"medien\" where \"id\"= "+change.id+" ;"; + System.out.println(sql1); + Return=stat.executeUpdate(sql1); + break; + default : return -1; + } + // perform operation on table an return number of updated rows + }catch(SQLException e){ + System.out.println("Exception in PGSqlInput.changeMedia: "+e); + } + */ + } + +/* + * returns an ArrayList of Results which are matching to the commited Find object + * + * @param media + * Object which describes search criterias + * @return ArrayList + * List with Results matching search criteria + */ + public void search(String str, MediaType[] types, MediasHolder result, YalpErrorHolder err) { + /* t.b.d. alter this to new database design + try{ + ArrayList searchWords=stringCut(media.str); + String query= new String(); + Boolean first; + for (int i=0;i resultList=new ArrayList(); + Statement stat= con.createStatement(); + ResultSet result=stat.executeQuery(query); + while(result.next()){ + resultList.add( new Result(result.getInt(1),result.getString(2),result.getString(3),result.getString(4),result.getString(5),result.getString(6),result.getString(7),result.getString(8),result.getInt(9),result.getInt(10),result.getString(11),result.getInt(12),result.getString(13),result.getString(14),result.getString(15))); + } + return resultList; + }catch(SQLException e){ + System.out.println("Exception in PGSqlInput.search: "+e); + return new ArrayList(); + } + */ + } + +/* + * cuts Strings and returns an ArrayList of the cutted Strings + * + * @param str + * String to cut + * @return ArrayList + * ArrayList with cutted Strings + */ + private ArrayList stringCut (String str){ + int i=0,j=0; + ArrayList list= new ArrayList(); + while(j!=-1){ + j=str.indexOf(" ",i); + if (j!=-1){ + list.add(new String (str.substring(i,j))); + i=j+1; + } else list.add(new String (str.substring(i,str.length()))); + } + return list; + } + +/* + * returns number of medias in database + * + * @return String + * Number of medias in database + */ + public void getNumOfMedias(IntHolder num, YalpErrorHolder err) { + try{ + ResultSet result=this.stat.executeQuery("select count (\"id\") from \"medien\";"); + result.next(); + num = new IntHolder(new Integer(result.getString(1))); + }catch(SQLException e){ + System.out.println("exception in PGSql Input getNumOfMedias: "+e); + YalpError error = new YalpError(); + error.code = YalpErrorCode.ERROR_SQL; + error.level= YalpErrorLevel.ERROR_LEVEL_ERROR; + error.descr= e.toString(); + err = new YalpErrorHolder(error); + } + } + +/* + * returns plugin information + * @param PluginInfoHolder info holder for PluginInformation + * @param YalpErrorHolder err holder for error information + */ + public void getInfo(PluginInfoHolder info, YalpErrorHolder err) + { + info = new PluginInfoHolder(pluginInfo); + } +} diff --git a/src/YalpInputs/YalpPGSqlInput/YalpPGSqlInput.java b/src/YalpInputs/YalpPGSqlInput/YalpPGSqlInput.java new file mode 100644 index 0000000..b816542 --- /dev/null +++ b/src/YalpInputs/YalpPGSqlInput/YalpPGSqlInput.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpInputs.YalpPGSqlInput; + +import YalpInterfaces.*; + +/* + * Class YalpPGSqlInput + * + * Implements functionality of the DBConnectionInterface + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006
+ */ +public class YalpPGSqlInput { + private YalpInputInterfaceImpl con; + private DatabaseDefines config; + + public static void main(String[] args) + { + System.out.println("YalpPGSqlInput\n"); + PGSqlInput input = new PGSqlInput(args); + } +} diff --git a/src/YalpInputs/YalpPGSqlInput/db-design-backup.sql b/src/YalpInputs/YalpPGSqlInput/db-design-backup.sql new file mode 100644 index 0000000..0ab8d4d --- /dev/null +++ b/src/YalpInputs/YalpPGSqlInput/db-design-backup.sql @@ -0,0 +1,321 @@ +-- +-- PostgreSQL database dump +-- + +-- Started on 2008-09-23 20:48:41 CEST + +SET client_encoding = 'UNICODE'; +SET check_function_bodies = false; +SET client_min_messages = warning; + +-- +-- TOC entry 1518 (class 0 OID 0) +-- Dependencies: 5 +-- Name: SCHEMA public; Type: COMMENT; Schema: -; Owner: postgres +-- + +COMMENT ON SCHEMA public IS 'Standard public schema'; + + +SET search_path = public, pg_catalog; + +SET default_tablespace = ''; + +SET default_with_oids = false; + +-- +-- TOC entry 1170 (class 1259 OID 17306) +-- Dependencies: 1491 5 +-- Name: IntProperties; Type: TABLE; Schema: public; Owner: yalp; Tablespace: +-- + +CREATE TABLE "IntProperties" ( + id bigserial NOT NULL, + description "char", + value integer +); + + +ALTER TABLE public."IntProperties" OWNER TO yalp; + +-- +-- TOC entry 1520 (class 0 OID 0) +-- Dependencies: 1169 +-- Name: IntProperties_id_seq; Type: SEQUENCE SET; Schema: public; Owner: yalp +-- + +SELECT pg_catalog.setval(pg_catalog.pg_get_serial_sequence('"IntProperties"', 'id'), 1, false); + + +-- +-- TOC entry 1172 (class 1259 OID 17313) +-- Dependencies: 1492 5 +-- Name: Medias; Type: TABLE; Schema: public; Owner: yalp; Tablespace: +-- + +CREATE TABLE "Medias" ( + id bigserial NOT NULL, + "type" character(1), + path "char", + "fileName" "char", + tags "char"[], + duration "char" +); + + +ALTER TABLE public."Medias" OWNER TO yalp; + +-- +-- TOC entry 1521 (class 0 OID 0) +-- Dependencies: 1171 +-- Name: Medias_id_seq; Type: SEQUENCE SET; Schema: public; Owner: yalp +-- + +SELECT pg_catalog.setval(pg_catalog.pg_get_serial_sequence('"Medias"', 'id'), 1, false); + + +-- +-- TOC entry 1174 (class 1259 OID 17323) +-- Dependencies: 1493 1494 1495 5 +-- Name: PropertyConnector; Type: TABLE; Schema: public; Owner: yalp; Tablespace: +-- + +CREATE TABLE "PropertyConnector" ( + "mediaId" integer, + "stringPropertyId" integer DEFAULT 0, + "intPropertyId" integer DEFAULT 0, + id bigserial NOT NULL +); + + +ALTER TABLE public."PropertyConnector" OWNER TO yalp; + +-- +-- TOC entry 1168 (class 1259 OID 17294) +-- Dependencies: 1490 5 +-- Name: StringProperties; Type: TABLE; Schema: public; Owner: yalp; Tablespace: +-- + +CREATE TABLE "StringProperties" ( + id bigserial NOT NULL, + description "char", + value "char" +); + + +ALTER TABLE public."StringProperties" OWNER TO yalp; + +-- +-- TOC entry 1522 (class 0 OID 0) +-- Dependencies: 1167 +-- Name: StringProperties_id_seq; Type: SEQUENCE SET; Schema: public; Owner: yalp +-- + +SELECT pg_catalog.setval(pg_catalog.pg_get_serial_sequence('"StringProperties"', 'id'), 1, false); + + +-- +-- TOC entry 1165 (class 1259 OID 17269) +-- Dependencies: 1488 1489 5 +-- Name: Users; Type: TABLE; Schema: public; Owner: yalp; Tablespace: +-- + +CREATE TABLE "Users" ( + name "char"[] NOT NULL, + "realName" name[], + "level" integer DEFAULT 1 NOT NULL, + id bigserial NOT NULL +); + + +ALTER TABLE public."Users" OWNER TO yalp; + +-- +-- TOC entry 1523 (class 0 OID 0) +-- Dependencies: 1166 +-- Name: Users_id_seq; Type: SEQUENCE SET; Schema: public; Owner: yalp +-- + +SELECT pg_catalog.setval(pg_catalog.pg_get_serial_sequence('"Users"', 'id'), 1, false); + + +-- +-- TOC entry 1524 (class 0 OID 0) +-- Dependencies: 1173 +-- Name: propertyConnector_id_seq; Type: SEQUENCE SET; Schema: public; Owner: yalp +-- + +SELECT pg_catalog.setval(pg_catalog.pg_get_serial_sequence('"PropertyConnector"', 'id'), 1, false); + + +-- +-- TOC entry 1513 (class 0 OID 17306) +-- Dependencies: 1170 +-- Data for Name: IntProperties; Type: TABLE DATA; Schema: public; Owner: yalp +-- + +COPY "IntProperties" (id, description, value) FROM stdin; +\. + + +-- +-- TOC entry 1514 (class 0 OID 17313) +-- Dependencies: 1172 +-- Data for Name: Medias; Type: TABLE DATA; Schema: public; Owner: yalp +-- + +COPY "Medias" (id, "type", path, "fileName", tags, duration) FROM stdin; +\. + + +-- +-- TOC entry 1515 (class 0 OID 17323) +-- Dependencies: 1174 +-- Data for Name: PropertyConnector; Type: TABLE DATA; Schema: public; Owner: yalp +-- + +COPY "PropertyConnector" ("mediaId", "stringPropertyId", "intPropertyId", id) FROM stdin; +\. + + +-- +-- TOC entry 1512 (class 0 OID 17294) +-- Dependencies: 1168 +-- Data for Name: StringProperties; Type: TABLE DATA; Schema: public; Owner: yalp +-- + +COPY "StringProperties" (id, description, value) FROM stdin; +\. + + +-- +-- TOC entry 1511 (class 0 OID 17269) +-- Dependencies: 1165 +-- Data for Name: Users; Type: TABLE DATA; Schema: public; Owner: yalp +-- + +COPY "Users" (name, "realName", "level", id) FROM stdin; +\. + + +-- +-- TOC entry 1507 (class 16386 OID 17329) +-- Dependencies: 1174 1174 +-- Name: key_id_con; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "PropertyConnector" + ADD CONSTRAINT key_id_con PRIMARY KEY (id); + + +ALTER INDEX public.key_id_con OWNER TO yalp; + +-- +-- TOC entry 1497 (class 16386 OID 17291) +-- Dependencies: 1165 1165 +-- Name: key_is_id; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "Users" + ADD CONSTRAINT key_is_id PRIMARY KEY (id); + + +ALTER INDEX public.key_is_id OWNER TO yalp; + +-- +-- TOC entry 1501 (class 16386 OID 17298) +-- Dependencies: 1168 1168 +-- Name: prim_key_id; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "StringProperties" + ADD CONSTRAINT prim_key_id PRIMARY KEY (id); + + +ALTER INDEX public.prim_key_id OWNER TO yalp; + +-- +-- TOC entry 1503 (class 16386 OID 17310) +-- Dependencies: 1170 1170 +-- Name: prim_key_int_id; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "IntProperties" + ADD CONSTRAINT prim_key_int_id PRIMARY KEY (id); + + +ALTER INDEX public.prim_key_int_id OWNER TO yalp; + +-- +-- TOC entry 1505 (class 16386 OID 17320) +-- Dependencies: 1172 1172 +-- Name: prim_key_m_id; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "Medias" + ADD CONSTRAINT prim_key_m_id PRIMARY KEY (id); + + +ALTER INDEX public.prim_key_m_id OWNER TO yalp; + +-- +-- TOC entry 1499 (class 16386 OID 17278) +-- Dependencies: 1165 1165 +-- Name: user_name_unique; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "Users" + ADD CONSTRAINT user_name_unique UNIQUE (name); + + +ALTER INDEX public.user_name_unique OWNER TO yalp; + +-- +-- TOC entry 1509 (class 16386 OID 17334) +-- Dependencies: 1174 1170 1502 +-- Name: int_prop; Type: FK CONSTRAINT; Schema: public; Owner: yalp +-- + +ALTER TABLE ONLY "PropertyConnector" + ADD CONSTRAINT int_prop FOREIGN KEY ("intPropertyId") REFERENCES "IntProperties"(id); + + +-- +-- TOC entry 1508 (class 16386 OID 17330) +-- Dependencies: 1174 1172 1504 +-- Name: media_prop; Type: FK CONSTRAINT; Schema: public; Owner: yalp +-- + +ALTER TABLE ONLY "PropertyConnector" + ADD CONSTRAINT media_prop FOREIGN KEY ("mediaId") REFERENCES "Medias"(id); + + +-- +-- TOC entry 1510 (class 16386 OID 17338) +-- Dependencies: 1174 1168 1500 +-- Name: string_prop; Type: FK CONSTRAINT; Schema: public; Owner: yalp +-- + +ALTER TABLE ONLY "PropertyConnector" + ADD CONSTRAINT string_prop FOREIGN KEY ("stringPropertyId") REFERENCES "StringProperties"(id); + + +-- +-- TOC entry 1519 (class 0 OID 0) +-- Dependencies: 5 +-- Name: public; Type: ACL; Schema: -; Owner: postgres +-- + +REVOKE ALL ON SCHEMA public FROM PUBLIC; +REVOKE ALL ON SCHEMA public FROM postgres; +GRANT ALL ON SCHEMA public TO postgres; +GRANT ALL ON SCHEMA public TO yalp; +GRANT ALL ON SCHEMA public TO PUBLIC; + + +-- Completed on 2008-09-23 20:48:41 CEST + +-- +-- PostgreSQL database dump complete +-- + diff --git a/src/YalpOutputs/YalpVlcTelnetOutput/TelnetInterface.java b/src/YalpOutputs/YalpVlcTelnetOutput/TelnetInterface.java new file mode 100644 index 0000000..c8441ac --- /dev/null +++ b/src/YalpOutputs/YalpVlcTelnetOutput/TelnetInterface.java @@ -0,0 +1,147 @@ +/*********************************************************************** + * + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + * + ************************************************************************/ + +package YalpOutputs.YalpVlcTelnetOutput; + +import java.net.Socket; +import java.io.*; + +import org.apache.commons.net.telnet.*; + +/******************************************************************************* +* +* Class TelnetInterface +* +* handels telnet connection +* +* @author Volker Dahnke / Manuel Traut +* +* @version 0.1 20-11-2005
+* +* @see VlcStreamer +* +******************************************************************************/ +public class TelnetInterface { + + private PrintStream out; + private InputStream in; + private TelnetClient tc = new TelnetClient(); + + /** + * creates socket, logs on + * + * @param host + * hostname of telnetserver + * @param port + * destination port + * @param pass + * password + * + */ + + public TelnetInterface(String host, int port, String pass){ + try{ + this.tc.connect(host,port); + this.out = new PrintStream(this.tc.getOutputStream()); + this.in = this.tc.getInputStream(); + } catch(IOException e){ + System.out.println("server.TelnetInterface.java: Telnet connection "+host+":"+port+" failed"); + return; + } + + readUntil( "Password:" ); + write(pass); + // Advance to a prompt + readUntil("> "); + } + + /** + * write to TelnetInterface + * @param value + * String to write to Interface + */ + public void write( String value ) { + try { + out.println( value ); + out.flush(); + System.out.println( value ); + } + catch( Exception e ) { + e.printStackTrace(); + } + } + + /** + * reads output of telnet client + * @param pattern + * for stop reading + * @return String + */ + public String readUntil( String pattern ) { + try { + char lastChar = pattern.charAt( pattern.length() - 1 ); + StringBuffer sb = new StringBuffer(); + char ch = ( char )in.read(); + while( true ) { + System.out.print( ch ); + sb.append( ch ); + if( ch == lastChar ) { + if( sb.toString().endsWith( pattern ) ) { + return sb.toString(); + } + } + ch = ( char )in.read(); + } + } + catch( Exception e ) { + e.printStackTrace(); + } + return null; + } + + /** + * executes command + * @param cmd + * any telnet command + * @return String + * telnet output caused by the command + * null if failed + */ + public String exec(String cmd){ + + try { + write(cmd); + return readUntil( "> " ); + } + catch( Exception e ) { + e.printStackTrace(); + } + return null; + } + + /** + * close telnet connection + * + * @return boolean + * true: connection closed + * false: connection close failed + */ + + public boolean close(){ + try { + this.tc.disconnect(); + } catch(IOException e){ + return false; + } + return true; + } +} diff --git a/src/YalpOutputs/YalpVlcTelnetOutput/VlcStreamer.java b/src/YalpOutputs/YalpVlcTelnetOutput/VlcStreamer.java new file mode 100644 index 0000000..568bfb8 --- /dev/null +++ b/src/YalpOutputs/YalpVlcTelnetOutput/VlcStreamer.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpOutputs.YalpVlcTelnetOutput; + +import YalpInterfaces.*; + +import java.io.*; +import java.util.LinkedList; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; +import org.omg.PortableServer.*; +import org.omg.PortableServer.POA; + +/* + * + * Class VlcStreamer + * + * Controlling Streams on a high level + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.6 04-12-2005
+ * + * @see InitServer + */ +public class VlcStreamer { + + private static ORB orb; + private static POA poa; + private static YalpOutputPluginImpl streamer; + private static OutputPluginInterface outputPlugin; + private static ServerControlInterface srvCon; + private static PluginInfo pluginInfo; +/* + * starts a vlc player in a new process + * + * @param serverIP + * where vlcStreamer is running + * @param startport + * first port used for streaming + * @param vlcCmd + * path and name of vlc player executable + * @param args + * from cmd line + */ + public VlcStreamer(String serverIP, int startport, String vlcCmd, + String[] argv) { + + pluginInfo = new PluginInfo(); + pluginInfo.name = "VLC Telnet Streamer"; + pluginInfo.description = "creates streams via VLC players telnet interface"; + pluginInfo.type = PluginType.OUTPUT_PLUGIN; + pluginInfo.supportedTypes = new MediaType[0]; + pluginInfo.access = new AccessInfo(); + pluginInfo.access.name = "stream provided by vlc player"; + pluginInfo.access.description = "streams can be displayed with vlc player"; + pluginInfo.access.executable = "vlc"; + pluginInfo.access.params = ""; + pluginInfo.access.type = AccessType.STREAM; + + try { + this.orb = ORB.init(argv, null); + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); + } catch(Exception e) { + /* t.b.d. error handling */ + System.out.println("couldn't host plugin implementation"); + } + + try { + poa.the_POAManager().activate(); + } catch(org.omg.PortableServer.POAManagerPackage.AdapterInactive e) { + /* t.b.d. error handling */ + System.out.println("poa inactive"); + } +/* + YalpError error = new YalpError(); + error.msg = ""; + error.descr = ""; + error.code = YalpErrorCode.OK; + error.level= YalpErrorLevel.ERROR_LEVEL_INFO; + */ + YalpErrorHolder err = new YalpErrorHolder(/*error*/); + + try { + /* only start vlc player if it isn't currently running */ + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + String name = "YALP_Server"; + srvCon = ServerControlInterfaceHelper.narrow(ncRef.resolve_str(name)); + } catch (Exception e) { + System.out.println("Couldn't connect to YALP Server"); + System.exit(0); + } + + streamer = new YalpOutputPluginImpl(); + streamer.setORB(orb); + + try { + poa.activate_object(streamer); + org.omg.CORBA.Object ref = poa.servant_to_reference(streamer); + outputPlugin = OutputPluginInterfaceHelper.narrow(ref); + + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + String name = "YALP_Vlc_Telnet_Streamer_Output"; + NameComponent path[] = ncRef.to_name(name); + ncRef.rebind(path, outputPlugin); + + PluginInfoHolder tmp = new PluginInfoHolder(pluginInfo); + srvCon.ping(err); + System.out.println(err.value.descr); + srvCon.registerOutputPlugin(outputPlugin, tmp, err ); + pluginInfo = tmp.value; + + if(err.value.code != YalpErrorCode.OK) + System.out.println("registring outputplugin failed"); + else + System.out.println("output plugin registered"); + + orb.run(); + + } catch (Exception e) { + System.out.println("binding plugin failed 1"); + e.printStackTrace(); + System.exit(0); + } + } +} diff --git a/src/YalpOutputs/YalpVlcTelnetOutput/YalpOutputPluginImpl.java b/src/YalpOutputs/YalpVlcTelnetOutput/YalpOutputPluginImpl.java new file mode 100644 index 0000000..50bdaa4 --- /dev/null +++ b/src/YalpOutputs/YalpVlcTelnetOutput/YalpOutputPluginImpl.java @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2008 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut + */ + +package YalpOutputs.YalpVlcTelnetOutput; + +import YalpInterfaces.*; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; + +import java.util.*; +import java.io.IOException; + +/* + * Class YalpOutputPluginImpl + * + * Implements VLC Telnet Streamer as YALP Plugin + * + * @author Volker Dahnke / Manuel Traut + * @version 0.7 10-09-2008 + */ +public class YalpOutputPluginImpl extends OutputPluginInterfacePOA { + + private ORB orb; + private static Process vlcPlayer = null; + private StreamCounter streamCounter= new StreamCounter(); + private LinkedList currentStreams = new LinkedList(); + private int startPort; + private String hostIP; + private String vlcCommand; + private ServerControlInterface srvCon; + private PluginInfo pluginInfo; + +/* + * starts a vlc player in a new process + * + * @param serverIP + * where vlcStreamer is running + * @param startport + * first port used for streaming + * @param vlcCmd + * path and name of vlc player executable + * + * @throws RemoteException + * @throws ClassNotFoundException + */ + public void setORB(ORB _orb) { + orb = _orb; + + pluginInfo = new PluginInfo(); + pluginInfo.name = "VLC Telnet Streamer"; + pluginInfo.description = "creates streams via VLC players telnet interface"; + pluginInfo.type = PluginType.OUTPUT_PLUGIN; + pluginInfo.access = new AccessInfo(); + pluginInfo.access.name = "stream provided by vlc player"; + pluginInfo.access.description = "streams can be displayed with vlc player"; + pluginInfo.access.executable = "vlc"; + pluginInfo.access.params = ""; + pluginInfo.access.type = AccessType.STREAM; + + /* t.b.d. read vlccmod, startport, hostip from config xml */ + String vlcCmd = "/usr/bin/vlc"; + vlcCommand = vlcCmd + " --reset-config -I telnet"; + startPort = 9000; + hostIP = "127.0.0.1"; + + if(vlcPlayer == null){ + try{ + vlcPlayer = Runtime.getRuntime().exec(this.vlcCommand); + } catch(IOException e){ + System.out.println("server.VlcStreamer.java: Streamingserver failed"); + } + } + } + + public void shutdown() { + /* t.b.d. */ + } + +/* + * controls Streaming (start, stop, etc) + * + * @param howtoStream + * specifies streaming options + */ + public void control(OutputHolder howtoStream, YalpErrorHolder err) { + + switch( howtoStream.value.outputAction.value() ) { + + case Action._START: + start(howtoStream.value); + break; + + case Action._STOP: + stop(howtoStream.value); + break; + + case Action._PAUSE: + pause(howtoStream.value); + break; + + case Action._PLAY: + play(howtoStream.value); + break; + + case Action._FORWARD: + next(howtoStream.value); + break; + + //add sth. to current playing stream + case Action._CREATE: + add(howtoStream.value); + break; + + default: + System.out.println("server.VlcStreamer.control: action not supported"); + break; + } + } + +/* + * get plugin infos + * + * @param PluginInfoHolder (out) + * @param YalpErrorHolder (out) + */ + public void getInfo(PluginInfoHolder info, YalpErrorHolder err) + { + info = new PluginInfoHolder(); + err = new YalpErrorHolder(); + err.value.code = YalpErrorCode.OK; + info.value = pluginInfo; + } + +/* + * request Streaming of submitted Output + * + * @param stream + * which should be streamed + * @return Output + * extends Information "how to receive" of submitted Output + */ + public Output request(Output stream) { + //stream.setIP(hostIP); for UDP + stream.info.name = streamName(); + stream.info.params = new Integer(++startPort).toString(); + currentStreams.add(stream); + return stream; + } + + + /** + * starts streaming of submitted streamInfo + * @param howtoStream + */ + private void start(Output howtoStream){ + /* + String newString, setup2; + this.streamCounter.actualStreams++; + this.streamCounter.allStreams++; + + switch (howtoStream.info.type.value()){ + case AccessType._VOD: + newString = "new "+howtoStream.info.name+" vod enabled"; + break; + case AccessType._BROADCAST: + newString = "new "+howtoStream.info.name+" broadcast enabled"; + break; + default: + newString =""; + System.out.println("server.VlcStreamer.start: unsupported Type"); + break; + } + + String comp = "#transcode{vcodec=mp2v,vb=1024,scale=1,acodec=mpga,ab=192,channels=2}:duplicate{dst="; + + setup2 = "setup "+howtoStream.info.name+" output "+comp+"std{"; + + switch (howtoStream.access_type.value()){ + case Access._STREAM: + setup2 += "access=http,"; + break; + case Access._UDP: + setup2 += "access=udp,"; + break; + default: + System.out.println("server.VlcStreamer.start: unsupported Accesstype"); + break; + } + + switch (howtoStream.mux_type.value()){ + case Mux._TS: + setup2 += "mux=ts,url="+howtoStream.ip+":"+howtoStream.port+"}"; + break; + case Mux._ES: + setup2 += "mux=es,url="+howtoStream.ip+":"+howtoStream.port+"}"; + break; + case Mux._OGG: + setup2 += "mux=ogg,url="+howtoStream.ip+":"+howtoStream.port+"}"; + break; + default: + System.out.println("server.VlcStreamer.start: unsupported Muxer"); + break; + } + + // DEBUG COMP + setup2 += "}"; + + String control = "control "+howtoStream.info.name+" play"; + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + // execute telnet commands + telnet.exec(newString); + + // Playlist + String input = ""; + for(int i=0; i < howtoStream.list.length; i++){ + input = "setup "+howtoStream.info.name+" "; + String fileItem = howtoStream.list[i]; + fileItem.replace(" ", "\\ "); + input += fileItem; + telnet.exec(input); + } + + telnet.exec(setup2); + telnet.exec(control); + + // close telnet connection + telnet.close(); + */ + } + + /** + * plays submitted streamInfo + * @param howtoStream + */ + private void play(Output howtoStream){ + + String control = "control "+howtoStream.info.name+" play"; + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + telnet.exec(control); + + // close telnet connection + telnet.close(); + } + + /** + * pause submitted streamInfo + * @param howtoStream + */ + private void pause(Output howtoStream){ + + String control = "control "+howtoStream.info.name+" pause"; + + // DEBUG + System.out.println("client.VlcStreamer: Telnetcmd: "); + System.out.println(control); + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + telnet.exec(control); + + // close telnet connection + telnet.close(); + } + + /** + * go to next file in playlist + * + * @param howtoStream + */ + private void next(Output howtoStream){ + + String control = "control "+howtoStream.info.name+" seek 100"; + + // DEBUG + System.out.println("client.VlcStreamer: Telnetcmd: "); + System.out.println(control); + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + telnet.exec(control); + + // close telnet connection + telnet.close(); + } + + /** + * stop streaming, delete stream + * + * @param howtoStream + */ + private void stop(Output howtoStream){ + + String del = "del "+howtoStream.info.name; + this.streamCounter.actualStreams--; + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + telnet.exec(del); + + // close telnet connection + telnet.close(); + + currentStreams.remove(howtoStream); + } + + /** + * register Stream at vlcPlayer + * @param howtoStream + */ + private void add(Output howtoStream){ + + String input = ""; + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + for(int i=0; i < howtoStream.playlist.length; i++){ + input += "setup "+howtoStream.info.name+" "; + input += howtoStream.playlist[i]; + telnet.exec(input); + input = ""; + } + telnet.close(); + } + + /** + * calculates streamName + * @return String streamName + */ + + private String streamName(){ + String streamName = "stream"; + streamName += streamCounter.allStreams; + return streamName; + } + + /** + * stops the streaming server + * + */ + + public void quit(){ + vlcPlayer.destroy(); + } + + /** + * returns the streamcounter + * @return StreamCounter + */ + public StreamCounter getStreamCounter(){ + return this.streamCounter; + } +} diff --git a/src/YalpOutputs/YalpVlcTelnetOutput/YalpVlcTelnetOutput.java b/src/YalpOutputs/YalpVlcTelnetOutput/YalpVlcTelnetOutput.java new file mode 100644 index 0000000..766936d --- /dev/null +++ b/src/YalpOutputs/YalpVlcTelnetOutput/YalpVlcTelnetOutput.java @@ -0,0 +1,20 @@ +package YalpOutputs.YalpVlcTelnetOutput; + +import YalpInterfaces.*; + +public class YalpVlcTelnetOutput { + + public static void main(String[] args) { + + try { + System.setProperty("java.security.policy","output.policy"); + } + catch (Exception e) {//DEBUG + System.out.println ("Output SecurityManager File not found" + e); + System.exit(0); + } + + VlcStreamer vlc = new VlcStreamer("localhost", 2501, "/usr/bin/vlc", args); + System.out.println("VlcTelnetOutput"); + } +} diff --git a/src/YalpServer/FileBrowser.java b/src/YalpServer/FileBrowser.java new file mode 100755 index 0000000..2f2a3a5 --- /dev/null +++ b/src/YalpServer/FileBrowser.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpServer; + +import java.util.ArrayList; +import java.io.File; +import java.io.Serializable; + +import YalpInterfaces.*; + +/* + * Class FileBrowser + * + * each Admin Client has his own FileBrowser, to browse through the + * subDirectories of the as startDir defined Directory + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.6 14-12-2005
+ * + * @see client.GUI.Browser + */ + +public class FileBrowser { + + private File actualFile, startDir; + private String owner; + private String userName; + private ArrayList fileList; + + /* t.b.d. add some more types */ + private String[] extensions = {".mp3",".mpg",".mpeg",".avi"}; + +/* + * Constructor starts Browsing in startDir + * + * @param startdir + * directory which could be browser recursively + * @param owner + * of the Browser (IP of the Client) + * @param userName + * of the Admin using this browser + */ + + public FileBrowser(String startdir, String owner,String userName) { + this.owner = owner; + this.userName=userName; + this.actualFile = new File(startdir); + this.startDir = new File(startdir); + this.fileList = new ArrayList(); + } + +/* + * returns owner of the browser + * + * @return String + * owner + */ + + public String getOwner(){ + return this.owner; + } + +/* + * returns user of the browser + * + * @return String + * user + */ + + public String getUserName(){ + return this.userName; + } + +/* + * returns list of all files in actual Folder + * (none recursive) + * + * @return ArrayList + * list of all files + */ + + public ArrayList getFiles(){ + return this.fileList; + } + +/* + * returns list of all files in actual Folder + * (recursive) + * + * @return ArrayList + * list of all files + */ + + public ArrayList findAll() { + + System.out.println( "server.FileBrowser.findAll: lookin in - " + + this.actualFile.toString() ); + + FileFinder ff = new FileFinder(actualFile.getPath(), extensions); + return ff.getFiles(); + } + +/* + * change actual Folder + * + * @param dirName + * String dir to change to + */ + + public void changeDir(String dirName) { + + this.actualFile = new File(this.startDir+dirName); + this.fileList.clear(); + + if(actualFile.isDirectory()) { + for ( File aFile : this.actualFile.listFiles() ) { + /* add to fileList if extension is allowed or File is a Directory */ + if (match(aFile.getName(), extensions) || aFile.isDirectory()) + { + YalpFile tmp = new YalpFile(); + tmp.name = aFile.getName(); + tmp.isDir = aFile.isDirectory(); + tmp.parent = aFile.getParent(); + this.fileList.add( tmp ); + } + } + } + } + +/* + * prints current directory out to console + * + * (for debugging) + */ + + public void printActualDir(){ + for(YalpFile one : this.fileList){ + if(one.isDir) System.out.print("+"); + else System.out.print("|"); + System.out.println(one.name); + } + } + +/* + * checks if file extension matches or not + * + * @param s + * fileName including Extension + * @param suffixes + * Array of allowed Extensions + * @return boolean + * true if yalp can handle this extension, else false + */ + + private static boolean match( String s, String suffixes[] ) { + for ( String suffix : suffixes ) { + int huhu = s.length(); + int huhu2 = suffix.length(); + int huhu3 = huhu - huhu2; + if ( s.length() >= suffix.length() && + s.substring( huhu3, s.length()).equalsIgnoreCase(suffix) ) + return true; + } + return false; + } +} diff --git a/src/YalpServer/FileFinder.java b/src/YalpServer/FileFinder.java new file mode 100755 index 0000000..2d6527c --- /dev/null +++ b/src/YalpServer/FileFinder.java @@ -0,0 +1,110 @@ +/*********************************************************************** + * + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + * + ***********************************************************************/ +package YalpServer; + +import java.io.*; +import java.util.*; + +/************************************************************************ + * + * Class FileFinder + * + * algorithm for scanning files recursively + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.6 14-12-2005
+ * + * @see FileBrowser + * + ************************************************************************/ + +public class FileFinder +{ + private ArrayList files; + + /** + * Constructor: scans subdirectories of commited directory + * uses only files with allowed extensions + * @param start + * directory to scan + * @param extensions + * allowed extensions + */ + public FileFinder( String start, String extensions[] ) { + + this.files = new ArrayList(); + Stack dirs = new Stack(); + File startdir = new File(start); + + // push startdir to stack + if (startdir.isDirectory()) dirs.push(startdir); + // startdir is File + else { + if (match(startdir.getName(), extensions)) this.files.add(startdir); + return; + } + // for each dir on stack + while (dirs.size() > 0) { + // contents of dir on stack + for (File file : dirs.pop().listFiles()){ + try { + // add subdirectory to stack + if (file.isDirectory()) dirs.push(file); + // if file is of correct filetype add it to filelist + else if (match(file.getName(), extensions)) this.files.add(file); + } catch (NullPointerException e) { + System.out.println("FileFinder: "+ file.getName() +"Premission denied"); + } + } + } + } + + /** + * returns and prints out all Medias found + * @return ArrayList + * all found Medias + */ + public ArrayList getFiles(){ + print(); + return this.files; + } + + /** + * prints out found medias + * + */ + public void print() { + System.out.println( "Found " + files.size() + " file" + (files.size() == 1 ? "." : "s.") ); + for ( File f : files ) System.out.println( f.getAbsolutePath() ); + } + + /** + * checks if file extension matches or not + * + * @param s + * file to check + * @param suffixes + * allowed extensions + * + * @return boolean: true if it's a media, yalp can handle + */ + private static boolean match( String s, String suffixes[] ) { + for ( String suffix : suffixes ) { + int huhu = s.length(); + int huhu2 = suffix.length(); + int huhu3 = huhu - huhu2; + if ( s.length() >= suffix.length() && s.substring(huhu3, s.length()).equalsIgnoreCase(suffix) ) return true; + } + return false; + } +} diff --git a/src/YalpServer/FileInfoManager.java b/src/YalpServer/FileInfoManager.java new file mode 100755 index 0000000..34fe49b --- /dev/null +++ b/src/YalpServer/FileInfoManager.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpServer; + +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +import de.hampelratte.id3.*; + +import YalpInterfaces.*; + +/* + * Class FileInfoManager + * + * Creates a Result out of FileInformations (ID3, etc) + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.1 14-12-2005
+ * + * @see ServerControl + */ + +public class FileInfoManager { + + private Media fileInfo; + private EncodingType eType; + +/* + * Constructor: tries to get all Informations about a file + * + * @param file + */ + + public FileInfoManager(File file) { + + this.eType = EncodingType.UNKNOWN; + this.fileInfo = new Media(); + this.fileInfo.path = file.getParent()+file.separator; + this.fileInfo.fileName = file.getName(); + + /* check extensions is mp3 */ + if( this.fileInfo.fileName.substring( this.fileInfo.fileName.length() - 3, + this.fileInfo.fileName.length()).equalsIgnoreCase( "mp3" ) ) + { + this.eType = EncodingType.MP3; + } + + switch(this.eType.value()) { + case EncodingType._MP3: + try + { + /* opening mp3 file for reading and writing */ + MP3File mp3 = new de.hampelratte.id3.MP3File(file.toString(), "r"); + this.fileInfo.type = MediaType.SOUND; + + if(mp3.hasID3v1Tag){ + ID3v1Tag tag = mp3.readID3v1Tag(); + /* t.b.d. create StringProperties + this.fileInfo.album = tag.getAlbum(); + this.fileInfo.author = tag.getArtist(); + this.fileInfo.category = tag.getGenre(); + this.fileInfo.name = tag.getTrack() +" - "+tag.getTitle(); + this.fileInfo.year = tag.getYear(); + */ + } + + if(mp3.hasID3v2Tag){ + + // reading the ID3v2Tag + ID3v2Tag tag = mp3.readID3v2Tag(); + /* t.b.d. create StringProperties + this.fileInfo.album = tag.getAlbum(); + this.fileInfo.author = tag.getArtist(); + this.fileInfo.category = tag.getGenre(); + this.fileInfo.year = tag.getYear(); + */ + if( !(tag.getTrack().equals(""))){ + this.fileInfo.name = tag.getTrack() +" - "+tag.getTitle(); + } else { + this.fileInfo.name = tag.getTitle(); + } + } + + if (this.fileInfo.name.equals("")) { + + this.fileInfo.name = + file.getName().substring( 0, file.getName().length() - 4 ); + } + + mp3.close(); + } catch (Exception e) { + + this.fileInfo.name = + file.getName().substring(0,file.getName().length() - 4); + } + break; + + default: + this.fileInfo.name = + file.getName().substring(0,file.getName().length()-4); + + this.fileInfo.type = MediaType.VIDEO; + break; + } + } + +/* + * returns the information to an media, found + * @return MediaChange + * Informations about the media + */ + + public Media getInfo(){ + return this.fileInfo; + } +} diff --git a/src/YalpServer/InitServer.java b/src/YalpServer/InitServer.java new file mode 100755 index 0000000..ac9d507 --- /dev/null +++ b/src/YalpServer/InitServer.java @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + * + */ + +package YalpServer; + +import java.net.Inet4Address; +import java.net.MalformedURLException; +import java.net.UnknownHostException; + +import java.beans.XMLDecoder; +import java.beans.XMLEncoder; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.File; + +import java.util.ArrayList; +import java.util.Properties; + +import java.security.*; + +import java.sql.SQLException; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; +import org.omg.PortableServer.*; +import org.omg.PortableServer.POA; + +import YalpInterfaces.*; + +/* + * Class InitServer + * + * Establishes DBConnection and creates VlcStreamer waits for + * further Instructions via Interfaces + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.1 20-11-2005
+ * + * @see Server + * + */ + +public class InitServer { + + private ServerSettings settings = new ServerSettings(); + private ServerControlImpl srvCon; + private ServerControlInterface srv; + private ORB orb; + private String[] orbArgs; + private POA poa; + private String serverIP; + private ArrayList browseList; + + /* + * Constructor: starts Server initialization + */ + public InitServer(String[] _orbArgs) { + + loadConfig("ServerSettings.xml"); + writeConfig("ServerSettings.xml"); + + this.browseList = new ArrayList(); + + this.orbArgs = _orbArgs; // t.b.d. read orbargs from config xml + + try { + this.serverIP = Inet4Address.getLocalHost().getHostAddress(); + } catch(UnknownHostException e) { + /* t.b.d. error handling */ + System.out.println("couldn't resolve hostname"); + } + + /* bind ServerControl to ORB and NamingService */ + this.orb = ORB.init(orbArgs, null); + + try { + this.poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); + } catch(org.omg.CORBA.ORBPackage.InvalidName e) { + /* t.b.d. error handling */ + System.out.println("couldn't get name ref of root poa"); + } + + try { + poa.the_POAManager().activate(); + } catch(org.omg.PortableServer.POAManagerPackage.AdapterInactive e) { + /* t.b.d. error handling */ + System.out.println("poa inactive"); + } + + this.srvCon = new ServerControlImpl(); + this.srvCon.setORB(this.orb); + + try { + org.omg.CORBA.Object ref = poa.servant_to_reference(this.srvCon); + this.srv = ServerControlInterfaceHelper.narrow(ref); + + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + String name = "YALP_Server"; + NameComponent path[] = ncRef.to_name(name); + ncRef.rebind(path, this.srv); + + System.out.println("YALP Server ready"); + this.orb.run(); + + } catch( org.omg.CosNaming.NamingContextPackage.InvalidName e) { + /* t.b.d. error handling */ + System.out.println("couldn't narrow ref to path"); + } catch( org.omg.CosNaming.NamingContextPackage.NotFound e) { + /* t.b.d. error handling */ + System.out.println("naming context not found, couldn't bind server ctl"); + } catch(org.omg.PortableServer.POAPackage.ServantNotActive e) { + /* t.b.d. error handling */ + System.out.println("couldn't get name ref of root poa"); + } catch (org.omg.CORBA.ORBPackage.InvalidName e) { + /* t.b.d. error handling */ + System.out.println("couldn't get NameService"); + } catch (org.omg.PortableServer.POAPackage.WrongPolicy e) { + /* t.b.d. error handling */ + System.out.println("policies not set correctly"); + } catch (org.omg.CosNaming.NamingContextPackage.CannotProceed e) { + /* t.b.d. error handling */ + System.out.println("rebind failed, cannot proceed"); + } + } + +/* + * write Configuration to XML File + * + * @param fileName + * where to write the configuration file + * @return boolean + * false - if failed + */ + + public boolean writeConfig(String fileName) { + try{ + FileOutputStream configFile = new FileOutputStream(fileName); + XMLEncoder configWriter = new XMLEncoder(configFile); + configWriter.writeObject(settings.imageDir); + configWriter.writeObject(settings.videoDir); + configWriter.writeObject(settings.soundDir); + configWriter.close(); + } catch (FileNotFoundException fnfe){ + return false; + } + return true; + } + +/* + * tries to load ServerSettings from XML File + * @param fileName + * Configuration file + * @return boolean + * false - if loading failed + */ + + public boolean loadConfig(String fileName) { + try{ + FileInputStream configFile = new FileInputStream(fileName); + XMLDecoder configLoader = new XMLDecoder(configFile); + settings.imageDir = (String)configLoader.readObject(); + settings.videoDir = (String)configLoader.readObject(); + settings.soundDir = (String)configLoader.readObject(); + configLoader.close(); + } catch(FileNotFoundException fnfe) { + System.out.println("Configuration not found, loading defaults..."); + return false; + } catch(ClassCastException cce) { + System.out.println("Errors in Configuration, loading defaults..."); + return false; + } + return true; + } + +/* + * returns actual configuration of the server + * @return ServerSettings + * actual configuration + */ + + public ServerSettings getConfig() { + return this.settings; + } + +/* + * sets and saves a new ServerConfiguration + * + * @param set + * new ServerSettings + * @return boolean + * true if succesfully saved + */ + + public boolean setConfig(ServerSettings set){ + this.settings = set; + return this.writeConfig("ServerConfiguration.xml"); + } + +/* + * t.b.d. session management + * + * Client logon (give him,his fileBrowser) + * + * @param ipAdress + * of the Client + * @param userName + * using the Client + * + + public void newClient(String ipAdress,String userName) { + this.browseList.add( new FileBrowser( this.settings.startDir, + ipAdress, + userName ) ); + } + */ + +/* + * Client logoff (free memory of his fileBrowser + * + * @param ipAdress + * of the Client + * @param userName + * using the Client + */ + + public void remClient(String ipAdress, String userName) { + for( FileBrowser aBrowser : this.browseList ) { + if( aBrowser.getOwner().equals(ipAdress) && + aBrowser.getUserName().equals(userName) ) { + this.browseList.remove(aBrowser); + break; + } + } + } + +/* + * change Directory in fileBrowser + * + * @param ip + * of the Client + * @param dir + * to which should be changed + * @return ArrayList + * content of the directory changed to + */ + + public ArrayList changeDir(String ip, String dir) { + FileBrowser aBrowser = null; + for(FileBrowser oneMoreBrowser : this.browseList) { + if( oneMoreBrowser.getOwner().equals(ip) ) { + oneMoreBrowser.changeDir(dir); + aBrowser = oneMoreBrowser; + break; + } + } + return aBrowser.getFiles(); + } + +/* + * Server Shutdown + */ + + public void serverShutdown() { + System.out.println("Server shutdown - Server is going down"); + System.exit(0); + } +} diff --git a/src/YalpServer/ServerControlImpl.java b/src/YalpServer/ServerControlImpl.java new file mode 100755 index 0000000..a88445a --- /dev/null +++ b/src/YalpServer/ServerControlImpl.java @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpServer; + +import YalpInterfaces.*; + +import java.net.*; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Properties; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; +import org.omg.PortableServer.*; +import org.omg.PortableServer.POA; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; + +/* + * Class ServerControlImpl + * + * Implements functionality of the ServerControl Interface + * + * @author Volker Dahnke / Manuel Traut + * @version 0.6 14-12-2005
+ * @see client + */ +public class ServerControlImpl extends ServerControlInterfacePOA { + + private ORB orb; + private InitServer srv; + private String log4jFile = "log4j_server.conf"; + private static Logger logger = Logger.getLogger("Yalp.Server"); + +public ServerControlImpl() { + PropertyConfigurator.configureAndWatch(log4jFile); + logger.debug("ServerControlImpl()"); +} + + public void setORB(ORB _orb) { + logger.debug("setOrb()"); + orb = _orb; + } + + public void init(InitServer srv) { + logger.debug("init()"); + this.srv=srv; + } + +/* + * client logon + * + * @param userName + * @param password + * @param ipAdress + * @param session (out) + * @param error (out) + */ + public void clientLogon( String userName, + String password, + String ipAdress, + SessionHolder session, + YalpErrorHolder err ) + { + logger.debug("clientLogon()"); + /* t.b.d. session managmnet */ + try { + System.out.println("logon: "+userName+" - "+ipAdress); + + session.value = new Session(); + session.value.id = 666; + session.value.me = new YalpUser(); + session.value.me.level = AccessRights.ADMIN; + + err.value = new YalpError(); + err.value.code = YalpErrorCode.OK; + + } catch (Exception e) { + System.out.println(e.toString()); + } + System.out.println("t.b.d. clientLogon nothing implemented at the moment"); + } + +/* + * client logoff + * + * @param session + * @param error (out) + */ + public void clientLogoff( Session bye, YalpErrorHolder err) { + logger.debug("clientLogoff"); + srv.remClient( bye.ip, bye.me.name ); + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * get user list + * + * @param user list (out) + * @param error (out) + */ + public void getUser(UsersHolder list, YalpErrorHolder err) { + logger.debug("getUser()"); + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * change user details + * + * @param user + * @param password + * @param action (create, delete, alter) + * @param error (out) + */ + public void changeUser(YalpUser usr, String passwd, Action todo, + YalpErrorHolder err) { + logger.debug("changeUser()"); + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * alter media informations + * + * @param media to change + * @param action (update, delete, create) + * @param error (out) + */ + public void changeMedia( Media toChange, Action todo, YalpErrorHolder err ) { + logger.debug("changeMedia()"); + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * count yalp medias + * + * @param num (out) + * @param error (out) + */ + public void getNumOfMedias( IntHolder num, YalpErrorHolder err ) { + logger.debug("getNumOfMedias()"); + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * control yalp medias + * + * @param control description (inout) + * @param error (out) + */ + public void control( OutputHolder ctlOutput, YalpErrorHolder err ) { + logger.debug("control()"); + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * search yalp media + * + * @param search string + * @param list of mediatypes + * @param result as list of medias (out) + */ + public void search( String str, MediaType[] types, MediasHolder result, + YalpErrorHolder err ) { + logger.debug("search()"); + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * register new output plugin + * + * @param plugin which should be registered + * @param error + */ + public void registerOutputPlugin( OutputPluginInterface itf, + PluginInfoHolder info, YalpErrorHolder err ) + { + logger.debug("registerOutputPlugin()"); + /* t.b.d. itf handling */ + System.out.println("registering output plugin: " + info.value.name ); + YalpError error = new YalpError(); + error.msg = "huhu"; + error.descr = "hihi"; + error.code = YalpErrorCode.OK; + error.level = YalpErrorLevel.ERROR_LEVEL_INFO; + err.value = error; + PluginInfo inf = new PluginInfo(); + inf.id = 666; + inf.name = info.value.name; + inf.description = info.value.description; + inf.type = info.value.type; + inf.supportedTypes= info.value.supportedTypes; + inf.access = info.value.access; + inf.maxClients = info.value.maxClients; + inf.actClients = info.value.actClients; + info.value = inf; + } + +/* + * remove output plugin + * + * @param plugin which should be registered + * @param error + */ + public void removeOutputPlugin( PluginInfo itf, YalpErrorHolder err ) + { + logger.debug("removeOutputPlugin()"); + /* t.b.d. itf handling */ + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * get all registered output plugins + * + * @param plugin list + * @param error + */ + public void getOutputPlugins( PluginInfosHolder itfs, String name, + YalpErrorHolder err ) + { + logger.debug("getOutputPlugins()"); + /* t.b.d. itf handling */ + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * register new input plugin + * + * @param plugin which should be registered + * @param error + */ + public void registerInputPlugin( org.omg.CORBA.Object itf, + PluginInfoHolder info, YalpErrorHolder err ) + { + logger.debug("registerInputPlugins()"); + /* t.b.d. itf handling */ + System.out.println("registering input plugin: " + info.value.name ); + YalpError error = new YalpError(); + error.msg = "huhu"; + error.descr = "hihi"; + error.code = YalpErrorCode.OK; + error.level = YalpErrorLevel.ERROR_LEVEL_INFO; + err.value = error; + PluginInfo inf = new PluginInfo(); + inf.id = 666; + inf.name = info.value.name; + inf.description = info.value.description; + inf.type = info.value.type; + inf.supportedTypes= info.value.supportedTypes; + inf.access = info.value.access; + inf.maxClients = info.value.maxClients; + inf.actClients = info.value.actClients; + info.value = inf; } + +/* + * remove input plugin + * + * @param plugin which should be registered + * @param error + */ + public void removeInputPlugin( PluginInfo itf, YalpErrorHolder err ) + { + logger.debug("removeInputPlugin()"); + /* t.b.d. itf handling */ + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * get all registered input plugins + * + * @param plugin list + * @param error + */ + public void getInputPlugins( PluginInfosHolder itfs, + String name, YalpErrorHolder err ) + { + logger.debug("getInputPlugins()"); + /* t.b.d. itf handling */ + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * register new auth plugin + * + * @param plugin which should be registered + * @param error + */ + public void registerAuthPlugin( org.omg.CORBA.Object itf, + PluginInfoHolder info, YalpErrorHolder err ) + { + logger.debug("registerAuthPlugin()"); + /* t.b.d. itf handling */ + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * remove input plugin + * + * @param plugin which should be registered + * @param error + */ + public void removeAuthPlugin( PluginInfo itf, + YalpErrorHolder err ) + { + logger.debug("removeAuthPlugin()"); + /* t.b.d. itf handling */ + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * get all registered auth plugins + * + * @param plugin list + * @param error + */ + public void getAuthPlugins( PluginInfosHolder itfs, + String name, YalpErrorHolder err ) + { + logger.debug("getAuthPlugins()"); + /* t.b.d. itf handling */ + YalpError error = new YalpError(); + error.code = YalpErrorCode.OK; + err = new YalpErrorHolder(error); + } + +/* + * to check if server is still ok + * + * @return Boolean true - if ok + */ + public void ping(YalpErrorHolder pong) { + logger.debug("ping()"); + YalpError err = new YalpError(); + err.descr = "PONG"; + err.msg = "huhu"; + err.level = YalpErrorLevel.ERROR_LEVEL_INFO; + err.code = YalpErrorCode.OK; + pong.value = err; + System.out.println("pong"); + } + +/* + * server shutdown + */ + public void serverShutdown() + { + logger.debug("server shutdown()"); + /* t.b.d. clear server shutdown */ + } +} diff --git a/src/YalpServer/ServerSettings.java b/src/YalpServer/ServerSettings.java new file mode 100755 index 0000000..313e875 --- /dev/null +++ b/src/YalpServer/ServerSettings.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpServer; + +/* + * Class ServerSettings + * + * + * + * @author Manuel Traut + * + * @version 0.1 27-03-2006
+ * + * @see server.InitServer + */ + +public class ServerSettings{ + + static final long serialVersionUID = 0; + + public String imageDir = "/media/image"; + public String videoDir = "/media/video"; + public String soundDir = "/media/sound"; + + /** + * set Directories which contains media Files + * @param startDir + */ + public void setImageDir(String startDir){ + this.imageDir = startDir; + } + + /** + * set Directories which contains media Files + * @param startDir + */ + public void setVideoDir(String startDir){ + this.videoDir = startDir; + } + + /** + * set Directories which contains media Files + * @param startDir + */ + public void setSoundDir(String startDir){ + this.soundDir = startDir; + } + + public String getVideoDir(){ + return this.videoDir; + } + + public String getImageDir(){ + return this.imageDir; + } + + public String getSoundDir(){ + return this.soundDir; + } +} diff --git a/src/YalpServer/YalpServer.java b/src/YalpServer/YalpServer.java new file mode 100755 index 0000000..0ddbe00 --- /dev/null +++ b/src/YalpServer/YalpServer.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ +package YalpServer; + +/* + * Class Server + * + * static main method + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.1 20-11-2005
+ */ +public class YalpServer{ + +/* + * starts Server initialization + * + * @param argv + * arguments which are not used + */ + public static void main (String[] argv) { + try{ + System.setProperty("java.security.policy","server.policy"); + } catch (Exception e) {//DEBUG + System.out.println ("Server SecurityManagerExeptions not caught jet " + e); + System.exit(0); + } + InitServer yalpServer = new InitServer(argv); + return; + } + +} diff --git a/src/yalp.idl b/src/yalp.idl new file mode 100644 index 0000000..6fb5203 --- /dev/null +++ b/src/yalp.idl @@ -0,0 +1,265 @@ +module YalpInterfaces +{ + +enum YalpErrorCode { + OK, + ERROR_SQL, + ERROR_UNDEFINED +}; + +enum YalpErrorLevel { + ERROR_LEVEL_DEBUG, + ERROR_LEVEL_INFO, + ERROR_LEVEL_ERROR, + ERROR_LEVEL_CRITICAL +}; + +struct YalpError { + string msg; + YalpErrorCode code; + YalpErrorLevel level; + string descr; +}; + +struct YalpFile { + boolean isDir; + string name; + string parent; +}; +typedef sequence YalpFiles; + +struct StreamCounter { + unsigned long actualStreams; + unsigned long allStreams; +}; + +enum AccessRights { + ADMIN, + USER, + NO_YALP_SERVER, + DENY +}; + +struct YalpUser { + unsigned long id; + string name; + string realName; + AccessRights level; +}; +typedef sequence Users; + +enum MediaType { + IMAGE, + VIDEO, + SOUND, + OTHER +}; +typedef sequence MediaTypes; + +struct StringProperty { + string property; + string value; +}; +typedef sequence StringProperties; + +struct IntProperty { + string property; + long value; +}; +typedef sequence IntProperties; + +typedef sequence MediaTags; + +struct Media { + /* mandatory */ + string name; + unsigned long id; + MediaType type; + unsigned long inputPluginId; + /* optional */ + YalpUser owner; + string lastEdit; + string path; + string fileName; + string duration; + StringProperties stringProps; + IntProperties intProps; + MediaTags tags; +}; +typedef sequence Medias; + +enum Action { + START, + PLAY, + PAUSE, + STOP, + FORWARD, + BACKWARD, + CREATE, + EDIT, + DELETE +}; +typedef sequence Actions; + +enum AccessType { + FILE, + FILES, + STREAM +}; + +enum EncodingType { + UNKNOWN, + MP3, + MPG, + MPEG, + AVI, + MOV, + M2T, + JPEG, + JPG, + TIFF +}; + +struct AccessInfo { + string name; + string description; + string executable; + string params; + AccessType type; +}; + +struct Output { + unsigned long id; + AccessInfo info; + Medias playlist; + Action outputAction; + string destIp; +}; + +enum PluginType { + INPUT_PLUGIN, + OUTPUT_PLUGIN, + AUTH_PLUGIN +}; + +struct PluginInfo { + /* mandatory */ + unsigned long id; + string name; + string description; + PluginType type; + /* optional */ + MediaTypes supportedTypes; + AccessInfo access; + unsigned short maxClients; + unsigned short actClients; +}; +typedef sequence PluginInfos; + +struct Session { + unsigned long id; + YalpUser me; + string ip; + PluginInfos availablePlugins; +}; + +/* YALP startup + * + * 1) CORBA - NameService + * 2) YALP - ServerControl (connects to Db via NameService) + * 4) YALP - all Plugins (connecting to ServerControl via NS) + * 5) YALP - Clients (connecting to ServerControl via NS, getting handles) + * (to available OutputPlugins via ServerControl ) + */ + +/* implemented by OutputPlugins */ +interface OutputPluginInterface { + void getInfo(out PluginInfo info, out YalpError err); + void control(inout Output ctlOutput, out YalpError err); + oneway void shutdown(); +}; + +/* implemented by InputPlugins */ +interface InputPluginInterface { + void getInfo(out PluginInfo info, out YalpError err); + void changeMedia(in Media toChange, in Action todo, out YalpError err); + + void search(in string str, in MediaTypes types, out Medias result, + out YalpError err); + + void getNumOfMedias(out unsigned long num, out YalpError err); +}; + +/* implemented by UserIdentificationPlugin */ +interface UserIdentificationInterface { + void getInfo(out PluginInfo info, out YalpError err); + void userVerify(in string user, in string passwd, out YalpError err, + out YalpUser acc); + + void getUser(out Users list, out YalpError err); + + void changeUser(in YalpUser usr, in string passwd, in Action todo, + out YalpError err); +}; + +/* implemented by YALP */ +interface ServerControlInterface { + +/* User Handling */ + + void clientLogon(in string userName, in string pass, in string ipAdress, + out Session hej, out YalpError err); + + void clientLogoff(in Session bye, out YalpError err); + + void getUser(out Users list, out YalpError err); + + void changeUser(in YalpUser usr, in string passwd, in Action todo, + out YalpError err); + +/* Media Handling */ + + void changeMedia(in Media toChange, in Action todo, out YalpError err); + void getNumOfMedias(out unsigned long num, out YalpError err); + void control(inout Output ctlOutput, out YalpError err); + + void search(in string str, in MediaTypes types, out Medias result, + out YalpError err); + + +/* Outputplugin Handling */ + + void registerOutputPlugin(in OutputPluginInterface itf, inout PluginInfo info, + out YalpError err); + + void removeOutputPlugin(in PluginInfo itf, out YalpError err); + + void getOutputPlugins(out PluginInfos itfs, in string name, + out YalpError err); + + +/* Inputplugin Handling */ + + void registerInputPlugin(in Object itf, inout PluginInfo info, + out YalpError err); + + void removeInputPlugin(in PluginInfo itf, out YalpError err); + + void getInputPlugins(out PluginInfos itfs, in string name, + out YalpError err); + + +/* Identificationplugin Handling */ + + void registerAuthPlugin(in Object itf, inout PluginInfo info, + out YalpError err); + + void removeAuthPlugin(in PluginInfo itf, out YalpError err); + void getAuthPlugins(out PluginInfos itfs, in string name, out YalpError err); + + /* Server related */ + void ping(out YalpError pong); + oneway void serverShutdown(); +}; + +}; diff --git a/svn-commit.tmp b/svn-commit.tmp new file mode 100644 index 0000000..82b4cd3 --- /dev/null +++ b/svn-commit.tmp @@ -0,0 +1,4 @@ +initial import +--This line, and those below, will be ignored-- + +A . -- cgit v1.2.3