1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
/*
* Lightweight telnet clone for shping and espping PMDAs.
*
* Usage: telnet-probe [-v] host port
*
* Once telnet connection is established:
* read stdin until EOF, writing to telnet connection
* read telnet until EOF, discarding data
* -c (connect only) flag skips the send-receive processing
*
* Exit status is 1 in the case of any errors, else 0.
*/
#include "pmapi.h"
#include "impl.h"
int
main(int argc, char *argv[])
{
__pmFdSet wfds;
__pmSockAddr *myAddr;
__pmHostEnt *servInfo;
void *enumIx;
int flags = 0;
char *endnum;
int port = 0;
int s;
int errflag = 0;
int cflag = 0;
int vflag = 0;
int sts = 1;
ssize_t bytes;
int ret;
struct timeval canwait = { 5, 000000 };
struct timeval stv;
struct timeval *pstv;
int c;
while ((c = getopt(argc, argv, "cv?")) != EOF) {
switch (c) {
case 'c':
cflag = 1;
break;
case 'v':
vflag = 1;
break;
case '?':
default:
errflag++;
break;
}
}
if (optind+2 != argc) {
fprintf(stderr, "%s: requires two arguments\n", argv[0]);
errflag++;
}
else {
port = (int)strtol(argv[optind+1], &endnum, 10);
if (*endnum != '\0' || port < 0) {
fprintf(stderr, "%s: port must be a positive number\n", argv[0]);
errflag++;
}
}
if (errflag) {
fprintf(stderr, "Usage: %s [-c] [-v] host port\n", argv[0]);
goto done;
}
if ((servInfo = __pmGetAddrInfo(argv[optind])) == NULL) {
if (vflag)
fprintf(stderr, "__pmGetAddrInfo: %s\n", hoststrerror());
goto done;
}
s = -1;
enumIx = NULL;
for (myAddr = __pmHostEntGetSockAddr(servInfo, &enumIx);
myAddr != NULL;
myAddr = __pmHostEntGetSockAddr(servInfo, &enumIx)) {
/* Create a socket */
if (__pmSockAddrIsInet(myAddr))
s = __pmCreateSocket();
else if (__pmSockAddrIsIPv6(myAddr))
s = __pmCreateIPv6Socket();
else
continue;
if (s < 0) {
__pmSockAddrFree(myAddr);
continue; /* Try the next address */
}
/* Attempt to connect */
flags = __pmConnectTo(s, myAddr, port);
__pmSockAddrFree(myAddr);
if (flags < 0) {
/*
* Mark failure in case we fall out the end of the loop
* and try next address. s has been closed in __pmConnectTo().
*/
setoserror(ECONNREFUSED);
s = -1;
continue;
}
/* FNDELAY and we're in progress - wait on select */
stv = canwait;
pstv = (stv.tv_sec || stv.tv_usec) ? &stv : NULL;
__pmFD_ZERO(&wfds);
__pmFD_SET(s, &wfds);
ret = __pmSelectWrite(s+1, &wfds, pstv);
/* Was the connection successful? */
if (ret == 0)
setoserror(ETIMEDOUT);
else if (ret > 0) {
ret = __pmConnectCheckError(s);
if (ret == 0)
break;
setoserror(ret);
}
/* Unsuccessful connection. */
__pmCloseSocket(s);
s = -1;
} /* loop over addresses */
__pmHostEntFree(servInfo);
if (s != -1)
s = __pmConnectRestoreFlags(s, flags);
if (s < 0) {
if (vflag)
fprintf(stderr, "connect: %s\n", netstrerror());
goto done;
}
if (cflag) {
/* skip send-recv exercise */
sts = 0;
goto done;
}
if (vflag)
fprintf(stderr, "send ...\n");
while ((c = getc(stdin)) != EOF) {
if (vflag) {
fputc(c, stderr);
fflush(stderr);
}
if (__pmWrite(s, &c, sizeof(c)) != sizeof(c)) {
if (vflag)
fprintf(stderr, "telnet write: %s\n", osstrerror());
goto done;
}
}
if (vflag)
fprintf(stderr, "recv ...\n");
while ((bytes = __pmRead(s, &c, sizeof(c))) == sizeof(c)) {
if (vflag) {
fputc(c, stderr);
fflush(stderr);
}
}
if (bytes < 0) {
/*
* If __pmSocketClosed(), then treat it as EOF.
*/
if (! __pmSocketClosed()) {
if (vflag)
fprintf(stderr, "telnet read: %s\n", osstrerror());
goto done;
}
}
sts = 0;
done:
if (vflag)
fprintf(stderr, "exit: %d\n", sts);
exit(sts);
}
|