Seeding from the 1.2 tree.
This commit is contained in:
869
dll/aim/toc/toc.c
Normal file
869
dll/aim/toc/toc.c
Normal file
@@ -0,0 +1,869 @@
|
||||
/*
|
||||
* gaim
|
||||
*
|
||||
* Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Heavily modified by Nadeem Riaz (nads@bleh.org)
|
||||
* for use in libtoc
|
||||
*/
|
||||
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "toc.h"
|
||||
|
||||
/* descriptor for talking to TOC */
|
||||
static int toc_fd;
|
||||
static int seqno;
|
||||
static unsigned int peer_ver=0;
|
||||
int state;
|
||||
/* static int inpa=-1; */
|
||||
int permdeny = PERMIT_PERMITALL;
|
||||
|
||||
int toc_login(char *username, char *password)
|
||||
{
|
||||
char *config;
|
||||
struct in_addr *sin;
|
||||
char buf[80];
|
||||
char buf2[2048];
|
||||
|
||||
toc_debug_printf("looking up host! %s", aim_host);
|
||||
|
||||
sin = (struct in_addr *)get_address(aim_host);
|
||||
if (!sin) {
|
||||
set_state(STATE_OFFLINE);
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"Unable to lookup %s", aim_host);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(toc_addy, sizeof(toc_addy), "%s", inet_ntoa(*sin));
|
||||
snprintf(buf, sizeof(buf), "Connecting to %s", inet_ntoa(*sin));
|
||||
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"%s",buf);
|
||||
|
||||
toc_fd = connect_address(sin->s_addr, aim_port);
|
||||
|
||||
if (toc_fd < 0) {
|
||||
set_state(STATE_OFFLINE);
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"Connect to %s failed", inet_ntoa(*sin));
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(sin);
|
||||
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"Signon: %s",username);
|
||||
|
||||
if (toc_signon(username, password) < 0) {
|
||||
set_state(STATE_OFFLINE);
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"Disconnected.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"Waiting for reply...");
|
||||
if (toc_wait_signon() < 0) {
|
||||
set_state(STATE_OFFLINE);
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"Authentication Failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
snprintf(aim_username, sizeof(aim_username), "%s", username);
|
||||
snprintf(aim_password, sizeof(aim_password), "%s", password);
|
||||
|
||||
save_prefs();
|
||||
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"Retrieving config...");
|
||||
if ((config=toc_wait_config()) == NULL) {
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"No Configuration\n");
|
||||
set_state(STATE_OFFLINE);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
init_lists();
|
||||
/* gtk_widget_hide(mainwindow);
|
||||
show_buddy_list(); */
|
||||
parse_toc_buddy_list(config);
|
||||
/* refresh_buddy_window(); */
|
||||
|
||||
snprintf(buf2, sizeof(buf2), "toc_init_done");
|
||||
sflap_send(buf2, -1, TYPE_DATA);
|
||||
|
||||
serv_finish_login();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void toc_close()
|
||||
{
|
||||
seqno = 0;
|
||||
state = STATE_OFFLINE;
|
||||
toc_remove_input_stream(toc_fd);
|
||||
close(toc_fd);
|
||||
toc_fd=-1;
|
||||
}
|
||||
|
||||
int toc_signon(char *username, char *password)
|
||||
{
|
||||
char buf[BUF_LONG];
|
||||
int res;
|
||||
struct signon so;
|
||||
|
||||
toc_debug_printf("State = %d\n", state);
|
||||
|
||||
strncpy(aim_username, username, sizeof(aim_username));
|
||||
|
||||
if ((res = write(toc_fd, FLAPON, strlen(FLAPON))) < 0)
|
||||
return res;
|
||||
/* Wait for signon packet */
|
||||
|
||||
state = STATE_FLAPON;
|
||||
|
||||
if ((res = wait_reply(buf, sizeof(buf)) < 0))
|
||||
return res;
|
||||
|
||||
if (state != STATE_SIGNON_REQUEST) {
|
||||
toc_debug_printf( "State should be %d, but is %d instead\n", STATE_SIGNON_REQUEST, state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Compose a response */
|
||||
|
||||
snprintf(so.username, sizeof(so.username), "%s", username);
|
||||
so.ver = ntohl(1);
|
||||
so.tag = ntohs(1);
|
||||
so.namelen = htons(strlen(so.username));
|
||||
|
||||
sflap_send((char *)&so, ntohs(so.namelen) + 8, TYPE_SIGNON);
|
||||
|
||||
snprintf(buf, sizeof(buf),
|
||||
"toc_signon %s %d %s %s %s \"%s\"",
|
||||
login_host, login_port, normalize(username), roast_password(password), LANGUAGE, REVISION);
|
||||
|
||||
toc_debug_printf("Send: %s\n", buf);
|
||||
|
||||
return sflap_send(buf, -1, TYPE_DATA);
|
||||
}
|
||||
|
||||
int toc_wait_signon()
|
||||
{
|
||||
/* Wait for the SIGNON to be approved */
|
||||
char buf[BUF_LEN];
|
||||
int res;
|
||||
res = wait_reply(buf, sizeof(buf));
|
||||
if (res < 0)
|
||||
return res;
|
||||
if (state != STATE_SIGNON_ACK) {
|
||||
toc_debug_printf("State should be %d, but is %d instead\n",STATE_SIGNON_ACK, state);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wait_reply(char *buffer, int buflen)
|
||||
{
|
||||
int res=6;
|
||||
struct sflap_hdr *hdr=(struct sflap_hdr *)buffer;
|
||||
char *c;
|
||||
|
||||
while((res = read(toc_fd, buffer, 1))) {
|
||||
if (res < 0)
|
||||
return res;
|
||||
if (buffer[0] == '*')
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
res = read(toc_fd, buffer+1, sizeof(struct sflap_hdr) - 1);
|
||||
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res += 1;
|
||||
|
||||
|
||||
toc_debug_printf( "Rcv: %s %s\n",print_header(buffer), "");
|
||||
|
||||
while (res < (sizeof(struct sflap_hdr) + ntohs(hdr->len))) {
|
||||
res += read(toc_fd, buffer + res, (ntohs(hdr->len) + sizeof(struct sflap_hdr)) - res);
|
||||
/* while(gtk_events_pending())
|
||||
gtk_main_iteration(); */
|
||||
}
|
||||
|
||||
if (res >= sizeof(struct sflap_hdr))
|
||||
buffer[res]='\0';
|
||||
else
|
||||
return res - sizeof(struct sflap_hdr);
|
||||
|
||||
switch(hdr->type) {
|
||||
case TYPE_SIGNON:
|
||||
memcpy(&peer_ver, buffer + sizeof(struct sflap_hdr), 4);
|
||||
peer_ver = ntohl(peer_ver);
|
||||
seqno = ntohs(hdr->seqno);
|
||||
state = STATE_SIGNON_REQUEST;
|
||||
break;
|
||||
case TYPE_DATA:
|
||||
if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "SIGN_ON:", strlen("SIGN_ON:")))
|
||||
state = STATE_SIGNON_ACK;
|
||||
else if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "CONFIG:", strlen("CONFIG:"))) {
|
||||
state = STATE_CONFIG;
|
||||
} else if (state != STATE_ONLINE && !strncasecmp(buffer + sizeof(struct sflap_hdr), "ERROR:", strlen("ERROR:"))) {
|
||||
c = strtok(buffer + sizeof(struct sflap_hdr) + strlen("ERROR:"), ":");
|
||||
translate_toc_error_code(c);
|
||||
toc_debug_printf("ERROR CODE: %s\n",c);
|
||||
}
|
||||
|
||||
toc_debug_printf("Data: %s\n",buffer + sizeof(struct sflap_hdr));
|
||||
|
||||
break;
|
||||
default:
|
||||
toc_debug_printf("Unknown/unimplemented packet type %d\n",hdr->type);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int sflap_send(char *buf, int olen, int type)
|
||||
{
|
||||
int len;
|
||||
int slen=0;
|
||||
struct sflap_hdr hdr;
|
||||
char obuf[MSG_LEN];
|
||||
|
||||
/* One _last_ 2048 check here! This shouldn't ever
|
||||
* get hit though, hopefully. If it gets hit on an IM
|
||||
* It'll lose the last " and the message won't go through,
|
||||
* but this'll stop a segfault. */
|
||||
if (strlen(buf) > (MSG_LEN - sizeof(hdr))) {
|
||||
buf[MSG_LEN - sizeof(hdr) - 3] = '"';
|
||||
buf[MSG_LEN - sizeof(hdr) - 2] = '\0';
|
||||
}
|
||||
|
||||
toc_debug_printf("%s [Len %d]\n", buf, strlen(buf));
|
||||
|
||||
|
||||
if (olen < 0)
|
||||
len = escape_message(buf);
|
||||
else
|
||||
len = olen;
|
||||
hdr.ast = '*';
|
||||
hdr.type = type;
|
||||
hdr.seqno = htons(seqno++ & 0xffff);
|
||||
hdr.len = htons(len + (type == TYPE_SIGNON ? 0 : 1));
|
||||
|
||||
toc_debug_printf("Escaped message is '%s'\n",buf);
|
||||
|
||||
memcpy(obuf, &hdr, sizeof(hdr));
|
||||
slen += sizeof(hdr);
|
||||
memcpy(&obuf[slen], buf, len);
|
||||
slen += len;
|
||||
if (type != TYPE_SIGNON) {
|
||||
obuf[slen]='\0';
|
||||
slen += 1;
|
||||
}
|
||||
/* print_buffer(obuf, slen); */
|
||||
|
||||
return write(toc_fd, obuf, slen);
|
||||
}
|
||||
|
||||
unsigned char *roast_password(char *pass)
|
||||
{
|
||||
/* Trivial "encryption" */
|
||||
static char rp[256];
|
||||
static char *roast = ROAST;
|
||||
int pos=2;
|
||||
int x;
|
||||
strcpy(rp, "0x");
|
||||
for (x=0;(x<150) && pass[x]; x++)
|
||||
pos+=sprintf(&rp[pos],"%02x", pass[x] ^ roast[x % strlen(roast)]);
|
||||
rp[pos]='\0';
|
||||
return rp;
|
||||
}
|
||||
|
||||
char *print_header(void *hdr_v)
|
||||
{
|
||||
static char s[80];
|
||||
struct sflap_hdr *hdr = (struct sflap_hdr *)hdr_v;
|
||||
snprintf(s,sizeof(s), "[ ast: %c, type: %d, seqno: %d, len: %d ]",
|
||||
hdr->ast, hdr->type, ntohs(hdr->seqno), ntohs(hdr->len));
|
||||
return s;
|
||||
}
|
||||
|
||||
int toc_callback(int fd)
|
||||
{
|
||||
char *buf;
|
||||
char *c;
|
||||
char **args = NULL;
|
||||
char *dup,*raw;
|
||||
char *l;
|
||||
int numargs =0;
|
||||
|
||||
buf = malloc(BUF_LONG);
|
||||
|
||||
if (wait_reply(buf, BUF_LONG) < 0) {
|
||||
toc_signoff();
|
||||
toc_debug_printf("need to do proper sign off on this\n");
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"Connection Closed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dup = strdup(buf+sizeof(struct sflap_hdr));
|
||||
raw = rindex(dup,':');
|
||||
c=strtok(buf+sizeof(struct sflap_hdr),":"); /* Ditch the first part */
|
||||
if (!strcasecmp(c,"UPDATE_BUDDY")) {
|
||||
char *uc, *t;
|
||||
int logged, evil, idle, type = 0;
|
||||
time_t signon;
|
||||
time_t time_idle;
|
||||
|
||||
numargs = 7;
|
||||
args = (char **) malloc(sizeof(char *)*numargs);
|
||||
use_handler(TOC_RAW_HANDLE,TOC_UPDATE_BUDDY,raw);
|
||||
c = strtok(NULL,":"); /* c is name */
|
||||
args[0] = strdup(c);
|
||||
|
||||
l = strtok(NULL,":"); /* l is T/F logged status */
|
||||
args[1] = strdup(l);
|
||||
|
||||
t = strtok(NULL, ":");
|
||||
args[2] = strdup(t);
|
||||
sscanf(t, "%d", &evil);
|
||||
|
||||
t = strtok(NULL, ":");
|
||||
args[3] = strdup(t);
|
||||
sscanf(t, "%ld", &signon);
|
||||
|
||||
t = strtok(NULL, ":");
|
||||
args[4] = strdup(t);
|
||||
sscanf(t, "%d", &idle);
|
||||
|
||||
uc = strtok(NULL, ":");
|
||||
args[5] = strdup(uc);
|
||||
|
||||
if (!strncasecmp(l,"T",1))
|
||||
logged = 1;
|
||||
else
|
||||
logged = 0;
|
||||
|
||||
|
||||
if (uc[0] == 'A')
|
||||
type |= UC_AOL;
|
||||
|
||||
switch(uc[1]) {
|
||||
case 'A':
|
||||
type |= UC_ADMIN;
|
||||
break;
|
||||
case 'U':
|
||||
type |= UC_UNCONFIRMED;
|
||||
break;
|
||||
case 'O':
|
||||
type |= UC_NORMAL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(uc[2]) {
|
||||
case 'U':
|
||||
type |= UC_UNAVAILABLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (idle) {
|
||||
time(&time_idle);
|
||||
time_idle -= idle*60;
|
||||
} else
|
||||
time_idle = 0;
|
||||
|
||||
serv_got_update(c, logged, evil, signon, time_idle, type);
|
||||
args[6] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_UPDATE_BUDDY,args);
|
||||
} else if (!strcasecmp(c, "ERROR")) {
|
||||
use_handler(TOC_RAW_HANDLE,TOC_ERROR,raw);
|
||||
c = strtok(NULL,":");
|
||||
translate_toc_error_code(c);
|
||||
args = (char **) malloc(sizeof(char *)*1 + 1);
|
||||
numargs = 1;
|
||||
args[0] = strdup(c);
|
||||
use_handler(TOC_HANDLE,TOC_ERROR,args);
|
||||
toc_debug_printf("ERROR: %s",c);
|
||||
} else if (!strcasecmp(c, "NICK")) {
|
||||
use_handler(TOC_RAW_HANDLE,TOC_NICK,raw);
|
||||
c = strtok(NULL,":");
|
||||
snprintf(aim_username, sizeof(aim_username), "%s", c);
|
||||
numargs = 2;
|
||||
args = (char **) malloc(sizeof(char *)*numargs);
|
||||
args[0] = strdup(c);
|
||||
args[1] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_NICK,args);
|
||||
} else if (!strcasecmp(c, "IM_IN")) {
|
||||
char *away, *message;
|
||||
int a = 0;
|
||||
use_handler(TOC_RAW_HANDLE,TOC_IM_IN,raw);
|
||||
c = strtok(NULL,":");
|
||||
away = strtok(NULL,":");
|
||||
|
||||
message = away;
|
||||
|
||||
while(*message && (*message != ':'))
|
||||
message++;
|
||||
|
||||
message++;
|
||||
|
||||
if (!strncasecmp(away, "T", 1))
|
||||
a = 1;
|
||||
|
||||
if ( serv_got_im(c, message,a) > 0 ) {
|
||||
numargs = 3;
|
||||
args = (char **) malloc(sizeof(char *)*numargs);
|
||||
args[0] = strdup(c);
|
||||
args[1] = strdup(message);
|
||||
args[2] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_IM_IN,args);
|
||||
}
|
||||
} else if (!strcasecmp(c, "GOTO_URL")) {
|
||||
char *name;
|
||||
char *url;
|
||||
|
||||
char tmp[256];
|
||||
|
||||
use_handler(TOC_RAW_HANDLE,TOC_GOTO_URL,raw);
|
||||
name = strtok(NULL, ":");
|
||||
url = strtok(NULL, ":");
|
||||
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "http://%s:%d/%s", toc_addy, aim_port, url);
|
||||
/* fprintf(stdout, "Name: %s\n%s\n", name, url);
|
||||
printf("%s", grab_url(tmp));*/
|
||||
|
||||
numargs = 2;
|
||||
args = (char **) malloc(sizeof(char *)*numargs);
|
||||
args[0] = strdup(tmp);
|
||||
args[1] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_GOTO_URL,args);
|
||||
/* statusprintf("GOTO_URL: %s","tmp"); */
|
||||
} else if (!strcasecmp(c, "EVILED")) {
|
||||
int lev;
|
||||
char *name = NULL;
|
||||
char *levc;
|
||||
|
||||
use_handler(TOC_RAW_HANDLE,TOC_EVILED,raw);
|
||||
levc = strtok(NULL, ":");
|
||||
sscanf(levc, "%d", &lev);
|
||||
name = strtok(NULL, ":");
|
||||
|
||||
toc_debug_printf("evil: %s | %d\n", name, lev);
|
||||
|
||||
numargs = 3;
|
||||
my_evil = lev;
|
||||
args = (char **) malloc(sizeof(char *)*numargs);
|
||||
if ( name != NULL )
|
||||
args[0] = strdup(name);
|
||||
else
|
||||
args[0] = NULL;
|
||||
args[1] = strdup(levc);
|
||||
args[2] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_EVILED,args);
|
||||
|
||||
} else if (!strcasecmp(c, "CHAT_JOIN")) {
|
||||
char *name,*idc;
|
||||
int id;
|
||||
|
||||
use_handler(TOC_RAW_HANDLE,TOC_CHAT_JOIN,raw);
|
||||
idc = strtok(NULL, ":");
|
||||
sscanf(idc, "%d", &id);
|
||||
name = strtok(NULL, ":");
|
||||
serv_got_joined_chat(id, name);
|
||||
numargs = 3;
|
||||
args = (char **) malloc(sizeof(char *)*numargs);
|
||||
args[0] = strdup(idc);
|
||||
args[1] = strdup(name);
|
||||
args[2] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_CHAT_JOIN,args);
|
||||
} else if (!strcasecmp(c, "DIR_STATUS")) {
|
||||
char *status;
|
||||
use_handler(TOC_RAW_HANDLE,TOC_DIR_STATUS,raw);
|
||||
status = strtok(NULL,":");
|
||||
numargs = 2;
|
||||
args = (char **) malloc(sizeof(char *)*numargs);
|
||||
args[0] = strdup(status);
|
||||
args[1] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_DIR_STATUS,args);
|
||||
} else if (!strcasecmp(c, "CHAT_UPDATE_BUDDY")) {
|
||||
int id;
|
||||
char *in,*idc;
|
||||
char *buddy;
|
||||
LLE t;
|
||||
struct buddy_chat *b = NULL;
|
||||
|
||||
use_handler(TOC_RAW_HANDLE,TOC_CHAT_UPDATE_BUDDY,raw);
|
||||
idc = strtok(NULL, ":");
|
||||
sscanf(idc, "%d", &id);
|
||||
|
||||
in = strtok(NULL, ":");
|
||||
|
||||
for ( TLL(buddy_chats,t) ) {
|
||||
b = (struct buddy_chat *)t->data;
|
||||
if (id == b->id)
|
||||
break;
|
||||
b = NULL;
|
||||
}
|
||||
|
||||
if (!b)
|
||||
return -2;
|
||||
|
||||
|
||||
if (!strcasecmp(in, "T")) {
|
||||
while((buddy = strtok(NULL, ":")) != NULL) {
|
||||
/*
|
||||
* Fuxin aim causes a problem here
|
||||
*/
|
||||
AddToLL(b->in_room, buddy,NULL);
|
||||
if ( b->init_chat ) {
|
||||
args = (char **) malloc(sizeof(char *)*3);
|
||||
args[0] = strdup(b->name);
|
||||
args[1] = strdup(buddy);
|
||||
args[2] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_BUDDY_JOIN_CHAT,args);
|
||||
free(args[0]); free(args[1]); free(args); args = NULL;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* init_chat is so that the user doenst get flooded
|
||||
* with user joined chat when he first joins a chat
|
||||
*/
|
||||
b->init_chat = 1;
|
||||
} else {
|
||||
while((buddy = strtok(NULL, ":")) != NULL) {
|
||||
RemoveFromLLByKey(b->in_room, buddy);
|
||||
/*
|
||||
* Since we might get multiple leave/joins at once
|
||||
* we allocate & deallocate here
|
||||
*/
|
||||
args = (char **) malloc(sizeof(char *)*3);
|
||||
args[0] = strdup(b->name);
|
||||
args[1] = strdup(buddy);
|
||||
args[2] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_BUDDY_LEFT_CHAT,args);
|
||||
free(args[0]); free(args[1]); free(args); args = NULL;
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp(c, "CHAT_LEFT")) {
|
||||
char *idc;
|
||||
int id;
|
||||
|
||||
use_handler(TOC_RAW_HANDLE,TOC_CHAT_LEFT,raw);
|
||||
idc = strtok(NULL, ":");
|
||||
sscanf(idc, "%d", &id);
|
||||
|
||||
serv_got_chat_left(id);
|
||||
|
||||
numargs = 2;
|
||||
args = (char **) malloc(sizeof(char *)*numargs);
|
||||
args[0] = strdup(idc);
|
||||
args[1] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_CHAT_LEFT,args);
|
||||
} else if (!strcasecmp(c, "CHAT_IN")) {
|
||||
|
||||
int id, w;
|
||||
char *m,*idc;
|
||||
char *who, *whisper, *chan;
|
||||
struct buddy_chat *b;
|
||||
|
||||
use_handler(TOC_RAW_HANDLE,TOC_CHAT_IN,raw);
|
||||
idc = strtok(NULL, ":");
|
||||
sscanf(idc, "%d", &id);
|
||||
who = strtok(NULL, ":");
|
||||
whisper = strtok(NULL, ":");
|
||||
m = whisper;
|
||||
while(*m && (*m != ':')) m++;
|
||||
m++;
|
||||
|
||||
if (!strcasecmp(whisper, "T"))
|
||||
w = 1;
|
||||
else
|
||||
w = 0;
|
||||
|
||||
/* serv_got_chat_in(id, who, w, m); */
|
||||
b = buddy_chat_getbyid(id);
|
||||
if ( ! b ) {
|
||||
chan = (char *) malloc(50);
|
||||
strcpy(chan,"ERROR Couldn't lookup chan!");
|
||||
} else {
|
||||
chan = (char *) malloc(strlen(b->name)+1);
|
||||
strcpy(chan,b->name);
|
||||
}
|
||||
numargs = 6;
|
||||
args = (char **) malloc(sizeof(char *)*numargs);
|
||||
args[0] = strdup(idc);
|
||||
args[1] = strdup(who);
|
||||
args[2] = strdup(whisper);
|
||||
args[3] = strdup(m);
|
||||
/* Added arg to make things simple */
|
||||
args[4] = chan;
|
||||
args[5] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_CHAT_IN,args);
|
||||
} else if (!strcasecmp(c, "CHAT_INVITE")) {
|
||||
char *name;
|
||||
char *who;
|
||||
char *message,*idc;
|
||||
int id, *pid;
|
||||
|
||||
use_handler(TOC_RAW_HANDLE,TOC_CHAT_INVITE,raw);
|
||||
name = strtok(NULL, ":");
|
||||
idc = strtok(NULL, ":");
|
||||
sscanf(idc, "%d", &id);
|
||||
who = strtok(NULL, ":");
|
||||
message = strtok(NULL, ":");
|
||||
/* serv_got_chat_invite(name, id, who, message); */
|
||||
pid = (int *) malloc(sizeof(int));
|
||||
*pid = id;
|
||||
AddToLL(invited_chats,name,pid);
|
||||
numargs = 5;
|
||||
args = (char **) malloc(sizeof(char *)*numargs);
|
||||
args[0] = strdup(name);
|
||||
args[1] = strdup(idc);
|
||||
args[2] = strdup(who);
|
||||
args[3] = strdup(message);
|
||||
args[4] = NULL;
|
||||
use_handler(TOC_HANDLE,TOC_CHAT_INVITE,args);
|
||||
} else {
|
||||
toc_debug_printf("don't know what to do with %s\n", c);
|
||||
}
|
||||
free(dup);
|
||||
free(buf);
|
||||
if ( args != NULL ) {
|
||||
int x;
|
||||
/* toc_debug_printf("\nGOING TO FREE!: numargs = %d",numargs); */
|
||||
for (x=0;x< numargs; x++)
|
||||
if ( args[x] != NULL ) {
|
||||
/* toc_debug_printf("freeing %d",x); */
|
||||
free(args[x]);
|
||||
}
|
||||
/* toc_debug_printf(""); */
|
||||
free(args);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *toc_wait_config()
|
||||
{
|
||||
/* Waits for configuration packet, returning the contents of the packet */
|
||||
static char buf[BUF_LEN];
|
||||
int res;
|
||||
res = wait_reply(buf, sizeof(buf));
|
||||
if (res < 0)
|
||||
return NULL;
|
||||
if (state != STATE_CONFIG) {
|
||||
toc_debug_printf("State should be %d, but is %d instead\n",STATE_CONFIG, state);
|
||||
return NULL;
|
||||
}
|
||||
/* At this point, it's time to setup automatic handling of incoming packets */
|
||||
state = STATE_ONLINE;
|
||||
|
||||
// inpa = gdk_input_add(toc_fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, toc_callback, NULL);
|
||||
toc_add_input_stream(toc_fd,&toc_callback);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void parse_toc_buddy_list(char *config)
|
||||
{
|
||||
char *c;
|
||||
char current[256];
|
||||
char *name;
|
||||
LL bud = CreateLL();
|
||||
|
||||
/* skip "CONFIG:" (if it exists)*/
|
||||
|
||||
c = strncmp(config + sizeof(struct sflap_hdr),"CONFIG:",strlen("CONFIG:"))?
|
||||
strtok(config, "\n"):
|
||||
strtok(config + sizeof(struct sflap_hdr)+strlen("CONFIG:"), "\n");
|
||||
|
||||
do {
|
||||
if (c == NULL)
|
||||
break;
|
||||
if (*c == 'g') {
|
||||
strncpy(current,c+2, sizeof(current));
|
||||
add_group(current);
|
||||
} else if (*c == 'b') {
|
||||
add_buddy(current, c+2);
|
||||
AddToLL(bud, c+2, NULL);
|
||||
} else if (*c == 'p') {
|
||||
name = malloc(strlen(c+2) + 2);
|
||||
snprintf(name, strlen(c+2) + 1, "%s", c+2);
|
||||
AddToLL(permit, name, NULL);
|
||||
} else if (*c == 'd') {
|
||||
name = malloc(strlen(c+2) + 2);
|
||||
snprintf(name, strlen(c+2) + 1, "%s", c+2);
|
||||
AddToLL(deny, name,NULL);
|
||||
} else if (*c == 'm') {
|
||||
sscanf(c + strlen(c) - 1, "%d", &permdeny);
|
||||
if (permdeny == 0)
|
||||
permdeny = PERMIT_PERMITALL;
|
||||
}
|
||||
} while ((c=strtok(NULL,"\n")));
|
||||
|
||||
serv_add_buddies(bud);
|
||||
FreeLL(bud);
|
||||
serv_set_permit_deny();
|
||||
}
|
||||
|
||||
int toc_signoff() {
|
||||
/* Leaking memory like a MOFO */
|
||||
FreeLL(groups);
|
||||
FreeLL(buddy_chats);
|
||||
FreeLL(invited_chats);
|
||||
FreeLL(permit);
|
||||
FreeLL(deny);
|
||||
deny = groups = permit = buddy_chats = invited_chats = NULL;
|
||||
toc_debug_printf("LEAKING MEMORY LIKE A BITCH in toc_signoff!");
|
||||
|
||||
serv_close();
|
||||
toc_msg_printf(TOC_CONNECT_MSGS,"%s signed off",aim_username);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void toc_build_config(char *s, int len)
|
||||
{
|
||||
struct group *g;
|
||||
struct buddy *b;
|
||||
LLE t,t1;
|
||||
LL mem;
|
||||
|
||||
int pos=0;
|
||||
toc_debug_printf("FIX this permdeny hack shit!");
|
||||
|
||||
if (!permdeny)
|
||||
permdeny = PERMIT_PERMITALL;
|
||||
pos += snprintf(&s[pos], len - pos, "m %d\n", permdeny);
|
||||
|
||||
/* Create Buddy List */
|
||||
for ( TLL(groups,t) ) {
|
||||
g = (struct group *)t->data;
|
||||
pos += snprintf(&s[pos], len - pos, "g %s\n", g->name);
|
||||
mem = g->members;
|
||||
for ( TLL(mem,t1) ) {
|
||||
b = (struct buddy *)t1->data;
|
||||
pos += snprintf(&s[pos], len - pos, "b %s\n", b->name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create Permit and Deny Lists */;
|
||||
for ( TLL(permit,t) ) {
|
||||
toc_debug_printf("permit: added %s\n",(char *)t->key);
|
||||
pos += snprintf(&s[pos], len - pos, "p %s\n", (char *)t->key);
|
||||
}
|
||||
for ( TLL(deny,t) ) {
|
||||
toc_debug_printf("deny: added %s\n",(char *)t->key);
|
||||
pos += snprintf(&s[pos], len - pos, "d %s\n", (char *)t->key);
|
||||
}
|
||||
}
|
||||
|
||||
void translate_toc_error_code(char *c) {
|
||||
|
||||
int no = atoi(c);
|
||||
char *w = strtok(NULL, ":");
|
||||
char buf[256];
|
||||
|
||||
switch ( no ) {
|
||||
case 901:
|
||||
snprintf(buf, sizeof(buf), "%s not currently logged in.", w);
|
||||
break;
|
||||
case 902:
|
||||
snprintf(buf, sizeof(buf), "Warning of %s not allowed.", w);
|
||||
break;
|
||||
case 903:
|
||||
snprintf(buf, sizeof(buf), "A message has been dropped, you are exceeding the server speed limit.");
|
||||
break;
|
||||
case 950:
|
||||
snprintf(buf, sizeof(buf), "Chat in %s is not available.", w);
|
||||
break;
|
||||
case 960:
|
||||
snprintf(buf, sizeof(buf), "You are sending messages too fast to %s.", w);
|
||||
break;
|
||||
case 961:
|
||||
snprintf(buf, sizeof(buf), "You missed an IM from %s because it was too big.", w);
|
||||
break;
|
||||
case 962:
|
||||
snprintf(buf, sizeof(buf), "You missed an IM from %s because it was sent too fast.", w);
|
||||
break;
|
||||
case 970:
|
||||
snprintf(buf, sizeof(buf), "Failure.");
|
||||
break;
|
||||
case 971:
|
||||
snprintf(buf, sizeof(buf), "Too many matches.");
|
||||
break;
|
||||
case 972:
|
||||
snprintf(buf, sizeof(buf), "Need more qualifiers.");
|
||||
break;
|
||||
case 973:
|
||||
snprintf(buf, sizeof(buf), "Dir service temporarily unavailable.");
|
||||
break;
|
||||
case 974:
|
||||
snprintf(buf, sizeof(buf), "Email lookup restricted.");
|
||||
break;
|
||||
case 975:
|
||||
snprintf(buf, sizeof(buf), "Keyword ignored.");
|
||||
break;
|
||||
case 976:
|
||||
snprintf(buf, sizeof(buf), "No keywords.");
|
||||
break;
|
||||
case 977:
|
||||
snprintf(buf, sizeof(buf), "User has no directory information.");
|
||||
/* snprintf(buf, sizeof(buf), "Language not supported."); */
|
||||
break;
|
||||
case 978:
|
||||
snprintf(buf, sizeof(buf), "Country not supported.");
|
||||
break;
|
||||
case 979:
|
||||
snprintf(buf, sizeof(buf), "Failure unknown: %s.", w);
|
||||
break;
|
||||
case 980:
|
||||
snprintf(buf, sizeof(buf), "Incorrect nickname or password.");
|
||||
break;
|
||||
case 981:
|
||||
snprintf(buf, sizeof(buf), "The service is temporarily unavailable.");
|
||||
break;
|
||||
case 982:
|
||||
snprintf(buf, sizeof(buf), "Your warning level is currently too high to log in.");
|
||||
break;
|
||||
case 983:
|
||||
snprintf(buf, sizeof(buf), "You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.");
|
||||
break;
|
||||
case 989:
|
||||
snprintf(buf, sizeof(buf), "An unknown signon error has occurred: %s.", w);
|
||||
break;
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "An unknown error, %d, has occured. Info: %s", no, w);
|
||||
}
|
||||
toc_msg_printf(TOC_TRANSLATED_ERROR,buf);
|
||||
return;
|
||||
}
|
||||
Reference in New Issue
Block a user