Initial import from FreeBSD RELENG_4:
[dragonfly.git] / usr.sbin / pccard / pccardd / server.c
1 /*
2  *      pccardd UNIX-domain socket interface
3  *      Copyright (C) 1996 by Tatsumi Hosokawa <hosokawa@mt.cs.keio.ac.jp>
4  *
5  * $Id: server.c,v 1.3 1999/02/07 08:02:44 kuriyama Exp $
6  */
7
8 #ifndef lint
9 static const char rcsid[] =
10   "$FreeBSD: src/usr.sbin/pccard/pccardd/server.c,v 1.2.2.1 2000/08/26 15:49:48 ume Exp $";
11 #endif /* not lint */
12
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <sys/types.h>
16 #include <sys/ioctl.h>
17 #include <sys/socket.h>
18 #include <sys/un.h>
19 #include <signal.h>
20 #include <setjmp.h>
21
22 #include "cardd.h"
23
24 static void
25 cardnum(char *buf)
26 {
27         int     i = 0;
28         struct slot *sp;
29
30         for (sp = slots; sp; sp = sp->next)
31                 i++;
32         if (i > MAXSLOT)
33                 i = MAXSLOT;
34         sprintf(buf, "%2d", i);
35 }
36
37 static struct slot *
38 find_slot(int slot)
39 {
40         struct slot *sp;
41
42         /* Search the list until we find the slot or get to the end */
43         for (sp = slots; sp && sp->slot != slot; sp = sp->next)
44                 continue;
45
46         return ( sp );
47 }
48
49 static void
50 cardname(char *buf, int slot)
51 {
52         struct slot *sp;
53         char   *manuf, *vers, *drv, *stat;
54
55         /* Look for the slot */
56         if ( (sp = find_slot(slot)) == NULL)
57                 return;
58
59         /* Fill in the information in the buff */
60         if (sp->cis) {
61
62                 manuf = sp->cis->manuf;
63                 vers = sp->cis->vers;
64                 if (sp->config && sp->config->driver &&
65                     sp->config->driver->name)
66                         drv = sp->config->driver->name;
67                 else
68                         drv = "";
69         } else
70                 manuf = vers = drv = "";
71
72         switch (sp->state) {
73         case empty:
74                 stat = "0";
75                 break;
76         case filled:
77                 stat = "1";
78                 break;
79         case inactive:
80                 stat = "2";
81                 break;
82         default:
83                 stat = "9";
84         }
85         sprintf(buf, "%d~%s~%s~%s~%s", slot, manuf, vers, drv, stat);
86 }
87
88 static void
89 cardpwr(int slot, int pwon)
90 {
91         struct slot *sp;
92
93         /* Look for the slot */
94         if ( (sp = find_slot(slot)) == NULL)
95                 return;
96
97         if (ioctl(sp->fd, PIOCSVIR, &pwon) < 0)
98                 logerr("invaild arguments for cardpwr");
99 }
100
101 static int sock = 0;
102 static int slen = 0;
103 static struct sockaddr_un sun;
104
105 void
106 set_socket(int s)
107 {
108         sock = s;
109 }
110
111 void
112 stat_changed(struct slot *sp)
113 {
114         int     len;
115         char    buf[512];
116
117         if (!slen)
118                 return;
119
120         cardname(buf, sp->slot);
121         len = strlen(buf);
122         if (sendto(sock, buf, len, 0, (struct sockaddr *) & sun, slen) != len) {
123                 logerr("sendto failed");
124                 slen = 0;
125         }
126 }
127
128 void
129 process_client(void)
130 {
131         char    buf[512], obuf[512];
132         int     len;
133         int     snum;
134
135         if (!sock)
136                 return;
137         slen = sizeof(sun);
138         len = recvfrom(sock, buf, sizeof(buf),
139                        0, (struct sockaddr *)&sun, &slen);
140         if (len < 0)
141                 logerr("recvfrom failed");
142         buf[len] = '\0';
143         obuf[0] = '\0';
144         switch (buf[0]) {       /* Protocol implementation */
145         case 'S':       /* How many slots? */
146                 cardnum(obuf);
147                 break;
148         case 'N':       /* Card name request */
149                 sscanf(buf + 1, "%d", &snum);
150                 if (snum >= 0 && snum <= MAXSLOT)
151                         cardname(obuf, snum);
152                 else 
153                         logerr("Illegal slot requests for N command");
154                 break;
155         case 'P':       /* Virtual insertion request */
156                 sscanf(buf + 1, "%d", &snum);
157                 if (snum >= 0 && snum <= MAXSLOT) {
158                         logmsg("slot %d: spring has come", snum);
159                         cardpwr(snum, 1);
160                 } else
161                         logerr("Illegal slot requests for P command");
162                 break;
163         case 'Q':       /* Virtual removal request */
164                 sscanf(buf + 1, "%d", &snum);
165                 if (snum >= 0 && snum <= MAXSLOT) {
166                         logmsg("slot %d: hibernation", snum);
167                         cardpwr(snum, 0);
168                 } else
169                         logerr("Illegal slot requests for Q command");
170                 break;
171         default:
172                 logerr("Unknown control message from socket");
173                 break;
174         }
175         len = strlen(obuf);
176         if (len) {
177                 if (sendto(sock, obuf, len, 0, (struct sockaddr *)&sun, slen)
178                     != len) {
179                         logerr("sendto failed");
180                         slen = 0;
181                 }
182         } else if (sendto(sock, 0, 0, 0, (struct sockaddr *)&sun, slen)
183                    != len) {
184                         logerr("sendto failed");
185                         slen = 0;
186         }
187 }