Merge pull request #2145 from profanity-im/fix/2143
fix: restore TTY access for eval_password commands
This commit is contained in:
73
.gitignore
vendored
73
.gitignore
vendored
@@ -1,72 +1,9 @@
|
|||||||
# git ls-files --others --exclude-from=.git/info/exclude
|
|
||||||
# Lines that start with '#' are comments.
|
|
||||||
# For a project mostly in C, the following would be a good set of
|
|
||||||
# exclude patterns (uncomment them if you want to use them):
|
|
||||||
# *.[oa]
|
|
||||||
# *~
|
|
||||||
|
|
||||||
# IDE
|
|
||||||
.codelite/
|
|
||||||
profanity.mk
|
|
||||||
profanity.project
|
|
||||||
profanity.workspace
|
|
||||||
compile_commands.json
|
|
||||||
.tern-port
|
|
||||||
.tern-project
|
|
||||||
.cproject
|
|
||||||
.project
|
|
||||||
.settings/
|
|
||||||
.vscode/
|
|
||||||
*.plist/
|
|
||||||
|
|
||||||
# autotools
|
|
||||||
.libs/
|
|
||||||
/Makefile
|
|
||||||
/Makefile.in
|
|
||||||
_configs.sed
|
|
||||||
aclocal.m4
|
|
||||||
autom4te.cache/
|
|
||||||
build-aux/
|
|
||||||
config.log
|
|
||||||
config.status
|
|
||||||
configure
|
|
||||||
configure*~
|
|
||||||
libprofanity.la
|
|
||||||
libtool
|
|
||||||
m4/
|
|
||||||
**/.deps/
|
|
||||||
**.dirstamp
|
|
||||||
src/config.h
|
|
||||||
src/config.h.in
|
|
||||||
src/config.h.in~
|
|
||||||
src/gitversion.h
|
|
||||||
src/stamp-h1
|
|
||||||
src/plugins/profapi.lo
|
|
||||||
|
|
||||||
# out-of-tree build folders
|
# out-of-tree build folders
|
||||||
build*/
|
build*/
|
||||||
|
|
||||||
# binaries
|
|
||||||
profanity
|
|
||||||
**/*.o
|
|
||||||
|
|
||||||
# test output
|
|
||||||
tests/functionaltests/functionaltests
|
|
||||||
tests/functionaltests/functionaltests.log
|
|
||||||
tests/functionaltests/functionaltests.trs
|
|
||||||
tests/unittests/unittests
|
|
||||||
tests/unittests/unittests.log
|
|
||||||
tests/unittests/unittests.trs
|
|
||||||
test-suite.log
|
|
||||||
|
|
||||||
# valgrind output
|
# valgrind output
|
||||||
profval*
|
profval*
|
||||||
|
|
||||||
# local scripts
|
|
||||||
clean-test.sh
|
|
||||||
gen_docs.sh
|
|
||||||
gitpushall.sh
|
|
||||||
|
|
||||||
# website files
|
# website files
|
||||||
main_fragment.html
|
main_fragment.html
|
||||||
toc_fragment.html
|
toc_fragment.html
|
||||||
@@ -88,18 +25,16 @@ apidocs/c/doxygen_sqlite3.db
|
|||||||
# Temp Vim files
|
# Temp Vim files
|
||||||
**/*.swp
|
**/*.swp
|
||||||
|
|
||||||
# Virtual envs
|
# GDB
|
||||||
python2/
|
|
||||||
python3/
|
|
||||||
|
|
||||||
.DS_Store
|
|
||||||
.gdbinit
|
.gdbinit
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
.DS_Store
|
||||||
*.bak
|
*.bak
|
||||||
*.orig
|
*.orig
|
||||||
*.patch
|
*.patch
|
||||||
*.rej
|
*.rej
|
||||||
breaks
|
breaks
|
||||||
|
|
||||||
*.tar.*
|
*.tar.*
|
||||||
*.zip
|
*.zip
|
||||||
*.log*
|
*.log*
|
||||||
|
|||||||
@@ -109,6 +109,35 @@ static gboolean _cmd_execute_alias(ProfWin* window, const char* const inp, gbool
|
|||||||
static gboolean
|
static gboolean
|
||||||
_download_install_plugin(ProfWin* window, gchar* url, gchar* path);
|
_download_install_plugin(ProfWin* window, gchar* url, gchar* path);
|
||||||
|
|
||||||
|
static void
|
||||||
|
_vcard_editor_finished_cb(gchar* message, void* user_data)
|
||||||
|
{
|
||||||
|
if (message) {
|
||||||
|
char** field = user_data;
|
||||||
|
if (*field) {
|
||||||
|
free(*field);
|
||||||
|
}
|
||||||
|
*field = g_strdup(message);
|
||||||
|
cons_show("Field updated. Remember to call /me save to apply changes.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_update_vcard_field(char** field, char* value)
|
||||||
|
{
|
||||||
|
if (!value) {
|
||||||
|
if (launch_editor(*field, _vcard_editor_finished_cb, field)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (*field) {
|
||||||
|
free(*field);
|
||||||
|
}
|
||||||
|
*field = strdup(value);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Processes a line of input and determines if profanity should continue.
|
* @brief Processes a line of input and determines if profanity should continue.
|
||||||
*
|
*
|
||||||
@@ -384,7 +413,10 @@ cmd_connect(ProfWin* window, const char* const command, gchar** args)
|
|||||||
|
|
||||||
// use eval_password if set
|
// use eval_password if set
|
||||||
} else if (account->eval_password) {
|
} else if (account->eval_password) {
|
||||||
|
ui_suspend();
|
||||||
gboolean res = account_eval_password(account);
|
gboolean res = account_eval_password(account);
|
||||||
|
ui_resume();
|
||||||
|
ui_resize();
|
||||||
if (res) {
|
if (res) {
|
||||||
conn_status = cl_ev_connect_account(account);
|
conn_status = cl_ev_connect_account(account);
|
||||||
free(account->password);
|
free(account->password);
|
||||||
@@ -1615,6 +1647,51 @@ cmd_help(ProfWin* window, const char* const command, gchar** args)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cmd_editor_finished_cb(gchar* message, void* user_data)
|
||||||
|
{
|
||||||
|
if (message) {
|
||||||
|
rl_insert_text(message);
|
||||||
|
rl_point = rl_end;
|
||||||
|
rl_forced_update_display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ProfWin* window;
|
||||||
|
char* roomjid;
|
||||||
|
} EditorFinishedContext;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cmd_room_editor_finished_cb(gchar* message, void* user_data)
|
||||||
|
{
|
||||||
|
EditorFinishedContext* ctx = user_data;
|
||||||
|
if (message && ctx->roomjid) {
|
||||||
|
message_send_groupchat_subject(ctx->roomjid, message);
|
||||||
|
}
|
||||||
|
if (ctx) {
|
||||||
|
g_free(ctx->roomjid);
|
||||||
|
g_free(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cmd_correct_editor_finished_cb(gchar* message, void* user_data)
|
||||||
|
{
|
||||||
|
EditorFinishedContext* ctx = user_data;
|
||||||
|
if (message && ctx->window) {
|
||||||
|
if (ctx->window->type == WIN_CHAT) {
|
||||||
|
ProfChatWin* chatwin = (ProfChatWin*)ctx->window;
|
||||||
|
cl_ev_send_msg_correct(chatwin, message, FALSE, TRUE);
|
||||||
|
} else if (ctx->window->type == WIN_MUC) {
|
||||||
|
ProfMucWin* mucwin = (ProfMucWin*)ctx->window;
|
||||||
|
cl_ev_send_muc_msg_corrected(mucwin, message, FALSE, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
cmd_about(ProfWin* window, const char* const command, gchar** args)
|
cmd_about(ProfWin* window, const char* const command, gchar** args)
|
||||||
{
|
{
|
||||||
@@ -4008,18 +4085,13 @@ cmd_subject(ProfWin* window, const char* const command, gchar** args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (g_strcmp0(args[0], "editor") == 0) {
|
if (g_strcmp0(args[0], "editor") == 0) {
|
||||||
gchar* message = NULL;
|
|
||||||
char* subject = muc_subject(mucwin->roomjid);
|
char* subject = muc_subject(mucwin->roomjid);
|
||||||
|
|
||||||
if (get_message_from_editor(subject, &message)) {
|
EditorFinishedContext* ctx = g_new0(EditorFinishedContext, 1);
|
||||||
return TRUE;
|
ctx->roomjid = g_strdup(mucwin->roomjid);
|
||||||
}
|
|
||||||
|
launch_editor(subject, _cmd_room_editor_finished_cb, ctx);
|
||||||
|
|
||||||
if (message) {
|
|
||||||
message_send_groupchat_subject(mucwin->roomjid, message);
|
|
||||||
} else {
|
|
||||||
cons_bad_cmd_usage(command);
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9542,16 +9614,7 @@ cmd_change_password(ProfWin* window, const char* const command, gchar** args)
|
|||||||
gboolean
|
gboolean
|
||||||
cmd_editor(ProfWin* window, const char* const command, gchar** args)
|
cmd_editor(ProfWin* window, const char* const command, gchar** args)
|
||||||
{
|
{
|
||||||
auto_gchar gchar* message = NULL;
|
launch_editor(NULL, _cmd_editor_finished_cb, NULL);
|
||||||
|
|
||||||
if (get_message_from_editor(NULL, &message)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
rl_insert_text(message);
|
|
||||||
ui_resize();
|
|
||||||
rl_point = rl_end;
|
|
||||||
rl_forced_update_display();
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -9565,20 +9628,10 @@ cmd_correct_editor(ProfWin* window, const char* const command, gchar** args)
|
|||||||
|
|
||||||
gchar* initial_message = win_get_last_sent_message(window);
|
gchar* initial_message = win_get_last_sent_message(window);
|
||||||
|
|
||||||
auto_gchar gchar* message = NULL;
|
EditorFinishedContext* ctx = g_new0(EditorFinishedContext, 1);
|
||||||
if (get_message_from_editor(initial_message, &message)) {
|
ctx->window = window;
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->type == WIN_CHAT) {
|
launch_editor(initial_message, _cmd_correct_editor_finished_cb, ctx);
|
||||||
ProfChatWin* chatwin = (ProfChatWin*)window;
|
|
||||||
|
|
||||||
cl_ev_send_msg_correct(chatwin, message, FALSE, TRUE);
|
|
||||||
} else if (window->type == WIN_MUC) {
|
|
||||||
ProfMucWin* mucwin = (ProfMucWin*)window;
|
|
||||||
|
|
||||||
cl_ev_send_muc_msg_corrected(mucwin, message, FALSE, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -10110,21 +10163,8 @@ cmd_vcard_set(ProfWin* window, const char* const command, gchar** args)
|
|||||||
|
|
||||||
switch (element->type) {
|
switch (element->type) {
|
||||||
case VCARD_NICKNAME:
|
case VCARD_NICKNAME:
|
||||||
if (!value) {
|
if (_update_vcard_field(&element->nickname, value)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->nickname, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->nickname) {
|
|
||||||
free(element->nickname);
|
|
||||||
}
|
|
||||||
element->nickname = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->nickname) {
|
|
||||||
free(element->nickname);
|
|
||||||
}
|
|
||||||
element->nickname = strdup(value);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VCARD_BIRTHDAY:
|
case VCARD_BIRTHDAY:
|
||||||
@@ -10140,130 +10180,38 @@ cmd_vcard_set(ProfWin* window, const char* const command, gchar** args)
|
|||||||
element->birthday = g_date_time_new_local(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 0, 0, 0);
|
element->birthday = g_date_time_new_local(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case VCARD_TELEPHONE:
|
case VCARD_TELEPHONE:
|
||||||
if (!value) {
|
if (_update_vcard_field(&element->telephone.number, value)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->telephone.number, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->telephone.number) {
|
|
||||||
free(element->telephone.number);
|
|
||||||
}
|
|
||||||
element->telephone.number = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->telephone.number) {
|
|
||||||
free(element->telephone.number);
|
|
||||||
}
|
|
||||||
element->telephone.number = strdup(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case VCARD_EMAIL:
|
case VCARD_EMAIL:
|
||||||
if (!value) {
|
if (_update_vcard_field(&element->email.userid, value)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->email.userid, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->email.userid) {
|
|
||||||
free(element->email.userid);
|
|
||||||
}
|
|
||||||
element->email.userid = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->email.userid) {
|
|
||||||
free(element->email.userid);
|
|
||||||
}
|
|
||||||
element->email.userid = strdup(value);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VCARD_JID:
|
case VCARD_JID:
|
||||||
if (!value) {
|
if (_update_vcard_field(&element->jid, value)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->jid, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->jid) {
|
|
||||||
free(element->jid);
|
|
||||||
}
|
|
||||||
element->jid = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->jid) {
|
|
||||||
free(element->jid);
|
|
||||||
}
|
|
||||||
element->jid = strdup(value);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VCARD_TITLE:
|
case VCARD_TITLE:
|
||||||
if (!value) {
|
if (_update_vcard_field(&element->title, value)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->title, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->title) {
|
|
||||||
free(element->title);
|
|
||||||
}
|
|
||||||
element->title = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->title) {
|
|
||||||
free(element->title);
|
|
||||||
}
|
|
||||||
element->title = strdup(value);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VCARD_ROLE:
|
case VCARD_ROLE:
|
||||||
if (!value) {
|
if (_update_vcard_field(&element->role, value)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->role, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->role) {
|
|
||||||
free(element->role);
|
|
||||||
}
|
|
||||||
element->role = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->role) {
|
|
||||||
free(element->role);
|
|
||||||
}
|
|
||||||
element->role = strdup(value);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VCARD_NOTE:
|
case VCARD_NOTE:
|
||||||
if (!value) {
|
if (_update_vcard_field(&element->note, value)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->note, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->note) {
|
|
||||||
free(element->note);
|
|
||||||
}
|
|
||||||
element->note = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->note) {
|
|
||||||
free(element->note);
|
|
||||||
}
|
|
||||||
element->note = strdup(value);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VCARD_URL:
|
case VCARD_URL:
|
||||||
if (!value) {
|
if (_update_vcard_field(&element->url, value)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->url, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->url) {
|
|
||||||
free(element->url);
|
|
||||||
}
|
|
||||||
element->url = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->url) {
|
|
||||||
free(element->url);
|
|
||||||
}
|
|
||||||
element->url = strdup(value);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -10271,123 +10219,32 @@ cmd_vcard_set(ProfWin* window, const char* const command, gchar** args)
|
|||||||
}
|
}
|
||||||
} else if (value) {
|
} else if (value) {
|
||||||
if (g_strcmp0(value, "pobox") == 0 && element->type == VCARD_ADDRESS) {
|
if (g_strcmp0(value, "pobox") == 0 && element->type == VCARD_ADDRESS) {
|
||||||
if (!value2) {
|
if (_update_vcard_field(&element->address.pobox, value2)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->address.pobox, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->address.pobox) {
|
|
||||||
free(element->address.pobox);
|
|
||||||
}
|
|
||||||
element->address.pobox = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->address.pobox) {
|
|
||||||
free(element->address.pobox);
|
|
||||||
}
|
|
||||||
element->address.pobox = strdup(value2);
|
|
||||||
}
|
}
|
||||||
} else if (g_strcmp0(value, "extaddr") == 0 && element->type == VCARD_ADDRESS) {
|
} else if (g_strcmp0(value, "extaddr") == 0 && element->type == VCARD_ADDRESS) {
|
||||||
if (!value2) {
|
if (_update_vcard_field(&element->address.extaddr, value2)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->address.extaddr, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->address.extaddr) {
|
|
||||||
free(element->address.extaddr);
|
|
||||||
}
|
|
||||||
element->address.extaddr = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->address.extaddr) {
|
|
||||||
free(element->address.extaddr);
|
|
||||||
}
|
|
||||||
element->address.extaddr = strdup(value2);
|
|
||||||
}
|
}
|
||||||
} else if (g_strcmp0(value, "street") == 0 && element->type == VCARD_ADDRESS) {
|
} else if (g_strcmp0(value, "street") == 0 && element->type == VCARD_ADDRESS) {
|
||||||
if (!value2) {
|
if (_update_vcard_field(&element->address.street, value2)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->address.street, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->address.street) {
|
|
||||||
free(element->address.street);
|
|
||||||
}
|
|
||||||
element->address.street = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->address.street) {
|
|
||||||
free(element->address.street);
|
|
||||||
}
|
|
||||||
element->address.street = strdup(value2);
|
|
||||||
}
|
}
|
||||||
} else if (g_strcmp0(value, "locality") == 0 && element->type == VCARD_ADDRESS) {
|
} else if (g_strcmp0(value, "locality") == 0 && element->type == VCARD_ADDRESS) {
|
||||||
if (!value2) {
|
if (_update_vcard_field(&element->address.locality, value2)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->address.locality, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->address.locality) {
|
|
||||||
free(element->address.locality);
|
|
||||||
}
|
|
||||||
element->address.locality = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->address.locality) {
|
|
||||||
free(element->address.locality);
|
|
||||||
}
|
|
||||||
element->address.locality = strdup(value2);
|
|
||||||
}
|
}
|
||||||
} else if (g_strcmp0(value, "region") == 0 && element->type == VCARD_ADDRESS) {
|
} else if (g_strcmp0(value, "region") == 0 && element->type == VCARD_ADDRESS) {
|
||||||
if (!value2) {
|
if (_update_vcard_field(&element->address.region, value2)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->address.region, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->address.region) {
|
|
||||||
free(element->address.region);
|
|
||||||
}
|
|
||||||
element->address.region = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->address.region) {
|
|
||||||
free(element->address.region);
|
|
||||||
}
|
|
||||||
element->address.region = strdup(value2);
|
|
||||||
}
|
}
|
||||||
} else if (g_strcmp0(value, "pocode") == 0 && element->type == VCARD_ADDRESS) {
|
} else if (g_strcmp0(value, "pocode") == 0 && element->type == VCARD_ADDRESS) {
|
||||||
if (!value2) {
|
if (_update_vcard_field(&element->address.pcode, value2)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->address.pcode, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->address.pcode) {
|
|
||||||
free(element->address.pcode);
|
|
||||||
}
|
|
||||||
element->address.pcode = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->address.pcode) {
|
|
||||||
free(element->address.pcode);
|
|
||||||
}
|
|
||||||
element->address.pcode = strdup(value2);
|
|
||||||
}
|
}
|
||||||
} else if (g_strcmp0(value, "country") == 0 && element->type == VCARD_ADDRESS) {
|
} else if (g_strcmp0(value, "country") == 0 && element->type == VCARD_ADDRESS) {
|
||||||
if (!value2) {
|
if (_update_vcard_field(&element->address.country, value2)) {
|
||||||
gchar* editor_value;
|
return TRUE;
|
||||||
if (get_message_from_editor(element->address.country, &editor_value)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->address.country) {
|
|
||||||
free(element->address.country);
|
|
||||||
}
|
|
||||||
element->address.country = editor_value;
|
|
||||||
} else {
|
|
||||||
if (element->address.country) {
|
|
||||||
free(element->address.country);
|
|
||||||
}
|
|
||||||
element->address.country = strdup(value2);
|
|
||||||
}
|
}
|
||||||
} else if (g_strcmp0(value, "type") == 0 && element->type == VCARD_ADDRESS) {
|
} else if (g_strcmp0(value, "type") == 0 && element->type == VCARD_ADDRESS) {
|
||||||
if (g_strcmp0(value2, "domestic") == 0) {
|
if (g_strcmp0(value2, "domestic") == 0) {
|
||||||
|
|||||||
@@ -138,13 +138,23 @@ account_eval_password(ProfAccount* account)
|
|||||||
gchar* stdout_buf = NULL;
|
gchar* stdout_buf = NULL;
|
||||||
GError* error = NULL;
|
GError* error = NULL;
|
||||||
gint exit_status = 0;
|
gint exit_status = 0;
|
||||||
|
gchar** argv = NULL;
|
||||||
|
|
||||||
if (!g_spawn_command_line_sync(account->eval_password, &stdout_buf, NULL, &exit_status, &error)) {
|
if (!g_shell_parse_argv(account->eval_password, NULL, &argv, &error)) {
|
||||||
log_error("Failed to execute `eval_password` command: %s", error->message);
|
log_error("Failed to parse `eval_password` command: %s", error->message);
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!g_spawn_sync(NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_CHILD_INHERITS_STDIN, NULL, NULL, &stdout_buf, NULL, &exit_status, &error)) {
|
||||||
|
log_error("Failed to execute `eval_password` command: %s", error->message);
|
||||||
|
g_strfreev(argv);
|
||||||
|
g_error_free(error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev(argv);
|
||||||
|
|
||||||
if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == 0) {
|
if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == 0) {
|
||||||
account->password = stdout_buf;
|
account->password = stdout_buf;
|
||||||
g_strstrip(account->password);
|
g_strstrip(account->password);
|
||||||
|
|||||||
@@ -75,6 +75,17 @@ _accounts_save(const char* account_name)
|
|||||||
auto_gchar gchar* sanitized = _sanitize_account_name(account_name);
|
auto_gchar gchar* sanitized = _sanitize_account_name(account_name);
|
||||||
|
|
||||||
if (_accounts_has_group(sanitized)) {
|
if (_accounts_has_group(sanitized)) {
|
||||||
|
// Remove keys from file that are no longer in memory
|
||||||
|
gsize nkeys_disk;
|
||||||
|
auto_gcharv gchar** keys_disk = g_key_file_get_keys(current.keyfile, sanitized, &nkeys_disk, NULL);
|
||||||
|
if (keys_disk) {
|
||||||
|
for (gsize j = 0; j < nkeys_disk; ++j) {
|
||||||
|
if (!g_key_file_has_key(accounts_prof_keyfile.keyfile, sanitized, keys_disk[j], NULL)) {
|
||||||
|
g_key_file_remove_key(current.keyfile, sanitized, keys_disk[j], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gsize nkeys;
|
gsize nkeys;
|
||||||
auto_gcharv gchar** keys = g_key_file_get_keys(accounts_prof_keyfile.keyfile, sanitized, &nkeys, NULL);
|
auto_gcharv gchar** keys = g_key_file_get_keys(accounts_prof_keyfile.keyfile, sanitized, &nkeys, NULL);
|
||||||
if (keys) {
|
if (keys) {
|
||||||
|
|||||||
@@ -449,7 +449,6 @@ _add_to_db(ProfMessage* message, char* type, const Jid* const from_jid, const Ji
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* err_msg;
|
|
||||||
auto_gchar gchar* date_fmt = prof_date_time_format_iso8601(message->timestamp);
|
auto_gchar gchar* date_fmt = prof_date_time_format_iso8601(message->timestamp);
|
||||||
const char* enc = _get_message_enc_str(message->enc);
|
const char* enc = _get_message_enc_str(message->enc);
|
||||||
|
|
||||||
|
|||||||
@@ -20,14 +20,52 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "xmpp/xmpp.h"
|
#include "xmpp/xmpp.h"
|
||||||
|
#include "ui/ui.h"
|
||||||
|
|
||||||
|
typedef struct EditorContext
|
||||||
|
{
|
||||||
|
gchar* filename;
|
||||||
|
void (*callback)(gchar* content, void* user_data);
|
||||||
|
void* user_data;
|
||||||
|
} EditorContext;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_editor_exit_cb(GPid pid, gint status, gpointer data)
|
||||||
|
{
|
||||||
|
EditorContext* ctx = data;
|
||||||
|
gchar* contents = NULL;
|
||||||
|
GError* error = NULL;
|
||||||
|
|
||||||
|
ui_resume();
|
||||||
|
ui_resize();
|
||||||
|
|
||||||
|
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
|
||||||
|
if (g_file_get_contents(ctx->filename, &contents, NULL, &error)) {
|
||||||
|
g_strchomp(contents);
|
||||||
|
ctx->callback(contents, ctx->user_data);
|
||||||
|
g_free(contents);
|
||||||
|
} else {
|
||||||
|
log_error("[Editor] could not read from %s: %s", ctx->filename, error->message);
|
||||||
|
cons_show_error("Could not read edited content: %s", error->message);
|
||||||
|
g_error_free(error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cons_show_error("Editor exited with error status %d", WEXITSTATUS(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove(ctx->filename) != 0) {
|
||||||
|
log_error("[Editor] error during file deletion of %s", ctx->filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(ctx->filename);
|
||||||
|
g_free(ctx);
|
||||||
|
g_spawn_close_pid(pid);
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if an error occurred
|
// Returns true if an error occurred
|
||||||
gboolean
|
gboolean
|
||||||
get_message_from_editor(gchar* message, gchar** returned_message)
|
launch_editor(gchar* initial_content, void (*callback)(gchar* content, void* data), void* user_data)
|
||||||
{
|
{
|
||||||
/* Make sure that there's no junk in the return-pointer in error cases */
|
|
||||||
*returned_message = NULL;
|
|
||||||
|
|
||||||
auto_gchar gchar* filename = NULL;
|
auto_gchar gchar* filename = NULL;
|
||||||
auto_gerror GError* glib_error = NULL;
|
auto_gerror GError* glib_error = NULL;
|
||||||
const char* jid = connection_get_barejid();
|
const char* jid = connection_get_barejid();
|
||||||
@@ -37,64 +75,65 @@ get_message_from_editor(gchar* message, gchar** returned_message)
|
|||||||
log_debug("[Editor] could not get JID");
|
log_debug("[Editor] could not get JID");
|
||||||
auto_gchar gchar* data_dir = files_get_data_path(DIR_EDITOR);
|
auto_gchar gchar* data_dir = files_get_data_path(DIR_EDITOR);
|
||||||
if (!create_dir(data_dir)) {
|
if (!create_dir(data_dir)) {
|
||||||
|
cons_show_error("Could not create editor directory.");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
filename = g_strdup_printf("%s/compose.md", data_dir);
|
filename = g_strdup_printf("%s/compose.md", data_dir);
|
||||||
}
|
}
|
||||||
if (!filename) {
|
if (!filename) {
|
||||||
log_error("[Editor] something went wrong while creating compose file");
|
log_error("[Editor] something went wrong while creating compose file");
|
||||||
|
cons_show_error("Could not create compose file.");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gsize messagelen = 0;
|
gsize messagelen = 0;
|
||||||
if (message != NULL) {
|
if (initial_content != NULL) {
|
||||||
messagelen = strlen(message);
|
messagelen = strlen(initial_content);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_file_set_contents(filename, message, messagelen, &glib_error)) {
|
if (!g_file_set_contents(filename, initial_content, messagelen, &glib_error)) {
|
||||||
log_error("[Editor] could not write to %s: %s", filename, PROF_GERROR_MESSAGE(glib_error));
|
log_error("[Editor] could not write to %s: %s", filename, PROF_GERROR_MESSAGE(glib_error));
|
||||||
|
cons_show_error("Could not write to compose file: %s", PROF_GERROR_MESSAGE(glib_error));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_gchar gchar* editor = prefs_get_string(PREF_COMPOSE_EDITOR);
|
auto_gchar gchar* editor = prefs_get_string(PREF_COMPOSE_EDITOR);
|
||||||
auto_gchar gchar* editor_with_filename = g_strdup_printf("%s %s", editor, filename);
|
gchar** editor_argv = NULL;
|
||||||
auto_gcharv gchar** editor_argv = g_strsplit(editor_with_filename, " ", 0);
|
GError* error = NULL;
|
||||||
|
|
||||||
if (!editor_argv || !editor_argv[0]) {
|
auto_gchar gchar* full_cmd = g_strdup_printf("%s %s", editor, filename);
|
||||||
log_error("[Editor] Failed to parse editor command: %s", editor);
|
if (!g_shell_parse_argv(full_cmd, NULL, &editor_argv, &error)) {
|
||||||
|
log_error("[Editor] Failed to parse editor command: %s", error->message);
|
||||||
|
cons_show_error("Failed to parse editor command: %s", error->message);
|
||||||
|
g_error_free(error);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fork / exec
|
EditorContext* ctx = g_new0(EditorContext, 1);
|
||||||
pid_t pid = fork();
|
ctx->filename = g_steal_pointer(&filename);
|
||||||
if (pid == 0) {
|
ctx->callback = callback;
|
||||||
if (editor_argv && editor_argv[0]) {
|
ctx->user_data = user_data;
|
||||||
int x = execvp(editor_argv[0], editor_argv);
|
|
||||||
if (x == -1)
|
|
||||||
log_error("[Editor] Failed to exec %s", editor);
|
|
||||||
}
|
|
||||||
_exit(EXIT_FAILURE);
|
|
||||||
} else {
|
|
||||||
if (pid == -1) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
waitpid(pid, NULL, 0);
|
|
||||||
|
|
||||||
gchar* contents;
|
ui_suspend();
|
||||||
gsize length;
|
|
||||||
if (!g_file_get_contents(filename, &contents, &length, &glib_error)) {
|
pid_t pid = fork();
|
||||||
log_error("[Editor] could not read from %s: %s", filename, PROF_GERROR_MESSAGE(glib_error));
|
if (pid == -1) {
|
||||||
return TRUE;
|
log_error("[Editor] Failed to fork: %s", strerror(errno));
|
||||||
}
|
ui_resume();
|
||||||
/* Remove all trailing new-line characters */
|
ui_resize();
|
||||||
g_strchomp(contents);
|
cons_show_error("Failed to start editor: %s", strerror(errno));
|
||||||
*returned_message = contents;
|
g_strfreev(editor_argv);
|
||||||
if (remove(filename) != 0) {
|
g_free(ctx->filename);
|
||||||
log_error("[Editor] error during file deletion of %s", filename);
|
g_free(ctx);
|
||||||
} else {
|
return TRUE;
|
||||||
log_debug("[Editor] deleted file: %s", filename);
|
} else if (pid == 0) {
|
||||||
}
|
// Child process: Inherits TTY from parent
|
||||||
|
execvp(editor_argv[0], editor_argv);
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parent process: Watch the child asynchronously
|
||||||
|
g_child_watch_add((GPid)pid, _editor_exit_cb, ctx);
|
||||||
|
g_strfreev(editor_argv);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,6 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
gboolean get_message_from_editor(gchar* message, gchar** returned_message);
|
gboolean launch_editor(gchar* initial_content, void (*callback)(gchar* content, void* data), void* user_data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -120,6 +120,11 @@ ui_sigwinch_handler(int sig)
|
|||||||
void
|
void
|
||||||
ui_update(void)
|
ui_update(void)
|
||||||
{
|
{
|
||||||
|
// UI is suspended
|
||||||
|
if (isendwin()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ProfWin* current = wins_get_current();
|
ProfWin* current = wins_get_current();
|
||||||
if (current->layout->paged == 0) {
|
if (current->layout->paged == 0) {
|
||||||
win_move_to_end(current);
|
win_move_to_end(current);
|
||||||
@@ -171,9 +176,26 @@ ui_reset_idle_time(void)
|
|||||||
g_timer_start(ui_idle_time);
|
g_timer_start(ui_idle_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ui_suspend(void)
|
||||||
|
{
|
||||||
|
endwin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ui_resume(void)
|
||||||
|
{
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ui_resize(void)
|
ui_resize(void)
|
||||||
{
|
{
|
||||||
|
// UI is suspended
|
||||||
|
if (isendwin()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct winsize w;
|
struct winsize w;
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
erase();
|
erase();
|
||||||
@@ -192,6 +214,11 @@ ui_resize(void)
|
|||||||
void
|
void
|
||||||
ui_redraw(void)
|
ui_redraw(void)
|
||||||
{
|
{
|
||||||
|
// UI is suspended
|
||||||
|
if (isendwin()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
title_bar_resize();
|
title_bar_resize();
|
||||||
wins_resize_all();
|
wins_resize_all();
|
||||||
status_bar_resize();
|
status_bar_resize();
|
||||||
|
|||||||
@@ -171,6 +171,12 @@ _inp_slashguard_check(void)
|
|||||||
char*
|
char*
|
||||||
inp_readline(void)
|
inp_readline(void)
|
||||||
{
|
{
|
||||||
|
// UI is suspended
|
||||||
|
if (isendwin()) {
|
||||||
|
g_usleep(100000); // 100ms
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
p_rl_timeout.tv_sec = inp_timeout / 1000;
|
p_rl_timeout.tv_sec = inp_timeout / 1000;
|
||||||
p_rl_timeout.tv_usec = inp_timeout % 1000 * 1000;
|
p_rl_timeout.tv_usec = inp_timeout % 1000 * 1000;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
@@ -996,6 +1002,16 @@ _inp_rl_down_arrow_handler(int count, int key)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_editor_finished_cb(gchar* message, void* user_data)
|
||||||
|
{
|
||||||
|
if (message) {
|
||||||
|
rl_replace_line(message, 0);
|
||||||
|
rl_point = rl_end;
|
||||||
|
rl_forced_update_display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_inp_rl_send_to_editor(int count, int key)
|
_inp_rl_send_to_editor(int count, int key)
|
||||||
{
|
{
|
||||||
@@ -1003,16 +1019,7 @@ _inp_rl_send_to_editor(int count, int key)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_gchar gchar* message = NULL;
|
launch_editor(rl_line_buffer, _editor_finished_cb, NULL);
|
||||||
|
|
||||||
if (get_message_from_editor(rl_line_buffer, &message)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rl_replace_line(message, 0);
|
|
||||||
ui_resize();
|
|
||||||
rl_point = rl_end;
|
|
||||||
rl_forced_update_display();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
|
|
||||||
// core UI
|
// core UI
|
||||||
void ui_init(void);
|
void ui_init(void);
|
||||||
|
void ui_suspend(void);
|
||||||
|
void ui_resume(void);
|
||||||
void ui_load_colours(void);
|
void ui_load_colours(void);
|
||||||
void ui_update(void);
|
void ui_update(void);
|
||||||
void ui_redraw(void);
|
void ui_redraw(void);
|
||||||
|
|||||||
@@ -62,6 +62,14 @@ ui_init(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
|
ui_suspend(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void
|
||||||
|
ui_resume(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void
|
||||||
ui_load_colours(void)
|
ui_load_colours(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user