📄 ckutio.c
字号:
#ifdef apollo_PROTOTYP( SIGTYP timerh, () );_PROTOTYP( SIGTYP cctrap, () );_PROTOTYP( SIGTYP esctrp, () );_PROTOTYP( SIGTYP sig_ign, () );#else_PROTOTYP( SIGTYP timerh, (int) );_PROTOTYP( SIGTYP cctrap, (int) );_PROTOTYP( SIGTYP esctrp, (int) );#endif /* apollo */_PROTOTYP( int do_open, (char *) );_PROTOTYP( int ttrpid, (char *) );_PROTOTYP( static int ttlock, (char *) );_PROTOTYP( static int ttunlck, (void) );_PROTOTYP( int mygetbuf, (void) );_PROTOTYP( int myfillbuf, (void) );_PROTOTYP( VOID conbgt, (int) );#ifdef ACUCNTRL_PROTOTYP( VOID acucntrl, (char *, char *) );#endif /* ACUCNTRL */#ifdef BSD44ORPOSIX_PROTOTYP( int carrctl, (struct termios *, int) );#else#ifdef ATTSV_PROTOTYP( int carrctl, (struct termio *, int) );#else_PROTOTYP( int carrctl, (struct sgttyb *, int) );#endif /* ATTSV */#endif /* BSD44ORPOSIX */#ifdef ATT7300_PROTOTYP( int attdial, (char *, long, char *) );_PROTOTYP( int offgetty, (char *) );_PROTOTYP( int ongetty, (char *) );#endif /* ATT7300 */#ifdef CK_ANSICstatic char *xxlast(char *s, char c)#elsestatic char *xxlast(s,c) char *s; char c;#endif /* CK_ANSIC *//* xxlast */ { /* Last occurrence of character c in string s. */ int i; for (i = (int)strlen(s); i > 0; i--) if ( s[i-1] == c ) return( s + (i - 1) ); return(NULL);}/* Timeout handler for communication line input functions */SIGTYPtimerh(foo) int foo; { ttimoff(); longjmp(sjbuf,1);}/* Control-C trap for communication line input functions */int cc_int; /* Flag */SIGTYP (* occt)(); /* For saving old SIGINT handler */SIGTYPcctrap(foo) int foo; { /* Needs arg for ANSI C */ cc_int = 1; /* signal() prototype. */ return;}/* S Y S I N I T -- System-dependent program initialization. */intsysinit() { int x; conbgt(0); /* See if we're in the background */#ifndef __386BSD__/* 386BSD doesn't allow opening /dev/tty if Kermit is running setuid.*/ congm(); /* Get console modes */#endif /* __386BSD__ */ signal(SIGALRM,SIG_IGN); /* Ignore alarms */#ifdef ultrix gtty(0,&vanilla); /* Get sgtty info */ iniflags = fcntl(0,F_GETFL,0); /* Get flags */#else#ifdef AUX set42sig(); /* Don't ask! (hakanson@cs.orst.edu) */#endif /* AUX */#endif /* ultrix *//* Initialize the setuid package. *//* Change to the user's real user and group id. *//* If this can't be done, don't run at all. */ if (x = priv_ini()) { if (x | 1) fprintf(stderr,"Fatal: setuid failure.\n"); if (x | 2) fprintf(stderr,"Fatal: setgid failure.\n"); if (x | 4) fprintf(stderr,"Fatal: C-Kermit setuid to root!\n"); exit(1); }#ifdef __386BSD__/* 386BSD... OK, now we have changed into ourselves, so can open /dev/tty.*/ congm(); /* Get console modes */#endif /* __386BSD__ */ return(0);}/* S Y S C L E A N U P -- System-dependent program cleanup. */intsyscleanup() {#ifdef ultrix stty(0,&vanilla); /* Get sgtty info */ fcntl(0,F_SETFL,iniflags); /* Restore flags */#endif /* ultrix */ /* No need to call anything in the suid package here, right? */ return(0);}/* T T O P E N -- Open a tty for exclusive access. *//* Call with: ttname: character string - device name or network host name. lcl: If called with lcl < 0, sets value of lcl as follows: 0: the terminal named by ttname is the job's controlling terminal. 1: the terminal named by ttname is not the job's controlling terminal. But watch out: if a line is already open, or if requested line can't be opened, then lcl remains (and is returned as) -1. modem: Less than zero: ttname is a network host name. Zero or greater: ttname is a terminal device name. Zero means a local connection (don't use modem signals). Positive means use modem signals. timo: 0 = no timer. nonzero = number of seconds to wait for open() to return before timing out. Returns: 0 on success -5 if device is in use -4 if access to device is denied -3 if access to lock directory denied -2 upon timeout waiting for device to open -1 on other error*/static int ttotmo = 0; /* Timeout flag *//* Flag kept here to avoid being clobbered by longjmp. */intttopen(ttname,lcl,modem,timo) char *ttname; int *lcl, modem, timo; {#ifdef BSD44#define ctermid(x) strcpy(x,"")#else#ifdef SVORPOSIX#ifndef CIE extern char *ctermid(); /* Wish they all had this! */#else /* CIE Regulus */#define ctermid(x) strcpy(x,"")#endif /* CIE */#endif /* SVORPOSIX */#endif /* BSD44 */ char *x; /* what's this ? */#ifndef MINIX extern char* ttyname();#endif /* MINIX */ char cname[DEVNAMLEN+4];#ifndef pdp11#define NAMEFD /* Feature to allow name to be an open file descriptor */#endif /* pdp11 */#ifdef NAMEFD char *p; debug(F101,"ttopen telnetfd","",telnetfd);#endif /* NAMEFD */ debug(F111,"ttopen entry modem",ttname,modem); debug(F101," ttyfd","",ttyfd); debug(F101," lcl","",*lcl);#ifdef MAXNAMLEN debug(F100,"ttopen MAXNAMLEN defined","",0);#else debug(F100,"ttopen MAXNAMLEN *NOT* defined","",0);#endif#ifdef BSD4 debug(F100,"ttopen BSD4 defined","",0);#else debug(F100,"ttopen BSD4 *NOT* defined","",0);#endif#ifdef BSD42 debug(F100,"ttopen BSD42 defined","",0);#else debug(F100,"ttopen BSD42 *NOT* defined","",0);#endif /* BSD42 */#ifdef MYREAD debug(F100,"ttopen MYREAD defined","",0);#else debug(F100,"ttopen MYREAD *NOT* defined","",0);#endif /* MYREAD */ if (ttyfd > -1) { /* if device already opened */ if (strncmp(ttname,ttnmsv,DEVNAMLEN)) /* are new & old names equal? */ ttclos(ttyfd); /* no, close old ttname, open new */ else /* else same, ignore this call, */ return(0); /* and return. */ }#ifdef NETCONN if (modem < 0) { /* modem < 0 = special code for net */ int x; ttmdm = modem; modem = -modem; /* Positive network type number */ fdflag = 0; /* Stdio not redirected. */ netconn = 1; /* And it's a network connection */ debug(F111,"ttopen net",ttname,modem);#ifdef NAMEFD for (p = ttname; isdigit(*p); p++) ; /* Check for all digits */ if (*p == '\0' && (telnetfd || x25fd)) { /* Avoid X.121 addresses */ ttyfd = atoi(ttname); /* Is there a way to test it's open? */ ttfdflg = 1; /* We got an open file descriptor */ debug(F111,"ttopen got open network fd",ttname,ttyfd); strncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */ x = 1; /* Return code is "good". */ if (telnetfd) { ttnet = NET_TCPB; ttnproto = NP_TELNET;#ifdef SUNX25 } else if (x25fd) { ttnet = NET_SX25; ttnproto = NP_NONE;#endif /* SUNX25 */ } } else { /* Host name or address given */#endif /* NAMEFD */ x = netopen(ttname, lcl, modem); /* (see ckcnet.h) */ if (x > -1) { strncpy(ttnmsv,ttname,DEVNAMLEN); } else netconn = 0;#ifdef NAMEFD }#endif /* NAMEFD */#ifdef sony_news /* Sony NEWS */ if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get Kanji mode */ perror("ttopen error getting Kanji mode (network)"); debug(F111,"ttopen error getting Kanji mode","network",0); km_ext = -1; /* Make sure this stays undefined. */ }#endif /* sony_news */ xlocal = *lcl = 1; /* Network connections are local. */ debug(F101,"ttopen net x","",x); if (x > -1 && !x25fd) x = tn_ini(); /* Initialize TELNET protocol */ return(x); } else { /* Terminal device */#endif /* NETCONN */#ifdef NAMEFD/* This code lets you give Kermit an open file descriptor for a serial communication device, rather than a device name. Kermit assumes that the line is already open, locked, conditioned with the right parameters, etc.*/ for (p = ttname; isdigit(*p); p++) ; /* Check for all digits */ if (*p == '\0') { ttyfd = atoi(ttname); /* Is there a way to test it's open? */ debug(F111,"ttopen got open fd",ttname,ttyfd); strncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */ xlocal = *lcl = 1; /* Assume it's local. */ netconn = 0; /* Assume it's not a network. */ tvtflg = 0; /* Might need to initialize modes. */ ttmdm = modem; /* Remember modem type. */ fdflag = 0; /* Stdio not redirected. */ ttfdflg = 1; /* Flag we were opened this way. */#ifdef sony_news /* Sony NEWS */ /* Get device Kanji mode */ if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { perror("ttopen error getting Kanji mode"); debug(F101,"ttopen error getting Kanji mode","",0); km_ext = -1; /* Make sure this stays undefined. */ }#endif /* sony_news */ return(0); /* Return success */ }#endif /* NAMEFD */#ifdef NETCONN }#endif /* NETCONN *//* Here we have to open a serial device of the given name. */ occt = signal(SIGINT, cctrap); /* Set Control-C trap, save old one */ tvtflg = 0; /* Flag for use by ttvt(). */ /* 0 = ttvt not called yet for this device */ fdflag = (!isatty(0) || !isatty(1)); /* Flag for stdio redirected */ debug(F101,"ttopen fdflag","",fdflag); ttmdm = modem; /* Make this available to other fns */ xlocal = *lcl; /* Make this available to other fns *//* Code for handling bidirectional tty lines goes here. *//* Use specified method for turning off logins and suppressing getty. */#ifdef ACUCNTRL /* Should put call to priv_on() here, but that would be very risky! */ acucntrl("disable",ttname); /* acucntrl() program. */ /* and priv_off() here... */#else#ifdef ATT7300 if ((attmodem & DOGETY) == 0) /* offgetty() program. */ attmodem |= offgetty(ttname); /* Remember response. */#endif /* ATT7300 */#endif /* ACUCNTRL *//* In the following section, we open the tty device for read/write. If a modem has been specified via "set modem" prior to "set line" then the O_NDELAY parameter is used in the open, provided this symbol is defined (e.g. in fcntl.h), so that the program does not hang waiting for carrier (which in most cases won't be present because a connection has not been dialed yet). O_NDELAY is removed later on in ttopen(). It would make more sense to first determine if the line is local before doing this, but because ttyname() requires a file descriptor, we have to open it first. See do_open(). Now open the device using the desired treatment of carrier. If carrier is REQUIRED, then open could hang forever, so an optional timer is provided. If carrier is not required, the timer should never go off, and should do no harm...*/ ttotmo = 0; /* Flag no timeout */ if (timo > 0) { int xx; saval = signal(SIGALRM,timerh); /* Timed, set up timer. */ xx = alarm(timo); /* Timed open() */ debug(F101,"ttopen alarm","",xx); if (setjmp(sjbuf)) { ttotmo = 1; /* Flag timeout. */ } else ttyfd = do_open(ttname); ttimoff(); debug(F111,"ttopen","modem",modem); debug(F101," ttyfd","",ttyfd); debug(F101," alarm return","",ttotmo); } else ttyfd = do_open(ttname); debug(F111,"ttopen ttyfd",ttname,ttyfd); if (ttyfd < 0) { /* If couldn't open, fail. */#ifdef ATT7300 if (attmodem & DOGETY) /* was getty(1m) running before us? */ ongetty(ttnmsv); /* yes, restart on tty line */ attmodem &= ~DOGETY; /* no phone in use, getty restored */#else#if ACUCNTRL /* Should put call to priv_on() here, but that would be risky! */ acucntrl("enable",ttname); /* acucntrl() program. */ /* and priv_off() here... */#endif /* ACUNTRL */#endif /* ATT7300 */ signal(SIGINT,occt); /* Put old Ctrl-C trap back. */ if (errno == EACCES) { /* Device is protected against user */ perror(ttname); /* Print message */ debug(F111,"ttopen tty access denied",ttname,errno); return(-4); } else return(ttotmo ? -2 : -1); } /* Make sure it's a real tty. */ if (!isatty(ttyfd)) { fprintf(stderr,"%s is not a tty!\n",ttname); debug(F110,"ttopen not a tty",ttname,0); close(ttyfd); ttyfd = -1; signal(SIGINT,occt); return(-1); }#ifdef aegis /* Apollo C runtime claims that console pads are tty devices, which * is reasonable, but they aren't any good for packet transfer. */ ios_$inq_type_uid((short)ttyfd, ttyuid, st); if (st.all != status_$ok) { fprintf(stderr, "problem getting tty object type: "); error_$print(st); } else if (ttyuid != sio_$uid) { /* reject non-SIO lines */ close(ttyfd); ttyfd = -1; errno = ENOTTY; perror(ttname); signal(SIGINT,occt); return(-1); }#endif /* aegis */ strncpy(ttnmsv,ttname,DEVNAMLEN); /* Keep copy of name locally. *//* Caller wants us to figure out if line is controlling tty */ if (*lcl < 0) { int x0 = 0, x1 = 0; if (strcmp(ttname,CTTNAM) == 0) { /* "/dev/tty" always remote */ xlocal = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -