aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-05-22 17:35:22 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-05-22 17:35:22 +0000
commitdfd8282464c56eda0dba62ad3b9a2a4b71ba725f (patch)
tree3d4d8f072800c7af08b9f44de99307dd66fcbbad
parent7b3863986db26f959040db45c52aec5e41ce2a5e (diff)
downloadbusybox-w32-dfd8282464c56eda0dba62ad3b9a2a4b71ba725f.tar.gz
busybox-w32-dfd8282464c56eda0dba62ad3b9a2a4b71ba725f.tar.bz2
busybox-w32-dfd8282464c56eda0dba62ad3b9a2a4b71ba725f.zip
last: make its output more like "standard" last (aka "fancy last").
The main difference is that LOGIN lines are still shown by non-fancy one. function old new delta static._ut_usr - 26 +26 last_main 448 471 +23 static._ut_lin - 7 +7 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 1/0 up/down: 56/0) Total: 56 bytes
-rw-r--r--miscutils/last.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/miscutils/last.c b/miscutils/last.c
index ef41444c5..2199d7524 100644
--- a/miscutils/last.c
+++ b/miscutils/last.c
@@ -32,12 +32,32 @@
32 32
33#else 33#else
34 34
35#if EMPTY != 0 || RUN_LVL != 1 || BOOT_TIME != 2 || NEW_TIME != 3 || \
36 OLD_TIME != 4
37#error Values for the ut_type field of struct utmp changed
38#endif
39
35int last_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 40int last_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
36int last_main(int argc, char **argv ATTRIBUTE_UNUSED) 41int last_main(int argc, char **argv ATTRIBUTE_UNUSED)
37{ 42{
38 struct utmp ut; 43 struct utmp ut;
39 int n, file = STDIN_FILENO; 44 int n, file = STDIN_FILENO;
40 time_t t_tmp; 45 time_t t_tmp;
46 off_t pos;
47 static const char _ut_usr[] ALIGN1 =
48 "runlevel\0" "reboot\0" "shutdown\0";
49 static const char _ut_lin[] ALIGN1 =
50 "~\0" "{\0" "|\0" /* "LOGIN\0" "date\0" */;
51 enum {
52 TYPE_RUN_LVL = RUN_LVL, /* 1 */
53 TYPE_BOOT_TIME = BOOT_TIME, /* 2 */
54 TYPE_SHUTDOWN_TIME = SHUTDOWN_TIME
55 };
56 enum {
57 _TILDE = EMPTY, /* 0 */
58 TYPE_NEW_TIME, /* NEW_TIME, 3 */
59 TYPE_OLD_TIME /* OLD_TIME, 4 */
60 };
41 61
42 if (argc > 1) { 62 if (argc > 1) {
43 bb_show_usage(); 63 bb_show_usage();
@@ -46,23 +66,33 @@ int last_main(int argc, char **argv ATTRIBUTE_UNUSED)
46 66
47 printf("%-10s %-14s %-18s %-12.12s %s\n", 67 printf("%-10s %-14s %-18s %-12.12s %s\n",
48 "USER", "TTY", "HOST", "LOGIN", "TIME"); 68 "USER", "TTY", "HOST", "LOGIN", "TIME");
69 /* yikes. We reverse over the file and that is a not too elegant way */
70 pos = xlseek(file, 0, SEEK_END);
71 pos = lseek(file, pos - sizeof(ut), SEEK_SET);
49 while ((n = full_read(file, &ut, sizeof(ut))) > 0) { 72 while ((n = full_read(file, &ut, sizeof(ut))) > 0) {
50 if (n != sizeof(ut)) { 73 if (n != sizeof(ut)) {
51 bb_perror_msg_and_die("short read"); 74 bb_perror_msg_and_die("short read");
52 } 75 }
53 76 n = index_in_strings(_ut_lin, ut.ut_line);
54 if (ut.ut_line[0] == '~') { 77 if (n == _TILDE) { /* '~' */
78#if 1
79/* do we really need to be cautious here? */
80 n = index_in_strings(_ut_usr, ut.ut_user);
81 if (++n > 0)
82 ut.ut_type = n;
83#else
55 if (strncmp(ut.ut_user, "shutdown", 8) == 0) 84 if (strncmp(ut.ut_user, "shutdown", 8) == 0)
56 ut.ut_type = SHUTDOWN_TIME; 85 ut.ut_type = SHUTDOWN_TIME;
57 else if (strncmp(ut.ut_user, "reboot", 6) == 0) 86 else if (strncmp(ut.ut_user, "reboot", 6) == 0)
58 ut.ut_type = BOOT_TIME; 87 ut.ut_type = BOOT_TIME;
59 else if (strncmp(ut.ut_user, "runlevel", 8) == 0) 88 else if (strncmp(ut.ut_user, "runlevel", 8) == 0)
60 ut.ut_type = RUN_LVL; 89 ut.ut_type = RUN_LVL;
90#endif
61 } else { 91 } else {
62 if (ut.ut_name[0] == '\0' || strcmp(ut.ut_name, "LOGIN") == 0) { 92 if (ut.ut_name[0] == '\0' || strcmp(ut.ut_name, "LOGIN") == 0) {
63 /* Don't bother. This means we can't find how long 93 /* Don't bother. This means we can't find how long
64 * someone was logged in for. Oh well. */ 94 * someone was logged in for. Oh well. */
65 continue; 95 goto next;
66 } 96 }
67 if (ut.ut_type != DEAD_PROCESS 97 if (ut.ut_type != DEAD_PROCESS
68 && ut.ut_name[0] && ut.ut_line[0] 98 && ut.ut_name[0] && ut.ut_line[0]
@@ -70,10 +100,10 @@ int last_main(int argc, char **argv ATTRIBUTE_UNUSED)
70 ut.ut_type = USER_PROCESS; 100 ut.ut_type = USER_PROCESS;
71 } 101 }
72 if (strcmp(ut.ut_name, "date") == 0) { 102 if (strcmp(ut.ut_name, "date") == 0) {
73 if (ut.ut_line[0] == '|') { 103 if (n == TYPE_OLD_TIME) { /* '|' */
74 ut.ut_type = OLD_TIME; 104 ut.ut_type = OLD_TIME;
75 } 105 }
76 if (ut.ut_line[0] == '{') { 106 if (n == TYPE_NEW_TIME) { /* '{' */
77 ut.ut_type = NEW_TIME; 107 ut.ut_type = NEW_TIME;
78 } 108 }
79 } 109 }
@@ -85,15 +115,18 @@ int last_main(int argc, char **argv ATTRIBUTE_UNUSED)
85 case NEW_TIME: 115 case NEW_TIME:
86 case RUN_LVL: 116 case RUN_LVL:
87 case SHUTDOWN_TIME: 117 case SHUTDOWN_TIME:
88 continue; 118 goto next;
89 case BOOT_TIME: 119 case BOOT_TIME:
90 strcpy(ut.ut_line, "system boot"); 120 strcpy(ut.ut_line, "system boot");
91 break;
92 } 121 }
93 } 122 }
94 t_tmp = (time_t)ut.ut_tv.tv_sec; 123 t_tmp = (time_t)ut.ut_tv.tv_sec;
95 printf("%-10s %-14s %-18s %-12.12s\n", 124 printf("%-10s %-14s %-18s %-12.12s\n",
96 ut.ut_user, ut.ut_line, ut.ut_host, ctime(&t_tmp) + 4); 125 ut.ut_user, ut.ut_line, ut.ut_host, ctime(&t_tmp) + 4);
126 next:
127 if (!pos)
128 break; /* done. */
129 pos = lseek(file, pos - sizeof(ut), SEEK_SET);
97 } 130 }
98 131
99 fflush_stdout_and_exit(EXIT_SUCCESS); 132 fflush_stdout_and_exit(EXIT_SUCCESS);