spdxl/src/Execlogin.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();
}