AUSAM/source/libc/addpwent.c
#
/*
* This function adds the entry pointed to by "pe" to a
* password file. If the pointer at uidtable(pe->pw_uid)==NULL
* then this is the new uid. If not then new uid is allocated.
* Returns the new uid or -1 for error
*/
#include <local-system>
#include <passwd.h>
char pwfd, pwfl;
extern char *etcpasswd;
addpwent(pe)
register struct pwent *pe;
{
register struct pwent *rp;
struct pwent p;
long t, hte;
int ht;
int ri;
ri = -1;
/* open and lock */
if( !pwfl)
{
if((pwfd=open(etcpasswd,2)) < 0) return (-1);
pwfl++;
}
writelock(pwfd);
/* initialise */
do {
rp = &p;
pe->pw_next = PWENTNULL;
ht=pwhash(pe->pw_strings[LNAME]);
if( !gethtab(pwfd,ht,&pe->pw_last)) break;
/* now list from "pe->pw_last" may/maynot be null and
may/maynot contain the entry. */
if( chkentry(pwfd,pe,&pe->pw_last) < 1) break;
/* now "pe->pw_last" is the seek address for the last list element
or "PWENTNULL" for a null list */
if(( !getutab(pwfd,pe->pw_uid,&hte)) || (hte != PWENTNULL))
{
if((pe->pw_uid=freetable(pwfd)) < 0) break;
}
if(pe->pw_last == PWENTNULL)
{
/* no list, so just add it in */
if(addentry(pwfd,pe,&t) <= 0) break;
if(!puthtab(pwfd,ht,&t)) break;
if(!pututab(pwfd,pe->pw_uid,&t)) break;
}
else
{
/* here for a list at least one long, so ad on at end */
if(!getentry(pwfd,rp,&pe->pw_last)) break;
if(addentry(pwfd,pe,&rp->pw_next) <= 0) break;
/* now "pe->pw_last" contains the seek address of the last list
element stored in "p". "rp->pw_next" contains the seek address
for the new element contained in "*pe". "pe->pw_uid" is the
new uid, and only remains to write data out */
if(!pututab(pwfd,pe->pw_uid,&rp->pw_next)) break;
if(!putentry(pwfd,rp,&pe->pw_last)) break;
}
/* return uid and that is all */
ri=pe->pw_uid;
} while(0);
unlock();
return(ri);
}