|
|
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.