Process Hacker
tcp.c
Go to the documentation of this file.
1 #include <phdk.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <stdarg.h>
6 
7 #ifdef _WIN32
8 #include <winsock2.h>
9 #else
10 #include <sys/socket.h>
11 #include <netinet/in.h>
12 #include <netinet/tcp.h>
13 #include <netdb.h>
14 #include <unistd.h>
15 #endif
16 
17 #include "tcp.h"
18 
19 int growl_tcp_parse_hostname( const char *const server , int default_port , struct sockaddr_in *const sockaddr );
20 
21 void growl_tcp_write_raw( SOCKET sock, const unsigned char * data, const int data_length )
22 {
23  send(sock, data, data_length, 0);
24 }
25 
26 void growl_tcp_write( SOCKET sock , const char *const format , ... )
27 {
28  int length;
29  char *output;
30  char *stop;
31 
32  va_list ap;
33 
34  va_start( ap , format );
35  length = vsnprintf( NULL , 0 , format , ap );
36  va_end(ap);
37 
38  va_start(ap,format);
39  output = (char*)PhAllocateSafe(length+1);
40  if (!output) {
41  va_end(ap);
42  return;
43  }
44  vsnprintf( output , length+1 , format , ap );
45  va_end(ap);
46 
47  while ((stop = strstr(output, "\r\n"))) strcpy(stop, stop + 1);
48 
49  send( sock , output , length , 0 );
50  send( sock , "\r\n" , 2 , 0 );
51 
52  PhFree(output);
53 }
54 
55 char *growl_tcp_read(SOCKET sock) {
56  const int growsize = 80;
57  char c = 0;
58  char* line = (char*) PhAllocateSafe(growsize);
59  if (line) {
60  int len = growsize, pos = 0;
61  char* newline;
62  while (line) {
63  if (recv(sock, &c, 1, 0) <= 0) break;
64  if (c == '\r') continue;
65  if (c == '\n') break;
66  line[pos++] = c;
67  if (pos >= len) {
68  len += growsize;
69  newline = (char*) realloc(line, len);
70  if (!newline) {
71  PhFree(line);
72  return NULL;
73  }
74  line = newline;
75  }
76  }
77  line[pos] = 0;
78  }
79  return line;
80 }
81 
82 /* dmex: modified to use INVALID_SOCKET and SOCKET_ERROR */
83 SOCKET growl_tcp_open(const char* server) {
84  SOCKET sock = INVALID_SOCKET;
85 #ifdef _WIN32
86  char on;
87 #else
88  int on;
89 #endif
90  struct sockaddr_in serv_addr;
91 
92  if( growl_tcp_parse_hostname( server , 23053 , &serv_addr ) == -1 ) {
93  return INVALID_SOCKET;
94  }
95 
96  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
97  perror("create socket");
98  return INVALID_SOCKET;
99  }
100 
101  if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR) {
102  perror("connect");
103  closesocket(sock); // dmex: fixed handle leaking on error
104  return INVALID_SOCKET;
105  }
106 
107  on = 1;
108  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == SOCKET_ERROR) {
109  perror("setsockopt");
110  closesocket(sock); // dmex: fixed handle leaking on error
111  return INVALID_SOCKET;
112  }
113 
114  return sock;
115 }
116 
117 /* dmex: modified to use INVALID_SOCKET */
118 void growl_tcp_close(SOCKET sock) {
119 #ifdef _WIN32
120  if (sock != INVALID_SOCKET) closesocket(sock);
121 #else
122  if (sock > 0) close(sock);
123 #endif
124 }
125 
126 int growl_tcp_parse_hostname( const char *const server , int default_port , struct sockaddr_in *const sockaddr )
127 {
128  char *hostname = PhDuplicateBytesZSafe((PSTR)server);
129  char *port = strchr( hostname, ':' );
130  struct hostent* host_ent;
131  if( port != NULL )
132  {
133  *port = '\0';
134  port++;
135  default_port = atoi(port);
136  }
137 
138  host_ent = gethostbyname(hostname);
139  if( host_ent == NULL )
140  {
141  perror("gethostbyname");
142  PhFree(hostname);
143  return -1;
144  }
145 
146  // dmex: fixed wrong sizeof argument
147  memset( sockaddr , 0 , sizeof(struct sockaddr_in) );
148  sockaddr->sin_family = AF_INET;
149  memcpy( &sockaddr->sin_addr , host_ent->h_addr , host_ent->h_length );
150  sockaddr->sin_port = htons(default_port);
151 
152  PhFree(hostname);
153  return 0;
154 }
155 
156 int growl_tcp_datagram( const char *server , const unsigned char *data , const int data_length )
157 {
158  int result;
159  struct sockaddr_in serv_addr;
160  SOCKET sock = 0;
161 
162  if( growl_tcp_parse_hostname( server , 9887 , &serv_addr ) == -1 )
163  {
164  return -1;
165  }
166 
167  sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
168  if( sock == INVALID_SOCKET )
169  {
170  return -1;
171  }
172 
173  if( sendto(sock, (char*)data , data_length , 0 , (struct sockaddr*)&serv_addr , sizeof(serv_addr) ) > 0 )
174  {
175  result = 0;
176  }
177  else
178  {
179  result = 1;
180  }
181 
182  closesocket(sock);
183  return result;
184 }