changeset 23:e56bb9f09ff1

sms-encode-text: port over -e option from fcup-smsend
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 02 Sep 2023 19:22:05 +0000
parents 8a2038c6a156
children f0139d74d3aa
files enc-text/gsm7.c enc-text/main.c enc-text/ucs2.c libcoding/gsm7_encode.c libcoding/utf8_decode2.c
diffstat 5 files changed, 106 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/enc-text/gsm7.c	Thu Aug 31 23:03:38 2023 +0000
+++ b/enc-text/gsm7.c	Sat Sep 02 19:22:05 2023 +0000
@@ -10,7 +10,7 @@
 #include <unistd.h>
 #include "defs.h"
 
-extern int utf8_input;
+extern int utf8_input, allow_escape;
 extern int concat_enable, concat_refno_set;
 extern char msgtext[MAX_MSG_CHARS*2+2];
 extern u_char concat_refno;
@@ -29,7 +29,7 @@
 		exit(1);
 	}
 	rc = latin1_to_gsm7(msgtext, msgtext_gsm7, MAX_MSG_CHARS,
-				&msgtext_gsmlen);
+				&msgtext_gsmlen, allow_escape);
 	if (rc == -1) {
 		fprintf(stderr, "error: message not valid for GSM7 charset\n");
 		exit(1);
@@ -38,6 +38,11 @@
 		fprintf(stderr, "error: message too long for max concat SMS\n");
 		exit(1);
 	}
+	if (rc == -3) {
+		fprintf(stderr,
+			"error: message contains invalid backslash escape\n");
+		exit(1);
+	}
 	if (msgtext_gsmlen <= 160) {
 		fputs("dcs 0 septet\nmsg ", stdout);
 		if (msgtext_gsmlen)
--- a/enc-text/main.c	Thu Aug 31 23:03:38 2023 +0000
+++ b/enc-text/main.c	Sat Sep 02 19:22:05 2023 +0000
@@ -10,9 +10,9 @@
 #include <unistd.h>
 #include "defs.h"
 
-int utf8_input, ucs2_mode;
+int utf8_input, ucs2_mode, allow_escape;
 int concat_enable, concat_refno_set;
-char msgtext[MAX_MSG_CHARS*2+2];
+char msgtext[MAX_MSG_CHARS*3+2];
 u_char concat_refno;
 
 process_cmdline(argc, argv)
@@ -22,7 +22,7 @@
 	extern int optind;
 	extern char *optarg;
 
-	while ((c = getopt(argc, argv, "cC:uU")) != EOF) {
+	while ((c = getopt(argc, argv, "cC:euU")) != EOF) {
 		switch (c) {
 		case 'c':
 			concat_enable = 1;
@@ -32,6 +32,9 @@
 			concat_refno = strtoul(optarg, 0, 0);
 			concat_refno_set = 1;
 			continue;
+		case 'e':
+			allow_escape = 1;
+			continue;
 		case 'u':
 			utf8_input = 1;
 			continue;
@@ -49,7 +52,7 @@
 	}
 	if (argc < optind + 1)
 		return(0);
-	if (strlen(argv[optind]) > MAX_MSG_CHARS*2) {
+	if (strlen(argv[optind]) > MAX_MSG_CHARS*3) {
 		fprintf(stderr, "error: message argument is too long\n");
 		exit(1);
 	}
--- a/enc-text/ucs2.c	Thu Aug 31 23:03:38 2023 +0000
+++ b/enc-text/ucs2.c	Sat Sep 02 19:22:05 2023 +0000
@@ -10,6 +10,7 @@
 #include <unistd.h>
 #include "defs.h"
 
+extern int allow_escape;
 extern int concat_enable, concat_refno_set;
 extern char msgtext[MAX_MSG_CHARS*2+2];
 extern u_char concat_refno;
@@ -23,7 +24,8 @@
 	u_char udh[6], ucs2_be[140];
 	unsigned pos, remain, chunk;
 
-	rc = utf8_to_ucs2(msgtext, msgtext_uni, MAX_MSG_UNI, &msgtext_unilen);
+	rc = utf8_to_ucs2(msgtext, msgtext_uni, MAX_MSG_UNI, &msgtext_unilen,
+			  allow_escape);
 	if (rc == -1) {
 		fprintf(stderr, "error: invalid UTF-8 message\n");
 		exit(1);
@@ -32,6 +34,11 @@
 		fprintf(stderr, "error: message too long for max concat SMS\n");
 		exit(1);
 	}
+	if (rc == -3) {
+		fprintf(stderr,
+			"error: message contains invalid backslash escape\n");
+		exit(1);
+	}
 	if (msgtext_unilen <= 70) {
 		fputs("dcs 8 octet\nmsg ", stdout);
 		if (msgtext_unilen) {
--- a/libcoding/gsm7_encode.c	Thu Aug 31 23:03:38 2023 +0000
+++ b/libcoding/gsm7_encode.c	Sat Sep 02 19:22:05 2023 +0000
@@ -4,10 +4,40 @@
  */
 
 #include <sys/types.h>
+#include <ctype.h>
 
 extern u_char gsm7_encode_table[256];
 
-latin1_to_gsm7(inbuf, outbuf, outmax, outlenp)
+static unsigned
+handle_escape(ipp)
+	u_char **ipp;
+{
+	unsigned c;
+
+	c = *(*ipp)++;
+	if (c >= '0' && c <= '7' && isxdigit(**ipp)) {
+		c = ((c - '0') << 4) | decode_hex_digit(*(*ipp)++);
+		return c;
+	}
+	switch (c) {
+	case 'n':
+		return '\n';
+	case 'r':
+		return '\r';
+	case 'e':
+		return 0x1B;
+	case 'E':		/* Euro currency symbol */
+		return 0xE5;
+	case '"':
+	case '\\':
+		c = gsm7_encode_table[c];
+		return c;
+	default:
+		return 0xFF;
+	}
+}
+
+latin1_to_gsm7(inbuf, outbuf, outmax, outlenp, allow_escape)
 	u_char *inbuf, *outbuf;
 	unsigned outmax, *outlenp;
 {
@@ -15,9 +45,15 @@
 	unsigned outcnt = 0, c, n;
 
 	while (c = *ip++) {
-		c = gsm7_encode_table[c];
-		if (c == 0xFF)
-			return(-1);
+		if (c == '\\' && allow_escape) {
+			c = handle_escape(&ip);
+			if (c == 0xFF)
+				return(-3);
+		} else {
+			c = gsm7_encode_table[c];
+			if (c == 0xFF)
+				return(-1);
+		}
 		if (c & 0x80)
 			n = 2;
 		else
--- a/libcoding/utf8_decode2.c	Thu Aug 31 23:03:38 2023 +0000
+++ b/libcoding/utf8_decode2.c	Sat Sep 02 19:22:05 2023 +0000
@@ -4,8 +4,44 @@
  */
 
 #include <sys/types.h>
+#include <ctype.h>
 
-utf8_to_ucs2(inbuf, outbuf, outmax, outlenp)
+static int
+handle_escape(ipp, outp)
+	u_char **ipp;
+	unsigned *outp;
+{
+	unsigned c, n, acc;
+
+	c = *(*ipp)++;
+	switch (c) {
+	case '"':
+	case '\\':
+		*outp = c;
+		return(0);
+	case 'n':
+		*outp = '\n';
+		return(0);
+	case 'r':
+		*outp = '\r';
+		return(0);
+	case 'u':
+		acc = 0;
+		for (n = 0; n < 4; n++) {
+			c = *(*ipp)++;
+			if (!isxdigit(c))
+				return(-3);
+			acc <<= 4;
+			acc |= decode_hex_digit(c);
+		}
+		*outp = acc;
+		return(0);
+	default:
+		return(-3);
+	}
+}
+
+utf8_to_ucs2(inbuf, outbuf, outmax, outlenp, allow_escape)
 	u_char *inbuf;
 	u_short *outbuf;
 	unsigned outmax, *outlenp;
@@ -13,8 +49,15 @@
 	u_char *ip = inbuf;
 	u_short *op = outbuf;
 	unsigned outcnt = 0, c, n, uni;
+	int rc;
 
 	while (c = *ip++) {
+		if (c == '\\' && allow_escape) {
+			rc = handle_escape(&ip, &uni);
+			if (rc < 0)
+				return(rc);
+			goto gotuni;
+		}
 		if (c < 0x80) {
 			uni = c;
 			goto gotuni;