-
-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: /fopen
command to auto-open downloaded files
#273
base: master
Are you sure you want to change the base?
Changes from all commits
e5e4244
26832c3
6f99015
3940f2b
d81eed0
a9b10b0
856d5a1
8c78994
44c5f05
58e79b3
401e554
96dc0f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,8 +20,10 @@ | |
* | ||
*/ | ||
|
||
#include <dirent.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <stdio.h> | ||
|
||
#include "chat.h" | ||
#include "conference.h" | ||
|
@@ -335,6 +337,117 @@ | |
|
||
#endif // GAMES | ||
|
||
|
||
void cmd_fopen(WINDOW *window, ToxWindow *self, Tox *tox, int argc, char (*argv)[MAX_STR_SIZE]) | ||
{ | ||
UNUSED_VAR(window); | ||
|
||
if (argc < 1) { | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File ID required."); | ||
return; | ||
} | ||
|
||
long int idx = strtol(argv[1], NULL, 10); | ||
|
||
if ((idx == 0 && strcmp(argv[1], "0")) || idx < 0 || idx >= MAX_FILES) { | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with ID %ld", idx); | ||
return; | ||
} | ||
|
||
FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV); | ||
|
||
if (!ft) { | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with ID %ld.", idx); | ||
return; | ||
} | ||
|
||
if (ft->state != FILE_TRANSFER_PENDING) { | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with ID %ld.", idx); | ||
return; | ||
} | ||
|
||
if ((ft->file = fopen(ft->file_path, "a")) == NULL) { | ||
const char *msg = "File transfer failed: Invalid download path."; | ||
close_file_transfer(self, tox, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); | ||
return; | ||
} | ||
|
||
Tox_Err_File_Control err; | ||
tox_file_control(tox, self->num, ft->filenumber, TOX_FILE_CONTROL_RESUME, &err); | ||
|
||
if (err != TOX_ERR_FILE_CONTROL_OK) { | ||
goto on_recv_error; | ||
} | ||
|
||
// make tmp_dir if it does not exist | ||
/// don't need this for now, prob should go somewhere else anyway. | ||
const char *tmp_dir = "/tmp/toxic-download-dir/"; | ||
DIR* dir = opendir("/tmp/toxic-download-dir/"); | ||
if (dir) { | ||
closedir(dir); | ||
} | ||
|
||
if (mkdir(tmp_dir, S_IRWXU) == -1) { | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Could not create tox download /tmp/ directory.\n", err); | ||
} | ||
// end make tmpdir if it does not exist | ||
|
||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The file path is '%s'", ft->file_path); | ||
|
||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Saving file [%ld] as: '%s'", idx, ft->file_path); | ||
|
||
const bool auto_accept_files = friend_get_auto_accept_files(self->num); | ||
const uint32_t line_skip = auto_accept_files ? 4 : 2; | ||
|
||
char progline[MAX_STR_SIZE]; | ||
init_progress_bar(progline); | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s", progline); | ||
ft->line_id = self->chatwin->hst->line_end->id + line_skip; | ||
ft->state = FILE_TRANSFER_STARTED; | ||
|
||
// make and call xdg command | ||
while (ft->state != FILE_TRANSFER_INACTIVE) { | ||
usleep(100000); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there are legitimate uses for opening files that are still being transferred (most streaming media types like videos and audio) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That sleep will freeze toxic. ft->state can't update while we're in that loop because that function is holding a mutex lock. Sleeps in random functions is almost never the correct solution. They're generally only used in the main loop or in task-specific threads. |
||
char command[MAX_STR_SIZE]; | ||
snprintf(command, sizeof(command), "xdg-open %s", ft->file_path); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to mitigate potential command injection, i suggest we sanitize the string and make them url encoded (with the exception of '/') There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "I am about to run the xdg command."); | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The file path is '%s'", ft->file_path); | ||
|
||
int open_result = popen(command, "r"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. while I agree with the first statement, said path is not portable.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ie we would have to search for the binary first (probably once at startup) |
||
|
||
if (open_result == -1) { | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Could not open file."); | ||
} | ||
// end make and call xdg command | ||
|
||
return; | ||
|
||
on_recv_error: | ||
|
||
switch (err) { | ||
case TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND: | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Friend not found."); | ||
return; | ||
|
||
case TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED: | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Friend is not online."); | ||
return; | ||
|
||
case TOX_ERR_FILE_CONTROL_NOT_FOUND: | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Invalid filenumber."); | ||
return; | ||
|
||
case TOX_ERR_FILE_CONTROL_SENDQ: | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Connection error."); | ||
return; | ||
|
||
default: | ||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed (error %d)\n", err); | ||
return; | ||
} | ||
} | ||
|
||
void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *tox, int argc, char (*argv)[MAX_STR_SIZE]) | ||
{ | ||
UNUSED_VAR(window); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am not sure what the reasoning behind the temp dir is.