还原URL-url_for()

本文详细介绍了Rails框架中URL的生成方法,特别是url_for()函数的使用技巧,包括默认值的利用、覆盖参数以及如何处理复杂的路由规则。
生成URL
“路由器”接受一个URL,并解码它到参数集中,这些参数再由Rails 分派给适当的“控
制器”和“动作”(也按此方式潜在地设置额外的参数)。但是这只是故事的一半。我们的应
用程序也需要创建能引用其自身的URL。例如,每次显示一个表单时,表单需要被连接回一
个“控制器”和“动作”。但应用程序的代码不必知道URL 格式的编码信息;它们被看成是
被调的参数,“路由器”用这些参数完成工作。
我们可以硬编码所有的URL 到应用程序中,但稍微懂些请求格式的人都会伤害到我们的
程序。这违反了DRY 原则;当修改应用程序的位置或URL 格式时,我们必须修改所有这些字
符串。
幸运地是我们不用担心,Rails 通过使用url_for()方法(还有很多高级用法)也抽象了
URL 的生成。要演示这个,让我们回到一个简单映射中。
map.connect ":controller/:action/:id"
url_for()方法通过将它的参数传递给一个映射来生成URL。在可以在“控制器”和“视
图”中工作。让我们试试。
url_for()方法通过将它的参数传递给一个映射来生成URL。在可以在“控制器”和“视图”
中工作。让我们试试。
@link = url_for :controller => "store", :action => "display", :id =>
123
这个代码将把@link 设置成像这样
http://pragprog.com/store/display/123
url_for()方法接受我们的参数并映射它们到一个与我们自己的“路由器”兼容的请求中。
如果用户选择了有些连接的URL,它将调用我们应用程序希望的动作。
经过重载后的url_for()会更聪明。它知道有关的缺省参数并生成你希望的最小限度的
URL。让我们看一些例子。
# 没有action 或者id, 则重载版本使用缺省值。
url_for(:controller => "store")
#=> http://pragprog.com/store
# 如果action 被丢失,则重载版本会在URL 中插入缺省值—index。
url_for(:controller => "store", :id => 123)
#=> http://pragprog.com/store/index/123
# id 是可选的。
url_for(:controller => "store", :action => "list")
#=> http://pragprog.com/store/list
# 一个完整的请求。
url_for(:controller => "store", :action => "list", :id => 123)
#=> http://pragprog.com/store/list/123
# 额外的参数被添加到URL 的尾部。
url_for(:controller => "store", :action => "list",:id => 123, :extra
=> "wibble")
#=> http://rubygarden.org/store/list/123?extra=wibble
缺省机制使用从当前请求获得的值。如果:controller 参数被忽略的话,这是大多数填
充当前“控制器”的名字的用法。假设下面例子在处理传递给store “控制器”的请求时运
行。注意,它如何填充URL 内的“控制器”名字。
url_for(:action => "status")
#=> http://pragprog.com/store/status
URL 生成工作以可用于更复杂的“路由器”。例如,我们博客的“路由器”包含下面映
射。
map.connect "blog/:year/:month/:day",
:controller => "blog",
:action => "show_date",
:requirements => { :year => /(19|20)dd/,
:month => /[01]?d/,
:day => /[0-3]?d/},
:day => nil, # optional
:month => nil # optional
map.connect "blog/show/:id",
:controller => "blog",
:action => "show",
:id => /d+/ # must be numeric
map.connect "blog/:controller/:action/:id"
假设引入请求是http://pragprog.com/blog/2005/4/15。这个请求会被第一个规则映射
给Blog “控制器”的show_date 动作。让我们看看在这些情况下,会产生什么样的url_for()
调用。
如果我们为不同的天要求一个URL,映射调用将接受来自请求的值做缺省值,只是day
参数改变了。
url_for(:day => "25")
#=> http://pragprog.com/blog/2005/4/25
现在让我们看看,如果我们给出年会发生什么情况。
url_for(:year => "2004")
#=> http://pragprog.com/blog/2004
太灵巧了。映射代码设想URL 被表示成一个值的层次。[在web 上这很正常,静态的内容
被存储在文件夹(目录)内,它们本身也可以是文件夹,等等。]一旦我们在这个层次的一个级
别上修改一些东西的缺省值,它会停止给较低级别提供缺省值。最合理的解释是:低层的参
数事实上只能在高层中使用,所以修改的缺省值在低层中无效。在这个例子中通过覆写年,
我们含蓄地告诉映射代码,我们不需要月和天。
也要注意映射代码会为提交的URL 尽可能地选择第一条规则。让我们看看,如果我们给
它不能由第一条规则—基于日期的规则,匹配的值,会发生什么事情。
url_for(:action => "edit", :id => 123)
#=> http://pragprog.com/blog/blog/edit/123
这儿,第一个blog 是固定文本,第二个blog 是“控制器”的名字,edit 是“动作”名
字—映射代码应用第三个规则。如果我们指定“动作”为show,则映射代码使用第二个规则。
url_for(:action => "show", :id => 123)
#=> http://pragprog.com/blog/show/123
大多数时候映射代码会完成你想要的工作。但是,它有时候也太聪明了。如果你想生成
2005 年的URL。你可以写
url_for(:year => "2005")
当你看到映射代码解释的URL 也包含月和天时,你会大吃一惊。
#=> http://pragprog.com/blog/2005/4/15
你提供的年的值也同样被用在当前请求中。因为这个参数没有被修改,映射为URL 的余
下部分使用了月和天的缺省值。要避免这样,可设置月的参数为nil。
url_for(:year => "2005", :month => nil)
#=> http://pragprog.com/blog/2005
通常,如果你想生成一个特定的URL,最好的办法是设置未被使用的第一个参数为nil;
这样做可避免使用URL 留下的参数。
有时候你希望做相反的事情,修改层次中高层参数的值,并强迫“路由器”代码继续使
用低层中的值。在我们例子中,这就像是在URL 指定了一个不同的年,并在它的后面添加现
有的月和日的缺省值。要做到这点,我们可以欺骗“路由器”代码—我们使
用:overwrite_params 选项来告诉它,原有请求的参数包含我们想使用的新的年。因为它认
为年没有被修改,它继续使用余下的缺省值。
url_for(:year => "2002")
#=> http://pragprog.com/blog/2002
url_for(:overwrite_params => {:year => "2002"})
#=> http://pragprog.com/blog/2002/4/15
一个映射有个必须条件,如
map.connect "blog/:year/:month/:day",
:controller => "blog",
:action => "show_date",
:requirements => { :year => /(19|20)dd/,
:month => /[01]d/,
:day => /[0-3]d/},
注意:day 参数必须匹配/[0-3]d/;它必须有两个数字长。这意味着当创建一个URL 时,
如果你传递的Fixnum 值小于10,这个规则将不会起作用。
url_for(:year => 2005, :month => 12, :day => 8)
因为数字8 被转换为字符串”8”,而那个字符没两个数字长,映射就不会被激活。可以
是对relax 规则(在请求中使用[0-3]?d 来要求前导的零)进行修改,或者是确保你传递两个数字。
url_for(:year=>year,
:month=>sprintf("%02d", month),
:day=>sprintf("%02d", day))


在182 页我们说过,“控制器”应该被分组到模块中,并且引入的URL 使用类似路径的
约定来确定这些“控制器”。http://my.app/admin/book/edit/123 的URL 将调用Admin 模块内Book“控制器”的edit“动作”。
这个映射也影响URL 的生成。
1、如果你没有指定一个:controller 参数给url_for(),它使用当前的“控制器”。
2、如果你传递一个以a/开头的“控制器”的名字,那么那个名字是绝对的。
3、所有其它的“控制器”名字则相对于请求的“控制器”的模块。
要说明这一点,让我们假设有个请求是
http://my.app/admin/book/edit/123
url_for(:action => "edit", :id => 123)
#=> http://my.app/admin/book/edit/123
url_for(:controller => "catalog", :action => "show", :id => 123)
#=> http://my.app/admin/catalog/show/123
url_for(:controller => "/store", :action => "purchase", :id => 123)
#=> http://my.app/store/purchase/123
url_for(:controller => "/archive/book", :action => "record", :id =>
123)
#=> http://my.app/archive/book/record/12
(如果在controller控制器内容的前面加上'/'号,则对应部分的内容会以绝对路径的形式显示在url地址中

Rails 用它自己的方式为怎么让URL 有个好名字而提供了足够的灵活性。事实上,它支
持的足够深,以至于你可以混合你的“模型”类。“模型”与“视图”之间的这种交互似乎
违背了MVC,但对我们却很有好处。
让我们假设你希望你的URL 看起来这样:/clients/pragprog/agilweb,以便你使用
/clients/:client/:project 做为“路由器”。你可以这样生成URL。
url_for :controller => "clients",
:client => @company.short_name,
:project => @project.code_name
这很好,但是它意味着我们要给一个公司生成一个URL 组件,我们需要记住调用
short_name(),并且每次我们都包括一个project 在URL 中,我们必须调用code_name()。
如果一个对象实现了方法to_param(),则方法的返回值将在向URL 提供值是被使用(不
是to_s())。通过在Company 和Project 两者中实现适当的to_param()方法,我们可以对连
接的生成简化为
url_for :controller => "clients",
:client => @company,
:project => @project
Doesn’t that just make you feel all warm and fuzzy?
----------------------------------------------------------
现在我们已经看到映射是如何被用于生成URL 的,我们可以全面地查看url_for()方法。
url_for 创建引用这个应用程序的一个URL。
url_for(option => value, ...)
在这个应用程序中创建个引用了一个“控制器”的URL。哈希表选项支持参数的名字和
它们用于填充URL(基于一个映射)的值。参数值必须匹配任何由使用的映射强加的约束。在
选项列表内的某些参数的名字:余下部分,被保留并且用于填充URL 的非路径部分。如果你
使用一个“活动记录”的“模型”对象做为url_for()(或者是任何相关的方法)内的一个参
数,则那个对象的数据库id 将会被使用。下面代码片断内的两个重定向调用有同样的效果。
user = User.find_by_name("dave thomas")
redirect_to(:action => 'delete', :id => user.id)
# can be written as
redirect_to(:action => 'delete', :id => user)
url_for( ) 也接受单个字符串或符号做为一个参数。这一般在Rails 内部使用。
在下面表内通过在你的“控制器”内实现方法default_url_options(),你就可以覆写用于参数
缺省值。这应该返回一个参数的哈希表,此表被传递给url_for()。
选项:
1、:anchor 字符串,附加给URL 的一个锚点名字。Rails 自动预定为#character。
2、:host 字符串,设置URL 内主机的名字和端口。使用字符串如store.pragprog.com 或
者helper.pragprog.com:8080,缺省是传给主机。
3、:only_path boolean ,只生成URL 的路径部分;协议,主机名字,和端口被忽略。
4、:protocol 字符串, 设置URL 的协议部分。使用一个字符串如”https://”。缺省
使用引入请求的协议。
5、:trailing_slash boolean ,给被生成的URL 附加一个反斜线。[如果你也使用页或
动作缓存的话,对:trailing_slash 应小心使用。额外的反斜线会弄乱缓存算法。]
/*!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
make[4]: Entering directory '/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd' make "make -C modules/tdpd MODULE_NAME=tdpd" make[5]: Entering directory '/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules/tdpd' mips-linux-gnu-gcc -Os -pipe -march=mips32r2 -g -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -DTAPO_USR_DEF_AUDIO_ALARM -DCONFIG_STATISTIC_REPORT_DOMAIN=n-da.tplinkcloud.com.cn -DTELEMETRY_SUPPORT -DPTZ_SUPPORT=gpio -DUPNPC_ENABLE -DOPTIONAL_ALARM_AUDIO -DMSG_PUSH_TO_ALEXA -DFACTORY_INFO_INTEGRITY_RESTORE_SUPPORT -DWLAN_MODULE_SUPPORT -DGZIP_SUPPORT -DBASE64_SUPPORT -DTELEMETRY_SUPPORT -DLOCAL_PROTOCOL_SECURE -DCLIENTS_CONN_MAX=4 -DHUB_MANAGE_SUPPORT -DCONFIG_MSG_PUSH_POST_URL=/api/v1 -DSENSITIVITY_INT -DMAKEROOM_BEFORE_UPGRADE -DAUDIO_ENABLE -DCONFIG_MOBILE_ACCESS_SET_SUPPORT -DCONFIG_SD_UPGRADE_FROM_MMCBLK0 -DSYSUPGRADE_CHECK_RSA -DCONFIG_TP_TAPO_SPMINIOS -DCONFIG_TP_TAPO_MAP_ROOTFS -DCDN_HTTPS_UPGRADE_SUPPORT -DAMAZON_FFS_SUPPORT -DTAPO_CARE_CDN_SUPPORT -DTP_TAPO -DCLOUD_IOT_SUPPORT -DCLOUD_IOT_SOUNDALARM_SUPPORT -DBIND_CODE_SUPPORT -DTP_TAPO_P2P_SHARE -DT43_CONFIG_CHECK_WHETHER_IS_CAL -DLENS_MASK_SUPPORT -DMULTI_MODEL -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/include -I/home/wyl/NVMP/nvmp/../sdk/soc/t31x/uclibc-toolchain-0.9.33/mips-gcc472-glibc216-64bit/mips-linux-gnu/libc/uclibc/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -Wall -Werror -ffunction-sections -fdata-sections -DMODULE_LIST="\"tdpd tdpc tmpd mactool wirelesstool nifc dhcpc dhcps httpd sntpc onvif system miniupnpc upgrade telemetry cloud_iot remote_debugger hub_manage ffs\"" -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/include -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common/ds -I./libXml -I./libutils -I../../include -I../../common/tdp_common -c -o tdpd.o tdpd.c mips-linux-gnu-gcc -Os -pipe -march=mips32r2 -g -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -DTAPO_USR_DEF_AUDIO_ALARM -DCONFIG_STATISTIC_REPORT_DOMAIN=n-da.tplinkcloud.com.cn -DTELEMETRY_SUPPORT -DPTZ_SUPPORT=gpio -DUPNPC_ENABLE -DOPTIONAL_ALARM_AUDIO -DMSG_PUSH_TO_ALEXA -DFACTORY_INFO_INTEGRITY_RESTORE_SUPPORT -DWLAN_MODULE_SUPPORT -DGZIP_SUPPORT -DBASE64_SUPPORT -DTELEMETRY_SUPPORT -DLOCAL_PROTOCOL_SECURE -DCLIENTS_CONN_MAX=4 -DHUB_MANAGE_SUPPORT -DCONFIG_MSG_PUSH_POST_URL=/api/v1 -DSENSITIVITY_INT -DMAKEROOM_BEFORE_UPGRADE -DAUDIO_ENABLE -DCONFIG_MOBILE_ACCESS_SET_SUPPORT -DCONFIG_SD_UPGRADE_FROM_MMCBLK0 -DSYSUPGRADE_CHECK_RSA -DCONFIG_TP_TAPO_SPMINIOS -DCONFIG_TP_TAPO_MAP_ROOTFS -DCDN_HTTPS_UPGRADE_SUPPORT -DAMAZON_FFS_SUPPORT -DTAPO_CARE_CDN_SUPPORT -DTP_TAPO -DCLOUD_IOT_SUPPORT -DCLOUD_IOT_SOUNDALARM_SUPPORT -DBIND_CODE_SUPPORT -DTP_TAPO_P2P_SHARE -DT43_CONFIG_CHECK_WHETHER_IS_CAL -DLENS_MASK_SUPPORT -DMULTI_MODEL -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/include -I/home/wyl/NVMP/nvmp/../sdk/soc/t31x/uclibc-toolchain-0.9.33/mips-gcc472-glibc216-64bit/mips-linux-gnu/libc/uclibc/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -Wall -Werror -ffunction-sections -fdata-sections -DMODULE_LIST="\"tdpd tdpc tmpd mactool wirelesstool nifc dhcpc dhcps httpd sntpc onvif system miniupnpc upgrade telemetry cloud_iot remote_debugger hub_manage ffs\"" -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/include -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common/ds -I./libXml -I./libutils -I../../include -I../../common/tdp_common -c -o tp_tlv.o tp_tlv.c mips-linux-gnu-ar crus -o tdpd.a tdpd.o tp_tlv.o cp -f tdpd.a ../../libraries/ cp -f *.h /home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include make[5]: Leaving directory '/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules/tdpd' make "make -C modules/tdpc MODULE_NAME=tdpc" make[5]: Entering directory '/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules/tdpc' mips-linux-gnu-gcc -Os -pipe -march=mips32r2 -g -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -DTAPO_USR_DEF_AUDIO_ALARM -DCONFIG_STATISTIC_REPORT_DOMAIN=n-da.tplinkcloud.com.cn -DTELEMETRY_SUPPORT -DPTZ_SUPPORT=gpio -DUPNPC_ENABLE -DOPTIONAL_ALARM_AUDIO -DMSG_PUSH_TO_ALEXA -DFACTORY_INFO_INTEGRITY_RESTORE_SUPPORT -DWLAN_MODULE_SUPPORT -DGZIP_SUPPORT -DBASE64_SUPPORT -DTELEMETRY_SUPPORT -DLOCAL_PROTOCOL_SECURE -DCLIENTS_CONN_MAX=4 -DHUB_MANAGE_SUPPORT -DCONFIG_MSG_PUSH_POST_URL=/api/v1 -DSENSITIVITY_INT -DMAKEROOM_BEFORE_UPGRADE -DAUDIO_ENABLE -DCONFIG_MOBILE_ACCESS_SET_SUPPORT -DCONFIG_SD_UPGRADE_FROM_MMCBLK0 -DSYSUPGRADE_CHECK_RSA -DCONFIG_TP_TAPO_SPMINIOS -DCONFIG_TP_TAPO_MAP_ROOTFS -DCDN_HTTPS_UPGRADE_SUPPORT -DAMAZON_FFS_SUPPORT -DTAPO_CARE_CDN_SUPPORT -DTP_TAPO -DCLOUD_IOT_SUPPORT -DCLOUD_IOT_SOUNDALARM_SUPPORT -DBIND_CODE_SUPPORT -DTP_TAPO_P2P_SHARE -DT43_CONFIG_CHECK_WHETHER_IS_CAL -DLENS_MASK_SUPPORT -DMULTI_MODEL -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/include -I/home/wyl/NVMP/nvmp/../sdk/soc/t31x/uclibc-toolchain-0.9.33/mips-gcc472-glibc216-64bit/mips-linux-gnu/libc/uclibc/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -Wall -Werror -ffunction-sections -fdata-sections -DMODULE_LIST="\"tdpd tdpc tmpd mactool wirelesstool nifc dhcpc dhcps httpd sntpc onvif system miniupnpc upgrade telemetry cloud_iot remote_debugger hub_manage ffs\"" -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/include -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common/ds -I./libXml -I./libutils -I../../include -I../../common/tdp_common -c -o tdp_client.o tdp_client.c mips-linux-gnu-gcc -Os -pipe -march=mips32r2 -g -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -DTAPO_USR_DEF_AUDIO_ALARM -DCONFIG_STATISTIC_REPORT_DOMAIN=n-da.tplinkcloud.com.cn -DTELEMETRY_SUPPORT -DPTZ_SUPPORT=gpio -DUPNPC_ENABLE -DOPTIONAL_ALARM_AUDIO -DMSG_PUSH_TO_ALEXA -DFACTORY_INFO_INTEGRITY_RESTORE_SUPPORT -DWLAN_MODULE_SUPPORT -DGZIP_SUPPORT -DBASE64_SUPPORT -DTELEMETRY_SUPPORT -DLOCAL_PROTOCOL_SECURE -DCLIENTS_CONN_MAX=4 -DHUB_MANAGE_SUPPORT -DCONFIG_MSG_PUSH_POST_URL=/api/v1 -DSENSITIVITY_INT -DMAKEROOM_BEFORE_UPGRADE -DAUDIO_ENABLE -DCONFIG_MOBILE_ACCESS_SET_SUPPORT -DCONFIG_SD_UPGRADE_FROM_MMCBLK0 -DSYSUPGRADE_CHECK_RSA -DCONFIG_TP_TAPO_SPMINIOS -DCONFIG_TP_TAPO_MAP_ROOTFS -DCDN_HTTPS_UPGRADE_SUPPORT -DAMAZON_FFS_SUPPORT -DTAPO_CARE_CDN_SUPPORT -DTP_TAPO -DCLOUD_IOT_SUPPORT -DCLOUD_IOT_SOUNDALARM_SUPPORT -DBIND_CODE_SUPPORT -DTP_TAPO_P2P_SHARE -DT43_CONFIG_CHECK_WHETHER_IS_CAL -DLENS_MASK_SUPPORT -DMULTI_MODEL -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/include -I/home/wyl/NVMP/nvmp/../sdk/soc/t31x/uclibc-toolchain-0.9.33/mips-gcc472-glibc216-64bit/mips-linux-gnu/libc/uclibc/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -Wall -Werror -ffunction-sections -fdata-sections -DMODULE_LIST="\"tdpd tdpc tmpd mactool wirelesstool nifc dhcpc dhcps httpd sntpc onvif system miniupnpc upgrade telemetry cloud_iot remote_debugger hub_manage ffs\"" -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/include -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common/ds -I./libXml -I./libutils -I../../include -I../../common/tdp_common -c -o tdp_cmd.o tdp_cmd.c mips-linux-gnu-ar crus -o tdpc.a tdp_client.o tdp_cmd.o cp -f tdpc.a ../../libraries/ cp -f *.h /home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include make[5]: Leaving directory '/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules/tdpc' make "make -C modules/tmpd MODULE_NAME=tmpd" make[5]: Entering directory '/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules/tmpd' mips-linux-gnu-gcc -Os -pipe -march=mips32r2 -g -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -DTAPO_USR_DEF_AUDIO_ALARM -DCONFIG_STATISTIC_REPORT_DOMAIN=n-da.tplinkcloud.com.cn -DTELEMETRY_SUPPORT -DPTZ_SUPPORT=gpio -DUPNPC_ENABLE -DOPTIONAL_ALARM_AUDIO -DMSG_PUSH_TO_ALEXA -DFACTORY_INFO_INTEGRITY_RESTORE_SUPPORT -DWLAN_MODULE_SUPPORT -DGZIP_SUPPORT -DBASE64_SUPPORT -DTELEMETRY_SUPPORT -DLOCAL_PROTOCOL_SECURE -DCLIENTS_CONN_MAX=4 -DHUB_MANAGE_SUPPORT -DCONFIG_MSG_PUSH_POST_URL=/api/v1 -DSENSITIVITY_INT -DMAKEROOM_BEFORE_UPGRADE -DAUDIO_ENABLE -DCONFIG_MOBILE_ACCESS_SET_SUPPORT -DCONFIG_SD_UPGRADE_FROM_MMCBLK0 -DSYSUPGRADE_CHECK_RSA -DCONFIG_TP_TAPO_SPMINIOS -DCONFIG_TP_TAPO_MAP_ROOTFS -DCDN_HTTPS_UPGRADE_SUPPORT -DAMAZON_FFS_SUPPORT -DTAPO_CARE_CDN_SUPPORT -DTP_TAPO -DCLOUD_IOT_SUPPORT -DCLOUD_IOT_SOUNDALARM_SUPPORT -DBIND_CODE_SUPPORT -DTP_TAPO_P2P_SHARE -DT43_CONFIG_CHECK_WHETHER_IS_CAL -DLENS_MASK_SUPPORT -DMULTI_MODEL -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/include -I/home/wyl/NVMP/nvmp/../sdk/soc/t31x/uclibc-toolchain-0.9.33/mips-gcc472-glibc216-64bit/mips-linux-gnu/libc/uclibc/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -Wall -Werror -ffunction-sections -fdata-sections -DMODULE_LIST="\"tdpd tdpc tmpd mactool wirelesstool nifc dhcpc dhcps httpd sntpc onvif system miniupnpc upgrade telemetry cloud_iot remote_debugger hub_manage ffs\"" -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/include -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common/ds -I./libXml -I./libutils -I../../include -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules/tmpd/script -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules/tmpd -c -o tmpd_utils.o tmpd_utils.c mips-linux-gnu-gcc -Os -pipe -march=mips32r2 -g -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -DTAPO_USR_DEF_AUDIO_ALARM -DCONFIG_STATISTIC_REPORT_DOMAIN=n-da.tplinkcloud.com.cn -DTELEMETRY_SUPPORT -DPTZ_SUPPORT=gpio -DUPNPC_ENABLE -DOPTIONAL_ALARM_AUDIO -DMSG_PUSH_TO_ALEXA -DFACTORY_INFO_INTEGRITY_RESTORE_SUPPORT -DWLAN_MODULE_SUPPORT -DGZIP_SUPPORT -DBASE64_SUPPORT -DTELEMETRY_SUPPORT -DLOCAL_PROTOCOL_SECURE -DCLIENTS_CONN_MAX=4 -DHUB_MANAGE_SUPPORT -DCONFIG_MSG_PUSH_POST_URL=/api/v1 -DSENSITIVITY_INT -DMAKEROOM_BEFORE_UPGRADE -DAUDIO_ENABLE -DCONFIG_MOBILE_ACCESS_SET_SUPPORT -DCONFIG_SD_UPGRADE_FROM_MMCBLK0 -DSYSUPGRADE_CHECK_RSA -DCONFIG_TP_TAPO_SPMINIOS -DCONFIG_TP_TAPO_MAP_ROOTFS -DCDN_HTTPS_UPGRADE_SUPPORT -DAMAZON_FFS_SUPPORT -DTAPO_CARE_CDN_SUPPORT -DTP_TAPO -DCLOUD_IOT_SUPPORT -DCLOUD_IOT_SOUNDALARM_SUPPORT -DBIND_CODE_SUPPORT -DTP_TAPO_P2P_SHARE -DT43_CONFIG_CHECK_WHETHER_IS_CAL -DLENS_MASK_SUPPORT -DMULTI_MODEL -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/include -I/home/wyl/NVMP/nvmp/../sdk/soc/t31x/uclibc-toolchain-0.9.33/mips-gcc472-glibc216-64bit/mips-linux-gnu/libc/uclibc/usr/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libiconv-full/include -I/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/lib/libintl-full/include -Wall -Werror -ffunction-sections -fdata-sections -DMODULE_LIST="\"tdpd tdpc tmpd mactool wirelesstool nifc dhcpc dhcps httpd sntpc onvif system miniupnpc upgrade telemetry cloud_iot remote_debugger hub_manage ffs\"" -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/include -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/common/ds -I./libXml -I./libutils -I../../include -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules/tmpd/script -I/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules/tmpd -c -o tmpd.o tmpd.c tmpd.c: In function 'tmpd_handle': tmpd.c:673:2: error: too few arguments to function 'tpssl_svr_init' In file included from tmpd.h:3:0, from tmpd.c:21: /home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include/sslApi.h:557:7: note: declared here <builtin>: recipe for target 'tmpd.o' failed make[5]: *** [tmpd.o] Error 1 make[5]: Leaving directory '/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/modules/tmpd' Makefile:30: recipe for target 'build_modules' failed make[4]: *** [build_modules] Error 2 make[4]: Leaving directory '/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd' Makefile:574: recipe for target '/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/.built' failed make[3]: *** [/home/wyl/NVMP/nvmp/build_dir/target-mips-openwrt-linux-uclibc-c510wv1/nsd/.built] Error 2 make[3]: Leaving directory '/home/wyl/NVMP/nvmp/tp_package/nsd' package/Makefile:105: recipe for target 'package/tp_package/nsd/compile' failed make[2]: *** [package/tp_package/nsd/compile] Error 2 make[2]: Leaving directory '/home/wyl/NVMP/nvmp' package/Makefile:101: recipe for target '/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/stamp/.package_compile' failed make[1]: *** [/home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/stamp/.package_compile] Error 2 make[1]: Leaving directory '/home/wyl/NVMP/nvmp' /home/wyl/NVMP/nvmp/include/toplevel.mk:277: recipe for target 'world' failed make: *** [world] Error 2
09-20
你这次遇到的错误是: ``` tmpd.c:673:2: error: too few arguments to function 'tpssl_svr_init' In file included from tmpd.h:3:0, from tmpd.c:21: /home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include/sslApi.h:557:7: note: declared here ``` --- ### ✅ 回答问题 #### 🔴 错误原因:函数调用参数不匹配 —— **`tpssl_svr_init()` 被声明为需要多个参数,但代码中只传了部分或没有传** 这说明: - 你在 `tmpd.c` 中调用了 `tpssl_svr_init(...)`; - 但这个函数在头文件 `sslApi.h` 中的原型已经变了(比如从无参变成了多参); - 而你的代码仍然按旧方式调用 → 编译失败。 --- ### 🧩 深入分析 #### 查看报错位置 ```c // tmpd.c:673 tpssl_svr_init(); // ❌ 只传了0个或1个参数 ``` 而头文件里定义的是: ```c // sslApi.h:557 int tpssl_svr_init(int port, const char *cert_path, const char *key_path, void *ctx); ``` 👉 明显:**你现在调用的方式参数太少!** --- ### ✅ 解决方法(C语言修复) 你需要根据新的 API 正确初始化 SSL 服务端。以下是修复后的示例代码: --- #### ✅ 修复后的 C 代码示例 ```c #include "sslApi.h" #include <stdio.h> #include <string.h> // 假设这些路径是你设备上证书存放的位置 #define SSL_CERT_PATH "/etc/certs/server.crt" #define SSL_KEY_PATH "/etc/certs/server.key" int tmpd_ssl_init(void) { int ret; // 检查证书是否存在(可选) if (access(SSL_CERT_PATH, R_OK) != 0 || access(SSL_KEY_PATH, R_OK) != 0) { printf("SSL: Certificate or key not found!\n"); return -1; } // 调用新版本 tpssl_svr_init,传入完整参数 ret = tpssl_svr_init( 8883, // port: MQTT over SSL 默认端口 SSL_CERT_PATH, // cert_path SSL_KEY_PATH, // key_path NULL // ctx: 可为空,由内部管理 ); if (ret != 0) { printf("SSL: Failed to init server, ret=%d\n", ret); return -1; } printf("SSL: Server initialized on port 8883\n"); return 0; } ``` 然后在 `tmpd_handle()` 函数中调用它: ```c // tmpd.c:673 附近 if (tmpd_ssl_init() != 0) { return -1; } ``` --- ### ✅ 关键解释 | 问题 | 原因 | 解法 | |------|------|--------| | `too few arguments to function 'tpssl_svr_init'` | SDK 升级后接口变更,旧代码未同步更新 | 补全所有必需参数 | | 头文件来自 `staging_dir` | 安装的是新版 SDK 的头文件 → 接口已变 | 必须适配新签名 | | 编译选项 `-Werror` | 所有警告视为错误 → 直接中断构建 | 必须完全修复调用 | --- ### ❓为什么会出现这种“接口变了”的情况? > ✅ **根本原因极大概率就是你之前怀疑的:分支切错了!** #### 场景还原: | 组件 | 来源分支 | 是否一致? | |------|----------|-----------| | `nsd/tmpd.c` | `feature/new-ssl-api` 分支 | 新代码,但调用方式未改 | | `sslApi.h` | `release/v2.1` 分支安装到 staging_dir | 已要求更多参数 | | 构建系统 | 使用混合产物 | ❌ 不兼容! | 👉 结果:**`.c` 文件以为还能用老接口,但头文件强制要求新参数 → 编译失败** --- ### ✅ 如何确认并解决? #### ✅ 第一步:检查当前 Git 分支一致性 ```bash cd /home/wyl/NVMP/nvmp git branch git status ``` 确保整个项目(包括子模块)都在同一个稳定分支上,例如: ```bash git checkout release/t31x-camera-sdk-v2.1 git submodule update --init --recursive ``` --- #### ✅ 第二步:查看 `tpssl_svr_init` 的真实原型 ```bash grep -n "tpssl_svr_init" /home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include/sslApi.h ``` 输出可能类似: ```c 557: int tpssl_svr_init(int port, const char *cert_path, const char *key_path, void *ctx); ``` 📌 这说明你必须提供 4 个参数! --- #### ✅ 第三步:清理旧构建缓存 防止 staging_dir 中残留旧头文件污染: ```bash # 清理 nsd 模块 make package/tp_package/nsd/clean # 或者手动删除 staging_dir 中相关头文件 rm -f /home/wyl/NVMP/nvmp/staging_dir/target-mips-openwrt-linux-uclibc-c510wv1/usr/include/sslApi.h ``` 然后重新编译时让正确的头文件被安装进来。 --- #### ✅ 第四步:修改 `tmpd.c` 调用方式 找到出错行(`tmpd.c:673`),将: ```c tpssl_svr_init(); ``` 改为: ```c int ssl_ret = tpssl_svr_init(8883, "/etc/certs/server.crt", "/etc/certs/server.key", NULL); if (ssl_ret != 0) { printf("Failed to initialize SSL server: %d\n", ssl_ret); return -1; } ``` --- ### ✅ 额外建议:如何避免这类问题? | 方法 | 说明 | |------|------| | `git diff HEAD^ HEAD sslApi.h` | 查看最近一次提交是否修改了关键接口 | | `nm libssl.a \| grep tpssl_svr_init` | 查看符号是否存在 | | 在 Makefile 中加入版本校验宏 | 如 `#error If this fails, you're using wrong SDK version` | | 使用统一的 SDK 版本管理脚本 | 自动检测分支和依赖 | --- ### ✅ 总结 | 现象 | 根本原因 | 解决方案 | |------|----------|-----------| | `too few arguments to function 'tpssl_svr_init'` | SDK 接口升级,旧代码未适配 | 更新调用参数 | | 头文件与源码不匹配 | 分支混乱或 staging_dir 污染 | 切对分支 + 清理缓存 | | 构建失败于 `-Werror` | C 编译器严格检查 | 必须完全符合函数签名 | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值