예제 #1
0
파일: main.c 프로젝트: 5kylight/DropKox
int main(int argc, char *argv[])
{	
	/*Prepare to exit */
	signal(SIGINT, exit_signal_handler);
	
	// TODO: AteXIT fun!
	atexit(before_exit);

	/* Reading configuration */
	configure_data();

	/* Creating, binding and listening on socket */
	struct sockaddr_in sa_server;

	sa_server.sin_family = AF_INET;
	sa_server.sin_addr.s_addr = INADDR_ANY;
	sa_server.sin_port = htons(port);
	server_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (bind(server_socket, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
		error("inet bind");
	if(listen(server_socket, SOMAXCONN) < 0)
		error("listen inet");

	/* FD set */
	fd_set read_set;
	FD_ZERO(&set);
	FD_SET(server_socket, &set);
	fd_hwm = server_socket;

	struct message message;
	int new_client;
	while(is_working) {
		read_set = set;
		if (select(fd_hwm + 1, &read_set, NULL, NULL, NULL) < 0)
			error("select");

		for (int fd = 0; fd <= fd_hwm; fd++) {
			if(FD_ISSET(fd, &read_set)) {
				/* If this is new connection to accept*/
				if (fd == server_socket) {
					new_client = accept(fd, NULL, 0);
					FD_SET(new_client, &set);
					fd_hwm = new_client > fd_hwm ? new_client : fd_hwm;
				}
				/* If this client is ready to read from him */
				else {
					recv(fd, &message, sizeof(message), 0);
					char *file_name = message.file.file_name;
					char *normalized_name = calloc(strlen(file_name) + strlen(backup_main_path),
						 sizeof(char));
					strcpy(normalized_name, backup_main_path);
					strcat(normalized_name, file_name);
					
					if (message.type == NEW_FILE) {	
						time(&last_client_push);
						receive_file_from_socket(fd, normalized_name, message.file);
						confirm_received(fd);
					
					} else if(message.type == NEW_DIR) {
						time(&last_client_push);
						receive_dir_from_socket(fd, normalized_name, message.file);
						confirm_received(fd);

					} else if(message.type == PULL_REQUEST) {
						current_socket = fd;
						current_time = message.last_update_time;
						if (difftime(last_client_push, current_time) > FILE_DIFF);
							ftw(backup_main_path, check_updates, 16);

					} else if(message.type == DISCONNECT) {
						FD_CLR(fd, &set);
					} 
					free(normalized_name);
					message.type = E;
				}
			}
		}
	}
}
예제 #2
0
int backup_client(char*ipaddr, int port, char*clientpath)
/*
Purpose:Backup the path of a specific client. Receive
the archives. Store them locally (on me, the server).
Params:	clientno - client# in g_clientlist[]
        clientpath - client's path to be backed up
Return: result (0=success, nonzero=failure)
*/
{
  struct s_server2client_msg_record rec_to_client;
  int res=0, socket_fd, noof_archives, i, len;
  char tmp[MAX_STR_LEN+1], outfile[MAX_STR_LEN+1];
  FILE*fout;

  log_it(info, "%s - backup of %s commencing", ipaddr, clientpath);
  sprintf(outfile, "/var/spool/monitas/%s/%lu.dat", ipaddr, time(NULL));
  if (does_file_exist(outfile)) { log_it(error, "Backup storage location '%s' exists already. That should be impossible.", outfile); return(1); }
  if (make_hole_for_file(outfile))
    { res++; log_it(error, "Cannot write archive to spool dir '%s'", outfile); }
  else if (!(fout=fopen(outfile, "w")))
    { res++; log_it(fatal, "Failed to openout temp data file '%s'", outfile); }
  else
    {
      log_it(debug, "Backing up %s - archive=%s", ipaddr, outfile);
      rec_to_client.msg_type = trigger_backup;
      strncpy(rec_to_client.body, clientpath, sizeof(rec_to_client.body));
      if (send_msg_to_client(&rec_to_client, ipaddr, port, &socket_fd))
        { log_it(error, "backup_client - failed to send msg to client"); return(1); }
      res += receive_file_from_socket(fout, socket_fd);
      len=read(socket_fd, (char*)&i, sizeof(i));
      if (!len) { res++; log_it(error, "Client hasn't told me the result of its call to mondoarchive"); }
      else if (len!=sizeof(i)) { res++; log_it(error, "Client didn't sent _entire_ result of its call to mondoarchive"); }
      else if (i) { res++; log_it(error, "Client said, mondoarchive returned an error."); }
      else { log_it(debug, "Client said, mondoarchive returned OK"); }
      fclose(fout);
      close(socket_fd);
    }
/* Shuffle older backups off the mortal coil. Leave maximum of 4 backup files in /var/spool/monitas/[ipaddr] */
  sprintf(tmp, "find /var/spool/monitas/%s -type f 2> /dev/null | grep -n \"\" | tail -n1 | cut -d':' -f1", ipaddr);
  noof_archives = atoi(call_program_and_get_last_line_of_output(tmp));
  i = noof_archives - 3;
  if (i>0)
    {
      sprintf(tmp, "rm -f `find /var/spool/monitas/%s -type f | sort | head -n%d`", ipaddr, i);
      call_program_and_log_output(tmp);
    }
/* Return success/failure value */
  if (res>0)
    {
      log_it(error, "%s - error(s) occurred while backing up %s", ipaddr, clientpath);
      rec_to_client.msg_type = backup_fail;
      sprintf(rec_to_client.body, "Failed to backup %s", clientpath);
      log_it(debug, rec_to_client.body);
      unlink(outfile);
    }
  else
    {
      log_it(info, "%s - backed up %s ok", ipaddr, clientpath);
      rec_to_client.msg_type = backup_ok;
      sprintf(rec_to_client.body, "%s - backed up ok", clientpath);
      log_it(debug, rec_to_client.body);
    }
  if (send_msg_to_client(&rec_to_client, ipaddr, port, &socket_fd))
    {
      res++;
      log_it(error, "Unable to notify %s of backup success/failure", ipaddr);
      i = find_client_in_clientlist(ipaddr);
      if (i>=0) { forcibly_logout_client(i); }
      log_it(info, "I'm assuming the backup was bad because the client cannot be reached.");
      unlink(outfile);
    }
  return(res);
}