File:  [ELWIX - Embedded LightWeight unIX -] / ansh / src / daemon2.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Oct 4 22:37:46 2011 UTC (12 years, 9 months ago) by misho
Branches: MAIN
CVS tags: HEAD
Initial revision

    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, &eth)) == 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, &eth.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>