1 /*
2 * tio - a simple TTY terminal I/O application
3 *
4 * Copyright (c) 2014-2018 Martin Lund
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA.
20 */
21
22 #include "config.h"
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <stdbool.h>
29 #include <errno.h>
30 #include <getopt.h>
31 #include <termios.h>
32 #include <limits.h>
33 #include "tio/options.h"
34 #include "tio/error.h"
35
36 /* Default options */
37 struct option_t option =
38 {
39 "", // Device name
40 115200, // Baudrate
41 8, // Databits
42 "none", // Flow
43 1, // Stopbits
44 "none", // Parity
45 0, // No output delay
46 false, // No autoconnect
47 false, // No log
48 false, // No local echo
49 false, // No timestamp
50 "", // Log filename
51 "" // Map string
52 };
53
print_help(char * argv[])54 void print_help(char *argv[])
55 {
56 printf("Usage: %s [<options>] <tty-device>\n", argv[0]);
57 printf("\n");
58 printf("Options:\n");
59 printf(" -b, --baudrate <bps> Baud rate (default: 115200)\n");
60 printf(" -d, --databits 5|6|7|8 Data bits (default: 8)\n");
61 printf(" -f, --flow hard|soft|none Flow control (default: none)\n");
62 printf(" -s, --stopbits 1|2 Stop bits (default: 1)\n");
63 printf(" -p, --parity odd|even|none Parity (default: none)\n");
64 printf(" -o, --output-delay <ms> Output delay (default: 0)\n");
65 printf(" -n, --no-autoconnect Disable automatic connect\n");
66 printf(" -e, --local-echo Do local echo\n");
67 printf(" -t, --timestamp Prefix each new line with a timestamp\n");
68 printf(" -l, --log <filename> Log to file\n");
69 printf(" -m, --map <flags> Map special characters\n");
70 printf(" -v, --version Display version\n");
71 printf(" -h, --help Display help\n");
72 printf("\n");
73 printf("See the man page for list of supported mapping flags.\n");
74 printf("\n");
75 printf("In session, press ctrl-t q to quit.\n");
76 printf("\n");
77 }
78
string_to_long(char * string)79 long string_to_long(char *string)
80 {
81 long result;
82 char *end_token;
83
84 errno = 0;
85 result = strtol(string, &end_token, 10);
86 if ((errno != 0) || (*end_token != 0))
87 {
88 error_printf("Invalid digit");
89 exit(EXIT_FAILURE);
90 }
91
92 return result;
93 }
94
parse_options(int argc,char * argv[])95 void parse_options(int argc, char *argv[])
96 {
97 int c;
98
99 if (argc == 1)
100 {
101 print_help(argv);
102 exit(EXIT_SUCCESS);
103 }
104
105 while (1)
106 {
107 static struct option long_options[] =
108 {
109 {"baudrate", required_argument, 0, 'b'},
110 {"databits", required_argument, 0, 'd'},
111 {"flow", required_argument, 0, 'f'},
112 {"stopbits", required_argument, 0, 's'},
113 {"parity", required_argument, 0, 'p'},
114 {"output-delay", required_argument, 0, 'o'},
115 {"no-autoconnect", no_argument, 0, 'n'},
116 {"local-echo", no_argument, 0, 'e'},
117 {"timestamp", no_argument, 0, 't'},
118 {"log", required_argument, 0, 'l'},
119 {"map", required_argument, 0, 'm'},
120 {"version", no_argument, 0, 'v'},
121 {"help", no_argument, 0, 'h'},
122 {0, 0, 0, 0 }
123 };
124
125 /* getopt_long stores the option index here */
126 int option_index = 0;
127
128 /* Parse argument using getopt_long */
129 c = getopt_long(argc, argv, "b:d:f:s:p:o:netl:m:vh", long_options, &option_index);
130
131 /* Detect the end of the options */
132 if (c == -1)
133 break;
134
135 switch (c)
136 {
137 case 0:
138 /* If this option sets a flag, do nothing else now */
139 if (long_options[option_index].flag != 0)
140 break;
141 printf("option %s", long_options[option_index].name);
142 if (optarg)
143 printf(" with arg %s", optarg);
144 printf("\n");
145 break;
146
147 case 'b':
148 option.baudrate = string_to_long(optarg);
149 break;
150
151 case 'd':
152 option.databits = string_to_long(optarg);
153 break;
154
155 case 'f':
156 option.flow = optarg;
157 break;
158
159 case 's':
160 option.stopbits = string_to_long(optarg);
161 break;
162
163 case 'p':
164 option.parity = optarg;
165 break;
166
167 case 'o':
168 option.output_delay = string_to_long(optarg);
169 break;
170
171 case 'n':
172 option.no_autoconnect = true;
173 break;
174
175 case 'e':
176 option.local_echo = true;
177 break;
178
179 case 't':
180 option.timestamp = true;
181 break;
182
183 case 'l':
184 option.log = true;
185 option.log_filename = optarg;
186 break;
187
188 case 'm':
189 option.map = optarg;
190 break;
191
192 case 'v':
193 printf("tio v%s\n", VERSION);
194 printf("Copyright (c) 2014-2018 Martin Lund\n");
195 printf("\n");
196 printf("License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>.\n");
197 printf("This is free software: you are free to change and redistribute it.\n");
198 printf("There is NO WARRANTY, to the extent permitted by law.\n");
199 exit(EXIT_SUCCESS);
200 break;
201
202 case 'h':
203 print_help(argv);
204 exit(EXIT_SUCCESS);
205 break;
206
207 case '?':
208 /* getopt_long already printed an error message */
209 exit(EXIT_FAILURE);
210 break;
211
212 default:
213 exit(EXIT_FAILURE);
214 }
215 }
216
217 /* Assume first non-option is the tty device name */
218 if (optind < argc)
219 option.tty_device = argv[optind++];
220
221 if (strlen(option.tty_device) == 0)
222 {
223 error_printf("Missing device name");
224 exit(EXIT_FAILURE);
225 }
226
227 /* Print any remaining command line arguments (unknown options) */
228 if (optind < argc)
229 {
230 printf("Error: unknown arguments: ");
231 while (optind < argc)
232 printf("%s ", argv[optind++]);
233 printf("\n");
234 exit(EXIT_FAILURE);
235 }
236 }
237