freebsd-nq/usr.sbin/pccard/pccardd/server.c
Hajimu UMEMOTO e0faad6850 Add UNIX domain socket feature to pccardd. This makes pccard
related PAO3/ports such as gxcardmon work.

Reviewed by:	imp
Obtained from:	PAO3
2000-08-20 16:16:57 +00:00

188 lines
3.5 KiB
C

/*
* pccardd UNIX-domain socket interface
* Copyright (C) 1996 by Tatsumi Hosokawa <hosokawa@mt.cs.keio.ac.jp>
*
* $Id: server.c,v 1.3 1999/02/07 08:02:44 kuriyama Exp $
*/
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <signal.h>
#include <setjmp.h>
#include "cardd.h"
static void
cardnum(char *buf)
{
int i = 0;
struct slot *sp;
for (sp = slots; sp; sp = sp->next)
i++;
if (i > MAXSLOT)
i = MAXSLOT;
sprintf(buf, "%2d", i);
}
static struct slot *
find_slot(int slot)
{
struct slot *sp;
/* Search the list until we find the slot or get to the end */
for (sp = slots; sp && sp->slot != slot; sp = sp->next)
continue;
return ( sp );
}
static void
cardname(char *buf, int slot)
{
struct slot *sp;
char *manuf, *vers, *drv, *stat;
/* Look for the slot */
if ( (sp = find_slot(slot)) == NULL)
return;
/* Fill in the information in the buff */
if (sp->cis) {
manuf = sp->cis->manuf;
vers = sp->cis->vers;
if (sp->config && sp->config->driver &&
sp->config->driver->name)
drv = sp->config->driver->name;
else
drv = "";
} else
manuf = vers = drv = "";
switch (sp->state) {
case empty:
stat = "0";
break;
case filled:
stat = "1";
break;
case inactive:
stat = "2";
break;
default:
stat = "9";
}
sprintf(buf, "%d~%s~%s~%s~%s", slot, manuf, vers, drv, stat);
}
static void
cardpwr(int slot, int pwon)
{
struct slot *sp;
/* Look for the slot */
if ( (sp = find_slot(slot)) == NULL)
return;
if (ioctl(sp->fd, PIOCSVIR, &pwon) < 0)
logerr("invaild arguments for cardpwr");
}
static int sock = 0;
static int slen = 0;
static struct sockaddr_un sun;
void
set_socket(int s)
{
sock = s;
}
void
stat_changed(struct slot *sp)
{
int len;
char buf[512];
if (!slen)
return;
cardname(buf, sp->slot);
len = strlen(buf);
if (sendto(sock, buf, len, 0, (struct sockaddr *) & sun, slen) != len) {
logerr("sendto failed");
slen = 0;
}
}
void
process_client(void)
{
char buf[512], obuf[512];
int len;
int snum;
if (!sock)
return;
slen = sizeof(sun);
len = recvfrom(sock, buf, sizeof(buf),
0, (struct sockaddr *)&sun, &slen);
if (len < 0)
logerr("recvfrom failed");
buf[len] = '\0';
obuf[0] = '\0';
switch (buf[0]) { /* Protocol implementation */
case 'S': /* How many slots? */
cardnum(obuf);
break;
case 'N': /* Card name request */
sscanf(buf + 1, "%d", &snum);
if (snum >= 0 && snum <= MAXSLOT)
cardname(obuf, snum);
else
logerr("Illegal slot requests for N command");
break;
case 'P': /* Virtual insertion request */
sscanf(buf + 1, "%d", &snum);
if (snum >= 0 && snum <= MAXSLOT) {
logmsg("slot %d: spring has come", snum);
cardpwr(snum, 1);
} else
logerr("Illegal slot requests for P command");
break;
case 'Q': /* Virtual removal request */
sscanf(buf + 1, "%d", &snum);
if (snum >= 0 && snum <= MAXSLOT) {
logmsg("slot %d: hibernation", snum);
cardpwr(snum, 0);
} else
logerr("Illegal slot requests for Q command");
break;
default:
logerr("Unknown control message from socket");
break;
}
len = strlen(obuf);
if (len) {
if (sendto(sock, obuf, len, 0, (struct sockaddr *)&sun, slen)
!= len) {
logerr("sendto failed");
slen = 0;
}
} else if (sendto(sock, 0, 0, 0, (struct sockaddr *)&sun, slen)
!= len) {
logerr("sendto failed");
slen = 0;
}
}