Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libcs/cslocal.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
* open|initiate /dev/fdp/local/<service>/user
26
* coded for bootstrap
27
*/
28
29
#include "cslib.h"
30
31
#include <wait.h>
32
33
#define DEVLOCAL "/dev/fdp/local/"
34
35
#ifdef SIGCHLD
36
37
static int children;
38
39
static void
40
child(int sig)
41
{
42
NoP(sig);
43
children++;
44
}
45
46
#endif
47
48
static int
49
initiate(Cs_t* state, const char* svc, char* cmd)
50
{
51
pid_t pid;
52
pid_t n;
53
char* av[3];
54
55
#ifdef SIGCHLD
56
Handler_t fun;
57
58
children = 0;
59
if ((fun = signal(SIGCHLD, child)) == SIG_DFL) signal(SIGCHLD, fun);
60
else if (children) children++;
61
#endif
62
pathcanon(cmd, 0, 0);
63
av[0] = cmd;
64
av[1] = (char*)svc;
65
av[2] = 0;
66
if ((pid = spawnveg(av[0], av, environ, 0)) == -1)
67
{
68
messagef((state->id, NiL, -1, "local: %s: cannot initiate %s", svc, cmd));
69
return -1;
70
}
71
while ((n = waitpid(pid, NiL, 0)) == -1 && errno == EINTR);
72
#ifdef SIGCHLD
73
if (fun != SIG_DFL)
74
{
75
signal(SIGCHLD, fun);
76
if (fun != SIG_IGN)
77
while (--children > 0)
78
(*fun)(SIGCHLD);
79
}
80
#endif
81
82
/*
83
* yuk: looks like we have to give fdp services time
84
* to start up -- a few seconds shouldn't hurt
85
*/
86
87
sleep(2);
88
return n;
89
}
90
91
int
92
cslocal(register Cs_t* state, const char* path)
93
{
94
register char* s;
95
register char* p;
96
register char* t;
97
register char* v;
98
struct stat st;
99
char cmd[PATH_MAX / 8];
100
char exe[PATH_MAX + 1];
101
char tmp[PATH_MAX + 1];
102
#if CS_LIB_STREAM || CS_LIB_V10 || CS_LIB_SOCKET_UN
103
int fd;
104
int n;
105
#endif
106
107
messagef((state->id, NiL, -8, "local(%s) call", path));
108
109
/*
110
* validate the path
111
*/
112
113
p = (char*)path;
114
if (strncmp(p, DEVLOCAL, sizeof(DEVLOCAL) - 1))
115
{
116
messagef((state->id, NiL, -1, "local: %s: %s* expected", path, DEVLOCAL));
117
goto sorry;
118
}
119
p += sizeof(DEVLOCAL) - 1;
120
for (t = p; *t && *t != '/'; t++);
121
if (!streq(t + 1, "user"))
122
{
123
messagef((state->id, NiL, -1, "local: %s: %s*/user expected", path, DEVLOCAL));
124
goto sorry;
125
}
126
127
/*
128
* locate the service
129
*/
130
131
s = cmd;
132
for (v = p; p <= t; *s++ = *p++);
133
t = s - 1;
134
for (p = v; p <= t; *s++ = *p++);
135
for (p = CS_SVC_SUFFIX; *s++ = *p++;);
136
p = pathbin();
137
for (;;)
138
{
139
p = pathcat(p, ':', "../lib/cs/fdp", cmd, exe, PATH_MAX + 1);
140
if (!eaccess(exe, X_OK) && !stat(exe, &st)) break;
141
if (!p)
142
{
143
messagef((state->id, NiL, -1, "local: %s: %s: cannot locate service on ../lib/cs/fdp", path, cmd));
144
goto sorry;
145
}
146
}
147
*t = 0;
148
sfsprintf(tmp, sizeof(tmp), "%s/fdp/%s/%s/%d-%d-/%c%s", csvar(state, CS_VAR_LOCAL, 0), csname(state, 0), cmd, st.st_uid, geteuid(), CS_MNT_STREAM, CS_MNT_TAIL);
149
150
#if CS_LIB_STREAM || CS_LIB_V10
151
152
for (n = 0; (fd = open(tmp, O_RDWR)) < 0; n++)
153
if (n || errno == EACCES)
154
{
155
messagef((state->id, NiL, -1, "local: %s: %s: cannot open service", path, tmp));
156
return -1;
157
}
158
else if (initiate(state, path, exe) < 0)
159
{
160
messagef((state->id, NiL, -1, "local: %s: %s: cannot initiate service %s", path, tmp, exe));
161
return -1;
162
}
163
messagef((state->id, NiL, -8, "local(%s) fd=%d server=%s stream=%s", path, fd, exe, tmp));
164
return fd;
165
166
#else
167
168
#if CS_LIB_SOCKET_UN
169
170
{
171
int namlen;
172
struct sockaddr_un nam;
173
174
nam.sun_family = AF_UNIX;
175
strcpy(nam.sun_path, tmp);
176
namlen = sizeof(nam.sun_family) + strlen(tmp);
177
n = 0;
178
fd = -1;
179
for (;;)
180
{
181
if (fd < 0 && (fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
182
{
183
messagef((state->id, NiL, -1, "local: %s: AF_UNIX socket error", path));
184
return -1;
185
}
186
if (!connect(fd, (struct sockaddr*)&nam, namlen))
187
{
188
#if CS_LIB_SOCKET_RIGHTS
189
if (read(fd, cmd, 1) != 1)
190
messagef((state->id, NiL, -1, "local: %s: connect ack read error", path));
191
else if (cssend(state, fd, NiL, 0))
192
messagef((state->id, NiL, -1, "local: %s: connect authentication send error", path));
193
else
194
#endif
195
return fd;
196
#if CS_LIB_SOCKET_RIGHTS
197
close(fd);
198
fd = -1;
199
#endif
200
}
201
else messagef((state->id, NiL, -1, "local: %s: connect error", path));
202
if (errno != EACCES) errno = ENOENT;
203
if (n || errno == EACCES || initiate(state, path, exe) < 0)
204
{
205
if (fd >= 0) close(fd);
206
return -1;
207
}
208
n = 1;
209
messagef((state->id, NiL, -1, "local: %s: connect retry", path));
210
}
211
}
212
213
#endif
214
215
#endif
216
217
sorry:
218
errno = ENOENT;
219
return -1;
220
}
221
222
int
223
_cs_local(const char* path)
224
{
225
return cslocal(&cs, path);
226
}
227
228