╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ ssh_helper.zig ───────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
185 if (escaping or quote != null) return error.InvalidSshCommand; 186 if (in_token) { 187 try tokens.append(allocator, try current.toOwnedSlice(allocator)); 188 } 189 190 return tokens; 191 } 192 193 fn parseService(value: []const u8) !Service { 194 if (std.mem.eql(u8, value, "upload-pack") or std.mem.eql(u8, value, "git-upload-pack")) return .upload_pack; 195 if (std.mem.eql(u8, value, "receive-pack") or std.mem.eql(u8, value, "git-receive-pack")) return .receive_pack; 196 return error.InvalidSshCommand; 197 } 198 199 fn serviceName(service: Service) []const u8 { 200 return switch (service) { 201 .upload_pack => "upload-pack", 202 .receive_pack => "receive-pack", 203 }; 204 } 205 206 fn parseConnectAddress(value: []const u8) !ConnectAddress { 207 const colon = std.mem.lastIndexOfScalar(u8, value, ':') orelse return error.InvalidConnectAddress; 208 if (colon == 0 or colon + 1 >= value.len) return error.InvalidConnectAddress; 209 const port = try std.fmt.parseInt(u16, value[colon + 1 ..], 10); 210 return .{ .host = value[0..colon], .port = port }; 211 } 212 213 fn copy(reader: *std.Io.Reader, writer: *std.Io.Writer) !void { 214 var buffer: [4096]u8 = undefined; 215 while (true) { 216 const len = try reader.readSliceShort(&buffer); 217 if (len == 0) break; 218 try writer.writeAll(buffer[0..len]); 219 try writer.flush(); 220 } 221 } 222 223 fn copyFd(src: std.posix.fd_t, dst: std.posix.fd_t) !void { 224 var buffer: [4096]u8 = undefined; 225 while (true) { 226 const len = try std.posix.read(src, &buffer); 227 if (len == 0) break; 228 try writeAllFd(dst, buffer[0..len]); 229 } 230 } 231 232 fn writeAllFd(fd: std.posix.fd_t, bytes: []const u8) !void { 233 var written: usize = 0; 234 while (written < bytes.len) { 235 const rc = std.posix.system.write(fd, bytes[written..].ptr, bytes.len - written); 236 switch (std.posix.errno(rc)) { 237 .SUCCESS => written += @intCast(rc), 238 .INTR => continue, 239 .PIPE => return error.BrokenPipe, 240 else => return error.WriteFailed, 241 } 242 } 243 } 244