Hi All!

I've made all patches except sanity.sh to incorporate %subj% into CVS.
File full.diff contains unified patch.

This version supports both local and pserver mode.
It has been tested under FreeBSD 4.3 and Cygnus.

Regards,
Andrey Aristarkhov
BiTechnology 
/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * Copyright (C) 2000-2002
 *  Andrey Aristarkhov <[EMAIL PROTECTED]>. 
 *  All rights reserved
 * Partial Copyright (C) 1996
 *  David L. Nugent.  All rights reserved.
 *
 * $Id: user.c,v 1.8.2.6 2002/08/16 15:48:42 dron Exp $
 *
 * Frontend functions for CVS' passwords manupulation
 *
 */

#include "user.h"
#include "cvs.h"

#ifndef safe_string
#define safe_string(s) s ? s : "null"
#endif

static char pathpwd[MAXPATHLEN];
static char * pwpath = pathpwd;

static int
pw_fileupdate(char const * filename, mode_t fmode, char const * newline, char const * 
prefix, int pfxlen, int updmode)
{
        int   rc = 0;
  int   updated = PWD_CREATE;
  int   linesize = PWBUFSZ;
  char  *line;
  FILE  *outfp;
  FILE  *infp;
  int   outfd;  
  char  file[MAXPATHLEN];          
  int   infd;
                                                                
        if (pfxlen <= 1)
                rc = EINVAL;
        else {
                infd = open(filename, O_RDWR | O_CREAT, fmode);
                if (infd == -1)
                        rc = errno;
                else {
                        infp = fdopen(infd, "r+");
                
                        if (infp == NULL) {
                                rc = errno;             /* Assumes fopen(3) sets errno 
from open(2) */
                                close(infd);
                        } else {

                                strcpy(file, filename);
                                strcat(file, ".new");
#ifdef __FreeBSD__
                                outfd = open(file, O_RDWR | O_CREAT | O_TRUNC | 
O_EXLOCK, fmode);
#else
                                outfd = open(file, O_RDWR | O_CREAT | O_TRUNC , fmode);
#endif
                                if (outfd == -1)
                                        rc = errno;
                                else {
                                        outfp = fdopen(outfd, "w+");

                                        if (outfp == NULL) {
                                                rc = errno;
                                                close(outfd);
                                        } else {
                                                updated = PWD_CREATE;
                                                linesize = PWBUFSZ;
                                                line = malloc(linesize);

                                                while (fgets(line, linesize, infp) != 
NULL) {
                                                        char  *p = strchr(line, '\n');

                                                        while ((p = strchr(line, 
'\n')) == NULL) {
                                                                int     l;
                                                                expand_string(&line, 
&linesize, linesize + PWBUFSZ);
                                                                l = strlen(line);
                                                                if (fgets(line + l, 
linesize - l, infp) == NULL)
                                                                        break;
                                                        }
                                                        if (*line != '#' && *line != 
'\n') {
                                                                if (!updated && 
strncmp(line, prefix, pfxlen) == 0) {
                                                                        updated = 
updmode == PWD_UPDATE ? PWD_UPDATE : PWD_DELETE;

                                                                        /*
                                                                         * Only 
actually write changes if updating
                                                                         */
                                                                        if (updmode == 
PWD_UPDATE)
                                                                                
strcpy(line, newline);
                                                                        else if 
(updmode == PWD_DELETE)
                                                                                
continue;
                                                                }
                                                        }
                                                        fputs(line, outfp);
                                                }

                                                /*
                                                 * Now, we need to decide what to do: 
If we are in
                                                 * update mode, and no record was 
updated, then error If
                                                 * we are in insert mode, and record 
already exists,
                                                 * then error
                                                 */
                                                if (updmode != updated)
                                                        /* -1 return means:
                                                         * update,delete=no user entry
                                                         * create=entry exists
                                                         */
                                                        rc = -1;
                                                else {

                                                        /*
                                                         * If adding a new record, 
append it to the end
                                                         */
                                                        if (updmode == PWD_CREATE)
                                                                fputs(newline, outfp);

                                                        /*
                                                         * Flush the file and check 
for the result
                                                         */
                                                        if (fflush(outfp) == EOF)
                                                                rc = errno;     /* 
Failed to update */
                                                        else {
                                                                /*
                                                                 * Copy data back into 
the
                                                                 * original file and 
truncate
                                                                 */
                                                                rewind(infp);
                                                                rewind(outfp);
                                                                while (fgets(line, 
linesize, outfp) != NULL)
                                                                        fputs(line, 
infp);

                                                                /*
                                                                 * If there was a 
problem with copying
                                                                 * we will just rename 
'file.new' 
                                                                 * to 'file'.
                                                                 * This is a gross 
hack, but we may have
                                                                 * corrupted the 
original file
                                                                 * Unfortunately, it 
will lose the inode
                                                                 * and hence the lock.
                                                                 */
                                                                if (fflush(infp) == 
EOF || ferror(infp))
                                                                        rename(file, 
filename);
                                                                else
                                                                        
ftruncate(infd, ftell(infp));
                                                        }
                                                }
                                                free(line);
                                                fclose(outfp);
                                        }
                                        remove(file);
                                }
                                fclose(infp);
                        }
                }
        }
        return rc;
}

static void setpwpath(const char * file) {
        strcpy(pathpwd,file);
}

static char * getpwpath()
{
  static char pathbuf[MAXPATHLEN];

  strcpy(pathbuf,pathpwd);
  return pathbuf;
}

/*
 * Return values:
 *  -1 -- generic error
 *   0 -- success
 *   1 -- user is empty or NULL
 *   2 -- passwd is empty or NULL 
 */
static int
fmtpwentry(char **buf, const char *user, const char * passwd, const char * alias)
{
  int  l;
  int  has_alias;
  char *pw;
  if (user == NULL || strlen(user) == 0) {
    return 1;
  } else if (passwd == NULL || strlen(passwd) == 0) {
    return 2;
  }
  if (alias == NULL || strlen(alias) == 0) {
    has_alias = 0;
  } else {
    has_alias = strlen(alias);
  }
  l = strlen(passwd)+strlen(user) +has_alias+ 2;

  pw = (char *)malloc(l);
  if (has_alias) {
    sprintf(pw,"%s:%s:%s\n",user,passwd,alias);
  } else {
    sprintf(pw,"%s:%s\n",user,passwd);
  }
  *buf = pw;
  return 0;
}


static int
pw_update(const char * user, const char * passwd, const char * alias, int mode)
{
  int             rc = 0;

  char            pfx[32];
  char            * pwbuf;
  int             l = sprintf(pfx, "%s:", user);

  /*
   * Update passwd file
   */
        if (mode != PWD_DELETE) {
    rc =  fmtpwentry(&pwbuf,user,passwd,alias);
    if (rc != 0) {
      return rc;
    }
  } else {
        pwbuf = malloc(strlen(user)+2);
        sprintf(pwbuf,"%s:",user);
  }
  
  rc = pw_fileupdate(getpwpath(), 0644, pwbuf, pfx, l, mode);
        
        if (pwbuf != NULL) {
        free(pwbuf);
  }     
  return rc;
}

#ifndef CHARSET_EBCDIC
#define LF 10
#define CR 13   
#else /*CHARSET_EBCDIC*/
#define LF '\n'
#define CR '\r'
#endif /*CHARSET_EBCDIC*/

static int getline(char *s, int n, FILE *f)
{
  register int i = 0;

  while (1) {
    s[i] = (char) fgetc(f);

    if (s[i] == CR) {
      s[i] = fgetc(f);
    }

    if ((s[i] == 0x4) || (s[i] == LF) || (i == (n - 1))) {
      s[i] = '\0';
      return (feof(f) ? 1 : 0);
    }
    ++i;
  }
}

#define MAX_STRING_LEN 256

static char * get_password(const char * user) {
  static char pwd[MAX_STRING_LEN];
  char line[MAX_STRING_LEN];
  FILE * fpw=NULL;
  char * token;
  fpw = fopen (getpwpath(), "r");
  if (fpw == NULL) {
        return NULL;
  }
  memset(pwd,0,MAX_STRING_LEN);
  while (!(getline (line, MAX_STRING_LEN, fpw))) {
    if (line[0] == '#') {
      continue;
    }
    token = strtok(line,":");
    if (token == NULL) {
      continue;
    }
    if (strcmp (user, token) != 0) {
      continue;
    }
    /* User found */
    token = strtok(NULL,":");
    strcpy(pwd,token);
    
    fclose(fpw);
    return pwd;
  }
  fclose(fpw);
  return NULL;
}

static char * get_alias(const char * user) {
  static char alias[MAX_STRING_LEN];
  char line[MAX_STRING_LEN];
  FILE * fpw;
  char * token;

  fpw = fopen (getpwpath(), "r");
  while (!(getline (line, sizeof (line), fpw))) {
    if (line[0] == '#') {
      continue;
    }
    token = strtok(line,":");
    if (strcmp (user, token) != 0) {
      continue;
    }
    /* User found */
    token = strtok(NULL,":");
    token = strtok(NULL,":");
    if (token == NULL) {
      return NULL;
    }
    strcpy(alias,token);
    
    fclose(fpw);
    return alias;
  }
  fclose(fpw);
  return NULL;
}

/*extern char * crypt(const char *, const char *);*/
static char const chars[] = 
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.";

static char * pw_crypt(const char *password)
{
  int             i;
  char            salt[12];

  static char     buf[256];

  /* 
   * Calculate a salt value
   */
#ifdef __FreeBSD__
  srandomdev();
#else
  srandom((unsigned long) (time(NULL) ^ getpid()));
#endif
  for (i = 0; i < 8; i++)
    salt[i] = chars[random() % 63];
  salt[i] = '\0';

  return strcpy(buf, crypt(password, salt));
}


/*
 * Return values:
 * -1 - user exists
 *  0 - user added, otherwise another code
 */
static int pw_add_user(const char * user, const char * passwd, const char * alias) {
        char * newpasswd;
        int res;

        if (trace) {
                printf("%s->pw_add_user: user=%s, passwd=%s, 
alias=%s\n",CLIENT_SERVER_STR,safe_string(user),safe_string(passwd),safe_string(alias));
                fflush(stdout);
        }
        if (get_password(user) != NULL) {
                return -1;
        }
        if (passwd == NULL || strlen(passwd) == 0) {
                newpasswd=xstrdup("*");
        } else {
                newpasswd = xstrdup(pw_crypt(passwd));
        }
        res = pw_update(user,newpasswd,alias,PWD_CREATE);
        free(newpasswd);
        return res;
}

/* -1 - user does not exists, otherwise 0
 */
static int pw_mod_user(const char * user, const char * passwd, const char * alias) {
  char * newpasswd;
#ifdef NEVER
        if (trace) {
                printf("%s->pw_mod_user: user=%s, passwd=%s, 
alias=%s\n",CLIENT_SERVER_STR,safe_string(user),safe_string(passwd),safe_string(alias));
                fflush(stdout);
        }
#endif
        if ((newpasswd = get_password(user)) == NULL) {
                return -1;
        }
        if (passwd != NULL) {
          newpasswd = pw_crypt(passwd);
        }
        if (alias == NULL) 
          alias = get_alias(user);
        
        return pw_update(user,newpasswd,alias,PWD_UPDATE);
}

/* -1 - user does not exists */
static int pw_del_user(const char * user) {
        if (get_password(user) == NULL) {
                return -1;
        }
        return pw_update(user,NULL,NULL,PWD_DELETE);
}  

static const char *const password_usage[] =
{
    "Usage: %s %s\n",
/*    "\tIf no \"username\" is given password will be set for the current user\n",
    "\t\"username\"\tUse it if you want to change password for the specified user\n"*/
    "(Specify the --help global option for a list of other help options)\n",
    NULL
};

static const char *const user_usage[] =
{
    "Usage: %s %s <[-a | -m | -d] username> [-u alias] [-p | -P password]\n",
    "\t-a|-m|-d\t'add', 'modify' or 'delete' user respectively\n",
    "\t-u\tUse \"alias\" to specify system user for cvs-user.\n",
    "\t-P\tUse \"password\" to specify user password in a command line OR\n",
    "\t-p\tenter user password interactively\n",
    "(Specify the --help global option for a list of other help options)\n",
    NULL
};

enum pwd_read_mode { PRM_NEW, PRM_ADMIN, PRM_CHECK };

static void verify_password_phrase(const char * password, unsigned char 
complete_check) {
  int plen, i;
  if (!password) {
    error(1,0,"Failed to read password");
  }
  if (!complete_check)
    return;
  plen = strlen(password);
  for (i=0;i<plen;i++) {
    if ((unsigned char)password[i] < 33 || (unsigned char)password[i] > 126) {
      error(1,0,"Invalid character in password (0x%x). Password can contain only 
printable characters.",password[i]); 
    }
  }
  if (plen < MIN_PASSWORD_LEN) {
    error(1,0,"Password length can't be less than %d characters",MIN_PASSWORD_LEN);
  }
  if (plen > MAX_PASSWORD_LEN) {
    error(1,0,"Password length can't be more than %d characters",MAX_PASSWORD_LEN);
  }
}

/*
 * Reads and verifies user's password from an input
 * Return password for the user
 */

static char * read_user_password(const char * user, int pwd_read_mode) {
  char prompt[128];
  char * pwd, * pwd_verify;
  static char password[_PASSWORD_LEN];

  memset(password,0,_PASSWORD_LEN);  
  switch (pwd_read_mode) {
    case PRM_NEW:
      sprintf(prompt,"Enter New password for user '%s':",user);
      /* We need to strdup because GETPASS uses static object */
      pwd_verify = GETPASS(prompt);
      verify_password_phrase(pwd_verify,TRUE);
      pwd = strdup(pwd_verify);
      memset(pwd_verify,0,strlen(pwd_verify));
      sprintf(prompt,"Re-type New password for user '%s':",user);
      pwd_verify = GETPASS(prompt);
      verify_password_phrase(pwd_verify,FALSE);
      if (strcmp(pwd,pwd_verify)) {
        free(pwd);
        error(1,0,"Passwords are different");
      } else {
        free(pwd);
        strcpy(password,pwd_verify);
        memset(pwd_verify,0,strlen(pwd_verify));
      }
    break;
    
   case PRM_CHECK:
    pwd = get_password(user);
    sprintf(prompt,"Enter current password for user '%s': ",user);
    pwd_verify = GETPASS(prompt);
    verify_password_phrase(pwd_verify,FALSE);
    if (strcmp(pwd,crypt(pwd_verify,pwd))==0) {
      strcpy(password,pwd);
    } else {
      error(1,0,"Wrong password",user);
    }
   break;
   
   case PRM_ADMIN:
    pwd = get_password(CVS_ADMIN_USER);
    if (pwd == NULL) 
      error(1,0,"Administrator's user accout not found. Please contact your CVS 
admin.");
    if (strcmp(pwd,"*")==0)
      error(1,0,"Password for Administrator's user accout is not set. Please contact 
your CVS admin.");
    pwd_verify = GETPASS("Enter CVS Administrator password: ");
    verify_password_phrase(pwd_verify,FALSE);
    if (strcmp(pwd,crypt(pwd_verify,pwd))==0) {
      strcpy(password,pwd);
    } else {
      error(1,0,"Administrator password is invalid");
    }
   break;
  }
  return password;
}

static void set_password_path(cvsroot_t * root) {
  char passwdFile[MAXPATHLEN];
  sprintf(passwdFile,"%s/%s/%s",root->directory,CVSROOTADM,CVSROOTADM_PASSWD);
  setpwpath(passwdFile);
}

static char * get_current_user(cvsroot_t * root) {
  char * user = root->username;
  if (user == NULL) {
        user=getcaller();
  }
  
  if (user==NULL) {
    error(1,0,"Fatal error: Can't detect current user.");
  } /*# It's impossible in pserver mode */
  return user;
}


int password(int argc, char ** argv) {
  char * user, * passwd, * passwd_to_send, * curr_password;
  char prompt[64];
  user = passwd = passwd_to_send = NULL;
  /*
   * Hacking "init" command
   */
  if (argc == -2) { /* called after mkmodules() in init() */
    char passwdFile[MAXPATHLEN];
    sprintf(passwdFile,"%s/%s",argv[0],CVSROOTADM_PASSWD); 
    setpwpath(passwdFile);
    /* If password faile exists, remove it */
    /*remove(passwdFile);*/
    /* constructing password. Need more relyable algorithm. */
    sprintf(passwdFile,"admin%d",getpid());
    error(0,0,"Creating administrator account '%s': password is 
'%s'.",CVS_ADMIN_USER,passwdFile);
    if (pw_add_user(CVS_ADMIN_USER,passwdFile,NULL) > 0) {
      error(0,errno,"Failed to add administrator account");
    }
#ifdef NEVER
                if (trace) {
                        printf("%s->user=%s 
added\n",CLIENT_SERVER_STR,safe_string(user));
                        fflush(stdout);
                }
#endif
    return 0;
  }
  /* End of init section */
  
  if (!server_active && current_parsed_root->method != pserver_method) {
                error (0, 0, "can only use `password' command with the 'pserver' 
method");
                error (1, 0, "CVSROOT: %s", current_parsed_root->original);
  }
        if (argc == -1)
    usage(password_usage);
#ifdef SERVER_SUPPORT
        if (server_active) {
          if (argc < 2) {
                printf("E protocol error: can't read password\n");
                return 1;
          }
          if (argc > 2) {
                printf("E protocol error: too many parameters\n");
                return 1;
          }
          passwd = descramble(argv[1]);
        }
#else
  if (argc > 1 || argc == -1) {
    usage(password_usage);
  }
#endif
        user = get_current_user(current_parsed_root);

        if (!server_active) {
          curr_password = get_cvs_password();
          if (curr_password==NULL) {
                error(1,0,"You are not logged into CVSROOT=%s. Try to login 
first.",current_parsed_root->original);
          }
                sprintf(prompt,"Enter current password for user '%s': ",user);
          passwd = GETPASS(prompt);
                curr_password = descramble(curr_password);
                if (strcmp(curr_password,passwd)!=0) {
                        error(1,0,"Wrong password. Command aborted.");
                }
                memset(curr_password,0,strlen(curr_password));
                free(curr_password);
                memset(passwd,0,strlen(passwd));
                passwd = read_user_password(user,PRM_NEW);
                passwd_to_send = scramble(passwd);

#ifdef CLIENT_SUPPORT
                start_server ();
                ign_setup ();
          send_arg (passwd_to_send);
          send_to_server("password\012",0);
          memset(passwd_to_send,0,strlen(passwd_to_send));
          free(passwd_to_send);
          return get_responses_and_close();
#endif  /* CLIENT_SUPPORT */
  }

#ifdef SERVER_SUPPORT
  set_password_path(current_parsed_root);
  if (pw_mod_user(user,passwd,NULL)==-1) {
        free(passwd);
        error(0,0,"User '%s'not found",user);
        return 1;
  }
  return 0;
#endif
}

#define checkOper(op) if (##op!= PWD_UNDEFINED) {\
  error(0,0,"Choose one of of options -a | -m | -d");\
  usage(user_usage);\
}

int user(int argc, char ** argv) {
  enum updtype op;
  char * user, * curr_user, * passwd, * alias, * curr_password;
  char * cvsroot;
  int res;
        char c;
        unsigned char hasPassword, needPassword;

  user = alias = passwd = NULL;
  op = PWD_UNDEFINED;
  hasPassword = needPassword = 0;

#ifdef NEVER
        if (trace) {
                printf("%s->cvs user: server_active: %d, argc=%d, argv[0]=%s, 
argv[1]=%s\n",CLIENT_SERVER_STR,server_active,argc,safe_string(argv[0]),safe_string(argv[1]));
                fflush(stdout);
        }
#endif
        
  /* parse args */
        if (argc == -1) 
          usage(user_usage);
  optind = 0;
  while ((c = getopt (argc, argv, "+a:d:m:u:pP:")) != -1)
  {
                switch (c) {
                        case 'a':
                          checkOper(op);
                                op = PWD_CREATE;
                                user = optarg;
                        break;
                        
                        case 'm':
                          checkOper(op);
                                op = PWD_UPDATE;
                                user = optarg;
                        break;
                        
                        case 'd':
                          checkOper(op);
                                op = PWD_DELETE;
                                user = optarg;
                        break;
                                
                case 'u':
                        alias = optarg;
                break;

          case 'P':
        hasPassword = 1;
                passwd = optarg;
          break;
          
          case 'p':
        needPassword = 1;
          break;
          
          case '?':
          default:
                        usage (user_usage);
                break;
        }
  }
  argc -= optind;
  argv += optind;
  if (op == PWD_UNDEFINED) {
    usage(user_usage);
  }
  if (hasPassword && needPassword) {
    error(0,0,"-p and -P options are mutually exclusive");
    usage(user_usage); 
  }
        /* end of parse args */

        curr_user = get_current_user(current_parsed_root);
  if ( strcmp(curr_user, CVS_ADMIN_USER) != 0) {
    error(1,0,"You are not an administrator");
  }
        if (!server_active) {
                char * tmppass;
          curr_password = get_cvs_password();
          if (curr_password==NULL) {
                error(1,0,"You are not logged into CVSROOT=%s. Try to login 
first.",current_parsed_root->original);
          }
          tmppass = GETPASS("Enter CVS Administrator password: ");
          if (!tmppass || strlen(tmppass)==0) {
                        error(1,0,"Failed to read password. Command aborted.");
          }
                curr_password = descramble(curr_password);
                if (trace) {
                        printf("OLD: %s, CUR: %s\n",curr_password,tmppass);
                        fflush(stdout);
                }
                
                if (strcmp(curr_password,tmppass)!=0) {
                        memset(curr_password,0,strlen(curr_password));
                        free(curr_password);
                        error(1,0,"Wrong password. Command aborted.");
                }
                memset(curr_password,0,strlen(curr_password));
                free(curr_password);
                memset(tmppass,0,strlen(tmppass));

                if (needPassword) {
                        passwd = read_user_password(user,PRM_NEW);
                }
#ifdef CLIENT_SUPPORT
                if (trace) {
                        printf("%s->cvs user: operation: %d, user=%s, passwd=%s(%d), 
alias=%s\n",CLIENT_SERVER_STR,op,safe_string(user),safe_string(passwd),needPassword | 
hasPassword,safe_string(alias));
                        fflush(stdout);
                }
                start_server ();
                ign_setup ();
                if (trace) {
                        printf("%s->sending options\n",CLIENT_SERVER_STR);
                        fflush(stdout);
                }
                if (op==PWD_CREATE) {
                  send_arg ("-a");
                } else if (op==PWD_UPDATE) {
                  send_arg ("-m");
                } else if (op==PWD_DELETE) {
                  send_arg ("-d");
                }
                send_arg(user);
                if (alias != NULL) {
                        send_arg("-u");
                        send_arg(alias);
                }
                if (needPassword | hasPassword) {
                        curr_password = scramble(passwd);
                        send_arg("-P");
                  send_arg (curr_password);
                } else {
                        curr_password = NULL;
                }
                
          send_to_server("admin_user\012",0);
          if (curr_password) {
                free(curr_password);
                memset(curr_password,0,strlen(curr_password));
          }
          if (passwd)
                memset(passwd,0,strlen(passwd));
                if (trace) {
                        printf("%s->waiting response\n",CLIENT_SERVER_STR);
                        fflush(stdout);
                }
          return get_responses_and_close();
#endif  /* CLIENT_SUPPORT */
        } else {/* (!server_active) */
#ifdef SERVER_SUPPORT
  if (hasPassword)
                passwd = descramble(passwd); /* Client scrmble it before sending */
        else 
                passwd = NULL;
#endif  
        }
  set_password_path(current_parsed_root);
  
        if (trace) {
                printf("%s->cvs user: operation: %d, user=%s, passwd=%s, 
alias=%s\n",CLIENT_SERVER_STR,op,safe_string(user),safe_string(passwd),safe_string(alias));
                fflush(stdout);
        }
        switch (op) {
        case PWD_CREATE:
                res = pw_add_user(user,passwd,alias);
                  if (res == -1) {
                    error(1,0,"User '%s' already exists.",user);
                  }
                  if (res != 0) {
                    error(1,errno,"Can't add user '%s' - Fatal internal error.",user);
                  }
                  error(0,0,"User '%s' successefully added.",user);
        break;
                
        case PWD_UPDATE:
                res = pw_mod_user(user,passwd,alias);
                  if (res == -1) {
                    error(1,0,"User '%s' not found.",user);
                  }
                  if (res != 0) {
                    error(1,errno,"Can't add user '%s' - Fatal internal error.",user);
                  }
                  error(0,0,"User '%s' successefully updated.",user);
        break;
                
        case PWD_DELETE:
        if (pw_del_user(user) == -1) {
                error(1,0,"Can't delete user '%s' - user not found.",user);
        } else {
                  error(0,0,"User '%s' successefully deleted.",user);
                }
        break;
        }       
        if (server_active && passwd!=NULL)
                free(passwd);
  return 0;
}

Attachment: src_server.c.diff
Description: Binary data

Attachment: src_mkmodules.c.diff
Description: Binary data

Attachment: src_Makefile.am.diff
Description: Binary data

Attachment: src_main.c.diff
Description: Binary data

Attachment: src_login.c.diff
Description: Binary data

Attachment: src_cvs.h.diff
Description: Binary data

Attachment: src_admin.c.diff
Description: Binary data

Attachment: full.diff
Description: Binary data

Attachment: doc_cvs.texinfo.diff
Description: Binary data

/*  
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:  
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * Copyright (C) 2000-2002
 *  Andrey Aristarkhov <[EMAIL PROTECTED]>. 
 *  All rights reserved
 * Partial Copyright (C) 1996
 *  David L. Nugent.  All rights reserved.
 *
 * $Id: user.h,v 1.2 2002/08/14 13:00:32 dron Exp $
 *
 * Header file for user & password file manipulation functions 
 * within CVS repository
 */

#ifndef CVS_USER_H_
#define CVS_USER_H_

#include <sys/types.h>
#include <pwd.h>
#include <grp.h>

#ifdef OS_FREEBSD
#include <sys/cdefs.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

int password (int argc, char **argv);
int user (int argc, char **argv);

enum updtype { PWD_CREATE, PWD_UPDATE, PWD_DELETE, PWD_UNDEFINED };
#define CVS_ADMIN_USER "admin"

#define PWBUFSZ 1024

#ifndef _PASSWORD_LEN
#define _PASSSWORD_LEN
#endif

#define MAX_PASSWORD_LEN  _PASSWORD_LEN
#define MIN_PASSWORD_LEN  6

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif


#ifdef HAVE_GETPASSPHRASE
#define GETPASS getpassphrase
#else
#define GETPASS getpass
#endif

#ifdef __cplucplus
}
#endif

#endif                          /* CVS_USER_H */

Reply via email to