Initial support for SQLite (90% approx).

Initial support for Firebird (30% approx).
Initial support for Access (10% approx).
Shared libraries code/installation scripts ported to 64bit, directory structure adapted.
Minor code adjustments.
This commit is contained in:
Bernardo Damele
2010-03-18 17:20:54 +00:00
parent f1fde2e443
commit 0d559d14df
61 changed files with 3769 additions and 670 deletions

View File

@@ -0,0 +1,16 @@
LIBDIR=/tmp
8.4:
gcc -Wall -I/usr/include/postgresql/8.4/server -Os -shared lib_postgresqludf_sys.c -o lib_postgresqludf_sys.so
strip -sx lib_postgresqludf_sys.so
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
8.3:
gcc -Wall -I/usr/include/postgresql/8.3/server -Os -shared lib_postgresqludf_sys.c -o lib_postgresqludf_sys.so
strip -sx lib_postgresqludf_sys.so
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
8.2:
gcc -Wall -I/usr/include/postgresql/8.2/server -Os -shared lib_postgresqludf_sys.c -o lib_postgresqludf_sys.so
strip -sx lib_postgresqludf_sys.so
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so

View File

@@ -0,0 +1,59 @@
#!/bin/bash
# lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions
# Copyright (C) 2009-2010 Bernardo Damele A. G.
# web: http://bernardodamele.blogspot.com/
# email: bernardo.damele@gmail.com
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# Adapt the following settings to your environment
USER="postgres"
PORT="5434"
VERSION="8.4"
#PORT="5433"
#VERSION="8.3"
#PORT="5432"
#VERSION="8.2"
echo "Compiling the PostgreSQL UDF"
make ${VERSION}
if test $? -ne 0; then
echo "ERROR: You need postgresql-server development software installed"
echo "to be able to compile this UDF, on Debian/Ubuntu just run:"
if test "${VERSION}" == "8.2"; then
echo "apt-get install postgresql-server-dev-8.2"
elif test "${VERSION}" == "8.3"; then
echo "apt-get install postgresql-server-dev-8.3"
elif test "${VERSION}" == "8.4"; then
echo "apt-get install postgresql-server-dev-8.4"
fi
exit 1
else
echo "PostgreSQL UDF compiled successfully"
fi
echo -e "\nPlease provide your PostgreSQL 'postgres' user's password"
psql -h 127.0.0.1 -p ${PORT} -U ${USER} -q template1 < lib_postgresqludf_sys.sql
if test $? -ne 0; then
echo "ERROR: unable to install the UDF"
exit 1
else
echo "PostgreSQL UDF installed successfully"
fi

View File

@@ -0,0 +1,275 @@
/*
lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions
Copyright (C) 2009-2010 Bernardo Damele A. G.
web: http://bernardodamele.blogspot.com/
email: bernardo.damele@gmail.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
#define _USE_32BIT_TIME_T
#define DLLEXP __declspec(dllexport)
#define BUILDING_DLL 1
#else
#define DLLEXP
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#endif
#include <postgres.h>
#include <fmgr.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
DWORD WINAPI exec_payload(LPVOID lpParameter);
#endif
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
char *text_ptr_to_char_ptr(text *arg)
{
char *retVal;
int arg_size = VARSIZE(arg) - VARHDRSZ;
retVal = (char *)malloc(arg_size + 1);
memcpy(retVal, VARDATA(arg), arg_size);
retVal[arg_size] = '\0';
return retVal;
}
text *chr_ptr_to_text_ptr(char *arg)
{
text *retVal;
retVal = (text *)malloc(VARHDRSZ + strlen(arg));
#ifdef SET_VARSIZE
SET_VARSIZE(retVal, VARHDRSZ + strlen(arg));
#else
VARATT_SIZEP(retVal) = strlen(arg) + VARHDRSZ;
#endif
memcpy(VARDATA(retVal), arg, strlen(arg));
return retVal;
}
PG_FUNCTION_INFO_V1(sys_exec);
#ifdef PGDLLIMPORT
extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
#else
extern DLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
#endif
text *argv0 = PG_GETARG_TEXT_P(0);
int32 result = 0;
char *command;
command = text_ptr_to_char_ptr(argv0);
/*
Only if you want to log
elog(NOTICE, "Command execution: %s", command);
*/
result = system(command);
free(command);
PG_FREE_IF_COPY(argv0, 0);
PG_RETURN_INT32(result);
}
PG_FUNCTION_INFO_V1(sys_eval);
#ifdef PGDLLIMPORT
extern PGDLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) {
#else
extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) {
#endif
text *argv0 = PG_GETARG_TEXT_P(0);
text *result_text;
char *command;
char *result;
FILE *pipe;
char *line;
int32 outlen, linelen;
command = text_ptr_to_char_ptr(argv0);
/*
Only if you want to log
elog(NOTICE, "Command evaluated: %s", command);
*/
line = (char *)malloc(1024);
result = (char *)malloc(1);
outlen = 0;
pipe = popen(command, "r");
while (fgets(line, sizeof(line), pipe) != NULL) {
linelen = strlen(line);
result = (char *)realloc(result, outlen + linelen);
strncpy(result + outlen, line, linelen);
outlen = outlen + linelen;
}
pclose(pipe);
if (*result) {
result[outlen-1] = 0x00;
}
result_text = chr_ptr_to_text_ptr(result);
PG_RETURN_POINTER(result_text);
}
PG_FUNCTION_INFO_V1(sys_bineval);
#ifdef PGDLLIMPORT
extern PGDLLIMPORT Datum sys_bineval(PG_FUNCTION_ARGS) {
#else
extern DLLIMPORT Datum sys_bineval(PG_FUNCTION_ARGS) {
#endif
text *argv0 = PG_GETARG_TEXT_P(0);
int32 argv0_size;
size_t len;
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
int pID;
char *code;
#else
int *addr;
size_t page_size;
pid_t pID;
#endif
argv0_size = VARSIZE(argv0) - VARHDRSZ;
len = (size_t)argv0_size;
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
// allocate a +rwx memory page
code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
strncpy(code, VARDATA(argv0), len);
WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE);
#else
pID = fork();
if(pID<0)
PG_RETURN_INT32(1);
if(pID==0)
{
page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size
page_size = (len+page_size) & ~(page_size); // align to page boundary
// mmap an rwx memory page
addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0);
if (addr == MAP_FAILED)
PG_RETURN_INT32(1);
strncpy((char *)addr, VARDATA(argv0), len);
((void (*)(void))addr)();
}
if(pID>0)
waitpid(pID, 0, WNOHANG);
#endif
PG_RETURN_INT32(0);
}
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
DWORD WINAPI exec_payload(LPVOID lpParameter)
{
__try
{
__asm
{
mov eax, [lpParameter]
call eax
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
return 0;
}
#endif
#undef fopen
PG_FUNCTION_INFO_V1(sys_fileread);
#ifdef PGDLLIMPORT
extern PGDLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
#else
extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
#endif
text *argv0 = PG_GETARG_TEXT_P(0);
text *result_text;
int32 len;
int32 i, j;
char *filename;
char *result;
char *buffer;
char table[] = "0123456789ABCDEF";
FILE *file;
filename = text_ptr_to_char_ptr(argv0);
file = fopen(filename, "rb");
if (!file)
{
PG_RETURN_NULL();
}
fseek(file, 0, SEEK_END);
len = ftell(file);
fseek(file, 0, SEEK_SET);
buffer=(char *)malloc(len + 1);
if (!buffer)
{
fclose(file);
PG_RETURN_NULL();
}
fread(buffer, len, 1, file);
fclose(file);
result = (char *)malloc(2*len + 1);
for (i=0, j=0; i<len; i++)
{
result[j++] = table[(buffer[i] >> 4) & 0x0f];
result[j++] = table[ buffer[i] & 0x0f];
}
result[j] = '\0';
result_text = chr_ptr_to_text_ptr(result);
free(result);
free(buffer);
free(filename);
PG_RETURN_POINTER(result_text);
}

View File

@@ -0,0 +1,25 @@
/*
lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions
Copyright (C) 2009-2010 Bernardo Damele A. G.
web: http://bernardodamele.blogspot.com/
email: bernardo.damele@gmail.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CREATE OR REPLACE FUNCTION sys_exec(text) RETURNS int4 AS '/tmp/lib_postgresqludf_sys.so', 'sys_exec' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/lib_postgresqludf_sys.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
CREATE OR REPLACE FUNCTION sys_bineval(text) RETURNS int4 AS '/tmp/lib_postgresqludf_sys.so', 'sys_bineval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
CREATE OR REPLACE FUNCTION sys_fileread(text) RETURNS text AS '/tmp/lib_postgresqludf_sys.so', 'sys_fileread' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;