diff options
Diffstat (limited to 'xpp/astribank_allow.c')
-rw-r--r-- | xpp/astribank_allow.c | 226 |
1 files changed, 13 insertions, 213 deletions
diff --git a/xpp/astribank_allow.c b/xpp/astribank_allow.c index 18c7573..39b7521 100644 --- a/xpp/astribank_allow.c +++ b/xpp/astribank_allow.c @@ -34,6 +34,7 @@ #include "mpp.h" #include "mpptalk.h" #include <debug.h> +#include "astribank_license.h" static const char rcsid[] = "$Id$"; @@ -49,6 +50,8 @@ static void usage() fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n"); fprintf(stderr, "\t\t[-w] # Write capabilities to EEPROM, otherwise read capabilities\n"); fprintf(stderr, "\t\t[-f filename] # License filename (stdin/stdout if not specified)\n\n"); + fprintf(stderr, "\t\t[-m num] # Numeric code of License markers to generate\n"); + license_markers_help("\t", stderr); exit(1); } @@ -70,216 +73,6 @@ static int capabilities_burn( return 0; } -static int bin_to_file(void *buf, int len, FILE *f) -{ - static int bytes_on_line; - unsigned char *p = buf; - if (buf == NULL) { - if (bytes_on_line != 0) { - if (fprintf(f, "\n") != 1) - return -1; - bytes_on_line = 0; - } - return 0; - } - int i; - for (i = 0; i < len; i++) { - if (fprintf(f, "%02x", *p++) != 2) - return -1; - bytes_on_line++; - if (bytes_on_line >= 16) { - if (fprintf(f, "\n") != 1) - return -1; - bytes_on_line = 0; - } - } - return 0; -} - -static int write_to_file(struct eeprom_table *eeprom_table, struct capabilities *caps, struct capkey *key, FILE *f) -{ - fprintf(f, "-----BEGIN XORCOM LICENSE BLOCK-----\n"); - fprintf(f, "Version: 1.0\n"); - fprintf(f, "Timestamp: %u\n", caps->timestamp); - fprintf(f, "Serial: %.*s\n", LABEL_SIZE, eeprom_table->label); - fprintf(f, "Capabilities.Port.FXS: %d\n", caps->ports_fxs); - fprintf(f, "Capabilities.Port.FXO: %d\n", caps->ports_fxo); - fprintf(f, "Capabilities.Port.BRI: %d\n", caps->ports_bri); - fprintf(f, "Capabilities.Port.PRI: %d\n", caps->ports_pri); - fprintf(f, "Capabilities.Port.ECHO: %d\n", caps->ports_echo); - fprintf(f, "Capabilities.Twinstar: %d\n", CAP_EXTRA_TWINSTAR(caps)); - fprintf(f, "Data:\n"); - bin_to_file(eeprom_table, sizeof(*eeprom_table), f); - bin_to_file(caps, sizeof(*caps), f); - bin_to_file(key, sizeof(*key), f); - bin_to_file(NULL, 0, f); - fprintf(f, "-----END XORCOM LICENSE BLOCK-----\n"); - return 0; -} - -/* - * Removes whitespace on both sizes of the string. - * Returns a pointer to the first non-space char. The string - * is modified in place to trim trailing whitespace. - * If the whole string is whitespace, returns NULL. - */ -char *trim(char *s) -{ - int len = strlen(s); - while (len > 0 && isspace(s[len-1])) { - len--; - } - if (len == 0) - return NULL; - s[len] = '\0'; - while (isspace(*s)) - s++; - /* *s is not a space, since in this case we'd return NULL above */ - return s; -} - -int get_key_value(char *line, char **key, char **value) -{ - char *p = strchr(line, ':'); - if (p == NULL) - return -1; - *p = '\0'; - *key = trim(line); - *value = trim(p + 1); - return 0; -} - -static int hex_digit_to_int(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - else if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - else - return -1; -} - -static int str_to_bin(char *line, void *buf, int maxlen) -{ - static int offset; - unsigned char *p = buf; - if (strlen(line) % 2 != 0) - return -1; - while (offset < maxlen && *line) { - uint8_t value; - char c = hex_digit_to_int(*line++); - if (c < 0 || *line == '\0') - return -1; - value = c << 4; - c = hex_digit_to_int(*line++); - if (c < 0) - return -1; - value |= c; - p[offset++] = value; - } - if (offset == maxlen && *line) - return -1; - return offset; -} - -static int read_from_file(struct eeprom_table *eeprom_table, struct capabilities *caps, struct capkey *capkey, FILE *f) -{ - char buf[256]; - char *line, *key, *value; - int state = 0; - int lineno = 0; - struct table { - struct eeprom_table eeprom_table; - struct capabilities capabilities; - struct capkey capkey; - } PACKED table; - - memset(&table, 0, sizeof(struct table)); - /* - * states: - * 0: start - before BEGIN_LICENSE_BLOCK line. on BEGIN_LICENSE_BLOCK line goto 1. - * 1: read Version, goto 2. if not version line then error. - * 2: after BEGIN line. split line into key:value. if line is Data:, goto 3. - * 3: read binary data. if line is END_LICENSE_BLOCK goto 4. - * 4: END_LICENSE_BLOCK - ignore lines. - */ - while (fgets(buf, 256, f) != NULL) { - lineno++; - int len = strlen(buf); - if (len > 0 && buf[len-1] != '\n') { - ERR("Line %d: Line too long\n", lineno); - return -1; - } - line = trim(buf); - if (line == NULL) { - if (state > 0 && state < 4) { - ERR("Line %d: Empty line\n", lineno); - return -1; - } - else - continue; - } - switch (state) { - case 0: - if (strcmp(line, "-----BEGIN XORCOM LICENSE BLOCK-----") == 0) - state = 1; - else { - ERR("Line %d: Invalid license begin block\n", lineno); - return -1; - } - break; - case 1: - if (get_key_value(line, &key, &value) < 0) { - ERR("Line %d: Can't parse line\n", lineno); - return -1; - } - if (strcmp(key, "Version") == 0) { - if (strcmp(value, "1.0") == 0) { - state = 2; - } else { - ERR("Line %d: Unknown license file version '%s', need version '1.0'\n", lineno, value); - return -1; - } - } else { - ERR("Line %d: No license file version\n", lineno); - return -1; - } - break; - case 2: - if (get_key_value(line, &key, &value) < 0) { - ERR("Line %d: Can't parse line\n", lineno); - return -1; - } - if (strcmp(key, "Data") == 0) { - state = 3; - break; - } - break; - case 3: - if (strcmp(line, "-----END XORCOM LICENSE BLOCK-----") == 0) { - state = 4; - break; - } - if (str_to_bin(line, &table, sizeof(table)) < 0) { - ERR("Line %d: Error in data block\n", lineno); - return -1; - } - break; - case 4: - break; - - } - } - if (state != 4) { - ERR("Invalid license file\n"); - return -1; - } - memcpy(eeprom_table, &table.eeprom_table, sizeof(*eeprom_table)); - memcpy(caps, &table.capabilities, sizeof(*caps)); - memcpy(capkey, &table.capkey, sizeof(*capkey)); - return 0; -} - int main(int argc, char *argv[]) { char *devpath = NULL; @@ -287,8 +80,9 @@ int main(int argc, char *argv[]) struct eeprom_table eeprom_table; struct capabilities caps; struct capkey key; - const char options[] = "vd:D:wf:"; + const char options[] = "vd:D:wf:m:"; int do_write = 0; + unsigned int marker = LICENSE_MARKER_GENERIC; FILE *file; char *filename = NULL; int ret; @@ -317,6 +111,11 @@ int main(int argc, char *argv[]) case 'f': filename = optarg; break; + case 'm': + marker = strtoul(optarg, NULL, 0); + if (!license_marker_valid(marker)) + usage(); + break; case 'h': default: ERR("Unknown option '%c'\n", c); @@ -343,6 +142,7 @@ int main(int argc, char *argv[]) return 1; } if (do_write) { + int used_marker; /* update capabilities based on input file */ file = stdin; if (filename) { @@ -352,7 +152,7 @@ int main(int argc, char *argv[]) return 1; } } - ret = read_from_file(&eeprom_table, &caps, &key, file); + ret = read_from_file(&eeprom_table, &caps, &key, &used_marker, file); if (ret < 0) { ERR("Failed to read capabilities from file: %d\n", ret); return 1; @@ -372,7 +172,7 @@ int main(int argc, char *argv[]) return 1; } } - ret = write_to_file(&eeprom_table, &caps, &key, file); + ret = write_to_file(&eeprom_table, &caps, &key, marker, file); if (ret < 0) { ERR("Failed to write capabilities to file: %d\n", ret); return 1; |