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 Srv Srv;
6 6f4d00ee 2013-09-23 0intro struct Srv {
9 6f4d00ee 2013-09-23 0intro char* service;
10 6f4d00ee 2013-09-23 0intro char* mntpnt;
12 6f4d00ee 2013-09-23 0intro Srv* next;
13 6f4d00ee 2013-09-23 0intro Srv* prev;
16 6f4d00ee 2013-09-23 0intro static struct {
17 4b576658 2013-09-23 0intro RWLock lock;
19 6f4d00ee 2013-09-23 0intro Srv* head;
20 6f4d00ee 2013-09-23 0intro Srv* tail;
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)
27 6f4d00ee 2013-09-23 0intro int n, srvfd;
28 6f4d00ee 2013-09-23 0intro char *p, buf[10];
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.
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;
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;
54 6f4d00ee 2013-09-23 0intro *mntpnt = p;
56 6f4d00ee 2013-09-23 0intro return srvfd;
60 6f4d00ee 2013-09-23 0intro static void
61 6f4d00ee 2013-09-23 0intro srvFree(Srv* srv)
63 6f4d00ee 2013-09-23 0intro if(srv->prev != nil)
64 6f4d00ee 2013-09-23 0intro srv->prev->next = srv->next;
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;
70 6f4d00ee 2013-09-23 0intro sbox.tail = srv->prev;
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);
79 6f4d00ee 2013-09-23 0intro static Srv*
80 6f4d00ee 2013-09-23 0intro srvAlloc(char* service, int mode, int fd)
84 6f4d00ee 2013-09-23 0intro int srvfd;
85 6f4d00ee 2013-09-23 0intro char *mntpnt;
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)
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.
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;
101 6f4d00ee 2013-09-23 0intro srvFree(srv);
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){
109 6f4d00ee 2013-09-23 0intro if((srvfd = srvFd(service, mode, fd, &mntpnt)) < 0){
111 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
112 6f4d00ee 2013-09-23 0intro return nil;
114 6f4d00ee 2013-09-23 0intro close(fd);
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;
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;
126 6f4d00ee 2013-09-23 0intro sbox.head = srv;
127 6f4d00ee 2013-09-23 0intro srv->prev = nil;
129 6f4d00ee 2013-09-23 0intro sbox.tail = srv;
130 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
132 6f4d00ee 2013-09-23 0intro return srv;
135 6f4d00ee 2013-09-23 0intro static int
136 6f4d00ee 2013-09-23 0intro cmdSrv(int argc, char* argv[])
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;
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;
148 6f4d00ee 2013-09-23 0intro ARGBEGIN{
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;
154 6f4d00ee 2013-09-23 0intro case 'I':
155 6f4d00ee 2013-09-23 0intro conflags |= ConIPCheck;
157 6f4d00ee 2013-09-23 0intro case 'N':
158 6f4d00ee 2013-09-23 0intro conflags |= ConNoneAllow;
160 6f4d00ee 2013-09-23 0intro case 'P':
161 6f4d00ee 2013-09-23 0intro conflags |= ConNoPermCheck;
162 6f4d00ee 2013-09-23 0intro mode = 0600;
164 6f4d00ee 2013-09-23 0intro case 'W':
165 6f4d00ee 2013-09-23 0intro conflags |= ConWstatAllow;
166 6f4d00ee 2013-09-23 0intro mode = 0600;
168 6f4d00ee 2013-09-23 0intro case 'd':
169 6f4d00ee 2013-09-23 0intro dflag = 1;
171 6f4d00ee 2013-09-23 0intro case 'p':
172 6f4d00ee 2013-09-23 0intro pflag = 1;
173 6f4d00ee 2013-09-23 0intro mode = 0600;
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;
182 6f4d00ee 2013-09-23 0intro switch(argc){
184 6f4d00ee 2013-09-23 0intro return cliError(usage);
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);
191 6f4d00ee 2013-09-23 0intro return 1;
193 6f4d00ee 2013-09-23 0intro if(!dflag)
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);
203 4b576658 2013-09-23 0intro wunlock(&sbox.lock);
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;
210 6f4d00ee 2013-09-23 0intro return 1;
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;
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;
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;
227 6f4d00ee 2013-09-23 0intro if(pflag)
228 6f4d00ee 2013-09-23 0intro r = consOpen(fd[1], srv->srvfd, -1);
230 6f4d00ee 2013-09-23 0intro con = conAlloc(fd[1], srv->mntpnt, conflags);
231 6f4d00ee 2013-09-23 0intro if(con == nil)
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);
243 6f4d00ee 2013-09-23 0intro return r;
247 6f4d00ee 2013-09-23 0intro srvInit(void)
249 6f4d00ee 2013-09-23 0intro cliAddCmd("srv", cmdSrv);
251 6f4d00ee 2013-09-23 0intro return 1;