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