From 3d315d3a4c2dc6993e0025335633a978420b5d82 Mon Sep 17 00:00:00 2001 From: David Hale Date: Fri, 16 Aug 2024 11:07:04 -0700 Subject: [PATCH 1/2] adopted c++ idiomataic practices for listener, sendcmd, md5 --- utils/listener.cpp | 41 ++++--- utils/md5.cpp | 41 ++++--- utils/md5.h | 5 +- utils/sendcmd.cpp | 259 +++++++++++++++++++++------------------------ 4 files changed, 169 insertions(+), 177 deletions(-) diff --git a/utils/listener.cpp b/utils/listener.cpp index d7125bf4..5bee1ab4 100644 --- a/utils/listener.cpp +++ b/utils/listener.cpp @@ -7,31 +7,38 @@ // Changes: // * Compiles for Linux // * Takes the port and group on the command line +// * adopted c++ idiomataic practices // #include #include #include #include -#include -#include -#include -#include +#include +#include -#define MSGBUFSIZE 256 +constexpr size_t MSGBUFSIZE=256; int main(int argc, char *argv[]) { if (argc < 3) { - printf("Command line args should be multicast group and port\n"); - printf("(e.g. for SSDP, `listener 239.255.255.250 1900`)\n"); + std::cout << "Command line args should be multicast group and port\n"; + std::cout << "e.g. for SSDP, `listener 239.255.255.250 1900`)\n"; return 1; } char *group = argv[1]; // e.g. 239.255.255.250 for SSDP - int port = atoi(argv[2]); // 0 if error, which is an invalid port + int port; + try { + port = std::stoi(argv[2]); + if ( port < 1 ) throw std::out_of_range("invalid port number"); + } + catch (...) { + std::cerr << "invalid port number\n"; + return 1; + } - char *filterstr = NULL; + char *filterstr = nullptr; if (argc == 4) filterstr = argv[3]; @@ -39,7 +46,7 @@ int main(int argc, char *argv[]) { // int fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { - perror("socket"); + std::cerr << "socket: " << std::strerror(errno) << "\n"; return 1; } @@ -51,7 +58,7 @@ int main(int argc, char *argv[]) { fd, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof(yes) ) < 0 ) { - perror("Reusing ADDR failed"); + std::cerr << "Reusing ADDR: " << std::strerror(errno) << "\n"; return 1; } @@ -66,7 +73,7 @@ int main(int argc, char *argv[]) { // bind to receive address // if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("bind"); + std::cerr << "bind: " << std::strerror(errno) << "\n"; return 1; } @@ -80,7 +87,7 @@ int main(int argc, char *argv[]) { fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq) ) < 0 ) { - perror("setsockopt"); + std::cerr << "setsockopt: " << std::strerror(errno) << "\n"; return 1; } @@ -98,13 +105,13 @@ int main(int argc, char *argv[]) { &addrlen ); if (nbytes < 0) { - perror("recvfrom"); + std::cerr << "recvfrom: " << std::strerror(errno) << "\n"; return 1; } msgbuf[nbytes] = '\0'; - if (filterstr != NULL) { - if (strstr(msgbuf, filterstr) != NULL) puts(msgbuf); - } else puts(msgbuf); + if (filterstr != nullptr) { + if (strstr(msgbuf, filterstr) != nullptr) std::cout << msgbuf << "\n"; + } else std::cout << msgbuf << "\n"; } return 0; diff --git a/utils/md5.cpp b/utils/md5.cpp index d07dcb1d..47feae42 100644 --- a/utils/md5.cpp +++ b/utils/md5.cpp @@ -9,29 +9,36 @@ * This implementation uses little endian byte order. * * obtained from https://github.com/B-Con/crypto-algorithms +* adopted c++ idiomataic practices, David Hale *********************************************************************/ /*************************** HEADER FILES ***************************/ -#include -#include +#include +#include #include "md5.h" /****************************** MACROS ******************************/ -#define ROTLEFT(a,b) ((a << b) | (a >> (32-b))) - -#define F(x,y,z) ((x & y) | (~x & z)) -#define G(x,y,z) ((x & z) | (y & ~z)) -#define H(x,y,z) (x ^ y ^ z) -#define I(x,y,z) (y ^ (x | ~z)) - -#define FF(a,b,c,d,m,s,t) { a += F(b,c,d) + m + t; \ - a = b + ROTLEFT(a,s); } -#define GG(a,b,c,d,m,s,t) { a += G(b,c,d) + m + t; \ - a = b + ROTLEFT(a,s); } -#define HH(a,b,c,d,m,s,t) { a += H(b,c,d) + m + t; \ - a = b + ROTLEFT(a,s); } -#define II(a,b,c,d,m,s,t) { a += I(b,c,d) + m + t; \ - a = b + ROTLEFT(a,s); } +constexpr uint32_t ROTLEFT(uint32_t a, uint32_t b) { return (a << b) | (a >> (32 - b)); } +constexpr uint32_t F(uint32_t x, uint32_t y, uint32_t z) { return (x & y ) | ( ~x & z ); } +constexpr uint32_t G(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | ( y & ~z ); } +constexpr uint32_t H(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; } +constexpr uint32_t I(uint32_t x, uint32_t y, uint32_t z) { return y ^ ( x | ~z ); } +constexpr void FF(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t m, uint32_t s, uint32_t t) { + a += F(b, c, d) + m + t; + a = b + ROTLEFT(a, s); +} +constexpr void GG(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t m, uint32_t s, uint32_t t) { + a += G(b, c, d) + m + t; + a = b + ROTLEFT(a, s); +} +constexpr void HH(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t m, uint32_t s, uint32_t t) { + a += H(b, c, d) + m + t; + a = b + ROTLEFT(a, s); +} +constexpr void II(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t m, uint32_t s, uint32_t t) { + a += I(b, c, d) + m + t; + a = b + ROTLEFT(a, s); +} /*********************** FUNCTION DEFINITIONS ***********************/ void md5_transform(MD5_CTX *ctx, const BYTE data[]) { diff --git a/utils/md5.h b/utils/md5.h index f9c7c1d9..c1ef9bd2 100644 --- a/utils/md5.h +++ b/utils/md5.h @@ -11,10 +11,11 @@ #pragma once /*************************** HEADER FILES ***************************/ -#include +#include +#include /****************************** MACROS ******************************/ -#define MD5_BLOCK_SIZE 16 // MD5 outputs a 16 byte digest +constexpr size_t MD5_BLOCK_SIZE=16; // MD5 outputs a 16 byte digest /**************************** DATA TYPES ****************************/ typedef unsigned char BYTE; // 8-bit byte diff --git a/utils/sendcmd.cpp b/utils/sendcmd.cpp index 2975cb70..9f5187e9 100644 --- a/utils/sendcmd.cpp +++ b/utils/sendcmd.cpp @@ -1,148 +1,125 @@ #include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include + #include +#include +#include + +constexpr size_t BUFSIZE=8192; +constexpr std::string_view usage() { + return "usage: sendcmd [-h hostname] [-p port] [-t timeout] [-m mode] command\n"; +} + +int main(int argc, char *argv[]) { + int sock; + int timeout=10; + struct timeval tvstart, tvend; + int nread; + std::string message; + std::vector response(BUFSIZE); + std::string hostname = "localhost"; + struct sockaddr_in address; + struct hostent *host_struct; + int mode = 0; // 0: wait, 1: not wait + int port = 3031; // set default port + + if ( argc==1 ) { std::cout << usage(); return 0; } + + try { + for ( size_t i=1; ih_addr, host_struct->h_length ); + address.sin_family = AF_INET; + address.sin_port = htons(port); + + if (gettimeofday (&tvstart, nullptr) <0) { + std::cerr << "ERROR reading time: " << std::strerror(errno) << "\n"; + close (sock); + return -errno; + } + + if ( (connect(sock, reinterpret_cast(&address), sizeof(address)) == -1) && + (errno != EINPROGRESS) ) { + std::cerr << "ERROR connecting: " << std::strerror(errno) << "\n"; + close (sock); + return -errno; + } + + message += "\n"; + + while ( ( nread = write( sock, message.c_str(), message.size() ) ) < 0 ) { + if (errno != EAGAIN) { + std::cerr << "ERROR writing message: " << std::strerror(errno) << "\n"; + close (sock); + return -errno; + } + gettimeofday (&tvend, nullptr); + if (tvend.tv_sec - tvstart.tv_sec >= timeout) { + std::cerr << "TIMEOUT: " << std::strerror(errno) << "\n"; + close (sock); + return -ETIME; + } + } + + if (mode == 0) { + while ( ( nread = read( sock, response.data(), BUFSIZE ) ) < 0 ) { + if (errno != EAGAIN) { + std::cerr << "(sendcmd) nread:" << nread << " error:" << std::strerror(errno) << "\n"; + close (sock); + return -errno; + } + usleep( 10000 ); + gettimeofday (&tvend, nullptr); + if (tvend.tv_sec - tvstart.tv_sec >= timeout) { + std::cerr << "TIMEOUT: " << std::strerror(errno) << "\n"; + close (sock); + return -ETIME; + } + } + std::cout << std::string( response.data(), nread ) << "\n"; + } + else std::cout << "cmd_sent\n"; -#define SEND_LEN 0 - -int main(int argc, char *argv[]) -{ - int sock, timeout=10; - struct timeval tvstart, tvend; - int bufsize = 8192; - int nread, len; - char *message = (char*)malloc(bufsize); - char *response = (char*)malloc(bufsize); - char *hostname = (char*)malloc (30); - struct sockaddr_in address; - struct hostent *host_struct; - int mode = 0; /* 0: wait, 1: not wait*/ - - int port = 3031; // set default port - int i = 1; - if (argc > 1) - while (i < argc) { - if (argv[i][0] == '-') { - if (argv[i][1] == 'h') - {hostname = argv[i+1]; i++;} - else - if (argv[i][1] == 'p') - {port = atoi (argv[i+1]); i++;} - else - if (argv[i][1] == 't') - {timeout = atoi(argv[i+1]); i++;} - else - if (argv[i][1] == 'm') - {mode = atoi (argv[i+1]); i++;} - else -// if (argv[i][1] == '?') - {printf ("usage: sendcmd [-h hostname] [-p port] [-t timeout] [-m mode] command\n"); return (0);} - } else - message = argv[i]; - i++; - } - if ((host_struct = gethostbyname (hostname)) == NULL){ - printf ("ERROR %d getting_mem\n", errno); - return (-errno); - } - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - printf("ERROR %d creating_socket\n", errno); - return (-errno); - } - - if (fcntl (sock, F_SETFL, O_NONBLOCK) <0){ - printf ("ERROR %d setting_socket", errno); - close (sock); - return (-errno); - } - - bcopy (host_struct->h_addr, (char *) &address.sin_addr.s_addr, host_struct->h_length); - address.sin_family = AF_INET; - address.sin_port = htons(port); - - if (gettimeofday (&tvstart, NULL) <0) { - printf ("ERROR %d reading_time\n", errno); - close (sock); - return (-errno); - } - - if ((connect(sock,(struct sockaddr *) &address, sizeof(address)) == -1) && (errno != EINPROGRESS)) { - printf ("ERROR %d connecting\n", errno); - close (sock); - return (-errno); - } - - len = strlen (message); - message[len]='\n'; - message[len+1]='\0'; - len++; - -#if SEND_LEN - char *stringlen = malloc(10); - - sprintf (stringlen, "%08d", len); - printf ("%s", stringlen); - while ((nread = write (sock, stringlen, 8)) < 0) { - if (errno != EAGAIN) { - printf ("ERROR %d writing_len\n", errno); - close (sock); - return (-errno); - } - gettimeofday (&tvend, NULL); - if (tvend.tv_sec - tvstart.tv_sec >= timeout) { - printf ("ERROR %d TIMEOUT\n", -ETIME); - close (sock); - return (-ETIME); - } - } -#endif - - while ((nread = write (sock, message, len)) < 0) { - if (errno != EAGAIN) { - printf ("ERROR %d writing_message\n", errno); - close (sock); - return (-errno); - } - gettimeofday (&tvend, NULL); - if (tvend.tv_sec - tvstart.tv_sec >= timeout) { - printf ("ERROR %d TIMEOUT\n", -ETIME); - close (sock); - return (-ETIME); - } - } - - if (mode == 0) { - while ((nread = read (sock, response, bufsize)) < 0) { - if (errno != EAGAIN) { - printf ("(sendcmd) ERROR %d reading\n", errno); - std::cerr << "(sendcmd) nread:" << nread << " response:" << response << "\n"; - close (sock); - return (-errno); - } - usleep (10000); - gettimeofday (&tvend, NULL); - if (tvend.tv_sec - tvstart.tv_sec >= timeout) { - printf ("ERROR %d TIMEOUT\n", -ETIME); - close (sock); - return (-ETIME); - } - } - } - if (mode == 0) - printf("%s\n", response); - else - printf("cmd_sent\n"); - - return (close(sock)); + return close(sock); } From 6b53c31e81669368f34aab59340617034403fe3c Mon Sep 17 00:00:00 2001 From: David Hale Date: Sat, 17 Aug 2024 00:19:34 -0700 Subject: [PATCH 2/2] fixes typo in comment --- utils/listener.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/listener.cpp b/utils/listener.cpp index 5bee1ab4..8b403aad 100644 --- a/utils/listener.cpp +++ b/utils/listener.cpp @@ -7,7 +7,7 @@ // Changes: // * Compiles for Linux // * Takes the port and group on the command line -// * adopted c++ idiomataic practices +// * adopted c++ idiomatic practices // #include