📄 ckutio.c
字号:
sysinit() { int x; char * s;#ifdef CK_UTSNAME struct utsname name;#endif /* CK_UTSNAME */ extern char startupdir[];/* BEFORE ANYTHING ELSE: 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.*/ x = priv_ini();#ifdef SUIDDEBUG fprintf(stderr,"PRIV_INI=%d\n",x);#endif /* SUIDDEBUG */ if (x) { 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); } signal(SIGINT,SIG_IGN); /* Ignore interrupts at first */ signal(SIGFPE,SIG_IGN); /* Ignore floating-point exceptions */ signal(SIGHUP,sighup); /* Catch SIGHUP */#ifndef NOSIGWINCH#ifdef SIGWINCH signal(SIGWINCH,winchh); /* Catch window-size change */#endif /* SIGWINCH */#endif /* NOSIGWINCH */#ifndef NOJC/* Get the initial job control state. If it is SIG_IGN, that means the shell does not support job control, and so we'd better not suspend ourselves.*/#ifdef SIGTSTP jchdlr = signal(SIGTSTP,SIG_IGN); if (jchdlr == SIG_IGN) { jcshell = 0; debug(F100,"sysinit jchdlr: SIG_IGN","",0); } else if (jchdlr == SIG_DFL) { debug(F100,"sysinit jchdlr: SIG_DFL","",0); jcshell = 1; } else { debug(F100,"sysinit jchdlr: other","",0); jcshell = 3; } (VOID) signal(SIGTSTP,jchdlr); /* Put it back... */#endif /* SIGTSTP */#endif /* NOJC */ conbgt(0); /* See if we're in the background */ congm(); /* Get console modes */ (VOID) signal(SIGALRM,SIG_IGN); /* Ignore alarms */ ignorsigs(); /* Ignore some other signals */#ifdef F_SETFL iniflags = fcntl(0,F_GETFL,0); /* Get stdin flags */#endif /* F_SETFL */#ifdef ultrix gtty(0,&vanilla); /* Get sgtty info */#else#ifdef AUX set42sig(); /* Don't ask! (hakanson@cs.orst.edu) */#endif /* AUX */#endif /* ultrix *//* Warning: on some UNIX systems (SVR4?), ttyname() reportedly opens /dev but never closes it. If it is called often enough, we run out of file descriptors and subsequent open()'s of other devices or files can fail.*/ s = NULL;#ifndef MINIX if (isatty(0)) /* Name of controlling terminal */ s = ttyname(0); else if (isatty(1)) s = ttyname(1); else if (isatty(2)) s = ttyname(2); debug(F110,"sysinit ttyname(0)",s,0);#endif /* MINIX */#ifdef BEOS if (!dftty) makestr(&dftty,s);#endif /* BEOS */ if (s) ckstrncpy((char *)cttnam,s,DEVNAMLEN+1);#ifdef SVORPOSIX if (!cttnam[0]) ctermid(cttnam);#endif /* SVORPOSIX */ if (!cttnam[0]) ckstrncpy((char *)cttnam,dftty,DEVNAMLEN+1); debug(F110,"sysinit CTTNAM",CTTNAM,0); debug(F110,"sysinit cttnam",cttnam,0); ttgwsiz(); /* Get window (screen) dimensions. */#ifndef NOSYSCONF#ifdef _SC_OPEN_MAX ckmaxfiles = sysconf(_SC_OPEN_MAX);#endif /* _SC_OPEN_MAX */#endif /* NOSYSCONF */#ifdef Plan9 if (!backgrd) { consctlfd = open("/dev/consctl", O_WRONLY); /*noisefd = open("/dev/noise", O_WRONLY)*/ } ckxech = 1;#endif /* Plan9 */#ifdef CK_UTSNAME if (uname(&name) > -1) { ckstrncpy(unm_mch,name.machine,CK_SYSNMLN); ckstrncpy(unm_nam,name.sysname,CK_SYSNMLN); ckstrncpy(unm_rel,name.release,CK_SYSNMLN); ckstrncpy(unm_ver,name.version,CK_SYSNMLN);#ifdef DEBUG if (deblog) { debug(F110,"sysinit uname machine",unm_mch,0); debug(F110,"sysinit uname sysname",unm_nam,0); debug(F110,"sysinit uname release",unm_rel,0); debug(F110,"sysinit uname version",unm_ver,0); }#endif /* DEBUG */#ifdef HPUX9PLUS if (name.machine[5] == '8') hpis800 = 1; else hpis800 = 0; debug(F101,"sysinit hpis800","",hpis800);#endif /* HPUX9PLUS */#ifdef TRU64 getsysinfo(GSI_PLATFORM_NAME, unm_mod, CK_SYSNMLN, 0, 0); debug(F110,"sysinit getsysinfo model",unm_mod,0);#endif /* TRU64 */#ifdef SOLARIS25 sysinfo(SI_PLATFORM, unm_mod, CK_SYSNMLN); debug(F110,"sysinit sysinfo model",unm_mod,0);#endif /* SOLARIS25 */ }#endif /* CK_UTSNAME */#ifdef CK_ENVIRONMENT {#ifdef TNCODE extern char tn_env_acct[], tn_env_disp[], tn_env_job[], tn_env_prnt[], tn_env_sys[];#endif /* TNCODE */ extern char uidbuf[]; extern char * whoami(); char *p;#ifdef CKSENDUID uidbuf[0] = '\0';#ifdef IKSD if (!inserver) {#endif /* IKSD */ p = getenv("USER"); debug(F110,"sysinit uidbuf from USER",uidbuf,0); if (!p) p = ""; if (!*p) { p = getenv("LOGNAME"); debug(F110,"sysinit uidbuf from LOGNAME",uidbuf,0); } if (!p) p = ""; if (!*p) { p = whoami(); debug(F110,"sysinit uidbuf from whoami()",uidbuf,0); } if (!p) p = ""; ckstrncpy(uidbuf, *p ? p : "UNKNOWN", UIDBUFLEN);#ifdef IKSD }#endif /* IKSD */ debug(F110,"sysinit final uidbuf",uidbuf,0);#endif /* CKSENDUID */#ifdef TNCODE if ((p = getenv("JOB"))) ckstrncpy(tn_env_job,p,63); if ((p = getenv("ACCT"))) ckstrncpy(tn_env_acct,p,63); if ((p = getenv("PRINTER"))) ckstrncpy(tn_env_prnt,p,63); if ((p = getenv("DISPLAY"))) ckstrncpy(tn_env_disp,p,63);#ifdef aegis ckstrncpy(tn_env_sys,"Aegis",64);#else#ifdef Plan9 ckstrncpy(tn_env_sys,"Plan9",64);#else ckstrncpy(tn_env_sys,"UNIX",64);#endif /* Plan9 */#endif /* aegis */#endif /* TNCODE */ }#endif /* CK_ENVIRONMENT */#ifdef CK_SNDLOC { extern char * tn_loc; char *p; if (p = getenv("LOCATION")) if (tn_loc = (char *)malloc((int)strlen(p)+1)) strcpy(tn_loc,p); /* safe */ }#endif /* CK_SNDLOC */ ckstrncpy(startupdir, zgtdir(), CKMAXPATH); startupdir[CKMAXPATH] = '\0'; x = strlen(startupdir); if (x <= 0) { startupdir[0] = '/'; startupdir[1] = '\0'; } else if (startupdir[x-1] != '/') { startupdir[x] = '/'; startupdir[x+1] = '\0'; } debug(F110,"sysinit startupdir",startupdir,0);#ifdef TTLEBUF le_init();#endif /* TTLEBUF */#ifdef BSD44ORPOSIX /* This should catch the ncurses platforms */ /* Some platforms don't have putenv(), like NeXTSTEP */ putenv("NCURSES_NO_SETBUF=1");#endif /* BSD44ORPOSIX */ return(0);}/* S Y S C L E A N U P -- System-dependent program cleanup. */intsyscleanup() {#ifdef F_SETFL if (iniflags > -1) fcntl(0,F_SETFL,iniflags); /* Restore stdin flags */#endif /* F_SETFL */#ifdef ultrix stty(0,&vanilla); /* Get sgtty info */#endif /* ultrix */#ifdef NETCMD if (ttpid) kill(ttpid,9);#endif /* NETCMD */ 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 */#ifdef ultrix int temp = 0;#endif /* ultrix */#ifndef OPENFIRST char fullname[DEVNAMLEN+1];#endif /* OPENFIRST */ char * fnam; /* Full name after expansion */ int y;#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(F110,"ttopen ttname",ttname,0); debug(F110,"ttopen ttnmsv",ttnmsv,0); debug(F101,"ttopen modem","",modem); debug(F101,"ttopen netconn","",netconn); debug(F101,"ttopen ttyfd","",ttyfd); debug(F101,"ttopen *lcl","",*lcl); debug(F101,"ttopen ttmdm","",ttmdm); debug(F101,"ttopen ttnet","",ttnet); ttpmsk = 0xff; lockpid[0] = '\0'; if (ttyfd > -1) { /* If device already opened */ if (!strncmp(ttname,ttnmsv,DEVNAMLEN)) /* are new & old names equal? */ return(0); /* Yes, nothing to do - just return */ ttnmsv[0] = '\0'; /* No, clear out old name */ ttclos(ttyfd); /* close old connection. */ } wasclosed = 0; /* New connection, not closed yet. */ ttpipe = 0; /* Assume it's not a pipe */ ttpty = 0; /* or a pty... */#ifdef NETCONN/* This is a bit tricky... Suppose that previously Kermit had dialed a telnet modem server ("set host xxx:2001, set modem type usr, dial ..."). Then the connection was closed (ttyfd = -1), and then a REDIAL command was given. At this point we've obliterated the negative modem type hack, and so would treat the IP hostname as a device name, and would then fail because of "No such device or directory". But the previous connection has left behind some clues, so let's use them...*/ if (ttyfd < 0) { /* Connection is not open */ if (!strcmp(ttname,ttnmsv)) { /* Old and new names the same? */ if (((netconn > 0) && (ttmdm < 0)) || ((ttnet > 0) && (!ckstrchr(ttname,'/')) && (ckstrchr(ttname,':'))) ) { int x, rc; x = (ttmdm < 0) ? -ttmdm : ttnet; rc = netopen(ttname, lcl, x); debug(F111,"ttopen REOPEN netopen",ttname,rc); if (rc > -1) { netconn = 1; xlocal = *lcl = 1; } else { netconn = 0; } gotsigs = 0; return(rc); } } }#endif /* NETCONN */#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 /* BSD4 */#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 */#ifdef NETCONN if (modem < 0) { /* modem < 0 = code for network */ 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 net ttfdflg",ttname,ttfdflg); debug(F101,"ttopen net ttyfd","",ttyfd); ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */ x = 1; /* Return code is "good". */ if (telnetfd) { ttnet = NET_TCPB; if (ttnproto != NP_TCPRAW) ttnproto = NP_TELNET;#ifdef SUNX25 } else if (x25fd) { ttnet = NET_SX25; ttnproto = NP_NONE;#endif /* SUNX25 */ } } else { /* Host name or address given */#ifdef NETPTY if (modem == NET_PTY) { int x; if (nopush) { debug(F100,"ttopen PTY: nopush","",0); return(-1); } ttnet = NET_PTY; ttnproto = NP_NONE; netconn = 1; /* but we don't use network i/o */ ttpty = 1; debug(F110,"ttopen PTY",ttname,0); x = do_pty(ttname); if (x > -1) { ckstrncpy(ttnmsv,ttname,DEVNAMLEN); xlocal = *lcl = 1; /* It's local */ } else { ttpty = 0; netconn = 0; } gotsigs = 0; return(x); }#endif /* NETPTY */#ifdef NETCMD/* dup2() is not available on older System V platforms like AT&T 3Bx. For those systems we punt by not defining NETCMD, but we might be able to do better -- see workarounds for this problem in ckufio.c (search for dup2).*/ if (modem == NET_CMD) { if (nopush) { debug(F100,"ttopen pipe: nopush","",0); return(-1); } if (pipe(pipe0) || pipe(pipe1)) { perror("Pipe error"); return(-1); } ttpid = fork(); /* Make a fork */ switch (ttpid) { case -1: /* Error making fork */ close(pipe0[0]); close(pipe0[1]); close(pipe1[0]); close(pipe1[1]); perror("Fork error"); return(-1); case 0: /* Child. */ close(pipe0[0]); close(pipe1[1]); dup2(pipe0[1], 1); close(pipe0[1]); dup2(pipe1[0], 0); close(pipe1[0]); system(ttname); _exit(0); default: /* Parent */ close(pipe0[1]); close(pipe1[0]); fdin = pipe0[0]; /* Read from pipe */ fdout = pipe1[1]; /* Write to pipe */ ttout = fdopen(fdout,"w"); /* Get stream so we can */ if (!ttout) { /* make it unbuffered. */ perror("fdopen failure"); return(-1); } setbuf(ttout,NULL); ckstrncpy(ttnmsv,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -