|
|
1.1 root 1: #include <sys/types.h>
2: #include <sys/filio.h>
3: #include <stdio.h>
4: #include <sys/stream.h>
5:
6: extern int conn_ld;
7: extern int mesg_ld;
8: #define msglen(mp) ((mp)->losize + ((mp)->hisize<<8))
9:
10: int count; /* max connections */
11: fd_set serving; /* clients being served */
12: int nserving;
13: fd_set waiting; /* clients waiting */
14: int nwaiting;
15: int fd; /* mounted fd */
16:
17:
18: main(ac, av)
19: int ac;
20: char *av[];
21: {
22: if(ac!=3)
23: die("usage: %s path count\n", av[0]);
24: fd=mountit(av[1]);
25: count=atoi(av[2]);
26: if(count<=0)
27: die("usage: %s path count\n", av[0]);
28: detach();
29: doit();
30: }
31:
32: doit()
33: {
34: int i, n;
35: fd_set afds;
36:
37: FD_ZERO(serving);
38: for(;;){
39: afds=serving;
40: FD_SET(fd, afds);
41: switch(n=select(NOFILE, &afds, 0, 10000L)){
42: case -1:
43: /* there's a bad fd in the group */
44: afds=serving;
45: for(i=0; i<NOFILE; i++)
46: if(FD_ISSET(i, afds))
47: dropclient(i);
48: break;
49: case 0:
50: /* timeout, try again */
51: break;
52: default:
53: /* look for new clients */
54: if(FD_ISSET(fd, afds)){
55: request();
56: n--;
57: }
58:
59: /* someone needs servicing */
60: for(i=0; n && i<NOFILE; i++){
61: if(FD_ISSET(i, afds)){
62: dropclient(i);
63: n--;
64: }
65: }
66: break;
67: }
68: }
69: }
70:
71: newclient(cfd)
72: int cfd;
73: {
74: FD_SET(cfd, waiting);
75: nwaiting++;
76: wtos();
77: }
78:
79: dropclient(cfd)
80: int cfd;
81: {
82: FD_CLR(cfd, serving);
83: nserving--;
84: close(cfd);
85: wtos();
86: }
87:
88: wtos()
89: {
90: int i=0;
91: struct mesg m;
92:
93: while(nwaiting && nserving<count){
94: for(;i<NOFILE;i++){
95: if(FD_ISSET(i,waiting)){
96: nwaiting--;
97: nserving++;
98: FD_SET(i, serving);
99: FD_CLR(i, waiting);
100: m.losize = 0;
101: m.hisize = 0 >> 8;
102: m.type = M_HANGUP;
103: m.magic = MSGMAGIC;
104: if(ioctl(i, FIOACCEPT, (void *)0)<0
105: || ioctl(i, FIOPUSHLD, &mesg_ld)<0
106: || write(i, &m, sizeof(m))!=sizeof(m)){
107: close(i);
108: FD_CLR(i, serving);
109: nserving--;
110: continue;
111: }
112: }
113: }
114: }
115: }
116:
117: request()
118: {
119: struct passfd pass;
120:
121: if(ioctl(fd, FIORCVFD, &pass)<0)
122: abort();
123: newclient(pass.fd);
124: }
125:
126: mountit(path)
127: char *path;
128: {
129: int pfd[2];
130:
131: /* make a node to mount onto */
132: if (access(path,0)<0 && creat(path, 0666)<0)
133: die("can't creat %s\n", path);
134:
135: /* get the stream to mount */
136: if (pipe(pfd) < 0)
137: die("out of pipes\n", 0);
138: if (ioctl(pfd[1], FIOPUSHLD, &conn_ld) < 0)
139: die("can't push line discipline\n", 0);
140:
141: /* mount */
142: if (fmount(3, pfd[1], path, 0) < 0)
143: die("can't mount onto %s\n", path);
144: umask(0);
145: chmod(path, 0666);
146: close(pfd[1]);
147: return pfd[0];
148: }
149:
150: detach()
151: {
152: switch(fork()){
153: case -1:
154: die("can't fork\n", 0);
155: case 0:
156: break;
157: default:
158: exit(0);
159: }
160: for(fd=0; fd<NSYSFILE; fd++)
161: close(fd);
162: setpgrp(getpid(), getpid());
163: }
164:
165: die(a, b)
166: char *a;
167: {
168: fprintf(stderr, a, b);
169: exit(1);
170: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.