kopia lustrzana https://github.com/sp9skp/spdxl
175 wiersze
4.9 KiB
C
175 wiersze
4.9 KiB
C
/*
|
|
* dxlAPRS toolchain
|
|
*
|
|
* Copyright (C) Christian Rabler <oe5dxl@oevsv.at>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
/* "@(#)Execlogin.c May 11 0:17:50 2017" */
|
|
|
|
|
|
#define X2C_int32
|
|
#define X2C_index32
|
|
#ifndef Execlogin_H_
|
|
#include "Execlogin.h"
|
|
#endif
|
|
#define Execlogin_C_
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#ifndef osi_H_
|
|
#include "osi.h"
|
|
#endif
|
|
#include <osic.h>
|
|
#ifndef mlib_H_
|
|
#include "mlib.h"
|
|
#endif
|
|
#include <stdlib.h>
|
|
#ifndef aprsstr_H_
|
|
#include "aprsstr.h"
|
|
#endif
|
|
#include <signal.h>
|
|
|
|
|
|
|
|
/*FROM stat IMPORT stat, stat_t;*/
|
|
/*, execv*/
|
|
/*IMPORT ptty; */
|
|
/**********************************************************************/
|
|
/* Find a currently unused pseudo tty and open its master side;
|
|
* return-value: 0=ok, <0=error
|
|
* on successfull function return, fd will contain the file descriptor,
|
|
* and PtyName the absolute path to the master-pty in the file system */
|
|
|
|
static int32_t GetNewTty(int32_t * fd, char ptsname[],
|
|
uint32_t ptsname_len)
|
|
{
|
|
int32_t res;
|
|
struct termios term;
|
|
*fd = open("/dev/ptmx", O_RDWR+O_NONBLOCK);
|
|
if (*fd<0L) osi_WrStrLn("error /dev/ptmx open", 21ul);
|
|
if (osi_getptsname(*fd, (char *)ptsname, ptsname_len)) {
|
|
osi_WrStrLn("no ttyname", 11ul);
|
|
}
|
|
/* WrStrLn(ptsname); */
|
|
if (osic_grantpts(*fd)) osi_WrStrLn("error ptty grant", 17ul);
|
|
if (osic_unlockpts(*fd)) osi_WrStrLn("error ptty unlock", 18ul);
|
|
res = tcgetattr(*fd, &term);
|
|
term.c_lflag = 0UL;
|
|
res = tcsetattr(*fd, 0L, &term);
|
|
return 0L;
|
|
} /* end GetNewTty() */
|
|
|
|
/**********************************************************************/
|
|
/* open the corresponding slave of a pseudo tty pair, adjust the
|
|
* terminal setting, redirect our stdin/out/err to this tty, and
|
|
* finalle make it our controlling terminal.
|
|
* return: 0=success, -1=failure */
|
|
|
|
static int32_t GetSlavePty(char name[], uint32_t name_len)
|
|
{
|
|
int32_t fd;
|
|
int32_t res;
|
|
struct termios term;
|
|
struct termios * anonym;
|
|
int32_t GetSlavePty_ret;
|
|
X2C_PCOPY((void **)&name,name_len);
|
|
res = chown((char *)name, 0L, 0L);
|
|
res = chmod((char *)name, 384L);
|
|
/* IF setsid()<0 THEN Close(fd); RETURN -1; END; */
|
|
/* fd:=open(name, O_RDWR+O_NOCTTY); */
|
|
fd = open(name, O_RDWR);
|
|
if (fd<0L) {
|
|
GetSlavePty_ret = -1L;
|
|
goto label;
|
|
}
|
|
/* now adjust the terminal settings */
|
|
res = tcgetattr(fd, &term);
|
|
{ /* with */
|
|
struct termios * anonym = &term;
|
|
anonym->c_lflag = (uint32_t)((uint32_t)anonym->c_lflag|0x8UL|0x2UL)
|
|
;
|
|
anonym->c_oflag = (uint32_t)((uint32_t)anonym->c_oflag|0x4UL);
|
|
anonym->c_iflag = (uint32_t)(((uint32_t)
|
|
anonym->c_iflag|0x100UL|0x1UL)&~0x1000UL);
|
|
}
|
|
/* c_cflag := CARDINAL( BITSET(c_cflag)-BITSET(CLOCAL)); */
|
|
res = tcsetattr(fd, 0L, &term);
|
|
/* create new session id, and set controlling terminal */
|
|
if (setsid()<0L) {
|
|
osic_Close(fd);
|
|
GetSlavePty_ret = -1L;
|
|
goto label;
|
|
}
|
|
if (ioctl(fd, 21518L, 0)<0L) {
|
|
osic_Close(fd);
|
|
GetSlavePty_ret = -1L;
|
|
goto label;
|
|
}
|
|
/* and finally redirect stdin, stdout, stderr */
|
|
if (fd) res = dup2(fd, 0L);
|
|
if (fd!=1L) res = dup2(fd, 1L);
|
|
if (fd!=2L) res = dup2(fd, 2L);
|
|
if (fd>2L) osic_Close(fd);
|
|
GetSlavePty_ret = 0L;
|
|
label:;
|
|
X2C_PFREE(name);
|
|
return GetSlavePty_ret;
|
|
} /* end GetSlavePty() */
|
|
|
|
/**********************************************************************/
|
|
/* Construct an array of arguments, and execute /bin/login with it.
|
|
* 'name' contains the username, which will be passed to /bin/login.
|
|
* it may be empty, in which case login will ask for the name.
|
|
* 'host' may optionally contain the users remote hostname, which e.g.
|
|
* is displayed by the 'who' command.
|
|
* 'passwd' can be set TRUE to force skipping the password authentication.
|
|
* This requires 'name' to be non-empty. */
|
|
|
|
extern int32_t Execlogin_StartLogin(struct Execlogin_tEXEC * cmd)
|
|
{
|
|
int32_t res;
|
|
int32_t PtyFd;
|
|
char PtyName[1024];
|
|
if (GetNewTty(&PtyFd, PtyName, 1024ul)<0L) return -1L;
|
|
res = fork();
|
|
if (res<0L) {
|
|
osic_Close(PtyFd);
|
|
return -1L;
|
|
}
|
|
if (res>0L) {
|
|
/* daddy */
|
|
/* signal(SIGINT, SIG_IGN); */
|
|
signal(SIGCHLD, SIG_IGN);
|
|
return PtyFd;
|
|
}
|
|
else {
|
|
/* child */
|
|
for (res = 0L; res<=1023L; res++) {
|
|
osic_Close(res);
|
|
} /* end for */
|
|
osic_Close(PtyFd);
|
|
/*
|
|
signal.signal(signal.SIGINT, signal.SIG_IGN);
|
|
signal.signal(signal.SIGHUP, signal.SIG_IGN);
|
|
*/
|
|
res = GetSlavePty(PtyName, 1024ul);
|
|
if (res<0L) exit(1L);
|
|
res = execv(cmd->cmdfn, cmd->args);
|
|
/* res := execve(cmd.cmdfn^, cmd.args^, NIL); */
|
|
/* RETURN -1; */
|
|
X2C_ABORT();
|
|
}
|
|
return 0;
|
|
} /* end StartLogin() */
|
|
|
|
|
|
extern void Execlogin_BEGIN(void)
|
|
{
|
|
static int Execlogin_init = 0;
|
|
if (Execlogin_init) return;
|
|
Execlogin_init = 1;
|
|
aprsstr_BEGIN();
|
|
osi_BEGIN();
|
|
}
|
|
|