Skip to content

Commit

Permalink
ls: add '--long' (-l) option to show last mod time
Browse files Browse the repository at this point in the history
The "last touch" (or use) time can be had by also specifying
the -u switch.

[copeland@lastpass.com implemented following changes:
 - put timestamps at the front
 - use short iso time format
 - show mtime by default, add a new switch for
   last touch]

Signed-off-by: Bob Copeland <copeland@lastpass.com>
  • Loading branch information
TheHippoMan authored and Bob Copeland committed Oct 5, 2015
1 parent 91d0218 commit fa870c1
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 8 deletions.
4 changes: 2 additions & 2 deletions blob.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ static struct account *account_parse(struct chunk *chunk, const unsigned char ke
entry_boolean(pwprotect);
skip(genpw);
skip(sn);
skip(last_touch);
entry_plain(last_touch);
skip(autologin);
skip(never_autofill);
skip(realm_data);
Expand All @@ -295,7 +295,7 @@ static struct account *account_parse(struct chunk *chunk, const unsigned char ke
skip(individualshare);
skip(notetype);
skip(noalert);
skip(last_modified_gmt);
entry_plain(last_modified_gmt);
skip(hasbeenshared);
skip(last_pwchange_gmt);
skip(created_gmt);
Expand Down
1 change: 1 addition & 0 deletions blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct account {
char *username, *username_encrypted;
char *password, *password_encrypted;
char *note, *note_encrypted;
char *last_touch, *last_modified_gmt;
bool pwprotect;

struct list_head field_head;
Expand Down
58 changes: 55 additions & 3 deletions cmd-ls.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>

static bool long_listing = false;
static bool show_mtime = true;

struct node {
char *name;
Expand All @@ -20,6 +24,26 @@ struct node {
struct node *next_sibling;
};

static char *format_timestamp(char *timestamp, bool utc)
{
char temp[60];
struct tm *ts_tm;

time_t ts_time_t = (time_t) strtoul(timestamp, NULL, 10);

if (ts_time_t == 0)
return xstrdup("");

if (utc)
ts_tm = gmtime(&ts_time_t);
else
ts_tm = localtime(&ts_time_t);

strftime(temp, sizeof(temp), "%Y-%m-%d %H:%M", ts_tm);

return xstrdup(temp);
}

static void insert_node(struct node *head, const char *path, struct account *account)
{
char *slash = NULL;
Expand Down Expand Up @@ -73,8 +97,17 @@ static void print_node(struct node *head, int level)
if (node->name) {
for (int i = 0; i < level; ++i)
printf(" ");
if (node->account)
if (node->account) {
if (long_listing) {
_cleanup_free_ char *timestr;
if (show_mtime)
timestr = format_timestamp(node->account->last_modified_gmt, true);
else
timestr = format_timestamp(node->account->last_touch, false);
terminal_printf(TERMINAL_FG_CYAN "%s ", timestr);
}
terminal_printf(TERMINAL_FG_GREEN TERMINAL_BOLD "%s" TERMINAL_NO_BOLD " [id: %s]" TERMINAL_RESET "\n", node->name, node->account->id);
}
else if (node->shared)
terminal_printf(TERMINAL_FG_CYAN TERMINAL_BOLD "%s" TERMINAL_RESET "\n", node->name);
else
Expand Down Expand Up @@ -104,6 +137,7 @@ int cmd_ls(int argc, char **argv)
static struct option long_options[] = {
{"sync", required_argument, NULL, 'S'},
{"color", required_argument, NULL, 'C'},
{"long", no_argument, NULL, 'l'},
{0, 0, 0, 0}
};
int option;
Expand All @@ -118,14 +152,23 @@ int cmd_ls(int argc, char **argv)
bool print_tree;
struct account *account;

while ((option = getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
while ((option = getopt_long(argc, argv, "lmu", long_options, &option_index)) != -1) {
switch (option) {
case 'S':
sync = parse_sync_string(optarg);
break;
case 'C':
cmode = parse_color_mode_string(optarg);
break;
case 'l':
long_listing = true;
break;
case 'm':
show_mtime = true;
break;
case 'u':
show_mtime = false;
break;
case '?':
default:
die_usage(cmd_ls_usage);
Expand Down Expand Up @@ -169,8 +212,17 @@ int cmd_ls(int argc, char **argv)

if (print_tree)
insert_node(root, fullname, account);
else
else {
if (long_listing) {
_cleanup_free_ char *timestr;
if (show_mtime)
timestr = format_timestamp(account->last_modified_gmt, true);
else
timestr = format_timestamp(account->last_touch, false);
printf("%s ", timestr);
}
printf("%s [id: %s]\n", fullname, account->id);
}

free(fullname);
}
Expand Down
2 changes: 1 addition & 1 deletion cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ int cmd_show(int argc, char **argv);
#define cmd_show_usage "show [--sync=auto|now|no] [--clip, -c] [--all|--username|--password|--url|--notes|--field=FIELD|--id|--name] [--basic-regexp, -G|--fixed-strings, -F] " color_usage " {UNIQUENAME|UNIQUEID}"

int cmd_ls(int argc, char **argv);
#define cmd_ls_usage "ls [--sync=auto|now|no] " color_usage " [GROUP]"
#define cmd_ls_usage "ls [--sync=auto|now|no] [--long, -l] " color_usage " [GROUP]"

int cmd_edit(int argc, char **argv);
#define cmd_edit_usage "edit [--sync=auto|now|no] [--non-interactive] " color_usage " {--name|--username|--password|--url|--notes|--field=FIELD} {NAME|UNIQUEID}"
Expand Down
7 changes: 5 additions & 2 deletions lpass.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ several subcommands:
lpass *login* [--trust] [--plaintext-key [--force, -f]] [--color=auto|never|always] USERNAME
lpass *logout* [--force, -f] [--color=auto|never|always]
lpass *show* [--sync=auto|now|no] [--clip, -c] [--all|--username|--password|--url|--notes|--field=FIELD|--id|--name] [--basic-regexp, -G|--fixed-strings, -F] [--color=auto|never|always] {NAME|UNIQUEID}
lpass *ls* [--sync=auto|now|no] [--color=auto|never|always] [GROUP]
lpass *ls* [--sync=auto|now|no] [--long, -l] [-m] [-u] [--color=auto|never|always] [GROUP]
lpass *edit* [--sync=auto|now|no] [--non-interactive] {--name|--username, -u|--password, -p|--url|--notes|--field=FIELD} [--color=auto|never|always] {NAME|UNIQUEID}
lpass *generate* [--sync=auto|now|no] [--clip, -c] [--username=USERNAME] [--url=URL] [--no-symbols] [--color=auto|never|always] {NAME|UNIQUEID} LENGTH
lpass *duplicate* [--sync=auto|now|no] [--color=auto|never|always] {UNIQUENAME|UNIQUEID}
Expand Down Expand Up @@ -105,7 +105,10 @@ Viewing
~~~~~~~
The 'show' subcommand will display a password or selected field.

The 'ls' subcommand will list names in groups in a tree structure.
The 'ls' subcommand will list names in groups in a tree structure. If
the '--long' or '-l' option is set, then also list the last modification
time. The '-u' option may be passed to show the last use (last touch) time
instead, if available. Both times are in GMT.

The 'export' subcommand will dump all account information including
passwords to stdout (unencrypted).
Expand Down

0 comments on commit fa870c1

Please sign in to comment.