From 1c624ac57c791b6df4b51eb86e04dc404052c700 Mon Sep 17 00:00:00 2001 From: ume Date: Sun, 20 Aug 2000 16:16:57 +0000 Subject: Add UNIX domain socket feature to pccardd. This makes pccard related PAO3/ports such as gxcardmon work. Reviewed by: imp Obtained from: PAO3 --- usr.sbin/pccard/pccardd/Makefile | 3 +- usr.sbin/pccard/pccardd/cardd.c | 7 +- usr.sbin/pccard/pccardd/cardd.h | 10 +- usr.sbin/pccard/pccardd/pccardd.c | 69 ++++++++++++-- usr.sbin/pccard/pccardd/server.c | 187 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 265 insertions(+), 11 deletions(-) create mode 100644 usr.sbin/pccard/pccardd/server.c (limited to 'usr.sbin/pccard') 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 #include #include +#include +#include +#include #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 + * + * $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 +#include +#include +#include +#include +#include +#include +#include + +#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; + } +} -- cgit v1.1