diff --git a/general/package/xmdp/src/netip.c b/general/package/xmdp/src/netip.c index 8572ae0b..69267e1f 100644 --- a/general/package/xmdp/src/netip.c +++ b/general/package/xmdp/src/netip.c @@ -4,8 +4,10 @@ #include #include +#include #include #include +#include #include "cjson/cJSON.h" #include "netip.h" @@ -43,8 +45,9 @@ typedef union netip_pkt { #define NETIP_HSIZE sizeof(netip_preabmle_t) #define NETIP_MAX_JSON sizeof(resp) - NETIP_HSIZE - 1 -bool netip_connect(const char *addr, uint16_t port) { - bool res = true; +enum ConnectStatus netip_connect(const char *addr, uint16_t port) { + bool res = CONNECT_OK; + cJSON *json = NULL; int s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) @@ -55,8 +58,22 @@ bool netip_connect(const char *addr, uint16_t port) { srv.sin_family = AF_INET; srv.sin_port = htons(port); - if (connect(s, (struct sockaddr *)&srv, sizeof(srv)) < 0) - return false; + const int flags = fcntl(s, F_GETFL, 0); + fcntl(s, F_SETFL, flags | O_NONBLOCK); + (void)connect(s, (struct sockaddr *)&srv, sizeof(srv)); + + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(s, &fdset); + struct timeval tv = { + .tv_sec = 2, /* 2 second timeout */ + }; + + if (select(s + 1, NULL, &fdset, NULL, &tv) != 1) { + res = CONNECT_ERR; + goto quit; + } + fcntl(s, F_SETFL, flags); netip_pkt_t msg; memset(&msg.header, 0, sizeof(msg.header)); @@ -69,29 +86,30 @@ bool netip_connect(const char *addr, uint16_t port) { msg.header.len_data = sizeof(default_login); if (send(s, &msg, sizeof(default_login) + NETIP_HSIZE, 0) < 0) { - puts("Send failed"); - return false; + return CONNECT_ERR; } if (recv(s, &msg, sizeof(msg), 0) <= NETIP_HSIZE) { puts("recv failed"); } - cJSON *json = cJSON_Parse(msg.header.data); + json = cJSON_Parse(msg.header.data); if (!json) { const char *error_ptr = cJSON_GetErrorPtr(); if (error_ptr != NULL) { fprintf(stderr, "Error before: %s\n", error_ptr); } - res = false; - goto skip_loop; + res = CONNECT_ERR; + goto quit; } const int retval = get_json_intval(json, "Ret", 0); if (retval != RESULT_OK) - return false; + return CONNECT_PWDREQ; -skip_loop: - cJSON_Delete(json); +quit: + if (json) + cJSON_Delete(json); + close(s); return res; } diff --git a/general/package/xmdp/src/netip.h b/general/package/xmdp/src/netip.h index b702384d..55fef381 100644 --- a/general/package/xmdp/src/netip.h +++ b/general/package/xmdp/src/netip.h @@ -1,6 +1,12 @@ #ifndef NETIP_H #define NETIP_H -bool netip_connect(const char* addr, uint16_t port); +enum ConnectStatus { + CONNECT_OK, + CONNECT_ERR, + CONNECT_PWDREQ, +}; + +enum ConnectStatus netip_connect(const char *addr, uint16_t port); #endif /* NETIP_H */ diff --git a/general/package/xmdp/src/xmdp.c b/general/package/xmdp/src/xmdp.c index 2a79dbaf..3cc8f545 100644 --- a/general/package/xmdp/src/xmdp.c +++ b/general/package/xmdp/src/xmdp.c @@ -26,6 +26,18 @@ const char brpkt[] = "\x00\x00\x00\x00"; static const char *Reset = "\x1b[0m"; static const char *FgRed = "\x1b[31m"; +static const char *FgBrightRed = "\033[31;1m"; + +static const char *color(enum ConnectStatus status) { + switch (status) { + case CONNECT_OK: + return FgRed; + case CONNECT_ERR: + return FgBrightRed; + default: + return ""; + } +} // get sockaddr, IPv4 or IPv6: void *get_in_addr(struct sockaddr *sa) { @@ -175,7 +187,7 @@ int main() { ipaddr_from32bit(abuf, sizeof abuf, host_ip); host_ip = abuf; } - bool netip_ok = netip_connect(host_ip, netip_port); + enum ConnectStatus netip_conn = netip_connect(host_ip, netip_port); char verstr[128] = {0}; if (strlen(version)) { @@ -191,23 +203,21 @@ int main() { version++; } - if (strlen(builddt)) { - const char *end; - if ((end = strchr(builddt, ' '))) { - strcat(verstr + strlen(verstr), " ("); - snprintf(verstr + strlen(verstr), - MIN(sizeof(verstr) - strlen(verstr), end - builddt + 1), - "%s", builddt); - strcat(verstr + strlen(verstr), ")"); - } + if (strlen(builddt) == 19 && builddt[10] == ' ') { + const char *end = builddt + 10; + strcat(verstr + strlen(verstr), " ("); + snprintf(verstr + strlen(verstr), + MIN(sizeof(verstr) - strlen(verstr), end - builddt + 1), "%s", + builddt); + strcat(verstr + strlen(verstr), ")"); } } - printf("%s%s\t%s\t%s %s, %s", netip_ok ? FgRed : "", host_ip, mac, + printf("%s%s\t%s\t%s %s, %s", color(netip_conn), host_ip, mac, chan_num > 1 ? "DVR" : "IPC", sn, hostname); if (strlen(verstr)) printf("\t%s", verstr); - printf("%s\n", netip_ok ? Reset : ""); + printf("%s\n", *color(netip_conn) ? Reset : ""); skip_loop: