#include "phn_location.h"
#include "phn_region_data.h"
-API int phone_number_replace_extra_location_data(phone_number_region_e region, const char *file_name)
-{
- RETVM_IF(PHONE_NUMBER_REGION_CHINA != region, PHONE_NUMBER_ERROR_NOT_SUPPORTED,
- "Not supported region(%d)", region);
- RETVM_IF(NULL == file_name, PHONE_NUMBER_ERROR_INVALID_PARAMETER, "Invalid parameter (file_name is NULL)");
- RETVM_IF(strchr(file_name, '/'), PHONE_NUMBER_ERROR_INVALID_PARAMETER, "Invalid parameter");
-
- int ret;
- ret = phn_location_validate_extra_data(region, file_name);
- RETVM_IF(PHONE_NUMBER_ERROR_NONE != ret, ret, "phn_location_validate_extra_data() Fail(%d)", ret);
-
- ret = phn_location_replace_extra_data(region, file_name);
- RETVM_IF(PHONE_NUMBER_ERROR_NONE != ret, ret, "phn_location_replace_extra_data() Fail(%d)", ret);
-
- return PHONE_NUMBER_ERROR_NONE;
-}
API int phone_number_get_location_from_number(const char *number,
phone_number_region_e region, phone_number_lang_e lang, char **location)
int mobile_prefix_len;
};
-static bool _phn_location_file_is_symlink(const char *full_path)
-{
- struct stat file_info;
- lstat(full_path, &file_info);
- if (file_info.st_mode & S_IFLNK)
- return true;
- return false;
-}
-
-int phn_location_validate_extra_data(phone_number_region_e region, const char *file_name)
-{
- int ret;
-
- char full_path[PHN_PATH_MAX_LEN] = {0};
- snprintf(full_path, sizeof(full_path), PHN_LOCATION_DOWNLOAD_DIR"/%s", file_name);
-
- if (_phn_location_file_is_symlink(full_path))
- return PHONE_NUMBER_ERROR_INVALID_PARAMETER;
-
- int fd = open(full_path, O_RDONLY);
- RETVM_IF(fd < 0, PHONE_NUMBER_ERROR_INVALID_PARAMETER, "open() Fail(%d)", errno);
-
- int start_mark = 0;
- ret = read(fd, &start_mark, sizeof(int));
- if (ret <= 0) {
- ERR("read() Fail(%d)", errno);
- close(fd);
- return PHONE_NUMBER_ERROR_INVALID_PARAMETER;
- }
-
- if (PHN_LOCATION_FILE_MARK != start_mark) {
- ERR("Invalid start_mark(%x)", start_mark);
- close(fd);
- return PHONE_NUMBER_ERROR_INVALID_PARAMETER;
- }
-
- struct phn_location_header header;
- ret = read(fd, &header, sizeof(struct phn_location_header));
- if (ret <= 0) {
- ERR("read() Fail(%d)", errno);
- close(fd);
- return PHONE_NUMBER_ERROR_INVALID_PARAMETER;
- }
-
- int i,j;
- int expected_len = 0;
-
- // province
- for (i=0;i<header.province_count;i++) {
- for (j=0;j<PHN_LOCATION_LANG_INDEX_MAX;j++) {
- expected_len += header.province_name_len[j];
- }
- }
-
- // telephone city
- for (i=0;i<header.telephone_city_count;i++) {
- expected_len += sizeof(gint8); // province index
- for (j=0;j<PHN_LOCATION_LANG_INDEX_MAX;j++) {
- expected_len += header.telephone_city_len[j];
- }
- expected_len += sizeof(gint16); // number
- }
-
- if (region == PHONE_NUMBER_REGION_CHINA) {
- // mobile city
- for (i=0;i<header.mobile_city_count;i++) {
- expected_len += sizeof(gint8); // province index
- for (j=0;j<PHN_LOCATION_LANG_INDEX_MAX;j++) {
- expected_len += header.mobile_city_len[j];
- }
- }
-
- // mobile prefix index
- expected_len += header.mobile_prefix_index_count * sizeof(gint16);
-
- // mobile prefix
- expected_len += header.mobile_prefix_index_count * sizeof(gint16) * PHN_LOCATION_CHINA_MOBILE_SUFFIX_OFFSET;
- }
-
- ret = lseek(fd, expected_len, SEEK_CUR);
- if (ret <= 0) {
- ERR("lseek() Fail(%d)", errno);
- close(fd);
- return PHONE_NUMBER_ERROR_INVALID_PARAMETER;
- }
-
- // crc
- ret = lseek(fd, sizeof(int), SEEK_CUR);
- if (ret <= 0) {
- ERR("read() Fail(%d)", errno);
- close(fd);
- return PHONE_NUMBER_ERROR_INVALID_PARAMETER;
- }
-
- int end_mark = 0;
- // check end mark
- ret = read(fd, &end_mark, sizeof(int));
- if (ret <= 0) {
- ERR("read() Fail(%d)", errno);
- close(fd);
- return PHONE_NUMBER_ERROR_INVALID_PARAMETER;
- }
-
- if (PHN_LOCATION_FILE_MARK != end_mark) {
- ERR("Invalid end_mark(%x)", end_mark);
- close(fd);
- return PHONE_NUMBER_ERROR_INVALID_PARAMETER;
- }
-
- // check eof
- gint8 temp;
- ret = read(fd, &temp, sizeof(gint8));
- if (0 != ret) {
- ERR("file size over (ret=%d)", ret);
- close(fd);
- return PHONE_NUMBER_ERROR_INVALID_PARAMETER;
- }
-
- close(fd);
- return PHONE_NUMBER_ERROR_NONE;
-}
-
-int phn_location_replace_extra_data(phone_number_region_e region, const char *file_name)
-{
- const char *region_str = NULL;
- region_str = phn_region_data_get_region_str(region);
- RETVM_IF(NULL == region_str, PHONE_NUMBER_ERROR_NOT_SUPPORTED, "phn_region_info not found(%d)", region);
-
- char dest_temp[PHN_STR_SHORT_LEN] = {0};
- snprintf(dest_temp, sizeof(dest_temp), "%s/location-%s.bin.new", PHN_LOCATION_DIR, region_str);
-
- char full_path[PHN_PATH_MAX_LEN] = {0};
- snprintf(full_path, sizeof(full_path), PHN_LOCATION_DOWNLOAD_DIR"/%s", file_name);
-
- int src_fd = open(full_path, O_RDONLY);
- RETVM_IF(src_fd < 0, PHONE_NUMBER_ERROR_INVALID_PARAMETER, "System : Open(src:%s) Fail(%d)", full_path, errno);
-
- int dest_fd = open(dest_temp, O_WRONLY|O_CREAT|O_TRUNC, 0660);
- if (dest_fd < 0) {
- ERR("Open Fail(%d)", errno);
- close(src_fd);
- return PHONE_NUMBER_ERROR_IO_ERROR;
- }
-
- int ret;
- int size;
- char buf[PHN_COPY_SIZE_MAX] = {0};
- while ((size = read(src_fd, buf, PHN_COPY_SIZE_MAX)) > 0) {
- ret = write(dest_fd, buf, size);
- if (ret <= 0) {
- if (EINTR == errno)
- continue;
- else {
- ERR("write() Fail(%d)", errno);
- if (ENOSPC == errno)
- ret = PHONE_NUMBER_ERROR_FILE_NO_SPACE_ON_DEVICE; // No space
- else
- ret = PHONE_NUMBER_ERROR_IO_ERROR; // IO error
- close(src_fd);
- close(dest_fd);
- unlink(dest_temp);
- return ret;
- }
- }
- }
- close(src_fd);
- close(dest_fd);
-
- char dest[PHN_STR_SHORT_LEN] = {0};
- snprintf(dest, sizeof(dest), "%s/location-%s.bin", PHN_LOCATION_DIR, region_str);
-
- ret = rename(dest_temp, dest);
- if (ret < 0) {
- ERR("reanme() Fail(%d)", errno);
- unlink(dest_temp);
- return PHONE_NUMBER_ERROR_IO_ERROR;
- }
-
- return PHONE_NUMBER_ERROR_NONE;
-}
-
int phn_location_find_extra_data(const char *region_str, char **p_location_file)
{
char *location_file = NULL;