basic commandline parsing + basic tox setup
This commit is contained in:
parent
04310100b5
commit
b7915c55a4
@ -6,6 +6,15 @@ project(tox_ngc_ft1_tool C CXX)
|
|||||||
|
|
||||||
add_executable(tox_ngc_ft1_tool
|
add_executable(tox_ngc_ft1_tool
|
||||||
./main.cpp
|
./main.cpp
|
||||||
|
|
||||||
|
./command_line.hpp
|
||||||
|
./command_line.cpp
|
||||||
|
|
||||||
|
./tox_utils.hpp
|
||||||
|
./tox_utils.cpp
|
||||||
|
|
||||||
|
./tox_client.hpp
|
||||||
|
./tox_client.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_features(tox_ngc_ft1_tool PUBLIC cxx_std_17)
|
target_compile_features(tox_ngc_ft1_tool PUBLIC cxx_std_17)
|
||||||
|
94
src/command_line.cpp
Normal file
94
src/command_line.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include "./command_line.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
CommandLine::CommandLine(int argc, char** argv) {
|
||||||
|
assert(argc > 0);
|
||||||
|
|
||||||
|
exe = argv[0];
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
std::string_view arg_sv{argv[i]};
|
||||||
|
|
||||||
|
if (arg_sv == "-v") {
|
||||||
|
version = true;
|
||||||
|
_should_exit = true;
|
||||||
|
} else if (arg_sv == "-V") {
|
||||||
|
verbose = true;
|
||||||
|
} else if (arg_sv == "-h") {
|
||||||
|
help = true;
|
||||||
|
printHelp();
|
||||||
|
_should_exit = true;
|
||||||
|
} else if (arg_sv == "-G") {
|
||||||
|
if (i+1 >= argc) {
|
||||||
|
std::cerr << "-G missing <chat_id> parameter!\n\n";
|
||||||
|
printHelp();
|
||||||
|
_should_exit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chat_id = argv[++i];
|
||||||
|
} else if (arg_sv == "-F") {
|
||||||
|
if (i+1 >= argc) {
|
||||||
|
std::cerr << "-F missing <path> parameter!\n\n";
|
||||||
|
printHelp();
|
||||||
|
_should_exit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
profile_path = argv[++i];
|
||||||
|
} else if (arg_sv == "-a") {
|
||||||
|
} else if (arg_sv == "-f") {
|
||||||
|
if (i+1 >= argc) {
|
||||||
|
std::cerr << "-f missing <path> parameter!\n\n";
|
||||||
|
printHelp();
|
||||||
|
_should_exit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
send_path = argv[++i];
|
||||||
|
} else if (arg_sv == "-d") {
|
||||||
|
if (i+1 >= argc) {
|
||||||
|
std::cerr << "-d missing <path> parameter!\n\n";
|
||||||
|
printHelp();
|
||||||
|
_should_exit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
receive_dump_dir = argv[++i];
|
||||||
|
} else if (arg_sv == "-D") {
|
||||||
|
if (i+1 >= argc) {
|
||||||
|
std::cerr << "-D missing <id/hash> parameter!\n\n";
|
||||||
|
printHelp();
|
||||||
|
_should_exit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
receive_id = argv[++i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandLine::printHelp(void) {
|
||||||
|
std::cout
|
||||||
|
<< "meta:\n"
|
||||||
|
<< " -v version info\n"
|
||||||
|
<< " -V verbose\n"
|
||||||
|
<< " -h help\n"
|
||||||
|
<< "\n"
|
||||||
|
<< " connectivity:\n"
|
||||||
|
<< " -G <chat_id>\n"
|
||||||
|
<< " -F profile.tox\n"
|
||||||
|
<< " will print friend id at startup\n"
|
||||||
|
<< " will autoaccept any invite\n"
|
||||||
|
<< " if no -F give, will not save profile.\n"
|
||||||
|
<< " if profile exists load, otherwise create new\n"
|
||||||
|
<< "\n"
|
||||||
|
<< " transfer variant:\n"
|
||||||
|
<< " -a id1/sha128_single/sha128_info/sha256_single/sha256_info\n"
|
||||||
|
<< "\n"
|
||||||
|
<< " send:\n"
|
||||||
|
<< " -f send_this_file.zip\n"
|
||||||
|
<< "\n"
|
||||||
|
<< " receive:\n"
|
||||||
|
<< " -d dump/everything/in/this/dir\n"
|
||||||
|
<< " -D <id/hash> (what to dl)\n"
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
65
src/command_line.hpp
Normal file
65
src/command_line.hpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// meta:
|
||||||
|
// -v version info
|
||||||
|
// -V verbose
|
||||||
|
// -h help
|
||||||
|
//
|
||||||
|
// connectivity:
|
||||||
|
// -G <chat_id>
|
||||||
|
// -F profile.tox
|
||||||
|
// will print friend id at startup
|
||||||
|
// will autoaccept any invite
|
||||||
|
// if no -F give, will not save profile.
|
||||||
|
// if profile exists load, otherwise create new
|
||||||
|
//
|
||||||
|
// transfer variant:
|
||||||
|
// -a id1/sha128_single/sha128_info/sha256_single/sha256_info
|
||||||
|
//
|
||||||
|
// send:
|
||||||
|
// -f send_this_file.zip
|
||||||
|
//
|
||||||
|
// receive:
|
||||||
|
// -d dump/everything/in/this/dir
|
||||||
|
// -D <id/hash> (what to dl)
|
||||||
|
|
||||||
|
struct CommandLine {
|
||||||
|
std::string exe;
|
||||||
|
|
||||||
|
// meta:
|
||||||
|
// -v
|
||||||
|
bool version {false};
|
||||||
|
// -V
|
||||||
|
bool verbose {false};
|
||||||
|
// -h
|
||||||
|
bool help {false};
|
||||||
|
|
||||||
|
// connectivity:
|
||||||
|
// -G <chat_id>
|
||||||
|
std::string chat_id;
|
||||||
|
// -F profile.tox
|
||||||
|
std::string profile_path;
|
||||||
|
|
||||||
|
// transfer variant:
|
||||||
|
// -a id1/sha128_single/sha128_info/sha256_single/sha256_info
|
||||||
|
// some enum?
|
||||||
|
|
||||||
|
// send:
|
||||||
|
// -f send_this_file.zip
|
||||||
|
std::string send_path;
|
||||||
|
|
||||||
|
// receive:
|
||||||
|
// -d dump/everything/in/this/dir
|
||||||
|
std::string receive_dump_dir;
|
||||||
|
// -D <id/hash> (what to dl)
|
||||||
|
std::string receive_id;
|
||||||
|
|
||||||
|
CommandLine(int argc, char** argv);
|
||||||
|
|
||||||
|
void printHelp(void);
|
||||||
|
|
||||||
|
bool _should_exit {false};
|
||||||
|
};
|
||||||
|
|
25
src/main.cpp
25
src/main.cpp
@ -1,6 +1,29 @@
|
|||||||
#include <tox/tox.h>
|
#include "./tox_client.hpp"
|
||||||
|
|
||||||
|
#include "./command_line.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <iostream>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
CommandLine cl(argc, argv);
|
||||||
|
|
||||||
|
if (cl.version) {
|
||||||
|
std::cout << "tox_ngc_ft1_tool v0.0.1\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cl._should_exit) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ToxClient client(cl);
|
||||||
|
|
||||||
|
std::cout << "tox id: " << client.getOwnAddress() << "\n";
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
client.iterate();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
98
src/tox_client.cpp
Normal file
98
src/tox_client.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include "./tox_client.hpp"
|
||||||
|
|
||||||
|
#include "./tox_utils.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
ToxClient::ToxClient(const CommandLine& cl) :
|
||||||
|
_tox_profile_path(cl.profile_path)
|
||||||
|
{
|
||||||
|
TOX_ERR_OPTIONS_NEW err_opt_new;
|
||||||
|
Tox_Options* options = tox_options_new(&err_opt_new);
|
||||||
|
assert(err_opt_new == TOX_ERR_OPTIONS_NEW::TOX_ERR_OPTIONS_NEW_OK);
|
||||||
|
|
||||||
|
// use cl for options
|
||||||
|
//tox_options_set_log_callback(options, log_cb);
|
||||||
|
tox_options_set_local_discovery_enabled(options, false);
|
||||||
|
tox_options_set_udp_enabled(options, true);
|
||||||
|
tox_options_set_hole_punching_enabled(options, true);
|
||||||
|
|
||||||
|
std::vector<uint8_t> profile_data{};
|
||||||
|
if (!_tox_profile_path.empty()) {
|
||||||
|
std::ifstream ifile{_tox_profile_path, std::ios::binary};
|
||||||
|
|
||||||
|
if (ifile.is_open()) {
|
||||||
|
std::cout << "TOX loading save " << _tox_profile_path << "\n";
|
||||||
|
// fill savedata
|
||||||
|
while (ifile.good()) {
|
||||||
|
auto ch = ifile.get();
|
||||||
|
if (ch == EOF) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
profile_data.push_back(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile_data.empty()) {
|
||||||
|
std::cerr << "empty tox save\n";
|
||||||
|
} else {
|
||||||
|
// set options
|
||||||
|
tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
|
||||||
|
tox_options_set_savedata_data(options, profile_data.data(), profile_data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
ifile.close(); // do i need this?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_NEW err_new;
|
||||||
|
_tox = tox_new(options, &err_new);
|
||||||
|
tox_options_free(options);
|
||||||
|
if (err_new != TOX_ERR_NEW_OK) {
|
||||||
|
std::cerr << "tox_new failed with error code " << err_new << "\n";
|
||||||
|
throw std::runtime_error{"tox failed"};
|
||||||
|
}
|
||||||
|
|
||||||
|
_tox_profile_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToxClient::iterate(void) {
|
||||||
|
tox_iterate(_tox, this);
|
||||||
|
|
||||||
|
if (_tox_profile_dirty) {
|
||||||
|
saveToxProfile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToxClient::getOwnAddress(void) const {
|
||||||
|
std::vector<uint8_t> self_addr{};
|
||||||
|
self_addr.resize(TOX_ADDRESS_SIZE);
|
||||||
|
|
||||||
|
tox_self_get_address(_tox, self_addr.data());
|
||||||
|
|
||||||
|
return bin2hex(self_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToxClient::saveToxProfile(void) {
|
||||||
|
if (_tox_profile_path.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> data{};
|
||||||
|
data.resize(tox_get_savedata_size(_tox));
|
||||||
|
tox_get_savedata(_tox, data.data());
|
||||||
|
|
||||||
|
std::ofstream ofile{_tox_profile_path, std::ios::binary};
|
||||||
|
// TODO: improve
|
||||||
|
for (const auto& ch : data) {
|
||||||
|
ofile.put(ch);
|
||||||
|
}
|
||||||
|
ofile.close(); // TODO: do i need this
|
||||||
|
|
||||||
|
_tox_profile_dirty = false;
|
||||||
|
}
|
||||||
|
|
31
src/tox_client.hpp
Normal file
31
src/tox_client.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "./command_line.hpp"
|
||||||
|
|
||||||
|
#include <tox/tox.h>
|
||||||
|
#include <ngc_ext.h>
|
||||||
|
#include <ngc_ft1.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct ToxClient final {
|
||||||
|
ToxClient(const CommandLine& cl);
|
||||||
|
|
||||||
|
void iterate(void);
|
||||||
|
|
||||||
|
void setToxProfilePath(const std::string& new_path) { _tox_profile_path = new_path; }
|
||||||
|
|
||||||
|
std::string getOwnAddress(void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void saveToxProfile(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Tox* _tox {nullptr};
|
||||||
|
NGC_EXT_CTX* _ext_ctx {nullptr};
|
||||||
|
NGC_FT1* _ft1_ctx {nullptr};
|
||||||
|
|
||||||
|
std::string _tox_profile_path;
|
||||||
|
bool _tox_profile_dirty {false}; // set in callbacks
|
||||||
|
};
|
||||||
|
|
23
src/tox_utils.cpp
Normal file
23
src/tox_utils.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "./tox_utils.hpp"
|
||||||
|
|
||||||
|
#include <sodium.h>
|
||||||
|
|
||||||
|
std::vector<uint8_t> hex2bin(const std::string& str) {
|
||||||
|
std::vector<uint8_t> bin{};
|
||||||
|
bin.resize(str.size()/2, 0);
|
||||||
|
|
||||||
|
sodium_hex2bin(bin.data(), bin.size(), str.c_str(), str.length(), nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
|
return bin;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string bin2hex(const std::vector<uint8_t>& bin) {
|
||||||
|
std::string str{};
|
||||||
|
str.resize(bin.size()*2, '?');
|
||||||
|
|
||||||
|
// HECK, std is 1 larger than size returns ('\0')
|
||||||
|
sodium_bin2hex(str.data(), str.size()+1, bin.data(), bin.size());
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
8
src/tox_utils.hpp
Normal file
8
src/tox_utils.hpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
std::vector<uint8_t> hex2bin(const std::string& str);
|
||||||
|
std::string bin2hex(const std::vector<uint8_t>& bin);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user