segmentation fault pro*c code for database connection - unix

I wrote simple pro*c program to check database connectivity. The code is :
int main()
{
char *conn_string = "IDA/IDA#DBISPSS";
int x = 10;
printf("value of x is before db connection %d\n",x);
printf(" conn_string %s \n",conn_string);
EXEC SQL CONNECT :conn_string;
EXEC SQL SELECT 1 INTO :x FROM DUAL;
printf("value of x is %d\n",x);
return 0;
}
Following commands I executed to create exectuable (test_connection) of pro*c code
proc test_connection.pc
cc -I${ORACLE_HOME}/precomp/public -c test_connection.c
cc test_connection.o -o test_connection -L$ORACLE_HOME/lib -lclntsh
and when I executed test_connection exe,the output is
value of x is before db connection 10
conn_string IDA/IDA#DBISPSS
Segmentation fault
But the same code workes well in another linux machine and solaris machine.
Why segmentation fault is thrown?

I tested in HPUX 11.11/Oracle 11 and work ok. I don't see any problem, but try some changes:
Declare 'x' into a DECLARE SECTION:
EXEC SQL BEGIN DECLARE SECTION;
int x = 0;
EXEC SQL END DECLARE SECTION;
Try this connection command:
EXEC SQL BEGIN DECLARE SECTION;
char *user = "abc", *password = "123", *database="base";
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE BASE_HANDLE DATABASE;
...
EXEC SQL CONNECT :user IDENTIFIED BY :password AT BASE_HANDLE USING :database;
...
EXEC SQL AT BASE_HANDLE SELECT 1...
Insert a printf("here 1"); between EXEC SQL CONNECT... and EXEC SQL SELECT ... to see where SEGFAULT is thrown.

I had that problem and no amount of fiddling with my source made any difference. What finally worked was when I reinitialized all (ALL) my libraries to make sure that Oracle only had access to the 32 bit versions of the library. It seems Oracle was somehow getting connected to a 64 bit library. Only by removing all references to any libraries or executables except the 32 bit versions worked. This included running a 32 bit version of Pro*C.

Related

How to get Rust sqlx sqlite query to work?

main.rs:
#[async_std::main]
async fn main() -> Result<(),sqlx::Error> {
use sqlx::Connect;
let mut conn = sqlx::SqliteConnection::connect("sqlite:///home/ace/hello_world/test.db").await?;
let row = sqlx::query!("SELECT * FROM tbl").fetch_all(&conn).await?;
println!("{}{}",row.0,row.1);
Ok(())
}
Cargo.toml:
[package]
name = "hello_world"
version = "0.1.0"
authors = ["ace"]
edition = "2018"
[dependencies]
async-std = {version = "1", features = ["attributes"]}
sqlx = { version="0.3.5", default-features=false, features=["runtime-async-std","macros","sqlite"] }
bash session:
ace#SLAB:~/hello_world$ sqlite test.db
SQLite version 2.8.17
Enter ".help" for instructions
sqlite> create table tbl ( num integer, chr varchar );
sqlite> insert into tbl values (1,'ok');
sqlite> .quit
ace#SLAB:~/hello_world$ pwd
/home/ace/hello_world
ace#SLAB:~/hello_world$ export DATABASE_URL=sqlite:///home/ace/hello_world/test.db
ace#SLAB:~/hello_world$ cargo run
Compiling hello_world v0.1.0 (/home/ace/hello_world)
error: failed to connect to database: file is not a database
--> src/main.rs:8:12
|
8 | let row = sqlx::query!("SELECT * FROM tbl").fetch_all(&conn).await?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error: could not compile `hello_world`.
To learn more, run the command again with --verbose.
ace#SLAB:~/hello_world$ rustc --version
rustc 1.44.0 (49cae5576 2020-06-01)
ace#SLAB:~/hello_world$ uname -r
5.4.0-33-generic
ace#SLAB:~/hello_world$ cat /etc/os-release | head -2
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ace#SLAB:~/hello_world$
Also tried using DATABASE_URL "sqlite::memory:" (both in environment variable and in main.rs) with system table "sqlite_master". Got different error:
error[E0277]: the trait bound `&sqlx_core::sqlite::connection::SqliteConnection: sqlx_core::executor::RefExecutor<'_>` is not satisfied
... but it must have gotten partway to success because when I used table name "Xsqlite_master" with memory db, it complained that there was no such table.
Tried "sqlite://home"(etc) and every other number of slashes, zero through 4. Tried several hundred other things. :(
Thank you!
There maybe several more things to try:
Try sqlite3 /home/ace/hello_world/test.db to double verify that the DB does exist. Make sure tbl table is defined there .schema tbl
Try DB path with a single slash i.e. sqlite:/home/ace/hello_world/test.db
Lastly try using the query function not the macro https://docs.rs/sqlx/0.3.5/sqlx/fn.query.html to see if it works.

Error using 'synaser.pas' with FreePascal (Lazarus)

I'm trying to read serial data from an Arduino to my Mac (10.12.6). I have downloaded the Synapse library for FreePascal (Lazarus v.2.0.8) from here but I run into an error...
The Arduino is programmed using the Arduino IDE and sends random numbers (between 0 and 255) as a string to the serial port. I am trying to read these strings using FreePascal so that I can plot the values.
Following instructions here I have downloaded and used the Synapse library in the following way:
1) Uncompress the library folder
2) In Lazarus goto 'Project' -> 'Project Inspector' -> 'Add Files from File System' -> select 'synaser.pas'.
3) Add the following code to the form button event:
procedure TForm1.Button1Click(Sender: TObject);
var
ser: TBlockSerial;
begin
ser := TBlockSerial.Create;
try
ser.Connect('my-com-port'); // write here Arduino COM port number (on linux it's something like '/dev/ttyUSB0')
Sleep(250);
ser.config(9600, 8, 'N', SB1, False, False);
ser.SendString('on'); // button 2 should have 'off' here
finally
ser.free;
end;
end;
4) Press run.
An error message appears in the synaser.pas file:
Error incompatible types: got "ShortInt" expected "Pointer"..
Here's the part of the synaser.pas file referred to:
{$IFNDEF MSWINDOWS}
procedure TBlockSerial.Purge;
begin
{$IFNDEF FPC}
SerialCheck(ioctl(FHandle, TCFLSH, TCIOFLUSH));
{$ELSE}
{$IFDEF DARWIN}
SerialCheck(fpioctl(FHandle, TCIOflush, TCIOFLUSH)); { <------ here*******}
{$ELSE}
SerialCheck(fpioctl(FHandle, TCFLSH, Pointer(PtrInt(TCIOFLUSH))));
{$ENDIF}
{$ENDIF}
FBuffer := '';
ExceptCheck;
end;
I am using a Mac and this error seems to be related to a windows system?
Thanks #tonypdmtr.
I had to change the 'synaser.pas' file in the following way to get it to work. Bit of a hack I feel:
Change line 1939 to the following:
SerialCheck(fpioctl(FHandle, TCIOflush, Pointer(PtrInt(TCIOFLUSH))));
Comment out lines 2201, 2202 and 2204 in the same. This sounds like a bad way of doing it but I got it to work.
Changing the button event to the following code allows me to read a single line of data from the Arduino with each button click:
procedure TForm1.Button1Click(Sender: TObject);
var
ser: TBlockSerial;
begin
ser := TBlockSerial.Create;
try
ser.Connect('/dev/cu.wchusbserial1420'); // write here Arduino COM port number (on linux it's something like '/dev/ttyUSB0')
Sleep(250);
ser.config(9600, 8, 'N', SB1, False, False);
Label1.Caption := ser.RecvString(100);
finally
ser.free;
end;
end;
I feel the library should just work without having to change it.

No Output in NPPExec with Pascal

I want to write and build and execute a Pascal Program in Notepad ++. If i execute the program in cmd the output is normal, but in the console in nppexec the output is empty
My Code:
Program Edgar;
Uses Crt;
Var cnt, tip, pot : INTEGER;
Begin
TextColor(Red);
WriteLn('Hallo');
tip := -1;
cnt := 0;
Randomize;
pot := Random(2501)*10;
WriteLn(pot);
WHILE (tip <> pot) do
Begin
WriteLn('Tip: ');
ReadLn(tip);
if (tip < pot) then begin
WriteLn('Too low');
cnt := cnt + 1
end;
if (tip > pot) then begin
WriteLn('Too High');
cnt := cnt + 1
end;
end;
cnt:= cnt + 1;
WriteLn('IA IA');
WriteLn('Tries: ',cnt );
End.
Build Commands:
cd $(CURRENT_DIRECTORY)
fpc $(NAME_PART).pas
$(NAME_PART).exe
Output(Nppexec):
Free Pascal Compiler version 2.6.2 [2013/02/12]
for i386 Copyright (c) 1993-2012 by Florian Klaempfl
and others Target OS: Win32 for i386
Compiling ue23.pas
Linking ue23.exe 27 lines compiled, 0.1 sec , 33536 bytes code, 1900 bytes data
<<< Process finished.
(Exit code 0)
ue23.exe Process started >>>
If you enable unit CRT, the application will write to the console directly (using *console winapi functions) instead of using stdout.
Probably the console screen of npp is not a real console screen, but a capture of stdout (-piped) only.
Except not using crt (and thus not using cursor movement and coloring) there is not much that can be done, this is probably a NPP limitation.
After that, you need to press "Enter" while your cursor blinking in output side.
And you will get the output with these lines at the end.
<<< Process finished. (Exit code 0)
================ READY ================
There is no limitation, you can run commands from that output side of notepad++.

How to get name of ODBC driver's DLL file for a given ODBC driver

How do I programatically get the name of an ODBC driver's DLL file for a given ODBC driver. For example, given "SQL Server Native Client 10.0" I want to find the name of that driver's DLL file: sqlncli10.dll. I can see this in REGEDIT in the "Driver" entry in the registry under HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI. If I try to read the value from the registry in my code it returns an empty string. I also tried using the ODBC API function SQLDrivers. The code below successfully returns all the values of the attributes in the Attribs variable except "Driver". Everything is there - APILevel, ConnectFunctions, CPTimeout, etc - but "Driver" is not in the list.
repeat
Status := SQLDrivers (HENV, SQL_FETCH_NEXT, PAnsiChar(DriverName), 255,
NameLen, PAnsiChar(Attribs), 1024, AttrLen);
if Status = 0 then begin
List.Add(DriverName);
List.Add(Attribs);
end;
until Status <> 0;
You can use SQLGetInfo() with InfoType=SQL_DRIVER_NAME
I hope this will look like:
Status := SQLGetInfo(ConnEnv, SQL_DRIVER_NAME, PAnsiChar(DriverName), 255, NameLen);
But this function works with already connected database.
I tried SQLDrives() and you are right: in my environment this function also do not return DLL name. So I tried to read it from registry and it worked this way:
DLLName := RegGetStringDirect(HKEY_LOCAL_MACHINE, 'SOFTWARE\ODBC\ODBCINST.INI\' + DriverName, 'Driver');
For driver: IBM INFORMIX ODBC DRIVER I got: C:\informix\bin\iclit09b.dll
For driver: SQL Server I got: C:\WINDOWS\system32\SQLSRV32.dll
RegGetStringDirect() is my function based on Windows API to read something from registry.
EDIT:
Two functions to read "SQL Server" ODBC driver dll name by Ron Schuster moved from comment:
procedure TForm1.Button1Click(Sender: TObject);
//using Windows API calls
var
KeyName, ValueName, Value: string;
Key: HKEY;
ValueSize: Integer;
begin
ValueName := 'Driver';
KeyName := 'SOFTWARE\ODBC\ODBCINST.INI\SQL Native Client';
if RegOpenKeyEx(HKEY_LOCAL_MACHINE, PChar(KeyName), 0, KEY_READ, Key) = 0 then
if RegQueryValueEx(Key, PChar(ValueName), nil, nil, nil, #ValueSize) = 0 then begin
SetLength(Value, ValueSize);
RegQueryValueEx(Key, PChar(ValueName), nil, nil, PByte(Value), #ValueSize);
ShowMessage(Value);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
//using TRegistry class
var
KeyName, ValueName, Value: string;
Reg: TRegistry;
begin
ValueName := 'Driver';
KeyName := 'SOFTWARE\ODBC\ODBCINST.INI\SQL Native Client';
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKeyReadOnly(KeyName) then begin
Value := Reg.ReadString(ValueName);
ShowMessage(Value);
end;
finally
Reg.Free;
end;
end;

how can i password protect my sqlite db in C. is it possible to partition the sqlite db?

I am working on embedded system and the device has linux kernel with sqlite database. Wanted to know if the sqlite database can be partitioned with secure and normal partitions.
How can the encryption be achieved for sqlite database file in linux.
Maybe I am too late to answer this question, but I was facing this issue from couple of days and couldn't find any solid solution online. I have found solution hence I am sharing it.
//Steps to make sqlite database authenticated
download sqlite3 amalgamation zip file
unzip the file. The file should contain shell.c, sqlite3.c, sqlite3.h, sqlite3ext.h
click on find the link here
3a. Open userauth.c and copy the entire code and paste it at the end of your sqlite3.c file.
3b. Open sqlite3userauth.h and copy the entire code and pase it at the end of your sqlite3.h file.
create a output file for executing the command in shell
command: gcc -o sqlite3Exe shell.c sqlite3.c -DSQLITE_USER_AUTHENTICATION -ldl -lpthread
4a. Youll get error no such file "sqlite3userauth.h" in your shell.c file:
solution: go to that file and comment th line.(this is because youve already included the necessary code when you copied sqlite3auth.h into sqlite3.h)
4b. Test your output file by running ./sqlite3Exe (this is the name youve given to the output file generated in previous step). you'll get sqlite console.
4c. Create a database and on the authentication flag:
command1: .open dbname.db
command2: .auth on
command3: .exit//command 3 is optional
Building the library
5a: creating object file
//Compiling sqlite3.c to create object after appending our new code
command: gcc -o sqlite3.o -c sqlite3.c -DSQLITE_USER_AUTHENTICATION
With this command, we generate object file which we can use to compile our c file.
Create c file to authenticate your database:
//authUser.c
#include "stdio.h"
#include "stdlib.h"
#include "sqlite3.h"
int main(int argc,char * argv[]){
int a = 10;
int rtn, rtn2;
sqlite3 *db;
char *sql, *zErMsg;
rtn = sqlite3_open("dbname.db", &db);
rtn = sqlite3_user_add(db,"username","password",2, 1);//last but one param is for number of bytes for password, last param is for weather the user is admin or not
if(rtn){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
}else{
fprintf(stderr, "Protected database successfully\n");
}
sqlite3_close(db);
return 0;
}
Compiling the program
//Compiling the program
command1: gcc authUser.c sqlite3.o -lpthread -ldl
command2: ./a.out //Output:protected database successfully
create c file to create table if the user is authenticated
//createTable.c
#include "stdio.h"
#include "stdlib.h"
#include "sqlite3.h"
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i less then argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc,char * argv[]){
int a = 10;
int rtn, rtn2;
sqlite3 *db;
char *sql, *zErMsg;
rtn = sqlite3_open("dbname.db", &db);
rtn = sqlite3_user_authenticate(db, "user","password",2);
if(rtn){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
sql = "create table newtable(id int not null primary key, name varchar(100) not null)";
//sql = "insert into newtable values(5, 'ishwar')";
rtn = sqlite3_exec(db, sql, callback, 0, &zErMsg);
if(rtn != SQLITE_OK){
sqlite3_free(zErMsg);
}else{
fprintf(stdout, "Table created successfully \n");
//fprintf(stdout, "inserted successfully \n");
}
sqlite3_close(db);
return 0;
}`
compiling the program
//Compiling the program
command1: gcc createTable.c sqlite3.o -lpthread -ldl
command2: ./a.out //Output:Table created successfully
Create c file to add values in table
from the previous code, you can see two sql variable and two fprintf inside else, now uncomment the commented line and comment the other one. and runt the same command as above
output: Inserted successfully
And youre done, try experimenting with the code, change the values of sqlite3_user_authenticate function you wont be able to do these operations,at max you may be able to open database(when you comment the sqlite3_user_authenticate functon.nothing else)
Testing it with shell
Run the command: ./sqlite3Exe (the output file we created in step 4)
command1: .open dbname.db
command2: .tables //you should get error, user_auth
Thank you(please feel free to mail me in case of any problem: ishwar.rimal#gmail.com)
for encryption to be achieved with SQLite, you need to license some extensions from the SQLite author.
http://www.sqlite.org/support.html
David Segleau here, Director of Product Management for Berkeley DB.
The recent 5.1 release of Oracle Berkeley DB (5.1.7) integrates the Berkeley DB encryption feature with the SQLite-based SQL API. You can read about it here.

Resources