Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/cs/fs_env.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1990-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Glenn Fowler
23
* AT&T Research
24
*
25
* /env nDFS file server
26
* the top level requests are
27
*
28
* request
29
*
30
* <op> <mount> <path> [pwd=<pwd>] [<name>=<value>] ...
31
*/
32
33
static const char id[] = "@(#)$Id: cs.fs_env (AT&T Research) 1997-05-05 $\0\n";
34
35
#ifndef DEBUG
36
#define DEBUG 1
37
#endif
38
39
#include <cs.h>
40
#include <msg.h>
41
#include <hashkey.h>
42
#include <ctype.h>
43
#include <error.h>
44
#include <debug.h>
45
#include <tok.h>
46
47
#define MAXIO (4*1024)
48
49
#define CON 0
50
#define CMD 1
51
#define KEY 2
52
#define ACT 3
53
54
static const char* state_name[] = { "CON", "CMD", "KEY", "ACT" };
55
56
typedef struct
57
{
58
Cs_id_t id;
59
int state;
60
char key[12];
61
off_t offset;
62
size_t size;
63
char* data;
64
} Connection_t;
65
66
typedef struct
67
{
68
int active;
69
int dormant;
70
char* clone;
71
Connection_t con[1];
72
} State_t;
73
74
static void*
75
svc_init(void* handle, int maxfd)
76
{
77
register State_t* state;
78
register int fd;
79
80
NoP(handle);
81
if (!(state = newof(0, State_t, 1, (maxfd - 1) * sizeof(Connection_t))))
82
exit(1);
83
cstimeout(CS_SVC_DORMANT * 1000L);
84
if ((fd = csopen("/dev/tcp/local/normal", CS_OPEN_CREATE)) < 0)
85
error(ERROR_SYSTEM|3, "cannot create clone connect stream");
86
if (!(state->clone = strdup(cspath(fd, 0))))
87
error(ERROR_SYSTEM|3, "out of space [clone]");
88
state->con[fd].state = CON;
89
csfd(fd, CS_POLL_READ);
90
return (void*)state;
91
}
92
93
static int
94
svc_connect(void* handle, int fd, CSID* id, int clone, char** args)
95
{
96
register State_t* state = (State_t*)handle;
97
98
NoP(fd);
99
NoP(clone);
100
NoP(args);
101
state->active++;
102
state->dormant = 0;
103
state->con[fd].id = *id;
104
state->con[fd].state = CMD;
105
return 0;
106
}
107
108
/*
109
* service a request
110
*/
111
112
static int
113
svc_read(void* handle, int fd)
114
{
115
register State_t* state = (State_t*)handle;
116
register Connection_t* con;
117
register int n;
118
int xd;
119
int err;
120
long ret;
121
char* op;
122
char* logical;
123
char* path;
124
Cs_id_t id;
125
Msg_call_t msg;
126
struct stat st;
127
128
static char buf[(3 * PATH_MAX) / 2 + 1];
129
130
con = state->con + fd;
131
message((-1, "fd=%d state=%s", fd, state_name[con->state]));
132
switch (con->state)
133
{
134
case CMD:
135
if ((n = csread(fd, buf, sizeof(buf), CS_LINE)) <= 1)
136
goto drop;
137
buf[n - 1] = 0;
138
if (tokscan(buf, NiL, " %s %s %s ", &op, &logical, &path) < 1)
139
goto nope;
140
switch (strkey(op))
141
{
142
case HASHKEY5('d','e','b','u','g'):
143
error_info.trace = -strtol(logical, NiL, 10);
144
goto nope;
145
case HASHKEY4('o','p','e','n'):
146
message((-2, "op=%s path=%s", op, path));
147
if (!(op = getenv(path)))
148
goto nope;
149
message((-2, "data=%s", op));
150
n = sfsprintf(buf, sizeof(buf), "/#%s/#%s\n", path, state->clone);
151
message((-2, "challenge `%-.*s'", n, buf));
152
if (cswrite(fd, buf, n) != n)
153
goto drop;
154
return 0;
155
case HASHKEY4('q','u','i','t'):
156
exit(0);
157
break;
158
default:
159
goto nope;
160
}
161
break;
162
case KEY:
163
if ((n = csread(fd, buf, sizeof(buf), CS_LINE)) <= 1)
164
goto drop;
165
buf[n - 1] = 0;
166
if (n <= 2 || !(op = getenv(buf + 2)))
167
goto drop;
168
con->state = ACT;
169
con->data = op;
170
con->size = strlen(op) + 1;
171
con->offset = 0;
172
return 0;
173
case ACT:
174
if (msgrecv(fd, &msg) <= 0)
175
goto drop;
176
if (error_info.trace <= -4)
177
msglist(sfstderr, &msg, 0, 0L);
178
ret = 0;
179
err = 0;
180
op = 0;
181
switch (msg.call)
182
{
183
case MSG_getdents:
184
err = ENOSYS;
185
break;
186
case MSG_read:
187
if ((long)msg.argv[2].number < 0)
188
err = EINVAL;
189
else if ((n = con->size - con->offset) > 0)
190
{
191
if (n > MAXIO)
192
n = MAXIO;
193
if (n > msg.argv[2].number)
194
n = msg.argv[2].number;
195
if (n > 0)
196
{
197
op = con->data + con->offset;
198
con->offset += n;
199
ret = n;
200
}
201
}
202
break;
203
case MSG_seek:
204
switch (msg.argv[2].number)
205
{
206
case SEEK_SET:
207
n = msg.argv[1].number;
208
break;
209
case SEEK_CUR:
210
n = con->offset + msg.argv[1].number;
211
break;
212
case SEEK_END:
213
n = con->size + msg.argv[1].number;
214
break;
215
default:
216
n = -1;
217
break;
218
}
219
if (n < 0)
220
err = EINVAL;
221
else
222
ret = con->offset = n;
223
break;
224
case MSG_stat:
225
memset(&st, 0, sizeof(st));
226
st.st_size = con->size;
227
st.st_mode = S_IRUSR|S_IWUSR;
228
st.st_mtime = st.st_atime = st.st_ctime = cs.time;
229
op = (char*)&st;
230
break;
231
case MSG_write:
232
err = ENOSYS;
233
break;
234
default:
235
err = ENOSYS;
236
break;
237
}
238
if (msgsend(fd, &msg, msg.call, err ? -1 : ret, err, op) <= 0)
239
goto drop;
240
return 0;
241
case CON:
242
if (csrecv(fd, &id, &xd, 1) != 1)
243
goto drop;
244
con = state->con + xd;
245
con->id = id;
246
con->state = KEY;
247
csfd(xd, CS_POLL_READ);
248
state->active++;
249
return 0;
250
default:
251
goto drop;
252
}
253
nope:
254
if (cswrite(fd, "\n", 1) == 1)
255
return 0;
256
drop:
257
state->active--;
258
message((-1, "drop fd=%d", fd));
259
return -1;
260
}
261
262
/*
263
* exit if inactive on timeout
264
*/
265
266
static int
267
svc_timeout(void* handle)
268
{
269
State_t* state = (State_t*)handle;
270
271
if (!state->active)
272
{
273
if (state->dormant)
274
exit(0);
275
state->dormant = 1;
276
}
277
return 0;
278
}
279
280
int
281
main(int argc, char** argv)
282
{
283
static State_t state;
284
285
NoP(argc);
286
cstimeout(CS_SVC_DORMANT * 1000L);
287
csserve(&state, argv[1], svc_init, NiL, svc_connect, svc_read, NiL, svc_timeout);
288
exit(1);
289
}
290
291