Last active
November 10, 2023 21:09
-
-
Save willeccles/e8bac6cee4dbee8c4939cdc2eec835c1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Compile with -DUSE_READLINE and -lreadline to use readline for input. */ | |
#include <arpa/inet.h> | |
#include <errno.h> | |
#include <poll.h> | |
#include <signal.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/socket.h> | |
#include <unistd.h> | |
#ifdef USE_READLINE | |
#include <readline/history.h> | |
#include <readline/readline.h> | |
#endif /* USE_READLINE */ | |
#define NETBFRLEN 1024 | |
int clientsocket; | |
void closeclient() { | |
if (clientsocket != -1 && clientsocket != 0) { | |
// shutdown(clientsocket, SHUT_WR); | |
// shutdown(clientsocket, SHUT_RD); | |
close(clientsocket); | |
} | |
} | |
void sighandler(int s) { | |
closeclient(); | |
_exit(0); | |
} | |
int main(int argc, char** argv) { | |
if (argc == 1) { | |
fprintf(stderr, "Please supply address and port\n"); | |
return 1; | |
} | |
struct sigaction sigint_handler; | |
sigint_handler.sa_handler = sighandler; | |
sigemptyset(&sigint_handler.sa_mask); | |
sigint_handler.sa_flags = 0; | |
sigaction(SIGINT, &sigint_handler, NULL); | |
char inbuffer[NETBFRLEN] = {0}; | |
struct sockaddr_in server_addr; | |
socklen_t addr_size; | |
if ((clientsocket = socket(PF_INET, SOCK_DGRAM, 0)) == -1) { | |
perror("socket"); | |
return 1; | |
} | |
server_addr.sin_family = AF_INET; | |
server_addr.sin_port = htons(atoi(argv[2])); | |
server_addr.sin_addr.s_addr = inet_addr(argv[1]); | |
memset(server_addr.sin_zero, 0, sizeof(server_addr.sin_zero)); | |
addr_size = sizeof(server_addr); | |
#if 0 | |
if (connect(clientsocket, (struct sockaddr*)&serverAddr, addr_size) == -1) { | |
perror("connect"); | |
return 1; | |
} | |
#endif | |
#ifndef USE_READLINE | |
char input[256] = {0}; | |
#else | |
char* input; | |
#endif /* USE_READLINE */ | |
ssize_t outbytes, inbytes; | |
int status; | |
struct pollfd pfd; | |
pfd.events = POLLIN; | |
pfd.fd = clientsocket; | |
puts("Enter SCPI commands here.\n" | |
"Queries will timeout after 1 second.\n" | |
"Type 'quit', 'exit', or Control-C to quit."); | |
#ifdef USE_READLINE | |
puts("Readline line editing features are supported."); | |
#endif /* USE_READLINE */ | |
while (1) { | |
#ifndef USE_READLINE | |
printf("> "); | |
scanf(" %253[^\n]", input); | |
#else | |
input = readline("> "); | |
if (!input) { | |
closeclient(); | |
return 0; | |
} | |
#endif /* USE_READLINE */ | |
if (0 == strcmp(input, "quit") || 0 == strcmp(input, "exit")) { | |
closeclient(); | |
return 0; | |
} | |
#ifdef USE_READLINE | |
add_history(input); | |
#endif /* USE_READLINE */ | |
size_t l = strlen(input); | |
#ifdef USE_READLINE | |
input = realloc(input, l + 3); | |
if (!input) { | |
perror("realloc"); | |
closeclient(); | |
return 1; | |
} | |
#endif /* USE_READLINE */ | |
strcpy(input + l, "\r\n"); | |
// outbytes = write(clientsocket, input, strlen(input)); | |
outbytes = sendto(clientsocket, input, strlen(input), 0, | |
(struct sockaddr*)&server_addr, addr_size); | |
if (outbytes == -1) { | |
perror("write"); | |
closeclient(); | |
return 1; | |
} | |
if (NULL != strchr(input, '?')) { | |
status = poll(&pfd, 1, 1000); | |
if (status == 0) { | |
printf("No response from server within 1 second!\n"); | |
} else if (status == -1) { | |
perror("poll"); | |
closeclient(); | |
return 1; | |
} else { | |
inbytes = read(clientsocket, inbuffer, NETBFRLEN); | |
if (inbytes == -1) { | |
perror("read"); | |
closeclient(); | |
return 1; | |
} | |
printf("%s", inbuffer); | |
memset(inbuffer, 0, NETBFRLEN); | |
} | |
} | |
#ifdef USE_READLINE | |
free(input); | |
#endif /* USE_READLINE */ | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment