Thread View: comp.bugs.4bsd
7 messages
7 total messages
Started by John F Haugh II
Tue, 15 Jan 1991 15:09
Bug in users command
Author: John F Haugh II
Date: Tue, 15 Jan 1991 15:09
Date: Tue, 15 Jan 1991 15:09
107 lines
3801 bytes
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
Author: Dan Bernstein
Date: Fri, 18 Jan 1991 11:17
Date: Fri, 18 Jan 1991 11:17
74 lines
2419 bytes
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
Author: John F Haugh II
Date: Fri, 18 Jan 1991 16:18
Date: Fri, 18 Jan 1991 16:18
16 lines
1533 bytes
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
Author: Larry Wall
Date: Fri, 18 Jan 1991 17:58
Date: Fri, 18 Jan 1991 17:58
31 lines
1949 bytes
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
Author: Bill Davidson
Date: Sat, 19 Jan 1991 01:36
Date: Sat, 19 Jan 1991 01:36
24 lines
1332 bytes
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
Author: Dan Bernstein
Date: Sat, 19 Jan 1991 16:26
Date: Sat, 19 Jan 1991 16:26
21 lines
1414 bytes
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
Author: John F Haugh II
Date: Sat, 19 Jan 1991 19:34
Date: Sat, 19 Jan 1991 19:34
24 lines
1822 bytes
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