src/ipc.c

/* [<][>]
[^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. hisGetIPC
  2. hisAddIPC
  3. GetStats
  4. PutStats
  5. PutSetGroup
  6. PutSetListGroup
  7. DoIPC

/* $Id: ipc.c,v 1.1.1.1 1998/08/02 20:35:00 proff Exp $
 * $Copyright$
 */

#include "nglobal.h"
#include "network.h"
#include "history.h"
#include "group.h"

#include "ipc.h"

EXPORT char *hisGetIPC (char *key)
/* [<][>][^][v][top][bottom][index][help] */
{
        static char buf[MAX_BFR];
        int l;
        int cc;
        *buf = IPC_GET_KEY;
        l = 1 + strlen (key) + 1;
        if (l > sizeof (buf))
                return NULL;
        strcpy (buf + 1, key);
        if (write (Master_fd, buf, l) < 1)
                return NULL;
        if ((cc = read (Master_fd, buf, sizeof buf)) < 1)
                return NULL;
        buf[cc] = '\0';
        if (*buf == IPC_KEY)
                return buf + 1;
        return NULL;
}

EXPORT bool hisAddIPC (char *key, char *val)
/* [<][>][^][v][top][bottom][index][help] */
{
        static char buf[MAX_BFR];
        int lkey;
        int l;
        *buf = IPC_ADD_KEY;
        lkey = strlen (key);
        l = 1 + lkey + 1 + strlen (val) + 1;
        if (l > sizeof (buf))
                return FALSE;
        strcpy (buf + 1, key);
        strcpy (buf + 1 + lkey + 1, val);
        if (write (Master_fd, buf, l) < 1)
                return FALSE;
        if (read (Master_fd, buf, sizeof buf) < 1)
                return FALSE;
        return (*buf == IPC_ADD_KEY_OK);
}

#if 0
EXPORT bool GetStats (struct stats * s, char *server)
/* [<][>][^][v][top][bottom][index][help] */
{
        char buf[MAX_BFR];
        int cc;
        struct stats *st = (struct stats *) buf;
        *buf = IPC_GET_STATS;
        strncpy (buf + 1, server, sizeof (buf) - 1);
        if (write (Master_fd, buf, 1 + strlen (server) + 1) < 1)
                return FALSE;
        if ((cc = read (Master_fd, buf, sizeof buf)) < 1)
                return FALSE;
        if (cc < sizeof *s)
                return FALSE;
        if (st->type != IPC_STATS)
                return FALSE;
        memcpy (s, buf, sizeof *s);
        return TRUE;
}
#endif

#if 0 /* these functions were used prior to our shared memory code */
EXPORT bool PutStats (struct stats *s)
/* [<][>][^][v][top][bottom][index][help] */
{
        s->type = IPC_STATS;
        s->client_elapsed = time (NULL) - s->time_client_started;
        if (write (Master_fd, (char *) s, sizeof *s) != sizeof *s)
                return FALSE;
        return TRUE;
}

EXPORT bool PutSetGroup (char *group, int msgs, int lo, int hi)
/* [<][>][^][v][top][bottom][index][help] */
{
        char buf[32+MAX_GROUP+1];
        struct set_group *s=(struct set_group *)buf;
        s->type = IPC_SET_GROUP;
        s->msgs = msgs;
        s->lo = lo;
        s->hi = hi;
        strcpy(s->group, group);
        if (write (Master_fd, (char *) s, sizeof *s) != sizeof *s)
                return FALSE;
        return TRUE;
}

EXPORT bool PutSetListGroup (char *group, time_t tim)
/* [<][>][^][v][top][bottom][index][help] */
{
        char buf[32+MAX_GROUP+1];
        struct set_listgroup *s=(struct set_listgroup *)buf;
        s->type = IPC_SET_LISTGROUP;
        s->time = tim;
        strcpy(s->group, group);
        if (write (Master_fd, (char *) s, sizeof *s) != sizeof *s)
                return FALSE;
        return TRUE;
}
#endif

EXPORT bool DoIPC (int fd)
/* [<][>][^][v][top][bottom][index][help] */
{

        int cc;
        char buf[MAX_BFR], reply[MAX_BFR];
        if ((cc = read (fd, buf, sizeof buf)) < 1)
                return FALSE;
        Stats->IPCfromChild++;
        Stats->IPCfromChildBytes += cc;
        switch (*buf)
        {
        case IPC_GET_KEY:
                {
                        char *val = hisGetDbz (buf + 1);
                        if (val)
                        {
                                *reply = IPC_KEY;
                                strcpy (reply + 1, val);
                                if ((cc = write (fd, reply, 1 + strlen (reply + 1) + 1)) <1)
                                {
                                        return FALSE;
                                }
                        } else
                        {
                                *reply = IPC_GET_KEY_FAILED;
                                if ((cc = write (fd, reply, 1)) <1)
                                        return FALSE;
                        }
                        Stats->IPCtoChild++;
                        Stats->IPCtoChildBytes += cc;
                        break;
                }
        case IPC_ADD_KEY:
                {
                        if (!hisAddDbz (buf + 1, buf + 1 + strlen (buf + 1) + 1))
                                *reply = IPC_ADD_KEY_FAILED;
                        else
                                *reply = IPC_ADD_KEY_OK;
                        if ((cc = write (fd, reply, 1)) == -1)
                                return FALSE;
                        Stats->IPCtoChild++;
                        Stats->IPCtoChildBytes += cc;
                        break;
                }
#if 0   /* not used since the introduction of shared memory */
        case IPC_SET_GROUP:
                {
                        struct set_group *s = (struct set_group *)buf;
                        struct newsgroup *n=newsgroup_find_add(s->group, NULL, TRUE);
                        if (n)
                        {
                                setGroup(n, s->msgs, s->lo, s->hi);
                                n->write_locks = 0;
                        }
                        break;
                }
        case IPC_SET_LISTGROUP:
                {
                        struct set_listgroup *s = (struct set_listgroup *)buf;
                        struct newsgroup *n=newsgroup_find_add(s->group, NULL, TRUE);
                        if (n)
                        {
                                n->listgroup_time = s->time;
                                n->write_locks = 0;
                        }
                        break;
                }
        case IPC_GET_STATS:
                {
                        struct stats *s = Stats;
                        statsUpdateServer ();
                        s->type = IPC_STATS;
                        if ((cc = write (fd, s, sizeof (*s) + strlen (s->servername))) <1)
                                return FALSE;
                        Stats->ipc_messages_out++;
                        Stats->ipc_messages_out_bytes += cc;
                        break;
                }
        case IPC_STATS:
                {
                        int *i, *o;
                        unsigned long *ii, *oo;
                        struct stats *p = (struct stats *) buf;
                        if (cc < sizeof *p)
                        {
                                logw (("short IPC_STATS %d<%d", cc, sizeof *p));
                                break;
                        }
                        for (o = &Stats->active_len, i = &p->active_len; i <= (int *) &p->newsgroups_entries; o++, i++)
                                if (*i)
                                        *o = *i;
                        for (o = &Stats->server_connects, i = &p->server_connects; i < (int *) &p->client_user_cpu; *o++ += *i++) ;     /* add */
                        for (oo = &Stats->client_user_cpu, ii = &p->client_user_cpu;
                             ii < (unsigned long *) &p->servername; *oo++ += *ii++) ;   /* add */
                        break;
                }
#endif
#ifdef GRRR
        case default:
                        logw (("invalid ipc command from child len=%d", cc));
#endif
        }
        return TRUE;
}

/* [<][>][^][v][top][bottom][index][help] */