Annotation of ansh/src/daemon3.c, revision 1.1.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>