ENUM_SERVICE_STATUS_PROCESS

博客介绍了ENUM_SERVICE_STATUS_PROCESS结构,该结构供EnumServicesStatusEx函数使用,用于返回服务控制管理器数据库中服务的名称,同时还能返回服务的相关信息,此外还提及了成员和要求。

ENUM_SERVICE_STATUS_PROCESS

The ENUM_SERVICE_STATUS_PROCESS structure is used by the EnumServicesStatusEx function to return the name of a service in a service control manager database. The structure also returns information about the service.

typedef struct _ENUM_SERVICE_STATUS_PROCESS {
LPTSTR lpServiceName;
LPTSTR lpDisplayName;
SERVICE_STATUS_PROCESS ServiceStatusProcess; } ENUM_SERVICE_STATUS_PROCESS,
*LPENUM_SERVICE_STATUS_PROCESS;
Members
lpServiceName
Pointer to a null-terminated string that specifies the name of a service in the service control manager database. The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. A slash (/), backslash (/), comma, and space are invalid service name characters.
lpDisplayName
Pointer to a null-terminated string that specifies a display name that can be used by service control programs, such as Services in Control Panel, to identify the service. This string has a maximum length of 256 characters. The case is preserved in the service control manager. Display name comparisons are always case-insensitive.
ServiceStatusProcess
A SERVICE_STATUS_PROCESS structure that contains status information for the lpServiceName service.
Requirements
ClientRequires Windows XP or Windows 2000 Professional.
ServerRequires Windows Server 2003 or Windows 2000 Server.
Header

Declared in Winsvc.h; include Windows.h.

Unicode

Implemented as ENUM_SERVICE_STATUS_PROCESSW (Unicode) and ENUM_SERVICE_STATUS_PROCESSA (ANSI).

测试结果 0/1 共有1组测试集,其中有1组测试结果不匹配。详情如下: 测试集1 消耗内存1690.84MB代码执行时长:0.14秒 —— 预期输出 ———— 实际输出 —— user private_letter mail_send_task mail_send_record system_message user_id user_name user_email private_letter_id read_status create_time private_letter_content receiver_id sender_id conversationalist_id user_id sender_id mail_send_task_id mail_string mail_topic mail_content create_time process_time process_status mail_send_record_id mail_address mail_send_task_id create_time send_time send_status system_message_id sender_id message_redirection_link_count create_time read_status system_message_type system_message_source extra_information system_message_content receiver_id send process_send_task push user private_letter mail_send_task mail_send_record出错,请重新检查 system_message user_id user_name user_email private_letter_id read_status create_time private_letter_content receiver_id sender_id conversationalist_id user_id sender_id mail_send_task_id mail_string mail_topic mail_content create_time process_time process_status mail_send_record_id出错,请重新检查 mail_address出错,请重新检查 mail_send_task_id出错,请重新检查 create_time出错,请重新检查 send_time出错,请重新检查 send_status出错,请重新检查 system_message_id sender_id message_redirection_link_count create_time read_status system_message_type system_message_source extra_information system_message_content receiver_id send出错,请重新检查 process_send_task出错,请重新检查 push出错,请重新检查 检查修改错误
最新发布
11-25
int ath12k_dp_service_srng(struct ath12k_base *ab, struct ath12k_ext_irq_grp *irq_grp, int budget) { struct napi_struct *napi = &irq_grp->napi; int grp_id = irq_grp->grp_id; int work_done = 0; int i = 0, j; int tot_work_done = 0; enum dp_monitor_mode monitor_mode; u8 ring_mask; if (ab->hw_params->ring_mask->tx[grp_id]) { i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1; ath12k_dp_tx_completion_handler(ab, i); } if (ab->hw_params->ring_mask->rx_err[grp_id]) { work_done = ath12k_dp_rx_process_err(ab, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) goto done; } if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) { work_done = ath12k_dp_rx_process_wbm_err(ab, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) goto done; } if (ab->hw_params->ring_mask->rx[grp_id]) { i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1; work_done = ath12k_dp_rx_process(ab, i, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) goto done; } if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) { ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id]; for (i = 0; i < ab->num_radios; i++) { for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { int id = i * ab->hw_params->num_rxdma_per_pdev + j; if (ring_mask & BIT(id)) { work_done = ath12k_dp_mon_process_ring(ab, id, napi, budget, 0); budget -= work_done; tot_work_done += work_done; if (budget <= 0) goto done; } } } } if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) { monitor_mode = ATH12K_DP_RX_MONITOR_MODE; ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id]; for (i = 0; i < ab->num_radios; i++) { for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { int id = i * ab->hw_params->num_rxdma_per_pdev + j; if (ring_mask & BIT(id)) { work_done = ath12k_dp_mon_process_ring(ab, id, napi, budget, monitor_mode); budget -= work_done; tot_work_done += work_done; if (budget <= 0) goto done; } } } } if (ab->hw_params->ring_mask->tx_mon_dest[grp_id]) { monitor_mode = ATH12K_DP_TX_MONITOR_MODE; ring_mask = ab->hw_params->ring_mask->tx_mon_dest[grp_id]; for (i = 0; i < ab->num_radios; i++) { for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { int id = i * ab->hw_params->num_rxdma_per_pdev + j; if (ring_mask & BIT(id)) { work_done = ath12k_dp_mon_process_ring(ab, id, napi, budget, monitor_mode); budget -= work_done; tot_work_done += work_done; if (budget <= 0) goto done; } } } } if (ab->hw_params->ring_mask->reo_status[grp_id]) ath12k_dp_rx_process_reo_status(ab); if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { struct ath12k_dp *dp = &ab->dp; struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; LIST_HEAD(list); ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); } /* TODO: Implement handler for other interrupts */ done: return tot_work_done; } 这个函数的作用
09-30
/*!Copyright(c) 2012-2019 Shenzhen TP-LINK Technologies Co.Ltd. * *\file url_class.c *\brief process for URL query * *\author Wanghao *\version 1.0.0 *\date 27Aug19 * *\history * */ #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> #include <string.h> #include <asm/types.h> #include <linux/netlink.h> #include <linux/socket.h> #include <getopt.h> #include <errno.h> #include <avira/auc/aucApi.h> #include <pthread.h> #include <signal.h> #include <sys/time.h> #include <curl/curl.h> #include "cJSON.h" #include <uci.h> #include <mali_url_check.h> #include <fcntl.h> #include <unistd.h> #define printErr(fmt, args...) printf("\033[1m[ %s ] %03d: "fmt"\033[0m", __FUNCTION__, __LINE__, ##args) #define printWar(fmt, args...) printf("\033[1m[ %s ] %03d: "fmt"\033[0m", __FUNCTION__, __LINE__, ##args) #define CURL_DEBUG 0 #define URL_CLASS_LOG_LEVEL LOG_LEVEL_MAX #define URL_CLASS_LOG(level, fmt, args...) \ do \ { \ if (level >= URL_CLASS_LOG_LEVEL) \ { \ static char cmd[1024] = {0}, final[1024+128] = {0}; \ struct timeval tv; \ struct tm* local; \ gettimeofday(&tv, NULL); \ local = localtime(&tv.tv_sec); \ memset(cmd,0,sizeof(cmd));memset(final,0,sizeof(final));\ snprintf(cmd, sizeof(cmd), fmt, ##args); \ snprintf(final, sizeof(final), "echo \"%04d-%02d-%02d %02d:%02d:%02d.%03d|level:%d|%s:%d|%s| - ",\ local->tm_year + 1900, local->tm_mon + 1, local->tm_mday, \ local->tm_hour, local->tm_min, local->tm_sec, (int)(tv.tv_usec / 1000), \ level, __FILE__, __LINE__, __func__); \ int _i = 0, _j = strlen(final); \ for(_i = 0; _i < 1024 && _j < 1024+128-15; _i++,_j++) \ { \ if(cmd[_i] == '\"' || cmd[_i] == '\\' || cmd[_i] == '`' || cmd[_i] == '$') \ { \ final[_j++] = '\\'; \ } \ final[_j] = cmd[_i]; \ } \ strncpy(final + (final[strlen(final) - 1] == '\n'? strlen(final)-1: strlen(final)), "\"> /dev/console", 16); \ system(final); \ } \ } while (0) #define MIN(a,b) ((a)<(b) ? (a):(b)) #define MALI_MAX_WAIT_TIME 1024 typedef enum { LOG_LEVEL_DEBUG = 0, // log level debug LOG_LEVEL_INFO, // log level information LOG_LEVEL_WARN, // log level warning LOG_LEVEL_ERROR, // log level error LOG_LEVEL_EMRG, // log level emergency LOG_LEVEL_MAX }E_LOG_LEVE; struct Options { bool use_tp_service; }; struct Options opts; #define MAX_PAYLOAD 1024 // maximum payload size #ifndef NETLINK_URL_CLASS #define NETLINK_URL_CLASS 27 #endif //#define MAX_URL_ENTRY_LEN 512//256 #define MAX_URL_LEN 256 #define MAX_URL_CAT_DEFAULT 9999 #define PCTL_WEB_URL_ID_ALL 0xfffe #if SUPPORT_CLOUD_UPDATE_AUC_INFO #define POST_TRANSFER_TIMEOUT 20 #define POST_CONNECT_TIMEOUT 20 #define AUC_UPDATE_TIME_INTERVAL_DEFAULT 3600 //1h #define AUC_UPDATE_TIME_INTERVAL_FAST 10 //10s #define REQUEST_TIMEOUT_MS 8000 #define MAX_TOKEN_LEN 128 #define FILE_CLOUD_TOKEN_HOMECARE "/tmp/cloud/cloud_token_homecare" #define GET_AUC_URL_POSTFIX "/v1/configuration/auc-service-info" #define CA_CRT_PATH "/etc/certificate/2048_newroot.cer" struct auc_update_status_info { int update_time_interval; time_t updata_time_stamp_last; }; static struct auc_update_status_info auc_update_status = { .update_time_interval = AUC_UPDATE_TIME_INTERVAL_DEFAULT, .updata_time_stamp_last = 0, }; typedef struct _st_http_resinfo { long status_code; }st_http_resinfo; #endif enum url_req { URL_REQ_VOID = 0, URL_REQ_HELLO, URL_REQ_CAT, URL_REQ_LOG, URL_REQ_LOG_HISTORY, URL_REQ_BYE, URL_REQ_END }; struct url_carrier { int id; int info_id; unsigned char url_len; unsigned int cat_id; unsigned int cat_map; char url[MAX_URL_LEN]; }; enum url_process_status { URL_PROCESS_READY = 0, //waiting for auc process URL_PROCESSING //auc is processing, changing url is useless }; struct url_entry { int id; int info_id; unsigned int cat_map; unsigned char query; unsigned char url_len; enum url_process_status process_flag; struct url_entry *prev; struct url_entry *next; char url[MAX_URL_LEN]; }; pthread_mutex_t url_lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mali_url_check_lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //struct url_entry url_array[MAX_URL_ENTRY_LEN]; struct url_entry *url_array; static struct url_entry url_list = { .id = 0, .info_id = 0, .cat_map = 0, .query = 0, .url_len = 0, .prev = NULL, .next = NULL, }; int sock_fd = -1; //cat mapping table int mapping_table[][32] = { {1, 274, 276, 374, 132, -1}, //1100, 1-Games {2, 193, 447, 449, -1}, //1000, 2-Download {3, 222, 223, 224, 357, -1}, //900, 3-Media {4, 107, 388, -1}, //800, 4-Pay-to-surf & Shopping {5, 414, 445, -1}, //700, 5-Social Networking {6, 359, 360, 355, 293, 397, 450, 451, -1}, //600, 6-Oline Communications and Search {7, 443, -1}, //500, 7-Gambling {10, 241, 179, 76, 170, 167, -1}, //200, 10-Sex Education {11, 234, 400, 269, 444, 446, 395, 429, 391, 390, 103, 64, 65, 66, 149, 452, 453, 442, -1}, //100, 11-Adult Content {13, 2, -1}, //000, unsafe, 13-Malware {14, 3, -1}, //000, unsafe, 14-Phishing {15, 197, -1}, // 15-web_search {12, MAX_URL_CAT_DEFAULT, -1}, //2000, 12-Other(Default) {-1} //END }; static inline void strncpy_safe(char *__dest, const char *__src, size_t __n) { strncpy(__dest, __src, __n); __dest[__n] = '\0'; } static void on_exit_handler() { struct sockaddr_nl dest_addr; struct nlmsghdr *nlh = NULL; struct iovec iov; struct msghdr msg; int state_smg = 0; nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); if (!nlh) { printErr("malloc nlmsghdr error!\n"); close(sock_fd); return; } //say bye to kernel memset(nlh,0,NLMSG_SPACE(MAX_PAYLOAD)); memset(&dest_addr,0,sizeof(dest_addr)); dest_addr.nl_family = AF_NETLINK; dest_addr.nl_pid = 0; dest_addr.nl_groups = 0; nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = 0; nlh->nlmsg_flags = 0; nlh->nlmsg_type = URL_REQ_BYE; iov.iov_base = (void *)nlh; iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); memset(&msg, 0, sizeof(msg)); msg.msg_name = (void *)&dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; state_smg = sendmsg(sock_fd, &msg, 0); if (state_smg < 0) { printErr("get error sendmsg = %s\n",strerror(errno)); } if (nlh) { free(nlh); } close(sock_fd); return; } static void signal_exit_handler(int sig) { exit(0); } static int url_send(int id, unsigned int cat_id, char *url, unsigned char url_len, unsigned short type) { struct nlmsghdr *nlh = NULL; struct iovec iov; struct msghdr msg; struct sockaddr_nl dest_addr; struct url_carrier data; int state_smg = 0; int ret = 0; nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); if (!nlh) { printErr("malloc nlmsghdr error!\n"); return -1; } memset(&dest_addr,0,sizeof(dest_addr)); dest_addr.nl_family = AF_NETLINK; dest_addr.nl_pid = 0; dest_addr.nl_groups = 0; nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = 0; nlh->nlmsg_type = type; memset(&data, 0, sizeof(struct url_carrier)); data.id = id; data.cat_id = cat_id; data.url_len = url_len; strncpy_safe(data.url, url, url_len); printWar("url_send to kernel, id=%d, cat_id=%x, url=%s, url_len=%d \n", data.id, data.cat_id, data.url, data.url_len); memcpy(NLMSG_DATA(nlh), &data, sizeof(struct url_carrier)); iov.iov_base = (void *)nlh; iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); memset(&msg, 0, sizeof(msg)); msg.msg_name = (void *)&dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; state_smg = sendmsg(sock_fd, &msg, 0); if (state_smg < 0) { printErr("get error sendmsg = %s\n",strerror(errno)); ret = -1; goto out; } out: if (nlh) { free(nlh); } return ret; } static void __attribute__((unused)) dump_list(struct url_entry *list) { printErr("dump:\n"); while (list) { printWar("id=%d url=%s\n", list->id, list->url); list = list->next; } } static void cond_timedwait(long timeout) { struct timespec abstime; struct timeval now; long nsec = 0; pthread_mutex_lock(&url_lock); gettimeofday(&now, NULL); nsec = now.tv_usec * 1000 + (timeout % 1000) * 1000000; abstime.tv_sec=now.tv_sec + nsec / 1000000000 + timeout / 1000; abstime.tv_nsec=nsec % 1000000000; pthread_cond_timedwait(&cond, &url_lock, &abstime); pthread_mutex_unlock(&url_lock); } #if SUPPORT_CLOUD_UPDATE_AUC_INFO static int OnDebug(CURL * curl, curl_infotype itype, char * pData, size_t size, void *lpVoid) { if (itype == CURLINFO_TEXT) { //URL_CLASS_LOG(LOG_LEVEL_DEBUG,"[TEXT]%s", pData); } else if (itype == CURLINFO_HEADER_IN) { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "[HEADER_IN]%s", pData); } else if (itype == CURLINFO_HEADER_OUT) { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "[HEADER_OUT]%s", pData); } else if (itype == CURLINFO_DATA_IN) { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "[DATA_IN]%s", pData); } else if (itype == CURLINFO_DATA_OUT) { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "[DATA_OUT]%s", pData); } return 0; } static size_t OnWriteData_Post(void* buffer, size_t size, size_t nmemb, void* lpVoid) { if (NULL == buffer) { return -1; } unsigned int len = (unsigned int)size * (unsigned int)nmemb; char *str = (char*)malloc(len + 1); if (NULL == str) { return -1; } char* pData = (char*)buffer; memset(str, 0, len + 1); memcpy(str, pData, len); URL_CLASS_LOG(LOG_LEVEL_DEBUG, "response: %s\n", str); char **response = (char**)lpVoid; *response = str; return len; } static size_t cloud_https_post(const char *pUrl, const char *requestHeader, const char *request, char **response, st_http_resinfo *pHttpResInfo) { CURLcode res; CURL* curl = NULL; struct curl_slist *headers = NULL; #ifdef CURL_DEBUG char errbuf[CURL_ERROR_SIZE]; memset(errbuf, '\0', CURL_ERROR_SIZE); #endif if (NULL == pUrl || NULL == request || NULL == response || NULL == pHttpResInfo) { return CURLE_FAILED_INIT; } URL_CLASS_LOG(LOG_LEVEL_DEBUG, "pUrl:%s\n requestHeader:%s\n request:%s\n", pUrl, requestHeader, request); res = curl_global_init(CURL_GLOBAL_ALL); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl global init fail and ret %d", res); return res; } curl = curl_easy_init(); if (NULL == curl) { res = CURLE_FAILED_INIT; URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl init fail"); goto exit; } //headers = curl_slist_append(headers, "Content-Type: application/json;charset=UTF-8"); headers = curl_slist_append(headers, "Content-Type: application/json"); if (NULL == headers) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl get header list fail"); goto exit; } if ((NULL != requestHeader) && (0 < strlen(requestHeader))) { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "requestHeader is %s", requestHeader); headers = curl_slist_append(headers, requestHeader); if (NULL == headers) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl append requestHeader fail"); goto exit; } } #ifdef CURL_DEBUG //provide a buffer to store errors in res = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_ERRORBUFFER ret %d", res); goto exit; } #endif if (CURL_DEBUG) { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "post sesstion debug on"); res = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_VERBOSE ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_DEBUGFUNCTION ret %d", res); goto exit; } } //set url res = curl_easy_setopt(curl, CURLOPT_URL, pUrl); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_URL ret %d", res); goto exit; } //set header res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_HTTPHEADER ret %d", res); goto exit; } //set post method res = curl_easy_setopt(curl, CURLOPT_POST, 1); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_POST ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_POSTFIELDS ret %d", res); goto exit; } //set read/write params res = curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_READFUNCTION ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData_Post); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_WRITEFUNCTION ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)response); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_WRITEDATA ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_NOSIGNAL ret %d", res); goto exit; } //set certificate info res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_SSL_VERIFYPEER ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_CAINFO, CA_CRT_PATH); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_CAINFO ret %d", res); goto exit; } //set CURLOPT_CONNECTTIMEOUT res = curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, POST_TRANSFER_TIMEOUT); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_CONNECTTIMEOUT ret %d", res); goto exit; } //set CURLOPT_TIMEOUT res = curl_easy_setopt(curl, CURLOPT_TIMEOUT, POST_CONNECT_TIMEOUT); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_TIMEOUT ret %d", res); goto exit; } //CURLOPT needs to be set_ FOLLOWLOCATION is 1, otherwise, the data after redirecting will not be returned res = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,1); if (CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "curl set option CURLOPT_FOLLOWLOCATION ret %d", res); goto exit; } res = curl_easy_perform(curl); #ifdef CURL_DEBUG if(CURLE_OK != res) { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "curl post return error: %s", errbuf); } #endif curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &(pHttpResInfo->status_code)); URL_CLASS_LOG(LOG_LEVEL_DEBUG, "cloud_https_post done. ret %d, http status code %d", res, pHttpResInfo->status_code); exit: if (headers) { curl_slist_free_all(headers); } if (curl) { curl_easy_cleanup(curl); } curl_global_cleanup(); return res; } static int get_token_url(char *token, char *url) { int ret = -1; int retry_count = 3; FILE *fp = NULL; while (retry_count > 0) { if(fp = fopen(FILE_CLOUD_TOKEN_HOMECARE, "r")) { fscanf(fp, "%s", token); fscanf(fp, "%s", url); fclose(fp); ret = 0; break; } else { system("cloud_getDevToken homecare"); } retry_count--; } if ((*(token + MAX_TOKEN_LEN - 1) != 0) || (*(url + MAX_URL_LEN - 1) != 0)) { URL_CLASS_LOG(LOG_LEVEL_WARN, "token or url pointer out of range"); ret = -1; } return ret; } static char* get_auc_info_from_cloud_request_data() { int ret = -1; cJSON* request_data_json = NULL; char* request_data = NULL; unsigned char country_code[3] = {0}; FILE *fp = NULL; if ((request_data_json = cJSON_CreateObject()) == NULL) { goto out; } if (fp = popen("getfirm COUNTRY | tr 'A-Z' 'a-z'", "r")) { if (fread(country_code, sizeof(char), 2, fp) > 0) { cJSON_AddStringToObject(request_data_json, (const char*)"region", (const char*)country_code); request_data = cJSON_PrintUnformatted(request_data_json); URL_CLASS_LOG(LOG_LEVEL_DEBUG, "request_data:%s", request_data); } pclose(fp); } cJSON_Delete(request_data_json); return request_data; out: return NULL; } static int get_auc_info_from_cloud(struct auc_info *auc_info, char *device_token, char *url_prefix) { int ret = -1; int ret_post = 0; char request_url[MAX_URL_LEN] = {0}; char request_header[MAX_TOKEN_LEN + 32] = {0}; char *request_data = NULL; char *response = NULL; st_http_resinfo httpResInfo; cJSON* response_json = NULL; cJSON* auc_server_json= NULL; cJSON* api_key_json = NULL; cJSON* user_guid_json = NULL; if (auc_info == NULL || device_token == NULL || url_prefix == NULL) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "params error\n"); return ret; } memset(&httpResInfo, 0, sizeof(st_http_resinfo)); snprintf(request_url, MAX_URL_LEN, "%s%s", url_prefix, GET_AUC_URL_POSTFIX); snprintf(request_header, MAX_TOKEN_LEN + 32, "Authorization: %s", device_token); request_data = get_auc_info_from_cloud_request_data(); //get post result ret_post = cloud_https_post(request_url, request_header, request_data, &response, &httpResInfo); URL_CLASS_LOG(LOG_LEVEL_DEBUG, "curl post return %d http retcode: %ld", ret_post, httpResInfo.status_code); if(request_data) { cJSON_free(request_data); } if (response && httpResInfo.status_code == 200) { response_json = cJSON_Parse(response); auc_server_json= cJSON_GetObjectItem(response_json, "aucServerUrl"); api_key_json = cJSON_GetObjectItem(response_json, "apiKey"); user_guid_json = cJSON_GetObjectItem(response_json, "userGuid"); if (auc_server_json->valuestring && api_key_json->valuestring && user_guid_json->valuestring) { snprintf(auc_info->auc_server, MAX_AUC_SERVER_LEN, "%s", auc_server_json->valuestring); snprintf(auc_info->api_key, MAX_API_KEY_LEN, "%s", api_key_json->valuestring); snprintf(auc_info->user_guid, MAX_USER_GUID, "%s", user_guid_json->valuestring); ret = 0; } } out: cJSON_Delete(response_json); return ret; } static void set_retry_time_interval(void) { if (auc_update_status.update_time_interval == AUC_UPDATE_TIME_INTERVAL_DEFAULT) { auc_update_status.update_time_interval = AUC_UPDATE_TIME_INTERVAL_FAST; } else if (auc_update_status.update_time_interval < AUC_UPDATE_TIME_INTERVAL_DEFAULT && (auc_update_status.update_time_interval * 2) < AUC_UPDATE_TIME_INTERVAL_DEFAULT) { auc_update_status.update_time_interval = auc_update_status.update_time_interval * 2; } else { auc_update_status.update_time_interval = AUC_UPDATE_TIME_INTERVAL_DEFAULT; } } static void update_libauc_url(struct auc_info *auc_info, bool use_tp_service) { char device_token[MAX_TOKEN_LEN] = {0}; char cloud_homecare_url[MAX_URL_LEN] = {0}; time_t time_stamp; memset(device_token, 0, MAX_TOKEN_LEN); memset(cloud_homecare_url, 0, MAX_URL_LEN); memset(auc_info->auc_server, 0, MAX_AUC_SERVER_LEN); memset(auc_info->api_key, 0, MAX_API_KEY_LEN); memset(auc_info->user_guid, 0, MAX_USER_GUID); //get time stamp time(&time_stamp); URL_CLASS_LOG(LOG_LEVEL_DEBUG, "start time_stamp:%d, updata_time_stamp_last:%d, update_time_interval:%d\n", time_stamp, auc_update_status.updata_time_stamp_last, auc_update_status.update_time_interval); if ((time_stamp - auc_update_status.updata_time_stamp_last) >= auc_update_status.update_time_interval) { if(use_tp_service) { if (0 == (get_token_url(device_token, cloud_homecare_url))) { memset(auc_info->tp_auc_server, 0, MAX_AUC_SERVER_LEN); snprintf(auc_info->tp_auc_server, MAX_AUC_SERVER_LEN, "%s", cloud_homecare_url); auc_update_status.updata_time_stamp_last = time_stamp; auc_update_status.update_time_interval = AUC_UPDATE_TIME_INTERVAL_DEFAULT; } else { auc_update_status.updata_time_stamp_last = time_stamp; set_retry_time_interval(); } } else { if (0 == (get_token_url(device_token, cloud_homecare_url))) { if (0 == get_auc_info_from_cloud(auc_info, device_token, cloud_homecare_url)) { auc_update_status.updata_time_stamp_last = time_stamp; auc_update_status.update_time_interval = AUC_UPDATE_TIME_INTERVAL_DEFAULT; } else { auc_update_status.updata_time_stamp_last = time_stamp; set_retry_time_interval(); } } else { auc_update_status.updata_time_stamp_last = time_stamp; set_retry_time_interval(); } } } else { } URL_CLASS_LOG(LOG_LEVEL_DEBUG, "end time_stamp:%d, updata_time_stamp_last:%d, update_time_interval:%d\n", time_stamp, auc_update_status.updata_time_stamp_last, auc_update_status.update_time_interval); URL_CLASS_LOG(LOG_LEVEL_DEBUG, "auc_server:%s, tp_auc_server:%s, api_key:%s, user_guid:%s\n", auc_info->auc_server, auc_info->tp_auc_server, auc_info->api_key, auc_info->user_guid); return; } #endif static void *mali_checkQuery(void *unused) { int ret = 0; int ret_mali = 0; int failed_num = 0; unsigned int wait_time = 0; parse_para para = {0, 0, 0}; srand((uint32_t)getpid()); while (1) { ret = parse_config(&para); if(0 == ret) { if ((web_protection)&&(para.web_protection)) { ret_mali = mali_url_hash_list_update(true); if (ret_mali < 0) { if (!failed_num) wait_time = 2 + (rand() % 254); else if (wait_time < MALI_MAX_WAIT_TIME) wait_time <<= 1; failed_num++; sleep(MIN(wait_time, MALI_MAX_WAIT_TIME)); } else { if (!access(CLOUD_HASH_FILE_UPDATE_FLAG, R_OK)) { pthread_mutex_lock(&mali_url_check_lock); mali_url_hash_list_update(false); pthread_mutex_unlock(&mali_url_check_lock); } failed_num = 0; } } else if ((web_protection)&&(!para.web_protection)) { pthread_mutex_lock(&mali_url_check_lock); mali_url_check_free(); web_protection = false; pthread_mutex_unlock(&mali_url_check_lock); failed_num = 0; } else if ((!web_protection)&&(para.web_protection)) { pthread_mutex_lock(&mali_url_check_lock); ret_mali = mali_url_check_init(false); if (0 == ret_mali) { web_protection = true; pthread_mutex_unlock(&mali_url_check_lock); failed_num = 0; } else { pthread_mutex_unlock(&mali_url_check_lock); if (!failed_num) wait_time = 2 + (rand() % 254); else if (wait_time < MALI_MAX_WAIT_TIME) wait_time <<= 1; failed_num++; sleep(MIN(wait_time, MALI_MAX_WAIT_TIME)); } } } sleep(5); } } void write_to_csv(const char *url, int original_cat_id, int mapped_cat_id) { int fd = open("/var/auc_classification_results.csv", O_CREAT | O_WRONLY | O_APPEND, 0644); if (fd!= -1) { char buffer[512]; snprintf(buffer, sizeof(buffer), "%s,%d,%d\n", url, original_cat_id, mapped_cat_id); write(fd, buffer, strlen(buffer)); close(fd); } } static void *aucQuery(void *unused) { int ret = 0; struct url_info url_info; bool is_mali = false; #if SUPPORT_CLOUD_UPDATE_AUC_INFO struct auc_info auc_info; #endif unsigned int cat_id = 0; int tmp_id = 0; int index = 0; int index_cat = 0; int index_subcat = 0; unsigned char matched = 0; struct url_entry *tmp_list = NULL; struct url_entry *clean = NULL; unsigned char tmp_url_len; char tmp_url[MAX_URL_LEN] = {0}; printWar("create AUC query thread\n"); while (1) { pthread_mutex_lock(&url_lock); tmp_list = url_list.next; pthread_mutex_unlock(&url_lock); while (tmp_list) { pthread_mutex_lock(&url_lock); tmp_list->process_flag = URL_PROCESSING; pthread_mutex_unlock(&url_lock); url_info.url = tmp_list->url; url_info.info_len = 0; ret = pthread_mutex_trylock(&mali_url_check_lock); if (!ret) { is_mali = web_protection? is_url_malicious(url_info.url) : false; if (is_mali) { cat_id = URL_CAT_SECURITY; #if DEBUG printWar("cat ret=%d url=%s id=%d info_id=%d\n", cat_id, url_info.url, tmp_list->id, tmp_list->info_id); #endif /* DEBUG */ pthread_mutex_lock(&url_lock); tmp_list->prev->next = tmp_list->next; if (tmp_list->next) { tmp_list->next->prev = tmp_list->prev; } tmp_list->query = 1; tmp_id = tmp_list->id; tmp_list->id = 0; tmp_list->info_id = 0; tmp_list->cat_map = 0; tmp_url_len = tmp_list->url_len; memset(tmp_url, 0, MAX_URL_LEN); strncpy_safe(tmp_url, tmp_list->url, tmp_list->url_len); clean = tmp_list; tmp_list = tmp_list->next; clean->next = NULL; clean->prev = NULL; pthread_mutex_unlock(&url_lock); pthread_mutex_unlock(&mali_url_check_lock); write_to_csv(url_info.url, cat_id, cat_id); goto block_mali; } else { pthread_mutex_unlock(&mali_url_check_lock); } } if((!opts.use_tp_service && tmp_list->cat_map) || (opts.use_tp_service && (tmp_list->info_id != PCTL_WEB_URL_ID_ALL) && (tmp_list->cat_map & (~URL_CAT_SECURITY)))) { printWar("before send to auc\n"); #if SUPPORT_CLOUD_UPDATE_AUC_INFO update_libauc_url(&auc_info, opts.use_tp_service); ret = auc_query(&url_info, &auc_info, opts.use_tp_service); #else ret = auc_query(&url_info, opts.use_tp_service); #endif printWar("after send to auc\n"); for (index = 0; index < url_info.info_len; index++) { printWar("cat ret=%d url=%s id=%d name=%s\n", ret, url_info.url, url_info.info[index].id, url_info.info[index].name); } } //remove from url_list pthread_mutex_lock(&url_lock); tmp_list->prev->next = tmp_list->next; if (tmp_list->next) { tmp_list->next->prev = tmp_list->prev; } tmp_list->query = 1; tmp_id = tmp_list->id; tmp_list->id = 0; tmp_list->info_id = 0; tmp_list->cat_map = 0; tmp_url_len = tmp_list->url_len; memset(tmp_url, 0, MAX_URL_LEN); strncpy_safe(tmp_url, tmp_list->url, tmp_list->url_len); clean = tmp_list; tmp_list = tmp_list->next; clean->next = NULL; clean->prev = NULL; pthread_mutex_unlock(&url_lock); //send to kernel cat_id = 0; int original_cat_id = 0; for (index = 0; index < url_info.info_len; index++) { original_cat_id = url_info.info[index].id; for (index_cat = 0; mapping_table[index_cat][0] > 0; index_cat++) { matched = 0; for (index_subcat = 1; mapping_table[index_cat][index_subcat] >= 0; index_subcat++) { if (url_info.info[index].id == mapping_table[index_cat][index_subcat] || mapping_table[index_cat][index_subcat] == MAX_URL_CAT_DEFAULT) { cat_id |= 0x1 << (mapping_table[index_cat][0] - 1); matched = 1; break; } } if (matched) { break; } } } write_to_csv(url_info.url, original_cat_id, cat_id); block_mali: printWar("send to kernel, url=%s cat_id=%x\n", url_info.url, cat_id); url_send(tmp_id, cat_id, tmp_url, tmp_url_len, URL_REQ_CAT); printWar("after send to kernel\n"); } cond_timedwait(500);//500ms } return 0; } static const char* short_opt = "s:h"; static struct option long_opt[] = { {"server" , required_argument , NULL, 'a'}, {"help" , no_argument , NULL, 'h'}, {0 , 0 , NULL, 0 } }; static void printHelp(char *progName); static int parseOpts(int argc, char* argv[], struct Options* opt); static void printHelpInstruction(char *progName); static unsigned int get_max_url_entry_len(void) { unsigned int *url_entry_len = NULL; int state; struct msghdr msg; struct iovec iov; struct nlmsghdr *nlh = NULL; nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); if (!nlh) { printErr("malloc nlmsghdr error!\n"); return 0; } nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = 0; nlh->nlmsg_type = URL_REQ_HELLO; iov.iov_base = (void *)nlh; iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); memset(&msg, 0, sizeof(msg)); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; if (sock_fd < 0) { printErr("error getting socket in recving: %s\n", strerror(errno)); return 0; } state = recvmsg(sock_fd, &msg, 0); if(state < 0) { printWar("state<1\n"); return 0; } //store to array url_entry_len = (unsigned int *)NLMSG_DATA(nlh); URL_CLASS_LOG(LOG_LEVEL_DEBUG, "msg from kernel, max_url_entry_len=%u\n", *url_entry_len); return *url_entry_len; } int main(int argc, char* argv[]) { int state; struct sockaddr_nl src_addr, dest_addr; struct nlmsghdr *nlh = NULL; struct iovec iov; struct msghdr msg; int retval; int state_smg = 0; pthread_t pid, pid_mali; int pret = 0; struct url_carrier *tmp = NULL; int index; pid_t fpid = 0; int ret = 0; int rc = parseOpts(argc, argv, &opts); unsigned int url_entry_len = 0; unsigned int malloc_url_entry_len = 0; if (!rc) { return 1; } fpid = fork(); if (fpid < 0) { printErr("error fork.../n"); exit(1); } else if (fpid > 0) { exit(0); } //setup exit handler atexit(on_exit_handler); signal(SIGTERM, signal_exit_handler); signal(SIGINT, signal_exit_handler); // Create a socket sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_URL_CLASS); if (sock_fd < 0) { printErr("error getting socket: %s\n", strerror(errno)); return -1; } int send_buf = 4096; int recv_buf = 4096; if(setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &send_buf, sizeof(send_buf)) < 0) { printErr("setsockopt: %s", strerror(errno)); } if(setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &recv_buf, sizeof(recv_buf)) < 0) { printErr("setsockopt: %s", strerror(errno)); } // To prepare binding memset(&src_addr, 0, sizeof(src_addr)); src_addr.nl_family = AF_NETLINK; src_addr.nl_pid = getpid(); src_addr.nl_groups = 0; retval = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)); if (retval < 0) { printErr("bind failed: %s\n", strerror(errno)); ret = -1; goto exit; } nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); if (!nlh) { printErr("malloc nlmsghdr error!\n"); ret = -1; goto exit; } memset(&dest_addr,0,sizeof(dest_addr)); dest_addr.nl_family = AF_NETLINK; dest_addr.nl_pid = 0; dest_addr.nl_groups = 0; nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = 0; nlh->nlmsg_type = URL_REQ_HELLO; iov.iov_base = (void *)nlh; iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); memset(&msg, 0, sizeof(msg)); msg.msg_name = (void *)&dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; state_smg = sendmsg(sock_fd, &msg, 0);//Hello to kernel if (state_smg < 0) { printErr("get error sendmsg = %s\n",strerror(errno)); ret = -1; goto exit; } url_entry_len = get_max_url_entry_len(); if(url_entry_len == 0) { printErr("error getting url_entry_len\n"); ret = -1; goto exit; } malloc_url_entry_len = url_entry_len * 2.5;//double for backup, ex. id=1 recv and querying, but id=1 deleted by xt_pctl, then another id=1 recv, place it at url_entry_len+1 //if third/fourth... id=1 recv, they are insert in 2*url_entry_len~2.5*url_entry_len in order url_array = (struct url_entry *)malloc(malloc_url_entry_len * sizeof(struct url_entry)); if (!nlh) { printErr("malloc url_array error!\n"); ret = -1; goto exit; } //mali_checkQuery thread and AUC query thread if (pthread_mutex_init(&mali_url_check_lock, NULL) != 0 ) { printErr("mali_checkQuery pthread_mutex_init failed...%d\n", pret); ret = -1; goto exit; } if (pthread_mutex_init(&url_lock, NULL) != 0 || pthread_cond_init(&cond, NULL) != 0) { printErr("auc pthread_mutex_init failed...%d\n", pret); ret = -1; goto exit; } if ((pret = pthread_create(&pid_mali, NULL, mali_checkQuery, NULL)) != 0){ printErr("mali_checkQuery pthread_create failed...%d\n", pret); ret = -1; goto exit; } if ((pret = pthread_create(&pid, NULL, aucQuery, NULL)) != 0){ printErr("auc pthread_create failed...%d\n", pret); ret = -1; goto exit; } memset(url_array, 0, malloc_url_entry_len * sizeof(struct url_entry)); memset(nlh,0,NLMSG_SPACE(MAX_PAYLOAD));//ready to recv kernel info while (1) { state = recvmsg(sock_fd, &msg, 0); if(state < 0) { printWar("state<1\n"); } //store to array tmp = (struct url_carrier *)NLMSG_DATA(nlh); index = tmp->id; //URL_CLASS_LOG(LOG_LEVEL_DEBUG, "msg from kernel, url=%s len=%d id=%d", tmp->url, tmp->url_len, tmp->id); pthread_mutex_lock(&url_lock); if(index >= url_entry_len) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "Error: xt_pctl url entry size is larger than url_class(%u)!", url_entry_len); pthread_mutex_unlock(&url_lock); continue; } if (url_array[index].prev) {//this node is already in list if(url_array[index].url_len != tmp->url_len || strncmp(url_array[index].url, tmp->url, tmp->url_len) || url_array[index].info_id != tmp->info_id || url_array[index].cat_map != tmp->cat_map) { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "Different node already in list, old_url=%s old_len=%d id=%d, old_process_flag=%d", url_array[index].url, url_array[index].url_len, url_array[index].id, url_array[index].process_flag); if(url_array[index].process_flag == URL_PROCESS_READY) {//Still can modify url_array[index].url_len = tmp->url_len; url_array[index].info_id = tmp->info_id; url_array[index].cat_map = tmp->cat_map; strncpy_safe(url_array[index].url, tmp->url, tmp->url_len); pthread_cond_signal(&cond); pthread_mutex_unlock(&url_lock); URL_CLASS_LOG(LOG_LEVEL_DEBUG, "Replace url=%s at url_array[%d]\n", tmp->url, index); continue; } else { index = url_entry_len + tmp->id; if (url_array[index].prev) { if(url_array[index].url_len == tmp->url_len && !strncmp(url_array[index].url, tmp->url, tmp->url_len) && url_array[index].info_id == tmp->info_id && url_array[index].cat_map == tmp->cat_map) {//Exactly same node is already in list URL_CLASS_LOG(LOG_LEVEL_DEBUG, "url=%s at url_array[%d] already exist!\n", tmp->url, index); pthread_mutex_unlock(&url_lock); continue; } if(url_array[index].process_flag == URL_PROCESS_READY) {//Still can modify url_array[index].url_len = tmp->url_len; url_array[index].info_id = tmp->info_id; url_array[index].cat_map = tmp->cat_map; strncpy_safe(url_array[index].url, tmp->url, tmp->url_len); pthread_cond_signal(&cond); pthread_mutex_unlock(&url_lock); URL_CLASS_LOG(LOG_LEVEL_WARN, "Replace url=%s at url_array[%d]\n", tmp->url, index); continue; } index = 2 * url_entry_len; while(index < malloc_url_entry_len && url_array[index].prev) { index++; } if(index >= malloc_url_entry_len) { //An auc query is ignored here! URL_CLASS_LOG(LOG_LEVEL_ERROR, "url_array is full! url=%s query is ignored!\n", tmp->url_len); pthread_mutex_unlock(&url_lock); continue; } } URL_CLASS_LOG(LOG_LEVEL_DEBUG, "Place url=%s at url_array[%d]\n", tmp->url, index); } } else {//Exactly same node is already in list pthread_mutex_unlock(&url_lock); continue; } } url_array[index].id = tmp->id; url_array[index].query = 0; url_array[index].process_flag = URL_PROCESS_READY; url_array[index].url_len = tmp->url_len; url_array[index].info_id = tmp->info_id; url_array[index].cat_map = tmp->cat_map; strncpy_safe(url_array[index].url, tmp->url, tmp->url_len); printWar("msg from kernel, url=%s len=%d id=%d\n", url_array[index].url, url_array[index].url_len, url_array[index].id); //add to list url_array[index].next = url_list.next; if (url_list.next) { url_list.next->prev = &url_array[index]; } url_array[index].prev = &url_list; url_list.next = &url_array[index]; pthread_cond_signal(&cond); pthread_mutex_unlock(&url_lock); } exit: if (nlh) { free(nlh); } if (url_array) { free(url_array); } on_exit_handler(); return ret; } static size_t _strlcpy(char *dst, const char *src, size_t dstsize) { size_t srclen = (size_t)strlen(src); if (dstsize > 0) { size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen; memset(dst, 0, (len + 1)); memcpy(dst, src, len); } return srclen; } static struct uci_context *_uci_context_init(const char *config_path) { struct uci_context *uci_ctx = NULL; uci_ctx = uci_alloc_context(); if (uci_ctx) { uci_set_confdir(uci_ctx, config_path); } return uci_ctx; } static void _uci_context_free(struct uci_context *uci_ctx) { if (uci_ctx) { uci_free_context(uci_ctx); } } static int _uci_get_value(char * p_uci_str, char* p_value) { struct uci_context *uci_ctx = NULL; struct uci_element *e = NULL; struct uci_ptr p_uci; if (NULL == p_uci_str || NULL == p_value) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "p_uci_str or p_value is null"); goto error; } uci_ctx = _uci_context_init("/etc/config"); if (!uci_ctx) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "fail to init uci context:%s", p_uci_str); goto error; } if (UCI_OK != uci_lookup_ptr(uci_ctx, &p_uci, p_uci_str, true)) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "fail to get ptr %s ", p_uci_str); goto error; } e = p_uci.last; if (UCI_TYPE_OPTION != e->type) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "element type is not option:%d", e->type); goto error; } if (UCI_TYPE_STRING != p_uci.o->type) { URL_CLASS_LOG(LOG_LEVEL_ERROR, "option type is not string:%d", p_uci.o->type); goto error; } _strlcpy(p_value, p_uci.o->v.string, 64); URL_CLASS_LOG(LOG_LEVEL_DEBUG, "Success to get option value %s = %s ", p_uci_str,p_uci.o->v.string); _uci_context_free(uci_ctx); return 0; error: _uci_context_free(uci_ctx); return -1; } int parseOpts(int argc, char* argv[], struct Options* opt) { int c; int rc = 999; int use_tp_service = -1; while((c = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) { switch(c) { case -1: /* no more arguments */ case 0: /* long options toggles */ break; case 's': if (optarg) { if(strcmp(optarg, "avira") == 0) { use_tp_service = 0; URL_CLASS_LOG(LOG_LEVEL_DEBUG, "parse Opts receive use avira service!"); } else if(strcmp(optarg, "tplink") == 0) { use_tp_service = 1; URL_CLASS_LOG(LOG_LEVEL_DEBUG, "parse Opts receive use tplink service!"); } else { URL_CLASS_LOG(LOG_LEVEL_ERROR, "parse Opts receive %s, not avaliable! Try %s -s tplink or %s -s avira", optarg, argv[0], argv[0]); } } rc = 's'; break; case 't': rc = 't'; break; case 'h': printHelp(argv[0]); rc = 0; break; case ':': case '?': printHelpInstruction(argv[0]); rc = 0; break; default: printf("%s : invalid option --\n", c); printHelpInstruction(argv[0]); rc = 0; break; } } if(use_tp_service == -1) { char _key[64] = "avira.info.status"; char _value[64] = {0}; if (_uci_get_value(_key, _value)) { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "-s Parameter not found! Config avira.info.status not found! use default avira service!"); opt->use_tp_service = false; } else { if(strncmp(_value, "available", sizeof("available") - 1) == 0 || strncmp(_value, "libauc_available", sizeof("libauc_available") - 1) == 0) { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "-s Parameter not found! Config avira.info.status=%s! use avira service!", _value); opt->use_tp_service = false; } else { URL_CLASS_LOG(LOG_LEVEL_DEBUG, "-s Parameter not found! Config avira.info.status=%s! use tplink service!", _value); opt->use_tp_service = true; } } } else { opt->use_tp_service = use_tp_service ? true : false; } return rc; } void printHelpInstruction(char *progName) { printf("Try: %s --help for more information\n", progName); } void printHelp(char *progName) { printf("Usage: %s\n\t -s <tplink/avira> Use the specified service provider", progName); } 还原出代码格式
09-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值