use gntppp instead of gntp-send

This commit is contained in:
Patrick von Reth 2011-07-19 18:18:30 +02:00
parent 9d97249ef6
commit ea8ab89e8e
22 changed files with 259 additions and 1769 deletions

View File

@ -1,23 +0,0 @@
if(WITH_GROWL_BACKEND)
add_definitions("-DGROWL_CPP_STATIC -DGROWL_STATIC")
if( WIN32 )
link_libraries ( ws2_32 )
if(MSVC)
add_definitions("-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 -D_CRT_NONSTDC_NO_WARNINGS")
endif(MSVC)
endif( WIN32 )
set( GROWL_SEND_SRC
gntp-send/source/growl.c
gntp-send/source/tcp.c
gntp-send/source/md5.c )
add_library( growl STATIC ${GROWL_SEND_SRC} )
add_library( growl_cpp STATIC gntp-send/source/growl++.cpp)
target_link_libraries ( growl_cpp growl)
endif(WITH_GROWL_BACKEND)

View File

@ -1,47 +0,0 @@
cmake_minimum_required( VERSION 2.6 )
option(WITH_STATIC "Build static growl library" OFF)
include_directories ( ./headers )
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wnon-virtual-dtor -fno-strict-aliasing")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_RELWITHDEBUGINFO "-g -O2 ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "-g -ggdb -fno-reorder-blocks -fno-schedule-insns -fno-inline ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUGFULL "-g3 ${CMAKE_CXX_FLAGS_DEBUG}")
endif(CMAKE_COMPILER_IS_GNUCXX)
if( WIN32 )
link_libraries ( ws2_32 )
endif( WIN32 )
set( GROWL_NTP_C_SRC
source/growl.c
source/tcp.c
source/md5.c )
add_library( growl SHARED ${GROWL_NTP_C_SRC} )
set_target_properties( growl PROPERTIES COMPILE_FLAGS "-DGROWL_DLL" )
if( WITH_STATIC )
add_library( growl-static STATIC ${GROWL_NTP_C_SRC} )
set_target_properties( growl-static PROPERTIES COMPILE_FLAGS "-DGROWL_DLL" )
endif( WITH_STATIC )
add_library( growl++ SHARED source/growl++.cpp )
target_link_libraries ( growl++ growl)
set_target_properties( growl++ PROPERTIES COMPILE_FLAGS "-DGROWL_CPP_DLL" )
if( WITH_STATIC )
add_library( growl++-static STATIC source/growl++.cpp )
target_link_libraries ( growl++-static growl)
set_target_properties( growl++-static PROPERTIES COMPILE_FLAGS "-DGROWL_CPP_DLL" )
endif( WITH_STATIC )
add_executable( gntp-send source/gntp-send.c )
target_link_libraries ( gntp-send growl)
add_executable( gntp-send++ source/gntp-send++.cpp )
target_link_libraries ( gntp-send++ growl growl++)

View File

@ -1,26 +0,0 @@
[The "BSD licence"]
Copyright (c) 2009-2010 Yasuhiro Matsumoto
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,3 +0,0 @@
Limited documentation available in the wiki.
http://wiki.github.com/psinnott/gntp-send

View File

@ -1,35 +0,0 @@
#include <stdio.h>
#ifdef _WIN32
#ifndef GROWL_CPP_STATIC
#ifdef GROWL_CPP_DLL
#define GROWL_CPP_EXPORT __declspec(dllexport)
#else
#define GROWL_CPP_EXPORT __declspec(dllimport)
#endif
#else
#define GROWL_CPP_EXPORT
#endif
#else
#define GROWL_CPP_EXPORT
#endif //_WIN32
enum Growl_Protocol { GROWL_UDP , GROWL_TCP };
class GROWL_CPP_EXPORT Growl
{
private:
char *server;
char *password;
char *application;
Growl_Protocol protocol;
void Register(const char **const _notifications, const int _notifications_count, const char* const icon = NULL );
public:
Growl(const Growl_Protocol _protocol, const char *const _password, const char* const _appliciation, const char **const _notifications, const int _notifications_count);
Growl(const Growl_Protocol _protocol, const char *const _server, const char *const _password, const char *const _application, const char **const _notifications, const int _notifications_count);
~Growl();
void Notify(const char *const notification, const char *const title, const char* const message);
void Notify(const char *const notification, const char *const title, const char* const message, const char *const url, const char *const icon);
};

View File

@ -1,46 +0,0 @@
#ifndef _GROWL_H_
#define _GROWL_H_
#ifdef _WIN32
#ifndef GROWL_STATIC
#ifdef GROWL_DLL
#define GROWL_EXPORT __declspec(dllexport)
#else
#define GROWL_EXPORT __declspec(dllimport)
#endif
#else
#define GROWL_EXPORT
#endif
#else
#define GROWL_EXPORT
#endif //_WIN32
#ifdef __cplusplus
extern "C" {
#endif
GROWL_EXPORT int growl( const char *const server,const char *const appname,const char *const notify,const char *const title, const char *const message ,
const char *const icon , const char *const password , const char *url );
GROWL_EXPORT int growl_tcp_notify( const char *const server,const char *const appname,const char *const notify,const char *const title, const char *const message ,
const char *const password, const char* const url, const char* const icon );
GROWL_EXPORT int growl_tcp_register( const char *const server , const char *const appname , const char **const notifications , const int notifications_count , const char *const password, const char *const icon );
GROWL_EXPORT int growl_udp( const char *const server,const char *const appname,const char *const notify,const char *const title, const char *const message ,
const char *const icon , const char *const password , const char *url );
GROWL_EXPORT int growl_udp_notify( const char *const server,const char *const appname,const char *const notify,const char *const title, const char *const message ,
const char *const password );
GROWL_EXPORT int growl_udp_register( const char *const server , const char *const appname , const char **const notifications , const int notifications_count , const char *const password );
GROWL_EXPORT int growl_init(void);
GROWL_EXPORT void growl_shutdown(void);
#ifdef __cplusplus
}
#endif
#endif /* _GROWL_H_ */

View File

@ -1,22 +0,0 @@
#ifndef _MD5_H_
#define _MD5_H_
#ifdef _MSC_VER
#include <msinttypes/stdint.h>
#else
#include <stdint.h>
#endif
typedef struct {
uint32_t total[2];
uint32_t state[4];
uint8_t buffer[64];
} md5_context;
void md5_starts(md5_context *ctx);
void md5_update(md5_context *ctx, const uint8_t *input, uint32_t length);
void md5_finish(md5_context *ctx, uint8_t digest[16]);
#endif /* _MD5_H_ */

View File

@ -1,305 +0,0 @@
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_INTTYPES_H_ // [
#define _MSC_INTTYPES_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <stdint.h>
// 7.8 Format conversion of integer types
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
// 7.8.1 Macros for format specifiers
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
// The fprintf macros for signed integers are:
#define PRId8 "d"
#define PRIi8 "i"
#define PRIdLEAST8 "d"
#define PRIiLEAST8 "i"
#define PRIdFAST8 "d"
#define PRIiFAST8 "i"
#define PRId16 "hd"
#define PRIi16 "hi"
#define PRIdLEAST16 "hd"
#define PRIiLEAST16 "hi"
#define PRIdFAST16 "hd"
#define PRIiFAST16 "hi"
#define PRId32 "I32d"
#define PRIi32 "I32i"
#define PRIdLEAST32 "I32d"
#define PRIiLEAST32 "I32i"
#define PRIdFAST32 "I32d"
#define PRIiFAST32 "I32i"
#define PRId64 "I64d"
#define PRIi64 "I64i"
#define PRIdLEAST64 "I64d"
#define PRIiLEAST64 "I64i"
#define PRIdFAST64 "I64d"
#define PRIiFAST64 "I64i"
#define PRIdMAX "I64d"
#define PRIiMAX "I64i"
#define PRIdPTR "Id"
#define PRIiPTR "Ii"
// The fprintf macros for unsigned integers are:
#define PRIo8 "o"
#define PRIu8 "u"
#define PRIx8 "x"
#define PRIX8 "X"
#define PRIoLEAST8 "o"
#define PRIuLEAST8 "u"
#define PRIxLEAST8 "x"
#define PRIXLEAST8 "X"
#define PRIoFAST8 "o"
#define PRIuFAST8 "u"
#define PRIxFAST8 "x"
#define PRIXFAST8 "X"
#define PRIo16 "ho"
#define PRIu16 "hu"
#define PRIx16 "hx"
#define PRIX16 "hX"
#define PRIoLEAST16 "ho"
#define PRIuLEAST16 "hu"
#define PRIxLEAST16 "hx"
#define PRIXLEAST16 "hX"
#define PRIoFAST16 "ho"
#define PRIuFAST16 "hu"
#define PRIxFAST16 "hx"
#define PRIXFAST16 "hX"
#define PRIo32 "I32o"
#define PRIu32 "I32u"
#define PRIx32 "I32x"
#define PRIX32 "I32X"
#define PRIoLEAST32 "I32o"
#define PRIuLEAST32 "I32u"
#define PRIxLEAST32 "I32x"
#define PRIXLEAST32 "I32X"
#define PRIoFAST32 "I32o"
#define PRIuFAST32 "I32u"
#define PRIxFAST32 "I32x"
#define PRIXFAST32 "I32X"
#define PRIo64 "I64o"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#define PRIX64 "I64X"
#define PRIoLEAST64 "I64o"
#define PRIuLEAST64 "I64u"
#define PRIxLEAST64 "I64x"
#define PRIXLEAST64 "I64X"
#define PRIoFAST64 "I64o"
#define PRIuFAST64 "I64u"
#define PRIxFAST64 "I64x"
#define PRIXFAST64 "I64X"
#define PRIoMAX "I64o"
#define PRIuMAX "I64u"
#define PRIxMAX "I64x"
#define PRIXMAX "I64X"
#define PRIoPTR "Io"
#define PRIuPTR "Iu"
#define PRIxPTR "Ix"
#define PRIXPTR "IX"
// The fscanf macros for signed integers are:
#define SCNd8 "d"
#define SCNi8 "i"
#define SCNdLEAST8 "d"
#define SCNiLEAST8 "i"
#define SCNdFAST8 "d"
#define SCNiFAST8 "i"
#define SCNd16 "hd"
#define SCNi16 "hi"
#define SCNdLEAST16 "hd"
#define SCNiLEAST16 "hi"
#define SCNdFAST16 "hd"
#define SCNiFAST16 "hi"
#define SCNd32 "ld"
#define SCNi32 "li"
#define SCNdLEAST32 "ld"
#define SCNiLEAST32 "li"
#define SCNdFAST32 "ld"
#define SCNiFAST32 "li"
#define SCNd64 "I64d"
#define SCNi64 "I64i"
#define SCNdLEAST64 "I64d"
#define SCNiLEAST64 "I64i"
#define SCNdFAST64 "I64d"
#define SCNiFAST64 "I64i"
#define SCNdMAX "I64d"
#define SCNiMAX "I64i"
#ifdef _WIN64 // [
# define SCNdPTR "I64d"
# define SCNiPTR "I64i"
#else // _WIN64 ][
# define SCNdPTR "ld"
# define SCNiPTR "li"
#endif // _WIN64 ]
// The fscanf macros for unsigned integers are:
#define SCNo8 "o"
#define SCNu8 "u"
#define SCNx8 "x"
#define SCNX8 "X"
#define SCNoLEAST8 "o"
#define SCNuLEAST8 "u"
#define SCNxLEAST8 "x"
#define SCNXLEAST8 "X"
#define SCNoFAST8 "o"
#define SCNuFAST8 "u"
#define SCNxFAST8 "x"
#define SCNXFAST8 "X"
#define SCNo16 "ho"
#define SCNu16 "hu"
#define SCNx16 "hx"
#define SCNX16 "hX"
#define SCNoLEAST16 "ho"
#define SCNuLEAST16 "hu"
#define SCNxLEAST16 "hx"
#define SCNXLEAST16 "hX"
#define SCNoFAST16 "ho"
#define SCNuFAST16 "hu"
#define SCNxFAST16 "hx"
#define SCNXFAST16 "hX"
#define SCNo32 "lo"
#define SCNu32 "lu"
#define SCNx32 "lx"
#define SCNX32 "lX"
#define SCNoLEAST32 "lo"
#define SCNuLEAST32 "lu"
#define SCNxLEAST32 "lx"
#define SCNXLEAST32 "lX"
#define SCNoFAST32 "lo"
#define SCNuFAST32 "lu"
#define SCNxFAST32 "lx"
#define SCNXFAST32 "lX"
#define SCNo64 "I64o"
#define SCNu64 "I64u"
#define SCNx64 "I64x"
#define SCNX64 "I64X"
#define SCNoLEAST64 "I64o"
#define SCNuLEAST64 "I64u"
#define SCNxLEAST64 "I64x"
#define SCNXLEAST64 "I64X"
#define SCNoFAST64 "I64o"
#define SCNuFAST64 "I64u"
#define SCNxFAST64 "I64x"
#define SCNXFAST64 "I64X"
#define SCNoMAX "I64o"
#define SCNuMAX "I64u"
#define SCNxMAX "I64x"
#define SCNXMAX "I64X"
#ifdef _WIN64 // [
# define SCNoPTR "I64o"
# define SCNuPTR "I64u"
# define SCNxPTR "I64x"
# define SCNXPTR "I64X"
#else // _WIN64 ][
# define SCNoPTR "lo"
# define SCNuPTR "lu"
# define SCNxPTR "lx"
# define SCNXPTR "lX"
#endif // _WIN64 ]
#endif // __STDC_FORMAT_MACROS ]
// 7.8.2 Functions for greatest-width integer types
// 7.8.2.1 The imaxabs function
#define imaxabs _abs64
// 7.8.2.2 The imaxdiv function
// This is modified version of div() function from Microsoft's div.c found
// in %MSVC.NET%\crt\src\div.c
#ifdef STATIC_IMAXDIV // [
static
#else // STATIC_IMAXDIV ][
_inline
#endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
{
imaxdiv_t result;
result.quot = numer / denom;
result.rem = numer % denom;
if (numer < 0 && result.rem > 0) {
// did division wrong; must fix up
++result.quot;
result.rem -= denom;
}
return result;
}
// 7.8.2.3 The strtoimax and strtoumax functions
#define strtoimax _strtoi64
#define strtoumax _strtoui64
// 7.8.2.4 The wcstoimax and wcstoumax functions
#define wcstoimax _wcstoi64
#define wcstoumax _wcstoui64
#endif // _MSC_INTTYPES_H_ ]

View File

@ -1,247 +0,0 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]

View File

@ -1,13 +0,0 @@
#ifndef _TCP_H_
#define _TCP_H_
#ifdef _MSC_VER
#define __attribute__(x)
#endif
void growl_tcp_write( int sock , const char *const format , ... ) __attribute__ ((format (printf, 2, 3)));
char* growl_tcp_read(int sock);
int growl_tcp_open(const char* server);
void growl_tcp_close(int sock);
int growl_tcp_datagram( const char *server , const unsigned char *data , const int data_length );
#endif /* _TCP_H_ */

View File

@ -1,12 +0,0 @@
#include <growl++.hpp>
int main(int argc, char **argv)
{
const char *n[2] = { "alice" , "bob" };
Growl *growl = new Growl(GROWL_TCP,NULL,"gntp_send++",(const char **const)n,2);
growl->Notify("bob","title","message");
delete(growl);
return 0;
}

View File

@ -1,137 +0,0 @@
#ifdef _WIN32
#include <winsock2.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "md5.h"
#include "tcp.h"
#include "growl.h"
static char* string_to_utf8_alloc(const char* str) {
#ifdef _WIN32
unsigned int codepage;
size_t in_len = strlen(str);
wchar_t* wcsdata;
char* mbsdata;
size_t mbssize, wcssize;
codepage = GetACP();
wcssize = MultiByteToWideChar(codepage, 0, str, in_len, NULL, 0);
wcsdata = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t));
wcssize = MultiByteToWideChar(codepage, 0, str, in_len, wcsdata, wcssize + 1);
wcsdata[wcssize] = 0;
mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsdata, -1, NULL, 0, NULL, NULL);
mbsdata = (char*) malloc((mbssize + 1));
mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsdata, -1, mbsdata, mbssize, NULL, NULL);
mbsdata[mbssize] = 0;
free(wcsdata);
return mbsdata;
#else
return strdup(str);
#endif
}
int opterr = 1;
int optind = 1;
int optopt;
char *optarg;
int getopts(int argc, char** argv, char* opts) {
static int sp = 1;
register int c;
register char *cp;
if(sp == 1) {
if(optind >= argc ||
argv[optind][0] != '-' || argv[optind][1] == '\0')
return(EOF);
else if(strcmp(argv[optind], "--") == 0) {
optind++;
return(EOF);
}
}
optopt = c = argv[optind][sp];
if(c == ':' || (cp=strchr(opts, c)) == NULL) {
if(argv[optind][++sp] == '\0') {
optind++;
sp = 1;
}
return('?');
}
if(*++cp == ':') {
if(argv[optind][sp+1] != '\0')
optarg = &argv[optind++][sp+1];
else if(++optind >= argc) {
sp = 1;
return('?');
} else
optarg = argv[optind++];
sp = 1;
} else {
if(argv[optind][++sp] == '\0') {
sp = 1;
optind++;
}
optarg = NULL;
}
return(c);
}
int main(int argc, char* argv[]) {
int c;
int rc;
char* server = NULL;
char* password = NULL;
char* appname = "gntp-send";
char* notify = "gntp-send notify";
char* title = NULL;
char* message = NULL;
char* icon = NULL;
char* url = NULL;
int tcpsend = 1;
opterr = 0;
while ((c = getopts(argc, argv, "a:n:s:p:u") != -1)) {
switch (optopt) {
case 'a': appname = optarg; break;
case 'n': notify = optarg; break;
case 's': server = optarg; break;
case 'p': password = optarg; break;
case 'u': tcpsend = 0; break;
case '?': break;
default: argc = 0; break;
}
optarg = NULL;
}
if ((argc - optind) < 2 || (argc - optind) > 4) {
fprintf(stderr, "%s: [-u] [-a APPNAME] [-n NOTIFY] [-s SERVER:PORT] [-p PASSWORD] title message [icon] [url]\n", argv[0]);
exit(1);
}
title = string_to_utf8_alloc(argv[optind]);
message = string_to_utf8_alloc(argv[optind + 1]);
if ((argc - optind) >= 3) icon = string_to_utf8_alloc(argv[optind + 2]);
if ((argc - optind) == 4) url = string_to_utf8_alloc(argv[optind + 3]);
if (!server) server = "127.0.0.1";
growl_init();
if (tcpsend) {
rc = growl(server,appname,notify,title,message,icon,password,url);
} else {
rc = growl_udp(server,appname,notify,title,message,icon,password,url);
}
growl_shutdown();
if (title) free(title);
if (message) free(message);
if (icon) free(icon);
if (url) free(url);
return rc;
}

View File

@ -1,74 +0,0 @@
#include <growl++.hpp>
#include <growl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
Growl::Growl(const Growl_Protocol _protocol, const char *const _password, const char *const _application, const char **_notifications, const int _notifications_count)
{
server = strdup("localhost");
password = strdup(_password);
protocol = _protocol;
application = strdup(_application);
Register(_notifications, _notifications_count);
}
Growl::Growl(const Growl_Protocol _protocol, const char *const _server, const char *const _password, const char *const _application, const char **_notifications, const int _notifications_count )
{
server = strdup(_server);
password = strdup(_password);
protocol = _protocol;
application = strdup(_application);
Register(_notifications, _notifications_count);
}
void Growl::Register(const char **const notifications, const int notifications_count , const char *const icon )
{
if( protocol == GROWL_TCP )
{
growl_tcp_register( server , application , notifications , notifications_count , password , icon );
}
else
{
growl_udp_register( server , application , notifications , notifications_count , password );
}
}
Growl::~Growl()
{
if(server != NULL)
{
free(server);
}
if(password != NULL)
{
free(password);
}
if(application == NULL)
{
free(application);
}
}
void Growl::Notify(const char *const notification, const char *const title, const char* const message)
{
Growl::Notify(notification, title, message, NULL, NULL);
}
void Growl::Notify(const char *const notification, const char *const title, const char* const message, const char *const url, const char *const icon)
{
if( protocol == GROWL_TCP )
{
growl_tcp_notify( server , application , notification , title , message , password , url , icon );
}
else
{
growl_udp_notify( server , application , notification , title , message , password );
}
}

View File

@ -1,390 +0,0 @@
#ifdef _WIN32
#include <windows.h>
#else
#include <arpa/inet.h>
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "md5.h"
#include "tcp.h"
#include "growl.h"
static const char hex_table[] = "0123456789ABCDEF";
static char* string_to_hex_alloc(const char* str, int len) {
int n, l;
char* tmp = (char*)malloc(len * 2 + 1);
memset(tmp, 0, len * 2 + 1);
for (l = 0, n = 0; l < len; l++) {
tmp[n++] = hex_table[(str[l] & 0xF0) >> 4];
tmp[n++] = hex_table[str[l] & 0x0F];
}
return tmp;
}
int growl_init_ = 0;
int growl_init()
{
if( growl_init_ == 0)
{
#ifdef _WIN32
WSADATA wsaData;
if( WSAStartup( MAKEWORD( 2 , 0 ) , &wsaData) != 0 )
{
return -1;
}
#endif
srand(time(NULL));
growl_init_ = 1;
}
return 1;
}
void growl_shutdown()
{
if( growl_init_ == 1 )
{
#ifdef _WIN32
WSACleanup();
#endif
}
}
char* gen_salt_alloc(int count) {
char* salt = (char*)malloc(count + 1);
int n;
for (n = 0; n < count; n++) salt[n] = (((int)rand()) % 255) + 1;
salt[n] = 0;
return salt;
}
char* gen_password_hash_alloc(const char* password, const char* salt) {
md5_context md5ctx;
char md5tmp[20];
char* md5digest;
memset(md5tmp, 0, sizeof(md5tmp));
md5_starts(&md5ctx);
md5_update(&md5ctx, (uint8_t*)password, strlen(password));
md5_update(&md5ctx, (uint8_t*)salt, strlen(salt));
md5_finish(&md5ctx, (uint8_t*)md5tmp);
md5_starts(&md5ctx);
md5_update(&md5ctx, (uint8_t*)md5tmp, 16);
md5_finish(&md5ctx, (uint8_t*)md5tmp);
md5digest = string_to_hex_alloc(md5tmp, 16);
return md5digest;
}
char *growl_generate_authheader_alloc(const char*const password)
{
char* salt;
char* salthash;
char* keyhash;
char* authheader = NULL;
if (password) {
salt = gen_salt_alloc(8);
keyhash = gen_password_hash_alloc(password, salt);
salthash = string_to_hex_alloc(salt, 8);
free(salt);
authheader = (char*)malloc(strlen(keyhash) + strlen(salthash) + 7);
sprintf(authheader, " MD5:%s.%s", keyhash, salthash);
free(salthash);
free(keyhash);
}
return authheader;
}
int growl_tcp_register( const char *const server , const char *const appname , const char **const notifications , const int notifications_count ,
const char *const password, const char* const icon )
{
int sock = -1;
int i=0;
char *authheader;
growl_init();
authheader = growl_generate_authheader_alloc(password);
sock = growl_tcp_open(server);
if (sock == -1) goto leave;
growl_tcp_write(sock, "GNTP/1.0 REGISTER NONE %s", authheader ? authheader : "");
growl_tcp_write(sock, "Application-Name: %s ", appname);
if(icon) growl_tcp_write(sock, "Application-Icon: %s ", icon);
growl_tcp_write(sock, "Notifications-Count: %d", notifications_count);
growl_tcp_write(sock, "" );
for(i=0;i<notifications_count;i++)
{
growl_tcp_write(sock, "Notification-Name: %s", notifications[i]);
growl_tcp_write(sock, "Notification-Display-Name: %s", notifications[i]);
growl_tcp_write(sock, "Notification-Enabled: True" );
if(icon) growl_tcp_write(sock, "Notification-Icon: %s", icon);
growl_tcp_write(sock, "" );
}
while (1) {
char* line = growl_tcp_read(sock);
int len = strlen(line);
/* fprintf(stderr, "%s\n", line); */
if (strncmp(line, "GNTP/1.0 -ERROR", 15) == 0) {
fprintf(stderr, "failed to register notification\n");
free(line);
goto leave;
}
free(line);
if (len == 0) break;
}
growl_tcp_close(sock);
sock = 0;
leave:
if (authheader) free(authheader);
return (sock == 0) ? 0 : -1;
}
int growl_tcp_notify( const char *const server,const char *const appname,const char *const notify,const char *const title, const char *const message ,
const char *const password, const char* const url, const char* const icon)
{
int sock = -1;
char *authheader = growl_generate_authheader_alloc(password);
growl_init();
sock = growl_tcp_open(server);
if (sock == -1) goto leave;
growl_tcp_write(sock, "GNTP/1.0 NOTIFY NONE %s", authheader ? authheader : "");
growl_tcp_write(sock, "Application-Name: %s", appname);
growl_tcp_write(sock, "Notification-Name: %s", notify);
growl_tcp_write(sock, "Notification-Title: %s", title);
growl_tcp_write(sock, "Notification-Text: %s", message);
if (icon) growl_tcp_write(sock, "Notification-Icon: %s", icon);
if (url) growl_tcp_write(sock, "Notification-Callback-Target: %s", url );
growl_tcp_write(sock, "");
while (1) {
char* line = growl_tcp_read(sock);
int len = strlen(line);
/* fprintf(stderr, "%s\n", line); */
if (strncmp(line, "GNTP/1.0 -ERROR", 15) == 0) {
fprintf(stderr, "failed to post notification\n");
free(line);
goto leave;
}
free(line);
if (len == 0) break;
}
growl_tcp_close(sock);
sock = 0;
leave:
if (authheader) free(authheader);
return (sock == 0) ? 0 : -1;
}
int growl( const char *const server,const char *const appname,const char *const notify,const char *const title, const char *const message ,
const char *const icon , const char *const password , const char *url )
{
int rc = growl_tcp_register( server , appname , (const char **const)&notify , 1 , password, icon );
if( rc == 0 )
{
rc = growl_tcp_notify( server, appname, notify, title, message , password, url, icon );
}
return rc;
}
void growl_append_md5( unsigned char *const data , const int data_length , const char *const password )
{
md5_context md5ctx;
char md5tmp[20];
memset(md5tmp, 0, sizeof(md5tmp));
md5_starts(&md5ctx);
md5_update(&md5ctx, (uint8_t*)data, data_length );
if(password != NULL)
{
md5_update(&md5ctx, (uint8_t*)password, strlen(password));
}
md5_finish(&md5ctx, (uint8_t*)md5tmp);
memcpy( data + data_length , md5tmp , 16 );
}
int growl_udp_register( const char *const server , const char *const appname , const char **const notifications , const int notifications_count , const char *const password )
{
int register_header_length = 22+strlen(appname);
unsigned char *data;
int pointer = 0;
int rc = 0;
int i=0;
uint8_t GROWL_PROTOCOL_VERSION = 1;
uint8_t GROWL_TYPE_REGISTRATION = 0;
uint16_t appname_length = ntohs(strlen(appname));
uint8_t _notifications_count = notifications_count;
uint8_t default_notifications_count = notifications_count;
uint8_t j;
growl_init();
for(i=0;i<notifications_count;i++)
{
register_header_length += 3 + strlen(notifications[i]);
}
data = (unsigned char*)malloc(register_header_length);
memset( data , 0 , register_header_length );
pointer = 0;
memcpy( data + pointer , &GROWL_PROTOCOL_VERSION , 1 );
pointer++;
memcpy( data + pointer , &GROWL_TYPE_REGISTRATION , 1 );
pointer++;
memcpy( data + pointer , &appname_length , 2 );
pointer += 2;
memcpy( data + pointer , &_notifications_count , 1 );
pointer++;
memcpy( data + pointer, &default_notifications_count , 1 );
pointer++;
sprintf( (char*)data + pointer , "%s" , appname );
pointer += strlen(appname);
for(i=0;i<notifications_count;i++)
{
uint16_t notify_length = ntohs(strlen(notifications[i]));
memcpy( data + pointer, &notify_length , 2 );
pointer +=2;
sprintf( (char*)data + pointer , "%s" , notifications[i] );
pointer += strlen(notifications[i]);
}
for(j=0;j<notifications_count;j++)
{
memcpy( data + pointer , &j , 1 );
pointer++;
}
growl_append_md5( data , pointer , password );
pointer += 16;
rc = growl_tcp_datagram( server , data , pointer );
free(data);
return rc;
}
int growl_udp_notify( const char *const server,const char *const appname,const char *const notify,const char *const title, const char *const message ,
const char *const password )
{
int notify_header_length = 28 + strlen(appname)+strlen(notify)+strlen(message)+strlen(title);
unsigned char *data = (unsigned char*)malloc(notify_header_length);
int pointer = 0;
int rc = 0;
uint8_t GROWL_PROTOCOL_VERSION = 1;
uint8_t GROWL_TYPE_NOTIFICATION = 1;
uint16_t flags = ntohs(0);
uint16_t appname_length = ntohs(strlen(appname));
uint16_t notify_length = ntohs(strlen(notify));
uint16_t title_length = ntohs(strlen(title));
uint16_t message_length = ntohs(strlen(message));
growl_init();
memset( data , 0 , notify_header_length );
pointer = 0;
memcpy( data + pointer , &GROWL_PROTOCOL_VERSION , 1 );
pointer++;
memcpy( data + pointer , &GROWL_TYPE_NOTIFICATION , 1 );
pointer++;
memcpy( data + pointer , &flags , 2 );
pointer += 2;
memcpy( data + pointer , &notify_length , 2 );
pointer += 2;
memcpy( data + pointer , &title_length , 2 );
pointer += 2;
memcpy( data + pointer , &message_length , 2 );
pointer += 2;
memcpy( data + pointer , &appname_length , 2 );
pointer += 2;
sprintf( (char*)data + pointer , notify );
pointer += strlen(notify);
sprintf( (char*)data + pointer , title );
pointer += strlen(title);
sprintf( (char*)data + pointer , message );
pointer += strlen(message);
sprintf( (char*)data + pointer , appname );
pointer += strlen(appname);
growl_append_md5( data , pointer , password );
pointer += 16;
rc = growl_tcp_datagram( server , data , pointer );
free(data);
return rc;
}
int growl_udp( const char *const server,const char *const appname,const char *const notify,const char *const title, const char *const message ,
const char *const icon , const char *const password , const char *url )
{
int rc = growl_udp_register( server , appname , (const char **const)&notify , 1 , password );
if( rc == 0 )
{
rc = growl_udp_notify( server, appname, notify, title, message , password );
}
return rc;
}
#ifdef _WIN32
void GrowlNotify(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
char* server = "127.0.0.1:23053";
char* password = NULL;
char* appname = "gntp-send";
char* notify = "gntp-send notify";
char* title = NULL;
char* message = NULL;
char* icon = NULL;
char* url = NULL;
char* first = strdup(lpszCmdLine);
char* ptr = first;
int rc;
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) return;
#define SKIP(x) while (*x && *x != ' ') x++; if (*x == ' ') *x++ = 0;
server = ptr; SKIP(ptr);
appname = ptr; SKIP(ptr);
notify = ptr; SKIP(ptr);
title = ptr; SKIP(ptr);
message = ptr; SKIP(ptr);
icon = ptr; SKIP(ptr);
url = ptr; SKIP(ptr);
rc = growl(server,appname,notify,title,message,icon,password,url);
WSACleanup();
free(ptr);
}
#endif

View File

@ -1,7 +0,0 @@
EXPORTS
growl
growl_udp
growl_udp_register
growl_udp_notify
growl_tcp_register
growl_tcp_notify

View File

@ -1,202 +0,0 @@
#include <string.h>
#include "md5.h"
#define GET_UINT32(n, b, i) n = b[i] + (b[i+1]<<8) + (b[i+2]<<16) + (b[i+3]<<24)
#define PUT_UINT32(n, b, i) do { b[i] = n; b[i+1] = n >> 8; b[i+2] = n >> 16; b[i+3] = n >> 24; } while(0)
void md5_starts(md5_context *ctx) {
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
}
void md5_process(md5_context *ctx, const uint8_t data[64]) {
uint32_t X[16], A, B, C, D;
GET_UINT32(X[0], data, 0);
GET_UINT32(X[1], data, 4);
GET_UINT32(X[2], data, 8);
GET_UINT32(X[3], data, 12);
GET_UINT32(X[4], data, 16);
GET_UINT32(X[5], data, 20);
GET_UINT32(X[6], data, 24);
GET_UINT32(X[7], data, 28);
GET_UINT32(X[8], data, 32);
GET_UINT32(X[9], data, 36);
GET_UINT32(X[10], data, 40);
GET_UINT32(X[11], data, 44);
GET_UINT32(X[12], data, 48);
GET_UINT32(X[13], data, 52);
GET_UINT32(X[14], data, 56);
GET_UINT32(X[15], data, 60);
#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a, b, c, d, k, s, t) \
{ \
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x, y, z) (z ^ (x & (y ^ z)))
P(A, B, C, D, 0, 7, 0xD76AA478);
P(D, A, B, C, 1, 12, 0xE8C7B756);
P(C, D, A, B, 2, 17, 0x242070DB);
P(B, C, D, A, 3, 22, 0xC1BDCEEE);
P(A, B, C, D, 4, 7, 0xF57C0FAF);
P(D, A, B, C, 5, 12, 0x4787C62A);
P(C, D, A, B, 6, 17, 0xA8304613);
P(B, C, D, A, 7, 22, 0xFD469501);
P(A, B, C, D, 8, 7, 0x698098D8);
P(D, A, B, C, 9, 12, 0x8B44F7AF);
P(C, D, A, B, 10, 17, 0xFFFF5BB1);
P(B, C, D, A, 11, 22, 0x895CD7BE);
P(A, B, C, D, 12, 7, 0x6B901122);
P(D, A, B, C, 13, 12, 0xFD987193);
P(C, D, A, B, 14, 17, 0xA679438E);
P(B, C, D, A, 15, 22, 0x49B40821);
#undef F
#define F(x, y, z) (y ^ (z & (x ^ y)))
P(A, B, C, D, 1, 5, 0xF61E2562);
P(D, A, B, C, 6, 9, 0xC040B340);
P(C, D, A, B, 11, 14, 0x265E5A51);
P(B, C, D, A, 0, 20, 0xE9B6C7AA);
P(A, B, C, D, 5, 5, 0xD62F105D);
P(D, A, B, C, 10, 9, 0x02441453);
P(C, D, A, B, 15, 14, 0xD8A1E681);
P(B, C, D, A, 4, 20, 0xE7D3FBC8);
P(A, B, C, D, 9, 5, 0x21E1CDE6);
P(D, A, B, C, 14, 9, 0xC33707D6);
P(C, D, A, B, 3, 14, 0xF4D50D87);
P(B, C, D, A, 8, 20, 0x455A14ED);
P(A, B, C, D, 13, 5, 0xA9E3E905);
P(D, A, B, C, 2, 9, 0xFCEFA3F8);
P(C, D, A, B, 7, 14, 0x676F02D9);
P(B, C, D, A, 12, 20, 0x8D2A4C8A);
#undef F
#define F(x, y, z) (x ^ y ^ z)
P(A, B, C, D, 5, 4, 0xFFFA3942);
P(D, A, B, C, 8, 11, 0x8771F681);
P(C, D, A, B, 11, 16, 0x6D9D6122);
P(B, C, D, A, 14, 23, 0xFDE5380C);
P(A, B, C, D, 1, 4, 0xA4BEEA44);
P(D, A, B, C, 4, 11, 0x4BDECFA9);
P(C, D, A, B, 7, 16, 0xF6BB4B60);
P(B, C, D, A, 10, 23, 0xBEBFBC70);
P(A, B, C, D, 13, 4, 0x289B7EC6);
P(D, A, B, C, 0, 11, 0xEAA127FA);
P(C, D, A, B, 3, 16, 0xD4EF3085);
P(B, C, D, A, 6, 23, 0x04881D05);
P(A, B, C, D, 9, 4, 0xD9D4D039);
P(D, A, B, C, 12, 11, 0xE6DB99E5);
P(C, D, A, B, 15, 16, 0x1FA27CF8);
P(B, C, D, A, 2, 23, 0xC4AC5665);
#undef F
#define F(x, y, z) (y ^ (x | ~z))
P(A, B, C, D, 0, 6, 0xF4292244);
P(D, A, B, C, 7, 10, 0x432AFF97);
P(C, D, A, B, 14, 15, 0xAB9423A7);
P(B, C, D, A, 5, 21, 0xFC93A039);
P(A, B, C, D, 12, 6, 0x655B59C3);
P(D, A, B, C, 3, 10, 0x8F0CCC92);
P(C, D, A, B, 10, 15, 0xFFEFF47D);
P(B, C, D, A, 1, 21, 0x85845DD1);
P(A, B, C, D, 8, 6, 0x6FA87E4F);
P(D, A, B, C, 15, 10, 0xFE2CE6E0);
P(C, D, A, B, 6, 15, 0xA3014314);
P(B, C, D, A, 13, 21, 0x4E0811A1);
P(A, B, C, D, 4, 6, 0xF7537E82);
P(D, A, B, C, 11, 10, 0xBD3AF235);
P(C, D, A, B, 2, 15, 0x2AD7D2BB);
P(B, C, D, A, 9, 21, 0xEB86D391);
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
}
void md5_update(md5_context *ctx, const uint8_t *input, uint32_t length) {
uint32_t left, fill;
if (!length)
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += length;
ctx->total[0] &= 0xFFFFFFFF;
if (ctx->total[0] < length)
ctx->total[1]++;
if (left && length >= fill) {
memcpy((void *)(ctx->buffer + left), (const void *)input, fill);
md5_process(ctx, ctx->buffer);
length -= fill;
input += fill;
left = 0;
}
while (length >= 64) {
md5_process(ctx, input);
length -= 64;
input += 64;
}
if (length) {
memcpy((void *)(ctx->buffer + left), (const void *)input, length);
}
}
const uint8_t md5_padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
void md5_finish(md5_context *ctx, uint8_t digest[16]) {
uint32_t last, padn;
uint32_t high, low;
uint8_t msglen[8];
high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
low = (ctx->total[0] << 3);
PUT_UINT32(low, msglen, 0);
PUT_UINT32(high, msglen, 4);
last = ctx->total[0] & 0x3F;
padn = (last < 56) ? (56 - last) : (120 - last);
md5_update(ctx, md5_padding, padn);
md5_update(ctx, msglen, 8);
PUT_UINT32(ctx->state[0], digest, 0);
PUT_UINT32(ctx->state[1], digest, 4);
PUT_UINT32(ctx->state[2], digest, 8);
PUT_UINT32(ctx->state[3], digest, 12);
}

View File

@ -1,143 +0,0 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#endif
#include "tcp.h"
int growl_tcp_parse_hostname( const char *const server , int default_port , struct sockaddr_in *const sockaddr );
void growl_tcp_write( int sock , const char *const format , ... )
{
int length;
char *output;
va_list ap;
va_start( ap , format );
length = vsnprintf( NULL , 0 , format , ap );
va_end(ap);
va_start(ap,format);
output = (char*)malloc(length+1);
vsnprintf( output , length+1 , format , ap );
va_end(ap);
send( sock , output , length , 0 );
send( sock , "\r\n" , 2 , 0 );
free(output);
}
char *growl_tcp_read(int sock) {
const int growsize = 80;
char c = 0;
char* line = (char*) malloc(growsize);
int len = growsize, pos = 0;
while (line) {
if (recv(sock, &c, 1, 0) <= 0) break;
if (c == '\r') continue;
if (c == '\n') break;
line[pos++] = c;
if (pos >= len) {
len += growsize;
line = (char*) realloc(line, len);
}
}
line[pos] = 0;
return line;
}
int growl_tcp_open(const char* server) {
int sock = -1;
struct sockaddr_in serv_addr;
if( growl_tcp_parse_hostname( server , 23053 , &serv_addr ) == -1 )
{
return -1;
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("create socket");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("connect");
return -1;
}
return sock;
}
void growl_tcp_close(int sock) {
#ifdef _WIN32
if (sock > 0) closesocket(sock);
#else
if (sock > 0) close(sock);
#endif
}
int growl_tcp_parse_hostname( const char *const server , int default_port , struct sockaddr_in *const sockaddr )
{
char *hostname = strdup(server);
char *port = strchr( hostname, ':' );
struct hostent* host_ent;
if( port != NULL )
{
*port = '\0';
port++;
default_port = atoi(port);
}
host_ent = gethostbyname(hostname);
if( host_ent == NULL )
{
perror("gethostbyname");
free(hostname);
return -1;
}
memset( sockaddr , 0 , sizeof(sockaddr) );
sockaddr->sin_family = AF_INET;
memcpy( &sockaddr->sin_addr , host_ent->h_addr , host_ent->h_length );
sockaddr->sin_port = htons(default_port);
free(hostname);
return 0;
}
int growl_tcp_datagram( const char *server , const unsigned char *data , const int data_length )
{
struct sockaddr_in serv_addr;
int sock = 0;
if( growl_tcp_parse_hostname( server , 9887 , &serv_addr ) == -1 )
{
return -1;
}
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if( sock < 0 )
{
return -1;
}
if( sendto(sock, (char*)data , data_length , 0 , (struct sockaddr*)&serv_addr , sizeof(serv_addr) ) > 0 )
{
return 0;
}
else
{
return 1;
}
}

View File

@ -6,6 +6,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package( Qt4 REQUIRED )
find_package( Automoc4 REQUIRED)
find_package( CryptoPP )
find_package( Boost COMPONENTS system )
include( ${QT_USE_FILE} )
include_directories(
@ -48,7 +50,6 @@ set(PLUGIN_INSTALL_PATH LIBRARY DESTINATION bin/snoreplugins)
add_subdirectory(data)
add_subdirectory(share)
add_subdirectory(3party)
add_subdirectory(src)

View File

@ -1,15 +1,20 @@
if( WITH_GROWL_BACKEND )
message( STATUS "Found libgrowl, adding libgrowl backend" )
set( GROWL__SRC
growl_backend.cpp
)
if(CRYPTOPP_LIBRARIES AND Boost_SYSTEM_LIBRARY)
message( STATUS "Found libgrowl, adding libgrowl backend" )
set( GROWL__SRC
growl_backend.cpp
)
automoc4_add_library(growl_backend MODULE ${GROWL__SRC} )
target_link_libraries(growl_backend snorecore ${QT_QTCORE_LIBRARY} ${GROWL_CPP} growl_cpp )
set_target_properties( growl_backend PROPERTIES COMPILE_FLAGS "-DGROWL_CPP_STATIC -DGROWL_STATIC" )
install(TARGETS growl_backend ${PLUGIN_INSTALL_PATH})
automoc4_add_library(growl_backend MODULE ${GROWL__SRC} )
target_link_libraries(growl_backend snorecore ${QT_QTCORE_LIBRARY} ${CRYPTOPP_LIBRARIES} ${Boost_SYSTEM_LIBRARY} wsock32 ws2_32)
install(TARGETS growl_backend ${PLUGIN_INSTALL_PATH})
else(CRYPTOPP_LIBRARIES AND Boost_SYSTEM_LIBRARY)
if(NOT CRYPTOPP_LIBRARIES)
message(STATUS "Cant build the growl backend because the dependency Cryptopp is missing")
endif(NOT CRYPTOPP_LIBRARIES)
if(NOT Boost_SYSTEM_LIBRARY)
message(STATUS "Cant build the growl backend because the dependency BOOST_SYSTEM is missing")
endif(NOT Boost_SYSTEM_LIBRARY)
endif(CRYPTOPP_LIBRARIES AND Boost_SYSTEM_LIBRARY)
endif( WITH_GROWL_BACKEND )

223
src/plugins/growl/gntp.h Normal file
View File

@ -0,0 +1,223 @@
#ifndef gntp_h
#define gntp_h
//#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 0
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <cryptopp/osrng.h>
#include <cryptopp/files.h>
#include <cryptopp/hex.h>
#include <cryptopp/sha.h>
#include <cryptopp/md5.h>
#include <cryptopp/des.h>
#include <cryptopp/aes.h>
#include <cryptopp/filters.h>
#include <cryptopp/modes.h>
#include <boost/asio.hpp>
class gntp {
private:
static inline std::string to_hex(CryptoPP::SecByteBlock& in) {
std::string out;
CryptoPP::HexEncoder hex( NULL, true, 2, "" );
hex.Attach(new CryptoPP::StringSink(out));
hex.PutMessageEnd(in.begin(), in.size());
return out;
}
static std::string sanitize_text(std::string name) {
std::string::size_type n = 0;
while((n = name.find("\r\n", n)) != std::string::npos)
name.erase(n, 1);
return name;
}
static std::string sanitize_name(std::string name) {
std::string::size_type n = 0;
while((n = name.find("-", n)) != std::string::npos)
name.erase(n, 1);
return name;
}
static void recv(boost::asio::ip::tcp::iostream& sock) throw (std::runtime_error) {
std::string error;
while (1) {
std::string line;
if (!std::getline(sock, line)) break;
//std::cout << "[" << line << "]" << std::endl;
if (line.find("GNTP/1.0 -ERROR") == 0) error = "unknown error";
if (line.find("Error-Description: ") == 0) error = line.substr(19);
if (line == "\r") break;
}
if (!error.empty()) throw std::range_error(error);
}
void send(const char* method, std::stringstream& stm) throw (std::runtime_error) {
boost::asio::ip::tcp::iostream sock(hostname_, port_);
if (!sock) throw std::range_error("can't connect to host");
if (!password_.empty()) {
// initialize salt and iv
CryptoPP::SecByteBlock salt(8);
rng.GenerateBlock(salt.begin(), salt.size());
// get digest of password+salt hex encoded
CryptoPP::SecByteBlock passtext(CryptoPP::Weak1::MD5::DIGESTSIZE);
CryptoPP::Weak1::MD5 hash;
hash.Update((byte*)password_.c_str(), password_.size());
hash.Update(salt.begin(), salt.size());
hash.Final(passtext);
CryptoPP::SecByteBlock digest(CryptoPP::Weak1::MD5::DIGESTSIZE);
hash.CalculateDigest(digest.begin(), passtext.begin(), passtext.size());
sock << "GNTP/1.0 "
<< method
<< " NONE "
<< " " <<
sanitize_name(CryptoPP::Weak1::MD5::StaticAlgorithmName())
<< ":" << to_hex(digest) << "." << to_hex(salt)
<< "\r\n"
<< stm.str() << "\r\n\r\n";
} else {
sock << "GNTP/1.0 "
<< method
<< " NONE\r\n"
<< stm.str() << "\r\n";
}
recv(sock);
}
template<class CIPHER_TYPE, class HASH_TYPE>
void send(const char* method, std::stringstream& stm) throw (std::runtime_error) {
boost::asio::ip::tcp::iostream sock(hostname_, port_);
if (!sock) throw std::range_error("can't connect to host");
if (!password_.empty()) {
// initialize salt and iv
CryptoPP::SecByteBlock salt(HASH_TYPE::DIGESTSIZE), iv(CIPHER_TYPE::BLOCKSIZE);
rng.GenerateBlock(salt.begin(), salt.size());
rng.GenerateBlock(iv.begin(), iv.size());
// get digest of password+salt hex encoded
CryptoPP::SecByteBlock passtext(HASH_TYPE::DIGESTSIZE);
HASH_TYPE hash;
hash.Update((byte*)password_.c_str(), password_.size());
hash.Update(salt.begin(), salt.size());
hash.Final(passtext);
CryptoPP::SecByteBlock digest(HASH_TYPE::DIGESTSIZE);
hash.CalculateDigest(digest.begin(), passtext.begin(), passtext.size());
class CryptoPP::CBC_Mode<CIPHER_TYPE>::Encryption
encryptor(passtext.begin(), iv.size(), iv.begin());
std::string cipher_text;
CryptoPP::StringSource(stm.str(), true,
new CryptoPP::StreamTransformationFilter(encryptor,
new CryptoPP::StringSink(cipher_text)
) // StreamTransformationFilter
); // StringSource
sock << "GNTP/1.0 "
<< method
<< " "
<< sanitize_name(CIPHER_TYPE::StaticAlgorithmName())
<< ":" << to_hex(iv)
<< " "
<< sanitize_name(HASH_TYPE::StaticAlgorithmName())
<< ":" << to_hex(digest) << "." << to_hex(salt)
<< "\r\n"
<< cipher_text << "\r\n\r\n";
} else {
sock << "GNTP/1.0 "
<< method
<< " NONE\r\n"
<< stm.str() << "\r\n";
}
recv(sock);
}
void make_regist(std::stringstream& stm, const char* name) {
stm << "Notification-Name: " << sanitize_text(name) << "\r\n";
stm << "Notification-Display-Name: " << sanitize_text(name) << "\r\n";
stm << "Notification-Enabled: True\r\n";
stm << "\r\n";
}
void make_notify(std::stringstream& stm, const char* name, const char* title, const char* text, const char* icon = NULL, const char* url = NULL) {
stm << "Application-Name: " << sanitize_text(application_) << "\r\n";
stm << "Notification-Name: " << sanitize_text(name) << "\r\n";
if (icon) stm << "Notification-Icon: " << sanitize_text(icon) << "\r\n";
if (url) stm << "Notification-Callback-Target: " << sanitize_text(url) << "\r\n";
stm << "Notification-Title: " << sanitize_text(title) << "\r\n";
stm << "Notification-Text: " << sanitize_text(text) << "\r\n";
stm << "\r\n";
}
std::string application_;
std::string hostname_;
std::string port_;
std::string password_;
CryptoPP::AutoSeededRandomPool rng;
public:
gntp(std::string application = "gntp-send", std::string password = "",
std::string hostname = "localhost", std::string port = "23053") :
application_(application),
password_(password),
hostname_(hostname),
port_(port) { }
void regist(const char* name) throw (std::runtime_error) {
std::stringstream stm;
stm << "Application-Name: " << sanitize_text(application_) << "\r\n";
stm << "Notifications-Count: 1\r\n";
stm << "\r\n";
make_regist(stm, name);
send("REGISTER", stm);
}
template<class CIPHER_TYPE, class HASH_TYPE>
void regist(const char* name) throw (std::runtime_error) {
std::stringstream stm;
stm << "Application-Name: " << sanitize_text(application_) << "\r\n";
stm << "Notifications-Count: 1\r\n";
stm << "\r\n";
make_regist(stm, name);
send<CIPHER_TYPE, HASH_TYPE>("REGISTER", stm);
}
template<class CIPHER_TYPE, class HASH_TYPE>
void regist(const std::vector<std::string> names) throw (std::runtime_error) {
std::stringstream stm;
stm << "Application-Name: " << sanitize_text(application_) << "\r\n";
stm << "Notifications-Count: " << names.size() << "\r\n";
stm << "\r\n";
std::vector<std::string>::const_iterator it;
for (it = names.begin(); it != names.end(); it++) {
make_regist(stm, it->c_str());
}
send<CIPHER_TYPE, HASH_TYPE>("REGISTER", stm);
}
void notify(const char* name, const char* title, const char* text, const char* icon = NULL, const char* url = NULL) throw (std::runtime_error) {
std::stringstream stm;
make_notify(stm, name, title, text, icon, url);
send("NOTIFY", stm);
}
template<class CIPHER_TYPE, class HASH_TYPE>
void notify(const char* name, const char* title, const char* text, const char* icon = NULL, const char* url = NULL) throw (std::runtime_error) {
std::stringstream stm;
make_notify(stm, name, title, text, icon, url);
send<CIPHER_TYPE, HASH_TYPE>("NOTIFY", stm);
}
};
#endif
// vim:set et:

View File

@ -15,10 +15,10 @@
****************************************************************************************/
#include "growl_backend.h"
#include "gntp.h"
#include "core/snoreserver.h"
#include <growl++.hpp>
#include <QtCore>
@ -28,8 +28,8 @@ Growl_Backend::Growl_Backend(SnoreServer *snore):
Notification_Backend("Growl",snore),
id(0)
{
const char *n[1] = { "Default Alert"};
Growl *growl = new Growl(GROWL_TCP,NULL,"SnoreNotify",n,1);
gntp *growl = new gntp("SnoreNotify");
growl->regist("Default Alert");
_applications.insert("SnoreNotify",growl);
}
@ -37,42 +37,35 @@ Growl_Backend::~Growl_Backend(){
foreach(Application *a,this->snore()->aplications().values()){
unregisterApplication(a);
}
qDebug()<<"Growl_Backend bye bye";
}
void Growl_Backend::registerApplication(Application *application){
QList<Alert*> aList = application->alerts().values();
int alertCount = application->alerts().count();
char **n = new char*[alertCount];
for (int i = 0 ; i < alertCount; ++i){
QString name = aList.at(i)->name();
n[i] = new char[name.length()+1];
strcpy(n[i],name.toUtf8().constData());
}
_applications.insert(application->name(),new Growl(GROWL_TCP,NULL,application->name().toUtf8().constData(),(const char**)n,application->alerts().count()));
for (int i = 0 ; i < alertCount; ++i){
delete [] n[i];
}
delete [] n;
gntp *growl = new gntp(application->name().toUtf8().constData());
foreach(Alert *a,application->alerts()){
growl->regist(a->name().toUtf8().constData());
}
_applications.insert(application->name(),growl);
}
void Growl_Backend::unregisterApplication(Application *application){
Growl *growl = _applications.take(application->name());
gntp *growl = _applications.take(application->name());
if(growl == NULL)
return;
delete growl;
}
int Growl_Backend::notify(Notification notification){
Growl *growl = _applications.value(notification.application());
gntp *growl = _applications.value(notification.application());
if(growl == NULL)
return -1;
QString title=Notification::toPlainText(notification.title());
QString text=Notification::toPlainText(notification.text());
qDebug()<<"Notify Growl:"<<notification.application()<<title;
growl->Notify(notification.alert().toUtf8().constData(),title.toUtf8().constData(),text.toUtf8().constData(),"",notification.icon().toUtf8().constData());
//qDebug()<<"Notify Growl:"<<notification.application()<<Notification.toPlainText(notification.title());
growl->notify(notification.alert().toUtf8().constData(),
Notification::toPlainText(notification.title()).toUtf8().constData(),
Notification::toPlainText(notification.text()).toUtf8().constData(),
notification.icon().isEmpty()?NULL:notification.icon().toUtf8().constData());
return ++id;
}

View File

@ -30,7 +30,7 @@ public:
bool isPrimaryNotificationBackend(){return true;}
private:
uint id;
QHash<QString,class Growl*> _applications;
QHash<QString,class gntp*> _applications;
public slots:
void registerApplication(Application *application);
void unregisterApplication(class Application *application);