/* -*- c -*-
 *
 * Author:      James Brister <brister@vix.com> -- berkeley-unix --
 * Start Date:  Wed Nov 29 23:44:47 1995
 * Project:     INN (innfeed)
 * File:        misc.h
 * RCSId:       $Id: misc.h,v 1.10 1996/08/20 13:40:12 brister Exp $
 *
 * Copyright:   Copyright (c) 1996 by Internet Software Consortium
 *
 *              Permission to use, copy, modify, and distribute this
 *              software for any purpose with or without fee is hereby
 *              granted, provided that the above copyright notice and this
 *              permission notice appear in all copies.
 *
 *              THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE
 *              CONSORTIUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 *              SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *              MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET
 *              SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
 *              INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *              WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 *              WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 *              TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
 *              USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Description: 
 * 
 */

#if ! defined ( misc_h__ )
#define misc_h__

#include "config.h"

#include <sys/types.h>

#if defined (DO_NEED_BOOL)
typedef enum { false = 0, true = 1 } bool ;
#endif


/* These typedefs are all here because C is too stupid to let me multiply
   define typedefs to the same things (as C++ will). Hence I can't redeclare
   the typedefs to get around recursive header file includes (like host.h and
   connection.h would need if they contained their own typedefs). */

typedef struct article_s *Article ;             /* see article.h */
typedef struct buffer_s *Buffer ;               /* see buffer.h */
typedef struct commander_s *Commander ;         /* see commander.h */
typedef struct config_s *Config ;               /* see config.h */
typedef struct connection_s *Connection ;       /* see connection.h */
typedef struct endpoint_s *EndPoint ;           /* see endpoint.h */
typedef struct host_s *Host ;                   /* see host.h */
typedef struct innlistener_s *InnListener ;     /* see innlistener.h */
typedef struct tape_s *Tape ;                   /* see tape.h */

typedef int TimeoutId ;                         /* see endpoint.h */
typedef enum {                                  /* see endpoint.h */
  IoDone, IoIncomplete, IoFailed, IoEOF
} IoStatus ; 

typedef void (*EndpRWCB) (EndPoint e,           /* see endpoint.h */
                          IoStatus i, Buffer *b, void *d) ;
typedef void (*EndpTCB) (TimeoutId tid, void *d) ; /* see endpoint.h */
typedef void (*EndpWorkCbk) (EndPoint ep, void *data) ;


#if defined (DO_NEED_U_INT)
typedef unsigned long u_long ;
typedef unsigned int u_int ;
typedef unsigned short u_short ;
#endif

/* debugging information */
extern char *program ;
extern u_int loggingLevel ;     /* if 0 then dprintf is a no-op */

/* the current count of file desccriptors */
extern u_int openfds ;

/* return the maximum number of fds this process can have. */
int maxFds (void) ;

/* if level <= loggingLevel then print */
void dprintf (u_int level, const char *fmt, ...) ;

/* for the gethostbyname() error code */
const char *host_err_str (void) ;

/* parse a reponse line into it's code and body. *rest will end up pointing
   into the middle of p */
bool getNntpResponse (char *p, int *code, char **rest) ;

/* parse out the first field of a nntp response code as a message-id. Caller
   must free the return value when done. */
char *getMsgId (const char *p) ;

/* pick out the next non-blank string inside PTR. TAIL is set to point at
   the first blank (or NULL) after the string. Returns a pointer into PTR */
char *findNonBlankString (char *ptr, char **tail) ;


/* print the arguments like printf to stderr then abort() */
void die (const char *fmt, ...) ;

/* print the arguments like printf to stderr. */
void warn (const char *fmt, ...) ;

/* return true of the file exists and is a regular file */
bool fileExistsP (const char *filename) ;

/* return true if file exists and is a directory */
bool isDirectory (const char *filename) ;

char *mystrtok (char *string, const char *sep) ;

/* remove trailing whitespace */
void trim_ws (char *string) ;

#if defined (DO_NEED_STRDUP)
char *strdup (const char *s) ;
#endif

/* locks the peer and returns true or returns false */
bool lockPeer (const char *peerName) ;

/* return true if the end of string matches tail. */
bool endsIn (const char *string, const char *tail) ;

/* scribble over then free up the null-terminated string */
void freeCharP (char *charp) ;

/* append the contents of src to dest. src is removed if append if
   successful */
bool appendFile (const char *dest, const char *src) ;

/* return the length of the file reference by the given file descriptor */
long fileLength (int fd) ;

bool lockFile (const char *fileName) ;
void unlockFile (const char *lockfile) ;


/* return true if file1 is older than file2 */
bool isOlder (const char *file1, const char *file2) ;

  /* lives in main.c */
void getHostDefaults (u_int *articleTout, u_int *respTout, u_int *initialCxns,
                      u_int *maxCxns, u_int *maxChecks, bool *streaming,
                      double *lowFilter, double *highFilter,
                      u_short *portNum) ;


const char *boolToString (bool val) ;

#define ASSERT(x) do{if (!(x))die("%s in file %s line %d\n",#x,__FILE__,__LINE__);}while(0)

#define INDENT_INCR 5
#define INDENT_BUFFER_SIZE 80
#if ! defined (MIN)
#define MIN(A,B) ((A) < (B) ? (A) : (B))
#endif

#endif /* misc_h__ */
