🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

7 total messages Started by John F Haugh II Tue, 15 Jan 1991 15:09
Bug in users command
#221
Author: John F Haugh II
Date: Tue, 15 Jan 1991 15:09
107 lines
3801 bytes
I think there is a bug in the code for "users" in the 4.3-reno
source.  The problem is that the first user name is always printed
as is the last user name.  If there is exactly one user on the
system, and the user is logged on more than once, you get the
user name twice.

Here is the code, as I have modified it to run on SCO Xenix.  The
file was short enough that a diff didn't seem warranted.  The problem
was in the for-while loop that was at the end of main().  I replaced
it with a simpler for loop.
--
/*
 * Copyright (c) 1980, 1987 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted provided
 * that: (1) source distributions retain this entire copyright notice and
 * comment, and (2) distributions including binaries display the following
 * acknowledgement:  ``This product includes software developed by the
 * University of California, Berkeley and its contributors'' in the
 * documentation or other materials provided with the distribution and in
 * all advertising materials mentioning features or use of this software.
 * Neither the name of the University nor the names of its contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\
 All rights reserved.\n";
#endif /* not lint */

#ifndef lint
static char sccsid[] = "@(#)users.c	5.9 (Berkeley) 6/1/90";
#endif /* not lint */

#include <sys/types.h>
#include <errno.h>
#include <utmp.h>
#include <stdio.h>

#define	MAXUSERS	200

#ifndef	UT_NAMESIZE
#define	UT_NAMESIZE	(sizeof ((struct utmp *) 0)->ut_name)
#endif

#ifndef	_PATH_UTMP
#define	_PATH_UTMP	"/etc/utmp"
#endif

main()
{
	register int cnt, ncnt;
	struct utmp utmp;
	char names[MAXUSERS][UT_NAMESIZE];
	int scmp();

	if (!freopen(_PATH_UTMP, "r", stdin)) {
		(void)fprintf(stderr, "users: can't open %s.\n", _PATH_UTMP);
		exit(1);
	}
	for (ncnt = 0;
	    fread((char *)&utmp, sizeof(utmp), 1, stdin) == 1;)
		if (*utmp.ut_name) {
#ifdef	USER_PROCESS
			if (utmp.ut_type != USER_PROCESS)
				continue;
#endif
			if (ncnt == MAXUSERS) {
				(void)fprintf(stderr,
				    "users: too many users.\n");
				break;
			}
			(void)strncpy(names[ncnt], utmp.ut_name, UT_NAMESIZE);
			++ncnt;
		}

	if (ncnt) {
		qsort(names, ncnt, UT_NAMESIZE, scmp);
		(void)printf("%s", names[0]);
		for (cnt = 1; cnt < ncnt; ++cnt) {
			if (! strncmp (names[cnt - 1], names[cnt], UT_NAMESIZE))
				continue;

			(void)printf(" %.*s", UT_NAMESIZE, names[cnt]);
		}
		(void)printf("\n");
	}
	exit(0);
}

scmp(p, q)
	char *p, *q;
{
	return(strcmp(p, q));
}
--
-- 
John F. Haugh II                             UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 832-8832                           Domain: jfh@rpp386.cactus.org
"While you are here, your wives and girlfriends are dating handsome American
 movie and TV stars. Stars like Tom Selleck, Bruce Willis, and Bart Simpson."
Re: Bug in users command
#222
Author: Dan Bernstein
Date: Fri, 18 Jan 1991 11:17
74 lines
2419 bytes
In article <18947@rpp386.cactus.org> jfh@rpp386.cactus.org (John F Haugh II) writes:
> I think there is a bug in the code for "users" in the 4.3-reno
> source.  The problem is that the first user name is always printed
> as is the last user name.  If there is exactly one user on the
> system, and the user is logged on more than once, you get the
> user name twice.

Two other obvious bugs: first, the number of users is limited to 200;
second, scmp() appears to take the wrong argument types. Here is a
public-domain version that fixes these problems. This is derived from
the public-domain u.c published on comp.sources.unix as part of the pty
package; neither program was derived from Berkeley source.

---Dan

/* Public domain. */
#include <stdio.h>
#include <utmp.h>
#include <strings.h>
extern char *malloc();
#define PTYUTMP_FILE "/etc/utmp"

int compar(s,t)
char (**s)[8];
char (**t)[8];
{
 return -strncmp(&(**s)[0],&(**t)[0],8);
}

main()
{
 register FILE *fi;
 struct utmp ut;
 char (*us)[8];
 char (**up)[8];
 int lines = 0;
 int i = 0;
 
 if (!(fi = fopen(PTYUTMP_FILE,"r")))
  {
   fprintf(stderr,"users: cannot open %s\n",PTYUTMP_FILE);
   exit(1);
  }
 while (fread((char *) &ut,sizeof(ut),1,fi))
   if (ut.ut_name[0])
     lines++;
 (void) fclose(fi);
 us = malloc(sizeof(*us) * (lines + 50));
 up = malloc(sizeof(*up) * (lines + 50));
 if ((!us) || (!up))
  {
   fprintf(stderr,"users: cannot allocate space for user list\n");
   exit(2);
  }
 if (!(fi = fopen(PTYUTMP_FILE,"r")))
  {
   fprintf(stderr,"users: cannot open %s\n",PTYUTMP_FILE);
   exit(1);
  }
 while (fread((char *) &ut,sizeof(ut),1,fi))
   if ((ut.ut_name[0]) && (i < lines + 50))
    {
     (void) strncpy(us[i],ut.ut_name,8);
     up[i] = us + i;
     i++;
    }
 (void) fclose(fi);
 (void) qsort(up,i,sizeof(*up),compar);

 while (i-- > 0)
   (void) printf((i ? "%.8s " : "%.8s\n"),up[i]);

 (void) exit(0);
}
Re: Bug in users command
#223
Author: John F Haugh II
Date: Fri, 18 Jan 1991 16:18
16 lines
1533 bytes
In article <1126:Jan1811:17:4091@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>Two other obvious bugs: first, the number of users is limited to 200;
>second, scmp() appears to take the wrong argument types. Here is a
>public-domain version that fixes these problems. This is derived from
>the public-domain u.c published on comp.sources.unix as part of the pty
>package; neither program was derived from Berkeley source.

Look at the array that is being sorted.  It will be pretty obvious
once you look at the type of that object that scmp is being called
properly.  And obviously, since the sort does work, it is being
called with the correct values.
-- 
John F. Haugh II                             UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 832-8832                           Domain: jfh@rpp386.cactus.org
"While you are here, your wives and girlfriends are dating handsome American
 movie and TV stars. Stars like Tom Selleck, Bruce Willis, and Bart Simpson."
Re: Bug in users command
#224
Author: Larry Wall
Date: Fri, 18 Jan 1991 17:58
31 lines
1949 bytes
In article <1126:Jan1811:17:4091@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
: In article <18947@rpp386.cactus.org> jfh@rpp386.cactus.org (John F Haugh II) writes:
: > I think there is a bug in the code for "users" in the 4.3-reno
: > source.  The problem is that the first user name is always printed
: > as is the last user name.  If there is exactly one user on the
: > system, and the user is logged on more than once, you get the
: > user name twice.
: 
: Two other obvious bugs: first, the number of users is limited to 200;
: second, scmp() appears to take the wrong argument types. Here is a
: public-domain version that fixes these problems. This is derived from
: the public-domain u.c published on comp.sources.unix as part of the pty
: package; neither program was derived from Berkeley source.

And here's one in Perl.  (I recognize that hardcoding the template
for the utmp structure is a weakness.  On the other hand, it's short
and to the point.  I refer you to the definition of "Minimalism" in
the Perl book.)

#!/usr/bin/perl
$UTMP = 'A8 A8 A16 l';	# Your machine may be different.
$utlen = length(pack($UTMP,0));
open(UTMP,'/etc/utmp') || die "utmp unreadable: $!\n";;
while (read(UTMP,$utmp,$utlen)) {
    ($line,$name,$host,$time) = unpack($UTMP,$utmp);
    $seen{$name}++ if $name;
}   
print join(' ', sort keys(%seen)), "\n";

Larry Wall
lwall@jpl-devvax.jpl.nasa.gov
Re: Bug in users command
#225
Author: Bill Davidson
Date: Sat, 19 Jan 1991 01:36
24 lines
1332 bytes
In article <11104@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
>And here's one in Perl.  (I recognize that hardcoding the template
>for the utmp structure is a weakness.  On the other hand, it's short
>and to the point.  I refer you to the definition of "Minimalism" in
>the Perl book.)

The perl version is probably faster but if for some reason you don't
have perl and you don't mind it being slightly slower:

% cat > users.sh
#!/bin/sh
USERS=`who|sort|awk '{print $1}'`
echo $USERS
^D
% chmod +x users.sh
% users.sh
bambam barney betty dino dino fred pebbles wilma

I'd say that's pretty minimal.  Of course it assumes that your shell
can handle back quotes reasonably and that the user name is the first
field in the output of "who" but nobody's perfect.  If you want to cut
out reports of repeat logins, just add a "-u" parameter to the "sort".

--Bill Davidson
Re: Bug in users command
#226
Author: Dan Bernstein
Date: Sat, 19 Jan 1991 16:26
21 lines
1414 bytes
In article <18958@rpp386.cactus.org> jfh@rpp386.cactus.org (John F Haugh II) writes:
> In article <1126:Jan1811:17:4091@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> >second, scmp() appears to take the wrong argument types. Here is a
> Look at the array that is being sorted.  It will be pretty obvious
> once you look at the type of that object that scmp is being called
> properly.

No. Unless I'm mistaken, the objects being passed in are pointers to
arrays of char, while the objects expected are pointers to char. There
is no implicit conversion that justifies this, though undoubtedly it
works on most machines.

> And obviously, since the sort does work, it is being
> called with the correct values.

Obviously there aren't any extra levels of indirection, but that doesn't
make the code right.

Anyway, the 200-user limit is purely silly.

---Dan
Re: Bug in users command
#228
Author: John F Haugh II
Date: Sat, 19 Jan 1991 19:34
24 lines
1822 bytes
In article <18928:Jan1916:26:3291@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>No. Unless I'm mistaken, the objects being passed in are pointers to
>arrays of char, while the objects expected are pointers to char. There
>is no implicit conversion that justifies this, though undoubtedly it
>works on most machines.

How does a pointer to an unknown number of characters differ from a
pointer to a known number of characters when passed as an argument?

qsort() invokes scmp() with the pointer to an array of UT_NAMESIZE
characters.  scmp() is expecting a pointer to a character, which is
coincidentally the same type object as "char a[UT_NAMESIZE]" since
any "array of type X" type parameters are converted to "pointer to
type X object" parameters.  I believe this is plainly specified
both by ANSI-C and K&R-Classic.

>Anyway, the 200-user limit is purely silly.

Agreed.
-- 
John F. Haugh II                             UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 832-8832                           Domain: jfh@rpp386.cactus.org
"While you are here, your wives and girlfriends are dating handsome American
 movie and TV stars. Stars like Tom Selleck, Bruce Willis, and Bart Simpson."
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads