ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/ihost/ihost.c
Revision: 1.8
Committed: Mon May 13 11:01:27 2002 UTC (22 years, 7 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.7: +8 -8 lines
Log Message:
Subtle "nice" changes.

File Contents

# Content
1 #include <stdio.h>
2 #include <sys/socket.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <syslog.h>
6 #include <netinet/in.h>
7 #include <ukcprog.h>
8 #include <netdb.h>
9 #include <strings.h>
10
11 #define RECONFIGURE_RETURN_CODE 2
12
13 typedef struct{
14 int fm_port;
15 char *fm_host;
16
17 char *my_fqdn;
18 char *server_fqdn;
19 int server_udp_port;
20 int server_tcp_port;
21 char *last_modified;
22 char *files_list;
23 char *key;
24 int udp_update_time;
25 int tcp_update_time;
26
27 }ihost_state_t;
28
29 char* sock_comm(FILE *f_r, FILE *f_w, char *sendString){
30 char *reply;
31 fprintf(f_w, "%s\n", sendString);
32 fflush(f_w);
33 reply=fpgetline(f_r);
34 /* Returns pointer to static buffer */
35 return reply;
36 }
37
38 int ihost_configure(ihost_state_t *ihost_state){
39 struct sockaddr_in addr;
40 struct in_addr haddr;
41 int sd;
42 FILE *fm_fd_r, *fm_fd_w;
43 char *reply;
44 char *reply_ptr;
45
46 /* Check to see if anything needs to be free'd */
47 if (ihost_state->my_fqdn!=NULL) free(ihost_state->my_fqdn);
48 if (ihost_state->server_fqdn!=NULL) free(ihost_state->server_fqdn);
49 if (ihost_state->last_modified!=NULL) free(ihost_state->last_modified);
50 if (ihost_state->files_list!=NULL) free(ihost_state->files_list);
51
52 if ((sd = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
53 errf("Can't create AF_INET socket (%m)");
54 return -1;
55 }
56
57 if (get_host_addr(ihost_state->fm_host, &haddr) != 0){
58 errf("Failed to resolve address %s (%m)", ihost_state->fm_host);
59 return -1;
60 }
61
62 memset((char *)&addr, 0, sizeof addr);
63 addr.sin_family = AF_INET;
64 memcpy((char *)&addr.sin_addr, &haddr, sizeof haddr);
65 addr.sin_port = htons(ihost_state->fm_port);
66
67 if (connect(sd, (struct sockaddr *)&addr, sizeof addr) != 0) {
68 errf("Failed to connect to %s on port %d (%m)", ihost_state->fm_host, ihost_state->fm_port);
69 return -1;
70 }
71
72 /* Need to open 2 files, one for reading one for writing, as it gets confused if we only use 1 :) */
73 if ((fm_fd_r=fdopen(sd,"r")) == NULL){
74 errf("Failed to open read stream (%m)");
75 return -1;
76 }
77
78 if ((fm_fd_w=fdopen(dup(sd),"w")) == NULL){
79 errf("Failed to open write stream (%m)");
80 return -1;
81 }
82
83 reply=sock_comm(fm_fd_r, fm_fd_w, "STARTCONFIG");
84 if ((reply==NULL) || (strncasecmp(reply, "OK", 2) != 0) ) {
85 errf("Server error");
86 return -1;
87 }
88
89 reply=sock_comm(fm_fd_r, fm_fd_w, "LASTMODIFIED");
90 if((reply== NULL) || (strncasecmp(reply, "ERROR", 5) ==0)){
91 errf("Server error (%m)");
92 return -1;
93 }
94 if((ihost_state->last_modified=strdup(reply)) == NULL){
95 errf("strdup failed (%m)");
96 return -1;
97 }
98
99 reply=sock_comm(fm_fd_r, fm_fd_w, "FILELIST");
100 if((reply== NULL) || (strncasecmp(reply, "ERROR", 5) ==0)){
101 errf("Server error (%m)");
102 return -1;
103 }
104 if((ihost_state->files_list=strdup(reply)) == NULL){
105 errf("strdup failed (%m)");
106 return -1;
107 }
108
109 reply=sock_comm(fm_fd_r, fm_fd_w, "FQDN");
110 if((reply== NULL) || (strncasecmp(reply, "ERROR", 5)==0)){
111 errf("Server error (%m)");
112 return -1;
113 }
114 if((ihost_state->my_fqdn=strdup(reply)) == NULL){
115 errf("strdup failed (%m)");
116 return -1;
117 }
118
119 reply=sock_comm(fm_fd_r, fm_fd_w, "UDPUpdateTime");
120 if(reply== NULL){
121 errf("Server error (%m)");
122 return -1;
123 }
124 if (strncasecmp(reply, "ERROR", 5) != 0){
125 ihost_state->udp_update_time=atoi(reply);
126 }
127
128 reply=sock_comm(fm_fd_r, fm_fd_w, "TCPUpdateTime");
129 if(reply== NULL){
130 errf("Server error (%m)");
131 return -1;
132 }
133 if (strncasecmp(reply, "ERROR", 5) != 0){
134 ihost_state->tcp_update_time=atoi(reply);
135 }
136
137 reply=sock_comm(fm_fd_r, fm_fd_w, "ENDCONFIG");
138 if(reply== NULL){
139 errf("Server error (%m)");
140 return -1;
141 }
142
143 reply=sock_comm(fm_fd_r, fm_fd_w, "FILTER");
144 if((reply== NULL) || (strncasecmp(reply, "ERROR", 5)==0)){
145 errf("Server error (%m)");
146 return -1;
147 }
148 reply_ptr=strchr(reply,';');
149 if (reply_ptr==NULL){
150 errf("Incorrect data returned");
151 return -1;
152 }
153 *reply_ptr='\0';
154 if((ihost_state->server_fqdn=strdup(reply)) == NULL){
155 errf("strdup failed (%m)");
156 return -1;
157 }
158 reply=reply_ptr + 1;
159 reply_ptr=strchr(reply,';');
160 if (reply_ptr==NULL){
161 errf("Incorrect data returned 2");
162 return -1;
163 }
164 *reply_ptr='\0';
165 ihost_state->server_udp_port=atoi(reply);
166 reply=reply_ptr+1;
167 ihost_state->server_tcp_port=atoi(reply);
168 if ((ihost_state->server_tcp_port==0) || (ihost_state->server_udp_port==0)){
169 errf("Incorrect data returned 3 ");
170 return -1;
171 }
172
173 reply=sock_comm(fm_fd_r, fm_fd_w, "END");
174 if((reply== NULL) || (strncasecmp(reply, "ERROR", 5) ==0 )){
175 errf("Server error (%m)");
176 return -1;
177 }
178
179 if(fclose(fm_fd_r) !=0){
180 errf("Failed to close read FD (%m)");
181 return -1;
182 }
183 if(fclose(fm_fd_w) !=0){
184 errf("Failed to close write FD (%m)");
185 return -1;
186 }
187
188 return 0;
189 }
190
191 int heartbeat(ihost_state_t *ihost_state){
192 struct sockaddr_in addr;
193 struct in_addr haddr;
194 int sd;
195 FILE *fm_fd_r, *fm_fd_w;
196 char *reply;
197 int exitcode=0;
198
199 if ((sd = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
200 errf("Can't create AF_INET socket (%m)");
201 return -1;
202 }
203
204 if (get_host_addr(ihost_state->server_fqdn, &haddr) != 0){
205 errf("Failed to resolve address %s (%m)", ihost_state->fm_host);
206 return -1;
207 }
208
209 memset((char *)&addr, 0, sizeof addr);
210 addr.sin_family = AF_INET;
211 memcpy((char *)&addr.sin_addr, &haddr, sizeof haddr);
212 addr.sin_port = htons(ihost_state->server_tcp_port);
213
214 if (connect(sd, (struct sockaddr *)&addr, sizeof addr) != 0) {
215 errf("Failed to connect to %s on port %d (%m)", ihost_state->fm_host, ihost_state->fm_port);
216 return -1;
217 }
218
219 /* Need to open 2 files, one for reading one for writing, as it gets confused if we only use 1 :) */
220 if ((fm_fd_r=fdopen(sd,"r")) == NULL){
221 errf("Failed to open stream (%m)");
222 return -1;
223 }
224
225 if ((fm_fd_w=fdopen(dup(sd),"w")) == NULL){
226 errf("Failed to open stream (%m)");
227 return -1;
228 }
229
230 reply=sock_comm(fm_fd_r, fm_fd_w, "HEARTBEAT");
231 if ((reply==NULL) || (strncasecmp(reply, "ERROR", 5) == 0) ) {
232 errf("Server error");
233 return -1;
234 }
235 if (ihost_state->fm_host!=NULL) free(ihost_state->fm_host);
236 reply=sock_comm(fm_fd_r, fm_fd_w, "CONFIG");
237 if ((reply==NULL) || (strncasecmp(reply, "ERROR", 5) == 0) ) {
238 errf("Server error");
239 return -1;
240 }
241
242 reply=sock_comm(fm_fd_r, fm_fd_w, ihost_state->files_list);
243 if ((reply==NULL) || (strncasecmp(reply, "OK", 2) != 0) ) {
244 errf("Server error");
245 return -1;
246 }
247
248 reply=sock_comm(fm_fd_r, fm_fd_w, ihost_state->last_modified);
249 if (reply==NULL) {
250 errf("Server error");
251 return -1;
252 }
253 if (strncasecmp(reply, "ERROR", 5) == 0){
254 /* Means the config has changed */
255 exitcode=RECONFIGURE_RETURN_CODE;
256 }
257 reply=sock_comm(fm_fd_r, fm_fd_w, "KEY");
258 if ((reply==NULL) || (strncasecmp(reply, "ERROR", 5) == 0) ) {
259 errf("Server error");
260 return -1;
261 }
262 if (ihost_state->key!=NULL) free(ihost_state->key);
263
264 if((ihost_state->key=strdup(reply)) == NULL){
265 errf("strdup failed (%m)");
266 return -1;
267 }
268
269 reply=sock_comm(fm_fd_r, fm_fd_w, "ENDHEARTBEAT");
270 if((reply== NULL) || (strncasecmp(reply, "ERROR", 5) ==0 )){
271 errf("Server error (%m)");
272 return -1;
273 }
274
275 if(fclose(fm_fd_r) !=0){
276 errf("Failed to close read FD (%m)");
277 return -1;
278 }
279 if(fclose(fm_fd_w) !=0){
280 errf("Failed to close write FD (%m)");
281 return -1;
282 }
283
284 return exitcode;
285 }
286
287
288 int main(int argc, char **argv){
289 ihost_state_t ihost_state;
290 int heartbeat_exit;
291 int counter=0;
292
293
294 /* NULL'ify so i can tell if i need to free it or not */
295 ihost_state.fm_host=NULL;
296 ihost_state.my_fqdn=NULL;
297 ihost_state.server_fqdn=NULL;
298 ihost_state.last_modified=NULL;
299 ihost_state.files_list=NULL;
300 ihost_state.key=NULL;
301
302 errf_set_progname(argv[0]);
303 if(argc!=3){
304 errf_usage("<host> <port>");
305 exit(1);
306 }
307
308 ihost_state.fm_host=argv[1];
309 ihost_state.fm_port=atoi(argv[2]);
310
311 if(ihost_configure(&ihost_state)!=0){
312 errf("configure failed");
313 /* Ok, ideally we prob should have 2 copies of the structure and carry on if this
314 happens.. But we dont :) (at the moment) */
315 exit(1);
316 }
317
318 while(TRUE){
319
320 heartbeat_exit=heartbeat(&ihost_state);
321 if(heartbeat_exit==RECONFIGURE_RETURN_CODE){
322 errf("heartbeat needs to be reconfigured");
323 ihost_configure(&ihost_state);
324 }
325 if(heartbeat_exit==-1){
326 errf("ah crap");
327 exit(1);
328 }
329 printf("Count : %d\n",counter++);
330 printf("waiting %d\n",ihost_state.tcp_update_time);
331 sleep(ihost_state.tcp_update_time);
332 }
333 return 0;
334 }
335