1 /* spdsend.c -- Send SSIP commands to Speech Dispatcher
2    Author: Milan Zamazal <pdm@brailcom.org>
3 */
4 
5 /* Copyright (C) 2004 Brailcom, o.p.s.
6 
7    COPYRIGHT NOTICE
8 
9    This program is free software; you can redistribute it and/or modify it
10    under the terms of the GNU General Public License as published by the Free
11    Software Foundation; either version 2, or (at your option) any later
12    version.
13 
14    This program is distributed in the hope that it will be useful, but
15    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17    for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <https://www.gnu.org/licenses/>.
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include "spdsend.h"
33 
34 const char *const SPDSEND_VERSION = "0.0.0";
35 
36 #ifndef HAVE_GETLINE
37 /*
38  * Added by Willie Walker - getline was a GNU libc extension, later adopted
39  * in the POSIX.1-2008 standard, but not yet found on all systems.
40  */
41 #define BUFFER_LEN 256
getline(char ** lineptr,size_t * n,FILE * f)42 ssize_t getline(char **lineptr, size_t * n, FILE * f)
43 {
44 	int ch;
45 	size_t m = 0;
46 	ssize_t buf_len = 0;
47 	char *buf = NULL;
48 	char *p = NULL;
49 
50 	if (errno != 0) {
51 		errno = 0;
52 	}
53 	while ((ch = getc(f)) != EOF) {
54 		if (errno != 0)
55 			return -1;
56 		if (m++ >= buf_len) {
57 			buf_len += BUFFER_LEN;
58 			buf = (char *)realloc(buf, buf_len + 1);
59 			if (buf == NULL) {
60 				return -1;
61 			}
62 			p = buf + buf_len - BUFFER_LEN;
63 		}
64 		*p = ch;
65 		p++;
66 		if (ch == '\n')
67 			break;
68 	}
69 	if (m == 0) {
70 		return -1;
71 	} else {
72 		*p = '\0';
73 		*lineptr = buf;
74 		*n = m;
75 		return m;
76 	}
77 }
78 #endif /* HAVE_GETLINE */
79 
usage(const char * const message)80 static void usage(const char *const message)
81 {
82 	if (message != NULL)
83 		fprintf(stderr, "spdsend: %s\n", message);
84 	fprintf(stderr,
85 		"usage: spdsend { --open SERVER PORT | --close ID | --send ID }\n");
86 	exit(EXIT_ERROR);
87 }
88 
string_to_number(const char * string,long low_limit,long high_limit)89 static long string_to_number(const char *string,
90 			     long low_limit, long high_limit)
91 {
92 	char *tailptr;
93 	errno = 0;
94 	long int number = strtol(string, &tailptr, 0);
95 	if (errno || *tailptr || number < low_limit || number > high_limit)
96 		usage("Invalid parameter");
97 	return number;
98 }
99 
main(int argc,char ** argv)100 int main(int argc, char **argv)
101 {
102 	if (argc < 2)
103 		usage("Invalid number of arguments");
104 
105 	{
106 		const char *const action = argv[1];
107 		Success(*function) (Stream, Connection_Id);
108 		Connection_Id conn_id;
109 		char *host;
110 		int port;
111 
112 		if (!strcmp(action, "--version")) {
113 			printf("spdsend %s\n", SPDSEND_VERSION);
114 			exit(EXIT_OK);
115 		}
116 
117 		const int action_is_open = strcmp(action, "--open") == 0;
118 		if (action_is_open) {
119 			if (argc != 4)
120 				usage("Invalid number of arguments");
121 			host = argv[2];
122 			port = string_to_number(argv[3], 0, 65535);
123 		} else {
124 			if (argc != 3)
125 				usage("Invalid number of arguments");
126 			conn_id = string_to_number(argv[2], CONNECTION_ID_MIN,
127 						   CONNECTION_ID_MAX);
128 			if (!strcmp(action, "--close"))
129 				function = close_connection;
130 			else if (!strcmp(action, "--send"))
131 				function = send_command;
132 			else
133 				usage("Invalid option");
134 		}
135 
136 		{
137 			Stream server = open_server();
138 			if (server == NONE)
139 				return EXIT_ERROR;
140 
141 			{
142 				int result = (action_is_open
143 					      ? open_connection(server, host,
144 								port)
145 					      : function(server, conn_id));
146 				return (result == OK ? EXIT_OK : EXIT_ERROR);
147 			}
148 		}
149 	}
150 }
151