Skip to content

Commit 7ea18b9

Browse files
committed
completed udp socket actions and updated nas status utility
1 parent 56971ab commit 7ea18b9

File tree

6 files changed

+268
-8
lines changed

6 files changed

+268
-8
lines changed

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ creates a tcp socket, and if creating a server socket, set listening to 1
184184
**socket-udp port non_blocking**<br />
185185
creates a udp socket
186186

187+
**socket-set-broadcast socket state_0_or_1**<br />
188+
apply SO_BROADCAST
189+
187190
**socket-tcp-connect socket host port**<br />
188191
connect to a tcp server with the supplied arguments. Returns 1 if the address is unknown, 2 if the host didnt connect, and 0 if successful
189192

@@ -193,6 +196,12 @@ sends string buffer to host. Returns the amount of sent bytes or -1 on error
193196
**socket-tcp-recv socket**<br />
194197
returns a string buffer if successful, -1 on error, or 1 if the socket would block on a nonblocking port
195198

199+
**socket-udp-send socket destination_address destination_port data**<br />
200+
sends string buffer to host. Returns the amount of sent bytes or -1 on error
201+
202+
**socket-udp-recv socket**<br />
203+
returns a string buffer if successful, -1 on error, or 1 if the socket would block on a nonblocking port
204+
196205
**socket-tcp-would-block socket**<br />
197206
returns 1 if the socket would block
198207

cli.c

+166-2
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ sts_value_t *cli_actions(sts_script_t *script, sts_value_t *action, sts_node_t *
11931193
ACTION(else if, "socket-udp") /* creates new udp socket. args are (port, non_blocking) */
11941194
{
11951195
GOTO_SET(&cli_actions);
1196-
if(args->next && args->next->next && args->next->next->next)
1196+
if(args->next && args->next->next)
11971197
{
11981198
EVAL_ARG(args->next);
11991199
first_arg_value = eval_value;
@@ -1202,7 +1202,7 @@ sts_value_t *cli_actions(sts_script_t *script, sts_value_t *action, sts_node_t *
12021202

12031203
if(first_arg_value->type != STS_NUMBER || second_arg_value->type != STS_NUMBER)
12041204
{
1205-
fprintf(stderr, "the socket-udp action requires 3 number arguments\n");
1205+
fprintf(stderr, "the socket-udp action requires 2 number arguments\n");
12061206
if(!sts_value_reference_decrement(script, first_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp action");
12071207
if(!sts_value_reference_decrement(script, second_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the second argument in the socket-udp action");
12081208
return NULL;
@@ -1235,6 +1235,36 @@ sts_value_t *cli_actions(sts_script_t *script, sts_value_t *action, sts_node_t *
12351235
}
12361236
else {STS_ERROR_SIMPLE("socket-udp action requires 3 arguments"); return NULL;}
12371237
}
1238+
ACTION(else if, "socket-set-broadcast") /* applies SO_BROADCAST socket option, (socket state) */
1239+
{
1240+
GOTO_SET(&cli_actions);
1241+
if(args->next && args->next->next)
1242+
{
1243+
int opt;
1244+
EVAL_ARG(args->next);
1245+
first_arg_value = eval_value;
1246+
EVAL_ARG(args->next->next);
1247+
second_arg_value = eval_value;
1248+
1249+
if(!IS_CLI_SOCKET(first_arg_value) || second_arg_value->type != STS_NUMBER)
1250+
{
1251+
fprintf(stderr, "the socket-set-broadcast action requires a socket argument and state\n");
1252+
if(!sts_value_reference_decrement(script, first_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-set-broadcast action");
1253+
if(!sts_value_reference_decrement(script, second_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the second argument in the socket-set-broadcast action");
1254+
return NULL;
1255+
}
1256+
1257+
opt = second_arg_value->number;
1258+
if(setsockopt(CLI_SOCKET(first_arg_value)->socket.handle, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(int)))
1259+
VALUE_FROM_NUMBER(ret, 1);
1260+
else
1261+
VALUE_FROM_NUMBER(ret, 0);
1262+
1263+
if(!sts_value_reference_decrement(script, first_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-set-broadcast action");
1264+
if(!sts_value_reference_decrement(script, second_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the second argument in the socket-set-broadcast action");
1265+
}
1266+
else {STS_ERROR_SIMPLE("socket-set-broadcast action requires 2 arguments"); return NULL;}
1267+
}
12381268
ACTION(else if, "socket-tcp-connect") /* connects to tcp server (socket, host, port) */
12391269
{
12401270
GOTO_SET(&cli_actions);
@@ -1411,6 +1441,140 @@ sts_value_t *cli_actions(sts_script_t *script, sts_value_t *action, sts_node_t *
14111441
}
14121442
else {STS_ERROR_SIMPLE("socket-tcp-send action requires a socket"); return NULL;}
14131443
}
1444+
ACTION(else if, "socket-udp-send") /* sends a string buffer to the host in the socket (socket, destination address, destination port, data) */
1445+
{
1446+
GOTO_SET(&cli_actions);
1447+
if(args->next && args->next->next && args->next->next->next && args->next->next->next->next)
1448+
{
1449+
EVAL_ARG(args->next);
1450+
first_arg_value = eval_value;
1451+
EVAL_ARG(args->next->next);
1452+
second_arg_value = eval_value;
1453+
EVAL_ARG(args->next->next->next);
1454+
third_arg_value = eval_value;
1455+
EVAL_ARG(args->next->next->next->next);
1456+
1457+
if(!IS_CLI_SOCKET(first_arg_value) || second_arg_value->type != STS_STRING || third_arg_value->type != STS_NUMBER || eval_value->type != STS_STRING)
1458+
{
1459+
fprintf(stderr, "the socket-udp-send action requires a socket, the destination, destination port, and the data to send\n");
1460+
if(!sts_value_reference_decrement(script, first_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp-send action");
1461+
if(!sts_value_reference_decrement(script, second_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the second argument in the socket-udp-send action");
1462+
if(!sts_value_reference_decrement(script, third_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the third argument in the socket-udp-send action");
1463+
if(!sts_value_reference_decrement(script, eval_value)) STS_ERROR_SIMPLE("could not decrement references for the fourth argument in the socket-udp-send action");
1464+
return NULL;
1465+
}
1466+
1467+
if(zed_net_get_address(&address, second_arg_value->string.data, third_arg_value->number))
1468+
{
1469+
fprintf(stderr, "could not get the address in socket-udp-send: %s\n", zed_net_get_error());
1470+
VALUE_FROM_NUMBER(ret, -1);
1471+
}
1472+
else
1473+
VALUE_FROM_NUMBER(ret, zed_net_udp_socket_send(&CLI_SOCKET(first_arg_value)->socket, address, eval_value->string.data, eval_value->string.length));
1474+
1475+
if(!sts_value_reference_decrement(script, first_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp-send action");
1476+
if(!sts_value_reference_decrement(script, second_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the second argument in the socket-udp-send action");
1477+
if(!sts_value_reference_decrement(script, third_arg_value)) STS_ERROR_SIMPLE("could not decrement references for the third argument in the socket-udp-send action");
1478+
if(!sts_value_reference_decrement(script, eval_value)) STS_ERROR_SIMPLE("could not decrement references for the fourth argument in the socket-udp-send action");
1479+
}
1480+
else {STS_ERROR_SIMPLE("socket-udp-send action requires a socket and a data string"); return NULL;}
1481+
}
1482+
ACTION(else if, "socket-udp-recv") /* returns a string of data from the socket. ret of 1 means would block, -1 means error, string is data */
1483+
{
1484+
GOTO_SET(&cli_actions);
1485+
if(args->next)
1486+
{
1487+
EVAL_ARG(args->next);
1488+
1489+
if(!IS_CLI_SOCKET(eval_value))
1490+
{
1491+
fprintf(stderr, "the socket-udp-recv action requires a socket and the data to send\n");
1492+
if(!sts_value_reference_decrement(script, eval_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp-recv action");
1493+
return NULL;
1494+
}
1495+
1496+
/* first check if it would block and return a 1 instead of a string */
1497+
1498+
if(zed_net_check_would_block(&CLI_SOCKET(eval_value)->socket) == 1)
1499+
{
1500+
if(!(ret = sts_value_from_number(script, 1)))
1501+
{
1502+
STS_ERROR_SIMPLE("could not create number retval in socket-udp-recv");
1503+
if(!sts_value_reference_decrement(script, eval_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp-recv action");
1504+
return NULL;
1505+
}
1506+
1507+
if(!sts_value_reference_decrement(script, eval_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp-recv action");
1508+
1509+
return ret;
1510+
}
1511+
1512+
do
1513+
{
1514+
if(zed_net_check_would_block(&CLI_SOCKET(eval_value)->socket))
1515+
break;
1516+
1517+
temp_int = zed_net_udp_socket_receive(&CLI_SOCKET(eval_value)->socket, &address, buf, sizeof(buf));
1518+
1519+
if(temp_int <= 0)
1520+
break;
1521+
1522+
/* this is bad, but this whole project is for personal use primarily */
1523+
if(!(temp_str = realloc(temp_str, temp_ulong + temp_int + 1)))
1524+
{
1525+
STS_ERROR_SIMPLE("could not resize temporary buffer in socket-udp-recv");
1526+
if(!sts_value_reference_decrement(script, eval_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp-recv action");
1527+
return NULL;
1528+
}
1529+
1530+
memcpy(&temp_str[temp_ulong], buf, temp_int);
1531+
1532+
temp_ulong += temp_int;
1533+
temp_str[temp_ulong] = 0x0;
1534+
} while(temp_int == sizeof(buf));
1535+
1536+
1537+
/* return a number instead of a string */
1538+
if(temp_int == -1)
1539+
{
1540+
if(!(ret = sts_value_from_number(script, -1)))
1541+
{
1542+
STS_ERROR_SIMPLE("could not create number retval in socket-udp-recv");
1543+
if(temp_str) free(temp_str);
1544+
if(!sts_value_reference_decrement(script, eval_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp-recv action");
1545+
return NULL;
1546+
}
1547+
1548+
if(temp_str) free(temp_str);
1549+
if(!sts_value_reference_decrement(script, eval_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp-recv action");
1550+
1551+
return ret;
1552+
}
1553+
/* create a string with the recieved data */
1554+
else if(temp_uint != -1 && !(ret = sts_value_create(script, STS_STRING)))
1555+
{
1556+
STS_ERROR_SIMPLE("could not create string retval in socket-udp-recv");
1557+
if(temp_str) free(temp_str);
1558+
if(!sts_value_reference_decrement(script, eval_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp-recv action");
1559+
return NULL;
1560+
}
1561+
1562+
if(temp_str)
1563+
{
1564+
ret->string.length = temp_ulong;
1565+
ret->string.data = temp_str;
1566+
}
1567+
else
1568+
{
1569+
ret->string.length = 0;
1570+
ret->string.data = sts_memdup("", 0);
1571+
}
1572+
1573+
1574+
if(!sts_value_reference_decrement(script, eval_value)) STS_ERROR_SIMPLE("could not decrement references for the first argument in the socket-udp-recv action");
1575+
}
1576+
else {STS_ERROR_SIMPLE("socket-tcp-send action requires a socket"); return NULL;}
1577+
}
14141578
ACTION(else if, "socket-tcp-would-block") /* tests if a socket will block */
14151579
{
14161580
GOTO_SET(&cli_actions);

examples/nas_status/nas_status.service

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Type=simple
88
Restart=always
99
RestartSec=1
1010
User=root
11+
Group=nasuser
1112
ExecStart=/usr/local/bin/nas_status.sts
1213

1314
[Install]

examples/nas_status/nas_status.sts

+68-6
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,23 @@
55
import stdlib.sts
66

77
# add drives and other info to test here
8+
# broadcast_event name acceptable_threshold
89
local config [hashmap \
10+
identity "test_nas_hostname" \
911
drives [array "/dev/sda"] \
10-
file "~/test_output.html" \
12+
file "/mnt/storage/archive/nas_health.html" \
1113
delay (* 1 24 60 60) \
14+
broadcast_addr "192.168.1.255" \
15+
broadcast_port 3621 \
16+
broadcast_event [hashmap \
17+
Raw_Read_Error_Rate 0 \
18+
Bad_Block_Count 0 \
19+
Bad_Cluster_Table_Count 0 \
20+
Seek_Error_Rate 0 \
21+
Spin_Retry_Count 0 \
22+
Offline_Uncorrectable 0 \
23+
UDMA_CRC_Error_Count 0 \
24+
] \
1225
]
1326

1427
local template "
@@ -69,6 +82,8 @@ local template "
6982
</html>
7083
"
7184

85+
local sock $nil
86+
7287
function strip_empty string_array {
7388
local ret [array ]
7489
local i 0
@@ -84,31 +99,46 @@ function strip_empty string_array {
8499
}
85100

86101
function neofetch_exec {
87-
local ret ""
102+
local ret (string "")
88103
pipeout $ret neofetch | aha --black
89104
pass $ret
90105
}
91106

92107
function date_exec {
93-
local ret ""
108+
local ret (string "")
94109
pipeout $ret date
95110
pass $ret
96111
}
97112

113+
function broadcast_warning_test attribute value {
114+
local message $nil
115+
if(hashmap-exists (hashmap-get $config broadcast_event) $attribute) {
116+
if(< [hashmap-get (hashmap-get $config broadcast_event) $attribute] $value) {
117+
set $message (string [hashmap-get $config identity] ": " "smart attribute " $attribute " above threshold at, " $value)
118+
broadcast $message
119+
stderr-write $message
120+
}
121+
}
122+
pass $nil
123+
}
124+
98125
# ID#", "ATTRIBUTE_NAME", "FLAG", "VALUE", "WORST", "THRESH", "TYPE", "UPDATED", "WHEN_FAILED", "RAW_VALUE
99126

100127
function render_smart_attribute line {
101128
local ret "<tr>"
102129
local split [strip_empty (string-tokenize $line " ")]
103-
set $ret [string $ret "<td><b>" (get $split 1) "</b></td><td>" (get $split 6) "</td><td>(higher is better)<progress max='" (get $split 4) "' value='" (get $split 3) "'></progress></td><td>" (get $split 9) "</td>"]
130+
131+
broadcast_warning_test (get $split 1) (get $split 9)
132+
133+
set $ret [string $ret "<td><b>" (get $split 1) "</b></td><td>" (get $split 6) "</td><td><progress max='" (get $split 4) "' value='" (get $split 3) "'></progress></td><td>" (get $split 9) "</td>"]
104134

105135
set $ret [string $ret "</tr>"]
106136
pass $ret
107137
}
108138

109139
function native_drive_health_parse {
110140
local ret ""
111-
local raw ""
141+
local raw (string "")
112142
local name ""
113143
local lines [array]
114144
local i 0
@@ -139,7 +169,7 @@ function native_drive_health_parse {
139169

140170
function df_render {
141171
local ret ""
142-
local raw ""
172+
local raw (string "")
143173
local lines [array]
144174
local line $nil
145175
local i 1
@@ -160,8 +190,40 @@ function df_render {
160190
pass $ret
161191
}
162192

193+
function init_broadcast {
194+
local ret 0
195+
set $sock (socket-udp [hashmap-get $config broadcast_port] 0)
196+
197+
if(== $sock $nil) {
198+
print could not open socket
199+
set $ret 1
200+
}
201+
else {
202+
socket-set-broadcast $sock 1
203+
}
204+
205+
pass $ret
206+
}
207+
208+
function broadcast message {
209+
local ret 0
210+
local buffer $nil
211+
local size $nil
212+
213+
set $size (string [num2bin (sizeof $message)])
214+
set $buffer (string [num2bin 0x214D4E53] [get $size 0] [get $size 1] $message)
215+
set $ret [socket-udp-send $sock (hashmap-get $config broadcast_addr) (hashmap-get $config broadcast_port) $buffer]
216+
217+
pass $ret
218+
}
219+
163220
function main args {
164221
local output ""
222+
223+
if (init_broadcast) {
224+
stderr-write unable to initialize broadcast socket
225+
exit 1
226+
}
165227

166228
loop 1 {
167229
print =================================

examples/stdlib_test.sts

+5
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ function test_misc {
106106
TEST_FOUR
107107

108108
print TEST_THREE value: $TEST_THREE
109+
110+
print testing serialization
111+
112+
local serialized (num2bin 0x3f3f3f3f)
113+
print serialized: $serialized
109114
}
110115

111116
# all tests below =====

stdlib.sts

+19
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,25 @@ function string-replace string replacee replacement {
523523

524524
# uncategorized =========================
525525

526+
function num2bin number {
527+
local ret (string "")
528+
local i 0
529+
local observe 0
530+
531+
if(== [typeof $number] [STS_NUMBER]) {
532+
loop (< $i 4) {
533+
set $observe [& (>> $number [* $i 8]) 0xFF]
534+
set $ret (string $ret [asc $observe])
535+
++ $i
536+
}
537+
}
538+
else {
539+
set $ret $nil
540+
}
541+
542+
pass $ret
543+
}
544+
526545
function getpwd self {
527546
local str $nil
528547
local pos 0

0 commit comments

Comments
 (0)