
#define MAX_FEED 100
#define MAX_DBN 10000


typedef struct Flink {
	int id;
	Chan *chan;
	struct QUE *que;
	struct QUE *cur;
	char in[BFSZ];
	char outbf[BFSZ];
	char rest[BFSZ];
	int outlen;
	int inlen;
	int sendtake;
	int stream;
	int sendat;
	int state;
	int nque;
	int nretry;
	int wait;
	int lastoffset;
	time_t lastdata;
	int last_len;
	char *last_data;
	char last_mid[BFSZ];
	int ihave;
	struct Flink *next;
	struct FEED *feed;
} Flink;

typedef struct FEED {
	char *site,*to,*bind;
	char problem[300];
	char reason[300];
	int ndup,nrej,nok,ndel,nlater,nscan;
	double nbytes;
	int islog;
	FILE *flog;
	FILE *fscan;
	int nchan;
	int n;			/* this feed entry in array */
	int time_retry;
	int len;
	int fid;
	int trycompress;
	int udp_speed,udp_ttl,isudp;
	char *in;
	Flink *links;
} Feed;

typedef struct QUE {
	char *mid;
	int datalen;
	int nref;
	int state;
	int spool,bkt,offset,len,pile;
	int ntries;
	time_t tread;
	struct QUE *next;
} Que;

typedef struct SORT {int site; char *mid; int bkt, offset, len,spool,item,pile ;   } Sort;
void feeds_read_line(Chan *c, Feed *f, Flink *l,char *datax);

void link_que_trim(Flink *l);
int feeds_free(void);
void que_show(Flink *l);;
void feeds_read_udp(Chan *c, void *p);
void feeds_write_udp(Chan *c, void *p1);
int feed_find(char *s);
char *file_bque_tmp(int n);
void que_trim(void);
int que_read_more(int bkt, Feed *f);
char *file_bkt(char *site);
int feeds_load(void);
void feeds_idle_open(void);
void feeds_status(FILE *fout);
int bkt_nwaiting(Feed *feed);
void que_read_free(void);
void link_ifempty(Flink *l);
void feeds_scan_upto(Feed *feed);
void stats_reset(void);

int feeds_load(void);
void feeds_read(Chan *c, void *p1);
void feeds_write(Chan *c, void *p1);
void feeds_idle(void);
void feeds_read(Chan *c, void *p);
void feeds_read_line(Chan *c, Feed *f, Flink *l, char *data);
void link_send(Flink *l);
void feeds_read_sending(Chan *c, Feed *f, Flink *l, char *status);
void feeds_idle_10(void);
void feeds_scan(Feed *feed);
int sendque_add(int site, char *mid, int spool, int bkt, int offset, int len, int pile);
void link_que_fill(Flink *l);
int read_cmp(const void *aa, const void *bb);;
int que_read(int bkt, int feed);
int feeds_load_site(char *site, char *to, char *bind, int nchan, int islog, int uspeed,  int uxxx, int trycompress);
void feeds_read(Chan *c, void *p1);
void que_append(Que **x, Que *xn);
FILE *bfile_open(Que *q);

char *que_get(Que *entryx, int from, int *got, int *total, Feed *f);
void bkt_add(Feed *feed,int bkt, int npend, int isset);
int bkt_find(Feed *feed);
void bkt_reque(Que *q, Feed *f);

void link_sendmore(Flink *l);

Que *link_que_remove(Flink *l, char *mid);
void link_rej(Flink *l, char *mid);
void link_takethis(Flink *l, char *mid);
void link_later(Flink *l, char *mid);
void link_rej(Flink *l, char *mid);
void link_ok(Flink *l, char *mid);
void link_ihave_rej(Flink *l);
void link_ihave_send(Flink *l);
void link_ihave_rej(Flink *l);
void link_ihave_ok(Flink *l);
void link_paused(Flink *l);
Que *link_que_find(Flink *l,char *mid);

void link_close(Flink *l,char *reason);
void link_add_msg(Flink *l,Que *q);
int link_isfull(Flink *l);

void link_ihave_dup(Flink *l);
void link_dup(Flink *l, char *mid);

void links_free(Flink *l);
void fque_free(Flink *l);
void pending_free(void);
void sendque_free(void);
void pending_free_data(Que *q);
void feeds_exit(void);

void fid_load(void);
int fid_findadd(char *name, int feed);
int fid_to_feed(int fid);
void bkt_deleted(int bkt);
int feeds_handles(void);
void udp_idle(void);
void imsg_feed(Feed *f, int xid);
void imsg_flush(void);
void imsg_open(void);
void imsg_flog(FILE *flog, char *s);
Que *link_que_find_state(Flink *l,int state);

char *feed_read_upto(Feed *f);
void feed_write_upto(Feed *f,char *mid);
void que_free(Que *q);
void feed_reque(Que *q, Feed *feed);
void pending_release(Que *q, Feed *f);

int send_read(FILE *f, char *mid, int *bkt, int *offset, int *len, int *spool, int *pile, int *ntries);
Que *link_next(Flink *l);
char *file_sendupto(char *site);