📄 x29d.c
字号:
/* * X.29 server * * Frank Pronk (...!ubc-vision!pronk) * April, September 1984 * * Laboratory for Computational Vision * University of British Columbia * Copyright (c) */#include <sys/param.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/wait.h>#include <netccitt/x25.h>#include <errno.h>#include <netdb.h>#include <signal.h>#include <sys/ioctl.h>#include <sys/termios.h>#include <paths.h>#include "../h/x29.h"#define BUFSIZ 1024#define MAXARGS 10 /* maximum size of server argument list */#define X25NET 0 /* no ITI parameters */#define CCITT1978 1 /* 1978 CCITT standard parameter set */#define CCITT1980 2 /* 1980 CCITT standard parameter set */char pibuf[BUFSIZ], fibuf[BUFSIZ];int pty, net;extern char **environ;extern int errno;char line[MAXPATHLEN];char console[] = "/dev/console";short packet_size;short debug;char *tracefn; /* trace file name */char *server;short send_banner;struct termios pt, old_pt;struct sockaddr_x25 sock;int reapchild();struct net *lookup ();char ccitt1978_prof[] = { /* initial profile */ Q_BIT, X29_SET_AND_READ_PARMS, X29_ECHO_CODE, 1, /* echo on */ X29_FORWARDING_SIGNAL_CODE, 126, /* forward on all cntl */ X29_IDLE_TIMER_CODE, 0, /* off */ X29_AUX_DEV_CONTROL_CODE, 0, /* off */ X29_RECEIVE_NET_MSGS_CODE, 1, /* xmit network msgs */ X29_BREAK_PROCEDURE_CODE, 21, X29_PADDING_CODE, 0, /* off */ X29_LINE_FOLDING_CODE, 0, /* off */ X29_TRANSMISSION_SPEED_CODE, 0, X29_XON_XOFF_CODE, 1, /* enable XON/XOFF */};char ccitt1980_prof[] = { /* initial profile */ Q_BIT, X29_SET_AND_READ_PARMS, X29_ECHO_CODE, 1, /* echo on */ X29_FORWARDING_SIGNAL_CODE, 126, /* forward on all cntl */ X29_IDLE_TIMER_CODE, 0, /* off */ X29_AUX_DEV_CONTROL_CODE, 0, /* off */ X29_RECEIVE_NET_MSGS_CODE, 1, /* xmit network msgs */ X29_BREAK_PROCEDURE_CODE, 21, X29_PADDING_CODE, 0, /* off */ X29_LINE_FOLDING_CODE, 0, /* off */ X29_TRANSMISSION_SPEED_CODE, 0, X29_XON_XOFF_CODE, 1, /* enable XON/XOFF */ X29_LF_AFTER_CR, 4, /* lf after cr from terminal */ X29_EDITING, 1, /* on */ X29_CHARACTER_DELETE, CERASE, X29_LINE_DELETE, CKILL, X29_LINE_DISPLAY, CRPRNT,};char datapac_prof[] = { /* Canadian X.25 network */ Q_BIT, X29_SET_AND_READ_PARMS, X29_ECHO_CODE, 1, /* echo on */ X29_FORWARDING_SIGNAL_CODE, 126, /* forward on all cntl */ X29_IDLE_TIMER_CODE, 0, /* off */ X29_AUX_DEV_CONTROL_CODE, 0, /* off */ X29_RECEIVE_NET_MSGS_CODE, 1, /* xmit network msgs */ X29_BREAK_PROCEDURE_CODE, 21, X29_PADDING_CODE, 0, /* off */ X29_LINE_FOLDING_CODE, 0, /* off */ X29_TRANSMISSION_SPEED_CODE, 0, X29_XON_XOFF_CODE, 1, /* enable XON/XOFF */ X29_LF_AFTER_CR, 4, /* lf after cr from terminal */ X29_EDITING, 1, /* on */ X29_CHARACTER_DELETE, CERASE, X29_LINE_DELETE, CKILL, X29_LINE_DISPLAY, CRPRNT, /* * This rubbish can be removed when Datapac * adopts the 1980 standard parameter set. */ 0, 0, /* national parameter marker */ 123, 0, /* parity off */};struct net { char *n_name; /* generic name */ short n_type; /* see defines above */ char *n_profile; /* initial profile */ short n_proflen; /* length of n_profile */} *netp, nets[] = { "x.25", X25NET, 0, 0, "1978", CCITT1978, ccitt1978_prof, sizeof(ccitt1978_prof), "ccitt1978", CCITT1978, ccitt1978_prof, sizeof(ccitt1978_prof), "1980", CCITT1980, ccitt1980_prof, sizeof(ccitt1980_prof), "ccitt1980", CCITT1980, ccitt1980_prof, sizeof(ccitt1980_prof), "datapac", CCITT1980, datapac_prof, sizeof(datapac_prof), 0, 0, 0, 0};main(argc, argv)register char **argv;{ register int s, pid; register char *p; /* * If this host doesn't support X.25, give up. */ s = socket(AF_CCITT, SOCK_STREAM, 0); if (s < 0 && errno == EPROTONOSUPPORT) fatal(2, "X.25 is not supported on this machine"); close(s); netp = lookup ("ccitt1978"); sock.x25_family = AF_CCITT; sock.x25_len = sizeof(sock); sock.x25_opts.op_flags = X25_MQBIT; sock.x25_udata[0] = ITI_CALL; sock.x25_udlen = 4; for (argv++; argc > 1; argc--, argv++) if (**argv == '-') for (p = *argv+1; *p; p++) switch (*p) { case 'b': send_banner++; break; case 'c': if (argc > 1) { argc--; argv++; if ((netp = lookup (*argv)) == 0) fatal(1, "Unknown network type"); } break; case 'p': if (argc > 1) { argc--; argv++; strcpy (sock.x25_udata, *argv); } break; case 'r': sock.x25_opts.op_flags |= X25_REVERSE_CHARGE; break; case 'd': debug++; break; case 't': if (argc > 1) { argc--; argv++; tracefn = *argv; } else fatal(1, "missing trace file"); break; default: fatal (1, "usage: x29d -b -c nettype -p protocol -r -t trace_file server"); } else server = *argv; if (server == 0) fatal (1, "no server specified"); if (debug == 0) daemon(0, 0); while ((s = socket(AF_CCITT, SOCK_STREAM, 0)) < 0) sleep(60); while (bind(s, (caddr_t)&sock, sizeof (sock)) < 0) sleep(60); signal(SIGCHLD, reapchild); listen(s, 5); for (;;) { struct sockaddr_x25 from; int fromlen = sizeof (from); if ((net = accept(s, (caddr_t)&from, &fromlen)) < 0) { if (errno != EINTR) sleep (60); continue; } while ((pid = fork()) < 0) sleep(60); if (pid == 0) { signal(SIGCHLD, SIG_DFL); doit(&from); } close(net); } /*NOTREACHED*/}struct net *lookup (name)char *name;{ register struct net *np; for (np = nets; np->n_name; np++) if (strcmp (np->n_name, name) == 0) return (np); return (0);}reapchild(){ union wait status; while (wait3(&status, WNOHANG, 0) > 0) ;}char *envinit[] = { "TERM=ccitt", 0 };int cleanup();struct termios term;/* * Get a pty, scan input lines. */doit(who)struct sockaddr_x25 *who;{ register char *cp; int i, p, t; packet_size = 1 << who->x25_opts.op_psize; i = forkpty(&pty, line, &term, 0); if (i > 0) x29d(); if (i < 0) fatalperror("fork", errno); environ = envinit; call_server (who); /*NOTREACHED*/}call_server (who)struct sockaddr_x25 *who;{ register struct hostent *hp = 0; register char *p, **ap; char *args[MAXARGS]; struct stat st; struct hostent *getx25hostbyaddr(); int ccitt = 0; p = server; while (*p && *p != ' ' && *p != '\t') /* split program from args */ p++; if (*p) *p++ = '\0'; ap = args; while (*p) { while (*p == ' ' || *p == '\t') p++; if (ap < &args[MAXARGS-2]) *ap++ = p; if (strcmp(p, "-ccitt") == 0) ccitt = 1; while (*p && *p != ' ' && *p != '\t') p++; if (*p) *p++ = '\0'; } if (stat (server, &st) < 0) fatalperror (server, errno); /* * For security: if running as root, switch to user * and group id of server. This prevents privately * maintainted or bogus servers from getting super- * user permissions. */ if (getuid() == 0) { setgid (st.st_gid); setuid (st.st_uid); } if (hp = getx25hostbyaddr (who->x25_addr)) *ap++ = hp->h_name; else *ap++ = (char *)who->x25_addr; /* * If the -ccitt flag was given, add another argument * to tell login if charging is being reversed or not. */ if (ccitt) *ap++ = (who->x25_opts.op_flags & X25_REVERSE_CHARGE) ? "y" : "n"; *ap = 0; execv (server, args); fatalperror (server, errno); /*NOTREACHED*/}fatal(f, msg) int f; char *msg;{ register char *p; char buf[BUFSIZ], *index(); p = buf; if (f == net) *p++ = 0; strcpy(p, "x29d: "); strcat(p, msg); strcat(p, "\n"); (void) write(f, p, (index(p, '\n')-p)+1); exit(1);}fatalperror(msg, err)char *msg;{ char buf[BUFSIZ]; extern char *sys_errlist[]; strcpy(buf, msg); strcat(buf, ": "); strcat(buf, sys_errlist[err]); fatal(net, buf);}/* * Main loop. Select from pty and network, and * hand data to iti receiver. */x29d(){ register int pcc, fcc, cc; register char *fbp; int pgrp, x25_interrupt(), on = 1; char hostname[32]; ioctl(net, FIONBIO, (char *)&on); ioctl(pty, FIONBIO, (char *)&on); /*ioctl(pty, TIOCREMECHO, (char *)&on); /* enable special pty mode */ /* new equivalent is no processing in pty, no echo, but let user set modes and have either remote end do line mode processing or do it in daemon */ ioctl(pty, TIOCEXT, (char *)&on); ioctl(pty, TIOCPKT, (char *)&on);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -