COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
prowl.c
Go to the documentation of this file.
1 /*
2  * ----------------------------------------------------------------------------
3  * "THE BEER-WARE LICENSE" (Revision 42):
4  * <abort@digitalise.net> wrote this file. As long as you retain this notice you
5  * can do whatever you want with this stuff. If we meet some day, and you think
6  * this stuff is worth it, you can buy me a beer in return J. Dijkstra (04/29/2010)
7  * ----------------------------------------------------------------------------
8  */
9 #include "prowl.h"
10 
11 
12 static int prowl_get_response_code(char* response);
14 static SOCKET prowl_tcp_connect();
15 static char* prowl_ssl_read(prowl_connection* c);
17 static char prowl_int_to_hex(char code);
18 static char* prowl_url_encode(char* str);
19 
20 int prowl_push_msg(char* api_key, int priority, char* application_name, char* event_name, char* description)
21 {
23  char buffer[MESSAGESIZE];
24  char* response = NULL;
25 #ifdef _WINDOWS
26  static int wsa_init = 0;
27 #endif
28 
29  application_name = prowl_url_encode(application_name);
30  event_name = prowl_url_encode(event_name);
31  description = prowl_url_encode(description);
32 
33 #ifdef _WINDOWS
34  if (wsa_init == 0)
35  {
36  WSAData wsad;
37 
38  if (WSAStartup(MAKEWORD(2, 2), &wsad) != 0)
39  {
40  fprintf(stderr, "Failed to initialize winsock (%d)\n", GetLastError());
41  goto end;
42  }
43 
44 #ifdef _DEBUG
45  printf("Prowl [debug]: Initialized Winsock\n");
46 #endif
47 
48  wsa_init = 1;
49  }
50 #endif
51 
52 
53  if ((c = prowl_ssl_connect()) == NULL) goto end;
54 
55 #ifdef _DEBUG
56  printf("Prowl [debug]: Connected\n");
57 #endif
58 
59  sprintf(buffer, "GET /publicapi/add?apikey=%s&priority=%d&application=%s&event=%s&description=%s\r\nHost: %s\r\n\r\n",
60  api_key, priority, application_name, event_name, description, HOSTNAME);
61  if (SSL_write(c->ssl_handle, buffer, strlen(buffer)) <= 0)
62  {
63  fprintf(stderr, "Failed to write buffer to SSL connection\n");
64  ERR_print_errors_fp(stderr);
65  goto end;
66  }
67 
68 #ifdef _DEBUG
69  printf("Prowl [debug]: Written buffer: %s\n", buffer);
70 #endif
71 
72  response = prowl_ssl_read(c);
73 
74 #ifdef _DEBUG
75  OutputDebugString("Prowl [debug]: server response:");
76  if (response != NULL) printf("%s\n", response);
77 #endif
78 
80 
81 end:
82  free(application_name);
83  free(event_name);
84  free(description);
85 
86  return (response == NULL ? -1 : prowl_get_response_code(response));
87 }
88 
89 static int prowl_get_response_code(char* response)
90 {
91  int code;
92  char* start = strstr(response, "<prowl>");
93 
94  /* invalid response */
95  if (start == NULL) return -1;
96 
97  start = strstr(start, "code");
98 
99  /* invalid response */
100  if (start == NULL) return -1;
101 
102  /* failed to parse code */
103  if (sscanf(start, "code=\"%d\"", &code) != 1) return -1;
104 
105  free(response);
106 
107  return code;
108 }
109 
111 {
112  prowl_connection* c = (prowl_connection*)malloc(sizeof(prowl_connection));
113 
114  c->socket = prowl_tcp_connect();
115  if (c->socket != SOCKET_ERROR)
116  {
117  SSL_library_init();
118  SSL_load_error_strings();
119 
120  c->ssl_context = SSL_CTX_new(SSLv23_client_method());
121  if (c->ssl_context == NULL) ERR_print_errors_fp(stderr);
122 
123  c->ssl_handle = SSL_new(c->ssl_context);
124  if (c->ssl_handle == NULL) ERR_print_errors_fp(stderr);
125 
126  SSL_CTX_set_verify(c->ssl_context, SSL_VERIFY_PEER, SSL_VERIFY_NONE);
127 
128  if (!SSL_set_fd(c->ssl_handle, c->socket)) ERR_print_errors_fp(stderr);
129 
130  if (SSL_connect(c->ssl_handle) != 1) ERR_print_errors_fp(stderr);
131 
132 #ifdef _DEBUG
133  printf("Prowl [debug]: SSL Handshake successful\n");
134 #endif
135  }
136  else
137  {
138 #ifdef _WINDOWS
139  fprintf(stderr, "Failed to retrieve a valid connected socket\n");
140  return NULL;
141 #else
142  perror("Prowl: Failed to retrieve connected socket");
143 #endif
144  }
145 
146  return c;
147 }
148 
150 {
151  SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
152  struct sockaddr_in server;
153  struct hostent* host = gethostbyname(HOSTNAME);
154 
155  if (s == SOCKET_ERROR)
156  {
157 #ifdef _WINDOWS
158  fprintf(stderr, "Could not create socket (%d)\n", WSAGetLastError());
159  return NULL;
160 #else
161  perror("Prowl: Could not create socket");
162 #endif
163  }
164 
165  if (host == NULL)
166  {
167 #ifdef _WINDOWS
168  fprintf(stderr, "Could not retrieve host by name (%d)\n", WSAGetLastError());
169  return NULL;
170 #else
171  perror("Prowl: Could not retrieve host by name");
172 #endif
173  }
174 
175  memset(&server, 0, sizeof(struct sockaddr_in));
176  server.sin_family = AF_INET;
177  server.sin_port = htons(SSL_PORT);
178  server.sin_addr = *(struct in_addr*)host->h_addr_list[0];
179 
180  if (connect(s, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
181  {
182 #ifdef _WINDOWS
183  fprintf(stderr, "Prowl connect error (%d)\n", WSAGetLastError());
184  return NULL;
185 #else
186  perror("Prowl: connect error");
187 #endif
188  }
189 
190  return s;
191 }
192 
194 {
195  int r = 1;
196  char buffer[BUFFERSIZE];
197  int size = BUFFERSIZE + 1;
198  char* retval = (char*)malloc(size);
199 
200  memset(retval, 0, size);
201 
202  while (r > 0)
203  {
204  r = SSL_read(c->ssl_handle, buffer, BUFFERSIZE);
205  if (r > 0)
206  {
207  buffer[r] = '\0';
208 
209  retval = realloc(retval, size + r);
210  strcat(retval, buffer);
211  }
212  }
213 
214  return retval;
215 }
216 
218 {
219  if (c->socket) closesocket(c->socket);
220  if (c->ssl_handle)
221  {
222  SSL_shutdown(c->ssl_handle);
223  SSL_free(c->ssl_handle);
224  }
225  if (c->ssl_context) SSL_CTX_free(c->ssl_context);
226 
227  free(c);
228 }
229 
230 static char prowl_int_to_hex(char code)
231 {
232  static char hex[] = "0123456789abcdef";
233  return hex[code & 15];
234 }
235 
236 static char* prowl_url_encode(char* str)
237 {
238  char* pstr = str;
239  char* buf = (char*)malloc(strlen(str) * 3 + 1);
240  char* pbuf = buf;
241 
242  while (*pstr)
243  {
244  if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
245  {
246  *pbuf++ = *pstr;
247  }
248  else
249  {
250  *pbuf++ = '%';
251  *pbuf++ = prowl_int_to_hex(*pstr >> 4);
252  *pbuf++ = prowl_int_to_hex(*pstr & 15);
253  }
254 
255  pstr++;
256  }
257  *pbuf = '\0';
258 
259  return buf;
260 }
#define MESSAGESIZE
Definition: prowl.h:17
#define SSL_PORT
Definition: prowl.h:15
#define BUFFERSIZE
Definition: prowl.h:18
static char * prowl_url_encode(char *str)
Definition: prowl.c:236
static SOCKET prowl_tcp_connect()
Definition: prowl.c:149
static prowl_connection * prowl_ssl_connect()
Definition: prowl.c:110
#define HOSTNAME
Definition: prowl.h:16
int prowl_push_msg(char *api_key, int priority, char *application_name, char *event_name, char *description)
Definition: prowl.c:20
SSL * ssl_handle
Definition: prowl.h:57
static void prowl_ssl_disconnect(prowl_connection *c)
Definition: prowl.c:217
SSL_CTX * ssl_context
Definition: prowl.h:58
SOCKET socket
Definition: prowl.h:56
#define closesocket(socket)
Definition: prowl.h:39
static char * prowl_ssl_read(prowl_connection *c)
Definition: prowl.c:193
static int prowl_get_response_code(char *response)
Definition: prowl.c:89
#define SOCKET
Definition: prowl.h:37
#define SOCKET_ERROR
Definition: prowl.h:38
static char prowl_int_to_hex(char code)
Definition: prowl.c:230
Send comments to:
COOLFluiD Web Admin