📄 main.c
字号:
/*- * Copyright (c) 1993 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Bill Jolitz. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. */#ifndef lintchar copyright[] ="@(#) Copyright (c) 1993 The Regents of the University of California.\n\ All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)main.c 5.2 (Berkeley) 5/29/93";#endif /* not lint */#include "main.h"#include <sys/time.h>#include <sys/ioctl.h>#include <signal.h>#include <sys/types.h>#include <utmp.h>#include <setjmp.h>#include <sys/reboot.h>#include <errno.h>#include <sys/file.h>#include <ttyent.h>#include <sys/syslog.h>#include <sys/stat.h>#define LINSIZ sizeof(wtmp.ut_line)#define CMDSIZ 200 /* max string length for getty or window command*/#define ALL p = itab; p ; p = p->next#define EVER ;;#define SCPYN(a, b) strncpy(a, b, sizeof(a))#define SCMPN(a, b) strncmp(a, b, sizeof(a))char shell[] = "/bin/sh";char minus[] = "-";char runc[] = "/etc/rc";char utmpf[] = "/etc/utmp";char wtmpf[] = "/usr/adm/wtmp";char ctty[] = "/dev/console";struct utmp wtmp;struct tab{ char line[LINSIZ]; char comn[CMDSIZ]; int baud; /* outgoing baud rate */ int sock; /* socket if outgoing connected */ int fd; /* file desc if we have, else -1 */ int errfd; /* error file desc if we have, else -1 */ char xflag; int gpid; /* pid of getty or connector */ time_t gettytime; int gettycnt; struct tab *next;} *itab;char tty3[LINSIZ] = { "tty3" } ;char tty2[LINSIZ] = { "tty2" } ;int fi;int mergflag;char tty[20];jmp_buf sjbuf, shutpass;time_t time0;int reset();int idle();char *strcpy(), *strcat();long lseek();struct conversation convers[MAXCONNECTS] ;jmp_buf terminate;fd_set rd_fdset, wr_fdset ;int term(), sigpipe();int debug;extern int errno;struct timeval tv_2th = { 0, 500000 } ;main (argc,argv) char *argv[]; { int sock, msgsock, rval, rv ; struct sockaddr_un rqsts; int err; struct iovec iov[4]; int constatus, rqst, resp; int optlen ; char *optp; struct connectdomain *cdp; int i,n,afd ; struct conversation *cd ; struct tab *p ; /* initialize */ n = 0; FD_ZERO(&rd_fdset) ; FD_ZERO(&wr_fdset) ; signal (SIGTTOU, SIG_IGN) ; signal (SIGTTIN, SIG_IGN) ; signal (SIGINT, term) ; signal (SIGTERM, term) ; signal (SIGPIPE, sigpipe) ; if(setjmp(terminate)) goto on_error; openlog("connectd", LOG_CONS|LOG_ODELAY, LOG_AUTH); /* disassociate from tty pgrp */ n = open ("/dev/tty", 2) ; ioctl(n,TIOCNOTTY, 0) ; close(n) ; /* make incoming request socket */ sock = socket (AF_UNIX, SOCK_STREAM, 0) ; if (sock < 0) { perror("stream socket") ; exit(1) ; } rqsts.sun_family = AF_UNIX ; strcpy (rqsts.sun_path,"/dev/connect") ; if (bind (sock, &rqsts, sizeof (rqsts))) { perror ("bind /dev/connect") ; exit (1) ; } /* debugging ? */ if ((argc <= 1) || strcmp(argv[1],"-d") != 0) { if (fork()) exit(0) ; close (0); close (1); close (2); } else debug = 1; /* build tables */ itab = (struct tab *)calloc(1, sizeof(*itab)); SCPYN(itab->line, tty3); itab->fd = -1; /* do we have a fd open */ itab->sock = -1; /* does someone else have this fd? */ itab->gpid = 0; /* does getty have this fd? */ itab->next = (struct tab *)calloc(1, sizeof(*itab)); itab->next->fd = -1; /* do we have a fd open */ itab->next->sock = -1; /* does someone else have this fd? */ itab->next->gpid = 0; /* does getty else have this fd? */ SCPYN(itab->next->line, tty2); p = itab ; /* accept connection requests on socket */ listen (sock, 5) ; FD_SET (sock, &rd_fdset) ; /* add requests from other lines */ for (ALL) openline(p) ; /* service requests as they come in */ for (;;) { int s, ctrl, n; fd_set readable, writeable; readable = rd_fdset; writeable = wr_fdset;#ifdef notdeffor (i=0; i <20 ; i++) {if (FD_ISSET(i,&readable)) fprintf(stderr, "rd%d ", i) ;if (FD_ISSET(i,&writeable)) fprintf(stderr, "wr%d ", i) ;}fprintf(stderr, "?\n") ;#endif if ((n = select(21, &readable, &writeable, (fd_set *)0, &tv_2th )) <= 0) { if (n < 0 && errno != EINTR) if (debug) perror ("select") ; else syslog(LOG_WARNING, "select: %m\n"); sleep(1); continue; } /* got a request, see who it is */fprintf(stderr, "select %d\n", n) ;for (i=0; i <20 ; i++) {if (FD_ISSET(i,&readable))fprintf(stderr, "rdsel%d ", i) ;if (FD_ISSET(i,&writeable))fprintf(stderr, "wrsel%d ", i) ;}fprintf(stderr, "\n") ; /* have we a new connection request? */ if (FD_ISSET(sock, &readable)) { msgsock = accept(sock, 0, 0) ; if (msgsock == -1) { perror ("accept") ; continue ; }/*allocate a connection */ convers[msgsock].co_sock = msgsock ; FD_SET (msgsock, &rd_fdset) ;fprintf(stderr, "accept %d\n", msgsock) ; } /* have we a incoming request */for (p = itab; p ; p = p->next) if (FD_ISSET(p->fd, &writeable)) { /* fork off getty after setting up line */printf("do a getty on fd%d\n", p->fd) ;if(p->sock >= 0) { printf("on a conn?\n") ; continue; } i = fork (); if (i < 0) { perror("cd:fork") ; exit(1); } if (!i) { dup2(p->fd, 0); dup2(p->fd, 1); dup2(p->fd, 2); i = getdtablesize(); for (n=3 ; n < i ; n++) close (n) ;ioctl(0,TIOCYESTTY, 0) ; execl("/etc/getty", "getty", "std.1200", "-", 0) ; perror("exec"); exit(1); } else {p->gpid = i ; i = wait(&n) ;printf("cd: waitgetty %d %d\n", i, n) ;p->gpid = 0 ; closeline (p, 0) ;rmut(p) ; sleep (1) ; openline (p) ; } } ; ; /* have we an existing socket request */ for (cd = convers; cd - convers < MAXCONNECTS ; cd++) { cdp = &cd->co_cd ; if (FD_ISSET(cd->co_sock, &readable)) {fprintf(stderr, "recv %d\n", cd->co_sock) ; /* recieve connnection request message */ rqst = rcvrequest(cd->co_sock, cd, &optp, &optlen, &afd) ;/*fprintf(stderr, "rqst %d\n", rqst) ;*/ if (rqst < 0) goto end_session ;/*printf("cd:request %d ", rqst) ;*/ /* process request */ switch (rqst) { case CDNEWREQUEST: cd->co_rqst = rqst ;/*printf("cd_family %d, cd_address %s, cd_alen %d\n", cdp->cd_family, cdp->cd_address, cdp->cd_alen) ;*//*if (optlen) printf("option:%s\n", optp);*/ if (afd>= 0) { cd->co_errfd = afd ; } else cd->co_errfd = -1 ; cd->co_constatus = -1;for (p = itab; p ; p = p->next) if (p->gpid == 0 && p->fd >= 0 && p->sock < 0) break;if (!p) exit(0); /* return error can't find a line */fprintf(stderr, "allocate fd%d line %s\n", p->fd, p->line) ;ioctl(p->fd, TIOCSIGNCAR, 0) ;p->errfd = cd->co_errfd;p->sock = cd->co_sock ; i = fork (); if (i < 0) { perror("cd:fork") ; exit(1); } if (!i) { dup2(p->fd, 0); dup2(p->fd, 1); if (cd->co_errfd) dup2(cd->co_errfd,2); else close(2) ; i = getdtablesize(); for (n=3 ; n < i ; n++) close (n) ; execl("con", "con", cdp->cd_address, 0) ; perror("exec"); exit(1); } else { cd->co_pid = i ; i = wait(&n) ;/*printf("cd: wait %d %d\n", i, n) ;*/ if (n == 0) cd->co_constatus = n; else { fprintf(stderr, "cd: con fails status %d\n", n) ; cd->co_constatus = (-1 <<16) | n ; closeline (p, 0) ; } }if (p->fd >= 0) { fprintf(stderr, "cd: sending fd %d \n", p->fd) ; ioctl(p->fd, TIOCCIGNCAR, 0) ;}optlen = 0; resp = CDNEWRESPONSE ; /* send connnection response message */ err = sendrequest(cd->co_sock, resp, cd, optp, optlen, p->fd) ; if(p->fd >= 0) closeline (p, 1) ; if (cd->co_constatus) goto end_session ; break ; case CDFINISHREQUEST:for (p = itab; p ; p = p->next) if (p->sock == cd->co_sock) break;if(!p) exit(0); /* return no such connection */ p->fd = afd ;fprintf(stderr, "cd: received fd %d \n", p->fd) ; cd->co_constatus = -1;ioctl(p->fd, TIOCSIGNCAR, 0) ; i = fork (); if (i < 0) { perror("cd:fork") ; exit(1); } if (!i) { dup2(p->fd, 0); dup2(p->fd, 1); if (cd->co_errfd <= 0) dup2(cd->co_errfd,2); else close(2) ; i = getdtablesize(); for (n=3 ; n < i ; n++) close (n) ; execl("con", "con", "drop" , 0) ; perror("exec"); exit(1); } else { cd->co_pid = i ; i = wait(&n) ;fprintf(stderr,"cd: wait %d %d\n", i, n) ; if (n == 0) cd->co_constatus = n; else cd->co_constatus = (-1 <<16) | n ; }fprintf(stderr,"cd: dropped \n") ; cd->co_rqst = resp = CDFINISHRESPONSE ; /* send connnection response message */ err = sendrequest(cd->co_sock, resp, cd, 0, 0, 0) ; goto end_session; } /* end of switch */ } ; continue; /* end of if */ end_session:/*fprintf(stderr, "end_session\n") ;*/ close (cd->co_errfd) ; FD_CLR (cd->co_sock, &rd_fdset) ; close (cd->co_sock) ; cd->co_sock = 0 ; if (p->fd >= 0) closeline (p, 0) ; sleep(1) ; openline (p) ; } /* end of conv for */ } /*end of foerever */on_error: close (sock) ; unlink ("/dev/connect") ;}term() { struct tab *p; for (p = itab ; p ; p = p->next) if (p->gpid) kill (p->gpid, SIGHUP); longjmp (terminate);}sigpipe() { printf("SIGPIPE\n") ; fflush (stdout) ; longjmp (terminate); }/* * open and prepare line for connectd */openline(p) struct tab *p; { char ttyn[32]; int n; /* open the bastard */ strcpy (ttyn, "/dev/"); strcat (ttyn, p->line) ; p->fd = open (ttyn, O_RDWR|O_NDELAY) ; /* disassociate from our pgrp */ n = open ("/dev/tty", O_RDWR|O_NDELAY) ; ioctl (n, TIOCNOTTY, 0) ; close(n) ; /* mark 'em to be watched for carrier */ FD_SET (p->fd, &wr_fdset) ; /* if set in a still open state */ ioctl(p->fd, TIOCCIGNCAR, 0) ; if (debug) fprintf(stderr, "openline: %s: fd %d\n", p->line, p->fd) ;}closeline(p, i) struct tab *p; { if (debug) fprintf(stderr, "closeline: %s: fd %d ", p->line, p->fd) ; close (p->fd) ; FD_CLR (p->fd, &wr_fdset) ; p->fd = -1 ; if (i) { if (debug) fprintf(stderr, "remove from use\n") ; return ; } if (debug) fprintf(stderr, "entirely\n") ; if (p->gpid) kill (p->gpid, SIGKILL); /* no mercy */ p->gpid = 0 ; if(p->sock >= 0) close (p->sock); p->sock = -1 ;}#ifdef notdefstruct sigvec rvec = { reset, sigmask(SIGHUP), 0 };main(argc, argv) char **argv;{ int howto, oldhowto; time0 = time(0); if (argc > 1 && argv[1][0] == '-') { char *cp; howto = 0; cp = &argv[1][1]; while (*cp) switch (*cp++) { case 'a': howto |= RB_ASKNAME; break; case 's': howto |= RB_SINGLE; break; } } else { howto = RB_SINGLE; } openlog("connectd", LOG_CONS|LOG_ODELAY, LOG_AUTH); sigvec(SIGTERM, &rvec, (struct sigvec *)0); signal(SIGTSTP, idle); signal(SIGSTOP, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); (void) setjmp(sjbuf); for (EVER) { oldhowto = howto; howto = RB_SINGLE; if (setjmp(shutpass) == 0) shutdown(); if (oldhowto & RB_SINGLE) single(); if (runcom(oldhowto) == 0) continue; merge(); multiple(); }}int shutreset();shutdown(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -