mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-25 18:31:14 +00:00
- it is now possible to make the serial drivers pipe their input/output
to programs by using a '|' followed by a command line as the modem or printer port setting (instead of a device name like '/dev/ttyS0') [Brian Johnson] - the option "--config FILE" tells B2 to use a different config file
This commit is contained in:
parent
586d299bfc
commit
3d2bac9f15
@ -4,6 +4,12 @@ V1.0 (snapshot) - <date>
|
||||
- Unix: cleaned up pthread attributes [Brian Johnson]
|
||||
- Unix: fixed floppy problems under Linux
|
||||
- Unix: implement "ignoresegv" feature on Linux/x86, Linux/ppc, Darwin/ppc
|
||||
- Unix: serial port baud rates are now set correctly
|
||||
- Unix: it is now possible to make the serial drivers pipe their input/output
|
||||
to programs by using a '|' followed by a command line as the modem or
|
||||
printer port setting (instead of a device name like '/dev/ttyS0')
|
||||
[Brian Johnson]
|
||||
- Unix: the option "--config FILE" tells B2 to use a different config file
|
||||
|
||||
V1.0 (snapshot) - 15.Jan.2002
|
||||
- added support for on-the-fly video resolution and depth switching, and
|
||||
|
@ -42,5 +42,4 @@ Unix:
|
||||
- sys_unix.cpp: SysFormat(), SysIsFixedDisk(), SysIsDiskInserted(),
|
||||
prevent/allow for non-floppy/CDROM devices
|
||||
- ESD is also available on Solaris
|
||||
- serial_unix.cpp: provide a way to pipe input/output to programs
|
||||
- display progress bar during disk file creation in prefs editor
|
||||
|
110
BasiliskII/src/Unix/Irix/README.networking
Normal file
110
BasiliskII/src/Unix/Irix/README.networking
Normal file
@ -0,0 +1,110 @@
|
||||
README file for networking under IRIX
|
||||
by Brian J. Johnson 7/23/2002
|
||||
version 1.0
|
||||
==================================================
|
||||
|
||||
BasiliskII does not currently support networking natively on IRIX.
|
||||
That is, the emulated Ethernet card does not do anything. There's no
|
||||
reason one couldn't use raw domain sockets and the snoop(7p) facility
|
||||
to do networking, but so far no one has written the required glue
|
||||
code.
|
||||
|
||||
However, it is possible to do TCP/IP networking with BasiliskII on
|
||||
IRIX via PPP, by connecting an emulated serial port to the IRIX PPP
|
||||
daemon. Here are the steps to set it up:
|
||||
|
||||
|
||||
Set up PPP on IRIX
|
||||
------------------
|
||||
|
||||
You need root privileges to do this.
|
||||
|
||||
First, make sure you have eoe.sw.ppp and eoe.sw.uucp installed:
|
||||
|
||||
IRIS# versions eoe.sw.ppp eoe.sw.uucp
|
||||
I = Installed, R = Removed
|
||||
|
||||
Name Date Description
|
||||
|
||||
I eoe 07/22/2002 IRIX Execution Environment, 6.5.17m
|
||||
I eoe.sw 07/22/2002 IRIX Execution Environment Software
|
||||
I eoe.sw.ppp 07/22/2002 Point-to-Point Protocol Software
|
||||
I eoe.sw.uucp 07/22/2002 UUCP Utilities
|
||||
|
||||
If they aren't installed, install them from your distribution CDs.
|
||||
|
||||
Next, pick IP addresses for the IRIX and MacOS sides of the PPP
|
||||
connection. You may want to ask your local network administrator
|
||||
about this, but any two unused addresses on your local subnet should
|
||||
work.
|
||||
|
||||
Edit /etc/ppp.conf and add these three lines:
|
||||
|
||||
_NET_INCOMING
|
||||
remotehost=<MacOS PPP IP address>
|
||||
localhost=<IRIX PPP IP address>
|
||||
|
||||
(Replace the angle brackets and the text in them with the appropriate
|
||||
IP addresses.)
|
||||
|
||||
Next, make a script to set up the environment properly when invoking
|
||||
pppd from BasiliskII. You can name this whatever you want; I chose
|
||||
/usr/etc/ppp-b2:
|
||||
|
||||
IRIS# whoami
|
||||
root
|
||||
IRIS# cat < /usr/etc/ppp-b2
|
||||
#!/bin/sh
|
||||
export USER=_NET_INCOMING
|
||||
exec /usr/etc/ppp "$@"
|
||||
IRIS# chmod 4775 /usr/etc/ppp-b2
|
||||
|
||||
Rewrite this in perl or python or C or whatever if you don't like
|
||||
setuid shell scripts. The alternative is to run BasiliskII as root:
|
||||
pppd _must_ be run as root.
|
||||
|
||||
|
||||
Configure BasiliskII to start the PPP daemon
|
||||
--------------------------------------------
|
||||
|
||||
Start up BasiliskII, and in the serial devices tab, enter:
|
||||
|
||||
|exec /usr/etc/ppp-b2
|
||||
|
||||
Supply the name you used for the script you created. Be sure to
|
||||
include the leading pipe symbol ("|").
|
||||
|
||||
The "exec" causes your PPP startup script to replace the shell
|
||||
BasiliskII runs to interpret the command. It's not strictly
|
||||
necessary, but cuts down on the number of extra processes hanging
|
||||
about.
|
||||
|
||||
|
||||
Install a PPP client on MacOS
|
||||
-----------------------------
|
||||
|
||||
The details of this step will vary depending on your PPP client
|
||||
software. Set it up for a "direct" connection, with no modem chatting
|
||||
or login scripting. For instance, with FreePPP I set the "Connect:"
|
||||
item on the "Edit..." screen under the "Accounts" tab to "Directly".
|
||||
Be sure to select the correct serial port. The serial port speed
|
||||
shouldn't matter (BasiliskII ignores it), but I set it to 115200 bps.
|
||||
|
||||
Next, configure MacOS's TCP/IP stack. If you're using Open Transport,
|
||||
Open the TCP/IP control panel and select "Using PPP Server" under the
|
||||
"Configure" item. Copy IRIX's DNS client info. from /etc/resolv.conf
|
||||
to the control panel: the addresses from the "nameserver" lines go in
|
||||
the "Name server addr.:" box, and the domains from the "search" lines
|
||||
go in the "Search domains:" box. The steps should be similar for
|
||||
MacTCP.
|
||||
|
||||
Now fire up PPP. Your PPP client should establish communication with
|
||||
the IRIX PPP daemon, and you're off and running.
|
||||
|
||||
|
||||
Disclaimer
|
||||
----------
|
||||
|
||||
I haven't tried this procedure from scratch on a freshly installed
|
||||
system, so I might have missed a step somewhere. But it should get
|
||||
you close....
|
@ -34,7 +34,7 @@ SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp
|
||||
timer_unix.cpp clip_unix.cpp ../adb.cpp ../serial.cpp ../ether.cpp \
|
||||
../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp ../video.cpp video_blit.cpp \
|
||||
video_x.cpp vm_alloc.cpp sigsegv.cpp ../audio.cpp ../extfs.cpp extfs_unix.cpp \
|
||||
../user_strings.cpp user_strings_unix.cpp \
|
||||
../user_strings.cpp user_strings_unix.cpp sshpty.c strlcpy.c \
|
||||
$(SYSSRCS) $(CPUSRCS)
|
||||
APP = BasiliskII
|
||||
|
||||
|
@ -80,6 +80,17 @@
|
||||
/* Define if libgnomeui is available */
|
||||
#undef HAVE_GNOMEUI
|
||||
|
||||
/* Additions from openssh-3.2.2p1, for sshpty.c */
|
||||
/* Define if you are on NEWS-OS */
|
||||
#undef HAVE_NEWS4
|
||||
|
||||
/* Define if you have /dev/ptmx */
|
||||
#undef HAVE_DEV_PTMX
|
||||
|
||||
/* Define if you have /dev/ptc */
|
||||
#undef HAVE_DEV_PTS_AND_PTC
|
||||
|
||||
|
||||
|
||||
/* Leave that blank line there!! Autoheader needs it.
|
||||
If you're adding to this file, keep in mind:
|
||||
|
@ -257,6 +257,50 @@ AC_CHECK_FUNCS(vm_allocate vm_deallocate vm_protect)
|
||||
dnl Darwin seems to define mach_task_self() instead of task_self().
|
||||
AC_CHECK_FUNCS(mach_task_self task_self)
|
||||
|
||||
dnl Check for headers and functions related to pty support (sshpty.c)
|
||||
dnl From openssh-3.2.2p1 configure.ac
|
||||
|
||||
AC_CHECK_HEADERS(strings.h login.h sys/bsdtty.h sys/stat.h util.h pty.h)
|
||||
AC_CHECK_FUNCS(_getpty vhangup strlcpy)
|
||||
|
||||
case "$host" in
|
||||
*-*-hpux10.26)
|
||||
disable_ptmx_check=yes
|
||||
;;
|
||||
*-*-linux*)
|
||||
no_dev_ptmx=1
|
||||
;;
|
||||
mips-sony-bsd|mips-sony-newsos4)
|
||||
AC_DEFINE(HAVE_NEWS4)
|
||||
;;
|
||||
*-*-sco3.2v4*)
|
||||
no_dev_ptmx=1
|
||||
;;
|
||||
*-*-sco3.2v5*)
|
||||
no_dev_ptmx=1
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$no_dev_ptmx" ; then
|
||||
if test "x$disable_ptmx_check" != "xyes" ; then
|
||||
AC_CHECK_FILE("/dev/ptmx",
|
||||
[
|
||||
AC_DEFINE_UNQUOTED(HAVE_DEV_PTMX)
|
||||
have_dev_ptmx=1
|
||||
]
|
||||
)
|
||||
fi
|
||||
fi
|
||||
AC_CHECK_FILE("/dev/ptc",
|
||||
[
|
||||
AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC)
|
||||
have_dev_ptc=1
|
||||
]
|
||||
)
|
||||
|
||||
dnl (end of code from openssh-3.2.2p1 configure.ac)
|
||||
|
||||
|
||||
dnl Select system-dependant source files.
|
||||
SERIALSRC=serial_unix.cpp
|
||||
ETHERSRC=../dummy/ether_dummy.cpp
|
||||
|
@ -61,6 +61,9 @@ struct sigstate {
|
||||
# include <X11/extensions/xf86dga.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
#include "cpu_emulation.h"
|
||||
#include "sys.h"
|
||||
#include "rom_patches.h"
|
||||
@ -226,11 +229,15 @@ static void sigsegv_dump_state(sigsegv_address_t fault_address, sigsegv_address_
|
||||
|
||||
static void usage(const char *prg_name)
|
||||
{
|
||||
printf("Usage: %s [OPTION...]\n", prg_name);
|
||||
printf("\nUnix options:\n");
|
||||
printf(" --display STRING\n X display to use\n");
|
||||
printf(" --break ADDRESS\n set ROM breakpoint\n");
|
||||
printf(" --rominfo\n dump ROM information\n");
|
||||
printf(
|
||||
"Usage: %s [OPTION...]\n"
|
||||
"\nUnix options:\n"
|
||||
" --config FILE\n read/write configuration from/to FILE\n"
|
||||
" --display STRING\n X display to use\n"
|
||||
" --break ADDRESS\n set ROM breakpoint\n"
|
||||
" --rominfo\n dump ROM information\n", prg_name
|
||||
);
|
||||
LoadPrefs(); // read the prefs file so PrefsPrintUsage() will print the correct default values
|
||||
PrefsPrintUsage();
|
||||
exit(0);
|
||||
}
|
||||
@ -249,6 +256,47 @@ int main(int argc, char **argv)
|
||||
printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
|
||||
printf(" %s\n", GetString(STR_ABOUT_TEXT2));
|
||||
|
||||
// Parse command line arguments
|
||||
for (int i=1; i<argc; i++) {
|
||||
if (strcmp(argv[i], "--help") == 0) {
|
||||
usage(argv[0]);
|
||||
} else if (strcmp(argv[i], "--display") == 0) {
|
||||
i++; // don't remove the argument, gtk_init() needs it too
|
||||
if (i < argc)
|
||||
x_display_name = strdup(argv[i]);
|
||||
} else if (strcmp(argv[i], "--break") == 0) {
|
||||
argv[i++] = NULL;
|
||||
if (i < argc) {
|
||||
ROMBreakpoint = strtol(argv[i], NULL, 0);
|
||||
argv[i] = NULL;
|
||||
}
|
||||
} else if (strcmp(argv[i], "--config") == 0) {
|
||||
argv[i++] = NULL;
|
||||
if (i < argc) {
|
||||
extern string UserPrefsPath; // from prefs_unix.cpp
|
||||
UserPrefsPath = argv[i];
|
||||
argv[i] = NULL;
|
||||
}
|
||||
} else if (strcmp(argv[i], "--rominfo") == 0) {
|
||||
argv[i] = NULL;
|
||||
PrintROMInfo = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove processed arguments
|
||||
for (int i=1; i<argc; i++) {
|
||||
int k;
|
||||
for (k=i; k<argc; k++)
|
||||
if (argv[k] != NULL)
|
||||
break;
|
||||
if (k > i) {
|
||||
k -= i;
|
||||
for (int j=i+k; j<argc; j++)
|
||||
argv[j-k] = argv[j];
|
||||
argc -= k;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_GTK
|
||||
#ifdef HAVE_GNOMEUI
|
||||
// Init GNOME/GTK
|
||||
@ -260,27 +308,14 @@ int main(int argc, char **argv)
|
||||
gtk_set_locale();
|
||||
gtk_init(&argc, &argv);
|
||||
#endif
|
||||
x_display_name = gdk_get_display(); // gtk_init() handles and removes the "--display" argument
|
||||
#endif
|
||||
|
||||
// Read preferences
|
||||
PrefsInit(argc, argv);
|
||||
|
||||
// Parse command line arguments
|
||||
// Any command line arguments left?
|
||||
for (int i=1; i<argc; i++) {
|
||||
if (strcmp(argv[i], "--help") == 0) {
|
||||
usage(argv[0]);
|
||||
} else if (strcmp(argv[i], "--display") == 0) {
|
||||
i++;
|
||||
if (i < argc)
|
||||
x_display_name = strdup(argv[i]);
|
||||
} else if (strcmp(argv[i], "--break") == 0) {
|
||||
i++;
|
||||
if (i < argc)
|
||||
ROMBreakpoint = strtol(argv[i], NULL, 0);
|
||||
} else if (strcmp(argv[i], "--rominfo") == 0) {
|
||||
PrintROMInfo = true;
|
||||
} else if (argv[i][0] == '-') {
|
||||
if (argv[i][0] == '-') {
|
||||
fprintf(stderr, "Unrecognized option '%s'\n", argv[i]);
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
#include "prefs.h"
|
||||
|
||||
|
||||
@ -42,7 +45,8 @@ prefs_desc platform_prefs_items[] = {
|
||||
|
||||
// Prefs file name and path
|
||||
const char PREFS_FILE_NAME[] = ".basilisk_ii_prefs";
|
||||
static char prefs_path[1024];
|
||||
string UserPrefsPath;
|
||||
static string prefs_path;
|
||||
|
||||
|
||||
/*
|
||||
@ -52,16 +56,16 @@ static char prefs_path[1024];
|
||||
void LoadPrefs(void)
|
||||
{
|
||||
// Construct prefs path
|
||||
prefs_path[0] = 0;
|
||||
char *home = getenv("HOME");
|
||||
if (home != NULL && strlen(home) < 1000) {
|
||||
strncpy(prefs_path, home, 1000);
|
||||
strcat(prefs_path, "/");
|
||||
}
|
||||
strcat(prefs_path, PREFS_FILE_NAME);
|
||||
if (UserPrefsPath.empty()) {
|
||||
char *home = getenv("HOME");
|
||||
if (home)
|
||||
prefs_path = string(home) + '/';
|
||||
prefs_path += PREFS_FILE_NAME;
|
||||
} else
|
||||
prefs_path = UserPrefsPath;
|
||||
|
||||
// Read preferences from settings file
|
||||
FILE *f = fopen(prefs_path, "r");
|
||||
FILE *f = fopen(prefs_path.c_str(), "r");
|
||||
if (f != NULL) {
|
||||
|
||||
// Prefs file found, load settings
|
||||
@ -83,7 +87,7 @@ void LoadPrefs(void)
|
||||
void SavePrefs(void)
|
||||
{
|
||||
FILE *f;
|
||||
if ((f = fopen(prefs_path, "w")) != NULL) {
|
||||
if ((f = fopen(prefs_path.c_str(), "w")) != NULL) {
|
||||
SavePrefsToStream(f);
|
||||
fclose(f);
|
||||
}
|
||||
|
@ -22,9 +22,11 @@
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
#ifdef __linux__
|
||||
#include <linux/lp.h>
|
||||
#include <linux/major.h>
|
||||
@ -38,6 +40,11 @@
|
||||
#include "serial.h"
|
||||
#include "serial_defs.h"
|
||||
|
||||
extern "C" {
|
||||
#include "sshpty.h"
|
||||
}
|
||||
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
@ -64,8 +71,9 @@ public:
|
||||
XSERDPort(const char *dev)
|
||||
{
|
||||
device_name = dev;
|
||||
is_parallel = false;
|
||||
protocol = serial;
|
||||
fd = -1;
|
||||
pid = 0;
|
||||
input_thread_active = output_thread_active = false;
|
||||
|
||||
Set_pthread_attr(&thread_attr, 2);
|
||||
@ -101,14 +109,17 @@ public:
|
||||
virtual int16 close(void);
|
||||
|
||||
private:
|
||||
bool open_pty(void);
|
||||
bool configure(uint16 config);
|
||||
void set_handshake(uint32 s, bool with_dtr);
|
||||
static void *input_func(void *arg);
|
||||
static void *output_func(void *arg);
|
||||
|
||||
const char *device_name; // Device name
|
||||
bool is_parallel; // Flag: Port is parallel
|
||||
enum {serial, parallel, pty, midi}
|
||||
protocol; // Type of device
|
||||
int fd; // FD of device
|
||||
pid_t pid; // PID of child process
|
||||
|
||||
bool io_killed; // Flag: KillIO called, I/O threads must not call deferred tasks
|
||||
bool quitting; // Flag: Quit threads
|
||||
@ -168,27 +179,39 @@ int16 XSERDPort::open(uint16 config)
|
||||
io_killed = false;
|
||||
quitting = false;
|
||||
|
||||
// Open port
|
||||
fd = ::open(device_name, O_RDWR);
|
||||
if (fd < 0)
|
||||
goto open_error;
|
||||
// Open port, according to the syntax of the path
|
||||
if (device_name[0] == '|') {
|
||||
// Open a process via ptys
|
||||
if (!open_pty())
|
||||
goto open_error;
|
||||
}
|
||||
else if (!strcmp(device_name, "midi")) {
|
||||
// MIDI: not yet implemented
|
||||
return openErr;
|
||||
}
|
||||
else {
|
||||
// Device special file
|
||||
fd = ::open(device_name, O_RDWR);
|
||||
if (fd < 0)
|
||||
goto open_error;
|
||||
|
||||
#if defined(__linux__)
|
||||
// Parallel port?
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == 0)
|
||||
if (S_ISCHR(st.st_mode))
|
||||
is_parallel = (MAJOR(st.st_rdev) == LP_MAJOR);
|
||||
// Parallel port?
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == 0)
|
||||
if (S_ISCHR(st.st_mode))
|
||||
protocol = ((MAJOR(st.st_rdev) == LP_MAJOR) ? parallel : serial);
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
// Parallel port?
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == 0)
|
||||
if (S_ISCHR(st.st_mode))
|
||||
is_parallel = ((st.st_rdev >> 16) == 16);
|
||||
// Parallel port?
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == 0)
|
||||
if (S_ISCHR(st.st_mode))
|
||||
protocol = (((st.st_rdev >> 16) == 16) ? parallel : serial);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Configure port for raw mode
|
||||
if (!is_parallel) {
|
||||
if (protocol == serial) {
|
||||
if (tcgetattr(fd, &mode) < 0)
|
||||
goto open_error;
|
||||
cfmakeraw(&mode);
|
||||
@ -280,7 +303,7 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
switch (code) {
|
||||
case 1: // KillIO
|
||||
io_killed = true;
|
||||
if (!is_parallel)
|
||||
if (protocol == serial)
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
while (read_pending || write_pending)
|
||||
usleep(10000);
|
||||
@ -301,7 +324,7 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
return noErr;
|
||||
|
||||
case kSERDSetBreak:
|
||||
if (!is_parallel)
|
||||
if (protocol == serial)
|
||||
tcsendbreak(fd, 0);
|
||||
return noErr;
|
||||
|
||||
@ -309,7 +332,7 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
return noErr;
|
||||
|
||||
case kSERDBaudRate: {
|
||||
if (is_parallel)
|
||||
if (protocol != serial)
|
||||
return noErr;
|
||||
uint16 rate = ReadMacInt16(pb + csParam);
|
||||
speed_t baud_rate;
|
||||
@ -350,8 +373,8 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
rate = 57600; baud_rate = B57600;
|
||||
}
|
||||
WriteMacInt16(pb + csParam, rate);
|
||||
cfsetispeed(&mode, B115200);
|
||||
cfsetospeed(&mode, B115200);
|
||||
cfsetispeed(&mode, baud_rate);
|
||||
cfsetospeed(&mode, baud_rate);
|
||||
tcsetattr(fd, TCSANOW, &mode);
|
||||
return noErr;
|
||||
}
|
||||
@ -362,7 +385,7 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
return noErr;
|
||||
|
||||
case kSERDMiscOptions:
|
||||
if (is_parallel)
|
||||
if (protocol != serial)
|
||||
return noErr;
|
||||
if (ReadMacInt8(pb + csParam) & kOptionPreserveDTR)
|
||||
mode.c_cflag &= ~HUPCL;
|
||||
@ -372,7 +395,7 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
return noErr;
|
||||
|
||||
case kSERDAssertDTR: {
|
||||
if (is_parallel)
|
||||
if (protocol != serial)
|
||||
return noErr;
|
||||
unsigned int status = TIOCM_DTR;
|
||||
ioctl(fd, TIOCMBIS, &status);
|
||||
@ -380,7 +403,7 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
}
|
||||
|
||||
case kSERDNegateDTR: {
|
||||
if (is_parallel)
|
||||
if (protocol != serial)
|
||||
return noErr;
|
||||
unsigned int status = TIOCM_DTR;
|
||||
ioctl(fd, TIOCMBIC, &status);
|
||||
@ -392,12 +415,12 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
return noErr; // Not supported under Unix
|
||||
|
||||
case kSERDResetChannel:
|
||||
if (!is_parallel)
|
||||
if (protocol == serial)
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
return noErr;
|
||||
|
||||
case kSERDAssertRTS: {
|
||||
if (is_parallel)
|
||||
if (protocol != serial)
|
||||
return noErr;
|
||||
unsigned int status = TIOCM_RTS;
|
||||
ioctl(fd, TIOCMBIS, &status);
|
||||
@ -405,7 +428,7 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
}
|
||||
|
||||
case kSERDNegateRTS: {
|
||||
if (is_parallel)
|
||||
if (protocol != serial)
|
||||
return noErr;
|
||||
unsigned int status = TIOCM_RTS;
|
||||
ioctl(fd, TIOCMBIC, &status);
|
||||
@ -413,7 +436,7 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
}
|
||||
|
||||
case kSERD115KBaud:
|
||||
if (is_parallel)
|
||||
if (protocol != serial)
|
||||
return noErr;
|
||||
cfsetispeed(&mode, B115200);
|
||||
cfsetospeed(&mode, B115200);
|
||||
@ -422,7 +445,7 @@ int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
|
||||
|
||||
case kSERD230KBaud:
|
||||
case kSERDSetHighSpeed:
|
||||
if (is_parallel)
|
||||
if (protocol != serial)
|
||||
return noErr;
|
||||
cfsetispeed(&mode, B230400);
|
||||
cfsetospeed(&mode, B230400);
|
||||
@ -458,7 +481,7 @@ int16 XSERDPort::status(uint32 pb, uint32 dce, uint16 code)
|
||||
WriteMacInt8(p + staXOffHold, 0);
|
||||
WriteMacInt8(p + staRdPend, read_pending);
|
||||
WriteMacInt8(p + staWrPend, write_pending);
|
||||
if (is_parallel) {
|
||||
if (protocol != serial) {
|
||||
WriteMacInt8(p + staCtsHold, 0);
|
||||
WriteMacInt8(p + staDsrHold, 0);
|
||||
WriteMacInt8(p + staModemStatus, dsrEvent | dcdEvent | ctsEvent);
|
||||
@ -509,10 +532,66 @@ int16 XSERDPort::close()
|
||||
if (fd > 0)
|
||||
::close(fd);
|
||||
fd = -1;
|
||||
|
||||
// Wait for the subprocess to exit
|
||||
if (pid)
|
||||
waitpid(pid, NULL, 0);
|
||||
pid = 0;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Open a process via ptys
|
||||
*/
|
||||
|
||||
bool XSERDPort::open_pty(void)
|
||||
{
|
||||
// Talk to a process via a pty
|
||||
char slave[128];
|
||||
int slavefd;
|
||||
|
||||
protocol = pty;
|
||||
if (!pty_allocate(&fd, &slavefd, slave, sizeof(slave)))
|
||||
return false;
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
switch (pid = fork()) {
|
||||
case -1: // error
|
||||
return false;
|
||||
break;
|
||||
case 0: // child
|
||||
::close(fd);
|
||||
|
||||
/* Make the pseudo tty our controlling tty. */
|
||||
pty_make_controlling_tty(&slavefd, slave);
|
||||
|
||||
::close(0); dup(slavefd); // Use the slave fd for stdin,
|
||||
::close(1); dup(slavefd); // stdout,
|
||||
::close(2); dup(slavefd); // and stderr.
|
||||
|
||||
// <should we be more paranoid about closing unused fds?>
|
||||
// <should we drop privileges if running setuid?>
|
||||
|
||||
// Let the shell do the dirty work
|
||||
execlp("/bin/sh", "/bin/sh", "-c", ++device_name, 0);
|
||||
|
||||
// exec failed!
|
||||
printf("serial_open: could not exec %s: %s\n",
|
||||
"/bin/sh", strerror(errno));
|
||||
exit(1);
|
||||
break;
|
||||
default: // parent
|
||||
// Pid was stored above
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Configure serial port with MacOS config word
|
||||
*/
|
||||
@ -520,7 +599,7 @@ int16 XSERDPort::close()
|
||||
bool XSERDPort::configure(uint16 config)
|
||||
{
|
||||
D(bug(" configure %04x\n", config));
|
||||
if (is_parallel)
|
||||
if (protocol != serial)
|
||||
return true;
|
||||
|
||||
// Set number of stop bits
|
||||
@ -604,7 +683,7 @@ void XSERDPort::set_handshake(uint32 s, bool with_dtr)
|
||||
D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3),
|
||||
ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7)));
|
||||
if (is_parallel)
|
||||
if (protocol != serial)
|
||||
return;
|
||||
|
||||
if (with_dtr) {
|
||||
|
470
BasiliskII/src/Unix/sshpty.c
Normal file
470
BasiliskII/src/Unix/sshpty.c
Normal file
@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Allocating a pseudo-terminal, and making it the controlling tty.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
#if 0 /* not in BasiliskII */
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshpty.c,v 1.4 2001/12/19 07:18:56 deraadt Exp $");
|
||||
#else /* not in BasiliskII */
|
||||
/* Selections from openssh's "includes.h" */
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h> /* For O_NONBLOCK */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <unistd.h> /* For STDIN_FILENO, etc */
|
||||
#include <termios.h> /* Struct winsize */
|
||||
|
||||
/*
|
||||
*-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively
|
||||
*/
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#ifdef HAVE_LOGIN_H
|
||||
# include <login.h>
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef HAVE_SYS_BSDTTY_H
|
||||
# include <sys/bsdtty.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h> /* For S_* constants and macros */
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_TTY
|
||||
# define _PATH_TTY "/dev/tty"
|
||||
#endif
|
||||
|
||||
#include "strlcpy.h"
|
||||
|
||||
#define debug(x) ;
|
||||
|
||||
#endif /* not in BasiliskII */
|
||||
|
||||
#ifdef HAVE_UTIL_H
|
||||
# include <util.h>
|
||||
#endif /* HAVE_UTIL_H */
|
||||
|
||||
#include "sshpty.h"
|
||||
#if 0 /* not in BasiliskII */
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#else /* stubs for BasiliskII */
|
||||
#define error printf
|
||||
#define fatal(x) {printf("Fatal error: %s", x); return 0}
|
||||
#endif /* not in BasiliskII */
|
||||
|
||||
/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */
|
||||
#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY)
|
||||
#undef HAVE_DEV_PTMX
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTY_H
|
||||
# include <pty.h>
|
||||
#endif
|
||||
#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H)
|
||||
# include <sys/stropts.h>
|
||||
#endif
|
||||
|
||||
#ifndef O_NOCTTY
|
||||
#define O_NOCTTY 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocates and opens a pty. Returns 0 if no pty could be allocated, or
|
||||
* nonzero if a pty was successfully allocated. On success, open file
|
||||
* descriptors for the pty and tty sides and the name of the tty side are
|
||||
* returned (the buffer must be able to hold at least 64 characters).
|
||||
*/
|
||||
|
||||
int
|
||||
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
{
|
||||
#if defined(HAVE_OPENPTY) || defined(BSD4_4)
|
||||
/* openpty(3) exists in OSF/1 and some other os'es */
|
||||
char *name;
|
||||
int i;
|
||||
|
||||
i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
|
||||
if (i < 0) {
|
||||
error("openpty: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
name = ttyname(*ttyfd);
|
||||
if (!name)
|
||||
fatal("openpty returns device for which ttyname fails.");
|
||||
|
||||
strlcpy(namebuf, name, namebuflen); /* possible truncation */
|
||||
return 1;
|
||||
#else /* HAVE_OPENPTY */
|
||||
#ifdef HAVE__GETPTY
|
||||
/*
|
||||
* _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
|
||||
* pty's automagically when needed
|
||||
*/
|
||||
char *slave;
|
||||
|
||||
slave = _getpty(ptyfd, O_RDWR, 0622, 0);
|
||||
if (slave == NULL) {
|
||||
error("_getpty: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
strlcpy(namebuf, slave, namebuflen);
|
||||
/* Open the slave side. */
|
||||
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("%.200s: %.100s", namebuf, strerror(errno));
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
#else /* HAVE__GETPTY */
|
||||
#if defined(HAVE_DEV_PTMX)
|
||||
/*
|
||||
* This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3
|
||||
* also has bsd-style ptys, but they simply do not work.)
|
||||
*/
|
||||
int ptm;
|
||||
char *pts;
|
||||
mysig_t old_signal;
|
||||
|
||||
ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
|
||||
if (ptm < 0) {
|
||||
error("/dev/ptmx: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
old_signal = mysignal(SIGCHLD, SIG_DFL);
|
||||
if (grantpt(ptm) < 0) {
|
||||
error("grantpt: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
mysignal(SIGCHLD, old_signal);
|
||||
if (unlockpt(ptm) < 0) {
|
||||
error("unlockpt: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
pts = ptsname(ptm);
|
||||
if (pts == NULL)
|
||||
error("Slave pty side name could not be obtained.");
|
||||
strlcpy(namebuf, pts, namebuflen);
|
||||
*ptyfd = ptm;
|
||||
|
||||
/* Open the slave side. */
|
||||
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("%.100s: %.100s", namebuf, strerror(errno));
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
#ifndef HAVE_CYGWIN
|
||||
/*
|
||||
* Push the appropriate streams modules, as described in Solaris pts(7).
|
||||
* HP-UX pts(7) doesn't have ttcompat module.
|
||||
*/
|
||||
if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
|
||||
error("ioctl I_PUSH ptem: %.100s", strerror(errno));
|
||||
if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)
|
||||
error("ioctl I_PUSH ldterm: %.100s", strerror(errno));
|
||||
#ifndef __hpux
|
||||
if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)
|
||||
error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));
|
||||
#endif
|
||||
#endif
|
||||
return 1;
|
||||
#else /* HAVE_DEV_PTMX */
|
||||
#ifdef HAVE_DEV_PTS_AND_PTC
|
||||
/* AIX-style pty code. */
|
||||
const char *name;
|
||||
|
||||
*ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
|
||||
if (*ptyfd < 0) {
|
||||
error("Could not open /dev/ptc: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
name = ttyname(*ptyfd);
|
||||
if (!name)
|
||||
fatal("Open of /dev/ptc returns device for which ttyname fails.");
|
||||
strlcpy(namebuf, name, namebuflen);
|
||||
*ttyfd = open(name, O_RDWR | O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("Could not open pty slave side %.100s: %.100s",
|
||||
name, strerror(errno));
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
#else /* HAVE_DEV_PTS_AND_PTC */
|
||||
#ifdef _CRAY
|
||||
char buf[64];
|
||||
int i;
|
||||
int highpty;
|
||||
|
||||
#ifdef _SC_CRAY_NPTY
|
||||
highpty = sysconf(_SC_CRAY_NPTY);
|
||||
if (highpty == -1)
|
||||
highpty = 128;
|
||||
#else
|
||||
highpty = 128;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < highpty; i++) {
|
||||
snprintf(buf, sizeof(buf), "/dev/pty/%03d", i);
|
||||
*ptyfd = open(buf, O_RDWR|O_NOCTTY);
|
||||
if (*ptyfd < 0)
|
||||
continue;
|
||||
snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i);
|
||||
/* Open the slave side. */
|
||||
*ttyfd = open(namebuf, O_RDWR|O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("%.100s: %.100s", namebuf, strerror(errno));
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
/* BSD-style pty code. */
|
||||
char buf[64];
|
||||
int i;
|
||||
const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
const char *ptyminors = "0123456789abcdef";
|
||||
int num_minors = strlen(ptyminors);
|
||||
int num_ptys = strlen(ptymajors) * num_minors;
|
||||
struct termios tio;
|
||||
|
||||
for (i = 0; i < num_ptys; i++) {
|
||||
snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
|
||||
ptyminors[i % num_minors]);
|
||||
snprintf(namebuf, namebuflen, "/dev/tty%c%c",
|
||||
ptymajors[i / num_minors], ptyminors[i % num_minors]);
|
||||
|
||||
*ptyfd = open(buf, O_RDWR | O_NOCTTY);
|
||||
if (*ptyfd < 0) {
|
||||
/* Try SCO style naming */
|
||||
snprintf(buf, sizeof buf, "/dev/ptyp%d", i);
|
||||
snprintf(namebuf, namebuflen, "/dev/ttyp%d", i);
|
||||
*ptyfd = open(buf, O_RDWR | O_NOCTTY);
|
||||
if (*ptyfd < 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Open the slave side. */
|
||||
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("%.100s: %.100s", namebuf, strerror(errno));
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
/* set tty modes to a sane state for broken clients */
|
||||
if (tcgetattr(*ptyfd, &tio) < 0)
|
||||
log("Getting tty modes for pty failed: %.100s", strerror(errno));
|
||||
else {
|
||||
tio.c_lflag |= (ECHO | ISIG | ICANON);
|
||||
tio.c_oflag |= (OPOST | ONLCR);
|
||||
tio.c_iflag |= ICRNL;
|
||||
|
||||
/* Set the new modes for the terminal. */
|
||||
if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0)
|
||||
log("Setting tty modes for pty failed: %.100s", strerror(errno));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#endif /* CRAY */
|
||||
#endif /* HAVE_DEV_PTS_AND_PTC */
|
||||
#endif /* HAVE_DEV_PTMX */
|
||||
#endif /* HAVE__GETPTY */
|
||||
#endif /* HAVE_OPENPTY */
|
||||
}
|
||||
|
||||
/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */
|
||||
|
||||
void
|
||||
pty_release(const char *ttyname)
|
||||
{
|
||||
if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0)
|
||||
error("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno));
|
||||
if (chmod(ttyname, (mode_t) 0666) < 0)
|
||||
error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno));
|
||||
}
|
||||
|
||||
/* Makes the tty the processes controlling tty and sets it to sane modes. */
|
||||
|
||||
void
|
||||
pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
{
|
||||
int fd;
|
||||
#ifdef USE_VHANGUP
|
||||
void *old;
|
||||
#endif /* USE_VHANGUP */
|
||||
|
||||
#ifdef _CRAY
|
||||
if (setsid() < 0)
|
||||
error("setsid: %.100s", strerror(errno));
|
||||
|
||||
fd = open(ttyname, O_RDWR|O_NOCTTY);
|
||||
if (fd != -1) {
|
||||
mysignal(SIGHUP, SIG_IGN);
|
||||
ioctl(fd, TCVHUP, (char *)NULL);
|
||||
mysignal(SIGHUP, SIG_DFL);
|
||||
setpgid(0, 0);
|
||||
close(fd);
|
||||
} else {
|
||||
error("Failed to disconnect from controlling tty.");
|
||||
}
|
||||
|
||||
debug("Setting controlling tty using TCSETCTTY.");
|
||||
ioctl(*ttyfd, TCSETCTTY, NULL);
|
||||
fd = open("/dev/tty", O_RDWR);
|
||||
if (fd < 0)
|
||||
error("%.100s: %.100s", ttyname, strerror(errno));
|
||||
close(*ttyfd);
|
||||
*ttyfd = fd;
|
||||
#else /* _CRAY */
|
||||
|
||||
/* First disconnect from the old controlling tty. */
|
||||
#ifdef TIOCNOTTY
|
||||
fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
|
||||
if (fd >= 0) {
|
||||
(void) ioctl(fd, TIOCNOTTY, NULL);
|
||||
close(fd);
|
||||
}
|
||||
#endif /* TIOCNOTTY */
|
||||
if (setsid() < 0)
|
||||
error("setsid: %.100s", strerror(errno));
|
||||
|
||||
/*
|
||||
* Verify that we are successfully disconnected from the controlling
|
||||
* tty.
|
||||
*/
|
||||
fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
|
||||
if (fd >= 0) {
|
||||
error("Failed to disconnect from controlling tty.");
|
||||
close(fd);
|
||||
}
|
||||
/* Make it our controlling tty. */
|
||||
#ifdef TIOCSCTTY
|
||||
debug("Setting controlling tty using TIOCSCTTY.");
|
||||
if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0)
|
||||
error("ioctl(TIOCSCTTY): %.100s", strerror(errno));
|
||||
#endif /* TIOCSCTTY */
|
||||
#ifdef HAVE_NEWS4
|
||||
if (setpgrp(0,0) < 0)
|
||||
error("SETPGRP %s",strerror(errno));
|
||||
#endif /* HAVE_NEWS4 */
|
||||
#ifdef USE_VHANGUP
|
||||
old = mysignal(SIGHUP, SIG_IGN);
|
||||
vhangup();
|
||||
mysignal(SIGHUP, old);
|
||||
#endif /* USE_VHANGUP */
|
||||
fd = open(ttyname, O_RDWR);
|
||||
if (fd < 0) {
|
||||
error("%.100s: %.100s", ttyname, strerror(errno));
|
||||
} else {
|
||||
#ifdef USE_VHANGUP
|
||||
close(*ttyfd);
|
||||
*ttyfd = fd;
|
||||
#else /* USE_VHANGUP */
|
||||
close(fd);
|
||||
#endif /* USE_VHANGUP */
|
||||
}
|
||||
/* Verify that we now have a controlling tty. */
|
||||
fd = open(_PATH_TTY, O_WRONLY);
|
||||
if (fd < 0)
|
||||
error("open /dev/tty failed - could not set controlling tty: %.100s",
|
||||
strerror(errno));
|
||||
else {
|
||||
close(fd);
|
||||
}
|
||||
#endif /* _CRAY */
|
||||
}
|
||||
|
||||
#if 0 /* not in BasiliskII */
|
||||
/* Changes the window size associated with the pty. */
|
||||
|
||||
void
|
||||
pty_change_window_size(int ptyfd, int row, int col,
|
||||
int xpixel, int ypixel)
|
||||
{
|
||||
struct winsize w;
|
||||
w.ws_row = row;
|
||||
w.ws_col = col;
|
||||
w.ws_xpixel = xpixel;
|
||||
w.ws_ypixel = ypixel;
|
||||
(void) ioctl(ptyfd, TIOCSWINSZ, &w);
|
||||
}
|
||||
|
||||
void
|
||||
pty_setowner(struct passwd *pw, const char *ttyname)
|
||||
{
|
||||
struct group *grp;
|
||||
gid_t gid;
|
||||
mode_t mode;
|
||||
struct stat st;
|
||||
|
||||
/* Determine the group to make the owner of the tty. */
|
||||
grp = getgrnam("tty");
|
||||
if (grp) {
|
||||
gid = grp->gr_gid;
|
||||
mode = S_IRUSR | S_IWUSR | S_IWGRP;
|
||||
} else {
|
||||
gid = pw->pw_gid;
|
||||
mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change owner and mode of the tty as required.
|
||||
* Warn but continue if filesystem is read-only and the uids match/
|
||||
* tty is owned by root.
|
||||
*/
|
||||
if (stat(ttyname, &st))
|
||||
fatal("stat(%.100s) failed: %.100s", ttyname,
|
||||
strerror(errno));
|
||||
|
||||
if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
|
||||
if (chown(ttyname, pw->pw_uid, gid) < 0) {
|
||||
if (errno == EROFS &&
|
||||
(st.st_uid == pw->pw_uid || st.st_uid == 0))
|
||||
error("chown(%.100s, %d, %d) failed: %.100s",
|
||||
ttyname, pw->pw_uid, gid,
|
||||
strerror(errno));
|
||||
else
|
||||
fatal("chown(%.100s, %d, %d) failed: %.100s",
|
||||
ttyname, pw->pw_uid, gid,
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) {
|
||||
if (chmod(ttyname, mode) < 0) {
|
||||
if (errno == EROFS &&
|
||||
(st.st_mode & (S_IRGRP | S_IROTH)) == 0)
|
||||
error("chmod(%.100s, 0%o) failed: %.100s",
|
||||
ttyname, mode, strerror(errno));
|
||||
else
|
||||
fatal("chmod(%.100s, 0%o) failed: %.100s",
|
||||
ttyname, mode, strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* not in BasiliskII */
|
26
BasiliskII/src/Unix/sshpty.h
Normal file
26
BasiliskII/src/Unix/sshpty.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* $OpenBSD: sshpty.h,v 1.4 2002/03/04 17:27:39 stevesk Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Functions for allocating a pseudo-terminal and making it the controlling
|
||||
* tty.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
#ifndef SSHPTY_H
|
||||
#define SSHPTY_H
|
||||
|
||||
int pty_allocate(int *, int *, char *, int);
|
||||
void pty_release(const char *);
|
||||
void pty_make_controlling_tty(int *, const char *);
|
||||
void pty_change_window_size(int, int, int, int, int);
|
||||
void pty_setowner(struct passwd *, const char *);
|
||||
|
||||
#endif /* SSHPTY_H */
|
75
BasiliskII/src/Unix/strlcpy.c
Normal file
75
BasiliskII/src/Unix/strlcpy.c
Normal file
@ -0,0 +1,75 @@
|
||||
/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifndef HAVE_STRLCPY
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include "strlcpy.h"
|
||||
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(dst, src, siz)
|
||||
char *dst;
|
||||
const char *src;
|
||||
size_t siz;
|
||||
{
|
||||
register char *d = dst;
|
||||
register const char *s = src;
|
||||
register size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0) {
|
||||
do {
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif /* !HAVE_STRLCPY */
|
12
BasiliskII/src/Unix/strlcpy.h
Normal file
12
BasiliskII/src/Unix/strlcpy.h
Normal file
@ -0,0 +1,12 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _BSD_STRLCPY_H
|
||||
#define _BSD_STRLCPY_H
|
||||
|
||||
#include "config.h"
|
||||
#ifndef HAVE_STRLCPY
|
||||
#include <sys/types.h>
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
#endif /* !HAVE_STRLCPY */
|
||||
|
||||
#endif /* _BSD_STRLCPY_H */
|
Loading…
Reference in New Issue
Block a user