changeset 2:a16b1b9728f6

enc-text: sms-encode-text program written
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 05 Aug 2023 02:07:22 +0000
parents 13518c86b73c
children 367dce9bf5a7
files .hgignore enc-text/Makefile enc-text/concat_refno.c enc-text/defs.h enc-text/gsm7.c enc-text/main.c enc-text/ucs2.c
diffstat 7 files changed, 347 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sat Aug 05 02:06:14 2023 +0000
+++ b/.hgignore	Sat Aug 05 02:07:22 2023 +0000
@@ -1,3 +1,5 @@
 syntax: regexp
 
 \.[oa]$
+
+^enc-text/sms-encode-text$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/enc-text/Makefile	Sat Aug 05 02:07:22 2023 +0000
@@ -0,0 +1,21 @@
+CC=	gcc
+CFLAGS=	-O2
+PROG=	sms-encode-text
+OBJS=	concat_refno.o gsm7.o main.o ucs2.o
+LIBS=	../libcoding/libcoding.a
+
+INSTALL_PREFIX=	/opt/freecalypso
+
+INSTBIN=${INSTALL_PREFIX}/bin
+
+all:	${PROG}
+
+${PROG}:	${OBJS} ${LIBS}
+	${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS}
+
+install:	${PROG}
+	mkdir -p ${INSTBIN}
+	install -c ${PROG} ${INSTBIN}
+
+clean:
+	rm -f *.o *.out *errs ${PROG}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/enc-text/concat_refno.c	Sat Aug 05 02:07:22 2023 +0000
@@ -0,0 +1,60 @@
+/*
+ * This module contains the messy code for automatic generation and
+ * increment of concat SMS reference numbers.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int
+initial_seed()
+{
+	struct timeval tv;
+	u_char refno, *cp, *endp;
+
+	gettimeofday(&tv, 0);
+	cp = (u_char *) &tv;
+	endp = cp + sizeof(struct timeval);
+	refno = 0;
+	while (cp < endp)
+		refno ^= *cp++;
+	return refno;
+}
+
+get_concsms_refno_from_host_fs()
+{
+	char *homedir, statefile[MAXPATHLEN];
+	int fd, cc;
+	char buf[6];
+	u_char refno;
+
+	homedir = getenv("HOME");
+	if (!homedir) {
+		fprintf(stderr,
+		"error: no HOME= defined, needed for concat SMS refno\n");
+		exit(1);
+	}
+	sprintf(statefile, "%s/.concat_sms_refno", homedir);
+	fd = open(statefile, O_RDWR|O_CREAT, 0666);
+	if (fd < 0) {
+		perror(statefile);
+		exit(1);
+	}
+	cc = read(fd, buf, 5);
+	if (cc == 5 && buf[0] == '0' && buf[1] == 'x' && isxdigit(buf[2]) &&
+	    isxdigit(buf[3]) && buf[4] == '\n')
+		refno = strtoul(buf, 0, 16) + 1;
+	else
+		refno = initial_seed();
+	sprintf(buf, "0x%02X\n", refno);
+	lseek(fd, 0, SEEK_SET);
+	write(fd, buf, 5);
+	close(fd);
+	return refno;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/enc-text/defs.h	Sat Aug 05 02:07:22 2023 +0000
@@ -0,0 +1,6 @@
+/*
+ * Miscellaneous definitions for sms-encode-text utility.
+ */
+
+#define	MAX_MSG_CHARS	(153*255)
+#define	MAX_MSG_UNI	(67*255)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/enc-text/gsm7.c	Sat Aug 05 02:07:22 2023 +0000
@@ -0,0 +1,78 @@
+/*
+ * In this module we implement SMS encoding in GSM7.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "defs.h"
+
+extern int utf8_input;
+extern int concat_enable, concat_refno_set;
+extern char msgtext[MAX_MSG_CHARS*2+2];
+extern u_char concat_refno;
+
+gsm7_mode_main()
+{
+	u_char msgtext_gsm7[MAX_MSG_CHARS];
+	unsigned msgtext_gsmlen;
+	int rc;
+	unsigned nparts, n;
+	u_char udh[6];
+	unsigned pos, remain, chunk;
+
+	if (utf8_input && utf8_to_latin1(msgtext) < 0) {
+		fprintf(stderr, "error: invalid UTF-8 message\n");
+		exit(1);
+	}
+	rc = latin1_to_gsm7(msgtext, msgtext_gsm7, MAX_MSG_CHARS,
+				&msgtext_gsmlen);
+	if (rc == -1) {
+		fprintf(stderr, "error: message not valid for GSM7 charset\n");
+		exit(1);
+	}
+	if (rc == -2) {
+		fprintf(stderr, "error: message too long for max concat SMS\n");
+		exit(1);
+	}
+	if (msgtext_gsmlen <= 160) {
+		fputs("dcs 0 septet\nmsg ", stdout);
+		if (msgtext_gsmlen)
+			emit_hex_out(msgtext_gsm7, msgtext_gsmlen, stdout);
+		else
+			fputs("empty", stdout);
+		putchar('\n');
+		exit(0);
+	}
+	if (!concat_enable) {
+		fprintf(stderr, "error: message exceeds 160 chars\n");
+		exit(1);
+	}
+	if (!concat_refno_set)
+		concat_refno = get_concsms_refno_from_host_fs();
+	puts("dcs 0 septet");
+	nparts = (msgtext_gsmlen + 152) / 153;
+	udh[0] = 5;
+	udh[1] = 0x00;
+	udh[2] = 0x03;
+	udh[3] = concat_refno;
+	udh[4] = nparts;
+	pos = 0;
+	remain = msgtext_gsmlen;
+	for (n = 1; n <= nparts; n++) {
+		udh[5] = n;
+		chunk = 153;
+		if (chunk > remain)
+			chunk = remain;
+		fputs("msg-udh ", stdout);
+		emit_hex_out(udh, 6, stdout);
+		emit_hex_out(msgtext_gsm7 + pos, chunk, stdout);
+		putchar('\n');
+		pos += chunk;
+		remain -= chunk;
+	}
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/enc-text/main.c	Sat Aug 05 02:07:22 2023 +0000
@@ -0,0 +1,106 @@
+/*
+ * This is the main module for sms-encode-text utility.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "defs.h"
+
+int utf8_input, ucs2_mode;
+int concat_enable, concat_refno_set;
+char msgtext[MAX_MSG_CHARS*2+2];
+u_char concat_refno;
+
+process_cmdline(argc, argv)
+	char **argv;
+{
+	int c;
+	extern int optind;
+	extern char *optarg;
+
+	while ((c = getopt(argc, argv, "cC:uU")) != EOF) {
+		switch (c) {
+		case 'c':
+			concat_enable = 1;
+			continue;
+		case 'C':
+			concat_enable = 1;
+			concat_refno = strtoul(optarg, 0, 0);
+			concat_refno_set = 1;
+			continue;
+		case 'u':
+			utf8_input = 1;
+			continue;
+		case 'U':
+			ucs2_mode = 1;
+			continue;
+		default:
+			/* error msg already printed */
+			exit(1);
+		}
+	}
+	if (argc > optind + 1) {
+		fprintf(stderr, "usage: %s [options] [message]\n", argv[0]);
+		exit(1);
+	}
+	if (argc < optind + 1)
+		return(0);
+	if (strlen(argv[optind]) > MAX_MSG_CHARS*2) {
+		fprintf(stderr, "error: message argument is too long\n");
+		exit(1);
+	}
+	strcpy(msgtext, argv[optind]);
+	return(1);
+}
+
+read_msgtext_from_stdin()
+{
+	unsigned pos, remain;
+	int cc;
+
+	pos = 0;
+	remain = sizeof(msgtext);
+	for (;;) {
+		if (!remain) {
+			fprintf(stderr,
+				"error: message on stdin is too long\n");
+			exit(1);
+		}
+		cc = read(0, msgtext + pos, remain);
+		if (cc < 0) {
+			fprintf(stderr, "error reading message from stdin\n");
+			exit(1);
+		}
+		if (cc == 0)
+			break;
+		pos += cc;
+		remain -= cc;
+	}
+	msgtext[pos] = '\0';
+}
+
+trim_trailing_newlines()
+{
+	char *cp;
+
+	cp = index(msgtext, '\0');
+	while (cp > msgtext && cp[-1] == '\n')
+		cp--;
+	*cp = '\0';
+}
+
+main(argc, argv)
+	char **argv;
+{
+	if (!process_cmdline(argc, argv))
+		read_msgtext_from_stdin();
+	trim_trailing_newlines();
+	if (ucs2_mode)
+		ucs2_mode_main();
+	else
+		gsm7_mode_main();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/enc-text/ucs2.c	Sat Aug 05 02:07:22 2023 +0000
@@ -0,0 +1,74 @@
+/*
+ * In this module we implement SMS encoding in UCS-2.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "defs.h"
+
+extern int concat_enable, concat_refno_set;
+extern char msgtext[MAX_MSG_CHARS*2+2];
+extern u_char concat_refno;
+
+ucs2_mode_main()
+{
+	u_short msgtext_uni[MAX_MSG_UNI];
+	unsigned msgtext_unilen;
+	int rc;
+	unsigned nparts, n;
+	u_char udh[6], ucs2_be[140];
+	unsigned pos, remain, chunk;
+
+	rc = utf8_to_ucs2(msgtext, msgtext_uni, MAX_MSG_UNI, &msgtext_unilen);
+	if (rc == -1) {
+		fprintf(stderr, "error: invalid UTF-8 message\n");
+		exit(1);
+	}
+	if (rc == -2) {
+		fprintf(stderr, "error: message too long for max concat SMS\n");
+		exit(1);
+	}
+	if (msgtext_unilen <= 70) {
+		fputs("dcs 8 octet\nmsg ", stdout);
+		if (msgtext_unilen) {
+			ucs2_out_bigend(msgtext_uni, ucs2_be, msgtext_unilen);
+			emit_hex_out(ucs2_be, msgtext_unilen * 2, stdout);
+		} else
+			fputs("empty", stdout);
+		putchar('\n');
+		exit(0);
+	}
+	if (!concat_enable) {
+		fprintf(stderr, "error: message exceeds 70 UCS-2 chars\n");
+		exit(1);
+	}
+	if (!concat_refno_set)
+		concat_refno = get_concsms_refno_from_host_fs();
+	puts("dcs 8 octet");
+	nparts = (msgtext_unilen + 66) / 67;
+	udh[0] = 5;
+	udh[1] = 0x00;
+	udh[2] = 0x03;
+	udh[3] = concat_refno;
+	udh[4] = nparts;
+	pos = 0;
+	remain = msgtext_unilen;
+	for (n = 1; n <= nparts; n++) {
+		udh[5] = n;
+		chunk = 67;
+		if (chunk > remain)
+			chunk = remain;
+		fputs("msg-udh ", stdout);
+		emit_hex_out(udh, 6, stdout);
+		ucs2_out_bigend(msgtext_uni + pos, ucs2_be, chunk);
+		emit_hex_out(ucs2_be, chunk * 2, stdout);
+		putchar('\n');
+		pos += chunk;
+		remain -= chunk;
+	}
+	exit(0);
+}