Ejemplo n.º 1
0
/* Object 拷贝操作 */
int main()
{
	unsigned short retcode = -1;			//保存服务器http返回码的解析结果;
	const char *retinfo = NULL;            //保存通过retcode获得的错误信息

	const char *source_bucket_name = "bucketname001";
	//const char *destination_bucket_name = "bucketname002";
	const char *destination_bucket_name = "bucket_example";
	const char *source_key = "glib-2.32.4.tar.xz";
	const char *destination_key = "copy-of-glib-2.32.4.tar.xz";

	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);

	oss_copy_object_request_t *request = copy_object_request_initialize(
			source_bucket_name, source_key,
			destination_bucket_name, destination_key);

	request->set_modified_since_constraints(request, "Fri, 26 Sep 2012 12:06:55 GMT");

	oss_copy_object_result_t *result = client_copy_object(client, request, &retcode);

	if (retcode == OK) {
		if (result != NULL) {
			printf("ETag: %s\n", result->get_etag(result));
			printf("LastModified: %s\n", result->get_last_modified(result));
		}
		printf("Copy object successfully.\n");
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("%s\n", retinfo);
	}
	if (request != NULL) copy_object_request_finalize(request);
	if (result != NULL) copy_object_result_finalize(result);
	client_finalize(client);
}
Ejemplo n.º 2
0
int main()
{
	unsigned short retcode;			//保存服务器http返回码的解析结果;
	const char *retinfo;            //保存通过retcode获得的错误信息

	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);
	const char *bucket_name = "bucket_example";       //设置bucket_name
	const char *key = "a_group_file.dat";             //设置object group的名称

	oss_get_object_group_request_t *request = get_object_group_request_initialize(bucket_name, key);
	request->set_modified_since_constraint(request, "Sat, 20 Sep 2012 23:23:23 GMT");
	oss_object_metadata_t *result = client_head_object_group(client, request, &retcode);

	printf("head_obejct_group result:\n\n");
	if(retcode == OK) {
		printf("head_object_group successfully.\n");
		printf("content-length = %ld\ncontent-type = %s\nlast-modified = %s\n",
				result->get_content_length(result),
				result->get_content_type(result),
				result->get_last_modified(result));
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("error = %s\n", retinfo);
	}

	/* *释放空间 */
	if(request != NULL) {
		get_object_group_request_finalize(request);
	}
	if(result) {
		object_metadata_finalize(result);
	}
	client_finalize(client);
	return 0;
}
Ejemplo n.º 3
0
int main()
{
	unsigned short retcode;			//保存服务器http返回码的解析结果
	const char *retinfo;            //保存通过retcode获得的错误信息

	int i;
	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);
	/* 构造 request 参数 */
	oss_list_objects_request_t *request = list_objects_request_initialize();
	request->set_bucket_name(request, "bucket_example");
	request->set_prefix(request,"fun/");          //设置prefix
	request->set_delimiter(request, "/");      //设置delimiter
	request->set_max_keys(request, 100);      //设置max_keys
	request->set_marker(request, "a");         //设置marker


	oss_object_listing_t *object_listing = client_list_objects(client, request, &retcode);
	printf("list_objects_with_request result:\n\n");
	if(retcode == 0) {
		printf("list_objects_with_request successfully.\n");
		printf("bucket_name = %s\nnext_marker = %s\nprefix = %s\nmarker = %s\nmax_keys = %d\ndelimiter = %s\nis_truncated = %d\n", 
				object_listing->bucket_name, object_listing->next_marker, object_listing->prefix, object_listing->marker,
				object_listing->max_keys, object_listing->delimiter, object_listing->is_truncated);
		for(i = 0; i < object_listing->_counts_summaries; i++) {
			printf("****************************************************************\n");
			printf("object [%d] : \n", i);
			printf("type = %s\netag = %s\nkey = %s\nlast_modified = %s\nsize = %ld\nstorage_class = %s\nid = %s\ndisplay_name = %s\n",
					object_listing->summaries[i]->type, object_listing->summaries[i]->etag,
					object_listing->summaries[i]->key, object_listing->summaries[i]->last_modified,
					object_listing->summaries[i]->size, object_listing->summaries[i]->storage_class,
					object_listing->summaries[i]->owner->id, object_listing->summaries[i]->owner->display_name);
		}
		printf("=============================================================\n");
		for(i = 0; i < object_listing->_counts_common_prefixes; i++) {
			printf("common_prefix = %s\n", (object_listing->common_prefixes)[i]);
		}
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("error = %s\n", retinfo);
	}

	/* *释放空间 */
	if(object_listing != NULL) {
		if(object_listing->summaries != NULL) {
			for(i = 0; i < object_listing->_counts_summaries; i++) {
				owner_finalize((object_listing->summaries)[i]->owner);
				object_summary_finalize((object_listing->summaries)[i]);
			}
			free(object_listing->summaries);
		}
		object_listing_finalize(object_listing);
	}
	if(request != NULL) {
		list_objects_request_finalize(request);
	}

	client_finalize(client);
	return 0;
}
Ejemplo n.º 4
0
/* 将内存中的内容上传至云服务器中 */
int main()
{
	unsigned short retcode = -1;			//保存服务器http返回码的解析结果;
	const char *retinfo = NULL;            //保存通过retcode获得的错误信息

	const char *bucket_name = "bucketexample";       //设置bucket_name
	const char *key         = "put-ojbect.data";      //设置上传key
	const char *local_file  = "proactor.pdf";         //设置需要上传的文件
	unsigned int retsize = 0; // 读取文件时的返回值

	FILE *fp = fopen(local_file, "r");
	if (fp == NULL) {
		fprintf(stderr, "error in opening file %s\n", local_file);
		return -1;
	}
	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);
	unsigned int file_len = oss_get_file_size(fp);

	char *buffer = (char *)malloc(sizeof(char) * file_len + 1);

	memset(buffer, '\0', file_len + 1);
	retsize = fread(buffer, 1, file_len, fp);

	if (retsize < 0) {
		fprintf(stderr, "error in reading file %s.\n", local_file);
		return -1;
	}

	/* 初始化元信息,并设置相关属性 */
	oss_object_metadata_t *metadata = object_metadata_initialize(); 
	metadata->set_content_length(metadata, file_len); /** 该参数必须设置 */
	metadata->set_content_type(metadata, "application/octet-stream");
	metadata->set_cache_control(metadata, "no-cache");
	metadata->set_content_encoding(metadata, "utf-8");
	metadata->set_content_disposition(metadata, "attachment;");
	metadata->set_expiration_time(metadata, "Thu, 13 Sep 2012 21:08:42 GMT");

	/* 将内存中的内容上传至云服务器中 */
	oss_put_object_result_t *result =
		client_put_object_from_buffer(client, bucket_name, key, buffer, metadata, &retcode);
	if (retcode == OK) {
		printf("put object from file successfully.\n");
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("%s\n", retinfo);
	}

	if (result != NULL) put_object_result_finalize(result);
	client_finalize(client);
	object_metadata_finalize(metadata);
	free(buffer);
	fclose(fp);
	return 0;
}
Ejemplo n.º 5
0
/* 将远程服务器上的文件下载到内存中 */
int main()
{

	unsigned short retcode = -1;			//保存服务器http返回码的解析结果;
	const char *retinfo = NULL;            //保存通过retcode获得的错误信息

	const char *bucket_name = "bucketname001";       //设置bucket_name
	const char *key         = "glibx-2.32.4.tar.xz";      //设置下载 key
	const char *local_file  = "local-file.data";         //设置需要保存到本地的文件名
	unsigned int file_len = -1; /**< 远程文件的长度  */
	void *buffer = NULL; /* 存放文件内容的缓冲区首指针 */

	FILE *fp = fopen(local_file, "w");
	if (fp == NULL) {
		fprintf(stderr, "error in opening file %s\n", local_file);
		return -1;
	}

	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);

	oss_get_object_request_t *request = get_object_request_initialize(bucket_name, key);
	// request->set_range(request, 0, 2 * 1024);

	/* 将远程服务器上的文件下载到内存中 */

	/* 以下两个函数均可以成功调用 */
	/* 警告: 获取Object的函数均会返回该对象的元信息,由于元信息是动态动态分配的,
	 * 你需要获取其元信息,并在程序退出时释放它,否则会造成少量的内存泄漏(数百字节)
	 * */
	//oss_object_metadata_t *metadata =
	//	client_get_object_to_buffer(client, request, &buffer, &file_len, &retcode);
	
	oss_object_metadata_t *metadata =
		client_get_object_to_buffer_2nd(client, request, &buffer, &file_len, &retcode);

	if (retcode == OK) {
		fwrite(buffer, file_len, 1, fp);
		printf("Get object to buffer successfully.\n");
		printf("File length: %d\n", file_len);
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("%s\n", retinfo);
	}

	if (buffer != NULL) free(buffer);
	if (request != NULL) get_object_request_finalize(request);
	if (metadata != NULL) object_metadata_finalize(metadata);
	client_finalize(client);
	fclose(fp);

	return 0;
}
Ejemplo n.º 6
0
/* 初始化Multipart Upload操作*/
int main()
{

    unsigned short retcode = -1;			//保存服务器http返回码的解析结果;
    const char *retinfo = NULL;            //保存通过retcode获得的错误信息

    const char *bucket_name = "bucketexample";       //设置bucket_name
    const char *key         = "multipart-upload.data";      //设置key


    oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);


#if 1 /* 设置带元信息的Multipart Upload 上传请求 */

    oss_object_metadata_t *metadata = object_metadata_initialize();

    /* 设置上传对象的元信息 */
    metadata->set_content_type(metadata, "application/octet-stream");
    metadata->set_cache_control(metadata, "no-cache");
    metadata->set_content_encoding(metadata, "utf-8");
    metadata->set_content_disposition(metadata, "attachment;");
    metadata->set_expiration_time(metadata, "Thu, 31 Oct 2012 21:08:42 GMT");

    oss_initiate_multipart_upload_request_t *request =
        initiate_multipart_upload_request_initialize_with_metadata(bucket_name, key, metadata);
#else /* 不带元信息的Multipart Upload上传请求 */
    oss_initiate_multipart_upload_request_t *request =
        initiate_multipart_upload_request_initialize(bucket_name, key, NULL);
#endif


    oss_initiate_multipart_upload_result_t *result =
        client_initiate_multipart_upload(client, request, &retcode);
    if (retcode == OK) {
        printf("%s\n", result->get_upload_id(result));
    } else {
        retinfo = oss_get_error_message_from_retcode(retcode);
        printf("%s\n", retinfo);
    }

    initiate_multipart_upload_result_finalize(result);
    initiate_multipart_upload_request_finalize(request);
    object_metadata_finalize(metadata);
    client_finalize(client);

    return 0;

}
Ejemplo n.º 7
0
/* 列出所有的Multipart Upload操作*/
int main()
{

	unsigned short retcode = -1;			//保存服务器http返回码的解析结果;
	const char *retinfo = NULL;            //保存通过retcode获得的错误信息

	const char *bucket_name = "bucketexample";       //设置bucket_name


	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);


	oss_list_multipart_uploads_request_t *request = 
		list_multipart_uploads_request_initialize(bucket_name);

	oss_multipart_upload_listing_t *listing = client_list_multipart_uploads(client, request, &retcode);

	if (retcode == OK) {

		printf("BUCKET NAME: %s\n", listing->get_bucket_name(listing));

		unsigned int upload_counts = 0;
		int i = 0;

		oss_multipart_upload_t **uploads = listing->get_multipart_uploads(listing, &upload_counts);
		for (i = 0; i < upload_counts; i++) {
			printf("***********************************CONTENT %d*******************************\n", i + 1);
			printf("KEY: %s\n", (*(uploads + i))->get_key(*(uploads + i)));
			printf("UPLOAD ID: %s\n", (*(uploads + i))->get_upload_id(*(uploads + i)));
			printf("STORAGE CLASS: %s\n", (*(uploads + i))->get_storage_class(*(uploads + i)));
			printf("INITIATED: %s\n", (*(uploads + i))->get_initiated(*(uploads + i)));

			/* 释放空间,否则会少量的内存泄漏 */
			multipart_upload_finalize(*(uploads + i));
		}
		if (uploads != NULL) free(uploads);
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("%s\n", retinfo);
	}

	list_multipart_uploads_request_finalize(request);
	if (listing != NULL) multipart_upload_listing_finalize(listing);
	client_finalize(client);

	return 0;

}
Ejemplo n.º 8
0
int main()
{
	bool result;
	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);
	const char *bucket_name = "bucket_example";       //设置bucket_name

	result = client_is_bucket_exist(client, bucket_name);
	printf("is_bucket_exist result:\n\n");
	if(result == true) {
		printf("bucket exist.\n");
	} else {
		printf("bucket not exist\n");
	}

	client_finalize(client);
	return 0;
}
Ejemplo n.º 9
0
int main()
{
	unsigned short retcode;			//保存服务器http返回码的解析结果
	const char *retinfo;            //保存通过retcode获得的错误信息

	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);

	int buckets_number;             //保存buckets的数目
	int i;
	oss_owner_t *owner = NULL;
	oss_bucket_t **buckets = client_list_buckets(client, &buckets_number, &retcode);
	printf("list buckets result:\n\n");
	if(retcode == 0) {
		printf("list buckets successfully.\n");
		if(buckets_number != 0) {
			for(i = 0; i < buckets_number; i++) {
				printf("***********************************************************************\n");
				printf("bucket [%d] : \n", i);
				printf("name = %s\tcreate_date = %s\n", buckets[i]->get_name(buckets[i]), buckets[i]->get_create_date(buckets[i]));
				owner = buckets[i]->get_owner(buckets[i]);
				printf("id = %s\tdisplay_name = %s\n", owner->get_id(owner), owner->get_display_name(owner));
			}
		} else {
			printf("empty bucket list.\n");
		}
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("error = %s\n", retinfo);
	}

	/* 释放空间 */
	if(buckets != NULL) {
		for(i = 0; i < buckets_number; i++) {
			if(buckets[i] != NULL) {
				bucket_finalize(buckets[i]);
			}
		}
		free(buckets);
	}
	if(owner != NULL) {
		owner_finalize(owner);
	}

	client_finalize(client);
	return 0;
}
Ejemplo n.º 10
0
int main()
{
	unsigned short retcode;			//保存服务器http返回码的解析结果;
	const char *retinfo;            //保存通过retcode获得的错误信息

	const char *bucket_name = "bucket_example";       //设置bucket_name
	const char *key = "a_group_file.dat";             //设置object group的名称
	int i;

	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);
	oss_get_object_group_index_result_t *result = client_get_object_group_index(client, bucket_name, key, &retcode);

	printf("get_obejct_group_index result:\n\n");
	if(retcode == OK) {
		printf("get_object_group_index successfully.\n");
		printf("bucket_name = %s\nkey = %s\netag = %s\nfile_length = %u\n", 
				result->get_bucket_name(result), result->get_key(result),
				result->get_etag(result), result->get_file_length(result));
		printf("============================================\n");
		for(i = 0; i < result->part_number; i++) {
			printf("part [%d] :\n", i);
			printf("etag = %s\npart_name = %s\npart_number = %d\npart_size = %u\n", 
					(result->group)[i]->etag, (result->group)[i]->part_name,
					(result->group)[i]->part_number, (result->group)[i]->part_size);
			printf("*****************************************\n");
		}
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("error = %s\n", retinfo);
	}

	/* *释放空间 */
	if(result != NULL) {
		if(result->group != NULL) {
			for(i = 0; i < result->part_number; i++) {
				multipart_object_group_finalize((result->group)[i]);
			}
			free(result->group);
		}
		get_object_group_index_result_finalize(result);
	}
	client_finalize(client);
	 return 0;
}
Ejemplo n.º 11
0
/* 下载云服务器中的文件至本地文件 */
int main()
{

	unsigned short retcode = -1;			//保存服务器http返回码的解析结果;
	const char *retinfo = NULL;            //保存通过retcode获得的错误信息

	const char *bucket_name = "bucketname001";       //设置bucket_name
	const char *key         = "glib-2.32.4.tar.xz";      //设置需要下载的key
	const char *local_file  = "local-file.data";         //设置需要下载的本地文件名,可以和key同名

	FILE *fp = fopen(local_file, "w");
	if (fp == NULL) {
		fprintf(stderr, "error in opening file %s\n", local_file);
		return -1;
	}

	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);

	oss_get_object_request_t *request = get_object_request_initialize(bucket_name, key);
	// request->set_range(request, 0, 2 * 1024 * 1024);

	/* 警告: 获取Object的函数均会返回该对象的元信息,由于元信息是动态动态分配的,
	 * 你需要获取其元信息,并在程序退出时释放它,否则会造成少量的内存泄漏(数百字节)
	 * */
	
	oss_object_metadata_t *metadata =
		client_get_object_to_file(client, request, fp, &retcode);

	if (retcode == OK) {
		printf("Get object to file successfully.\n");
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("%s\n", retinfo);
	}

	if (request != NULL) get_object_request_finalize(request);
	if (metadata != NULL) object_metadata_finalize(metadata);
	client_finalize(client);
	fclose(fp);

	return 0;

}
Ejemplo n.º 12
0
int main()
{
	unsigned short retcode;			//保存服务器http返回码的解析结果;
	const char *retinfo;            //保存通过retcode获得的错误信息

	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);
	const char *bucket_name = "bucket_example";       //设置bucket_name

	client_create_bucket(client, bucket_name, &retcode);
	printf("create_bucket result:\n\n");
	if(retcode == OK) {
		printf("create bucket successfully.\n");
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("error = %s\n", retinfo);
	}

	client_finalize(client);
	return 0;
}
Ejemplo n.º 13
0
int main()
{
	unsigned short retcode;			//保存服务器http返回码的解析结果
	const char *retinfo;            //保存通过retcode获得的错误信息

	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);
	const char *bucket_name = "bucket_example";    //设置bucket_name

	const char *acl = "public-read";            //设置bucket的访问权限(private,public-read,public-read-write中的一个)
	client_set_bucket_acl(client, bucket_name, acl, &retcode);
	printf("set_bucket_acl result:\n\n");
	if(retcode == 0) {
		printf("set bucket acl successfully.\n");
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("error = %s\n", retinfo);
	}

	client_finalize(client);
	return 0;
}
Ejemplo n.º 14
0
int main()
{
	unsigned short retcode;			//保存服务器http返回码的解析结果;
	const char *retinfo;            //保存通过retcode获得的错误信息

	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);
	const char *bucket_name = "bucket_example";       //设置bucket_name
	const char *key = "a_group_file.dat";             //设置object group的名称

	client_delete_object_group(client, bucket_name, key, &retcode);

	printf("delete_obejct_group result:\n\n");
	if(retcode == NO_CONTENT) {
		printf("delete_object_group successfully.\n");
	} else {
		retinfo = oss_get_error_message_from_retcode(retcode);
		printf("error = %s\n", retinfo);
	}

	/* *释放空间 */
	client_finalize(client);
	return 0;
}
Ejemplo n.º 15
0
/* 上传 Part 操作,本例演示了如果使用上传Part操作来上传一个文件,
 * 适合上传大文件,但是如果想多线程断点续传,请在Unix/Linux下使用
 * OSSC 的 extra 子程序库中的 client_extra_put_object()函数。*/
int main()
{

	unsigned short retcode = -1;			//保存服务器http返回码的解析结果;
	const char *retinfo = NULL;            //保存通过retcode获得的错误信息

	const char *bucket_name = "bucketexample";       //设置bucket_name
	const char *key         = "multipart-upload.data";      //设置key

	/* TODO: 设置upload id,此upload id由initiate multipart upload 操作返回 */
	const char *upload_id = "0004CA5FAC0DD11BFCEE7E76679BD09D"; 

	FILE *fp= fopen("mysql-5.1.52.tar.gz", "r"); /* 需要通过multipart upload上传的文件 */
	if (fp == NULL) {
		fprintf(stderr, "error in opening file...\nplease check again before upload part !\n");
		return -1;
	}
	unsigned int file_len = oss_get_file_size(fp); /* 获取文件大小 */
	
	char *buffer = (char *)malloc(sizeof(char) * file_len + 1);
	memset(buffer, '\0', file_len + 1);
	unsigned int file_sz = fread(buffer, 1, file_len, fp);
	if (file_sz < file_len) {fprintf(stderr, "fread error.\n"); return -1;}
	const int single_request_len = 8 * 1024 * 1024; /* 每个Part的大小 */
	int requests_num = file_len / single_request_len; /* 需要多少次上传 */
	int current_part_number = 0; /* 当前上传的 Part Number */

	oss_client_t *client = client_initialize_with_endpoint(access_id, access_key, endpoint);

	oss_upload_part_request_t *request = upload_part_request_initialize();
	request->set_bucket_name(request, bucket_name);
	request->set_key(request, key);
	request->set_upload_id(request, upload_id);

	for (current_part_number = 0; current_part_number < requests_num + 1; current_part_number++) {
		/* 除了最后一块的其他块,最小为 5MB,此处设置单个Part为single_request_len = 8MB */
		if (current_part_number < requests_num) { 
			request->set_part_number(request, current_part_number + 1);
			request->set_input_stream(request,
					buffer + current_part_number * single_request_len, single_request_len);
			request->set_part_size(request, single_request_len);

			/* 上传Part */
			oss_upload_part_result_t *result = client_upload_part(client, request, &retcode);

			if (retcode == OK) { /* 打印返回信息,包括 Part Number 和 ETag 值 */
				printf("PartNumber:%d, ETag:%s\n", result->get_part_number(result), result->get_etag(result));
			} else { /* 打印出错信息 */
				retinfo = oss_get_error_message_from_retcode(retcode);
				printf("%s\n", retinfo);
			}
			/* 最好此时释放 result 空间 */
			upload_part_result_finalize(result);
		} else { /* 最后一块,可以小于5MB */
			request->set_part_number(request, current_part_number + 1);
			request->set_input_stream(request,
					buffer + current_part_number *single_request_len,
					file_len - single_request_len * current_part_number);
			request->set_part_size(request, file_len - single_request_len * current_part_number);

			/* 上传Part */
			oss_upload_part_result_t *result = client_upload_part(client, request, &retcode);
			
			if (retcode == OK) { /* 打印返回信息,包括 Part Number 和 ETag 值 */
				printf("PartNumber:%d, ETag:%s\n", result->get_part_number(result), result->get_etag(result));
			} else { /* 打印出错信息 */
				retinfo = oss_get_error_message_from_retcode(retcode);
				printf("%s\n", retinfo);
			}
			/* 最好及时释放 result 空间,否则回造成内存泄漏 */
			upload_part_result_finalize(result);
		}
	}

	free(buffer);

	upload_part_request_finalize(request);
	client_finalize(client);
	fclose(fp);

	return 0;

}
Ejemplo n.º 16
0
/**
 * Performs a 'File Send' operation for the client
 *
 * @param remote_filename     filename in destination location
 * @param local_filename      filename in location of origin
 * @param addr                server IP
 * @param port                server port
 * @param timeout             timeout for messages, can be 0 for default
 * @param timeout_ack         timeout for ack messages, can be 0 for default
 * @param log_writer          a pointer to a callback logging function
 *                            that receives two parameters:
 *                                      
 *                            function: name of the function in which
 *                                      logger_write is being called.
 *                            message:  body of the message.
 *
 * @return                    result code
 */
int client_file_send( char * remote_filename, 
                      char * local_filename, 
                      char * addr, 
                      char * port, 
                      int timeout, 
                      int timeout_ack, 
                      void (*log_writer) (const char* function, char* message) ) {

  char l_msg[_BUFFER_SIZE_S];

  char * request  = NULL;
  char * response = NULL;

  char * content  = NULL;

  unsigned long request_len;
  unsigned long response_len;
  unsigned long content_len;

  int message_type = 0;
  int result = RESULT_UNDEFINED;

  quickft_client_t * client;

  // Stores the log writer function
  gl_log_writer = log_writer;
  
  LOGGER(__FUNCTION__, "Begins a File Send operation.");

  if (addr == NULL) {
    LOGGER(__FUNCTION__, "Server Addr can not be null");
    return result;
  }
  
  // Initializes a client
  if (port == NULL) {
    client = client_initialize( addr, DEFAULT_PORT, timeout, timeout_ack );
  }
  else {
    client = client_initialize( addr, atoi(port), timeout, timeout_ack );
  }

  if (client == NULL) {

    LOGGER(__FUNCTION__, "Error on client initialization.");
    return result;
  }

  // Generates content for request
  result = client_generate_content_from_file(local_filename, &content, &content_len);  
  if ( result == RESULT_SUCCESS ) {

    // Generates request message
    request = message_file_send_request(remote_filename, content_len, content, &request_len);

    // Sends the message
    if ( process_outgoing_message(client->connection, request, request_len) == TRUE) {

      message_type = client_get_response(client, &response, &response_len);
      if ( message_type == FILE_SND_B ) {
      
        if (response != NULL  && response_len != 0) {

          // Logs response
          LOGGER(__FUNCTION__, "Gets response from server...");
          if ( response_len >= _BUFFER_SIZE_S ) {
            snprintf(l_msg, _BUFFER_SIZE_S, "%s", response);
            l_msg[_BUFFER_SIZE_S - 1] = '\0';
          }
          else {
            snprintf(l_msg, response_len, "%s", response);
            l_msg[response_len] = '\0';
          }
        
          LOGGER(__FUNCTION__, l_msg);

          // Completes the operation and gets the result
          result = client_get_file_send_response_result(response, response_len);
        }
        else {

          sprintf(l_msg, "Could not get a valid response from the QUICKFT server at %s:%s", addr, port);
          LOGGER(__FUNCTION__, l_msg);
          result = RESULT_CONNECTION_ERROR;
        }
      
      }
      else {

        // If the response message type is not correct
        if (message_type > 0) {
          sprintf(l_msg, "Message type [%02d] is invalid for expected response.", message_type);
          LOGGER(__FUNCTION__, l_msg);

          result = RESULT_INVALID_RESPONSE;
        }
        // If an error occurred
        else {
          sprintf(l_msg, "An error ocurred when trying to read response [%d]", message_type);
          LOGGER(__FUNCTION__, l_msg);

          result = message_type;
        }

      }

    }
    else {
      LOGGER(__FUNCTION__, "An error occurred while trying to send the request.");
      result = RESULT_CONNECTION_ERROR;
    }

  }
  else {
    snprintf(l_msg, _BUFFER_SIZE_S, "An error occurred while trying to generate content from file [%s]", local_filename);
    LOGGER(__FUNCTION__, l_msg);
  }

  // Finalizes the client data structure
  client_finalize(&client);

  // Frees allocated memory
  if (request != NULL) {
    free(request);
  }
  if (response != NULL) {
    free(response);
  }
  if (content != NULL) {
    free(content);
  }

  LOGGER(__FUNCTION__, "Finalizes File Send operation.");

  return result;

}