diff uip/ttyw.c @ 0:bce86c4163a3

Initial revision
author kono
date Mon, 18 Apr 2005 23:46:02 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uip/ttyw.c	Mon Apr 18 23:46:02 2005 +0900
@@ -0,0 +1,134 @@
+#ifndef	BSD42
+#undef	TTYD
+#endif
+
+#ifdef	TTYD
+/* ttyw.c - the writer */
+
+#include <errno.h>
+#include <stdio.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include "../h/netdb.h"
+#ifndef	hpux
+#include <arpa/inet.h>
+#endif
+#include "ttyd.h"
+#include "ttym.c"
+
+struct hostent *mh_gethostbyname();
+
+/*  */
+
+ttyw (command, host, line, user)
+char   *command,
+       *host,
+       *line,
+       *user;
+{
+    int	    privd,
+            sd;
+    unsigned    times;
+    char        buffer[BUFSIZ];
+    struct	hostent *hp;
+    struct	servent *sp;
+    struct sockaddr_in  tty_socket,
+                       *tsock = &tty_socket;
+
+    if (command == NULL) {
+	errno = EINVAL;
+	return NOTOK;
+    }
+
+    if ((sp = getservbyname ("ttyserver", "tcp")) == NULL) {
+	errno = ENETDOWN;
+	return NOTOK;
+    }
+    if (host == NULL)
+	(void) gethostname (host = buffer, sizeof buffer);
+    if ((hp = mh_gethostbyname (host))==NULL) {
+	errno = ENETDOWN;
+	return NOTOK;
+    }
+
+    if (line && strncmp (line, "/dev/", strlen ("/dev/")) == 0)
+	line += strlen ("/dev/");
+
+    privd = *command >= 'A' && *command <= 'Z';/* crude */
+
+/*  */
+
+    for (times = 1; times <= 16; times *= 2) {
+	if ((sd = getport (0, privd)) == NOTOK)
+	    return NOTOK;
+
+	bzero ((char *) tsock, sizeof *tsock);
+	tsock -> sin_family = hp -> h_addrtype;
+	tsock -> sin_port = sp -> s_port;
+	bcopy (hp -> h_addr, (char *) &tsock -> sin_addr, hp -> h_length);
+
+	if (connect (sd, (struct sockaddr *) tsock, sizeof *tsock) == NOTOK) {
+	    (void) close (sd);
+	    if (errno == ECONNREFUSED || errno == EINTR) {
+		sleep (times);
+		continue;
+	    }
+	    break;
+	}
+
+	ttym (sd, command, line, user, NULL);
+	if (ttyv (sd) == NOTOK || ttyv (sd) == NOTOK) {
+	    (void) close (sd);
+	    errno = EPERM;	/* what else??? */
+	    return NOTOK;
+	}
+	else
+	    return sd;
+    }
+
+    return NOTOK;
+}
+
+/*  */
+
+static int  getport (options, privd)
+unsigned    options;
+int     privd;
+{
+    int     sd,
+            port;
+    struct sockaddr_in  unx_socket,
+                       *usock = &unx_socket;
+
+    if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK)
+	return sd;
+
+    if (options & SO_DEBUG)
+	(void) setsockopt (sd, SOL_SOCKET, SO_DEBUG, NULL, 0);
+    (void) setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, NULL, 0);
+
+    if (!privd)
+	return sd;
+
+    usock -> sin_family = AF_INET;
+    usock -> sin_addr.s_addr = INADDR_ANY;
+
+    for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) {
+	usock -> sin_port = htons (port);
+
+	switch (bind (sd, (struct sockaddr *) usock, sizeof *usock)) {
+	    case NOTOK: 
+		if (errno != EADDRINUSE && errno != EADDRNOTAVAIL)
+		    return NOTOK;
+		continue;
+
+	    default: 
+		return sd;
+	}
+    }
+
+    return NOTOK;
+}
+#endif /* TTYD */