]> git.sur5r.net Git - tio/blob - src/options.c
Imported Upstream version 1.14
[tio] / src / options.c
1 /*
2  * tio - a simple TTY terminal I/O application
3  *
4  * Copyright (c) 2014-2016  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 <sys/types.h>
23 #include <sys/stat.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <errno.h>
28 #include <getopt.h>
29 #include <termios.h>
30 #include <limits.h>
31 #include "config.h"
32 #include "tio/options.h"
33 #include "tio/error.h"
34
35 struct option_t option =
36 {
37     "",       // Device name
38     false,    // No log
39     "",       // Log filename
40     false,    // No autoconnect
41     0,        // No output delay
42     {},
43     115200,   // Baudrate
44     8,        // Databits
45     "none",   // Flow
46     1,        // Stopbits
47     "none"    // Parity
48 };
49
50 void print_options_help(char *argv[])
51 {
52     printf("Usage: %s [<options>] <tty device>\n", argv[0]);
53     printf("\n");
54     printf("Options:\n");
55     printf("  -b, --baudrate <bps>        Baud rate (default: 115200)\n");
56     printf("  -d, --databits 5|6|7|8      Data bits (default: 8)\n");
57     printf("  -f, --flow hard|soft|none   Flow control (default: none)\n");
58     printf("  -s, --stopbits 1|2          Stop bits (default: 1)\n");
59     printf("  -p, --parity odd|even|none  Parity (default: none)\n");
60     printf("  -o, --output-delay <ms>     Output delay (default: 0)\n");
61     printf("  -n, --no-autoconnect        Disable automatic connect\n");
62     printf("  -l, --log <filename>        Log to file\n");
63     printf("  -v, --version               Display version\n");
64     printf("  -h, --help                  Display help\n");
65     printf("\n");
66     printf("In session, press ctrl-t + q to quit.\n");
67     printf("\n");
68 }
69
70 void parse_options(int argc, char *argv[])
71 {
72     int c;
73     int baudrate;
74
75     if (argc == 1)
76     {
77         print_options_help(argv);
78         exit(EXIT_SUCCESS);
79     }
80
81     /* Set default termios settings:
82      * (115200 baud, 8 data bits, no flow control, 1 stop bit, no parity) */
83     bzero(&option.tio, sizeof(option.tio));
84     option.tio.c_cflag = B115200 | CS8;
85
86     /* Set default output delay */
87     option.output_delay = 0;
88
89     while (1)
90     {
91         static struct option long_options[] =
92         {
93             {"baudrate",       required_argument, 0, 'b'},
94             {"databits",       required_argument, 0, 'd'},
95             {"flow",           required_argument, 0, 'f'},
96             {"stopbits",       required_argument, 0, 's'},
97             {"parity",         required_argument, 0, 'p'},
98             {"output-delay",   required_argument, 0, 'o'},
99             {"no-autoconnect", no_argument,       0, 'n'},
100             {"log",            required_argument, 0, 'l'},
101             {"version",        no_argument,       0, 'v'},
102             {"help",           no_argument,       0, 'h'},
103             {0,                0,                 0,  0 }
104         };
105
106         /* getopt_long stores the option index here */
107         int option_index = 0;
108
109         /* Parse argument using getopt_long */
110         c = getopt_long(argc, argv, "b:d:f:s:p:o:nl:vh", long_options, &option_index);
111
112         /* Detect the end of the options */
113         if (c == -1)
114             break;
115
116         switch (c)
117         {
118             case 0:
119                 /* If this option sets a flag, do nothing else now */
120                 if (long_options[option_index].flag != 0)
121                     break;
122                 printf("option %s", long_options[option_index].name);
123                 if (optarg)
124                     printf(" with arg %s", optarg);
125                 printf("\n");
126                 break;
127
128             case 'b':
129                 option.baudrate = baudrate = atoi(optarg);
130                 switch (baudrate)
131                 {
132                     case 0:
133                         baudrate = B0;
134                         break;
135                     case 50:
136                         baudrate = B50;
137                         break;
138                     case 75:
139                         baudrate = B75;
140                         break;
141                     case 110:
142                         baudrate = B110;
143                         break;
144                     case 134:
145                         baudrate = B134;
146                         break;
147                     case 150:
148                         baudrate = B150;
149                         break;
150                     case 300:
151                         baudrate = B300;
152                         break;
153                     case 600:
154                         baudrate = B600;
155                         break;
156                     case 1200:
157                         baudrate = B1200;
158                         break;
159                     case 2400:
160                         baudrate = B2400;
161                         break;
162                     case 4800:
163                         baudrate = B4800;
164                         break;
165                     case 9600:
166                         baudrate = B9600;
167                         break;
168                     case 19200:
169                         baudrate = B19200;
170                         break;
171                     case 38400:
172                         baudrate = B38400;
173                         break;
174                     case 57600:
175                         baudrate = B57600;
176                         break;
177                     case 115200:
178                         baudrate = B115200;
179                         break;
180                     case 230400:
181                         baudrate = B230400;
182                         break;
183                     case 460800:
184                         baudrate = B460800;
185                         break;
186                     case 500000:
187                         baudrate = B500000;
188                         break;
189                     case 576000:
190                         baudrate = B576000;
191                         break;
192                     case 921600:
193                         baudrate = B921600;
194                         break;
195                     case 1000000:
196                         baudrate = B1000000;
197                         break;
198                     case 1152000:
199                         baudrate = B1152000;
200                         break;
201                     case 1500000:
202                         baudrate = B1500000;
203                         break;
204                     case 2000000:
205                         baudrate = B2000000;
206                         break;
207                     case 2500000:
208                         baudrate = B2500000;
209                         break;
210                     case 3000000:
211                         baudrate = B3000000;
212                         break;
213                     case 3500000:
214                         baudrate = B3500000;
215                         break;
216                     case 4000000:
217                         baudrate = B4000000;
218                         break;
219                     default:
220                         error_printf("Invalid baud rate");
221                         exit(EXIT_FAILURE);
222                 }
223
224                 cfsetispeed(&option.tio, baudrate);
225                 cfsetospeed(&option.tio, baudrate);
226
227                 break;
228
229             case 'd':
230                 option.databits = atoi(optarg);
231                 option.tio.c_cflag &= ~CSIZE;
232                 switch (option.databits)
233                 {
234                     case 5:
235                         option.tio.c_cflag |= CS5;
236                         break;
237                     case 6:
238                         option.tio.c_cflag |= CS6;
239                         break;
240                     case 7:
241                         option.tio.c_cflag |= CS7;
242                         break;
243                     case 8:
244                         option.tio.c_cflag |= CS8;
245                         break;
246                     default:
247                         error_printf("Invalid data bits");
248                         exit(EXIT_FAILURE);
249                 }
250                 break;
251
252             case 'f':
253                 option.flow = optarg;
254
255                 if (strcmp("hard", optarg) == 0)
256                 {
257                     option.tio.c_cflag |= CRTSCTS;
258                     option.tio.c_iflag &= ~(IXON | IXOFF | IXANY);
259                 }
260                 else if (strcmp("soft", optarg) == 0)
261                 {
262                     option.tio.c_cflag &= ~CRTSCTS;
263                     option.tio.c_iflag |= IXON | IXOFF;
264                 }
265                 else if (strcmp("none", optarg) == 0)
266                 {
267                     option.tio.c_cflag &= ~CRTSCTS;
268                     option.tio.c_iflag &= ~(IXON | IXOFF | IXANY);
269                 }
270                 else
271                 {
272                     error_printf("Invalid flow control");
273                     exit(EXIT_FAILURE);
274                 }
275                 break;
276
277             case 's':
278                 option.stopbits = atoi(optarg);
279                 switch (option.stopbits)
280                 {
281                     case 1:
282                         option.tio.c_cflag &= ~CSTOPB;
283                         break;
284                     case 2:
285                         option.tio.c_cflag |= CSTOPB;
286                         break;
287                     default:
288                         error_printf("Invalid stop bits");
289                         exit(EXIT_FAILURE);
290                 }
291                 break;
292
293             case 'p':
294                 option.parity = optarg;
295
296                 if (strcmp("odd", optarg) == 0)
297                 {
298                     option.tio.c_cflag |= PARENB;
299                     option.tio.c_cflag |= PARODD;
300                 }
301                 else if (strcmp("even", optarg) == 0)
302                 {
303                     option.tio.c_cflag |= PARENB;
304                     option.tio.c_cflag &= ~PARODD;
305                 }
306                 else if (strcmp("none", optarg) == 0)
307                     option.tio.c_cflag &= ~PARENB;
308                 else
309                 {
310                     error_printf("Invalid parity");
311                     exit(EXIT_FAILURE);
312                 }
313                 break;
314
315             case 'o':
316                 option.output_delay = atoi(optarg);
317                 break;
318
319             case 'n':
320                 option.no_autoconnect = true;
321                 break;
322
323             case 'l':
324                 option.log = true;
325                 option.log_filename = optarg;
326                 break;
327
328             case 'v':
329                 printf("tio v%s\n", VERSION);
330                 printf("Copyright (c) 2014-2016 Martin Lund\n");
331                 printf("\n");
332                 printf("License GPLv2: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>.\n");
333                 printf("This is free software: you are free to change and redistribute it.\n");
334                 printf("There is NO WARRANTY, to the extent permitted by law.\n");
335                 exit(EXIT_SUCCESS);
336                 break;
337
338             case 'h':
339                 print_options_help(argv);
340                 exit(EXIT_SUCCESS);
341                 break;
342
343             case '?':
344                 /* getopt_long already printed an error message */
345                 exit(EXIT_FAILURE);
346                 break;
347
348             default:
349                 exit(EXIT_FAILURE);
350         }
351     }
352
353     /* Assume first non-option is the tty device name */
354     if (optind < argc)
355         option.tty_device = argv[optind++];
356
357     if (strlen(option.tty_device) == 0)
358     {
359         error_printf("Missing device name");
360         exit(EXIT_FAILURE);
361     }
362
363     /* Print any remaining command line arguments (unknown options) */
364     if (optind < argc)
365     {
366         printf("Error: unknown arguments: ");
367         while (optind < argc)
368             printf("%s ", argv[optind++]);
369         printf("\n");
370         exit(EXIT_FAILURE);
371     }
372 }