xref: /plan9/sys/src/cmd/aux/stub.c (revision 0eaa34de0a46536251d3ec568681dc67b0f0e144)
1 #include <u.h>
2 #include <libc.h>
3 #include <fcall.h>
4 #include <thread.h>
5 #include <9p.h>
6 
7 uint time0;
8 
9 enum
10 {
11 	Qroot = 0,
12 	Qkid,
13 };
14 
15 char *kidname;
16 uint kidmode;
17 
18 void
fsattach(Req * r)19 fsattach(Req *r)
20 {
21 	char *spec;
22 
23 	spec = r->ifcall.aname;
24 	if(spec && spec[0]){
25 		respond(r, "invalid attach specifier");
26 		return;
27 	}
28 	r->ofcall.qid = (Qid){Qroot, 0, QTDIR};
29 	r->fid->qid = r->ofcall.qid;
30 	respond(r, nil);
31 }
32 
33 char*
fswalk1(Fid * fid,char * name,Qid * qid)34 fswalk1(Fid *fid, char *name, Qid *qid)
35 {
36 	switch((int)fid->qid.path){
37 	default:
38 		return "path not found";
39 	case Qroot:
40 		if(strcmp(name, "..") == 0)
41 			break;
42 		if(strcmp(name, kidname) == 0){
43 			fid->qid = (Qid){Qkid, 0, kidmode>>24};
44 			break;
45 		}
46 		return "path not found";
47 	case Qkid:
48 		if(strcmp(name, "..") == 0){
49 			fid->qid = (Qid){Qroot, 0, QTDIR};
50 			break;
51 		}
52 		return "path not found";
53 	}
54 	*qid = fid->qid;
55 	return nil;
56 }
57 
58 void
fsstat(Req * r)59 fsstat(Req *r)
60 {
61 	int q;
62 	Dir *d;
63 
64 	d = &r->d;
65 	memset(d, 0, sizeof *d);
66 	q = r->fid->qid.path;
67 	d->qid = r->fid->qid;
68 	switch(q){
69 	case Qroot:
70 		d->name = estrdup9p("/");
71 		d->mode = DMDIR|0777;
72 		break;
73 
74 	case Qkid:
75 		d->name = estrdup9p(kidname);
76 		d->mode = kidmode;
77 		break;
78 	}
79 
80 	d->atime = d->mtime = time0;
81 	d->uid = estrdup9p("stub");
82 	d->gid = estrdup9p("stub");
83 	d->muid = estrdup9p("");
84 	respond(r, nil);
85 }
86 
87 int
dirgen(int off,Dir * d,void *)88 dirgen(int off, Dir *d, void*)
89 {
90 	if(off != 0)
91 		return -1;
92 
93 	memset(d, 0, sizeof *d);
94 	d->atime = d->mtime = time0;
95 	d->name = estrdup9p(kidname);
96 	d->mode = kidmode;
97 	d->qid = (Qid){Qkid, 0, kidmode>>24};
98 	d->qid.type = d->mode>>24;
99 	d->uid = estrdup9p("stub");
100 	d->gid = estrdup9p("stub");
101 	d->muid = estrdup9p("");
102 	return 0;
103 }
104 
105 void
fsread(Req * r)106 fsread(Req *r)
107 {
108 	int q;
109 
110 	q = r->fid->qid.path;
111 	switch(q){
112 	default:
113 		respond(r, "bug");
114 		return;
115 
116 	case Qroot:
117 		dirread9p(r, dirgen, nil);
118 		respond(r, nil);
119 		return;
120 	}
121 }
122 
123 void
fswrite(Req * r)124 fswrite(Req *r)
125 {
126 	respond(r, "no writing");
127 }
128 
129 void
fsopen(Req * r)130 fsopen(Req *r)
131 {
132 	if(r->fid->qid.path != Qroot){
133 		respond(r, "permission denied");
134 		return;
135 	}
136 
137 	if(r->ifcall.mode != OREAD)
138 		respond(r, "permission denied");
139 	else
140 		respond(r, nil);
141 }
142 
143 Srv fs = {
144 	.attach=	fsattach,
145 	.open=	fsopen,
146 	.read=	fsread,
147 	.write=	fswrite,
148 	.stat=	fsstat,
149 	.walk1=	fswalk1,
150 };
151 
152 void
usage(void)153 usage(void)
154 {
155 	fprint(2, "usage: aux/stub [-Dd] path/name\n");
156 	exits("usage");
157 }
158 
159 void
main(int argc,char ** argv)160 main(int argc, char **argv)
161 {
162 	char *p, *mtpt;
163 
164 	quotefmtinstall();
165 
166 	time0 = time(0);
167 	ARGBEGIN{
168 	case 'D':
169 		chatty9p++;
170 		break;
171 	case 'd':
172 		kidmode = DMDIR;
173 		break;
174 	default:
175 		usage();
176 	}ARGEND
177 
178 	if(argc != 1)
179 		usage();
180 
181 	if((p = strrchr(argv[0], '/')) == 0){
182 		mtpt = ".";
183 		kidname = argv[0];
184 	}else if(p == argv[0]){
185 		mtpt = "/";
186 		kidname = argv[0]+1;
187 	}else{
188 		mtpt = argv[0];
189 		*p++ = '\0';
190 		kidname = p;
191 	}
192 	/* don't leave standard descriptors open to confuse mk */
193 	close(0);
194 	close(1);
195 	close(2);
196 	postmountsrv(&fs, nil, mtpt, MBEFORE);
197 	exits(nil);
198 }
199