1: /*************************************************************************
2: * (C) 2011 AITNET - Sofia/Bulgaria - <office@aitnet.org>
3: * by Michael Pounov <misho@elwix.org>
4: *
5: * $Author: misho $
6: * $Id: daemon2.c,v 1.1 2011/10/04 22:37:46 misho Exp $
7: *
8: *************************************************************************/
9: #include "global.h"
10: #include "anshd.h"
11:
12:
13: void *
14: pktTx(sched_task_t *task)
15: {
16: struct tagProc *proc;
17: int wlen;
18:
19: FTRACE(3);
20:
21: /* not found argument, drop data */
22: if (!(proc = TASK_ARG(task)))
23: return (void*) -1;
24:
25: if ((wlen = pktSend(TASK_FD(task), proc->proc_id, proc->proc_flg, proc->proc_buf_[FD2NET],
26: proc->proc_rlen_[FD2NET], &proc->proc_ea)) != ANSH_FLG_ERR) {
27: proc->proc_flg = ANSH_FLG_OK;
28: proc->proc_rlen_[FD2NET] = 0;
29: }
30: VERB(5) LOG("Sended %d bytes", wlen);
31:
32: return NULL;
33: }
34:
35: void *
36: pktRx(sched_task_t *task)
37: {
38: u_char *buf;
39: struct ether_header eth;
40: int rlen, n = 0;
41: struct tagProc *proc = NULL;
42: char ret;
43: u_short *b;
44:
45: FTRACE(3);
46:
47: rlen = bpfLEN;
48: if (!(buf = malloc(rlen)))
49: goto end;
50:
51: if ((ret = pktRecv(TASK_FD(task), buf, &rlen, ð)) == ANSH_FLG_ERR)
52: goto end;
53: VERB(5) LOG("Received %d bytes", rlen);
54:
55: /* packet is ok find active session */
56: SLIST_FOREACH(proc, &pH, proc_next)
57: if (proc->proc_id == ntohs(eth.ether_type)) {
58: n = ANSH_CODE;
59: break;
60: }
61: /* not found in sessions, drop packet */
62: if (n != ANSH_CODE)
63: goto end;
64:
65: switch (ret) {
66: case ANSH_FLG_EOF:
67: case ANSH_FLG_CPOUT:
68: break;
69: case ANSH_FLG_WINZ:
70: b = (u_short*) buf;
71: ioChgWinPTY(proc->proc_pty, ntohs(buf[0]), ntohs(buf[1]), ntohs(buf[2]), ntohs(buf[3]));
72: /* if not started login, lets start & go! */
73: if (!proc->proc_pid) {
74: memcpy(&proc->proc_ea.octet, ð.ether_shost, ETHER_ADDR_LEN);
75: spawnLogin(task, proc);
76: }
77: default:
78: goto end;
79: }
80:
81: proc->proc_flg = ret;
82: proc->proc_rlen_[NET2FD] = rlen;
83: memset(proc->proc_buf_[NET2FD], 0, proc->proc_blen);
84: memcpy(proc->proc_buf_[NET2FD], buf, proc->proc_rlen_[NET2FD]);
85: schedWrite(TASK_ROOT(task), fdTx, proc, proc->proc_pty);
86: end:
87: free(buf);
88: schedRead(TASK_ROOT(task), pktRx, NULL, proc ? proc->proc_sock : TASK_FD(task));
89: return NULL;
90: }
91:
92: void *
93: fdTx(sched_task_t *task)
94: {
95: struct tagProc *proc;
96: int wlen;
97:
98: FTRACE(3);
99:
100: /* not found argument, drop data */
101: if (!(proc = TASK_ARG(task)))
102: return (void*) -1;
103:
104: /* if != ANSH_FLG_CPOUT isnt received from client */
105: if (proc->proc_flg != ANSH_FLG_CPOUT)
106: return NULL;
107:
108: if (waitpid(proc->proc_pid, &wlen, WNOHANG)) {
109: schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
110: ioFreePTY(TASK_FD(task), proc->proc_ttyname);
111:
112: proc->proc_pid = 0;
113: proc->proc_flg = ANSH_FLG_EOF;
114: proc->proc_rlen_[FD2NET] = 0;
115:
116: schedWrite(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
117: return NULL;
118: }
119:
120: wlen = write(TASK_FD(task), proc->proc_buf_[NET2FD], proc->proc_rlen_[NET2FD]);
121: switch (wlen) {
122: case -1:
123: ERR("write2tty #%d - %s", errno, strerror(errno));
124: /* exit from shell and release tty */
125: schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
126: waitpid(proc->proc_pid, &wlen, 0);
127: ioFreePTY(TASK_FD(task), proc->proc_ttyname);
128:
129: proc->proc_pid = 0;
130: proc->proc_flg = ANSH_FLG_EOF;
131: proc->proc_rlen_[FD2NET] = 0;
132:
133: schedWrite(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
134: return NULL;
135: default:
136: proc->proc_flg = ANSH_FLG_OK;
137: proc->proc_rlen_[NET2FD] = 0;
138: }
139: VERB(3) LOG("Writed %d bytes - %s", wlen, proc->proc_buf_[NET2FD]);
140:
141: return NULL;
142: }
143:
144: void *
145: fdRx(sched_task_t *task)
146: {
147: struct tagProc *proc;
148: int rlen;
149:
150: FTRACE(3);
151:
152: /* not found argument, drop data */
153: if (!(proc = TASK_ARG(task)))
154: return (void*) -1;
155:
156: if (waitpid(proc->proc_pid, &rlen, WNOHANG)) {
157: schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
158: ioFreePTY(TASK_FD(task), proc->proc_ttyname);
159:
160: proc->proc_pid = 0;
161: proc->proc_flg = ANSH_FLG_EOF;
162: proc->proc_rlen_[FD2NET] = 0;
163:
164: schedWrite(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
165: return NULL;
166: }
167:
168: memset(proc->proc_buf_[FD2NET], 0, proc->proc_blen);
169: rlen = read(TASK_FD(task), proc->proc_buf_[FD2NET], proc->proc_blen);
170: switch (rlen) {
171: case -1:
172: ERR("readtty #%d - %s", errno, strerror(errno));
173: case 0:
174: /* exit from shell and release tty */
175: schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
176: waitpid(proc->proc_pid, &rlen, 0);
177: VERB(3) LOG("EOF process status %d", rlen);
178: ioFreePTY(TASK_FD(task), proc->proc_ttyname);
179:
180: proc->proc_pid = 0;
181: proc->proc_flg = ANSH_FLG_EOF;
182: proc->proc_rlen_[FD2NET] = 0;
183:
184: schedWrite(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
185: return NULL;
186: default:
187: proc->proc_flg = ANSH_FLG_OK;
188: proc->proc_rlen_[FD2NET] = rlen;
189: }
190: VERB(3) LOG("Readed %d bytes - %s", rlen, proc->proc_buf_[FD2NET]);
191:
192: schedWrite(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
193: schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
194: return NULL;
195: }
196:
197: int
198: spawnLogin(sched_task_t *task, struct tagProc *proc)
199: {
200: FTRACE(3);
201:
202: assert(proc);
203:
204: switch ((proc->proc_pid = ioForkPTY(&proc->proc_pty, proc->proc_ttyname,
205: sizeof proc->proc_ttyname, NULL, NULL, NULL))) {
206: case -1:
207: ERR("ioForkPTY() #%d - %s", io_GetErrno(), io_GetError());
208: return -1;
209: case 0:
210: execl("/usr/bin/login", "login", NULL);
211: // execl("/bin/echo", "echo", "MUUUUUUUUUUUUUUUUU", NULL);
212: /* never reached */
213: return -1;
214: default:
215: VERB(3) LOG("Parent know child pid %d - ptyfd=%d", proc->proc_pid, proc->proc_pty);
216: schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
217: break;
218: }
219:
220: return 0;
221: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>