1 6f4d00ee 2013-09-23 0intro #include "stdinc.h"
3 6f4d00ee 2013-09-23 0intro #include "9.h"
5 6f4d00ee 2013-09-23 0intro typedef struct Lstn Lstn;
6 6f4d00ee 2013-09-23 0intro struct Lstn {
9 6f4d00ee 2013-09-23 0intro char* address;
10 6f4d00ee 2013-09-23 0intro char dir[NETPATHLEN];
12 6f4d00ee 2013-09-23 0intro Lstn* next;
13 6f4d00ee 2013-09-23 0intro Lstn* prev;
16 6f4d00ee 2013-09-23 0intro static struct {
17 4b576658 2013-09-23 0intro RWLock lock;
19 6f4d00ee 2013-09-23 0intro Lstn* head;
20 6f4d00ee 2013-09-23 0intro Lstn* tail;
23 6f4d00ee 2013-09-23 0intro static void
24 6f4d00ee 2013-09-23 0intro lstnFree(Lstn* lstn)
26 4b576658 2013-09-23 0intro wlock(&lbox.lock);
27 6f4d00ee 2013-09-23 0intro if(lstn->prev != nil)
28 6f4d00ee 2013-09-23 0intro lstn->prev->next = lstn->next;
30 6f4d00ee 2013-09-23 0intro lbox.head = lstn->next;
31 6f4d00ee 2013-09-23 0intro if(lstn->next != nil)
32 6f4d00ee 2013-09-23 0intro lstn->next->prev = lstn->prev;
34 6f4d00ee 2013-09-23 0intro lbox.tail = lstn->prev;
35 4b576658 2013-09-23 0intro wunlock(&lbox.lock);
37 6f4d00ee 2013-09-23 0intro if(lstn->afd != -1)
38 6f4d00ee 2013-09-23 0intro close(lstn->afd);
39 4b576658 2013-09-23 0intro vtfree(lstn->address);
40 4b576658 2013-09-23 0intro vtfree(lstn);
43 6f4d00ee 2013-09-23 0intro static void
44 6f4d00ee 2013-09-23 0intro lstnListen(void* a)
46 6f4d00ee 2013-09-23 0intro Lstn *lstn;
47 6f4d00ee 2013-09-23 0intro int dfd, lfd;
48 6f4d00ee 2013-09-23 0intro char newdir[NETPATHLEN];
50 4b576658 2013-09-23 0intro threadsetname("listen");
54 6f4d00ee 2013-09-23 0intro if((lfd = listen(lstn->dir, newdir)) < 0){
55 6f4d00ee 2013-09-23 0intro fprint(2, "listen: listen '%s': %r", lstn->dir);
58 6f4d00ee 2013-09-23 0intro if((dfd = accept(lfd, newdir)) >= 0)
59 6f4d00ee 2013-09-23 0intro conAlloc(dfd, newdir, lstn->flags);
61 6f4d00ee 2013-09-23 0intro fprint(2, "listen: accept %s: %r\n", newdir);
62 6f4d00ee 2013-09-23 0intro close(lfd);
64 6f4d00ee 2013-09-23 0intro lstnFree(lstn);
67 6f4d00ee 2013-09-23 0intro static Lstn*
68 6f4d00ee 2013-09-23 0intro lstnAlloc(char* address, int flags)
71 6f4d00ee 2013-09-23 0intro Lstn *lstn;
72 6f4d00ee 2013-09-23 0intro char dir[NETPATHLEN];
74 4b576658 2013-09-23 0intro wlock(&lbox.lock);
75 6f4d00ee 2013-09-23 0intro for(lstn = lbox.head; lstn != nil; lstn = lstn->next){
76 6f4d00ee 2013-09-23 0intro if(strcmp(lstn->address, address) != 0)
78 4b576658 2013-09-23 0intro werrstr("listen: already serving '%s'", address);
79 4b576658 2013-09-23 0intro wunlock(&lbox.lock);
80 6f4d00ee 2013-09-23 0intro return nil;
83 6f4d00ee 2013-09-23 0intro if((afd = announce(address, dir)) < 0){
84 4b576658 2013-09-23 0intro werrstr("listen: announce '%s': %r", address);
85 4b576658 2013-09-23 0intro wunlock(&lbox.lock);
86 6f4d00ee 2013-09-23 0intro return nil;
89 4b576658 2013-09-23 0intro lstn = vtmallocz(sizeof(Lstn));
90 6f4d00ee 2013-09-23 0intro lstn->afd = afd;
91 4b576658 2013-09-23 0intro lstn->address = vtstrdup(address);
92 6f4d00ee 2013-09-23 0intro lstn->flags = flags;
93 6f4d00ee 2013-09-23 0intro memmove(lstn->dir, dir, NETPATHLEN);
95 6f4d00ee 2013-09-23 0intro if(lbox.tail != nil){
96 6f4d00ee 2013-09-23 0intro lstn->prev = lbox.tail;
97 6f4d00ee 2013-09-23 0intro lbox.tail->next = lstn;
100 6f4d00ee 2013-09-23 0intro lbox.head = lstn;
101 6f4d00ee 2013-09-23 0intro lstn->prev = nil;
103 6f4d00ee 2013-09-23 0intro lbox.tail = lstn;
104 4b576658 2013-09-23 0intro wunlock(&lbox.lock);
106 4b576658 2013-09-23 0intro if(proccreate(lstnListen, lstn, STACK) < 0){
107 4b576658 2013-09-23 0intro werrstr("listen: thread '%s': %r", lstn->address);
108 6f4d00ee 2013-09-23 0intro lstnFree(lstn);
109 6f4d00ee 2013-09-23 0intro return nil;
112 6f4d00ee 2013-09-23 0intro return lstn;
115 6f4d00ee 2013-09-23 0intro static int
116 6f4d00ee 2013-09-23 0intro cmdLstn(int argc, char* argv[])
118 6f4d00ee 2013-09-23 0intro int dflag, flags;
119 6f4d00ee 2013-09-23 0intro Lstn *lstn;
120 6f4d00ee 2013-09-23 0intro char *usage = "usage: listen [-dIN] [address]";
122 6f4d00ee 2013-09-23 0intro dflag = 0;
123 6f4d00ee 2013-09-23 0intro flags = 0;
124 6f4d00ee 2013-09-23 0intro ARGBEGIN{
126 6f4d00ee 2013-09-23 0intro return cliError(usage);
127 6f4d00ee 2013-09-23 0intro case 'd':
128 6f4d00ee 2013-09-23 0intro dflag = 1;
130 6f4d00ee 2013-09-23 0intro case 'I':
131 6f4d00ee 2013-09-23 0intro flags |= ConIPCheck;
133 6f4d00ee 2013-09-23 0intro case 'N':
134 6f4d00ee 2013-09-23 0intro flags |= ConNoneAllow;
138 6f4d00ee 2013-09-23 0intro switch(argc){
140 6f4d00ee 2013-09-23 0intro return cliError(usage);
142 4b576658 2013-09-23 0intro rlock(&lbox.lock);
143 6f4d00ee 2013-09-23 0intro for(lstn = lbox.head; lstn != nil; lstn = lstn->next)
144 6f4d00ee 2013-09-23 0intro consPrint("\t%s\t%s\n", lstn->address, lstn->dir);
145 4b576658 2013-09-23 0intro runlock(&lbox.lock);
148 6f4d00ee 2013-09-23 0intro if(!dflag){
149 6f4d00ee 2013-09-23 0intro if(lstnAlloc(argv[0], flags) == nil)
150 6f4d00ee 2013-09-23 0intro return 0;
154 4b576658 2013-09-23 0intro wlock(&lbox.lock);
155 6f4d00ee 2013-09-23 0intro for(lstn = lbox.head; lstn != nil; lstn = lstn->next){
156 6f4d00ee 2013-09-23 0intro if(strcmp(lstn->address, argv[0]) != 0)
157 6f4d00ee 2013-09-23 0intro continue;
158 6f4d00ee 2013-09-23 0intro if(lstn->afd != -1){
159 6f4d00ee 2013-09-23 0intro close(lstn->afd);
160 6f4d00ee 2013-09-23 0intro lstn->afd = -1;
164 4b576658 2013-09-23 0intro wunlock(&lbox.lock);
166 6f4d00ee 2013-09-23 0intro if(lstn == nil){
167 4b576658 2013-09-23 0intro werrstr("listen: '%s' not found", argv[0]);
168 6f4d00ee 2013-09-23 0intro return 0;
173 6f4d00ee 2013-09-23 0intro return 1;
177 6f4d00ee 2013-09-23 0intro lstnInit(void)
179 6f4d00ee 2013-09-23 0intro cliAddCmd("listen", cmdLstn);
181 6f4d00ee 2013-09-23 0intro return 1;