Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const std = @import("std");
- const net = @cImport(@cInclude("netinet/in.h"));
- const socket = @cImport(@cInclude("sys/socket.h"));
- const cio = @cImport(@cInclude("stdio.h"));
- const netdb = @cImport(@cInclude("netdb.h"));
- const assert = std.debug.assert;
- const warn = std.debug.warn;
- const irc_port = 6667;
- const addr = c"irc.esper.net";
- const channel = "#openredstone";
- const nick = "tbot_zig";
- const real = nick;
- const user = nick;
- const recv_buf_len = 1024;
- var recv_buf: [recv_buf_len]u8 = undefined;
- fn strchr(str: []const u8, char: u8) ?usize {
- for (str) |c, i| {
- if (c == char) {
- return i;
- }
- }
- return null;
- }
- test "strings contain characters" {
- assert(strchr("foobar", 'f').? == 0);
- assert(strchr("foobar", 'o').? == 1);
- assert(strchr("foobar", 'b').? == 3);
- assert(strchr("foobar", 'a').? == 4);
- assert(strchr("foobar", 'x') == null);
- }
- fn streq(s: []const u8, t: []const u8) bool {
- if (s.len != t.len) {
- return false;
- }
- var i: usize = 0;
- while (i < s.len) : (i += 1) {
- if (s[i] != t[i]) {
- return false;
- }
- }
- return true;
- }
- test "strings are equal to each other" {
- assert(streq("foo bar", "foo bar"));
- assert(streq("", ""));
- assert(!streq("foo", "foobar"));
- assert(!streq("foo", "bar"));
- }
- fn strstr(str: []const u8, s: []const u8) ?usize {
- if (s.len == 0) {
- return 0;
- }
- outer: for (str) |c, i| {
- if (i + s.len > str.len) {
- break;
- }
- for (s) |sc, si| {
- if (sc != str[i + si]) {
- continue :outer;
- }
- }
- return i;
- }
- return null;
- }
- test "strings contain other strings" {
- assert(strstr("foobar", "foo").? == 0);
- assert(strstr("foobar", "bar").? == 3);
- assert(strstr("foobar", "foox") == null);
- assert(strstr("foobar", "xfoo") == null);
- }
- fn parse_nick(line: []const u8) ?[]const u8 {
- if (line[0] == ':') {
- var spce = strchr(line, ' ') orelse return null;
- var excl = strchr(line, '!') orelse return null;
- if (spce < excl) {
- return null;
- }
- var nick_end: usize = excl;
- return line[1..nick_end];
- }
- return null;
- }
- test "parse nickname" {
- const line = ":tyler!testtesttest foo bar :trail\r\n";
- assert(streq(parse_nick(line).?, "tyler"));
- const line2 = "foo bar :trail\r\n";
- assert(parse_nick(line2) == null);
- }
- fn parse_command(line: []const u8) ?[]const u8 {
- var cmd_start: usize = 0;
- var cmd_end: usize = 0;
- if (line[0] == ':') {
- cmd_start = strchr(line, ' ') orelse unreachable;
- cmd_start += 1;
- cmd_end = strchr(line[cmd_start..], ' ') orelse strchr(line[cmd_start..], '\r') orelse unreachable;
- cmd_end += cmd_start;
- } else {
- cmd_end = strchr(line, ' ') orelse strchr(line, '\r') orelse unreachable;
- }
- return line[cmd_start..cmd_end];
- }
- test "parse command" {
- const line = ":tyler!testtesttest foo bar :trail\r\n";
- assert(streq(parse_command(line).?, "foo"));
- const line2 = "foo bar :trail\r\n";
- assert(streq(parse_command(line2).?, "foo"));
- }
- const CError = error.CError;
- fn perror(msg: []const u8) anyerror {
- cio.perror(msg.ptr);
- return error.CError;
- }
- fn irc_send(sock: i32, value: []const u8) void {
- // for loop on var args kills compiler
- // for (args) |arg| {
- // warn("{}", arg);
- // socket.send(sock, arg, arg.len, 0);
- // }
- // var i: usize = 0;
- // while (i < args.len) : (i += 1) {
- // warn("{}", args[i]);
- // _ = socket.send(sock, args[i], args[i].len, 0);
- // }
- // inline for (args) |arg| {
- // warn("{}", arg);
- // socket.send(sock, arg, arg.len, 0);
- // }
- warn("<< {}\n", value);
- _ = socket.send(sock, value.ptr, value.len, 0);
- _ = socket.send(sock, c"\r\n", 2, 0);
- }
- pub fn main() !void {
- var stdout = try std.io.getStdOut();
- try stdout.write("Test\n");
- const buf_index: usize = 0;
- const host: ?*netdb.hostent = @ptrCast(?*netdb.hostent, netdb.gethostbyname(addr)) orelse return perror("getaddr");
- const sock: i32 = socket.socket(socket.AF_INET, @enumToInt(socket.SOCK_STREAM), 0);
- if (sock == -1) {
- return perror("sock");
- }
- var remote = net.sockaddr_in{
- .sin_family = socket.AF_INET,
- .sin_port = net.htons(irc_port),
- .sin_addr = undefined,
- .sin_zero = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
- };
- // @ptrCast(*net.in_addr, @alignCast(4, host.?.h_addr_list.?[0].?)).*,
- @memcpy(@ptrCast([*]u8, &remote.sin_addr), host.?.h_addr_list[0], @sizeOf(@typeOf(remote.sin_addr)));
- var conn_result = socket.connect(sock, @ptrCast([*]const socket.sockaddr, &remote), @sizeOf(@typeOf(remote)));
- if (conn_result == -1) {
- return perror("connect");
- }
- irc_send(sock, "USER " ++ nick ++ " 0 * :" ++ nick);
- irc_send(sock, "NICK " ++ nick);
- irc_send(sock, "JOIN " ++ channel);
- var buffer_index: usize = 0;
- while (true) {
- // main loop
- var len: isize = 0;
- warn("buffer_index: {}\n", buffer_index);
- len = socket.recv(sock, @ptrCast(?*c_void, &recv_buf[buffer_index]), recv_buf_len - buffer_index, 0);
- // is there a better way to do this?
- var buf_view: []u8 = undefined;
- buf_view.ptr = @ptrCast([*]u8, &recv_buf);
- buf_view.len = @intCast(usize, len) + buffer_index;
- var one_line_end = strchr(recv_buf, '\n');
- while (one_line_end != null) {
- warn("buf view at {} - {}\n", @ptrToInt(buf_view.ptr) - @ptrToInt(&recv_buf), @ptrToInt(buf_view.ptr) - @ptrToInt(&recv_buf) + buf_view.len);
- warn("buf_view len: {}\n", buf_view.len);
- warn("recv_buf: {x}\n", recv_buf);
- warn("buf_view: {x}\n", buf_view);
- warn("one_line_end: {}\n", one_line_end.?);
- var line = buf_view[0 .. one_line_end.? - 1];
- warn(">> {}\n", line);
- var line_nick = parse_nick(line);
- var line_command = parse_command(line);
- warn(" nick: {}\n", line_nick);
- warn(" command: {}\n", line_command);
- if (streq(line_command.?, "PING")) {
- line[1] = 'O'; // @fragile
- irc_send(sock, line);
- }
- if (streq(line_command.?, "MODE")) {
- irc_send(sock, "PRIVMSG NickServ :IDENTIFY orepassword");
- irc_send(sock, "JOIN #openredstone");
- }
- if (strstr(line, "~test")) |_| {
- irc_send(sock, "PRIVMSG #openredstone :ayy test");
- }
- // var zero_used: usize = 0;
- // while (buf_view[zero_used] != '\n') : (zero_used += 1) {
- // buf_view[zero_used] = 0;
- // }
- // buf_view[zero_used] = 0;
- buf_view = buf_view[one_line_end.? + 1 ..];
- one_line_end = strchr(buf_view, '\n');
- }
- // warn("recv_buf: 0x{x}\n", @ptrToInt(&recv_buf));
- // warn("buf_view: 0x{x}\n", @ptrToInt(buf_view.ptr));
- // warn("moving {}\n", recv_buf_len - (@ptrToInt(buf_view.ptr) - @ptrToInt(&recv_buf)));
- // @memset(
- // @ptrCast([*]u8, &recv_buf) + buf_view.len,
- // 0,
- // recv_buf_len - buf_view.len
- // );
- if (buf_view.len != 0) {
- @memcpy(&recv_buf, buf_view.ptr, buf_view.len);
- // var i: usize = buf_view.len;
- // while (i<recv_buf_len) : (i += 1) {
- // recv_buf[i] = 0;
- // }
- buffer_index = buf_view.len;
- } else {
- buffer_index = 0;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement