Related
I am working with FastCgi, trying to generate a dynamic html webpage.
I am able to get the QUERY_STRING easily enough, but I am having trouble trying to copy it into a char array.
If there is even a shorter way of just getting the value from QUERY_STRING, please advise because I am a little over my head.
char *queryString = getenv(ENV_VARS[7]);
char newDeviceName[64];
strncpy( newDeviceName, *queryString, sizeof(*queryString) -1);
printf("------- %c ------------", newDeviceName);
This compiles with only warnings, but once i try to load the webpage, the characters are some weird Chinese looking characters. -> �ፙ�
Thank you in advance.
EDIT: More of my code
const char *ENV_VARS[] = {
"DOCUMENT_ROOT",
"HTTP_COOKIE",
"HTTP_HOST",
"HTTP_REFERER",
"HTTP_USER_AGENT",
"HTTPS",
"PATH",
"QUERY_STRING",
"REMOTE_ADDR",
"REMOTE_HOST",
"REMOTE_PORT",
"REMOTE_USER",
"REQUEST_METHOD",
"REQUEST_URI",
"SCRIPT_FILENAME",
"SCRIPT_NAME",
"SERVER_ADMIN",
"SERVER_NAME",
"SERVER_PORT",
"SERVER_SOFTWARE"
};
int main(void)
{
char deviceName[]=ADAPTERNAME;
time_t t;
/* Intializes random number generator */
srand((unsigned) time(&t));
while (FCGI_Accept() >= 0) {
printf("Content-type: text/html \r\n\r\n");
printf("");
printf("<html>\n");
printf("<script src=\"/js/scripts.js\"></script>");
/* CODE CODE CODE */
printf("<p> hi </p>");
printf("<p> hi </p>");
char *queryString = getenv(ENV_VARS[7]);
char newDeviceName[64];
if (queryString == NULL)
printf("<p> +++++ERROR++++++ </p>");
else {
strcpy( newDeviceName, queryString);
newDeviceName[sizeof(newDeviceName) - 1] = 0;
printf("<p> ------- %s ------------ </p> ", newDeviceName);
}
SOLVED: Amateur mistake, for some reason none of my new edits went into effect until after i restart my lighttpd server.
Your program has undefined behavior. Read those warnings issued by the compiler. They're important.
Don't dereference the pointer when you're passing the string to strncpy(). When you do that, you're now passing a single char. That's converted to a pointer when it's given to strncpy() (which is where you probably get your warning, i.e. passing a char to a function that expects a char*).
You also can't get the size of an array that has decayed to a pointer using sizeof. You're just getting the size of the pointer (which is probably either 8 or 4 bytes depending on your system). Since you don't know the length of the string anyway, it might even be better to just use strcpy() instead of strncpy().
Here's what your code probably should look like:
char *queryString = getenv(ENV_VARS[7]);
char newDeviceName[64];
strcpy( newDeviceName, queryString);
printf("------- %s ------------", newDeviceName); /* use %s to print strings */
The length on your strncpy is wrong [too short], the second argument is wrong, and the format string is incorrect.
Try this:
strncpy( newDeviceName, queryString, sizeof(newDeviceName) - 1);
newDeviceName[sizeof(newDeviceName) - 1] = 0;
printf("------- %s ------------", newDeviceName);
In the call to strncpy, it expects a char * for the second argument, but you pass it a char.
Also, the size is not correct. *queryString is a char and has size 1. Using sizeof(queryString) is not correct either because it will return the size of a pointer. What you actually want is the size of the detination buffer.
In the printf call the %c format specifier expects a char but you pass it a char *. You should instead use %s which expects a char * pointing to a null terminated string.
So what you want to do is this:
strncpy( newDeviceName, queryString, sizeof(newDeviceName) -1);
newDeviceName[sizeof(newDeviceName) - 1] = 0;
printf("------- %s ------------", newDeviceName);
What you want is
strncpy(newDeviceName, queryString, sizeof(newDeviceName)-1);
newDeviceName[63] = '\0'; // Guarantee NUL terminator
printf("----- %s -----", newDeviceName);
So multiple problems:
*queryString just gets you the first character, which strncpy tries to treat as a pointer.
sizeof(*queryString) is the size of a char (i.e. 1)
%c prints a single character, not the string
I've seen this question several times relating to PHP (here is an example). The answer was generally 'stop using magic quotes'. I am having this problem in C however. When I insert binary data into a BLOB in my MySQL database, having run it through mysql_real_escape_string(), some 5c ('\') characters appear in the blob. This disrupts the data and makes it unusable. How can I prevent / fix this?
#define CHUNK_SZ (1024*256)
void insertdb(int16_t *data, size_t size, size_t nmemb)
{
static int16_t *buf;
static unsigned long index;
static short initialized;
unsigned long i;
struct tm *info;
time_t rawtime;
char dbuf[12];
char tbuf[12];
char *chunk;
if(initialized==0){
buf = (int16_t *) malloc(CHUNK_SZ);
initialized = 1;
}
if(index + (nmemb*size) + 1 >= CHUNK_SZ || do_exit == 1){
time(&rawtime);
info = localtime(&rawtime);
snprintf(dbuf, 16, "%d-%02d-%02d", 1900+info->tm_year, 1+info->tm_mon, info->tm_mday);
snprintf(tbuf, 16, "%02d:%02d:%02d", info->tm_hour, info->tm_min, info->tm_sec);
chunk = (char *) malloc(index*2+1);
mysql_real_escape_string(con, chunk, (char *) buf, index);
char *st = "INSERT INTO %s (date, time, tag, data) VALUES ('%s', '%s', %d, '%s')";
int len = strlen(st)+strlen(db_mon_table)+strlen(dbuf)+strlen(tbuf)+sizeof(tag)+index*2+1;
char *query = (char *) malloc(len);
int qlen = snprintf(query, len, st, our_table, dbuf, tbuf, tag, chunk);
if(mysql_real_query(con, query, qlen)){
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
free(chunk);
index = 0;
} else {
memcpy((void *) buf+index, (void *) data, nmemb*size);
index += (nmemb*size);
}
return;
}
EDIT: Please look here. They use the same function to escape binary data (from an image), insert it, and afterward get the same image from the database. That my binary data is somehow different from an image's binary data makes no sense to me.
If you're inserting into a BLOB column, then instead of escaping the data via mysql_real_escape_string(), you should probably express it as a HEX string. You will have to figure out how to encode your int16_t data into the needed byte sequence, as at minimum you have a byte-order question to sort out (but if you're in control of both encoding and decoding then you just need to make them match).
Alternatively, if the data are genuinely textual, rather than binary, then the type of the column should probably be Text rather than BLOB. In that case, you should continue to use an ordinary SQL string and mysql_real_escape_string().
I used mysql connector and extract data from Database in visual studio 2010. Also inserted data successfully as value. But was fail to insert data with variable. Need a help, please.
this one worked.
mysql_query(connect,"INSERT INTO input VALUES(111,'Bangladesh','Khulna','Male','Muhammad Ashikuzzaman KUET','b+')");
But this are not working.
str="Muhammad Ashikuzzaman KUET";
mysql_query(connect,"INSERT INTO input VALUES(111,'Bangladesh','Khulna','Male','#str','b+')");
or
mysql_query(connect,"INSERT INTO input VALUES(111,'Bangladesh','Khulna','Male',#str,'b+')");
Please suggest a solution.
You have to create the string before calling mysql_query():
char statement[512], *str = "Muhammad Ashikuzzaman KUET";
snprintf(statement, sizeof statement, "INSERT INTO input VALUES(111,'Bangladesh','Khulna','Male','%s','b+')", str);
mysql_query(connect, statement);
Also, be careful when creating those query strings. Don't use functions like sprintf() if you cannot be sure how long the resulting string is. Don't write over the boundaries of the memory segment.
Edit
For precaution, You can use mysql_real_escape_string() additionally if the string usually comes from arbitrary sources:
int insertData(MYSQL *connect, char *str, int str_len) {
if (str_len < 0) {
str_len = strlen(str);
}
char esc[2 * str_len + 1];
unsigned long esclen = mysql_real_escape_string(connect, esc, str, str_len);
char statement[512];
snprintf(statement, sizeof statement, "INSERT INTO input VALUES(111,'Bangladesh','Khulna','Male','%s','b+')", esc);
return mysql_query(connect, statement);
}
Also here I've assumed your input string is small enough to fit into 512 characters string. Practically, it won't work. So declare statement length variable according to input string length plus some extra length to fit with the query string together.
I am creating a program that can make mysql transactions through C and html.
I have this query string
query = -id=103&-id=101&-id=102&-act=Delete
Extracting "Delete" by sscanf isn't that hard, but I need help extracting the integers and putting them in an array of int id[]. The number of -id entries can vary depending on how many checkboxes were checked in the html form.
I've been searching for hours but haven't found any applicable solution; or I just did not understand them. Any ideas?
Thanks
You can use strstr and atoi to extract the numbers in a loop, like this:
char *query = "-id=103&-id=101&-id=102&-act=Delete";
char *ptr = strstr(query, "-id=");
if (ptr) {
ptr += 4;
int n = atoi(ptr);
printf("%d\n", n);
for (;;) {
ptr = strstr(ptr, "&-id=");
if (!ptr) break;
ptr += 5;
int n = atoi(ptr);
printf("%d\n", n);
}
}
Demo on ideone.
You want to use strtok or a better solution, to tokenize this string with & and = as tokens.
Take a look at cplusplus.com for more information and an example.
This is the output you would get from strtok
Output:
Splitting string "- This, a sample string." into tokens:
This
a
sample
string
Once you figure out how to split them, the next hurdle is to convert the numbers from strings to ints. For this you need to look at atoi or its safer more robust cousin strtol
Most likely I would write a small lexical scanner to tackle the task. Meaning, I would analyze the string one character at a time, according to a regular expression representing the set of possible inputs.
I try to execute mysql query passing variable. Here is my code
char str[100] = "My String";
mysql_query(conn, printf("INSERT INTO table VALUES %s"), str);
I get that warning during compile process
warning: passing argument 2 of ‘mysql_query’ makes pointer from integer without a cast
What I miss ?
Extending #ckruse's answer, you should take care to use mysql_real_escape_string() if your string comes from arbitrary sources.
int insert_data(MYSQL * mysql, char * str, int len)
{
if (len < 0) {
len = strlen(str);
}
char esc[2*len+1];
unsigned long esclen = mysql_real_escape_string(mysql, esc, str, len);
char statement[512];
snprintf(statement, sizeof statement, "INSERT INTO table VALUES ('%s')", esc);
return mysql_query(mysql, statement);
}
(An alternative could be mysql_hex_string() if dealt with correctly.)
You cannot do that. printf() returns the number of characters printed. You have to create the string before calling mysql_query():
char statement[512], *my_str = "MyString";
snprintf(statement, 512, "INSERT INTO table VALUES ('%s')", str);
mysql_query(conn, statement);
Also, be careful when creating those query strings. Don't use functions like sprintf() if you cannot be sure how long the resulting string is. Don't write over the boundaries of the memory segment.
you should put "'' in front and after the string
like this
mysql_query(conn, printf("INSERT INTO table VALUES ('%s')"), str);