AUSAM/source/S/cnvtwtmp.c
#
/*
* convert old wtmp format to AUSAM
*
* Piers Lauder Mar '78
*/
#include <local-system>
#ifdef AUSAM
#include <wtmp.h>
char etcpasswd[] "/etc/passwd"; /* old passwd file */
#define PASSWDZ 4000 /* size of old passwd file (should use stat) */
#define USERTIME 60*HZ /* fudge user times */
#define SYSTIME 30*HZ /* fudge system times */
struct oldfmt
{
union { char type; char name[2]; } o0;
char o_fill0[2];
long o_odate;
union { struct { char otty; char fill1; long time; } o2;
struct { long ndate; char fill2[2]; } od;
} o1;
char o_fill1[2];
}
old[512/16];
struct wtmp new[512/WTMPSIZ];
#define NENT ((sizeof new)/(sizeof new[0]))
#define UERROR 0177777
int nowarn;
main( argc, argv )
{
register struct oldfmt *op;
register struct wtmp *ep;
register n;
unsigned enteruid(), fetchuid();
if ( argc > 1 )
nowarn++;
ep = new;
while ( (n = read( 0, old, (sizeof old) )) > 0 )
{
for ( op = old , n =/ WTMPSIZ ; n-- ; op++ )
{
switch ( op->o0.type )
{
case '\004': /* date change */
ep->d_type = D_TYPE;
ep->d_newtime = op->o1.od.ndate;
ep->d_oldtime = op->o_odate;
break;
default:
if ( (op->o0.type > ' ') && (op->o1.o2.time) ) /* log on */
{
ep->u_type = U_TYPE;
ep->u_ttyid = op->o1.o2.otty;
fixname( op->o0.name );
if ( (ep->u_u_id = enteruid( op )) == UERROR )
{
warn( "Unrecognised user" , op );
}
ep->u_logintime = op->o1.o2.time;
copyname( op->o0.name, ep->u_u_name );
}
else
{
warn( "Bad entry" , op );
continue;
}
break;
case '\0':
if ( op->o1.o2.time ) /* log off */
{
if ( op->o1.o2.otty == '~' ) /* system boot */
{
ep->s_type = S_TYPE;
ep->s_boottime = op->o1.o2.time;
}
else
{
ep->w_type = O_TYPE;
ep->w_ttyid = op->o1.o2.otty;
if ( (ep->w_uid = fetchuid( op )) == UERROR )
{
warn( "Unrecognised logoff", op );
}
ep->w_finishtime = op->o1.o2.time;
ep->w_usertime = USERTIME;
ep->w_systime = SYSTIME;
}
}
else
{
warn( "Bad entry" , op );
continue;
}
break;
}
if ( ++ep >= &new[NENT] )
{
write( 1, new, (sizeof new) );
ep = new;
}
}
}
if ( n = ep - new )
write( 1, new, n*WTMPSIZ );
return( 0 );
}
fixname( cp )
register char *cp;
{
register i = 8;
register f = 0;
do
{
if ( *cp == ' ' || !*cp || f )
{
f++;
*cp = '\0';
}
cp++;
}
while
( --i );
}
copyname( cp1, cp2 )
register char *cp1, *cp2;
{
register i = 8;
do *cp2++ = *cp1++; while ( --i );
}
struct nm_entry
{
unsigned nm_uid;
char nm_name[8];
char nm_flags;
}
ents[NUSERS];
struct nm_entry *ttys[0177];
int nusers;
int passwd, passwdz;
char pwbuf[PASSWDZ+2] "\n\n"; /* first char assumed by "matchname" */
unsigned enteruid( op )
register struct oldfmt *op;
{
register struct nm_entry *ep, *fp;
struct nm_entry **tp;
unsigned uid, matchname();
if ( *(tp = &ttys[op->o1.o2.otty&0177]) )
{
/* struct wtmp fix;
fix.w_type = O_TYPE; /* log off previous user */
/* fix.w_ttyid = op->o1.o2.otty;
fix.w_uid = (*tp)->nm_uid;
fix.w_finishtime = op->o1.o2.time;
fix.w_usertime = USERTIME;
fix.w_systime = SYSTIME;
write( 1, &fix, (sizeof fix) );
*/
warn( "Multi-logon", op );
}
for ( fp = 0 , ep = ents ; ep <= &ents[nusers] ; ep++ )
if ( eqname( op->o0.name , ep->nm_name ) )
goto found;
else
if ( !fp && !ep->nm_flags )
fp = ep;
if ( !(ep = fp) )
{
prints( 2, "Too many users!\n" );
exit( -1 );
}
if ( !passwd )
{
if ( (passwd = open( etcpasswd, 0 )) < 0 )
{
prints( 2, etcpasswd );
prints( 2, ": cannot open.\n" );
exit( -1 );
}
if ( (passwdz = read( passwd, &pwbuf[2], (sizeof pwbuf)-2 )) == ((sizeof pwbuf)-2) )
{
prints( 2, etcpasswd );
prints( 2, ": too large!\n" );
exit( -1 );
}
}
if ( (uid = matchname( op->o0.name )) != UERROR )
{
nusers++;
copyname( op->o0.name, ep->nm_name );
ep->nm_uid = uid;
ep->nm_flags++;
found:
*tp = ep;
return( ep->nm_uid );
}
return( UERROR );
}
unsigned fetchuid( op )
struct oldfmt *op;
{
register struct nm_entry *ep;
register char tty = op->o1.o2.otty & 0177;
if ( ep = ttys[tty] )
{
ttys[tty] = 0;
return( ep->nm_uid );
}
return( UERROR );
}
int eqname( cp1, cp2 )
register char *cp1, *cp2;
{
register i = 8;
do
if ( *cp1++ != *cp2++ )
return( 0 );
while
( --i );
return( 1 );
}
unsigned matchname( np )
char *np;
{
static char mname[10] "\n"; int dvec[(sizeof mname)+1], mnsiz;
{
/*
* initialise match string
*/
register i; register char *cp1, *cp2;
for ( cp1 = np , cp2 = &mname[1] , i = 0 ;
(*cp1 != '\0') && (++i <= 8) ;
*cp2++ = *cp1++ );
*cp2 = ':';
mnsiz = i+2;
}
{
/*
* initialise match vector
*/
register i = 0; register d_hb = 0;
while ( d_hb != mnsiz )
{
register j = 0; i++;
while ( (j < (mnsiz - i)) && (mname[j] == mname[i+j]) )
j++;
while ( d_hb < (j+i) )
dvec[++d_hb] = i;
}
}
{
/*
* match the string
*/
register r = 0; register k = 0; register N = mnsiz;
int M_N = passwdz - N;
while ( r <= M_N )
{
while ( (k != N) && (mname[k] == pwbuf[r+k]) )
k++;
if ( k == N )
{
/*
* extract uid
*/
struct { char *cp; };
N.cp = &pwbuf[r+k];
while ( *N.cp++ != ':' ); /* skip password */
return( atoi( N.cp ) );
}
else if ( k )
{
r =+ dvec[k];
k =- dvec[k];
}
else
r++;
}
return( UERROR );
}
}
warn( s, op )
char *s;
register struct oldfmt *op;
{
char n[9];
if ( nowarn )
return;
prints( 2, s );
prints( 2, " -" );
if ( op->o0.type > ' ' )
{
prints( 2, " name: '" );
copyname( op->o0.name, n );
n[8] = '\0';
prints( 2, n );
ptty:
prints( 2, "' tty: '" );
op->o1.o2.fill1 = '\0';
prints( 2, &op->o1.o2.otty );
}
else
{
prints( 2, " type: '" );
op->o0.name[1] = '\0';
op->o0.type =+ '0';
prints( 2, &op->o0.type );
if ( op->o0.type == '0' )
goto ptty;
}
prints( 2, "' on: " );
prints( 2, ctime( op->o1.o2.time ) );
}
#endif