/* Copyright 2001 2002 Debajyoti Bera */
/* This file is part of mGet.
 * mGet is free Software; please refer to COPYING for terms and conditions */

/*-----------------------------------------------------------------------/
 * Header file for mGet: multithreaded wget
 * contains important structures for the program 
 * and included files 
 */
#ifndef __MGET_H
#define __MGET_H

#include "common.h"
#include "mgetutil.h"
#include "http_connect.h"

#include <assert.h>

/* to handle Ctrl-C signal ans write log */
#include <signal.h>
void catch_interrupt_signal(int);

#if defined(HAVE_GETOPT_LONG) || defined(HAVE_GETOPT_GETOPT_H)
#include <getopt.h>
#elif defined(HAVE_GETOPT_STDLIB_H)
#include <stdlib.h>
/*
getopt() is in POSIX, so at least it is in unistd
#else
error "getopt or getopt_long is not supported"
*/
#endif

#if defined (HAVE_GETOPT_LONG)
# define no_argument            0
# define required_argument      1
# define optional_argument      2
#endif

#if !defined(HAVE_INET_NTOP)
char *inet_ntop(int , INADDR *, char *, size_t );
#endif

#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 33
#endif

#define GET_STR \
"GET %s://%s HTTP/1.1 \r\nHOST:%s\r\nUser-Agent: mGet/"VERSION"\r\nPragma:no-cache\r\nCache-Control:no-cache\r\nAccept:*/*\r\nRange: bytes=%ld-%ld\r\n%s%s%s%sConnection:close\r\n\r\n"

#define GET_STR_NO_RANGE \
"GET %s://%s HTTP/1.1 \r\nHOST:%s\r\nUser-Agent: mGet/"VERSION"\r\nPragma:no-cache\r\nCache-Control:no-cache\r\nAccept:*/*\r\n%s%s%s%sConnection:close\r\n\r\n"

#define HEAD_STR_HTTP \
"HEAD %s://%s HTTP/1.1 \r\nHOST:%s\r\nUser-Agent: mGet/"VERSION"\r\nPragma:no-cache\r\nCache-Control:no-cache\r\nAccept:*/*\r\nRange: bytes=1-2\r\n%s%s%s%sConnection:close\r\n\r\n" 

#define HEAD_STR_FTP \
"GET %s://%s HTTP/1.1 \r\nHOST:%s\r\nUser-Agent: mGet/"VERSION"\r\nPragma:no-cache\r\nCache-Control:no-cache\r\nAccept:*/*\r\nRange: bytes=1-2\r\n%s%s%s%sConnection:close\r\n\r\n" 

//------------- Typedefs ------------------//
typedef struct sockaddr SADDR;
typedef struct sockaddr_in SADDR_IN;
typedef struct in_addr INADDR;
typedef struct hostent HOST;
typedef unsigned char byte;

//------------- Global Variables ----------//
int num_segment=1; //number of segment the file can be broken into, default 1
int proxy_port=PROXY_PORT, port=PORT; 
char *proxy=NULL;
char *file_name=NULL; //name of the file to get
char *save_file_name=NULL; //name of the file to save
char *user_name=NULL, *user_passwd=NULL, *host_name=NULL;
pthread_t *thread_id; //pointer to store thread ids
FILE *file=NULL, *outfile=NULL; 
int thread_timeout_second=60;
int RETRY_TIME=5; //retry for socket create/connect error
char *protocol; //default
char *referrer=NULL;
int rollback=0;  //rollback, default=0 ;DO U REALLY NEED TO ROLLBACK
char error_buffer[1024]={0};

//parameters
BOOL PROXY=FALSE; //default ... no proxy
BOOL PROXY_AUTH=FALSE; //default...no authorization
BOOL REFERRER=FALSE; //default no referrer
BOOL SUPPORT_RESUME=TRUE; //default, support resume
BOOL HAS_LENGTH=TRUE; //default file length is returned
BOOL PROTO_HTTP=TRUE; //default protocol: HTTP
BOOL VERBOSE=FALSE; //how much to babble :)
BOOL USE_HTTP_CONNECT=FALSE; //use connect protocol in HTTP

int curr_threads=0;
pthread_mutex_t thread_done_mutex;
pthread_cond_t thread_done_cond;
pthread_mutex_t file_mutex;

SOCKET s; //primary socket
SADDR_IN saddr;
/* HOST *host; */

//------------- Structures ----------------//
struct request{
	long size_file;
	char *version; //HTTP version of server, actually 9 fields
	int status_code; //status-code of file
}; //contains the informations for a request
typedef struct request REQUEST;

struct present_page{
	unsigned int page_id; //maybe needed to identify a page
	long size_total; //total size: reduntant
	long range_start; //start byte
	long range_end; //end byte
	long range_size; // range size: reduntant
	SOCKET sock; //thread socket
	long present_seek_pos; //present lseek position
	long present_read_pos; //present position till which file is read
}; //contains the information for the present page
typedef struct present_page PPAGE;

//error codes
#define ERR_M_OK 0
#define ERR_M_SOCKERR -1 //socket create error
#define ERR_M_CONNERR -2 //connect error
#define ERR_M_TIMEOUT -3 //timeout

#define SIZE_PER_SEGMENT 10240
#define ALLOWANCE 1024

//------------- Function Declarations ------//
void print_usage(); //prints usage information and exits
void get_options(int , char **); //get the options
void err_exit(char *, int, SOCKET); //print error,process by option and exit
void init_socket(); //initialize the main sock
int get_head(REQUEST *); //get the header for this request
void get_name_passwd(void); //get the user name and password
void process_thread(REQUEST *); //start the threads for the request
void* start_thread(void *); //function on each thread
int start_thread_sock(PPAGE *); //thread socket function
int get_thread_request(PPAGE *); //thread specific download routine
inline int do_timeout(PPAGE *); //code to handle timeout
inline void print_segments(); //to print individual segment status and values
int check_file_segment_num(int, int); //checks if the number of segment is not too large
/* writing log for resuming later */
void write_log_file(FILE *);
void read_log_file(char *);
void cleanup(); /* maybe any cleanup function */

REQUEST main_request;
PPAGE *ppage;
char *sep="+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";//separator string
/*char *info="
        ------------ mGet - "VERSION"--------------\n
	----------------- Made by -----------------\n
	-------- Arindam Chakraborty 98071 --------\n
	-------- Ashutosh Kumar      98091 --------\n
	-------- Chinmoy Dutta       98115 --------\n
	-------- Debajyoti Bera      98117 --------\n
	----- as a part of Assignment #1, CS425 ---\n";	
*/

#endif

//----------- end of mget.h --------------//	


syntax highlighted by Code2HTML, v. 0.9.1