/***************************************
					$Header$

					
***************************************/


#ifndef UTIL_H
#define UTIL_H    /*+ To stop multiple inclusions. +*/

/* mem.c */

#include <malloc.h>
#include <stdio.h>

void * 
pcalloc1(size_t,size_t,const char *);

void * 
pcalloc2(size_t,size_t,size_t,size_t,const char *);

int 
pfree1(void *);

int 
pfree2(void **);

int 
r_mem1(void **,void **,void **,int,const char *);

int
l_str1(char **,char **,char **,const char *,...);

int
l_mem1(char **,char **,char **,const void *,size_t);

#define mem(a,b) do {\
if (!((a)=pcalloc1((b),sizeof(*(a)),# a))) \
errret("Cannot mem %s to %d\b",(# a),(b));\
} while(0)

#define mem2(a,b,c) do {\
if (!((a)=pcalloc2((b),sizeof(*(a)),(c),sizeof(**(a)),# a))) \
errret("Cannot mem %s to %d, %d\b",(# a),(b),(c));\
} while(0)

#define emem(a,b) do {\
if (a) pfree1(a); \
mem(a,b);\
} while (0)

#define emem2(a,b,c) do {\
if (a) pfree2(a);\
mem2(a,b,c);\
} while(0)

#define r_mem(a,b) \
r_mem1((void **)&(a ## 1),(void **)&(a),(void **)&(a ## e),(b)*sizeof(*(a ## 1)),(# a))

#define l_str(a,b,c...) \
l_str1((char **)&(a ## 1),(char **)&(a),(char **)&(a ## e),(b) , ## c)

#define l_mem(a,b,c) \
l_mem1((void **)&(a ## 1),(void **)&(a),(void **)&(a ## e),(b),(c))


/* sock.c */

typedef struct msock {
  int s;
  char *v1,*v,*vi,*vz,*ve;
  void *ssl;
  char *ip1,*ip,*ipe;
  unsigned port,do_ssl;
  int (*done)(struct msock *);
} Sock;

int
socks_init(Sock *,Sock *,const char *,unsigned short,int (*)(Sock *));

int
socks_process(Sock *,Sock *);

/* err.c */

extern void (*my_err)(const char *,const char *,int,const char *,...);

void
std_err(const char *,const char *,int,const char *,...);

#define err(a,b...) my_err(__FILE__,__FUNCTION__,__LINE__, a , ## b)
#define inf(a,b...) my_err(NULL,NULL,0, a , ## b)

#define errret(a,b...) do {err(a,##b);return -1;} while(0)
#define errretv(a,b,c...) do {err(b,##c);return a;} while(0)
#define error(a,b...) do {err(a,##b);exit(-1);} while(0)

/* map.c */

typedef struct {
  void *m1,*m,*me;
  int l,ro;
  unsigned o,size;
  const char *n;
} Map;

extern __inline__ int
map_open(Map *,const char *,int);

#define map_true(a) map_get((a),(a)->o,(a)->o+(char *)(a)->m-(char *)(a)->m1)
extern __inline__ int
map_get(Map *,unsigned,unsigned);

#define map_write_array(a,b)   map_write(a,b,sizeof(b))
#define map_write_string(a,b)  map_write(a,b,strlen(b)+1)
#define map_write_element(a,b) map_write(a,&b,sizeof(b))
#define map_write_gen(a,b)     map_write(a,g.v,g.w)
extern __inline__ int
map_write(Map *,const void *,unsigned);

extern __inline__ int
map_close(Map *);

char *
map_temp_str(const char *,...);

extern __inline__ int
map_fgets(Map *,FILE *);




#endif /* UTIL_H */
