use gntppp instead of gntp-send
This commit is contained in:
parent
9d97249ef6
commit
ea8ab89e8e
|
@ -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)
|
|
@ -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++)
|
||||
|
|
@ -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.
|
|
@ -1,3 +0,0 @@
|
|||
Limited documentation available in the wiki.
|
||||
|
||||
http://wiki.github.com/psinnott/gntp-send
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ ]
|
|
@ -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_ ]
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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)¬ify , 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, ¬ify_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 , ¬ify_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)¬ify , 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
|
|
@ -1,7 +0,0 @@
|
|||
EXPORTS
|
||||
growl
|
||||
growl_udp
|
||||
growl_udp_register
|
||||
growl_udp_notify
|
||||
growl_tcp_register
|
||||
growl_tcp_notify
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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:
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue