Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/wtmpdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ extern int64_t wtmpdb_login (const char *db_path, int type,
const char *service, char **error);
extern int wtmpdb_logout (const char *db_path, int64_t id,
uint64_t usec_logout, char **error);
extern int wtmpdb_read_all (const char *db_path,
extern int wtmpdb_read_all (const char *db_path, int uniq,
int (*cb_func) (void *unused, int argc,
char **argv, char **azColName),
char **error);
extern int wtmpdb_read_all_v2 (const char *db_path,
extern int wtmpdb_read_all_v2 (const char *db_path, int uniq,
int (*cb_func) (void *unused, int argc,
char **argv, char **azColName),
void *userdata, char **error);
Expand Down
12 changes: 6 additions & 6 deletions lib/libwtmpdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ wtmpdb_get_id (const char *db_path, const char *tty, char **error)
each entry.
Returns 0 on success, -1 on failure. */
int
wtmpdb_read_all (const char *db_path,
wtmpdb_read_all (const char *db_path, int uniq,
int (*cb_func)(void *unused, int argc, char **argv,
char **azColName),
char **error)
Expand All @@ -168,7 +168,7 @@ wtmpdb_read_all (const char *db_path,
#if WITH_WTMPDBD
int r;

r = varlink_read_all (cb_func, NULL, error);
r = varlink_read_all (uniq, cb_func, NULL, error);
if (r >= 0)
return r;

Expand All @@ -185,11 +185,11 @@ wtmpdb_read_all (const char *db_path,
#endif
}

return sqlite_read_all (db_path?db_path:_PATH_WTMPDB, cb_func, NULL, error);
return sqlite_read_all (db_path?db_path:_PATH_WTMPDB, uniq, cb_func, NULL, error);
}

int
wtmpdb_read_all_v2 (const char *db_path,
wtmpdb_read_all_v2 (const char *db_path, int uniq,
int (*cb_func)(void *unused, int argc, char **argv,
char **azColName),
void *userdata, char **error)
Expand All @@ -199,7 +199,7 @@ wtmpdb_read_all_v2 (const char *db_path,
#if WITH_WTMPDBD
int r;

r = varlink_read_all (cb_func, userdata, error);
r = varlink_read_all (uniq, cb_func, userdata, error);
if (r >= 0)
return r;

Expand All @@ -216,7 +216,7 @@ wtmpdb_read_all_v2 (const char *db_path,
#endif
}

return sqlite_read_all (db_path?db_path:_PATH_WTMPDB, cb_func, userdata, error);
return sqlite_read_all (db_path?db_path:_PATH_WTMPDB, uniq, cb_func, userdata, error);
}


Expand Down
8 changes: 6 additions & 2 deletions lib/sqlite.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ sqlite_get_id (const char *db_path, const char *tty, char **error)
each entry.
Returns 0 on success, -1 on failure. */
int
sqlite_read_all (const char *db_path,
sqlite_read_all (const char *db_path, int uniq,
int (*cb_func)(void *unused, int argc, char **argv,
char **azColName),
void *userdata, char **error)
Expand All @@ -471,7 +471,11 @@ sqlite_read_all (const char *db_path,
if (r != 0)
return -r;

char *sql = "SELECT * FROM wtmp ORDER BY Login DESC, Logout ASC";
char *sql = uniq
? "SELECT ID, Type, User, Login, Logout, TTY, RemoteHost, Service FROM ("
"SELECT *,ROW_NUMBER() OVER (PARTITION BY User ORDER BY Login DESC) AS rn "
"FROM wtmp WHERE Login IS NOT NULL AND TTY != '~') WHERE rn = 1"
: "SELECT * FROM wtmp ORDER BY Login DESC, Logout ASC";

r = sqlite3_exec (db, sql, cb_func, userdata, &err_msg);
sqlite3_close (db);
Expand Down
2 changes: 1 addition & 1 deletion lib/sqlite.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ extern int sqlite_logout (const char *db_path, int64_t id,
uint64_t usec_logout, char **error);
extern int64_t sqlite_get_id (const char *db_path, const char *tty,
char **error);
extern int sqlite_read_all (const char *db_path,
extern int sqlite_read_all (const char *db_path, int uniq,
int (*cb_func)(void *unused, int argc, char **argv,
char **azColName),
void *userdata, char **error);
Expand Down
15 changes: 13 additions & 2 deletions lib/varlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ wtmpdb_entry_free (struct wtmpdb_entry *var)
}

int
varlink_read_all (int (*cb_func)(void *unused, int argc, char **argv,
varlink_read_all (int uniq, int (*cb_func)(void *unused, int argc, char **argv,
char **azColName),
void *userdata, char **error)
{
Expand All @@ -539,15 +539,26 @@ varlink_read_all (int (*cb_func)(void *unused, int argc, char **argv,
{}
};
_cleanup_(sd_varlink_unrefp) sd_varlink *link = NULL;
_cleanup_(sd_json_variant_unrefp) sd_json_variant *params = NULL;
sd_json_variant *result;
int r;

r = connect_to_wtmpdbd(&link, _VARLINK_WTMPDB_SOCKET, error);
if (r < 0)
return r;

r = sd_json_buildo(&params, SD_JSON_BUILD_PAIR("Uniq", SD_JSON_BUILD_INTEGER(uniq)));
if (r < 0)
{
if (error)
if (asprintf (error, "Failed to build JSON data: %s",
strerror(-r)) < 0)
*error = strdup ("Out of memory");
return r;
}

const char *error_id;
r = sd_varlink_call(link, "org.openSUSE.wtmpdb.ReadAll", NULL, &result, &error_id);
r = sd_varlink_call(link, "org.openSUSE.wtmpdb.ReadAll", params, &result, &error_id);
if (r < 0)
{
if (error)
Expand Down
2 changes: 1 addition & 1 deletion lib/varlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ extern int64_t varlink_login (int type, const char *user,
char **error);
extern int varlink_logout (int64_t id, uint64_t usec_logout, char **error);
extern int64_t varlink_get_id (const char *tty, char **error);
extern int varlink_read_all (int (*cb_func)(void *unused, int argc, char **argv,
extern int varlink_read_all (int uniq, int (*cb_func)(void *unused, int argc, char **argv,
char **azColName),
void *userdata, char **error);
extern int varlink_get_boottime (uint64_t *boottime, char **error);
Expand Down
13 changes: 13 additions & 0 deletions man/wtmpdb.8.xml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,19 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-u, --unique</option>
</term>
<listitem>
<para>
Display only the most recent log entry for each user.
This is the default when called as lastlog.
In contrast to the legacy lastlog tool, users without any log entries
will not be shown.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-w, --fullnames</option>
Expand Down
1 change: 1 addition & 0 deletions src/varlink-org.openSUSE.wtmpdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static SD_VARLINK_DEFINE_METHOD(
static SD_VARLINK_DEFINE_METHOD(
ReadAll,
SD_VARLINK_FIELD_COMMENT("Get all entries from the database"),
SD_VARLINK_DEFINE_INPUT(Uniq, SD_VARLINK_INT, 0),
SD_VARLINK_DEFINE_OUTPUT(Success, SD_VARLINK_BOOL, 0),
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(Data, WtmpdbEntry, SD_VARLINK_ARRAY | SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_OUTPUT(ErrorMsg, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
Expand Down
16 changes: 13 additions & 3 deletions src/wtmpdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ static int iflag = 0;
static int jflag = 0;
static int wflag = 0;
static int xflag = 0;
static int uniq = 0;
static const int name_len = 8; /* LAST_LOGIN_LEN */
static int login_fmt = TIMEFMT_SHORT;
static int login_len = 16; /* 16 = short, 24 = full */
Expand Down Expand Up @@ -663,6 +664,7 @@ usage (int retval)
fputs (" -S, --service Display PAM service used to login\n", output);
fputs (" -s, --since TIME Display who was logged in after TIME\n", output);
fputs (" -t, --until TIME Display who was logged in until TIME\n", output);
fputs (" -u, --unique Display the latest entry for each user, only.\n", output);
fputs (" -w, --fullnames Display full IP addresses and user and domain names\n", output);
fputs (" -x, --system Display system shutdown entries\n", output);
fputs (" --time-format FORMAT Display timestamps in the specified FORMAT:\n", output);
Expand Down Expand Up @@ -780,6 +782,7 @@ main_last (int argc, char **argv)
{"service", no_argument, NULL, 'S'},
{"since", required_argument, NULL, 's'},
{"system", no_argument, NULL, 'x'},
{"unique", no_argument, NULL, 'u'},
{"until", required_argument, NULL, 't'},
{"time-format", required_argument, NULL, TIMEFMT_VALUE},
{"json", no_argument, NULL, 'j'},
Expand All @@ -789,7 +792,7 @@ main_last (int argc, char **argv)
char *error = NULL;
int c;

while ((c = getopt_long (argc, argv, "0123456789adf:Fijn:p:RSs:t:wx",
while ((c = getopt_long (argc, argv, "0123456789adf:Fijn:p:RSs:t:uwx",
longopts, NULL)) != -1)
{
switch (c)
Expand Down Expand Up @@ -857,6 +860,9 @@ main_last (int argc, char **argv)
exit (EXIT_FAILURE);
}
break;
case 'u':
uniq = 1;
break;
case 'w':
wflag = 1;
break;
Expand Down Expand Up @@ -907,7 +913,7 @@ main_last (int argc, char **argv)
if (jflag)
printf ("{\n \"entries\": [\n");

if (wtmpdb_read_all (wtmpdb_path, print_entry, &error) != 0)
if (wtmpdb_read_all (wtmpdb_path, uniq, print_entry, &error) != 0)
{
if (error)
{
Expand Down Expand Up @@ -1282,7 +1288,11 @@ main (int argc, char **argv)

if (strcmp (basename(argv[0]), "last") == 0)
return main_last (argc, argv);
else if (argc == 1)
if (strcmp (basename(argv[0]), "lastlog") == 0) {
uniq = 1;
return main_last (argc, argv);
}
if (argc == 1)
usage (EXIT_SUCCESS);
else if (strcmp (argv[1], "last") == 0)
return main_last (--argc, ++argv);
Expand Down
10 changes: 8 additions & 2 deletions src/wtmpdbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,24 +473,30 @@ vl_method_read_all(sd_varlink *link, sd_json_variant *parameters,
sd_varlink_method_flags_t _unused_(flags),
void _unused_(*userdata))
{
struct p {
int uniq;
} p {
.uniq = 0
};
_cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL;
static const sd_json_dispatch_field dispatch_table[] = {
{ "Uniq", SD_JSON_VARIANT_INTEGER, sd_json_dispatch_int, offsetof(struct p, uniq), SD_JSON_MANDATORY },
{}
};
_cleanup_(freep) char *error = NULL;
int r;

log_msg (LOG_INFO, "Varlink method \"ReadAll\" called...");

r = sd_varlink_dispatch(link, parameters, dispatch_table, /* userdata= */ NULL);
r = sd_varlink_dispatch(link, parameters, dispatch_table, &p);
if (r != 0)
{
log_msg(LOG_ERR, "Get all entries request: varlink dispatch failed: %s", strerror (-r));
return r;
}

incomplete = 0;
r = wtmpdb_read_all_v2 (_PATH_WTMPDB, &wtmpdb_cb_func, (void *)&array, &error);
r = wtmpdb_read_all_v2 (_PATH_WTMPDB, p.uniq, &wtmpdb_cb_func, (void *)&array, &error);
if (r < 0 || error != NULL || incomplete)
{
log_msg(LOG_ERR, "Didn't got all entries from db: %s", error);
Expand Down
4 changes: 2 additions & 2 deletions tests/tst-login-logout.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ test_rotate (const char *db_path, const int days)
char *error = NULL;

counter = 0;
if (wtmpdb_read_all (db_path, count_entry, &error) != 0)
if (wtmpdb_read_all (db_path, 0, count_entry, &error) != 0)
{
if (error)
{
Expand Down Expand Up @@ -134,7 +134,7 @@ test_rotate (const char *db_path, const int days)
}

counter = 0;
if (wtmpdb_read_all (db_path, count_entry, &error) != 0)
if (wtmpdb_read_all (db_path, 0, count_entry, &error) != 0)
{
if (error)
{
Expand Down