Rip IRC bits out of rtl

This commit is contained in:
Kevin Lange 2015-07-30 22:50:29 -07:00
parent 4547929321
commit fd5e7b48b9
2 changed files with 276 additions and 454 deletions

276
modules/irc.c Normal file
View File

@ -0,0 +1,276 @@
#include <module.h>
#include <logging.h>
#include <printf.h>
#include <mod/shell.h>
#include <mod/net.h>
#include <ipv4.h>
static fs_node_t * irc_socket;
static spin_lock_t irc_tty_lock = { 0 };
static char irc_input[400] = {'\0'};
static char irc_prompt[100] = {'\0'};
static char irc_nick[32] = {'\0'};
static char irc_payload[512];
static char * fgets(char * buf, int size, fs_node_t * stream) {
char * x = buf;
int collected = 0;
while (collected < size) {
int r = read_fs(stream, 0, 1, (unsigned char *)x);
collected += r;
if (r == -1) return NULL;
if (!r) break;
if (*x == '\n') break;
x += r;
}
x++;
*x = '\0';
return buf;
}
static void irc_send(char * payload) {
/* Uh, stuff */
}
static int tty_readline(fs_node_t * dev, char * linebuf, int max) {
int read = 0;
tty_set_unbuffered(dev);
while (read < max) {
uint8_t buf[1];
int r = read_fs(dev, 0, 1, (unsigned char *)buf);
if (!r) {
debug_print(WARNING, "Read nothing?");
continue;
}
spin_lock(irc_tty_lock);
linebuf[read] = buf[0];
if (buf[0] == '\n') {
linebuf[read] = 0;
spin_unlock(irc_tty_lock);
break;
} else if (buf[0] == 0x08) {
if (read > 0) {
fprintf(dev, "\010 \010");
read--;
linebuf[read] = 0;
}
} else if (buf[0] < ' ') {
switch (buf[0]) {
case 0x0C: /* ^L */
/* Should reset display here */
spin_unlock(irc_tty_lock);
break;
default:
/* do nothing */
spin_unlock(irc_tty_lock);
break;
}
} else {
fprintf(dev, "%c", buf[0]);
read += r;
}
spin_unlock(irc_tty_lock);
}
tty_set_buffered(dev);
return read;
}
static void handle_irc_packet(fs_node_t * tty, size_t size, uint8_t * packet) {
char * c = (char *)packet;
while ((uintptr_t)c < (uintptr_t)packet + size) {
char * e = strstr(c, "\r\n");
if ((uintptr_t)e > (uintptr_t)packet + size) {
break;
}
spin_lock(irc_tty_lock);
if (!e) {
/* XXX */
c[size-1] = '\0';
fprintf(tty, "\r\033[36m%s\033[0m\033[K\n", c);
goto prompt_;
}
e[0] = '\0';
if (startswith(c, "PING")) {
char tmp[100];
char * t = strstr(c, ":");
sprintf(tmp, "PONG %s\r\n", t);
irc_send(tmp);
goto prompt_;
}
char * user;
char * command;
char * channel;
char * message;
user = c;
command = strstr(user, " ");
if (!command) {
fprintf(tty, "\r\033[36m%s\033[0m\033[K\n", user);
goto prompt_;
}
command[0] = '\0';
command++;
channel = strstr(command, " ");
if (!channel) {
fprintf(tty, "\r\033[36m%s %s\033[0m\033[K\n", user, command);
goto prompt_;
}
channel[0] = '\0';
channel++;
if (!strcmp(command, "PRIVMSG")) {
message = strstr(channel, " ");
if (!message) {
fprintf(tty, "\r\033[36m%s %s %s\033[0m\033[K\n", user, command, channel);
goto prompt_;
}
message[0] = '\0';
message++;
if (message[0] == ':') { message++; }
if (user[0] == ':') { user++; }
char * t = strstr(user, "!");
if (t) { t[0] = '\0'; }
t = strstr(user, "@");
if (t) { t[0] = '\0'; }
uint16_t hr, min, sec;
get_time(&hr, &min, &sec);
if (startswith(message, "\001ACTION ")) {
message = message + 8;
char * x = strstr(message, "\001");
if (x) *x = '\0';
fprintf(tty, "\r%2d:%2d:%2d * \033[32m%s\033[0m:\033[34m%s\033[0m %s\033[K\n", hr, min, sec, user, channel, message);
} else {
fprintf(tty, "\r%2d:%2d:%2d \033[90m<\033[32m%s\033[0m:\033[34m%s\033[90m>\033[0m %s\033[K\n", hr, min, sec, user, channel, message);
}
} else {
fprintf(tty, "\r\033[36m%s %s %s\033[0m\033[K\n", user, command, channel);
}
prompt_:
/* Redraw prompt */
fprintf(tty, "%s", irc_prompt);
fprintf(tty, "%s", irc_input);
spin_unlock(irc_tty_lock);
if (!e) break;
c = e + 2;
}
}
static void ircd(void * data, char * name) {
fs_node_t * tty = data;
char * buf = malloc(4096);
while (1) {
char * result = fgets(buf, 4095, irc_socket);
if (!result) continue;
size_t len = strlen(buf);
if (!len) continue;
handle_irc_packet(tty, len, (unsigned char *)buf);
}
}
DEFINE_SHELL_FUNCTION(irc_init, "irc connector") {
if (argc < 2) {
fprintf(tty, "Specify a username\n");
return 1;
}
memcpy(irc_nick, argv[1], strlen(argv[1])+1);
sprintf(irc_payload, "NICK %s\r\nUSER %s * 0 :%s\r\n", irc_nick, irc_nick, irc_nick);
irc_send(irc_payload);
return 0;
}
DEFINE_SHELL_FUNCTION(irc_join, "irc channel tool") {
if (argc < 2) {
fprintf(tty, "Specify a channel.\n");
return 1;
}
char * channel = argv[1];
sprintf(irc_payload, "JOIN %s\r\n", channel);
irc_send(irc_payload);
sprintf(irc_prompt, "\r[%s] ", channel);
while (1) {
fprintf(tty, irc_prompt);
int c = tty_readline(tty, irc_input, 400);
spin_lock(irc_tty_lock);
irc_input[c] = '\0';
if (startswith(irc_input, "/part")) {
fprintf(tty, "\n");
sprintf(irc_payload, "PART %s\r\n", channel);
irc_send(irc_payload);
spin_unlock(irc_tty_lock);
break;
}
if (startswith(irc_input, "/me ")) {
char * m = strstr(irc_input, " ");
m++;
uint16_t hr, min, sec;
get_time(&hr, &min, &sec);
fprintf(tty, "\r%2d:%2d:%2d * \033[35m%s\033[0m:\033[34m%s\033[0m %s\n\033[K", hr, min, sec, irc_nick, channel, m);
sprintf(irc_payload, "PRIVMSG %s :\1ACTION %s\1\r\n", channel, m);
irc_send(irc_payload);
} else {
uint16_t hr, min, sec;
get_time(&hr, &min, &sec);
fprintf(tty, "\r%2d:%2d:%2d \033[90m<\033[35m%s\033[0m:\033[34m%s\033[90m>\033[0m %s\n\033[K", hr, min, sec, irc_nick, channel, irc_input);
sprintf(irc_payload, "PRIVMSG %s :%s\r\n", channel, irc_input);
irc_send(irc_payload);
}
memset(irc_input, 0x00, sizeof(irc_input));
spin_unlock(irc_tty_lock);
}
memset(irc_prompt, 0x00, sizeof(irc_prompt));
memset(irc_input, 0x00, sizeof(irc_input));
return 0;
}
static int init(void) {
BIND_SHELL_FUNCTION(irc_init);
BIND_SHELL_FUNCTION(irc_join);
return 0;
}
static int fini(void) {
return 0;
}
MODULE_DEF(irc, init, fini);
MODULE_DEPENDS(debugshell);
MODULE_DEPENDS(net);

View File

@ -41,7 +41,6 @@ static void find_rtl(uint32_t device, uint16_t vendorid, uint16_t deviceid, void
#define RTL_PORT_CONFIG 0x52
static list_t * net_queue = NULL;
//static volatile uint8_t net_queue_lock = 0;
static spin_lock_t net_queue_lock = { 0 };
@ -62,40 +61,8 @@ static int next_tx = 0;
static list_t * rx_wait;
static fs_node_t * irc_socket;
static spin_lock_t irc_tty_lock = { 0 };
//static volatile uint8_t irc_tty_lock = 0;
//static struct netif rtl_netif;
static fs_node_t *_atty = NULL;
static char irc_input[400] = {'\0'};
static char irc_prompt[100] = {'\0'};
static char irc_nick[32] = {'\0'};
static char irc_payload[512];
static char * fgets(char * buf, int size, fs_node_t * stream) {
char * x = buf;
int collected = 0;
while (collected < size) {
int r = read_fs(stream, 0, 1, (unsigned char *)x);
collected += r;
if (r == -1) return NULL;
if (!r) break;
if (*x == '\n') break;
x += r;
}
x++;
*x = '\0';
return buf;
}
//static volatile uint8_t _lock;
static spin_lock_t _lock;
static int next_tx_buf(void) {
int out;
@ -109,123 +76,6 @@ static int next_tx_buf(void) {
return out;
}
static void irc_send(char * payload) {
// int my_tx = next_tx_buf();
// int l = strlen(payload);
// size_t packet_size = write_tcp_packet(rtl_tx_buffer[my_tx], (uint8_t *)payload, l, (TCP_FLAGS_ACK | DATA_OFFSET_5));
// seq_no += l;
// outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]);
// outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, packet_size);
}
static void handle_irc_packet(fs_node_t * tty, size_t size, uint8_t * packet) {
char * c = (char *)packet;
while ((uintptr_t)c < (uintptr_t)packet + size) {
char * e = strstr(c, "\r\n");
if ((uintptr_t)e > (uintptr_t)packet + size) {
break;
}
spin_lock(irc_tty_lock);
if (!e) {
/* XXX */
c[size-1] = '\0';
fprintf(tty, "\r\033[36m%s\033[0m\033[K\n", c);
goto prompt_;
}
e[0] = '\0';
if (startswith(c, "PING")) {
char tmp[100];
char * t = strstr(c, ":");
sprintf(tmp, "PONG %s\r\n", t);
irc_send(tmp);
goto prompt_;
}
char * user;
char * command;
char * channel;
char * message;
user = c;
command = strstr(user, " ");
if (!command) {
fprintf(tty, "\r\033[36m%s\033[0m\033[K\n", user);
goto prompt_;
}
command[0] = '\0';
command++;
channel = strstr(command, " ");
if (!channel) {
fprintf(tty, "\r\033[36m%s %s\033[0m\033[K\n", user, command);
goto prompt_;
}
channel[0] = '\0';
channel++;
if (!strcmp(command, "PRIVMSG")) {
message = strstr(channel, " ");
if (!message) {
fprintf(tty, "\r\033[36m%s %s %s\033[0m\033[K\n", user, command, channel);
goto prompt_;
}
message[0] = '\0';
message++;
if (message[0] == ':') { message++; }
if (user[0] == ':') { user++; }
char * t = strstr(user, "!");
if (t) { t[0] = '\0'; }
t = strstr(user, "@");
if (t) { t[0] = '\0'; }
uint16_t hr, min, sec;
get_time(&hr, &min, &sec);
if (startswith(message, "\001ACTION ")) {
message = message + 8;
char * x = strstr(message, "\001");
if (x) *x = '\0';
fprintf(tty, "\r%2d:%2d:%2d * \033[32m%s\033[0m:\033[34m%s\033[0m %s\033[K\n", hr, min, sec, user, channel, message);
} else {
fprintf(tty, "\r%2d:%2d:%2d \033[90m<\033[32m%s\033[0m:\033[34m%s\033[90m>\033[0m %s\033[K\n", hr, min, sec, user, channel, message);
}
} else {
fprintf(tty, "\r\033[36m%s %s %s\033[0m\033[K\n", user, command, channel);
}
prompt_:
/* Redraw prompt */
fprintf(tty, "%s", irc_prompt);
fprintf(tty, "%s", irc_input);
spin_unlock(irc_tty_lock);
if (!e) break;
c = e + 2;
}
}
static void rtl_ircd(void * data, char * name) {
fs_node_t * tty = data;
char * buf = malloc(4096);
while (1) {
char * result = fgets(buf, 4095, irc_socket);
if (!result) continue;
size_t len = strlen(buf);
if (!len) continue;
handle_irc_packet(tty, len, (unsigned char *)buf);
}
}
void* rtl_dequeue() {
while (!net_queue->length) {
sleep_on(rx_wait);
@ -439,23 +289,6 @@ static void rtl_netd(void * data, char * name) {
fprintf(tty, "[eth] s-next=0x%x, r-next=0x%x\n", seq_no, ack_no);
#endif
#if 0
{
irc_send(
"GET / HTTP/1.1\r\n"
"Host: forum.osdev.org\r\n"
"Cookie: phpbb3_9i66l_u=11616; phpbb3_9i66l_k=ebe8e4f9892d97ab; phpbb3_9i66l_sid=d99d2e26e2a503fdfbe13e9b794dae23\r\n"
"\r\n");
}
#endif
// irc_socket = make_pipe(4096);
// vfs_mount("/dev/net_irc", irc_socket);
// create_kernel_tasklet(rtl_ircd, "[ircd]", tty);
_atty = tty;
@ -467,288 +300,6 @@ static void rtl_netd(void * data, char * name) {
fprintf(tty, "rtl_netd: net_handler has been started\n");
}
static int tty_readline(fs_node_t * dev, char * linebuf, int max) {
int read = 0;
tty_set_unbuffered(dev);
while (read < max) {
uint8_t buf[1];
int r = read_fs(dev, 0, 1, (unsigned char *)buf);
if (!r) {
debug_print(WARNING, "Read nothing?");
continue;
}
spin_lock(irc_tty_lock);
linebuf[read] = buf[0];
if (buf[0] == '\n') {
linebuf[read] = 0;
spin_unlock(irc_tty_lock);
break;
} else if (buf[0] == 0x08) {
if (read > 0) {
fprintf(dev, "\010 \010");
read--;
linebuf[read] = 0;
}
} else if (buf[0] < ' ') {
switch (buf[0]) {
case 0x0C: /* ^L */
/* Should reset display here */
spin_unlock(irc_tty_lock);
break;
default:
/* do nothing */
spin_unlock(irc_tty_lock);
break;
}
} else {
fprintf(dev, "%c", buf[0]);
read += r;
}
spin_unlock(irc_tty_lock);
}
tty_set_buffered(dev);
return read;
}
DEFINE_SHELL_FUNCTION(irc_test, "irc test") {
// char * payloads[] = {
// "NICK toarutest\r\nUSER toaru 0 * :Toaru Test\r\nJOIN #levchins\r\n\0\0\0",
// "PRIVMSG #levchins :99 bottles of beer on the wall\r\n\0\0",
// "PRIVMSG #levchins :99 bottles of beer\r\n\0\0",
// "PRIVMSG #levchins :Take one down\r\n\0\0",
// "PRIVMSG #levchins :pass it around\r\n\0\0",
// "PRIVMSG #levchins :98 bottles of beer on the wall\r\n\0\0",
// "PART #levchins :Thank you, and good night!\r\n\0\0",
// "QUIT\r\n\0\0",
// };
// for (unsigned int i = 0; i < sizeof(payloads) / sizeof(uint8_t *); ++i) {
// int my_tx = next_tx_buf();
// int l = strlen(payloads[i]);
// size_t packet_size = write_tcp_packet(rtl_tx_buffer[my_tx], (uint8_t *)payloads[i], l, (TCP_FLAGS_ACK | DATA_OFFSET_5));
// seq_no += l;
// outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]);
// outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, packet_size);
// unsigned long s, ss;
// relative_time(0, 500, &s, &ss);
// sleep_until((process_t *)current_process, s, ss);
// switch_task(0);
// }
return 0;
}
DEFINE_SHELL_FUNCTION(irc_init, "irc connector") {
if (argc < 2) {
fprintf(tty, "Specify a username\n");
return 1;
}
memcpy(irc_nick, argv[1], strlen(argv[1])+1);
sprintf(irc_payload, "NICK %s\r\nUSER %s * 0 :%s\r\n", irc_nick, irc_nick, irc_nick);
irc_send(irc_payload);
return 0;
}
static char * log_channel = NULL;
static uint32_t irc_write(fs_node_t * node, uint32_t offset, uint32_t size, uint8_t *buffer) {
sprintf(irc_payload, "PRIVMSG %s :%s\r\n", log_channel, buffer);
irc_send(irc_payload);
return size;
}
static fs_node_t _irc_log_fnode = {
.name = "irc_log",
.write = irc_write,
};
DEFINE_SHELL_FUNCTION(irc_log, "spew debug log to irc") {
if (argc < 2) {
fprintf(tty, "Need a channel to log to.\n");
return 1;
}
if (!strlen(irc_nick)) {
fprintf(tty, "Did you run irc_init?\n");
return 1;
}
fprintf(tty, "May the gods have mercy on your soul.\n");
log_channel = strdup(argv[1]);
sprintf(irc_payload, "JOIN %s\r\n", log_channel);
irc_send(irc_payload);
debug_file = &_irc_log_fnode;
if (argc > 2) {
debug_level = atoi(argv[2]);
}
return 0;
}
DEFINE_SHELL_FUNCTION(irc_join, "irc channel tool") {
if (argc < 2) {
fprintf(tty, "Specify a channel.\n");
return 1;
}
char * channel = argv[1];
sprintf(irc_payload, "JOIN %s\r\n", channel);
irc_send(irc_payload);
sprintf(irc_prompt, "\r[%s] ", channel);
while (1) {
fprintf(tty, irc_prompt);
int c = tty_readline(tty, irc_input, 400);
spin_lock(irc_tty_lock);
irc_input[c] = '\0';
if (startswith(irc_input, "/part")) {
fprintf(tty, "\n");
sprintf(irc_payload, "PART %s\r\n", channel);
irc_send(irc_payload);
spin_unlock(irc_tty_lock);
break;
}
if (startswith(irc_input, "/me ")) {
char * m = strstr(irc_input, " ");
m++;
uint16_t hr, min, sec;
get_time(&hr, &min, &sec);
fprintf(tty, "\r%2d:%2d:%2d * \033[35m%s\033[0m:\033[34m%s\033[0m %s\n\033[K", hr, min, sec, irc_nick, channel, m);
sprintf(irc_payload, "PRIVMSG %s :\1ACTION %s\1\r\n", channel, m);
irc_send(irc_payload);
} else {
uint16_t hr, min, sec;
get_time(&hr, &min, &sec);
fprintf(tty, "\r%2d:%2d:%2d \033[90m<\033[35m%s\033[0m:\033[34m%s\033[90m>\033[0m %s\n\033[K", hr, min, sec, irc_nick, channel, irc_input);
sprintf(irc_payload, "PRIVMSG %s :%s\r\n", channel, irc_input);
irc_send(irc_payload);
}
memset(irc_input, 0x00, sizeof(irc_input));
spin_unlock(irc_tty_lock);
}
memset(irc_prompt, 0x00, sizeof(irc_prompt));
memset(irc_input, 0x00, sizeof(irc_input));
return 0;
}
DEFINE_SHELL_FUNCTION(http, "Open a prompt to send HTTP commands.") {
char tmp[100];
char * payload = malloc(10000);
while (1) {
fprintf(tty, "http> ");
tty_readline(tty, tmp, 100);
if (startswith(tmp, "/quit")) {
break;
} else if (startswith(tmp, "get ")) {
char * m = strstr(tmp, " ");
m++;
sprintf(payload,
"GET %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Cookie: phpbb3_9i66l_u=11616; phpbb3_9i66l_k=ebe8e4f9892d97ab; phpbb3_9i66l_sid=d99d2e26e2a503fdfbe13e9b794dae23\r\n"
"\r\n", m, "forum.osdev.org");
irc_send(payload);
} else if (startswith(tmp, "post")) {
/* /posting.php?mode=post&f=7 */
char * content =
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"subject\"\r\n"
"\r\n"
"test post please ignore\r\n"
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"addbbcode20\"\r\n"
"\r\n"
"100\r\n"
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"helpbox\"\r\n"
"\r\n"
"Tip: Styles can be applied quickly to selected text.\r\n"
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"message\"\r\n"
"\r\n"
"test post please ignore\r\n"
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"attach_sig\"\r\n"
"\r\n"
"on\r\n"
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"post\"\r\n"
"\r\n"
"Submit\r\n"
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"fileupload\"; filename=\"\"\r\n"
"Content-Type: application/octet-stream\r\n"
"\r\n"
"\r\n"
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"filecomment\"\r\n"
"\r\n"
"\r\n"
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"lastclick\"\r\n"
"\r\n"
"1424062664\r\n"
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"creation_time\"\r\n"
"\r\n"
"1424062664\r\n"
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"form_token\"\r\n"
"\r\n"
"3fdbc52648cb6f50b72df5bbd5e145bc333cfc0e\r\n"
"-----------------------------2611311029845263341299213952--\r\n";
sprintf(payload,
"POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Cookie: phpbb3_9i66l_u=11616; phpbb3_9i66l_k=ebe8e4f9892d97ab; phpbb3_9i66l_sid=d99d2e26e2a503fdfbe13e9b794dae23\r\n"
"Referer: http://forum.osdev.org/posting.php?mode=post&f=7\r\n"
"User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0\r\n"
"Content-Type: multipart/form-data; boundary=---------------------------2611311029845263341299213952\r\n"
"Content-Length: %d\r\n"
"\r\n"
"%s",
"/posting.php?mode=post&f=7&sid=d99d2e26e2a503fdfbe13e9b794dae23",
"forum.osdev.org",
strlen(content),
content);
irc_send(payload);
}
}
return 0;
}
DEFINE_SHELL_FUNCTION(rtl, "rtl8139 experiments") {
if (rtl_device_pci) {
fprintf(tty, "Located an RTL 8139: 0x%x\n", rtl_device_pci);
@ -928,11 +479,6 @@ DEFINE_SHELL_FUNCTION(rtl, "rtl8139 experiments") {
static int init(void) {
BIND_SHELL_FUNCTION(rtl);
BIND_SHELL_FUNCTION(irc_test);
BIND_SHELL_FUNCTION(irc_init);
BIND_SHELL_FUNCTION(irc_join);
BIND_SHELL_FUNCTION(irc_log);
BIND_SHELL_FUNCTION(http);
pci_scan(&find_rtl, -1, &rtl_device_pci);
if (!rtl_device_pci) {