Addons API - XIYO/asuswrt-merlin.ng-kr GitHub Wiki
384.15 λ²μ λΆν° Asuswrt-Merlinμ μ 3μ μ λμ¨μ μΉ ν΅ν©μ μ§μν©λλ€. κΈ°μ‘΄μ webui μΉμ μ μ νμΌλ‘ μ΅λ μ΄ κ°μ μ¬μ©μ μ μ νμ΄μ§λ₯Ό μΆκ°ν μ μμ΅λλ€.
λν nvramκ³Ό λ³λλ‘ μ λμ¨μ μν μ μ© μ€μ μ μ₯μκ° μμΌλ©°, λ°λΌμ κ·Έ μ νμ ꡬμλ°μ§ μμ΅λλ€(i.e. νμ¨μ΄ μ΄λ―Έμ§λ₯Ό λ€μ μ»΄νμΌνμ§ μκ³ λ μ μ€μ μ λ§λ€ μ μμ΅λλ€).
μ§μμ rc_support nvram κ°μ am_addons νλκ·Έμ μ‘΄μ¬λ‘ κ°μ§ν μ μμ΅λλ€.
/jffs/addons/ λλ ν λ¦¬κ° νμ€ μμΉμ λλ€. μ¬κΈ°μ λͺ¨λ νμΌμ μ μ₯ν λλ ν 리λ₯Ό μμ±ν΄μΌ ν©λλ€. μ΄ λλ ν 리μ 루νΈμ νμΌμ μΆκ°νμ§ λ§μμμ€.
λͺ¨λ μ λμ¨μ λν μ¬μ©μ μ μ μ€μ μ /jffs/addons/custom_settings.txtμ μ μ₯λ©λλ€.
νμ¨μ΄λ μ΅λ 20κ°μ μ¬μ©μ μ μ νμ΄μ§λ₯Ό μ§μν©λλ€(386.1 μ΄μ μλ 10κ°μμ΅λλ€). μ΄λ¬ν νμ΄μ§λ λΆν μμ μ€ν¬λ¦½νΈλ₯Ό ν΅ν΄ λ§μ΄νΈν΄μΌ νλ©°, μ΄λ ideally services-startμμ νΈμΆν΄μΌ ν©λλ€. μ¬μ©μ μ μ νμ΄μ§λ₯Ό /jffs/addons/my_addon/ ν΄λμ μ€μΉ μ€ν¬λ¦½νΈμ ν¨κ» λμ΄μΌ ν©λλ€. λ€μμ Tools μΉμ μ μ νμΌλ‘ νμ΄μ§λ₯Ό μ½μ ν μ€μΉ μ€ν¬λ¦½νΈμ μμ λλ€.
#!/bin/sh
source /usr/sbin/helper.sh
# Does the firmware support addons?
nvram get rc_support | grep -q am_addons
if [ $? != 0 ]
then
logger "MyPage" "This firmware does not support addons!"
exit 5
fi
# Obtain the first available mount point in $am_webui_page
am_get_webui_page /jffs/addons/my_addon/MyPage.asp
if [ "$am_webui_page" = "none" ]
then
logger "MyPage" "Unable to install Mypage"
exit 5
fi
logger "MyPage" "Mounting MyPage as $am_webui_page"
# Copy custom page
cp /jffs/addons/my_addon/MyPage.asp /www/user/$am_webui_page
# Copy menuTree (if no other script has done it yet) so we can modify it
if [ ! -f /tmp/menuTree.js ]
then
cp /www/require/modules/menuTree.js /tmp/
mount -o bind /tmp/menuTree.js /www/require/modules/menuTree.js
fi
# Insert link at the end of the Tools menu. Match partial string, since tabname can change between builds (if using an AS tag)
sed -i "/url: \"Tools_OtherSettings.asp\", tabName:/a {url: \"$am_webui_page\", tabName: \"My Page\"}," /tmp/menuTree.js
# sed and binding mounts don't work well together, so remount modified file
umount /www/require/modules/menuTree.js && mount -o bind /tmp/menuTree.js /www/require/modules/menuTree.js
μλ‘μ΄ nvram μ€μ μ νμ¨μ΄ μ¬λΉλ μμ΄ λμ μΌλ‘ μΆκ°ν μ μμΌλ©°, λν μ κ· Broadcom HND νλ«νΌμ ν¬κΈ° μ ν(μ λ³μλ μ΅λ 100λ°μ΄νΈμ κ°μ κ°μ§) λλ¬Έμ μ λμ¨μ μν μλ‘μ΄ μ€μ μ μ₯μκ° κ΅¬νλμμ΅λλ€. /jffs/addons/custom_settings.txt νμΌμλ λͺ¨λ μ 3μ μ€μ μ΄ ν¬ν¨λ©λλ€. κ° μ€μλ λ€μκ³Ό κ°μ΄ μ μλ νλμ μ€μ μ΄ ν¬ν¨λ©λλ€:
setting1 My First Setting
setting2 My Second Setting
λ³μ μ΄λ¦μ μμ«μ, λμ(-) λ° λ°μ€(_) λ¬Έμλ‘ μ νν΄μΌ ν©λλ€. μ΄λ¦μ μ΅λ κΈΈμ΄λ 29μμ λλ€.
λ³μ λ΄μ©μ μ΄λ‘ μ μΌλ‘ λͺ¨λ 7λΉνΈ ASCII μΈμ κ°λ₯ λ¬Έμλ₯Ό νμ©ν΄μΌ ν©λλ€. λ΄μ©μ ν¬κΈ° μ νμ 2999μμ λλ€. λ 볡μ‘ν κ°μ΄ νμν κ²½μ°(μ: μ€ λ°κΏμ΄ μλ λ¬Έμμ΄), base64 μΈμ½λ©μ μ¬μ©νκ±°λ λ°μ΄ν°λ₯Ό λ³λμ νμΌλ‘ μ΄λνλ κ²μ΄ μ’μ΅λλ€(λ무 ν¬κ±°λ 볡μ‘ν κ²½μ°). μΉ νμ΄μ§μμ μ½κΈ° μ‘μΈμ€κ° νμν κ²½μ° /www/user/ ν΄λμ μ΄λ¬ν νμΌμ μμ±ν μ μλ€λ μ μ μ μνμΈμ. μ΄ κ²½μ° κ³ μ ν μ΄λ¦μ μ¬μ©νκ±°λ(μ: κΈ°μ‘΄μ λ€μμ€νμ΄μ€λ₯Ό μ¬μ¬μ©) λ°μ΄ν°λ₯Ό νμ λλ ν 리μ μ μ₯νλλ‘ νμμμ€.
μ 체 μ μ₯μμ μ΅λ μ΄ ν¬κΈ°λ 8KBμ λλ€. μ΄λ¬ν ν¬κΈ° μ νμΌλ‘ μΈν΄, κ±°κΈ°μ λ§μ μμ λ°μ΄ν°λ₯Ό μ μ₯νμ§ μλλ‘ λ Έλ ₯νμμμ€ - νμν κ²½μ° λ³λμ νμΌμ μ¬μ©νμμμ€. λ 컀μ§λ©΄, μΉ μλ²μμ μ²λ¦¬ν λ μ€μ μ΄ μ릴 κ²μ λλ€.
λͺ¨λ μ λμ¨μ΄ λμΌν μ μ₯μλ₯Ό 곡μ νκ² λλ―λ‘, μ€μ μ μ½κ² μλ³ν μ μλλ‘ λ€μμ€νμ΄μ€λ₯Ό μ μν΄μΌ ν©λλ€. μ΄λ λ€μκ³Ό κ°μ΄ λ³΄μΌ κ²μ λλ€:
my_addon_version 3.0.2
my_addon_state enabled
diversion_version 2.0
diversion_whitelist /jffs/addons/diversion/my-whitelist.txt
μ μ€ν¬λ¦½νΈ μ‘°μμ μν΄, helper.shλ λ΄μ©μ κ²μνκ³ μ μ₯νλ ν¨μ μμ μ 곡ν©λλ€.
# set a value
am_settings_set addon_title Cool Addon 1.0
# retrieve it, in the $TITLE variable
TITLE=$(am_settings_get addon_tittle)
μΉ ν΅ν©μ μν΄ νμ΄μ§μ μμ λΆκ·Όμ λ€μμ μ½μ νμ¬ νμ΄μ§ λ΄μμ μ΄λ¬ν μ€μ μ μλ°μ€ν¬λ¦½νΈ κ°μ²΄λ‘ μ‘μΈμ€ν μ μμ΅λλ€:
var custom_settings = <% get_custom_settings(); %>;
HTML μΉμ μμ nvram μ€μ μ μ¬μ©νλ νλμ²λΌ μ λ ₯ νλλ₯Ό μ μν©λλ€:
<tr>
<th>Diversion path</th>
<td>
<input type="text" maxlength="100" class="input_25_table" id="diversion_whitelist" autocorrect="off" autocapitalize="off">
</td>
</tr>
λν μ€μ μ μ μ©ν λ μ€μ μ λ€μ μ μ‘νλ λ° μ¬μ©λλ μ¨κ²¨μ§ amng_custom μ λ ₯ νλλ₯Ό μ μν©λλ€:
<input type="hidden" name="amng_custom" id="amng_custom" value="">
κ·Έλ° λ€μ initial() ν¨μμμ κ°μ²΄μμ κ°μ κ²μνκ³ νλμ ν λΉν©λλ€:
if (custom_settings.diversion_whitelist == undefined)
document.getElementById('diversion_whitelist').value = "/jffs/addons/diversion/diversion-white.txt";
else
document.getElementById('diversion_whitelist').value = custom_settings.diversion_whitelist;
μ¬μ©μκ° μ μ© λ²νΌμ ν΄λ¦ν λ νΈμΆλλ apply() ν¨μμμ νλ κ°μ κ²μνκ³ , κ°μ²΄μ λ€μ μ μ₯νκ³ , κ°μ²΄λ₯Ό λ¬Έμμ΄λ‘ λ³ννκ³ μ¨κ²¨μ§ amng_custom νλμ ν λΉν λ€μ μμμ μ μΆν©λλ€:
function applySettings(){
/* Retrieve value from input fields, and store in object */
custom_settings.diversion_whitelist = document.getElementById('diversion_whitelist').value;
/* Store object as a string in the amng_custom hidden input field */
document.getElementById('amng_custom').value = JSON.stringify(custom_settings);
/* Apply */
showLoading();
document.form.submit();
}
μ΄λ¬ν μ€μ λ³κ²½μ λν μμ μ μννκΈ° μν΄ λΌμ°ν°μμ μΌλΆ μ€ν¬λ¦½νΈλ₯Ό μ€νν΄μΌ ν κ²μ λλ€. service-event μ€ν¬λ¦½νΈλ μ΄λ₯Ό μνν μ μλ μ₯μμ λλ€. λΌμ°ν°μμ μΈμνμ§ λͺ»νλ μ΄λ²€νΈμ λν΄μλ μ€νλλ―λ‘ μ체 μλΉμ€ νΈλ€λ¬λ₯Ό μ€κ³ν μ μμ΅λλ€.
νμ΄μ§μμ μλΉμ€λ₯Ό λ€μ μμνλλ‘ κ΅¬μ±ν©λλ€. μλ₯Ό λ€μ΄ "myservice"λΌκ³ νΈμΆν΄ λ΄ μλ€:
<input type="hidden" name="action_script" value="restart_myservice">
/jffs/addons/my_addon/myservice.sh μ€ν¬λ¦½νΈλ₯Ό λ§λ€κ³ μ΄μ κ°μ λ΄μ©μ ν¬ν¨μν΅λλ€:
#!/bin/sh
TYPE=$1
EVENT=$2
if [ "$EVENT" = "myservice" -a "$TYPE" = "restart" ]
then
logger -t "myservice" "Restarting my service..."
# do your stuff here, access /jffs/addons/custom_settings.txt, etc...
fi
κ·Έλ¦¬κ³ _/jffs/scripts/service-event_μμ μ€ν¬λ¦½νΈλ₯Ό νΈμΆν©λλ€:
#!/bin/sh
### MyService start
/jffs/addons/my_addon/myservice.sh $*
### MyService end
μ°Έκ³ : 볡μ‘ν μ€ν¬λ¦½νΈλ₯Ό μμ€ν /jffs/scripts/* μ€ν¬λ¦½νΈμ μΆκ°νμ§ λ§μμμ€. λμ μ€ν¬λ¦½νΈλ₯Ό /jffs/addons/my_addon/ ν΄λμ λ£κ³ κ΄λ ¨ μμ€ν μ€ν¬λ¦½νΈμμ ν΄λΉ μ€ν¬λ¦½νΈλ₯Ό νΈμΆν©λλ€. μ΄λ κ²νλ©΄ μμ/μ’ λ£ μ€μ μ°Ύμ μ 체 λΈλ‘μ μ κ±°νκ³ λ€λ₯Έ μ€μΉλ μ λμ¨μ μν₯μ μ£Όμ§ μλ μ κ±° νλ‘κ·Έλ¨μ μ½κ² κ°λ°ν μ μμ΅λλ€.
λ€μμ μμμ μΌλ‘ μ¬μ©ν μ μλ κ°λ¨ν μμ νμ΄μ§μ λλ€.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
<meta HTTP-EQUIV="Expires" CONTENT="-1">
<link rel="shortcut icon" href="images/favicon.png">
<link rel="icon" href="images/favicon.png">
<title>ν
μ€νΈ νμ΄μ§</title>
<link rel="stylesheet" type="text/css" href="index_style.css">
<link rel="stylesheet" type="text/css" href="form_style.css">
<script language="JavaScript" type="text/javascript" src="/state.js"></script>
<script language="JavaScript" type="text/javascript" src="/general.js"></script>
<script language="JavaScript" type="text/javascript" src="/popup.js"></script>
<script language="JavaScript" type="text/javascript" src="/help.js"></script>
<script type="text/javascript" language="JavaScript" src="/validator.js"></script>
<script>
var custom_settings = <% get_custom_settings(); %>;
function initial(){
SetCurrentPage();
show_menu();
if (custom_settings.diversion_path == undefined)
document.getElementById('diversion_path').value = "/tmp/default";
else
document.getElementById('diversion_path').value = custom_settings.diversion_path;
}
function SetCurrentPage() {
/* Set the proper return pages */
document.form.next_page.value = window.location.pathname.substring(1);
document.form.current_page.value = window.location.pathname.substring(1);
}
function applySettings(){
/* Retrieve value from input fields, and store in object */
custom_settings.diversion_path = document.getElementById('diversion_path').value;
/* Store object as a string in the amng_custom hidden input field */
document.getElementById('amng_custom').value = JSON.stringify(custom_settings);
/* Apply */
showLoading();
document.form.submit();
}
</script>
</head>
<body onload="initial();" class="bg">
<div id="TopBanner"></div>
<div id="Loading" class="popup_bg"></div>
<iframe name="hidden_frame" id="hidden_frame" src="" width="0" height="0" frameborder="0"></iframe>
<form method="post" name="form" action="start_apply.htm" target="hidden_frame">
<input type="hidden" name="current_page" value="MyPage.asp">
<input type="hidden" name="next_page" value="MyPage.asp">
<input type="hidden" name="group_id" value="">
<input type="hidden" name="modified" value="0">
<input type="hidden" name="action_mode" value="apply">
<input type="hidden" name="action_wait" value="5">
<input type="hidden" name="first_time" value="">
<input type="hidden" name="action_script" value="">
<input type="hidden" name="preferred_lang" id="preferred_lang" value="<% nvram_get("preferred_lang"); %>">
<input type="hidden" name="firmver" value="<% nvram_get("firmver"); %>">
<input type="hidden" name="amng_custom" id="amng_custom" value="">
<table class="content" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="17"> </td>
<td valign="top" width="202">
<div id="mainMenu"></div>
<div id="subMenu"></div>
</td>
<td valign="top">
<div id="tabMenu" class="submenuBlock"></div>
<table width="98%" border="0" align="left" cellpadding="0" cellspacing="0">
<tr>
<td align="left" valign="top">
<table width="760px" border="0" cellpadding="5" cellspacing="0" bordercolor="#6b8fa3" class="FormTitle" id="FormTitle">
<tr>
<td bgcolor="#4D595D" colspan="3" valign="top">
<div> </div>
<div class="formfonttitle">ν
μ€νΈ νμ΄μ§ - μ¬μ©μ μ μ μ€μ </div>
<div style="margin:10px 0 10px 5px;" class="splitLine"></div>
<div class="formfontdesc"><#1838#></div>
<table width="100%" border="1" align="center" cellpadding="4" cellspacing="0" bordercolor="#6b8fa3" class="FormTable">
<tr>
<th>Diversion path</th>
<td>
<input type="text" maxlength="100" class="input_25_table" id="diversion_path" autocorrect="off" autocapitalize="off">
</td>
</tr>
</table>
<div class="apply_gen">
<input name="button" type="button" class="button_gen" onclick="applySettings();" value="μ
μ©"/>
</div>
</form>
<div>
<table class="apply_gen">
<tr class="apply_gen" valign="top">
</tr>
</table>
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td width="10" align="center" valign="top"></td>
</tr>
</table>
<div id="footer"></div>
</body>
</html>