示例#1
0
static int sync_rm(csiebox_server *server, int conn_fd, csiebox_protocol_rm *rm)/*{{{*/
{
	char client_path[PATH_MAX];
	char target_path[PATH_MAX];
	if (recv_message(conn_fd, client_path, PATH_MAX)) {
		sprintf(target_path, "%s%s", get_user_homedir(server, server->client[conn_fd]), make_path(client_path));
		struct stat fstatus;
		memset(&fstatus, 0, sizeof(fstatus));
		lstat(target_path, &fstatus);
		if (S_ISDIR(fstatus.st_mode)) rmdir(target_path);
		else unlink(target_path);
		fprintf(stderr, "removed : %s\n", target_path);
	}
	// resend message back to client
	csiebox_protocol_header header;
	memset(&header, 0, sizeof(header));
	header.res.magic = CSIEBOX_PROTOCOL_MAGIC_RES;
	header.res.op = CSIEBOX_PROTOCOL_OP_RM;
	header.res.status = CSIEBOX_PROTOCOL_STATUS_OK;
	if (!send_message(conn_fd, &header, sizeof(header))) {
		fprintf(stderr, "send back message error\n");
		return 0;
	}
	return 1;
}/*}}}*/
示例#2
0
static void rm_file(csiebox_server* server, int conn_fd, csiebox_protocol_rm* rm) {
	csiebox_client_info* info = server->client[conn_fd];
	char* homedir = get_user_homedir(server, info);
	char req_path[PATH_MAX], buf[PATH_MAX];
	memset(req_path, 0, PATH_MAX);
	memset(buf, 0, PATH_MAX);
	recv_message(conn_fd, buf, rm->message.body.pathlen);
	sprintf(req_path, "%s%s", homedir, buf);
	free(homedir);
	fprintf(stderr, "rm (%zd, %s)\n", strlen(req_path), req_path);
	struct stat stat;
	memset(&stat, 0, sizeof(stat));
	lstat(req_path, &stat);
	if ((stat.st_mode & S_IFMT) == S_IFDIR) {
		rmdir(req_path);
	} else {
		unlink(req_path);
	}

	csiebox_protocol_header header;
	memset(&header, 0, sizeof(header));
	header.res.magic = CSIEBOX_PROTOCOL_MAGIC_RES;
	header.res.op = CSIEBOX_PROTOCOL_OP_RM;
	header.res.datalen = 0;
	header.res.client_id = conn_fd;
	header.res.status = CSIEBOX_PROTOCOL_STATUS_OK;
	send_message(conn_fd, &header, sizeof(header));
}
示例#3
0
static int sync_file(csiebox_server *server, int conn_fd, csiebox_protocol_file *file)/*{{{*/
{
	// receive path
	char full_path[PATH_MAX];
	recv_message(conn_fd, full_path, PATH_MAX);
	char target_path[PATH_MAX];
	sprintf(target_path, "%s%s", get_user_homedir(server, server->client[conn_fd]), make_path(full_path));
	fprintf(stderr, "sync file : target path : %s\n", target_path);
	// receive data
	struct stat fstatus;
	memset(&fstatus, 0, sizeof(fstatus));
	int open_success = lstat(target_path, &fstatus);
	if (S_ISREG(fstatus.st_mode)){
		int fd = open(target_path, O_WRONLY | O_CREAT | O_TRUNC);
		if (fd < 0) fprintf(stderr, "sync file : open fail\n");
		while(1){
			uint8_t buffer[1025];
			memset(buffer, 0, 1025);
			recv_message(conn_fd, buffer, 1024);
			write(fd, buffer, strlen(buffer));
			if (strlen(buffer) < 1024) break;
		}
		fsync(fd);
		close(fd);
		fprintf(stderr, "sync file : write success\n");
	}
	// symbolic link
	if (open_success == -1 || S_ISLNK(fstatus.st_mode)) {
		uint8_t actual_path[PATH_MAX];
		memset(actual_path, 0, PATH_MAX);
		recv_message(conn_fd, actual_path, PATH_MAX);
		if (symlink(actual_path, target_path) == 0) {
			fprintf(stderr, "sync file : symbolic link create/modify success\n");
		}
	}

	// resend message back to client for time
	csiebox_protocol_header header;
	memset(&header, 0, sizeof(header));
	header.res.magic = CSIEBOX_PROTOCOL_MAGIC_RES;
	header.res.op = CSIEBOX_PROTOCOL_OP_SYNC_FILE;
	header.res.status = CSIEBOX_PROTOCOL_STATUS_OK;
	send_message(conn_fd, &header, sizeof(header));
	fprintf(stderr, "sync file : success\n");

	// utime
	struct utimbuf meta_time;
	memset(&meta_time, 0, sizeof(meta_time));
	recv_message(conn_fd, &meta_time, sizeof(meta_time));
	utime(target_path, &meta_time);
	fprintf(stderr, "sync file : utime\n");
	
	return 1;
}/*}}}*/
示例#4
0
static int sync_hardlink(csiebox_server *server, int conn_fd, csiebox_protocol_hardlink *hardlink)/*{{{*/
{
	char client_src_path[PATH_MAX];
	char client_target_path[PATH_MAX];
	if (!recv_message(conn_fd, client_src_path, PATH_MAX) || 
		!recv_message(conn_fd, client_target_path, PATH_MAX)) {
		fprintf(stderr, "receive path error\n");
		return 0;
	}
	// sync hardlink
	fprintf(stderr, "sync hardlink : receive path :\n\t%s\n\t%s\n", client_src_path, client_target_path);
	char src_path[PATH_MAX], target_path[PATH_MAX];
	sprintf(src_path, "%s%s", get_user_homedir(server, server->client[conn_fd]), make_path(client_src_path));
	sprintf(target_path, "%s%s", get_user_homedir(server, server->client[conn_fd]), make_path(client_target_path));
	remove(target_path);
	fprintf(stderr, "sync hardlink : remove : %s\n", target_path);
	link(src_path, target_path);

	// send back message for time
	csiebox_protocol_header header;
	memset(&header, 0, sizeof(header));
	header.res.magic = CSIEBOX_PROTOCOL_MAGIC_RES;
	header.res.op = CSIEBOX_PROTOCOL_OP_SYNC_HARDLINK;
	header.res.status = CSIEBOX_PROTOCOL_STATUS_OK;
	send_message(conn_fd, &header, sizeof(header));
	fprintf(stderr, "sync hardlink : success\n");
	
	// utime
	struct utimbuf meta_time;
	memset(&meta_time, 0, sizeof(meta_time));
	recv_message(conn_fd, &meta_time, sizeof(meta_time));
	utime(src_path, &meta_time);

	fprintf(stderr, "sync hardlink : utime\n");
	return 1;
}/*}}}*/
示例#5
0
/*============================================
 * expand_special_fname_chars -- Replace ~ with home
 *==========================================*/
BOOLEAN
expand_special_fname_chars (STRING buffer, INT buflen, INT utf8)
{
	char * sep=0;
	if (buffer[0]=='~') {
		if (is_dir_sep(buffer[1])) {
			STRING home = get_home();
			if (home && home[0]) {
				STRING tmp;
				if ((INT)strlen(home) + 1 + (INT)strlen(buffer) > buflen) {
					return FALSE;
				}
				tmp = strsave(buffer);
				buffer[0] = 0;
				llstrapps(buffer, buflen, utf8, home);
				llstrapps(buffer, buflen, utf8, tmp+1);
				strfree(&tmp);
				return TRUE;
			}
		}
		/* check for ~name/... and resolve the ~name */
		if ((sep = strchr(buffer,LLCHRDIRSEPARATOR))) {
			STRING username = strsave(buffer+1);
			STRING homedir;
			username[sep-buffer+1] = 0;
			homedir = get_user_homedir(username);
			strfree(&username);
			if (homedir) {
				STRING tmp=0;
				if ((INT)strlen(homedir) + 1 + (INT)strlen(sep+1) > buflen) {
					return FALSE;
				}
				tmp = strsave(sep+1);
				buffer[0] = 0;
				llstrapps(buffer, buflen, utf8, homedir);
				llstrapps(buffer, buflen, utf8, tmp+(sep-buffer+1));
				strfree(&tmp);
				return TRUE;
			}
		}
	}
	return TRUE;
}
示例#6
0
//handle the login request from client
static void login(
  csiebox_server* server, int conn_fd, csiebox_protocol_login* login) {
  int succ = 1;
  csiebox_client_info* info =
    (csiebox_client_info*)malloc(sizeof(csiebox_client_info));
  memset(info, 0, sizeof(csiebox_client_info));
  if (!get_account_info(server, login->message.body.user, &(info->account))) {
    fprintf(stderr, "cannot find account\n");
    succ = 0;
  }
  if (succ &&
      memcmp(login->message.body.passwd_hash,
             info->account.passwd_hash,
             MD5_DIGEST_LENGTH) != 0) {
    fprintf(stderr, "passwd miss match\n");
    succ = 0;
  }

  csiebox_protocol_header header;
  memset(&header, 0, sizeof(header));
  header.res.magic = CSIEBOX_PROTOCOL_MAGIC_RES;
  header.res.op = CSIEBOX_PROTOCOL_OP_LOGIN;
  header.res.datalen = 0;
  if (succ) {
    if (server->client[conn_fd]) {
      free(server->client[conn_fd]);
    }
    info->conn_fd = conn_fd;
    server->client[conn_fd] = info;
    header.res.status = CSIEBOX_PROTOCOL_STATUS_OK;
    header.res.client_id = info->conn_fd;
    char* homedir = get_user_homedir(server, info);
    mkdir(homedir, DIR_S_FLAG);
    printf("%s\n",homedir);
    free(homedir);
  } else {
    header.res.status = CSIEBOX_PROTOCOL_STATUS_FAIL;
    free(info);
  }
  send_message(conn_fd, &header, sizeof(header));
}
示例#7
0
static int sync_meta(csiebox_server *server, int conn_fd, csiebox_protocol_meta *meta)/*{{{*/
{
	char full_path[PATH_MAX];
	recv_message(conn_fd, full_path, sizeof(full_path));
	// make a short path
	char *client_path = make_path(full_path);
	char *cur_dir = get_user_homedir(server, server->client[conn_fd]);
	if (chdir(cur_dir) == -1) {
		fprintf(stderr, "change to user directory error\n");
		return 0;
	}
	// start to traverse
	int file_check = 0;
	char *object = strtok(client_path, "/");
	while(object != NULL){
		strcat(cur_dir, "/");
		strcat(cur_dir, object);
		struct stat object_stat;
		memset(&object_stat, 0, sizeof(object_stat));
		int open_success = lstat(cur_dir, &object_stat);
		// if file not exist
		if (open_success == -1){
			if (S_ISDIR(meta->message.body.stat.st_mode)) {
				mkdir(cur_dir, meta->message.body.stat.st_mode);
				fprintf(stderr, "sync meta : create dir\n");
				// dir utime
				struct utimbuf meta_time;
				memset(&meta_time, 0, sizeof(meta_time));
				meta_time.actime = meta->message.body.stat.st_atime;
				meta_time.modtime = meta->message.body.stat.st_mtime;
				utime(cur_dir, &meta_time);
				fprintf(stderr, "create dir\n");
			}
			if (S_ISREG(meta->message.body.stat.st_mode)) {
				int fd = creat(cur_dir, meta->message.body.stat.st_mode);
				// file utime
				struct utimbuf meta_time;
				memset(&meta_time, 0, sizeof(meta_time));
				meta_time.actime = meta->message.body.stat.st_atime;
				meta_time.modtime = meta->message.body.stat.st_mtime;
				utime(cur_dir, &meta_time);
				fprintf(stderr, "sync meta : create file\n");
				close(fd);
				file_check = 1;
			}
			if (S_ISLNK(meta->message.body.stat.st_mode)) {
				fprintf(stderr, "sync meta : is symbolic link\n");
				file_check = 1;
			}
			object = strtok(NULL, "/");
		}
		// file exist
		else {
			// is directory
			if (S_ISDIR(object_stat.st_mode)){
				if (chdir(cur_dir) == -1) {
					fprintf(stderr, "chdir error\n");
					return 0;
				}
			}
			else {
			// is file
				// file chmod
				chmod(cur_dir, meta->message.body.stat.st_mode);
				chown(cur_dir, meta->message.body.stat.st_uid, meta->message.body.stat.st_gid);
				// check if is same
				uint8_t content_hash[MD5_DIGEST_LENGTH];
				memset(content_hash, 0, sizeof(content_hash));
				md5_file(cur_dir, content_hash);
				if (memcmp(content_hash, meta->message.body.hash, MD5_DIGEST_LENGTH) != 0) file_check = 1;
				// file utime
				struct utimbuf meta_time;
				memset(&meta_time, 0, sizeof(meta_time));
				meta_time.actime = meta->message.body.stat.st_atime;
				meta_time.modtime = meta->message.body.stat.st_mtime;
				utime(cur_dir, &meta_time);
			}
			object = strtok(NULL, "/");
			// dir chmod
			if (object == NULL) {
				chmod(cur_dir, meta->message.body.stat.st_mode);
				chown(cur_dir, meta->message.body.stat.st_uid, meta->message.body.stat.st_gid);
				struct utimbuf meta_time;
				// dir utime
				memset(&meta_time, 0, sizeof(meta_time));
				meta_time.actime = meta->message.body.stat.st_atime;
				meta_time.modtime = meta->message.body.stat.st_mtime;
				utime(cur_dir, &meta_time);
			}
		}
	}
	// send back message
	csiebox_protocol_header header;
	memset(&header, 0, sizeof(header));
	header.res.magic = CSIEBOX_PROTOCOL_MAGIC_RES;
	header.res.op = CSIEBOX_PROTOCOL_OP_SYNC_META;
	header.res.status = (file_check == 1)? CSIEBOX_PROTOCOL_STATUS_MORE : CSIEBOX_PROTOCOL_STATUS_OK;
	header.res.datalen = 0;
	send_message(conn_fd, &header, sizeof(header));
	fprintf(stderr, "sync meta : success\n");

	return 1;
}/*}}}*/
示例#8
0
// flock
static void sync_file(csiebox_server* server, int conn_fd, csiebox_protocol_meta* meta) {
	csiebox_client_info* info = server->client[conn_fd];
	char* homedir = get_user_homedir(server, info);
	printf("homedir = %s\n", homedir);
	char buf[PATH_MAX], req_path[PATH_MAX];
	memset(buf, 0, PATH_MAX);
	memset(req_path, 0, PATH_MAX);
	recv_message(conn_fd, buf, meta->message.body.pathlen);
	sprintf(req_path, "%s%s", homedir, buf);
	free(homedir);
	fprintf(stderr, "req_path: %s\n", req_path);
	struct stat stat;
	memset(&stat, 0, sizeof(struct stat));
	int need_data = 0, change = 0;
	if (lstat(req_path, &stat) < 0) {
		need_data = 1;
		change = 1;
	} else { 					
		if(stat.st_mode != meta->message.body.stat.st_mode) { 
			chmod(req_path, meta->message.body.stat.st_mode);
		}				
		if(stat.st_atime != meta->message.body.stat.st_atime ||
				stat.st_mtime != meta->message.body.stat.st_mtime){
			struct utimbuf* buf = (struct utimbuf*)malloc(sizeof(struct utimbuf));
			buf->actime = meta->message.body.stat.st_atime;
			buf->modtime = meta->message.body.stat.st_mtime;
			if(utime(req_path, buf)!=0){
				printf("time fail\n");
			}
		}
		uint8_t hash[MD5_DIGEST_LENGTH];
		memset(hash, 0, MD5_DIGEST_LENGTH);
		if ((stat.st_mode & S_IFMT) == S_IFDIR) {
		} else {
			md5_file(req_path, hash);
		}
		if (memcmp(hash, meta->message.body.hash, MD5_DIGEST_LENGTH) != 0) {
			need_data = 1;
		}
	}

	csiebox_protocol_header header;
	memset(&header, 0, sizeof(header));
	header.res.magic = CSIEBOX_PROTOCOL_MAGIC_RES;
	header.res.op = CSIEBOX_PROTOCOL_OP_SYNC_META;
	header.res.datalen = 0;
	header.res.client_id = conn_fd;
	if (need_data) {
		header.res.status = CSIEBOX_PROTOCOL_STATUS_MORE;
	} else {
		header.res.status = CSIEBOX_PROTOCOL_STATUS_OK;
	}
	send_message(conn_fd, &header, sizeof(header));

	if (need_data) {
		csiebox_protocol_file file;
		memset(&file, 0, sizeof(file));
		// receive upload request
		recv_message(conn_fd, &file, sizeof(file));
		fprintf(stderr, "sync file: %zd\n", file.message.body.datalen);
		if ((meta->message.body.stat.st_mode & S_IFMT) == S_IFDIR) {
			fprintf(stderr, "dir\n");
			mkdir(req_path, DIR_S_FLAG);
		} else {
			fprintf(stderr, "regular file\n");
			int fd = open(req_path, O_CREAT | O_WRONLY | O_TRUNC, REG_S_FLAG);
			// request flock
			csiebox_protocol_header block;
			int request;
			while (flock(fd, LOCK_NB | LOCK_EX) != 0) { 
				fprintf(stderr, "data locked, blocking...\n");
				block.res.status = CSIEBOX_PROTOCOL_STATUS_BLOCKED;
				recv_message(conn_fd, &request, sizeof(int));
				send_message(conn_fd, &block, sizeof(block));
			}
			recv_message(conn_fd, &request, sizeof(int));
			block.res.status = CSIEBOX_PROTOCOL_STATUS_OK;
			send_message(conn_fd, &block, sizeof(block));
			// start receiving data
			size_t total = 0, readlen = 0;
			char buf[4096];
			memset(buf, 0, 4096);
			while (file.message.body.datalen > total) {
				if (file.message.body.datalen - total < 4096) {
					readlen = file.message.body.datalen - total;
				} else {
					readlen = 4096;
				}
				if (!recv_message(conn_fd, buf, readlen)) {
					fprintf(stderr, "file broken\n");
					break;
				}
				total += readlen;
				if (fd > 0) {
					write(fd, buf, readlen);
				}
			}
			if (fd > 0) {
				// unlock
				flock(fd, LOCK_UN);
				close(fd);
			}
		}
		if (change) {
			chmod(req_path, meta->message.body.stat.st_mode);
			struct utimbuf* buf = (struct utimbuf*)malloc(sizeof(struct utimbuf));
			buf->actime = meta->message.body.stat.st_atime;
			buf->modtime = meta->message.body.stat.st_mtime;
			utime(req_path, buf);
		}
		header.res.op = CSIEBOX_PROTOCOL_OP_SYNC_FILE;
		header.res.status = CSIEBOX_PROTOCOL_STATUS_OK;
		send_message(conn_fd, &header, sizeof(header));
	}
}
示例#9
0
文件: config.c 项目: dfjdejulio/fizmo
static char *expand_configuration_value(char *unexpanded_value)
{
  static char *homedir;
  static int homedir_len;
  char *ptr = unexpanded_value;
  int resultlen;
  char *result, *resultindex;
  char *var_name;
  char buf;

  if (unexpanded_value == NULL)
    return NULL;

  if ((homedir = get_user_homedir()) == NULL)
    homedir = empty_string;
  homedir_len = strlen(homedir);

  TRACE_LOG("Value to expand: \"%s\".\n", unexpanded_value);

  resultlen = 0;
  while (*ptr != 0)
  {
    if (*ptr == '$')
    {
      ptr++;
      if (*ptr == '(')
      {
        ptr++;
        var_name = ptr;
        while ( (*ptr != 0) && (*ptr != ')') )
          ptr++;
        if (*ptr != ')')
          return NULL;
        buf = *ptr;
        *ptr = 0;

        if (strcmp(var_name, "HOME") == 0)
        {
          resultlen += strlen(homedir);
        }
        else
        {
          *ptr = buf;
          return NULL;
        }

        *ptr = buf;
        ptr++;
      }
      else
        return NULL;
    }
    else
    {
      ptr++;
      resultlen++;
    }
  }

  TRACE_LOG("result len: %d.\n", resultlen);
  result = fizmo_malloc(resultlen + 1);
  resultindex = result;

  ptr = unexpanded_value;
  while (*ptr != 0)
  {
    if (*ptr == '$')
    {
      ptr++;
      if (*ptr == '(')
      {
        ptr++;
        var_name = ptr;
        while ( (*ptr != 0) && (*ptr != ')') )
          ptr++;
        if (*ptr != ')')
        {
          free(result);
          return NULL;
        }
        buf = *ptr;
        *ptr = 0;

        if (strcmp(var_name, "HOME") == 0)
        {
          strcpy(resultindex, homedir);
          resultindex += homedir_len;
        }
        else
        {
          *ptr = buf;
          // Can't ever reach this point due to loop 1.
        }

        *ptr = buf;
        ptr++;
      }
    }
    else
    {
      *resultindex = *ptr;
      ptr++;
      resultindex++;
    }
  }

  *resultindex = 0;

  TRACE_LOG("result expanded value: %s / %p.\n", result, result);
  return result;
}