Annotation of ansh/src/daemon2.c, revision 1.2

1.1       misho       1: /*************************************************************************
                      2:  * (C) 2011 AITNET - Sofia/Bulgaria - <office@aitnet.org>
                      3:  *  by Michael Pounov <misho@elwix.org>
                      4:  *
                      5:  * $Author: misho $
1.2     ! misho       6:  * $Id: daemon2.c,v 1.1.1.1.2.10 2011/10/17 09:28:19 misho Exp $
1.1       misho       7:  *
1.2     ! misho       8:  *************************************************************************
        !             9: The ELWIX and AITNET software is distributed under the following
        !            10: terms:
        !            11: 
        !            12: All of the documentation and software included in the ELWIX and AITNET
        !            13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
        !            14: 
        !            15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
        !            16:        by Michael Pounov <misho@elwix.org>.  All rights reserved.
        !            17: 
        !            18: Redistribution and use in source and binary forms, with or without
        !            19: modification, are permitted provided that the following conditions
        !            20: are met:
        !            21: 1. Redistributions of source code must retain the above copyright
        !            22:    notice, this list of conditions and the following disclaimer.
        !            23: 2. Redistributions in binary form must reproduce the above copyright
        !            24:    notice, this list of conditions and the following disclaimer in the
        !            25:    documentation and/or other materials provided with the distribution.
        !            26: 3. All advertising materials mentioning features or use of this software
        !            27:    must display the following acknowledgement:
        !            28: This product includes software developed by Michael Pounov <misho@elwix.org>
        !            29: ELWIX - Embedded LightWeight unIX and its contributors.
        !            30: 4. Neither the name of AITNET nor the names of its contributors
        !            31:    may be used to endorse or promote products derived from this software
        !            32:    without specific prior written permission.
        !            33: 
        !            34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
        !            35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            44: SUCH DAMAGE.
        !            45: */
1.1       misho      46: #include "global.h"
                     47: #include "anshd.h"
                     48: 
                     49: 
                     50: void *
                     51: pktTx(sched_task_t *task)
                     52: {
                     53:        struct tagProc *proc;
                     54:        int wlen;
                     55: 
                     56:        FTRACE(3);
                     57: 
                     58:        /* not found argument, drop data */
                     59:        if (!(proc = TASK_ARG(task)))
                     60:                return (void*) -1;
                     61: 
1.2     ! misho      62:        if ((wlen = pktSend(TASK_FD(task), ++proc->proc_seq, proc->proc_flg, Crypted, 
        !            63:                                        proc->proc_buf_[FD2NET], proc->proc_rlen_[FD2NET], 
        !            64:                                        &proc->proc_ea)) != ANSH_FLG_ERR) {
1.1       misho      65:                proc->proc_flg = ANSH_FLG_OK;
                     66:                proc->proc_rlen_[FD2NET] = 0;
                     67:        }
                     68:        VERB(5) LOG("Sended %d bytes", wlen);
                     69: 
                     70:        return NULL;
                     71: }
                     72: 
                     73: void *
                     74: pktRx(sched_task_t *task)
                     75: {
                     76:        u_char *buf;
                     77:        struct ether_header eth;
                     78:        int rlen, n = 0;
                     79:        struct tagProc *proc = NULL;
                     80:        char ret;
                     81:        u_short *b;
1.2     ! misho      82:        u_int seq;
1.1       misho      83: 
                     84:        FTRACE(3);
                     85: 
                     86:        rlen = bpfLEN;
                     87:        if (!(buf = malloc(rlen)))
                     88:                goto end;
1.2     ! misho      89:        else
        !            90:                memset(buf, 0, rlen);
1.1       misho      91: 
1.2     ! misho      92:        if ((ret = pktRecv(TASK_FD(task), &seq, &Crypted, buf, &rlen, &eth)) == ANSH_FLG_ERR)
1.1       misho      93:                goto end;
                     94:        VERB(5) LOG("Received %d bytes", rlen);
1.2     ! misho      95:        if (!(ret & ANSH_FLG_CPOUT))
        !            96:                goto end;
1.1       misho      97: 
                     98:        /* packet is ok find active session */
                     99:        SLIST_FOREACH(proc, &pH, proc_next)
                    100:                if (proc->proc_id == ntohs(eth.ether_type)) {
                    101:                        n = ANSH_CODE;
                    102:                        break;
                    103:                }
                    104:        /* not found in sessions, drop packet */
1.2     ! misho     105:        if (n != ANSH_CODE) {
        !           106:                proc = NULL;
1.1       misho     107:                goto end;
1.2     ! misho     108:        }
1.1       misho     109: 
                    110:        switch (ret) {
                    111:                case ANSH_FLG_EOF:
                    112:                case ANSH_FLG_CPOUT:
1.2     ! misho     113:                        if (seq <= proc->proc_seq)
        !           114:                                goto end;
        !           115:                        else if (seq > (proc->proc_seq + 1))
        !           116:                                LOG("LOST PACKET(s) detect: %d; received seq=%d - %d", 
        !           117:                                                seq - proc->proc_seq + 1, seq, proc->proc_seq);
        !           118:                        proc->proc_seq = seq;
1.1       misho     119:                        break;
                    120:                case ANSH_FLG_WINZ:
                    121:                        b = (u_short*) buf;
1.2     ! misho     122:                        ioChgWinPTY(proc->proc_pty, ntohs(b[0]), ntohs(b[1]), ntohs(b[2]), ntohs(b[3]));
1.1       misho     123:                        /* if not started login, lets start & go! */
                    124:                        if (!proc->proc_pid) {
1.2     ! misho     125:                                memcpy(&proc->proc_ea, &eth.ether_shost, ETHER_ADDR_LEN);
1.1       misho     126:                                spawnLogin(task, proc);
                    127:                        }
                    128:                default:
                    129:                        goto end;
                    130:        }
                    131: 
                    132:        proc->proc_flg = ret;
                    133:        proc->proc_rlen_[NET2FD] = rlen;
                    134:        memset(proc->proc_buf_[NET2FD], 0, proc->proc_blen);
                    135:        memcpy(proc->proc_buf_[NET2FD], buf, proc->proc_rlen_[NET2FD]);
                    136:        schedWrite(TASK_ROOT(task), fdTx, proc, proc->proc_pty);
                    137: end:
                    138:        free(buf);
                    139:        schedRead(TASK_ROOT(task), pktRx, NULL, proc ? proc->proc_sock : TASK_FD(task));
                    140:        return NULL;
                    141: }
                    142: 
                    143: void *
                    144: fdTx(sched_task_t *task)
                    145: {
                    146:        struct tagProc *proc;
1.2     ! misho     147:        struct timeval tv = { 0 };
1.1       misho     148:        int wlen;
                    149: 
                    150:        FTRACE(3);
                    151: 
                    152:        /* not found argument, drop data */
                    153:        if (!(proc = TASK_ARG(task)))
                    154:                return (void*) -1;
                    155: 
                    156:        /* if != ANSH_FLG_CPOUT isnt received from client */
1.2     ! misho     157:        if (proc->proc_flg != ANSH_FLG_CPOUT || !proc->proc_pid)
1.1       misho     158:                return NULL;
                    159: 
1.2     ! misho     160:        /* if Timeout defined, disarm timer */
        !           161:        if (Timeout)
        !           162:                schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL);
1.1       misho     163: 
                    164:        wlen = write(TASK_FD(task), proc->proc_buf_[NET2FD], proc->proc_rlen_[NET2FD]);
                    165:        switch (wlen) {
                    166:                case -1:
                    167:                        ERR("write2tty #%d - %s", errno, strerror(errno));
                    168:                        /* exit from shell and release tty */
                    169:                        return NULL;
                    170:                default:
                    171:                        proc->proc_flg = ANSH_FLG_OK;
                    172:                        proc->proc_rlen_[NET2FD] = 0;
                    173:        }
                    174:        VERB(3) LOG("Writed %d bytes - %s", wlen, proc->proc_buf_[NET2FD]);
                    175: 
1.2     ! misho     176:        /* if Timeout defined, go arm timer */
        !           177:        if (Timeout) {
        !           178:                tv.tv_sec = Timeout;
        !           179:                schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
        !           180:        }
1.1       misho     181:        return NULL;
                    182: }
                    183: 
                    184: void *
                    185: fdRx(sched_task_t *task)
                    186: {
                    187:        struct tagProc *proc;
1.2     ! misho     188:        struct timeval tv = { 0 };
1.1       misho     189:        int rlen;
                    190: 
                    191:        FTRACE(3);
                    192: 
                    193:        /* not found argument, drop data */
                    194:        if (!(proc = TASK_ARG(task)))
                    195:                return (void*) -1;
1.2     ! misho     196:        if (!proc->proc_pid)
        !           197:                return NULL;
1.1       misho     198: 
1.2     ! misho     199:        /* if Timeout defined, disarm timer */
        !           200:        if (Timeout)
        !           201:                schedCancelby(TASK_ROOT(task), &TASK_ROOT(task)->root_timer, CRITERIA_CALL, TOfunc, NULL);
1.1       misho     202: 
                    203:        memset(proc->proc_buf_[FD2NET], 0, proc->proc_blen);
1.2     ! misho     204:        rlen = read(TASK_FD(task), proc->proc_buf_[FD2NET], 
        !           205:                        proc->proc_blen - ETHER_HDR_LEN + sizeof(struct ansh_hdr));
1.1       misho     206:        switch (rlen) {
                    207:                case -1:
                    208:                        ERR("readtty #%d - %s", errno, strerror(errno));
                    209:                case 0:
                    210:                        /* exit from shell and release tty */
                    211:                        return NULL;
                    212:                default:
                    213:                        proc->proc_flg = ANSH_FLG_OK;
                    214:                        proc->proc_rlen_[FD2NET] = rlen;
                    215:        }
                    216:        VERB(3) LOG("Readed %d bytes - %s", rlen, proc->proc_buf_[FD2NET]);
                    217: 
1.2     ! misho     218:        schedCallOnce(TASK_ROOT(task), pktTx, proc, proc->proc_sock);
1.1       misho     219:        schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
1.2     ! misho     220: 
        !           221:        /* if Timeout defined, go arm timer */
        !           222:        if (Timeout) {
        !           223:                tv.tv_sec = Timeout;
        !           224:                schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
        !           225:        }
1.1       misho     226:        return NULL;
                    227: }
                    228: 
                    229: int
                    230: spawnLogin(sched_task_t *task, struct tagProc *proc)
                    231: {
1.2     ! misho     232:        int flg;
        !           233:        struct timeval tv = { 0 };
        !           234:        char str[STRSIZ] = { 0 };
        !           235: 
1.1       misho     236:        FTRACE(3);
                    237: 
                    238:        assert(proc);
                    239: 
                    240:        switch ((proc->proc_pid = ioForkPTY(&proc->proc_pty, proc->proc_ttyname, 
                    241:                                        sizeof proc->proc_ttyname, NULL, NULL, NULL))) {
                    242:                case -1:
                    243:                        ERR("ioForkPTY() #%d - %s", io_GetErrno(), io_GetError());
                    244:                        return -1;
                    245:                case 0:
1.2     ! misho     246:                        printf("anshd ELWIX remote management system (%s)\n\n", proc->proc_ttyname);
        !           247:                        strlcpy(str, "-hansh@", sizeof str);
        !           248:                        io_ether_ntoa((const struct io_ether_addr*) &proc->proc_ea, str + 7, 18);
        !           249: 
        !           250:                        execl("/usr/bin/login", "login", str, NULL);
1.1       misho     251:                        /* never reached */
                    252:                        return -1;
                    253:                default:
1.2     ! misho     254:                        flg = fcntl(proc->proc_pty, F_GETFL);
        !           255:                        fcntl(proc->proc_pty, F_SETFL, flg | O_NONBLOCK);
        !           256: 
        !           257:                        VERB(3) LOG("Parent know child pid %d", proc->proc_pid);
1.1       misho     258:                        schedRead(TASK_ROOT(task), fdRx, proc, proc->proc_pty);
1.2     ! misho     259: 
        !           260:                        /* if Timeout defined, go arm timer */
        !           261:                        if (Timeout) {
        !           262:                                tv.tv_sec = Timeout;
        !           263:                                schedTimer(TASK_ROOT(task), TOfunc, proc, tv);
        !           264:                        }
1.1       misho     265:                        break;
                    266:        }
                    267: 
                    268:        return 0;
                    269: }

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