#include "cvs.h"
#include "getline.h"
#ifdef AUTH_CLIENT_SUPPORT
#ifndef _CRAY
extern char *getpass ();
#endif
#ifndef CVS_PASSWORD_FILE
#define CVS_PASSWORD_FILE ".cvspass"
#endif
static char *cvs_password = NULL;
static char *construct_cvspass_filename PROTO ((void));
static char *
construct_cvspass_filename ()
{
char *homedir;
char *passfile;
if ((passfile = getenv ("CVS_PASSFILE")) != NULL)
return xstrdup (passfile);
homedir = get_homedir ();
if (! homedir)
{
error (1, errno, "could not find out home directory");
return (char *) NULL;
}
passfile =
(char *) xmalloc (strlen (homedir) + strlen (CVS_PASSWORD_FILE) + 3);
strcpy (passfile, homedir);
#ifndef NO_SLASH_AFTER_HOME
strcat (passfile, "/");
#endif
strcat (passfile, CVS_PASSWORD_FILE);
if (isfile (passfile))
chmod (passfile, 0600);
return passfile;
}
static const char *const login_usage[] =
{
"Usage: %s %s\n",
"(Specify the --help global option for a list of other help options)\n",
NULL
};
int
login (argc, argv)
int argc;
char **argv;
{
char *passfile;
FILE *fp;
char *typed_password, *found_password;
char *linebuf = (char *) NULL;
size_t linebuf_len;
int root_len, already_entered = 0;
int line_length;
if (argc < 0)
usage (login_usage);
if (CVSroot_method != pserver_method)
{
error (0, 0, "can only use pserver method with `login' command");
error (1, 0, "CVSROOT: %s", CVSroot_original);
}
if (! CVSroot_username)
{
error (0, 0, "CVSROOT \"%s\" is not fully-qualified.",
CVSroot_original);
error (1, 0, "Please make sure to specify \"user@host\"!");
}
printf ("(Logging in to %s@%s)\n", CVSroot_username, CVSroot_hostname);
fflush (stdout);
passfile = construct_cvspass_filename ();
typed_password = getpass ("CVS password: ");
typed_password = scramble (typed_password);
cvs_password = xstrdup (typed_password);
connect_to_pserver (NULL, NULL, 1, 0);
root_len = strlen (CVSroot_original);
fp = CVS_FOPEN (passfile, "r");
if (fp != NULL)
{
while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
{
if (strncmp (CVSroot_original, linebuf, root_len) == 0)
{
already_entered = 1;
break;
}
}
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", passfile);
}
else if (!existence_error (errno))
error (0, errno, "cannot open %s", passfile);
if (already_entered)
{
strtok (linebuf, " ");
found_password = strtok (NULL, "\n");
if (strcmp (found_password, typed_password))
{
char *tmp_name;
FILE *tmp_fp;
tmp_name = cvs_temp_name ();
if ((tmp_fp = CVS_FOPEN (tmp_name, "w")) == NULL)
{
error (1, errno, "unable to open temp file %s", tmp_name);
return 1;
}
chmod (tmp_name, 0600);
fp = CVS_FOPEN (passfile, "r");
if (fp == NULL)
{
error (1, errno, "unable to open %s", passfile);
if (linebuf)
free (linebuf);
return 1;
}
chmod (passfile, 0600);
while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
{
if (strncmp (CVSroot_original, linebuf, root_len))
{
if (fprintf (tmp_fp, "%s", linebuf) == EOF)
error (0, errno, "cannot write %s", tmp_name);
}
else
{
if (fprintf (tmp_fp, "%s %s\n", CVSroot_original,
typed_password) == EOF)
error (0, errno, "cannot write %s", tmp_name);
}
}
if (line_length < 0 && !feof (fp))
error (0, errno, "cannot read %s", passfile);
if (linebuf)
free (linebuf);
if (fclose (tmp_fp) < 0)
error (0, errno, "cannot close %s", tmp_name);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", passfile);
copy_file (tmp_name, passfile);
unlink_file (tmp_name);
chmod (passfile, 0600);
free (tmp_name);
}
}
else
{
if (linebuf)
free (linebuf);
if ((fp = CVS_FOPEN (passfile, "a")) == NULL)
{
error (1, errno, "could not open %s", passfile);
free (passfile);
return 1;
}
if (fprintf (fp, "%s %s\n", CVSroot_original, typed_password) == EOF)
error (0, errno, "cannot write %s", passfile);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", passfile);
}
chmod (passfile, 0600);
memset (typed_password, 0, strlen (typed_password));
free (typed_password);
free (passfile);
free (cvs_password);
cvs_password = NULL;
return 0;
}
char *
get_cvs_password ()
{
int found_it = 0;
int root_len;
char *password;
char *linebuf = (char *) NULL;
size_t linebuf_len;
FILE *fp;
char *passfile;
int line_length;
if (cvs_password)
return cvs_password;
if (getenv ("CVS_PASSWORD") != NULL)
{
error (0, 0, "CVS_PASSWORD is no longer supported; ignored");
}
if (CVSroot_method != pserver_method)
{
error (0, 0, "can only call GET_CVS_PASSWORD with pserver method");
error (1, 0, "CVSROOT: %s", CVSroot_original);
}
if (! CVSroot_username)
{
error (0, 0, "CVSROOT \"%s\" is not fully-qualified.",
CVSroot_original);
error (1, 0, "Please make sure to specify \"user@host\"!");
}
passfile = construct_cvspass_filename ();
fp = CVS_FOPEN (passfile, "r");
if (fp == NULL)
{
error (0, errno, "could not open %s", passfile);
free (passfile);
error (1, 0, "use \"cvs login\" to log in first");
}
root_len = strlen (CVSroot_original);
while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
{
if (strncmp (CVSroot_original, linebuf, root_len) == 0)
{
found_it = 1;
break;
}
}
if (line_length < 0 && !feof (fp))
error (0, errno, "cannot read %s", passfile);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", passfile);
if (found_it)
{
char *tmp;
strtok (linebuf, " ");
password = strtok (NULL, "\n");
tmp = xstrdup (password);
memset (password, 0, strlen (password));
free (linebuf);
return tmp;
}
else
{
if (linebuf)
free (linebuf);
error (0, 0, "cannot find password");
error (1, 0, "use \"cvs login\" to log in first");
}
return NULL;
}
static const char *const logout_usage[] =
{
"Usage: %s %s\n",
"(Specify the --help global option for a list of other help options)\n",
NULL
};
int
logout (argc, argv)
int argc;
char **argv;
{
char *passfile;
FILE *fp;
char *tmp_name;
FILE *tmp_fp;
char *linebuf = (char *) NULL;
size_t linebuf_len;
int root_len, found = 0;
int line_length;
if (argc < 0)
usage (logout_usage);
if (CVSroot_method != pserver_method)
{
error (0, 0, "can only use pserver method with `logout' command");
error (1, 0, "CVSROOT: %s", CVSroot_original);
}
if (! CVSroot_username)
{
error (0, 0, "CVSROOT \"%s\" is not fully-qualified.",
CVSroot_original);
error (1, 0, "Please make sure to specify \"user@host\"!");
}
printf ("(Logging out of %s@%s)\n", CVSroot_username, CVSroot_hostname);
fflush (stdout);
passfile = construct_cvspass_filename ();
tmp_name = cvs_temp_name ();
if ((tmp_fp = CVS_FOPEN (tmp_name, "w")) == NULL)
{
error (1, errno, "unable to open temp file %s", tmp_name);
return 1;
}
chmod (tmp_name, 0600);
root_len = strlen (CVSroot_original);
fp = CVS_FOPEN (passfile, "r");
if (fp == NULL)
error (1, errno, "Error opening %s", passfile);
while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
{
if (strncmp (CVSroot_original, linebuf, root_len))
{
if (fprintf (tmp_fp, "%s", linebuf) == EOF)
error (0, errno, "cannot write %s", tmp_name);
}
else
found = 1;
}
if (line_length < 0 && !feof (fp))
error (0, errno, "cannot read %s", passfile);
if (linebuf)
free (linebuf);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", passfile);
if (fclose (tmp_fp) < 0)
error (0, errno, "cannot close %s", tmp_name);
if (! found)
{
printf ("Entry not found for %s\n", CVSroot_original);
unlink_file (tmp_name);
}
else
{
copy_file (tmp_name, passfile);
unlink_file (tmp_name);
chmod (passfile, 0600);
}
return 0;
}
#endif