src/protocols/napster/napster.c

branch
gaim
changeset 20470
77693555855f
parent 13071
b98e72d4089a
parent 20469
b2836a24d81e
child 20471
1966704b3e42
equal deleted inserted replaced
13071:b98e72d4089a 20470:77693555855f
1 /*
2 * gaim - Napster Protocol Plugin
3 *
4 * Copyright (C) 2000-2001, Rob Flynn <rob@marko.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #include "internal.h"
21
22 #include "account.h"
23 #include "accountopt.h"
24 #include "blist.h"
25 #include "conversation.h"
26 #include "debug.h"
27 #include "notify.h"
28 #include "prpl.h"
29 #include "proxy.h"
30 #include "util.h"
31 #include "version.h"
32
33 #define NAP_SERVER "64.124.41.187"
34 #define NAP_PORT 8888
35
36 #define NAPSTER_CONNECT_STEPS 2
37
38 GSList *nap_connections = NULL;
39
40 struct nap_data {
41 int fd;
42 gchar *email;
43 };
44
45 static GaimConversation *nap_find_chat(GaimConnection *gc, const char *name)
46 {
47 GSList *bcs = gc->buddy_chats;
48
49 while (bcs) {
50 GaimConversation *b = bcs->data;
51 if (!gaim_utf8_strcasecmp(b->name, name))
52 return b;
53 bcs = bcs->next;
54 }
55
56 return NULL;
57 }
58
59 static void nap_write_packet(GaimConnection *gc, unsigned short command, const char *format, ...)
60 {
61 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
62 va_list ap;
63 gchar *message;
64 unsigned short size;
65
66 va_start(ap, format);
67 message = g_strdup_vprintf(format, ap);
68 va_end(ap);
69
70 size = strlen(message);
71 gaim_debug(GAIM_DEBUG_MISC, "napster", "S %3hd: %s\n", command, message);
72
73 write(ndata->fd, &size, 2);
74 write(ndata->fd, &command, 2);
75 write(ndata->fd, message, size);
76
77 g_free(message);
78 }
79
80 static int nap_do_irc_style(GaimConnection *gc, const char *message, const char *name)
81 {
82 gchar **res;
83
84 gaim_debug(GAIM_DEBUG_MISC, "napster", "C %s\n", message);
85
86 res = g_strsplit(message, " ", 2);
87
88 if (!g_ascii_strcasecmp(res[0], "/ME")) { /* MSG_CLIENT_PUBLIC */
89 nap_write_packet(gc, 824, "%s \"%s\"", name, res[1]);
90
91 } else if (!g_ascii_strcasecmp(res[0], "/MSG")) { /* MSG_CLIENT_PUBLIC */
92 nap_write_packet(gc, 205, "%s", res[1]);
93
94 } else if (!g_ascii_strcasecmp(res[0], "/JOIN")) { /* join chatroom MSG_CLIENT_JOIN */
95 if (!res[1]) {
96 g_strfreev(res);
97 return 1;
98 }
99 if (res[1][0] != '#')
100 nap_write_packet(gc, 400, "#%s", res[1]);
101 else
102 nap_write_packet(gc, 400, "%s", res[1]);
103
104 } else if (!g_ascii_strcasecmp(res[0], "/PART")) { /* partchatroom MSG_CLIENT_PART */
105 nap_write_packet(gc, 401, "%s", res[1] ? res[1] : name);
106
107 } else if (!g_ascii_strcasecmp(res[0], "/TOPIC")) { /* set topic MSG_SERVER_TOPIC */
108 nap_write_packet(gc, 410, "%s", res[1] ? res[1] : name);
109
110 } else if (!g_ascii_strcasecmp(res[0], "/WHOIS")) { /* whois request MSG_CLIENT_WHOIS */
111 nap_write_packet(gc, 603, "%s", res[1]);
112
113 } else if (!g_ascii_strcasecmp(res[0], "/PING")) { /* send ping MSG_CLIENT_PING */
114 nap_write_packet(gc, 751, "%s", res[1]);
115
116 } else if (!g_ascii_strcasecmp(res[0], "/KICK")) { /* kick asswipe MSG_CLIENT_KICK */
117 nap_write_packet(gc, 829, "%s", res[1]);
118
119 } else {
120 g_strfreev(res);
121 return 1;
122 }
123
124 g_strfreev(res);
125 return 0;
126 }
127
128 /* 205 - MSG_CLIENT_PRIVMSG */
129 static int nap_send_im(GaimConnection *gc, const char *who, const char *message, GaimMessageFlags flags)
130 {
131 char *tmp = gaim_unescape_html(message);
132
133 if ((strlen(tmp) < 2) || (tmp[0] != '/' ) || (tmp[1] == '/')) {
134 /* Actually send a chat message */
135 nap_write_packet(gc, 205, "%s %s", who, tmp);
136 } else {
137 /* user typed an IRC-style command */
138 nap_do_irc_style(gc, tmp, who);
139 }
140
141 g_free(tmp);
142
143 return 1;
144 }
145
146 /* 207 - MSG_CLIENT_ADD_HOTLIST */
147 static void nap_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group)
148 {
149 nap_write_packet(gc, 207, "%s", buddy->name);
150 }
151
152 /* 208 - MSG_CLIENT_ADD_HOTLIST_SEQ */
153 static void nap_send_buddylist(GaimConnection *gc)
154 {
155 GaimBuddyList *blist;
156 GaimBlistNode *gnode, *cnode, *bnode;
157 GaimBuddy *buddy;
158
159 if ((blist = gaim_get_blist()) != NULL)
160 {
161 for (gnode = blist->root; gnode != NULL; gnode = gnode->next)
162 {
163 if (!GAIM_BLIST_NODE_IS_GROUP(gnode))
164 continue;
165 for (cnode = gnode->child; cnode != NULL; cnode = cnode->next)
166 {
167 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode))
168 continue;
169 for (bnode = cnode->child; bnode != NULL; bnode = bnode->next)
170 {
171 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode))
172 continue;
173 buddy = (GaimBuddy *)bnode;
174 nap_write_packet(gc, 208, "%s", buddy->name);
175 }
176 }
177 }
178 }
179 }
180
181 /* 303 - MSG_CLIENT_REMOVE_HOTLIST */
182 static void nap_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group)
183 {
184 nap_write_packet(gc, 303, "%s", buddy->name);
185 }
186
187 static char *nap_get_chat_name(GHashTable *data) {
188 char *name = g_hash_table_lookup(data, "group");
189
190 /* Make sure the name has a # preceding it */
191 if (name[0] != '#') {
192 return g_strdup_printf("#%s", name);
193 }
194
195 return g_strdup(name);
196 }
197
198 /* 400 - MSG_CLIENT_JOIN */
199 static void nap_join_chat(GaimConnection *gc, GHashTable *data)
200 {
201 char *name;
202
203 if (!data)
204 return;
205
206 name = nap_get_chat_name(data);
207
208 if (name) {
209 nap_write_packet(gc, 400, "%s", name);
210 g_free(name);
211 }
212 }
213
214 /* 401 - MSG_CLIENT_PART */
215 static void nap_chat_leave(GaimConnection *gc, int id)
216 {
217 GaimConversation *c = gaim_find_chat(gc, id);
218
219 if (!c)
220 return;
221
222 nap_write_packet(gc, 401, "%s", c->name);
223 }
224
225 /* 402 - MSG_CLIENT_PUBLIC */
226 static int nap_chat_send(GaimConnection *gc, int id, const char *message, GaimMessageFlags flags)
227 {
228 GaimConversation *c = gaim_find_chat(gc, id);
229 char *tmp = gaim_unescape_html(message);
230
231 if (!c)
232 return -EINVAL;
233
234 if ((strlen(tmp) < 2) || (tmp[0] != '/' ) || (tmp[1] == '/')) {
235 /* Actually send a chat message */
236 nap_write_packet(gc, 402, "%s %s", c->name, tmp);
237 } else {
238 /* user typed an IRC-style command */
239 nap_do_irc_style(gc, tmp, c->name);
240 }
241
242 g_free(tmp);
243
244 return 0;
245 }
246
247 /* 603 - MSG_CLIENT_WHOIS */
248 static void nap_get_info(GaimConnection *gc, const char *who)
249 {
250 nap_write_packet(gc, 603, "%s", who);
251 }
252
253 static void nap_callback(gpointer data, gint source, GaimInputCondition condition)
254 {
255 GaimConnection *gc = data;
256 struct nap_data *ndata = gc->proto_data;
257 GaimAccount *account = gaim_connection_get_account(gc);
258 GaimConversation *c;
259 gchar *buf, *buf2, *buf3, **res;
260 unsigned short header[2];
261 int len;
262 int command;
263 int i;
264
265 if (read(source, (void*)header, 4) != 4) {
266 gaim_connection_error(gc, _("Unable to read header from server"));
267 return;
268 }
269
270 len = header[0];
271 command = header[1];
272 buf = (gchar *)g_malloc((len + 1) * sizeof(gchar));
273 buf[len] = '\0';
274
275 i = 0;
276 do {
277 int tmp = read(source, buf + i, len - i);
278 if (tmp <= 0) {
279 g_free(buf);
280 buf = g_strdup_printf(_("Unable to read message from server: %s. Command is %hd, length is %hd."), strerror(errno), len, command);
281 gaim_connection_error(gc, buf);
282 g_free(buf);
283 return;
284 }
285 i += tmp;
286 } while (i != len);
287
288 gaim_debug(GAIM_DEBUG_MISC, "napster", "R %3hd: %s\n", command, buf);
289
290 switch (command) {
291 case 000: /* MSG_SERVER_ERROR */
292 gaim_notify_error(gc, NULL, buf, NULL);
293 gaim_input_remove(gc->inpa);
294 gc->inpa = 0;
295 close(source);
296 gaim_connection_error(gc, _("Unknown server error."));
297 break;
298
299 case 003: /* MSG_SERVER_EMAIL */
300 gaim_debug(GAIM_DEBUG_MISC, "napster", "Registered with e-mail address: %s\n", buf);
301 ndata->email = g_strdup(buf);
302
303 /* Our signon is complete */
304 gaim_connection_set_state(gc, GAIM_CONNECTED);
305
306 /* Send the server our buddy list */
307 nap_send_buddylist(gc);
308
309 break;
310
311 case 201: /* MSG_SERVER_SEARCH_RESULT */
312 res = g_strsplit(buf, " ", 0);
313 gaim_prpl_got_user_status(account, res[0], "available", NULL);
314 g_strfreev(res);
315 break;
316
317 case 202: /* MSG_SERVER_SEARCH_END */
318 gaim_prpl_got_user_status(account, buf, "offline", NULL);
319 break;
320
321 case 205: /* MSG_CLIENT_PRIVMSG */
322 res = g_strsplit(buf, " ", 2);
323 buf2 = g_markup_escape_text(res[1], -1);
324 serv_got_im(gc, res[0], buf2, 0, time(NULL));
325 g_free(buf2);
326 g_strfreev(res);
327 break;
328
329 case 209: /* MSG_SERVER_USER_SIGNON */
330 /* USERNAME SPEED */
331 res = g_strsplit(buf, " ", 2);
332 gaim_prpl_got_user_status(account, res[0], "available", NULL);
333 g_strfreev(res);
334 break;
335
336 case 210: /* MSG_SERVER_USER_SIGNOFF */
337 /* USERNAME SPEED */
338 res = g_strsplit(buf, " ", 2);
339 gaim_prpl_got_user_status(account, res[0], "offline", NULL);
340 g_strfreev(res);
341 break;
342
343 case 214: /* MSG_SERVER_STATS */
344 res = g_strsplit(buf, " ", 3);
345 buf2 = g_strdup_printf(_("users: %s, files: %s, size: %sGB"), res[0], res[1], res[2]);
346 serv_got_im(gc, "server", buf2, 0, time(NULL));
347 g_free(buf2);
348 g_strfreev(res);
349 break;
350
351 case 301: /* MSG_SERVER_HOTLIST_ACK */
352 /* Our buddy was added successfully */
353 break;
354
355 case 302: /* MSG_SERVER_HOTLIST_ERROR */
356 buf2 = g_strdup_printf(_("Unable to add \"%s\" to your Napster hotlist"), buf);
357 gaim_notify_error(gc, NULL, buf2, NULL);
358 g_free(buf2);
359 break;
360
361 case 316: /* MSG_SERVER_DISCONNECTING */
362 /* we have been kicked off =^( */
363 gaim_connection_error(gc, _("You were disconnected from the server."));
364 break;
365
366 case 401: /* MSG_CLIENT_PART */
367 c = nap_find_chat(gc, buf);
368 if (c)
369 serv_got_chat_left(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(c)));
370 break;
371
372 case 403: /* MSG_SERVER_PUBLIC */
373 res = g_strsplit(buf, " ", 3);
374 c = nap_find_chat(gc, res[0]);
375 if (c)
376 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(c)), res[1], 0, res[2], time((time_t)NULL));
377 g_strfreev(res);
378 break;
379
380 case 404: /* MSG_SERVER_NOSUCH */
381 /* abused by opennap servers to broadcast stuff */
382 buf2 = g_markup_escape_text(buf, -1);
383 serv_got_im(gc, "server", buf2, 0, time(NULL));
384 g_free(buf2);
385 break;
386
387 case 405: /* MSG_SERVER_JOIN_ACK */
388 c = nap_find_chat(gc, buf);
389 if (!c)
390 serv_got_joined_chat(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(c)), buf);
391 break;
392
393 case 407: /* MSG_SERVER_PART */
394 res = g_strsplit(buf, " ", 0);
395 c = nap_find_chat(gc, res[0]);
396 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(c), res[1], NULL);
397 g_strfreev(res);
398 break;
399
400 case 406: /* MSG_SERVER_JOIN */
401 case 408: /* MSG_SERVER_CHANNEL_USER_LIST */
402 res = g_strsplit(buf, " ", 4);
403 c = nap_find_chat(gc, res[0]);
404 gaim_conv_chat_add_user(GAIM_CONV_CHAT(c), res[1], NULL, GAIM_CBFLAGS_NONE, TRUE);
405 g_strfreev(res);
406 break;
407
408 case 409: /* MSG_SERVER_CHANNEL_USER_LIST_END */
409 break;
410
411 case 410: /* MSG_SERVER_TOPIC */
412 /* display the topic in the channel */
413 res = g_strsplit(buf, " ", 2);
414 c = nap_find_chat(gc, res[0]);
415 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), res[0], res[1]);
416 g_strfreev(res);
417 break;
418
419 case 603: /* MSG_CLIENT_WHOIS */
420 buf2 = g_strdup_printf(_("%s requested your information"), buf);
421 serv_got_im(gc, "server", buf2, 0, time(NULL));
422 g_free(buf2);
423 break;
424
425 case 604: /* MSG_SERVER_WHOIS_RESPONSE */
426 /* XXX - Format is: "Elite" 37 " " "Active" 0 0 0 0 "gaim 0.63cvs" 0 0 192.168.1.41 32798 0 unknown flounder */
427 res = g_strsplit(buf, " ", 2);
428 /* res[0] == username */
429 gaim_notify_userinfo(gc, res[0], res[1], NULL, NULL);
430 g_strfreev(res);
431 break;
432
433 case 621:
434 case 622: /* MSG_CLIENT_MOTD */
435 /* also replaces MSG_SERVER_MOTD, so we should display it */
436 buf2 = g_markup_escape_text(buf, -1);
437 serv_got_im(gc, "motd", buf2, 0, time(NULL));
438 g_free(buf2);
439 break;
440
441 case 627: /* MSG_CLIENT_WALLOP */
442 /* abused by opennap server maintainers to broadcast stuff */
443 buf2 = g_markup_escape_text(buf, -1);
444 serv_got_im(gc, "wallop", buf2, 0, time(NULL));
445 g_free(buf2);
446 break;
447
448 case 628: /* MSG_CLIENT_ANNOUNCE */
449 buf2 = g_markup_escape_text(buf, -1);
450 serv_got_im(gc, "announce", buf2, 0, time(NULL));
451 g_free(buf);
452 break;
453
454 case 748: /* MSG_SERVER_GHOST */
455 /* Looks like someone logged in as us! =-O */
456 gaim_connection_error(gc, _("You have signed on from another location."));
457 break;
458
459 case 751: /* MSG_CLIENT_PING */
460 buf2 = g_strdup_printf(_("%s requested a PING"), buf);
461 serv_got_im(gc, "server", buf2, 0, time(NULL));
462 g_free(buf2);
463 /* send back a pong */
464 /* MSG_CLIENT_PONG */
465 nap_write_packet(gc, 752, "%s", buf);
466 break;
467
468 case 752: /* MSG_CLIENT_PONG */
469 buf2 = g_strdup_printf("Received pong from %s", buf);
470 gaim_notify_info(gc, NULL, buf2, NULL);
471 g_free(buf2);
472 break;
473
474 case 824: /* MSG_CLIENT_EMOTE */
475 res = g_strsplit(buf, " ", 3);
476 buf2 = g_strndup(res[2]+1, strlen(res[2]) - 2); /* chomp off the surround quotes */
477 buf3 = g_strdup_printf("/me %s", buf2);
478 g_free(buf2);
479 if ((c = nap_find_chat(gc, res[0]))) {
480 gaim_conv_chat_write(GAIM_CONV_CHAT(c), res[1], buf3, GAIM_MESSAGE_NICK, time(NULL));
481 }
482 g_free(buf3);
483 g_strfreev(res);
484 break;
485
486 default:
487 gaim_debug(GAIM_DEBUG_MISC, "napster", "Unknown packet %hd: %s\n", command, buf);
488 break;
489 }
490
491 g_free(buf);
492 }
493
494 /* 002 - MSG_CLIENT_LOGIN */
495 static void nap_login_connect(gpointer data, gint source, GaimInputCondition cond)
496 {
497 GaimConnection *gc = data;
498 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
499 gchar *buf;
500
501 if (!g_list_find(gaim_connections_get_all(), gc)) {
502 close(source);
503 return;
504 }
505
506 if (source < 0) {
507 gaim_connection_error(gc, _("Unable to connect."));
508 return;
509 }
510
511 ndata->fd = source;
512
513 /* Update the login progress status display */
514 buf = g_strdup_printf("Logging in: %s", gaim_account_get_username(gc->account));
515 gaim_connection_update_progress(gc, buf, 1, NAPSTER_CONNECT_STEPS);
516 g_free(buf);
517
518 /* Write our signon data */
519 nap_write_packet(gc, 2, "%s %s 0 \"gaim %s\" 0",
520 gaim_account_get_username(gc->account),
521 gaim_connection_get_password(gc), VERSION);
522
523 /* And set up the input watcher */
524 gc->inpa = gaim_input_add(ndata->fd, GAIM_INPUT_READ, nap_callback, gc);
525 }
526
527 static void nap_login(GaimAccount *account)
528 {
529 GaimConnection *gc = gaim_account_get_connection(account);
530
531 gaim_connection_update_progress(gc, _("Connecting"), 0, NAPSTER_CONNECT_STEPS);
532
533 gc->proto_data = g_new0(struct nap_data, 1);
534 if (gaim_proxy_connect(account,
535 gaim_account_get_string(account, "server", NAP_SERVER),
536 gaim_account_get_int(account, "port", NAP_PORT),
537 nap_login_connect, gc) != 0) {
538 gaim_connection_error(gc, _("Unable to connect."));
539 }
540 }
541
542 static void nap_close(GaimConnection *gc)
543 {
544 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
545
546 if (gc->inpa)
547 gaim_input_remove(gc->inpa);
548
549 if (!ndata)
550 return;
551
552 close(ndata->fd);
553
554 g_free(ndata->email);
555 g_free(ndata);
556 }
557
558 static const char* nap_list_icon(GaimAccount *a, GaimBuddy *b)
559 {
560 return "napster";
561 }
562
563 static void nap_list_emblems(GaimBuddy *b, const char **se, const char **sw,
564 const char **nw, const char **ne)
565 {
566 if(!GAIM_BUDDY_IS_ONLINE(b))
567 *se = "offline";
568 }
569
570 static GList *nap_status_types(GaimAccount *account)
571 {
572 GList *types = NULL;
573 GaimStatusType *type;
574
575 g_return_val_if_fail(account != NULL, NULL);
576
577 type = gaim_status_type_new_full(GAIM_STATUS_AVAILABLE,
578 NULL, NULL, TRUE, TRUE, FALSE);
579 types = g_list_append(types, type);
580
581 type = gaim_status_type_new_full(GAIM_STATUS_OFFLINE,
582 NULL, NULL, TRUE, TRUE, FALSE);
583 types = g_list_append(types, type);
584
585 return types;
586 }
587
588 static GList *nap_chat_info(GaimConnection *gc)
589 {
590 GList *m = NULL;
591 struct proto_chat_entry *pce;
592
593 pce = g_new0(struct proto_chat_entry, 1);
594 pce->label = _("_Group:");
595 pce->identifier = "group";
596 m = g_list_append(m, pce);
597
598 return m;
599 }
600
601 GHashTable *nap_chat_info_defaults(GaimConnection *gc, const char *chat_name)
602 {
603 GHashTable *defaults;
604
605 defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
606
607 if (chat_name != NULL)
608 g_hash_table_insert(defaults, "group", g_strdup(chat_name));
609
610 return defaults;
611 }
612
613 static GaimPlugin *my_protocol = NULL;
614
615 static GaimPluginProtocolInfo prpl_info =
616 {
617 OPT_PROTO_CHAT_TOPIC,
618 NULL, /* user_splits */
619 NULL, /* protocol_options */
620 NO_BUDDY_ICONS, /* icon_spec */
621 nap_list_icon, /* list_icon */
622 nap_list_emblems, /* list_emblems */
623 NULL, /* status_text */
624 NULL, /* tooltip_text */
625 nap_status_types, /* status_types */
626 NULL, /* blist_node_menu */
627 nap_chat_info, /* chat_info */
628 nap_chat_info_defaults, /* chat_info_defaults */
629 nap_login, /* login */
630 nap_close, /* close */
631 nap_send_im, /* send_im */
632 NULL, /* set_info */
633 NULL, /* send_typing */
634 nap_get_info, /* get_info */
635 NULL, /* set_away */
636 NULL, /* set_idle */
637 NULL, /* change_passwd */
638 nap_add_buddy, /* add_buddy */
639 NULL, /* add_buddies */
640 nap_remove_buddy, /* remove_buddy */
641 NULL, /* remove_buddies */
642 NULL, /* add_permit */
643 NULL, /* add_deny */
644 NULL, /* rem_permit */
645 NULL, /* rem_deny */
646 NULL, /* set_permit_deny */
647 nap_join_chat, /* join_chat */
648 NULL, /* reject chat invite */
649 nap_get_chat_name, /* get_chat_name */
650 NULL, /* chat_invite */
651 nap_chat_leave, /* chat_leave */
652 NULL, /* chat_whisper */
653 nap_chat_send, /* chat_send */
654 NULL, /* keepalive */
655 NULL, /* register_user */
656 NULL, /* get_cb_info */
657 NULL, /* get_cb_away */
658 NULL, /* alias_buddy */
659 NULL, /* group_buddy */
660 NULL, /* rename_group */
661 NULL, /* buddy_free */
662 NULL, /* convo_closed */
663 NULL, /* normalize */
664 NULL, /* set_buddy_icon */
665 NULL, /* remove_group */
666 NULL, /* get_cb_real_name */
667 NULL, /* set_chat_topic */
668 NULL, /* find_blist_chat */
669 NULL, /* roomlist_get_list */
670 NULL, /* roomlist_cancel */
671 NULL, /* roomlist_expand_category */
672 NULL, /* can_receive_file */
673 NULL, /* send_file */
674 NULL, /* new_xfer */
675 NULL, /* offline_message */
676 NULL, /* whiteboard_prpl_ops */
677 NULL, /* media_prpl_ops */
678 };
679
680 static GaimPluginInfo info =
681 {
682 GAIM_PLUGIN_MAGIC,
683 GAIM_MAJOR_VERSION,
684 GAIM_MINOR_VERSION,
685 GAIM_PLUGIN_PROTOCOL, /**< type */
686 NULL, /**< ui_requirement */
687 0, /**< flags */
688 NULL, /**< dependencies */
689 GAIM_PRIORITY_DEFAULT, /**< priority */
690
691 "prpl-napster", /**< id */
692 "Napster", /**< name */
693 VERSION, /**< version */
694 /** summary */
695 N_("NAPSTER Protocol Plugin"),
696 /** description */
697 N_("NAPSTER Protocol Plugin"),
698 NULL, /**< author */
699 GAIM_WEBSITE, /**< homepage */
700
701 NULL, /**< load */
702 NULL, /**< unload */
703 NULL, /**< destroy */
704
705 NULL, /**< ui_info */
706 &prpl_info, /**< extra_info */
707 NULL,
708 NULL
709 };
710
711 static void init_plugin(GaimPlugin *plugin)
712 {
713 GaimAccountOption *option;
714
715 option = gaim_account_option_string_new(_("Server"), "server",
716 NAP_SERVER);
717 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
718 option);
719
720 option = gaim_account_option_int_new(_("Port"), "port", 8888);
721 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
722 option);
723
724 my_protocol = plugin;
725 }
726
727 GAIM_INIT_PLUGIN(napster, init_plugin, info);

mercurial