This commit was generated by cvs2svn to compensate for changes in r2,

which included commits to RCS files with non-trunk default branches.


git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@625 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2002-08-02 10:01:35 +00:00
parent 9b3b220a13
commit 3e9e73ec59
177 changed files with 37677 additions and 0 deletions

59
Contrib/NSISdl/ReadMe.txt Normal file
View file

@ -0,0 +1,59 @@
NSIS-DL 1.1 - http downloading DLL for NSIS
Copyright (C) 2001 Yaroslav Faybishenko & Justin Frankel
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
This dll can be used from NSIS to download files via http.
How to use (for another example, see waplugin.nsi in the nsis directory):
Pass the url and filename on the stack
Result is returned in $0
"cancel" if cancelled
"success" if success
otherwise, an error string describing the error
Example:
; pack the dll in the install file
File /oname=$TEMP\nsdtmp09.dll nsisdl.dll
; make the call to download
Push "http://www.xcf.berkeley.edu/~yaroslav/photos/mike/mike1-full.jpg"
Push "$INSTDIR\test.jpg"
CallInstDLL $TEMP\nsdtmp09.dll download ; for a quiet install, use download_quiet
; delete DLL from temporary directory
Delete $TEMP\nsdtmp09.dll
; check if download succeeded
StrCmp $0 "success" successful
StrCmp $0 "cancel" cancelled
; we failed
DetailPrint "Download failed: $0"
goto done
cancelled:
DetailPrint "Download cancelled"
goto done
successful:
DetailPrint "Download successful"
ExecShell $INSTDIR\test.jpg
goto done

78
Contrib/NSISdl/Script1.rc Normal file
View file

@ -0,0 +1,78 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 265, 104
STYLE DS_CONTROL | WS_CHILD
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Progress1",IDC_PROGRESS1,"msctls_progress32",WS_BORDER,
0,36,265,11
CTEXT "",IDC_STATIC2,0,25,263,8
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

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;
}

38
Contrib/NSISdl/asyncdns.h Normal file
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;
}

135
Contrib/NSISdl/connection.h Normal file
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_

471
Contrib/NSISdl/httpget.cpp Normal file
View file

@ -0,0 +1,471 @@
/*
** 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"
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;
}

109
Contrib/NSISdl/httpget.h Normal file
View file

@ -0,0 +1,109 @@
/*
** 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"
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_

82
Contrib/NSISdl/netinc.h Normal file
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_

448
Contrib/NSISdl/nsisdl.cpp Normal file
View file

@ -0,0 +1,448 @@
/*
NSIS-DL 1.1 - http downloading DLL for NSIS
Copyright (C) 2001 Yaroslav Faybishenko & Justin Frankel
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Note: this source code is pretty hacked together right now, improvements
and cleanups will come later.
*/
#include <windows.h>
#include <stdio.h>
#include <commctrl.h>
#include "netinc.h"
#include "util.h"
#include "resource.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); }
typedef struct _stack_t {
struct _stack_t *next;
char text[1]; // this should be the length of string_size
} stack_t;
static int popstring(char *str); // 0 on success, 1 on empty stack
static void setuservariable(int varnum, char *var);
enum
{
INST_0, // $0
INST_1, // $1
INST_2, // $2
INST_3, // $3
INST_4, // $4
INST_5, // $5
INST_6, // $6
INST_7, // $7
INST_8, // $8
INST_9, // $9
INST_R0, // $R0
INST_R1, // $R1
INST_R2, // $R2
INST_R3, // $R3
INST_R4, // $R4
INST_R5, // $R5
INST_R6, // $R6
INST_R7, // $R7
INST_R8, // $R8
INST_R9, // $R9
INST_CMDLINE, // $CMDLINE
INST_INSTDIR, // $INSTDIR
INST_OUTDIR, // $OUTDIR
INST_EXEDIR, // $EXEDIR
__INST_LAST
};
HANDLE hModule;
HWND g_parent;
HWND g_dialog;
HWND g_childwnd;
int g_stringsize;
stack_t **g_stacktop;
char *g_variables;
static int g_cancelled;
BOOL CALLBACK DownloadDialogProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
return 0;
}
static void *lpWndProcOld;
static LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_COMMAND && LOWORD(wParam) == IDCANCEL)
{
g_cancelled = 1;
return 0;
}
return CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam);
}
BOOL APIENTRY DllMain( HANDLE _hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
hModule = _hModule;
JNL::open_socketlib ();
break;
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
JNL::close_socketlib ();
break;
}
return TRUE;
}
static int g_file_size;
static void progress_callback(char *msg, int read_bytes)
{
if (g_dialog)
{
HWND hwndProgressBar = GetDlgItem (g_dialog, IDC_PROGRESS1);
SetDlgItemText (g_dialog, IDC_STATIC2, msg);
if (g_file_size) SendMessage(hwndProgressBar, PBM_SETPOS, (WPARAM)MulDiv(read_bytes,30000,g_file_size), 0);
}
}
static int getProxyInfo(char *out)
{
DWORD v=0;
HKEY hKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",0,KEY_READ,&hKey) == ERROR_SUCCESS)
{
DWORD l = 4;
DWORD t;
if (RegQueryValueEx(hKey,"ProxyEnable",NULL,&t,(unsigned char *)&v,&l) == ERROR_SUCCESS && t == REG_DWORD)
{
l=8192;
if (RegQueryValueEx(hKey,"ProxyServer",NULL,&t,(unsigned char *)out,&l ) != ERROR_SUCCESS || t != REG_SZ)
{
v=0;
*out=0;
}
}
else v=0;
out[8192-1]=0;
RegCloseKey(hKey);
}
return v;
}
extern char *_strstr(char *i, char *s);
static
void downloadFile(char *url,
HANDLE hFile,
char **error)
{
static char buf[8192];
char *p=NULL;
if (getProxyInfo(buf))
{
p=_strstr(buf,"http=");
if (!p) p=buf;
else
{
p+=5;
char *tp=_strstr(p,";");
if (tp) *tp=0;
}
}
DWORD start_time=GetTickCount();
JNL_HTTPGet *get=new JNL_HTTPGet(JNL_CONNECTION_AUTODNS,16384,(p&&p[0])?p:NULL);
int st;
int has_printed_headers = 0;
int cl;
int len;
int sofar = 0;
get->addheader ("User-Agent: NSISDL/1.1 (Mozilla)");
get->addheader ("Accept: */*");
get->connect (url);
while (1) {
if (g_dialog)
{
MSG msg;
while (PeekMessage(&msg,g_dialog,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Sleep(25);
if (g_cancelled) break;
st = get->run ();
if (st == -1) {
*error=get->geterrorstr();
break;
} else if (st == 1) {
if (sofar < cl)
*error="download incomplete";
break;
} else {
if (get->get_status () == 0) {
// progressFunc ("Connecting ...", 0);
} else if (get->get_status () == 1) {
progress_callback("Reading headers", 0);
} else if (get->get_status () == 2) {
if (! has_printed_headers) {
has_printed_headers = 1;
cl = get->content_length ();
if (cl == 0) {
*error = "Server did not specify content length.";
break;
} else if (g_dialog) {
HWND hwndProgressBar = GetDlgItem (g_dialog, IDC_PROGRESS1);
SendMessage(hwndProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0,30000));
g_file_size=cl;
}
}
while ((len = get->bytes_available ()) > 0) {
if (len > 8192)
len = 8192;
len = get->get_bytes (buf, len);
if (len > 0) {
DWORD dw;
WriteFile(hFile,buf,len,&dw,NULL);
sofar += len;
int time_sofar=(GetTickCount()-start_time)/1000;
int bps=sofar/(time_sofar?time_sofar:1);
int remain=MulDiv(time_sofar,cl,sofar) - time_sofar;
char *rtext="second";
if (remain >= 60)
{
remain/=60;
rtext="minute";
if (remain >= 60)
{
remain/=60;
rtext="hour";
}
}
wsprintf (buf,
"%dkB (%d%%) of %dkB @ %d.%01dkB/s",
sofar/1024,
MulDiv(100,sofar,cl),
cl/1024,
bps/1024,((bps*10)/1024)%10
);
if (remain) wsprintf(buf+lstrlen(buf)," (%d %s%s remaining)",
remain,
rtext,
remain==1?"":"s"
);
progress_callback(buf, sofar);
} else {
if (sofar < cl)
*error = "Server aborted.";
break;
}
}
} else {
*error = "Bad response status.";
break;
}
}
}
if (*error)
{
char *t=*error;
*error = (char *)GlobalAlloc(GPTR,strlen(t)+1);
lstrcpy(*error,t);
}
delete get;
}
extern "C"
{
__declspec(dllexport) void download (HWND parent,
int stringsize,
char *variables,
stack_t **stacktop)
{
static char buf[1024];
static char url[1024];
static char filename[1024];
int wasen=0;
HWND hwndL=0;
HWND hwndB=0;
g_parent = parent;
g_stringsize = stringsize;
g_variables = variables;
g_stacktop = stacktop;
popstring (filename);
popstring (url);
HANDLE hFile = CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL);
if (hFile == INVALID_HANDLE_VALUE) {
wsprintf (buf, "Unable to open %s", filename);
setuservariable(INST_0, buf);
} else {
if (g_parent)
{
g_childwnd=FindWindowEx(g_parent,NULL,"#32770",NULL);
hwndL=GetDlgItem(g_childwnd,1016);
hwndB=GetDlgItem(g_childwnd,1027);
if (hwndL && IsWindowVisible(hwndL)) ShowWindow(hwndL,SW_HIDE);
else hwndL=NULL;
if (hwndB && IsWindowVisible(hwndB)) ShowWindow(hwndB,SW_HIDE);
else hwndB=NULL;
wasen=EnableWindow(GetDlgItem(g_parent,IDCANCEL),1);
lpWndProcOld = (void *) GetWindowLong(g_parent,GWL_WNDPROC);
SetWindowLong(g_parent,GWL_WNDPROC,(long)ParentWndProc);
g_dialog = CreateDialog((HINSTANCE)hModule,
MAKEINTRESOURCE(IDD_DIALOG1),
g_childwnd,
DownloadDialogProc);
if (g_dialog)
{
RECT r;
GetWindowRect(GetDlgItem(g_childwnd,1016),&r);
ScreenToClient(g_childwnd,(LPPOINT)&r);
SetWindowPos(g_dialog,0,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
ShowWindow(g_dialog,SW_SHOWNA);
char *p=filename;
while (*p) p++;
while (*p != '\\' && p != filename) p=CharPrev(filename,p);
wsprintf(buf,"Downloading %s", p+1);
SetDlgItemText(g_childwnd,1006,buf);
wsprintf(buf,"Connecting ...");
SetDlgItemText (g_dialog, IDC_STATIC2, buf);
}
}
char *error=NULL;
downloadFile(url, hFile, &error);
CloseHandle(hFile);
if (g_parent)
{
if (g_dialog) DestroyWindow(g_dialog);
if (lpWndProcOld)
SetWindowLong(g_parent,GWL_WNDPROC,(long)lpWndProcOld);
if (g_childwnd)
{
if (hwndB) ShowWindow(hwndB,SW_SHOWNA);
if (hwndL) ShowWindow(hwndL,SW_SHOWNA);
}
if (wasen) EnableWindow(GetDlgItem(g_parent,IDCANCEL),0);
}
if (g_cancelled) {
setuservariable(INST_0, "cancel");
DeleteFile(filename);
} else if (error == NULL) {
setuservariable(INST_0, "success");
} else {
DeleteFile(filename);
setuservariable(INST_0, error);
}
if (error) GlobalFree(error);
}
}
__declspec(dllexport) void download_quiet(HWND parent,
int stringsize,
char *variables,
stack_t **stacktop)
{
download(NULL,stringsize,variables,stacktop);
}
}
// utility functions (not required but often useful)
static
int popstring(char *str)
{
stack_t *th;
if (!g_stacktop || !*g_stacktop) return 1;
th=(*g_stacktop);
lstrcpy(str,th->text);
*g_stacktop = th->next;
GlobalFree((HGLOBAL)th);
return 0;
}
static
void setuservariable(int varnum, char *var)
{
if (var != NULL && varnum >= 0 && varnum < __INST_LAST) {
lstrcpy (g_variables + varnum*g_stringsize, var);
}
}

152
Contrib/NSISdl/nsisdl.dsp Normal file
View file

@ -0,0 +1,152 @@
# Microsoft Developer Studio Project File - Name="nsisdl" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=nsisdl - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "nsisdl.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "nsisdl.mak" CFG="nsisdl - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "nsisdl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "nsisdl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "nsisdl - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NSISDL_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NSISDL_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /entry:"DllMain" /dll /machine:I386 /nodefaultlib /out:"../../nsisdl.dll" /opt:nowin98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "nsisdl - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NSISDL_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NSISDL_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "nsisdl - Win32 Release"
# Name "nsisdl - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\asyncdns.cpp
# End Source File
# Begin Source File
SOURCE=.\connection.cpp
# End Source File
# Begin Source File
SOURCE=.\httpget.cpp
# End Source File
# Begin Source File
SOURCE=.\nsisdl.cpp
# End Source File
# Begin Source File
SOURCE=.\Script1.rc
# End Source File
# Begin Source File
SOURCE=.\util.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\asyncdns.h
# End Source File
# Begin Source File
SOURCE=.\connection.h
# End Source File
# Begin Source File
SOURCE=.\httpget.h
# End Source File
# Begin Source File
SOURCE=.\netinc.h
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File
SOURCE=.\util.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

29
Contrib/NSISdl/nsisdl.dsw Normal file
View file

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "nsisdl"=.\nsisdl.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

19
Contrib/NSISdl/resource.h Normal file
View file

@ -0,0 +1,19 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Script1.rc
//
#define IDD_DIALOG1 101
#define IDC_PROGRESS1 1001
#define IDC_STATIC1 1002
#define IDC_STATIC2 1003
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1004
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

64
Contrib/NSISdl/util.cpp Normal file
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++;
}

41
Contrib/NSISdl/util.h Normal file
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_