Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libcs/csclient.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
* client line by line interaction
26
*/
27
28
#include "cslib.h"
29
30
#include "FEATURE/termios"
31
#if !_lib_tcgetattr || !_lib_tcsetattr
32
#undef _hdr_termios
33
#endif
34
#if _hdr_termios
35
#include <termios.h>
36
#endif
37
38
#if _hdr_termios
39
40
static struct State_s
41
{
42
struct termios new_term; /* raw term for -r */
43
struct termios old_term; /* original term for -r */
44
} state;
45
46
static void
47
restore(void)
48
{
49
tcsetattr(0, TCSANOW, &state.old_term);
50
}
51
52
#endif
53
54
/*
55
* if fd<0 then establish client connection to service
56
* if argv specified then each is a command line to be executed
57
* if CS_CLIENT_ARGV not set then additional commands read from stdin
58
*/
59
60
int
61
csclient(Cs_t* cs, int fd, const char* service, const char* prompt, char** argv, unsigned int flags)
62
{
63
register int i;
64
char* s;
65
Sfio_t* tmp;
66
int done;
67
int promptlen;
68
int timeout;
69
ssize_t n;
70
int sdf[2];
71
Cspoll_t fds[2];
72
char buf[8 * 1024];
73
74
if (fd < 0 && (fd = csopen(cs, service, CS_OPEN_TEST)) < 0)
75
{
76
if (errno == ENOENT)
77
error(3, "%s: server not running", service);
78
else
79
error(ERROR_SYSTEM|3, "%s: cannot open connect stream", service);
80
}
81
#if _hdr_termios
82
if (flags & CS_CLIENT_RAW)
83
{
84
tcgetattr(0, &state.old_term);
85
atexit(restore);
86
state.new_term = state.old_term;
87
state.new_term.c_iflag &= ~(BRKINT|IGNPAR|PARMRK|INLCR|IGNCR|ICRNL);
88
state.new_term.c_lflag &= ~(ECHO|ECHOK|ICANON|ISIG);
89
state.new_term.c_cc[VTIME] = 0;
90
state.new_term.c_cc[VMIN] = 1;
91
tcsetattr(0, TCSANOW, &state.new_term);
92
}
93
#endif
94
sdf[0] = fd;
95
sdf[1] = 1;
96
if (argv && *argv)
97
{
98
fds[0].fd = 1;
99
fds[0].events = CS_POLL_WRITE;
100
}
101
else
102
{
103
argv = 0;
104
fds[0].fd = 0;
105
fds[0].events = CS_POLL_READ;
106
}
107
fds[1].fd = fd;
108
fds[1].events = CS_POLL_READ;
109
done = 0;
110
if (promptlen = (!argv && prompt && isatty(fds[0].fd) && isatty(1)) ? strlen(prompt) : 0)
111
write(1, prompt, promptlen);
112
timeout = CS_NEVER;
113
tmp = 0;
114
while (cspoll(cs, fds, elementsof(fds), timeout) > 0)
115
for (i = 0; i < elementsof(fds); i++)
116
if (fds[i].status & (CS_POLL_READ|CS_POLL_WRITE))
117
{
118
if (!i && argv)
119
{
120
if (!*argv)
121
{
122
argv = 0;
123
fds[0].fd = 0;
124
if (flags & CS_CLIENT_ARGV)
125
{
126
if (done++)
127
return 0;
128
timeout = 500;
129
}
130
fds[0].events = CS_POLL_READ;
131
continue;
132
}
133
if (!tmp && !(tmp = sfstropen()))
134
error(ERROR_SYSTEM|3, "out of space");
135
for (;;)
136
{
137
s = *argv++;
138
if ((flags & CS_CLIENT_SEP) && *s == ':' && !*(s + 1))
139
break;
140
if (sfstrtell(tmp))
141
sfputc(tmp, ' ');
142
sfprintf(tmp, "%s", s);
143
if (!(flags & CS_CLIENT_SEP) || !*argv)
144
break;
145
}
146
sfputc(tmp, '\n');
147
n = sfstrtell(tmp);
148
s = sfstruse(tmp);
149
}
150
else if ((n = read(fds[i].fd, s = buf, sizeof(buf) - 1)) < 0)
151
error(ERROR_SYSTEM|3, "/dev/fd/%d: read error", fds[i].fd);
152
if (!n)
153
{
154
if (done++)
155
return 0;
156
if (!i)
157
write(sdf[i], "quit\n", 5);
158
continue;
159
}
160
if (!i)
161
{
162
#if _hdr_termios
163
register char* u;
164
register int m;
165
166
s[n] = 0;
167
if ((u = strchr(s, 035)))
168
{
169
if ((m = u - s) > 0 && write(sdf[i], s, m) != m)
170
error(ERROR_SYSTEM|3, "/dev/fd/%d: write error", sdf[i]);
171
tcsetattr(0, TCSANOW, &state.old_term);
172
if (promptlen)
173
write(1, prompt, promptlen);
174
if ((n = read(fds[i].fd, s = buf, sizeof(buf) - 1)) <= 0)
175
{
176
write(1, "\n", 1);
177
return 0;
178
}
179
buf[n - 1] = 0;
180
if (*u == 'q' || *u == 'Q')
181
return 0;
182
tcsetattr(0, TCSANOW, &state.new_term);
183
if (*u)
184
error(1, "%s: unknown command", u);
185
continue;
186
}
187
#endif
188
}
189
if (write(sdf[i], s, n) != n)
190
error(ERROR_SYSTEM|3, "/dev/fd/%d: write error", sdf[i]);
191
if (sdf[i] == 1 && promptlen)
192
write(1, prompt, promptlen);
193
}
194
return error_info.errors != 0;
195
}
196
197
int
198
_cs_client(int fd, const char* service, const char* prompt, char** argv, unsigned int flags)
199
{
200
return csclient(&cs, fd, service, prompt, argv, flags);
201
}
202
203