forked from SerenityOS/serenity
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
utmpupdate: Add a program for updating /var/run/utmp
To keep track of ongoing terminal sessions, we now have a sort-of traditional /var/run/utmp file, like other Unix systems. Unlike other Unix systems however, ours is of course JSON. :^) The /bin/utmpupdate program is used to update the file, which is not writable by regular user accounts. This helper program is set-GID "utmp".
- Loading branch information
1 parent
35b844b
commit dcd4765
Showing
4 changed files
with
94 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#include <AK/JsonObject.h> | ||
#include <AK/JsonValue.h> | ||
#include <LibCore/ArgsParser.h> | ||
#include <LibCore/File.h> | ||
#include <LibCore/DateTime.h> | ||
|
||
// utmpupdate -c /dev/pts/0 | ||
// utmpupdate -d /dev/pts/0 | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
pid_t pid = 0; | ||
bool flag_create = false; | ||
bool flag_delete = false; | ||
const char* tty_name = nullptr; | ||
const char* from = nullptr; | ||
|
||
Core::ArgsParser args_parser; | ||
args_parser.add_option(flag_create, "Create entry", "create", 'c'); | ||
args_parser.add_option(flag_delete, "Delete entry", "delete", 'd'); | ||
args_parser.add_option(pid, "PID", "PID", 'p', "PID"); | ||
args_parser.add_option(from, "From", "from", 'f', "From"); | ||
args_parser.add_positional_argument(tty_name, "TTY name", "tty"); | ||
|
||
args_parser.parse(argc, argv); | ||
|
||
if (flag_create && flag_delete) { | ||
warn() << "-c and -d are mutually exclusive"; | ||
return 1; | ||
} | ||
|
||
dbg() << "Updating utmp from UID=" << getuid() << " GID=" << getgid() << " EGID=" << getegid() << " PID=" << pid; | ||
|
||
auto file_or_error = Core::File::open("/var/run/utmp", Core::IODevice::ReadWrite); | ||
if (file_or_error.is_error()) { | ||
dbg() << "Error: " << file_or_error.error(); | ||
return 1; | ||
} | ||
|
||
auto& file = *file_or_error.value(); | ||
|
||
auto file_contents = file.read_all(); | ||
auto previous_json = JsonValue::from_string(file_contents); | ||
|
||
JsonObject json; | ||
|
||
if (!previous_json.has_value() || !previous_json.value().is_object()) { | ||
dbg() << "Error: Could not parse JSON"; | ||
} else { | ||
json = previous_json.value().as_object(); | ||
} | ||
|
||
if (flag_create) { | ||
JsonObject entry; | ||
entry.set("pid", pid); | ||
entry.set("uid", getuid()); | ||
entry.set("from", from); | ||
entry.set("login_at", Core::DateTime::now().to_string()); | ||
json.set(tty_name, move(entry)); | ||
} else { | ||
ASSERT(flag_delete); | ||
dbg() << "Removing " << tty_name << " from utmp"; | ||
json.remove(tty_name); | ||
} | ||
|
||
if (!file.seek(0)) { | ||
dbg() << "Seek failed"; | ||
return 1; | ||
} | ||
|
||
if (!file.truncate(0)) { | ||
dbg() << "Truncation failed"; | ||
return 1; | ||
} | ||
|
||
if (!file.write(json.to_string())) { | ||
dbg() << "Write failed"; | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} |