SDDSlib
Loading...
Searching...
No Matches
sddslogclient.c
Go to the documentation of this file.
1/**
2 * @file sddslogclient.c
3 * @brief A simple TCP client for sending commands to a server.
4 *
5 * This program establishes a TCP connection to a specified server and port,
6 * sends commands either from the command line arguments or interactively
7 * from the user, and processes the server's responses. The client supports
8 * persistent connections, allowing multiple commands to be sent over a single
9 * socket until a "disconnect" command is issued.
10 *
11 * ## Usage
12 *
13 * ```
14 * ./sddslogclient <hostname> <port> [<command> ...]
15 * ```
16 *
17 * - `hostname`: The server's hostname or IP address.
18 * - `port`: The port number on which the server is listening.
19 * - `<command>`: (Optional) One or more commands to send to the server initially.
20 *
21 * If no commands are provided as arguments, the client enters an interactive
22 * mode where the user can input commands manually.
23 *
24 * ## Functions
25 *
26 * - `void error(const char *msg)`: Prints an error message and exits the program.
27 * - `int processCommand(char *buffer, int sockfd)`: Sends a command to the server
28 * and processes the response.
29 * - `int main(int argc, char *argv[])`: The main function that handles
30 * argument parsing, socket creation, connection, and command processing.
31 *
32 * ## Example
33 *
34 * To connect to a server at `localhost` on port `8080` and send the commands
35 * `HELLO` and `STATUS`:
36 *
37 * ```
38 * ./sddslogclient localhost 8080 HELLO STATUS
39 * ```
40 *
41 * After sending the initial commands, the client will enter interactive mode
42 * where additional commands can be entered until `disconnect` is typed.
43 *
44 * @copyright
45 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
46 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
47 *
48 * @license
49 * This file is distributed under the terms of the Software License Agreement
50 * found in the file LICENSE included with this distribution.
51 *
52 * @author M. Borland, R. Soliday
53 */
54
55#include <stdio.h>
56#include <stdlib.h>
57#include <unistd.h>
58#include <string.h>
59#include <sys/types.h>
60#include <sys/socket.h>
61#include <netinet/in.h>
62#include <netdb.h>
63
64#define BUFLEN 16384
65
66/* Error handling function */
67void error_exit(const char *msg) {
68 perror(msg);
69 exit(EXIT_FAILURE);
70}
71
72/* Process a single command */
73int process_command(char *buffer, int sockfd) {
74 ssize_t n;
75
76 n = write(sockfd, buffer, strlen(buffer));
77 if (n < 0)
78 error_exit("ERROR writing to socket");
79
80 memset(buffer, 0, BUFLEN);
81 n = read(sockfd, buffer, BUFLEN - 1);
82 if (n < 0)
83 error_exit("ERROR reading from socket");
84
85 printf("%s\n", buffer);
86 return n;
87}
88
89/* Main function */
90int main(int argc, char *argv[]) {
91 int sockfd, portno, arg_index;
92 struct sockaddr_in serv_addr;
93 struct hostent *server;
94 int persist = 1;
95
96 char buffer[BUFLEN];
97
98 if (argc < 3) {
99 fprintf(stderr, "Usage: %s hostname port [<command> [<command> ...]]\n", argv[0]);
100 exit(EXIT_FAILURE);
101 }
102
103 portno = atoi(argv[2]);
104 sockfd = socket(AF_INET, SOCK_STREAM, 0);
105 if (sockfd < 0)
106 error_exit("ERROR opening socket");
107
108 server = gethostbyname(argv[1]);
109 if (server == NULL) {
110 fprintf(stderr, "ERROR, no such host\n");
111 exit(EXIT_FAILURE);
112 }
113
114 memset(&serv_addr, 0, sizeof(serv_addr));
115 serv_addr.sin_family = AF_INET;
116 memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
117 serv_addr.sin_port = htons(portno);
118
119 if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
120 error_exit("ERROR connecting");
121
122 for (arg_index = 3; persist && arg_index < argc; arg_index++) {
123 if (snprintf(buffer, BUFLEN, "%s\n", argv[arg_index]) >= BUFLEN) {
124 fprintf(stderr, "ERROR: Command too long\n");
125 continue;
126 }
127
128 if (strcmp(buffer, "disconnect\n") == 0)
129 persist = 0;
130
131 printf("Processing command: %s", buffer);
132 fflush(stdout);
133
134 process_command(buffer, sockfd);
135 }
136
137 while (persist) {
138 printf("Please enter the message: ");
139 fflush(stdout);
140
141 memset(buffer, 0, BUFLEN);
142 if (fgets(buffer, BUFLEN - 1, stdin) == NULL)
143 break;
144
145 if (strcmp(buffer, "disconnect\n") == 0)
146 persist = 0;
147
148 process_command(buffer, sockfd);
149 }
150
151 close(sockfd);
152 return EXIT_SUCCESS;
153}