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:
parent
9b3b220a13
commit
3e9e73ec59
177 changed files with 37677 additions and 0 deletions
59
Contrib/NSISdl/ReadMe.txt
Normal file
59
Contrib/NSISdl/ReadMe.txt
Normal 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
78
Contrib/NSISdl/Script1.rc
Normal 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
|
||||
|
78
Contrib/NSISdl/asyncdns.cpp
Normal file
78
Contrib/NSISdl/asyncdns.cpp
Normal 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
38
Contrib/NSISdl/asyncdns.h
Normal 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_
|
447
Contrib/NSISdl/connection.cpp
Normal file
447
Contrib/NSISdl/connection.cpp
Normal 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
135
Contrib/NSISdl/connection.h
Normal 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
471
Contrib/NSISdl/httpget.cpp
Normal 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
109
Contrib/NSISdl/httpget.h
Normal 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
82
Contrib/NSISdl/netinc.h
Normal 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
448
Contrib/NSISdl/nsisdl.cpp
Normal 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
152
Contrib/NSISdl/nsisdl.dsp
Normal 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
29
Contrib/NSISdl/nsisdl.dsw
Normal 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
19
Contrib/NSISdl/resource.h
Normal 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
64
Contrib/NSISdl/util.cpp
Normal 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
41
Contrib/NSISdl/util.h
Normal 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_
|
Loading…
Add table
Add a link
Reference in a new issue