source: trunk/monitas/client.c @ 1041

Last change on this file since 1041 was 783, checked in by bruno, 13 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.