Skip to content

Instantly share code, notes, and snippets.

@yne yne/xlc.c
Created Dec 18, 2015

Embed
What would you like to do?
XMPP Lightweight Client
/* libstroph build under win+tcc reminder
tcc -I. src/ctx.c src/snprintf.c src/sock.c src/tls_schannel.c src/util.c src/auth.c src/conn.c src/event.c src/handler.c src/hash.c src/jid.c src/md5.c src/sasl.c src/scram.c src/sha1.c src/stanza.c src/thread.c src/parser_expat.c -lws2_32 -ladvapi -lwinmm -lexpat -shared -rdynamic -o libstroph.dll
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <windows.h>
#include <strophe.h>
int readLine(char*dst,int max){
int i=0,c;
while(i<max-1 && (c=getc(stdin))!=EOF && c!='\n')
dst[i++]=c;
dst[i]='\0';
return i;
}
int setColor(int c){
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo);
int old=consoleInfo.wAttributes;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
return old;
}
int requestRoster(xmpp_conn_t * const conn,xmpp_ctx_t *ctx){
xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(iq, "iq");
xmpp_stanza_set_type(iq, "get");
//xmpp_stanza_set_id(iq, "roster1");
xmpp_stanza_t *query = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(query, "query");
xmpp_stanza_set_ns(query, XMPP_NS_ROSTER);
xmpp_stanza_add_child(iq, query);
xmpp_stanza_release(query);
xmpp_send(conn, iq);
}
void sendMessage(xmpp_conn_t * const conn,xmpp_ctx_t *ctx,const char*message){
xmpp_stanza_t *reply = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(reply, "message");
xmpp_stanza_set_type(reply, "chat");
char to[256];
GetConsoleTitleA(to,sizeof(to));
xmpp_stanza_set_attribute(reply, "to", to);
xmpp_stanza_t *body = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(body, "body");
xmpp_stanza_t *text = xmpp_stanza_new(ctx);
xmpp_stanza_set_text(text, message);
xmpp_stanza_add_child(body, text);
xmpp_stanza_add_child(reply, body);
xmpp_send(conn, reply);
xmpp_stanza_release(reply);
}
int sender_thread(void * const userdata){
xmpp_conn_t * const conn = (xmpp_conn_t * const)userdata;
xmpp_ctx_t *ctx = xmpp_conn_get_context(conn);
char message[1024];
while(1){
readLine(message,sizeof(message));
if(!strncmp(message,"ls",2))
requestRoster(conn,ctx);
else if(!strncmp(message,"cd ",3))
SetConsoleTitleA(message+3);
else
sendMessage(conn,ctx,message);
}
return 0;
}
int message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata){
xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata;
if(!xmpp_stanza_get_child_by_name(stanza, "body")) return 1;
if(!strcmp(xmpp_stanza_get_attribute(stanza, "type"), "error")) return 1;
SetConsoleTitleA(xmpp_stanza_get_attribute(stanza, "from"));
int old=setColor(4|8);
printf("%s\n",xmpp_stanza_get_text(xmpp_stanza_get_child_by_name(stanza, "body")));
Beep(2500, 150);
setColor(old);
return 1;
}
int roster_handler(xmpp_conn_t * const conn,xmpp_stanza_t * const stanza,void * const userdata){
if (!strcmp(xmpp_stanza_get_type(stanza), "error"))
return printf("ERROR: query failed\n");
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, "query");
xmpp_stanza_t *item;
for (item = xmpp_stanza_get_children(query); item; item = xmpp_stanza_get_next(item)){
int old=setColor(7|8);
printf("%s ",xmpp_stanza_get_attribute(item, "name"));
setColor(0|8);
printf("%s\n",xmpp_stanza_get_attribute(item, "jid"));
setColor(old);
}
return 0;
}
int thid=0;
xmpp_ctx_t *quit_arg;//any alternativ ?
int quit(unsigned int type){
TerminateThread(&thid,0);
xmpp_stop(quit_arg);
return 1;//I handle it guys !
}
/* define a handler for connection events */
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, const int error, xmpp_stream_error_t * const stream_error,void * const userdata){
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
if (status == XMPP_CONN_CONNECT) {
SetConsoleTitleA(xmpp_conn_get_bound_jid(conn));
xmpp_handler_add(conn,message_handler, NULL, "message", NULL, ctx);
xmpp_handler_add(conn, roster_handler, XMPP_NS_ROSTER, "iq", NULL, ctx);
//xmpp_id_handler_add(conn, roster_handler, "roster1", ctx);
//must broadcast online presence to receive messages
xmpp_stanza_t* pres = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(pres, "presence");
xmpp_send(conn, pres);
xmpp_stanza_release(pres);
} else {
xmpp_stop(ctx);
}
}
int main(int argc, char **argv){
char user[256]={0}, pass[256]={0};
int color;
if(argc < 2)//jid not provided
printf("user:"),
readLine(user,sizeof(user));
if(argc < 3)//password not provided
printf("pass:"),
color=setColor(0),
readLine(pass,sizeof(pass)),
setColor(color);
SetConsoleCtrlHandler((PHANDLER_ROUTINE)quit,1);
xmpp_initialize();
xmpp_ctx_t *ctx = quit_arg = xmpp_ctx_new(NULL, /*xmpp_get_default_logger(XMPP_LEVEL_DEBUG)*/NULL);
xmpp_conn_t *conn = xmpp_conn_new(ctx);
xmpp_conn_set_jid(conn, user[0]?user:argv[1]);
xmpp_conn_set_pass(conn, pass[0]?pass:argv[2]);
xmpp_connect_client(conn, NULL, 0, conn_handler, ctx);
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)sender_thread,conn,0,&thid);
xmpp_run(ctx);
printf("closing...\n");
xmpp_conn_release(conn);
xmpp_ctx_free(ctx);
xmpp_shutdown();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.