More utmp stuff

Freddie freddie at
Thu Mar 23 14:53:07 GMT 2000

Hmm. Playing around with the utmp stuff (oh yay)...

A question, why is there a utmp directory parameter? This from the 
GETUTENT(3) man page:

        utmpname() sets the name of the utmp-format file  for  the
        other utmp functions to access.  If utmpname() is not used
        to set the filename before the other functions  are  used,
        they assume _PATH_UTMP, as defined in <paths.h>.

If there's already a valid OS default path (at least, there is on 
Linux/glibc 2.0.x/2.1.x), why force the user to specify it? Perhaps it 
should be an optional parameter, only needed if _PATH_UTMP isn't defined?

Apart from that, I added setutent() and endutent() around the pututline(u) 
call, as the docs say you should do. Rewinding to the start of the utmp 
file before updating/adding an entry is usually a Good Idea, and so is 
closing it after we're done.

I think the problem with utmp showing up multiple times for the same pid is 
the way that pututline() searches for the right entry to use.

        pututline()  writes  the  utmp  structure ut into the utmp
        file.  It uses getutid() to search for the proper place in
        the  file  to  insert the new entry.  If it cannot find an
        appropriate slot for ut, pututline() will append  the  new

        getutid()  searches forward from the current file position
        in the  utmp  file  based  upon  ut.   If  ut->ut_type  is
        RUN_LVL,  BOOT_TIME, NEW_TIME, or OLD_TIME, getutid() will
        find  the  first  entry  whose   ut_type   field   matches
        ut->ut_type.   If  ut->ut_type  is  one  of  INIT_PROCESS,
        will  find  the  first  entry  whose  ut_id  field matches

ut->ut_id is set to the "int i" parameter that utmp_claim gets called with, 
which ends up being...

#ifdef WITH_UTMP
	utmp_claim(&crec, conn, foundi);

in claim_connection. foundi is... umm... a free spot? (don't understand 
this code)

	/* find a free spot */
	for (i=0;i<max_connections;i++) {
		if (i>=total_recs ||
		    sys_lseek(fd,i*sizeof(crec),SEEK_SET) != i*sizeof(crec) ||
		    read(fd,&crec,sizeof(crec)) != sizeof(crec)) {
			if (foundi < 0) foundi = i;

If foundi changes for each connection (to a new share etc), then obviously 
you'll end up with a different ut->ut_id, and therefore, a new utmp entry.

freddie  smb/1    zugzug            1:13am  0.00s 34:52m   ?     -
freddie  smb/2    zugzug            1:13am  0.00s 34:52m   ?     -
freddie  smb/3    zugzug            1:13am  0.00s 34:52m   ?     -

Service      uid      gid      pid     machine
freddie      freddie  users     9493   zugzug   ( Fri Mar 24 
01:13:49 2000
software     freddie  users     9493   zugzug   ( Fri Mar 24 
01:13:51 2000
public       freddie  users     9493   zugzug   ( Fri Mar 24 
01:13:52 2000

These are _all the same pid_, and there should be _a single utmp entry_ for 
the whole lot of them. Phew.

Anyone feel like commenting/coming up with another way to do ut->ut_id? 
I'll work on it while I wait :)


More information about the samba-technical mailing list