Mercurial > pidgin
annotate src/gaim-remote.c @ 11261:b53606580f68
[gaim-migrate @ 13439]
Patch #1226486 from Levi Bard
Fixes bug #1224178
If you change the topic in a chat room and that topic change is rejected, the
topic field is wrong -- it shows the new topic even thought it didn't get set.
This patch resets the GUI's topic immediately when you hit enter. Then, if the
topic change is successful, the server will echo the topic change back to us
and we'll update the GUI to the new topic.
The only question is, does the server always echo the topic back to us? From the
core's point of view, I'm ready to assume yes. It's the case for both IRC and
Jabber*. If someone could test changing a topic in SILC or Zephyr, that'd be
great. If servers using those protocols do not echo the topic back, the prpl
will have to fake it as appropriate.
* I didn't actually test on Jabber, but Nathan said the server will echo the
topic change back. If it's broken, let me know.
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Sun, 14 Aug 2005 06:55:57 +0000 |
parents | b4b9dabdd7c7 |
children |
rev | line source |
---|---|
3480 | 1 /* |
2 * gaim-remote | |
3 * | |
8046 | 4 * Gaim is the legal property of its developers, whose names are too numerous |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
3480 | 7 * |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 * | |
22 */ | |
23 | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5859
diff
changeset
|
24 #include "internal.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5859
diff
changeset
|
25 |
3533 | 26 #include <getopt.h> |
5859
022786c7ab53
[gaim-migrate @ 6290]
Christian Hammond <chipx86@chipx86.com>
parents:
5124
diff
changeset
|
27 |
022786c7ab53
[gaim-migrate @ 6290]
Christian Hammond <chipx86@chipx86.com>
parents:
5124
diff
changeset
|
28 #include <gaim-remote/remote.h> |
3480 | 29 |
10005 | 30 /* To be implemented: |
31 " info Show information about connected accounts\n" | |
32 " list Print buddy list\n" | |
33 " ison Show presence state of your buddy\n" | |
34 " convo Open a new conversation window\n" | |
35 " add Add buddy to buddy list\n" | |
36 " remove Remove buddy from list\n" | |
37 " -q, --quiet Send message without showing a conversation\n" | |
38 " window\n" | |
4242 | 39 */ |
3480 | 40 |
41 static struct option longopts[] = { | |
42 {"message", required_argument, NULL, 'm'}, | |
43 {"to", required_argument, NULL, 't'}, | |
44 {"protocol",required_argument, NULL, 'p'}, | |
45 {"from", required_argument, NULL, 'f'}, | |
10086 | 46 {"session", required_argument, NULL, 's'}, |
3480 | 47 {"quiet", no_argument, NULL, 'q'}, |
48 {"help", no_argument, NULL, 'h'}, | |
49 {0,0,0,0} | |
50 }; | |
51 | |
52 struct remoteopts { | |
53 char *command; | |
54 char *uri; | |
55 gboolean help, quiet; | |
10086 | 56 char *message, *to, *from, *protocol, *session; |
10003 | 57 /*int protocol;*/ |
3480 | 58 }; |
9752 | 59 struct remoteopts opts; |
3480 | 60 |
9752 | 61 /* |
62 * Prints a message to the terminal/shell/console. | |
63 * We try to convert "text" from UTF-8 to the user's locale. | |
64 * If that fails then UTF-8 is used as a fallback. | |
65 * | |
66 * If channel is 1, the message is printed to stdout. | |
67 * if channel is 2, the message is printed to stderr. | |
10395 | 68 */ |
9752 | 69 static void |
70 message(char *text, int channel) | |
71 { | |
72 char *text_conv = NULL,*text_output; | |
73 GError *error = NULL; | |
74 | |
75 text_conv = g_locale_from_utf8(text, -1, NULL, NULL, &error); | |
76 | |
77 if (text_conv == NULL) { | |
78 g_warning("%s\n", error->message); | |
79 g_error_free(error); | |
80 } | |
81 | |
82 text_output = (text_conv ? text_conv : text); | |
3480 | 83 |
9752 | 84 switch (channel) { |
85 case 1: | |
86 puts(text_output); | |
87 break; | |
88 case 2: | |
89 fputs(text_output, stderr); | |
90 break; | |
91 default: | |
92 break; | |
93 } | |
94 | |
95 if (text_conv) | |
96 g_free(text_conv); | |
97 } | |
98 | |
99 static void | |
100 show_remote_usage(const char *name) | |
101 { | |
102 char *text = NULL; | |
103 | |
104 text = g_strdup_printf(_("Usage: %s command [OPTIONS] [URI]\n\n" | |
105 " COMMANDS:\n" | |
10395 | 106 " send Send message\n" |
9752 | 107 " uri Handle AIM: URI\n" |
108 " away Popup the away dialog with the default message\n" | |
109 " back Remove the away dialog\n" | |
10395 | 110 " logout Log out all accounts\n" |
111 " quit Close running copy of Gaim\n" | |
112 "\n" | |
9752 | 113 " OPTIONS:\n" |
10003 | 114 " -m, --message=MESG Message to send or show in conversation window\n" |
115 " -t, --to=SCREENNAME Select a target for command\n" | |
116 " -p, --protocol=PROTO Specify protocol to use\n" | |
117 " -f, --from=SCREENNAME Specify screen name to use\n" | |
10086 | 118 " -s, --session=SESSION Specify which Gaim session to use\n" |
9752 | 119 " -h, --help [command] Show help for command\n"), name); |
120 | |
121 message(text, 1); | |
122 g_free(text); | |
123 | |
124 return; | |
125 } | |
126 | |
127 int | |
128 get_options(int argc, char *argv[]) | |
3480 | 129 { |
130 int i; | |
9752 | 131 |
3480 | 132 memset(&opts, 0, sizeof(opts)); |
10003 | 133 /*opts.protocol = -1;*/ |
9752 | 134 |
10086 | 135 while ((i=getopt_long(argc, argv, "m:t:p:f:s:qh", longopts, NULL)) != -1) { |
3480 | 136 switch (i) { |
137 case 'm': | |
138 opts.message = optarg; | |
139 break; | |
140 case 't': | |
141 opts.to = optarg; | |
142 break; | |
143 case 'p': | |
10003 | 144 opts.protocol = optarg; |
3480 | 145 break; |
146 case 'f': | |
147 opts.from = optarg; | |
148 break; | |
10086 | 149 case 's': |
150 opts.session = optarg; | |
151 break; | |
3480 | 152 case 'q': |
153 opts.quiet = TRUE; | |
154 break; | |
155 case 'h': | |
156 opts.help = TRUE; | |
157 break; | |
158 } | |
159 } | |
10086 | 160 |
3480 | 161 /* We must have non getopt'ed argument-- the command */ |
162 if (optind < argc) | |
163 opts.command = g_strdup(argv[optind++]); | |
164 else | |
165 return 1; | |
166 | |
9674 | 167 if (opts.help) |
6643 | 168 return 0; |
169 | |
3480 | 170 /* And we can have another argument--the URI. */ |
6643 | 171 /* but only if we're using the uri command. */ |
172 if (!strcmp(opts.command, "uri")) { | |
9674 | 173 if (argc-optind == 1) |
3480 | 174 opts.uri = g_strdup(argv[optind++]); |
175 else | |
176 return 1; | |
9752 | 177 } else if (optind == argc) |
6643 | 178 return 0; |
179 else | |
180 return 1; | |
181 | |
10086 | 182 return 0; |
183 } | |
184 | |
185 static int | |
186 open_session() { | |
187 int fd = 0, session = 0; | |
188 char *msg; | |
189 | |
190 if (opts.session != NULL) | |
191 session = atoi(opts.session); | |
192 | |
193 fd = gaim_remote_session_connect(session); | |
194 if (fd < 0) { | |
195 msg = g_strdup_printf(_("Gaim not running (on session %d)\nIs the \"Remote Control\" plugin loaded?\n"), session); | |
196 message(msg, 2); | |
197 g_free(msg); | |
198 return -1; | |
199 } | |
200 | |
201 return fd; | |
3480 | 202 } |
203 | |
9752 | 204 static int |
205 send_generic_command(guchar type, guchar subtype) { | |
3480 | 206 int fd = 0; |
5859
022786c7ab53
[gaim-migrate @ 6290]
Christian Hammond <chipx86@chipx86.com>
parents:
5124
diff
changeset
|
207 GaimRemotePacket *p = NULL; |
9752 | 208 |
10086 | 209 fd = open_session(); |
9752 | 210 if (fd < 0) { |
211 return 1; | |
212 } | |
213 p = gaim_remote_packet_new(type, subtype); | |
214 gaim_remote_session_send_packet(fd, p); | |
215 close(fd); | |
216 gaim_remote_packet_free(p); | |
217 | |
218 return 0; | |
219 } | |
220 | |
221 static int | |
222 send_command_uri() { | |
223 int fd = 0; | |
224 GaimRemotePacket *p = NULL; | |
225 | |
10086 | 226 fd = open_session(); |
9752 | 227 if (fd < 0) { |
3480 | 228 return 1; |
229 } | |
5859
022786c7ab53
[gaim-migrate @ 6290]
Christian Hammond <chipx86@chipx86.com>
parents:
5124
diff
changeset
|
230 p = gaim_remote_packet_new(CUI_TYPE_REMOTE, CUI_REMOTE_URI); |
022786c7ab53
[gaim-migrate @ 6290]
Christian Hammond <chipx86@chipx86.com>
parents:
5124
diff
changeset
|
231 gaim_remote_packet_append_string(p, opts.uri); |
022786c7ab53
[gaim-migrate @ 6290]
Christian Hammond <chipx86@chipx86.com>
parents:
5124
diff
changeset
|
232 gaim_remote_session_send_packet(fd, p); |
3480 | 233 close(fd); |
5859
022786c7ab53
[gaim-migrate @ 6290]
Christian Hammond <chipx86@chipx86.com>
parents:
5124
diff
changeset
|
234 gaim_remote_packet_free(p); |
3480 | 235 |
3559 | 236 return 0; |
237 } | |
238 | |
10003 | 239 static int |
240 send_command_send() { | |
241 int fd = 0; | |
242 GaimRemotePacket *p = NULL; | |
10005 | 243 char temp[10003]; /* TODO: Future implementation should send packets instead */ |
10003 | 244 |
10086 | 245 fd = open_session(); |
10003 | 246 if (fd < 0) { |
247 return 1; | |
248 } | |
249 p = gaim_remote_packet_new(CUI_TYPE_REMOTE, CUI_REMOTE_SEND); | |
250 | |
10005 | 251 /* |
252 * Format is as follows: | |
253 * Each string has a 4 character 'header' containing the length of the string | |
254 * The strings are: To, From, Protocol name, Message | |
255 * Following the message is the quiet flag, expressed in a single int (0/1) | |
256 * Because the header is 4 characters long, there is a 9999 char limit on any | |
257 * given string, though none of these strings should be exceeding this. | |
258 * -JBS | |
10003 | 259 */ |
260 | |
10005 | 261 if (opts.to && *opts.to && opts.from && *opts.from && |
262 opts.protocol && *opts.protocol && opts.message && *opts.message && | |
263 (strlen(opts.to) < 10000) && (strlen(opts.from) < 10000) && | |
264 (strlen(opts.protocol) < 20) && (strlen(opts.message) < 10000) ) | |
265 { | |
10112 | 266 sprintf(temp, "%04zd%s", strlen(opts.to), opts.to); |
10003 | 267 gaim_remote_packet_append_string(p, temp); |
10112 | 268 sprintf(temp, "%04zd%s", strlen(opts.from), opts.from); |
10003 | 269 gaim_remote_packet_append_string(p, temp); |
10112 | 270 sprintf(temp, "%04zd%s", strlen(opts.protocol), opts.protocol); |
10003 | 271 gaim_remote_packet_append_string(p, temp); |
10112 | 272 sprintf(temp, "%04zd%s", strlen(opts.message), opts.message); |
10003 | 273 gaim_remote_packet_append_string(p, temp); |
10005 | 274 sprintf(temp, "%d", 0); /* quiet flag - off for now */ |
10003 | 275 gaim_remote_packet_append_string(p, temp); |
276 | |
277 gaim_remote_session_send_packet (fd, p); | |
278 close(fd); | |
279 gaim_remote_packet_free(p); | |
280 return 0; | |
10005 | 281 } else { |
10003 | 282 message(_("Insufficient arguments (-t, -f, -p, & -m are all required) or arguments greater than 9999 chars\n"), 2); |
283 close(fd); | |
284 gaim_remote_packet_free(p); | |
285 return 1; | |
286 } | |
287 } | |
288 | |
9752 | 289 static void |
290 show_longhelp( char *name, char *command) | |
9608 | 291 { |
9752 | 292 if (!strcmp(command, "uri")) { |
7724 | 293 message(_("\n" |
294 "Using AIM: URIs:\n" | |
8152 | 295 "Sending an IM to a screen name:\n" |
7724 | 296 " gaim-remote uri 'aim:goim?screenname=Penguin&message=hello+world'\n" |
8152 | 297 "In this case, 'Penguin' is the screen name we wish to IM, and 'hello world'\n" |
7724 | 298 "is the message to be sent. '+' must be used in place of spaces.\n" |
299 "Please note the quoting used above - if you run this from a shell the '&'\n" | |
300 "needs to be escaped, or the command will stop at that point.\n" | |
8152 | 301 "Also,the following will just open a conversation window to a screen name,\n" |
7724 | 302 "with no message:\n" |
303 " gaim-remote uri 'aim:goim?screenname=Penguin'\n\n" | |
304 "Joining a chat:\n" | |
305 " gaim-remote uri 'aim:gochat?roomname=PenguinLounge'\n" | |
306 "...joins the 'PenguinLounge' chat room.\n\n" | |
307 "Adding a buddy to your buddy list:\n" | |
308 " gaim-remote uri 'aim:addbuddy?screenname=Penguin'\n" | |
309 "...prompts you to add 'Penguin' to your buddy list.\n"), 1); | |
5116 | 310 } |
9695 | 311 |
10395 | 312 else if (!strcmp(command, "logout")) { |
313 message(_("\nLog out all accounts\n"), 1); | |
314 } | |
315 | |
9695 | 316 else if (!strcmp(command, "quit")) { |
7724 | 317 message(_("\nClose running copy of Gaim\n"), 1); |
5116 | 318 } |
9695 | 319 |
320 else if (!strcmp(command, "away")) { | |
321 message(_("\nMark all accounts as \"away\" with the default message.\n"), 1); | |
322 } | |
323 | |
324 else if (!strcmp(command, "back")) { | |
325 message(_("\nSet all accounts as not away.\n"), 1); | |
326 } | |
327 | |
10003 | 328 else if (!strcmp(command, "send")) { |
329 message(_("\nSend instant message\n"), 1); | |
330 } | |
331 | |
5116 | 332 else { |
333 show_remote_usage(name); | |
334 } | |
4242 | 335 } |
336 | |
9752 | 337 int main(int argc, char *argv[]) |
3480 | 338 { |
5116 | 339 #ifdef ENABLE_NLS |
340 setlocale (LC_ALL, ""); | |
341 bindtextdomain(PACKAGE, LOCALEDIR); | |
342 bind_textdomain_codeset(PACKAGE, "UTF-8"); | |
343 textdomain(PACKAGE); | |
344 #endif | |
345 | |
3480 | 346 if (get_options(argc, argv)) { |
347 show_remote_usage(argv[0]); | |
348 return 0; | |
349 } | |
9674 | 350 |
3480 | 351 if (!strcmp(opts.command, "uri")) { |
9674 | 352 if (opts.help) |
353 show_longhelp(argv[0], "uri"); | |
354 else | |
9752 | 355 return send_command_uri(); |
9674 | 356 } |
357 | |
10003 | 358 else if (!strcmp(opts.command, "send")) { |
359 if (opts.help) | |
360 show_longhelp(argv[0], "send"); | |
361 else | |
362 return send_command_send(); | |
363 } | |
364 | |
9674 | 365 else if (!strcmp(opts.command, "away")) { |
366 if (opts.help) | |
367 show_longhelp(argv[0], "away"); | |
368 else | |
9752 | 369 return send_generic_command(CUI_TYPE_USER, CUI_USER_AWAY); |
9674 | 370 } |
371 | |
372 else if (!strcmp(opts.command, "back")) { | |
373 if (opts.help) | |
374 show_longhelp(argv[0], "back"); | |
375 else | |
9752 | 376 return send_generic_command(CUI_TYPE_USER, CUI_USER_BACK); |
9674 | 377 } |
378 | |
10395 | 379 else if (!strcmp(opts.command, "logout")) { |
380 if (opts.help) | |
381 show_longhelp(argv[0], "logout"); | |
382 else | |
383 return send_generic_command(CUI_TYPE_USER, CUI_USER_LOGOUT); | |
384 } | |
385 | |
9674 | 386 else if (!strcmp(opts.command, "quit")) { |
387 if (opts.help) | |
388 show_longhelp(argv[0], "quit"); | |
389 else | |
9752 | 390 return send_generic_command(CUI_TYPE_META, CUI_META_QUIT); |
9674 | 391 } |
392 | |
393 else { | |
3480 | 394 show_remote_usage(argv[0]); |
395 return 1; | |
396 } | |
10395 | 397 |
3480 | 398 return 0; |
399 } |