1 #include "commands.h"
2
3 #include "command_funcs.h"
4 #include "debug.h"
5 #include "flist.h"
6 #include "tox.h"
7
8 #include "layout/friend.h" // TODO, we should try to remove this dependency
9 #include "ui/edit.h"
10
11 #include <string.h>
12
13 struct Command commands[MAX_NUM_CMDS] = {
14 { "alias", 5, slash_alias },
15 { "invite", 6, slash_invite },
16 { "d", 1, slash_device },
17 { "sendfile", 8, slash_send_file },
18 { "topic", 5, slash_topic },
19 { NULL, 0, NULL },
20 };
21
utox_run_command(char * string,uint16_t string_length,char ** cmd,char ** argument,int trusted)22 uint16_t utox_run_command(char *string, uint16_t string_length, char **cmd, char **argument, int trusted) {
23 if (trusted == 0) {
24 return 0; /* We don't currently support commands from non-trusted sources, before you run commands from friends
25 * or elsewhere, you MUST implement error checking better than what exists */
26 }
27
28 uint16_t cmd_length = 0, argument_length = 0;
29
30 if (string[0] == '/') { /* Cool it's a command we support! */
31 // LOG_TRACE("Commands", "command found!" );
32 uint16_t i;
33 for (i = 0; i < string_length; ++i) {
34 if (string[i] == ' ') {
35 cmd_length = i;
36 break;
37 }
38 }
39
40 ++i;
41 for (; i < string_length; ++i) {
42 if (string[i] != ' ') {
43 argument_length = string_length - i;
44 *argument = string + i;
45 break;
46 }
47 }
48
49 if (cmd_length) {
50 --cmd_length;
51 *cmd = string + 1;
52 }
53 } else {
54 // LOG_TRACE("Commands", "No command found" ); /* Sad, we don't support this command. */
55 *argument = string;
56 cmd = NULL;
57 return 0;
58 }
59
60 int i = 0;
61 while(commands[i].cmd){
62 if (commands[i].cmd_length == cmd_length && memcmp(commands[i].cmd, *cmd, cmd_length) == 0) {
63 void* object = flist_get_friend() ? (void*)flist_get_friend() : (void*)flist_get_groupchat();
64 bool ret = commands[i].func(object, *argument, argument_length);
65 if (ret) {
66 cmd_length = -1;
67 }
68 break;
69 }
70 i++;
71 }
72
73 return cmd_length;
74 }
75
76 bool g_select_add_friend_later = 0;
77
do_tox_url(uint8_t * url_string,int len)78 void do_tox_url(uint8_t *url_string, int len) {
79 LOG_TRACE("Commands", "Command: %.*s" , len, url_string);
80
81 //! lacks max length checks, writes to inputs even on failure, no notice of failure
82 // doesn't reset unset inputs
83
84 // slashes are removed later
85 if (len > 4 && memcmp(url_string, "tox:", 4) == 0) {
86 url_string += 4;
87 len -= 4;
88 } else {
89 return;
90 }
91
92 // wtf??
93 uint8_t *b = (uint8_t *)edit_add_new_friend_id.data, *a = url_string, *end = url_string + len;
94 uint16_t *l = &edit_add_new_friend_id.length;
95 *l = 0;
96 while (a != end) {
97 switch (*a) {
98 case 'a' ... 'z':
99 case 'A' ... 'Z':
100 case '0' ... '9':
101 case '@':
102 case '.':
103 case ' ': {
104 *b++ = *a;
105 *l = *l + 1;
106 break;
107 }
108
109 case '+': {
110 *b++ = ' ';
111 *l = *l + 1;
112 break;
113 }
114
115 case '?':
116 case '&': {
117 a++;
118 if (end - a >= 8 && memcmp(a, "message=", 8) == 0) {
119 b = (uint8_t *)edit_add_new_friend_msg.data;
120 l = &edit_add_new_friend_msg.length;
121 *l = 0;
122 a += 7;
123 } else {
124 // skip everythng up to the next &
125 while (*a != '&' && a != end) {
126 a++;
127 }
128 // set the track back to the & so we can proceed normally
129 a--;
130 }
131 break;
132 }
133
134 case '/': {
135 break;
136 }
137
138 default: {
139 return;
140 }
141 }
142 a++;
143 }
144
145 if (tox_thread_init != UTOX_TOX_THREAD_INIT_SUCCESS) {
146 // if we receive a URL event before the profile is loaded, save it for later.
147 // this usually happens when we are launched as the result of a URL click.
148 g_select_add_friend_later = 1;
149 } else {
150 flist_selectaddfriend();
151 }
152 }
153