|
Extreme 7
How to Execute "C" Programs
Stored in an Empress Database
Introduction
Empress RDBMS can store any kind of information inside
its database. This includes not only all types of data
one could imagine, but also a programming logic which can drive,
for example, knowledge-based or rule-based systems.
Empress database can serve as a repository
for programs, shell scripts, executables of all kinds.
Then, those executables can be invoked via Empress PSM technology.
This technical note explains the basic steps one needs to
do in order to acquire this functionality.
In future Empress versions (V8.60+),
invoking an executable stored in
the database will be an automatic process. Hence, a built-in
functionality will be provided.
Example
In this technical note we present an example of how to store
a simple "Hello World" C program in the database and execute it from an
SQL interface.
At the end of this exercise we would be able to do the following:
SELECT executeBLOB(executable_name, executable_object)
FROM execRepositoryTable
WHERE where_condition
where module_executeBLOB is Empress PSM function which reads
the content of the executable_object (e.g. "Hello World" executable)
in table execRepositoryTable and executes it.
# A simple "Hello World" C program
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return(0);
}
The executable hello could be created in the following way:
Let us create a database execRepositoryDB which will serve as a repository
for different kind of executables/shell scripts.
Create table execRepositoryTable with the following attributes:
exec_id - Identificator of the executable
exec_name - Name of the executable
exec_blob - Object containing an executable
CREATE TABLE execRepositoryTable (exec_id integer, exec_name char, exec_object bulk);
Insert "ls" executable from the system into the table execRepositoryTable
INSERT INTO TABLE execRepositoryTable VALUES (1, "ls", DIRECT_FROM '/bin/ls');
Insert "hello" executable in the table execRepositoryTable
INSERT INTO TABLE execRepositoryTable VALUES (2, "hello", DIRECT_FROM './hello');
Pseudo Code for an Empress PSM function is given (the full source code
is given in the appendix):
function executeBLOB(executable_name, executable_object)
{
Write contents of the executable_object to a temporary file
Change "execute" permissions on the file
Use "system" command to execute the file
Remove the temporary file
Return execution status
}
APPENDIX
The following script can be executed with EMPRESS V8.60 installed
on Intel x86 machine running Linux OS Release 2.0 with libc.so.6 (ELF)
in order to acquire the above described functionality. The script is
simplified in order to show the basic idea. Other platforms (e.g. MS Windows)
would require changes.
#!/bin/sh
cat > ./hello.c <<EOM
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return (0);
}
EOM
cc -o hello hello.c
cat > ./module_executeBLOB.c <<EOM
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <usrfns.h>
char *executeBLOB( char *name, gen_binary *blob )
{
FILE *fp;
char *rc;
char fname[32] = "./";
int i;
rc = mspsm_malloc (128);
strcat(fname, name);
if ((fp = fopen ( fname, "w")) == NULL)
{
snprintf(rc, 128, "Failed to open file %s", fname);
return (rc);
}
for (i = 0; i < blob->num_segments; i++)
{
if (fwrite (blob->segment[i].data, blob->segment[i].data_len, 1, fp) < 1)
{
fclose (fp);
snprintf(rc, 128, "Failed to write data to file %s", fname);
return (rc);
}
}
chmod(fname, S_IXUSR);
fclose (fp);
system(fname);
remove(fname);
strcpy(rc, "Success");
return (rc);
}
EOM
emppsmcc -o module_executeBLOB.dll module_executeBLOB.c
empmkdb execRepositoryDB
empbatch execRepositoryDB <<EOM
CREATE MODULE module_executeBLOB
FUNCTION executeBLOB( GENERIC CHAR, GENERIC BINARY)
RETURNS GENERIC CHAR
EXTERNAL NAME executeBLOB;
END MODULE
UPDATE MODULE module_executeBLOB
FROM './module_executeBLOB.dll';
CREATE TABLE execRepositoryTable (exec_id integer, exec_name char, exec_object bulk);
INSERT INTO TABLE execRepositoryTable VALUES (1, "ls", DIRECT_FROM '/bin/ls');
INSERT INTO TABLE execRepositoryTable VALUES (2, "hello", DIRECT_FROM './hello');
EOM
rm ./hello
empcmd execRepositoryDB "SELECT executeBLOB(exec_name, exec_object)
FROM execRepositoryTable WHERE exec_id=2;"
|