zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: ztcp
@ 2001-09-08 21:07 Clint Adams
  2001-09-09 18:31 ` Bart Schaefer
  2001-09-10  6:15 ` Module dependencies issue still open Borsenkow Andrej
  0 siblings, 2 replies; 10+ messages in thread
From: Clint Adams @ 2001-09-08 21:07 UTC (permalink / raw)
  To: zsh-workers

This is a bit fragile, but it allows you to
do things such as

% ztcp hostname port
hostname:port is now on fd 5
% stty -F /dev/fd/5 -icanon
% while (( 1 ))
  do
  read -teu5k1
  read -trk1 CHAR && print -rn $CHAR >&5
  done

The stuff at the beginning is mostly just whitespace.

Index: Src/Modules/tcp.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/tcp.c,v
retrieving revision 1.4
diff -u -r1.4 tcp.c
--- Src/Modules/tcp.c	2001/06/15 13:01:42	1.4
+++ Src/Modules/tcp.c	2001/09/08 20:50:55
@@ -1,5 +1,5 @@
 /*
- * tcp.c - builtin FTP client
+ * tcp.c - TCP module
  *
  * This file is part of zsh, the Z shell.
  *
@@ -89,16 +89,16 @@
 mod_export char const *
 zsh_inet_ntop(int af, void const *cp, char *buf, size_t len)
 {       
-        if(af != AF_INET) {
-                errno = EAFNOSUPPORT;
-                return NULL;
-        } 
-        if(len < INET_ADDRSTRLEN) {
-                errno = ENOSPC;
-                return NULL;
-        }
-        strcpy(buf, inet_ntoa(*(struct in_addr *)cp));
-        return buf;
+    if(af != AF_INET) {
+	errno = EAFNOSUPPORT;
+	return NULL;
+    } 
+    if(len < INET_ADDRSTRLEN) {
+	errno = ENOSPC;
+	return NULL;
+    }
+    strcpy(buf, inet_ntoa(*(struct in_addr *)cp));
+    return buf;
 }
 
 /**/
@@ -139,11 +139,11 @@
 mod_export int
 zsh_inet_pton(int af, char const *src, void *dst)
 {
-        if(af != AF_INET) {
-                errno = EAFNOSUPPORT;
-                return -1;
-        }
-        return !!zsh_inet_aton(src, dst);
+    if(af != AF_INET) {
+	errno = EAFNOSUPPORT;
+	return -1;
+    }
+    return !!zsh_inet_aton(src, dst);
 }
 
 #else /* !HAVE_INET_PTON */
@@ -163,11 +163,11 @@
 mod_export struct hostent *
 zsh_gethostbyname2(char const *name, int af)
 {
-	if(af != AF_INET) {
-		h_errno = NO_RECOVERY;
-		return NULL;
-	}
-	return gethostbyname(name);
+    if(af != AF_INET) {
+	h_errno = NO_RECOVERY;
+	return NULL;
+    }
+    return gethostbyname(name);
 }
 
 /**/
@@ -187,28 +187,28 @@
 mod_export struct hostent *
 zsh_getipnodebyname(char const *name, int af, int flags, int *errorp)
 {
-	static struct hostent ahe;
-	static char nbuf[16];
-	static char *addrlist[] = { nbuf, NULL };
+    static struct hostent ahe;
+    static char nbuf[16];
+    static char *addrlist[] = { nbuf, NULL };
 # ifdef SUPPORT_IPV6
-	static char pbuf[INET6_ADDRSTRLEN];
+    static char pbuf[INET6_ADDRSTRLEN];
 # else
-	static char pbuf[INET_ADDRSTRLEN];
+    static char pbuf[INET_ADDRSTRLEN];
 # endif
-	struct hostent *he;
-	if(zsh_inet_pton(af, name, nbuf) == 1) {
-		zsh_inet_ntop(af, nbuf, pbuf, sizeof(pbuf));
-		ahe.h_name = pbuf;
-		ahe.h_aliases = addrlist+1;
-		ahe.h_addrtype = af;
-		ahe.h_length = (af == AF_INET) ? 4 : 16;
-		ahe.h_addr_list = addrlist;
-		return &ahe;
-	}
-	he = zsh_gethostbyname2(name, af);
-	if(!he)
-		*errorp = h_errno;
-	return he;
+    struct hostent *he;
+    if(zsh_inet_pton(af, name, nbuf) == 1) {
+	zsh_inet_ntop(af, nbuf, pbuf, sizeof(pbuf));
+	ahe.h_name = pbuf;
+	ahe.h_aliases = addrlist+1;
+	ahe.h_addrtype = af;
+	ahe.h_length = (af == AF_INET) ? 4 : 16;
+	ahe.h_addr_list = addrlist;
+	return &ahe;
+    }
+    he = zsh_gethostbyname2(name, af);
+    if(!he)
+	*errorp = h_errno;
+    return he;
 }
 
 /**/
@@ -226,29 +226,130 @@
 /**/
 #endif /* !HAVE_GETIPNODEBYNAME */
 
+Tcp_session ztcp_head = NULL, ztcp_tail = NULL;
+
+static Tcp_session
+zts_head(void)
+{
+    return ztcp_head;
+}
+
+static Tcp_session
+zts_next(Tcp_session cur)
+{
+    return cur ? cur->next : NULL;
+}
+
+/* "allocate" a tcp_session */
+static Tcp_session
+zts_alloc(int ztflags)
+{
+    Tcp_session sess;
+
+    sess = (Tcp_session)zcalloc(sizeof(struct tcp_session));
+    if(!sess) return NULL;
+    sess->fd=-1;
+    sess->next=NULL;
+    sess->flags=ztflags;
+
+    if(!zts_head()) {
+	ztcp_head = ztcp_tail = sess;
+    }
+    else {
+	ztcp_tail->next = sess;
+    }
+    return sess;
+}
+
 /**/
-mod_export int
-tcp_socket(int domain, int type, int protocol, Tcp_session sess)
+mod_export Tcp_session
+tcp_socket(int domain, int type, int protocol, int ztflags)
 {
+    Tcp_session sess;
+
+    sess = zts_alloc(ztflags);
+    if(!sess) return NULL;
+
     sess->fd = socket(domain, type, protocol);
-    return sess->fd;
+    return sess;
+}
+
+static int
+zts_delete(Tcp_session sess)
+{
+    Tcp_session tsess;
+
+    tsess = zts_head();
+
+    if(tsess == sess)
+    {
+	ztcp_head = sess->next;
+	free(sess);
+	return 0;
+    }
+
+    while((tsess->next != sess) && (tsess->next))
+    {
+	tsess = zts_next(tsess);
+    }
+
+    if(!tsess->next) return 1;
+
+    tsess->next = tsess->next->next;
+    free(tsess->next);
+    return 0;
+
+}
+
+static Tcp_session
+zts_byfd(int fd)
+{
+    Tcp_session tsess;
+
+    tsess = zts_head();
+
+    do {
+	if(tsess->fd == fd)
+	    return tsess;
+
+	tsess = zts_next(tsess);
+    }
+    while(tsess != NULL);
+
+    return NULL;
 }
 
 static void
 tcp_cleanup(void)
 {
+    Tcp_session sess, prev;
+    
+    for(sess = zts_head(); sess != NULL; sess = zts_next(prev))
+    {
+	prev = sess;
+	tcp_close(sess);
+	zts_delete(sess);
+    }
 }
 
 /**/
 mod_export int
 tcp_close(Tcp_session sess)
 {
-    if(!close(sess->fd))
-    {
-	sess->fd = -1;
+    int err;
+    
+    if(sess->fd != -1)
+    {  
+	err = close(sess->fd);
+	if(err)
+	{
+	    zwarn("connection close failed: %e", NULL, errno);
+	    return -1;
+	}
 	return 0;
     }
-       else return -1;
+
+    return -1;
 }
 
 /**/
@@ -270,12 +371,122 @@
     {
 	memcpy(&(sess->peer.in.sin_addr), addrp, zhost->h_length);
 	sess->peer.in.sin_port = d_port;
+	sess->peer.a.sa_family = zhost->h_addrtype;
 	salen = sizeof(struct sockaddr_in);
     }
 
     return connect(sess->fd, (struct sockaddr *)&(sess->peer), salen);
 }
 
+static int
+bin_ztcp(char *nam, char **args, char *ops, int func)
+{
+    int herrno, err=1, destport, force=0, len;
+    char **addrp, *desthost;
+    struct hostent *zthost = NULL;
+    Tcp_session sess;
+
+    if (ops['f'])
+	force=1;
+    
+    if (ops['c']) {
+	if (!args[0]) {
+	    tcp_cleanup();
+	}
+	else {
+	    int targetfd = atoi(args[0]);
+	    sess = zts_byfd(targetfd);
+
+	    if(sess)
+	    {
+		if((sess->flags & ZTCP_ZFTP) && !force)
+		{
+		    zwarnnam(nam, "use -f to force closure of a zftp control connection", NULL, 0);
+		    return 1;
+		}
+		tcp_close(sess);
+		zts_delete(sess);
+		return 0;
+	    }
+	    else
+	    {
+		zwarnnam(nam, "fd not found in tcp table", NULL, 0);
+		return 1;
+	    }
+	}
+    }
+    else {
+	
+	if (!args[0]) {
+	    for(sess = zts_head(); sess != NULL; sess = zts_next(sess))
+	    {
+		if(sess->fd != -1)
+		{
+		    zthost = gethostbyaddr(&(sess->peer.in.sin_addr), sizeof(struct sockaddr_in), AF_INET);
+		    if(zthost) fprintf(shout, "%s:%d is on fd %d%s\n", zthost->h_name, ntohs(sess->peer.in.sin_port), sess->fd, (sess->flags & ZTCP_ZFTP) ? " ZFTP" : "");
+		    else fprintf(shout, "%s:%d is on fd %d%s\n", "UNKNOWN", sess->peer.in.sin_port, sess->fd, (sess->flags & ZTCP_ZFTP) ? " ZFTP" : "");
+		}
+	    }
+	    return 0;
+	}
+	else if (!args[1]) {
+	    destport = 23;
+	}
+	else {
+	    destport = atoi(args[1]);
+	}
+	
+	desthost = ztrdup(args[0]);
+	
+	zthost = zsh_getipnodebyname(desthost, AF_INET, 0, &herrno);
+	if (!zthost || errflag) {
+	    zwarnnam(nam, "host resolution failure: %s", desthost, 0);
+	    return 1;
+	}
+	
+	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, 0);
+#ifdef SO_OOBINLINE
+	len = 1;
+	setsockopt(sess->fd, SOL_SOCKET, SO_OOBINLINE, (char *)&len, sizeof(len));
+#endif
+
+	if(!sess) {
+	    zwarnnam(nam, "unable to allocate a TCP session slot", NULL, 0);
+	    return 1;
+	}
+	if (sess->fd < 0) {
+	    zwarnnam(nam, "socket creation failed: %e", NULL, errno);
+	    zsfree(desthost);
+	    zts_delete(sess);
+	    return 1;
+	}
+	
+	for (addrp = zthost->h_addr_list; err && *addrp; addrp++) {
+	    if(zthost->h_length != 4)
+		zwarnnam(nam, "address length mismatch", NULL, 0);
+	    do {
+		err = tcp_connect(sess, *addrp, zthost, htons(destport));
+	    } while (err && errno == EINTR && !errflag);
+	}
+	
+	if(err)
+	    zwarnnam(nam, "connection failed: %e", NULL, errno);
+	else
+	{
+	    fprintf(shout, "%s:%d is now on fd %d\n", desthost, destport, sess->fd);
+	}
+	
+	zsfree(desthost);
+    }
+
+    return 0;
+    
+}
+
+static struct builtin bintab[] = {
+    BUILTIN("ztcp", 0, bin_ztcp, 0, 2, 0, "c", NULL),
+};
+
 /* The load/unload routines required by the zsh library interface */
 
 /**/
@@ -289,8 +500,9 @@
 int
 boot_(Module m)
 {
-    return 0;
+    return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
 }
+
 
 /**/
 int
Index: Src/Modules/tcp.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/tcp.h,v
retrieving revision 1.2
diff -u -r1.2 tcp.h
--- Src/Modules/tcp.h	2001/06/08 03:05:50	1.2
+++ Src/Modules/tcp.h	2001/09/08 20:50:55
@@ -63,20 +63,24 @@
 #endif
 
 union tcp_sockaddr {
-	struct sockaddr a;
-	struct sockaddr_in in;
+    struct sockaddr a;
+    struct sockaddr_in in;
 #ifdef SUPPORT_IPV6
-	struct sockaddr_in6 in6;
+    struct sockaddr_in6 in6;
 #endif
 };
 
+typedef struct tcp_session *Tcp_session;
+
+#define ZTCP_ZFTP 16
+
 struct tcp_session {
-	int fd;				/* file descriptor */
-	union tcp_sockaddr sock;  	/* local address   */
-	union tcp_sockaddr peer;  	/* remote address  */
+    int fd;				/* file descriptor */
+    union tcp_sockaddr sock;  	/* local address   */
+    union tcp_sockaddr peer;  	/* remote address  */
+    Tcp_session next;
+    int flags;
 };
-
-typedef struct tcp_session *Tcp_session;
 
 #include "tcp.mdh"
 #include "tcp.pro"
Index: Src/Modules/tcp.mdd
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/tcp.mdd,v
retrieving revision 1.2
diff -u -r1.2 tcp.mdd
--- Src/Modules/tcp.mdd	2001/06/06 19:14:30	1.2
+++ Src/Modules/tcp.mdd	2001/09/08 20:50:56
@@ -3,3 +3,4 @@
 load=no
 
 objects="tcp.o"
+autobins="ztcp"
Index: Src/Modules/zftp.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/zftp.c,v
retrieving revision 1.18
diff -u -r1.18 zftp.c
--- Src/Modules/zftp.c	2001/06/19 06:59:24	1.18
+++ Src/Modules/zftp.c	2001/09/08 20:51:17
@@ -75,10 +75,10 @@
 #endif
 
 union zftp_sockaddr {
-	struct sockaddr a;
-	struct sockaddr_in in;
+    struct sockaddr a;
+    struct sockaddr_in in;
 #ifdef SUPPORT_IPV6
-	struct sockaddr_in6 in6;
+    struct sockaddr_in6 in6;
 #endif
 };
 
@@ -301,7 +301,7 @@
     char **params;		/* parameters ordered as in zfparams */
     char **userparams;		/* user parameters set by zftp_params */
     FILE *cin;			/* control input file */
-    struct tcp_session control;	/* the control connection */
+    Tcp_session control;	/* the control connection */
     int dfd;			/* data connection */
     int has_size;		/* understands SIZE? */
     int has_mdtm;		/* understands MDTM? */
@@ -643,7 +643,7 @@
 		cmdbuf[0] = (char)IAC;
 		cmdbuf[1] = (char)DONT;
 		cmdbuf[2] = ch;
-		write(zfsess->control.fd, cmdbuf, 3);
+		write(zfsess->control->fd, cmdbuf, 3);
 		continue;
 
 	    case DO:
@@ -653,7 +653,7 @@
 		cmdbuf[0] = (char)IAC;
 		cmdbuf[1] = (char)WONT;
 		cmdbuf[2] = ch;
-		write(zfsess->control.fd, cmdbuf, 3);
+		write(zfsess->control->fd, cmdbuf, 3);
 		continue;
 
 	    case EOF:
@@ -703,7 +703,7 @@
     char line[256], *ptr, *verbose;
     int stopit, printing = 0, tmout;
 
-    if (zfsess->control.fd == -1)
+    if ((zfsess->control && zfsess->control->fd == -1))
 	return 6;
     zsfree(lastmsg);
     lastmsg = NULL;
@@ -831,7 +831,7 @@
      */
     int ret, tmout;
 
-    if (zfsess->control.fd == -1)
+    if ((zfsess->control && zfsess->control->fd == -1))
 	return 6;
     tmout = getiparam("ZFTP_TMOUT");
     if (setjmp(zfalrmbuf)) {
@@ -840,7 +840,7 @@
 	return 6;
     }
     zfalarm(tmout);
-    ret = write(zfsess->control.fd, cmd, strlen(cmd));
+    ret = write(zfsess->control->fd, cmd, strlen(cmd));
     alarm(0);
 
     if (ret <= 0) {
@@ -874,7 +874,7 @@
 	int err, salen;
 
 #ifdef SUPPORT_IPV6
-	if(zfsess->control.peer.a.sa_family == AF_INET6)
+	if(zfsess->control->peer.a.sa_family == AF_INET6)
 	    psv_cmd = "EPSV\r\n";
 	else
 #endif /* SUPPORT_IPV6 */
@@ -890,9 +890,9 @@
 	    zfclosedata();
 	    return zfopendata(name, zdsockp, is_passivep);
 	}
-	zdsockp->a.sa_family = zfsess->control.peer.a.sa_family;
+	zdsockp->a.sa_family = zfsess->control->peer.a.sa_family;
 #ifdef SUPPORT_IPV6
-	if(zfsess->control.peer.a.sa_family == AF_INET6) {
+	if(zfsess->control->peer.a.sa_family == AF_INET6) {
 	    /* see RFC 2428 for explanation */
 	    char const *ptr, *end;
 	    char delim, portbuf[6], *pbp;
@@ -920,7 +920,7 @@
 	    portnum = strtoul(portbuf, &pbp, 10);
 	    if(*pbp || portnum > 65535UL)
 		goto bad_epsv;
-	    *zdsockp = zfsess->control.peer;
+	    *zdsockp = zfsess->control->peer;
 	    zdsockp->in6.sin6_port = htons((unsigned)portnum);
 	    salen = sizeof(struct sockaddr_in6);
 	} else
@@ -980,7 +980,7 @@
 	    return 1;
 	}
 
-	*zdsockp = zfsess->control.sock;
+	*zdsockp = zfsess->control->sock;
 #ifdef SUPPORT_IPV6
 	if(zdsockp->a.sa_family == AF_INET6) {
 	    zdsockp->in6.sin6_port = 0;	/* to be set by bind() */
@@ -1015,9 +1015,9 @@
 	    /* see RFC 2428 for explanation */
 	    strcpy(portcmd, "EPRT |2|");
 	    zsh_inet_ntop(AF_INET6, &zdsockp->in6.sin6_addr,
-		portcmd+8, INET6_ADDRSTRLEN);
+			  portcmd+8, INET6_ADDRSTRLEN);
 	    sprintf(strchr(portcmd, 0), "|%u|\r\n",
-		(unsigned)ntohs(zdsockp->in6.sin6_port));
+		    (unsigned)ntohs(zdsockp->in6.sin6_port));
 	} else
 #endif /* SUPPORT_IPV6 */
 	{
@@ -1171,8 +1171,8 @@
     }
 #endif
 #if defined(F_SETFD) && defined(FD_CLOEXEC)
-	/* If the shell execs a program, we don't want this fd left open. */
-	fcntl(zfsess->dfd, F_SETFD, FD_CLOEXEC);
+    /* If the shell execs a program, we don't want this fd left open. */
+    fcntl(zfsess->dfd, F_SETFD, FD_CLOEXEC);
 #endif
 
     return 0;
@@ -1655,8 +1655,8 @@
 
 	/* the following is black magic, as far as I'm concerned. */
 	/* what are we going to do if it fails?  not a lot, actually. */
-	send(zfsess->control.fd, (char *)msg, 3, 0);
-	send(zfsess->control.fd, (char *)msg+3, 1, MSG_OOB);
+	send(zfsess->control->fd, (char *)msg, 3, 0);
+	send(zfsess->control->fd, (char *)msg+3, 1, MSG_OOB);
 
 	zfsendcmd("ABOR\r\n");
 	if (lastcode == 226) {
@@ -1718,7 +1718,7 @@
      * Probably this is the safest thing to do.  It's possible
      * a `QUIT' will hang, though.
      */
-    if (zfsess->control.fd != -1)
+    if ((zfsess->control && zfsess->control->fd != -1))
 	zfclose(0);
 
     /* this is going to give 0.  why bother? */
@@ -1757,12 +1757,12 @@
 # define SUCCEEDED() break
 # define FAILED() if(af == AF_INET) { } else continue
 #else
-    af = AF_INET;
+	af = AF_INET;
 # define SUCCEEDED() do { } while(0)
 # define FAILED() do { } while(0)
 #endif
     {
-    	zhostp = zsh_getipnodebyname(args[0], af, 0, &herrno);
+	zhostp = zsh_getipnodebyname(args[0], af, 0, &herrno);
 	if (!zhostp || errflag) {
 	    /* should use herror() here if available, but maybe
 	     * needs configure test. on AIX it's present but not
@@ -1777,7 +1777,6 @@
 	}
 	zfsetparam("ZFTP_HOST", ztrdup(zhostp->h_name), ZFPM_READONLY);
 
-	zfsess->control.peer.a.sa_family = af;
 #ifdef SUPPORT_IPV6
 	if(af == AF_INET6) {
 	    hlen = 16;
@@ -1786,9 +1785,10 @@
 	{
 	    hlen = 4;
 	}
+
+	zfsess->control = tcp_socket(af, SOCK_STREAM, 0, ZTCP_ZFTP);
 
-	tcp_socket(af, SOCK_STREAM, 0, &(zfsess->control));
-	if (zfsess->control.fd < 0) {
+	if (!(zfsess->control) || (zfsess->control->fd < 0)) {
 	    freehostent(zhostp);
 	    zfunsetparam("ZFTP_HOST");
 	    FAILED();
@@ -1811,7 +1811,7 @@
 	    if(hlen != zhostp->h_length)
 		zwarnnam(name, "address length mismatch", NULL, 0);
 	    do {
-		err = tcp_connect(&(zfsess->control), *addrp, zhostp, zservp->s_port);
+		err = tcp_connect(zfsess->control, *addrp, zhostp, zservp->s_port);
 	    } while (err && errno == EINTR && !errflag);
 	    /* you can check whether it's worth retrying here */
 	}
@@ -1846,15 +1846,15 @@
      * Move the fd out of the user-visible range.  We need to do
      * this after the connect() on some systems.
      */
-    zfsess->control.fd = zfmovefd(zfsess->control.fd);
+    zfsess->control->fd = zfmovefd(zfsess->control->fd);
 
 #if defined(F_SETFD) && defined(FD_CLOEXEC)
     /* If the shell execs a program, we don't want this fd left open. */
-    fcntl(zfsess->control.fd, F_SETFD, FD_CLOEXEC);
+    fcntl(zfsess->control->fd, F_SETFD, FD_CLOEXEC);
 #endif
 
-    len = sizeof(zfsess->control.sock);
-    if (getsockname(zfsess->control.fd, (struct sockaddr *)&zfsess->control.sock, &len) < 0) {
+    len = sizeof(zfsess->control->sock);
+    if (getsockname(zfsess->control->fd, (struct sockaddr *)&zfsess->control->sock, &len) < 0) {
 	zwarnnam(name, "getsockname failed: %e", NULL, errno);
 	zfclose(0);
 	return 1;
@@ -1866,20 +1866,20 @@
      * do clever things with SIGURG.
      */
     len = 1;
-    setsockopt(zfsess->control.fd, SOL_SOCKET, SO_OOBINLINE,
+    setsockopt(zfsess->control->fd, SOL_SOCKET, SO_OOBINLINE,
 	       (char *)&len, sizeof(len));
 #endif
 #if defined(IP_TOS) && defined(IPTOS_LOWDELAY)
     /* for control connection we want low delay.  please don't laugh. */
     len = IPTOS_LOWDELAY;
-    setsockopt(zfsess->control.fd, IPPROTO_IP, IP_TOS, (char *)&len, sizeof(len));
+    setsockopt(zfsess->control->fd, IPPROTO_IP, IP_TOS, (char *)&len, sizeof(len));
 #endif
 
     /*
      * We use stdio with line buffering for convenience on input.
      * On output, we can just dump a complete message to the fd via write().
      */
-    zfsess->cin = fdopen(zfsess->control.fd, "r");
+    zfsess->cin = fdopen(zfsess->control->fd, "r");
 
     if (!zfsess->cin) {
 	zwarnnam(name, "file handling error", NULL, 0);
@@ -1923,17 +1923,17 @@
 	unlink(fname);
     }
 
-    if (zfsess->control.fd == -1) {
+    if (zfsess->control->fd == -1) {
 	/* final paranoid check */
 	return 1;
     }
 	
     zfsetparam("ZFTP_MODE", ztrdup("S"), ZFPM_READONLY);
     /* if remaining arguments, use them to log in. */
-    if (zfsess->control.fd > -1 && *++args)
+    if (zfsess->control->fd > -1 && *++args)
 	return zftp_login(name, args, flags);
     /* if something wayward happened, connection was already closed */
-    return zfsess->control.fd == -1;
+    return zfsess->control->fd == -1;
 }
 
 /*
@@ -1995,7 +1995,7 @@
 	/* '\n' didn't get echoed */
 	fputc('\n', stdout);
 	fflush(stdout);
-    	settyinfo(&shttyinfo);
+	settyinfo(&shttyinfo);
     }
 
     return strret;
@@ -2127,7 +2127,7 @@
     }
 
     zsfree(ucmd);
-    if (zfsess->control.fd == -1)
+    if (zfsess->control->fd == -1)
 	return 1;
     if (stopit == 2 || (lastcode != 230 && lastcode != 202)) {
 	zwarnnam(name, "login failed", NULL, 0);
@@ -2206,7 +2206,7 @@
     struct timeval tv;
 # endif /* HAVE_POLL */
 
-    if (zfsess->control.fd == -1)
+    if (zfsess->control->fd == -1)
 	return 1;
 
 # ifdef HAVE_POLL
@@ -2214,7 +2214,7 @@
     /* safety first, though I think POLLIN is more common */
 #   define POLLIN POLLNORM
 #  endif /* HAVE_POLL */
-    pfd.fd = zfsess->control.fd;
+    pfd.fd = zfsess->control->fd;
     pfd.events = POLLIN;
     if ((ret = poll(&pfd, 1, 0)) < 0 && errno != EINTR && errno != EAGAIN)
 	zfclose(0);
@@ -2224,10 +2224,10 @@
     }
 # else
     FD_ZERO(&f);
-    FD_SET(zfsess->control.fd, &f);
+    FD_SET(zfsess->control->fd, &f);
     tv.tv_sec = 0;
     tv.tv_usec = 0;
-    if ((ret = select(zfsess->control.fd +1, (SELECT_ARG_2_T) &f,
+    if ((ret = select(zfsess->control->fd +1, (SELECT_ARG_2_T) &f,
 		      NULL, NULL, &tv)) < 0
 	&& errno != EINTR)
 	zfclose(0);
@@ -2236,8 +2236,8 @@
 	zfgetmsg();
     }
 # endif /* HAVE_POLL */
-    /* if we now have zfsess->control.fd == -1, then we've just been dumped out. */
-    return (zfsess->control.fd == -1) ? 2 : 0;
+    /* if we now have zfsess->control->fd == -1, then we've just been dumped out. */
+    return (zfsess->control->fd == -1) ? 2 : 0;
 #else
     zfwarnnam(name, "not supported on this system.", NULL, 0);
     return 3;
@@ -2659,7 +2659,7 @@
     char **aptr;
     Eprog prog;
 
-    if (zfsess->control.fd == -1)
+    if (zfsess->control->fd == -1)
 	return;
 
     zfclosing = 1;
@@ -2675,9 +2675,9 @@
 	fclose(zfsess->cin);
 	zfsess->cin = NULL;
     }
-    if (zfsess->control.fd != -1) {
+    if (zfsess->control->fd != -1) {
 	zfnopen--;
-	tcp_close(&(zfsess->control));
+	tcp_close(zfsess->control);
     }
 
     if (zfstatfd != -1) {
@@ -2750,7 +2750,7 @@
     if (!nptr) {
 	zfsess = (Zftp_session) zcalloc(sizeof(struct zftp_session));
 	zfsess->name = ztrdup(nm);
-	zfsess->control.fd = zfsess->dfd = -1;
+	zfsess->dfd = -1;
 	zfsess->params = (char **) zcalloc(sizeof(zfparams));
 	zaddlinknode(zfsessions, zfsess);
 
@@ -2965,7 +2965,7 @@
 	int oldstatus = zfstatusp[zfsessno];
 	lseek(zfstatfd, 0, 0);
 	read(zfstatfd, (char *)zfstatusp, sizeof(int)*zfsesscnt);
-	if (zfsess->control.fd != -1 && (zfstatusp[zfsessno] & ZFST_CLOS)) {
+	if ((zfsess->control && zfsess->control->fd != -1) && (zfstatusp[zfsessno] & ZFST_CLOS)) {
 	    /* got closed in subshell without us knowing */
 	    zcfinish = 2;
 	    zfclose(0);
@@ -2986,7 +2986,7 @@
 	}
     }
 #if defined(HAVE_SELECT) || defined (HAVE_POLL)
-    if (zfsess->control.fd != -1 && !(zptr->flags & (ZFTP_TEST|ZFTP_SESS))) {
+    if ((zfsess->control && zfsess->control->fd != -1) && !(zptr->flags & (ZFTP_TEST|ZFTP_SESS))) {
 	/*
 	 * Test the connection for a bad fd or incoming message, but
 	 * only if the connection was last heard of open, and
@@ -2996,7 +2996,7 @@
 	ret = zftp_test("zftp test", NULL, 0);
     }
 #endif
-    if ((zptr->flags & ZFTP_CONN) && zfsess->control.fd == -1) {
+    if ((zptr->flags & ZFTP_CONN) && (zfsess->control && zfsess->control->fd == -1)) {
 	if (ret != 2) {
 	    /*
 	     * with ret == 2, we just got dumped out in the test,


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: PATCH: ztcp
  2001-09-08 21:07 PATCH: ztcp Clint Adams
@ 2001-09-09 18:31 ` Bart Schaefer
  2001-09-09 22:01   ` Clint Adams
  2001-09-10  6:15 ` Module dependencies issue still open Borsenkow Andrej
  1 sibling, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2001-09-09 18:31 UTC (permalink / raw)
  To: Clint Adams, zsh-workers

On Sep 8,  5:07pm, Clint Adams wrote:
} 
} % ztcp hostname port
} hostname:port is now on fd 5

Rather than print this to stdout, you'd be better off stuffing it into
te value of the $REPLY parameter, or allowing the caller to pass a
parameter name into which the fd number would be stuffed.

Even better, allow the caller to pass in an fd number to which the new
connection will be dup2'd.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: PATCH: ztcp
  2001-09-09 18:31 ` Bart Schaefer
@ 2001-09-09 22:01   ` Clint Adams
  2001-09-09 23:30     ` Bart Schaefer
  0 siblings, 1 reply; 10+ messages in thread
From: Clint Adams @ 2001-09-09 22:01 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

> Rather than print this to stdout, you'd be better off stuffing it into
> te value of the $REPLY parameter, or allowing the caller to pass a
> parameter name into which the fd number would be stuffed.
> 
> Even better, allow the caller to pass in an fd number to which the new
> connection will be dup2'd.

This does the first.  Also lets you use service names in lieu of
port numbers.

I don't understand what fd duplication buys you.

Index: Src/Modules/tcp.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/tcp.c,v
retrieving revision 1.7
diff -u -r1.7 tcp.c
--- Src/Modules/tcp.c	2001/09/09 09:39:25	1.7
+++ Src/Modules/tcp.c	2001/09/09 21:40:37
@@ -384,6 +384,7 @@
     int herrno, err=1, destport, force=0, verbose=0, len, rfd;
     char **addrp, *desthost, *localname, *remotename;
     struct hostent *zthost = NULL, *ztpeer = NULL;
+    struct servent *srv;
     Tcp_session sess;
 
     if (ops['f'])
@@ -419,18 +420,22 @@
 	}
     }
     else if (ops['l']) {
-	int lport;
+	int lport = 0;
 
 	if (!args[0]) {
 	    zwarnnam(nam, "-l requires an argument", NULL, 0);
 	    return 1;
 	}
-	lport = atoi(args[0]);
-	if (!lport) {
-	    zwarnnam(nam, "bad port number", NULL, 0);
-	    return 1;
+
+	srv = getservbyname(args[0],"tcp");
+	if (srv)
+	    lport = srv->s_port;
+	else
+	    lport = htons(atoi(args[0]));
+	if (!lport) { zwarnnam(nam, "bad service name or port number", NULL, 0);
+	return 1;
 	}
-	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, 0);
+	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, ZTCP_INBOUND);
 
 	if (!sess) {
 	    zwarnnam(nam, "unable to allocate a TCP session slot", NULL, 0);
@@ -447,7 +452,7 @@
 	}
 
 	sess->sock.in.sin_family = AF_INET;
-	sess->sock.in.sin_port = htons(lport);
+	sess->sock.in.sin_port = lport;
 
 
 	if (bind(sess->fd, (struct sockaddr *)&sess->sock.in, sizeof(struct sockaddr_in)))
@@ -481,8 +486,11 @@
 	    return -1;
 	}
 	sess->fd = rfd;
+
+	setiparam("REPLY", sess->fd);
 
-	fprintf(shout, "%d is on fd %d\n", ntohs(sess->peer.in.sin_port), sess->fd);
+	if(verbose)
+	    fprintf(shout, "%d is on fd %d\n", ntohs(sess->peer.in.sin_port), sess->fd);
 
 	return 0;
 
@@ -504,16 +512,21 @@
 			remotename = ztpeer->h_name;
 		    else
 			remotename = ztrdup(inet_ntoa(sess->sock.in.sin_addr));
-		    fprintf(shout, "%s:%d -> %s:%d is on fd %d%s%s\n", localname, ntohs(sess->sock.in.sin_port), remotename, ntohs(sess->peer.in.sin_port), sess->fd, (sess->flags & ZTCP_ZFTP) ? " ZFTP" : "", (sess->flags & ZTCP_INBOUND) ? "INBOUND" : "");
+		    fprintf(shout, "%s:%d %s %s:%d is on fd %d%s\n", localname, ntohs(sess->sock.in.sin_port), (sess->flags & ZTCP_INBOUND) ? "<-" : "->", remotename, ntohs(sess->peer.in.sin_port), sess->fd, (sess->flags & ZTCP_ZFTP) ? " ZFTP" : "");
 		}
 	    }
 	    return 0;
 	}
 	else if (!args[1]) {
-	    destport = 23;
+	    destport = htons(23);
 	}
 	else {
-	    destport = atoi(args[1]);
+
+	    srv = getservbyname(args[1],"tcp");
+	    if (srv)
+		destport = srv->s_port;
+	    else
+		destport = htons(atoi(args[1]));
 	}
 	
 	desthost = ztrdup(args[0]);
@@ -547,7 +560,7 @@
 	    if (zthost->h_length != 4)
 		zwarnnam(nam, "address length mismatch", NULL, 0);
 	    do {
-		err = tcp_connect(sess, *addrp, zthost, htons(destport));
+		err = tcp_connect(sess, *addrp, zthost, destport);
 	    } while (err && errno == EINTR && !errflag);
 	}
 	
@@ -555,10 +568,10 @@
 	    zwarnnam(nam, "connection failed: %e", NULL, errno);
 	else
 	{
+	    setiparam("REPLY", sess->fd);
+
 	    if (verbose)
 		fprintf(shout, "%s:%d is now on fd %d\n", desthost, destport, sess->fd);
-	    else
-		fprintf(shout, "%d\n", sess->fd);
 	}
 	
 	zsfree(desthost);


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: PATCH: ztcp
  2001-09-09 22:01   ` Clint Adams
@ 2001-09-09 23:30     ` Bart Schaefer
  2001-09-10  0:06       ` Clint Adams
  0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2001-09-09 23:30 UTC (permalink / raw)
  To: Clint Adams; +Cc: zsh-workers

On Sep 9,  6:01pm, Clint Adams wrote:
} 
} I don't understand what fd duplication buys you.

It lets you choose a specific fd to which to assign the descriptor, rather
than having to take whatever you get.  In POSIX emulation mode, fds > 9
can't [*] be redirected to/from, so it's important to be able to specify
a known-free number.

[*] Actually, it does work, but it's a bug in zsh's POSIX emulation and
shouldn't be relied upon.

Incidentally, I did mention your objection to /dev/tcp/portname on the
shell mailing list, but the response was that several unix variants have
already implemented /dev/tcp/* as special files, so the shell would only
be emulating that interface on platforms that don't support it, much as
zsh already does with /dev/fd/.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: PATCH: ztcp
  2001-09-09 23:30     ` Bart Schaefer
@ 2001-09-10  0:06       ` Clint Adams
  2001-09-10 11:09         ` Oliver Kiddle
  0 siblings, 1 reply; 10+ messages in thread
From: Clint Adams @ 2001-09-10  0:06 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

> It lets you choose a specific fd to which to assign the descriptor, rather
> than having to take whatever you get.  In POSIX emulation mode, fds > 9
> can't [*] be redirected to/from, so it's important to be able to specify
> a known-free number.

I had imagined that you could do something like 'exec 9<&$REPLY'
if you wanted to pick the fd.  Unfortunately this doesn't
update the session table.

> Incidentally, I did mention your objection to /dev/tcp/portname on the
> shell mailing list, but the response was that several unix variants have
> already implemented /dev/tcp/* as special files, so the shell would only
> be emulating that interface on platforms that don't support it, much as
> zsh already does with /dev/fd/.

Hmm.  Is there a spec yet, or is bash just the reference implementation?


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Module dependencies issue still open
  2001-09-08 21:07 PATCH: ztcp Clint Adams
  2001-09-09 18:31 ` Bart Schaefer
@ 2001-09-10  6:15 ` Borsenkow Andrej
  2001-09-10 10:58   ` Peter Stephenson
  1 sibling, 1 reply; 10+ messages in thread
From: Borsenkow Andrej @ 2001-09-10  6:15 UTC (permalink / raw)
  To: 'Clint Adams', zsh-workers

What was final decision (if any) on module dependencies problem (when
one external module depends on another one)? There was some discussion,
but I do not remember any solution was accepted. 

-andrej


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Module dependencies issue still open
  2001-09-10  6:15 ` Module dependencies issue still open Borsenkow Andrej
@ 2001-09-10 10:58   ` Peter Stephenson
  0 siblings, 0 replies; 10+ messages in thread
From: Peter Stephenson @ 2001-09-10 10:58 UTC (permalink / raw)
  To: Zsh hackers list

Borsenkow Andrej wrote:
> What was final decision (if any) on module dependencies problem (when
> one external module depends on another one)? There was some discussion,
> but I do not remember any solution was accepted. 

No, indeed.

I still think we need to use RTLD_LAZY properly on systems that support it,
allowing us to hook in required modules from the appropriate module boot
routine.  This can be done without any change of format or introducing
incompatibilities --- except we may need to be more careful with data
symbols which need to be resolved when the module is loaded, and I haven't
investigated how much of a problem this is is.  It's possible there aren't
any inter-module dependencies of this kind (there are already some hooks
for this kind of thing built into the main module).

For the rest, I'm agnostic between burying something in the .so files (bit
hacky) or adding an extra dependency (.zd?) file (bit messy), which seem to
be the major possibilities.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR Ltd., Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: PATCH: ztcp
  2001-09-10  0:06       ` Clint Adams
@ 2001-09-10 11:09         ` Oliver Kiddle
  2001-09-10 15:20           ` Clint Adams
  0 siblings, 1 reply; 10+ messages in thread
From: Oliver Kiddle @ 2001-09-10 11:09 UTC (permalink / raw)
  To: zsh-workers

 --- Clint Adams <clint@zsh.org> wrote: >
> 
> I had imagined that you could do something like 'exec 9<&$REPLY'
> if you wanted to pick the fd.  Unfortunately this doesn't
> update the session table.

I think it is better as Bart suggested with the option to specify a
choice of fd because for everything else, you need to manage fd numbers
yourself.

What might be quite useful though is some sort of special variable
which would generate an unused fd number so you can do something like:
  ztcp -u ${fd:=$NEWFD} host:port
and then use $fd thereafter for the file descriptor.

> > Incidentally, I did mention your objection to /dev/tcp/portname on
> the
> > shell mailing list, but the response was that several unix variants
> 
> Hmm.  Is there a spec yet, or is bash just the reference
implementation? 

I doubt there will be any spec for quite some time. I also doubt that
bash or any other particular shell will be declared the reference
implementation though any new feature will need at least one
implementation.

Oliver

____________________________________________________________
Do You Yahoo!?
Get your free @yahoo.co.uk address at http://mail.yahoo.co.uk
or your free @yahoo.ie address at http://mail.yahoo.ie


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: PATCH: ztcp
  2001-09-10 11:09         ` Oliver Kiddle
@ 2001-09-10 15:20           ` Clint Adams
  2001-09-10 15:37             ` Clint Adams
  0 siblings, 1 reply; 10+ messages in thread
From: Clint Adams @ 2001-09-10 15:20 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: zsh-workers

> I think it is better as Bart suggested with the option to specify a
> choice of fd because for everything else, you need to manage fd numbers
> yourself.

Well, here goes.  I am utterly perplexed because,
if I am not hallucinating, the desthost = ztrdup(arg[0]);
is actually passing the args[0] pointer, and thus
it chokes.

Index: Src/Modules/tcp.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/tcp.c,v
retrieving revision 1.12
diff -u -r1.12 tcp.c
--- Src/Modules/tcp.c	2001/09/10 12:37:22	1.12
+++ Src/Modules/tcp.c	2001/09/10 15:17:02
@@ -298,7 +298,7 @@
     if (!tsess->next) return 1;
 
     if (ztcp_tail == sess)
-	    ztcp_tail = tsess;
+	ztcp_tail = tsess;
     tsess->next = sess->next;
     free(sess);
     return 0;
@@ -385,8 +385,8 @@
 static int
 bin_ztcp(char *nam, char **args, char *ops, int func)
 {
-    int herrno, err=1, destport, force=0, verbose=0, test=0, len;
-    char **addrp, *desthost, *localname, *remotename;
+    int herrno, err=1, destport, force=0, verbose=0, test=0, targetfd=0, len;
+    char **addrp, *desthost, *localname, *remotename, **arg = args;
     struct hostent *zthost = NULL, *ztpeer = NULL;
     struct servent *srv;
     Tcp_session sess = NULL;
@@ -399,14 +399,29 @@
 
     if (ops['t'])
         test = 1;
+
+    if (ops['d']) {
+	targetfd = atoi(arg[0]);
+	arg++;
+	if (!targetfd) {
+	    zwarnnam(nam, "%s is an invalid argument to -d", args[0], 0);
+	    return 1;
+	}
+    }
+
+
     
     if (ops['c']) {
-	if (!args[0]) {
+	if (!arg[0]) {
 	    tcp_cleanup();
 	}
 	else {
-	    int targetfd = atoi(args[0]);
+	    targetfd = atoi(arg[0]);
 	    sess = zts_byfd(targetfd);
+	    if(!targetfd) {
+		zwarnnam(nam, "%s is an invalid argument to -c", arg[0], 0);
+		return 1;
+	    }
 
 	    if (sess)
 	    {
@@ -420,7 +435,7 @@
 	    }
 	    else
 	    {
-		zwarnnam(nam, "fd %s not found in tcp table", args[0], 0);
+		zwarnnam(nam, "fd %s not found in tcp table", arg[0], 0);
 		return 1;
 	    }
 	}
@@ -428,16 +443,16 @@
     else if (ops['l']) {
 	int lport = 0;
 
-	if (!args[0]) {
+	if (!arg[0]) {
 	    zwarnnam(nam, "-l requires an argument", NULL, 0);
 	    return 1;
 	}
 
-	srv = getservbyname(args[0], "tcp");
+	srv = getservbyname(arg[0], "tcp");
 	if (srv)
 	    lport = srv->s_port;
 	else
-	    lport = htons(atoi(args[0]));
+	    lport = htons(atoi(arg[0]));
 	if (!lport) { zwarnnam(nam, "bad service name or port number", NULL, 0);
 	return 1;
 	}
@@ -475,8 +490,14 @@
 	    return 1;
 	}
 
-	/* move the fd since no one will want to read from it */
-	sess->fd = movefd(sess->fd);
+	if (targetfd) {
+	    redup(sess->fd,targetfd);
+	    sess->fd = targetfd;
+	}
+	else {
+	    /* move the fd since no one will want to read from it */
+	    sess->fd = movefd(sess->fd);
+	}
 
 	setiparam("REPLY", sess->fd);
 
@@ -490,12 +511,12 @@
     {
 	int lfd, rfd;
 
-	if (!args[0]) {
+	if (!arg[0]) {
 	    zwarnnam(nam, "-a requires an argument", NULL, 0);
 	    return 1;
 	}
 
-	lfd = atoi(args[0]);
+	lfd = atoi(arg[0]);
 
 	if (!lfd) {
 	    zwarnnam(nam, "invalid numerical argument", NULL, 0);
@@ -504,7 +525,7 @@
 
 	sess = zts_byfd(lfd);
 	if (!sess) {
-	    zwarnnam(nam, "fd %s is not registered as a tcp connection", args[0], 0);
+	    zwarnnam(nam, "fd %s is not registered as a tcp connection", arg[0], 0);
 	    return 1;
 	}
 
@@ -535,8 +556,15 @@
 	    zwarnnam(nam, "could not accept connection: %e", NULL, errno);
 	    tcp_close(sess);
 	    return 1;
+	}
+
+	if (targetfd) {
+	    redup(rfd, targetfd);
+	    sess->fd = targetfd;
+	}
+	else {
+	    sess->fd = rfd;
 	}
-	sess->fd = rfd;
 
 	setiparam("REPLY", sess->fd);
 
@@ -547,7 +575,7 @@
     else
     {
 	
-	if (!args[0]) {
+	if (!arg[0]) {
 	    for(sess = zts_head(); sess != NULL; sess = zts_next(sess))
 	    {
 		if (sess->fd != -1)
@@ -567,19 +595,19 @@
 	    }
 	    return 0;
 	}
-	else if (!args[1]) {
+	else if (!arg[1]) {
 	    destport = htons(23);
 	}
 	else {
 
-	    srv = getservbyname(args[1],"tcp");
+	    srv = getservbyname(arg[1],"tcp");
 	    if (srv)
 		destport = srv->s_port;
 	    else
-		destport = htons(atoi(args[1]));
+		destport = htons(atoi(arg[1]));
 	}
 	
-	desthost = ztrdup(args[0]);
+	desthost = ztrdup(arg[0]);
 	
 	zthost = zsh_getipnodebyname(desthost, AF_INET, 0, &herrno);
 	if (!zthost || errflag) {
@@ -614,10 +642,17 @@
 	    } while (err && errno == EINTR && !errflag);
 	}
 	
-	if (err)
+	if (err) {
 	    zwarnnam(nam, "connection failed: %e", NULL, errno);
+	    tcp_close(sess);
+	}
 	else
 	{
+	    if (targetfd) {
+		redup(sess->fd, targetfd);
+		sess->fd = targetfd;
+	    }
+
 	    setiparam("REPLY", sess->fd);
 
 	    if (verbose)
@@ -632,7 +667,7 @@
 }
 
 static struct builtin bintab[] = {
-    BUILTIN("ztcp", 0, bin_ztcp, 0, 2, 0, "acfltv", NULL),
+    BUILTIN("ztcp", 0, bin_ztcp, 0, 3, 0, "acdfltv", NULL),
 };
 
 /* The load/unload routines required by the zsh library interface */


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: PATCH: ztcp
  2001-09-10 15:20           ` Clint Adams
@ 2001-09-10 15:37             ` Clint Adams
  0 siblings, 0 replies; 10+ messages in thread
From: Clint Adams @ 2001-09-10 15:37 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: zsh-workers

> Well, here goes.  I am utterly perplexed because,
> if I am not hallucinating, the desthost = ztrdup(arg[0]);
> is actually passing the args[0] pointer, and thus
> it chokes.

I was hallucinating, so this is unnecessary.

Index: Src/Modules/tcp.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/tcp.c,v
retrieving revision 1.13
diff -u -r1.13 tcp.c
--- Src/Modules/tcp.c	2001/09/10 15:23:38	1.13
+++ Src/Modules/tcp.c	2001/09/10 15:36:07
@@ -386,7 +386,7 @@
 bin_ztcp(char *nam, char **args, char *ops, int func)
 {
     int herrno, err=1, destport, force=0, verbose=0, test=0, targetfd=0, len;
-    char **addrp, *desthost, *localname, *remotename, **arg = args;
+    char **addrp, *desthost, *localname, *remotename, **dargs;
     struct hostent *zthost = NULL, *ztpeer = NULL;
     struct servent *srv;
     Tcp_session sess = NULL;
@@ -401,25 +401,27 @@
         test = 1;
 
     if (ops['d']) {
-	targetfd = atoi(arg[0]);
-	arg++;
+	targetfd = atoi(args[0]);
+	dargs = args + 1;
 	if (!targetfd) {
 	    zwarnnam(nam, "%s is an invalid argument to -d", args[0], 0);
 	    return 1;
 	}
     }
+    else
+	dargs = args;
 
 
     
     if (ops['c']) {
-	if (!arg[0]) {
+	if (!dargs[0]) {
 	    tcp_cleanup();
 	}
 	else {
-	    targetfd = atoi(arg[0]);
+	    targetfd = atoi(dargs[0]);
 	    sess = zts_byfd(targetfd);
 	    if(!targetfd) {
-		zwarnnam(nam, "%s is an invalid argument to -c", arg[0], 0);
+		zwarnnam(nam, "%s is an invalid argument to -c", dargs[0], 0);
 		return 1;
 	    }
 
@@ -435,7 +437,7 @@
 	    }
 	    else
 	    {
-		zwarnnam(nam, "fd %s not found in tcp table", arg[0], 0);
+		zwarnnam(nam, "fd %s not found in tcp table", dargs[0], 0);
 		return 1;
 	    }
 	}
@@ -443,16 +445,16 @@
     else if (ops['l']) {
 	int lport = 0;
 
-	if (!arg[0]) {
+	if (!dargs[0]) {
 	    zwarnnam(nam, "-l requires an argument", NULL, 0);
 	    return 1;
 	}
 
-	srv = getservbyname(arg[0], "tcp");
+	srv = getservbyname(dargs[0], "tcp");
 	if (srv)
 	    lport = srv->s_port;
 	else
-	    lport = htons(atoi(arg[0]));
+	    lport = htons(atoi(dargs[0]));
 	if (!lport) { zwarnnam(nam, "bad service name or port number", NULL, 0);
 	return 1;
 	}
@@ -511,12 +513,12 @@
     {
 	int lfd, rfd;
 
-	if (!arg[0]) {
+	if (!dargs[0]) {
 	    zwarnnam(nam, "-a requires an argument", NULL, 0);
 	    return 1;
 	}
 
-	lfd = atoi(arg[0]);
+	lfd = atoi(dargs[0]);
 
 	if (!lfd) {
 	    zwarnnam(nam, "invalid numerical argument", NULL, 0);
@@ -525,7 +527,7 @@
 
 	sess = zts_byfd(lfd);
 	if (!sess) {
-	    zwarnnam(nam, "fd %s is not registered as a tcp connection", arg[0], 0);
+	    zwarnnam(nam, "fd %s is not registered as a tcp connection", dargs[0], 0);
 	    return 1;
 	}
 
@@ -575,7 +577,7 @@
     else
     {
 	
-	if (!arg[0]) {
+	if (!dargs[0]) {
 	    for(sess = zts_head(); sess != NULL; sess = zts_next(sess))
 	    {
 		if (sess->fd != -1)
@@ -595,19 +597,19 @@
 	    }
 	    return 0;
 	}
-	else if (!arg[1]) {
+	else if (!dargs[1]) {
 	    destport = htons(23);
 	}
 	else {
 
-	    srv = getservbyname(arg[1],"tcp");
+	    srv = getservbyname(dargs[1],"tcp");
 	    if (srv)
 		destport = srv->s_port;
 	    else
-		destport = htons(atoi(arg[1]));
+		destport = htons(atoi(dargs[1]));
 	}
 	
-	desthost = ztrdup(arg[0]);
+	desthost = ztrdup(dargs[0]);
 	
 	zthost = zsh_getipnodebyname(desthost, AF_INET, 0, &herrno);
 	if (!zthost || errflag) {


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2001-09-10 15:38 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-08 21:07 PATCH: ztcp Clint Adams
2001-09-09 18:31 ` Bart Schaefer
2001-09-09 22:01   ` Clint Adams
2001-09-09 23:30     ` Bart Schaefer
2001-09-10  0:06       ` Clint Adams
2001-09-10 11:09         ` Oliver Kiddle
2001-09-10 15:20           ` Clint Adams
2001-09-10 15:37             ` Clint Adams
2001-09-10  6:15 ` Module dependencies issue still open Borsenkow Andrej
2001-09-10 10:58   ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).