/*
 *   Copyright 1995 Peter Scott  (OZ2ABA/OZ7SAT)
 *              All Rights Reserved
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 1, or (at your option)
 *   any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

/*
	filerequest.c

	Request a file from the satellite. Controls the pb program
*/

#define VERSION_STRING "(version 1.0 by oz2aba)"

#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>
#include <strings.h>

#include "pb.h"
#include "request.h"


char	UDPPort [100];
int	UdpPort = 5100;
char	Id [100];

int sock;
struct sockaddr_in loc_addr;
struct sockaddr_in rem_addr;
struct request request;

/* Download files control structures */
unsigned long download_list [MAXDOWNLOAD];

unsigned long fileId = 0xFFFFFFFF;

int main(int argc, char **argv)
{
	int 		n;

	FILE		*paramf;
	char		s1[100], s2[100];

	FILE		*fp;
	unsigned long	l;
	int		x;

	/* Read the parameter file pb.conf */
	if ((paramf = fopen ("pb.conf", "r")) == NULL) {
		perror ("bp.conf fopen");
		exit (1);
	}

	while (! feof (paramf)) {
		fscanf (paramf, "%100s %100s\n", s1, s2);

		if (! strcmp (s1, "UDPPORT"))    {strcpy (UDPPort,    s2); continue;}
	}
	fclose (paramf);

	/* Process command line options */
	for (n = 1; n < argc; n++) {
		if (! strcmp (argv [n], "-U")) {strcpy (UDPPort,    argv [++n]); continue;}

		/* Unprefixed parameter. This is the requested FileID */
		strcpy (Id, argv [n]);
	}

	/* Convert UDPPort to a number */
	if (UDPPort [0] != '\0') {
		UdpPort = atoi (UDPPort);
		if (UdpPort < 1024) UdpPort = 5100;
	}


	/* setup to talk to pb */
	memset((char *)&loc_addr, 0, sizeof(rem_addr));
	loc_addr.sin_family      = AF_INET;
	loc_addr.sin_addr.s_addr = INADDR_ANY;
	loc_addr.sin_port        = htons(0);

	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
	{
		perror("socket");
		return (1);
	}

	if (bind(sock, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) == -1)
	{
		perror("bind");
		return (1);
	}

	memset((char *)&rem_addr, 0, sizeof(rem_addr));
	rem_addr.sin_family      = AF_INET;
	rem_addr.sin_port        = htons(UdpPort);
	rem_addr.sin_addr.s_addr = htonl(0x7f000001);

	request.type = REQ_TYPE_REFILE;
	sscanf(Id, "%lx", &fileId);

	/* ???? Check if this file exist in the directory */

	/* Read the download.req file and check if the wanted file exist */

	fp = fopen ("download.req", "r+");
	if (fp == NULL) {		/* No download file. Abort */
		printf ("download.req control file does not exist\n");
		exit (1);
	}

	fread (download_list, sizeof (unsigned long), MAXDOWNLOAD, fp);
	if (ferror (fp)) {			/* Error reading. Abort */
		printf ("Error reading download.req\n");
		exit (1);
	}

	/* Check if the requested file exist in the list */
	for (x = 0; x < MAXDOWNLOAD; x++) {
		if (download_list [x] == fileId) {
			/* The file is allready in the list */
			printf ("The file %lx has allready been requested\n",
			        fileId);
			fclose (fp);
			exit (0);
		}
	}

	/* The request does not exist. Find a empty slot */
	for (x = 0; x < MAXDOWNLOAD; x++) {
		if (download_list [x] == 0xFFFFFFFF) break;
	}
	if (download_list [x] != 0xFFFFFFFF) {
		printf ("Not space for more requests\n");
		fclose (fp);
		exit (10);
	}

	/* Set the entry in the list and the file */
	download_list [x] = fileId;
	l = sizeof (unsigned long) * x;
	fseek (fp, l, SEEK_SET);
	fwrite (&download_list [x], sizeof (unsigned long), 1, fp);
	if (ferror (fp)) {		/* Error writing to file */
		printf ("Error writing to download.req file\n");
		fclose (fp);
		exit (1);
	}
	fclose (fp);


	/* Notify the user */
	printf ("File %lx requested\n", fileId);

	if (sendto(sock, (char *)&request, sizeof(struct request), 0, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) == -1)
		printf ("pb is not listening\n");

	return (0);		/* Return OK */
}
