5 written by Christian A. Lademann <cal@zls.com>
9 02.05.95:cal:ported to samba-1.9.13
15 /* #include <stdio.h> */
16 /* #include <fcntl.h> */
17 /* #include <sys/types.h> */
18 /* #include <unistd.h> */
19 /* #include <signal.h> */
20 /* #include <errno.h> */
21 /* #include <ctype.h> */
22 /* #include <utmp.h> */
23 /* #include <sys/param.h> */
24 /* #include <sys/ioctl.h> */
25 /* #include <stdlib.h> */
26 /* #include <string.h> */
33 extern char *strdup();
49 extern int DEBUGLEVEL
;
50 extern char *InBuffer
, *OutBuffer
;
51 extern int done_become_user
;
53 char master_name
[64], slave_name
[64];
54 int master
, slave
, i
, o
, e
;
56 int ms_type
= MS_NONE
,
61 VT_Check: test incoming packet for "vtp" or "iVT1\0"
63 int VT_Check(char *buffer
)
65 DEBUG(3,("Checking packet: <%10s...>\n", buffer
+4));
66 if((strncmp(buffer
+4, "vtp", 3) == 0 && smb_len(buffer
) == 3) || (strncmp(buffer
+4, "iVT1\0", 5) == 0 && smb_len(buffer
) == 5))
74 VT_Start_utmp: prepare /etc/utmp for /bin/login
76 int VT_Start_utmp(void)
84 strcpy(u
.ut_line
, VT_Line
);
86 if((v
= getutline(&u
)) == NULL
) {
87 if(strncmp(VT_Line
, "tty", 3) == 0)
89 else if(strlen(VT_Line
) > 4)
90 tt
= VT_Line
+ strlen(VT_Line
) - 4;
95 u
.ut_time
= time((time_t*)0);
98 strcpy(u
.ut_user
, "LOGIN");
99 strcpy(u
.ut_line
, VT_Line
);
101 u
.ut_type
= LOGIN_PROCESS
;
111 VT_Stop_utmp: prepare /etc/utmp for other processes
113 int VT_Stop_utmp(void)
118 if(VT_Line
!= NULL
) {
121 strcpy(u
.ut_line
, VT_Line
);
123 if((v
= getutline(&u
)) != NULL
) {
124 strcpy(v
->ut_user
, "");
125 v
->ut_type
= DEAD_PROCESS
;
126 v
->ut_time
= time((time_t*)0);
138 VT_AtExit: Things to do when the program exits
142 if(VT_ChildPID
> 0) {
143 kill(VT_ChildPID
, SIGHUP
);
152 VT_SigCLD: signalhandler for SIGCLD: set flag if child-process died
154 void VT_SigCLD(int sig
)
156 if(wait(NULL
) == VT_ChildPID
)
159 signal(SIGCLD
, VT_SigCLD
);
164 VT_SigEXIT: signalhandler for signals that cause the process to exit
166 void VT_SigEXIT(int sig
)
175 VT_Start: initialize vt-specific data, alloc pty, spawn shell and send ACK
179 char OutBuf
[64], *X
, *Y
;
187 # define MASTER_TMPL "/dev/pty "
188 # define SLAVE_TMPL "/dev/tty "
189 # define LETTER1 "pqrs"
191 # define LETTER2 "0123456789abcdef"
196 # define MASTER_TMPL "/dev/ptyp_ "
197 # define SLAVE_TMPL "/dev/ttyp_ "
198 # define LETTER1 "0123456"
200 # define LETTER2 "0123456789abcdef"
204 if(ms_poll
== MS_VTY
|| ms_poll
== 0) {
205 strcpy(master_name
, MASTER_TMPL
);
206 strcpy(slave_name
, SLAVE_TMPL
);
208 for(X
= LETTER1
; *X
&& master
< 0; X
++)
209 for(Y
= LETTER2
; *Y
&& master
< 0; Y
++) {
210 master_name
[POS1
] = *X
;
211 master_name
[POS2
] = *Y
;
212 if((master
= open(master_name
, O_RDWR
)) >= 0) {
213 slave_name
[POS1
] = *X
;
214 slave_name
[POS2
] = *Y
;
215 if((slave
= open(slave_name
, O_RDWR
)) < 0)
220 if(master
>= 0 && slave
>= 0)
235 # define MASTER_TMPL "/dev/ptyp%d"
236 # define SLAVE_TMPL "/dev/ttyp%d"
241 if(ms_poll
== MS_PTY
|| ms_poll
== 0) {
244 for(i
= MIN_I
; i
<= MAX_I
&& master
< 0; i
++) {
245 sprintf(master_name
, MASTER_TMPL
, i
);
246 if((master
= open(master_name
, O_RDWR
)) >= 0) {
247 sprintf(slave_name
, SLAVE_TMPL
, i
);
248 if((slave
= open(slave_name
, O_RDWR
)) < 0)
253 if(master
>= 0 && slave
>= 0)
267 VT_Line
= strdup(strrchr(slave_name
, '/') + 1);
269 switch((VT_ChildPID
= fork())) {
282 i
= open(slave_name
, O_RDWR
);
283 o
= open(slave_name
, O_RDWR
);
284 e
= open(slave_name
, O_RDWR
);
288 if (ioctl(slave
, TIOCSCTTY
, (char *)NULL
) == -1)
292 tcsetpgrp(0, getpid());
298 execlp("/bin/login", "login", "-c", (char*)0);
305 VT_ChildDied
= False
;
308 signal(SIGCLD
, VT_SigCLD
);
310 signal(SIGHUP
, VT_SigEXIT
);
311 signal(SIGTERM
, VT_SigEXIT
);
312 signal(SIGINT
, VT_SigEXIT
);
313 signal(SIGQUIT
, VT_SigEXIT
);
315 memset(OutBuf
, 0, sizeof(OutBuf
));
317 _smb_setlen(OutBuf
, 1);
319 send_smb(Client
,OutBuf
);
328 VT_Output: transport data from socket to pty
330 int VT_Output(char *Buffer
)
335 if(VT_Status
!= VT_OPEN
)
338 len
= smb_len(Buffer
);
340 nb
= write(VT_Fd
, Buffer
+ 4, len
);
342 return((nb
== len
) ? 0 : -1);
347 VT_Input: transport data from pty to socket
349 int VT_Input(char *Buffer
,int Size
)
354 if(VT_Status
!= VT_OPEN
)
357 memset(Buffer
, 0, Size
);
358 len
= read(VT_Fd
, Buffer
+ 4, MIN(VT_MAXREAD
, Size
));
360 _smb_setlen(Buffer
, len
);
367 VT_Process: main loop while in vt-mode
369 void VT_Process(void)
371 static int trans_num
= 0;
385 int last_keepalive
=0;
387 struct timeval to
, *top
;
392 t
= SMBD_SELECT_LOOP
*1000;
401 to
.tv_sec
= t
/ 1000;
402 to
.tv_usec
= t
- (to
.tv_sec
* 1000);
409 goto leave_VT_Process
;
411 n
= select(MAX(VT_Fd
, Client
) + 1, &si
, NULL
, NULL
, top
);
414 goto leave_VT_Process
;
420 extern int keepalive
;
422 counter
+= SMBD_SELECT_LOOP
;
426 if (keepalive
&& (counter
-last_keepalive
)>keepalive
) {
427 if (!send_keepalive(Client
))
428 goto leave_VT_Process
;
429 last_keepalive
= counter
;
434 if(FD_ISSET(VT_Fd
, &si
)) {
435 /* got input from vt */
436 nread
= VT_Input(OutBuffer
, MIN(BUFFER_SIZE
,lp_maxxmit()));
439 send_smb(Client
,OutBuffer
);
442 if(FD_ISSET(Client
, &si
)) {
443 /* got input from socket */
445 if(receive_smb(Client
,InBuffer
, 0)) {
446 msg_type
= CVAL(InBuffer
,0);
447 msg_flags
= CVAL(InBuffer
,1);
449 len
= smb_len(InBuffer
);
451 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type
,len
));
455 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num
,nread
));
460 nread
= construct_reply(InBuffer
,OutBuffer
,nread
,MIN(BUFFER_SIZE
,lp_maxxmit()));
463 if (nread
!= smb_len(OutBuffer
) + 4) {
464 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
466 smb_len(OutBuffer
)));
468 send_smb(Client
,OutBuffer
);
473 goto leave_VT_Process
;
483 kill(VT_ChildPID, SIGHUP);
485 VT_Stop_utmp(VT_Line);