mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
Move hostname helpers to src/os/hostname.zig
This commit is contained in:
44
src/os/hostname.zig
Normal file
44
src/os/hostname.zig
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const posix = std.posix;
|
||||||
|
|
||||||
|
pub fn bufPrintHostnameFromFileUri(buf: []u8, uri: std.Uri) ![]const u8 {
|
||||||
|
// Get the raw string of the URI. Its unclear to me if the various
|
||||||
|
// tags of this enum guarantee no percent-encoding so we just
|
||||||
|
// check all of it. This isn't a performance critical path.
|
||||||
|
const host_component = uri.host orelse return error.NoHostnameInUri;
|
||||||
|
const host = switch (host_component) {
|
||||||
|
.raw => |v| v,
|
||||||
|
.percent_encoded => |v| v,
|
||||||
|
};
|
||||||
|
|
||||||
|
// When the "Private Wi-Fi address" setting is toggled on macOS the hostname
|
||||||
|
// is set to a string of digits separated by a colon, e.g. '12:34:56:78:90:12'.
|
||||||
|
// The URI will be parsed as if the last set o digit is a port, so we need to
|
||||||
|
// make sure that part is included when it's set.
|
||||||
|
if (uri.port) |port| {
|
||||||
|
var fbs = std.io.fixedBufferStream(buf);
|
||||||
|
std.fmt.format(fbs.writer().any(), "{s}:{d}", .{ host, port }) catch |err| switch (err) {
|
||||||
|
error.NoSpaceLeft => return error.NoSpaceLeft,
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
|
||||||
|
return fbs.getWritten();
|
||||||
|
}
|
||||||
|
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn isLocalHostname(hostname: []const u8) !bool {
|
||||||
|
// A 'localhost' hostname is always considered local.
|
||||||
|
if (std.mem.eql(u8, "localhost", hostname)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If hostname is not "localhost" it must match our hostname.
|
||||||
|
var buf: [posix.HOST_NAME_MAX]u8 = undefined;
|
||||||
|
const ourHostname = posix.gethostname(&buf) catch |err| {
|
||||||
|
return err;
|
||||||
|
};
|
||||||
|
|
||||||
|
return std.mem.eql(u8, hostname, ourHostname);
|
||||||
|
}
|
@ -5,6 +5,7 @@ const xev = @import("xev");
|
|||||||
const apprt = @import("../apprt.zig");
|
const apprt = @import("../apprt.zig");
|
||||||
const build_config = @import("../build_config.zig");
|
const build_config = @import("../build_config.zig");
|
||||||
const configpkg = @import("../config.zig");
|
const configpkg = @import("../config.zig");
|
||||||
|
const hostname = @import("../os/hostname.zig");
|
||||||
const renderer = @import("../renderer.zig");
|
const renderer = @import("../renderer.zig");
|
||||||
const termio = @import("../termio.zig");
|
const termio = @import("../termio.zig");
|
||||||
const terminal = @import("../terminal/main.zig");
|
const terminal = @import("../terminal/main.zig");
|
||||||
@ -1030,48 +1031,6 @@ pub const StreamHandler = struct {
|
|||||||
self.terminal.markSemanticPrompt(.command);
|
self.terminal.markSemanticPrompt(.command);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bufPrintHostnameFromFileUri(buf: []u8, uri: std.Uri) ![]const u8 {
|
|
||||||
// Get the raw string of the URI. Its unclear to me if the various
|
|
||||||
// tags of this enum guarantee no percent-encoding so we just
|
|
||||||
// check all of it. This isn't a performance critical path.
|
|
||||||
const host_component = uri.host orelse return error.NoHostnameInUri;
|
|
||||||
const host = switch (host_component) {
|
|
||||||
.raw => |v| v,
|
|
||||||
.percent_encoded => |v| v,
|
|
||||||
};
|
|
||||||
|
|
||||||
// When the "Private Wi-Fi address" setting is toggled on macOS the hostname
|
|
||||||
// is set to a string of digits separated by a colon, e.g. '12:34:56:78:90:12'.
|
|
||||||
// The URI will be parsed as if the last set o digit is a port, so we need to
|
|
||||||
// make sure that part is included when it's set.
|
|
||||||
if (uri.port) |port| {
|
|
||||||
var fbs = std.io.fixedBufferStream(buf);
|
|
||||||
std.fmt.format(fbs.writer().any(), "{s}:{d}", .{ host, port }) catch |err| switch (err) {
|
|
||||||
error.NoSpaceLeft => return error.NoSpaceLeft,
|
|
||||||
else => unreachable,
|
|
||||||
};
|
|
||||||
|
|
||||||
return fbs.getWritten();
|
|
||||||
}
|
|
||||||
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isLocalHostname(hostname: []const u8) !bool {
|
|
||||||
// A 'localhost' hostname is always considered local.
|
|
||||||
if (std.mem.eql(u8, "localhost", hostname)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If hostname is not "localhost" it must match our hostname.
|
|
||||||
var buf: [posix.HOST_NAME_MAX]u8 = undefined;
|
|
||||||
const ourHostname = posix.gethostname(&buf) catch |err| {
|
|
||||||
return err;
|
|
||||||
};
|
|
||||||
|
|
||||||
return std.mem.eql(u8, hostname, ourHostname);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reportPwd(self: *StreamHandler, url: []const u8) !void {
|
pub fn reportPwd(self: *StreamHandler, url: []const u8) !void {
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
log.warn("reportPwd unimplemented on windows", .{});
|
log.warn("reportPwd unimplemented on windows", .{});
|
||||||
@ -1097,7 +1056,7 @@ pub const StreamHandler = struct {
|
|||||||
// Make sure there is space for a max length hostname + the max number of digits.
|
// Make sure there is space for a max length hostname + the max number of digits.
|
||||||
var host_and_port_buf: [posix.HOST_NAME_MAX + PORT_NUMBER_MAX_DIGITS]u8 = undefined;
|
var host_and_port_buf: [posix.HOST_NAME_MAX + PORT_NUMBER_MAX_DIGITS]u8 = undefined;
|
||||||
|
|
||||||
const hostname = bufPrintHostnameFromFileUri(&host_and_port_buf, uri) catch |err| switch (err) {
|
const hostname_from_uri = hostname.bufPrintHostnameFromFileUri(&host_and_port_buf, uri) catch |err| switch (err) {
|
||||||
error.NoHostnameInUri => {
|
error.NoHostnameInUri => {
|
||||||
log.warn("OSC 7 uri must contain a hostname: {}", .{err});
|
log.warn("OSC 7 uri must contain a hostname: {}", .{err});
|
||||||
return;
|
return;
|
||||||
@ -1111,7 +1070,7 @@ pub const StreamHandler = struct {
|
|||||||
// OSC 7 is a little sketchy because anyone can send any value from
|
// OSC 7 is a little sketchy because anyone can send any value from
|
||||||
// any host (such an SSH session). The best practice terminals follow
|
// any host (such an SSH session). The best practice terminals follow
|
||||||
// is to valid the hostname to be local.
|
// is to valid the hostname to be local.
|
||||||
const host_valid = isLocalHostname(hostname) catch |err| switch (err) {
|
const host_valid = hostname.isLocalHostname(hostname_from_uri) catch |err| switch (err) {
|
||||||
error.PermissionDenied, error.Unexpected => {
|
error.PermissionDenied, error.Unexpected => {
|
||||||
log.warn("failed to get hostname for OSC 7 validation: {}", .{err});
|
log.warn("failed to get hostname for OSC 7 validation: {}", .{err});
|
||||||
return;
|
return;
|
||||||
|
Reference in New Issue
Block a user