Please find the code . I could not find any errors . but the "Type1" supplied to ? in SQL is not binded via SQLITE3_BIND_TEXT.
I need your help, since im an amatuer programmer in sqlite.
char * sql = "SELECT tube_id FROM tubes where type=?";
sqlite3_stmt * stmt;
sqlite3_prepare_v2 (db, sql, strlen (sql) + 1, & stmt, NULL);
int rc=sqlite3_bind_text(stmt,1, /* The number of the argument. */ "Type1",-1,SQLITE_STATIC/* The callback. */);
TRACE(_T("sql: %d %S\n "),rc, sql);
int s = sqlite3_step (stmt);
TRACE(_T("prepared query: %S\n"), sqlite3_sql(stmt));
if (s == SQLITE_DONE) {
int bytes;
const unsigned char * text;
bytes = sqlite3_column_bytes(stmt, 0);
text = sqlite3_column_text (stmt, 0);
TRACE(_T("text: %S\n"), text);
TRACE(_T("stmt: %S\n"), bytes);
} else {
fprintf (stderr, "Failed.\n");
}
sqlite3_reset(stmt);
sqlite3_clear_bindings(stmt);
What #ColonelThirtyTwo told is correct. I have used SQLITE_ROW to over come this problem.
Regards,
Selva
Related
I recently started using Arduino so I still have to adapt and find the differences between C/C++ and the Arduino language.
So I have a question for you.
When I see someone using a C-style string in Arduino (char *str), they always initialize it like this (and never free it) :
char *str = "Hello World";
In pure C, I would have done something like this:
int my_strlen(char const *str)
{
int i = 0;
while (str[i]) {
i++;
}
return (i);
}
char *my_strcpy(char *dest, char const *src)
{
char *it = dest;
while (*src != 0) {
*it = *src;
it++;
src++;
}
return (dest);
}
char *my_strdup(char const *s)
{
char *result = NULL;
int length = my_strlen(s);
result = my_malloc(sizeof(char const) * (length + 1));
if (result == NULL) {
return (NULL);
}
my_strcpy(result, s);
return (result);
}
and then initialize it like this:
char *str = my_strdup("Hello World");
my_free(str);
So here is my question, on C-style Arduino strings, is malloc optional or these people just got it wrong?
Thank you for your answers.
In C++ it's better to use new[]/delete[] and not mix it with malloc/free.
In the Arduino there is also String class, that hides those allocations from you.
However using dynamic memory allocations in such restrained platform has its pitfalls, like heap fragmentation (mainly because String overloads + operator, so everyone is overusing it like: Serial.println(String{"something : "} + a + b + c + d + ......) and then wonders about mysterious crashes.
More about it on Majenko's blog: The Evils of Arduino String class (Majenko has highest reputation on the arduino stackexchange)
Basically with the String class your strdup code would be simple as this:
String str{"Hello World"};
String copyOfStr = str;
enter image description here Delete a record which has Id:2 and Name:Gosling from the below shown table After deleting the records to be reordered by updating Id of all remaining records using below c code. But it it's not reordering instead it updating the same Id to all the record. Please help me out to resolve this issue.
Thanks in advance.
Before delete
Id|Name | MacId| State | Type
-----------------------------
1|Dennis|456731|NOT CONNECTED|NOT FAVORITE
2|Gosling|456731|NOT CONNECTED|NOT FAVORITE
3|MOTO|4568971|NOT CONNECTED|NOT FAVORITE
4|KARBAN|4568971|CONNECTED|NOT FAVORITE
5|Lenovo|4568971|CONNECTED|NOT FAVORITE
After deleting 2nd record It should be like as shown in the below table.
Id|Name |MacId |State | Type
--------------------------------
1|Dennis|456731|NOT CONNECTED|NOT FAVORITE
2|MOTO|4568971|NOT CONNECTED|NOT FAVORITE
3|KARBAN|4568971|CONNECTED|NOT FAVORITE
4|Lenovo|4568971|CONNECTED|NOT FAVORITE
deleteDevice() this method is to delete the record and update remaining Id.
void deleteDevice(char deviceId, char *table)
{
sqlite3 *db;
char *err_msg = 0;
sqlite3_stmt *res;
char query[100];
int rc = sqlite3_open("phonebook2.db", &db);
int lastDeveciId=getLastDeviceId(table);
if (rc != SQLITE_OK)
{
fprintf(stderr, "Cannot open database: %s\n",sqlite3_errmsg(db));
sqlite3_close(db);
return;
}
sprintf(query,"delete from %s where DEVICE_ID =%d;",table,deviceId) ;
rc = sqlite3_exec(db, query, NULL, 0, 0);
if (rc != SQLITE_OK) {
enter code here
fprintf(stderr, "Failed to fetch data: %s;\n", sqlite3_errmsg(db));
sqlite3_close(db);
return;
}
if(lastDeveciId > deviceId)
{
for(int i=deviceId;i<lastDeveciId;i++)
{
sprintf(query,"update %s set DEVICE_ID=%d where DEVICE_ID =%d",table,i-1,i);
printf("Query:%s\n",query);
printf("Breakpoint\n");
rc = sqlite3_exec(db, query, NULL, 0, 0);
update(table,i);
}
}
sqlite3_close(db);
}
int main()
{
deleteDevice(0x02,"paired_phones");
return 0;
}
I'm trying to decrypt a file in memory and this file was encrypted with openssl.
For doing that, i use mmap for loading my encrypted file in memory like that:
void* src = mmap(0, statbuf.st_size,PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
and duplicate it because i don't want to modify my original file
void* dst = mmap(0, statbuf.st_size,PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
memcpy (dst, src, statbuf.st_size);
At this step all is ok but i don't know what to do next.
Initialy for testing purpose, i encrypt my file with the openssl command :
system("openssl enc -aes-256-cbc -salt -in my_encryptedfile -out my_encryptedfile.enc -pass")
and decrypt it with this command:
system("openssl enc -d -aes-256-cbc -in my_encryptedfile.enc -out my_encryptedfile -pass pass:")
But i can't use dst in this case, so i search and discovered EVP Symmetric Encryption and Decryption.
link here
Then i encrypted and decrypted my file with that code github code
I try using Key and IV and the decryption in memory and it seem working but i have a problem that i don't understand. When i dump the buffer of my decripted file, i saw "SPACES/NULS" at the end of the file and i don't figure out why it display that. When i try to execute my binany in memory by calling this function :
func()
i got a segmentation fault
Any clues?
typedef void (*JittedFunc)(void);
void* alloc_writable_memory(void *ptr, size_t size) {
ptr = mmap(0, size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (ptr == (void*)-1) {
perror("mmap");
return NULL;
}
return ptr;
}
int make_memory_executable(void* m, size_t size) {
if (mprotect(m, size, PROT_READ |PROT_WRITE | PROT_EXEC) == -1) {
perror("mprotect");
return -1;
}
return 0;
}
int do_crypt(char *in, char *out, int do_encrypt, int inlen)
{
/* Allow enough space in output buffer for additional block */
unsigned char outbuf[inlen + EVP_MAX_BLOCK_LENGTH];
int outlen;
EVP_CIPHER_CTX *ctx;
/* Bogus key and IV: we'd normally set these from
* another source.
*/
unsigned char key[] = "0123456789abcdeF";
unsigned char iv[] = "1234567887654321";
//int n;
printf("step1\n");
/* Don't set key or IV right away; we want to check lengths */
ctx = EVP_CIPHER_CTX_new();
printf("step2\n");
EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, NULL, NULL,do_encrypt);
printf("step3\n");
OPENSSL_assert(EVP_CIPHER_CTX_key_length(ctx) == 16);
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == 16);
/* Now we can set key and IV */
EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, do_encrypt);
printf("step4\n");
if(!EVP_CipherUpdate(ctx, outbuf,&outlen, in, inlen))
{
printf("test 2.1: %d %d\n", inlen, outlen);
printf("step8\n");
/* Error */
EVP_CIPHER_CTX_free(ctx);
return 0;
}
//BIO_dump_fp (stdout, (const char *)outbuf, outlen);
printf(" test 2: %d %d\n", inlen, outlen);
if(!EVP_CipherFinal_ex(ctx, outbuf, &outlen))
{
printf("step11\n");
EVP_CIPHER_CTX_free(ctx);
return 0;
}
//copy the decryted buffer in another memory space
memcpy(out, outbuf, outlen);
printf(" test 3: %d %d\n", inlen, outlen);
//BIO_dump_fp (stdout, (const char *)outbuf, outlen);
printf("step12\n");
//fwrite(outbuf, 1, outlen, out);
printf("step13\n");
EVP_CIPHER_CTX_free(ctx);
return 1;
}
int main()
{
FILE *src, *dst;
char *src_mem, *dst_mem, *dst2_mem = NULL;
struct stat statbuf;
int fd;
src = fopen("hello_encrypted", "rb");
if (!src) {
/* Unable to open file for reading */
fprintf(stderr, "ERROR: fopen error: %s\n", strerror(errno));
return errno;
}
/*get the file des from a file*/
fd = fileno(src);
/* find size of input file */
if (fstat (fd,&statbuf) < 0)
{printf ("fstat error");
return 0;
}
/* go to the location corresponding to the last byte */
if (lseek (fd, statbuf.st_size - 1, SEEK_SET) == -1)
{printf ("lseek error");
return 0;
}
if ((src_mem = mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0)) == (caddr_t) -1)
{
printf ("mmap error for input");
return 0;
}
if ((dst_mem = mmap (0, statbuf.st_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS , -1, 0)) == (caddr_t) -1)
{
printf ("mmap error for output");
return 0;
}
if ((dst2_mem = mmap (0, statbuf.st_size , PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS , -1, 0)) == (caddr_t) -1)
{
printf ("mmap error for output");
return 0;
}
memcpy(dst_mem, src_mem, statbuf.st_size);
int n;
/* 0 for decrypting or 1 for encrypting*/
n = do_crypt(dst_mem,dst2_mem, 0, statbuf.st_size);
printf("%d\n", n);
make_memory_executable(dst2_mem, statbuf.st_size);
//dump of the decrypt binary
BIO_dump_fp (stdout, (const char *)dst2_mem, statbuf.st_size);
//try to launch the decrypted binary ==> segmentation fault
JittedFunc func = dst2_mem;
func();
fclose(src);
return 0;
}
I would remove from the first mmap the flag PROT_WRITE, because you dont want to modify the original file, I think you can also use PROT_PRIV, but have a look to what says the man of mmap.
On the other hand for decrypt your buffer you can use many libraries (a lot of them based on openssl), I specially like CryptoPP but there are many others. Here is an example of how your code will look like on CryptoPP
try {
// CryptoPP::ECB_Mode< CryptoPP::AES >::Decryption d;
// CrypoPP::CBC_Mode< CryptoPP::AES >::Decryption d;
CrypoPP::CBC_CTS_Mode< CryptoPP::AES >::Decryption d;
// What ever mode is best for you
d.SetKey(key.data(), key.size());
// The StreamTransformationFilter removes
// padding as required.
CryptoPP::StringSource s((const uint8_t*)dst, length_dst, true,
new CryptoPP::StreamTransformationFilter(d,
new CryptoPP::StringSink(recovered)
) // StreamTransformationFilter
); // StringSource
} catch(const CryptoPP::Exception& e) {
std::cout << "ERROR decrypting:" << e.what() << std::endl;
return;
}
I have a xml and schema which I want to validate. I don't want schema to be stored in file, but in database location. I use xmlSchemaNewMemParserCtxt to parse the schema. The problem is that this schema references another schema for basic types: <xs:include schemaLocation="CommonTypes.xsd"/>, which libXml2 searches in the current working directory. Is there any way to supply these additional schemas in memory buffer?
xmlRegisterInputCallbacks is what you're probably looking for.
The advantage, they let you construct some kind of a virtual I/O layer. The disadvantage, inputcallbacks are set globally (there is however xmlPopInputCallbacks and xmlCleanupInputCallbacks).
The code below (built upon code from http://knol2share.blogspot.be) demonstrates the use of xmlRegisterInputCallbacks.
All xml and xsd files are loaded from the file system, except when the URI contains "DataTypes.xsd" the schema is fetched from a string. (since schemaLocation is only a hint one could for example prefix schema's
"test.xsd": the main xml schema (please ignore the reference to peacelane.org, namespaces are from a hobby project, just occurred to me now www.peacelane.org might exist, apparently it does...)
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://peacelane.org/ApplianceType/config/45/LIGHTING1/ARC"
xmlns:dt="http://peacelane.org/ApplianceType/config/45/DataTypes"
targetNamespace="http://peacelane.org/ApplianceType/config/45/LIGHTING1/ARC"
elementFormDefault="qualified">
<import namespace="http://peacelane.org/ApplianceType/config/45/DataTypes" schemaLocation="DataTypes.xsd" />
<complexType name="ConfigType">
<sequence>
<element name="housecode" type="dt:char" />
</sequence>
</complexType>
<element name="Config" type="tns:ConfigType"/>
</schema>
"test.xml": a test xml to validate
<?xml version="1.0"?>
<Config xmlns="http://peacelane.org/ApplianceType/config/45/LIGHTING1/ARC">
<housecode>A</housecode>
</Config>
"main.c": the actual code (update the paths for "XMLFileName" and "XSDFileName")
#define LIBXML_SCHEMAS_ENABLED
#include <libxml/xmlschemastypes.h>
#include <stdio.h>
static const char *databaseSchema =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
" <schema elementFormDefault=\"qualified\" xmlns:tns=\"http://peacelane.org/ApplianceType/config/45/DataTypes\" targetNamespace=\"http://peacelane.org/ApplianceType/config/45/DataTypes\" xmlns=\"http://www.w3.org/2001/XMLSchema\">"
" <simpleType name=\"char\">"
" <restriction base=\"string\">"
" <length value=\"1\" />"
" </restriction>"
" </simpleType>"
" </schema>";
//-----------------------------------------------------------------------------
//-- SQL Callbacks (~ simulated db actions)
//-----------------------------------------------------------------------------
static void* sqlOpen(const char * URI) {
return ((void *) databaseSchema );
}
static int sqlClose(void * context) {
return (0);
}
static int sqlRead(void * context, char * buffer, int len) {
const char* result= (const char *) context;
int rlen = strlen(result);
memcpy(buffer, result, rlen);
return rlen +1;
}
static int sqlMatch(const char * URI) {
if ((URI != NULL )&& (strstr(URI, "DataTypes.xsd") != NULL) )return 1;
return 0;
}
//-----------------------------------------------------------------------------
//-- File callbacks
//-----------------------------------------------------------------------------
static void* fileOpen(const char * URI) {
if (URI == NULL )
return (NULL );
FILE* fh = fopen(URI, "rt");
return ((void *) fh);
}
static int fileClose(void * context) {
FILE* fh = (FILE*) context;
if (fh != NULL )
fclose(fh);
return (0);
}
static int fileRead(void * context, char * buffer, int len) {
FILE* fh = (FILE*) context;
fseek(fh, 0L, SEEK_END);
long flen = ftell(fh);
rewind(fh);
if (buffer != NULL )
fread(buffer, flen, 1, fh);
return flen + 1;
}
static int fileMatch(const char * URI) {
if ((URI != NULL ))
if (strstr(URI, "DataTypes.xsd") == NULL ) {
return (1);
}
return (0);
}
//-----------------------------------------------------------------------------
//-- Main
//-----------------------------------------------------------------------------
int main(int argc, char *argv[]) {
xmlDocPtr doc;
xmlSchemaPtr schema = NULL;
xmlSchemaParserCtxtPtr ctxt;
char *XMLFileName =
"/home/dogguts/Projects/libxml2tests/xsdparse/Debug/test.xml";
char *XSDFileName =
"/home/dogguts/Projects/libxml2tests/xsdparse/Debug/test.xsd";
xmlLineNumbersDefault(1);
if (xmlRegisterInputCallbacks(fileMatch, fileOpen, fileRead, fileClose)
< 0) {
fprintf(stderr, "failed to register File handler\n");
exit(1);
}
if (xmlRegisterInputCallbacks(sqlMatch, sqlOpen, sqlRead, sqlClose) < 0) {
fprintf(stderr, "failed to register SQL handler\n");
exit(1);
}
ctxt = xmlSchemaNewParserCtxt(XSDFileName);
xmlSchemaSetParserErrors(ctxt, (xmlSchemaValidityErrorFunc) fprintf,
(xmlSchemaValidityWarningFunc) fprintf, stderr);
schema = xmlSchemaParse(ctxt);
xmlSchemaFreeParserCtxt(ctxt);
xmlSchemaDump(stdout, schema);
doc = xmlReadFile(XMLFileName, NULL, 0);
if (doc == NULL ) {
fprintf(stderr, "Could not parse %s\n", XMLFileName);
} else {
xmlSchemaValidCtxtPtr ctxt;
int ret;
ctxt = xmlSchemaNewValidCtxt(schema);
xmlSchemaSetValidErrors(ctxt, (xmlSchemaValidityErrorFunc) fprintf,
(xmlSchemaValidityWarningFunc) fprintf, stderr);
ret = xmlSchemaValidateDoc(ctxt, doc);
if (ret == 0) {
printf("%s validates\n", XMLFileName);
} else if (ret > 0) {
printf("%s fails to validate\n", XMLFileName);
} else {
printf("%s validation generated an internal error\n", XMLFileName);
}
xmlSchemaFreeValidCtxt(ctxt);
xmlFreeDoc(doc);
}
if (schema != NULL )
xmlSchemaFree(schema);
xmlSchemaCleanupTypes();
xmlCleanupParser();
xmlMemoryDump();
return (0);
}
Notice that, for brevity, the above code doesnt' perform any checks wether (file, memory,...) operations succeeded.
This is a better example how to do it: io1.c
http://www.xmlsoft.org/examples/
It saves a lot of time when you can find what is good way to return value from Read function.
I am currently making a simple client and server but I have run into an issue. Part of the system is for the client to query about a local file on the server. The contents of that file must be then sent to the client. I am able to send all the text within a file to the client however it seems to be stuck in the read loop on the client. Below are the code spits for both the client and server that are meant to deal with this:
Client Code That Reads The Loop
else if(strcmp(commandCopy, get) == 0)
{
char *ptr;
int total = 0;
char *arguments[1024];
char copy[2000];
char * temp;
int rc;
strcpy(copy, command);
ptr = strtok(copy," ");
while (ptr != NULL)
{
temp = (char *)malloc(sizeof(ptr));
temp = ptr;
arguments[total] = temp;
total++;
ptr = strtok (NULL, " ");
}
if(total == 4)
{
if (strcmp(arguments[2], "-f") == 0)
{
printf("1111111111111");
send(sockfd, command, sizeof(command), 0 );
printf("sent %s\n", command);
memset(&command, '\0', sizeof(command));
cc = recv(sockfd, command, 2000, 0);
if (cc == 0)
{
exit(0);
}
}
else
{
printf("Here");
strcpy(command, "a");
send(sockfd, command, sizeof(command), 0 );
printf("sent %s\n", command);
memset(&command, '\0', sizeof(command));
cc = recv(sockfd, command, 2000, 0);
}
}
else
{
send(sockfd, command, sizeof(command), 0 );
printf("sent %s\n", command);
memset(&command, '\0', sizeof(command));
while ((rc = read(sockfd, command, 1000)) > 0)
{
printf("%s", command);
}
if (rc)
perror("read");
}
}
Server Code That Reads the File
char* getRequest(char buf[], int fd)
{
char * ptr;
char results[1000];
int total = 0;
char *arguments[1024];
char data[100];
FILE * pFile;
pFile = fopen("test.txt", "r");
ptr = strtok(buf," ");
while (ptr != NULL)
{
char * temp;
temp = (char *)malloc(sizeof(ptr));
temp = ptr;
arguments[total] = temp;
total++;
ptr = strtok (NULL, " ");
}
if(total < 2)
{
strcpy(results, "Invaild Arguments \n");
return results;
}
if(pFile != NULL)
{
while(fgets(results, sizeof(results), pFile) != NULL)
{
//fputs(mystring, fd);
write(fd,results,strlen(results));
}
}
else
{
printf("Invalid File or Address \n");
}
fclose(pFile);
return "End of File \0";
}
Server Code to execute the command
else if(strcmp(command, "get") == 0)
{
int pid = fork();
if (pid ==-1)
{
printf("Failed To Fork...\n");
return-1;
}
if (pid !=0)
{
wait(NULL);
}
else
{
char* temp;
temp = getRequest(buf, newsockfd);
strcpy(buf, temp);
send(newsockfd, buf, sizeof(buf), 0 );
exit(1);
}
}
The whole else if clause in the client code is a bit large for a function, let alone a part of a function as it presumably is. The logic in the code is ... interesting. Let us dissect the first section:
else if (strcmp(commandCopy, get) == 0)
{
char *ptr;
int total = 0;
char *arguments[1024];
char *temp;
ptr = strtok(copy, " ");
while (ptr != NULL)
{
temp = (char *)malloc(sizeof(ptr));
temp = ptr;
arguments[total] = temp;
total++;
ptr = strtok(NULL, " ");
}
I've removed immaterial declarations and some code. The use of strtok() is fine in context, but the memory allocation is leaky. You allocate enough space for a character pointer, and then copy the pointer from strtok() over the only pointer to the allocated space (thus leaking it). Then the pointer is copied to arguments[total]. The code could, therefore, be simplified to:
else if (strcmp(commandCopy, get) == 0)
{
char *ptr;
int total = 0;
char *arguments[1024];
ptr = strtok(copy, " ");
while (ptr != NULL)
{
arguments[total++] = ptr;
ptr = strtok(NULL, " ");
}
Nominally, there should be a check that you don't overflow the arguments list, but since the original limits the string to 2000 characters, you can't have more than 1000 arguments (all single characters separated by single spaces).
What you have works - it achieves the same assignment the long way around, but it leaks memory prodigiously.
The main problem seems to be that the server sends all the contents, but it doesn't close the socket, so the client has no way of knowing the server's done. If you close the socket after you finish sending the data (or just call shutdown()), then the client's read() will return 0 when it finishes reading the data.
FWIW, there are lots of other problems with this code:
getRequest: you call malloc but never free. In fact, the return value is thrown away.
Why bother forking if you're just going to wait() on the child?
You probably want to use strlcpy instead of strpcy to avoid buffer overruns.