Changes: * Move network interface configuration logic from bin/pattyd.c to bin/if.c; implement a more robust state machine * Move KISS TNC configuration code from bin/pattyd.c to bin/kiss.c * Ensure configuration file name, line number, and erroneous part of an expression are clearly indicated upon failure Other changes: * Improve bin/Makefile to rebuild objects when accompanying header files change * Refer to HEADERS_SUBDIR, not HEADER_SUBDIR, in Makefiles
134 lines
3.3 KiB
C
134 lines
3.3 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <patty/bin/if.h>
|
|
|
|
enum mode {
|
|
MODE_NONE,
|
|
MODE_IFNAME,
|
|
MODE_IFOPTS,
|
|
MODE_IFADDR,
|
|
MODE_KISS,
|
|
MODE_BAUD,
|
|
MODE_FLOW
|
|
};
|
|
|
|
static int eprintf(patty_bin_if_data *data, const char *format, ...) {
|
|
int ret;
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
|
|
ret = vsnprintf(data->err, sizeof(data->err)-1, format, args);
|
|
|
|
va_end(args);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int patty_bin_if_config(patty_bin_if_data *data, int argc, char **argv) {
|
|
enum mode mode = MODE_NONE;
|
|
patty_kiss_tnc_info *info = &data->info;
|
|
|
|
int i;
|
|
|
|
for (i=0; i<argc; i++) {
|
|
switch (mode) {
|
|
case MODE_NONE:
|
|
if (strcmp(argv[i], "if") != 0) {
|
|
eprintf(data, "Unexpected start of expression '%s'",
|
|
argv[i]);
|
|
|
|
goto error_invalid;
|
|
} else {
|
|
mode = MODE_IFNAME;
|
|
}
|
|
|
|
break;
|
|
|
|
case MODE_IFNAME:
|
|
data->name = argv[i];
|
|
|
|
mode = MODE_IFOPTS;
|
|
|
|
break;
|
|
|
|
case MODE_IFOPTS:
|
|
if (strcmp(argv[i], "ax25") == 0) {
|
|
mode = MODE_IFADDR;
|
|
} else if (strcmp(argv[i], "kiss") == 0) {
|
|
mode = MODE_KISS;
|
|
} else if (strcmp(argv[i], "baud") == 0) {
|
|
mode = MODE_BAUD;
|
|
} else if (strcmp(argv[i], "flow") == 0) {
|
|
mode = MODE_FLOW;
|
|
} else {
|
|
eprintf(data, "Invalid parameter '%s'", argv[i]);
|
|
|
|
goto error_invalid;
|
|
}
|
|
|
|
break;
|
|
|
|
case MODE_IFADDR:
|
|
if (patty_ax25_pton(argv[i], &data->addr) < 0) {
|
|
eprintf(data, "Invalid AX.25 address '%s': %s",
|
|
argv[i], strerror(errno));
|
|
|
|
goto error_invalid;
|
|
}
|
|
|
|
mode = MODE_IFOPTS;
|
|
|
|
break;
|
|
|
|
case MODE_KISS:
|
|
data->type = PATTY_AX25_IF_KISS_TNC;
|
|
info->flags |= PATTY_KISS_TNC_DEVICE;
|
|
info->device = argv[i];
|
|
|
|
mode = MODE_IFOPTS;
|
|
|
|
break;
|
|
|
|
case MODE_BAUD:
|
|
if (!(argv[i][0] >= '0' && argv[i][0] <= '9')) {
|
|
eprintf(data, "Invalid baud rate '%s'", argv[i]);
|
|
|
|
goto error_invalid;
|
|
}
|
|
|
|
info->flags |= PATTY_KISS_TNC_BAUD;
|
|
info->baud = atoi(argv[i]);
|
|
|
|
mode = MODE_IFOPTS;
|
|
|
|
break;
|
|
|
|
case MODE_FLOW:
|
|
if (strcmp(argv[i], "crtscts") == 0) {
|
|
info->flags |= PATTY_KISS_TNC_FLOW;
|
|
info->flow = PATTY_KISS_TNC_FLOW_CRTSCTS;
|
|
} else if (strcmp(argv[i], "xonxoff") == 0) {
|
|
info->flags |= PATTY_KISS_TNC_FLOW;
|
|
info->flow = PATTY_KISS_TNC_FLOW_XONXOFF;
|
|
} else {
|
|
eprintf(data, "Invalid flow control '%s'", argv[i]);
|
|
|
|
goto error_invalid;
|
|
}
|
|
|
|
mode = MODE_IFOPTS;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
|
|
error_invalid:
|
|
return -1;
|
|
}
|