summaryrefslogtreecommitdiff
path: root/src/telnet-probe/telnet-probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/telnet-probe/telnet-probe.c')
-rw-r--r--src/telnet-probe/telnet-probe.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/src/telnet-probe/telnet-probe.c b/src/telnet-probe/telnet-probe.c
new file mode 100644
index 0000000..3754a2d
--- /dev/null
+++ b/src/telnet-probe/telnet-probe.c
@@ -0,0 +1,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);
+}