用 C 编写的 IRC 机器人
IRC Bot Written in C
我从 here 那里得到了一个 IRC 机器人框架
它不编译,尽管作者说它应该编译。 gcc 基本上会抛出这些错误
/tmp/cc39tOaX.o: In function raw': bot.c:(.text+0x73): undefined
reference to
va_start' bot.c:(.text+0xaa): undefined reference to
`va_end' collect2: error: ld returned 1 exit status
这似乎意味着这两个函数在原始函数中被调用之前没有定义?
无论如何,这是代码。任何帮助开始解决这个问题的帮助都会很大。
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
int conn;
char sbuf[512];
void raw(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vsnprintf(sbuf, 512, fmt, ap);
va_end(ap);
printf("<< %s", sbuf);
write(conn, sbuf, strlen(sbuf));
}
int main() {
char *nick = "test";
char *channel = NULL;
char *host = "irc.dav7.net";
char *port = "6667";
char *user, *command, *where, *message, *sep, *target;
int i, j, l, sl, o = -1, start, wordcount;
char buf[513];
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo(host, port, &hints, &res);
conn = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
connect(conn, res->ai_addr, res->ai_addrlen);
raw("USER %s 0 0 :%s\r\n", nick, nick);
raw("NICK %s\r\n", nick);
while ((sl = read(conn, sbuf, 512))) {
for (i = 0; i < sl; i++) {
o++;
buf[o] = sbuf[i];
if ((i > 0 && sbuf[i] == '\n' && sbuf[i - 1] == '\r') || o == 512) {
buf[o + 1] = '[=10=]';
l = o;
o = -1;
printf(">> %s", buf);
if (!strncmp(buf, "PING", 4)) {
buf[1] = 'O';
raw(buf);
} else if (buf[0] == ':') {
wordcount = 0;
user = command = where = message = NULL;
for (j = 1; j < l; j++) {
if (buf[j] == ' ') {
buf[j] = '[=10=]';
wordcount++;
switch(wordcount) {
case 1: user = buf + 1; break;
case 2: command = buf + start; break;
case 3: where = buf + start; break;
}
if (j == l - 1) continue;
start = j + 1;
} else if (buf[j] == ':' && wordcount == 3) {
if (j < l - 1) message = buf + j + 1;
break;
}
}
if (wordcount < 2) continue;
if (!strncmp(command, "001", 3) && channel != NULL) {
raw("JOIN %s\r\n", channel);
} else if (!strncmp(command, "PRIVMSG", 7) || !strncmp(command, "NOTICE", 6)) {
if (where == NULL || message == NULL) continue;
if ((sep = strchr(user, '!')) != NULL) user[sep - user] = '[=10=]';
if (where[0] == '#' || where[0] == '&' || where[0] == '+' || where[0] == '!') target = where; else target = user;
printf("[from: %s] [reply-with: %s] [where: %s] [reply-to: %s] %s", user, command, where, target, message);
//raw("%s %s :%s", command, target, message); // If you enable this the IRCd will get its "*** Looking up your hostname..." messages thrown back at it but it works...
}
}
}
}
}
return 0;
}
我尝试在函数 raw() 之前用
定义 va_start 和 va_end
void va_start();
void va_end();
但这并没有改变任何东西..
man va_start
给我:
SYNOPSIS
#include <stdarg.h>
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
void va_copy(va_list dest, va_list src);
通过添加对我有用的 #include <stdarg.h>
。
我从 here 那里得到了一个 IRC 机器人框架 它不编译,尽管作者说它应该编译。 gcc 基本上会抛出这些错误
/tmp/cc39tOaX.o: In function
raw': bot.c:(.text+0x73): undefined reference to
va_start' bot.c:(.text+0xaa): undefined reference to `va_end' collect2: error: ld returned 1 exit status
这似乎意味着这两个函数在原始函数中被调用之前没有定义?
无论如何,这是代码。任何帮助开始解决这个问题的帮助都会很大。
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
int conn;
char sbuf[512];
void raw(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vsnprintf(sbuf, 512, fmt, ap);
va_end(ap);
printf("<< %s", sbuf);
write(conn, sbuf, strlen(sbuf));
}
int main() {
char *nick = "test";
char *channel = NULL;
char *host = "irc.dav7.net";
char *port = "6667";
char *user, *command, *where, *message, *sep, *target;
int i, j, l, sl, o = -1, start, wordcount;
char buf[513];
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo(host, port, &hints, &res);
conn = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
connect(conn, res->ai_addr, res->ai_addrlen);
raw("USER %s 0 0 :%s\r\n", nick, nick);
raw("NICK %s\r\n", nick);
while ((sl = read(conn, sbuf, 512))) {
for (i = 0; i < sl; i++) {
o++;
buf[o] = sbuf[i];
if ((i > 0 && sbuf[i] == '\n' && sbuf[i - 1] == '\r') || o == 512) {
buf[o + 1] = '[=10=]';
l = o;
o = -1;
printf(">> %s", buf);
if (!strncmp(buf, "PING", 4)) {
buf[1] = 'O';
raw(buf);
} else if (buf[0] == ':') {
wordcount = 0;
user = command = where = message = NULL;
for (j = 1; j < l; j++) {
if (buf[j] == ' ') {
buf[j] = '[=10=]';
wordcount++;
switch(wordcount) {
case 1: user = buf + 1; break;
case 2: command = buf + start; break;
case 3: where = buf + start; break;
}
if (j == l - 1) continue;
start = j + 1;
} else if (buf[j] == ':' && wordcount == 3) {
if (j < l - 1) message = buf + j + 1;
break;
}
}
if (wordcount < 2) continue;
if (!strncmp(command, "001", 3) && channel != NULL) {
raw("JOIN %s\r\n", channel);
} else if (!strncmp(command, "PRIVMSG", 7) || !strncmp(command, "NOTICE", 6)) {
if (where == NULL || message == NULL) continue;
if ((sep = strchr(user, '!')) != NULL) user[sep - user] = '[=10=]';
if (where[0] == '#' || where[0] == '&' || where[0] == '+' || where[0] == '!') target = where; else target = user;
printf("[from: %s] [reply-with: %s] [where: %s] [reply-to: %s] %s", user, command, where, target, message);
//raw("%s %s :%s", command, target, message); // If you enable this the IRCd will get its "*** Looking up your hostname..." messages thrown back at it but it works...
}
}
}
}
}
return 0;
}
我尝试在函数 raw() 之前用
定义 va_start 和 va_endvoid va_start();
void va_end();
但这并没有改变任何东西..
man va_start
给我:
SYNOPSIS #include <stdarg.h> void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_end(va_list ap); void va_copy(va_list dest, va_list src);
通过添加对我有用的 #include <stdarg.h>
。