#include #include #include #include #include typedef void* BarevClient; typedef void* BarevBuddy; typedef void (*barev_log_cb)(const char* level, const char* msg, void* userdata); typedef void (*barev_typing_cb)(BarevBuddy buddy, int isTyping, void* userdata); typedef void (*barev_buddy_status_cb)(BarevBuddy buddy, int oldStatus, int newStatus, void* userdata); typedef void (*barev_message_cb)(BarevBuddy buddy, const char* msg, void* userdata); typedef void (*barev_conn_state_cb)(BarevBuddy buddy, int state, void* userdata); extern void barev_strfree(char* p); extern BarevClient barev_client_new(const char* nick, const char* myipv6, uint16_t port); extern void barev_client_free(BarevClient c); extern int barev_client_start(BarevClient c); extern void barev_client_stop(BarevClient c); extern void barev_client_process(BarevClient c); extern char* barev_client_myjid(BarevClient c); extern BarevBuddy barev_client_add_buddy(BarevClient c, const char* buddynick, const char* buddyipv6, uint16_t port); extern int barev_client_connect(BarevClient c, const char* buddyjid); extern int barev_client_send_message(BarevClient c, const char* buddyjid, const char* msg); extern int barev_client_send_typing(BarevClient c, const char* buddyjid); extern int barev_client_send_paused(BarevClient c, const char* buddyjid); extern void barev_set_userdata(BarevClient c, void* userdata); extern void barev_set_log_cb(BarevClient c, barev_log_cb cb); extern void barev_set_typing_cb(BarevClient c, barev_typing_cb cb); extern void barev_set_buddy_status_cb(BarevClient c, barev_buddy_status_cb cb); extern void barev_set_message_cb(BarevClient c, barev_message_cb cb); extern void barev_set_conn_state_cb(BarevClient c, barev_conn_state_cb cb); extern char* barev_buddy_get_jid(BarevBuddy b); #define LINE_MAX_LEN 2048 static int running = 1; static BarevClient g_client = 0; static void on_log(const char *lvl, const char *msg, void *ud) { (void)ud; printf("[%s] %s\n", lvl ? lvl : "?", msg ? msg : ""); } static void on_msg(BarevBuddy b, const char *msg, void *ud) { char *jid; (void)ud; jid = barev_buddy_get_jid(b); printf("\n*** Message from %s: %s\n", jid ? jid : "(unknown)", msg ? msg : ""); if (jid) barev_strfree(jid); } static void on_conn(BarevBuddy b, int st, void *ud) { char *jid; (void)ud; jid = barev_buddy_get_jid(b); printf("*** Conn %s state=%d\n", jid ? jid : "(unknown)", st); if (jid) barev_strfree(jid); } static void on_typing(BarevBuddy b, int typing, void *ud) { char *jid; (void)ud; jid = barev_buddy_get_jid(b); printf("*** %s %s typing\n", jid ? jid : "(unknown)", typing ? "is" : "stopped"); if (jid) barev_strfree(jid); } static void on_buddy_status(BarevBuddy b, int oldst, int newst, void *ud) { char *jid; (void)oldst; (void)ud; jid = barev_buddy_get_jid(b); printf("*** %s status=%d\n", jid ? jid : "(unknown)", newst); if (jid) barev_strfree(jid); } static void show_help(void) { printf("Commands:\n"); printf(" help\n"); printf(" add [port]\n"); printf(" connect \n"); printf(" msg \n"); printf(" typing \n"); printf(" paused \n"); printf(" quit\n"); } static void run_command(char *line) { char *cmd = strtok(line, " "); if (!cmd || !*cmd) return; if (strcmp(cmd, "help") == 0) { show_help(); } else if (strcmp(cmd, "add") == 0) { char *nick = strtok(0, " "); char *ip = strtok(0, " "); char *p = strtok(0, " "); uint16_t port = (uint16_t)(p ? atoi(p) : 1337); BarevBuddy b; char *jid; if (!nick || !ip) { printf("usage: add [port]\n"); return; } b = barev_client_add_buddy(g_client, nick, ip, port); jid = b ? barev_buddy_get_jid(b) : 0; if (jid) { printf("added %s\n", jid); barev_strfree(jid); } else { printf("failed add\n"); } } else if (strcmp(cmd, "connect") == 0) { char *jid = strtok(0, " "); if (!jid) printf("usage: connect \n"); else printf("connect %s\n", barev_client_connect(g_client, jid) ? "ok" : "fail"); } else if (strcmp(cmd, "msg") == 0) { char *jid = strtok(0, " "); char *txt = strtok(0, ""); if (!jid || !txt) printf("usage: msg \n"); else printf("send %s\n", barev_client_send_message(g_client, jid, txt) ? "ok" : "fail"); } else if (strcmp(cmd, "typing") == 0) { char *jid = strtok(0, " "); if (!jid) printf("usage: typing \n"); else printf("typing %s\n", barev_client_send_typing(g_client, jid) ? "ok" : "fail"); } else if (strcmp(cmd, "paused") == 0) { char *jid = strtok(0, " "); if (!jid) printf("usage: paused \n"); else printf("paused %s\n", barev_client_send_paused(g_client, jid) ? "ok" : "fail"); } else if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "exit") == 0) { running = 0; } else { printf("unknown command: %s\n", cmd); } } int main(int argc, char **argv) { char line[LINE_MAX_LEN]; char *myjid; if (argc < 3) { printf("usage: %s [port]\n", argv[0]); return 2; } g_client = barev_client_new(argv[1], argv[2], (uint16_t)((argc > 3) ? atoi(argv[3]) : 1337)); if (!g_client) return 1; barev_set_userdata(g_client, 0); barev_set_log_cb(g_client, on_log); barev_set_typing_cb(g_client, on_typing); barev_set_buddy_status_cb(g_client, on_buddy_status); barev_set_message_cb(g_client, on_msg); barev_set_conn_state_cb(g_client, on_conn); if (!barev_client_start(g_client)) { barev_client_free(g_client); return 1; } myjid = barev_client_myjid(g_client); printf("barevclient-libbarev started as %s\n", myjid ? myjid : "(unknown)"); if (myjid) barev_strfree(myjid); show_help(); while (running) { fd_set rfds; struct timeval tv; int rc; barev_client_process(g_client); FD_ZERO(&rfds); FD_SET(0, &rfds); tv.tv_sec = 0; tv.tv_usec = 20000; rc = select(1, &rfds, 0, 0, &tv); if (rc > 0 && FD_ISSET(0, &rfds)) { printf("> "); fflush(stdout); if (!fgets(line, sizeof(line), stdin)) break; line[strcspn(line, "\r\n")] = '\0'; run_command(line); } } barev_client_stop(g_client); barev_client_free(g_client); return 0; }