FreeCalypso > hg > freecalypso-tools
diff miscutil/make-imeisv.c @ 744:2dcfad8a3ed0
make-imeisv utility written
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 19 Oct 2020 06:35:35 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/miscutil/make-imeisv.c Mon Oct 19 06:35:35 2020 +0000 @@ -0,0 +1,76 @@ +/* + * This utility constructs a 16-digit IMEISV from a 15-digit IMEI + * (which must have a valid Luhn check digit) and a 2-digit SV field. + * It is intended for use in shell scripts. + */ + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +parse_imei_arg(input, buf) + char *input, *buf; +{ + char *cp; + int i; + + cp = input; + if (!isdigit(*cp)) { +inv: fprintf(stderr, + "error: IMEI argument must have 15 decimal digits\n"); + exit(1); + } + for (i = 0; i < 15; i++) { + if (ispunct(*cp)) + cp++; + if (!isdigit(*cp)) + goto inv; + buf[i] = *cp++; + } + if (*cp) + goto inv; +} + +check_luhn(digits) + char *digits; +{ + int i, dig, sum; + + sum = 0; + for (i = 0; i < 14; i++) { + dig = digits[i] - '0'; + if (i & 1) { + dig *= 2; + if (dig > 9) + dig -= 9; + } + sum += dig; + } + dig = sum % 10; + if (dig) + dig = 10 - dig; + if (digits[14] != dig + '0') { + fprintf(stderr, "error: given IMEI fails Luhn check\n"); + exit(1); + } +} + +main(argc, argv) + char **argv; +{ + char imeibuf[15]; + + if (argc != 3) { + fprintf(stderr, "usage: %s IMEI SV\n", argv[0]); + exit(1); + } + parse_imei_arg(argv[1], imeibuf); + check_luhn(imeibuf); + if (!isdigit(argv[2][0]) || !isdigit(argv[2][1]) || argv[2][2]) { + fprintf(stderr, + "error: SV argument must have 2 decimal digits\n"); + exit(1); + } + printf("%.8s-%.6s-%s\n", imeibuf, imeibuf + 8, argv[2]); + exit(0); +}