1
2 #include "irc.h"
3 #include "struct.h"
4 #include "dcc.h"
5 #include "ircaux.h"
6 #include "ctcp.h"
7 #include "cdcc.h"
8 #include "input.h"
9 #include "status.h"
10 #include "lastlog.h"
11 #include "screen.h"
12 #include "vars.h"
13 #include "misc.h"
14 #include "output.h"
15 #include "module.h"
16 #include "hook.h"
17 #include "hash2.h"
18 #include "napster.h"
19 #include "bsdglob.h"
20 #include "modval.h"
21
22 #include <sys/stat.h>
23 #include <sys/ioctl.h>
24 #ifdef HAVE_SYS_FILIO_H
25 #include <sys/filio.h>
26 #endif
27
28 GetFile *getfile_struct = NULL;
29 ResumeFile *resume_struct = NULL;
30
31
napster_status(void)32 char *napster_status(void)
33 {
34 int upload = 0;
35 int download = 0;
36 GetFile *tmp;
37 char buffer[NAP_BUFFER_SIZE+1];
38 char tmpbuff[80];
39 double perc = 0.0;
40 if (!get_dllint_var("napster_window"))
41 return m_strdup(empty_string);
42 sprintf(buffer, statistics.shared_files ? "%s [Sh:%lu/%3.2f%s] ": "%s ",
43 nap_current_channel ? nap_current_channel : empty_string,
44 statistics.shared_files, _GMKv(statistics.shared_filesize),
45 _GMKs(statistics.shared_filesize));
46 for (tmp = getfile_struct; tmp; tmp = tmp->next, download++)
47 {
48 if (!tmp->filesize)
49 continue;
50 perc = (100.0 * (((double)(tmp->received + tmp->resume)) / (double)tmp->filesize));
51 sprintf(tmpbuff, "%4.1f%%%%", perc);
52 if (download)
53 strcat(buffer, ",");
54 else
55 strcat(buffer, " [G:");
56 strcat(buffer, tmpbuff);
57 }
58 if (download)
59 strcat(buffer, "]");
60 for (tmp = napster_sendqueue; tmp; tmp = tmp->next, upload++)
61 {
62 if (!tmp->filesize)
63 continue;
64 perc = (100.0 * (((double)(tmp->received + tmp->resume)) / (double)tmp->filesize));
65 sprintf(tmpbuff, "%4.1f%%%%", perc);
66 if (upload)
67 strcat(buffer, ",");
68 else
69 strcat(buffer, " [S:");
70 strcat(buffer, tmpbuff);
71 }
72 if (upload)
73 strcat(buffer, "]");
74 sprintf(tmpbuff, " [U:%d/D:%d]", upload, download);
75 strcat(buffer, tmpbuff);
76 return m_strdup(buffer);
77 }
78
BUILT_IN_DLL(nap_del)79 BUILT_IN_DLL(nap_del)
80 {
81 int count = 0;
82 GetFile *tmp, *last = NULL;
83 int num;
84 char *t;
85 if (!args && !*args)
86 return;
87 if (*args == '*')
88 {
89 if ((do_hook(MODULE_LIST, "NAP DEL ALL")))
90 nap_say("%s", cparse("Removing ALL file send/upload", NULL));
91 while (getfile_struct)
92 {
93 count++;
94 tmp = getfile_struct;
95 last = tmp->next;
96 if ((do_hook(MODULE_LIST, "NAP DEL GET %s %s", tmp->nick, tmp->filename)))
97 nap_say("%s", cparse("Removing $0 [$1-]", "%s %s", tmp->nick, base_name(tmp->filename)));
98 nap_finished_file(tmp->socket, tmp);
99 getfile_struct = last;
100 send_ncommand(CMDS_UPDATE_GET, NULL);
101 }
102 while (napster_sendqueue)
103 {
104 count++;
105 tmp = napster_sendqueue;
106 last = tmp->next;
107 if ((do_hook(MODULE_LIST, "NAP DEL SEND %s %s", tmp->nick, tmp->filename)))
108 nap_say("%s", cparse("Removing $0 [$1-]", "%s %s", tmp->nick, base_name(tmp->filename)));
109 nap_finished_file(tmp->socket, tmp);
110 napster_sendqueue = last;
111 send_ncommand(CMDS_UPDATE_SEND, NULL);
112 }
113 build_napster_status(NULL);
114 return;
115 }
116 while ((t = next_arg(args, &args)))
117 {
118 char *name = NULL;
119 count = 1;
120 if (!(num = my_atol(t)))
121 name = t;
122 for (tmp = getfile_struct; tmp; tmp = tmp->next, count++)
123 {
124 if ((count == num) || (name && !my_stricmp(name, tmp->nick)))
125 {
126 if (last)
127 last->next = tmp->next;
128 else
129 getfile_struct = tmp->next;
130 if ((do_hook(MODULE_LIST, "NAP DEL GET %s %s", tmp->nick, tmp->filename)))
131 nap_say("%s", cparse("Removing $0 [$1-]", "%s %s", tmp->nick, base_name(tmp->filename)));
132 nap_finished_file(tmp->socket, tmp);
133 build_napster_status(NULL);
134 send_ncommand(CMDS_UPDATE_GET, NULL);
135 return;
136 }
137 last = tmp;
138 }
139 last = NULL;
140 for (tmp = napster_sendqueue; tmp; tmp = tmp->next, count++)
141 {
142 if ((count == num) || (name && !my_stricmp(name, tmp->nick)))
143 {
144 if (last)
145 last->next = tmp->next;
146 else
147 napster_sendqueue = tmp->next;
148 if ((do_hook(MODULE_LIST, "NAP DEL SEND %s %s", tmp->nick, tmp->filename)))
149 nap_say("%s", cparse("Removing $0 [$1-]", "%s %s", tmp->nick, base_name(tmp->filename)));
150 nap_finished_file(tmp->socket, tmp);
151 build_napster_status(NULL);
152 send_ncommand(CMDS_UPDATE_SEND, NULL);
153 return;
154 }
155 last = tmp;
156 }
157 }
158 }
159
BUILT_IN_DLL(nap_glist)160 BUILT_IN_DLL(nap_glist)
161 {
162 int count = 1;
163 GetFile *sg = getfile_struct;
164 time_t snow = now;
165 char *dformat = "%W#$[3]0%n %Y$4%n $[14]1 $[-6]2$3 $5/$6 $7-";
166
167 for(sg = getfile_struct; sg; sg = sg->next, count++)
168 {
169 char buff[80];
170 char buff1[80];
171 char buff2[80];
172 char ack[4];
173 double perc = 0.0;
174 if (count == 1)
175 {
176 nap_put("%s", cparse("������%GD%gownloads", NULL));
177 nap_put("%s", cparse("%K���%n�%W�%n�%K��������������%n�%W�%n�%K������%n�%W�%n�%K��������%n�%W�%n�%K�����%n�%W�%n�%K�����%n�%W�%n�%K������������������", NULL, NULL));
178 }
179 if (sg->starttime)
180 sprintf(buff, "%2.3f", sg->received / 1024.0 / (snow - sg->starttime));
181 else
182 strcpy(buff, "N/A");
183 if (sg->filesize)
184 perc = (100.0 * (((double)(sg->received + sg->resume)) / (double)sg->filesize));
185 sprintf(buff1, "%4.1f%%", perc);
186 sprintf(buff2, "%4.2f", _GMKv(sg->filesize));
187 *ack = 0;
188 if (sg->up & NAP_QUEUED)
189 strcpy(ack, "Q");
190 strcat(ack, sg->starttime ? "D" : "W");
191 nap_put("%s", cparse(dformat, "%d %s %s %s %s %s %s %s",
192 count, sg->nick, buff2, _GMKs(sg->filesize),
193 ack, buff, buff1, base_name(sg->filename)));
194 }
195 for (sg = napster_sendqueue; sg; sg = sg->next, count++)
196 {
197 char buff[80];
198 char buff1[80];
199 char buff2[80];
200 char ack[10];
201 double perc = 0.0;
202 if (count == 1)
203 {
204 nap_put("%s", cparse("������%GU%gploads", NULL));
205 nap_put("%s", cparse("%K���%n�%W�%n�%K��������������%n�%W�%n�%K������%n�%W�%n�%K��������%n�%W�%n�%K�����%n�%W�%n�%K�����%n�%W�%n�%K������������������", NULL, NULL));
206 }
207 if (sg->starttime)
208 sprintf(buff, "%2.3f", sg->received / 1024.0 / (snow - sg->starttime));
209 else
210 strcpy(buff, "N/A");
211 if (sg->filesize)
212 perc = (100.0 * (((double)(sg->received + sg->resume)) / (double)sg->filesize));
213 sprintf(buff1, "%4.1f%%", perc);
214 sprintf(buff2, "%4.2f", _GMKv(sg->filesize));
215 *ack = 0;
216 if (sg->up & NAP_QUEUED)
217 strcpy(ack, "Q");
218 strcat(ack, sg->starttime ? "U" : "W");
219 nap_put("%s", cparse(dformat, "%d %s %s %s %s %s %s %s",
220 count, sg->nick, buff2, _GMKs(sg->filesize),
221 ack, buff, buff1, base_name(sg->filename)));
222 }
223 }
224
NAP_COMM(cmd_resumerequest)225 NAP_COMM(cmd_resumerequest)
226 {
227 char *nick, *file, *checksum;
228 int port;
229 unsigned long filesize;
230 unsigned long ip;
231 int speed;
232 int count = 0;
233 ResumeFile *sf;
234
235 nick = next_arg(args, &args);
236 ip = my_atol(next_arg(args, &args));
237 port = my_atol(next_arg(args, &args));
238 file = new_next_arg(args, &args);
239 checksum = next_arg(args, &args);
240 filesize = my_atol(next_arg(args, &args));
241 speed = my_atol(next_arg(args, &args));
242
243 for (sf = resume_struct; sf; sf = sf->next)
244 {
245 if (!strcmp(checksum, sf->checksum) && (filesize == sf->filesize))
246 {
247 FileStruct *new;
248 new = new_malloc(sizeof(FileStruct));
249 new->nick = m_strdup(nick);
250 new->ip = ip;
251 new->name = m_strdup(file);
252 new->checksum = m_strdup(checksum);
253 new->port = port;
254 new->filesize = filesize;
255 new->speed = speed;
256 new->next = sf->results;
257 sf->results = new;
258 count++;
259 }
260 }
261 if (!count)
262 nap_say("error in resume request. no match");
263 return 0;
264 }
265
NAP_COMM(cmd_resumerequestend)266 NAP_COMM(cmd_resumerequestend)
267 {
268 char *checksum;
269 unsigned long filesize;
270 ResumeFile *sf;
271 checksum = next_arg(args, &args);
272 filesize = my_atol(next_arg(args, &args));
273 for (sf = resume_struct; sf; sf = sf->next)
274 {
275 if (!strcmp(checksum, sf->checksum) && (filesize == sf->filesize))
276 {
277 FileStruct *new;
278 int count = 1;
279 for (new = sf->results; new; new = new->next)
280 print_file(new, count++);
281 }
282 }
283 return 0;
284 }
285
BUILT_IN_DLL(nap_request)286 BUILT_IN_DLL(nap_request)
287 {
288 char *nick, *filen, *comm;
289
290 if (!my_stricmp(command, "nrequest"))
291 {
292 nick = next_arg(args, &args);
293 filen = new_next_arg(args, &args);
294 if (nick && filen && *filen)
295 {
296 GetFile *new;
297 do_hook(MODULE_LIST, "NAP REQUESTFILE %s %s", nick, filen);
298 send_ncommand(CMDS_REQUESTFILE, "%s \"%s\"", nick, filen);
299 new = new_malloc(sizeof(GetFile));
300 new->nick = m_strdup(nick);
301 new->filename = m_strdup(filen);
302 new->next = getfile_struct;
303 getfile_struct = new;
304 }
305 }
306 else if (!my_stricmp(command, "nget") || !my_stricmp(command, "nresume"))
307 {
308 int i = 0, count = 1, resume = 0;
309 FileStruct *sf = NULL;
310 ResumeFile *rf = NULL;
311
312 resume = !my_stricmp(command, "nresume") ? 1 : 0;
313 while (args && *args)
314 {
315 int req, browse;
316
317 sf = NULL;
318 req = browse = 0;
319 count = 1;
320 comm = next_arg(args, &args);
321 if (!my_strnicmp(comm, "-request", 3))
322 {
323 req = 1;
324 comm = next_arg(args, &args);
325 }
326 else if (!my_strnicmp(comm, "-browse", 3))
327 {
328 browse = 1;
329 comm = next_arg(args, &args);
330 }
331
332 if (comm && *comm)
333 i = strtoul(comm, NULL, 10);
334 if (!req && !browse)
335 {
336 if (file_search)
337 sf = file_search;
338 else
339 sf = file_browse;
340 }
341 else if (req)
342 sf = file_search;
343 else
344 sf = file_browse;
345
346 if (sf && i)
347 {
348 for (; sf; sf = sf->next, count++)
349 {
350 if (i == count)
351 {
352 GetFile *new;
353 if (resume)
354 {
355 for (rf = resume_struct; rf; rf= rf->next)
356 {
357 if (!strcmp(rf->checksum, sf->checksum) && (sf->filesize == rf->filesize))
358 {
359 nap_say("Already a Resume request for %s", base_name(sf->name));
360 return;
361 }
362 }
363 rf = new_malloc(sizeof(ResumeFile));
364 rf->checksum = m_strdup(sf->checksum);
365 rf->filename = m_strdup(sf->name);
366 rf->filesize = sf->filesize;
367 rf->next = resume_struct;
368 resume_struct = rf;
369 send_ncommand(CMDS_REQUESTRESUME, "%s %lu", rf->checksum, rf->filesize);
370 do_hook(MODULE_LIST, "NAP RESUMEREQUEST %s %lu %s", sf->checksum, rf->filesize, rf->filename);
371 return;
372 }
373 do_hook(MODULE_LIST, "NAP REQUESTFILE %s %s", sf->nick, sf->name);
374 send_ncommand(CMDS_REQUESTFILE, "%s \"%s\"", sf->nick, sf->name);
375 new = new_malloc(sizeof(GetFile));
376 new->nick = m_strdup(sf->nick);
377 new->filename = m_strdup(sf->name);
378 new->filesize = sf->filesize;
379 new->checksum = m_strdup(sf->checksum);
380 new->next = getfile_struct;
381 getfile_struct = new;
382 return;
383 }
384 }
385 }
386 else if (sf)
387 {
388 for (; sf; sf = sf->next)
389 print_file(sf, count++);
390 return;
391 }
392 }
393 if (file_search)
394 {
395 for (sf = file_search; sf; sf = sf->next)
396 print_file(sf, count++);
397 } else if (file_browse)
398 for (sf = file_browse; sf; sf = sf->next)
399 print_file(sf, count++);
400 }
401 }
402
find_in_getfile(GetFile ** fn,int remove,char * nick,char * check,char * file,int speed,int up)403 GetFile *find_in_getfile(GetFile **fn, int remove, char *nick, char *check, char *file, int speed, int up)
404 {
405 GetFile *last, *tmp;
406 last = NULL;
407 if (!nick)
408 return NULL;
409 for (tmp = *fn; tmp; tmp = tmp->next)
410 {
411 if (!my_stricmp(tmp->nick, nick))
412 {
413 if (check && my_stricmp(tmp->checksum, check))
414 {
415 last = tmp;
416 continue;
417 }
418 if (file && my_stricmp(tmp->filename, file))
419 {
420 last = tmp;
421 continue;
422 }
423 if ((speed != -1) && (tmp->speed != speed))
424 {
425 last = tmp;
426 continue;
427 }
428 if ((up != -1) && ((tmp->up & ~NAP_QUEUED) != up))
429 {
430 last = tmp;
431 continue;
432 }
433 if (remove)
434 {
435 if (last)
436 last->next = tmp->next;
437 else
438 *fn = tmp->next;
439 }
440 return tmp;
441 }
442 last = tmp;
443 }
444 return NULL;
445 }
446
getfile_cleanup(int snum)447 void getfile_cleanup(int snum)
448 {
449 SocketList *s;
450 if ((s = get_socket(snum)) && s->info)
451 {
452 GetFile *f = (GetFile *)s->info;
453 if ((f = find_in_getfile(&getfile_struct, 1, f->nick, f->checksum, f->filename, -1, NAP_DOWNLOAD)))
454 {
455 new_free(&f->nick);
456 new_free(&f->filename);
457 new_free(&f->realfile);
458 new_free(&f->ip);
459 new_free(&f->checksum);
460 if (f->write > 0)
461 close(f->write);
462 new_free(&f);
463 }
464 s->info = NULL;
465 }
466 close_socketread(snum);
467 build_napster_status(NULL);
468 return;
469 }
470
nap_getfile(int snum)471 void nap_getfile(int snum)
472 {
473 char indata[2*NAP_BUFFER_SIZE+1];
474 SocketList *s;
475 int rc;
476 int count = sizeof(indata) - 1;
477 GetFile *gf;
478 unsigned long nbytes = 0;
479
480 s = get_socket(snum);
481 gf = (GetFile *)get_socketinfo(snum);
482 if (gf && gf->count)
483 {
484 int flags = O_WRONLY;
485 memset(&indata, 0, 200);
486 if ((rc = read(snum, &indata, gf->count)) != gf->count)
487 return;
488 if (!isdigit(*indata) || !*(indata+1) || !isdigit(*(indata+1)))
489 {
490 rc += read(snum, &indata[gf->count], sizeof(indata)-1);
491 indata[rc] = 0;
492 nap_say("Request from %s is %s", gf->nick, indata);
493 gf = find_in_getfile(&getfile_struct, 1, gf->nick, gf->checksum, gf->filename, -1, NAP_DOWNLOAD);
494 nap_finished_file(snum, gf);
495 return;
496 }
497 gf->count = 0;
498 set_non_blocking(snum);
499 gf->starttime = time(NULL);
500 if (!gf->resume)
501 flags |= O_CREAT;
502 if (!gf->realfile || ((gf->write = open(gf->realfile, flags, 0666)) == -1))
503 {
504 nap_say("Error opening output file %s: %s\n", base_name(gf->realfile), strerror(errno));
505 gf = find_in_getfile(&getfile_struct, 1, gf->nick, gf->checksum, gf->filename, -1, NAP_DOWNLOAD);
506 nap_finished_file(snum, gf);
507 return;
508 }
509 if (gf->resume)
510 lseek(gf->write, gf->resume, SEEK_SET);
511 if (do_hook(MODULE_LIST, "NAP GETFILE %sING %s %lu %s",gf->resume ? "RESUM": "GETT", gf->nick, gf->filesize, gf->filename))
512 {
513 sprintf(indata, "%4.2g%s %4.2g%s", _GMKv(gf->resume), _GMKs(gf->resume), _GMKv(gf->filesize), _GMKs(gf->filesize));
514 nap_say("%s", cparse(gf->resume ?"$0ing from $1 $2/$3 [$4-]":"$0ing from $1 $3 [$4-]", "%s %s %s %s", gf->resume?"Resum":"Gett", gf->nick, indata, base_name(gf->filename)));
515 }
516 add_sockettimeout(snum, 0, NULL);
517 send_ncommand(CMDS_UPDATE_GET1, NULL);
518 build_napster_status(NULL);
519 return;
520 }
521 else if (!gf)
522 {
523 s->is_write = 0;
524 close_socketread(snum);
525 send_ncommand(CMDS_UPDATE_GET, NULL);
526 return;
527 }
528 if ((rc = ioctl(snum, FIONREAD, &nbytes) != -1))
529 {
530 if (nbytes)
531 {
532 count = (nbytes > count) ? count : nbytes;
533 rc = read(snum, indata, count);
534 } else
535 rc = 0;
536 }
537 switch (rc)
538 {
539 case -1:
540 nap_say("ERROR reading file [%s]", strerror(errno));
541 case 0:
542 {
543 if (gf && (gf = find_in_getfile(&getfile_struct, 1, gf->nick, gf->checksum, gf->filename, -1, NAP_DOWNLOAD)))
544 {
545 char speed1[80];
546 double speed;
547 speed = gf->received / 1024.0 / (now - gf->starttime);
548 sprintf(speed1, "%4.2fK/s", speed);
549 if ((gf->received + gf->resume) >= gf->filesize)
550 {
551 char rs[60];
552 sprintf(rs, "%4.2g%s", _GMKv(gf->filesize), _GMKs(gf->filesize));
553 if (rc != -1 && do_hook(MODULE_LIST, "NAP GETFILE FINISH %sING %s %s %lu %s", gf->resume ? "RESUM":"GETT", gf->nick, speed1, gf->received + gf->resume, gf->filename))
554 nap_say("%s", cparse("Finished $2ing [$3-] from $0 $1", "%s %s %s %s %s", gf->nick, speed1, gf->resume ? "Resum":"Gett", rs, base_name(gf->filename)));
555 if (speed > statistics.max_downloadspeed)
556 statistics.max_downloadspeed = speed;
557 statistics.files_received++;
558 statistics.filesize_received += gf->received;
559 }
560 else if (do_hook(MODULE_LIST, "NAP GETFILE ERROR %sING %s %s %lu %lu %s", gf->resume? "RESUM":"GETT", gf->nick, speed1, gf->filesize, gf->received + gf->resume, gf->filename))
561 {
562 char fs[60];
563 char rs[60];
564 sprintf(fs, "%4.2g%s", _GMKv(gf->filesize), _GMKs(gf->filesize));
565 sprintf(rs, "%4.2g%s", _GMKv(gf->received), _GMKs(gf->received));
566 nap_say("%s", cparse("Error $2ing [$3-] from $0 $1", "%s %s %s %s %s %s", gf->nick, speed1, gf->resume ? "Resum":"Gett", fs, rs, base_name(gf->filename)));
567 }
568 }
569 send_ncommand(CMDS_UPDATE_GET, NULL);
570 nap_finished_file(snum, gf);
571 build_napster_status(NULL);
572 return;
573 }
574 default:
575 break;
576 }
577 write(gf->write, indata, rc);
578 gf->received += rc;
579 if ((gf->received+gf->resume) >= gf->filesize)
580 {
581 if ((gf = find_in_getfile(&getfile_struct, 1,
582 gf->nick, gf->checksum, gf->filename, -1, NAP_DOWNLOAD)))
583 {
584 char speed1[80];
585 double speed;
586 speed = gf->received / 1024.0 / (now - gf->starttime);
587 sprintf(speed1, "%4.2fK/s", speed);
588 if (speed > statistics.max_downloadspeed)
589 statistics.max_downloadspeed = speed;
590 if (do_hook(MODULE_LIST, "NAP GETFILE FINISH %sING %s %s %lu %s", gf->resume ? "RESUM":"GETT", gf->nick, speed1, gf->filesize, gf->filename))
591 {
592 char rs[60];
593 sprintf(rs, "%4.2g%s", _GMKv(gf->filesize), _GMKs(gf->filesize));
594 nap_say("%s", cparse("Finished $2ing [$3-] from $0 at $1", "%s %s %s %s %s", gf->nick, speed1, gf->resume?"Resum":"Gett", rs, base_name(gf->filename)));
595 }
596 statistics.files_received++;
597 statistics.filesize_received += gf->received;
598 }
599 send_ncommand(CMDS_UPDATE_GET, NULL);
600 nap_finished_file(snum, gf);
601 build_napster_status(NULL);
602 }
603 }
604
nap_getfilestart(int snum)605 void nap_getfilestart(int snum)
606 {
607 SocketList *s;
608 int rc;
609 char c;
610 GetFile *gf;
611 s = get_socket(snum);
612 gf = (GetFile *)get_socketinfo(snum);
613 if (gf)
614 {
615 set_blocking(snum);
616 if ((rc = read(snum, &c, 1)) != 1)
617 return;
618 s->func_read = nap_getfile;
619 return;
620 }
621 close_socketread(snum);
622 }
623
624
nap_firewall_get(int snum)625 void nap_firewall_get(int snum)
626 {
627 char indata[2*NAP_BUFFER_SIZE+1];
628 int rc;
629 memset(indata, 0, sizeof(indata));
630 alarm(15);
631 rc = recv(snum, indata, sizeof(indata)-1, 0);
632 alarm(0);
633 switch(rc)
634 {
635 case -1:
636 close_socketread(snum);
637 nap_say("ERROR in nap_firewall_get %s", strerror(errno));
638 case 0:
639 break;
640 default:
641 {
642 char *args, *nick, *filename;
643 unsigned long filesize;
644 GetFile *gf;
645 SocketList *s;
646
647 s = get_socket(snum);
648 if (!strncmp(indata, "FILE NOT", 8) || !strncmp(indata, "INVALID DATA", 10))
649 {
650 close_socketread(snum);
651 return;
652 }
653 args = &indata[0];
654 if (!(nick = next_arg(args, &args)))
655 {
656 close_socketread(snum);
657 return;
658 }
659 filename = new_next_arg(args, &args);
660 filesize = my_atol(next_arg(args, &args));
661 if (!filename || !*filename || !filesize)
662 {
663 close_socketread(snum);
664 return;
665 }
666 if ((gf = find_in_getfile(&getfile_struct, 0, nick, NULL, filename, -1, NAP_DOWNLOAD)))
667 {
668 int flags = O_WRONLY;
669 #ifndef NO_STRUCT_LINGER
670 int len;
671 struct linger lin;
672 len = sizeof(lin);
673 lin.l_onoff = lin.l_linger = 1;
674 #endif
675
676 gf->count = 0;
677 set_non_blocking(snum);
678 gf->starttime = time(NULL);
679 gf->socket = snum;
680 gf->filesize = filesize;
681 if (!gf->resume)
682 flags |= O_CREAT;
683 if (!gf->realfile || ((gf->write = open(gf->realfile, flags, 0666)) == -1))
684 {
685 nap_say("Error opening output file %s: %s\n", base_name(gf->realfile), strerror(errno));
686 gf = find_in_getfile(&getfile_struct, 1, gf->nick, gf->checksum, gf->filename, -1, NAP_DOWNLOAD);
687 nap_finished_file(snum, gf);
688 return;
689 }
690 if (gf->resume)
691 lseek(gf->write, gf->resume, SEEK_SET);
692 sprintf(indata, "%lu", gf->resume);
693 write(snum, indata, strlen(indata));
694 if (do_hook(MODULE_LIST, "NAP GETFILE %sING %s %lu %s",gf->resume ? "RESUM": "GETT", gf->nick, gf->filesize, gf->filename))
695 {
696 sprintf(indata, "%4.2g%s %4.2g%s", _GMKv(gf->resume), _GMKs(gf->resume), _GMKv(gf->filesize), _GMKs(gf->filesize));
697 nap_say("%s", cparse("$0ing from $1 $3 [$4-]", "%s %s %s %s", gf->resume?"Resum":"Gett", gf->nick, indata, base_name(gf->filename)));
698 }
699 add_sockettimeout(snum, 0, NULL);
700 send_ncommand(CMDS_UPDATE_GET1, NULL);
701 build_napster_status(NULL);
702 s->func_read = nap_getfile;
703 set_socketinfo(snum, gf);
704 #ifndef NO_STRUCT_LINGER
705 setsockopt(snum, SOL_SOCKET, SO_LINGER, (char *)&lin, len);
706 #endif
707 }
708 }
709 }
710 }
711
NAP_COMM(cmd_getfileinfo)712 NAP_COMM(cmd_getfileinfo)
713 {
714 char *nick;
715 GetFile *gf;
716 char indata[2*NAP_BUFFER_SIZE+1];
717 int count;
718 nick = next_arg(args, &args);
719 count = my_atol(args);
720 if ((gf = find_in_getfile(&getfile_struct, 0, nick, NULL, NULL, count, NAP_DOWNLOAD)))
721 {
722 sprintf(indata, "%lu", gf->filesize);
723 gf->count = strlen(indata);
724 write(gf->socket, "GET", 3);
725 snprintf(indata, sizeof(indata), "%s \"%s\" %lu", get_dllstring_var("napster_user"), gf->filename, gf->resume);
726 write(gf->socket, indata, strlen(indata));
727 add_socketread(gf->socket, gf->port, gf->write, gf->nick, nap_getfilestart, NULL);
728 set_socketinfo(gf->socket, gf);
729 add_sockettimeout(gf->socket, 180, getfile_cleanup);
730 }
731 return 0;
732 }
733
NAP_COMM(cmd_getfile)734 NAP_COMM(cmd_getfile)
735 {
736 /*
737 gato242 3068149784 6699 "d:\mp3\Hackers_-_07_-_Orbital_-_Halcyon_&_On_&_On.mp3"
738 8b451240c17fec98ea4f63e26bd42c60 7
739 */
740 unsigned short port;
741 int getfd = -1;
742 int speed;
743 char *nick, *file, *checksum, *ip, *dir = NULL;
744 char *realfile = NULL;
745 char indata[2*NAP_BUFFER_SIZE+1];
746 struct sockaddr_in socka;
747 GetFile *gf = NULL;
748 struct stat st;
749
750 nick = next_arg(args, &args);
751 ip = next_arg(args, &args);
752 port = my_atol(next_arg(args, &args));
753 file = new_next_arg(args, &args);
754 checksum = next_arg(args, &args);
755 speed = my_atol(args);
756
757 if (!(gf = find_in_getfile(&getfile_struct, 1, nick, checksum, file, -1, NAP_DOWNLOAD)))
758 {
759 nap_say("%s", "request not in getfile");
760 return 0;
761 }
762 gf->ip = m_strdup(ip);
763 gf->checksum = m_strdup(checksum);
764 gf->speed = atol(args);
765 gf->port = port;
766
767 if (!(dir = get_dllstring_var("napster_download_dir")))
768 if (!(dir = get_string_var(DCC_DLDIR_VAR)))
769 dir = "~";
770 snprintf(indata, sizeof(indata), "%s/%s", dir, base_name(file));
771
772 realfile = expand_twiddle(indata);
773
774 gf->realfile = realfile;
775 if (!(stat(realfile, &st)) && get_dllint_var("napster_resume_download"))
776 gf->resume = st.st_size;
777
778 gf->write = -1;
779
780 if (!port)
781 {
782 /* this is a firewalled host. make a listen socket instead */
783 send_ncommand(CMDS_REQUESTFILEFIRE, "%s \"%s\"", nick, file);
784 nap_say("Attempting to get from a firewalled host");
785 }
786 else
787 {
788 #ifndef NO_STRUCT_LINGER
789 int len;
790 struct linger lin;
791 len = sizeof(lin);
792 lin.l_onoff = lin.l_linger = 1;
793 #endif
794
795 getfd = socket(AF_INET, SOCK_STREAM, 0);
796 socka.sin_addr.s_addr = strtoul(ip, NULL, 10);
797 socka.sin_family = AF_INET;
798 socka.sin_port = htons(port);
799 alarm(get_int_var(CONNECT_TIMEOUT_VAR));
800 if (connect(getfd, (struct sockaddr *)&socka, sizeof(struct sockaddr)) != 0)
801 {
802 nap_say("ERROR connecting [%s]", strerror(errno));
803 send_ncommand(CMDR_DATAPORTERROR, gf->nick);
804 new_free(&gf->nick);
805 new_free(&gf->filename);
806 new_free(&gf->ip);
807 new_free(&gf->checksum);
808 new_free(&gf->realfile);
809 new_free(&gf);
810 return 0;
811 }
812 alarm(0);
813 #ifndef NO_STRUCT_LINGER
814 setsockopt(getfd, SOL_SOCKET, SO_LINGER, (char *)&lin, len);
815 #endif
816 send_ncommand(CMDS_REQUESTINFO, nick);
817 }
818
819 gf->socket = getfd;
820 gf->next = getfile_struct;
821 gf->up = NAP_DOWNLOAD;
822 getfile_struct = gf;
823 return 0;
824 }
825
NAP_COMM(cmd_send_limit_msg)826 NAP_COMM(cmd_send_limit_msg)
827 {
828 char *nick, *filename, *limit, *filesize;
829 GetFile *gf;
830 nick = next_arg(args, &args);
831 filename = new_next_arg(args, &args);
832 filesize = next_arg(args, &args);
833 limit = args;
834 if (!(gf = find_in_getfile(&getfile_struct, 1, nick, NULL, filename, -1, NAP_DOWNLOAD)))
835 {
836 nap_say("%s %s[%s]", "request not in getfile", nick, filename);
837 return 0;
838 }
839 /* nap_finished_file(gf->socket, gf);*/
840 gf->up &= NAP_QUEUED;
841 if (do_hook(MODULE_LIST, "NAP QUEUE FULL %s %s %s %s", nick, filesize, limit, filename))
842 nap_say("%s", cparse("$0 send queue[$1] is full.", "%s %s %s", nick, limit, filename));
843 return 0;
844
845 }
846