moved update back to makensisw

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@4077 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2005-06-19 10:56:42 +00:00
parent ba4c723d07
commit c69dedddda
12 changed files with 1481 additions and 12 deletions

View file

@ -6,6 +6,11 @@ files = Split("""
toolbar.cpp
utils.cpp
version.cpp
update.cpp
jnetlib/asyncdns.cpp
jnetlib/connection.cpp
jnetlib/httpget.cpp
jnetlib/util.cpp
""")
res = Split("""
@ -31,6 +36,7 @@ libs = Split("""
shell32
comdlg32
comctl32
wsock32
""")
Import('BuildUtil')

View file

@ -0,0 +1,78 @@
/*
** JNetLib
** Copyright (C) 2000-2001 Nullsoft, Inc.
** Author: Justin Frankel
** File: asyncdns.cpp - JNL portable asynchronous DNS implementation
** License: see jnetlib.h
*/
#include "netinc.h"
#include "util.h"
#include "asyncdns.h"
JNL_AsyncDNS::JNL_AsyncDNS(int max_cache_entries)
{
m_thread_kill=1;
m_thread=0;
m_addr=0;
m_hostname[0]=0;
}
JNL_AsyncDNS::~JNL_AsyncDNS()
{
m_thread_kill=1;
if (m_thread)
{
WaitForSingleObject(m_thread,INFINITE);
CloseHandle(m_thread);
}
}
unsigned long WINAPI JNL_AsyncDNS::_threadfunc(LPVOID _d)
{
JNL_AsyncDNS *_this=(JNL_AsyncDNS*)_d;
int nowinsock=JNL::open_socketlib();
struct hostent *hostentry;
hostentry=::gethostbyname(_this->m_hostname);
if (hostentry)
{
_this->m_addr=*((int*)hostentry->h_addr);
}
else
_this->m_addr=INADDR_NONE;
if (!nowinsock) JNL::close_socketlib();
_this->m_thread_kill=1;
return 0;
}
int JNL_AsyncDNS::resolve(char *hostname, unsigned long *addr)
{
// return 0 on success, 1 on wait, -1 on unresolvable
unsigned long ip=inet_addr(hostname);
if (ip != INADDR_NONE)
{
*addr=ip;
return 0;
}
if (lstrcmpi(m_hostname,hostname)) m_addr=0;
else if (m_addr == INADDR_NONE) return -1;
else if (m_addr)
{
*addr=m_addr;
return 0;
}
lstrcpy(m_hostname,hostname);
if (m_thread_kill)
{
DWORD id;
if (m_thread) return -1;
m_thread_kill=0;
m_thread=CreateThread(NULL,0,_threadfunc,(LPVOID)this,0,&id);
if (!m_thread) return -1;
}
return 1;
}

View file

@ -0,0 +1,38 @@
/*
** JNetLib
** Copyright (C) 2000-2001 Nullsoft, Inc.
** Author: Justin Frankel
** File: asyncdns.h - JNL portable asynchronous DNS interface
** License: see jnetlib.h
**
** Usage:
** 1. Create JNL_AsyncDNS object, optionally with the number of cache entries.
** 2. call resolve() to resolve a hostname into an address. The return value of
** resolve is 0 on success (host successfully resolved), 1 on wait (meaning
** try calling resolve() with the same hostname in a few hundred milliseconds
** or so), or -1 on error (i.e. the host can't resolve).
** 4. enjoy.
*/
#ifndef _ASYNCDNS_H_
#define _ASYNCDNS_H_
class JNL_AsyncDNS
{
public:
JNL_AsyncDNS(int max_cache_entries=64);
~JNL_AsyncDNS();
int resolve(char *hostname, unsigned long *addr); // return 0 on success, 1 on wait, -1 on unresolvable
private:
char m_hostname[256];
unsigned long m_addr;
volatile int m_thread_kill;
HANDLE m_thread;
static unsigned long WINAPI _threadfunc(LPVOID _d);
};
#endif //_ASYNCDNS_H_

View file

@ -0,0 +1,447 @@
/*
** JNetLib
** Copyright (C) 2000-2001 Nullsoft, Inc.
** Author: Justin Frankel
** File: connection.cpp - JNL TCP connection implementation
** License: see jnetlib.h
*/
#include "netinc.h"
#include "util.h"
#include "connection.h"
JNL_Connection::JNL_Connection(JNL_AsyncDNS *dns, int sendbufsize, int recvbufsize)
{
m_errorstr="";
if (dns == JNL_CONNECTION_AUTODNS)
{
m_dns=new JNL_AsyncDNS();
m_dns_owned=1;
}
else
{
m_dns=dns;
m_dns_owned=0;
}
m_recv_buffer_len=recvbufsize;
m_send_buffer_len=sendbufsize;
m_recv_buffer=(char*)malloc(m_recv_buffer_len);
m_send_buffer=(char*)malloc(m_send_buffer_len);
m_socket=-1;
memset(m_recv_buffer,0,recvbufsize);
memset(m_send_buffer,0,sendbufsize);
m_remote_port=0;
m_state=STATE_NOCONNECTION;
m_recv_len=m_recv_pos=0;
m_send_len=m_send_pos=0;
m_host[0]=0;
memset(&m_saddr,0,sizeof(m_saddr));
}
void JNL_Connection::connect(int s, struct sockaddr_in *loc)
{
close(1);
m_socket=s;
m_remote_port=0;
m_dns=NULL;
if (loc) m_saddr=*loc;
else memset(&m_saddr,0,sizeof(m_saddr));
if (m_socket != -1)
{
SET_SOCK_BLOCK(m_socket,0);
m_state=STATE_CONNECTED;
}
else
{
m_errorstr="invalid socket passed to connect";
m_state=STATE_ERROR;
}
}
void JNL_Connection::connect(char *hostname, int port)
{
close(1);
m_remote_port=(short)port;
m_socket=::socket(AF_INET,SOCK_STREAM,0);
if (m_socket==-1)
{
m_errorstr="creating socket";
m_state=STATE_ERROR;
}
else
{
SET_SOCK_BLOCK(m_socket,0);
strncpy(m_host,hostname,sizeof(m_host)-1);
m_host[sizeof(m_host)-1]=0;
memset(&m_saddr,0,sizeof(m_saddr));
if (!m_host[0])
{
m_errorstr="empty hostname";
m_state=STATE_ERROR;
}
else
{
m_state=STATE_RESOLVING;
m_saddr.sin_family=AF_INET;
m_saddr.sin_port=htons((unsigned short)port);
m_saddr.sin_addr.s_addr=inet_addr(hostname);
}
}
}
JNL_Connection::~JNL_Connection()
{
if (m_socket >= 0)
{
::shutdown(m_socket, SHUT_RDWR);
::closesocket(m_socket);
m_socket=-1;
}
free(m_recv_buffer);
free(m_send_buffer);
if (m_dns_owned)
{
delete m_dns;
}
}
void JNL_Connection::run(int max_send_bytes, int max_recv_bytes, int *bytes_sent, int *bytes_rcvd)
{
int bytes_allowed_to_send=(max_send_bytes<0)?m_send_buffer_len:max_send_bytes;
int bytes_allowed_to_recv=(max_recv_bytes<0)?m_recv_buffer_len:max_recv_bytes;
if (bytes_sent) *bytes_sent=0;
if (bytes_rcvd) *bytes_rcvd=0;
switch (m_state)
{
case STATE_RESOLVING:
if (m_saddr.sin_addr.s_addr == INADDR_NONE)
{
int a=m_dns?m_dns->resolve(m_host,(unsigned long int *)&m_saddr.sin_addr.s_addr):-1;
if (!a) { m_state=STATE_CONNECTING; }
else if (a == 1)
{
m_state=STATE_RESOLVING;
break;
}
else
{
m_errorstr="resolving hostname";
m_state=STATE_ERROR;
return;
}
}
if (!::connect(m_socket,(struct sockaddr *)&m_saddr,16))
{
m_state=STATE_CONNECTED;
}
else if (ERRNO!=EINPROGRESS)
{
m_errorstr="connecting to host";
m_state=STATE_ERROR;
}
else { m_state=STATE_CONNECTING; }
break;
case STATE_CONNECTING:
{
fd_set f[3];
FD_ZERO(&f[0]);
FD_ZERO(&f[1]);
FD_ZERO(&f[2]);
FD_SET(m_socket,&f[0]);
FD_SET(m_socket,&f[1]);
FD_SET(m_socket,&f[2]);
struct timeval tv;
memset(&tv,0,sizeof(tv));
if (select(m_socket+1,&f[0],&f[1],&f[2],&tv)==-1)
{
m_errorstr="connecting to host (calling select())";
m_state=STATE_ERROR;
}
else if (FD_ISSET(m_socket,&f[1]))
{
m_state=STATE_CONNECTED;
}
else if (FD_ISSET(m_socket,&f[2]))
{
m_errorstr="connecting to host";
m_state=STATE_ERROR;
}
}
break;
case STATE_CONNECTED:
case STATE_CLOSING:
if (m_send_len>0 && bytes_allowed_to_send>0)
{
int len=m_send_buffer_len-m_send_pos;
if (len > m_send_len) len=m_send_len;
if (len > bytes_allowed_to_send) len=bytes_allowed_to_send;
if (len > 0)
{
int res=::send(m_socket,m_send_buffer+m_send_pos,len,0);
if (res==-1 && ERRNO != EWOULDBLOCK)
{
// m_state=STATE_CLOSED;
// return;
}
if (res>0)
{
bytes_allowed_to_send-=res;
if (bytes_sent) *bytes_sent+=res;
m_send_pos+=res;
m_send_len-=res;
}
}
if (m_send_pos>=m_send_buffer_len)
{
m_send_pos=0;
if (m_send_len>0)
{
len=m_send_buffer_len-m_send_pos;
if (len > m_send_len) len=m_send_len;
if (len > bytes_allowed_to_send) len=bytes_allowed_to_send;
int res=::send(m_socket,m_send_buffer+m_send_pos,len,0);
if (res==-1 && ERRNO != EWOULDBLOCK)
{
// m_state=STATE_CLOSED;
}
if (res>0)
{
bytes_allowed_to_send-=res;
if (bytes_sent) *bytes_sent+=res;
m_send_pos+=res;
m_send_len-=res;
}
}
}
}
if (m_recv_len<m_recv_buffer_len)
{
int len=m_recv_buffer_len-m_recv_pos;
if (len > m_recv_buffer_len-m_recv_len) len=m_recv_buffer_len-m_recv_len;
if (len > bytes_allowed_to_recv) len=bytes_allowed_to_recv;
if (len>0)
{
int res=::recv(m_socket,m_recv_buffer+m_recv_pos,len,0);
if (res == 0 || (res < 0 && ERRNO != EWOULDBLOCK))
{
m_state=STATE_CLOSED;
break;
}
if (res > 0)
{
bytes_allowed_to_recv-=res;
if (bytes_rcvd) *bytes_rcvd+=res;
m_recv_pos+=res;
m_recv_len+=res;
}
}
if (m_recv_pos >= m_recv_buffer_len)
{
m_recv_pos=0;
if (m_recv_len < m_recv_buffer_len)
{
len=m_recv_buffer_len-m_recv_len;
if (len > bytes_allowed_to_recv) len=bytes_allowed_to_recv;
if (len > 0)
{
int res=::recv(m_socket,m_recv_buffer+m_recv_pos,len,0);
if (res == 0 || (res < 0 && ERRNO != EWOULDBLOCK))
{
m_state=STATE_CLOSED;
break;
}
if (res > 0)
{
bytes_allowed_to_recv-=res;
if (bytes_rcvd) *bytes_rcvd+=res;
m_recv_pos+=res;
m_recv_len+=res;
}
}
}
}
}
if (m_state == STATE_CLOSING)
{
if (m_send_len < 1) m_state = STATE_CLOSED;
}
break;
default: break;
}
}
void JNL_Connection::close(int quick)
{
if (quick || m_state == STATE_RESOLVING || m_state == STATE_CONNECTING)
{
m_state=STATE_CLOSED;
if (m_socket >= 0)
{
::shutdown(m_socket, SHUT_RDWR);
::closesocket(m_socket);
}
m_socket=-1;
memset(m_recv_buffer,0,m_recv_buffer_len);
memset(m_send_buffer,0,m_send_buffer_len);
m_remote_port=0;
m_recv_len=m_recv_pos=0;
m_send_len=m_send_pos=0;
m_host[0]=0;
memset(&m_saddr,0,sizeof(m_saddr));
}
else
{
if (m_state == STATE_CONNECTED) m_state=STATE_CLOSING;
}
}
int JNL_Connection::send_bytes_in_queue(void)
{
return m_send_len;
}
int JNL_Connection::send_bytes_available(void)
{
return m_send_buffer_len-m_send_len;
}
int JNL_Connection::send(char *data, int length)
{
if (length > send_bytes_available())
{
return -1;
}
int write_pos=m_send_pos+m_send_len;
if (write_pos >= m_send_buffer_len)
{
write_pos-=m_send_buffer_len;
}
int len=m_send_buffer_len-write_pos;
if (len > length)
{
len=length;
}
memcpy(m_send_buffer+write_pos,data,len);
if (length > len)
{
memcpy(m_send_buffer,data+len,length-len);
}
m_send_len+=length;
return 0;
}
int JNL_Connection::send_string(char *line)
{
return send(line,strlen(line));
}
int JNL_Connection::recv_bytes_available(void)
{
return m_recv_len;
}
int JNL_Connection::peek_bytes(char *data, int maxlength)
{
if (maxlength > m_recv_len)
{
maxlength=m_recv_len;
}
int read_pos=m_recv_pos-m_recv_len;
if (read_pos < 0)
{
read_pos += m_recv_buffer_len;
}
int len=m_recv_buffer_len-read_pos;
if (len > maxlength)
{
len=maxlength;
}
memcpy(data,m_recv_buffer+read_pos,len);
if (len < maxlength)
{
memcpy(data+len,m_recv_buffer,maxlength-len);
}
return maxlength;
}
int JNL_Connection::recv_bytes(char *data, int maxlength)
{
int ml=peek_bytes(data,maxlength);
m_recv_len-=ml;
return ml;
}
int JNL_Connection::getbfromrecv(int pos, int remove)
{
int read_pos=m_recv_pos-m_recv_len + pos;
if (pos < 0 || pos > m_recv_len) return -1;
if (read_pos < 0)
{
read_pos += m_recv_buffer_len;
}
if (read_pos >= m_recv_buffer_len)
{
read_pos-=m_recv_buffer_len;
}
if (remove) m_recv_len--;
return m_recv_buffer[read_pos];
}
int JNL_Connection::recv_lines_available(void)
{
int l=recv_bytes_available();
int lcount=0;
int lastch=0;
int pos;
for (pos=0; pos < l; pos ++)
{
int t=getbfromrecv(pos,0);
if (t == -1) return lcount;
if ((t=='\r' || t=='\n') &&(
(lastch != '\r' && lastch != '\n') || lastch==t
)) lcount++;
lastch=t;
}
return lcount;
}
int JNL_Connection::recv_line(char *line, int maxlength)
{
if (maxlength > m_recv_len) maxlength=m_recv_len;
while (maxlength--)
{
int t=getbfromrecv(0,1);
if (t == -1)
{
*line=0;
return 0;
}
if (t == '\r' || t == '\n')
{
int r=getbfromrecv(0,0);
if ((r == '\r' || r == '\n') && r != t) getbfromrecv(0,1);
*line=0;
return 0;
}
*line++=(char)t;
}
return 1;
}
unsigned long JNL_Connection::get_interface(void)
{
if (m_socket==-1) return 0;
struct sockaddr_in sin;
memset(&sin,0,sizeof(sin));
socklen_t len=16;
if (::getsockname(m_socket,(struct sockaddr *)&sin,&len)) return 0;
return (unsigned long) sin.sin_addr.s_addr;
}

View file

@ -0,0 +1,135 @@
/*
** JNetLib
** Copyright (C) 2000-2001 Nullsoft, Inc.
** Author: Justin Frankel
** File: connection.h - JNL TCP connection interface
** License: see jnetlib.h
**
** Usage:
** 1. Create a JNL_Connection object, optionally specifying a JNL_AsyncDNS
** object to use (or NULL for none, or JNL_CONNECTION_AUTODNS for auto),
** and the send and receive buffer sizes.
** 2. Call connect() to have it connect to a host/port (the hostname will be
** resolved if possible).
** 3. call run() with the maximum send/recv amounts, and optionally parameters
** so you can tell how much has been send/received. You want to do this a lot, while:
** 4. check get_state() to check the state of the connection. The states are:
** JNL_Connection::STATE_ERROR
** - an error has occured on the connection. the connection has closed,
** and you can no longer write to the socket (there still might be
** data in the receive buffer - use recv_bytes_available()).
** JNL_Connection::STATE_NOCONNECTION
** - no connection has been made yet. call connect() already! :)
** JNL_Connection::STATE_RESOLVING
** - the connection is still waiting for a JNL_AsycnDNS to resolve the
** host.
** JNL_Connection::STATE_CONNECTING
** - the asynchronous call to connect() is still running.
** JNL_Connection::STATE_CONNECTED
** - the connection has connected, all is well.
** JNL_Connection::STATE_CLOSING
** - the connection is closing. This happens after a call to close,
** without the quick parameter set. This means that the connection
** will close once the data in the send buffer is sent (data could
** still be being received when it would be closed). After it is
** closed, the state will transition to:
** JNL_Connection::STATE_CLOSED
** - the connection has closed, generally without error. There still
** might be data in the receieve buffer, use recv_bytes_available().
** 5. Use send() and send_string() to send data. You can use
** send_bytes_in_queue() to see how much has yet to go out, or
** send_bytes_available() to see how much you can write. If you use send()
** or send_string() and not enough room is available, both functions will
** return error ( < 0)
** 6. Use recv() and recv_line() to get data. If you want to see how much data
** there is, use recv_bytes_available() and recv_lines_available(). If you
** call recv() and not enough data is available, recv() will return how much
** data was actually read. See comments at the function defs.
**
** 7. To close, call close(1) for a quick close, or close() for a close that will
** make the socket close after sending all the data sent.
**
** 8. delete ye' ol' object.
*/
#ifndef _CONNECTION_H_
#define _CONNECTION_H_
#include "asyncdns.h"
#define JNL_CONNECTION_AUTODNS ((JNL_AsyncDNS*)-1)
class JNL_Connection
{
public:
typedef enum
{
STATE_ERROR,
STATE_NOCONNECTION,
STATE_RESOLVING,
STATE_CONNECTING,
STATE_CONNECTED,
STATE_CLOSING,
STATE_CLOSED
} state;
JNL_Connection(JNL_AsyncDNS *dns=JNL_CONNECTION_AUTODNS, int sendbufsize=8192, int recvbufsize=8192);
~JNL_Connection();
void connect(char *hostname, int port);
void connect(int sock, struct sockaddr_in *loc=NULL); // used by the listen object, usually not needed by users.
void run(int max_send_bytes=-1, int max_recv_bytes=-1, int *bytes_sent=NULL, int *bytes_rcvd=NULL);
int get_state() { return m_state; }
char *get_errstr() { return m_errorstr; }
void close(int quick=0);
void flush_send(void) { m_send_len=m_send_pos=0; }
int send_bytes_in_queue(void);
int send_bytes_available(void);
int send(char *data, int length); // returns -1 if not enough room
int send_string(char *line); // returns -1 if not enough room
int recv_bytes_available(void);
int recv_bytes(char *data, int maxlength); // returns actual bytes read
unsigned int recv_int(void);
int recv_lines_available(void);
int recv_line(char *line, int maxlength); // returns 0 if the line was terminated with a \r or \n, 1 if not.
// (i.e. if you specify maxlength=10, and the line is 12 bytes long
// it will return 1. or if there is no \r or \n and that's all the data
// the connection has.)
int peek_bytes(char *data, int maxlength); // returns bytes peeked
unsigned long get_interface(void); // this returns the interface the connection is on
unsigned long get_remote(void) { return m_saddr.sin_addr.s_addr; } // remote host ip.
short get_remote_port(void) { return m_remote_port; } // this returns the remote port of connection
protected:
int m_socket;
short m_remote_port;
char *m_recv_buffer;
char *m_send_buffer;
int m_recv_buffer_len;
int m_send_buffer_len;
int m_recv_pos;
int m_recv_len;
int m_send_pos;
int m_send_len;
struct sockaddr_in m_saddr;
char m_host[256];
JNL_AsyncDNS *m_dns;
int m_dns_owned;
state m_state;
char *m_errorstr;
int getbfromrecv(int pos, int remove); // used by recv_line*
};
#endif // _Connection_H_

View file

@ -0,0 +1,473 @@
/*
** JNetLib
** Copyright (C) 2000-2001 Nullsoft, Inc.
** Author: Justin Frankel
** File: httpget.cpp - JNL HTTP GET implementation
** License: see jnetlib.h
*/
#include "netinc.h"
#include "util.h"
#include "httpget.h"
void *operator new( unsigned int num_bytes ){return GlobalAlloc(GPTR,num_bytes);}
void operator delete( void *p ) { if (p) GlobalFree(p); }
JNL_HTTPGet::JNL_HTTPGet(JNL_AsyncDNS *dns, int recvbufsize, char *proxy)
{
m_recvbufsize=recvbufsize;
m_dns=dns;
m_con=NULL;
m_http_proxylpinfo=0;
m_http_proxyhost=0;
m_http_proxyport=0;
if (proxy && *proxy)
{
char *p=(char*)malloc(strlen(proxy)+1);
if (p)
{
char *r=NULL;
strcpy(p,proxy);
do_parse_url(p,&m_http_proxyhost,&m_http_proxyport,&r,&m_http_proxylpinfo);
free(r);
free(p);
}
}
m_sendheaders=NULL;
reinit();
}
void JNL_HTTPGet::reinit()
{
m_errstr=0;
m_recvheaders=NULL;
m_recvheaders_size=0;
m_http_state=0;
m_http_port=0;
m_http_url=0;
m_reply=0;
m_http_host=m_http_lpinfo=m_http_request=NULL;
}
void JNL_HTTPGet::deinit()
{
delete m_con;
free(m_recvheaders);
free(m_http_url);
free(m_http_host);
free(m_http_lpinfo);
free(m_http_request);
free(m_errstr);
free(m_reply);
reinit();
}
JNL_HTTPGet::~JNL_HTTPGet()
{
deinit();
free(m_sendheaders);
free(m_http_proxylpinfo);
free(m_http_proxyhost);
}
void JNL_HTTPGet::addheader(char *header)
{
//if (strstr(header,"\r") || strstr(header,"\n")) return;
if (!m_sendheaders)
{
m_sendheaders=(char*)malloc(strlen(header)+3);
if (m_sendheaders)
{
strcpy(m_sendheaders,header);
strcat(m_sendheaders,"\r\n");
}
}
else
{
char *t=(char*)malloc(strlen(header)+strlen(m_sendheaders)+1+2);
if (t)
{
strcpy(t,m_sendheaders);
strcat(t,header);
strcat(t,"\r\n");
free(m_sendheaders);
m_sendheaders=t;
}
}
}
void JNL_HTTPGet::do_encode_mimestr(char *in, char *out)
{
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int shift = 0;
int accum = 0;
while (*in)
{
if (*in)
{
accum <<= 8;
shift += 8;
accum |= *in++;
}
while ( shift >= 6 )
{
shift -= 6;
*out++ = alphabet[(accum >> shift) & 0x3F];
}
}
if (shift == 4)
{
*out++ = alphabet[(accum & 0xF)<<2];
*out++='=';
}
else if (shift == 2)
{
*out++ = alphabet[(accum & 0x3)<<4];
*out++='=';
*out++='=';
}
*out++=0;
}
void JNL_HTTPGet::connect(char *url)
{
deinit();
m_http_url=(char*)malloc(strlen(url)+1);
strcpy(m_http_url,url);
do_parse_url(m_http_url,&m_http_host,&m_http_port,&m_http_request, &m_http_lpinfo);
strcpy(m_http_url,url);
if (!m_http_host || !m_http_host[0] || !m_http_port)
{
m_http_state=-1;
seterrstr("invalid URL");
return;
}
int sendbufferlen=0;
if (!m_http_proxyhost || !m_http_proxyhost[0])
{
sendbufferlen += 4 /* GET */ + strlen(m_http_request) + 9 /* HTTP/1.0 */ + 2;
}
else
{
sendbufferlen += 4 /* GET */ + strlen(m_http_url) + 9 /* HTTP/1.0 */ + 2;
if (m_http_proxylpinfo&&m_http_proxylpinfo[0])
{
sendbufferlen+=58+strlen(m_http_proxylpinfo)*2; // being safe here
}
}
sendbufferlen += 5 /* Host: */ + strlen(m_http_host) + 2;
if (m_http_lpinfo&&m_http_lpinfo[0])
{
sendbufferlen+=46+strlen(m_http_lpinfo)*2; // being safe here
}
if (m_sendheaders) sendbufferlen+=strlen(m_sendheaders);
char *str=(char*)malloc(sendbufferlen+1024);
if (!str)
{
seterrstr("error allocating memory");
m_http_state=-1;
}
if (!m_http_proxyhost || !m_http_proxyhost[0])
{
wsprintf(str,"GET %s HTTP/1.0\r\n",m_http_request);
}
else
{
wsprintf(str,"GET %s HTTP/1.0\r\n",m_http_url);
}
wsprintf(str+strlen(str),"Host:%s\r\n",m_http_host);
if (m_http_lpinfo&&m_http_lpinfo[0])
{
strcat(str,"Authorization: Basic ");
do_encode_mimestr(m_http_lpinfo,str+strlen(str));
strcat(str,"\r\n");
}
if (m_http_proxylpinfo&&m_http_proxylpinfo[0])
{
strcat(str,"Proxy-Authorization: Basic ");
do_encode_mimestr(m_http_proxylpinfo,str+strlen(str));
strcat(str,"\r\n");
}
if (m_sendheaders) strcat(str,m_sendheaders);
strcat(str,"\r\n");
int a=m_recvbufsize;
if (a < 4096) a=4096;
m_con=new JNL_Connection(m_dns,strlen(str)+4,a);
if (m_con)
{
if (!m_http_proxyhost || !m_http_proxyhost[0])
{
m_con->connect(m_http_host,m_http_port);
}
else
{
m_con->connect(m_http_proxyhost,m_http_proxyport);
}
m_con->send_string(str);
}
else
{
m_http_state=-1;
seterrstr("could not create connection object");
}
free(str);
}
static int _strnicmp(char *b1, char *b2, int l)
{
while (l-- && *b1 && *b2)
{
char bb1=*b1++;
char bb2=*b2++;
if (bb1>='a' && bb1 <= 'z') bb1+='A'-'a';
if (bb2>='a' && bb2 <= 'z') bb2+='A'-'a';
if (bb1 != bb2) return bb1-bb2;
}
return 0;
}
char *_strstr(char *i, char *s)
{
if (strlen(i)>=strlen(s)) while (i[strlen(s)-1])
{
int l=strlen(s)+1;
char *ii=i;
char *is=s;
while (--l>0)
{
if (*ii != *is) break;
ii++;
is++;
}
if (l==0) return i;
i++;
}
return NULL;
}
#define strstr _strstr
void JNL_HTTPGet::do_parse_url(char *url, char **host, int *port, char **req, char **lp)
{
char *p,*np;
free(*host); *host=0;
free(*req); *req=0;
free(*lp); *lp=0;
if (strstr(url,"://")) np=p=strstr(url,"://")+3;
else np=p=url;
while (*np != '/' && *np) np++;
if (*np)
{
*req=(char*)malloc(strlen(np)+1);
if (*req) strcpy(*req,np);
*np++=0;
}
else
{
*req=(char*)malloc(2);
if (*req) strcpy(*req,"/");
}
np=p;
while (*np != '@' && *np) np++;
if (*np)
{
*np++=0;
*lp=(char*)malloc(strlen(p)+1);
if (*lp) strcpy(*lp,p);
p=np;
}
else
{
*lp=(char*)malloc(1);
if (*lp) strcpy(*lp,"");
}
np=p;
while (*np != ':' && *np) np++;
if (*np)
{
*np++=0;
*port=my_atoi(np);
} else *port=80;
*host=(char*)malloc(strlen(p)+1);
if (*host) strcpy(*host,p);
}
char *JNL_HTTPGet::getallheaders()
{ // double null terminated, null delimited list
if (m_recvheaders) return m_recvheaders;
else return "\0\0";
}
char *JNL_HTTPGet::getheader(char *headername)
{
char *ret=NULL;
if (strlen(headername)<1||!m_recvheaders) return NULL;
char *p=m_recvheaders;
while (*p)
{
if (!_strnicmp(headername,p,strlen(headername)))
{
ret=p+strlen(headername);
while (*ret == ' ') ret++;
break;
}
p+=strlen(p)+1;
}
return ret;
}
int JNL_HTTPGet::run()
{
int cnt=0;
if (m_http_state==-1||!m_con) return -1; // error
run_again:
static char buf[4096];
m_con->run();
if (m_con->get_state()==JNL_Connection::STATE_ERROR)
{
seterrstr(m_con->get_errstr());
return -1;
}
if (m_con->get_state()==JNL_Connection::STATE_CLOSED) return 1;
if (m_http_state==0) // connected, waiting for reply
{
if (m_con->recv_lines_available()>0)
{
m_con->recv_line(buf,4095);
buf[4095]=0;
m_reply=(char*)malloc(strlen(buf)+1);
strcpy(m_reply,buf);
if (strstr(buf,"200")) m_http_state=2; // proceed to read headers normally
else if (strstr(buf,"301") || strstr(buf,"302"))
{
m_http_state=1; // redirect city
}
else
{
seterrstr(buf);
m_http_state=-1;
return -1;
}
cnt=0;
}
else if (!cnt++) goto run_again;
}
if (m_http_state == 1) // redirect
{
while (m_con->recv_lines_available() > 0)
{
m_con->recv_line(buf,4096);
if (!buf[0])
{
m_http_state=-1;
return -1;
}
if (!_strnicmp(buf,"Location:",9))
{
char *p=buf+9; while (*p== ' ') p++;
if (*p)
{
connect(p);
return 0;
}
}
}
}
if (m_http_state==2)
{
if (!cnt++ && m_con->recv_lines_available() < 1) goto run_again;
while (m_con->recv_lines_available() > 0)
{
m_con->recv_line(buf,4096);
if (!buf[0]) { m_http_state=3; break; }
if (!m_recvheaders)
{
m_recvheaders_size=strlen(buf)+1;
m_recvheaders=(char*)malloc(m_recvheaders_size+1);
if (m_recvheaders)
{
strcpy(m_recvheaders,buf);
m_recvheaders[m_recvheaders_size]=0;
}
}
else
{
int oldsize=m_recvheaders_size;
m_recvheaders_size+=strlen(buf)+1;
char *n=(char*)malloc(m_recvheaders_size+1);
if (n)
{
memcpy(n,m_recvheaders,oldsize);
strcpy(n+oldsize,buf);
n[m_recvheaders_size]=0;
free(m_recvheaders);
m_recvheaders=n;
}
}
}
}
if (m_http_state==3)
{
}
return 0;
}
int JNL_HTTPGet::get_status() // returns 0 if connecting, 1 if reading headers,
// 2 if reading content, -1 if error.
{
if (m_http_state < 0) return -1;
if (m_http_state < 2) return 0;
if (m_http_state == 2) return 1;
if (m_http_state == 3) return 2;
return -1;
}
int JNL_HTTPGet::getreplycode()// returns 0 if none yet, otherwise returns http reply code.
{
if (!m_reply) return 0;
char *p=m_reply;
while (*p && *p != ' ') p++; // skip over HTTP/x.x
if (!*p) return 0;
return my_atoi(++p);
}
int JNL_HTTPGet::bytes_available()
{
if (m_con && m_http_state==3) return m_con->recv_bytes_available();
return 0;
}
int JNL_HTTPGet::get_bytes(char *buf, int len)
{
if (m_con && m_http_state==3) return m_con->recv_bytes(buf,len);
return 0;
}
int JNL_HTTPGet::peek_bytes(char *buf, int len)
{
if (m_con && m_http_state==3) return m_con->peek_bytes(buf,len);
return 0;
}

View file

@ -0,0 +1,110 @@
/*
** JNetLib
** Copyright (C) 2000-2001 Nullsoft, Inc.
** Author: Justin Frankel
** File: httpget.h - JNL interface for doing HTTP GETs.
** License: see jnetlib.h
**
** Usage:
** 1. Create a JNL_HTTPGet object, optionally specifying a JNL_AsyncDNS
** object to use (or NULL for none, or JNL_CONNECTION_AUTODNS for auto),
** and the receive buffer size, and a string specifying proxy (or NULL
** for none). See note on proxy string below.
** 2. call addheader() to add whatever headers you want. It is recommended to
** add at least the following two:
** addheader("User-Agent:MyApp (Mozilla)");
*/// addheader("Accept:*/*");
/* ( the comment weirdness is there so I Can do the star-slash :)
** 3. Call connect() with the URL you wish to GET (see URL string note below)
** 4. Call run() once in a while, checking to see if it returns -1
** (if it does return -1, call geterrorstr() to see what the error is).
** (if it returns 1, no big deal, the connection has closed).
** 5. While you're at it, you can call bytes_available() to see if any data
** from the http stream is available, or getheader() to see if any headers
** are available, or getreply() to see the HTTP reply, or getallheaders()
** to get a double null terminated, null delimited list of headers returned.
** 6. If you want to read from the stream, call get_bytes (which returns how much
** was actually read).
** 7. content_length() is a helper function that uses getheader() to check the
** content-length header.
** 8. Delete ye' ol' object when done.
**
** Proxy String:
** should be in the format of host:port, or user@host:port, or
** user:password@host:port. if port is not specified, 80 is assumed.
** URL String:
** should be in the format of http://user:pass@host:port/requestwhatever
** note that user, pass, port, and /requestwhatever are all optional :)
** note that also, http:// is really not important. if you do poo://
** or even leave out the http:// altogether, it will still work.
*/
#ifndef _HTTPGET_H_
#define _HTTPGET_H_
#include "connection.h"
#include "util.h"
class JNL_HTTPGet
{
public:
JNL_HTTPGet(JNL_AsyncDNS *dns=JNL_CONNECTION_AUTODNS, int recvbufsize=16384, char *proxy=NULL);
~JNL_HTTPGet();
void addheader(char *header);
void connect(char *url);
int run(); // returns: 0 if all is OK. -1 if error (call geterrorstr()). 1 if connection closed.
int get_status(); // returns 0 if connecting, 1 if reading headers,
// 2 if reading content, -1 if error.
char *getallheaders(); // double null terminated, null delimited list
char *getheader(char *headername);
char *getreply() { return m_reply; }
int getreplycode(); // returns 0 if none yet, otherwise returns http reply code.
char *geterrorstr() { return m_errstr;}
int bytes_available();
int get_bytes(char *buf, int len);
int peek_bytes(char *buf, int len);
int content_length() { char *p=getheader("content-length:"); if (p) return my_atoi(p); return 0; }
JNL_Connection *get_con() { return m_con; }
public:
void reinit();
void deinit();
void seterrstr(char *str) { if (m_errstr) free(m_errstr); m_errstr=(char*)malloc(strlen(str)+1); strcpy(m_errstr,str); }
void do_parse_url(char *url, char **host, int *port, char **req, char **lp);
void do_encode_mimestr(char *in, char *out);
JNL_AsyncDNS *m_dns;
JNL_Connection *m_con;
int m_recvbufsize;
int m_http_state;
int m_http_port;
char *m_http_url;
char *m_http_host;
char *m_http_lpinfo;
char *m_http_request;
char *m_http_proxylpinfo;
char *m_http_proxyhost;
int m_http_proxyport;
char *m_sendheaders;
char *m_recvheaders;
int m_recvheaders_size;
char *m_reply;
char *m_errstr;
};
#endif // _HTTPGET_H_

View file

@ -0,0 +1,82 @@
/*
** JNetLib
** Copyright (C) 2000-2001 Nullsoft, Inc.
** Author: Justin Frankel
** File: netinc.h - network includes and portability defines (used internally)
** License: see jnetlib.h
*/
#ifndef _NETINC_H_
#define _NETINC_H_
#ifdef _WIN32
#include <windows.h>
#include <stdio.h>
#include <time.h>
#define strcasecmp(x,y) stricmp(x,y)
#define ERRNO (WSAGetLastError())
#define SET_SOCK_BLOCK(s,block) { unsigned long __i=block?0:1; ioctlsocket(s,FIONBIO,&__i); }
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EINPROGRESS WSAEWOULDBLOCK
typedef int socklen_t;
#else
#ifndef THREAD_SAFE
#define THREAD_SAFE
#endif
#ifndef _REENTRANT
#define _REENTRANT
#endif
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#define ERRNO errno
#define closesocket(s) close(s)
#define SET_SOCK_BLOCK(s,block) { int __flags; if ((__flags = fcntl(s, F_GETFL, 0)) != -1) { if (!block) __flags |= O_NONBLOCK; else __flags &= ~O_NONBLOCK; fcntl(s, F_SETFL, __flags); } }
#define stricmp(x,y) strcasecmp(x,y)
#define strnicmp(x,y,z) strncasecmp(x,y,z)
#define wsprintf sprintf
#endif // !_WIN32
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
#ifndef INADDR_ANY
#define INADDR_ANY 0
#endif
#ifndef SHUT_RDWR
#define SHUT_RDWR 2
#endif
extern void mini_memset(void *,char,int);
extern void mini_memcpy(void *,void*,int);
#define memset mini_memset
#define memcpy mini_memcpy
#define strcpy lstrcpy
#define strncpy lstrcpyn
#define strcat lstrcat
#define strlen lstrlen
#define malloc(x) GlobalAlloc(GPTR,(x))
#define free(x) { if (x) GlobalFree(x); }
#endif //_NETINC_H_

View file

@ -0,0 +1,64 @@
/*
** JNetLib
** Copyright (C) 2000-2001 Nullsoft, Inc.
** Author: Justin Frankel
** File: util.cpp - JNL implementation of basic network utilities
** License: see jnetlib.h
*/
#include "netinc.h"
#include "util.h"
int JNL::open_socketlib()
{
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData)) return 1;
#endif
return 0;
}
void JNL::close_socketlib()
{
#ifdef _WIN32
WSACleanup();
#endif
}
unsigned long JNL::ipstr_to_addr(const char *cp)
{
return ::inet_addr(cp);
}
void JNL::addr_to_ipstr(unsigned long addr, char *host, int maxhostlen)
{
struct in_addr a; a.s_addr=addr;
char *p=::inet_ntoa(a); strncpy(host,p?p:"",maxhostlen);
}
int my_atoi(char *s)
{
int sign=0;
int v=0;
if (*s == '-') { s++; sign++; }
for (;;)
{
int c=*s++ - '0';
if (c < 0 || c > 9) break;
v*=10;
v+=c;
}
if (sign) return -(int) v;
return (int)v;
}
void mini_memset(void *o,char i,int l)
{
char *oo=(char*)o;
while (l-- > 0) *oo++=i;
}
void mini_memcpy(void *o,void*i,int l)
{
char *oo=(char*)o;
char *ii=(char*)i;
while (l-- > 0) *oo++=*ii++;
}

View file

@ -0,0 +1,41 @@
/*
** JNetLib
** Copyright (C) 2000-2001 Nullsoft, Inc.
** Author: Justin Frankel
** File: util.h - JNL interface for basic network utilities
** License: see jnetlib.h
**
** routines you may be interested in:
** JNL::open_socketlib();
** opens the socket library. Call this once before using any network
** code. If you create a new thread, call this again. Only really an
** issue for Win32 support, but use it anyway for portability/
**
** JNL::close_Socketlib();
** closes the socketlib. Call this when you're done with the network,
** after all your JNetLib objects have been destroyed.
**
** unsigned long JNL::ipstr_to_addr(const char *cp);
** gives you the integer representation of a ip address in dotted
** decimal form.
**
** JNL::addr_to_ipstr(unsigned long addr, char *host, int maxhostlen);
** gives you the dotted decimal notation of an integer ip address.
**
*/
#ifndef _UTIL_H_
#define _UTIL_H_
class JNL
{
public:
static int open_socketlib();
static void close_socketlib();
static unsigned long ipstr_to_addr(const char *cp);
static void addr_to_ipstr(unsigned long addr, char *host, int maxhostlen);
};
int my_atoi(char *p);
#endif //_UTIL_H_

View file

@ -26,6 +26,7 @@
#include "resource.h"
#include "noclib.h"
#include "toolbar.h"
#include "update.h"
NSCRIPTDATA g_sdata;
NRESIZEDATA g_resize;
@ -69,6 +70,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char *cmdParam, int cmd
}
}
if (g_sdata.script_alloced) GlobalFree(g_sdata.script);
FinalizeUpdate();
ExitProcess(msg.wParam);
return msg.wParam;
}
@ -464,17 +466,7 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
}
case IDM_NSISUPDATE:
{
int rv;
rv = MessageBox(g_sdata.hwnd,NSISUPDATEPROMPT,"Question",MB_YESNO|MB_ICONQUESTION);
if(rv == IDYES) {
char pathf[MAX_PATH],*path;
GetModuleFileName(NULL,pathf,sizeof(pathf));
path=my_strrchr(pathf,'\\');
if(path!=NULL) *path=0;
lstrcat(pathf,NSIS_UPDATE);
ShellExecute(g_sdata.hwnd,"open",pathf,NULL,NULL,SW_SHOWNORMAL);
PostMessage(g_sdata.hwnd,WM_COMMAND, IDM_EXIT, 0);
}
Update();
return TRUE;
}
case IDM_SELECTALL:

View file

@ -33,7 +33,8 @@
// Defines
#define NSIS_URL "http://nsis.sourceforge.net/"
#define NSIS_FOR "http://forums.winamp.com/forumdisplay.php?forumid=65"
#define NSIS_UPDATE "\\Bin\\NSISUpdate.exe"
#define NSIS_UPDATE "http://nsis.sourceforge.net/update.php?version="
#define NSIS_DL_URL "http://nsis.sourceforge.net/download/"
#define USAGE "Usage:\r\n\r\n - File | Load Script...\r\n - Drag the .nsi file into this window\r\n - Right click the .nsi file and choose \"Compile NSIS Script\""
#define COPYRIGHT "Copyright © 2002 Robert Rainwater"
#define CONTRIB "Fritz Elfert, Justin Frankel, Amir Szekely, Sunil Kamath, Joost Verburg"
@ -193,6 +194,8 @@ typedef struct NSISScriptData {
int recompile_test;
} NSCRIPTDATA;
extern NSCRIPTDATA g_sdata;
typedef struct ResizeData {
RECT resizeRect;
RECT griprect;