Update of /cvsroot/planeshift/planeshift/src/updater/client
In directory usw-pr-cvs1:/tmp/cvs-serv21470/src/updater/client
Modified Files:
config.xml main.cpp Makefile.am
Added Files:
uclient.cpp uclient.h untgz.c
Removed Files:
uconnect.cpp uconnect.h
Log Message:
Added support for XML file list sent by the server.
Added untgz function for the patch files.
Using MD5 instead of CRC32
--- NEW FILE: uclient.cpp ---
/*
* uclient.cpp by Marc-Andre R. Courtois <courtoma@...>
*
* Copyright (C) 2001 PlaneShift Team (info@...,
* http://www.planeshift.it)
*
* 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 (version 2 of the License)
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include <config.h>
#include <csutil/csstring.h>
#include <csutil/csmd5.h>
#include <util/psxmlparser.h>
#include <fstream.h>
#include <zlib.h>
#include "../common/release.h"
#include "../common/packet.h"
#include "../common/util.h"
#include "../common/net.h"
#include "uclient.h"
extern bool bRunning;
extern "C" {
int tar OF((gzFile, int, int, int, char **));
}
static void printHash(const unsigned long amount, const unsigned long total,
unsigned long progressCurrent, const unsigned long progressTotal);
static int hashesPrinted = 0;
// create the client and load configuration
uClient::uClient(sConfig *config)
{
bRunning = true;
if(U_DEBUG) cout << "Creating class: uClient (" << hex << this << dec << ")" << endl;
_config = config;
_sock = 0;
tptr = NULL;
// start the thread for this class
tptr = task::create(thread_main, (void*)this);
if(!tptr)
{
cout << "Error while creating client thread." << endl;
bRunning = false;
}
if(U_DEBUG) cout << "Creating process (" << hex << tptr << dec << ")" << endl;
}
// destroy stuff
uClient::~uClient()
{
if(U_DEBUG) cout << "Destroying class: uClient (" << hex << this << dec << ")" << endl;
if(_sock) SOCK_CLOSE(_sock);
exitSocket();
// kill the process
if(U_DEBUG) cout << "Killing process (" << hex << tptr << dec << ")" << endl;
if(tptr)
{
tptr->stop();
delete tptr;
}
bRunning = false;
}
// initialize the server socket
bool uClient::init(void)
{
hostent *lpHostEntry;
struct in_addr iaHost;
// Initialize socket library
if(initSocket())
{
// Error, cleanup and return error number
cout << "Error while loading socket library." << endl;
return 1;
}
if(U_DEBUG) cout << "Socket library initialized." << endl;
// get the server address
iaHost.s_addr = inet_addr(_config->addr.GetData());
if(iaHost.s_addr == INADDR_NONE)
{
// wasnt ip, assume name
lpHostEntry = gethostbyname(_config->addr.GetData());
}
else
{
// it was a valid ip
lpHostEntry = gethostbyaddr((const char*)&iaHost, sizeof(struct in_addr), AF_INET);
}
if(lpHostEntry == NULL)
{
cout << "Error getting host <" << _config->addr.GetData() << ">" << endl;
return 1;
}
// fill in the address structure
_sockaddr.sin_family = AF_INET;
_sockaddr.sin_addr = *((struct in_addr*)*lpHostEntry->h_addr_list);
_sockaddr.sin_port = htons(_config->port);
return 0;
}
bool uClient::open(packet & p, eRequest r, csString filename)
{
// Create ip stream socket to listen
_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(_sock == 0)
{
return 1;
}
// open the connection
if(connect(_sock, (LPSOCKADDR)&_sockaddr, sizeof(sockaddr)) != 0)
{
cout << "Error while connecting to host <" << _config->addr.GetData() << ">:" << strerror(errno) << endl;
return 1;
}
// send a login request
p.type = LOGIN_REQUEST;
strcpy(p.login_request.version, UC_VERSION);
p.login_request.request = r;
p.login_request.platform = _config->platform;
strcpy(p.login_request.param, filename.GetData());
if(U_DEBUG) cout << "Out: " << Packet2Str(p).GetData() << endl;
sendall(_sock, (char*)(void*)&p, PACKET_SIZE);
// get login reply
recvall(_sock, (char*)(void*)&p, PACKET_SIZE);
if(U_DEBUG) cout << "In: " << Packet2Str(p).GetData() << endl;
if(p.type == LOGIN_REPLY)
{
if(p.login_reply.reply == GET_NEW_UPDATER)
{
cout << "Your updater is out of date. Please get the new version from http://www.planeshift.it/" << endl;
return 1;
}
else if(p.login_reply.reply == CUSTOM_ERROR)
{
cout << "Server error: " << p.login_reply.param << endl;
return 1;
}
else if(p.login_reply.reply == SENDING_LIST || p.login_reply.reply == SENDING_FILE)
{
return 0;
}
else if(p.login_reply.reply == FILE_NOT_FOUND)
{
cout << "Server is unable to find the file. Contact the admin." << endl;
return 1;
}
else
{
cout << "Error while recieving login reply from server. Terminating." << endl;
return 1;
}
}
else
{
cout << "Error while recieving login reply from server. Terminating." << endl;
return 1;
}
return 0;
}
void uClient::end(void)
{
packet p;
// send terminate packet
p.type = TERMINATE;
if(U_DEBUG) cout << "Out: " << Packet2Str(p).GetData() << endl;
sendall(_sock, (char*)(void*)&p, PACKET_SIZE);
// close the socket
SOCK_CLOSE(_sock);
}
bool uClient::request_list(csString & file_buffer)
{
packet p;
unsigned long filesize;
char buffer[4096];
if(open(p, LIST_REQUEST, "")) return 1;
// prepare to get file_list.xml
filesize = atol(p.login_reply.param);
// tell server we're ready for the file
p.type = WAITING;
if(U_DEBUG) cout << "Out: " << Packet2Str(p).GetData() << endl;
sendall(_sock, (char*)(void*)&p, PACKET_SIZE);
//***************************** FILE TRANSFER PROGRESS **********************************
unsigned long total = 0;
unsigned long left = filesize;
unsigned long progress = 0, last = 0;
cout << "Receiving file list (" << filesize << ")\n"
<< "\tProgress -[ ";
cout.flush();
hashesPrinted = 0;
while(total < filesize)
{
if(left < 4096)
{
recvall(_sock, buffer, left);
file_buffer.Append(buffer, left);
total += left;
left -= left;
}
else
{
recvall(_sock, buffer, 4096);
file_buffer.Append(buffer, 4096);
total += 4096;
left -= 4096;
}
// do progress bar
// *** PARTIALLY WORKING
printHash(25, 25, total, filesize);
}
cout << endl;
//***************************** FILE TRANSFER PROGRESS **********************************
end();
return 0;
}
bool uClient::request_file(csString filename)
{
packet p;
unsigned long filesize;
ofstream os;
char buffer[4096];
if(open(p, FILE_REQUEST, filename)) return 1;
// prepare to get file
filesize = atol(p.login_reply.param);
// open the file
os.open("temp.tar.gz", ios::out|ios::binary);
// tell server we're ready for the file
p.type = WAITING;
if(U_DEBUG) cout << "Out: " << Packet2Str(p).GetData() << endl;
sendall(_sock, (char*)(void*)&p, PACKET_SIZE);
//***************************** FILE TRANSFER PROGRESS **********************************
unsigned long total = 0;
unsigned long left = filesize;
unsigned long progress = 0, last = 0;
cout << "Receiving: " << filename << " (" << filesize << ")\n"
<< "\tProgress -[ ";
cout.flush();
hashesPrinted = 0;
while(total < filesize)
{
if(left < 4096)
{
recvall(_sock, buffer, left);
os.write(buffer, left);
total += left;
left -= left;
}
else
{
recvall(_sock, buffer, 4096);
os.write(buffer, 4096);
total += 4096;
left -= 4096;
}
// do progress bar
// *** PARTIALLY WORKING
printHash(25, 25, total, filesize);
}
cout << endl;
//***************************** FILE TRANSFER PROGRESS **********************************
// close the file
os.close();
end();
// install the file
gzFile f;
f = gzopen("temp.tar.gz", "rb");
if(f != NULL)
{
tar(f, 0, 0, 0, NULL);
}
if(remove("temp.tar.gz") == -1)
{
cout << "Error while deleting temp.tar.gz." << endl;
}
return 0;
}
void task_proc uClient::thread_main(void *arg)
{
uClient *This=(uClient *) arg;
csString list_buffer;
list<sFileInfo> fil;
// initialize the network
if(!This->init())
{
if(!This->request_list(list_buffer))
{
ParseFileList(list_buffer, fil);
CompareFiles(fil);
if(!fil.empty())
{
list<sFileInfo>::iterator i = fil.begin();
while(i != fil.end())
{
This->request_file((*i).name);
i++;
}
fil.clear();
}
else
cout << "No new updates available." << endl;
}
}
bRunning = false;
}
char * GetMD5(void * buffer, int len)
{
char cachename[33];
csMD5::Digest digest = csMD5::Encode(buffer, len);
sprintf (cachename,
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
digest.data[0], digest.data[1], digest.data[2], digest.data[3],
digest.data[4], digest.data[5], digest.data[6], digest.data[7],
digest.data[8], digest.data[9], digest.data[10], digest.data[11],
digest.data[12], digest.data[13], digest.data[14], digest.data[15]);
return cachename;
}
void ParseFileList(csString & buffer, list<sFileInfo> & fil)
{
psXMLString mainString;
psXMLString sectionString;
int startTag;
sFileInfo fi;
// filling the xml main string
mainString.Append(buffer);
int startSection = mainString.FindTag("file_list");
mainString.GetTagSection(startSection, "file_list", sectionString);
// Read in all the file infos
cout << "Parsing XML file list.. please wait" << endl;
startTag = sectionString.FindTag("file", 1);
do
{
psXMLTag tag(sectionString, startTag);
csString tmp;
tag.GetTagParm("path", fi.name);
tag.GetTagParm("size", tmp);
fi.size = atol(tmp.GetData());
tag.GetTagParm("md5", tmp);
strcpy(fi.md5, tmp.GetData());
fil.push_front(fi);
startTag = sectionString.FindTag("file", startTag+1);
} while ( startTag != -1 );
}
void CompareFiles(list<sFileInfo> & fil)
{
ifstream is;
unsigned long filesize;
char *buffer;
csString abs_path = "./";
list<sFileInfo>::iterator i = fil.begin();
cout << "Comparing local files with server file list... please wait." << endl;
while(i != fil.end())
{
abs_path.Append((*i).name);
if(U_DEBUG) cout << "Checking " << abs_path.GetData() << ": ";
is.open(abs_path.GetData(), ios::in|ios::binary);
if(is)
{
// get the size of the file
is.seekg(0, ios::end);
filesize = is.tellg();
is.seekg(0, ios::beg);
buffer = new char[filesize];
is.read(buffer, filesize);
if(strcmp((*i).md5, GetMD5((void*)buffer, filesize)) == 0)
{
i = fil.erase(i);
if(U_DEBUG) cout << "MD5 match." << endl;
}
else
{
i++;
if(U_DEBUG) cout << "MD5 different." << endl;
}
delete [] buffer;
is.close();
}
else
{
i++;
if(U_DEBUG) cout << "file doesnt exist." << endl;
}
abs_path.Clear();
abs_path += "./";
}
}
static void printHash(const unsigned long amount, const unsigned long total,
unsigned long progressCurrent, const unsigned long progressTotal)
{
int hashesNeeded;
int hashesTotal = 50;
if (isatty (STDOUT_FILENO))
hashesTotal = 44;
if (hashesPrinted != hashesTotal) {
hashesNeeded = hashesTotal * (total ? (((float) amount) / total) : 1);
while (hashesNeeded > hashesPrinted) {
if (isatty (STDOUT_FILENO)) {
int i;
for (i = 0; i < hashesPrinted; i++) (void) putchar ('#');
for (; i < hashesTotal; i++) (void) putchar (' ');
fprintf(stdout, "(%3d%%)",
(int)(100 * (total ? (((float) amount) / total) : 1)));
for (i = 0; i < (hashesTotal + 6); i++) (void) putchar ('\b');
} else
fprintf(stdout, "#");
hashesPrinted++;
}
(void) fflush(stdout);
hashesPrinted = hashesNeeded;
if (hashesPrinted == hashesTotal) {
int i;
progressCurrent++;
if (isatty(STDOUT_FILENO)) {
for (i = 1; i < hashesPrinted; i++) (void) putchar ('#');
fprintf(stdout, " [%3d%%]", (int)(100 * (progressTotal ?
(((float) progressCurrent) / progressTotal) : 1)));
}
fprintf(stdout, "\n");
}
(void) fflush(stdout);
}
}
--- NEW FILE: uclient.h ---
/*
* uclient.h by Marc-Andre R. Courtois <courtoma@...>
*
* Copyright (C) 2001 PlaneShift Team (info@...,
* http://www.planeshift.it)
*
* 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 (version 2 of the License)
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include <sal/task.h>
#include <list>
#include "../common/util.h"
#include "../common/packet.h"
// Include platform specific socket settings
#ifdef USE_WINSOCK
# include "net/sockwin.h"
#endif
#ifdef USE_UNISOCK
# include "net/sockuni.h"
#endif
#ifndef __UCLIENT_H__
// Client configuration structure
struct sConfig {
int port;
csString addr;
char list_md5[33];
ePlatform platform;
};
// Server class
class uClient
{
public:
uClient(sConfig *config);
~uClient();
bool request_list(csString & file_buffer);
bool request_file(csString filename);
private:
bool init(void);
static void task_proc thread_main(void *arg);
void end(void);
bool open(packet & p, eRequest r, csString filename);
private:
sConfig *_config; // client configuration
SOCKET _sock; // socket of the client
SOCKADDR_IN _sockaddr;// address struct
task *tptr;
};
char * GetMD5(void * buffer, int len);
void ParseFileList(csString & buffer, list<sFileInfo> & fil);
void CompareFiles(list<sFileInfo> & fil);
#define __UCLIENT_H__
#endif
--- NEW FILE: untgz.c ---
/*
* untgz.c -- Display contents and/or extract file from
* a gzip'd TAR file
* written by "Pedro A. Aranda Guti\irrez" <paag@...>
* adaptation to Unix by Jean-loup Gailly <jloup@...>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#ifdef unix
# include <unistd.h>
#else
# include <direct.h>
# include <io.h>
#endif
#include <zlib.h>
#ifdef WIN32
# ifndef F_OK
# define F_OK (0)
# endif
# ifdef _MSC_VER
# define mkdir(dirname,mode) _mkdir(dirname)
# define strdup(str) _strdup(str)
# define unlink(fn) _unlink(fn)
# define access(path,mode) _access(path,mode)
# else
# define mkdir(dirname,mode) _mkdir(dirname)
# endif
#else
# include <utime.h>
#endif
/* Values used in typeflag field. */
#define REGTYPE '0' /* regular file */
#define AREGTYPE '\0' /* regular file */
#define LNKTYPE '1' /* link */
#define SYMTYPE '2' /* reserved */
#define CHRTYPE '3' /* character special */
#define BLKTYPE '4' /* block special */
#define DIRTYPE '5' /* directory */
#define FIFOTYPE '6' /* FIFO special */
#define CONTTYPE '7' /* reserved */
#define BLOCKSIZE 512
struct tar_header
{ /* byte offset */
char name[100]; /* 0 */
char mode[8]; /* 100 */
char uid[8]; /* 108 */
char gid[8]; /* 116 */
char size[12]; /* 124 */
char mtime[12]; /* 136 */
char chksum[8]; /* 148 */
char typeflag; /* 156 */
char linkname[100]; /* 157 */
char magic[6]; /* 257 */
char version[2]; /* 263 */
char uname[32]; /* 265 */
char gname[32]; /* 297 */
char devmajor[8]; /* 329 */
char devminor[8]; /* 337 */
char prefix[155]; /* 345 */
/* 500 */
};
union tar_buffer {
char buffer[BLOCKSIZE];
struct tar_header header;
};
enum { TGZ_EXTRACT = 0, TGZ_LIST };
static char *TGZfname OF((const char *));
void TGZnotfound OF((const char *));
int getoct OF((char *, int));
char *strtime OF((time_t *));
int ExprMatch OF((char *,char *));
int makedir OF((char *));
int matchname OF((int,int,char **,char *));
void error OF((const char *));
int tar OF((gzFile, int, int, int, char **));
char *prog;
/* This will give a benign warning */
static char *TGZprefix[] = { "\0", ".tgz", ".tar.gz", ".tar", NULL };
/* Return the real name of the TGZ archive */
/* or NULL if it does not exist. */
static char *TGZfname OF((const char *fname))
{
static char buffer[1024];
int origlen,i;
strcpy(buffer,fname);
origlen = strlen(buffer);
for (i=0; TGZprefix[i]; i++)
{
strcpy(buffer+origlen,TGZprefix[i]);
if (access(buffer,F_OK) == 0)
return buffer;
}
return NULL;
}
/* error message for the filename */
void TGZnotfound OF((const char *fname))
{
int i;
fprintf(stderr,"%s : couldn't find ",prog);
for (i=0;TGZprefix[i];i++)
fprintf(stderr,(TGZprefix[i+1]) ? "%s%s, " : "or %s%s\n",
fname,
TGZprefix[i]);
exit(1);
}
/* help functions */
int getoct(char *p,int width)
{
int result = 0;
char c;
while (width --)
{
c = *p++;
if (c == ' ')
continue;
if (c == 0)
break;
result = result * 8 + (c - '0');
}
return result;
}
char *strtime (time_t *t)
{
struct tm *local;
static char result[32];
local = localtime(t);
sprintf(result,"%2d/%02d/%4d %02d:%02d:%02d",
local->tm_mday, local->tm_mon+1, local->tm_year+1900,
local->tm_hour, local->tm_min, local->tm_sec);
return result;
}
/* regular expression matching */
#define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
int ExprMatch(char *string,char *expr)
{
while (1)
{
if (ISSPECIAL(*expr))
{
if (*expr == '/')
{
if (*string != '\\' && *string != '/')
return 0;
string ++; expr++;
}
else if (*expr == '*')
{
if (*expr ++ == 0)
return 1;
while (*++string != *expr)
if (*string == 0)
return 0;
}
}
else
{
if (*string != *expr)
return 0;
if (*expr++ == 0)
return 1;
string++;
}
}
}
/* recursive make directory */
/* abort if you get an ENOENT errno somewhere in the middle */
/* e.g. ignore error "mkdir on existing directory" */
/* */
/* return 1 if OK */
/* 0 on error */
int makedir (char *newdir)
{
char *buffer = strdup(newdir);
char *p;
int len = strlen(buffer);
if (len <= 0) {
free(buffer);
return 0;
}
if (buffer[len-1] == '/') {
buffer[len-1] = '\0';
}
if (mkdir(buffer, 0775) == 0)
{
free(buffer);
return 1;
}
p = buffer+1;
while (1)
{
char hold;
while(*p && *p != '\\' && *p != '/')
p++;
hold = *p;
*p = 0;
if ((mkdir(buffer, 0775) == -1) && (errno == ENOENT))
{
fprintf(stderr,"%s: couldn't create directory %s\n",prog,buffer);
free(buffer);
return 0;
}
if (hold == 0)
break;
*p++ = hold;
}
free(buffer);
return 1;
}
int matchname (int arg,int argc,char **argv,char *fname)
{
if (arg == argc) /* no arguments given (untgz tgzarchive) */
return 1;
while (arg < argc)
if (ExprMatch(fname,argv[arg++]))
return 1;
return 0; /* ignore this for the moment being */
}
/* Tar file list or extract */
int tar (gzFile in,int action,int arg,int argc,char **argv)
{
union tar_buffer buffer;
int len;
int err;
int getheader = 1;
int remaining = 0;
FILE *outfile = NULL;
char fname[BLOCKSIZE];
time_t tartime;
if (action == TGZ_LIST)
printf(" day time size file\n"
" ---------- -------- --------- -------------------------------------\n");
while (1)
{
len = gzread(in, &buffer, BLOCKSIZE);
if (len < 0)
error (gzerror(in, &err));
/*
* Always expect complete blocks to process
* the tar information.
*/
if (len != BLOCKSIZE)
error("gzread: incomplete block read");
/*
* If we have to get a tar header
*/
if (getheader == 1)
{
/*
* if we met the end of the tar
* or the end-of-tar block,
* we are done
*/
if ((len == 0) || (buffer.header.name[0]== 0)) break;
tartime = (time_t)getoct(buffer.header.mtime,12);
strcpy(fname,buffer.header.name);
switch (buffer.header.typeflag)
{
case DIRTYPE:
if (action == TGZ_LIST)
printf(" %s <dir> %s\n",strtime(&tartime),fname);
if (action == TGZ_EXTRACT)
makedir(fname);
break;
case REGTYPE:
case AREGTYPE:
remaining = getoct(buffer.header.size,12);
if (action == TGZ_LIST)
printf(" %s %9d %s\n",strtime(&tartime),remaining,fname);
if (action == TGZ_EXTRACT)
{
if ((remaining) && (matchname(arg,argc,argv,fname)))
{
outfile = fopen(fname,"wb");
if (outfile == NULL) {
/* try creating directory */
char *p = strrchr(fname, '/');
if (p != NULL) {
*p = '\0';
makedir(fname);
*p = '/';
outfile = fopen(fname,"wb");
}
}
fprintf(stderr,
"%s %s\n",
(outfile) ? "Extracting" : "Couldn't create",
fname);
}
else
outfile = NULL;
}
/*
* could have no contents
*/
getheader = (remaining) ? 0 : 1;
break;
default:
if (action == TGZ_LIST)
printf(" %s <---> %s\n",strtime(&tartime),fname);
break;
}
}
else
{
unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
if ((action == TGZ_EXTRACT) && (outfile != NULL))
{
if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
{
fprintf(stderr,"%s : error writing %s skipping...\n",prog,fname);
fclose(outfile);
unlink(fname);
}
}
remaining -= bytes;
if (remaining == 0)
{
getheader = 1;
if ((action == TGZ_EXTRACT) && (outfile != NULL))
{
#ifdef WIN32
HANDLE hFile;
FILETIME ftm,ftLocal;
SYSTEMTIME st;
struct tm localt;
fclose(outfile);
localt = *localtime(&tartime);
hFile = CreateFile(fname, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
st.wYear = (WORD)localt.tm_year+1900;
st.wMonth = (WORD)localt.tm_mon;
st.wDayOfWeek = (WORD)localt.tm_wday;
st.wDay = (WORD)localt.tm_mday;
st.wHour = (WORD)localt.tm_hour;
st.wMinute = (WORD)localt.tm_min;
st.wSecond = (WORD)localt.tm_sec;
st.wMilliseconds = 0;
SystemTimeToFileTime(&st,&ftLocal);
LocalFileTimeToFileTime(&ftLocal,&ftm);
SetFileTime(hFile,&ftm,NULL,&ftm);
CloseHandle(hFile);
outfile = NULL;
#else
struct utimbuf settime;
settime.actime = settime.modtime = tartime;
fclose(outfile);
outfile = NULL;
utime(fname,&settime);
#endif
}
}
}
}
if (gzclose(in) != Z_OK)
error("failed gzclose");
return 0;
}
/* int action = TGZ_EXTRACT;
gzFile *f;
f = gzopen(TGZfile,"rb");
if (f == NULL)
{
fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile);
return 1;
}
tar(f, action, arg, argc, argv);
*/
Index: config.xml
===================================================================
RCS file: /cvsroot/planeshift/planeshift/src/updater/client/config.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** config.xml 24 May 2002 01:09:03 -0000 1.1
--- config.xml 30 May 2002 07:11:30 -0000 1.2
***************
*** 1,5 ****
<updater_config>
<port>13330</port>
! <server>localhost</server>
! <list_crc></list_crc>
</updater_config>
--- 1,5 ----
<updater_config>
<port>13330</port>
! <server>the-wing.com</server>
! <list_md5></list_md5>
</updater_config>
Index: main.cpp
===================================================================
RCS file: /cvsroot/planeshift/planeshift/src/updater/client/main.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** main.cpp 24 May 2002 01:09:03 -0000 1.1
--- main.cpp 30 May 2002 07:11:30 -0000 1.2
***************
*** 21,63 ****
#include <fstream.h>
#include <csutil/csstring.h>
! #include <csutil/csmd5.h>
! #include "util/psxmlparser.h"
#include "../common/release.h"
#include "../common/packet.h"
! #include "uconnect.h"
! void LoadConfig(csString & addr, int & port);
! char * GetMD5(void * buffer, int len);
int main(int argc, char **argv)
{
! csString sAddr;
! int iPort;
! uConnect *uc;
// display program info
printf("PlaneShift MMORPG - %s [%s (%s)]\n\n", UC_NAME, UC_VERSION, U_BUILD);
! // load the config file
! LoadConfig(sAddr, iPort);
!
! uc = new uConnect(sAddr, iPort, X86_LINUX); // temp hardcode for platform
! // do stuff
! delete uc;
return 0;
}
! void LoadConfig(csString & addr, int & port)
{
! psXMLString mainString;
ifstream is;
char *buffer;
! // load file into buffer
! is.open("config.xml", ios::in|ios::binary);
// get filesize
--- 21,102 ----
#include <fstream.h>
#include <csutil/csstring.h>
! #include <csutil/cmdline.h>
! #include <util/psxmlparser.h>
#include "../common/release.h"
#include "../common/packet.h"
! #include "uclient.h"
! bool LoadConfig(sConfig & config, char *filename);
! void Help(void);
!
! bool bRunning;
int main(int argc, char **argv)
{
! csCommandLineParser *clp;
! sConfig config;
! char * filename = "config.xml";
! const char *val;
! uClient *uc;
// display program info
printf("PlaneShift MMORPG - %s [%s (%s)]\n\n", UC_NAME, UC_VERSION, U_BUILD);
! // get commandline options
! clp = new csCommandLineParser(argc, argv);
! if(clp->GetOption("help") || clp->GetOption("h"))
! {
! Help();
! return EXIT_SUCCESS;
! }
! // override default values
! if((val = clp->GetOption("config")) || (val = clp->GetOption("c"))) filename = csStrNew(val);
! if((val = clp->GetOption("port")) || (val = clp->GetOption("p"))) config.port = atoi(csStrNew(val));
! else config.port = 0;
! if((val = clp->GetOption("serv")) || (val = clp->GetOption("s"))) config.addr = csStrNew(val);
! else config.addr = "";
! // free the commandline parser
! delete clp;
! // load the config file
! if(!LoadConfig(config, filename))
! {
! // create the client
! uc = new uClient(&config);
+ // idle loop
+ while(bRunning)
+ {
+ // console stuff~
+ //if(getchar() == 'q') break;
+ }
+ }
! // free the client class
! if(uc)
! {
! delete uc;
! uc = NULL;
! }
return 0;
}
! bool LoadConfig(sConfig & config, char *filename)
{
! psXMLString mainString, tagString, sectionString;
! int startTag;
ifstream is;
char *buffer;
+
! // load file into buffer
! is.open(filename, ios::in|ios::binary);
!
! if(!is)
! {
! cout << "Error while trying to open file: " << filename << endl;
! return 1;
! }
// get filesize
***************
*** 78,113 ****
int startSection = mainString.FindTag("updater_config");
- psXMLString sectionString;
mainString.GetTagSection(startSection, "updater_config", sectionString);
! // get the port
! int startTag = sectionString.FindTag("port");
! psXMLString tagString;
! sectionString.GetWithinTagSection(startTag, "port", tagString);
! port = atoi(tagString.GetData());
! printf("Port: %i\n", port);
! // get server addr
! startTag = sectionString.FindTag("server");
! sectionString.GetWithinTagSection(startTag, "server", tagString);
! buffer = tagString.GetData();
! addr.Append(buffer, strlen(buffer));
! printf("Address: %s\n", addr.GetData());
! }
! char * GetMD5(void * buffer, int len)
! {
! char cachename[33];
! csMD5::Digest digest = csMD5::Encode(buffer, len);
! sprintf (cachename,
! "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
! digest.data[0], digest.data[1], digest.data[2], digest.data[3],
! digest.data[4], digest.data[5], digest.data[6], digest.data[7],
! digest.data[8], digest.data[9], digest.data[10], digest.data[11],
! digest.data[12], digest.data[13], digest.data[14], digest.data[15]);
! return cachename;
! }
\ No newline at end of file
--- 117,175 ----
int startSection = mainString.FindTag("updater_config");
mainString.GetTagSection(startSection, "updater_config", sectionString);
! // get the port if needed
! if(config.port == 0)
! {
! startTag = sectionString.FindTag("port");
! sectionString.GetWithinTagSection(startTag, "port", tagString);
! if(startTag != -1) config.port = atoi(tagString.GetData());
! }
! cout << "Port: " << config.port << endl;
! // get server addr if needed
! if(config.addr.IsEmpty())
! {
! startTag = sectionString.FindTag("server");
! sectionString.GetWithinTagSection(startTag, "server", tagString);
! buffer = tagString.GetData();
! if(startTag != -1) config.addr.Append(buffer, strlen(buffer));
! }
! printf("Address: %s\n", config.addr.GetData());
! // get file_list.xml MD5
! startTag = sectionString.FindTag("list_md5");
! sectionString.GetWithinTagSection(startTag, "list_md5", tagString);
! buffer = tagString.GetData();
! if(startTag != -1) strcpy(config.list_md5, buffer);
! printf("List MD5: %s\n", config.list_md5);
! // set platform type
! #if defined(OS_UNIX)
! config.platform = X86_LINUX;
! #elif defined(OS_WIN32)
! config.platform = X86_WIN;
! #else
! config.platform = UNKNOWN;
! #endif
! return 0;
! }
! // horrible commandline help display
! void Help(void) {
! cout << "Usage: uclient [options]" << endl << endl;
! cout << "Options:" << endl;
! cout << " -[c]onfig=<filename> Use alternate config file (default: config.xml)" << endl;
! cout << " -[p]ort=<number> Override config file port value" << endl;
! cout << " -[s]erv=<ip|name> Override config file server address" << endl;
! cout << " ** MD5 of last file list must be in config.xml, if not it will check everything." << endl << endl;
! cout << "Config file format:" << endl;
! cout << " <updater_config>" << endl;
! cout << " <port>13330</port>" <<endl;
! cout << " <server>1.1.1.1</server>" << endl;
! cout << " <list_md5>blah</list_md5>" << endl;
! cout << " </updater_config>" << endl << endl;
! cout << "Report bugs to <courtoma@...>" << endl;
! }
Index: Makefile.am
===================================================================
RCS file: /cvsroot/planeshift/planeshift/src/updater/client/Makefile.am,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** Makefile.am 24 May 2002 01:09:03 -0000 1.1
--- Makefile.am 30 May 2002 07:11:30 -0000 1.2
***************
*** 1,3 ****
! LIBS = @LIB_SOCKET@ @CS_LIBS@
COMMONSRC = $(top_srcdir)/src/common
UCOMMONSRC = $(top_srcdir)/src/updater/common
--- 1,3 ----
! LIBS = @LIB_SOCKET@ @CS_LIBS@ @LIB_TASK@
COMMONSRC = $(top_srcdir)/src/common
UCOMMONSRC = $(top_srcdir)/src/updater/common
***************
*** 8,15 ****
# $LIB=ws2_32
bin_PROGRAMS = uclient
! uclient_SOURCES = main.cpp uconnect.h uconnect.cpp
! uclient_LDADD = $(COMMONSRC)/util/libpsutil.la \
$(UCOMMONSRC)/libucommon.la
$(COMMONSRC)/util/libpsutil.la:
--- 8,18 ----
# $LIB=ws2_32
bin_PROGRAMS = uclient
! uclient_SOURCES = main.cpp uclient.h uclient.cpp untgz.c
! uclient_LDADD = $(COMMONSRC)/sal/libsal.la $(COMMONSRC)/util/libpsutil.la \
$(UCOMMONSRC)/libucommon.la
+
+ $(COMMONSRC)/sal/libsal.la:
+ $(MAKE) -C $(COMMONSRC)/sal libsal.la
$(COMMONSRC)/util/libpsutil.la:
--- uconnect.cpp DELETED ---
--- uconnect.h DELETED ---
|