| #include "stat_api.h" |
| #include "stat_general.h" |
| #include <uci.h> |
| #include <stdlib.h> |
| #include <time.h> |
| #include <fcntl.h> |
| #include <sys/socket.h> |
| #include <sys/un.h> |
| #include <errno.h> |
| #include <netinet/in.h> |
| #include <linux/netlink.h> |
| #include <include/log.h> |
| #include "diag_API.h" |
| |
| #define STAT_DEBUG |
| #ifdef STAT_DEBUG |
| #define STAT_DBG(CAT, format, args...) RLOG_DPRINTF(TRAFFIC_SERVICE, CAT, format, ##args) |
| #else |
| #define STAT_DBG(...) do {} while (0) |
| #endif |
| |
| #ifndef STAT_ERR |
| #define STAT_ERR(CAT, format, args...) RLOG_ERROR(TRAFFIC_SERVICE, CAT, format, ##args) |
| #endif |
| |
| char *stat_get_filename(const char *path) |
| { |
| char *p; |
| |
| p = strrchr(path, '/'); |
| if (!p) |
| return NULL; |
| p++; |
| if (!*p) |
| return NULL; |
| return p; |
| } |
| |
| int stat_get_line(FILE * file, struct stat_read_buf *read_buf) |
| { |
| int read_len = 0; |
| char *ret_p = NULL; |
| int ret = STAT_READ_OK; |
| |
| if (!file) { |
| ret = STAT_READ_ERR; |
| goto end; |
| } |
| if (read_buf->size == 0) { |
| read_buf->buf = malloc(STAT_LINEBUF_LEN); |
| if (!read_buf->buf) { |
| ret = STAT_NO_MEM_ERR; |
| goto end; |
| } |
| read_buf->size = STAT_LINEBUF_LEN; |
| memset(read_buf->buf, 0, read_buf->size); |
| } else { |
| memset(read_buf->buf, 0, read_buf->size); |
| } |
| |
| do { |
| ret_p = fgets(read_buf->buf + strlen(read_buf->buf), read_buf->size, file); |
| if (!ret_p || !*ret_p) { |
| ret = STAT_READ_ERR; |
| goto end; |
| } |
| read_len = strlen(read_buf->buf); |
| if (read_len > 1) { |
| if (read_buf->buf[read_len - 1] == '\n') { |
| if (read_len >= 2 && read_buf->buf[read_len - 2] == '\r') |
| read_buf->buf[read_len - 2] = 0; |
| else |
| read_buf->buf[read_len - 1] = 0; |
| |
| ret = STAT_READ_OK; |
| goto end; |
| } |
| } |
| read_buf->size += STAT_LINEBUF_LEN; |
| read_buf->buf = realloc(read_buf->buf, read_buf->size); |
| if (!read_buf->buf) { |
| ret = STAT_NO_MEM_ERR; |
| goto end; |
| } |
| } while (1); |
| end: |
| STAT_ERR(stat_get_line, "done with ret %d", ret); |
| return ret; |
| } |
| |
| int isdigit_dot_colon(char in_char) |
| { |
| if (((in_char >= '0') && (in_char <= '9')) || (in_char == '.') || (in_char == ':') |
| || ((in_char >= 'a') && (in_char <= 'f')) || ((in_char >= 'A') && (in_char <= 'F'))) { |
| return 1; |
| } |
| return 0; |
| } |
| |
| char *find_none_white_space(char *instr) |
| { |
| char *ch = NULL; |
| int nExit = 0; |
| |
| if (!instr) { |
| return NULL; |
| } |
| ch = instr; |
| |
| while (nExit == 0) { |
| switch (*ch) { |
| case '\n': |
| case ' ': |
| case '\t': |
| case '\r': |
| break; |
| default: |
| nExit = 1; |
| } |
| if (nExit == 0) |
| ch++; |
| } |
| return ch; |
| } |
| |
| char *find_last_none_white_space(char *instr) |
| { |
| char *ch = NULL; |
| int nExit = 0; |
| |
| if (!instr) { |
| return NULL; |
| } |
| ch = instr; |
| |
| while (nExit == 0) { |
| switch (*ch) { |
| case '\n': |
| case ' ': |
| case '\t': |
| case '\r': |
| nExit = 1; |
| break; |
| } |
| if (nExit == 0) |
| ch++; |
| } |
| if (instr == ch) |
| return NULL; |
| else |
| return ch - 1; |
| } |
| |
| char *find_last_digit(char *instr) |
| { |
| char *cur_char = NULL; |
| |
| if (!instr) { |
| return NULL; |
| } |
| if (!isdigit(*instr)) { |
| return NULL; |
| } |
| cur_char = instr; |
| while (isdigit(*(cur_char + 1))) { |
| cur_char++; |
| } |
| |
| return cur_char; |
| |
| } |
| |
| char *find_last_digit_dot_colon(char *instr) |
| { |
| char *cur_char = NULL; |
| |
| if (!instr) { |
| return NULL; |
| } |
| if (!isdigit_dot_colon(*instr)) { |
| return NULL; |
| } |
| cur_char = instr; |
| while (isdigit_dot_colon(*(cur_char + 1))) { |
| cur_char++; |
| } |
| return cur_char; |
| } |
| |
| /*=============================================== |
| Convert IP string(192.168.1.120) to ASCII 192 168 1 120(4 bytes) |
| ===============================================*/ |
| int convert_ip_str_to_ascii(char *in_str, unsigned char *out_str) |
| { |
| int index = 0; |
| char *ptr = NULL; |
| char *nextdot = NULL; |
| |
| if (!in_str || !out_str) { |
| STAT_ERR(convert_ip_str_to_ascii, "input param error"); |
| return STAT_RETURN_ERROR; |
| } |
| ptr = in_str; |
| for (index = 0; index < 4; index++) { |
| *(out_str + index) = (unsigned char)strtoul(ptr, &nextdot, 10); |
| ptr = nextdot + 1; |
| } |
| return STAT_RETURN_OK; |
| } |
| |
| /*=============================================== |
| Convert MAC string(192.168.1.120) to ASCII 192 168 1 120(4 bytes) |
| ===============================================*/ |
| int convert_MAC_str_to_ascii(char *in_str, unsigned char *out_str) |
| { |
| int index = 0; |
| char *ptr = NULL; |
| char *nextdot = NULL; |
| |
| if (!in_str || !out_str) { |
| STAT_ERR(convert_MAC_str_to_ascii, "input param error"); |
| return STAT_RETURN_ERROR; |
| } |
| ptr = in_str; |
| for (index = 0; index < 6; index++) { |
| *(out_str + index) = strtoul(ptr, &nextdot, 16); |
| ptr = nextdot + 1; |
| } |
| return STAT_RETURN_OK; |
| } |
| |
| /*============================================= |
| Convert MAC Hex To String |
| |
| =============================================*/ |
| int convert_MAC_asc_to_str(unsigned char *in_str, char *out_str) |
| { |
| int i = 0; |
| |
| for (i = 0; i < 6; i++) { |
| if ((in_str[i] >> 4) >= 10) { |
| out_str[i * 3] = 'A' + (in_str[i] >> 4) - 0x0A; |
| } else |
| out_str[i * 3] = '0' + (in_str[i] >> 4); |
| |
| if (((in_str[i]) & 0x0F) >= 10) { |
| out_str[i * 3 + 1] = 'A' + (in_str[i] & 0x0F) - 0x0A; |
| } else |
| out_str[i * 3 + 1] = '0' + (in_str[i] & 0x0F); |
| out_str[i * 3 + 2] = ':'; |
| } |
| out_str[17] = '\0'; |
| return STAT_RETURN_OK; |
| } |
| |
| int convert_ip_asc_to_str(unsigned char *in_str, char *out_str) |
| { |
| int i = 0; |
| int index = 0; |
| |
| for (i = 0; i < 4; i++) { |
| if (in_str[i] >= 100) |
| out_str[index++] = '0' + (in_str[i] / 100); |
| if (in_str[i] >= 10) |
| out_str[index++] = '0' + (in_str[i] % 100) / 10; |
| out_str[index++] = '0' + in_str[i] % 10; |
| out_str[index++] = '.'; |
| } |
| out_str[index - 1] = '\0'; |
| return STAT_RETURN_OK; |
| } |
| |
| int is_Feb_29(int year) |
| { |
| if (year > 0) { |
| if (year % 4 == 0) { |
| return 1; |
| } |
| } |
| return 0; |
| } |
| |
| int is_mon_31(int mon) |
| { |
| int days[] = { 31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
| if (mon > 0 && mon <= 12) { |
| if (days[mon - 1] == 31) { |
| return 1; |
| } |
| } |
| return 0; |
| } |
| |
| int stat_init_socket(const char *name) |
| { |
| int fd, len; |
| struct sockaddr_un un; |
| int ret = 0; |
| |
| /*create a UNIX domain stream socket */ |
| fd = socket(AF_UNIX, SOCK_STREAM, 0); |
| if (fd < 0) { |
| return -1; |
| } |
| unlink(name); |
| |
| memset(&un, 0, sizeof(un)); |
| un.sun_family = AF_UNIX; |
| //un.sun_path[0] = '\0'; |
| strncpy(un.sun_path, name, sizeof(un.sun_path) - 1); |
| len = offsetof(struct sockaddr_un, sun_path) + strlen(name); |
| ret = bind(fd, (struct sockaddr *)&un, len); |
| STAT_ERR(stat_init_socket, "RET:%d", ret); |
| if (ret < 0) { |
| STAT_ERR(stat_init_socket1, "errno=%d", errno); |
| STAT_ERR(stat_init_socket2, "bind error"); |
| close(fd); |
| return -1; |
| } |
| return fd; |
| } |
| |
| int stat_system(const char *cmd) |
| { |
| FILE *fp; |
| int res; |
| char buf[1024]; |
| if (cmd == NULL) { |
| STAT_ERR(stat_system, "my_system cmd is NULL!\n"); |
| return -1; |
| } |
| if ((fp = popen(cmd, "r")) == NULL) { |
| STAT_ERR(stat_system0, "popen error: %s/n", strerror(errno)); |
| return -1; |
| } else { |
| while (fgets(buf, sizeof(buf), fp)) { |
| STAT_DBG(stat_system1, "%s", buf); |
| } |
| if ((res = pclose(fp)) == -1) { |
| STAT_ERR(stat_system2, "close popen file pointer fp error!\n"); |
| return res; |
| } else if (res == 0) { |
| return res; |
| } else { |
| STAT_DBG(stat_system3, "popen res is :%d\n", res); |
| return res; |
| } |
| } |
| } |
| |
| int stat_init_uevent_sock(void) |
| { |
| const int buffersize = UEVENT_BUFFER_SIZE; |
| int ret, sock_fd; |
| struct sockaddr_nl snl; |
| |
| bzero(&snl, sizeof(struct sockaddr_nl)); |
| snl.nl_family = AF_NETLINK; |
| snl.nl_pid = getpid(); |
| snl.nl_groups = 1; |
| |
| sock_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); |
| if (sock_fd < 0) |
| { |
| STAT_DBG(stat_init_uevent_sock, "[stat_init_uevent_sock] socket error"); |
| return -1; |
| } |
| |
| setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); |
| |
| ret = bind(sock_fd, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl)); |
| if (ret < 0) |
| { |
| STAT_DBG(stat_init_uevent_sock1, "stat_init_uevent_sock: bind error\n"); |
| close(sock_fd); |
| return -1; |
| } |
| |
| return sock_fd; |
| } |
| |
| char *search_key(const char *searchkey, char *buf, size_t buflen) |
| { |
| size_t keylen, pos = 0, searchkeylen = strlen(searchkey); |
| char *key; |
| |
| while (pos < buflen) { |
| key = buf + pos; |
| keylen = strlen(key); |
| if (keylen == 0) |
| break; |
| if (!strncmp(searchkey, key, searchkeylen) && key[searchkeylen] == '=') |
| return key + searchkeylen + 1; |
| pos += keylen + 1; |
| } |
| return NULL; |
| } |
| /*============================================ |
| read data from USB_CLIENT_MAC_FILE/USB_CLIENT_STATE_FILE |
| return long long |
| =============================================*/ |
| char* get_file_data(const char *filename) |
| { |
| FILE *fstream = NULL; |
| struct stat_read_buf read_buf; |
| int ret = 0; |
| char *ret_str = NULL; |
| |
| if (!filename) { |
| STAT_ERR(get_file_data, " filename NULL"); |
| return 0; |
| } |
| fstream = fopen(filename, "r"); |
| if (!fstream) { |
| STAT_ERR(get_file_data1, "open file %s fail", filename); |
| return 0; |
| } |
| if (feof(fstream)) { |
| STAT_ERR(get_file_data2, "empty file"); |
| fclose(fstream); |
| return 0; |
| } |
| memset(&read_buf, 0, sizeof(struct stat_read_buf)); |
| ret = stat_get_line(fstream, &read_buf); |
| STAT_ERR(get_file_data3, "ret :%d", ret); |
| if (ret == STAT_READ_OK) { |
| ret_str = strdup(read_buf.buf); |
| STAT_DBG(get_file_data4, "read_buf:%s,ret_str%s", read_buf.buf, ret_str); |
| } |
| fclose(fstream); |
| if (read_buf.buf) { |
| free(read_buf.buf); |
| read_buf.buf = NULL; |
| } |
| return ret_str; |
| } |
| |