#include "config.h"
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "channel.h"
#include <time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <fcntl.h>
#include "h.h"
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#ifdef _WIN32
#include "version.h"
#endif

#define RPL_IRCOPS                337
#define RPL_ENDOFIRCOPS                338
#define MSG_IRCOPS                 "IRCOPS"
#define TOK_IRCOPS                 "IO"
#define MyMod                        ModIrcops->handle
#define IsAway(x)                (x)->user->away
#define IsSkoAdmin(sptr)        (IsAdmin(sptr) || IsNetAdmin(sptr) || IsSAdmin(sptr) || IsCoAdmin(sptr))
#define DelCommand(x)                if (x) CommandDel(x); x = NULL

static Command                        *AddCommand(char *msg, char *token, int (*func)());
DLLFUNC int                        m_ircops(aClient *cptr, aClient *sptr, int parc, char *parv[]);

ModuleInfo                        *ModIrcops;
Command                                *CmdIrcops;

#ifndef DYNAMIC_LINKING
ModuleHeader m_ircops_Header
#else
#define m_ircops_Header Mod_Header
ModuleHeader Mod_Header
#endif
  = {
        "ircops",
        "$Id: m_ircops.c,v 2.3 2003/12/01 11:46:08 Salazar Exp $",
        "command /ircops",
        "3.2-b8-1",
        NULL
    };


/* The purpose of these ifdefs, are that we can "static" link the ircd if we
 * want to
*/

/* This is called on module init, before Server Ready */
#ifdef DYNAMIC_LINKING
DLLFUNC int        Mod_Init(ModuleInfo *modinfo)
#else
int    m_ircops_Init(ModuleInfo *modinfo)
#endif
{
        ModIrcops        = modinfo;
        CmdIrcops        = AddCommand(MSG_IRCOPS, TOK_IRCOPS, m_ircops);

        if (!CmdIrcops)
                return MOD_FAILED;

        return MOD_SUCCESS;
}

/* Is first run when server is 100% ready */
#ifdef DYNAMIC_LINKING
DLLFUNC int        Mod_Load(int module_load)
#else
int    m_ircops_Load(int module_load)
#endif
{
        return MOD_SUCCESS;
}


/* Called when module is unloaded */
#ifdef DYNAMIC_LINKING
DLLFUNC int        Mod_Unload(int module_unload)
#else
int        m_ircops_Unload(int module_unload)
#endif
{
        DelCommand(CmdIrcops);

        return MOD_SUCCESS;
}

typedef struct
{
        unsigned long        *umode;
        char                *text;
} oflag;

static oflag otypes[] =
{
        { &UMODE_NETADMIN,                "Network Administrator"        },
        { &UMODE_ADMIN,                        "Server Administrator"        },
        { &UMODE_SADMIN,                "Services Administrator"        },
        { &UMODE_COADMIN,                "Co Administrator"                },
        { &UMODE_OPER,                        "IRC Operator"                },
        { &UMODE_LOCOP,                        "Local IRC Operator"                
},
        { NULL,                                NULL                                }
};

static char *find_otype(unsigned long umodes)
{
        unsigned int i;

        for (i = 0; otypes[i].umode; i++)
                if (*otypes[i].umode & umodes)
                        return otypes[i].text;

        return "an unknown operator";
}

static Command *AddCommand(char *msg, char *token, int (*func)())
{
        Command *cmd;

        if (CommandExists(msg))
            {
                config_error("Command %s already exists", msg);
                return NULL;
            }
            if (CommandExists(token))
        {
                config_error("Token %s already exists", token);
                return NULL;
            }

        cmd = CommandAdd(MyMod, msg, token, func, MAXPARA, 0);

#ifndef _WIN32
        if (ModuleGetError(MyMod) != MODERR_NOERROR || !cmd)
#else
        if (!cmd)
#endif
        {
#ifndef _WIN32
                config_error("Error adding command %s: %s", msg,
                        ModuleGetErrorStr(MyMod));
#else
                config_error("Error adding command %s", msg);
#endif
                return NULL; /* just to be sure */
        }

        return cmd;
}


int m_ircops(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
        aClient                *acptr;
        char                buf[BUFSIZE];
        int                opers = 0, admins = 0, globs = 0, aways = 0;

      sendto_one(sptr, ":%s 339 %s :+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+",
            me.name, sptr->name);
      sendto_one(sptr, ":%s 339 %s :   \2Sunucuda Online olan Yönetici Listesi\2             ",
            me.name, sptr->name);
      sendto_one(sptr, ":%s 339 %s :                            ",
            me.name, sptr->name);
      sendto_one(sptr, ":%s 339 %s :+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+",
            me.name, sptr->name);
        for (acptr = client; acptr; acptr = acptr->next)
        {
                /* List only real IRC Operators */
                if (IsULine(acptr) || !IsPerson(acptr) || !IsAnOper(acptr))
                        continue;
                /* Don't list +H users */
                if (!IsAnOper(sptr) && IsHideOper(acptr))
                        continue;

                sendto_one(sptr, ":%s %d %s : \2Rumuz\2 : %-13s   \2Yetki\2 : %-20s " "%s",
                        me.name, RPL_IRCOPS, sptr->name,
                        acptr->name,
                        find_otype(acptr->umodes),
                        (IsAway(acptr) ? "- Meşgul" : IsHelpOp(acptr) ? "" : ""));

                if (IsAway(acptr))
                        aways++;
                else if (IsSkoAdmin(acptr))
                        admins++;
                else
                        opers++;

        }

        globs = opers + admins + aways;

        sprintf(buf,
                "Toplam: %d Operatör%s Bağlı - %d Yönetici%s , %d IRC Operatör%s ve %d Meşgul",
                globs, (globs) > 1 ? "" : "", admins, admins > 1 ? "" : "",
                opers, opers > 1 ? "" : "", aways);
      sendto_one(sptr, ":%s 339 %s :+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+",
                me.name, sptr->name);

        sendto_one(sptr, ":%s %d %s :%s", me.name, RPL_IRCOPS, sptr->name, buf);
        sendto_one(sptr, ":%s %d %s :Yönetici listesi sonu", me.name, RPL_ENDOFIRCOPS, sptr->name);

        return 0;
}

