ODBC write blob example Oracle C++ - c++

Could you give me an example in c++ of inserting a blob in an Oracle database using ODBC API? It's my first time working with BLOB type so it is abstract to me. I have researched the Internet a lot and now it is all messy in my head. An example would really help me.

I have a short(ish) example in C. The basic principle to insert blobs via ODBC is this:
SQLPrepare("insert into mytable (mycolumne) values(?)");
SQLBindParameter(1, other_args, indicator SQL_LEN_DATA_AT_EXEC(size));
SQLExecute will return SQL_NEED_DATA
call SQLParamData to find which parameter data is required for
call SQLPutData as much as you like in chunks to insert data
call SQLParamData again to find the next parameter requiring data
In example code here you'll have to write your own do_a_error() function but it just calls SQLGetDiagRec.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined (WIN32)
# include <windows.h>
# include <io.h>
#else
# include <unistd.h>
#endif
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
#include "helper.h" /* contained do_a_error() defn etc - you won't have this header */
#ifdef WIN32
# define F_OK 0
# define W_OK 2
# define R_OK 4
# define access _access /* file check */
#endif
static SQLUINTEGER array_row_counts;
static SQLUINTEGER array_selects;
static SQLUINTEGER static_ca1;
static SQLUINTEGER static_ca2;
unsigned int debug=0;
const char fixed_data_source[] = "example";
#define TEST_FILE "easycd.jpg"
#define DISPLAY_GIF "/usr/X11/bin/xv"
static short insert_into_table(
SQLHDBC *hdbc,
typeinfo_t typeinfo);
/************************************************************************/
/* */
/* main */
/* ==== */
/* */
/************************************************************************/
int main(int argc, char *argv[], char *envp[])
{
SQLHENV henv; /* environment handle */
SQLHDBC hdbc; /* database handle */
char *data_source_name; /* chosen datasource */
SQLRETURN ret; /* function return status */
char in_connection_string[512]; /* SQLDriverConnect string */
char out_connection_string[512]; /* returned connection string */
SQLSMALLINT out_connection_string_len; /* ... and length */
unsigned int i; /* loop variable */
typeinfo_t typeinfo[100]; /* data type information */
int type_element = -1;
SQLINTEGER max_column_size = 0; /* largest column */
/*
* Get the datasource name.
*/
if (argc > 1)
{
for (i = 1; i < argc; i++)
{
if (!strcmp (argv[i], "-d")) debug = 1;
}
if (((argc > 2) && debug) ||
((argc > 1) && !debug))
data_source_name = argv[argc - 1];
}
else
{
data_source_name = fixed_data_source;
}
sprintf(in_connection_string, "DSN=%s;", data_source_name);
/*
* Allocate and set up the environment and connection.
*/
if (SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv) != SQL_SUCCESS)
{
fprintf(stderr, "** Failed to allocate environment **\n");
exit(1);
}
if (SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3, 0) != SQL_SUCCESS)
{
do_a_error(SQL_HANDLE_ENV, henv, "SQLSetEnvAttr");
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(2);
}
if (SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc) != SQL_SUCCESS)
{
do_a_error(SQL_HANDLE_ENV, henv, "SQLAllocHandle");
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(3);
}
ret = SQLDriverConnect(hdbc, NULL,
(SQLCHAR *)in_connection_string, SQL_NTS,
(SQLCHAR *)out_connection_string,
sizeof(out_connection_string),
&out_connection_string_len, SQL_DRIVER_COMPLETE);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_DBC, hdbc, "SQLDriverConnect");
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(4);
}
if (out_connection_string_len > sizeof(out_connection_string))
{
out_connection_string[sizeof(out_connection_string) - 1] = '\0';
}
else
{
out_connection_string[out_connection_string_len] ='\0';
}
printf("%s\n", out_connection_string);
if (ret == SQL_SUCCESS_WITH_INFO)
{
do_a_error(SQL_HANDLE_DBC, hdbc, "SQLDriverConnect");
}
/*
* Get a list of the types supported.
*/
memset(typeinfo, '\0', sizeof(typeinfo));
do_get_info(hdbc, &array_row_counts, &array_selects,
&static_ca1, &static_ca2);
if (!SQL_SUCCEEDED(do_type_info(hdbc, typeinfo)))
{
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(5);
}
/*
* Find a type big enough for our gif image.
*/
for (i = 0; strlen(typeinfo[i].type_name); i++)
{
if ((typeinfo[i].column_size > max_column_size) &&
(max_column_size != SQL_NO_TOTAL))
{
max_column_size = typeinfo[i].column_size;
type_element = i;
}
else
{
if (typeinfo[i].column_size == SQL_NO_TOTAL)
{
if (max_column_size != SQL_NO_TOTAL)
{
max_column_size = SQL_NO_TOTAL;
type_element = i;
}
}
}
}
if (type_element < 0) abort();
if (debug)
printf("\t Biggest type is %s at %ld in size, requiring \"%s\"\n",
typeinfo[type_element].type_name,
typeinfo[type_element].column_size,
typeinfo[type_element].create_params);
/*
* Delete existing table and create a new one.
*/
ret = do_create_table(hdbc, "\"blob\"", CREATE_TABLE_BIGCOL,
typeinfo[type_element].column_size,
typeinfo[type_element].type_name,
typeinfo[type_element].create_params);
if (!SQL_SUCCEEDED(ret))
{
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(4);
}
insert_into_table(hdbc, typeinfo[type_element]);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}
/************************************************************************/
/* */
/* insert_into_table */
/* ================= */
/* */
/************************************************************************/
static short insert_into_table(
SQLHDBC *hdbc,
typeinfo_t typeinfo)
{
SQLINTEGER len_ind[2]; /* parameter lengths */
SQLINTEGER p1; /* first parameter array */
SQLCHAR p2[50000]; /* second parameter array */
SQLINTEGER row_counts; /* rows affected */
SQLRETURN ret; /* function status return */
unsigned int row; /* current row */
SQLHSTMT hstmt; /* statement handle */
char qbuf[1024]; /* query buffer */
FILE *fp; /* test file file ptr */
size_t readb; /* bytes read from test file */
size_t writeb; /* bytes written to test file */
SQLINTEGER retrieved; /* data retrieved from GetData */
unsigned int pos; /* position in GetData buffer */
printf("---------- insert_into_table ----------\n");
printf("-- Creating rows with BIG column data --\n");
if (access(TEST_FILE, R_OK))
{
fprintf(stderr, "Can't find test binary %s\n", TEST_FILE);
return SQL_ERROR;
}
if (!(fp = fopen(TEST_FILE, "rb")))
{
fprintf(stderr, "Failed to open %s for reading\n", TEST_FILE);
return SQL_ERROR;
}
clearerr(fp);
readb = fread(p2, 1, sizeof(p2), fp);
if ((readb == 0) || ferror(fp))
{
fprintf(stderr, "Failed to read data from %s\n", TEST_FILE);
return SQL_ERROR;
}
if (readb >= sizeof(p2))
{
fprintf(stderr, "%s is too big a file\n", TEST_FILE);
return SQL_ERROR;
}
fclose(fp);
if (SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt) != SQL_SUCCESS)
{
do_a_error(SQL_HANDLE_DBC, hdbc, "SQLAllocHandle");
return SQL_ERROR;
}
/*
* Delete all the rows.
*/
sprintf(qbuf, "delete from \"blob\"");
printf("\"%s\"\n", qbuf);
ret = SQLExecDirect(hstmt, (SQLCHAR *)qbuf, SQL_NTS);
if (ret != SQL_SUCCESS)
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLExecDirect");
/*
* Create the rows.
*/
sprintf(qbuf, "insert into \"blob\" (a,b) values(?,?)");
printf("\"%s\"\n", qbuf);
if (SQLPrepare(hstmt, (SQLCHAR *)qbuf, SQL_NTS) != SQL_SUCCESS)
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLPrepare");
return SQL_ERROR;
}
/*
* Bind Parameters
*/
ret = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER,
5, 0, &p1, 0, &len_ind[0]);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLBindParameter");
return ret;
}
ret = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY,
typeinfo.sql_data_type,
sizeof(p2), 0, (SQLPOINTER)2, 0,
&len_ind[1]);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLBindParameter");
return ret;
}
printf("\tInserting rows into table\n");
for (row = 0; row < 1; row++)
{
/* a */
p1 = row;
len_ind[0] = sizeof(p1);
/* b */
len_ind[1] = SQL_LEN_DATA_AT_EXEC(readb);
ret = SQLExecute(hstmt);
if (ret == SQL_NEED_DATA)
{
SQLPOINTER val;
ret = SQLParamData(hstmt, &val);
if (ret != SQL_NEED_DATA)
{
fprintf(stderr,
"** SQLParamData returned %d, "
"expected SQL_NEED_DATA **\n", ret);
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLParamData");
return SQL_ERROR;
}
if (val != (SQLPOINTER)2)
{
fprintf(stderr,
"** SQLParamData said it required data for parameter "
"marker %p, and we expected 2 **\n", val);
return SQL_ERROR;
}
ret = SQLPutData(hstmt, p2, readb);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLPutData");
return SQL_ERROR;
}
ret = SQLParamData(hstmt, &val);
if (!SQL_SUCCEEDED(ret))
{
fprintf(stderr,
"** Second SQLParamData returned %d, "
"We though all data was sent **\n", ret);
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLParamData");
return SQL_ERROR;
}
}
else if (!SQL_SUCCEEDED(ret))
{
fprintf(stderr,
"** Driver returned a successful state for SQLExecute "
"buf there were data-at-exec parameters **\n");
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLExecute");
return SQL_ERROR;
}
else
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLExecute");
}
if (!SQL_SUCCEEDED(SQLRowCount(hstmt, &row_counts)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLRowCount");
}
if (row_counts != 1)
{
fprintf(stderr, "** RowCount=%ld, expected 1 **\n", row_counts);
}
printf(".");
fflush(stdout);
}
printf("\n");
/*
* Now get it back to check we sent it OK.
*/
memset(p2, '\0', sizeof(p2));
sprintf(qbuf, "select * from \"blob\"");
if (!SQL_SUCCEEDED(ret = SQLPrepare(hstmt, (SQLCHAR *)qbuf, SQL_NTS)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLPrepare");
return SQL_ERROR;
}
if (!SQL_SUCCEEDED(ret = SQLExecute(hstmt)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLExecute");
}
if (!SQL_SUCCEEDED(ret = SQLFetch(hstmt)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFetch");
}
pos = 0;
while(SQL_SUCCEEDED(ret = SQLGetData(hstmt, 2, SQL_C_BINARY,
&p2[pos], sizeof(p2), &retrieved)))
{
if (retrieved == SQL_NO_TOTAL) abort();
if (retrieved == SQL_NULL_DATA) abort();
pos += retrieved;
}
if (ret != SQL_NO_DATA)
{
fprintf(stderr,
"** SQLGetData finished with a status other than SQL_NO_DATA **\n");
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLGetData");
return SQL_ERROR;
}
if (!SQL_SUCCEEDED(SQLCloseCursor(hstmt)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLCloseCursor");
}
if (!(fp = fopen("out.jpg", "w")))
{
fprintf(stderr, "** Failed to open out.jpg for writing **\n");
return SQL_ERROR;
}
writeb = fwrite(p2, 1, pos, fp);
if (writeb != pos)
{
fprintf(stderr, "** Failed to write out.jpg **\n");
return SQL_ERROR;
}
fclose(fp);
system(DISPLAY_GIF" out.jpg");
printf("\tResetting parameters\n");
if (!SQL_SUCCEEDED(SQLFreeStmt(hstmt, SQL_RESET_PARAMS)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFreeStmt");
}
printf("\tClosing statement\n");
if (!SQL_SUCCEEDED(SQLFreeStmt(hstmt, SQL_CLOSE)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFreeStmt");
}
printf("\tDropping Statement\n");
ret = SQLFreeStmt(hstmt, SQL_DROP);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFreeStmt");
}
return ret;
}

Related

Segmentation Fault SQLite Backup

I want to backup the SQLite database from my file system to in memory database using C++. I read this website and try the example 1. It compiled perfectly but I get an error "Segmentation Fault". The code looks like this:
Ps: The last line printf("foo1"); is not printed
#include <stdio.h>
#include <sqlite3.h>
#include <nlohmann/json.hpp>
using namespace std;
using json = nlohmann::json;
static int callback(void *NotUsed, int count, char **data, char **column) {
int i;
int lastEntry = count - 1;
printf("{");
for (i=0; i<count; i++) {
if (i == lastEntry ) {
printf("\"%s\" : \"%s\"", column[i], data[i] ? data[i] : "NULL");
} else {
printf("\"%s\" : \"%s\",", column[i], data[i] ? data[i] : "NULL");
}
}
printf("}\n");
return 0;
}
int loadOrSaveDb(sqlite3 *pFile, const char *zFilename, int isSave){
int rc; /* Function return code */
sqlite3 *pInMemory; /* Database connection opened on zFilename */
sqlite3_backup *pBackup; /* Backup object used to copy data */
sqlite3 *pTo; /* Database to copy to (pFile or pInMemory) */
sqlite3 *pFrom; /* Database to copy from (pFile or pInMemory) */
/* Open the database file identified by zFilename. Exit early if this fails
** for any reason. */
rc = sqlite3_open(zFilename, &pFile);
if( rc==SQLITE_OK ){
pFrom = (isSave ? pInMemory : pFile);
pTo = (isSave ? pFile : pInMemory);
pBackup = sqlite3_backup_init(pTo, "main", pFrom, "main");
if( pBackup ){
(void)sqlite3_backup_step(pBackup, -1);
(void)sqlite3_backup_finish(pBackup);
}
printf("foo");
rc = sqlite3_errcode(pTo);
}
/* Close the database connection opened on database file zFilename
** and return the result of this function. */
(void)sqlite3_close(pFile);
return rc;
}
int main(int argc, char* argv[]) {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
string sql;
/* Open Database */
rc = sqlite3_open("test.db", &db);
if( rc ) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
} else {
fprintf(stderr, "Opened database successfully\n");
}
/* Create SQL Statement */
sql = "CREATE TABLE COMPANY(" \
"ID INT PRIMARY KEY NOT NULL," \
"name TEXT NOT NULL," \
"AGE INT NOT NULL," \
"ADDRESS CHAR(50)," \
"SALARY REAL );";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Table created successfully\n");
}
/* Insert SQL statement */
sql = "INSERT INTO COMPANY " \
"VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
"INSERT INTO COMPANY " \
"VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); " \
"INSERT INTO COMPANY " \
"VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
"INSERT INTO COMPANY " \
"VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Records created successfully\n");
}
/* Select SQL statement */
//sql = "SELECT * from COMPANY WHERE NAME LIKE 'Paul'";
sql = "SELECT * from COMPANY";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
if( rc != SQLITE_OK ) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Operation done successfully\n");
}
loadOrSaveDb(db, "test.db", 0);
sqlite3_close(db);
printf("foo1");
return 0;
}
The destination for sqlite3_backup_init has to be a database connection handle. In order to use sqlite3 *pInMemory; as the destination, you should initialise it with such a handle:
sqlite3 *pInMemory; /* Database connection opened on zFilename */
sqlite3_open(":memory:", &pInMemory);

Why a ZeroMQ PGM multicast is not receiving a Multicast message? ( C++, Windows )

Environment setup:
- Both a multicast send & receive applications are running in the same machine
I am integrating ZeroMQ multicast with OpenPGM support, but facing problem in below my sample code.
i.e. "Multicast message is not received" in receiver application. Kindly correct me if I am doing wrong. Also not able to find proper examples on ZeroMQ PGM multicast requirement.
// ZMQ_pgm_receive.cpp :
//
//Headers
#include "stdafx.h"
#include "zmq.h"
#include <iostream>
#include <windows.h>
std::string fullurl = "pgm://eth0;239.255.0.1:30001";
static int roundtrip_count = 50;
static size_t message_size = 4;
int _tmain(int argc, _TCHAR* argv[])
{
void *ctx = NULL,
*s = NULL;
int con;
int i;
ctx = zmq_init (1);
if (!ctx) {
printf ("error in zmq_init: %s\n", zmq_strerror (errno));
return -1;
}
s = zmq_socket (ctx, ZMQ_SUB);
if (!s) {
printf ("error in zmq_socket: %s\n", zmq_strerror (errno));
return -1;
}
con = zmq_bind(socket, fullurl.c_str());
if (con == 0) {
printf ("error in zmq_bind: %s\n", zmq_strerror (errno));
return -1;
}
zmq_msg_t msg;
int rc = zmq_msg_init (&msg);
if (rc != 0) {
printf ("error in zmq_msg_init: %s\n", zmq_strerror (errno));
return -1;
}
for (i = 0; i != roundtrip_count; i++) {
rc = zmq_recvmsg (s, &msg, 0);
if (rc < 0) {
printf ("error in zmq_recvmsg: %s\n", zmq_strerror (errno));
return -1;
}
printf("message received\n");
if (zmq_msg_size (&msg) != message_size) {
printf ("message of incorrect size received\n");
return -1;
}
Sleep(1000);
}
rc = zmq_msg_close (&msg);
if (rc != 0) {
printf ("error in zmq_msg_close: %s\n", zmq_strerror (errno));
return -1;
}
rc = zmq_close (s);
if (rc != 0) {
printf ("error in zmq_close: %s\n", zmq_strerror (errno));
return -1;
}
/*rc = zmq_ctx_term (ctx);
if (rc != 0) {
printf ("error in zmq_ctx_term: %s\n", zmq_strerror (errno));
return -1;
}
ctx = NULL;
*/
return 0;
}
// ZMQ_pgm_send.cpp :
//
#include "stdafx.h"
#include "zmq.h"
#include <iostream>
#include <windows.h>
std::string fullurl = "pgm://eth0;239.255.0.1:30001";
static int roundtrip_count = 50;
static size_t message_size = 4;
int _tmain(int argc, _TCHAR* argv[])
{
void *ctx = NULL,
*s = NULL;
int con;
int i;
ctx = zmq_init (1);
if (!ctx) {
printf ("error in zmq_init: %s\n", zmq_strerror (errno));
return -1;
}
s = zmq_socket (ctx, ZMQ_PUB);
if (!s) {
printf ("error in zmq_socket: %s\n", zmq_strerror (errno));
return -1;
}
con = zmq_connect(socket, fullurl.c_str());
if (con == 0) {
printf ("error in zmq_connect: %s\n", zmq_strerror (errno));
return -1;
}
zmq_msg_t msg;
int rc = zmq_msg_init_size (&msg,message_size);
if (rc != 0) {
printf ("error in zmq_msg_init: %s\n", zmq_strerror (errno));
return -1;
}
memset(zmq_msg_data (&msg),'A', message_size );
for (i = 0; i != roundtrip_count; i++) {
rc = zmq_sendmsg (s, &msg, 0);
if (rc < 0) {
printf ("error in zmq_sendmsg: %s\n", zmq_strerror (errno));
return -1;
}
}
rc = zmq_msg_close (&msg);
if (rc != 0) {
printf ("error in zmq_msg_close: %s\n", zmq_strerror (errno));
return -1;
}
rc = zmq_close (s);
if (rc != 0) {
printf ("error in zmq_close: %s\n", zmq_strerror (errno));
return -1;
}
/*rc = zmq_ctx_term (ctx);
if (rc != 0) {
printf ("error in zmq_ctx_term: %s\n", zmq_strerror (errno));
return -1;
}
ctx = NULL;
*/
return 0;
}
Please correct me if I am doing wrong.
Having solved the [Step 0], proposed above in the comment,
one ought
detect
a Missing ZMQ_SUBSCRIBE setup, thus SUB-side filters all traffic
ZMQ_SUBSCRIBE: Establish message filter
The ZMQ_SUBSCRIBE option shall establish a new message filter on a ZMQ_SUB socket. Newly created ZMQ_SUB sockets shall filter out all incoming messages, therefore you should call this option to establish an initial message filter.
An empty option_value of length zero shall subscribe to all incoming messages. A non-empty option_value shall subscribe to all messages beginning with the specified prefix. Multiple filters may be attached to a single ZMQ_SUB socket, in which case a message shall be accepted if it matches at least one filter.
Anyway, welcome & enjoy these smart tools for distributed systems computing!

Sniffing an ethernet interface on linux

I am trying to capture only packets from a specific interface and instead I am getting packets from all of the interfaces. what am I doing wrong?
bool Snooper::raw_init (const char *device)
{
uid_t privid = geteuid();
int retval;
bool retVal = false;
do {
if ((retval = setuid(0)) != 0) {
perror("seteuid error");
break;
}
cap_t caps = cap_get_proc();
cap_value_t cap_list[2];
cap_list[0] = CAP_NET_RAW;
cap_list[1] = CAP_SETUID;
if ((retval = cap_set_flag(caps, CAP_EFFECTIVE, 2, cap_list, CAP_SET)) == -1) {
perror("cap_set_flag error");
break;
}
if ((retval = cap_set_proc(caps)) == -1) {
perror("cap_set_proc error");
break;
}
struct ifreq ifr;
memset(&ifr, 0, sizeof (struct ifreq));
/* Open A Raw Socket */
if ((m_sockfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 1) {
perror("Snooper::raw_init:socket Error");
break;
}
/* Set the device to use */
strncpy(ifr.ifr_name, device, strlen(device) + 1);
/* Get the current flags that the device might have */
if (ioctl(m_sockfd, SIOCGIFFLAGS, &ifr) == -1) {
perror("Error: Could not retrieve the flags from the device.\n");
break;
}
printf("The interface is ::: %s\n", device);
perror("Retrieved flags from interface successfully");
/* Set the old flags plus the IFF_PROMISC flag */
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl(m_sockfd, SIOCSIFFLAGS, &ifr) == -1) {
perror("Error: Could not set flag IFF_PROMISC");
break;
}
printf("Setting interface ::: %s ::: to promisc\n", device);
/* Configure the device */
if (ioctl(m_sockfd, SIOCGIFINDEX, &ifr) < 0) {
perror("Error: Error getting the device index.\n");
break;
}
retVal = true;
} while(false);
if ((retval = seteuid(privid)) != 0) {
perror("seteuid error");
}
return retVal;
}
I first validate that I can suid to root since IFF_PROMISC requires it. Then create the socket for UDP traffic, preform the IOCtl for the device, and finally IOCtl for PROMISC.
Now that I have a socket ready I loop on a recv, however I get packets from the other interfaces as well.
To capture packets from a specific interface, you have to bind your socket to that interface using bind function. You can check out this answer for an example.
A small pcap Program that might be able to help You
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pcap/pcap.h>
#include<netinet/if_ether.h>
#include<netinet/ip.h>
#include<netinet/tcp.h>
void process_packet(u_char *args, const struct pcap_pkthdr *header,
const u_char *buffer)
{
// printf("In Process_Packet\n");
struct ethhdr *eth = (struct ethhdr *)(buffer);
printf("%.2x: %.2x: %.2x: %.2x: %.2x: %.2x: %.2x:\n ", eth->h_dest[0], eth->h_dest[1], eth->h_dest[2], eth->h_dest[3], eth->h_dest[4], eth->h_dest[5], eth->h_dest[6]);
printf("%x \n", htons(eth->h_proto));
if(htons(eth->h_proto)== ETHERTYPE_ARP)
{
printf("ARP PACKET\n");
}
struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));
int ipheader = iph-> ihl *4;
printf("Source IP Address :%s\n ", inet_ntoa(iph->saddr));
printf("Destination IP Address :%s\n ", inet_ntoa(iph->daddr));
}
int main()
{
pcap_if_t *alldevspec,*devices;
pcap_addr_t *a;
pcap_t *handle;
const char filter_exp[]="IP";
bpf_u_int32 netp;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program fp;
int ret=0, count =1, n=0;
char devs[100][100],*devicename;
ret = pcap_findalldevs(&alldevspec,errbuf);
if(ret < 0)
{
printf("Error in finding the devices\n");
return -1;
}
for(devices = alldevspec; devices!= NULL; devices = devices->next)
{
printf("%d %s-%s \n",count, devices->name,devices->description);
for(a=devices->addresses;a;a=a->next)
{
printf("family %d \n", (a->addr)->sa_family);
if(devices->name != NULL)
{
strcpy(devs[count], devices->name);
}
switch((a->addr)->sa_family)
{
case AF_INET:
printf("%s \n",inet_ntoa(((struct sockaddr_in*)a->addr)->sin_addr.s_addr));
break;
case AF_INET6:
break;
}
}
++count;
}
printf("Enter the device u want to select\n");
scanf("%d",&n);
devicename = devs[n];
handle = pcap_open_live(devicename,65536,1,-1,errbuf);
if(handle == NULL)
{
printf("Error in opening the device\n");
return -1;
}
pcap_compile(handle,&fp, filter_exp,-1,netp);
pcap_setfilter(handle, &fp);
pcap_loop(handle,-1,process_packet,NULL);
return 0;
}

creating daemon processing from server socket

I have one socket, which act as server while executed and response some results.
First I compile it: g++ -o a daemon.cpp dictionary.cpp -lpthread c++11
then execute : ./a
Now it will listen for the request on some port.
I want that one I create the object file a, it should not manually executed. Rather work as daemon file, which continously listen for the request.
I saw using fork() id something can be done. But I could not correct place in my below code:
variable declation I have removed:
using namespace std;
using namespace boost;
void *SocketHandler(void *);
int main(int argv, char **argc)
{
pthread_t thread_id = 0;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if (hsock == -1)
{
printf("Error initializing socket %dn", errno);
goto FINISH;
}
p_int = (int *) malloc(sizeof(int));
*p_int = 1;
if ((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) p_int, sizeof(int)) == -1)
|| (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) p_int, sizeof(int)) == -1))
{
printf("Error setting options %dn", errno);
free(p_int);
goto FINISH;
}
free(p_int);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(hsock, (sockaddr *) & my_addr, sizeof(my_addr)) == -1)
{
fprintf(stderr, "Error binding to socket, make sure nothing else is listening on this port %dn", errno);
goto FINISH;
}
if (listen(hsock, 10) == -1)
{
fprintf(stderr, "Error listening %dn", errno);
goto FINISH;
}
//Now lets do the server stuff
addr_size = sizeof(sockaddr_in);
int pid;
pid_t pid=fork();
if(pid<0)
exit(EXIT_FAILURE);
else if(pid>0){
//this is parent process, exit now
exit(EXIT_SUCCESS); // again no goto
}
else{
//this is child or daemon
unmask();
pid_t childid = setsid();
while (true)
{
printf("waiting for a connectionn\n");
csock = (int *) malloc(sizeof(int));
if ((*csock = accept(hsock, (sockaddr *) & sadr, &addr_size)) != -1)
{
printf("---------------------nReceived connection from %s\n", inet_ntoa(sadr.sin_addr));
pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
pthread_detach(thread_id);
}
else
{
fprintf(stderr, "Error accepting %dn", errno);
}
sleep(60);
}
FINISH:
;
}
void *SocketHandler(void *lp)
{
char *ch;/* stores references to 50 words. */
char *ch2[50] = { 0 };
char *excluded_string;
char *word;
if ((bytecount = recv(*csock, (char*) rcv.c_str(), rcv.length(), 0)) == -1)
{
fprintf(stderr, "Error receiving data %d \n", errno);
goto FINISH;
}
do
{
bytesReceived = recv(*csock, buffer.data(), buffer.size(), 0);
// append string from buffer.
if ( bytesReceived == -1 )
{
fprintf(stderr, "Error receiving data %d \n", errno);
goto FINISH;
}
else
rcv.append( buffer.cbegin(), buffer.cend() );
} while ( bytesReceived == MAX_BUF_LENGTH );
word = strtok(& rcv[0]," ");
while (word!= NULL)
{
skp = BoyerMoore_skip(word, strlen(word) );
if(skp != NULL)
{
i++;
printf("this also \n");
word = strtok(NULL, " ");
continue;
}
printf("\n Word %s \n",word);
bfr << word << " ";
result_string = bfr.str();
word = strtok(NULL, " ");
j++;
}
ss<<result_string;
while (std::getline(ss, item, ' '))
{
writable.push_back(item);
}
for (std::vector < std::string >::iterator it = writable.begin(); it != writable.end(); it++)
++src[*it];
std::transform(src.begin(), src.end(), std::inserter(dst, dst.begin()), mytransform);
rec=dst.begin();
for (auto it = dst.begin(); it != dst.end(); ++it)
std::cout << it->second << ":" << it->first << std::endl;
if ((bytecount = send(*csock, (char *)ar, i *sizeof(int), 0)) == -1)
{ // Here we cant send lenth-1. It consider exact
fprintf(stderr, "Error sending data %d\n", errno);
goto FINISH;
}
FINISH:
free(csock);
return 0;
}
#include <sys/types.h>
#include <unistd.h>
pid_t pid=fork();
if(pid<0)
exit(EXIT_FAILURE); //see no goto
else if(pid>0){
//this is parent process, exit now
exit(EXIT_SUCCESS); // again no goto
}
else{
//this is child or daemon
unmask();
pid_t childid = setsid();
while(true){
myTask(); //Run the Process
sleep(60);
}
}
Ok I studied your program and made changes. This is how your code in main should look like.
using namespace std;
using namespace boost;
#define CHECK_THROW(condtion, code) if(condition) throw code
void *SocketHandler(void *);
int OpenSockets();
int main(int argv, char **argc)
{
try{
pid_t pid = fork();
CHECK_THROW(pid<0, -5);
if(pid==0)
{
//this is child or daemon
mode_t oldMask, newMask;
oldMask=unmask(newMask);
pid_t childid = setsid();
int hsock = OpenSocket();
CHECK_THROW(listen(hsock, 10) == -1, -4);
addr_size = sizeof(sockaddr_in);
while (true)
{
printf("waiting for a connectionn\n");
csock = (int *) malloc(sizeof(int));
*csock = accept(hsock, (sockaddr *) & sadr, &addr_size);
CHECK_THROW(*csock!=-1, -7);
printf("---------------------nReceived connection from %s\n", inet_ntoa(sadr.sin_addr));
pthread_t thread_id = pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
pthread_detach(thread_id);
}
}
}
catch(int ierror)
{
switch(ierror)
{
case -4: fprintf(stderr, "Error listening %dn", errno); break;
case -7: fprintf(stderr, "Error accepting %dn", errno); break;
}
}
}
int OpenSockets()
{
// Create your socket and return the socket handle from this function
}
void *SocketHandler(void *lp){ /*blah blah */ }

What is the barebones C++ code necessary to put a jpeg into MySQL table?

I have created a MySQL table where one of the columns stores a BLOB type. (The Internet told me BLOB is the correct data type for images.)
I am pretty much a beginner with both C++ and MySQL. What I would like to do is to write a small program with a main() that puts a jpeg into that table. For the sake of this exercise, I do not want to store a reference to a directory that contains an image.
Am I wrong to think that it is as simple as filling out the part in BLOCK 2 below?
#include <iostream>
#include <string>
#include <mysql.h>
using namespace std;
int main(int argc, char **argv)
{
//BLOCK 1: INIT
MYSQL *connection, mysql;
MYSQL_RES *result;
MYSQL_ROW row;
int query_state;
mysql_init(&mysql);
connection = mysql_real_connect(&mysql, "localhost", "root", "secret", "beginner_db",0,0,0);
//BLOCK 2: SEND QUERY
/* do something to insert image to table */
//BLOCK 3: DISPLAY QUERY RESULTS
result = mysql_store_result(connection);
/* do something with result */
//BLOCK 4: FREE
mysql_free_result(result);
mysql_close(connection);
return 0;
}
For this scenario, a good solution would be to use the mysql_stmt_send_long_data() function.
There is an example on the MySQL Manual page that I linked to, but here is a more relevant example of sending file contents:
#ifdef _WIN32
#include <windows.h>
#endif
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/scope_exit.hpp>
#include <mysql.h>
#define ARR_LEN(arr_id) ((sizeof (arr_id))/(sizeof (arr_id)[0]))
int main()
{
using namespace std;
MYSQL *pconn = mysql_init(NULL);
BOOST_SCOPE_EXIT( (pconn) ) {
mysql_close(pconn);
} BOOST_SCOPE_EXIT_END
const char *db_name = "test";
if (!mysql_real_connect(pconn, "localhost", "test", "********", db_name, 0, NULL, CLIENT_COMPRESS)) {
cerr << "Error: mysql_real_connect() failed to connect to `" << db_name << "`." << endl;
return EXIT_FAILURE;
}
MYSQL_STMT *pinsert_into_images_stmt = mysql_stmt_init(pconn);
BOOST_SCOPE_EXIT( (pinsert_into_images_stmt) ) {
mysql_stmt_close(pinsert_into_images_stmt);
} BOOST_SCOPE_EXIT_END
const char sql1[] = "INSERT INTO images(data) VALUES (?)";
if (mysql_stmt_prepare(pinsert_into_images_stmt, sql1, strlen(sql1)) != 0) {
cerr << "Error: mysql_stmt_prepare() failed to prepare `" << sql1 << "`." << endl;
return EXIT_FAILURE;
}
MYSQL_BIND bind_structs[] = {
{ 0 } // One for each ?-placeholder
};
unsigned long length0;
bind_structs[0].length = &length0;
bind_structs[0].buffer_type = MYSQL_TYPE_BLOB;
bind_structs[0].is_null_value = 0;
if (mysql_stmt_bind_param(pinsert_into_images_stmt, bind_structs) != 0) {
cerr << "Error: mysql_stmt_bind_param() failed." << endl;
return EXIT_FAILURE;
}
const char *file_name = "image.jpg";
FILE *fp = fopen(file_name, "rb");
BOOST_SCOPE_EXIT( (fp) ) {
fclose(fp);
} BOOST_SCOPE_EXIT_END
// Use mysql_stmt_send_long_data() to send the file data in chunks.
char buf[10*1024];
while (!ferror(fp) && !feof(fp)) {
size_t res = fread(buf, 1, ARR_LEN(buf), fp);
if (mysql_stmt_send_long_data(pinsert_into_images_stmt, 0, buf, res) != 0) {
cerr << "Error: mysql_stmt_send_long_data() failed." << endl;
return EXIT_FAILURE;
}
}
if (!feof(fp)) {
cerr << "Error: Failed to read `" << file_name << "` in its entirety." << endl;
return EXIT_FAILURE;
}
if (mysql_stmt_execute(pinsert_into_images_stmt) != 0) {
cerr << "Error: mysql_stmt_execute() failed." << endl;
return EXIT_FAILURE;
}
cout << "Inserted record #" << mysql_insert_id(pconn) << endl;
return EXIT_SUCCESS;
}
I am using the following definition of table `images`:
CREATE TABLE images (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
data MEDIUMBLOB NOT NULL,
PRIMARY KEY (id)
);
Upon running this program, it successfully sent the 38,339-byte JPEG image.jpg to the server and outputted "Inserted record #1".
You can verify that the correct number of bytes were sent:
mysql> SELECT octet_length(data) FROM images WHERE id=1;
+--------------------+
| octet_length(data) |
+--------------------+
| 38339 |
+--------------------+
1 row in set (0.00 sec)
I found this solution that worked... for images under 10kb.
//http://zetcode.com/tutorials/mysqlcapitutorial/
//g++ -o output source.cpp $(mysql_config --cflags) $(mysql_config --libs)
#include <stdio.h>
#include <iostream>
#include <mysql.h>
int main(int argc, char **argv)
{
MYSQL *conn;
int len, size;
char data[1000*1024];
char chunk[2*1000*1024+1];
char query[1024*5000];
FILE *fp;
conn = mysql_init(NULL);
mysql_real_connect(conn, "localhost", "root", "secret", "beginner_db", 0, NULL, 0);
fp = fopen("filename.png", "rb");
size = fread(data, 1, 1024*1000, fp);
mysql_real_escape_string(conn, chunk, data, size);
char *stat = "INSERT INTO pic_tbl(name, pic) VALUES('cexample', '%s')";
len = snprintf(query, sizeof(stat)+sizeof(chunk) , stat, chunk);
mysql_real_query(conn, query, len);
fclose(fp);
mysql_close(conn);
}
Something like this:
CString SaveFile( CMemoryFile& File )
{
*pFileKey = -1;
SQLRETURN retcode;
SQLHSTMT hstmt;
CLoggEntryList LoggEntryList( this ); // logg entries cannot be made while busy inside the hstmt, use this class to add them later
SQLINTEGER cbDocumentBlock; // For binding the main image
long lDocumentBufferSize = 0;
unsigned char* pDocumentBuffer; // Will be set to point to the buffer that should be written into the document blob field
unsigned char pDummyChar[] = {'0'}; // Dummy buffer to write in the image/thumbnail blob fields when using external storage
lDocumentBufferSize = File.m_lBufferSize;
pDocumentBuffer = File.m_pFileBuffer;
// Allocate statement handle
retcode = SQLAllocHandle(SQL_HANDLE_STMT, m_Database.m_hdbc, &hstmt);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{ // Create a result set
CString szSQL;
szSQL = ( "INSERT INTO ObjectTable (ObjectData) VALUES ( ? )");
retcode = SQLPrepare(hstmt, (SQLCHAR*)szSQL.GetBuffer(), SQL_NTS);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
// Bind the parameters. For parameter 1, pass the parameter number in ParameterValuePtr instead of a buffer address.
SQLINTEGER cbNULL = 0;
SQLINTEGER cbTEXT = SQL_NTS;
int nColumn = 1;
// Bind ObjectData
cbDocumentBlock = SQL_LEN_DATA_AT_EXEC(0); //SQL_LEN_DATA_AT_EXEC(lImageBufferSize);
retcode = SQLBindParameter(hstmt, nColumn++, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY,
0, 0, (SQLPOINTER) DOCUMENT, 0, &cbDocumentBlock);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
// Set values so data for parameter 1 will be passed at execution. Note that the length parameter in
// the macro SQL_LEN_DATA_AT_EXEC is 0. This assumes that the driver returns "N" for the
// SQL_NEED_LONG_DATA_LEN information type in SQLGetInfo.
retcode = SQLExecute(hstmt);
const long nMaxChunkSize = 400000;
// For data-at-execution parameters, call SQLParamData to get the parameter number set by SQLBindParameter.
// Call InitUserData. Call GetUserData and SQLPutData repeatedly to get and put all data for the parameter.
// Call SQLParamData to finish processing this parameter.
while (retcode == SQL_NEED_DATA)
{
SQLPOINTER pToken;
retcode = SQLParamData(hstmt, &pToken);
switch( (int)pToken )
{
case DOCUMENT:
{
if (retcode == SQL_NEED_DATA)
{
for( int nPos = 0; nPos < lDocumentBufferSize; nPos += nMaxChunkSize )
{
int nBufferSize = min( lDocumentBufferSize - nPos, nMaxChunkSize );
SQLRETURN retcode2 = SQLPutData(hstmt, pDocumentBuffer+nPos, nBufferSize );
if (retcode2 != SQL_SUCCESS && retcode2 != SQL_SUCCESS_WITH_INFO)
{
SQLCHAR Sqlstate[6];
SQLINTEGER NativeError;
SQLCHAR MessageText[201];
SQLSMALLINT TextLengthPtr;
retcode2 = SQLGetDiagRec( SQL_HANDLE_STMT, hstmt, 1, Sqlstate, &NativeError, MessageText, 200, &TextLengthPtr );
if (retcode2 == SQL_SUCCESS || retcode2 == SQL_SUCCESS_WITH_INFO)
{
MessageText[TextLengthPtr] = 0;
Sqlstate[5] = 0;
CString szSQLState( Sqlstate );
CString szMessageText( MessageText );
CString szMessage;
szMessage.Format("Error in SaveFile(). SQL State %s. Native %ld. Source: %s", szSQLState, NativeError, szMessageText );
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
return szMessage;
}
}
}
}
break;
}
default:
{
CString szMessage;
szMessage.Format("Error in SaveBuffer(). Unknown parameter buffer.");
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
return szMessage;
}
break;
}
}
}
SQLRETURN retcode3;
retcode3 = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
ASSERT(retcode3 == SQL_SUCCESS);
}
}
}
This code is not tested or even compiled, but it should point you in the right direction.