Logo Search packages:      
Sourcecode: dctc version File versions  Download package

gdl.h

/* DCTC - a Direct Connect text clone for Linux
 * Copyright (C) 2001 Eric Prevoteau
 *
 * gdl.h: Copyright (C) Eric Prevoteau <www@a2pb.gotdns.org>
 *
 * 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 2 of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
/*
$Id: gdl.h,v 1.8 2003/12/28 08:12:38 uid68112 Exp $
*/

#ifndef __GDL_H__
#define __GDL_H__

#ifdef WITH_GCRYPT
#include <gcrypt.h>
#ifndef MD4_DIGEST_LENGTH 
#define MD4_DIGEST_LENGTH 16
#endif
#else
#include <openssl/md4.h>
#endif

typedef struct
{
      GString *nickname;
      GString *remote_fname;
      off_t remote_fsize;

      GString *temp_local_fname;
      off_t range[2];   /* start position (included) and end position (excluded) in the file (valid when is_allocated==1) */
      off_t cur_dled;   /* number of bytes downloaded since the beginning of the range (valid when is_allocated==1) */
      
      time_t last_start_time;
      pthread_t thread_id;                /* if is_started==1, this is the thread_id of the download thread */

      unsigned int is_running:1;    /* set to 1 when GDL sends the download command, */
                                                            /* last_start_time is initialized at this time */
                                                            /* this means we have made a download request */

      unsigned int is_started:1;    /* set to 1 when the xfer begins (== when /GDLSTART is received) */
                                                            /* when set to 1, is_running is already set to 1 */
                                                            /* a range have been initialized */
} GDL_DL_ENTRY;

typedef struct
{
      time_t last_scan;                   /* time this entry has been used for the last time */
      unsigned long gae_id;         /* id of this entry. This id is uniq for on GDL */
      gchar *search_pattern;        /* pattern to use in the search request */
                                                            /* the pattern is the 1 character file type, '?', pattern to search */
} GDL_AS_ENTRY;

typedef struct
{
      unsigned int gdl_id;                /* it is a uniq ID identifying this GDL */
      time_t start_time;                  /* date of creation of this GDL */
      off_t dl_offset;                    /* to avoid erroneous speed computation, this var contains the number of */
                                                            /* already downloaded bytes (0 for create, -xxx for an attach */
      int lock_fd;                              /* it is the fd of the .lock file of this gdl */
      unsigned int is_completed;    /* this flag is set to 0 until all parts of the file have been downloaded */
                                                            /* when ==1, all parts are here, gathering in progress (or soon start) */
                                                            /* if ==2, there is an internal error, this GDL is dead and will remain as is */
      GString *local_fname;         /* it is the name of the local file after download (when fragments are gathered) */
                                                            /* After GDL creation, this variable cannot be modified */

      GString *post_fname;                /* these 2 variables contains the final filename and the final directory, after fragment gathering */
      GString *post_dir;                  /* unlike local_fname, they can be altered at any time, even during fragment gathering */

      GString *at_end_script;       /* these variable contains the name of a program (script or real program) to start at the end */
                                                            /* of GDL */

      gboolean has_crc;                   /* if TRUE, ed2k_crc is populated */
      guint8 ed2k_crc[MD4_DIGEST_LENGTH];

      guint8 *ed2k_partial_crc;     /* MD4_LENGTH*((total_size+PARTSIZE-1)/PARTSIZE) bytes */
      guint nb_partial_crc_seg;     /* only valid if ed2k_partial_crc!=NULL. =((total_size+PARTSIZE-1)/PARTSIZE) */

      off_t total_size;
                                                            /* length of the file to download */
      GPtrArray *gdl_links;         /* it is an array of all known nicks from where we (can) download */
                                                            /* each pointer points on a GDL_DL_ENTRY */
      GArray *dld_ranges;                 /* list of all downloaded ranges with their filename */
                                                            /* it is a sorted list of RANGE_ENTRY */

      unsigned long cur_spd;        /* this is the number of bytes downloaded in the previous 10 seconds range */
      unsigned long instant_spd;    /* this is the number of bytes already download in the current 10 seconds range */

      int autoscan_sockfd;                /* =-1 as long as autoscan is empty. When autoscan [has] contain[s|ed] something it is an UDP socket */
      unsigned short autoscan_sock_port;  /* port number used by the following socket, only valid when autoscan_sockfd!=-1 */
      GArray *autoscan;                   /* it is a list of pattern regularly used to perform automatic research and add new sources */
                                                            /* each entry  is a GDL_AS_ENTRY */
} GDL_ENTRY;

typedef struct
{
      GString *temp_local_fname;          /* name of the temporary filename associated here */
      off_t range[2];                           /* start position and end position in the file */
} RANGE_ENTRY;

/**********************************************************/
/* create the GDL thread. On error, program is terminated */
/**********************************************************/
void start_gdl_thread(void);

/* -------------------------------------------------------------------------- */
/**************************************************************/
/* the following functions are called using keyboard commands */
/**************************************************************/

/*******************************************/
/* create a new GDL_ENTRY inside gdl_array */
/*******************************************/
/* output: 0= success                  */
/*         1=gdl with same name exists */
/*         2=gdl with same idx exists  */
/***************************************/
int do_gdl_new(unsigned int gdl_id, char *local_filename, unsigned long int total_size);

/**********************************************************************/
/* try to attach an unused GDL named "filename" to the current client */
/**********************************************************************/
void do_gdl_attach(char *filename);

/***************************************/
/* detach a running GDL of this client */
/***************************************/
int do_gdl_detach(unsigned int gdl_id);

/*********************************************/
/* add a new GDL_DL_ENTRY inside a GDL_ENTRY */
/*********************************************/
/* output: 0= success, !=0: error */
/**********************************/
int do_gdl_add(unsigned int gdl_id, char *nickname, char *remote_fname,unsigned long int remote_fsize);

/********************************************/
/* delete a GDL_DL_ENTRY inside a GDL_ENTRY */
/********************************************/
/* output: 0= success, !=0: error */
/**********************************/
int do_gdl_del(unsigned int gdl_id, char *nickname, char *remote_fname);

/***********************************/
/* delete a GDL_ENTRY of gdl_array */
/********************************************************************************/
/* input: override must always be ==0. The only case where it is !=0 is when    */
/*        the GDL thread call this function after successfully gather all parts */
/*        of the downloaded files.                                              */
/********************************************************************************/
/* output: 0= success, !=0: error */
/**********************************/
int do_gdl_end(unsigned int gdl_id, int override);

/***********************************************/
/* add a new autoscan pattern to the given GDL */
/***********************************************/
void do_gdl_as_add(unsigned int gdl_id, int filetype, char *pattern);

/***********************************************/
/* remove an autoscan pattern to the given GDL */
/***********************************************/
void do_gdl_as_del(unsigned int gdl_id, unsigned long gae_id);

/****************************************************/
/* change the final filename [and dirname] of a GDL */
/*********************************************************************/
/* if dirname == "", only filename is altered                        */
/* if both filename and dirname == "", the file renaming is disabled */
/*********************************************************************/
void do_gdl_rename(unsigned int gdl_id, char *filename, char *dirname);

/***************************************************************/
/* change the name of the program to start at the end of a GDL */
/***************************************************************/
/* if filename is NULL or == "", the file renaming is disabled */
/***************************************************************/
void do_gdl_script(unsigned int gdl_id, char *programname);

/***************************/
/* set or remove a GDL crc */
/**************************************************************************/
/* if md_crc==NULL, the CRC is removed                                    */
/* if md_crc!=NULL, it is a CRC stored in a MD4_DIGEST_LENGTH byte buffer */
/**************************************************************************/
void do_gdl_set_crc(unsigned int gdl_id, guint8 *md_crc);

/************************************************************/
/* call this function to update already existing socket TOS */
/************************************************************/
void gdl_alter_socket_tos(void);

/* -------------------------------------------------------------------------- */
/*************************************************************************/
/* the following functions are used by the standard download function to */
/* return status of transfert.                                           */
/*************************************************************************/

/********************************************************************/
/* this function is called when a GDL download fails                */
/* this works when a request has been made but has never started    */
/* this can occurs either if another xfer is still in progress with */
/* the given user or either because it never replies to request     */
/********************************************************************/
void do_gdl_abort(unsigned int gdl_id, char *nickname);

/**************************************************************************/
/* this function is called when a queued GDL download has a download slot */
/**************************************************************************/
/* output: 0= a range has been assigned */
/*        !=0 no range available        */
/******************************************************************/
/* if a range is assigned, *str is contains the $Get line to send */
/* and *lfile contains the name of the local filename and         */
/* *start_pos is the download start position (for information)    */
/******************************************************************/
int do_gdl_start(unsigned int gdl_id, char *nickname, pthread_t thread_id, GString **str,GString **lfile, unsigned long *start_pos);

/******************************************************************************/
/* this function is called when a GDL download fails but after a do_gdl_start */
/******************************************************************************/
/* if is_fatal is set, this GDL_DL_ENTRY is discarded */
/******************************************************/
void do_gdl_fail(unsigned int gdl_id, char *nickname, char *local_fname, int is_fatal);

/*****************************************************************/
/* this function is called when a GDL download successfully ends */
/* if the remote client is standard, there is no way to start another */
/* segment, this entry must released because the thread will die */
/*****************************************************************/
void do_gdl_success(unsigned int gdl_id, pthread_t ptid, int with_end);

/***********************************************************************************/
/* update the number of bytes downloaded since the beginning of the DL_ENTRY range */
/* at the same time, compute the number of bytes we can download (max: 8192 bytes) */
/* when nothing can be downloaded, return 0                                        */
/***********************************************************************************/
unsigned int gdl_get_amount(unsigned int gdl_id, pthread_t ptid, unsigned long total_pos);

/******************************/
/* display the GDL quick list */
/******************************/
void do_gdl_qlst(int sck);

/*****************************/
/* display the GDL long list */
/*****************************/
void do_gdl_lst(int sck);

/*********************************************************************************************************/
/* modify the timeout of waiting GDL sources having the given nickname to force them to retry immediatly */
/*********************************************************************************************************/
void gdl_wake_up_sources(char *nickname, int without_lock);

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* ------------------ GDL with erroneous CRC support ------------------------ */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#define MIN_DELAY_BETWEEN_2_ED2K_CRC_QUERY 600

typedef struct
{
      unsigned int broken_gdl_id;               /* it is a uniq ID identifying this GDL */

      GString *local_fname;         /* it is the name of the local file after download (when fragments are gathered) */
                                                            /* After GDL creation, this variable cannot be modified */
      guint8 ed2k_crc[MD4_DIGEST_LENGTH];

      off_t total_size;
                                                            /* length of the file to download */
      int locked_crc_file_fd;

      /* we periodically try to obtain the partial CRC */
      time_t last_attempt;
      guint8 *ed2k_partial_crc;

} BROKEN_GDL_ENTRY;

/*******************************************************************/
/* check inside the broken GDL list if a GDL match the given value */
/*******************************************************************/
void incoming_partial_md(const guint8 *g_crc, off_t total_size, const guint8 *partial_crc, guint32 partial_size);

/* -------------------------------------------------------------------------- */
/* ---------------------------- MET file support ---------------------------- */
/* -------------------------------------------------------------------------- */

/****************************************************************/
/* set the time in minutes between 2 scans of the met directory */
/****************************************************************/
void set_met_scan_interval(int duration);

/*******************************************/
/* set the directory containing .met files */
/*******************************************/
void set_met_dir(const char *dirname);

/**************************************/
/* get the current .met scan interval */
/**************************************/
int get_met_scan_interval(void);

/***********************************************/
/* get the current .met dir (must not be free) */
/***********************************************/
const GString *get_met_dir(void);

/********************************************/
/* display GDL met variables in VAR message */
/********************************************/
void disp_met_vars(void);

#endif

Generated by  Doxygen 1.6.0   Back to index