Blame


1 6f4d00ee 2013-09-23 0intro #include "stdinc.h"
2 6f4d00ee 2013-09-23 0intro
3 6f4d00ee 2013-09-23 0intro #include "9.h"
4 6f4d00ee 2013-09-23 0intro
5 6f4d00ee 2013-09-23 0intro typedef struct Srv Srv;
6 6f4d00ee 2013-09-23 0intro struct Srv {
7 6f4d00ee 2013-09-23 0intro int fd;
8 6f4d00ee 2013-09-23 0intro int srvfd;
9 6f4d00ee 2013-09-23 0intro char* service;
10 6f4d00ee 2013-09-23 0intro char* mntpnt;
11 6f4d00ee 2013-09-23 0intro
12 6f4d00ee 2013-09-23 0intro Srv* next;
13 6f4d00ee 2013-09-23 0intro Srv* prev;
14 6f4d00ee 2013-09-23 0intro };
15 6f4d00ee 2013-09-23 0intro
16 6f4d00ee 2013-09-23 0intro static struct {
17 4b576658 2013-09-23 0intro RWLock lock;
18 6f4d00ee 2013-09-23 0intro
19 6f4d00ee 2013-09-23 0intro Srv* head;
20 6f4d00ee 2013-09-23 0intro Srv* tail;
21 6f4d00ee 2013-09-23 0intro } sbox;
22 6f4d00ee 2013-09-23 0intro
23 b32de4ae 2013-09-26 0intro #ifndef PLAN9PORT
24 6f4d00ee 2013-09-23 0intro static int
25 6f4d00ee 2013-09-23 0intro srvFd(char* name, int mode, int fd, char** mntpnt)
26 6f4d00ee 2013-09-23 0intro {
27 6f4d00ee 2013-09-23 0intro int n, srvfd;
28 6f4d00ee 2013-09-23 0intro char *p, buf[10];
29 6f4d00ee 2013-09-23 0intro
30 6f4d00ee 2013-09-23 0intro /*
31 6f4d00ee 2013-09-23 0intro * Drop a file descriptor with given name and mode into /srv.
32 6f4d00ee 2013-09-23 0intro * Create with ORCLOSE and don't close srvfd so it will be removed
33 6f4d00ee 2013-09-23 0intro * automatically on process exit.
34 6f4d00ee 2013-09-23 0intro */
35 6f4d00ee 2013-09-23 0intro p = smprint("/srv/%s", name);
36 6f4d00ee 2013-09-23 0intro if((srvfd = create(p, ORCLOSE|OWRITE, mode)) < 0){
37 4b576658 2013-09-23 0intro vtfree(p);
38 6f4d00ee 2013-09-23 0intro p = smprint("#s/%s", name);
39 6f4d00ee 2013-09-23 0intro if((srvfd = create(p, ORCLOSE|OWRITE, mode)) < 0){
40 4b576658 2013-09-23 0intro werrstr("create %s: %r", p);
41 4b576658 2013-09-23 0intro vtfree(p);
42 6f4d00ee 2013-09-23 0intro return -1;
43 6f4d00ee 2013-09-23 0intro }
44 6f4d00ee 2013-09-23 0intro }
45 6f4d00ee 2013-09-23 0intro
46 6f4d00ee 2013-09-23 0intro n = snprint(buf, sizeof(buf), "%d", fd);
47 6f4d00ee 2013-09-23 0intro if(write(srvfd, buf, n) < 0){
48 6f4d00ee 2013-09-23 0intro close(srvfd);
49 4b576658 2013-09-23 0intro werrstr("write %s: %r", p);
50 4b576658 2013-09-23 0intro vtfree(p);
51 6f4d00ee 2013-09-23 0intro return -1;
52 6f4d00ee 2013-09-23 0intro }
53 6f4d00ee 2013-09-23 0intro
54 6f4d00ee 2013-09-23 0intro *mntpnt = p;
55 6f4d00ee 2013-09-23 0intro
56 6f4d00ee 2013-09-23 0intro return srvfd;
57 6f4d00ee 2013-09-23 0intro }
58 b32de4ae 2013-09-26 0intro #endif
59 6f4d00ee 2013-09-23 0intro
60 6f4d00ee 2013-09-23 0intro static void
61 6f4d00ee 2013-09-23 0intro srvFree(Srv* srv)
62 6f4d00ee 2013-09-23 0intro {
63 6f4d00ee 2013-09-23 0intro if(srv->prev != nil)
64 6f4d00ee 2013-09-23 0intro srv->prev->next = srv->next;
65 6f4d00ee 2013-09-23 0intro else
66 6f4d00ee 2013-09-23 0intro sbox.head = srv->next;
67 6f4d00ee 2013-09-23 0intro if(srv->next != nil)
68 6f4d00ee 2013-09-23 0intro srv->next->prev = srv->prev;
69 6f4d00ee 2013-09-23 0intro else
70 6f4d00ee 2013-09-23 0intro sbox.tail = srv->prev;
71 6f4d00ee 2013-09-23 0intro
72 6f4d00ee 2013-09-23 0intro if(srv->srvfd != -1)
73 6f4d00ee 2013-09-23 0intro close(srv->srvfd);
74 4b576658 2013-09-23 0intro vtfree(srv->service);
75 4b576658 2013-09-23 0intro vtfree(srv->mntpnt);
76 4b576658 2013-09-23 0intro vtfree(srv);
77 6f4d00ee 2013-09-23 0intro }
78 6f4d00ee 2013-09-23 0intro
79 6f4d00ee 2013-09-23 0intro static Srv*
80 6f4d00ee 2013-09-23 0intro srvAlloc(char* service, int mode, int fd)
81 6f4d00ee 2013-09-23 0intro {
82 6f4d00ee 2013-09-23 0intro Dir *dir;
83 6f4d00ee 2013-09-23 0intro Srv *srv;
84 6f4d00ee 2013-09-23 0intro int srvfd;
85 6f4d00ee 2013-09-23 0intro char *mntpnt;
86 6f4d00ee 2013-09-23 0intro
87 4b576658 2013-09-23 0intro wlock(&sbox.lock);
88 6f4d00ee 2013-09-23 0intro for(srv = sbox.head; srv != nil; srv = srv->next){
89 6f4d00ee 2013-09-23 0intro if(strcmp(srv->service, service) != 0)
90 6f4d00ee 2013-09-23 0intro continue;
91 6f4d00ee 2013-09-23 0intro /*
92 6f4d00ee 2013-09-23 0intro * If the service exists, but is stale,
93 6f4d00ee 2013-09-23 0intro * free it up and let the name be reused.
94 6f4d00ee 2013-09-23 0intro */
95 6f4d00ee 2013-09-23 0intro if((dir = dirfstat(srv->srvfd)) != nil){
96 6f4d00ee 2013-09-23 0intro free(dir);
97 4b576658 2013-09-23 0intro werrstr("srv: already serving '%s'", service);
98 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
99 6f4d00ee 2013-09-23 0intro return nil;
100 6f4d00ee 2013-09-23 0intro }
101 6f4d00ee 2013-09-23 0intro srvFree(srv);
102 6f4d00ee 2013-09-23 0intro break;
103 6f4d00ee 2013-09-23 0intro }
104 6f4d00ee 2013-09-23 0intro
105 b32de4ae 2013-09-26 0intro #ifdef PLAN9PORT
106 b32de4ae 2013-09-26 0intro mntpnt = nil;
107 b32de4ae 2013-09-26 0intro if((srvfd = post9pservice(fd, service, mntpnt)) < 0){
108 b32de4ae 2013-09-26 0intro #else
109 6f4d00ee 2013-09-23 0intro if((srvfd = srvFd(service, mode, fd, &mntpnt)) < 0){
110 b32de4ae 2013-09-26 0intro #endif
111 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
112 6f4d00ee 2013-09-23 0intro return nil;
113 6f4d00ee 2013-09-23 0intro }
114 6f4d00ee 2013-09-23 0intro close(fd);
115 6f4d00ee 2013-09-23 0intro
116 4b576658 2013-09-23 0intro srv = vtmallocz(sizeof(Srv));
117 6f4d00ee 2013-09-23 0intro srv->srvfd = srvfd;
118 4b576658 2013-09-23 0intro srv->service = vtstrdup(service);
119 6f4d00ee 2013-09-23 0intro srv->mntpnt = mntpnt;
120 6f4d00ee 2013-09-23 0intro
121 6f4d00ee 2013-09-23 0intro if(sbox.tail != nil){
122 6f4d00ee 2013-09-23 0intro srv->prev = sbox.tail;
123 6f4d00ee 2013-09-23 0intro sbox.tail->next = srv;
124 6f4d00ee 2013-09-23 0intro }
125 6f4d00ee 2013-09-23 0intro else{
126 6f4d00ee 2013-09-23 0intro sbox.head = srv;
127 6f4d00ee 2013-09-23 0intro srv->prev = nil;
128 6f4d00ee 2013-09-23 0intro }
129 6f4d00ee 2013-09-23 0intro sbox.tail = srv;
130 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
131 6f4d00ee 2013-09-23 0intro
132 6f4d00ee 2013-09-23 0intro return srv;
133 6f4d00ee 2013-09-23 0intro }
134 6f4d00ee 2013-09-23 0intro
135 6f4d00ee 2013-09-23 0intro static int
136 6f4d00ee 2013-09-23 0intro cmdSrv(int argc, char* argv[])
137 6f4d00ee 2013-09-23 0intro {
138 6f4d00ee 2013-09-23 0intro Con *con;
139 6f4d00ee 2013-09-23 0intro Srv *srv;
140 6f4d00ee 2013-09-23 0intro char *usage = "usage: srv [-APWdp] [service]";
141 6f4d00ee 2013-09-23 0intro int conflags, dflag, fd[2], mode, pflag, r;
142 6f4d00ee 2013-09-23 0intro
143 6f4d00ee 2013-09-23 0intro dflag = 0;
144 6f4d00ee 2013-09-23 0intro pflag = 0;
145 6f4d00ee 2013-09-23 0intro conflags = 0;
146 6f4d00ee 2013-09-23 0intro mode = 0666;
147 6f4d00ee 2013-09-23 0intro
148 6f4d00ee 2013-09-23 0intro ARGBEGIN{
149 6f4d00ee 2013-09-23 0intro default:
150 6f4d00ee 2013-09-23 0intro return cliError(usage);
151 6f4d00ee 2013-09-23 0intro case 'A':
152 6f4d00ee 2013-09-23 0intro conflags |= ConNoAuthCheck;
153 6f4d00ee 2013-09-23 0intro break;
154 6f4d00ee 2013-09-23 0intro case 'I':
155 6f4d00ee 2013-09-23 0intro conflags |= ConIPCheck;
156 6f4d00ee 2013-09-23 0intro break;
157 6f4d00ee 2013-09-23 0intro case 'N':
158 6f4d00ee 2013-09-23 0intro conflags |= ConNoneAllow;
159 6f4d00ee 2013-09-23 0intro break;
160 6f4d00ee 2013-09-23 0intro case 'P':
161 6f4d00ee 2013-09-23 0intro conflags |= ConNoPermCheck;
162 6f4d00ee 2013-09-23 0intro mode = 0600;
163 6f4d00ee 2013-09-23 0intro break;
164 6f4d00ee 2013-09-23 0intro case 'W':
165 6f4d00ee 2013-09-23 0intro conflags |= ConWstatAllow;
166 6f4d00ee 2013-09-23 0intro mode = 0600;
167 6f4d00ee 2013-09-23 0intro break;
168 6f4d00ee 2013-09-23 0intro case 'd':
169 6f4d00ee 2013-09-23 0intro dflag = 1;
170 6f4d00ee 2013-09-23 0intro break;
171 6f4d00ee 2013-09-23 0intro case 'p':
172 6f4d00ee 2013-09-23 0intro pflag = 1;
173 6f4d00ee 2013-09-23 0intro mode = 0600;
174 6f4d00ee 2013-09-23 0intro break;
175 6f4d00ee 2013-09-23 0intro }ARGEND
176 6f4d00ee 2013-09-23 0intro
177 6f4d00ee 2013-09-23 0intro if(pflag && (conflags&ConNoPermCheck)){
178 4b576658 2013-09-23 0intro werrstr("srv: cannot use -P with -p");
179 6f4d00ee 2013-09-23 0intro return 0;
180 6f4d00ee 2013-09-23 0intro }
181 6f4d00ee 2013-09-23 0intro
182 6f4d00ee 2013-09-23 0intro switch(argc){
183 6f4d00ee 2013-09-23 0intro default:
184 6f4d00ee 2013-09-23 0intro return cliError(usage);
185 6f4d00ee 2013-09-23 0intro case 0:
186 4b576658 2013-09-23 0intro rlock(&sbox.lock);
187 6f4d00ee 2013-09-23 0intro for(srv = sbox.head; srv != nil; srv = srv->next)
188 6f4d00ee 2013-09-23 0intro consPrint("\t%s\t%d\n", srv->service, srv->srvfd);
189 4b576658 2013-09-23 0intro runlock(&sbox.lock);
190 6f4d00ee 2013-09-23 0intro
191 6f4d00ee 2013-09-23 0intro return 1;
192 6f4d00ee 2013-09-23 0intro case 1:
193 6f4d00ee 2013-09-23 0intro if(!dflag)
194 6f4d00ee 2013-09-23 0intro break;
195 6f4d00ee 2013-09-23 0intro
196 4b576658 2013-09-23 0intro wlock(&sbox.lock);
197 6f4d00ee 2013-09-23 0intro for(srv = sbox.head; srv != nil; srv = srv->next){
198 6f4d00ee 2013-09-23 0intro if(strcmp(srv->service, argv[0]) != 0)
199 6f4d00ee 2013-09-23 0intro continue;
200 6f4d00ee 2013-09-23 0intro srvFree(srv);
201 6f4d00ee 2013-09-23 0intro break;
202 6f4d00ee 2013-09-23 0intro }
203 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
204 6f4d00ee 2013-09-23 0intro
205 6f4d00ee 2013-09-23 0intro if(srv == nil){
206 4b576658 2013-09-23 0intro werrstr("srv: '%s' not found", argv[0]);
207 6f4d00ee 2013-09-23 0intro return 0;
208 6f4d00ee 2013-09-23 0intro }
209 6f4d00ee 2013-09-23 0intro
210 6f4d00ee 2013-09-23 0intro return 1;
211 6f4d00ee 2013-09-23 0intro }
212 6f4d00ee 2013-09-23 0intro
213 b32de4ae 2013-09-26 0intro #ifdef PLAN9PORT /* fossilcons unsupported */
214 b32de4ae 2013-09-26 0intro if(pflag)
215 b32de4ae 2013-09-26 0intro return 1;
216 b32de4ae 2013-09-26 0intro #endif
217 b32de4ae 2013-09-26 0intro
218 6f4d00ee 2013-09-23 0intro if(pipe(fd) < 0){
219 4b576658 2013-09-23 0intro werrstr("srv pipe: %r");
220 6f4d00ee 2013-09-23 0intro return 0;
221 6f4d00ee 2013-09-23 0intro }
222 6f4d00ee 2013-09-23 0intro if((srv = srvAlloc(argv[0], mode, fd[0])) == nil){
223 6f4d00ee 2013-09-23 0intro close(fd[0]); close(fd[1]);
224 6f4d00ee 2013-09-23 0intro return 0;
225 6f4d00ee 2013-09-23 0intro }
226 6f4d00ee 2013-09-23 0intro
227 6f4d00ee 2013-09-23 0intro if(pflag)
228 6f4d00ee 2013-09-23 0intro r = consOpen(fd[1], srv->srvfd, -1);
229 6f4d00ee 2013-09-23 0intro else{
230 6f4d00ee 2013-09-23 0intro con = conAlloc(fd[1], srv->mntpnt, conflags);
231 6f4d00ee 2013-09-23 0intro if(con == nil)
232 6f4d00ee 2013-09-23 0intro r = 0;
233 6f4d00ee 2013-09-23 0intro else
234 6f4d00ee 2013-09-23 0intro r = 1;
235 6f4d00ee 2013-09-23 0intro }
236 6f4d00ee 2013-09-23 0intro if(r == 0){
237 6f4d00ee 2013-09-23 0intro close(fd[1]);
238 4b576658 2013-09-23 0intro wlock(&sbox.lock);
239 6f4d00ee 2013-09-23 0intro srvFree(srv);
240 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
241 6f4d00ee 2013-09-23 0intro }
242 6f4d00ee 2013-09-23 0intro
243 6f4d00ee 2013-09-23 0intro return r;
244 6f4d00ee 2013-09-23 0intro }
245 6f4d00ee 2013-09-23 0intro
246 6f4d00ee 2013-09-23 0intro int
247 6f4d00ee 2013-09-23 0intro srvInit(void)
248 6f4d00ee 2013-09-23 0intro {
249 6f4d00ee 2013-09-23 0intro cliAddCmd("srv", cmdSrv);
250 6f4d00ee 2013-09-23 0intro
251 6f4d00ee 2013-09-23 0intro return 1;
252 6f4d00ee 2013-09-23 0intro }