1
2 #define IN_MODULE
3 #include "irc.h"
4 #include "struct.h"
5 #include "dcc.h"
6 #include "ircaux.h"
7 #include "ctcp.h"
8 #include "cdcc.h"
9 #include "input.h"
10 #include "status.h"
11 #include "lastlog.h"
12 #include "screen.h"
13 #include "vars.h"
14 #include "misc.h"
15 #include "output.h"
16 #include "module.h"
17 #include "hook.h"
18 #include "hash2.h"
19
20 #include "bsdglob.h"
21 #include "modval.h"
22 #include "napster.h"
23 #include "md5.h"
24
25 #include <sys/time.h>
26 #include <sys/stat.h>
27 #if !defined(WINNT) || !defined(__EMX__)
28 #include <sys/mman.h>
29 #endif
30
31 #define DEFAULT_FILEMASK "*.mp3"
32
33 #ifndef MAP_FAILED
34 #define MAP_FAILED (void *) -1
35 #endif
36
37 Stats statistics = { 0, };
38
39
40 #define MP3_ONLY 0
41 #define ANY_FILE -1
42 #define VIDEO_ONLY 1
43 #define IMAGE_ONLY 2
44
45
46 static int current_sending = 0;
47
48 GetFile *napster_sendqueue = NULL;
49
50 #define MODE_STEREO 0
51 #define MODE_JOINT_STEREO 1
52 #define MODE_DUAL_CHANNEL 2
53 #define MODE_MONO 3
54
55 #define DEFAULT_MD5_SIZE 292 * 1024
56 Files *fserv_files = NULL;
57
58 char *mime_string[] = { "audio/", "image/", "video/", "application/", "text/", "" };
59 char *mime_type[] = { "x-wav", "x-aiff", "x-midi", "x-mod", "x-mp3", /* 0-4 */
60 "gif", "jpeg", /* 5-6 */
61 "mpeg", /* 7 */
62 "UNIX Compressed", "x-Compressed", "x-bzip2", "x-Zip File", /* 8-11 */
63 "x-executable", /* 9 */
64 "plain", ""}; /* 10 */
65 char *audio[] = {".wav", ".aiff", ".mid", ".mod", ".mp3", ""};
66 char *image[] = {".jpg", ".gif", ""};
67 char *video[] = {".mpg", ".dat", ""};
68 char *application[] = {".tar.gz" ".tar.Z", ".Z", ".gz", ".arc", ".bz2", ".zip", ""};
69
find_mime_type(char * fn)70 char *find_mime_type(char *fn)
71 {
72 static char mime_str[100];
73 if (fn)
74 {
75 int i;
76 int type = 4;
77 int mim = 10;
78 if (!end_strcmp(fn, ".exe", 4))
79 {
80 type = 3;
81 mim = 9;
82 sprintf(mime_str, "%s%s", mime_string[type], mime_type[mim]);
83 return mime_str;
84 }
85 for (i = 0; *audio[i]; i++)
86 {
87 if (!end_strcmp(fn, audio[i], strlen(audio[i])))
88 {
89 type = 0;
90 mim = i;
91 sprintf(mime_str, "%s%s", mime_string[type], mime_type[mim]);
92 return mime_str;
93 }
94 }
95 for (i = 0; *image[i]; i++)
96 {
97 if (!end_strcmp(fn, image[i], strlen(image[i])))
98 {
99 type = 1;
100 mim = i + 5;
101 sprintf(mime_str, "%s%s", mime_string[type], mime_type[mim]);
102 return mime_str;
103 }
104 }
105 for (i = 0; *video[i]; i++)
106 {
107 if (!end_strcmp(fn, video[i], strlen(video[i])))
108 {
109 type = 2;
110 mim = 7;
111 sprintf(mime_str, "%s%s", mime_string[type], mime_type[mim]);
112 return mime_str;
113 }
114 }
115 for (i = 0; *application[i]; i++)
116 {
117 if (!end_strcmp(fn, application[i], strlen(application[i])))
118 {
119 type = 3;
120 switch(i)
121 {
122 case 0:
123 case 1:
124 case 2:
125 case 3:
126 mim = 8;
127 break;
128 case 4:
129 mim = 9;
130 break;
131 case 5:
132 mim = 10;
133 break;
134 case 6:
135 mim = 11;
136 break;
137 }
138 sprintf(mime_str, "%s%s", mime_string[type], mime_type[mim]);
139 return mime_str;
140 }
141 }
142 sprintf(mime_str, "%s%s", mime_string[type], mime_type[mim]);
143 return mime_str;
144 }
145 return NULL;
146 }
147
clear_files(Files ** f)148 void clear_files(Files **f)
149 {
150 Files *last, *f1 = *f;
151 while (f1)
152 {
153 last = f1->next;
154 new_free(&f1->filename);
155 new_free(&f1->checksum);
156 new_free(&f1);
157 f1 = last;
158 }
159 *f = NULL;
160 }
161
convertnap_dos(char * str)162 static char *convertnap_dos(char *str)
163 {
164 register char *p;
165 for (p = str; *p; p++)
166 if (*p == '/')
167 *p = '\\';
168 return str;
169 }
170
convertnap_unix(char * arg)171 static char *convertnap_unix(char *arg)
172 {
173 register char *x = arg;
174 while (*x)
175 {
176 if (*x == '\\')
177 *x = '/';
178 x++;
179 }
180 return arg;
181 }
182
183
mode_str(int mode)184 char *mode_str(int mode)
185 {
186 switch(mode)
187 {
188 case 0:
189 return "St";
190 case 1:
191 return "JS";
192 case 2:
193 return "DC";
194 case 3:
195 return "M";
196 }
197 return empty_string;
198 }
199
print_time(time_t input)200 char *print_time(time_t input)
201 {
202 static char buff[40];
203 time_t seconds,
204 minutes;
205 seconds = input;
206 minutes = seconds / 60;
207 seconds = seconds % 60;
208 sprintf(buff, "%02u:%02u", (unsigned int)minutes, (unsigned int)seconds);
209 return buff;
210 }
211
make_mp3_string(FILE * fp,Files * f,char * fs,char * dirbuff)212 char *make_mp3_string(FILE *fp, Files *f, char *fs, char *dirbuff)
213 {
214 static char buffer[2*NAP_BUFFER_SIZE+1];
215 char *s,
216 *loc,
217 *p,
218 *fn;
219
220 if (!fs || !*fs)
221 return empty_string;
222 memset(buffer, 0, sizeof(buffer));
223
224 loc = LOCAL_COPY(f->filename);
225 fn = strrchr(loc, '/');
226 *fn++ = 0;
227 if ((p = strrchr(loc, '/')))
228 *p++ = 0;
229 /* fn should point to the filename and p to the dir */
230 /*
231 * init the dir keeper
232 * or cmp the old dir with the new
233 */
234 if (dirbuff && (!*dirbuff || strcmp(dirbuff, p)))
235 {
236 strcpy(dirbuff, p);
237 if (fp)
238 fprintf(fp, "\nDirectory [ %s ]\n", dirbuff);
239 else
240 return NULL;
241 }
242 /* size bitrate [time] filename */
243 s = buffer;
244 while (*fs)
245 {
246 if (*fs == '%')
247 {
248 int prec = 0, fl = 0;
249 fs++;
250 if (isdigit(*fs))
251 {
252 prec = strtol(fs, &fs, 0);
253 if (*fs == '.')
254 fl = strtoul(fs+1, &fs, 0);
255 }
256 switch(*fs)
257 {
258 case '%':
259 *s++ = *fs;
260 break;
261 case 'b':
262 sprintf(s, "%*u", prec, f->bitrate);
263 break;
264 case 's':
265 if (!prec) prec = 3;
266 sprintf(s, "%*.*f%s", prec, fl, _GMKv(f->filesize), _GMKs(f->filesize));
267 break;
268 case 't':
269 strcpy(s, print_time(f->time));
270 break;
271 case 'T':
272 strcpy(s, ltoa(f->time));
273 break;
274 case 'f':
275 strcpy(s, fn);
276 break;
277 case 'F':
278 strcpy(s, f->filename);
279 break;
280 case 'M':
281 strcpy(s, f->checksum);
282 break;
283 case 'S':
284 strcpy(s, mode_str(f->stereo));
285 break;
286 case 'H':
287 sprintf(s, "%*.*f", prec, fl, ((double)f->freq) / ((double)1000.0));
288 break;
289 case 'h':
290 sprintf(s, "%*u", prec, f->freq);
291 break;
292 default:
293 *s++ = *fs;
294 break;
295 }
296 }
297 else if (*fs == '\\')
298 {
299 fs++;
300 switch(*fs)
301 {
302 case 'n':
303 strcpy(s, "\n");
304 break;
305 case 't':
306 strcpy(s, "\t");
307 break;
308 default:
309 *s++ = *fs++;
310 }
311 }
312 else
313 *s++ = *fs;
314 while (*s) s++;
315 fs++;
316 }
317 if (fp && *buffer)
318 fputs(buffer, fp);
319 return buffer;
320 }
321
322
read_glob_dir(char * path,int globflags,glob_t * globpat,int recurse)323 int read_glob_dir(char *path, int globflags, glob_t *globpat, int recurse)
324 {
325 char buffer[NAP_BUFFER_SIZE+1];
326
327 sprintf(buffer, "%s/*", path);
328 bsd_glob(buffer, globflags, NULL, globpat);
329 if (recurse)
330 {
331 int i = 0;
332 int old_glpathc = globpat->gl_pathc;
333 for (i = 0; i < old_glpathc; i++)
334 {
335 char *fn;
336 fn = globpat->gl_pathv[i];
337 if (fn[strlen(fn)-1] != '/')
338 continue;
339 sprintf(buffer, "%s*", fn);
340 bsd_glob(buffer, globflags|GLOB_APPEND, NULL, globpat);
341 }
342 while (i < globpat->gl_pathc)
343 {
344 for (i = old_glpathc, old_glpathc = globpat->gl_pathc; i < old_glpathc; i++)
345 {
346 char *fn;
347 fn = globpat->gl_pathv[i];
348 if (fn[strlen(fn)-1] != '/')
349 continue;
350 sprintf(buffer, "%s*", fn);
351 bsd_glob(buffer, globflags|GLOB_APPEND, NULL, globpat);
352 }
353 }
354 }
355 return 0;
356 }
357
print_mp3(char * pattern,char * format,int freq,int number,int bitrate,int md5)358 unsigned int print_mp3(char *pattern, char *format, int freq, int number, int bitrate, int md5)
359 {
360 unsigned int count = 0;
361 Files *new;
362 char dir[NAP_BUFFER_SIZE];
363 char *fs = NULL;
364 *dir = 0;
365 for (new = fserv_files; new; new = new->next)
366 {
367 if (!pattern || (pattern && wild_match(pattern, new->filename)))
368 {
369 char *p;
370 p = base_name(new->filename);
371 if ((bitrate != -1) && (new->bitrate != bitrate))
372 continue;
373 if ((freq != -1) && (new->freq != freq))
374 continue;
375 if (do_hook(MODULE_LIST, "NAP MATCH %s %s %u %lu", p, new->checksum, new->bitrate, new->time))
376 {
377 if (!format || !*format)
378 {
379 if (md5)
380 put_it("\"%s\" %s %dk [%s]", p, new->checksum, new->bitrate, print_time(new->time));
381 else
382 put_it("\"%s\" %s %dk [%s]", p, mode_str(new->stereo), new->bitrate, print_time(new->time));
383 }
384 else
385 {
386 if ((fs = make_mp3_string(NULL, new, format, dir)))
387 put_it("%s", fs);
388 else
389 put_it("%s", make_mp3_string(NULL, new, format, dir));
390 }
391 }
392 }
393 if ((number > 0) && (count == number))
394 break;
395 count++;
396 }
397 return count;
398 }
399
BUILT_IN_DLL(print_napster)400 BUILT_IN_DLL(print_napster)
401 {
402 int count = 0;
403 int bitrate = -1;
404 int number = -1;
405 int freq = -1;
406 int md5 = 0;
407 char *fs_output = NULL;
408 char *tmp_pat = NULL;
409
410 if ((get_dllstring_var("napster_format")))
411 fs_output = m_strdup(get_dllstring_var("napster_format"));
412 if (args && *args)
413 {
414 char *tmp;
415 while ((tmp = next_arg(args, &args)) && *tmp)
416 {
417 int len;
418 len = strlen(tmp);
419 if (!my_strnicmp(tmp, "-BITRATE", len))
420 {
421 if ((tmp = next_arg(args, &args)))
422 bitrate = (unsigned int) my_atol(tmp);
423 }
424 else if (!my_strnicmp(tmp, "-COUNT", len))
425 {
426 if ((tmp = next_arg(args, &args)))
427 number = (unsigned int) my_atol(tmp);
428 }
429 else if (!my_strnicmp(tmp, "-FREQ", 3))
430 {
431 if ((tmp = next_arg(args, &args)))
432 freq = (unsigned int)my_atol(tmp);
433 }
434 else if (!my_strnicmp(tmp, "-MD5", 3))
435 {
436 md5 = 1;
437 }
438 else if (!my_strnicmp(tmp, "-FORMAT", 3))
439 {
440 if ((tmp = new_next_arg(args, &args)))
441 malloc_strcpy(&fs_output, tmp);
442 }
443 else
444 {
445 count += print_mp3(tmp, fs_output, freq, number, bitrate, md5);
446 m_s3cat(&tmp_pat, " ", tmp);
447 }
448 }
449 }
450 else
451 count += print_mp3(NULL, fs_output, freq, number, bitrate, md5);
452
453 if (do_hook(MODULE_LIST, "NAP MATCHEND %d %s", count, tmp_pat ? tmp_pat : "*"))
454 nap_say("Found %d files matching \"%s\"", count, tmp_pat ? tmp_pat : "*");
455 new_free(&tmp_pat);
456 new_free(&fs_output);
457 }
458
459
convert_to_header(unsigned char * buf)460 static unsigned long convert_to_header(unsigned char * buf)
461 {
462 return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
463 }
464
465
mpg123_head_check(unsigned long head)466 static int mpg123_head_check(unsigned long head)
467 {
468 if ((head & 0xffe00000) != 0xffe00000)
469 return 0;
470 if (!((head >> 17) & 3))
471 return 0;
472 if (((head >> 12) & 0xf) == 0xf)
473 return 0;
474 if (!((head >> 12) & 0xf))
475 return 0;
476 if (((head >> 10) & 0x3) == 0x3)
477 return 0;
478 if (((head >> 19) & 1) == 1 && ((head >> 17) & 3) == 3 && ((head >> 16) & 1) == 1)
479 return 0;
480 if ((head & 0xffff0000) == 0xfffe0000)
481 return 0;
482
483 return 1;
484 }
485
486 int tabsel_123[2][3][16] =
487 {
488 {
489 {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
490 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
491 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}},
492
493 {
494 {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
495 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
496 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}}
497 };
498
499 long mpg123_freqs[9] =
500 {44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000};
501
parse_header(AUDIO_HEADER * fr,unsigned long newhead)502 int parse_header(AUDIO_HEADER *fr, unsigned long newhead)
503 {
504 double bpf;
505
506 /* 00 2.5
507 01 reserved
508 10 version2
509 11 version1
510 */
511 if (newhead & (1 << 20))
512 {
513 fr->ID = (newhead & (1 << 19)) ? 0x0 : 0x1;
514 fr->mpeg25 = 0;
515 }
516 else
517 {
518 fr->ID = 1;
519 fr->mpeg25 = 1;
520 }
521 fr->layer = ((newhead >> 17) & 3);
522 if (fr->mpeg25)
523 fr->sampling_frequency = 6 + ((newhead >> 10) & 0x3);
524 else
525 fr->sampling_frequency = ((newhead >> 10) & 0x3) + (fr->ID * 3);
526
527 fr->error_protection = ((newhead >> 16) & 0x1) ^ 0x1;
528
529 if (fr->mpeg25) /* allow Bitrate change for 2.5 ... */
530 fr->bitrate_index = ((newhead >> 12) & 0xf);
531
532 fr->bitrate_index = ((newhead >> 12) & 0xf);
533 fr->padding = ((newhead >> 9) & 0x1);
534 fr->extension = ((newhead >> 8) & 0x1);
535 fr->mode = ((newhead >> 6) & 0x3);
536 fr->mode_ext = ((newhead >> 4) & 0x3);
537 fr->copyright = ((newhead >> 3) & 0x1);
538 fr->original = ((newhead >> 2) & 0x1);
539 fr->emphasis = newhead & 0x3;
540
541 fr->stereo = (fr->mode == 3) ? 1 : 2;
542 fr->true_layer = 4 - fr->layer;
543
544 if (!fr->bitrate_index)
545 return 0;
546
547 switch (fr->true_layer)
548 {
549 case 1:
550 fr->bitrate = tabsel_123[fr->ID][0][fr->bitrate_index];
551 fr->framesize = (long) tabsel_123[fr->ID][0][fr->bitrate_index] * 12000;
552 fr->framesize /= mpg123_freqs[fr->sampling_frequency];
553 fr->framesize = ((fr->framesize + fr->padding) << 2) - 4;
554 fr->freq = mpg123_freqs[fr->sampling_frequency];
555 break;
556 case 2:
557 fr->framesize = (long) tabsel_123[fr->ID][1][fr->bitrate_index] * 144000;
558 fr->framesize /= mpg123_freqs[fr->sampling_frequency];
559 fr->framesize += fr->padding - 4;
560 fr->freq = mpg123_freqs[fr->sampling_frequency];
561 fr->bitrate = tabsel_123[fr->ID][1][fr->bitrate_index];
562 break;
563 case 3:
564 {
565 fr->bitrate = tabsel_123[fr->ID][2][fr->bitrate_index];
566 fr->framesize = (long) tabsel_123[fr->ID][2][fr->bitrate_index] * 144000;
567 fr->framesize /= mpg123_freqs[fr->sampling_frequency] << (fr->ID);
568 fr->framesize = fr->framesize + fr->padding - 4;
569 fr->freq = mpg123_freqs[fr->sampling_frequency];
570 break;
571 }
572 default:
573 return 0;
574 }
575 if (fr->framesize > 1792) /* supposedly max framesize */
576 return 0;
577 switch (fr->true_layer)
578 {
579 case 1:
580 bpf = tabsel_123[fr->ID][0][fr->bitrate_index];
581 bpf *= 12000.0 * 4.0;
582 bpf /= mpg123_freqs[fr->sampling_frequency] << (fr->ID);
583 break;
584 case 2:
585 case 3:
586 bpf = tabsel_123[fr->ID][fr->true_layer - 1][fr->bitrate_index];
587 bpf *= 144000;
588 bpf /= mpg123_freqs[fr->sampling_frequency] << (fr->ID);
589 break;
590 default:
591 bpf = 1.0;
592 }
593 fr->totalframes = fr->filesize / bpf;
594 return 1;
595 }
596
compute_tpf(AUDIO_HEADER * fr)597 double compute_tpf(AUDIO_HEADER *fr)
598 {
599 static int bs[4] = {0, 384, 1152, 1152};
600 double tpf;
601
602 tpf = (double) bs[fr->true_layer];
603 tpf /= mpg123_freqs[fr->sampling_frequency] << (fr->ID);
604 return tpf;
605 }
606
607
get_bitrate(int fdes,time_t * mp3_time,unsigned int * freq_rate,unsigned long * filesize,int * stereo,long * id3,int * mime_type)608 long get_bitrate(int fdes, time_t *mp3_time, unsigned int *freq_rate, unsigned long *filesize, int *stereo, long *id3, int *mime_type)
609 {
610
611
612 AUDIO_HEADER header = {0};
613 unsigned long btr = 0;
614 struct stat st;
615 unsigned long head;
616
617 unsigned char buf[1025];
618 unsigned char tmp[5];
619
620 if (freq_rate)
621 *freq_rate = 0;
622
623 fstat(fdes, &st);
624
625 if (!(*filesize = st.st_size))
626 return 0;
627 memset(tmp, 0, sizeof(tmp));
628 read(fdes, tmp, 4);
629
630 if (!strcmp(tmp, "PK\003\004")) /* zip magic */
631 return 0;
632 if (!strcmp(tmp, "PE") || !strcmp(tmp, "MZ")) /* windows Exe magic */
633 return 0;
634 if (!strcmp(tmp, "\037\235")) /* gzip/compress */
635 return 0;
636 if (!strcmp(tmp, "\037\213") || !strcmp(tmp, "\037\036") || !strcmp(tmp, "BZh")) /* gzip/compress/bzip2 */
637 return 0;
638 if (!strcmp(tmp, "\177ELF")) /* elf binary */
639 return 0;
640
641 head = convert_to_header(tmp);
642
643 if ((head == 0x000001ba) || (head == 0x000001b3)) /* got a video mpeg header */
644 return 0;
645 if ((head == 0xffd8ffe0) || (head == 0x47494638)) /* jpeg image gif image */
646 return 0;
647 if ((head == 0xea60)) /* ARJ magic */
648 return 0;
649
650 while (!mpg123_head_check(head))
651 {
652 int in_buf;
653 int i;
654 /*
655 * The mpeg-stream can start anywhere in the file,
656 * so we check the entire file
657 */
658 /* Optimize this */
659 if ((in_buf = read(fdes, buf, sizeof(buf)-1)) != (sizeof(buf)-1))
660 return 0;
661 for (i = 0; i < in_buf; i++)
662 {
663 head <<= 8;
664 head |= buf[i];
665 if(mpg123_head_check(head))
666 {
667 lseek(fdes, i+1-in_buf, SEEK_CUR);
668 break;
669 }
670 }
671 }
672 header.filesize = st.st_size;
673 parse_header(&header, head);
674
675 btr = header.bitrate;
676
677 *mp3_time = (time_t) (header.totalframes * compute_tpf(&header));
678 *freq_rate = header.freq;
679
680 if (id3)
681 {
682 char buff[130];
683 int rc;
684 lseek(fdes, 0, SEEK_SET);
685 *id3 = 0;
686 rc = read(fdes, buff, 128);
687 if (!strncmp(buff, "ID3", 3))
688 {
689 struct id3v2 {
690 char tag[3];
691 unsigned char ver[2];
692 unsigned char flag;
693 unsigned char size[4];
694 } id3v2;
695 unsigned char bytes[4];
696 /* this is id3v2 */
697 memcpy(&id3v2, buff, sizeof(id3v2));
698 bytes[3] = id3v2.size[3] | ((id3v2.size[2] & 1 ) << 7);
699 bytes[2] = ((id3v2.size[2] >> 1) & 63) | ((id3v2.size[1] & 3) << 6);
700 bytes[1] = ((id3v2.size[1] >> 2) & 31) | ((id3v2.size[0] & 7) << 5);
701 bytes[0] = ((id3v2.size[0] >> 3) & 15);
702
703 *id3 = (bytes[3] | (bytes[2] << 8) | ( bytes[1] << 16) | ( bytes[0] << 24 )) + sizeof(struct id3v2);
704 }
705 lseek(fdes, st.st_size-128, SEEK_SET);
706 rc = read(fdes, buff, 128);
707 if ((rc == 128) && !strncmp(buff, "TAG", 3))
708 *id3 = *id3 ? (*id3 * -1) : 1;
709 }
710 *stereo = header.mode;
711 return btr;
712 }
713
file_size(char * filename)714 off_t file_size (char *filename)
715 {
716 struct stat statbuf;
717
718 if (!stat(filename, &statbuf))
719 return (off_t)(statbuf.st_size);
720 else
721 return -1;
722 }
723
calc_md5(int r,unsigned long mapsize)724 char *calc_md5(int r, unsigned long mapsize)
725 {
726 unsigned char digest[16];
727 md5_state_t state;
728 char buffer[BIG_BUFFER_SIZE+1];
729 struct stat st;
730 unsigned long size = DEFAULT_MD5_SIZE;
731 int di = 0;
732 int rc;
733
734 #if !defined(WINNT) && !defined(__EMX__)
735 char *m;
736 #endif
737
738 *buffer = 0;
739 md5_init(&state);
740 if ((fstat(r, &st)) == -1)
741 return m_strdup("");
742
743 if (!mapsize)
744 {
745 if (st.st_size < size)
746 size = st.st_size;
747 }
748 else if (st.st_size < mapsize)
749 size = st.st_size;
750 else
751 size = mapsize;
752
753 #if defined(WINNT) || defined(__EMX__)
754 while (size)
755 {
756 unsigned char md5_buff[8 * NAP_BUFFER_SIZE+1];
757 rc = (size >= (8 * NAP_BUFFER_SIZE)) ? 8 * NAP_BUFFER_SIZE : size;
758 rc = read(r, md5_buff, rc);
759 md5_append(&state, (unsigned char *)md5_buff, rc);
760 if (size >= 8 * NAP_BUFFER_SIZE)
761 size -= rc;
762 else
763 size = 0;
764 }
765 md5_finish(digest, &state);
766 {
767 #else
768 if ((m = mmap((void *)0, size, PROT_READ, MAP_PRIVATE, r, 0)) != MAP_FAILED)
769 {
770 md5_append(&state, (unsigned char *)m, size);
771 md5_finish(digest, &state);
772 munmap(m, size);
773 #endif
774 memset(buffer, 0, 200);
775 for (di = 0, rc = 0; di < 16; ++di, rc += 2)
776 snprintf(&buffer[rc], BIG_BUFFER_SIZE, "%02x", digest[di]);
777 strcat(buffer, "-");
778 strcat(buffer, ltoa(st.st_size));
779 }
780 return m_strdup(buffer);
781 }
782
783 unsigned int scan_mp3_dir(char *path, int recurse, int reload, int share, int search_type)
784 {
785 int mt = 0;
786 glob_t globpat;
787 int i = 0;
788 Files *new;
789 int count = 0;
790 int r;
791 char buffer[2*NAP_BUFFER_SIZE+1];
792
793 memset(&globpat, 0, sizeof(glob_t));
794 read_glob_dir(path, GLOB_MARK|GLOB_NOSORT, &globpat, recurse);
795 for (i = 0; i < globpat.gl_pathc; i++)
796 {
797 char *fn;
798 long id3 = 0;
799 fn = globpat.gl_pathv[i];
800 if (fn[strlen(fn)-1] == '/')
801 continue;
802 switch (search_type)
803 {
804 case MP3_ONLY:
805 if (!(mt = wild_match(DEFAULT_FILEMASK, fn)))
806 continue;
807 break;
808 case VIDEO_ONLY:
809 if (!(mt = wild_match("*.mpg", fn)) && !(mt = wild_match("*.dat", fn)))
810 continue;
811 break;
812 case IMAGE_ONLY:
813 if (!(mt = wild_match("*.jpg", fn)) && !(mt = wild_match("*.gif", fn)))
814 continue;
815 break;
816 case ANY_FILE:
817 break;
818 }
819 if (reload && find_in_list((List **)&fserv_files, globpat.gl_pathv[i], 0))
820 continue;
821 if ((r = open(fn, O_RDONLY)) == -1)
822 continue;
823 new = (Files *) new_malloc(sizeof(Files));
824 new->filename = m_strdup(fn);
825 new->bitrate = get_bitrate(r, &new->time, &new->freq, &new->filesize, &new->stereo, &id3, &new->type);
826 if (new->filesize && new->bitrate)
827 {
828 unsigned long size = DEFAULT_MD5_SIZE;
829 switch(id3)
830 {
831 case 1:
832 {
833 if (new->filesize < size)
834 size = new->filesize - 128;
835 }
836 case 0:
837 lseek(r, 0, SEEK_SET);
838 break;
839 default:
840 {
841 lseek(r, (id3 < 0) ? -id3 : id3, SEEK_SET);
842 if (id3 > 0)
843 {
844 if ((new->filesize - id3) < size)
845 size = new->filesize - id3;
846 }
847 else
848 {
849 /*blah. got both tags. */
850 if ((new->filesize + id3 - 128) < size)
851 size = new->filesize + id3 - 128;
852 }
853 break;
854 }
855 }
856 new->checksum = calc_md5(r, size);
857 close(r);
858 r = -1;
859 add_to_list((List **)&fserv_files, (List *)new);
860 statistics.total_files++;
861 statistics.total_filesize += new->filesize;
862 count++;
863 if (share && (nap_socket != -1))
864 {
865 sprintf(buffer, "\"%s\" %s %lu %u %u %ld", new->filename,
866 new->checksum, new->filesize, new->bitrate, new->freq,
867 (long)new->time);
868 send_ncommand(CMDS_ADDFILE, convertnap_dos(buffer));
869 statistics.shared_files++;
870 statistics.shared_filesize += new->filesize;
871 }
872 if (!(count % 25))
873 {
874 lock_stack_frame();
875 io("scan_mp3_dir");
876 unlock_stack_frame();
877 build_napster_status(NULL);
878 }
879 }
880 else if (search_type != MP3_ONLY)
881 {
882 unsigned long size = DEFAULT_MD5_SIZE;
883 if (new->filesize < size)
884 size = new->filesize;
885 new->checksum = calc_md5(r, size);
886 close(r);
887 r = -1;
888 add_to_list((List **)&fserv_files, (List *)new);
889 statistics.total_files++;
890 statistics.total_filesize += new->filesize;
891 count++;
892 }
893 else
894 {
895 new_free(&new->filename);
896 new_free(&new);
897 }
898 if (r != -1)
899 close(r);
900 }
901 bsd_globfree(&globpat);
902 return count;
903 }
904
905 void load_shared(char *fname)
906 {
907 char buffer[BIG_BUFFER_SIZE+1];
908 char *expand = NULL;
909 FILE *fp;
910 int count = 0;
911 Files *new;
912 if (!fname || !*fname)
913 return;
914 if (!strchr(fname, '/'))
915 sprintf(buffer, "%s/%s", get_string_var(CTOOLZ_DIR_VAR), fname);
916 else
917 sprintf(buffer, "%s", fname);
918 expand = expand_twiddle(buffer);
919 if ((fp = fopen(expand, "r")))
920 {
921 char *fn, *md5, *fs, *br, *fr, *t, *args;
922 while (!feof(fp))
923 {
924 if (!fgets(buffer, BIG_BUFFER_SIZE, fp))
925 break;
926 args = &buffer[0];
927 fn = new_next_arg(args, &args);
928 if (fn && *fn && find_in_list((List **)&fserv_files, fn, 0))
929 continue;
930 if (!(md5 = next_arg(args, &args)) ||
931 !(fs = next_arg(args, &args)) ||
932 !(br = next_arg(args, &args)) ||
933 !(fr = next_arg(args, &args)) ||
934 !(t = next_arg(args, &args)))
935 continue;
936 new = (Files *) new_malloc(sizeof(Files));
937 new->filename = m_strdup(fn);
938 new->checksum = m_strdup(md5);
939 new->time = my_atol(t);
940 new->bitrate = my_atol(br);
941 new->freq = my_atol(fr);
942 new->filesize = my_atol(fs);
943 new->stereo = 1;
944 add_to_list((List **)&fserv_files, (List *)new);
945 count++;
946 statistics.total_files++;
947 statistics.total_filesize += new->filesize;
948 }
949 fclose(fp);
950 } else
951 nap_say("Error loading %s[%s]", buffer, strerror(errno));
952 if (count)
953 nap_say("Finished loading %s/%s. Sharing %d files", get_string_var(CTOOLZ_DIR_VAR), fname, count);
954 new_free(&expand);
955 }
956
957 void save_shared(char *fname)
958 {
959 char buffer[BIG_BUFFER_SIZE+1];
960 char *expand = NULL;
961 FILE *fp;
962 int count = 0;
963 Files *new;
964 if (!fname || !*fname)
965 return;
966 if (!strchr(fname, '/'))
967 sprintf(buffer, "%s/%s", get_string_var(CTOOLZ_DIR_VAR), fname);
968 else
969 sprintf(buffer, "%s", fname);
970 expand = expand_twiddle(buffer);
971 if ((fp = fopen(expand, "w")))
972 {
973 for (new = fserv_files; new; new = new->next)
974 {
975 fprintf(fp, "\"%s\" %s %lu %u %u %ld\n",
976 new->filename, new->checksum, new->filesize,
977 new->bitrate, new->freq, (long)new->time);
978 count++;
979 }
980 fclose(fp);
981 nap_say("Finished saving %s [%d]", buffer, count);
982 statistics.total_files = 0;
983 statistics.total_filesize = 0;
984 } else
985 nap_say("Error saving %s %s", buffer, strerror(errno));
986 new_free(&expand);
987 }
988
989 static int in_load = 0;
990 BUILT_IN_DLL(load_napserv)
991 {
992 char *path = NULL;
993 int recurse = 1;
994 char *pch;
995 int count = 0;
996 int reload = 0;
997 int share = 0;
998 int type = MP3_ONLY;
999
1000 char fname[] = "shared.dat";
1001
1002 if (command && !my_stricmp(command, "NRELOAD"))
1003 reload = 1;
1004
1005 if (in_load)
1006 {
1007 nap_say("Already loading files. Please wait");
1008 return;
1009 }
1010 in_load++;
1011 if (args && *args)
1012 {
1013 if (!my_stricmp(args, "-clear"))
1014 {
1015 Files *new;
1016 if (statistics.shared_files)
1017 {
1018 for (new = fserv_files; new; new = new->next)
1019 send_ncommand(CMDS_REMOVEFILE, new->filename);
1020 }
1021 statistics.total_files = 0;
1022 statistics.total_filesize = 0;
1023 statistics.shared_files = 0;
1024 statistics.shared_filesize = 0;
1025 clear_files(&fserv_files);
1026 in_load--;
1027 return;
1028 }
1029 else if (!my_stricmp(args, "-file"))
1030 {
1031 char *fn;
1032 next_arg(args, &args);
1033 fn = next_arg(args, &args);
1034 load_shared((fn && *fn) ? fn : fname);
1035 in_load--;
1036 return;
1037 }
1038 else if (!my_stricmp(args, "-save"))
1039 {
1040 char *fn;
1041 next_arg(args, &args);
1042 fn = next_arg(args, &args);
1043 save_shared((fn && *fn) ? fn : fname);
1044 in_load--;
1045 return;
1046 }
1047 else if (!my_strnicmp(args, "-video", 4))
1048 {
1049 next_arg(args, &args);
1050 type = VIDEO_ONLY;
1051 }
1052 else if (!my_strnicmp(args, "-image", 4))
1053 {
1054 next_arg(args, &args);
1055 type = IMAGE_ONLY;
1056 }
1057 while ((path = new_next_arg(args, &args)) && path && *path)
1058 {
1059 int len = strlen(path);
1060 if (!my_strnicmp(path, "-recurse", len))
1061 {
1062 recurse ^= 1;
1063 continue;
1064 }
1065 if (!my_strnicmp(path, "-share", len))
1066 {
1067 share ^= 1;
1068 continue;
1069 }
1070 count += scan_mp3_dir(path, recurse, reload, share, type);
1071 }
1072 }
1073 else
1074 {
1075 path = get_dllstring_var("napster_dir");
1076
1077 if (!path || !*path)
1078 {
1079 nap_say("No path. /set napster_dir first.");
1080 in_load = 0;
1081 return;
1082 }
1083
1084 pch = LOCAL_COPY(path);
1085 while ((path = new_next_arg(pch, &pch)) && path && *path)
1086 count += scan_mp3_dir(path, recurse, reload, share, type);
1087 }
1088
1089 build_napster_status(NULL);
1090 if (!fserv_files || !count)
1091 nap_say("Could not read dir");
1092 else if (do_hook(MODULE_LIST, "NAP LOAD %d", count))
1093 nap_say("Found %d files%s", count, share ? "" : ". To share these type /nshare");
1094 in_load = 0;
1095 return;
1096 }
1097
1098 static int in_sharing = 0;
1099
1100 BUILT_IN_DLL(share_napster)
1101 {
1102 unsigned long count = 0;
1103 char buffer[2*NAP_BUFFER_SIZE+1];
1104 Files *new;
1105 if (in_sharing)
1106 {
1107 nap_say("Already Attempting share");
1108 return;
1109 }
1110 in_sharing++;
1111 for (new = fserv_files; new && (nap_socket != -1); new = new->next, count++)
1112 {
1113 int rc;
1114 int len;
1115 int cmd;
1116 char *name;
1117
1118 if (!new->checksum || !new->filesize || !new->filename)
1119 continue;
1120 name = LOCAL_COPY(new->filename);
1121 name = convertnap_dos(name);
1122
1123 if (new->freq && new->bitrate)
1124 {
1125 sprintf(buffer, "\"%s\" %s %lu %u %u %ld", name,
1126 new->checksum, new->filesize, new->bitrate, new->freq,
1127 (long)new->time);
1128 cmd = CMDS_ADDFILE;
1129 }
1130 else
1131 {
1132 char *s;
1133 if (!(s = find_mime_type(new->filename)))
1134 continue;
1135 sprintf(buffer, "\"%s\" %lu %s %s", name, new->filesize, new->checksum, s);
1136 cmd = CMDS_ADDMIMEFILE;
1137 }
1138 len = strlen(buffer);
1139 if ((rc = send_ncommand(cmd, buffer)) == -1)
1140 {
1141 nclose(NULL, NULL, NULL, NULL, NULL);
1142 in_sharing = 0;
1143 return;
1144 }
1145 statistics.shared_files++;
1146 statistics.shared_filesize += new->filesize;
1147 while (rc != len)
1148 {
1149 int i;
1150 if (!(count % 2))
1151 {
1152 lock_stack_frame();
1153 io("share napster");
1154 unlock_stack_frame();
1155 build_napster_status(NULL);
1156 }
1157 if ((nap_socket > -1) && (i = write(nap_socket, buffer+rc, strlen(buffer+rc))) != -1)
1158 rc += i;
1159 else
1160 {
1161 nclose(NULL, NULL, NULL, NULL, NULL);
1162 in_sharing = 0;
1163 return;
1164 }
1165 }
1166 if (!(count % 20))
1167 {
1168 lock_stack_frame();
1169 io("share napster");
1170 unlock_stack_frame();
1171 build_napster_status(NULL);
1172 }
1173 }
1174 build_napster_status(NULL);
1175 if (do_hook(MODULE_LIST, "NAP SHARE %d", count))
1176 nap_say("%s", cparse("Sharing $0 files", "%l", count));
1177 in_sharing = 0;
1178 }
1179
1180 int nap_finished_file(int snum, GetFile *gf)
1181 {
1182 SocketList *s = NULL;
1183 if (snum > 0)
1184 {
1185 if ((s = get_socket(snum)))
1186 {
1187 s->is_write = 0;
1188 s->info = NULL;
1189 }
1190 close_socketread(snum);
1191 }
1192 if (gf)
1193 {
1194 if (gf->write > 0)
1195 close(gf->write);
1196 new_free(&gf->nick);
1197 new_free(&gf->filename);
1198 new_free(&gf->checksum);
1199 new_free(&gf->realfile);
1200 new_free(&gf->ip);
1201 if (gf->up == NAP_UPLOAD)
1202 current_sending--;
1203 new_free(&gf);
1204 }
1205 return 0;
1206 }
1207
1208 void sendfile_timeout(int snum)
1209 {
1210 GetFile *f = NULL;
1211 if ((f = (GetFile *)get_socketinfo(snum)))
1212 {
1213 f = find_in_getfile(&napster_sendqueue, 1, f->nick, NULL, f->filename, -1, NAP_UPLOAD);
1214 if (do_hook(MODULE_LIST, "NAP SENDTIMEOUT %s %s", f->nick, strerror(errno)))
1215 nap_say("%s", cparse("Send to $0 timed out [$1-]", "%s %s", f->nick, strerror(errno)));
1216 if (f->socket)
1217 send_ncommand(CMDS_UPDATE_SEND, NULL);
1218 }
1219 nap_finished_file(snum, f);
1220 build_napster_status(NULL);
1221 return;
1222 }
1223
1224 int clean_queue(GetFile **gf, int timeout)
1225 {
1226 GetFile *ptr;
1227 int count = 0;
1228 if (!gf || !*gf || timeout <= 0)
1229 return 0;
1230 ptr = *gf;
1231 while (ptr)
1232 {
1233 if (ptr->addtime && (ptr->addtime <= (now - timeout)))
1234 {
1235 if (!(ptr = find_in_getfile(gf, 1, ptr->nick, NULL, ptr->filename, -1, NAP_UPLOAD)))
1236 continue;
1237 if (ptr->write > 0)
1238 close(ptr->write);
1239 if (ptr->socket > 0)
1240 {
1241 SocketList *s;
1242 s = get_socket(ptr->socket);
1243 s->is_write = 0;
1244 s->info = NULL;
1245 close_socketread(ptr->socket);
1246 send_ncommand(CMDS_UPDATE_SEND, NULL);
1247 }
1248 new_free(&ptr->nick);
1249 new_free(&ptr->filename);
1250 new_free(&ptr->checksum);
1251 new_free(&ptr->realfile);
1252 new_free(&ptr->ip);
1253 if (ptr->up == NAP_UPLOAD)
1254 current_sending--;
1255 new_free(&ptr);
1256 ptr = *gf;
1257 count++;
1258 }
1259 else
1260 ptr = ptr->next;
1261 }
1262 if (count)
1263 nap_say("Cleaned queue of stale entries");
1264 return count;
1265 }
1266
1267 NAP_COMM(cmd_accepterror)
1268 {
1269 char *nick, *filename;
1270 nick = next_arg(args, &args);
1271 filename = new_next_arg(args, &args);
1272 if (nick && filename)
1273 {
1274 GetFile *gf;
1275 if (!(gf = find_in_getfile(&napster_sendqueue, 1, nick, NULL, filename, -1, NAP_UPLOAD)))
1276 return 0;
1277 nap_say("%s", cparse("Removing $0 from the send queue. Accept error", "%s", nick));
1278 nap_finished_file(gf->socket, gf);
1279 }
1280 return 0;
1281 }
1282
1283 void naplink_handleconnect(int);
1284
1285 NAP_COMM(cmd_firewall_request) /* 501 */
1286 {
1287 char *nick,
1288 *ip,
1289 *filename,
1290 *md5;
1291 unsigned short port = 0;
1292 nick = next_arg(args, &args);
1293 ip = next_arg(args, &args);
1294 port = my_atol(next_arg(args, &args));
1295 filename = new_next_arg(args, &args);
1296 convertnap_unix(filename);
1297 md5 = next_arg(args, &args);
1298 if (!port)
1299 nap_say("Unable to send to a firewalled system");
1300 else
1301 {
1302 GetFile *gf;
1303 int getfd;
1304 struct sockaddr_in socka;
1305 #ifndef NO_STRUCT_LINGER
1306 int len;
1307 struct linger lin;
1308 len = sizeof(lin);
1309 lin.l_onoff = lin.l_linger = 1;
1310 #endif
1311 if (!(gf = find_in_getfile(&napster_sendqueue, 1, nick, NULL, filename, -1, -1)))
1312 {
1313 nap_say("no such file requested %s %s", nick, filename);
1314 return 0;
1315 }
1316 gf->checksum = m_strdup(md5);
1317
1318 getfd = socket(AF_INET, SOCK_STREAM, 0);
1319 socka.sin_addr.s_addr = strtoul(ip, NULL, 10);
1320 socka.sin_family = AF_INET;
1321 socka.sin_port = htons(port);
1322 alarm(get_int_var(CONNECT_TIMEOUT_VAR));
1323 if (connect(getfd, (struct sockaddr *)&socka, sizeof(struct sockaddr)) != 0)
1324 {
1325 nap_say("ERROR connecting [%s]", strerror(errno));
1326 send_ncommand(CMDR_DATAPORTERROR, gf->nick);
1327 new_free(&gf->nick);
1328 new_free(&gf->filename);
1329 new_free(&gf->ip);
1330 new_free(&gf->checksum);
1331 new_free(&gf->realfile);
1332 new_free(&gf);
1333 return 0;
1334 }
1335 alarm(0);
1336 #ifndef NO_STRUCT_LINGER
1337 setsockopt(getfd, SOL_SOCKET, SO_LINGER, (char *)&lin, len);
1338 #endif
1339 gf->socket = getfd;
1340 gf->next = napster_sendqueue;
1341 napster_sendqueue = gf;
1342 add_socketread(getfd, getfd, 0, inet_ntoa(socka.sin_addr), naplink_handleconnect, NULL);
1343 set_socketinfo(getfd, gf);
1344 write(getfd, "1", 1);
1345 }
1346 return 0;
1347 }
1348
1349 NAP_COMM(cmd_filerequest)
1350 {
1351 char *nick;
1352 Files *new = NULL;
1353 char *filename;
1354 int count = 0;
1355
1356 nick = next_arg(args, &args);
1357 filename = new_next_arg(args, &args);
1358 if (!nick || !filename || !*filename || check_nignore(nick))
1359 return 0;
1360 convertnap_unix(filename);
1361 for (new = fserv_files; new; new = new->next)
1362 {
1363 if (!strcmp(filename, new->filename))
1364 break;
1365 }
1366 if (new)
1367 {
1368 char buffer[2*NAP_BUFFER_SIZE+1];
1369 GetFile *gf;
1370 int dl_limit, dl_count;
1371 for (gf = napster_sendqueue; gf; gf = gf->next)
1372 {
1373 if (!gf->filename)
1374 {
1375 nap_say("ERROR in cmd_filerequest. gf->filename is null");
1376 return 0;
1377
1378 }
1379 count++;
1380 if (!strcmp(filename, gf->filename) && !strcmp(nick, gf->nick))
1381 {
1382 if (do_hook(MODULE_LIST, "NAP SENDFILE already queued %s %s", gf->nick, gf->filename))
1383 nap_say("%s", cparse("$0 is already queued for $1-", "%s %s", gf->nick, gf->filename));
1384 break;
1385 }
1386 }
1387 dl_limit = get_dllint_var("napster_max_send_nick");
1388 dl_count = count_download(nick);
1389 if (!get_dllint_var("napster_share") || (get_dllint_var("napster_send_limit") && count > get_dllint_var("napster_send_limit")) || (dl_limit && (dl_count >= dl_limit)))
1390 {
1391 sprintf(buffer, "%s \"%s\" %d", nick, convertnap_dos(filename), (dl_limit && dl_count >= dl_limit) ? dl_limit : get_dllint_var("napster_send_limit"));
1392 send_ncommand(CMDS_SENDLIMIT, buffer);
1393 return 0;
1394 }
1395 if (do_hook(MODULE_LIST, "NAP SENDFILE %s %s", nick, filename))
1396 nap_say("%s", cparse("$0 has requested [$1-]", "%s %s", nick, base_name(filename)));
1397 sprintf(buffer, "%s \"%s\"", nick, new->filename);
1398 send_ncommand(CMDS_REQUESTINFO, nick);
1399 send_ncommand(CMDS_FILEINFO, convertnap_dos(buffer));
1400 if (!gf)
1401 {
1402 gf = new_malloc(sizeof(GetFile));
1403 gf->nick = m_strdup(nick);
1404 gf->checksum = m_strdup(new->checksum);
1405 gf->filename = m_strdup(new->filename);
1406 if ((gf->write = open(new->filename, O_RDONLY)) < 0)
1407 nap_say("Unable to open %s for sending [%s]", new->filename, strerror(errno));
1408 gf->filesize = new->filesize;
1409 gf->next = napster_sendqueue;
1410 gf->up = NAP_UPLOAD;
1411 napster_sendqueue = gf;
1412 current_sending++;
1413 }
1414 gf->addtime = time(NULL);
1415 clean_queue(&napster_sendqueue, 300);
1416 }
1417 return 0;
1418 }
1419
1420 void napfile_sendfile(int snum)
1421 {
1422 GetFile *gf;
1423 unsigned char buffer[NAP_BUFFER_SIZE+1];
1424 int rc, numread;
1425 if (!(gf = (GetFile *)get_socketinfo(snum)))
1426 return;
1427 gf->addtime = now;
1428 numread = read(gf->write, buffer, sizeof(buffer)-1);
1429 switch(numread)
1430 {
1431 case -1:
1432 case 0:
1433 {
1434 close(gf->write);
1435 if ((gf = find_in_getfile(&napster_sendqueue, 1, gf->nick, NULL, gf->filename, -1, NAP_UPLOAD)))
1436 {
1437 if ((gf->received + gf->resume) >= gf->filesize)
1438 {
1439 double speed;
1440 char speed1[80];
1441 statistics.files_served++;
1442 statistics.filesize_served += gf->received;
1443 speed = gf->received / 1024.0 / (time(NULL) - gf->starttime);
1444 if (speed > statistics.max_uploadspeed)
1445 statistics.max_uploadspeed = speed;
1446 sprintf(speed1, "%4.2fK/s", speed);
1447 if (do_hook(MODULE_LIST, "NAP SENDFILE FINISHED %s %s %s", gf->nick, speed1, gf->filename))
1448 nap_say("%s", cparse("Finished Sending $0 [$2-] at $1", "%s %s %s", gf->nick, speed1, base_name(gf->filename)));
1449 }
1450 else if (do_hook(MODULE_LIST, "NAP SENDFILE ERROR %s %lu %lu %s", gf->nick, gf->filesize, gf->received + gf->resume, base_name(gf->filename)))
1451 {
1452 char rs[60];
1453 sprintf(rs, "%4.2g%s", _GMKv(gf->received+gf->resume), _GMKs(gf->received+gf->resume));
1454 nap_say("%s", cparse("Error sending [$2-] to $0 ", "%s %s \"%s\"", gf->nick, rs, base_name(gf->filename)));
1455 }
1456 }
1457 nap_finished_file(snum, gf);
1458 build_napster_status(NULL);
1459 send_ncommand(CMDS_UPDATE_SEND, NULL);
1460 break;
1461 }
1462 default:
1463 {
1464 rc = send(snum, buffer, numread, 0);
1465 if (rc != numread)
1466 {
1467 if (rc == -1)
1468 {
1469 if (errno == EWOULDBLOCK || errno == ENOBUFS)
1470 lseek(gf->write, -numread, SEEK_CUR);
1471 else
1472 {
1473 if ((gf = find_in_getfile(&napster_sendqueue, 1, gf->nick, NULL, gf->filename, -1, NAP_UPLOAD)))
1474 {
1475 if (do_hook(MODULE_LIST, "NAP SENDFILE ERROR %s %lu %lu \"%s\" %s", gf->nick, gf->filesize, gf->received + gf->resume, base_name(gf->filename), strerror(errno)))
1476 {
1477 char rs[60];
1478 sprintf(rs, "%4.2g%s", _GMKv(gf->received+gf->resume), _GMKs(gf->received+gf->resume));
1479 nap_say("%s", cparse("Error sending [$2-] to $0 ", "%s %s \"%s\" %s", gf->nick, rs, base_name(gf->filename), strerror(errno)));
1480 }
1481 }
1482 nap_finished_file(snum, gf);
1483 build_napster_status(NULL);
1484 send_ncommand(CMDS_UPDATE_SEND, NULL);
1485 }
1486 return;
1487 }
1488 else
1489 lseek(gf->write, -(numread - rc), SEEK_CUR);
1490 }
1491 gf->received += rc;
1492 if (!(gf->received % (10 * (sizeof(buffer)-1))))
1493 build_napster_status(NULL);
1494 }
1495 }
1496 }
1497
1498 void napfirewall_pos(int snum)
1499 {
1500 int rc;
1501 char buff[80];
1502 GetFile *gf;
1503 unsigned long pos;
1504 SocketList *s;
1505 s = get_socket(snum);
1506 if (!s || !(gf = (GetFile *)get_socketinfo(snum)))
1507 return;
1508 alarm(10);
1509 if ((rc = read(snum, buff, sizeof(buff)-1)) < 1)
1510 {
1511 alarm(0);
1512 return;
1513 }
1514 alarm(0);
1515 buff[rc] = 0;
1516 pos = my_atol(buff);
1517 gf->resume = pos;
1518 lseek(gf->write, SEEK_SET, pos);
1519 s->func_read = napfile_sendfile;
1520 napfile_sendfile(snum);
1521 }
1522
1523 void nap_firewall_start(int snum)
1524 {
1525 GetFile *gf;
1526 unsigned char buffer[NAP_BUFFER_SIZE+1];
1527 SocketList *s;
1528 s = get_socket(snum);
1529 if (!s || !(gf = (GetFile *)get_socketinfo(snum)))
1530 return;
1531 if ((read(snum, buffer, 4)) < 1)
1532 return;
1533
1534 #if 0
1535 sprintf(buffer, "%s \"%s\" %lu", gf->nick, gf->filename, gf->filesize);
1536 write(snum, convertnap_dos(buffer), strlen(buffer));
1537 #endif
1538 if (*buffer && !strcmp(buffer, "SEND"))
1539 s->func_read = napfirewall_pos;
1540 else
1541 close_socketread(snum);
1542 }
1543
1544 void napfile_read(int snum)
1545 {
1546 GetFile *gf;
1547 unsigned char buffer[NAP_BUFFER_SIZE+1];
1548 int rc;
1549 SocketList *s;
1550 s = get_socket(snum);
1551 if (!(gf = (GetFile *)get_socketinfo(snum)))
1552 {
1553 unsigned char buff[2*NAP_BUFFER_SIZE+1];
1554 unsigned char fbuff[2*NAP_BUFFER_SIZE+1];
1555 char *nick, *filename, *args;
1556
1557 alarm(10);
1558 if ((rc = read(snum, buff, sizeof(buff)-1)) < 0)
1559 {
1560 alarm(0);
1561 close_socketread(snum);
1562 return;
1563 }
1564 alarm(0);
1565 buff[rc] = 0;
1566 args = &buff[0];
1567 if (!*args || !strcmp(buff, "FILE NOT FOUND") || !strcmp(buff, "INVALID REQUEST"))
1568 {
1569 close_socketread(snum);
1570 nap_say("Error %s", *args ? args : "unknown read");
1571 return;
1572 }
1573
1574 nick = next_arg(args, &args);
1575 if ((filename = new_next_arg(args, &args)) && *filename)
1576 {
1577 strcpy(fbuff, filename);
1578 convertnap_unix(fbuff);
1579 }
1580 if (!nick || !filename || !*filename || !args || !*args
1581 || !(gf = find_in_getfile(&napster_sendqueue, 0, nick, NULL, fbuff, -1, NAP_UPLOAD))
1582 || (gf->write == -1))
1583 {
1584 memset(buff, 0, 80);
1585 if (!gf)
1586 sprintf(buff, "0INVALID REQUEST");
1587 else
1588 {
1589 sprintf(buff, "0FILE NOT FOUND");
1590 if ((gf = find_in_getfile(&napster_sendqueue, 1, nick, NULL, fbuff, -1, NAP_UPLOAD)))
1591 gf->socket = snum;
1592 }
1593 write(snum, buff, strlen(buffer));
1594 nap_finished_file(snum, gf);
1595 return;
1596 }
1597 gf->resume = strtoul(args, NULL, 0);
1598 if (gf->resume >= gf->filesize)
1599 {
1600 gf = find_in_getfile(&napster_sendqueue, 1, nick, NULL, fbuff, -1, NAP_UPLOAD);
1601 nap_finished_file(snum, gf);
1602 return;
1603 }
1604 gf->socket = snum;
1605 lseek(gf->write, SEEK_SET, gf->resume);
1606 set_socketinfo(snum, gf);
1607 memset(buff, 0, 80);
1608 sprintf(buff, "%lu", gf->filesize);
1609 write(snum, buff, strlen(buff));
1610 s->func_write = s->func_read;
1611 s->is_write = s->is_read;
1612 if (do_hook(MODULE_LIST, "NAP SENDFILE %sING %s %s",gf->resume ? "RESUM" : "SEND", gf->nick, gf->filename))
1613 nap_say("%s", cparse("$0ing file to $1 [$2-]", "%s %s %s", gf->resume ? "Resum" : "Send", gf->nick, base_name(gf->filename)));
1614 add_sockettimeout(snum, 0, NULL);
1615 set_non_blocking(snum);
1616 build_napster_status(NULL);
1617 send_ncommand(CMDS_UPDATE_SEND1, NULL);
1618 return;
1619 } else if (!gf->starttime)
1620 gf->starttime = now;
1621 s->func_read = napfile_sendfile;
1622 napfile_sendfile(snum);
1623 }
1624
1625 void naplink_handleconnect(int snum)
1626 {
1627 unsigned char buff[2*NAP_BUFFER_SIZE+1];
1628 SocketList *s;
1629 int rc;
1630 memset(buff, 0, sizeof(buff) - 1);
1631 switch ((rc = recv(snum, buff, 4, MSG_PEEK)))
1632 {
1633
1634 case -1:
1635 nap_say("naplink_handleconnect %s", strerror(errno));
1636 close_socketread(snum);
1637 case 0:
1638 return;
1639 default:
1640 break;
1641 }
1642
1643 buff[rc] = 0;
1644 if (!(s = get_socket(snum)))
1645 {
1646 close_socketread(snum);
1647 return;
1648 }
1649 if (rc == 1 && (buff[0] == '1' || buff[0] == '\n'))
1650 {
1651 read(snum, buff, 1);
1652 /* write(snum, "SEND", 4);*/
1653 s->func_read = nap_firewall_start;
1654 }
1655 else if (!strncmp(buff, "GET", 3))
1656 {
1657 /* someone has requested a non-firewalled send */
1658 read(snum, buff, 3);
1659 set_napster_socket(snum);
1660 s->func_read = napfile_read;
1661 }
1662 else if (!strncmp(buff, "SEND", 4))
1663 {
1664 /* we have requested a file from someone who is firewalled */
1665 read(snum, buff, 4);
1666 s->func_read = nap_firewall_get;
1667 }
1668 else
1669 close_socketread(snum);
1670 }
1671
1672 void naplink_handlelink(int snum)
1673 {
1674 struct sockaddr_in remaddr;
1675 socklen_t sra = sizeof(struct sockaddr_in);
1676 int sock = -1;
1677 if ((sock = accept(snum, (struct sockaddr *) &remaddr, &sra)) > -1)
1678 {
1679 add_socketread(sock, snum, 0, inet_ntoa(remaddr.sin_addr), naplink_handleconnect, NULL);
1680 add_sockettimeout(sock, 180, sendfile_timeout);
1681 write(sock, "\n", 1);
1682 }
1683 }
1684
1685