diff -u -r -N ccvs/NEWS ccvs.1/NEWS
--- ccvs/NEWS Tue Jul 9 15:15:32 2002
+++ ccvs.1/NEWS Thu Sep 12 18:19:21 2002
@@ -1,5 +1,11 @@
Changes since 1.11.2:
+* When cvs needs a passphrase (e.g. login) it will read it from the current
+terminal (console) if is available. If no terminal associated with it, cvs
+will attempt to run a program pointed by CVS_ASKPASS variable. This is
+particularly useful when calling cvs from X session. (Note that on some machines
+it may be necessary to redirect the input from /dev/null to get it working.)
+
* When waiting for another user's lock, the message timestamps are now
in UTC rather than the server's local time.
diff -u -r -N ccvs/src/ChangeLog ccvs.1/src/ChangeLog
--- ccvs/src/ChangeLog Thu Aug 29 02:00:59 2002
+++ ccvs.1/src/ChangeLog Thu Sep 12 18:46:40 2002
@@ -1,3 +1,8 @@
+2000-09-12 Dmitri Dmitrienko
+
+ * login.c: Add support for 3rd party passphrase asking programs.
+ * askpass.c: Implement running 3rd party passphrase asking programs.
+
2002-08-28 Larry Jones
* logmsg.c (do_editor): Fix bug which prevented reusing log messages.
diff -u -r -N ccvs/src/Makefile.am ccvs.1/src/Makefile.am
--- ccvs/src/Makefile.am Wed May 8 14:39:20 2002
+++ ccvs.1/src/Makefile.am Thu Sep 12 18:36:16 2002
@@ -30,6 +30,7 @@
add.c \
admin.c \
annotate.c \
+ askpass.c \
buffer.c \
checkin.c \
checkout.c \
diff -u -r -N ccvs/src/askpass.c ccvs.1/src/askpass.c
--- ccvs/src/askpass.c Wed Dec 31 21:00:00 1969
+++ ccvs.1/src/askpass.c Thu Sep 12 19:22:10 2002
@@ -0,0 +1,111 @@
+/*
+ Allow user to log in using graphical front-end.
+ written by Dmitri Dmitrienko
+*/
+
+
+#include "cvs.h"
+#include "askpass.h"
+
+#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */
+
+#ifdef HAVE_GETPASSPHRASE
+#define GETPASS getpassphrase
+#else
+#define GETPASS getpass
+#endif
+
+/* There seems to be very little agreement on which system header
+ getpass is declared in. With a lot of fancy autoconfiscation,
+ we could perhaps detect this, but for now we'll just rely on
+ _CRAY, since Cray is perhaps the only system on which our own
+ declaration won't work (some Crays declare the 2#$@% thing as
+ varadic, believe it or not). On Cray, getpass will be declared
+ in either stdlib.h or unistd.h. */
+#ifndef _CRAY
+extern char *GETPASS ();
+#endif
+
+
+static char pass_buff[1024]; // don't worry, login() cleans it up
+
+char *cvs_run_askpass(askpass_prog, pass_prompt)
+ char *askpass_prog;
+ char *pass_prompt;
+{
+ char *argv[3];
+ int tofdp, fromfdp;
+ int len, ret;
+ int askpass_pid, status;
+
+ argv[0] = askpass_prog;
+ argv[1] = pass_prompt;
+ argv[2] = NULL;
+ if (trace)
+ {
+ int i;
+
+ fprintf (stderr, " -> Starting askpass: ");
+ for (i = 0; argv[i]; i++)
+ fprintf (stderr, "%s ", argv[i]);
+ putc ('\n', stderr);
+ }
+ askpass_pid = piped_child (argv, &tofdp, &fromfdp);
+
+ if (askpass_pid < 0) {
+ error (1, errno, "cannot start askpass");
+ }
+
+ len = ret = 0;
+ do {
+ ret = read(fromfdp, pass_buff + len, sizeof(pass_buff) - 1 - len);
+ if (ret == -1 && errno == EINTR)
+ continue;
+ if (ret <= 0)
+ break;
+ len += ret;
+ } while (len < sizeof(pass_buff) - 1);
+ pass_buff[len] = '\0';
+
+ close(fromfdp);
+ close(tofdp);
+
+ while (waitpid(askpass_pid, &status, 0) < 0)
+ if (errno != EINTR)
+ break;
+
+ pass_buff[strcspn(pass_buff, "\r\n")] = '\0';
+ return pass_buff;
+}
+
+/* Prompt for a password, and scrambles it.
+ */
+
+char *cvs_ask_pass(cvs_root)
+ char *cvs_root;
+{
+ char *tmp, *retval, *askpass_prog;
+ int ttyfd, use_askpass = 0;
+
+// test TTY availability
+ ttyfd = open(_PATH_TTY, O_RDONLY);
+ if (ttyfd >= 0)
+ close(ttyfd);
+ else
+ use_askpass = 1;
+
+ if (use_askpass) {
+ askpass_prog = getenv(CVS_ASKPASS_ENV);
+ if (!askpass_prog)
+ askpass_prog = _CVS_ASKPASS_DEFAULT;
+ tmp = cvs_run_askpass(askpass_prog, cvs_root);
+ }
+ else {
+ tmp = GETPASS ("CVS password: ");
+ }
+ retval = scramble (tmp);
+ memset (tmp, 0, strlen (tmp));
+ return retval;
+}
+
+#endif
diff -u -r -N ccvs/src/askpass.h ccvs.1/src/askpass.h
--- ccvs/src/askpass.h Wed Dec 31 21:00:00 1969
+++ ccvs.1/src/askpass.h Thu Sep 12 19:05:46 2002
@@ -0,0 +1,26 @@
+#ifndef _ASKPASS_H
+#define _ASKPASS_H
+
+#ifndef _PATH_TTY
+#ifdef HAVE_CYGWIN
+# define _PATH_TTY "/dev/tty"
+#else
+#ifdef WIN32
+# define _PATH_TTY "CONIN$"
+#else
+# define _PATH_TTY "/dev/tty"
+#endif
+#endif
+#endif
+
+
+#ifndef _CVS_ASKPASS_DEFAULT
+#define _CVS_ASKPASS_DEFAULT "cvs-askpass"
+#endif
+
+#define CVS_ASKPASS_ENV "CVS_ASKPASS"
+
+
+extern char *cvs_ask_pass PROTO((char *));
+
+#endif
diff -u -r -N ccvs/src/login.c ccvs.1/src/login.c
--- ccvs/src/login.c Thu May 23 15:13:17 2002
+++ ccvs.1/src/login.c Thu Sep 12 19:10:09 2002
@@ -12,22 +12,7 @@
#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */
-#ifdef HAVE_GETPASSPHRASE
-#define GETPASS getpassphrase
-#else
-#define GETPASS getpass
-#endif
-
-/* There seems to be very little agreement on which system header
- getpass is declared in. With a lot of fancy autoconfiscation,
- we could perhaps detect this, but for now we'll just rely on
- _CRAY, since Cray is perhaps the only system on which our own
- declaration won't work (some Crays declare the 2#$@% thing as
- varadic, believe it or not). On Cray, getpass will be declared
- in either stdlib.h or unistd.h. */
-#ifndef _CRAY
-extern char *GETPASS ();
-#endif
+#include "askpass.h"
#ifndef CVS_PASSWORD_FILE
#define CVS_PASSWORD_FILE ".cvspass"
@@ -541,7 +526,7 @@
else
{
char *tmp;
- tmp = GETPASS ("CVS password: ");
+ tmp = cvs_ask_pass (cvsroot_canonical);
/* Must deal with a NULL return value here. I haven't managed to
* disconnect the CVS process from the tty and force a NULL return
* in sanity.sh, but the Linux version of getpass is documented