/*
* XmNap A Motif napster client
*
* Copyright (C) 2000 Mats Peterson
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Please send any comments/bug reports to
*
[email protected] (Mats Peterson)
*/
#include <Xm/Xm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "main.h"
#include "message.h"
#include "connect.h"
#include "command.h"
#include "chat.h"
#include "search.h"
#include "shared.h"
#include "msgbox.h"
#include "chnlist.h"
#include "hotlist.h"
#include "linklist.h"
#include "banlist.h"
#include "ullist.h"
#include "netutil.h"
XtInputId srvCB;
int srvSock, srvPort;
int srvConn = 0;
int reconnTimeOut = 15;
static int reconnId = 0;
static String Redirect(String metaServer, int metaPort, int first,
int *connRet)
{
int i, r, metaSock;
String tmp = XtMalloc(4096);
char c;
sprintf(tmp, "Trying metaserver %s...", metaServer);
if (first)
SimpleMsg(tmp);
else
ShowMiscInfo(tmp, 0);
if ((*connRet = ConnSock(metaServer, metaPort, &metaSock)))
goto error;
memset(tmp, 0, strlen(tmp));
i = 0;
while (1) {
while (((r = read(metaSock, &c, 1)) == -1) && (errno == EAGAIN))
usleep(1000);
if (r <= 0) {
if (r == -1) {
close(metaSock);
ErrMsg(strerror(r));
goto error;
}
break;
}
if (c == '\n')
break;
tmp[i++] = c;
}
close(metaSock);
if (first)
SimpleMsgRemove();
return tmp;
error:
XtFree(tmp);
return NULL;
}
void Connect(String server, int port, int meta, int first)
{
char loginMsg[256];
int realPort;
String tmp, srvString;
XmString xms;
static int connInProgress = 0;
int connRet;
if (srvConn)
return;
if (connInProgress) {
ErrMsg("Connect already in progress");
return;
}
connInProgress = 1;
if (reconnId) {
XtRemoveTimeOut(reconnId);
reconnId = 0;
}
if (curServer.name)
XtFree(curServer.name);
curServer.name = XtNewString(server);
curServer.port = port;
curServer.meta = meta;
if (realSrvName) {
XtFree(realSrvName);
realSrvName = NULL;
}
if (meta) {
if (! (srvString = Redirect(server, port, first, &connRet)))
goto error;
if ((! strlen(srvString)) || (! strchr(srvString, ':'))) {
ErrMsg("Got invalid string from metaserver");
XtFree(srvString);
goto error;
}
tmp = strtok(srvString, ":");
realSrvName = XtNewString(tmp);
realPort = atoi(strtok(NULL, "\0"));
XtFree(srvString);
} else {
realSrvName = XtNewString(server);
realPort = port;
}
tmp = XtMalloc(sizeof("Connecting to ") +
strlen(realSrvName) + sizeof("...") + 1);
sprintf(tmp, "Connecting to %s...", realSrvName);
if (first)
SimpleMsg(tmp);
else
ShowMiscInfo(tmp, 0);
XtFree(tmp);
if ((connRet = ConnSock(realSrvName, realPort, &srvSock)))
goto error;
srvCB = XtAppAddInput(appCon, srvSock, (XtPointer)XtInputReadMask,
(XtInputCallbackProc)GetMsg, NULL);
if (! userInfo.registered) {
if (SendMsg(MSG_CLIENT_REGISTER, userInfo.userName)) {
Disconnect(strerror(errno));
goto error;
}
} else {
sprintf(loginMsg, "%s %s %04d \"%s\" %d",
userInfo.userName, userInfo.passWord,
userInfo.dataPort, client, userInfo.linkType);
if (SendMsg(MSG_CLIENT_LOGIN, loginMsg)) {
Disconnect(strerror(errno));
goto error;
}
}
XtVaSetValues(mainBtn[0],
XmNlabelPixmap, mainPix[6],
XmNarmPixmap, armPix[6],
NULL);
xms = XmStringCreateLocalized("Disc");
XtVaSetValues(mainLbl[0], XmNlabelString, xms, NULL);
XmStringFree(xms);
srvConn = 1;
error:
connInProgress = 0;
if (first)
SimpleMsgRemove();
#ifdef AUTORECONNECT_ON_REFUSED
if (connRet == -2)
WaitReconnect();
#endif
}
void DoLoginStuff(XtPointer closure, XtIntervalId *id)
{
NotifySharedFiles();
SendHotList();
SendAutoCommands();
}
static void Reconnect(XtPointer clientData, XtInputId *id)
{
String tmp;
tmp = XtNewString(curServer.name);
Connect(tmp, curServer.port, curServer.meta, 0);
XtFree(tmp);
}
void WaitReconnect(void)
{
Disconnect("");
ShowMiscInfo("Waiting...", 0);
reconnId = XtAppAddTimeOut(appCon, reconnTimeOut * 1000,
(XtTimerCallbackProc)Reconnect, (XtPointer)NULL);
}
void Disconnect(String err)
{
XmString xms;
if (! srvConn)
return;
if (strlen(err))
ErrMsg(err);
PartAllChannels();
CloseAllPrivs();
ClearOnLineList();
DestroyResultsWin();
DestroyLinksWin();
DestroyUlListWin();
DestroyChnListWin();
DestroyBanListWin();
DestroyOnLineListWin();
XtRemoveInput(srvCB);
close(srvSock);
XtVaSetValues(mainBtn[0],
XmNlabelPixmap, mainPix[0],
XmNarmPixmap, armPix[0],
NULL);
xms = XmStringCreateLocalized("Connect");
XtVaSetValues(mainLbl[0], XmNlabelString, xms, NULL);
XmStringFree(xms);
xms = XmStringCreateLocalized("");
XtVaSetValues(statusLbl1, XmNlabelString, xms, NULL);
XtVaSetValues(statusLbl2, XmNlabelString, xms, NULL);
XmStringFree(xms);
srvConn = 0;
}