source: MondoRescue/trunk/monitas/client.c@ 1041

Last change on this file since 1041 was 783, checked in by Bruno Cornec, 18 years ago
  • Massive rewrite continues for memory management.
  • main structure should now have all parameters allocated dynamically
  • new lib libmr.a + dir + build process reviewed to support it.
  • new include subdir to host external definitions of the new lib
  • code now compiles. Still one remaining link issues for mondorestore. This should allow for some tests soon.

(goal is to separate completely reviewed code and functions and provide clean interfaces)

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