source: trunk/monitas/client.c @ 387

Last change on this file since 387 was 353, checked in by bcornec, 13 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.