[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Replace history's "<remote>" with client's IP
From: |
Mark D. Baushke |
Subject: |
Re: Replace history's "<remote>" with client's IP |
Date: |
Tue, 18 Oct 2005 14:22:06 -0700 |
Hi Todd,
Todd Denniston <Todd.Denniston@ssa.crane.navy.mil> writes:
> "Mark D. Baushke" wrote:
> >
> >
> <SNIP>
> > Well, I did something like this once for a test version of cvs.
>
> Mark,
> I know this is a quick test version, but I think I spotted a small problem
> you may want to fix, in case you ever get around to getting it in the
> mainline.
>
> I believe
>
> if (CurDir == NULL)
> CurDir = xstrdup ("<remote>");
>
> should go after the #endif, so that you get the same behavior with the new
> version as it would have before if SERVER_SUPPORT is undefined.
You raise a very good point.
My test hack always had a '#define SERVER_SUPPORT' in it. Revised
(untested) patch attached.
Looking at it again, I see another problem that may arise with the use
of IPv6 which may have eight sixteen-bit pieces of address defined as
either all hex segments
xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
or a mixture of hex segments in the first six sixteen-bit pieces
followed by decimal values representing the older IPv4 address
xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd
Adding that to the possibity of two decimal represenatations of a 16-bit
port number means that there needs to be enough space in buf for
"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd ddddd ddddd\0"
which is 58 characters... allow a few extra for a nice round 64 number...
Thanks!
-- Mark
Index: main.c
===================================================================
RCS file: /cvsroot/cvs/ccvs/src/main.c,v
retrieving revision 1.172.4.16
diff -u -p -u -p -r1.172.4.16 main.c
--- main.c 2 Sep 2005 19:37:34 -0000 1.172.4.16
+++ main.c 18 Oct 2005 21:19:41 -0000
@@ -24,6 +24,10 @@
#include <winsock.h>
#else
extern int gethostname ();
+#ifdef SERVER_SUPPORT
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
#endif
const char *program_name;
@@ -716,7 +720,67 @@ distribution kit for a complete list of
it is worth the trouble. */
if (server_active)
- CurDir = xstrdup ("<remote>");
+ {
+#ifdef SERVER_SUPPORT
+ int len, indx, ip;
+ /* hold at least ddd.ddd.ddd.ddd for IPv4
+ hold either xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
+ or xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd for
+ IPv6 along with a possible " dddddd dddddd\0" at the
+ end of it. */
+ char buf[64];
+ union bigsockaddr
+ {
+ struct sockaddr sa; /* general version */
+ struct sockaddr_in sin; /* INET family */
+ } peer;
+ char *cp;
+
+ CurDir = NULL;
+
+ /* Note: It may not be desirable to trust the SSH_CLIENT
+ * environment variable, but a quick test shows that using
+ * ssh differs from using rsh as to being able to check
+ * the family of the STDIN to get the hostname of the
+ * remote host.
+ */
+ if ((cp = getenv ("SSH_CLIENT")) != NULL)
+ {
+ char *ind;
+
+ strncpy (buf, cp, sizeof buf);
+ buf[sizeof(buf) - 1] = '\0';
+
+ if ((ind = strchr (buf, ' ')) != NULL)
+ {
+ *ind = '\0';
+ CurDir = strdup (buf);
+ }
+ }
+#ifdef AF_INET
+ else
+ {
+ len = sizeof peer;
+ if ((getpeername (0, &peer.sa, &len) >= 0))
+ {
+ if (peer.sa.sa_family == AF_INET)
+ {
+ memcpy (&ip, &peer.sin.sin_addr, sizeof ip);
+ ip = htonl (ip);
+ if (snprintf (buf, sizeof buf, "%d.%d.%d.%d",
+ (ip >> 24) & 0xff,
+ (ip >> 16) & 0xff,
+ (ip >> 8) & 0xff,
+ ip & 0xff) < sizeof buf)
+ CurDir = strdup(buf);
+ }
+ }
+ }
+#endif
+#endif
+ if (CurDir == NULL)
+ CurDir = xstrdup ("<remote>");
+ }
else
{
CurDir = xgetwd ();