/[inetutils]/inetutils/telnetd/sys_term.c
ViewVC logotype

Diff of /inetutils/telnetd/sys_term.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.21 by alainm, Sat Oct 27 19:10:33 2001 UTC revision 1.22 by gray, Thu Mar 14 14:25:36 2002 UTC
# Line 45  static char sccsid[] = "@(#)sys_term.c 8 Line 45  static char sccsid[] = "@(#)sys_term.c 8
45  # define PARENT_DOES_UTMP  # define PARENT_DOES_UTMP
46  #endif  #endif
47    
 #ifdef  NEWINIT  
   
 #include <initreq.h>  
 int     utmp_len = MAXHOSTNAMELEN;      /* sizeof(init_request.host) */  
 #else   /* !NEWINIT*/  
 # ifdef HAVE_UTMPX_H  
 #  define __USE_GNU  
 #  include <utmpx.h>  
 struct  utmpx wtmp;  
 #  ifdef HAVE_UTMPX_UT_TV  
 #   define HAVE_WTMP_UT_TV HAVE_UTMPX_UT_TV  
 #  endif  
 # else /* !HAVE_UTMPX_H */  
 #  include <utmp.h>  
 struct  utmp wtmp;  
 #  ifdef HAVE_UTMP_UT_TV  
 #   define HAVE_WTMP_UT_TV HAVE_UTMP_UT_TV  
 #  endif  
 # endif /* HAVE_UTMPX_H */  
   
 #ifdef HAVE_UTMP_UT_HOST  
 int     utmp_len = sizeof(wtmp.ut_host);  
 #endif  
 # ifndef PARENT_DOES_UTMP  
 char    wtmpf[] = PATH_WTMP;  
 char    utmpf[] = PATH_UTMP;  
 # else /* PARENT_DOES_UTMP */  
 char    wtmpf[] = PATH_WTMP;  
 # endif /* PARENT_DOES_UTMP */  
   
 # ifdef CRAY  
 #  include <tmpdir.h>  
 #  include <sys/wait.h>  
 #  if (UNICOS_LVL == '7.0') || (UNICOS_LVL == '7.1')  
 #   define UNICOS7x  
 #  endif  
   
 #  ifdef UNICOS7x  
 #   include <sys/sysv.h>  
 #   include <sys/secstat.h>  
 extern int secflag;  
 extern struct sysv sysv;  
 #  endif /* UNICOS7x */  
 # endif /* CRAY */  
   
 #endif  /* NEWINIT */  
   
 #ifdef  HAVE_STREAMSPTY  
 #include <sac.h>  
 #include <sys/stropts.h>  
 #endif  
   
 #define SCPYN(a, b)     (void) strncpy(a, b, sizeof(a))  
 #define SCMPN(a, b)     strncmp(a, b, sizeof(a))  
   
48  #ifdef  HAVE_SYS_STREAM_H  #ifdef  HAVE_SYS_STREAM_H
49  #include <sys/stream.h>  # include <sys/stream.h>
 #endif  
 #ifdef __hpux  
 #include <sys/resource.h>  
 #include <sys/proc.h>  
50  #endif  #endif
51    
52  #if defined(UNICOS5) && defined(CRAY2) && !defined(EXTPROC)  #if defined(UNICOS5) && defined(CRAY2) && !defined(EXTPROC)
# Line 178  int cleanopen(char *); Line 119  int cleanopen(char *);
119   */   */
120    
121  void  void
122  init_termbuf()  init_termbuf ()
123  {  {
124  #ifndef USE_TERMIO  #ifndef USE_TERMIO
125          (void) ioctl(pty, TIOCGETP, (char *)&termbuf.sg);    ioctl (pty, TIOCGETP, (char *)&termbuf.sg);
126          (void) ioctl(pty, TIOCGETC, (char *)&termbuf.tc);    ioctl (pty, TIOCGETC, (char *)&termbuf.tc);
127          (void) ioctl(pty, TIOCGLTC, (char *)&termbuf.ltc);    ioctl (pty, TIOCGLTC, (char *)&termbuf.ltc);
128  # ifdef TIOCGSTATE  # ifdef TIOCGSTATE
129          (void) ioctl(pty, TIOCGSTATE, (char *)&termbuf.state);    ioctl (pty, TIOCGSTATE, (char *)&termbuf.state);
130  # endif  # endif
131  #else  #else
132  # ifdef  HAVE_STREAMSPTY  # ifdef  HAVE_STREAMSPTY
133          (void) tcgetattr(ttyfd, &termbuf);    tcgetattr(ttyfd, &termbuf);
134  # else  # else
135          (void) tcgetattr(pty, &termbuf);    tcgetattr(pty, &termbuf);
136  # endif  # endif
137  #endif  #endif
138          termbuf2 = termbuf;    termbuf2 = termbuf;
139  }  }
140    
141  #if     defined(LINEMODE) && defined(TIOCPKT_IOCTL)  #if defined(LINEMODE) && defined(TIOCPKT_IOCTL)
142  void  void
143  copy_termbuf(char *cp, int len)  copy_termbuf (char *cp, int len)
144  {  {
145          if (len > sizeof(termbuf))    if (len > sizeof (termbuf))
146                  len = sizeof(termbuf);      len = sizeof (termbuf);
147          memmove((char *)&termbuf, cp, len);    memmove ((char *)&termbuf, cp, len);
148          termbuf2 = termbuf;    termbuf2 = termbuf;
149  }  }
150  #endif  /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */  #endif  /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */
151    
152  void  void
153  set_termbuf()  set_termbuf ()
154  {  {
155          /*    /*
156           * Only make the necessary changes.     * Only make the necessary changes.
157           */     */
158  #ifndef USE_TERMIO  #ifndef USE_TERMIO
159          if (memcmp((char *)&termbuf.sg, (char *)&termbuf2.sg,    if (memcmp (&termbuf.sg, &termbuf2.sg, sizeof (termbuf.sg)))
160                                                          sizeof(termbuf.sg)))      ioctl(pty, TIOCSETN, (char *)&termbuf.sg);
161                  (void) ioctl(pty, TIOCSETN, (char *)&termbuf.sg);    if (memcmp (&termbuf.tc, &termbuf2.tc, sizeof (termbuf.tc)))
162          if (memcmp((char *)&termbuf.tc, (char *)&termbuf2.tc,      ioctl (pty, TIOCSETC, (char *)&termbuf.tc);
163                                                          sizeof(termbuf.tc)))    if (memcmp (&termbuf.ltc, &termbuf2.ltc, sizeof (termbuf.ltc)))
164                  (void) ioctl(pty, TIOCSETC, (char *)&termbuf.tc);      ioctl (pty, TIOCSLTC, (char *)&termbuf.ltc);
165          if (memcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc,    if (termbuf.lflags != termbuf2.lflags)
166                                                          sizeof(termbuf.ltc)))      ioctl (pty, TIOCLSET, &termbuf.lflags);
                 (void) ioctl(pty, TIOCSLTC, (char *)&termbuf.ltc);  
         if (termbuf.lflags != termbuf2.lflags)  
                 (void) ioctl(pty, TIOCLSET, (char *)&termbuf.lflags);  
167  #else   /* USE_TERMIO */  #else   /* USE_TERMIO */
168          if (memcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))    if (memcmp (&termbuf, &termbuf2, sizeof (termbuf)))
169        {
170  # ifdef  HAVE_STREAMSPTY  # ifdef  HAVE_STREAMSPTY
171                  (void) tcsetattr(ttyfd, TCSANOW, &termbuf);        tcsetattr (ttyfd, TCSANOW, &termbuf);
172  # else  # else
173                  (void) tcsetattr(pty, TCSANOW, &termbuf);        tcsetattr (pty, TCSANOW, &termbuf);
174  # endif  # endif
175  # if    defined(CRAY2) && defined(UNICOS5)      }
176          needtermstat = 1;  # if defined(CRAY2) && defined(UNICOS5)
177      needtermstat = 1;
178  # endif  # endif
179  #endif  /* USE_TERMIO */  #endif  /* USE_TERMIO */
180  }  }
181    
   
182  /*  /*
183   * spcset(func, valp, valpp)   * spcset(func, valp, valpp)
184   *   *
# Line 253  set_termbuf() Line 192  set_termbuf()
192    
193  #ifndef USE_TERMIO  #ifndef USE_TERMIO
194  int  int
195  spcset(int func, cc_t *valp, cc_t **valpp)  spcset (int func, cc_t *valp, cc_t **valpp)
196  {  {
197          switch(func) {    switch (func)
198          case SLC_EOF:      {
199                  *valp = termbuf.tc.t_eofc;      case SLC_EOF:
200                  *valpp = (cc_t *)&termbuf.tc.t_eofc;        *valp = termbuf.tc.t_eofc;
201                  return(SLC_VARIABLE);        *valpp = (cc_t *)&termbuf.tc.t_eofc;
202          case SLC_EC:        return SLC_VARIABLE;
203                  *valp = termbuf.sg.sg_erase;        
204                  *valpp = (cc_t *)&termbuf.sg.sg_erase;      case SLC_EC:
205                  return(SLC_VARIABLE);        *valp = termbuf.sg.sg_erase;
206          case SLC_EL:        *valpp = (cc_t *)&termbuf.sg.sg_erase;
207                  *valp = termbuf.sg.sg_kill;        return SLC_VARIABLE;
208                  *valpp = (cc_t *)&termbuf.sg.sg_kill;        
209                  return(SLC_VARIABLE);      case SLC_EL:
210          case SLC_IP:        *valp = termbuf.sg.sg_kill;
211                  *valp = termbuf.tc.t_intrc;        *valpp = (cc_t *)&termbuf.sg.sg_kill;
212                  *valpp = (cc_t *)&termbuf.tc.t_intrc;        return SLC_VARIABLE;
213                  return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);        
214          case SLC_ABORT:      case SLC_IP:
215                  *valp = termbuf.tc.t_quitc;        *valp = termbuf.tc.t_intrc;
216                  *valpp = (cc_t *)&termbuf.tc.t_quitc;        *valpp = (cc_t *)&termbuf.tc.t_intrc;
217                  return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);        return SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT;
218          case SLC_XON:        
219                  *valp = termbuf.tc.t_startc;      case SLC_ABORT:
220                  *valpp = (cc_t *)&termbuf.tc.t_startc;        *valp = termbuf.tc.t_quitc;
221                  return(SLC_VARIABLE);        *valpp = (cc_t *)&termbuf.tc.t_quitc;
222          case SLC_XOFF:        return SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT;
223                  *valp = termbuf.tc.t_stopc;        
224                  *valpp = (cc_t *)&termbuf.tc.t_stopc;      case SLC_XON:
225                  return(SLC_VARIABLE);        *valp = termbuf.tc.t_startc;
226          case SLC_AO:        *valpp = (cc_t *)&termbuf.tc.t_startc;
227                  *valp = termbuf.ltc.t_flushc;        return SLC_VARIABLE;
228                  *valpp = (cc_t *)&termbuf.ltc.t_flushc;        
229                  return(SLC_VARIABLE);      case SLC_XOFF:
230          case SLC_SUSP:        *valp = termbuf.tc.t_stopc;
231                  *valp = termbuf.ltc.t_suspc;        *valpp = (cc_t *)&termbuf.tc.t_stopc;
232                  *valpp = (cc_t *)&termbuf.ltc.t_suspc;        return SLC_VARIABLE;
233                  return(SLC_VARIABLE);        
234          case SLC_EW:      case SLC_AO:
235                  *valp = termbuf.ltc.t_werasc;        *valp = termbuf.ltc.t_flushc;
236                  *valpp = (cc_t *)&termbuf.ltc.t_werasc;        *valpp = (cc_t *)&termbuf.ltc.t_flushc;
237                  return(SLC_VARIABLE);        return SLC_VARIABLE;
238          case SLC_RP:        
239                  *valp = termbuf.ltc.t_rprntc;      case SLC_SUSP:
240                  *valpp = (cc_t *)&termbuf.ltc.t_rprntc;        *valp = termbuf.ltc.t_suspc;
241                  return(SLC_VARIABLE);        *valpp = (cc_t *)&termbuf.ltc.t_suspc;
242          case SLC_LNEXT:        return SLC_VARIABLE;
243                  *valp = termbuf.ltc.t_lnextc;        
244                  *valpp = (cc_t *)&termbuf.ltc.t_lnextc;      case SLC_EW:
245                  return(SLC_VARIABLE);        *valp = termbuf.ltc.t_werasc;
246          case SLC_FORW1:        *valpp = (cc_t *)&termbuf.ltc.t_werasc;
247                  *valp = termbuf.tc.t_brkc;        return SLC_VARIABLE;
248                  *valpp = (cc_t *)&termbuf.ltc.t_lnextc;        
249                  return(SLC_VARIABLE);      case SLC_RP:
250          case SLC_BRK:        *valp = termbuf.ltc.t_rprntc;
251          case SLC_SYNCH:        *valpp = (cc_t *)&termbuf.ltc.t_rprntc;
252          case SLC_AYT:        return SLC_VARIABLE;
253          case SLC_EOR:        
254                  *valp = (cc_t)0;      case SLC_LNEXT:
255                  *valpp = (cc_t *)0;        *valp = termbuf.ltc.t_lnextc;
256                  return(SLC_DEFAULT);        *valpp = (cc_t *)&termbuf.ltc.t_lnextc;
257          default:        return SLC_VARIABLE;
258                  *valp = (cc_t)0;        
259                  *valpp = (cc_t *)0;      case SLC_FORW1:
260                  return(SLC_NOSUPPORT);        *valp = termbuf.tc.t_brkc;
261          }        *valpp = (cc_t *)&termbuf.ltc.t_lnextc;
262          return SLC_VARIABLE;
263          
264        case SLC_BRK:
265        case SLC_SYNCH:
266        case SLC_AYT:
267        case SLC_EOR:
268          *valp = (cc_t)0;
269          *valpp = (cc_t *)0;
270          return SLC_DEFAULT;
271          
272        default:
273          *valp = (cc_t)0;
274          *valpp = (cc_t *)0;
275          return SLC_NOSUPPORT;
276        }
277  }  }
278    
279  #else   /* USE_TERMIO */  #else   /* USE_TERMIO */
280    
 int  
 spcset(int func, cc_t *valp, cc_t **valpp)  
 {  
   
281  #define setval(a, b)    *valp = termbuf.c_cc[a]; \  #define setval(a, b)    *valp = termbuf.c_cc[a]; \
282                          *valpp = &termbuf.c_cc[a]; \                          *valpp = &termbuf.c_cc[a]; \
283                          return(b);                          return b;
284  #define defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT);  #define defval(a)       *valp = ((cc_t)a); \
285                            *valpp = (cc_t *)0; \
286          switch(func) {                          return SLC_DEFAULT;
287          case SLC_EOF:  
288                  setval(VEOF, SLC_VARIABLE);  int
289          case SLC_EC:  spcset (int func, cc_t *valp, cc_t **valpp)
290                  setval(VERASE, SLC_VARIABLE);  {
291          case SLC_EL:    switch (func)
292                  setval(VKILL, SLC_VARIABLE);      {
293          case SLC_IP:      case SLC_EOF:
294                  setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);        setval (VEOF, SLC_VARIABLE);
295          case SLC_ABORT:        
296                  setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);      case SLC_EC:
297          case SLC_XON:        setval (VERASE, SLC_VARIABLE);
298          
299        case SLC_EL:
300          setval (VKILL, SLC_VARIABLE);
301          
302        case SLC_IP:
303          setval (VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
304          
305        case SLC_ABORT:
306          setval (VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
307          
308        case SLC_XON:
309  #ifdef  VSTART  #ifdef  VSTART
310                  setval(VSTART, SLC_VARIABLE);        setval (VSTART, SLC_VARIABLE);
311  #else  #else
312                  defval(0x13);        defval (0x13);
313  #endif  #endif
314          case SLC_XOFF:        
315        case SLC_XOFF:
316  #ifdef  VSTOP  #ifdef  VSTOP
317                  setval(VSTOP, SLC_VARIABLE);        setval (VSTOP, SLC_VARIABLE);
318  #else  #else
319                  defval(0x11);        defval (0x11);
320  #endif  #endif
321          case SLC_EW:        
322        case SLC_EW:
323  #ifdef  VWERASE  #ifdef  VWERASE
324                  setval(VWERASE, SLC_VARIABLE);        setval (VWERASE, SLC_VARIABLE);
325  #else  #else
326                  defval(0);        defval (0);
327  #endif  #endif
328          case SLC_RP:        
329        case SLC_RP:
330  #ifdef  VREPRINT  #ifdef  VREPRINT
331                  setval(VREPRINT, SLC_VARIABLE);        setval (VREPRINT, SLC_VARIABLE);
332  #else  #else
333                  defval(0);        defval(0);
334  #endif  #endif
335          case SLC_LNEXT:        
336        case SLC_LNEXT:
337  #ifdef  VLNEXT  #ifdef  VLNEXT
338                  setval(VLNEXT, SLC_VARIABLE);        setval (VLNEXT, SLC_VARIABLE);
339  #else  #else
340                  defval(0);        defval (0);
341  #endif  #endif
342          case SLC_AO:        
343  #if     !defined(VDISCARD) && defined(VFLUSHO)      case SLC_AO:
344    #if !defined(VDISCARD) && defined(VFLUSHO)
345  # define VDISCARD VFLUSHO  # define VDISCARD VFLUSHO
346  #endif  #endif
347  #ifdef  VDISCARD  #ifdef  VDISCARD
348                  setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);        setval (VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);
349  #else  #else
350                  defval(0);        defval (0);
351  #endif  #endif
352          case SLC_SUSP:        
353        case SLC_SUSP:
354  #ifdef  VSUSP  #ifdef  VSUSP
355                  setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);        setval (VSUSP, SLC_VARIABLE|SLC_FLUSHIN);
356  #else  #else
357                  defval(0);        defval (0);
358  #endif  #endif
359          
360  #ifdef  VEOL  #ifdef  VEOL
361          case SLC_FORW1:      case SLC_FORW1:
362                  setval(VEOL, SLC_VARIABLE);        setval (VEOL, SLC_VARIABLE);
363  #endif  #endif
364          
365  #ifdef  VEOL2  #ifdef  VEOL2
366          case SLC_FORW2:      case SLC_FORW2:
367                  setval(VEOL2, SLC_VARIABLE);        setval (VEOL2, SLC_VARIABLE);
368  #endif  #endif
369          case SLC_AYT:        
370        case SLC_AYT:
371  #ifdef  VSTATUS  #ifdef  VSTATUS
372                  setval(VSTATUS, SLC_VARIABLE);        setval (VSTATUS, SLC_VARIABLE);
373  #else  #else
374                  defval(0);        defval (0);
375  #endif  #endif
376    
377          case SLC_BRK:      case SLC_BRK:
378          case SLC_SYNCH:      case SLC_SYNCH:
379          case SLC_EOR:      case SLC_EOR:
380                  defval(0);        defval (0);
381    
382          default:      default:
383                  *valp = 0;        *valp = 0;
384                  *valpp = 0;        *valpp = 0;
385                  return(SLC_NOSUPPORT);        return SLC_NOSUPPORT;
386          }      }
387  }  }
388  #endif  /* USE_TERMIO */  #endif  /* USE_TERMIO */
389    
 #ifdef CRAY  
 /*  
  * getnpty()  
  *  
  * Return the number of pty's configured into the system.  
  */  
 int  
 getnpty()  
 {  
 #ifdef _SC_CRAY_NPTY  
         int numptys;  
   
         if ((numptys = sysconf(_SC_CRAY_NPTY)) != -1)  
                 return numptys;  
         else  
 #endif /* _SC_CRAY_NPTY */  
                 return 128;  
 }  
 #endif /* CRAY */  
   
 #ifndef convex  
 /*  
  * getpty()  
  *  
  * Allocate a pty.  As a side effect, the external character  
  * array "line" contains the name of the slave side.  
  *  
  * Returns the file descriptor of the opened pty.  
  */  
 static char Xline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";  
 char *line = Xline;  
   
 #ifdef  CRAY  
 static char Xmyline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";  
 char *myline = Xmyline;  
 #endif  /* CRAY */  
   
 int  
 getpty(int *ptynum)  
 {  
         register int p;  
 #ifdef  HAVE_STREAMSPTY  
         int t;  
         char *ptsname();  
   
         p = open("/dev/ptmx", O_RDWR);  
         if (p > 0) {  
                 grantpt(p);  
                 unlockpt(p);  
                 strcpy(line, ptsname(p));  
                 return(p);  
         }  
   
 #else   /* ! HAVE_STREAMSPTY */  
 #ifndef CRAY  
         register char *cp, *p1, *p2;  
         register int i;  
 #if defined(sun) && defined(TIOCGPGRP) && BSD < 199207  
         int dummy;  
 #endif  
   
 #ifndef __hpux  
         (void) sprintf(line, "/dev/ptyXX");  
         p1 = &line[8];  
         p2 = &line[9];  
 #else  
         (void) sprintf(line, "/dev/ptym/ptyXX");  
         p1 = &line[13];  
         p2 = &line[14];  
 #endif  
   
         for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) {  
                 struct stat stb;  
   
                 *p1 = *cp;  
                 *p2 = '0';  
                 /*  
                  * This stat() check is just to keep us from  
                  * looping through all 256 combinations if there  
                  * aren't that many ptys available.  
                  */  
                 if (stat(line, &stb) < 0)  
                         break;  
                 for (i = 0; i < 16; i++) {  
                         *p2 = "0123456789abcdef"[i];  
                         p = open(line, O_RDWR);  
                         if (p > 0) {  
 #ifndef __hpux  
                                 line[5] = 't';  
 #else  
                                 for (p1 = &line[8]; *p1; p1++)  
                                         *p1 = *(p1+1);  
                                 line[9] = 't';  
 #endif  
                                 chown(line, 0, 0);  
                                 chmod(line, 0600);  
 #if defined(sun) && defined(TIOCGPGRP) && BSD < 199207  
                                 if (ioctl(p, TIOCGPGRP, &dummy) == 0  
                                     || errno != EIO) {  
                                         chmod(line, 0666);  
                                         close(p);  
                                         line[5] = 'p';  
                                 } else  
 #endif /* defined(sun) && defined(TIOCGPGRP) && BSD < 199207 */  
                                         return(p);  
                         }  
                 }  
         }  
 #else   /* CRAY */  
         extern lowpty, highpty;  
         struct stat sb;  
   
         for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) {  
                 (void) sprintf(myline, "/dev/pty/%03d", *ptynum);  
                 p = open(myline, O_RDWR);  
                 if (p < 0)  
                         continue;  
                 (void) sprintf(line, "/dev/ttyp%03d", *ptynum);  
                 /*  
                  * Here are some shenanigans to make sure that there  
                  * are no listeners lurking on the line.  
                  */  
                 if(stat(line, &sb) < 0) {  
                         (void) close(p);  
                         continue;  
                 }  
                 if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) {  
                         chown(line, 0, 0);  
                         chmod(line, 0600);  
                         (void)close(p);  
                         p = open(myline, O_RDWR);  
                         if (p < 0)  
                                 continue;  
                 }  
                 /*  
                  * Now it should be safe...check for accessability.  
                  */  
                 if (access(line, 6) == 0)  
                         return(p);  
                 else {  
                         /* no tty side to pty so skip it */  
                         (void) close(p);  
                 }  
         }  
 #endif  /* CRAY */  
 #endif  /* HAVE_STREAMSPTY */  
         return(-1);  
 }  
 #endif  /* convex */  
   
390  #ifdef  LINEMODE  #ifdef  LINEMODE
391  /*  /*
392   * tty_flowmode()       Find out if flow control is enabled or disabled.   * tty_flowmode()       Find out if flow control is enabled or disabled.
# Line 599  tty_linemode() Line 419  tty_linemode()
419  #ifndef convex  #ifndef convex
420  #ifdef  USE_TERMIO  #ifdef  USE_TERMIO
421  #ifdef EXTPROC  #ifdef EXTPROC
422          return(termbuf.c_lflag & EXTPROC);    return (termbuf.c_lflag & EXTPROC);
423  #else  #else
424          return 0;               /* Can't ever set it either. */    return 0;             /* Can't ever set it either. */
425  #endif /* EXTPROC */  #endif /* EXTPROC */
426  #else /* !USE_TERMIO */  #else /* !USE_TERMIO */
427          return(termbuf.state & TS_EXTPROC);    return termbuf.state & TS_EXTPROC;
428  #endif /* USE_TERMIO */  #endif /* USE_TERMIO */
429  #else /* convex */  #else /* convex */
430          return(linestate);    return linestate;
431  #endif /* !convex */  #endif /* !convex */
432  }  }
433    
434          void  void
435  tty_setlinemode(on)  tty_setlinemode (int on)
         int on;  
436  {  {
437  #ifdef  TIOCEXT  #ifdef  TIOCEXT
438  # ifndef convex  # ifndef convex
439          set_termbuf();    set_termbuf ();
440  # else  # else
441          linestate = on;    linestate = on;
442  # endif  # endif
443          (void) ioctl(pty, TIOCEXT, (char *)&on);    ioctl (pty, TIOCEXT, (char *)&on);
444  # ifndef convex  # ifndef convex
445          init_termbuf();    init_termbuf ();
446  # endif  # endif
447  #else   /* !TIOCEXT */  #else   /* !TIOCEXT */
448  # ifdef EXTPROC  # ifdef EXTPROC
449          if (on)    if (on)
450                  termbuf.c_lflag |= EXTPROC;      termbuf.c_lflag |= EXTPROC;
451          else    else
452                  termbuf.c_lflag &= ~EXTPROC;      termbuf.c_lflag &= ~EXTPROC;
453  # endif  # endif
454  #endif  /* TIOCEXT */  #endif  /* TIOCEXT */
455  }  }
456  #endif  /* LINEMODE */  #endif  /* LINEMODE */
457    
458  int  int
459  tty_isecho()  tty_isecho ()
460  {  {
461  #ifndef USE_TERMIO  #ifndef USE_TERMIO
462          return (termbuf.sg.sg_flags & ECHO);    return termbuf.sg.sg_flags & ECHO;
463  #else  #else
464          return (termbuf.c_lflag & ECHO);    return termbuf.c_lflag & ECHO;
465  #endif  #endif
466  }  }
467    
468  int  int
469  tty_flowmode()  tty_flowmode ()
470  {  {
471  #ifndef USE_TERMIO  #ifndef USE_TERMIO
472          return(((termbuf.tc.t_startc) > 0 && (termbuf.tc.t_stopc) > 0) ? 1 : 0);    return ((termbuf.tc.t_startc) > 0 && (termbuf.tc.t_stopc) > 0) ? 1 : 0;
473  #else  #else
474          return((termbuf.c_iflag & IXON) ? 1 : 0);    return (termbuf.c_iflag & IXON) ? 1 : 0;
475  #endif  #endif
476  }  }
477    
478  int  int
479  tty_restartany()  tty_restartany ()
480  {  {
481  #ifndef USE_TERMIO  #ifndef USE_TERMIO
482  # ifdef DECCTQ  # ifdef DECCTQ
483          return((termbuf.lflags & DECCTQ) ? 0 : 1);    return (termbuf.lflags & DECCTQ) ? 0 : 1;
484  # else  # else
485          return(-1);    return -1;
486  # endif  # endif
487  #else  #else
488          return((termbuf.c_iflag & IXANY) ? 1 : 0);    return (termbuf.c_iflag & IXANY) ? 1 : 0;
489  #endif  #endif
490  }  }
491    
492  void  void
493  tty_setecho(on)  tty_setecho(int on)
         int on;  
494  {  {
495  #ifndef USE_TERMIO  #ifndef USE_TERMIO
496          if (on)    if (on)
497                  termbuf.sg.sg_flags |= ECHO|CRMOD;      termbuf.sg.sg_flags |= ECHO|CRMOD;
498          else    else
499                  termbuf.sg.sg_flags &= ~(ECHO|CRMOD);      termbuf.sg.sg_flags &= ~(ECHO|CRMOD);
500  #else  #else
501          if (on)    if (on)
502                  termbuf.c_lflag |= ECHO;      termbuf.c_lflag |= ECHO;
503          else    else
504                  termbuf.c_lflag &= ~ECHO;      termbuf.c_lflag &= ~ECHO;
505  #endif  #endif
506  }  }
507    
508  int  int
509  tty_israw()  tty_israw ()
510  {  {
511  #ifndef USE_TERMIO  #ifndef USE_TERMIO
512          return(termbuf.sg.sg_flags & RAW);    return termbuf.sg.sg_flags & RAW;
513  #else  #else
514          return(!(termbuf.c_lflag & ICANON));    return !(termbuf.c_lflag & ICANON);
515  #endif  #endif
516  }  }
517    
518  #if     defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)  #if defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
519  int  int
520  tty_setraw(int on)  tty_setraw(int on)
521  {  {
522  #  ifndef USE_TERMIO  # ifndef USE_TERMIO
523          if (on)    if (on)
524                  termbuf.sg.sg_flags |= RAW;      termbuf.sg.sg_flags |= RAW;
525          else    else
526                  termbuf.sg.sg_flags &= ~RAW;      termbuf.sg.sg_flags &= ~RAW;
527  #  else  # else
528          if (on)    if (on)
529                  termbuf.c_lflag &= ~ICANON;      termbuf.c_lflag &= ~ICANON;
530          else    else
531                  termbuf.c_lflag |= ICANON;      termbuf.c_lflag |= ICANON;
532  #  endif  # endif
533  }  }
534  #endif  #endif
535    
536  void  void
537  tty_binaryin(int on)  tty_binaryin (int on)
538  {  {
539  #ifndef USE_TERMIO  #ifndef USE_TERMIO
540          if (on)    if (on)
541                  termbuf.lflags |= LPASS8;      termbuf.lflags |= LPASS8;
542          else    else
543                  termbuf.lflags &= ~LPASS8;      termbuf.lflags &= ~LPASS8;
544  #else  #else
545          if (on) {    if (on)
546                  termbuf.c_iflag &= ~ISTRIP;      termbuf.c_iflag &= ~ISTRIP;
547          } else {    else
548                  termbuf.c_iflag |= ISTRIP;      termbuf.c_iflag |= ISTRIP;
         }  
549  #endif  #endif
550  }  }
551    
552  void  void
553  tty_binaryout(int on)  tty_binaryout (int on)
554  {  {
555  #ifndef USE_TERMIO  #ifndef USE_TERMIO
556          if (on)    if (on)
557                  termbuf.lflags |= LLITOUT;      termbuf.lflags |= LLITOUT;
558          else    else
559                  termbuf.lflags &= ~LLITOUT;      termbuf.lflags &= ~LLITOUT;
560  #else  #else
561          if (on) {    if (on)
562                  termbuf.c_cflag &= ~(CSIZE|PARENB);      {
563                  termbuf.c_cflag |= CS8;        termbuf.c_cflag &= ~(CSIZE|PARENB);
564                  termbuf.c_oflag &= ~OPOST;        termbuf.c_cflag |= CS8;
565          } else {        termbuf.c_oflag &= ~OPOST;
566                  termbuf.c_cflag &= ~CSIZE;      }
567                  termbuf.c_cflag |= CS7|PARENB;    else
568                  termbuf.c_oflag |= OPOST;      {
569          }        termbuf.c_cflag &= ~CSIZE;
570          termbuf.c_cflag |= CS7|PARENB;
571          termbuf.c_oflag |= OPOST;
572        }
573  #endif  #endif
574  }  }
575    
576          int  int
577  tty_isbinaryin()  tty_isbinaryin ()
578  {  {
579  #ifndef USE_TERMIO  #ifndef USE_TERMIO
580          return(termbuf.lflags & LPASS8);    return termbuf.lflags & LPASS8;
581  #else  #else
582          return(!(termbuf.c_iflag & ISTRIP));    return !(termbuf.c_iflag & ISTRIP);
583  #endif  #endif
584  }  }
585    
586  int  int
587  tty_isbinaryout()  tty_isbinaryout ()
588  {  {
589  #ifndef USE_TERMIO  #ifndef USE_TERMIO
590          return(termbuf.lflags & LLITOUT);    return termbuf.lflags & LLITOUT;
591  #else  #else
592          return(!(termbuf.c_oflag&OPOST));    return !(termbuf.c_oflag&OPOST);
593  #endif  #endif
594  }  }
595    
596  #ifdef  LINEMODE  #ifdef  LINEMODE
597  int  int
598  tty_isediting()  tty_isediting ()
599  {  {
600  #ifndef USE_TERMIO  #ifndef USE_TERMIO
601          return(!(termbuf.sg.sg_flags & (CBREAK|RAW)));    return !(termbuf.sg.sg_flags & (CBREAK|RAW));
602  #else  #else
603          return(termbuf.c_lflag & ICANON);    return termbuf.c_lflag & ICANON;
604  #endif  #endif
605  }  }
606    
# Line 788  int Line 608  int
608  tty_istrapsig()  tty_istrapsig()
609  {  {
610  #ifndef USE_TERMIO  #ifndef USE_TERMIO
611          return(!(termbuf.sg.sg_flags&RAW));    return !(termbuf.sg.sg_flags&RAW);
612  #else  #else
613          return(termbuf.c_lflag & ISIG);    return termbuf.c_lflag & ISIG;
614  #endif  #endif
615  }  }
616    
617  void  void
618  tty_setedit(int on)  tty_setedit (int on)
619  {  {
620  #ifndef USE_TERMIO  #ifndef USE_TERMIO
621          if (on)    if (on)
622                  termbuf.sg.sg_flags &= ~CBREAK;      termbuf.sg.sg_flags &= ~CBREAK;
623          else    else
624                  termbuf.sg.sg_flags |= CBREAK;      termbuf.sg.sg_flags |= CBREAK;
625  #else  #else
626          if (on)    if (on)
627                  termbuf.c_lflag |= ICANON;      termbuf.c_lflag |= ICANON;
628          else    else
629                  termbuf.c_lflag &= ~ICANON;      termbuf.c_lflag &= ~ICANON;
630  #endif  #endif
631  }  }
632    
633  void  void
634  tty_setsig(int on)  tty_setsig (int on)
635  {  {
636  #ifndef USE_TERMIO  #ifdef  USE_TERMIO
637          if (on)    if (on)
638                  ;      termbuf.c_lflag |= ISIG;
639  #else    else
640          if (on)      termbuf.c_lflag &= ~ISIG;
                 termbuf.c_lflag |= ISIG;  
         else  
                 termbuf.c_lflag &= ~ISIG;  
641  #endif  #endif
642  }  }
643  #endif  /* LINEMODE */  #endif  /* LINEMODE */
644    
645  int  int
646  tty_issofttab()  tty_issofttab ()
647  {  {
648  #ifndef USE_TERMIO  #ifndef USE_TERMIO
649          return (termbuf.sg.sg_flags & XTABS);    return termbuf.sg.sg_flags & XTABS;
650  #else  #else
651  # ifdef OXTABS  # ifdef OXTABS
652          return (termbuf.c_oflag & OXTABS);    return termbuf.c_oflag & OXTABS;
653  # endif  # endif
654  # ifdef TABDLY  # ifdef TABDLY
655          return ((termbuf.c_oflag & TABDLY) == TAB3);    return (termbuf.c_oflag & TABDLY) == TAB3;
656  # endif  # endif
657  #endif  #endif
658  }  }
659    
660  void  void
661  tty_setsofttab(int on)  tty_setsofttab (int on)
662  {  {
663  #ifndef USE_TERMIO  #ifndef USE_TERMIO
664          if (on)    if (on)
665                  termbuf.sg.sg_flags |= XTABS;      termbuf.sg.sg_flags |= XTABS;
666          else    else
667                  termbuf.sg.sg_flags &= ~XTABS;      termbuf.sg.sg_flags &= ~XTABS;
668  #else  #else
669          if (on) {    if (on)
670        {
671  # ifdef OXTABS  # ifdef OXTABS
672                  termbuf.c_oflag |= OXTABS;        termbuf.c_oflag |= OXTABS;
673  # endif  # endif
674  # ifdef TABDLY  # ifdef TABDLY
675                  termbuf.c_oflag &= ~TABDLY;        termbuf.c_oflag &= ~TABDLY;
676                  termbuf.c_oflag |= TAB3;        termbuf.c_oflag |= TAB3;
677  # endif  # endif
678          } else {      }
679      else
680        {
681  # ifdef OXTABS  # ifdef OXTABS
682                  termbuf.c_oflag &= ~OXTABS;        termbuf.c_oflag &= ~OXTABS;
683  # endif  # endif
684  # ifdef TABDLY  # ifdef TABDLY
685                  termbuf.c_oflag &= ~TABDLY;        termbuf.c_oflag &= ~TABDLY;
686                  termbuf.c_oflag |= TAB0;        termbuf.c_oflag |= TAB0;
687  # endif  # endif
688          }      }
689  #endif  #endif
690  }  }
691    
692  int  int
693  tty_islitecho()  tty_islitecho ()
694  {  {
695  #ifndef USE_TERMIO  #ifndef USE_TERMIO
696          return (!(termbuf.lflags & LCTLECH));    return !(termbuf.lflags & LCTLECH);
697  #else  #else
698  # ifdef ECHOCTL  # ifdef ECHOCTL
699          return (!(termbuf.c_lflag & ECHOCTL));    return !(termbuf.c_lflag & ECHOCTL);
700  # endif  # endif
701  # ifdef TCTLECH  # ifdef TCTLECH
702          return (!(termbuf.c_lflag & TCTLECH));    return !(termbuf.c_lflag & TCTLECH);
703  # endif  # endif
704  # if    !defined(ECHOCTL) && !defined(TCTLECH)  # if!defined(ECHOCTL) && !defined(TCTLECH)
705          return (0);     /* assumes ctl chars are echoed '^x' */    return 0;     /* assumes ctl chars are echoed '^x' */
706  # endif  # endif
707  #endif  #endif
708  }  }
709    
710  void  void
711  tty_setlitecho(int on)  tty_setlitecho (int on)
712  {  {
713  #ifndef USE_TERMIO  #ifndef USE_TERMIO
714          if (on)    if (on)
715                  termbuf.lflags &= ~LCTLECH;      termbuf.lflags &= ~LCTLECH;
716          else    else
717                  termbuf.lflags |= LCTLECH;      termbuf.lflags |= LCTLECH;
718  #else  #else
719  # ifdef ECHOCTL  # ifdef ECHOCTL
720          if (on)    if (on)
721                  termbuf.c_lflag &= ~ECHOCTL;      termbuf.c_lflag &= ~ECHOCTL;
722          else    else
723                  termbuf.c_lflag |= ECHOCTL;      termbuf.c_lflag |= ECHOCTL;
724  # endif  # endif
725  # ifdef TCTLECH  # ifdef TCTLECH
726          if (on)    if (on)
727                  termbuf.c_lflag &= ~TCTLECH;      termbuf.c_lflag &= ~TCTLECH;
728          else    else
729                  termbuf.c_lflag |= TCTLECH;      termbuf.c_lflag |= TCTLECH;
730  # endif  # endif
731  #endif  #endif
732  }  }
733    
734  int  int
735  tty_iscrnl()  tty_iscrnl ()
736  {  {
737  #ifndef USE_TERMIO  #ifndef USE_TERMIO
738          return (termbuf.sg.sg_flags & CRMOD);    return termbuf.sg.sg_flags & CRMOD;
739  #else  #else
740          return (termbuf.c_iflag & ICRNL);    return termbuf.c_iflag & ICRNL;
741  #endif  #endif
742  }  }
743    
# Line 934  tty_iscrnl() Line 754  tty_iscrnl()
754   * A table of available terminal speeds   * A table of available terminal speeds
755   */   */
756  struct termspeeds {  struct termspeeds {
757          int     speed;    int   speed;
758          int     value;    int   value;
759  } termspeeds[] = {  } termspeeds[] = {
760          { 0,     B0 },    { 50,    B50 },   { 75,    B75 },    { 0,     B0 },    { 50,    B50 },   { 75,    B75 },
761          { 110,   B110 },  { 134,   B134 },  { 150,   B150 },    { 110,   B110 },  { 134,   B134 },  { 150,   B150 },
762          { 200,   B200 },  { 300,   B300 },  { 600,   B600 },    { 200,   B200 },  { 300,   B300 },  { 600,   B600 },
763          { 1200,  B1200 }, { 1800,  B1800 }, { 2400,  B2400 },    { 1200,  B1200 }, { 1800,  B1800 }, { 2400,  B2400 },
764          { 4800,   B4800 },    { 4800,   B4800 },
765  #ifdef  B7200  #ifdef  B7200
766          { 7200,  B7200 },    { 7200,  B7200 },
767  #endif  #endif
768          { 9600,   B9600 },    { 9600,   B9600 },
769  #ifdef  B14400  #ifdef  B14400
770          { 14400,  B14400 },    { 14400,  B14400 },
771  #endif  #endif
772  #ifdef  B19200  #ifdef  B19200
773          { 19200,  B19200 },    { 19200,  B19200 },
774  #endif  #endif
775  #ifdef  B28800  #ifdef  B28800
776          { 28800,  B28800 },    { 28800,  B28800 },
777  #endif  #endif
778  #ifdef  B38400  #ifdef  B38400
779          { 38400,  B38400 },    { 38400,  B38400 },
780  #endif  #endif
781  #ifdef  B57600  #ifdef  B57600
782          { 57600,  B57600 },    { 57600,  B57600 },
783  #endif  #endif
784  #ifdef  B115200  #ifdef  B115200
785          { 115200, B115200 },    { 115200, B115200 },
786  #endif  #endif
787  #ifdef  B230400  #ifdef  B230400
788          { 230400, B230400 },    { 230400, B230400 },
789  #endif  #endif
790          { -1,     0 }    { -1,     0 }
791  };  };
792  #endif  /* DECODE_BUAD */  #endif  /* DECODE_BAUD */
793    
794  void  void
795  tty_tspeed(int val)  tty_tspeed (int val)
796  {  {
797  #ifdef  DECODE_BAUD  #ifdef  DECODE_BAUD
798          register struct termspeeds *tp;    register struct termspeeds *tp;
799    
800          for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)    for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
801                  ;      ;
802          if (tp->speed == -1)    /* back up to last valid value */    if (tp->speed == -1)  /* back up to last valid value */
803                  --tp;      --tp;
804          cfsetospeed(&termbuf, tp->value);    cfsetospeed (&termbuf, tp->value);
805  #else   /* DECODE_BUAD */  #else  
806          cfsetospeed(&termbuf, val);    cfsetospeed (&termbuf, val);
807  #endif  /* DECODE_BUAD */  #endif  /* DECODE_BAUD */
808  }  }
809    
810  void  void
811  tty_rspeed(int val)  tty_rspeed (int val)
812  {  {
813  #ifdef  DECODE_BAUD  #ifdef  DECODE_BAUD
814          register struct termspeeds *tp;    register struct termspeeds *tp;
815    
816          for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)    for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
817                  ;      ;
818          if (tp->speed == -1)    /* back up to last valid value */    if (tp->speed == -1)  /* back up to last valid value */
819                  --tp;      --tp;
820          cfsetispeed(&termbuf, tp->value);    cfsetispeed (&termbuf, tp->value);
821  #else   /* DECODE_BAUD */  #else   /* DECODE_BAUD */
822          cfsetispeed(&termbuf, val);    cfsetispeed (&termbuf, val);
823  #endif  /* DECODE_BAUD */  #endif  /* DECODE_BAUD */
824  }  }
825    
826  #if     defined(CRAY2) && defined(UNICOS5)  #if defined(CRAY2) && defined(UNICOS5)
 int  
 tty_isnewmap()  
 {  
         return((termbuf.c_oflag & OPOST) && (termbuf.c_oflag & ONLCR) &&  
                         !(termbuf.c_oflag & ONLRET));  
 }  
 #endif  
   
 #ifdef PARENT_DOES_UTMP  
 # ifndef NEWINIT  
 extern  struct utmp wtmp;  
 extern char wtmpf[];  
 # else  /* NEWINIT */  
 int     gotalarm;  
   
         /* ARGSUSED */  
 void  
 nologinproc(int sig)  
 {  
         gotalarm++;  
 }  
 # endif /* NEWINIT */  
 #endif /* PARENT_DOES_UTMP */  
   
 #ifndef NEWINIT  
 # ifdef PARENT_DOES_UTMP  
 extern void utmp_sig_init P((void));  
 extern void utmp_sig_reset P((void));  
 extern void utmp_sig_wait P((void));  
 extern void utmp_sig_notify P((int));  
 # endif /* PARENT_DOES_UTMP */  
 #endif  
   
 /*  
  * getptyslave()  
  *  
  * Open the slave side of the pty, and do any initialization  
  * that is necessary.  The return value is a file descriptor  
  * for the slave side.  
  */  
 int  
 getptyslave()  
 {  
         register int t = -1;  
   
 #if     !defined(CRAY) || !defined(NEWINIT)  
 # ifdef LINEMODE  
         int waslm;  
 # endif  
 # ifdef TIOCGWINSZ  
         struct winsize ws;  
         extern int def_row, def_col;  
 # endif  
         extern int def_tspeed, def_rspeed;  
         /*  
          * Opening the slave side may cause initilization of the  
          * kernel tty structure.  We need remember the state of  
          *      if linemode was turned on  
          *      terminal window size  
          *      terminal speed  
          * so that we can re-set them if we need to.  
          */  
 # ifdef LINEMODE  
         waslm = tty_linemode();  
 # endif  
   
   
         /*  
          * Make sure that we don't have a controlling tty, and  
          * that we are the session (process group) leader.  
          */  
 # ifdef TIOCNOTTY  
         t = open(PATH_TTY, O_RDWR);  
         if (t >= 0) {  
                 (void) ioctl(t, TIOCNOTTY, (char *)0);  
                 (void) close(t);  
         }  
 # endif  
   
   
 # ifdef PARENT_DOES_UTMP  
         /*  
          * Wait for our parent to get the utmp stuff to get done.  
          */  
         utmp_sig_wait();  
 # endif  
   
         t = cleanopen(line);  
         if (t < 0)  
                 fatalperror(net, line);  
   
 #ifdef  HAVE_STREAMSPTY  
 #ifdef  USE_TERMIO  
         ttyfd = t;  
 #endif  
         if (ioctl(t, I_PUSH, "ptem") < 0)  
                 fatal(net, "I_PUSH ptem");  
         if (ioctl(t, I_PUSH, "ldterm") < 0)  
                 fatal(net, "I_PUSH ldterm");  
         if (ioctl(t, I_PUSH, "ttcompat") < 0)  
                 fatal(net, "I_PUSH ttcompat");  
         if (ioctl(pty, I_PUSH, "pckt") < 0)  
                 fatal(net, "I_PUSH pckt");  
 #endif  
   
         /*  
          * set up the tty modes as we like them to be.  
          */  
         init_termbuf();  
 # ifdef TIOCGWINSZ  
         if (def_row || def_col) {  
                 memset((char *)&ws, 0, sizeof(ws));  
                 ws.ws_col = def_col;  
                 ws.ws_row = def_row;  
                 (void)ioctl(t, TIOCSWINSZ, (char *)&ws);  
         }  
 # endif  
   
         /*  
          * Settings for sgtty based systems  
          */  
 # ifndef        USE_TERMIO  
         termbuf.sg.sg_flags |= CRMOD|ANYP|ECHO|XTABS;  
 # endif /* USE_TERMIO */  
   
         /*  
          * Settings for UNICOS (and HPUX)  
          */  
 # if defined(CRAY) || defined(__hpux)  
         termbuf.c_oflag = OPOST|ONLCR|TAB3;  
         termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;  
         termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;  
         termbuf.c_cflag = EXTB|HUPCL|CS8;  
 # endif  
   
         /*  
          * Settings for all other termios/termio based  
          * systems, other than 4.4BSD.  In 4.4BSD the  
          * kernel does the initial terminal setup.  
          */  
 # if defined(USE_TERMIO) && !(defined(CRAY) || defined(__hpux)) && (BSD <= 43)  
 #  ifndef       OXTABS  
 #   define OXTABS       0  
 #  endif  
         termbuf.c_lflag |= ECHO;  
         termbuf.c_oflag |= ONLCR|OXTABS;  
         termbuf.c_iflag |= ICRNL;  
         termbuf.c_iflag &= ~IXOFF;  
 # endif /* defined(USE_TERMIO) && !defined(CRAY) && (BSD <= 43) */  
         tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600);  
         tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);  
 # ifdef LINEMODE  
         if (waslm)  
                 tty_setlinemode(1);  
 # endif /* LINEMODE */  
   
         /*  
          * Set the tty modes, and make this our controlling tty.  
          */  
         set_termbuf();  
         if (login_tty(t) == -1)  
                 fatalperror(net, "login_tty");  
 #endif  /* !defined(CRAY) || !defined(NEWINIT) */  
         if (net > 2)  
                 (void) close(net);  
 #if     defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)  
         /*  
          * Leave the pty open so that we can write out the rlogin  
          * protocol for /bin/login, if the authentication works.  
          */  
 #else  
         if (pty > 2) {  
                 (void) close(pty);  
                 pty = -1;  
         }  
 #endif  
 }  
   
 #if     !defined(CRAY) || !defined(NEWINIT)  
 #ifndef O_NOCTTY  
 #define O_NOCTTY        0  
 #endif  
 /*  
  * Open the specified slave side of the pty,  
  * making sure that we have a clean tty.  
  */  
 int  
 cleanopen(char *line)  
 {  
         register int t;  
 #ifdef  UNICOS7x  
         struct secstat secbuf;  
 #endif  /* UNICOS7x */  
   
 #ifndef HAVE_STREAMSPTY  
         /*  
          * Make sure that other people can't open the  
          * slave side of the connection.  
          */  
         (void) chown(line, 0, 0);  
         (void) chmod(line, 0600);  
 #endif  
   
 # if !defined(CRAY) && (BSD > 43)  
         (void) revoke(line);  
 # endif  
 #ifdef  UNICOS7x  
         if (secflag) {  
                 if (secstat(line, &secbuf) < 0)  
                         return(-1);  
                 if (setulvl(secbuf.st_slevel) < 0)  
                         return(-1);  
                 if (setucmp(secbuf.st_compart) < 0)  
                         return(-1);  
         }  
 #endif  /* UNICOS7x */  
   
         t = open(line, O_RDWR|O_NOCTTY);  
   
 #ifdef  UNICOS7x  
         if (secflag) {  
                 if (setulvl(sysv.sy_minlvl) < 0)  
                         return(-1);  
                 if (setucmp(0) < 0)  
                         return(-1);  
         }  
 #endif  /* UNICOS7x */  
   
         if (t < 0)  
                 return(-1);  
   
         /*  
          * Hangup anybody else using this ttyp, then reopen it for  
          * ourselves.  
          */  
 # if !(defined(CRAY) || defined(__hpux)) && (BSD <= 43) && !defined(HAVE_STREAMSPTY)  
         (void) signal(SIGHUP, SIG_IGN);  
         vhangup();  
         (void) signal(SIGHUP, SIG_DFL);  
         t = open(line, O_RDWR|O_NOCTTY);  
         if (t < 0)  
                 return(-1);  
 # endif  
 # if    defined(CRAY) && defined(TCVHUP)  
         {  
                 register int i;  
                 (void) signal(SIGHUP, SIG_IGN);  
                 (void) ioctl(t, TCVHUP, (char *)0);  
                 (void) signal(SIGHUP, SIG_DFL);  
   
 #ifdef  UNICOS7x  
                 if (secflag) {  
                         if (secstat(line, &secbuf) < 0)  
                                 return(-1);  
                         if (setulvl(secbuf.st_slevel) < 0)  
                                 return(-1);  
                         if (setucmp(secbuf.st_compart) < 0)  
                                 return(-1);  
                 }  
 #endif  /* UNICOS7x */  
   
                 i = open(line, O_RDWR);  
   
 #ifdef  UNICOS7x  
                 if (secflag) {  
                         if (setulvl(sysv.sy_minlvl) < 0)  
                                 return(-1);  
                         if (setucmp(0) < 0)  
                                 return(-1);  
                 }  
 #endif  /* UNICOS7x */  
   
                 if (i < 0)  
                         return(-1);  
                 (void) close(t);  
                 t = i;  
         }  
 # endif /* defined(CRAY) && defined(TCVHUP) */  
         return(t);  
 }  
 #endif  /* !defined(CRAY) || !defined(NEWINIT) */  
   
 #if BSD <= 43  
   
827  int  int
828  login_tty(int t)  tty_isnewmap ()
829  {  {
830          if (setsid() < 0) {    return (termbuf.c_oflag & OPOST) && (termbuf.c_oflag & ONLCR) &&
831  #ifdef ultrix                          !(termbuf.c_oflag & ONLRET);
                 /*  
                  * The setsid() may have failed because we  
                  * already have a pgrp == pid.  Zero out  
                  * our pgrp and try again...  
                  */  
                 if ((setpgrp(0, 0) < 0) || (setsid() < 0))  
 #endif  
                         fatalperror(net, "setsid()");  
         }  
 # ifdef TIOCSCTTY  
         if (ioctl(t, TIOCSCTTY, (char *)0) < 0)  
                 fatalperror(net, "ioctl(sctty)");  
 #  if defined(CRAY)  
         /*  
          * Close the hard fd to /dev/ttypXXX, and re-open through  
          * the indirect /dev/tty interface.  
          */  
         close(t);  
         if ((t = open("/dev/tty", O_RDWR)) < 0)  
                 fatalperror(net, "open(/dev/tty)");  
 #  endif  
 # else  
         /*  
          * We get our controlling tty assigned as a side-effect  
          * of opening up a tty device.  But on BSD based systems,  
          * this only happens if our process group is zero.  The  
          * setsid() call above may have set our pgrp, so clear  
          * it out before opening the tty...  
          */  
         setpgid (0, 0);  
   
         close(open(line, O_RDWR));  
 # endif  
         if (t != 0)  
                 (void) dup2(t, 0);  
         if (t != 1)  
                 (void) dup2(t, 1);  
         if (t != 2)  
                 (void) dup2(t, 2);  
         if (t > 2)  
                 close(t);  
         return(0);  
832  }  }
 #endif  /* BSD <= 43 */  
   
 #ifdef  NEWINIT  
 char *gen_id = "fe";  
833  #endif  #endif
834    
 /*  
  * startslave(host)  
  *  
  * Given a hostname, do whatever  
  * is necessary to startup the login process on the slave side of the pty.  
  */  
   
 /* ARGSUSED */  
 void  
 startslave(char *host, int autologin, char *autoname)  
 {  
         register int i;  
         char name[256];  
 #ifdef  NEWINIT  
         extern char *ptyip;  
         struct init_request request;  
         void nologinproc();  
         register int n;  
 #endif  /* NEWINIT */  
   
 #if     defined(AUTHENTICATION)  
         if (!autoname || !autoname[0])  
                 autologin = 0;  
   
         if (autologin < auth_level) {  
                 fatal(net, "Authorization failed");  
                 exit(1);  
         }  
 #endif  
   
 #ifndef NEWINIT  
 # ifdef PARENT_DOES_UTMP  
         utmp_sig_init();  
 # endif /* PARENT_DOES_UTMP */  
   
         if ((i = fork()) < 0)  
                 fatalperror(net, "fork");  
         if (i) {  
 # ifdef PARENT_DOES_UTMP  
                 /*  
                  * Cray parent will create utmp entry for child and send  
                  * signal to child to tell when done.  Child waits for signal  
                  * before doing anything important.  
                  */  
                 register int pid = i;  
                 void sigjob P((int));  
   
                 setpgrp();  
                 utmp_sig_reset();               /* reset handler to default */  
                 /*  
                  * Create utmp entry for child  
                  */  
                 (void) time(&wtmp.ut_time);  
                 wtmp.ut_type = LOGIN_PROCESS;  
                 wtmp.ut_pid = pid;  
                 SCPYN(wtmp.ut_user, "LOGIN");  
                 SCPYN(wtmp.ut_host, host);  
                 SCPYN(wtmp.ut_line, line + sizeof("/dev/") - 1);  
 #ifndef __hpux  
                 SCPYN(wtmp.ut_id, wtmp.ut_line+3);  
 #else  
                 SCPYN(wtmp.ut_id, wtmp.ut_line+7);  
 #endif  
                 pututline(&wtmp);  
                 endutent();  
                 if ((i = open(wtmpf, O_WRONLY|O_APPEND)) >= 0) {  
                         (void) write(i, (char *)&wtmp, sizeof(struct utmp));  
                         (void) close(i);  
                 }  
 #ifdef  CRAY  
                 (void) signal(WJSIGNAL, sigjob);  
 #endif  
                 utmp_sig_notify(pid);  
 # endif /* PARENT_DOES_UTMP */  
         } else {  
                 getptyslave(autologin);  
                 start_login(host, autologin, autoname);  
                 /*NOTREACHED*/  
         }  
 #else   /* NEWINIT */  
   
         /*  
          * Init will start up login process if we ask nicely.  We only wait  
          * for it to start up and begin normal telnet operation.  
          */  
         if ((i = open(INIT_FIFO, O_WRONLY)) < 0) {  
                 char tbuf[128];  
                 (void) sprintf(tbuf, "Can't open %s\n", INIT_FIFO);  
                 fatalperror(net, tbuf);  
         }  
         memset((char *)&request, 0, sizeof(request));  
         request.magic = INIT_MAGIC;  
         SCPYN(request.gen_id, gen_id);  
         SCPYN(request.tty_id, &line[8]);  
         SCPYN(request.host, host);  
         SCPYN(request.term_type, terminaltype ? terminaltype : "network");  
 #if     !defined(UNICOS5)  
         request.signal = SIGCLD;  
         request.pid = getpid();  
 #endif  
 #ifdef BFTPDAEMON  
         /*  
          * Are we working as the bftp daemon?  
          */  
         if (bftpd) {  
                 SCPYN(request.exec_name, BFTPPATH);  
         }  
 #endif /* BFTPDAEMON */  
         if (write(i, (char *)&request, sizeof(request)) < 0) {  
                 char tbuf[128];  
                 (void) sprintf(tbuf, "Can't write to %s\n", INIT_FIFO);  
                 fatalperror(net, tbuf);  
         }  
         (void) close(i);  
         (void) signal(SIGALRM, nologinproc);  
         for (i = 0; ; i++) {  
                 char tbuf[128];  
                 alarm(15);  
                 n = read(pty, ptyip, BUFSIZ);  
                 if (i == 3 || n >= 0 || !gotalarm)  
                         break;  
                 gotalarm = 0;  
                 snprintf (tbuf, sizeof tbuf,  
                          "telnetd: waiting for /etc/init to start login process on %s\r\n",  
                                   line);  
                 (void) write(net, tbuf, strlen(tbuf));  
         }  
         if (n < 0 && gotalarm)  
                 fatal(net, "/etc/init didn't start login process");  
         pcc += n;  
         alarm(0);  
         (void) signal(SIGALRM, SIG_DFL);  
   
         return;  
 #endif  /* NEWINIT */  
 }  
   
835  char    *envinit[3];  char    *envinit[3];
836  extern char **environ;  extern char **environ;
837    
# Line 1499  init_env() Line 852  init_env()
852          environ = envinit;          environ = envinit;
853  }  }
854    
 #ifndef NEWINIT  
   
 /* Security fix included in telnet-95.10.23.NE of David Borman <deb@cray.com>.  
  */  
 /*  
  * scrub_env()  
  *  
  * Remove a few things from the environment that  
  * don't need to be there.  
  */  
 static void  
 scrub_env()  
 {  
         register char **cpp, **cpp2;  
   
         for (cpp2 = cpp = environ; *cpp; cpp++) {  
                 if (strncmp(*cpp, "LD_", 3) &&  
                     strncmp(*cpp, "_RLD_", 5) &&  
                     strncmp(*cpp, "LIBPATH=", 8) &&  
                     strncmp(*cpp, "IFS=", 4))  
                         *cpp2++ = *cpp;  
         }  
         *cpp2 = 0;  
 }  
   
 /*  
  * start_login(host)  
  *  
  * Assuming that we are now running as a child processes, this  
  * function will turn us into the login process.  
  */  
   
 void  
 start_login(char *host, int autologin, char *name)  
 {  
         register char *cp;  
         register char **argv;  
         char **addarg();  
         extern char *getenv();  
 #ifdef  HAVE_UTMPX_H  
         register int pid = getpid();  
         struct utmpx utmpx;  
 #endif  
 #ifdef SOLARIS  
         char *term;  
         char termbuf[64];  
 #endif  
   
 #ifdef  UTMPX  
         /*  
          * Create utmp entry for child  
          */  
   
         memset(&utmpx, 0, sizeof(utmpx));  
         SCPYN(utmpx.ut_user, ".telnet");  
         SCPYN(utmpx.ut_line, line + sizeof("/dev/") - 1);  
         utmpx.ut_pid = pid;  
         utmpx.ut_id[0] = 't';  
         utmpx.ut_id[1] = 'n';  
 #define SC_WILDC 'e'  
         utmpx.ut_id[2] = SC_WILDC;  
         utmpx.ut_id[3] = SC_WILDC;  
         utmpx.ut_type = LOGIN_PROCESS;  
         (void) time(&utmpx.ut_tv.tv_sec);  
         if (pututxline(&utmpx) == NULL)  
                 fatal(net, "pututxline failed");  
 #endif  
   
         scrub_env();  
   
         /*  
          * -h : pass on name of host.  
          *              WARNING:  -h is accepted by login if and only if  
          *                      getuid() == 0.  
          * -p : don't clobber the environment (so terminal type stays set).  
          *  
          * -f : force this login, he has already been authenticated  
          */  
         argv = addarg(0, "login");  
   
 #if     !defined(NO_LOGIN_H)  
   
 # if    defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)  
         /*  
          * Don't add the "-h host" option if we are going  
          * to be adding the "-r host" option down below...  
          */  
         if ((auth_level < 0) || (autologin != AUTH_VALID))  
 # endif  
         {  
                 argv = addarg(argv, "-h");  
                 argv = addarg(argv, host);  
 #ifdef  SOLARIS  
                 /*  
                  * SVR4 version of -h takes TERM= as second arg, or -  
                  */  
                 term = getenv("TERM");  
                 if (term == NULL || term[0] == 0) {  
                         term = "-";  
                 } else {  
                         strcpy(termbuf, "TERM=");  
                         strncat(termbuf, term, sizeof(termbuf) - 6);  
                         term = termbuf;  
                 }  
                 argv = addarg(argv, term);  
 #endif  
         }  
 #endif  
 #if     !defined(NO_LOGIN_P)  
         argv = addarg(argv, "-p");  
 #endif  
 #ifdef  LINEMODE  
         /*  
          * Set the environment variable "LINEMODE" to either  
          * "real" or "kludge" if we are operating in either  
          * real or kludge linemode.  
          */  
         if (lmodetype == REAL_LINEMODE)  
                 setenv("LINEMODE", "real", 1);  
 # ifdef KLUDGELINEMODE  
         else if (lmodetype == KLUDGE_LINEMODE || lmodetype == KLUDGE_OK)  
                 setenv("LINEMODE", "kludge", 1);  
 # endif  
 #endif  
 #ifdef  BFTPDAEMON  
         /*  
          * Are we working as the bftp daemon?  If so, then ask login  
          * to start bftp instead of shell.  
          */  
         if (bftpd) {  
                 argv = addarg(argv, "-e");  
                 argv = addarg(argv, BFTPPATH);  
         } else  
 #endif  
 #if     defined (SecurID)  
         /*  
          * don't worry about the -f that might get sent.  
          * A -s is supposed to override it anyhow.  
          */  
         if (require_SecurID)  
                 argv = addarg(argv, "-s");  
 #endif  
 #if     defined (AUTHENTICATION)  
         if (auth_level >= 0 && autologin == AUTH_VALID) {  
 # if    !defined(NO_LOGIN_F)  
                 argv = addarg(argv, "-f");  
                 argv = addarg(argv, name);  
 # else  
 #  if defined(LOGIN_R)  
                 /*  
                  * We don't have support for "login -f", but we  
                  * can fool /bin/login into thinking that we are  
                  * rlogind, and allow us to log in without a  
                  * password.  The rlogin protocol expects  
                  *      local-user\0remote-user\0term/speed\0  
                  */  
   
                 if (pty > 2) {  
                         register char *cp;  
                         char speed[128];  
                         int isecho, israw, xpty, len;  
                         extern int def_rspeed;  
 #  ifndef LOGIN_HOST  
                         /*  
                          * Tell login that we are coming from "localhost".  
                          * If we passed in the real host name, then the  
                          * user would have to allow .rhost access from  
                          * every machine that they want authenticated  
                          * access to work from, which sort of defeats  
                          * the purpose of an authenticated login...  
                          * So, we tell login that the session is coming  
                          * from "localhost", and the user will only have  
                          * to have "localhost" in their .rhost file.  
                          */  
 #                       define LOGIN_HOST "localhost"  
 #  endif  
                         argv = addarg(argv, "-r");  
                         argv = addarg(argv, LOGIN_HOST);  
   
                         xpty = pty;  
 # ifndef  HAVE_STREAMSPTY  
                         pty = 0;  
 # else  
                         ttyfd = 0;  
 # endif  
                         init_termbuf();  
                         isecho = tty_isecho();  
                         israw = tty_israw();  
                         if (isecho || !israw) {  
                                 tty_setecho(0);         /* Turn off echo */  
                                 tty_setraw(1);          /* Turn on raw */  
                                 set_termbuf();  
                         }  
                         len = strlen(name)+1;  
                         write(xpty, name, len);  
                         write(xpty, name, len);  
                         snprintf (speed, sizeof speed,  
                                           "%s/%d", (cp = getenv("TERM")) ? cp : "",  
                                           (def_rspeed > 0) ? def_rspeed : 9600);  
                         len = strlen(speed)+1;  
                         write(xpty, speed, len);  
   
                         if (isecho || !israw) {  
                                 init_termbuf();  
                                 tty_setecho(isecho);  
                                 tty_setraw(israw);  
                                 set_termbuf();  
                                 if (!israw) {  
                                         /*  
                                          * Write a newline to ensure  
                                          * that login will be able to  
                                          * read the line...  
                                          */  
                                         write(xpty, "\n", 1);  
                                 }  
                         }  
                         pty = xpty;  
                 }  
 #  else  
                 argv = addarg(argv, name);  
 #  endif  
 # endif  
         } else  
 #endif  
         if (getenv("USER")) {  
                 argv = addarg(argv, getenv("USER"));  
 #if     defined(LOGIN_ARGS) && defined(NO_LOGIN_P)  
                 {  
                         register char **cpp;  
                         for (cpp = environ; *cpp; cpp++)  
                                 argv = addarg(argv, *cpp);  
                 }  
 #endif  
                 /*  
                  * Assume that login will set the USER variable  
                  * correctly.  For SysV systems, this means that  
                  * USER will no longer be set, just LOGNAME by  
                  * login.  (The problem is that if the auto-login  
                  * fails, and the user then specifies a different  
                  * account name, he can get logged in with both  
                  * LOGNAME and USER in his environment, but the  
                  * USER value will be wrong.  
                  */  
                 unsetenv("USER");  
         }  
 #ifdef  SOLARIS  
         else {  
                 char **p;  
   
                 argv = addarg(argv, "");        /* no login name */  
                 for (p = environ; *p; p++) {  
                         argv = addarg(argv, *p);  
                 }  
         }  
 #endif  /* SOLARIS */  
 #if     defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)  
         if (pty > 2)  
                 close(pty);  
 #endif  
         closelog();  
         /*  
          * This sleep(1) is in here so that telnetd can  
          * finish up with the tty.  There's a race condition  
          * the login banner message gets lost...  
          */  
         sleep(1);  
         execv(PATH_LOGIN, argv);  
   
         syslog(LOG_ERR, "%s: %m\n", PATH_LOGIN);  
         fatalperror(net, PATH_LOGIN);  
         /*NOTREACHED*/  
 }  
   
 char **  
 addarg(register char **argv, register char *val)  
 {  
         register char **cpp;  
   
         if (argv == NULL) {  
                 /*  
                  * 10 entries, a leading length, and a null  
                  */  
                 argv = (char **)malloc(sizeof(*argv) * 12);  
                 if (argv == NULL)  
                         return(NULL);  
                 *argv++ = (char *)10;  
                 *argv = (char *)0;  
         }  
         for (cpp = argv; *cpp; cpp++)  
                 ;  
         if (cpp == &argv[(long)argv[-1]]) {  
                 --argv;  
                 *argv = (char *)((long)(*argv) + 10);  
                 argv = (char **)realloc(argv, sizeof(*argv)*((long)(*argv) + 2));  
                 if (argv == NULL)  
                         return(NULL);  
                 argv++;  
                 cpp = &argv[(long)argv[-1] - 10];  
         }  
         *cpp++ = val;  
         *cpp = 0;  
         return(argv);  
 }  
 #endif  /* NEWINIT */  
   
 /*  
  * cleanup()  
  *  
  * This is the routine to call when we are all through, to  
  * clean up anything that needs to be cleaned up.  
  */  
         /* ARGSUSED */  
 void  
 cleanup(int sig)  
 {  
 #ifndef PARENT_DOES_UTMP  
 # if (BSD > 43) || defined(convex)  
         char *p;  
   
         p = line + sizeof("/dev/") - 1;  
         if (logout(p))  
                 logwtmp(p, "", "");  
         (void)chmod(line, 0666);  
         (void)chown(line, 0, 0);  
         *p = 'p';  
         (void)chmod(line, 0666);  
         (void)chown(line, 0, 0);  
         (void) shutdown(net, 2);  
         exit(1);  
 # else  
         void rmut();  
   
         rmut();  
         vhangup();      /* XXX */  
         (void) shutdown(net, 2);  
         exit(1);  
 # endif  
 #else   /* PARENT_DOES_UTMP */  
 # ifdef NEWINIT  
         (void) shutdown(net, 2);  
         exit(1);  
 # else  /* NEWINIT */  
 #  ifdef CRAY  
         static int incleanup = 0;  
         register int t;  
         int child_status; /* status of child process as returned by waitpid */  
         int flags = WNOHANG|WUNTRACED;  
   
         /*  
          * 1: Pick up the zombie, if we are being called  
          *    as the signal handler.  
          * 2: If we are a nested cleanup(), return.  
          * 3: Try to clean up TMPDIR.  
          * 4: Fill in utmp with shutdown of process.  
          * 5: Close down the network and pty connections.  
          * 6: Finish up the TMPDIR cleanup, if needed.  
          */  
         if (sig == SIGCHLD) {  
                 while (waitpid(-1, &child_status, flags) > 0)  
                         ;       /* VOID */  
                 /* Check if the child process was stopped  
                  * rather than exited.  We want cleanup only if  
                  * the child has died.  
                  */  
                 if (WIFSTOPPED(child_status)) {  
                         return;  
                 }  
         }  
         t = sigblock(sigmask(SIGCHLD));  
         if (incleanup) {  
                 sigsetmask(t);  
                 return;  
         }  
         incleanup = 1;  
         sigsetmask(t);  
 #ifdef  UNICOS7x  
         if (secflag) {  
                 /*  
                  *      We need to set ourselves back to a null  
                  *      label to clean up.  
                  */  
   
                 setulvl(sysv.sy_minlvl);  
                 setucmp((long)0);  
         }  
 #endif  /* UNICOS7x */  
   
         t = cleantmp(&wtmp);  
         setutent();     /* just to make sure */  
 #  endif /* CRAY */  
         rmut(line);  
         close(pty);  
         (void) shutdown(net, 2);  
 #  ifdef CRAY  
         if (t == 0)  
                 cleantmp(&wtmp);  
 #  endif /* CRAY */  
         exit(1);  
 # endif /* NEWINT */  
 #endif  /* PARENT_DOES_UTMP */  
 }  
   
 #if defined(PARENT_DOES_UTMP) && !defined(NEWINIT)  
 /*  
  * _utmp_sig_rcv  
  * utmp_sig_init  
  * utmp_sig_wait  
  *      These three functions are used to coordinate the handling of  
  *      the utmp file between the server and the soon-to-be-login shell.  
  *      The server actually creates the utmp structure, the child calls  
  *      utmp_sig_wait(), until the server calls utmp_sig_notify() and  
  *      signals the future-login shell to proceed.  
  */  
 static int caught=0;            /* NZ when signal intercepted */  
 static void (*func)();          /* address of previous handler */  
   
 void  
 _utmp_sig_rcv(int sig)  
 {  
         caught = 1;  
         (void) signal(SIGUSR1, func);  
 }  
   
 void  
 utmp_sig_init()  
 {  
         /*  
          * register signal handler for UTMP creation  
          */  
         if ((int)(func = signal(SIGUSR1, _utmp_sig_rcv)) == -1)  
                 fatalperror(net, "telnetd/signal");  
 }  
   
 void  
 utmp_sig_reset()  
 {  
         (void) signal(SIGUSR1, func);   /* reset handler to default */  
 }  
855    
 # ifdef __hpux  
 # define sigoff() /* do nothing */  
 # define sigon() /* do nothing */  
 # endif  
   
 void  
 utmp_sig_wait()  
 {  
         /*  
          * Wait for parent to write our utmp entry.  
          */  
         sigoff();  
         while (caught == 0) {  
                 pause();        /* wait until we get a signal (sigon) */  
                 sigoff();       /* turn off signals while we check caught */  
         }  
         sigon();                /* turn on signals again */  
 }  
   
 void  
 utmp_sig_notify(int pid)  
 {  
         kill(pid, SIGUSR1);  
 }  
   
 # ifdef CRAY  
 static int gotsigjob = 0;  
   
         /*ARGSUSED*/  
 void  
 sigjob(int sig)  
 {  
         register int jid;  
         register struct jobtemp *jp;  
   
         while ((jid = waitjob(NULL)) != -1) {  
                 if (jid == 0) {  
                         return;  
                 }  
                 gotsigjob++;  
                 jobend(jid, NULL, NULL);  
         }  
 }  
   
 /*  
  *      jid_getutid:  
  *              called by jobend() before calling cleantmp()  
  *              to find the correct $TMPDIR to cleanup.  
  */  
   
 struct utmp *  
 jid_getutid(int jid)  
 {  
         struct utmp *cur = NULL;  
   
         setutent();     /* just to make sure */  
         while (cur = getutent()) {  
                 if ( (cur->ut_type != NULL) && (jid == cur->ut_jid) ) {  
                         return(cur);  
                 }  
         }  
   
         return(0);  
 }  
   
 /*  
  * Clean up the TMPDIR that login created.  
  * The first time this is called we pick up the info  
  * from the utmp.  If the job has already gone away,  
  * then we'll clean up and be done.  If not, then  
  * when this is called the second time it will wait  
  * for the signal that the job is done.  
  */  
 int  
 cleantmp(register struct utmp *wtp)  
 {  
         struct utmp *utp;  
         static int first = 1;  
         register int mask, omask, ret;  
         extern struct utmp *getutid P((const struct utmp *_Id));  
   
   
         mask = sigmask(WJSIGNAL);  
   
         if (first == 0) {  
                 omask = sigblock(mask);  
                 while (gotsigjob == 0)  
                         sigpause(omask);  
                 return(1);  
         }  
         first = 0;  
         setutent();     /* just to make sure */  
   
         utp = getutid(wtp);  
         if (utp == 0) {  
                 syslog(LOG_ERR, "Can't get /etc/utmp entry to clean TMPDIR");  
                 return(-1);  
         }  
         /*  
          * Nothing to clean up if the user shell was never started.  
          */  
         if (utp->ut_type != USER_PROCESS || utp->ut_jid == 0)  
                 return(1);  
   
         /*  
          * Block the WJSIGNAL while we are in jobend().  
          */  
         omask = sigblock(mask);  
         ret = jobend(utp->ut_jid, utp->ut_tpath, utp->ut_user);  
         sigsetmask(omask);  
         return(ret);  
 }  
   
 int  
 jobend(register int jid, register char *path, register char *user)  
 {  
         static int saved_jid = 0;  
         static int pty_saved_jid = 0;  
         static char saved_path[sizeof(wtmp.ut_tpath)+1];  
         static char saved_user[sizeof(wtmp.ut_user)+1];  
   
         /*  
          * this little piece of code comes into play  
          * only when ptyreconnect is used to reconnect  
          * to an previous session.  
          *  
          * this is the only time when the  
          * "saved_jid != jid" code is executed.  
          */  
   
         if ( saved_jid && saved_jid != jid ) {  
                 if (!path) {    /* called from signal handler */  
                         pty_saved_jid = jid;  
                 } else {  
                         pty_saved_jid = saved_jid;  
                 }  
         }  
   
         if (path) {  
                 strncpy(saved_path, path, sizeof(wtmp.ut_tpath));  
                 strncpy(saved_user, user, sizeof(wtmp.ut_user));  
                 saved_path[sizeof(saved_path)] = '\0';  
                 saved_user[sizeof(saved_user)] = '\0';  
         }  
         if (saved_jid == 0) {  
                 saved_jid = jid;  
                 return(0);  
         }  
   
         /* if the jid has changed, get the correct entry from the utmp file */  
   
         if ( saved_jid != jid ) {  
                 struct utmp *utp = NULL;  
                 struct utmp *jid_getutid();  
   
                 utp = jid_getutid(pty_saved_jid);  
   
                 if (utp == 0) {  
                         syslog(LOG_ERR, "Can't get /etc/utmp entry to clean TMPDIR");  
                         return(-1);  
                 }  
   
                 cleantmpdir(jid, utp->ut_tpath, utp->ut_user);  
                 return(1);  
         }  
   
         cleantmpdir(jid, saved_path, saved_user);  
         return(1);  
 }  
   
 /*  
  * Fork a child process to clean up the TMPDIR  
  */  
 int  
 cleantmpdir(register int jid, register char *tpath, register char *user)  
 {  
         switch(fork()) {  
         case -1:  
                 syslog(LOG_ERR, "TMPDIR cleanup(%s): fork() failed: %m\n",  
                                                         tpath);  
                 break;  
         case 0:  
                 execl(CLEANTMPCMD, CLEANTMPCMD, user, tpath, 0);  
                 syslog(LOG_ERR, "TMPDIR cleanup(%s): execl(%s) failed: %m\n",  
                                                         tpath, CLEANTMPCMD);  
                 exit(1);  
         default:  
                 /*  
                  * Forget about child.  We will exit, and  
                  * /etc/init will pick it up.  
                  */  
                 break;  
         }  
 }  
 # endif /* CRAY */  
 #endif  /* defined(PARENT_DOES_UTMP) && !defined(NEWINIT) */  
   
 /*  
  * rmut()  
  *  
  * This is the function called by cleanup() to  
  * remove the utmp entry for this person.  
  */  
   
 #ifdef  HAVE_UTMPX_H  
 void  
 rmut()  
 {  
         register f;  
         int found = 0;  
         //struct utmp *u, *utmp;  
         int nutmp;  
         struct stat statbf;  
   
         struct utmpx *utxp, utmpx;  
   
         /*  
          * This updates the utmpx and utmp entries and make a wtmp/x entry  
          */  
   
         SCPYN(utmpx.ut_line, line + sizeof("/dev/") - 1);  
         utxp = getutxline(&utmpx);  
         if (utxp) {  
                 utxp->ut_type = DEAD_PROCESS;  
                 utxp->ut_exit.e_termination = 0;  
                 utxp->ut_exit.e_exit = 0;  
                 (void) time(&utmpx.ut_tv.tv_sec);  
                 utmpx.ut_tv.tv_usec = 0;  
                 //modutx(utxp);  
                 updwtmpx(PATH_UTMP, utxp);  
         }  
         endutxent();  
 }  /* end of rmut */  
 #endif  
   
 #if !defined(HAVE_UTMPX_H) && !(defined(CRAY) || defined(__hpux)) && BSD <= 43  
 void  
 rmut()  
 {  
         register f;  
         int found = 0;  
         struct utmp *u, *utmp;  
         int nutmp;  
         struct stat statbf;  
   
         f = open(utmpf, O_RDWR);  
         if (f >= 0) {  
                 (void) fstat(f, &statbf);  
                 utmp = (struct utmp *)malloc((unsigned)statbf.st_size);  
                 if (!utmp)  
                         syslog(LOG_ERR, "utmp malloc failed");  
                 if (statbf.st_size && utmp) {  
                         nutmp = read(f, (char *)utmp, (int)statbf.st_size);  
                         nutmp /= sizeof(struct utmp);  
   
                         for (u = utmp ; u < &utmp[nutmp] ; u++) {  
                                 if (SCMPN(u->ut_line, line+5) ||  
                                     u->ut_name[0]==0)  
                                         continue;  
                                 (void) lseek(f, ((long)u)-((long)utmp), SEEK_SET);  
                                 SCPYN(u->ut_name, "");  
 #ifdef HAVE_UTMP_UT_HOST  
                                 SCPYN(u->ut_host, "");  
 #endif  
                                 (void) time(&u->ut_time);  
                                 (void) write(f, (char *)u, sizeof(wtmp));  
                                 found++;  
                         }  
                 }  
                 (void) close(f);  
         }  
         if (found) {  
                 f = open(wtmpf, O_WRONLY|O_APPEND);  
                 if (f >= 0) {  
                         SCPYN(wtmp.ut_line, line+5);  
                         SCPYN(wtmp.ut_name, "");  
 #ifdef HAVE_UTMP_UT_HOST  
                         SCPYN(wtmp.ut_host, "");  
 #endif  
 #ifdef HAVE_WTMP_UT_TV  
                         (void) time(&wtmp.ut_tv.tv_sec);  
 #else  
                         (void) time(&wtmp.ut_time);  
 #endif  
                         (void) write(f, (char *)&wtmp, sizeof(wtmp));  
                         (void) close(f);  
                 }  
         }  
         (void) chmod(line, 0666);  
         (void) chown(line, 0, 0);  
         line[strlen("/dev/")] = 'p';  
         (void) chmod(line, 0666);  
         (void) chown(line, 0, 0);  
 }  /* end of rmut */  
 #endif  /* CRAY */  
   
 #ifdef __hpux  
 int  
 rmut (char *line)  
 {  
         struct utmp utmp;  
         struct utmp *utptr;  
         int fd;                 /* for /etc/wtmp */  
   
         utmp.ut_type = USER_PROCESS;  
         (void) strncpy(utmp.ut_id, line+12, sizeof(utmp.ut_id));  
         (void) setutent();  
         utptr = getutid(&utmp);  
         /* write it out only if it exists */  
         if (utptr) {  
                 utptr->ut_type = DEAD_PROCESS;  
                 utptr->ut_time = time((long *) 0);  
                 (void) pututline(utptr);  
                 /* set wtmp entry if wtmp file exists */  
                 if ((fd = open(wtmpf, O_WRONLY | O_APPEND)) >= 0) {  
                         (void) write(fd, utptr, sizeof(utmp));  
                         (void) close(fd);  
                 }  
         }  
         (void) endutent();  
   
         (void) chmod(line, 0666);  
         (void) chown(line, 0, 0);  
         line[14] = line[13];  
         line[13] = line[12];  
         line[8] = 'm';  
         line[9] = '/';  
         line[10] = 'p';  
         line[11] = 't';  
         line[12] = 'y';  
         (void) chmod(line, 0666);  
         (void) chown(line, 0, 0);  
 }  
 #endif  

Legend:
Removed from v.1.21  
changed lines
  Added in v.1.22

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26