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