AUSAM/source/libc/chngpwent.c

#
/*
 *	alters the passwd entry specified by "pe->pw_uid" and "*pe->pw_strings[LNAME]
 *	to contain the data in the area pointed to by "pe".
 *	Returns 1 for success, 0 for failure and -1 for error
 *	Note: the uid and login name MUST match
 */

#include <local-system>
#include	<passwd.h>

char	pwfd, pwfl;
extern char	*etcpasswd;

chngpwent(pe)
register struct pwent	*pe;
{
register struct pwent	*rp;

struct pwent	p;
int	ht;
int	ri;
long	hte, te, newt;


ri = -1;

/*	open and lock	*/

if( !pwfl)
	{
	if((pwfd=open(etcpasswd,2)) < 0) return (-1);
	pwfl++;
	}
writelock(pwfd);

/*	initialise	*/

do	{
	rp = &p;
	if(!getutab(pwfd,pe->pw_uid,&te)) break;
	if(equalentry(pwfd,pe,&te) < 1)
		{
		ri=0;
		break;
		}
	if(!getentry(pwfd,rp,&te)) break;
	
	/* got entry ok */
	
	pe->pw_next = rp->pw_next;
	pe->pw_last = rp->pw_last;
	
	/* add new entry before deleting old */
	
	if(addentry(pwfd,pe,&newt) <= 0)break;
	
	/* now newt is the address of the added entry */
	
	if(pe->pw_last == PWENTNULL)
		{
		/* beginning of list - update the hash ptr */
		ht=pwhash(pe->pw_strings[LNAME]);
		if(!gethtab(pwfd,ht,&hte))break;
		if(hte != te) break;
		if(!puthtab(pwfd,ht,&newt)) break;
		}
	
	if(pe->pw_next != PWENTNULL)
		{
		/* this element has a next in list */
		if(!getentry(pwfd,rp,&pe->pw_next))break;
		rp->pw_last=newt;
		if(!putentry(pwfd,rp,&pe->pw_next))break;
		}
	
	if(pe->pw_last != PWENTNULL)
		{
		/* this element has a last in list */
		if(!getentry(pwfd,rp,&pe->pw_last))break;
		rp->pw_next=newt;
		if(!putentry(pwfd,rp,&pe->pw_last))break;
		}
	
	/* done, zap the uid entry and that is all */
	
	if(!pututab(pwfd,pe->pw_uid,&newt))break;
	
	ri=1;
	} while(0);

unlock();

return(ri);
}