"Invalid command" error with git_remote_connect - c++

I'm actually try to use libgit2 with C++ to commit and push in a git repository.
No problem with HTTPS but with SSH I have the error :
git_remote_connect : Invalid command: 'XXX 'YYY/test.git''
You appear to be using ssh to clone a git:// URL.
Make sure your core.gitProxy config option and the
GIT_PROXY_COMMAND environment variable are NOT set
After long research I finally found where my problem normally comes from.
In git_remote_connect the third argument is a git_remote_callbacks.
I need to define a payload in this callbacks.
The payload need to be a git_strarray containing two string but I have absolutly no idea of what string I'm supposed to write. A shell command? A c++ function? An username?
If I don't add the payload in the callbacks, I have the error :
"invalid ssh paths, must be two strings"
I create a payload :
char * str1 = "";
char * str2 = "XXX"; //The string that appear in the error message
char * astr[2];
astr[0] = str1;
astr[1] = str2;
git_strarray payload = {astr, 2};
push_options.callbacks.payload = &payload;
My question is: Did you know what I'm supposed to write in the two string of the payload?
Solved
I solved my problem: I added transport to my callbacks, that's why that didn't work. Thank you Carlosmn for your patience!
There is a slack for libgit2, you can join it if you have problem: http://slack.libgit2.org/

Related

Config File using Environment Variables

I have a .cfg file and I'd like to use an environment variable to configure one of the fields.
directory=${HOME}/folder1/
However, when I parse this config, it's reading ${HOME} as a string, which is obviously not what I want.
I wrote my own parser in C++, in case I need to do something special. Right now it is a very basic read and parse.
void Config_Parser::parse_config_by_delimiter(string config, string delimiter) {
ifstream infile(config);
while (infile >> line) {
key = line.substr(0, line.find(delimiter));
value = line.substr(line.find(delimiter)+1);
if (this->config_settings.find(key) != this->config_settings.end()) {
cout << "Cannot use config... same key is set multiple times" << endl;
}
this->config_settings.insert({key, value});
}
}
The code seems to work fine for all other config settings (anything not using an environment variable), so I don't think its a problem with the code. But, I am a C++ noobie, so it's here anyways.
When I parse and print out the value:
Actual output: ${HOME}/folder1/
Expected/desired output: /home/my_dir/folder1/
Untested
You can use wordexp to do posix shell-like expansion of strings.
The function wordexp() performs a shell-like expansion of the string
s and returns the result in the structure pointed to by p.
You will need to #include <wordexp.h>
You also probably want to specify the flag WRDE_NOCMD to prevent subshell command execution.
http://man7.org/linux/man-pages/man3/wordexp.3.html
Is the following configuration syntax acceptable to you?
directory = getenv("HOME") + "/folder1/";
If so, then a configuration file parser library I wrote called Config4* can do what you want. You can find it on http://www.config4star.org.
I recommend you scroll down the web page to "Download the Manuals" and retrieve Config4* Getting Started Guide and Config4* C++ API Guide. Chapters 2 (overview of syntax) and 3 (overview of API) of the "Getting Started" guide should be more than sufficient to get you up and running.

Ssh command from Qt

I have a problem with ssh in my Qt application. I need to run a command which removes a file on a remote server. I tried to use a QProcess class to achieve it. So I pass "ssh" as a name of command and necessary args. In common it looks like this:
QStringList params;
params.append(" user#" + ::host +
" \"rm /tmp/" + ::fileName + "\"");
d->impDelProcess->start("ssh", params);
But after all it keeps asking a password, though I generated ssh keys and copied a public key to the remote server. Moreover, when I run the command above in the terminal like this:
ssh user#host "rm /path/fileName"
it works perfect. The file is deleted and no password is asked. So, the problem is somwhere in QProcess. Is any way to get rid of asking a password? Thank you!
Those are separate arguments, when you use string list. Try this:
params.append("user#" + ::host");
params.append("rm /tmp/" + ::fileName);
That will make Qt pass two arguments for ssh, the login string and the command to execute at remote host.
Important note! Above assumes ::filename does not contain spaces or anything else nasty!. You can get around spaces with this:
params.append("rm '/tmp/" + ::fileName + "'");
But it won't help against wild cards or .. in path... Imagine if file name was ../home/user/* for example... So that is better be trusted input, or you need to sanitize it (but that is beyond scope of this answer).
What you do in the question code is to construct a single argument, equivalent to this shell command line:
ssh 'user#host "rm /path/filename"'

C++ how can I add a linux user to a group programatically

is it possible to add a user on Linux to a group, programatically when I start my program? I am using C++. I know it can be done with the shell, but I need to do it in my C++ program, however I don't know what to use.
You could take 2 approaches:
Use the system() call to execute a shell command to do the work.
Directly modify the /etc/group file. It should be fairly easy to locate the line that contains the group you wish to add to, and then append the user you want to add on the end (making sure to add a comma if there's already a group member).
Given the choice, I'd probably use the first option from the above.
EDIT: As #DevSolar pointed out in his comment, this answer is assuming that your system is using standard local authentication using passwd/shadow/group files in /etc. If your system is NOT using local auth, then that's a completely different ballgame.
Jared Sutton's two options are valid, but I'd like to point out that you don't have to implement editing /etc/group yourself if you use an existing library.
I know of at least busybox, which has implemented this. There's a function defined in libbb/update_passwd.c
int update_passwd(const char *filename, // /etc/group
const char *name, // username
const char *new_passwd, // nullptr
const char *member) // groupname
If you do want to implement it yourself, then you can check out how their function works.
This task is solved by many configuration management software. For example in Salt:
def adduser(name, username):
on_redhat_5 = __grains__.get('os_family') == 'RedHat' and __grains__.get('osmajorrelease') == '5'
if __grains__['kernel'] == 'Linux':
if on_redhat_5:
cmd = 'gpasswd -a {0} {1}'.format(username, name)
else:
cmd = 'gpasswd --add {0} {1}'.format(username, name)
else:
cmd = 'usermod -G {0} {1}'.format(name, username)
retcode = __salt__['cmd.retcode'](cmd, python_shell=False)
return not retcode
As you can see, operating system commands are used. Which one depends on what operating system it is :)

Why this o/P...Server Upload Failed

Please tell me why iam always getting "Server Upload Failed!" in the code
given below.
int rval = 28;
char *return_str=NULL;
return_str = strdup((rval!=28) ? ("Server Upload Failed!") : ("Server TimeOut Reached!"));
printf(" return_str : %s\n", return_str);
Output that iam getting is ====> Server Upload Failed! . I want to know why it is not giving
"Server TimeOut Reached!" as output .
Platform : Linux , gcc-compiler
It looks correct to me, once I read it a couple of extra times. It should generate the latter string ("Server TimeOut Reached").
Not sure why you would ever need to call strdup() on a static string, instead of just using the literal directly. One case would be if there sometimes a need for a more dynamic string I guess, so whoever receives the value assumes it's dynamic and takes ownership.

How do I use a variable in an argument line?

I am using SOCI to make MYSQL connections from my QT4 C++ application. I could hard code a mysql server IP, username, and password but I would rather pass this information in as a variable instead.
For example, I would like to do something like this, but there are no functions that accept these kinds of parameters:
char host [9];
sprintf(host, "192.x.x.x");
session sql(mysql, "host=%s db=dbname user=user password=password", host);
I also tried:
string host = "192.x.x.x";
session sql(mysql,
boost::format("host=%1% db=dbname user=user password='pword'",
%host));
But this also fails.
UPDATE: I was able to solve the problem like so:
QString connection;
connection.append("host=" + host +
" db=dbname user=" + uname +
" password=" + pword);
session sql(mysql, connection.toLatin1().data());
Try using QString's arg function.
session sql(mysql, QString("host=%1 db=%2 user=%3 password=%4").arg(sqlserver).arg(dbname).arg(user).arg(password));
I know it's ugly, and Qt should come up with a prettier solution, but it works.
You can't just arbitrarily pass any function that expects a string one that contains formatting and then a variable amount of whatever after it. C++ simply doesn't work that way. You need to build your string before passing it in. How? The other two answers provide ways even if they get the calling semantics of the session constructor wrong (that's your part to figure out). You might also consider use of boost::format or, if you want to be evil, sprintf.
Use string streams.
Then you can construct the string and concatenate variables as you go. Call .str().c_str() at the end.