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

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

monitas latest version

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