/*
* msg.c
*
* Written by Archie Cobbs <archie@freebsd.org>
* Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
* See ``COPYRIGHT.whistle''
*/
#include "ppp.h"
#include "msg.h"
/*
* DEFINITIONS
*/
/* Which pipe file descriptor is which */
#define PIPE_READ 0
#define PIPE_WRITE 1
struct mpmsg
{
long type;
void *arg;
};
typedef struct mpmsg *Msg;
struct msghandler
{
int pipe[2];
int prio;
void (*func)(int type, void *arg);
EventRef event;
Bund bund;
Link lnk;
};
/*
* INTERNAL FUNCTIONS
*/
static void MsgEvent(int type, void *cookie);
static void MsgReregister(MsgHandler m);
/*
* MsgRegister()
*/
MsgHandler
MsgRegister(void (*func)(int type, void *arg), int prio)
{
MsgHandler m;
m = Malloc(MB_UTIL, sizeof(*m));
if (pipe(m->pipe) < 0)
{
Log(LG_ERR, ("mpd: pipe: %s", strerror(errno)));
DoExit(EX_ERRDEAD);
}
fcntl(m->pipe[PIPE_READ], F_SETFD, 1);
fcntl(m->pipe[PIPE_WRITE], F_SETFD, 1);
m->prio = prio;
m->func = func;
m->bund = bund;
m->lnk = lnk;
MsgReregister(m);
return(m);
}
/*
* MsgUnRegister()
*/
void
MsgUnRegister(MsgHandler *m)
{
close((*m)->pipe[PIPE_WRITE]);
close((*m)->pipe[PIPE_READ]);
EventUnRegister(&(*m)->event);
Freee(*m);
*m = NULL;
}
/*
* MsgEvent()
*/
static void
MsgEvent(int type, void *cookie)
{
MsgHandler const m = (MsgHandler) cookie;
int nread, nrode;
struct mpmsg msg;
lnk = m->lnk;
bund = m->bund;
for (nrode = 0; nrode < sizeof(msg); nrode += nread)
{
if ((nread = read(m->pipe[PIPE_READ],
(u_char *) &msg + nrode, sizeof(msg) - nrode)) < 0)
{
Log(LG_ERR, ("mpd: %s: read: %s", __FUNCTION__, strerror(errno)));
DoExit(EX_ERRDEAD);
}
if (nread == 0)
{
Log(LG_ERR, ("mpd: %s: EOF", __FUNCTION__));
DoExit(EX_ERRDEAD);
}
}
(*m->func)(msg.type, msg.arg);
MsgReregister(m);
}
/*
* MsgSend()
*/
void
MsgSend(MsgHandler m, int type, void *arg)
{
struct mpmsg msg;
int nw, nwrote;
if (m == NULL)
return;
msg.type = type;
msg.arg = arg;
for (nwrote = 0; nwrote < sizeof(msg); nwrote += nw)
if ((nw = write(m->pipe[PIPE_WRITE],
(u_char *) &msg + nwrote, sizeof(msg) - nwrote)) < 0)
{
Perror("MsgSend: write");
DoExit(EX_ERRDEAD);
}
}
/*
* MsgReregister()
*/
static void
MsgReregister(MsgHandler m)
{
if (EventRegister(&m->event, EVENT_READ,
m->pipe[PIPE_READ], m->prio, MsgEvent, m) < 0)
{
Log(LG_ERR, ("mpd: can't register event"));
DoExit(EX_ERRDEAD);
}
}
/*
* MsgName()
*/
const char *
MsgName(int msg)
{
switch (msg)
{
case MSG_OPEN:
return("OPEN");
case MSG_CLOSE:
return("CLOSE");
case MSG_UP:
return("UP");
case MSG_DOWN:
return("DOWN");
default:
return("???");
}
}
syntax highlighted by Code2HTML, v. 0.9.1