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