#ifndef _SYS_
#define _SYS_

/* System-wide includes, 'cuz I'm too lazy to repeat them throughout
 * the entire source tree.
 */

// C
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <netdb.h>
#include <regex.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>

#ifdef INADDR_NONE
#   define HAVE_INADDR_NONE
#else
#   define INADDR_NONE 0xffffffff
#endif

// C++
#include <exception>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#include <queue>

/* Profiling support on/off */
#ifdef PROFILER
#   define PROFILE(x) Profiler local_prof(x)
#else
#   define PROFILE(x)
#endif

/* Memory debugging on/off */
#ifdef MEMDEBUG
#   define MEM(x) x
#else
#   define MEM(x)
#endif

/* If you fear that your malloc() / realloc() may have threading problems,
 * uncomment the following. It will cause mutex locks around the calls. */
// #define MISTRUST_MALLOC_THREADSAFE

/* If you fear racing conditions in thread_create() then uncomment this.
 * BTW it would be really weird if thread_create() weren't thread-safe., so
 * defining this is very likely not necessary. */
// #define MISTRUST_THREAD_CREATE_THREADSAFE

using namespace std;

// This we need locally for msg(), debugmsg()
#include "mstr/mstr"
// This is for the Servertype of serversocket()
#include "servertype/servertype"

/* Messaging. Conditionals are defined as a macro to speed things up. */
void _msg (Mstr const &s);
#define msg(x) if(config.verbose()) _msg(x)
void _debugmsg (Mstr const &s);
#define debugmsg(x) if (config.debug()) _debugmsg(x)
void reportmsg (Mstr const &s);
void warnmsg (Mstr const &s);
void anymsg(Mstr const &s, ostream &o, string const &label);

/* Other */
int serversocket (string addr, int port, string description,
		  Servertype::Type t);
bool ipmatch (struct in_addr addr, struct in_addr mask);
void socketclose (int fd);
vector<string> str2parts (string const &s, char sep);
void mt_srand(unsigned long s);
unsigned long mt_rand(void);
bool check_acl(string const &ipstr, struct in_addr ipaddr);
int sysrun (string const &s);
int maxtimeout(int a, int b);

#ifndef HAVE_INET_ATON
int inet_aton (char const *name, struct in_addr *addr);
#endif

#ifndef HAVE_STRNSTR
char *strnstr (char const *s, char const *find, size_t slen);
#endif

#endif
