I'm trying to connect to a MariaDB database in a C script and I can't find the necessary documentation. I installed libmariadbclient-dev, but I couldn't find any accompanying documentation such as a man page. There's a basic description and limited documentation here, but the documentation only includes descriptions of functions. The fact is, despite having scoured all sorts of Google results, I don't even know what to import to get this to work, much less how to use it. Is there any guide or documentation on how to use a MariaDB database in C?
The MariaDB Client Library for C has exactly the same API as the MySQL
Connector/C for MySQL 5.5
Here it is: http://dev.mysql.com/doc/refman/5.5/en/c-api-function-overview.html
Another one:
http://zetcode.com/db/mysqlc/
You can compile a minimal test like
#include <my_global.h>
#include <mysql.h>
int main(int argc, char **argv)
{
MYSQL *con = mysql_init(NULL);
if (con == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
exit(1);
}
if (mysql_real_connect(con, "localhost", "root", "root_pswd",
NULL, 0, NULL, 0) == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
if (mysql_query(con, "CREATE DATABASE testdb"))
{
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
mysql_close(con);
exit(0);
}
using
gcc -o mysql-test mysql-test.c $(mysql_config --libs)
Related
I want to make query like this one:
SELECT lyrics FROM cache WHERE author=%s0, title=%s1 LIMIT 1;
where strings %s0 and %s1 should be substituted. Assuming strings are not sanitized, UTF-8 encoded (As database itself), simple null-terminated char* arrays. What are my options to do this? Are there any built-in functions in SQLite (C API) for this?
Like mentioned in comments already prepared statements should be used.
Why Prepared Statements Should Be Favoured
When you create SQL queries yourself as a string, they almost always contain parts of a user's input. An attacker can take advantage of this by, for example, cleverly changing the semantics of the query using ' and thus gaining unauthorized access to data or destroying data.
This is called SQL injection and is one of the top most critical security risks, see here:
https://www.owasp.org/images/7/72/OWASP_Top_10-2017_%28en%29.pdf.pdf
Defense
The use of prepared statements with variable binding (aka parameterized queries) is how all developers should first be taught how to write database queries.
https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html#defense-option-1-prepared-statements-with-parameterized-queries
How to use prepared statements with SQLite
For prepared statements see https://www.sqlite.org/c3ref/stmt.html.
Basic steps are:
create the prepared statement
bind values to parameters
run the SQL
destroy the object to avoid resource leaks
Example
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
void exit_with_error(sqlite3 *db, const char * msg) {
fprintf(stderr, "%s: %s\n", msg, sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
int main() {
sqlite3 *db;
sqlite3_stmt *stmt;
int rc = sqlite3_open("path-to-lyrics", &db);
if (rc != SQLITE_OK)
exit_with_error(db, "can't open db: ");
//create prepared statement
rc = sqlite3_prepare_v2(db, "SELECT lyrics FROM cache WHERE author=?1 AND title=?2 LIMIT 1;", -1, &stmt, 0);
if (rc != SQLITE_OK)
exit_with_error(db, "failure fetching data: ");
//bind values to parameters
sqlite3_bind_text(stmt, 1, "Don Brownrigg", -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, "Just Breathe", -1, SQLITE_STATIC);
//run the SQL
rc = sqlite3_step(stmt);
if (rc == SQLITE_ROW) {
printf("%s\n", sqlite3_column_text(stmt, 0));
}
//destroy the object to avoid resource leaks
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
Build
With CMake it could look like this:
cmake_minimum_required(VERSION 3.14)
project(sqlitequery C)
set(CMAKE_C_STANDARD 99)
add_executable(sqlitequery main.c)
target_link_libraries (sqlitequery sqlite3)
On command line one could build with something like:
gcc -Wall -Wextra main.c -lsqlite3 -o sqlitequery
I'm trying to load regexp.c extension in order to add REGEXP operator into sqlite. What I have done:
Download sqlite3 amalgamation file
Found regexp.c loadable extension
Created test project in VS2015
#include <stdio.h>
#include "stdafx.h"
#include "sqlite3.h"
const char* SQL = "SELECT load_extension('sqlite3.obj', 'sqlite3_regexp_init');";
int main(int argc, char **argv) {
sqlite3 *db = 0; // the hande of connection object to db
char *err = 0;
char *errMsg = "unable to load extension";
// open connection
if (sqlite3_open("my_cosy_database.dblite", &db))
fprintf(stderr, "Error during opening/creation DB: %s\n", sqlite3_errmsg(db));
/*else if (sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0))
{
fprintf(stderr, "Cannot enable extensions loading: %s\n", sqlite3_errmsg(db));
}*/
else if (sqlite3_enable_load_extension(db, 1))
{
fprintf(stderr, "Cannot enable extensions loading: %s\n", sqlite3_errmsg(db));
}
// execute SQL
else if (sqlite3_load_extension(db, "sqlite3.obj", "sqlite3_regexp_init", &errMsg))
{
fprintf(stderr, "Cannot load sqlite3_regexp_init extension: %s\n", sqlite3_errmsg(db));
}
else if (sqlite3_exec(db, SQL, callback, 0, &err))
{
fprintf(stderr, "Ошибка SQL: %sn", err);
sqlite3_free(err);
}
// close connection
sqlite3_close(db);
return 0;
}
Official documentation says: "For security reasons, extension loading is turned off by default. In order to use either the C-language or SQL extension loading functions, one must first enable extension loading using the sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION,1,NULL) C-language API in your application." So this is what I've done. The problem is that I got every time sqlite3_load_extension or sqlite3_exec is called. The same problem appears with commented sqlite3_enable_load_extension and uncommented sqlite3_db_config. I have no idea what causes this exception and there is no clear example of C api usage (even in 'Using Sqlite' book). One thing i could find out is the statement which causes this exception: "(pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/ IMP: R-24505-23230 */" in the SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe p / The VDBE */).
So please, help.
I am attempting to write a simple program that calls git checkout -- . on a Github repo that would be a command line argument. I would like to call it like > clearRepo repoName. I keep all my repos in the same Github directory.
The code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
void print_error()
{
fprintf(stderr, "Error executing: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
void print_usage(char* this)
{
printf("SYNTAX ERROR:\n%s [directoryName]\n", this);
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
if(argc != 2)
{
print_usage(argv[0]);
}
pid_t pid = fork();
if (pid == 0)
{
static char* params[] = {"git", "checkout", "--", ".", NULL};
char s[50], s2[50];
strcpy(s, "/home/myname/Documents/Github/");
strcpy(s2, argv[1]);
strcat(s, s2);
printf("s: %s\n", s);
int err = execv(s, params);
if(err == -1)
{
print_error();
}
exit(127);
}
else
{
waitpid(pid, 0, 0);
}
return 0;
}
It compiles fine, but print_error() will spit out Error executing: Permission denied every time I run it. I am not too familiar with writing programs for Linux, so it is probably a simple mistake. Information on what I'm doing wrong is appreciated. Thanks.
The first argument you're passing to execv is a directory, but execv expects a program. The error "Permission denied" is slightly misleading, because there is no such thing as "permission to execute directories".
To change the current directory, call chdir. Then, call whichever one of the exec* functions you like to invoke git.
chmod u+x filename for changing file permission.
If you want to checkout of a branch, but save the changes, use git stash. You can use git stash pop or git stash apply when you come back to the branch.
https://git-scm.com/docs/git-stash
Git commands and programs are quite tricky.
Follow these steps and you might debug your problem.
Enter the git commands written in the program into a terminal and check if the logic actually works. (Suggested this as you said you were new to Linux)
If it works, change the permission of your file by typing "chmod +x filename.extention".
Hello and Happy new Year ,
I have to accept juste txt files in my C programme ,
I don't have any idea to how to made it .. any ideas?
And I don't know if text file contain Header or something which characterize it..
PS: I'm using Ubuntu so file extension is not seen.
Thank you
In a Linux environment, I would personally go with libmagic, which is the core of the utility program file. The purpose of this library is to do exactly what you are trying to accomplish: identify the type of a file based on it content.
Example usage would look like this.
/* identify.c */
#define _POSIX_SOURCE /* required for fileno() */
#include <magic.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
const char *description;
magic_t cookie;
FILE *fp;
fp = fopen("example.txt", "r");
if(fp == NULL) {
fprintf(stderr, "error: cannot open file\n");
exit(EXIT_FAILURE);
}
cookie = magic_open(MAGIC_NONE);
if(cookie == NULL) {
fprintf(stderr, "error: cannot initialize library\n");
fclose(fp);
exit(EXIT_FAILURE);
}
if( magic_load(cookie, NULL) != 0 ) {
fprintf(stderr, "error: cannot load database : %s\n",
magic_error(cookie));
magic_close(cookie);
fclose(fp);
exit(EXIT_FAILURE);
}
description = magic_descriptor(cookie, fileno(fp));
printf("%s\n", description);
magic_close(cookie);
fclose(fp);
return EXIT_SUCCESS;
}
Name this source file identify.c, create a text file name example.txt with some content in the same directory, and compile with:
gcc -Wall -std=c99 -pedantic -lmagic -o identify identify.c
Then run it.
./identify
And you get something like this printed:
UTF-8 Unicode text
This library can be used in a few different ways, so you should probably have a look at the man page. For example, you can get a MIME type instead of a description like the one above.
The file package of which libmagic is a part is probably already installed on your machine. However, if you are using a distribution such as RHEL of CentOS that splits development headers into a separate package, make sure you have file-devel installed.
I just want to fetch a webpage(its HTML code,if its like www.example.com/example.html) into a text file using C. Is it possible using any library study or anything?
I am really getting lost into "maybe i should learn" PHP or python or something and then use command line invocation of these scripts using system() or exec(). Whats the best way to do so?
My Exact current need is to fetch http://livechat.rediff.com/sports/score/score.txt, which by chance happened to be a .txt file.
use curl or libcurl. It will fetch a webpage for you and you can do whatever you like with it.
As Toby already mentioned, libcurl is probably your best bet. Here is an actual program demonstrating how retrieve a webpage using the libcurl-easy interface:
#include <stdio.h>
#include <curl/curl.h>
int main(int argc, char *argv[]) {
CURL *curl;
CURLcode curl_result;
const char *site;
if (argc != 2) {
fprintf(stderr, "Usage: %s site\n", argv[0]);
return 1;
}
site = argv[1];
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, site);
curl_result = curl_easy_perform(curl);
if(curl_result != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(curl_result));
}
curl_easy_cleanup(curl);
}
else {
fprintf(stderr, "Failed to initialize curl\n");
return 1;
}
return 0;
}
The program takes one argument, the name of the site to retrieve. When compiled with gcc curltest.c -lcurl -o curltest and run as curltest http://livechat.rediff.com/sports/score/score.txt, outputs the following:
l1=England vs South Africa
l2=England
interval=1
message=England 16-2 (13)
tagline=J Trott(6) I Bell(4)*
date=19 August, 2012
ver=19