File:  [ELWIX - Embedded LightWeight unIX -] / ansh / src / daemon3.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 4 22:37:46 2011 UTC (12 years, 10 months ago) by misho
Branches: misho
CVS tags: start, ansh1_0
ansh ELWIX remote managment

    1: /*************************************************************************
    2:  * (C) 2011 AITNET - Sofia/Bulgaria - <office@aitnet.org>
    3:  *  by Michael Pounov <misho@elwix.org>
    4:  *
    5:  * $Author: misho $
    6:  * $Id: daemon3.c,v 1.1.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: icmpTx(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 = icmpSend(TASK_FD(task), proc->proc_id, proc->proc_flg, proc->proc_buf_[FD2NET], 
   26: 			proc->proc_rlen_[FD2NET], &proc->proc_cli, sizeof proc->proc_cli)) != 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: icmpRx(sched_task_t *task)
   37: {
   38: 	u_char *buf;
   39: 	struct sockaddr sa;
   40: 	int rlen, n = 0, salen = sizeof sa;
   41: 	struct tagProc *proc = NULL;
   42: 	char ret;
   43: 	u_short id, *b;
   44: 
   45: 	FTRACE(3);
   46: 
   47: 	rlen = bpfLEN;
   48: 	if (!(buf = malloc(rlen)))
   49: 		goto end;
   50: 
   51: 	if ((ret = icmpRecv(TASK_FD(task), &id, buf, &rlen, &sa, (socklen_t *) &salen)) == ANSH_FLG_ERR)
   52: 		goto end;
   53: 	VERB(5) LOG("Received %d bytes", rlen);
   54: 	if (!(ret & ANSH_FLG_CPOUT))
   55: 		goto end;
   56: 
   57: 	/* packet is ok find active session */
   58: 	SLIST_FOREACH(proc, &pH, proc_next)
   59: 		if (proc->proc_id == id) {
   60: 			n = ANSH_CODE;
   61: 			break;
   62: 		}
   63: 	/* not found in sessions, drop packet */
   64: 	if (n != ANSH_CODE) {
   65: 		proc = NULL;
   66: 		goto end;
   67: 	}
   68: 
   69: 	switch (ret) {
   70: 		case ANSH_FLG_EOF:
   71: 		case ANSH_FLG_CPOUT:
   72: 			break;
   73: 		case ANSH_FLG_WINZ:
   74: 			b = (u_short*) buf;
   75: 			ioChgWinPTY(proc->proc_pty, ntohs(b[0]), ntohs(b[1]), ntohs(b[2]), ntohs(b[3]));
   76: 			/* if not started login, lets start & go! */
   77: 			if (!proc->proc_pid) {
   78: 				memcpy(&proc->proc_cli, &sa, sizeof sa);
   79: 				spawnLogin(task, proc);
   80: 			}
   81: 		default:
   82: 			goto end;
   83: 	}
   84: 
   85: 	proc->proc_flg = ret;
   86: 	proc->proc_rlen_[NET2FD] = rlen;
   87: 	memset(proc->proc_buf_[NET2FD], 0, proc->proc_blen);
   88: 	memcpy(proc->proc_buf_[NET2FD], buf, proc->proc_rlen_[NET2FD]);
   89: 	schedWrite(TASK_ROOT(task), fdTx, proc, proc->proc_pty);
   90: end:
   91: 	free(buf);
   92: 	schedRead(TASK_ROOT(task), icmpRx, NULL, proc ? proc->proc_sock : TASK_FD(task));
   93: 	return NULL;
   94: }
   95: 
   96: void *
   97: fdTx(sched_task_t *task)
   98: {
   99: 	struct tagProc *proc;
  100: 	struct timeval tv = { 0 };
  101: 	int wlen;
  102: 
  103: 	FTRACE(3);
  104: 
  105: 	/* not found argument, drop data */
  106: 	if (!(proc = TASK_ARG(task)))
  107: 		return (void*) -1;
  108: 
  109: 	/* if != ANSH_FLG_CPOUT isnt received from client */
  110: 	if (proc->proc_flg != ANSH_FLG_CPOUT || !proc->proc_pid)
  111: 		return NULL;
  112: 
  113: 	if (waitpid(proc->proc_pid, &wlen, WNOHANG)) {
  114: 		ioFreePTY(TASK_FD(task), proc->proc_ttyname);
  115: 		schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
  116: 
  117: 		proc->proc_pid = 0;
  118: 		proc->proc_flg = ANSH_FLG_EOF;
  119: 		proc->proc_rlen_[FD2NET] = 0;
  120: 
  121: 		schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock);
  122: 		return NULL;
  123: 	}
  124: 
  125: 	/* if Timeout defined, disarm timer */
  126: 	if (Timeout)
  127: 		schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL);
  128: 
  129: 	wlen = write(TASK_FD(task), proc->proc_buf_[NET2FD], proc->proc_rlen_[NET2FD]);
  130: 	switch (wlen) {
  131: 		case -1:
  132: 			ERR("write2tty #%d - %s", errno, strerror(errno));
  133: 			/* exit from shell and release tty */
  134: 			waitpid(proc->proc_pid, &wlen, 0);
  135: 			ioFreePTY(TASK_FD(task), proc->proc_ttyname);
  136: 			schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
  137: 
  138: 			proc->proc_pid = 0;
  139: 			proc->proc_flg = ANSH_FLG_EOF;
  140: 			proc->proc_rlen_[FD2NET] = 0;
  141: 
  142: 			schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock);
  143: 			return NULL;
  144: 		default:
  145: 			proc->proc_flg = ANSH_FLG_OK;
  146: 			proc->proc_rlen_[NET2FD] = 0;
  147: 	}
  148: 	VERB(3) LOG("Writed %d bytes - %s", wlen, proc->proc_buf_[NET2FD]);
  149: 
  150: 	/* if Timeout defined, go arm timer */
  151: 	if (Timeout) {
  152: 		tv.tv_sec = Timeout;
  153: 		schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
  154: 	}
  155: 	return NULL;
  156: }
  157: 
  158: void *
  159: fdRx(sched_task_t *task)
  160: {
  161: 	struct tagProc *proc;
  162: 	struct timeval tv = { 0 };
  163: 	int rlen;
  164: 
  165: 	FTRACE(3);
  166: 
  167: 	/* not found argument, drop data */
  168: 	if (!(proc = TASK_ARG(task)))
  169: 		return (void*) -1;
  170: 	if (!proc->proc_pid)
  171: 		return NULL;
  172: 
  173: 	if (waitpid(proc->proc_pid, &rlen, WNOHANG)) {
  174: 		ioFreePTY(TASK_FD(task), proc->proc_ttyname);
  175: 		schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
  176: 
  177: 		proc->proc_pid = 0;
  178: 		proc->proc_flg = ANSH_FLG_EOF;
  179: 		proc->proc_rlen_[FD2NET] = 0;
  180: 
  181: 		schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock);
  182: 		return NULL;
  183: 	}
  184: 
  185: 	/* if Timeout defined, disarm timer */
  186: 	if (Timeout)
  187: 		schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL);
  188: 
  189: 	memset(proc->proc_buf_[FD2NET], 0, proc->proc_blen);
  190: 	rlen = read(TASK_FD(task), proc->proc_buf_[FD2NET], proc->proc_blen);
  191: 	switch (rlen) {
  192: 		case -1:
  193: 			ERR("readtty #%d - %s", errno, strerror(errno));
  194: 		case 0:
  195: 			/* exit from shell and release tty */
  196: 			waitpid(proc->proc_pid, &rlen, 0);
  197: 			ioFreePTY(TASK_FD(task), proc->proc_ttyname);
  198: 			schedCancelby(TASK_ROOT(task), NULL, CRITERIA_FD, (void*) TASK_FD(task), NULL);
  199: 			VERB(3) LOG("EOF process status %d", rlen);
  200: 
  201: 			proc->proc_pid = 0;
  202: 			proc->proc_flg = ANSH_FLG_EOF;
  203: 			proc->proc_rlen_[FD2NET] = 0;
  204: 
  205: 			schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock);
  206: 			return NULL;
  207: 		default:
  208: 			proc->proc_flg = ANSH_FLG_OK;
  209: 			proc->proc_rlen_[FD2NET] = rlen;
  210: 	}
  211: 	VERB(3) LOG("Readed %d bytes - %s", rlen, proc->proc_buf_[FD2NET]);
  212: 
  213: 	schedWrite(TASK_ROOT(task), icmpTx, proc, proc->proc_sock);
  214: 	schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
  215: 
  216: 	/* if Timeout defined, go arm timer */
  217: 	if (Timeout) {
  218: 		tv.tv_sec = Timeout;
  219: 		schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
  220: 	}
  221: 	return NULL;
  222: }
  223: 
  224: int
  225: spawnLogin(sched_task_t *task, struct tagProc *proc)
  226: {
  227: 	int flg;
  228: 	struct timeval tv = { 0 };
  229: 	char str[STRSIZ] = { 0 };
  230: 	struct sockaddr_in *sin;
  231: 	struct sockaddr_in6 *sin6;
  232: 
  233: 	FTRACE(3);
  234: 
  235: 	assert(proc);
  236: 
  237: 	switch ((proc->proc_pid = ioForkPTY(&proc->proc_pty, proc->proc_ttyname, 
  238: 					sizeof proc->proc_ttyname, NULL, NULL, NULL))) {
  239: 		case -1:
  240: 			ERR("ioForkPTY() #%d - %s", io_GetErrno(), io_GetError());
  241: 			return -1;
  242: 		case 0:
  243: 			printf("ansh3d ELWIX remote management system over ICMP (%s)\n\n", 
  244: 					proc->proc_ttyname);
  245: 			strlcpy(str, "-hansh3@", sizeof str);
  246: 			if (proc->proc_cli.sa_family == AF_INET) {
  247: 				sin = (struct sockaddr_in*) &proc->proc_cli;
  248: 				inet_ntop(AF_INET, &sin->sin_addr, str + 8, INET_ADDRSTRLEN);
  249: 			} else if (proc->proc_cli.sa_family == AF_INET) {
  250: 				sin6 = (struct sockaddr_in6*) &proc->proc_cli;
  251: 				inet_ntop(AF_INET6, &sin6->sin6_addr, str + 8, INET6_ADDRSTRLEN);
  252: 			}
  253: 			execl("/usr/bin/login", "login", str, NULL);
  254: 			/* never reached */
  255: 			return -1;
  256: 		default:
  257: 			flg = fcntl(proc->proc_pty, F_GETFL);
  258: 			fcntl(proc->proc_pty, F_SETFL, flg | O_NONBLOCK);
  259: 
  260: 			VERB(3) LOG("Parent know child pid %d", proc->proc_pid);
  261: 			schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
  262: 
  263: 			/* if Timeout defined, go arm timer */
  264: 			if (Timeout) {
  265: 				tv.tv_sec = Timeout;
  266: 				schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
  267: 			}
  268: 			break;
  269: 	}
  270: 
  271: 	return 0;
  272: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>