hebraize

rewrite terminal contents in hebrew
git clone https://a3nm.net/git/hebraize/
Log | Files | Refs | README

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); + } +}