source: MondoRescue/branches/stable/monitas/client.c@ 352

Last change on this file since 352 was 352, checked in by bcornec, 18 years ago

monitas v0.1a

  • Property svn:executable set to *
File size: 43.3 KB
Line 
1/* client.c
2
3CLIENT
4
5
6
7FIXME
8- perror() --- replace with log_it()
9
10
11
1206/19
13- fixed bugs in mondoarchive compare code
14- added track_restore_task_progress()
15
1606/16
17- when calling mondoarchive in bkgd, see if it starts OK; if it
18 doesn't then say so & return error
19
2006/14
21- added a FIFO to let user request backup/compare/restore
22- send progress info to server - % done, etc. - when backing up
23- pipe logs to logfile, not stdout
24
2506/11
26- added call to register_pid()
27- commented code a bit
28- implemented compare_archives and restore_archives()
29
3006/10
31- create function to call external executable in background
32- create function to wait for it to terminate & to grab its result
33- put them in common.c
34
3505/27
36- fixed watch_port_for_triggers()
37- turned st_'s into a global and some locals
38- fork in login thingy becomes a thread
39- added bind_client_port()
40- added accept_and_recv_thru_client_port()
41- changed flag (recv) from DONTWAIT to 0 [no flag]
42
4305/21
44- added back_my_smitch_up(), compare_archives(), restore_archives()
45- added log_it(); fixed fprintf(stderr,"") and printf() reporting
46- parallelize/fork the 'watch for triggers from server' process
47- added tmsg_to_string()
48- forked port-watcher to receive triggers from server in bkgd
49
5005/11
51- clarified structures & their names
52- improved login/logout OK/fail feedback
53
5405/08
55- did some housecleaning
56- added comments; removed strcpy()'s
57- replaced silly exit()'s with return()'s
58
59*/
60
61
62#include "structs.h"
63//#define LOG_THESE_AND_HIGHER debug
64#define LOGFILE "/var/log/monitas-client.log"
65
66
67
68/* global vars */
69
70bool g_logged_in_currently=false, g_logging_out=false;
71int g_sClient=-1, g_client_port=0; /* client port; set by login */
72struct sockaddr_in g_sinClient; /* client port */
73char g_server_name[MAX_STR_LEN+1];
74pthread_t g_mondo_thread=0;
75char g_command_fifo[MAX_STR_LEN+1];
76char g_logfile[MAX_STR_LEN+1] = "/var/log/monitas-client.log";
77
78/* externs */
79
80extern char *call_program_and_get_last_line_of_output(char*);
81extern int call_program_and_log_output(char*);
82extern void call_program_in_background(pthread_t*, char*);
83extern int create_and_watch_fifo_for_commands(char*);
84extern bool does_file_exist(char*);
85extern int get_bkgd_prog_result(pthread_t*);
86extern void log_it_SUB(char*, t_loglevel level, char *sz_message);
87extern bool program_still_running(char*);
88extern int receive_file_from_socket(FILE*, int);
89extern void register_pid(pid_t, char*);
90extern char *tmsg_to_string(t_msg msg_type);
91extern int transmit_file_to_socket(FILE*, int);
92extern void register_pid(pid_t, char*);
93extern void set_signals(bool);
94
95/* prototypes */
96
97int accept_and_recv_thru_client_port(int, int*, struct sockaddr_in*, char*, int);
98int back_my_smitch_up(char*, int);
99int bind_client_port(struct sockaddr_in*, int);
100int compare_archives(char*, int);
101int find_and_bind_free_server_port(struct sockaddr_in*, int*);
102long increment_magic_number(void);
103int login_to_server(char*,char*);
104void logout_and_exit(char*);
105int logout_of_server(char*);
106int process_incoming_command(char*);
107int restore_archives(char*, char*, int);
108void restore_archives_SIGPIPE(int);
109int send_final_progress_report(char*);
110int send_msg_to_server(struct s_client2server_msg_record*, char*);
111int send_ping_to_server(char*,char*);
112int send_progress_rpt_to_server(char*, char*);
113void terminate_daemon(int);
114void *track_backup_task_progress(void*);
115void *track_compare_task_progress(void*);
116void *track_restore_task_progress(void*);
117void *watch_port_for_triggers_from_server(void*);
118
119
120
121
122/*-----------------------------------------------------------*/
123
124
125
126int accept_and_recv_thru_client_port(int sClient, int *new_sClient, struct sockaddr_in*sinClient, char*incoming, int expected_length)
127/*
128Purpose:Run accept() and recv() to open port and receive
129 message from server.
130Params: sClient - file descriptor of port
131 new_sClient - [returned] file descriptor of the
132 new connection to port which we open in this func
133 sinClient - record about port
134 expected_length - expected length of incoming block
135Return: length of block received, or <0 if error
136*/
137{
138 int len;
139
140 len = sizeof(struct sockaddr_in);
141 if ((*new_sClient = accept(sClient, (struct sockaddr*)sinClient, (unsigned int*)&len)) < 0) { log_it(error, "[child] Cannot accept"); return(-6); }
142 if ((len = recv(*new_sClient, incoming, expected_length, /*MSG_DONTWAIT*/0)) <= 0) { log_it(error, "[child] Cannot recv"); return(-7); }
143 return(len);
144}
145
146
147
148/*-----------------------------------------------------------*/
149
150
151
152char *get_param_from_rcfile(char*fname, char*field)
153{
154 char command[MAX_STR_LEN+1], tmp[MAX_STR_LEN+1];
155 static char sz_res[MAX_STR_LEN+1];
156
157 sz_res[0]='\0';
158 if (does_file_exist(fname))
159 {
160 sprintf(command, "cat %s | grep %s= | cut -d'=' -f2,3,4,5,6,7,8,9", fname, field);
161 strcpy(tmp, call_program_and_get_last_line_of_output(command));
162 strcpy(sz_res, tmp);
163 }
164 return(sz_res);
165}
166
167
168
169int back_my_smitch_up(char*msgbody, int socket_fd)
170/*
171Purpose:Backup archives to server.
172Params: msgbody - char[MSG_BODY_SIZE] containing info
173 about the archives to be created
174 socket_fd - file descriptor to which to
175 write the archives to server.
176Return: result (0=success; nonzero=failure)
177*/
178{
179 char tmp[MAX_STR_LEN+1], command[MAX_STR_LEN+1], tempdev[MAX_STR_LEN+1];
180 char temporary_logfile[MAX_STR_LEN+1]; // where mondoarchive writes its stdout,stderr
181 char mondoparams_str[MAX_STR_LEN+1];
182 struct s_server2client_msg_record incoming_rec;
183 int retval=0, len, new_sClient, res=0;
184 FILE*fin;
185 pthread_t progress_thread;
186
187 sprintf(tmp, "Backup of %s commenced", msgbody);
188 log_it(info, tmp);
189 if (send_progress_rpt_to_server(g_server_name, tmp)) { log_it(error, "Unable to send 'yep, got this msg' progress_rpt to server"); }
190 sprintf(temporary_logfile, "/tmp/monitas-client.templog.%d", (int)random()%32767);
191 sprintf(tempdev, "/tmp/monitas-client.device.%d", (int)random()%32767);
192 unlink(tempdev);
193 if (mkfifo(tempdev, 700))
194 {
195 log_it(error, "Unable to create temporary data output fifo in preparation for the call to mondoarchive");
196 return(1);
197 }
198 unlink(temporary_logfile);
199 if (mkfifo(temporary_logfile, 700))
200 {
201 log_it(error, "Unable to create temporary logfile fifo in preparation for the call to mondoarchive");
202 return(1);
203 }
204 strcpy(mondoparams_str, get_param_from_rcfile(CLIENT_RCFILE, "mondoarchive_params"));
205 sprintf(tmp, "mondoarchive_params --> '%s'", mondoparams_str);
206 log_it(debug, tmp);
207 sprintf(command, "mondoarchive -Ou %s -d %s -I %s -F &> %s; rm -f %s %s", mondoparams_str, tempdev, msgbody, temporary_logfile, tempdev, temporary_logfile);
208 call_program_in_background(&g_mondo_thread, command);
209 sleep(10);
210 if (!program_still_running(command))
211 { res=1; log_it(error, "Unable to start mondoarchive. Please check /var/log/mondo-archive.log"); }
212 else
213 {
214 if (pthread_create(&progress_thread, NULL, track_backup_task_progress, (void*)temporary_logfile))
215 { log_it(error, "Cannot create pthread to track mondo task progress"); return(1); }
216 log_it(debug, "Opening fopen() to tempdev");
217 if (!(fin = fopen(tempdev, "r"))) { log_it(error, "Cannot open FIFO"); return(1); }
218 log_it(debug, "fopen() OK");
219 retval = transmit_file_to_socket(fin, socket_fd);
220 fclose(fin);
221 res = get_bkgd_prog_result(&g_mondo_thread);
222 pthread_join(progress_thread, NULL);
223 }
224 if (res)
225 { retval++; log_it(error, "Mondoarchive returned an error. Notifying server..."); }
226 if (res)
227 { retval++; log_it(error, "Mondoarchive returned an error."); }
228 if (retval) { log_it(debug, "Errors have occurred. Notifing server..."); }
229 else { log_it(debug, "Everything is OK so far. Notifying server..."); }
230 if (write(socket_fd, (char*)&retval, sizeof(retval))!=sizeof(retval)) {retval++;}
231/* receive msg from server; did backup go OK at its end or not? */
232 unlink(tempdev);
233 unlink(temporary_logfile);
234 log_it(debug, "Waiting for progress thread to join us");
235 log_it(debug, "Groovy. Continuing..");
236 len = accept_and_recv_thru_client_port(g_sClient, &new_sClient, &g_sinClient, (char*)&incoming_rec, sizeof(incoming_rec));
237 if (len<0) { log_it(error, "After backup, unable to accept/recv thru client port"); return(-10); }
238 sprintf(tmp, "After backup, I received %s - %s", tmsg_to_string(incoming_rec.msg_type), incoming_rec.body);
239 log_it(debug, tmp);
240 if (incoming_rec.msg_type == backup_fail)
241 { retval++; log_it(error, "Server reported error(s) during backup, although client didn't."); }
242 if (retval)
243 {
244 sprintf(tmp, "Backup of %s failed", msgbody);
245 log_it(error, tmp);
246 call_program_and_log_output("tail -n6 /var/log/mondo-archive.log");
247 }
248 else
249 {
250 sprintf(tmp, "Server agrees, backup of %s succeeded :-)", msgbody);
251 log_it(info, tmp);
252 }
253 if (send_final_progress_report(tmp) < 0) { retval++; log_it(error, "Unable to send final progress_rpt to server"); }
254 return(retval);
255}
256
257
258
259/*-----------------------------------------------------------*/
260
261
262
263int bind_client_port(struct sockaddr_in *sinClient, int client_port)
264/*
265Purpose:Bind one of my ports so that I may open it later and
266 write/read data to/from server with it.
267Params: sinClient - record/structure relating to the socket
268 client_port - port# to be bound
269Return: socket handle, to be used by other subroutines, if success
270 or <0 if failure
271*/
272{
273 int sClient=-1;
274 char tmp[MAX_STR_LEN+1];
275
276 memset((void*)sinClient, 0, sizeof(struct sockaddr_in));
277 sinClient->sin_family = AF_INET;
278 sinClient->sin_addr.s_addr = INADDR_ANY;
279 sinClient->sin_port = htons(client_port);
280 if ((sClient = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
281 {
282 sprintf(tmp, "Unable to open socket on port #%d", g_client_port);
283 log_it(error, tmp);
284 return(-1);
285 }
286 if (bind(sClient, (struct sockaddr*)sinClient, sizeof(struct sockaddr_in)) < 0)
287 {
288 sprintf(tmp, "Cannot bind %d - %s", g_client_port, strerror(errno));
289 log_it(error, tmp);
290 return(-2);
291 }
292 if (listen(sClient, MAX_PENDING) < 0)
293 {
294 sprintf(tmp, "Cannot setup listen (%d) - %sn", g_client_port, strerror(errno));
295 log_it(error, tmp);
296 return(-3);
297 }
298 log_it(debug, "Successfully bound client port.");
299 return(sClient);
300}
301
302
303
304/*-----------------------------------------------------------*/
305
306
307
308int compare_archives(char*msgbody, int socket_fd)
309/*
310Purpose:Compare archives, sent by server.
311Params: msgbody - char[MSG_BODY_SIZE] containing info
312about the archives to be compared
313socket_fd - file descriptor from which to
314read the archives sent by server to be compared.
315Return: result (0=success; nonzero=failure)
316*/
317{
318 char tmp[MAX_STR_LEN+1], command[MAX_STR_LEN+1], tempdev[MAX_STR_LEN+1], *p;
319 char temporary_logfile[MAX_STR_LEN+1]; // where mondoarchive writes its stdout,stderr
320 char mondoparams_str[MAX_STR_LEN+1];
321 struct s_server2client_msg_record incoming_rec;
322 int retval=0, len, new_sClient, res=0;
323 FILE*fout, *fin;
324 long diffs=0;
325 pthread_t progress_thread;
326
327 sprintf(tmp, "Comparison of %s commenced", msgbody);
328 log_it(info, tmp);
329 if (send_progress_rpt_to_server(g_server_name, tmp)) { log_it(error, "Unable to send 'yep, got this msg' progress_rpt to server"); }
330 sprintf(temporary_logfile, "/tmp/monitas-client.templog.%d", (int)random()%32767);
331 sprintf(tempdev, "/tmp/monitas-client.device.%d", (int)random()%32767);
332 unlink(tempdev);
333 if (mkfifo(tempdev, 700))
334 {
335 log_it(error, "Unable to create temporary fifo in preparation for the call to mondoarchive");
336 return(1);
337 }
338 unlink(temporary_logfile);
339 if (mkfifo(temporary_logfile, 700))
340 {
341 log_it(error, "Unable to create temporary logfile fifo in preparation for the call to mondoarchive");
342 return(1);
343 }
344 strcpy(mondoparams_str, get_param_from_rcfile(CLIENT_RCFILE, "mondoarchive_params"));
345 sprintf(tmp, "mondoarchive_params --> '%s'", mondoparams_str);
346 log_it(debug, tmp);
347 sprintf(command, "mondoarchive -Vu -F %s -d %s -I %s > %s"/*; rm -f %s %s"*/, mondoparams_str, tempdev, msgbody, temporary_logfile/*, tempdev, temporary_logfile*/);
348 call_program_in_background(&g_mondo_thread, command);
349 sleep(5);
350 if (!program_still_running(command))
351 { res=1; log_it(error, "Unable to start mondoarchive. Please check /var/log/mondo-archive.log"); }
352 else
353 {
354 if (pthread_create(&progress_thread, NULL, track_compare_task_progress, (void*)temporary_logfile))
355 { log_it(error, "Cannot create pthread to track mondo task progress"); return(1); }
356 fout = fopen(tempdev, "w");
357 log_it(debug, "Opened fopen() to tempdev");
358 retval = receive_file_from_socket(fout, socket_fd);
359 log_it(debug, "Calling get_bkgd_prog_result");
360 fclose(fout);
361 res = get_bkgd_prog_result(&g_mondo_thread);
362 res = 0; // *shrug* Seems to help :)
363 pthread_join(progress_thread, NULL);
364 }
365 if (res)
366 { retval++; log_it(error, "Mondoarchive returned an error."); }
367 if (retval) { log_it(debug, "Errors have occurred. Notifing server..."); }
368 else { log_it(debug, "Everything is OK so far. Notifying server..."); }
369 if (write(socket_fd, (char*)&retval, sizeof(retval))!=sizeof(retval)) {retval++;}
370/* receive msg from server; did comparison go OK at its end or not? */
371 unlink(tempdev);
372 unlink(temporary_logfile);
373 len = accept_and_recv_thru_client_port(g_sClient, &new_sClient, &g_sinClient, (char*)&incoming_rec, sizeof(incoming_rec));
374 if (len<0) { log_it(error, "After comparison, unable to accept/recv thru client port"); return(-10); }
375 sprintf(tmp, "After comparison, I received %s - %s", tmsg_to_string(incoming_rec.msg_type), incoming_rec.body);
376 log_it(debug, tmp);
377 if (incoming_rec.msg_type == compare_fail)
378 { retval++; log_it(error, "Server reported error(s) during comparison, although client didn't."); }
379 if (retval)
380 {
381 sprintf(tmp, "Errors occurred during comparison of %s", msgbody);
382 strcpy(command, call_program_and_get_last_line_of_output("tail -n20 /var/log/mondo-archive.log | grep /tmp/changed | head -n1"));
383 p = strstr(command, "/tmp/changed");
384 if (p)
385 {
386 strcat(command, " ");
387 sprintf(tmp, "command = '%s'", command);
388 log_it(debug, tmp);
389 *(strchr(p, ' '))='\0';
390 sprintf(tmp, "Opening list of changed files ('%s')", p);
391 log_it(debug, tmp);
392 log_it(info, "---Changed files---");
393 if ((fin=fopen(p, "r")))
394 { for(diffs=0; !feof(fin); diffs++) { fgets(tmp, MAX_STR_LEN, fin); if (strlen(tmp)>0) {tmp[strlen(tmp)-1]='\0';} log_it(info, tmp); } fclose(fin); }
395 log_it(info, "----End of list----");
396 sprintf(tmp, "%ld differences were found during comparison of %s", diffs, msgbody);
397 log_it(warn, tmp);
398 unlink(p);
399 }
400 else
401 {
402 sprintf(tmp, "Errors occurred during comparison of %s", msgbody);
403 log_it(error, tmp);
404 call_program_and_log_output("tail -n6 /var/log/mondo-archive.log");
405 log_it(info, "Please check /var/log/mondo-archive.log for more information");
406 }
407 }
408 else
409 {
410 sprintf(tmp, "Server agrees, comparison of %s succeeded :-)", msgbody);
411 log_it(info, tmp);
412 }
413 if (send_final_progress_report(tmp)) { retval++; log_it(error, "Unable to send final progress_rpt to server"); }
414 return(retval);
415}
416
417
418
419/*-----------------------------------------------------------*/
420
421
422
423int find_and_bind_free_server_port(struct sockaddr_in *sin, int *p_s)
424/*
425Purpose:Find a free port on the server. Bind to it, so that
426 whichever subroutine called me can then send data
427 to the server.
428Params: sin - server's IP address in a structure
429 p_s - [return] file descriptor of port binding
430Return: result (>0=success, -1=failure)
431*/
432{
433 int server_port;
434 char tmp[MAX_STR_LEN+1];
435
436 for(server_port = 8700; server_port < 8710; server_port++)
437 {
438 sin->sin_port = htons(server_port);
439 if ((*p_s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
440 {
441 perror("socket");
442 return(-1);
443 }
444 if (connect(*p_s, (struct sockaddr*)sin, sizeof(struct sockaddr_in)) < 0)
445 {
446 sprintf(tmp, "Not connecting at %d", server_port);
447 log_it(debug, tmp);
448 continue;
449 }
450 return(server_port);
451 }
452 return(-1);
453}
454
455
456
457/*-----------------------------------------------------------*/
458
459
460
461long increment_magic_number()
462/*
463Purpose:Increment the magic number which is attached to
464 each message sent from client to server, to make
465 the packet unique.
466Params: none
467Return: magic number
468*/
469{
470 static unsigned long magic=1;
471 magic=(magic % 999999999) + 1;
472 return(magic);
473}
474
475
476
477/*-----------------------------------------------------------*/
478
479
480
481int login_to_server(char*hostname, char*servername)
482/*
483Purpose:Ask server to log me (client) in.
484Params: hostname - client's hostname (not IP address
485 necessarily but it should resolve to it)
486 servername - server's hostname
487Return: result (-1=failure, N=client's port #)
488NB: The client's port # is chosen at random by
489 send_msg_to_server and returned to me.
490*/
491{
492 struct s_client2server_msg_record orig_rec;
493
494 orig_rec.msg_type = login;
495 strncpy(orig_rec.body, hostname, sizeof(orig_rec.body));
496 if (send_msg_to_server(&orig_rec, servername) < 0)
497 { return(-1); }
498 else
499 { return(orig_rec.port); }
500}
501
502
503
504/*-----------------------------------------------------------*/
505
506
507
508
509void logout_and_exit(char*servername)
510/*
511Purpose:Logout of server. Terminate.
512Params: servername - ip address of server
513Return: none
514*/
515{
516 if (g_logged_in_currently)
517 {
518 if (logout_of_server(servername))
519 { log_it(warn, "Failed to logout of server."); }
520 }
521 call_program_and_log_output("rm -Rf /tmp/monitas-client.*");
522 register_pid(0, "client");
523// chmod(g_command_fifo, 0);
524 unlink(g_command_fifo);
525 log_it(info, "---------- Monitas (client) has terminated ----------");
526 exit(0);
527}
528
529
530
531/*-----------------------------------------------------------*/
532
533
534
535int logout_of_server(char*servername)
536/*
537Purpose:Instruct server to log client out.
538Params: servername - hostname of server
539Return: result (0=success; nonzero=failure)
540*/
541{
542 struct s_client2server_msg_record orig_rec;
543
544 g_logging_out = true;
545 log_it(debug, "Logging out of server");
546 orig_rec.msg_type = logout;
547 strncpy(orig_rec.body, "Bye bye!", sizeof(orig_rec.body));
548 if (send_msg_to_server(&orig_rec, servername) < 0)
549 { return(1); }
550 else
551 { return(0); }
552}
553
554
555
556/*-----------------------------------------------------------*/
557
558
559
560int process_incoming_command(char*incoming)
561/*
562Purpose:Process incoming command, presumably
563 read from FIFO and sent there by sysadm/user.
564Params: incoming - raw command string itself
565Return: result (0=success; nonzero=failure)
566*/
567{
568 int res=0;
569 char tmp[MAX_STR_LEN+1];
570 int pos, i;
571 char command[MAX_STR_LEN+1], path[MAX_STR_LEN+1], aux[MAX_STR_LEN+1];
572 struct s_client2server_msg_record orig_rec;
573
574 pos=0;
575 sscanf(incoming, "%s %s", command, path);
576 for(i=0; i<strlen(command); i++) { command[i]=command[i]|0x60; }
577 if (!strcmp(command, "restore"))
578 { sscanf(incoming, "%s %s %s", command, path, aux); }
579 else
580 { aux[0] = '\0'; }
581 sprintf(tmp, "cmd=%s path=%s aux=%s", command, path, aux);
582 log_it(debug, tmp);
583 sprintf(tmp, "%s of %s [aux='%s'] <-- command received", command, path, aux);
584 log_it(info, tmp);
585 if (strcmp(command, "restore") && aux[0]!='\0')
586 { log_it(warn, "Ignoring auxiliary parameter: it is superfluous."); }
587 if (strcmp(command, "backup") && strcmp(command, "compare") && strcmp(command, "restore"))
588 {
589 sprintf(tmp, "%s - command unknown.", command);
590 log_it(error, tmp);
591 res=1;
592 }
593 else
594 {
595 sprintf(tmp, "'%s' sent to server as a formal request", incoming);
596 orig_rec.msg_type = user_req;
597 strncpy(orig_rec.body, incoming, sizeof(orig_rec.body));
598 if (send_msg_to_server(&orig_rec, g_server_name) < 0)
599 { res++; log_it(error, "Unable to send user req to server"); }
600 else
601 { log_it(debug, tmp); }
602 }
603 return(res);
604}
605
606
607
608/*-----------------------------------------------------------*/
609
610
611
612int restore_archives(char*msgbody, char*msgbodyAux, int socket_fd)
613/*
614Purpose:Restore archives, sent by server.
615Params: msgbody - char[MSG_BODY_SIZE] containing info
616about the archives to be restored
617socket_fd - file descriptor from which to
618read the archives sent by server.
619Return: result (0=success; nonzero=failure)
620*/
621{
622 char tmp[MAX_STR_LEN+1], command[MAX_STR_LEN+1], tempdev[MAX_STR_LEN+1], *p;
623 char temporary_logfile[MAX_STR_LEN+1]; // where mondorestore writes its stdout,stderr
624 struct s_server2client_msg_record incoming_rec;
625 int retval=0, len, new_sClient, res=0;
626 FILE*fout, *fin;
627 long diffs=0;
628 pthread_t progress_thread;
629
630 sprintf(tmp, "Restoration of %s commenced", msgbody);
631 log_it(info, tmp);
632 if (send_progress_rpt_to_server(g_server_name, tmp)) { log_it(error, "Unable to send 'yep, got this msg' progress_rpt to server"); }
633 sprintf(temporary_logfile, "/tmp/monitas-client.templog.%d", (int)random()%32767);
634 sprintf(tempdev, "/tmp/monitas-client.device.%d", (int)random()%32767);
635 unlink(tempdev);
636 if (mkfifo(tempdev, 700))
637 {
638 log_it(error, "Unable to create temporary fifo in preparation for the call to mondorestore");
639 return(1);
640 }
641 unlink(temporary_logfile);
642 if (mkfifo(temporary_logfile, 700))
643 {
644 log_it(error, "Unable to create temporary logfile in preparation for the call to mondorestore");
645 return(1);
646 }
647 sprintf(command, "mondorestore --monitas-live %s %s %s &> %s", tempdev, msgbody, msgbodyAux, temporary_logfile);
648// sprintf(command, "cat %s > %s", tempdev, "/tmp/out.dat");
649 call_program_in_background(&g_mondo_thread, command);
650 sleep(5);
651 if (!program_still_running(command))
652 {
653 res=1; log_it(error, "mondorestore could not be started. Please check /tmp/mondo-restore.log");
654 }
655 else
656 {
657 if (pthread_create(&progress_thread, NULL, track_restore_task_progress, (void*)temporary_logfile))
658 { log_it(error, "Cannot create pthread to track mondo task progress"); return(1); }
659 fout = fopen(tempdev, "w");
660 log_it(debug, "Opened fopen() to tempdev");
661 retval = receive_file_from_socket(fout, socket_fd);
662 if (retval && !system("cat /tmp/mondo-restore.log | grep -i \"End of restore_live_from_monitas_server\" &> /dev/null"))
663 {
664 retval=0;
665 log_it(debug, "SIGPIPE caught but that's OK, it was anticipated.");
666 res=0;
667 }
668 log_it(debug, "Calling get_bkgd_prog_result");
669 fclose(fout);
670 res = get_bkgd_prog_result(&g_mondo_thread);
671 pthread_join(progress_thread, NULL);
672 }
673 unlink(tempdev);
674 unlink(temporary_logfile);
675 if (res)
676 { retval++; log_it(error, "mondorestore returned an error."); }
677 if (retval) { log_it(debug, "Errors have occurred. Notifing server..."); }
678 else { log_it(debug, "Everything is OK so far. Notifying server..."); }
679 sleep(1); // probably unnecessary
680/* I do this thrice because mondorestore often causes a SIGPIPE, which means... I have to do this thrice :-) */
681 if (write(socket_fd, (char*)&retval, sizeof(retval))!=sizeof(retval)) {log_it(debug, "Failed to write wtf-info"); retval++;}
682 if (write(socket_fd, (char*)&retval, sizeof(retval))!=sizeof(retval)) {log_it(debug, "Failed to write wtf-info"); retval++;}
683 if (write(socket_fd, (char*)&retval, sizeof(retval))!=sizeof(retval)) {log_it(debug, "Failed to write wtf-info"); retval++;}
684/* receive msg from server; did restoration go OK at its end or not? */
685 unlink(tempdev);
686 unlink(temporary_logfile);
687 len = accept_and_recv_thru_client_port(g_sClient, &new_sClient, &g_sinClient, (char*)&incoming_rec, sizeof(incoming_rec));
688 if (len<0) { log_it(error, "After restoration, unable to accept/recv thru client port"); return(-10); }
689 sprintf(tmp, "After restoration, I received %s - %s", tmsg_to_string(incoming_rec.msg_type), incoming_rec.body);
690 log_it(debug, tmp);
691 if (incoming_rec.msg_type == restore_fail)
692 { retval++; log_it(error, "Server reported error(s) during restoration, although client didn't."); }
693 if (retval)
694 {
695 sprintf(tmp, "Errors occurred during restoration of %s", msgbody);
696 strcpy(command, call_program_and_get_last_line_of_output("tail -n20 /var/log/mondo-archive.log | grep /tmp/changed | head -n1"));
697 p = strstr(command, "/tmp/changed");
698 if (p)
699 {
700 strcat(command, " ");
701 sprintf(tmp, "command = '%s'", command);
702 log_it(debug, tmp);
703 *(strchr(p, ' '))='\0';
704 sprintf(tmp, "Opening list of changed files ('%s')", p);
705 log_it(debug, tmp);
706 log_it(info, "---Changed files---");
707 if ((fin=fopen(p, "r")))
708 { for(diffs=0; !feof(fin); diffs++) { fgets(tmp, MAX_STR_LEN, fin); if (strlen(tmp)>0) {tmp[strlen(tmp)-1]='\0';} log_it(info, tmp); } fclose(fin); }
709 log_it(info, "----End of list----");
710 sprintf(tmp, "%ld differences were found during restoration of %s", diffs, msgbody);
711 log_it(warn, tmp);
712 }
713 else
714 {
715 sprintf(tmp, "Errors occurred during restoration of %s", msgbody);
716 log_it(error, tmp);
717 call_program_and_log_output("tail -n6 /var/log/mondo-archive.log");
718 log_it(info, "Please check /var/log/mondo-archive.log for more information");
719 }
720 }
721 else
722 {
723 sprintf(tmp, "Server agrees, restoration of %s succeeded :-)", msgbody);
724 log_it(info, tmp);
725 }
726 if (send_final_progress_report(tmp)) { retval++; log_it(error, "Unable to send final progress_rpt to server"); }
727 return(retval);
728}
729
730
731
732/*-----------------------------------------------------------*/
733
734
735
736void *send_final_progress_report_SUB(void*inp)
737{
738 char message[MAX_STR_LEN+1];
739
740 strncpy(message, (char*)inp, MAX_STR_LEN);
741 sleep(10);
742 send_progress_rpt_to_server(g_server_name, message);
743 pthread_exit(NULL);
744}
745
746
747
748int send_final_progress_report(char*final_string)
749{
750 pthread_t thread;
751
752 if (send_progress_rpt_to_server(g_server_name, final_string)) { return(1); }
753 if (pthread_create(&thread, NULL, send_final_progress_report_SUB, (void*)"Idle")) { log_it(error, "Unable to create pthread"); return(1); }
754 return(0);
755}
756
757
758
759/*-----------------------------------------------------------*/
760
761
762
763int send_msg_to_server(struct s_client2server_msg_record *rec, char *servername)
764/*
765Purpose:Send message to server - a login/logout/ping request
766 or perhaps a request for data to be restored.
767Params: rec - the message to be sent to server
768 servername - the hostname of server
769Return: result (<0=failure, 0+=success)
770*/
771{
772 struct hostent *hp;
773 struct sockaddr_in sin;
774 int server_port, new_sClient, s, len, res;
775 struct s_server2client_msg_record incoming_rec;
776 struct pollfd ufds;
777 char tmp[MAX_STR_LEN+1];
778 void *thread_result;
779 pthread_t a_thread;
780
781/* If logging out then kill the trigger-watcher before trying;
782otherwise, the trigger-watcher will probably catch the
783'logout_ok' packet and go nutty on us :-)
784*/
785 if ((hp = gethostbyname(servername)) == NULL)
786 {
787 sprintf(tmp, "%s: unknown host", servername);
788 log_it(error, tmp);
789 return(-1);
790 }
791 if (g_logged_in_currently && rec->msg_type == login) { log_it(error, "Already logged in. Why try again?"); return(-1); }
792 if (!g_logged_in_currently && rec->msg_type != login)
793 {
794 log_it(fatal, "Server has forcibly logged you out.");
795 } /* or you never logged in to begin which, which suggests the programmer screwed up */
796 /* open client port if login */
797 if (rec->msg_type == login)
798 {
799 log_it(info, "Trying to login");
800 g_client_port = 8800 + rand()%100; // FIXME: retry if I can't use this port
801 g_sClient = bind_client_port(&g_sinClient, g_client_port);
802 if (g_sClient<0) { log_it(error, "Cannot bind client port"); return(-1); }
803 }
804 /* send msg to server */
805 rec->port = g_client_port;
806 memset((void*)&sin, 0, sizeof(sin));
807 sin.sin_family = AF_INET;
808 memcpy((void*)&sin.sin_addr, hp->h_addr, hp->h_length);
809 server_port = find_and_bind_free_server_port(&sin, &s);
810 if (server_port<=0)
811 {
812 sprintf(tmp, "Cannot find+bind free server port. Is server running?");
813 log_it(error, tmp);
814 return(-3);
815 }
816 rec->magic = increment_magic_number();
817 send (s, (char*)rec, sizeof(struct s_client2server_msg_record), 0);
818 close(s);
819 /* wait for ack/pong/feedback (if logging in/out) */
820 if (rec->msg_type == login /* || rec->msg_type == logout */)
821 {
822 ufds.fd = g_sClient;
823 ufds.events = POLLIN|POLLPRI;
824 poll(&ufds, 1, 1000);
825 if (!ufds.revents) { log_it(error, "Failed to poll"); return(-5); }
826 len = accept_and_recv_thru_client_port(g_sClient, &new_sClient, &g_sinClient, (char*)&incoming_rec, sizeof(incoming_rec));
827 if (len<0) { log_it(error, "Unable to accept/recv thru client port"); return(-10); }
828 sprintf(tmp, "Received %s - %s", tmsg_to_string(incoming_rec.msg_type), incoming_rec.body);
829 log_it(info, tmp);
830 if (rec->msg_type != login && incoming_rec.msg_type == login_ok) { log_it(error, "WTF? login_ok but I wasn't logging in"); }
831 if (rec->msg_type != logout&& incoming_rec.msg_type == logout_ok){ log_it(error, "WTF? logout_ok but I wasn't logging out"); }
832 close(new_sClient);
833 new_sClient=-1;
834 }
835 if (incoming_rec.msg_type == backup_fail) { log_it(error, "Failed, says server"); return(-8); }
836 /* fork the process which watches in the background for pings/requests/etc. */
837 if (rec->msg_type == login)
838 {
839 g_logged_in_currently = true;
840 strcpy(tmp, "Hello world!");
841 res = pthread_create(&a_thread, NULL, watch_port_for_triggers_from_server, (void*)tmp);
842 log_it(debug, "Returning from login + call to pthread_create");
843 return(server_port);
844 }
845 if (rec->msg_type == logout)
846 {
847 log_it(debug, "Calling pthread_join to reunite trigger-watcher and main loop");
848 res = pthread_join(a_thread, &thread_result);
849 if (res) { /*perror("Thread join failed");*/ log_it(debug, "Thread join failed in send_msg_to_server()"); }
850 else { sprintf(tmp, "Thread join succeeded. Result: %s", (char*)thread_result); log_it(debug, tmp); }
851 }
852 return(0);
853}
854
855
856
857/*-----------------------------------------------------------*/
858
859
860
861int send_ping_to_server(char*servername, char*msg)
862/*
863Purpose:Send a 'ping' to server.
864Params: msg - string to send ("Hello world"?)
865 servername - server's hostname
866Return: result (0=success, nonzero=failure)
867*/
868{
869 struct s_client2server_msg_record orig_rec;
870 orig_rec.msg_type = ping;
871 strncpy(orig_rec.body, msg, sizeof(orig_rec.body));
872 if (send_msg_to_server(&orig_rec, servername) < 0)
873 { return(1); }
874 else
875 { return(0); }
876}
877
878
879
880/*-----------------------------------------------------------*/
881
882
883
884int send_progress_rpt_to_server(char*servername, char*msg)
885/*
886Purpose:Send a 'progress_rpt' string to server.
887Params: msg - string to send ("Hello world"?)
888 servername - server's hostname
889Return: result (0=success, nonzero=failure)
890*/
891{
892 struct s_client2server_msg_record orig_rec;
893 orig_rec.msg_type = progress_rpt;
894 strncpy(orig_rec.body, msg, sizeof(orig_rec.body));
895 if (send_msg_to_server(&orig_rec, servername) < 0)
896 { return(1); }
897 else
898 { return(0); }
899}
900
901
902
903/*-----------------------------------------------------------*/
904
905
906
907void terminate_daemon(int sig)
908/*
909Purpose: Shut down the server in response to interrupt.
910Params: Signal received.
911Returns: None
912*/
913{
914 int res;
915
916// FIXME - takes server 1-2 mins to realize I've aborted. I want that to be 5-10 seconds :)
917 set_signals(false); // termination in progress
918 log_it(info, "Abort signal caught by interrupt handler");
919 call_program_and_log_output("kill `ps ax | grep mondo | grep -v \"ps ax\" | grep -v \"grep mondo\" | grep monitas | cut -d' ' -f1`");
920 if (send_ping_to_server(g_server_name, "I'm pinging you before I logout"))
921 { log_it(error, "Server has shut down without warning."); }
922 if (g_mondo_thread)
923 {
924 res = get_bkgd_prog_result(&g_mondo_thread);
925 }
926 logout_and_exit(g_server_name);
927}
928
929
930
931/*-----------------------------------------------------------*/
932
933
934
935void *track_backup_task_progress(void*inp)
936{
937 char fname[MAX_STR_LEN+1],
938 tmp[MAX_STR_LEN+1],
939 progress_str[MAX_STR_LEN+1],
940 old_progstr[MAX_STR_LEN+1],
941 *p;
942 struct s_client2server_msg_record rec;
943 FILE*fin;
944 bool biggies=false, regulars=false;
945 int prev_percentage=0, i;
946
947 rec.msg_type = progress_rpt;
948 strcpy(fname, (char*)inp);
949 log_it(debug, "track_backup_task_progres() --- entering");
950 fin = fopen(fname, "r");
951 old_progstr[0]='\0';
952 sprintf(tmp, "fname = %s", fname);
953 log_it(debug, tmp);
954 sleep(2);
955 if (!does_file_exist(fname)) { log_it(fatal, "track_backup_task_progress() -- fname not found"); }
956 strcpy(rec.body, "Working");
957 if (send_msg_to_server(&rec, g_server_name) < 0) { log_it(error, "Failed to send progress_rpt msg to server."); pthread_exit(NULL); }
958 log_it(debug, rec.body);
959/* skip initial stuff */
960 while(!feof(fin))
961 {
962 fgets(progress_str, MAX_STR_LEN, fin);
963 progress_str[MAX_STR_LEN]='\0';
964 if (strlen(progress_str)<2) { continue; }
965 if (strstr(progress_str, "TASK")) { break; }
966 }
967/* skip more stuff */
968 while(!feof(fin))
969 {
970 fgets(progress_str, MAX_STR_LEN, fin);
971 progress_str[MAX_STR_LEN]='\0';
972 if (strlen(progress_str)<2) { continue; }
973 if (!strstr(progress_str, "TASK")) { break; }
974 }
975/* report on regular+biggie files */
976 while(!feof(fin))
977 {
978 fgets(progress_str, MAX_STR_LEN, fin);
979 progress_str[MAX_STR_LEN]='\0';
980 if (strstr(progress_str, "rchiving set 0"))
981 { prev_percentage = 0; regulars = true; }
982 if (strstr(progress_str, "acking up all large files"))
983 { prev_percentage = 0; regulars = false; biggies = true; }
984 if (strlen(progress_str)<2) { continue; }
985 if (!strstr(progress_str, "TASK")) { continue; }
986 progress_str[strlen(progress_str)-1] = '\0';
987 log_it(debug, progress_str);
988 if (!biggies && !regulars)
989 { strcpy(progress_str, "Still working..."); }
990 if (strcmp(progress_str, old_progstr))
991 {
992 strcpy(old_progstr, progress_str);
993 if (biggies)
994 { sprintf(rec.body, "Large files: %s", progress_str+6); }
995 else if (regulars)
996 { sprintf(rec.body, "Regular files: %s", progress_str+6); }
997 if (!(p=strstr(progress_str, "% done"))) { continue; }
998
999 log_it(info, rec.body);
1000 if (send_progress_rpt_to_server(g_server_name, rec.body)) { log_it(error, "Failed to send progress_rpt msg to server."); pthread_exit(NULL); }
1001 continue;
1002
1003 while(!isdigit(*(p-1))) { p--; }
1004 strcpy(tmp, p);
1005 *(strchr(tmp, '%')) = '\0';
1006 i = atoi(tmp);
1007 if (i > prev_percentage)
1008 {
1009 prev_percentage = i;
1010 log_it(info, rec.body);
1011// FIXME - could simply call send_progress_rpt_to_server()
1012 if (send_msg_to_server(&rec, g_server_name) < 0) { log_it(error, "Failed to send progress_rpt msg to server."); pthread_exit(NULL); }
1013 }
1014 }
1015 }
1016 log_it(debug, "track_backup_task_progress() --- leaving");
1017 pthread_exit(NULL);
1018}
1019
1020
1021
1022/*-----------------------------------------------------------*/
1023
1024
1025
1026void *track_compare_task_progress(void*inp)
1027{
1028 char fname[MAX_STR_LEN+1],
1029 tmp[MAX_STR_LEN+1],
1030 progress_str[MAX_STR_LEN+1],
1031 old_progstr[MAX_STR_LEN+1],
1032 *p;
1033// struct s_client2server_msg_record rec;
1034 FILE*fin;
1035 bool biggies=false, regulars=false;
1036 int prev_percentage=0, i;
1037
1038 strcpy(fname, (char*)inp);
1039 log_it(debug, "track_compare_task_progress() --- entering");
1040 if (!(fin = fopen(fname, "r"))) { log_it(fatal, "Unable to openin tempdev while comparing"); }
1041 old_progstr[0]='\0';
1042 sprintf(tmp, "fname = %s", fname);
1043 log_it(debug, tmp);
1044 sleep(2);
1045 if (!does_file_exist(fname)) { log_it(fatal, "track_compare_task_progress() -- fname not found"); }
1046 log_it(debug, "Working");
1047 if (send_progress_rpt_to_server(g_server_name, "Working")) { log_it(error, "Failed to send progress_rpt msg to server."); pthread_exit(NULL); }
1048
1049/* report on regular+biggie files */
1050 while(!feof(fin))
1051 {
1052 fgets(progress_str, MAX_STR_LEN, fin);
1053 progress_str[MAX_STR_LEN]='\0';
1054 log_it(debug, progress_str);
1055 if (strstr(progress_str, "erifying fileset #0"))
1056 { prev_percentage = 0; regulars = true; }
1057 if (strstr(progress_str, "erifying all bigfiles"))
1058 { prev_percentage = 0; regulars = false; biggies = true; }
1059 if (strlen(progress_str)<2) { continue; }
1060 if (!strstr(progress_str, "TASK")) { continue; }
1061 progress_str[strlen(progress_str)-1] = '\0';
1062 if (!biggies && !regulars)
1063 { strcpy(progress_str, "Still working..."); }
1064 if (strcmp(progress_str, old_progstr))
1065 {
1066 strcpy(old_progstr, progress_str);
1067 if (biggies)
1068 { sprintf(tmp, "Large files: %s", progress_str+6); }
1069 else if (regulars)
1070 { sprintf(tmp, "Regular files: %s", progress_str+6); }
1071 if (!(p=strstr(progress_str, "% done"))) { continue; }
1072
1073 log_it(info, tmp);
1074 if (send_progress_rpt_to_server(g_server_name, tmp)) { log_it(error, "Failed to send progress_rpt msg to server."); pthread_exit(NULL); }
1075 continue;
1076
1077 while(!isdigit(*(p-1))) { p--; }
1078 strcpy(tmp, p);
1079 *(strchr(tmp, '%')) = '\0';
1080 i = atoi(tmp);
1081 if (i > prev_percentage)
1082 {
1083 prev_percentage = i;
1084 log_it(info, tmp);
1085// FIXME - could simply call send_progress_rpt_to_server()
1086 if (send_progress_rpt_to_server(g_server_name, tmp)) { log_it(error, "Failed to send progress_rpt msg to server."); pthread_exit(NULL); }
1087 }
1088 }
1089 }
1090 log_it(debug, "track_compare_task_progress() --- leaving");
1091 pthread_exit(NULL);
1092}
1093
1094
1095
1096/*-----------------------------------------------------------*/
1097
1098
1099
1100void *track_restore_task_progress(void*inp)
1101{
1102 char fname[MAX_STR_LEN+1],
1103 tmp[MAX_STR_LEN+1],
1104 progress_str[MAX_STR_LEN+1],
1105 old_progstr[MAX_STR_LEN+1],
1106 *p;
1107// struct s_client2server_msg_record rec;
1108 FILE*fin;
1109 bool biggies=false, regulars=false;
1110 int prev_percentage=0, i;
1111
1112 strcpy(fname, (char*)inp);
1113 log_it(debug, "track_restore_task_progress() --- entering");
1114 if (!(fin = fopen(fname, "r"))) { log_it(fatal, "Unable to openin tempdev while restoring"); }
1115 old_progstr[0]='\0';
1116 sprintf(tmp, "fname = %s", fname);
1117 log_it(debug, tmp);
1118 sleep(2);
1119 if (!does_file_exist(fname)) { log_it(fatal, "track_restore_task_progress() -- fname not found"); }
1120 log_it(debug, "Working");
1121 if (send_progress_rpt_to_server(g_server_name, "Working")) { log_it(error, "Failed to send progress_rpt msg to server."); pthread_exit(NULL); }
1122
1123// FIXME --- mondorestore does not yet spit out its progress in
1124// a user-friendly format; so, most of the following code won't
1125// work. The server will know we're working but it won't know
1126// how far along we've gotten.
1127
1128/* report on regular+biggie files */
1129 while(!feof(fin))
1130 {
1131 fgets(progress_str, MAX_STR_LEN, fin);
1132 progress_str[MAX_STR_LEN]='\0';
1133 continue;
1134
1135 log_it(debug, progress_str);
1136 if (strstr(progress_str, "estoring fileset #0"))
1137 { prev_percentage = 0; regulars = true; }
1138 if (strstr(progress_str, "erifying all bigfiles"))
1139 { prev_percentage = 0; regulars = false; biggies = true; }
1140 if (strlen(progress_str)<2) { continue; }
1141 if (!strstr(progress_str, "TASK")) { continue; }
1142 progress_str[strlen(progress_str)-1] = '\0';
1143 if (!biggies && !regulars)
1144 { strcpy(progress_str, "Still working..."); }
1145 if (strcmp(progress_str, old_progstr))
1146 {
1147 strcpy(old_progstr, progress_str);
1148 if (biggies)
1149 { sprintf(tmp, "Large files: %s", progress_str+6); }
1150 else if (regulars)
1151 { sprintf(tmp, "Regular files: %s", progress_str+6); }
1152 if (!(p=strstr(progress_str, "% done"))) { continue; }
1153
1154 log_it(info, tmp);
1155 if (send_progress_rpt_to_server(g_server_name, tmp)) { log_it(error, "Failed to send progress_rpt msg to server."); pthread_exit(NULL); }
1156 continue;
1157
1158 while(!isdigit(*(p-1))) { p--; }
1159 strcpy(tmp, p);
1160 *(strchr(tmp, '%')) = '\0';
1161 i = atoi(tmp);
1162 if (i > prev_percentage)
1163 {
1164 prev_percentage = i;
1165 log_it(info, tmp);
1166// FIXME - could simply call send_progress_rpt_to_server()
1167 if (send_progress_rpt_to_server(g_server_name, tmp)) { log_it(error, "Failed to send progress_rpt msg to server."); pthread_exit(NULL); }
1168 }
1169 }
1170 }
1171 log_it(debug, "track_restore_task_progress() --- leaving");
1172 pthread_exit(NULL);
1173}
1174
1175
1176
1177/*-----------------------------------------------------------*/
1178
1179
1180
1181void *watch_port_for_triggers_from_server(void*arg)
1182/*
1183Purpose:Watch client port for incoming trigger
1184Params: none; uses global vars instead
1185Return: none
1186*/
1187{
1188 struct pollfd ufds;
1189 struct s_server2client_msg_record incoming_rec;
1190 int len, res, new_s;
1191 char tmp[MAX_STR_LEN+1];
1192
1193 strcpy(tmp,(char*)arg);
1194 log_it(info, "Awaiting triggers from server");
1195 for(;;)
1196 {
1197 /* wait for ack/pong/feedback/trigger */
1198 ufds.fd = g_sClient;
1199 ufds.events = POLLIN|POLLPRI;
1200 poll(&ufds, 1, 1000);
1201 if (!ufds.revents) { continue; } /* wait again */
1202 len = accept_and_recv_thru_client_port(g_sClient, &new_s, &g_sinClient, (char*)&incoming_rec, sizeof(incoming_rec));
1203 if (len<0) { log_it(error, "Unable to receive incoming trigger from server"); continue; }
1204 switch(incoming_rec.msg_type)
1205 {
1206 case trigger_backup:
1207 res = back_my_smitch_up(incoming_rec.body, new_s); /* no need to multitask: it's the client! :) */
1208 break;
1209 case trigger_compare:
1210 res = compare_archives(incoming_rec.body, new_s);
1211 break;
1212 case trigger_restore:
1213 res = restore_archives(incoming_rec.body, incoming_rec.bodyAux, new_s);
1214 break;
1215 case logout_ok:
1216 if (!g_logging_out)
1217 { log_it(fatal, "Server has forcibly logged you out. Has server shut down?"); }
1218 g_logged_in_currently = false;
1219 g_logging_out = false;
1220// exit(0);
1221 pthread_exit("Thou hast been logged out.");
1222 case login_fail:
1223 log_it(fatal, "Failed to login. Server thinks we're logged in already.");
1224 default:
1225 sprintf(tmp, "Received %s - '%s'", tmsg_to_string(incoming_rec.msg_type), incoming_rec.body);
1226 log_it(info, tmp);
1227 }
1228 close(new_s);
1229 }
1230}
1231
1232
1233
1234/*-----------------------------------------------------------*/
1235
1236
1237
1238int main(int argc, char*argv[])
1239/*
1240Purpose: main subroutine
1241Parameters: none
1242Return: result (0=success, nonzero=failure)
1243*/
1244{
1245 int client_port;
1246 char hostname[MAX_STR_LEN+1], tmp[MAX_STR_LEN+1];
1247// char msg[MAX_STR_LEN+1];
1248// bool done;
1249// pthread_t thread;
1250
1251 log_it(info, "---------- Monitas (client) by Hugo Rabson ----------");
1252 register_pid(getpid(), "client");
1253 set_signals(true);
1254 srandom(time(NULL));
1255 /* FIXME - add Ctrl-C / sigterm trapping */
1256
1257/*
1258 call_program_in_background(&thread, "ls aaa");
1259 if (program_still_running("ls aaa"))
1260 { printf("Program is still running\n"); }
1261 else
1262 { printf("Program is no longer running\n"); }
1263 exit(0);
1264*/
1265 if (argc == 2)
1266 {
1267 strncpy(g_server_name, argv[1], MAX_STR_LEN);
1268 g_server_name[MAX_STR_LEN]='\0';
1269 }
1270 else
1271 {
1272 fprintf(stderr, "client <server addr>\n");
1273 exit(1);
1274 }
1275 gethostname(hostname, sizeof(hostname));
1276 sprintf(tmp, "Logging onto server as client '%s'", hostname);
1277 log_it(info, tmp);
1278 client_port = login_to_server(hostname, g_server_name);
1279 if (client_port <= 0)
1280 {
1281 fprintf(stderr, "Unable to login to server.\n");
1282 log_it(error, "Unable to login to server.");
1283 exit(1);
1284 }
1285
1286// set_param_in_rcfile(CLIENT_RCFILE, "mondoarchive_params", "-1 -L");
1287 log_it(debug, "Awaiting commands from FIFO");
1288 create_and_watch_fifo_for_commands(CLIENT_COMDEV);
1289 logout_and_exit(g_server_name);
1290 exit(0);
1291}
1292/* end main() */
1293
1294
1295
Note: See TracBrowser for help on using the repository browser.