summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pccard/pccardd
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2000-08-20 16:16:57 +0000
committerume <ume@FreeBSD.org>2000-08-20 16:16:57 +0000
commit1c624ac57c791b6df4b51eb86e04dc404052c700 (patch)
tree5ffa29a5a2d7aa241e19cb06405335128593e8bc /usr.sbin/pccard/pccardd
parentd89ba315b05ef2cd7fa9a001561b6192bf3f2fa3 (diff)
downloadFreeBSD-src-1c624ac57c791b6df4b51eb86e04dc404052c700.zip
FreeBSD-src-1c624ac57c791b6df4b51eb86e04dc404052c700.tar.gz
Add UNIX domain socket feature to pccardd. This makes pccard
related PAO3/ports such as gxcardmon work. Reviewed by: imp Obtained from: PAO3
Diffstat (limited to 'usr.sbin/pccard/pccardd')
-rw-r--r--usr.sbin/pccard/pccardd/Makefile3
-rw-r--r--usr.sbin/pccard/pccardd/cardd.c7
-rw-r--r--usr.sbin/pccard/pccardd/cardd.h10
-rw-r--r--usr.sbin/pccard/pccardd/pccardd.c69
-rw-r--r--usr.sbin/pccard/pccardd/server.c187
5 files changed, 265 insertions, 11 deletions
diff --git a/usr.sbin/pccard/pccardd/Makefile b/usr.sbin/pccard/pccardd/Makefile
index af70e31..aa1e58e 100644
--- a/usr.sbin/pccard/pccardd/Makefile
+++ b/usr.sbin/pccard/pccardd/Makefile
@@ -1,7 +1,8 @@
# Makefile for pccardd
+# $FreeBSD$
PROG= pccardd
-SRCS= pccardd.c cardd.c file.c util.c readcis.c printcis.c
+SRCS= pccardd.c cardd.c file.c util.c readcis.c printcis.c server.c
MAN8= pccardd.8
MAN5= pccard.conf.5
DPADD= ${LIBUTIL}
diff --git a/usr.sbin/pccard/pccardd/cardd.c b/usr.sbin/pccard/pccardd/cardd.c
index 0f65460..9f11acc 100644
--- a/usr.sbin/pccard/pccardd/cardd.c
+++ b/usr.sbin/pccard/pccardd/cardd.c
@@ -49,6 +49,8 @@ static void pr_cmd(struct cmd *);
static void read_ether(struct slot *);
static void read_ether_attr2(struct slot *sp);
+struct slot *slots;
+
/*
* Dump configuration file data.
*/
@@ -105,7 +107,7 @@ readslots(void)
{
char name[128];
int i, fd;
- struct slot *slots, *sp;
+ struct slot *sp;
slots = NULL;
for (i = 0; i < MAXSLOT; i++) {
@@ -158,6 +160,7 @@ slot_change(struct slot *sp)
}
switch (state.state) {
case empty:
+ case inactive:
case noslot:
/* Debounce potentially incorrectly reported removals */
if (state.laststate == filled || state.laststate == suspend)
@@ -173,6 +176,8 @@ slot_change(struct slot *sp)
/* ignored */
break;
}
+ sp->state = state.state;
+ stat_changed(sp);
}
/*
diff --git a/usr.sbin/pccard/pccardd/cardd.h b/usr.sbin/pccard/pccardd/cardd.h
index b6dde10..726a82b 100644
--- a/usr.sbin/pccard/pccardd/cardd.h
+++ b/usr.sbin/pccard/pccardd/cardd.h
@@ -139,6 +139,9 @@ struct slot {
#define AFLAGS (IO_ASSIGNED | MEM_ASSIGNED | IRQ_ASSIGNED)
#define CFLAGS (EADDR_CONFIGED | WL_CONFIGED)
+EXTERN struct slot *slots, *current_slot;
+EXTERN int slen;
+
EXTERN struct allocblk *pool_ioblks; /* I/O blocks in the pool */
EXTERN struct allocblk *pool_mem; /* Memory in the pool */
EXTERN int pool_irq[16]; /* IRQ allocations */
@@ -170,9 +173,14 @@ char *newstr();
void reset_slot(struct slot *);
void *xmalloc(int);
-/* file.c */
+/* file.c functions */
void readfile(char *);
+/* server.c functions */
+void set_socket(int);
+void stat_changed(struct slot *);
+void process_client(void);
+
#define IOPORTS 0x400
#define MEMUNIT 0x1000
#define MEMSTART 0xA0000
diff --git a/usr.sbin/pccard/pccardd/pccardd.c b/usr.sbin/pccard/pccardd/pccardd.c
index 16157b2..f911d33 100644
--- a/usr.sbin/pccard/pccardd/pccardd.c
+++ b/usr.sbin/pccard/pccardd/pccardd.c
@@ -35,12 +35,22 @@ static const char rcsid[] =
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
#define EXTERN
#include "cardd.h"
char *config_file = "/etc/defaults/pccard.conf";
static char *pid_file = "/var/run/pccardd.pid";
+/*
+ * pathname of UNIX-domain socket
+ */
+static char *socket_name = "/var/tmp/.pccardd";
+static char *sock = 0;
+static int server_sock;
+
/* SIGHUP signal handler */
static void
restart(void)
@@ -49,6 +59,7 @@ restart(void)
bitstr_t bit_decl(mem_inuse, MEMBLKS);
int irq_inuse[16];
int i;
+ struct sockaddr_un sun;
bit_nclear(io_inuse, 0, IOPORTS-1);
bit_nclear(mem_inuse, 0, MEMBLKS-1);
@@ -98,6 +109,22 @@ restart(void)
pool_irq[i] = 0;
}
}
+ close(server_sock);
+ if ((server_sock = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0)
+ die("socket failed");
+ bzero(&sun, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ if (sock) {
+ socket_name = sock;
+ }
+ strcpy(sun.sun_path, socket_name);
+ slen = SUN_LEN(&sun);
+ (void)unlink(socket_name);
+ if (bind(server_sock, (struct sockaddr *) & sun, slen) < 0)
+ die("bind failed");
+ chown(socket_name, 0, 5); /* XXX - root.operator */
+ chmod(socket_name, 0660);
+ set_socket(server_sock);
}
/* SIGTERM/SIGINT signal handler */
@@ -127,18 +154,20 @@ int doverbose = 0;
int
main(int argc, char *argv[])
{
- struct slot *slots, *sp;
+ struct slot *sp;
int count, dodebug = 0;
int delay = 0;
int irq_arg[16];
int irq_specified = 0;
int i;
+ struct sockaddr_un sun;
+#define COM_OPTS ":dvf:s:i:z"
bzero(irq_arg, sizeof(irq_arg));
debug_level = 0;
pccard_init_sleep = 5000000;
cards = last_card = 0;
- while ((count = getopt(argc, argv, ":dvf:i:z")) != -1) {
+ while ((count = getopt(argc, argv, COM_OPTS)) != -1) {
switch (count) {
case 'd':
setbuf(stdout, 0);
@@ -160,6 +189,9 @@ main(int argc, char *argv[])
irq_arg[i] = 1;
irq_specified = 1;
break;
+ case 's':
+ sock = optarg;
+ break;
case 'z':
delay = 1;
break;
@@ -200,23 +232,44 @@ main(int argc, char *argv[])
logmsg("pccardd started", NULL);
write_pid();
+ if ((server_sock = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0)
+ die("socket failed");
+ bzero(&sun, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ if (sock) {
+ socket_name = sock;
+ }
+ strcpy(sun.sun_path, socket_name);
+ slen = SUN_LEN(&sun);
+ (void)unlink(socket_name);
+ if (bind(server_sock, (struct sockaddr *) & sun, slen) < 0)
+ die("bind failed");
+ chown(socket_name, 0, 5); /* XXX - root.operator */
+ chmod(socket_name, 0660);
+ set_socket(server_sock);
+
(void)signal(SIGINT, dodebug ? term : SIG_IGN);
(void)signal(SIGTERM, term);
(void)signal(SIGHUP, (void (*)(int))restart);
for (;;) {
- fd_set mask;
- FD_ZERO(&mask);
+ fd_set rmask, emask;
+ FD_ZERO(&emask);
+ FD_ZERO(&rmask);
for (sp = slots; sp; sp = sp->next)
- FD_SET(sp->fd, &mask);
- count = select(32, 0, 0, &mask, 0);
+ FD_SET(sp->fd, &emask);
+ FD_SET(server_sock, &rmask);
+ count = select(32, &rmask, 0, &emask, 0);
if (count == -1) {
logerr("select");
continue;
}
- if (count)
+ if (count) {
for (sp = slots; sp; sp = sp->next)
- if (FD_ISSET(sp->fd, &mask))
+ if (FD_ISSET(sp->fd, &emask))
slot_change(sp);
+ if (FD_ISSET(server_sock, &rmask))
+ process_client();
+ }
}
}
diff --git a/usr.sbin/pccard/pccardd/server.c b/usr.sbin/pccard/pccardd/server.c
new file mode 100644
index 0000000..d5a271f
--- /dev/null
+++ b/usr.sbin/pccard/pccardd/server.c
@@ -0,0 +1,187 @@
+/*
+ * 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;
+ }
+}
OpenPOWER on IntegriCloud