is it possible for SQLite conncet to ftp file? - c

I want to connect to a file on my ftp server.
I can download the db file by wget:
wget ftp://hello:world#192.168.137.181:21/test.db
my is as follows:
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
sqlite3_config(SQLITE_CONFIG_URI,1);
/* Open database */
rc = sqlite3_open_v2("ftp://hello:world#192.168.137.181:21/test.db", &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_URI , NULL);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stdout, "Opened database successfully\n");
}
but it showed the error:
Can't open database: unable to open database file
if I change ftp URI to a local db file path,it will work perfectly fine. so how can I solve this problem?

No, it is not possible.
Why don't you read the documentation before asking?

Related

facing linking issue for using mariadb connector/c

I am trying to interact with mariadb database using mariadb connector/c. I have installed mariadb connector using msi file from official site. But bin file of connector is empty. I am new to c coding, if someone knows the reason for bin file to be empty, please suggest me what I can do to solve this?
Following is the code:
#include <stdio.h>
#include <stdlib.h>
#include "C:\Program Files\MariaDB 10.6\include\mysql\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", "admin",
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);
}
Command I am using to compile is:
gcc -o Dbcon.exe Dbcon.c -I"C:\Program Files\MariaDB\MariaDB Connector C 64-bit\include" -L"C:\Program Files\MariaDB\MariaDB Connector C 64-bit\lib" -lmariadb
I am getting error as:
C:\Program Files\MariaDB\MariaDB Connector C 64-bit\lib\libmariadb.dll: file not recognized: File format not recognized
What wrong I am doing? Can anyone suggest the right way to do this?

Get logged in user in Ubuntu 16.04 LTS Desktop

I'm working on a C application in which I need the name of the currently logged in user. I have tried using getlogin() and getlogin_r() with no success (tested on multiple systems with Ubuntu 16.04 LTS). The application will run as root so I cannot use the environment variables.
Both getlogin() and getlogin_r() work just fine on other Ubuntu 17.04/17.10/18.04(beta) so I don't understand why it doesn't work in 16.04.
Here is a code snippet that I used to test:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
int main(int argc, char *argv[])
{
char user[512] = {0};
int ret = getlogin_r(user, 512);
if ( ret != 0){
fprintf(stderr, "Unable to get User name. Return: %d\n", ret);
}
else{
fprintf(stdout, "Username: %s\n", user);
}
char *lgn;
struct passwd *pw;
if ((lgn = getlogin()) == NULL || (pw = getpwnam(lgn)) == NULL)
{
fprintf(stderr, "Get of user information failed.\n");
}
struct passwd *pwd = getpwuid(getuid());
if (pwd){
fprintf(stdout, "Success! Username: %s\n", pwd->pw_name);
}else
fprintf(stderr, "Failed");
return 0;
}
This is the output generated when I execute the code as root:
Unable to get User name. Return : 2
Get of user information failed.
Success! Username: root
getpwuid returns the details of the user running the process so it is not helpful.
I'm kind of stuck now and any help is highly appreciated.
Output using strerror()
getlogin_r() : No such process
getlogin() : No such file or directory
Success! Username: root

How not to open a file twice in linux?

I have a linked list with an fd and a string I used to open this file in each entry. I want to open and add files to this list only if this file is not already opened, because I open and parse this files and do not want to do it twice. My idea was to compare the filename with every single name in this list, but my program do it multiple times and one file in Linux can have multiple names (soft/hard links). I think it should not be so complicated, because its easy for the OS to check, whether I already used a inode or not, r?
I already tried to open the same file with and without flock, but I always get a new fd.
When you successfully open a file use fstat on the file. Check to see if the st_ino and st_dev of the struct stat filed in by fstat have already been recorded in your linked list. If so then close the file descriptor and move on to the next file. Otherwise add the file descriptor, the file name and st_ino and st_dev values to the list.
You can instead use stat to check before opening the file, but using fstat after will be slightly faster if the usual case is that file hasn't already been opened.
In situations like this, it's often useful to consider your data structures. Change to a data structure which does not allow duplicates, such as a hash table.
Maintain a set of which data you've seen before. I've used a hash table for this set. As per #RossRidge's answer, use the inode and device as the key. This allows duplicates to be discovered in O(1) time.
Here is an example implementation.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
static int get_fd(GHashTable *fds, const char *filename, int mode) {
int fd;
struct stat stat;
int keysize = 33;
char key[keysize]; /* Two 64 bit numbers as hex and a separator */
/* Resolve any symlinks */
char *real_filename = realpath(filename, NULL);
if( real_filename == NULL ) {
printf("%s could not be resolved.\n", filename);
return -1;
}
/* Open and stat */
fd = open( real_filename, mode );
if( fd < 0 ) {
printf("Could not open %s: %s.\n", real_filename, strerror(errno));
return -1;
}
if( fstat(fd, &stat) != 0 ) {
printf("Could not stat %s: %s.\n", real_filename, strerror(errno));
return -1;
}
/* Make a key for tracking which data we've processed.
This uses both the inode and the device it's on.
It could be done more efficiently as a bit field.
*/
snprintf(key, keysize, "%lx|%lx", (long int)stat.st_ino, (long int)stat.st_dev);
/* See if we've already processed that */
if( g_hash_table_contains(fds, key) ) {
return 0;
}
else {
/* Note that we've processed it */
g_hash_table_add(fds, key);
return fd;
}
}
int main(int argc, char** argv) {
int mode = O_RDONLY;
int fd;
GHashTable *fds = g_hash_table_new(&g_str_hash, &g_str_equal);
for(int i = 1; i < argc; i++) {
char *filename = argv[i];
fd = get_fd(fds, filename, mode);
if( fd == 0 ) {
printf("%s has already been processed.\n", filename);
}
else if( fd < 0 ) {
printf("%s could not be processed.\n", filename);
}
else {
printf("%s: %d\n", filename, fd);
}
}
}
And here's a sample result.
$ touch one two three
$ ln one one_link
$ ln -s two two_sym
$ ./test one* two* three*
one: 3
one_link has already been processed.
two: 5
two_sym has already been processed.
three: 7
As long as you don't close the successfully and intentionally opened files, you can use nonblocking flock to prevent another lock on the same file:
#include <unistd.h>
#include <sys/file.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <assert.h>
int openAndLock(const char* fn){
int fd = -1;
if(((fd = open(fn, O_RDONLY)) >= 0) && (flock(fd, LOCK_EX|LOCK_NB) == 0)){
fprintf(stderr, "Successfully opened and locked %s\n", fn);
return fd;
}else{
fprintf(stderr, "Failed to open or lock %s\n", fn);
close(fd);
return -1;
}
}
int main(int argc, char** argv){
for(int i=1; i<argc; i++){
openAndLock(argv[i]);
}
return 0;
}
Example:
$ touch foo
$ ln foo bar
$ ./a.out foo foo
Successfully opened and locked foo
Failed to open or lock foo
$ ./a.out foo bar
Successfully opened and locked foo
Failed to open or lock bar

How to do double authentication using libssh module?

My SSH server uses double authtication. I do not know how its implemented. But initially its asks for a password, then again asks for another password to login to a separate console which is different from usual control.
My code is similar to the example code shown in the documentations,
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <libssh/libssh.h>
int main(int argc, char * argv[])
{
ssh_session my_ssh_session = ssh_new();
int rc;
char * password;
char * username = "admin";
// Check if ssh session exists.
if(my_ssh_session == NULL)
{
exit(-1);
}
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "x.x.x.x");
rc = ssh_connect(my_ssh_session);
if (rc != SSH_OK)
{
fprintf(stderr, "Error Connecting to Server: %s.\n", ssh_get_error(my_ssh_session));
exit(-1);
}
password = getpass("Password: ");
rc = ssh_userauth_password(my_ssh_session, username, password);
if (rc != SSH_AUTH_SUCCESS)
{
fprintf(stderr, "ERROR Authenticating: %s.\n", ssh_get_error(my_ssh_session));
ssh_disconnect(my_ssh_session);
ssh_free(my_ssh_session);
}
else
{
printf("Authentication Successful.\n");
}
ssh_free(my_ssh_session);
}
How do i implement a double authtication in this ? can you kindly help me out ?
What version of
libssh do you have?
"versions 0.5.1 and above have a logical error in the handling of a SSH_MSG_NEWKEYS and SSH_MSG_KEXDH_REPLY package. A detected error did not set the session into the error state correctly and further processed the packet which leads to a null pointer dereference. This is the packet after the initial key exchange and doesn’t require authentication."
Ref libssh

Why is my sqlite3 file never being created?

I'm trying to create a sqlite3 database in Xcode.
Here is the code I'm using:
#include <stdlib.h>
#include <stdio.h>
#include <sqlite3.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
printf("called here");
return 0;
}
int main(int argc, const char * argv[]) {
sqlite3 *db;
char *zErrMsg = 0;
int result = sqlite3_open("noodle.sqlite3", &db);
if (result != SQLITE_OK) {
printf("did not work\n");
exit(0);
}
char *sql = "CREATE TABLE TEST (ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL);";
result = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if (result != SQLITE_OK) {
printf("heya");
exit(0);
}
char *sql2 = "INSERT INTO TEST VALUES (3, 'NEATO');";
result = sqlite3_exec(db, sql2, callback, 0, &zErrMsg);
if (result != SQLITE_OK) {
printf("dangit");
exit(0);
}
const char* data = "Callback function called";
char *sql3 = "SELECT * FROM TEST;";
result = sqlite3_exec(db, sql3, callback, (void *)data, &zErrMsg);
return 0;
}
And I'm following this tutorial. But the directory that I have my main.c file in never sees the creation of a noodle.sqlite3 file.
What am I doing wrong? I thought sqlite3_open creates the database if one doesn't exist already.
Unless you're seeing your error message, it probably is creating the file, but probably not where you're looking for it.
Because you don't specify the folder in which the file should be placed, the file will generally be in the "current working directory". If you run it from a Terminal window, that will be whatever folder you ran it from. If you're running this from Xcode, the "current working folder" could be the folder in which the executable product has been placed, which you can identify by right clicking on the "product" and choosing "Show in Finder":
.
I've also seen it create file in the Documents folder.
Bottom line, if you don't see the file, search your Mac using the Finder's search feature and look for "name:noodle", and you should find it that way.
Frankly, I would take the ambiguity out of the process, and explicitly tell it to save the file in the documents folder:
NSString *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *path = [documents stringByAppendingPathComponent:#"noodle.sqlite3"];
sqlite3 *db;
char *zErrMsg = 0;
int result = sqlite3_open([path UTF8String], &db);

Resources