comparison src/protocols/napster/napster.c @ 2220:8b7ba25a7ece

[gaim-migrate @ 2230] removed the file transfer stuff. sorry rob. it's still in the cvs diff history so you can resurrect it and play with it still. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Thu, 06 Sep 2001 02:16:05 +0000
parents cff4fbe01c7b
children 8c4ff1a368bd
comparison
equal deleted inserted replaced
2219:20a4d5da0b95 2220:8b7ba25a7ece
20 */ 20 */
21 21
22 #include <config.h> 22 #include <config.h>
23 23
24 #include <netdb.h> 24 #include <netdb.h>
25 #include <gtk/gtk.h>
26 #include <unistd.h> 25 #include <unistd.h>
27 #include <errno.h> 26 #include <errno.h>
28 #include <netinet/in.h> 27 #include <netinet/in.h>
29 #include <arpa/inet.h> 28 #include <arpa/inet.h>
30 #include <time.h> 29 #include <time.h>
32 #include <stdlib.h> 31 #include <stdlib.h>
33 #include <stdio.h> 32 #include <stdio.h>
34 #include <time.h> 33 #include <time.h>
35 #include <sys/socket.h> 34 #include <sys/socket.h>
36 #include <sys/stat.h> 35 #include <sys/stat.h>
37 #include <sys/types.h>
38 #include <fcntl.h>
39 #include <ctype.h>
40 #include "multi.h" 36 #include "multi.h"
41 #include "prpl.h" 37 #include "prpl.h"
42 #include "gaim.h" 38 #include "gaim.h"
43 #include "proxy.h" 39 #include "proxy.h"
44 #include "pixmaps/napster.xpm" 40 #include "pixmaps/napster.xpm"
47 43
48 GSList *nap_connections = NULL; 44 GSList *nap_connections = NULL;
49 45
50 static unsigned int chat_id = 0; 46 static unsigned int chat_id = 0;
51 47
52 struct search_window {
53 GtkWidget *window;
54 GtkWidget *list;
55 };
56
57 struct browse_window {
58 GtkWidget *window;
59 GtkWidget *list;
60 struct gaim_connection *gc;
61 char *name;
62 };
63
64 struct nap_download_box {
65 GtkWidget *window;
66 GtkWidget *ok;
67 GtkWidget *entry;
68 gchar *who;
69 };
70
71 struct nap_channel { 48 struct nap_channel {
72 unsigned int id; 49 unsigned int id;
73 gchar *name; 50 gchar *name;
74 }; 51 };
75 52
76 struct nap_file_request {
77 gchar *name;
78 gchar *file;
79 int fd;
80 long size;
81 long total;
82 int status;
83 int inpa;
84 FILE *mp3;
85 GtkWidget *window;
86 GtkWidget *progress;
87 GtkWidget *ok;
88 GtkWidget *cancel;
89 struct gaim_connection *gc;
90 };
91
92 struct nap_data { 53 struct nap_data {
93 int fd; 54 int fd;
94 int inpa; 55 int inpa;
95 56
96 gchar *email; 57 gchar *email;
97 GSList *channels; 58 GSList *channels;
98 GSList *requests;
99 GSList *browses;
100 }; 59 };
101
102 static struct search_window *search_dialog = NULL;
103 60
104 static char *nap_name() 61 static char *nap_name()
105 { 62 {
106 return "Napster"; 63 return "Napster";
107 } 64 }
112 { 69 {
113 struct nap_data *ndata = (struct nap_data *)gc->proto_data; 70 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
114 unsigned short size; 71 unsigned short size;
115 72
116 size = strlen(message); 73 size = strlen(message);
74
117 write(ndata->fd, &size, 2); 75 write(ndata->fd, &size, 2);
118 write(ndata->fd, &command, 2); 76 write(ndata->fd, &command, 2);
119 write(ndata->fd, message, size); 77 write(ndata->fd, message, size);
120
121 }
122
123 static void nap_send_download_req(struct gaim_connection *gc, char *who, char *file)
124 {
125 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
126 gchar buf[NAP_BUF_LEN];
127
128 g_snprintf(buf, NAP_BUF_LEN, "%s \"%s\"", who, file);
129
130 printf("%s\n", buf);
131 printf("%d\n", ndata->fd);
132 nap_write_packet(gc, 0xCB, buf);
133 }
134
135 // FIXME: These next two windows should really be together
136 // and should use the same clist style look too.
137
138 static void nap_handle_download(GtkCList *clist, gint row, gint col, GdkEventButton *event, gpointer user_data)
139 {
140 gchar *results;
141 struct browse_window *bw = (struct browse_window *)user_data;
142
143 gtk_clist_get_text(GTK_CLIST(clist), row, 0, &results);
144
145 nap_send_download_req(bw->gc, bw->name, results);
146
147 }
148
149 static void nap_handle_download_search(GtkCList *clist, gint row, gint col, GdkEventButton *event, gpointer user_data)
150 {
151 gchar *filename;
152 gchar *nick;
153
154 struct gaim_connection *gc = (struct gaim_connection *)user_data;
155
156 filename = (gchar *)gtk_clist_get_row_data(GTK_CLIST(clist), row);
157
158 gtk_clist_get_text(GTK_CLIST(clist), row, 1, &nick);
159
160 printf("Trying to download: %s from %s\n", filename, nick);
161 nap_send_download_req(gc, nick, filename);
162 }
163
164 static struct browse_window *browse_window_new(struct gaim_connection *gc, char *name)
165 {
166 struct browse_window *browse = g_new0(struct browse_window, 1);
167 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
168
169 browse->window = gtk_window_new(GTK_WINDOW_DIALOG);
170 browse->name = g_strdup(name);
171 browse->list = gtk_clist_new(1);
172 browse->gc = gc;
173
174 gtk_widget_show(browse->list);
175 gtk_container_add(GTK_CONTAINER(browse->window), browse->list);
176
177 gtk_widget_set_usize(GTK_WIDGET(browse->window), 300, 250);
178 gtk_widget_show(browse->window);
179
180 /*FIXME: I dont like using select-row. Im lazy. Ill fix it later */
181 gtk_signal_connect(GTK_OBJECT(browse->list), "select-row", GTK_SIGNAL_FUNC(nap_handle_download), browse);
182
183 ndata->browses = g_slist_append(ndata->browses, browse);
184
185 return browse;
186 }
187
188 static void browse_window_add_file(struct browse_window *bw, char *name)
189 {
190 char *fn[1];
191 fn[0] = strdup(name);
192 printf("User '%s' has file '%s'\n", bw->name, name);
193 gtk_clist_append(GTK_CLIST(bw->list), fn);
194
195 free(fn[0]);
196 }
197
198 static struct browse_window *find_browse_window_by_name(struct gaim_connection *gc, char *name)
199 {
200 struct browse_window *browse;
201 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
202 GSList *browses;
203
204 browses = ndata->browses;
205
206 while (browses) {
207 browse = (struct browse_window *)browses->data;
208
209 if (browse) {
210 if (!g_strcasecmp(name, browse->name)) {
211 return browse;
212 }
213 }
214 browses = g_slist_next(browses);
215 }
216
217 return NULL;
218 } 78 }
219 79
220 static int nap_send_im(struct gaim_connection *gc, char *who, char *message, int away) 80 static int nap_send_im(struct gaim_connection *gc, char *who, char *message, int away)
221 { 81 {
222 gchar buf[NAP_BUF_LEN]; 82 gchar buf[NAP_BUF_LEN];
284 } 144 }
285 145
286 return b; 146 return b;
287 } 147 }
288 148
289 /* This is a strange function. I smoke too many bad bad things :-) */
290 static struct nap_file_request * find_request_by_fd(struct gaim_connection *gc, int fd)
291 {
292 struct nap_file_request *req;
293 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
294 GSList *requests;
295
296 requests = ndata->requests;
297
298 while (requests) {
299 req = (struct nap_file_request *)requests->data;
300
301 if (req) {
302 if (req->fd == fd)
303 return req;
304 }
305 requests = g_slist_next(requests);
306 }
307
308 return NULL;
309 }
310
311 static void nap_ctc_callback(gpointer data, gint source, GaimInputCondition condition)
312 {
313 struct gaim_connection *gc = (struct gaim_connection *)data;
314 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
315 struct nap_file_request *req;
316 unsigned char *buf;
317 int i = 0;
318
319 req = find_request_by_fd(gc, source);
320 if (!req) /* Something bad happened */
321 return;
322
323 buf = (char *)malloc(sizeof(char) * (NAP_BUF_LEN + 1));
324
325 if (req->status == 0)
326 {
327 int j;
328 gchar tmp[32];
329 long filesize;
330 gchar **parse_name;
331 gchar path[2048];
332 GtkWidget *hbox;
333 GtkWidget *vbox;
334 GtkWidget *label;
335 gchar *buf2;
336
337 recv(source, buf, 1, 0);
338
339 /* We should receive a '1' upon connection */
340 if (buf[0] != '1')
341 {
342 do_error_dialog("Uh Oh", "Uh Oh");
343 gaim_input_remove(req->inpa);
344 ndata->requests = g_slist_remove(ndata->requests, req);
345 g_free(req->name);
346 g_free(req->file);
347 close(source);
348 g_free(req);
349 free(buf);
350 return;
351 }
352
353 /* Lets take a peek at the awaiting data */
354 i = recv(source, buf, NAP_BUF_LEN, MSG_PEEK);
355 buf[i] = 0; /* Make sure that we terminate our string */
356
357 /* Looks like the uploader sent the proper data. Let's see how big the
358 * file is */
359
360 for (j = 0, i = 0; isdigit(buf[i]); i++, j++)
361 {
362 tmp[j] = buf[i];
363 }
364 tmp[j] = 0;
365 filesize = atol(tmp);
366
367 /* Save the size of the file */
368 req->total = filesize;
369
370 /* If we have a zero file size then something bad happened */
371 if (filesize == 0) {
372 gaim_input_remove(req->inpa);
373 ndata->requests = g_slist_remove(ndata->requests, req);
374 g_free(req->name);
375 g_free(req->file);
376 g_free(req);
377 free(buf);
378 close(source);
379 return;
380 }
381
382 /* Now that we've done that, let's go ahead and read that
383 * data to get it out of the way */
384 recv(source, buf, strlen(tmp), 0);
385
386 /* Now, we should tell the server that we're download something */
387 nap_write_packet(gc, 0xda, "\n");
388
389 req->status = 1;
390
391 /* FIXME: We dont want to force the file name. I'll parse this
392 * later */
393
394 parse_name = g_strsplit(req->file, "\\", 0);
395 g_snprintf(path, sizeof(path), "%s/%s", getenv("HOME"), parse_name[sizeof(parse_name)]);
396 printf("Gonna try to save to: %s\n", path);
397 g_strfreev(parse_name);
398
399 req->mp3 = fopen(path, "w");
400
401 req->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
402
403 vbox = gtk_vbox_new(FALSE, 5);
404
405 buf2 = (gchar *)g_malloc(sizeof(gchar) * (strlen(req->file) + 33));
406 g_snprintf(buf2, strlen(req->file) + 32, "Downloading File: %s", req->file);
407 label = gtk_label_new(buf2);
408 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);
409
410 req->progress = gtk_progress_bar_new();
411 gtk_progress_bar_update(GTK_PROGRESS_BAR(req->progress), 0);
412 gtk_progress_configure(GTK_PROGRESS(req->progress), 0, 0, (float)req->total/(float)1024);
413 gtk_progress_set_format_string(GTK_PROGRESS(req->progress), "%P%% (%VKB / %UKB)");
414 gtk_progress_set_show_text(GTK_PROGRESS(req->progress), TRUE);
415 gtk_box_pack_start(GTK_BOX(vbox), req->progress, FALSE, FALSE, 5);
416
417 hbox = gtk_hbox_new(TRUE, 5);
418
419 req->ok = gtk_button_new_with_label("Ok");
420 req->cancel = gtk_button_new_with_label("Cancel");
421
422 gtk_box_pack_end(GTK_BOX(hbox), req->cancel, FALSE, FALSE, 5);
423 gtk_box_pack_end(GTK_BOX(hbox), req->ok, FALSE, FALSE, 5);
424
425 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
426
427 gtk_container_add(GTK_CONTAINER(req->window), vbox);
428
429 gtk_widget_show_all(req->window);
430
431 free(buf);
432 return;
433 }
434
435 /* Looks like our status isn't 1. It's safe to assume we're downloadin' */
436 i = recv(source, buf, NAP_BUF_LEN, 0);
437
438 req->size += i; /* Lets add up the total */
439
440 // printf("Downloaded %ld of %ld (%f)\n", req->size, req->total, (float)req->size/(float)req->total);
441
442 gtk_progress_bar_update(GTK_PROGRESS_BAR(req->progress), (float)req->size/(float)req->total);
443
444 while (gtk_events_pending())
445 gtk_main_iteration();
446
447 fwrite(buf, i, sizeof(char), req->mp3);
448
449 free(buf);
450
451 if (req->size >= req->total) {
452 printf("Download complete.\n");
453 nap_write_packet(gc, 0xdb, "\n"); /* Tell the server we're finished */
454 gaim_input_remove(req->inpa);
455
456 ndata->requests = g_slist_remove(ndata->requests, req);
457
458 if (req->name != NULL)
459 g_free(req->name);
460
461 if (req->file != NULL)
462 g_free(req->file);
463
464 g_free(req);
465 fclose(req->mp3);
466 close(source);
467 }
468 }
469
470 static void nap_get_file_connect(gpointer data, gint source, GaimInputCondition cond)
471 {
472 char buf[NAP_BUF_LEN];
473 struct nap_file_request *req = data;
474 struct gaim_connection *gc = req->gc;
475 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
476
477 if (source < 0) {
478 do_error_dialog("Error connecting to user", "Gaim: Napster error");
479 g_free(req->name);
480 g_free(req->file);
481 g_free(req);
482 return;
483 }
484
485 if (req->fd != source)
486 req->fd = source;
487
488 send(req->fd, "GET", 3, 0);
489
490 /* Send our request to the user */
491 g_snprintf(buf, sizeof(buf), "%s \"%s\" 0", gc->username, req->file);
492
493 send(req->fd, buf, strlen(buf), 0);
494
495 /* Add our request */
496 ndata->requests = g_slist_append(ndata->requests, req);
497
498 /* And start monitoring */
499 req->inpa = gaim_input_add(req->fd, GAIM_INPUT_READ, nap_ctc_callback, gc);
500 }
501
502 static void nap_get_file(struct gaim_connection *gc, gchar *user, gchar *file, gchar *host, unsigned int port)
503 {
504 struct nap_file_request *req = g_new0(struct nap_file_request, 1);
505
506 req->name = g_strdup(user);
507 req->file = g_strdup(file);
508 req->size = 0;
509 req->status = 0;
510 req->total = 0;
511 req->gc = gc;
512
513 /* Make a connection with the server */
514 req->fd = proxy_connect(host, port, nap_get_file_connect, req);
515 if (req->fd < 0) {
516 do_error_dialog("Error connecting to user", "Gaim: Napster error");
517 g_free(req->name);
518 g_free(req->file);
519 g_free(req);
520 }
521 }
522
523 static void nap_callback(gpointer data, gint source, GaimInputCondition condition) 149 static void nap_callback(gpointer data, gint source, GaimInputCondition condition)
524 { 150 {
525 struct gaim_connection *gc = data; 151 struct gaim_connection *gc = data;
526 struct nap_data *ndata = gc->proto_data; 152 struct nap_data *ndata = gc->proto_data;
527 gchar *buf; 153 gchar *buf;
528 unsigned short header[2]; 154 unsigned short header[2];
529 int len; 155 int len;
530 int command; 156 int command;
531 gchar **res; 157 gchar **res;
532 158 int i;
533 recv(source, header, 4, 0); 159
534 // read(source, header, 4); 160 if (recv(source, header, 4, 0) != 4) {
161 hide_login_progress(gc, "Unable to read");
162 signoff(gc);
163 return;
164 }
165
535 len = header[0]; 166 len = header[0];
536 command = header[1]; 167 command = header[1];
537 168
538 buf = (gchar *)g_malloc(sizeof(gchar) * (len + 1)); 169 buf = (gchar *)g_malloc(sizeof(gchar) * (len + 1));
539 170
540 // read(source, buf, len); 171 i = 0;
541 recv(source, buf, len, 0); 172 do {
173 int tmp = recv(source, buf + i, len - i, 0);
174 if (tmp <= 0) {
175 g_free(buf);
176 hide_login_progress(gc, "Unable to read");
177 signoff(gc);
178 return;
179 }
180 i += tmp;
181 } while (i != len);
542 182
543 buf[len] = 0; 183 buf[len] = 0;
544 184
545 printf("DEBUG: %s\n", buf); 185 debug_printf("DEBUG: %s\n", buf);
546 186
547 if (command == 0xd6) { 187 if (command == 0xd6) {
548 res = g_strsplit(buf, " ", 0); 188 res = g_strsplit(buf, " ", 0);
549 /* Do we want to report what the users are doing? */ 189 /* Do we want to report what the users are doing? */
550 printf("users: %s, files: %s, size: %sGB\n", res[0], res[1], res[2]); 190 printf("users: %s, files: %s, size: %sGB\n", res[0], res[1], res[2]);
551 g_strfreev(res); 191 g_strfreev(res);
552 free(buf); 192 g_free(buf);
553 return; 193 return;
554 } 194 }
555 195
556 if (command == 0x26d) { 196 if (command == 0x26d) {
557 /* Do we want to use the MOTD? */ 197 /* Do we want to use the MOTD? */
558 free(buf); 198 g_free(buf);
559 return; 199 return;
560 } 200 }
561 201
562 if (command == 0xCD) { 202 if (command == 0xCD) {
563 res = g_strsplit(buf, " ", 1); 203 res = g_strsplit(buf, " ", 1);
564 serv_got_im(gc, res[0], res[1], 0, time((time_t)NULL)); 204 serv_got_im(gc, res[0], res[1], 0, time((time_t)NULL));
565 g_strfreev(res); 205 g_strfreev(res);
566 free(buf); 206 g_free(buf);
567 return; 207 return;
568 } 208 }
569 209
570 if (command == 0x195) { 210 if (command == 0x195) {
571 struct nap_channel *channel; 211 struct nap_channel *channel;
583 ndata->channels = g_slist_append(ndata->channels, channel); 223 ndata->channels = g_slist_append(ndata->channels, channel);
584 224
585 serv_got_joined_chat(gc, chat_id, buf); 225 serv_got_joined_chat(gc, chat_id, buf);
586 } 226 }
587 227
588 free(buf); 228 g_free(buf);
589 return; 229 return;
590 } 230 }
591 231
592 if (command == 0x198 || command == 0x196) { 232 if (command == 0x198 || command == 0x196) {
593 struct nap_channel *channel; 233 struct nap_channel *channel;
601 241
602 add_chat_buddy(convo, res[1]); 242 add_chat_buddy(convo, res[1]);
603 243
604 g_strfreev(res); 244 g_strfreev(res);
605 245
606 free(buf); 246 g_free(buf);
607 return; 247 return;
608 } 248 }
609 249
610 if (command == 0x197) { 250 if (command == 0x197) {
611 struct nap_channel *channel; 251 struct nap_channel *channel;
618 convo = find_conversation_by_id(gc, channel->id); 258 convo = find_conversation_by_id(gc, channel->id);
619 259
620 remove_chat_buddy(convo, res[1]); 260 remove_chat_buddy(convo, res[1]);
621 261
622 g_strfreev(res); 262 g_strfreev(res);
623 free(buf); 263 g_free(buf);
624 return; 264 return;
625 } 265 }
626 266
627 if (command == 0x193) { 267 if (command == 0x193) {
628 gchar **res; 268 gchar **res;
634 274
635 if (channel) 275 if (channel)
636 serv_got_chat_in(gc, channel->id, res[1], 0, res[2], time((time_t)NULL)); 276 serv_got_chat_in(gc, channel->id, res[1], 0, res[2], time((time_t)NULL));
637 277
638 g_strfreev(res); 278 g_strfreev(res);
639 free(buf); 279 g_free(buf);
640 return; 280 return;
641 } 281 }
642 282
643 if (command == 0x194) { 283 if (command == 0x194) {
644 do_error_dialog(buf, "Gaim: Napster Error"); 284 do_error_dialog(buf, "Gaim: Napster Error");
645 free(buf); 285 g_free(buf);
646 return; 286 return;
647 } 287 }
648 288
649 if (command == 0x12e) { 289 if (command == 0x12e) {
650 gchar buf2[NAP_BUF_LEN]; 290 gchar buf2[NAP_BUF_LEN];
651 291
652 g_snprintf(buf2, NAP_BUF_LEN, "Unable to add '%s' to your hotlist", buf); 292 g_snprintf(buf2, NAP_BUF_LEN, "Unable to add '%s' to your hotlist", buf);
653 do_error_dialog(buf2, "Gaim: Napster Error"); 293 do_error_dialog(buf2, "Gaim: Napster Error");
654 294
655 free(buf); 295 g_free(buf);
656 return; 296 return;
657 297
658 } 298 }
659 299
660 if (command == 0x191) { 300 if (command == 0x191) {
666 return; 306 return;
667 307
668 serv_got_chat_left(gc, channel->id); 308 serv_got_chat_left(gc, channel->id);
669 ndata->channels = g_slist_remove(ndata->channels, channel); 309 ndata->channels = g_slist_remove(ndata->channels, channel);
670 310
671 free(buf); 311 g_free(buf);
672 return; 312 return;
673 313
674 } 314 }
675 315
676 if (command == 0xd1) { 316 if (command == 0xd1) {
679 res = g_strsplit(buf, " ", 0); 319 res = g_strsplit(buf, " ", 0);
680 320
681 serv_got_update(gc, res[0], 1, 0, 0, 0, 0, 0); 321 serv_got_update(gc, res[0], 1, 0, 0, 0, 0, 0);
682 322
683 g_strfreev(res); 323 g_strfreev(res);
684 free(buf); 324 g_free(buf);
685 return; 325 return;
686 } 326 }
687 327
688 if (command == 0xd2) { 328 if (command == 0xd2) {
689 serv_got_update(gc, buf, 0, 0, 0, 0, 0, 0); 329 serv_got_update(gc, buf, 0, 0, 0, 0, 0, 0);
690 free(buf);
691 return;
692 }
693
694 if (command == 0xd4) {
695 /* Looks like we're getting a browse response */
696 gchar user[64];
697 gchar file[2048];
698 struct browse_window *bw = NULL;
699
700 int i,j;
701
702 for (i = 0, j = 0; buf[i] != ' '; i++, j++)
703 {
704 user[j] = buf[i];
705 }
706 user[j] = 0; i++; i++;
707
708 for (j = 0; buf[i] != '\"'; i++, j++)
709 {
710 file[j] = buf[i];
711 }
712 file[j] = 0;
713
714 bw = find_browse_window_by_name(gc, user);
715 if (!bw)
716 {
717 /* If a browse window isn't found, let's create one */
718 bw = browse_window_new(gc, user);
719 }
720
721 browse_window_add_file(bw, file);
722
723 free(buf);
724 return;
725
726 }
727
728 if (command == 0xc9) {
729 /* We've received a search response */
730 gchar *file = (gchar *)g_malloc(sizeof(gchar) * (NAP_BUF_LEN+1));
731 gchar *tmp;
732 gchar rest[NAP_BUF_LEN];
733 gchar *data[5];
734 gchar **parse_name;
735
736 int i, j;
737
738 for (i = 1, j = 0; ((buf[i] != '\"') && (buf[i] != 0)); i++, j++)
739 {
740 file[j] = buf[i];
741 }
742
743 file[j] = 0; i++;
744
745 tmp = (gchar *)g_malloc(sizeof(gchar) * (strlen(file) + 1));
746 strcpy(tmp, rindex(file, '\\')+1);
747
748 strcpy(rest, buf+i);
749
750 parse_name = g_strsplit(rest, " ", 0);
751
752 data[0] = g_strdup(tmp);
753 data[1] = g_strdup(parse_name[6]);
754 data[2] = g_strdup(parse_name[2]);
755 data[3] = g_strdup(parse_name[3]);
756 data[4] = g_strdup(parse_name[8]);
757
758 // printf("File: %s, 1: %s, 2: %s, 3: %s\n", data[0], data[1], data[2], data[3]);
759 i = gtk_clist_append(GTK_CLIST(search_dialog->list), data);
760
761 gtk_clist_set_row_data(GTK_CLIST(search_dialog->list), i, file);
762 g_strfreev(parse_name);
763 // g_free(file);
764 g_free(tmp);
765 g_free(buf);
766 return;
767 }
768
769 if (command == 0xca)
770 {
771 /* End of search */
772 g_free(buf); 330 g_free(buf);
773 return; 331 return;
774 } 332 }
775 333
776 if (command == 0x12d) { 334 if (command == 0x12d) {
777 /* Our buddy was added successfully */ 335 /* Our buddy was added successfully */
778 free(buf); 336 g_free(buf);
779 return; 337 return;
780 } 338 }
781 339
782 if (command == 0x2ec) { 340 if (command == 0x2ec) {
783 /* Looks like someone logged in as us! =-O */ 341 /* Looks like someone logged in as us! =-O */
784 free(buf); 342 g_free(buf);
785 343
786 signoff(gc); 344 signoff(gc);
787 return; 345 return;
788 } 346 }
789 347
790 if (command == 0xcc) { 348 debug_printf("NAP: [COMMAND: 0x%04x] %s\n", command, buf);
791 /* We received a Download ACK from a user. The way this is printed is kind of 349
792 * strange so we'll need to parse this one ourselves. */ 350 g_free(buf);
793
794 gchar user[64];
795 gchar file[2048];
796 gchar hoststr[16];
797 gchar portstr[16];
798 int i,j;
799
800 for (i = 0, j = 0; buf[i] != ' '; i++, j++)
801 {
802 user[j] = buf[i];
803 }
804 user[j] = 0; i++;
805
806 for (j = 0; buf[i] != ' '; i++, j++)
807 {
808 hoststr[j] = buf[i];
809 }
810 hoststr[j] = 0; i++;
811
812 for (j = 0; buf[i] != ' '; i++, j++)
813 {
814 portstr[j] = buf[i];
815 }
816 portstr[j] = 0; i++;
817
818 i++; /* We do this to ignore the first quotation mark */
819
820 for (j = 0; buf[i] != '\"'; i++, j++)
821 {
822 file[j] = buf[i];
823 }
824 file[j] = 0;
825
826 /* Aaight. We dont need nuttin' else. Let's download the file */
827 nap_get_file(gc, user, file, hoststr, atoi(portstr));
828
829 free(buf);
830
831 return;
832 }
833
834 printf("NAP: [COMMAND: 0x%04x] %s\n", command, buf);
835
836 free(buf);
837 } 351 }
838 352
839 353
840 static void nap_login_callback(gpointer data, gint source, GaimInputCondition condition) 354 static void nap_login_callback(gpointer data, gint source, GaimInputCondition condition)
841 { 355 {
999 513
1000 static void nap_close(struct gaim_connection *gc) 514 static void nap_close(struct gaim_connection *gc)
1001 { 515 {
1002 struct nap_data *ndata = (struct nap_data *)gc->proto_data; 516 struct nap_data *ndata = (struct nap_data *)gc->proto_data;
1003 struct nap_channel *channel; 517 struct nap_channel *channel;
1004 struct browse_window *browse;
1005 struct nap_file_request *req;
1006 518
1007 if (gc->inpa) 519 if (gc->inpa)
1008 gaim_input_remove(gc->inpa); 520 gaim_input_remove(gc->inpa);
1009 521
1010 while (ndata->channels) { 522 while (ndata->channels) {
1012 g_free(channel->name); 524 g_free(channel->name);
1013 ndata->channels = g_slist_remove(ndata->channels, channel); 525 ndata->channels = g_slist_remove(ndata->channels, channel);
1014 g_free(channel); 526 g_free(channel);
1015 } 527 }
1016 528
1017 while (ndata->browses) { 529 g_free(gc->proto_data);
1018 browse = (struct browse_window *)ndata->browses->data;
1019 g_free(browse->name);
1020 gtk_widget_destroy(browse->window);
1021 ndata->browses = g_slist_remove(ndata->browses, browse);
1022 g_free(browse);
1023 }
1024
1025 while (ndata->requests) {
1026 req = (struct nap_file_request *)ndata->requests->data;
1027 g_free(req->name);
1028 g_free(req->file);
1029 if (req->inpa) {
1030 gaim_input_remove(req->inpa);
1031 }
1032 ndata->requests = g_slist_remove(ndata->requests, req);
1033 g_free(req);
1034
1035 }
1036
1037 free(gc->proto_data);
1038 } 530 }
1039 531
1040 static void nap_add_buddies(struct gaim_connection *gc, GList *buddies) 532 static void nap_add_buddies(struct gaim_connection *gc, GList *buddies)
1041 { 533 {
1042 while (buddies) { 534 while (buddies) {
1043 nap_write_packet(gc, 0xd0, (char *)buddies->data); 535 nap_write_packet(gc, 0xd0, (char *)buddies->data);
1044 buddies = buddies -> next; 536 buddies = buddies -> next;
1045 } 537 }
1046 } 538 }
1047 539
1048 static void nap_draw_new_user(GtkWidget *box)
1049 {
1050 GtkWidget *label;
1051
1052 label = gtk_label_new(_("Napster registration is currently under development"));
1053
1054 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1055 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 5);
1056 gtk_widget_show(label);
1057 }
1058
1059
1060 static void nap_send_browse(struct gaim_connection *gc, char *who)
1061 {
1062 gchar buf[NAP_BUF_LEN];
1063
1064 g_snprintf(buf, NAP_BUF_LEN, "%s", who);
1065 nap_write_packet(gc, 0xd3, buf);
1066 }
1067
1068 static void nap_find_callback(GtkObject *w, GtkWidget *entry)
1069 {
1070 struct gaim_connection *gc = (struct gaim_connection *)gtk_object_get_user_data(w);
1071 const gchar *search;
1072 gchar buf[NAP_BUF_LEN];
1073
1074 search = gtk_entry_get_text(GTK_ENTRY(entry));
1075 g_snprintf(buf, NAP_BUF_LEN, "FILENAME CONTAINS \"%s\" MAX_RESULTS 50", search);
1076
1077 nap_write_packet(gc, 0xc8, buf);
1078 }
1079
1080 static void destroy_window(GtkObject *w, GtkWidget *win)
1081 {
1082 gtk_widget_destroy(win);
1083 }
1084
1085 static void nap_show_search(struct gaim_connection *gc, char *omit)
1086 {
1087 if (!search_dialog)
1088 {
1089 GtkWidget *window;
1090 GtkWidget *sw;
1091 GtkWidget *vbox;
1092 GtkWidget *hbox;
1093 GtkWidget *label;
1094 GtkWidget *button;
1095 GtkWidget *entry;
1096 GtkWidget *list;
1097 gchar *titles[5] = {"Mp3 Name", "Nick", "Size", "Bitrate", "Connection"};
1098 search_dialog = g_new0(struct search_window, 1);
1099
1100 window = gtk_window_new(GTK_WINDOW_DIALOG);
1101
1102 vbox = gtk_vbox_new(FALSE, 0);
1103
1104 /* First Line */
1105 hbox = gtk_hbox_new(FALSE, 5);
1106 label = gtk_label_new("Search for:");
1107 gtk_widget_show(label);
1108 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
1109
1110 entry = gtk_entry_new();
1111 gtk_widget_show(entry);
1112 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5);
1113
1114 button = gtk_button_new_with_label("Find");
1115 gtk_widget_show(button);
1116 gtk_object_set_user_data(GTK_OBJECT(button), gc);
1117 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(nap_find_callback), entry);
1118
1119 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
1120
1121 button = gtk_button_new_with_label("Cancel");
1122 gtk_widget_show(button);
1123 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
1124
1125
1126 gtk_widget_show(hbox);
1127 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
1128 /* End First List */
1129
1130 /* Second Line */
1131
1132 sw = gtk_scrolled_window_new(NULL, NULL);
1133
1134 list = gtk_clist_new_with_titles(5, titles);
1135
1136 gtk_clist_column_titles_show(GTK_CLIST(list));
1137
1138 gtk_signal_connect(GTK_OBJECT(list), "select-row", GTK_SIGNAL_FUNC(nap_handle_download_search), gc);
1139
1140 gtk_container_add(GTK_CONTAINER(sw), list);
1141 gtk_widget_show(list);
1142
1143 gtk_box_pack_start(GTK_BOX(vbox), sw, FALSE, FALSE, 5);
1144
1145 gtk_widget_show(sw);
1146
1147 /* End Second Line */
1148
1149 gtk_widget_show(vbox);
1150
1151 gtk_container_add(GTK_CONTAINER(window), vbox);
1152 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
1153
1154 gtk_widget_set_usize(GTK_WIDGET(list), 500, 350);
1155 gtk_widget_set_usize(GTK_WIDGET(window), 500, 400);
1156
1157 gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(destroy_window), window);
1158 gtk_widget_show(window);
1159
1160 search_dialog->window = window;
1161 search_dialog->list = list;
1162 }
1163
1164 gtk_widget_show(search_dialog->window);
1165 }
1166
1167 static GList *nap_buddy_menu(struct gaim_connection *gc, char *who)
1168 {
1169 GList *m = NULL;
1170 struct proto_buddy_menu *pbm;
1171
1172 pbm = g_new0(struct proto_buddy_menu, 1);
1173 pbm->label = _("Browse Files");
1174 pbm->callback = nap_send_browse;
1175 pbm->gc = gc;
1176 m = g_list_append(m, pbm);
1177
1178 pbm = g_new0(struct proto_buddy_menu, 1);
1179 pbm->label = _("Search Napster");
1180 pbm->callback = nap_show_search;
1181 pbm->gc = gc;
1182 m = g_list_append(m, pbm);
1183
1184 return m;
1185 }
1186
1187 static char** nap_list_icon(int uc) 540 static char** nap_list_icon(int uc)
1188 { 541 {
1189 return napster_xpm; 542 return napster_xpm;
1190 } 543 }
1191 544
1194 void napster_init(struct prpl *ret) 547 void napster_init(struct prpl *ret)
1195 { 548 {
1196 ret->protocol = PROTO_NAPSTER; 549 ret->protocol = PROTO_NAPSTER;
1197 ret->name = nap_name; 550 ret->name = nap_name;
1198 ret->list_icon = nap_list_icon; 551 ret->list_icon = nap_list_icon;
1199 ret->buddy_menu = nap_buddy_menu;
1200 ret->user_opts = NULL; 552 ret->user_opts = NULL;
1201 ret->login = nap_login; 553 ret->login = nap_login;
1202 ret->close = nap_close; 554 ret->close = nap_close;
1203 ret->send_im = nap_send_im; 555 ret->send_im = nap_send_im;
1204 ret->set_info = NULL; 556 ret->set_info = NULL;
1223 ret->chat_invite = NULL; 575 ret->chat_invite = NULL;
1224 ret->chat_leave = nap_chat_leave; 576 ret->chat_leave = nap_chat_leave;
1225 ret->chat_whisper = NULL; 577 ret->chat_whisper = NULL;
1226 ret->chat_send = nap_chat_send; 578 ret->chat_send = nap_chat_send;
1227 ret->keepalive = NULL; 579 ret->keepalive = NULL;
1228 ret->draw_new_user = nap_draw_new_user;
1229 580
1230 my_protocol = ret; 581 my_protocol = ret;
1231 } 582 }
1232 583
1233 #ifndef STATIC 584 #ifndef STATIC