(I hope this is the right forum. If not, I guess I'll hear about it...)
I have found it very useful to be able to specify port number for pserver
(to support multiple repositories on the same host). Following patch
implements ":pserver/port:" syntax (where "/port" is optional of course).
I would really appreciate if someone on the development team could find
time to look at it, and tell me if it is possible to get it into the main
tree. I will gladly modify the code to conform to any rules I may have
missed. Note that I have added some comments about what I've done and not
done. I'll be happy to remove them and produce a cleaner patch if needed.
Note that I have tried to modify the current code as little as
possible. As my comments state, I believe more work could be done, but I
refrained from this in an attempt to make something that doesn't break
any old behaviour. I haven't followed CVS development closely enough to
have a strong view about how to implement all this, so please disregard my
comments if you find them stupid! :-)
I _really_ need this functionality, so any comments about how to proceed
(if this isn't enough) are welcome.
/m
Index: client.c
===================================================================
RCS file: /home2/cvsroot/ccvs/src/client.c,v
retrieving revision 1.279
diff -u -r1.279 client.c
--- client.c 2000/05/20 22:00:32 1.279
+++ client.c 2000/05/28 20:01:23
@@ -3654,15 +3654,43 @@
static int auth_server_port_number PROTO ((void));
+/*
+ * auth_server_port_number() returns numeric port number (host byte order)
+ * for the active root_method. The port number, or service name, is
+ * specified in (global var) CVSroot_method_port, which is set by
+ * parse_cvsroot().
+ *
+ * XXX We should clean up the naming of the xxx_PORT defs.
+ * XXX We should clean up the port specification logic further;
+ * start_tcp_server() still contains some logic (I didn't want to
+ * break old behavior)/<[EMAIL PROTECTED]>
+ */
static int
auth_server_port_number ()
{
- struct servent *s = getservbyname ("cvspserver", "tcp");
+ struct servent *s = getservbyname (CVSroot_method_port, "tcp");
+ int port;
+ char *p;
if (s)
return ntohs (s->s_port);
else
- return CVS_AUTH_PORT;
+ {
+ port = strtol (CVSroot_method_port, &p, 10);
+ if (strcmp (CVSroot_method_port, "cvspserver") == 0)
+ return CVS_AUTH_PORT;
+#if HAVE_KERBEROS
+ if (strcmp (CVSroot_method_port, "cvs") == 0)
+ return CVS_PORT;
+#endif /* HAVE_KERBEROS */
+ if (p == CVSroot_method_port || port < 1 || port > 65535)
+ {
+ fprintf (stderr, "Invalid root server port %s.\n",
+ CVSroot_method_port);
+ error_exit ();
+ }
+ return port;
+ }
}
@@ -3983,6 +4011,13 @@
if (s < 0)
error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO));
+ /*
+ * XXX
+ * Old port selection logic is kept intact here; the env var
+ * CVS_CLIENT_PORT overrides the new spec "kserver/port".
+ * This should be fixed (remove env var usage!?)/<[EMAIL PROTECTED]>
+ */
+
/* Get CVS_CLIENT_PORT or look up cvs/tcp with CVS_PORT as default */
portenv = getenv ("CVS_CLIENT_PORT");
if (portenv != NULL)
@@ -4000,13 +4035,11 @@
}
else
{
- struct servent *sp;
-
- sp = getservbyname ("cvs", "tcp");
- if (sp == NULL)
- port = CVS_PORT;
- else
- port = ntohs (sp->s_port);
+ /*
+ * Get port number from CVSroot_method_port; it will try service
+ * "cvs", then CVS_PORT.
+ */
+ port = auth_server_port_number ();
}
hp = init_sockaddr (&sin, CVSroot_hostname, port);
Index: cvs.h
===================================================================
RCS file: /home2/cvsroot/ccvs/src/cvs.h,v
retrieving revision 1.201
diff -u -r1.201 cvs.h
--- cvs.h 2000/05/16 18:57:15 1.201
+++ cvs.h 2000/05/28 20:01:31
@@ -380,6 +380,7 @@
extern char *CVSroot_original; /* the active, complete CVSroot string */
extern int client_active; /* nonzero if we are doing remote access */
extern CVSmethod CVSroot_method; /* one of the enum values above */
+extern char *CVSroot_method_port; /* port no for method (cur only pserver) */
extern char *CVSroot_username; /* the username or NULL if method == local */
extern char *CVSroot_hostname; /* the hostname or NULL if method == local */
extern char *CVSroot_directory; /* the directory name */
Index: root.c
===================================================================
RCS file: /home2/cvsroot/ccvs/src/root.c,v
retrieving revision 1.36
diff -u -r1.36 root.c
--- root.c 1999/03/07 20:17:02 1.36
+++ root.c 2000/05/28 20:01:33
@@ -286,6 +286,7 @@
char *CVSroot_original = NULL; /* the CVSroot that was passed in */
int client_active; /* nonzero if we are doing remote access */
CVSmethod CVSroot_method; /* one of the enum values defined in cvs.h */
+char *CVSroot_method_port; /* port no for method (cur only pserver) */
char *CVSroot_username; /* the username or NULL if method == local */
char *CVSroot_hostname; /* the hostname or NULL if method == local */
char *CVSroot_directory; /* the directory name */
@@ -313,9 +314,10 @@
char *method = ++cvsroot_copy;
/* Access method specified, as in
- * "cvs -d :pserver:user@host:/path",
* "cvs -d :local:e:\path",
- * "cvs -d :kserver:user@host:/path", or
+ * "cvs -d :pserver[/port]:user@host:/path",
+ * "cvs -d :gserver[/port]:user@host:/path",
+ * "cvs -d :kserver[/port]:user@host:/path", or
* "cvs -d :fork:/path".
* We need to get past that part of CVSroot before parsing the
* rest of it.
@@ -329,16 +331,40 @@
*p = '\0';
cvsroot_copy = ++p;
+ CVSroot_method_port = NULL;
+
/* Now we have an access method -- see if it's valid. */
if (strcmp (method, "local") == 0)
CVSroot_method = local_method;
- else if (strcmp (method, "pserver") == 0)
+ else if ((strncmp (method, "pserver", 7) == 0) &&
+ (method[7] == '\0' || method[7] == '/'))
+ {
CVSroot_method = pserver_method;
- else if (strcmp (method, "kserver") == 0)
+ if (method[7] == '/')
+ CVSroot_method_port = method + 8;
+ else
+ CVSroot_method_port = "cvspserver";
+ }
+ else if ((strncmp (method, "kserver", 7) == 0) &&
+ (method[7] == '\0' || method[7] == '/'))
+ {
CVSroot_method = kserver_method;
- else if (strcmp (method, "gserver") == 0)
+ if (method[7] == '/')
+ CVSroot_method_port = method + 8;
+ else
+ CVSroot_method_port = "cvs";
+ }
+ else if ((strncmp (method, "gserver", 7) == 0) &&
+ (method[7] == '\0' || method[7] == '/'))
+ {
CVSroot_method = gserver_method;
+ if (method[7] == '/')
+ CVSroot_method_port = method + 8;
+ else
+ /* GSSAPI auth is done via pserver, use pserver port */
+ CVSroot_method_port = "cvspserver";
+ }
else if (strcmp (method, "server") == 0)
CVSroot_method = server_method;
else if (strcmp (method, "ext") == 0)