commit 359cf4814470f3e66f0fd6511d9a218c7ec63243
Author: Antoine Amarilli <a3nm@a3nm.net>
Date: Sat, 17 Nov 2012 16:12:27 +0100
initial commit
Diffstat:
Makefile | | | 30 | ++++++++++++++++++++++++++++++ |
README | | | 2 | ++ |
hebraize.c | | | 639 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 671 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,30 @@
+CC = gcc
+DEFS= -DSVR4 -D_GNU_SOURCE
+CFLAGS = -O2 -g -fomit-frame-pointer -Wall $(DEFS)
+VERSION = 1.0.8
+
+DESTDIR=
+
+TARGET = hebraize
+
+DIST = hebraize.c README Makefile
+
+all: $(TARGET)
+
+hebraize: hebraize.o
+ $(CC) $(CFLAGS) -o hebraize hebraize.o
+
+install:
+ install hebraize $(DESTDIR)/usr/bin
+
+clean:
+ rm -f *.o $(TARGET) *~
+
+dist:
+ rm -rf hebraize-$(VERSION)
+ rm -f hebraize-$(VERSION).tar.gz
+
+ mkdir hebraize-$(VERSION)
+ cp $(DIST) hebraize-$(VERSION)
+ tar zcf hebraize-$(VERSION).tar.gz hebraize-$(VERSION)
+ rm -rf hebraize-$(VERSION)
diff --git a/README b/README
@@ -0,0 +1,2 @@
+Hacked from ttyrec, hebraize the terminal with some basic understanding of
+finals, phonetics, and escape sequences.
diff --git a/hebraize.c b/hebraize.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* 2012-11-17 Antoine Amarilli <a3nm@a3nm.net>
+ * created from ttyrec
+ */
+
+/*
+ * script
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/signal.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if defined(SVR4)
+#include <fcntl.h>
+#include <stropts.h>
+#endif /* SVR4 */
+
+#include <sys/time.h>
+
+#define HAVE_inet_aton
+#define HAVE_scsi_h
+#define HAVE_kd_h
+
+#define _(FOO) FOO
+
+#ifdef HAVE_openpty
+#include <libutil.h>
+#endif
+
+#if defined(SVR4) && !defined(CDEL)
+#if defined(_POSIX_VDISABLE)
+#define CDEL _POSIX_VDISABLE
+#elif defined(CDISABLE)
+#define CDEL CDISABLE
+#else /* not _POSIX_VISIBLE && not CDISABLE */
+#define CDEL 255
+#endif /* not _POSIX_VISIBLE && not CDISABLE */
+#endif /* SVR4 && ! CDEL */
+
+void done(void);
+void fail(void);
+void fixtty(void);
+void getmaster(void);
+void getslave(void);
+void doinput(void);
+void dooutput(void);
+void doshell(const char*);
+void spawnshell();
+
+char *shell;
+int master;
+int slave;
+int child;
+int subchild;
+int freq;
+
+struct termios tt;
+struct winsize win;
+int lb;
+int l;
+#if !defined(SVR4)
+#ifndef HAVE_openpty
+char line[] = "/dev/ptyXX";
+#endif
+#endif /* !SVR4 */
+int aflg;
+int force;
+int limit;
+char *command = NULL;
+
+static void
+resize(int dummy) {
+ /* transmit window change information to the child */
+ (void) ioctl(0, TIOCGWINSZ, (char *)&win);
+ (void) ioctl(master, TIOCSWINSZ, (char *)&win);
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct sigaction sa;
+ extern int optind;
+ int ch;
+ void finish();
+ char *getenv();
+
+ freq = 1;
+
+ while ((ch = getopt(argc, argv, "f:h?")) != EOF)
+ switch((char)ch) {
+ case 'f':
+ freq = atoi(optarg);
+ break;
+ case 'h':
+ case '?':
+ default:
+ //fprintf(stderr, _("usage: hebraize [-u] [-e command] [-a] [-f] [-l limit] [file]\n"));
+ fprintf(stderr, _("usage: hebraize TODO\n"));
+ exit(1);
+ }
+ argc -= optind;
+ argv += optind;
+
+ shell = getenv("SHELL");
+ if (shell == NULL)
+ shell = "/bin/sh";
+
+ getmaster();
+ fixtty();
+
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = finish;
+ sigaction(SIGCHLD, &sa, NULL);
+ child = fork();
+ if (child < 0) {
+ if (!force) perror("fork");
+ fail();
+ }
+ if (child == 0) {
+ subchild = child = fork();
+ if (child < 0) {
+ if (!force) perror("fork");
+ fail();
+ }
+ if (child) {
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGCHLD, &sa, NULL);
+ dooutput();
+ } else
+ doshell(command);
+ }
+ sa.sa_handler = resize;
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGWINCH, &sa, NULL);
+ doinput();
+
+ return 0;
+}
+
+void
+doinput()
+{
+ register int cc;
+ char ibuf[BUFSIZ];
+
+#ifdef HAVE_openpty
+ (void) close(slave);
+#endif
+ while ((cc = read(0, ibuf, BUFSIZ)) > 0)
+ (void) write(master, ibuf, cc);
+ done();
+}
+
+#include <sys/wait.h>
+
+void
+finish()
+{
+#if defined(SVR4)
+ int status;
+#else /* !SVR4 */
+ union wait status;
+#endif /* !SVR4 */
+ register int pid;
+
+ while ((pid = wait3((int *)&status, WNOHANG, 0)) > 0)
+ if (pid == child)
+ break;
+}
+
+struct linebuf {
+ char str[BUFSIZ + 1]; /* + 1 for an additional NULL character.*/
+ int len;
+};
+
+
+inline int soft(unsigned char c) {
+ return c == 'e' || c == 'i' || c == 'y' || c == 'E' || c == 'I' || c == 'Y';
+}
+inline int vowel(unsigned char c) {
+ return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y'
+ || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || c == 'Y';
+}
+inline int final_changes(unsigned char c) {
+ return c == 0xA7 || c == 0x9E || c == 0xA0 || c == 0xA4;
+}
+
+void
+dooutput()
+{
+ int cc;
+ int i;
+ int escape = 0;
+ int ncc;
+ unsigned char last = 0;
+ unsigned char lastw = 0;
+ int may_voice = 0;
+ char obuf[BUFSIZ];
+ char nobuf[9*BUFSIZ];
+ int count = 0;
+
+ setbuf(stdout, NULL);
+ (void) close(0);
+#ifdef HAVE_openpty
+ (void) close(slave);
+#endif
+ for (;;) {
+
+ cc = read(master, obuf, BUFSIZ);
+ ncc = 0;
+ for (i = 0; i < cc; i++) {
+ char c = obuf[i];
+ if (escape == 0) {
+ if (last == 'c' || last == 'C') {
+ if (soft(c)) {
+ nobuf[ncc++] = 0x08;
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0xA1;
+ }
+ }
+ if (last == 'c' || last == 'C') {
+ if (soft(c)) {
+ nobuf[ncc++] = 0x08;
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0xA1;
+ }
+ }
+ if (last == 'g' || last == 'G') {
+ if (soft(c)) {
+ nobuf[ncc++] = 0x08;
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x96;
+ }
+ }
+ if ((last == 's' || last == 'S') && may_voice) {
+ if (vowel(c)) {
+ nobuf[ncc++] = 0x08;
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x96;
+ }
+ }
+ if (final_changes(lastw)) {
+ //printf("%c %d\n", lastw, lastw == 0x9E);
+// nobuf[ncc++] = 'A';
+// nobuf[ncc++] = 'A';
+// nobuf[ncc++] = 'A';
+ if (c == ' ') {
+ nobuf[ncc++] = 0x08;
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = lastw - 1;
+ }
+ }
+ if (!(count++ % freq)) {
+ switch (c) {
+ case 'a':
+ case 'A':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x90;
+ break;
+ case 'b':
+ case 'B':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x91;
+ break;
+ case 'g':
+ case 'G':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x92;
+ break;
+ case 'd':
+ case 'D':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x93;
+ break;
+ case 'e':
+ case 'E':
+ case 'h':
+ case 'H':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x94;
+ break;
+ case 'v':
+ case 'V':
+ case 'u':
+ case 'U':
+ case 'w':
+ case 'W':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x95;
+ break;
+ case 'z':
+ case 'Z':
+ case 'j':
+ case 'J':
+ // geresh, but it will make it move
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x96;
+ break;
+
+ case 't':
+ case 'T':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x98;
+ break;
+ case 'i':
+ case 'I':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x99;
+ break;
+
+ case 'l':
+ case 'L':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x9C;
+ break;
+ case 'm':
+ case 'M':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0x9E;
+ nobuf[ncc-1] = 0x9E;
+ break;
+ case 'n':
+ case 'N':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0xA0;
+ break;
+ case 's':
+ case 'S':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0xA1;
+ may_voice = (vowel(last));
+ break;
+
+ case 'f':
+ case 'F':
+ case 'p':
+ case 'P':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0xA4;
+ break;
+
+ case 'c':
+ case 'C':
+ case 'k':
+ case 'K':
+ case 'q':
+ case 'Q':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0xA7;
+ break;
+ case 'r':
+ case 'R':
+ nobuf[ncc++] = 0xD7;
+ nobuf[ncc++] = 0xA8;
+ break;
+
+ // schwa
+ // case 'e':
+ // case 'E':
+ nobuf[ncc++] = 0xC6;
+ nobuf[ncc++] = 0x8F;
+ break;
+
+ case 0x1B:
+ escape = 1;
+ default:
+ nobuf[ncc++] = c;
+ }
+ } else {
+ switch (c) {
+ case 0x1B:
+ escape = 1;
+ default:
+ nobuf[ncc++] = c;
+ }
+ }
+ count = count % freq;
+ last = c;
+ if (ncc) {
+ lastw = nobuf[ncc-1];
+ //printf("set lastw to %x because read %d, eqauls %d\n", lastw, c, lastw == 0x9E);
+ }
+ } else {
+ nobuf[ncc++] = c;
+ if (escape == 1) {
+ if (c == '[') {
+ escape = 2;
+ } else {
+ if (c >= 64 && c <= 95) {
+ escape = 0;
+ }
+ }
+ } else if (escape == 2) {
+ if (c >= 64 && c <= 126)
+ escape = 0;
+ }
+ }
+ }
+
+ (void) write(1, nobuf, ncc);
+ }
+ done();
+}
+
+void
+doshell(const char* command)
+{
+ /***
+ int t;
+
+ t = open(_PATH_TTY, O_RDWR);
+ if (t >= 0) {
+ (void) ioctl(t, TIOCNOTTY, (char *)0);
+ (void) close(t);
+ }
+ ***/
+ getslave();
+ (void) close(master);
+ (void) dup2(slave, 0);
+ (void) dup2(slave, 1);
+ (void) dup2(slave, 2);
+ (void) close(slave);
+
+ spawnshell();
+ perror(shell);
+ fail();
+}
+
+void
+fixtty()
+{
+ struct termios rtt;
+
+ rtt = tt;
+#if defined(SVR4)
+#if !defined(XCASE)
+#define XCASE 0
+#endif
+ rtt.c_iflag = 0;
+ rtt.c_lflag &= ~(ISIG|ICANON|XCASE|ECHO|ECHOE|ECHOK|ECHONL);
+ rtt.c_oflag = OPOST;
+ rtt.c_cc[VINTR] = CDEL;
+ rtt.c_cc[VQUIT] = CDEL;
+ rtt.c_cc[VERASE] = CDEL;
+ rtt.c_cc[VKILL] = CDEL;
+ rtt.c_cc[VEOF] = 1;
+ rtt.c_cc[VEOL] = 0;
+#else /* !SVR4 */
+ cfmakeraw(&rtt);
+ rtt.c_lflag &= ~ECHO;
+#endif /* !SVR4 */
+ (void) tcsetattr(0, TCSAFLUSH, &rtt);
+}
+
+void
+fail()
+{
+ if (force) {
+ spawnshell();
+ perror(shell);
+ }
+ (void) kill(0, SIGTERM);
+ done();
+}
+
+void
+done()
+{
+ if (subchild) {
+ (void) close(master);
+ } else {
+ (void) tcsetattr(0, TCSAFLUSH, &tt);
+ }
+ exit(0);
+}
+
+void
+getmaster()
+{
+#if defined(SVR4)
+ (void) tcgetattr(0, &tt);
+ (void) ioctl(0, TIOCGWINSZ, (char *)&win);
+ if ((master = open("/dev/ptmx", O_RDWR)) < 0) {
+ if (!force) perror("open(\"/dev/ptmx\", O_RDWR)");
+ fail();
+ }
+#else /* !SVR4 */
+#ifdef HAVE_openpty
+ (void) tcgetattr(0, &tt);
+ (void) ioctl(0, TIOCGWINSZ, (char *)&win);
+ if (openpty(&master, &slave, NULL, &tt, &win) < 0) {
+ fprintf(stderr, _("openpty failed\n"));
+ fail();
+ }
+#else
+#ifdef HAVE_getpt
+ if ((master = getpt()) < 0) {
+ if (!force) perror("getpt()");
+ fail();
+ }
+#else
+ char *pty, *bank, *cp;
+ struct stat stb;
+
+ pty = &line[strlen("/dev/ptyp")];
+ for (bank = "pqrs"; *bank; bank++) {
+ line[strlen("/dev/pty")] = *bank;
+ *pty = '0';
+ if (stat(line, &stb) < 0)
+ break;
+ for (cp = "0123456789abcdef"; *cp; cp++) {
+ *pty = *cp;
+ master = open(line, O_RDWR);
+ if (master >= 0) {
+ char *tp = &line[strlen("/dev/")];
+ int ok;
+
+ /* verify slave side is usable */
+ *tp = 't';
+ ok = access(line, R_OK|W_OK) == 0;
+ *tp = 'p';
+ if (ok) {
+ (void) tcgetattr(0, &tt);
+ (void) ioctl(0, TIOCGWINSZ,
+ (char *)&win);
+ return;
+ }
+ (void) close(master);
+ }
+ }
+ }
+ fprintf(stderr, _("Out of pty's\n"));
+ fail();
+#endif /* not HAVE_getpt */
+#endif /* not HAVE_openpty */
+#endif /* !SVR4 */
+}
+
+void
+getslave()
+{
+#if defined(SVR4)
+ (void) setsid();
+ grantpt( master);
+ unlockpt(master);
+ if ((slave = open((const char *)ptsname(master), O_RDWR)) < 0) {
+ if (!force) perror("open(fd, O_RDWR)");
+ fail();
+ }
+ if (isastream(slave)) {
+ if (ioctl(slave, I_PUSH, "ptem") < 0) {
+ if (!force) perror("ioctl(fd, I_PUSH, ptem)");
+ fail();
+ }
+ if (ioctl(slave, I_PUSH, "ldterm") < 0) {
+ if (!force) perror("ioctl(fd, I_PUSH, ldterm)");
+ fail();
+ }
+#ifndef _HPUX_SOURCE
+ if (ioctl(slave, I_PUSH, "ttcompat") < 0) {
+ if (!force) perror("ioctl(fd, I_PUSH, ttcompat)");
+ fail();
+ }
+#endif
+ }
+ (void) tcsetattr(slave, TCSAFLUSH, &tt);
+ (void) ioctl(slave, TIOCSWINSZ, (char *)&win);
+ (void) ioctl(slave, TIOCSCTTY, 0);
+#else /* !SVR4 */
+#ifndef HAVE_openpty
+ line[strlen("/dev/")] = 't';
+ slave = open(line, O_RDWR);
+ if (slave < 0) {
+ if (!force) perror(line);
+ fail();
+ }
+ (void) tcsetattr(slave, TCSAFLUSH, &tt);
+ (void) ioctl(slave, TIOCSWINSZ, (char *)&win);
+#endif
+ (void) setsid();
+ (void) ioctl(slave, TIOCSCTTY, 0);
+#endif /* SVR4 */
+}
+
+void
+spawnshell()
+{
+ force = 0;
+
+ if (!command) {
+ execl(shell, strrchr(shell, '/') + 1, "-i", NULL);
+ } else {
+ execl(shell, strrchr(shell, '/') + 1, "-c", command, NULL);
+ }
+}