src/ipc.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- hisGetIPC
- hisAddIPC
- GetStats
- PutStats
- PutSetGroup
- PutSetListGroup
- 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;
}