Line data Source code
1 : /* GNU's users.
2 : Copyright (C) 1992-2005, 2007 Free Software Foundation, Inc.
3 :
4 : This program is free software: you can redistribute it and/or modify
5 : it under the terms of the GNU General Public License as published by
6 : the Free Software Foundation, either version 3 of the License, or
7 : (at your option) any later version.
8 :
9 : This program is distributed in the hope that it will be useful,
10 : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : GNU General Public License for more details.
13 :
14 : You should have received a copy of the GNU General Public License
15 : along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 :
17 : /* Written by jla; revised by djm */
18 :
19 : #include <config.h>
20 : #include <getopt.h>
21 : #include <stdio.h>
22 :
23 : #include <sys/types.h>
24 : #include "system.h"
25 :
26 : #include "error.h"
27 : #include "long-options.h"
28 : #include "quote.h"
29 : #include "readutmp.h"
30 :
31 : /* The official name of this program (e.g., no `g' prefix). */
32 : #define PROGRAM_NAME "users"
33 :
34 : #define AUTHORS "Joseph Arceneaux", "David MacKenzie"
35 :
36 : /* The name this program was run with. */
37 : char *program_name;
38 :
39 : static int
40 0 : userid_compare (const void *v_a, const void *v_b)
41 : {
42 0 : char **a = (char **) v_a;
43 0 : char **b = (char **) v_b;
44 0 : return strcmp (*a, *b);
45 : }
46 :
47 : static void
48 9 : list_entries_users (size_t n, const STRUCT_UTMP *this)
49 : {
50 9 : char **u = xnmalloc (n, sizeof *u);
51 : size_t i;
52 9 : size_t n_entries = 0;
53 :
54 18 : while (n--)
55 : {
56 0 : if (IS_USER_PROCESS (this))
57 : {
58 : char *trimmed_name;
59 :
60 0 : trimmed_name = extract_trimmed_name (this);
61 :
62 0 : u[n_entries] = trimmed_name;
63 0 : ++n_entries;
64 : }
65 0 : this++;
66 : }
67 :
68 9 : qsort (u, n_entries, sizeof (u[0]), userid_compare);
69 :
70 9 : for (i = 0; i < n_entries; i++)
71 : {
72 0 : char c = (i < n_entries - 1 ? ' ' : '\n');
73 0 : fputs (u[i], stdout);
74 0 : putchar (c);
75 : }
76 :
77 9 : for (i = 0; i < n_entries; i++)
78 0 : free (u[i]);
79 9 : free (u);
80 9 : }
81 :
82 : /* Display a list of users on the system, according to utmp file FILENAME.
83 : Use read_utmp OPTIONS to read FILENAME. */
84 :
85 : static void
86 9 : users (const char *filename, int options)
87 : {
88 : size_t n_users;
89 : STRUCT_UTMP *utmp_buf;
90 :
91 9 : if (read_utmp (filename, &n_users, &utmp_buf, options) != 0)
92 0 : error (EXIT_FAILURE, errno, "%s", filename);
93 :
94 9 : list_entries_users (n_users, utmp_buf);
95 :
96 9 : free (utmp_buf);
97 9 : }
98 :
99 : void
100 28 : usage (int status)
101 : {
102 28 : if (status != EXIT_SUCCESS)
103 26 : fprintf (stderr, _("Try `%s --help' for more information.\n"),
104 : program_name);
105 : else
106 : {
107 2 : printf (_("Usage: %s [OPTION]... [ FILE ]\n"), program_name);
108 2 : printf (_("\
109 : Output who is currently logged in according to FILE.\n\
110 : If FILE is not specified, use %s. %s as FILE is common.\n\
111 : \n\
112 : "),
113 : UTMP_FILE, WTMP_FILE);
114 2 : fputs (HELP_OPTION_DESCRIPTION, stdout);
115 2 : fputs (VERSION_OPTION_DESCRIPTION, stdout);
116 2 : emit_bug_reporting_address ();
117 : }
118 28 : exit (status);
119 : }
120 :
121 : int
122 38 : main (int argc, char **argv)
123 : {
124 : initialize_main (&argc, &argv);
125 38 : program_name = argv[0];
126 38 : setlocale (LC_ALL, "");
127 : bindtextdomain (PACKAGE, LOCALEDIR);
128 : textdomain (PACKAGE);
129 :
130 38 : atexit (close_stdout);
131 :
132 38 : parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, VERSION,
133 : usage, AUTHORS, (char const *) NULL);
134 35 : if (getopt_long (argc, argv, "", NULL, NULL) != -1)
135 6 : usage (EXIT_FAILURE);
136 :
137 29 : switch (argc - optind)
138 : {
139 2 : case 0: /* users */
140 2 : users (UTMP_FILE, READ_UTMP_CHECK_PIDS);
141 2 : break;
142 :
143 7 : case 1: /* users <utmp file> */
144 7 : users (argv[optind], 0);
145 7 : break;
146 :
147 20 : default: /* lose */
148 20 : error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
149 20 : usage (EXIT_FAILURE);
150 : }
151 :
152 9 : exit (EXIT_SUCCESS);
153 : }
|