Annotation of ansh/src/daemon3.c, revision 1.1

1.1     ! misho       1: /*************************************************************************
        !             2:  * (C) 2011 AITNET - Sofia/Bulgaria - <office@aitnet.org>
        !             3:  *  by Michael Pounov <misho@elwix.org>
        !             4:  *
        !             5:  * $Author: misho $
        !             6:  * $Id: global.h,v 1.2 2011/06/08 12:45:40 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>