Commit acad1058 authored by stettberger's avatar stettberger

Buddylist support is now complete :)

parent 002285c1
......@@ -22,17 +22,42 @@
/* Buddylist stuff */
#define MAX_CONNS 20
typedef struct BuddyStruct {
SilcClientEntry client;
struct BuddyStruct *next;
} *Buddy;
Buddy buddies=NULL;
int buddy_conns[MAX_CONNS];
SILC_TASK_CALLBACK(si_handle_buddyfd_input);
SILC_TASK_CALLBACK(si_handle_buddy_conn_input);
void send_buddy_list(int fd);
void add_pubkey_callback(SilcClient client, SilcClientConnection conn,
SilcClientEntry *clients, SilcUInt32 clients_count,
void *context);
void refresh_buddylist() {
int i;
for (i=0; i < MAX_CONNS; i++){
if(!buddy_conns[i])
continue;
write(buddy_conns[i], "update\n", 7);
DEBUG("Refresh");
}
}
void
add_buddy(SilcClientEntry client) {
Buddy new=calloc(1, sizeof (Buddy)), tmp;
NULL_TEST(new);
new->client=client;
for (tmp=buddies; tmp; tmp=tmp->next)
if (tmp->client==client)
return;
if(buddies) {
for (tmp=buddies; tmp->next; tmp=tmp->next);
tmp->next=new;
......@@ -42,8 +67,10 @@ add_buddy(SilcClientEntry client) {
}
void rm_buddy(SilcClientEntry client){
Buddy del, tmp;
if ( buddies->client==client)
if (buddies && buddies->client==client){
buddies=buddies->next;
return;
}
for(del=buddies; del->next; del=del->next)
if(del->next->client==client){
tmp=del->next;
......@@ -108,6 +135,13 @@ void init_buddylist() {
struct sockaddr_un strAddr;
socklen_t lenAddr;
int yes=1;
int i=0;
while(i<MAX_CONNS){
buddy_conns[i]=0;
i++;
}
/* Init the buddylist itself */
path=malloc(strlen(getenv("HOME"))+40);
NULL_TEST(path);
......@@ -129,6 +163,7 @@ void init_buddylist() {
path=malloc(strlen(ircdir)+20);
NULL_TEST(path);
sprintf(path,"%s/buddylist", ircdir);
unlink(path);
if ((buddyfd=socket(PF_UNIX, SOCK_STREAM,0))==-1) {
perror("si: couldn't initalize buddy socket (socket)");
return;
......@@ -146,7 +181,7 @@ void init_buddylist() {
perror("si: couldn't initalize buddy socket (bind)");
return;
}
if (listen(buddyfd, 20) != 0){
if (listen(buddyfd, MAX_CONNS) != 0){
perror("si: couldn't initalize buddy socket (listen)");
return;
}
......@@ -156,18 +191,68 @@ void init_buddylist() {
}
SILC_TASK_CALLBACK(si_handle_buddyfd_input) {
int conn=0;
int conn=0;
socklen_t lenAddr;
int i;
struct sockaddr_un *addr=context;
lenAddr=sizeof(addr->sun_family)+strlen(addr->sun_path);
if((conn=accept(fd, addr, &lenAddr))<0) {
perror("si: couldn't accept connection on buddylist");
return;
}
silc_schedule_task_add(silc_client->client->schedule, conn,
si_handle_buddy_conn_input, NULL, 0, 0,
SILC_TASK_FD, SILC_TASK_PRI_NORMAL);
for(i=0; i < MAX_CONNS; i++)
if(!buddy_conns[i]){
buddy_conns[i]=conn;
break;
}
DEBUG("New Connection on Buddylist");
}
SILC_TASK_CALLBACK(si_handle_buddy_conn_input) {
DEBUG("Data");
void si_handle_buddy_conn_input(int fd) {
int pos=0, len=1;
char buf[1], *data=malloc(len);
int count=0;
NULL_TEST(data);
data[0]=0;
while(buf[0]!='\n' && (count = read(fd, buf, 1)) > 0){
len+=count;
data=realloc(data, len);
NULL_TEST(data);
data=strcat(data, buf);
}
if(count <= 0) {
DEBUG("Closed connection on Buddylist");
pos=0;
while(pos<MAX_CONNS) {
if(buddy_conns[pos]==fd)
buddy_conns[pos]=0;
pos++;
}
close(fd);
return;
}
char *p=strchr(data, '\n');
p[0]=0;
/* Proc data */
if(!strncmp("getbuddylist", data, 12)) {
send_buddy_list(fd);
}
free(data);
}
void send_buddy_list(int fd) {
Buddy tmp;
char *umode, *line;
for(tmp=buddies; tmp; tmp=tmp->next) {
umode=silc_client_umode(tmp->client->mode);
line=malloc(strlen(umode)+strlen(tmp->client->nickname)+3);
NULL_TEST(line);
sprintf(line, "%s,%s\n", umode, tmp->client->nickname);
write(fd, line, strlen(line));
free(line);
free(umode);
fsync(fd);
}
write(fd, "END,nouser\n", 11);
fsync(fd);
}
#!/usr/bin/python
import socket, select, os, sys, re, time
import curses
class BuddyList:
def __init__(self, server, prefix="%s/irc"%os.environ['HOME'], buffer=1024):
self.server=os.path.join(prefix,server)
self.server=os.path.join(self.server, "buddylist")
self.socket=socket.socket(socket.AF_UNIX, socket.SOCK_STREAM,0)
self.buffer=buffer
try:
self.socket.connect(self.server)
except:
self.socket=None
def has_data(self):
(iwtd, owtd, ewtd)=select.select([self.socket],[],[],0.05)
if len(iwtd)==0:
return False
return True
def get_buddylist(self):
self.socket.send("getbuddylist\n")
text=self.socket.recv(self.buffer)
ret=[]
for i in text.split('\n'):
(status, nickname)=i.split(",",2)
if(status=="END"):
return ret
ret.append([status, nickname])
return ret
def read(self):
return self.socket.recv(self.buffer).replace("\n", "")
class DeMultiplexer:
def __init__(self, prefix="%s/irc"%os.environ['HOME']):
self.scr = curses.initscr()
curses.noecho()
self.servers=[]
self.buddylist=[]
for i in os.walk(prefix):
if "buddylist" in i[2]:
server=BuddyList(i[0].replace(prefix, "")[1:])
if server.socket==None:
continue
self.servers.append(server)
self.refresh()
def refresh(self):
self.buddylist=[]
for i in self.servers:
for x in i.get_buddylist():
self.buddylist.append(x)
self.scr.clear()
for i in self.buddylist:
self.scr.addstr("[%s] %s\n"%(i[0], i[1]))
self.scr.refresh()
def run(self):
while True:
for i in self.servers:
if i.has_data():
if i.read() == "update":
self.refresh()
fd=DeMultiplexer()
fd.run()
sys.exit(1)
......@@ -89,11 +89,6 @@ typedef struct SIMimeStruct {
struct SIMimeStruct *next;
} *SIMime;
typedef struct BuddyStruct {
SilcClientEntry client;
struct BuddyStruct *next;
} *Buddy;
typedef struct Channel Channel;
struct Channel {
int fd;
......@@ -133,7 +128,6 @@ char ircdir[1024];
Channel *channels=NULL;
Query *queries=NULL;
Transfer *transfers=NULL;
Buddy buddies=NULL;
int debug=1;
int connected=0;
SilcClientOperations ops;
......@@ -616,6 +610,7 @@ void proc_watch(SilcClientEntry client, SilcUInt32 mode, SilcNotifyType type){
switch(type) {
case SILC_NOTIFY_TYPE_UMODE_CHANGE:
str=silc_client_umode(mode);
add_buddy(client);
print_out("", "-!- Watch: %s new user mode is: %s", client->nickname, str);
free(str);
break;
......@@ -638,6 +633,7 @@ void proc_watch(SilcClientEntry client, SilcUInt32 mode, SilcNotifyType type){
default:
DEBUG("Error: Unimplemented Watch Type: %d", type);
}
refresh_buddylist();
}
/* }}} */
......@@ -937,7 +933,7 @@ void run_once() {
/* Select the different fifo's */
Channel *c;
Query *q;
int r, maxfd=0;
int r, maxfd=0, i;
fd_set rd;
struct timeval tv;
if (silc_client->auto_away){
......@@ -965,6 +961,13 @@ void run_once() {
maxfd = q->fd;
FD_SET(q->fd, &rd);
}
for(i=0; i<MAX_CONNS; i++){
if(!buddy_conns[i])
continue;
if(maxfd < buddy_conns[i])
maxfd = buddy_conns[i];
FD_SET(buddy_conns[i], &rd);
}
tv.tv_sec = 0;
tv.tv_usec = 1;
r = select(maxfd + 1, &rd, 0, 0, &tv);
......@@ -980,6 +983,12 @@ void run_once() {
for(q = queries; q; q = q->next)
if(FD_ISSET(q->fd, &rd))
handle_query_input(q);
for(i=0; i<MAX_CONNS; i++){
if(!buddy_conns[i])
continue;
if(FD_ISSET(buddy_conns[i], &rd))
si_handle_buddy_conn_input(buddy_conns[i]);
}
/* Run the Silc Client one Time */
silc_client_run_one(silc_client->client);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment