return NULL;
}
-struct ChanNode* addChannel(const char *chan) {
- return NULL; //to be continued
+struct ChanNode* addChannel(const char *name) {
+ int chanListIndex = get_chanlist_entry(name[1]);
+ if(chanListIndex == -1 || !is_valid_chan(name))
+ return NULL;
+ struct ChanNode *chan = malloc(sizeof(*chan));
+ if (!chan)
+ {
+ perror("malloc() failed");
+ return NULL;
+ }
+ strcpy(chan->name, name);
+ chan->user = NULL;
+ chan->topic[0] = 0;
+ chan->flags = 0;
+ chan->next = chanList[chanListIndex];
+ chanList[chanListIndex] = chan;
+ return chan;
}
void delChannel(struct ChanNode* chan, int freeChan) {
- //to be continued
+ int chanListIndex = get_chanlist_entry(chan->name[1]);
+ if(chanListIndex == -1) return;
+ struct ChanNode *cchan, *last_chan = NULL;
+ for(cchan = chanList[chanListIndex]; cchan; cchan = cchan->next) {
+ if(cchan == chan) {
+ if(last_chan)
+ last_chan->next = chan->next;
+ else
+ chanList[chanListIndex] = chan->next;
+ break;
+ } else
+ last_chan = cchan;
+ }
+ if(freeChan)
+ free(chan);
+ else
+ chan->next = NULL;
}
struct ChanUser;
+#define CHANFLAG_RECEIVED_USERLIST 0x01;
+
struct ChanNode {
char name[CHANNELLEN+1];
char topic[TOPICLEN+1];
struct ChanUser *user;
+ char flags;
struct ChanNode *next;
};
--- /dev/null
+
+#include "ChanUser.h"
+#include "ChanNode.h"
+#include "UserNode.h"
+
+struct ChanUser* addChanUser(struct ChanNode *chan, struct UserNode *user) {
+ struct ChanUser *chanuser = malloc(sizeof(*chan));
+ if (!chanuser)
+ {
+ perror("malloc() failed");
+ return NULL;
+ }
+ chanuser->user = user;
+ chanuser->chan = chan;
+
+ chanuser->next_user = chan->user;
+ chan->user = chanuser;
+
+ chanuser->next_chan = user->channel;
+ user->channel = chanuser;
+
+ return chanuser;
+}
+
+int isUserOnChan(struct UserNode *user, struct ChanNode *chan) {
+ struct ChanUser *chanuser;
+ for(chanuser = user->channel; chanuser; chanuser = chanuser->next_chan) {
+ if(chanuser->chan == chan)
+ return 1;
+ }
+ return 0;
+}
+
+struct ChanUser* getChanUser(struct UserNode *user, struct ChanNode *chan) {
+ struct ChanUser *chanuser;
+ for(chanuser = user->channel; chanuser; chanuser = chanuser->next_chan) {
+ if(chanuser->chan == chan)
+ return chanuser;
+ }
+ return NULL;
+}
+
+struct ChanUser* getChannelUsers(struct ChanNode *chan, struct ChanUser *last) {
+ if(last == NULL)
+ return chan->user;
+ else
+ return last->next_user;
+}
+
+struct ChanUser* getUserChannels(struct UserNode *user, struct ChanUser *last) {
+ if(last == NULL)
+ return user->channel;
+ else
+ return last->next_chan;
+}
+
+void delChanUser(struct ChanUser *chanuser, int freeChanUser) {
+ struct ChanUser *cchanuser, *last;
+ //remove it from the user's channel-list
+ last = NULL;
+ for(cchanuser = chanuser->user->channel; cchanuser; cchanuser = cchanuser->next_chan) {
+ if(cchanuser == chanuser) {
+ if(last)
+ last->next_chan = chanuser->next_chan;
+ else
+ chanuser->user->channel = chanuser->next_chan;
+ break;
+ } else
+ last = cchanuser;
+ }
+
+ //remove it from the channel's user-list
+ last = NULL;
+ for(cchanuser = chanuser->chan->user; cchanuser; cchanuser = cchanuser->next_user) {
+ if(cchanuser == chanuser) {
+ if(last)
+ last->next_user = chanuser->next_user;
+ else
+ chanuser->chan->user = chanuser->next_user;
+ break;
+ } else
+ last = cchanuser;
+ }
+
+ if(freeChanUser)
+ free(chanuser);
+ else {
+ chanuser->next_chan = NULL;
+ chanuser->next_user = NULL;
+ }
+}
+
+void quitChanUser(struct ChanUser *chanuser, int freeChanUser) {
+ struct ChanUser *cchanuser, *last = NULL;
+ last = NULL;
+ for(cchanuser = chanuser->chan->user; cchanuser; cchanuser = cchanuser->next_user) {
+ if(cchanuser == chanuser) {
+ if(last)
+ last->next_user = chanuser->next_user;
+ else
+ chanuser->chan->user = chanuser->next_user;
+ break;
+ } else
+ last = cchanuser;
+ }
+
+ if(freeChanUser)
+ free(chanuser);
+ else
+ chanuser->next_user = NULL;
+}
+
struct ChanUser *next_chan;
};
+struct ChanUser* addChanUser(struct ChanNode *chan, struct UserNode *user);
+int isUserOnChan(struct UserNode *user, struct ChanNode *chan);
+struct ChanUser* getChanUser(struct UserNode *user, struct ChanNode *chan);
+struct ChanUser* getChannelUsers(struct ChanNode *chan, struct ChanUser *last);
+struct ChanUser* getUserChannels(struct UserNode *user, struct ChanUser *last);
+void delChanUser(struct ChanUser *chanuser, int freeChanUser);
+
#endif
\ No newline at end of file
int event_join(struct ChanUser *chanuser);
int event_part(struct ChanUser *chanuser, char *reason);
int event_quit(struct UserNode *user, char *reason);
+int event_kick(struct UserNode *user, struct ChanUser *target, char *reason);
int event_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message);
int event_privmsg(struct UserNode *user, struct UserNode *target, char *message);
struct ChanNode *chan = getChanByName(argv[0]);
if(chan == NULL) {
chan = addChannel(argv[0]);
-
+ //request member list
+ //TODO!
+ } else if(!isUserOnChan(user, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) {
+ struct ChanUser *chanuser = addChanUser(chan, user);
+ event_join(chanuser);
+ }
+ return 1;
+}
+
+static IRC_CMD(raw_part) {
+ if(from == NULL || argc < 2) return 0;
+ struct UserNode *user = getUserByMask(from);
+ if(user == NULL) return 0;
+ struct ChanNode *chan = getChanByName(argv[0]);
+ if(chan == NULL) return 0;
+ if(isUserOnChan(user, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) {
+ struct ChanUser *chanuser = getChanUser(user, chan);
+ delChanUser(chanuser, 0); //we need to free the chanuser manually!
+ event_part(chanuser, argv[1]);
+ free(chanuser);
+ if(user->flags & USERFLAG_ISBOT) {
+ //check if theres another bot in the channel - otherwise free it
+
+ }
+ }
+ if(user->channel == NULL && !(user->flags & USERFLAG_ISBOT)) {
+ //remove the user
+ delUser(user, 1);
}
- putsock(client, "PRIVMSG #pktest :hi");
return 1;
}
+static IRC_CMD(raw_quit) {
+ if(from == NULL || argc < 2) return 0;
+ struct UserNode *user = getUserByMask(from);
+ if(user == NULL) return 0;
+ delUser(user, 0); //a little bit crazy, but we want to delete the user on the channel's userlists - but not the users channel list
+ event_quit(user, argv[1]);
+ if(user->flags & USERFLAG_ISBOT) {
+ //check if there are other bots in the users channel - otherwise free them
+
+ }
+ delUser(user, 1); //now we fully free the user
+ return 1;
+}
+
+static IRC_CMD(raw_kick) {
+ if(from == NULL || argc < 3) return 0;
+ struct UserNode *user = getUserByMask(from);
+ struct UserNode *target = getUserByNick(argv[1]);
+ if(user == NULL || target == NULL) return 0;
+ struct ChanNode *chan = getChanByName(argv[0]);
+ if(chan == NULL) return 0;
+ if(isUserOnChan(target, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) {
+ struct ChanUser *chanuser = getChanUser(target, chan);
+ delChanUser(chanuser, 0); //we need to free the chanuser manually!
+ event_kick(user, chanuser, argv[1]);
+ free(chanuser);
+ if(target->flags & USERFLAG_ISBOT) {
+ //check if theres another bot in the channel - otherwise free it
+
+ }
+ }
+ if(target->channel == NULL && !(target->flags & USERFLAG_ISBOT)) {
+ //remove the user
+ delUser(user, 1);
+ }
+ return 1;
+}
+
static IRC_CMD(raw_ping) {
if(argc == 0) return 0;
putsock(client, "PONG :%s", argv[0]);
void parser_init() {
//all the raws we receive...
register_irc_function("001", raw_001);
+ register_irc_function("KICK", raw_kick);
register_irc_function("JOIN", raw_join);
+ register_irc_function("PART", raw_part);
+ register_irc_function("QUIT", raw_quit);
register_irc_function("PING", raw_ping);
}
#include "UserNode.h"
+#include "ChanUser.h"
static struct UserNode **userList;
} else
last_user = cuser;
}
+ if(user->channel) {
+ struct ChanUser *chanUser, *next;
+ for(chanUser = user->channel; chanUser; chanUser = next) {
+ next = chanUser->next_chan;
+ quitChanUser(chanUser, freeUser);
+ }
+ }
if(freeUser)
free(user);
else
int renameUser(struct UserNode* user, const char *new_nick);
void delUser(struct UserNode* user, int freeUser);
-#endif
\ No newline at end of file
+#endif