上節介紹了存儲管理配置信息的結構體struct server_config_t,該結構體貫穿整個server端程序的運行。數組
在dhcpd.c裏的用該結構體定義個一個全局的變量:網絡
struct server_config_t server_config;函數
在server啓動作的第一件事就是初始化這個全局變量server_config:學習
如今就進入read_config函數,一睹其真容!ui
學習這個函數,在之後遇到要讀取配置信息能夠參照read_config函數的寫法。指針
read_config函數的定義是在file.c文件裏。server
分析read_config函數以前先來看一個結構體數組:對象
結構體的定義:token
該結構體數組的定義以及初始化:ip
結構體名和數組名能夠看出,config_keyword,配置信息關鍵字,正如其名,是輔助讀取配置信息的。
數組裏的每一個config_keyword結構體元素中的keyword成員的值,與server_config_t裏的成員變量名一一對應,該成員指示的就是配置的是server_config_t裏的哪一個成員。
讀取配置信息的操做,配置信息讀取存儲到哪裏,以及配置信息的默認值,這些由config_keywork裏的後面的3個成員給出的。
成員heandler是一個函數指針,指向的函數即提供了怎麼讀取配置信息,以及把配置信息寫到指定地址內。
arg, def則做爲handler指向函數的兩個各參數,arg告訴函數把配置信息存儲到的地址,def則是配置信息的值,def是配置信息的默認值。
keyword數組裏每一個元素裏的函數指針handler指向的這些函數,其定義都在file.c文件裏。
handler函數的類型 : int (const *handler)(const char *line, void *arg)
1) read_ip: 把字符串格式的IP地址轉換成uint32_t的IP格式,並存儲到arg所指的內存。
2) read_u32: 把字符串格式的數轉換成uint32_t類型數字,並存儲到arg所指的內存。
3) read_yn: line字符串是「yes」 仍是 「no」?若「yes」,將arg所指的內存賦1,反之,賦0
4) read_str:首先free(*arg)釋放掉*arg指的內存,再根據字符串line的大小分配內存,並把line裏的值複製到裏面,讓*arg指向新分配的內存。
5) read_opt: 從字符串line裏讀取options寫到*arg所指的struct option_set鏈表裏。(鏈表的每一個結點data以CLV方式組織數據)。
read_opt對選項的信息的讀取藉助裏也藉助結構數組(在options.c裏定義的),因此函數比較複雜,這裏只用知道函數做用。
6) read_staticlease:從line字符串裏讀取MAC、IP地址字符串裏MAC與IP用’/t’or’=’做爲分隔)再把MAC和IP添加到*arg所指的static_lease鏈表裏。static_lease鏈表是dhcp Server管理已租賃出去的IP和得到該IP的客戶機的MAC綁定。
7) read_mac: 從字符串格式MAC地址裏讀出MAC並轉化的MAC存儲arg所指的內存裏
上面的read_xxx函數,read成功返回1, 失敗返回0。
上面講解的這麼的多都是read_config函數的基礎,好啦,如今正式進入read_config函數:
若read_config函數到這就結束了,server依靠這些默認配置的值也能夠工做(options字段沒有默認值,不能給client其餘的網絡配置,但能夠給client端分配IP的),但這樣的話,程序就缺少靈活性,IP地址池不能修改,租賃時間沒法設定等。
上面這段就是從文件裏讀取配置信息,下面是摘自udhcp.conf文件的部分配置信息:
while(fgets(buffer, READ_CONFIG_BUF_SIZE, in))
每次從文件裏讀取一行,存放在buffer裏,在對buffer處理,空行、註釋行(還有隻有token, 沒有line的)直接跳過繼續讀取下一行。
token = strtok(buffer, 「 /t」); 取到該行的keyword (文件裏key與value之間使用空格或’/t’)
line = strtok(NULL, 「」); 取到該行的配置信息值
這樣(還需簡單處理下)就能夠根據keywords數組把從文件讀取到的配置信息寫到server_config相應的成員裏。
差很少了,總結下read_config函數,她對配置的對象全局變量server_conifg,經過一個輔助結構數組來對server_config裏的成員變量進行賦值的。真正對於成員的賦值操做都是經過數組裏元素的函數指針handler指向的函數進行的。
read_config只是作了從文件的每行讀出信息,並做些處理,獲得token和line,利用token在數組裏找到對應的handler和arg,………