注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BCB-DG's Blog

...

 
 
 

日志

 
 

mini telnetd  

2014-10-14 15:50:29|  分类: Socket |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
pty_fun.h
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <linux/limits.h>
    #include <features.h>
    #include <termios.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>

    #ifndef OPEN_PTY_ERR
    #define OPEN_PTY_ERR -1
    #endif

    #ifndef GRANT_PTY_ERR
    #define GRANT_PTY_ERR -2
    #endif

    #ifndef UNLOCK_PTY_ERR
    #define UNLOCK_PTY_ERR -3
    #endif

    #ifndef GET_PTYS_NAME_ERR
    #define GET_PTYS_NAME_ERR -4
    #endif

    #ifndef OPEN_PTYS_ERR
    #define OPEN_PTYS_ERR -5
    #endif

    #ifndef FORK_ERR
    #define FORK_ERR -6
    #endif

    #ifndef SETSID_ERR
    #define SETSID_ERR -7
    #endif

    #ifndef TIOCSCTTY_ERR
    #define TIOCSCTTY_ERR -8
    #endif

    #ifndef INIT_ATTR_ERR
    #define INIT_ATTR_ERR -9
    #endif

    #ifndef DUP_STDIN_ERR
    #define DUP_STDIN_ERR -10
    #endif

    #ifndef DUP_STDOUT_ERR
    #define DUP_STDOUT_ERR -11
    #endif

    #ifndef DUP_STDERR_ERR
    #define DUP_STDERR_ERR -12
    #endif

    int ptym_open(char *pts_name, int pts_namesz);
    int ptys_open(char *pts_name);
    int pty_fork(int *ptrfdm, char *slave_name, int slave_namesz,
            const struct termios *slave_termiors,
            const struct winsize *slave_winsize, pid_t *ppid);

pty_fun.cpp
    #include "pty_fun.h"

    int ptym_open(char *pts_name, int pts_namesz)
    {
        char *ptr;
        char fdm;
        strncpy(pts_name, "/dev/ptmx", pts_namesz);
        pts_name[pts_namesz - 1] = '\0';
        fdm = posix_openpt(O_RDWR);
        if (fdm < 0) return OPEN_PTY_ERR;
        if (grantpt(fdm) < 0)
        {
            close(fdm);
            return GRANT_PTY_ERR;
        }
        if (unlockpt(fdm) < 0)
        {
            close(fdm);
            return UNLOCK_PTY_ERR;
        }
        if ((ptr = ptsname(fdm)) == NULL)
        {
            close(fdm);
            return GET_PTYS_NAME_ERR;
        }
        strncpy(pts_name, ptr, pts_namesz);
        pts_name[pts_namesz - 1] = '\0';
        return fdm;
    }

    int ptys_open(char *pts_name)
    {
        int fds;
        if ((fds = open(pts_name, O_RDWR)) < 0) return OPEN_PTYS_ERR;
        return fds;
    }

    int pty_fork(int *ptrfdm, char *slave_name, int slave_namesz,
            const struct termios *slave_termiors,
            const struct winsize *slave_winsize, pid_t *ppid)
    {
        int fdm, fds;
        pid_t pid;
        char pts_name[20];

        if ((fdm = ptym_open(pts_name, sizeof(pts_name))) < 0) return fdm;

        if (slave_name != NULL)
        {
            strncpy(slave_name, pts_name, slave_namesz);
            slave_name[slave_namesz - 1] = '\0';
        }

        if ((pid = fork()) < 0) return FORK_ERR;

        if (pid == 0)
        {
            if (setsid() < 0)
                return SETSID_ERR;
            if ((fds = ptys_open(pts_name)) < 0)
            {
                close(fdm);
                return OPEN_PTYS_ERR;
            }
    #ifdef TIOCSCTTY
            if (ioctl(fds, TIOCSCTTY, (char *) 0) < 0) return TIOCSCTTY_ERR;
    #endif
            if (dup2(fds, STDIN_FILENO) != STDIN_FILENO) return DUP_STDIN_ERR;
            if (dup2(fds, STDOUT_FILENO) != STDOUT_FILENO) return DUP_STDOUT_ERR;
            if (dup2(fds, STDERR_FILENO) != STDERR_FILENO) return DUP_STDERR_ERR;
            if (fds != STDIN_FILENO && fds != STDOUT_FILENO && fds != STDERR_FILENO) close(fds);
            *ppid = 0;
            return 0;
        }
        else
        {
            *ptrfdm =fdm;
            *ppid = pid;
            return 0;
        }
    }

telnetserver.cpp
    #include <stdarg.h>
    #include <errno.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <string.h>
    #include <time.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <resolv.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <getopt.h>
    #include <pthread.h>
    #include "pty_fun.h"

    #define DEFAULTIP         "127.0.0.1"
    #define DEFAULTPORT       "20013"
    #define DEFAULTBACK       "10"
    #define DEFAULTDIR        "/root"
    #define DEFAULTLOG        "/tmp/telnet-server.log"
    #define PTY_NAME_SIZE     20
    #define MAX_BUFSIZE       512

    typedef struct thread_arg
    {
        int pty;
        int sockfd;
    } thread_arg;

    void prterrmsg(char *msg);
    #define prterrmsg(msg)        { perror(msg); abort(); }
    void wrterrmsg(char *msg);
    #define wrterrmsg(msg)        { fputs(msg, logfp); fputs(strerror(errno), logfp);fflush(logfp); abort(); }

    void prtinfomsg(char *msg);
    #define prtinfomsg(msg)        { fputs(msg, stdout);  }
    void wrtinfomsg(char *msg);
    #define wrtinfomsg(msg)        {  fputs(msg, logfp); fflush(logfp);}

    #define MAXBUF        1024
    #define MAXPATH        150

    char buffer[MAXBUF + 1];
    char *host = 0;
    char *port = 0;
    char *back = 0;
    char *dirroot = 0;
    char *logdir = 0;
    unsigned char daemon_y_n = 0;
    FILE *logfp;

    void AllocateMemory(char **s, int l, char *d)
    {
        *s = malloc(l + 1);
        bzero(*s, l + 1);
        memcpy(*s, d, l);
    }

    void getoption(int argc, char **argv)
    {
        int c, len;
        char *p = 0;
        opterr = 0;
        while (1)
        {
            int option_index = 0;
            static struct option long_options[] =
            {
            { "host", 1, 0, 0 },
            { "port", 1, 0, 0 },
            { "back", 1, 0, 0 },
            { "dir", 1, 0, 0 },
            { "log", 1, 0, 0 },
            { "daemon", 0, 0, 0 },
            { 0, 0, 0, 0 } };

            c = getopt_long(argc, argv, "H:P:B:D:L", long_options, &option_index);
            if (c == -1 || c == '?') break;

            if (optarg)
                len = strlen(optarg);
            else
                len = 0;

            if ((!c && !(strcasecmp(long_options[option_index].name, "host"))) || c == 'H')
                p = host = malloc(len + 1);
            else if ((!c && !(strcasecmp(long_options[option_index].name, "port"))) || c == 'P')
                p = port = malloc(len + 1);
            else if ((!c && !(strcasecmp(long_options[option_index].name, "back"))) || c == 'B')
                p = back = malloc(len + 1);
            else if ((!c && !(strcasecmp(long_options[option_index].name, "dir"))) || c == 'D')
                p = dirroot = malloc(len + 1);
            else if ((!c && !(strcasecmp(long_options[option_index].name, "log"))) || c == 'L')
                p = logdir = malloc(len + 1);
            else if ((!c && !(strcasecmp(long_options[option_index].name, "daemon"))))
            {
                daemon_y_n = 1;
                continue;
            }
            else
                break;
            bzero(p, len + 1);
            memcpy(p, optarg, len);
        }
    }

    void *thread_recv_add_write_pyt(void *arg)
    {
        int ret, sockfd, pty;
        char buffer[MAX_BUFSIZE];
        thread_arg *arg1 = (thread_arg*) arg;
        sockfd = arg1->sockfd;
        pty = arg1->pty;
        while (1)
        {
            memset(buffer, 0, MAX_BUFSIZE);
            ret = recv(sockfd, buffer, MAX_BUFSIZE, 0);
            if (ret < 0) continue;
            printf("%s", buffer);
            write(pty, buffer, strlen(buffer));
        }
    }

    void read_write_pty(int pty, int sockfd)
    {
        char buffer[MAX_BUFSIZE];
        int ret;
        pid_t pid;

        if ((pid = fork()) < 0)
        {
            perror("");
            exit(1);
        }
        else if (pid == 0)
        {
            while (1)
            {
                memset(buffer, 0, MAX_BUFSIZE);
                ret = recv(sockfd, buffer, MAX_BUFSIZE - 1, 0);
                if (ret < 0) continue;
                write(pty, buffer, strlen(buffer));
            }
        }
        memset(buffer, 0, MAX_BUFSIZE);
        while (ret = read(pty, buffer, MAX_BUFSIZE - 1))
        {
            if (ret <= 0) break;
            buffer[ret] = 0;
            fflush(stdout);
            printf("%s", buffer);
            send(sockfd, buffer, strlen(buffer), 0);
            memset(buffer, 0, MAX_BUFSIZE);
        }
    }

    int main(int argc, char **argv)
    {
        struct sockaddr_in addr;
        int sock_fd, addrlen;

        getoption(argc, argv);
        if (!host)
        {
            addrlen = strlen(DEFAULTIP);
            AllocateMemory(&host, addrlen, DEFAULTIP);
        }
        if (!port)
        {
            addrlen = strlen(DEFAULTPORT);
            AllocateMemory(&port, addrlen, DEFAULTPORT);
        }
        if (!back)
        {
            addrlen = strlen(DEFAULTBACK);
            AllocateMemory(&back, addrlen, DEFAULTBACK);
        }
        if (!dirroot)
        {
            addrlen = strlen(DEFAULTDIR);
            AllocateMemory(&dirroot, addrlen, DEFAULTDIR);
        }
        if (!logdir)
        {
            addrlen = strlen(DEFAULTLOG);
            AllocateMemory(&logdir, addrlen, DEFAULTLOG);
        }

        if (daemon_y_n)
        {
            if (fork()) exit(0);
            if (fork()) exit(0);
            close(0), close(1), close(2);
            logfp = fopen(logdir, "a+");
            if (!logfp) exit(0);
        }

        signal(SIGCHLD, SIG_IGN);
        if ((sock_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
        {
            if (!daemon_y_n)
                prterrmsg("socket()");
            else
                wrterrmsg("socket()");
        }
        addrlen = 1;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(atoi(port));
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
        addrlen = sizeof(struct sockaddr_in);
        setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &addrlen, sizeof(addrlen));
        if (bind(sock_fd, (struct sockaddr *) &addr, addrlen) < 0)
        {
            if (!daemon_y_n)
                prterrmsg("bind()");
            else
                wrterrmsg("bind()");
        }
        if (listen(sock_fd, atoi(back)) < 0)
        {
            if (!daemon_y_n)
                prterrmsg("listen()");
            else
                wrterrmsg("listen()");
        }

        printf("host=%s port=%s back=%s dirroot=%s logdir=%s %s daemon(PID:%d)\n",
                host, port, back, dirroot, logdir, daemon_y_n ? "" : "no", getpid());

        while (1)
        {
            int new_fd;
            addrlen = sizeof(struct sockaddr_in);
            new_fd = accept(sock_fd, (struct sockaddr *) &addr, &addrlen);
            if (new_fd < 0)
            {
                if (!daemon_y_n)
                    prterrmsg("accept()");
                else
                    wrterrmsg("accept()");
                break;
            }
            bzero(buffer, MAXBUF + 1);
            sprintf(buffer, "connected: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
            if (!daemon_y_n)
                prtinfomsg(buffer);
            else
                wrtinfomsg(buffer);
            if (!fork())
            {
                int ret, ptrfdm;
                char slave_name[PTY_NAME_SIZE];
                struct termios slave_termiors;
                struct winsize slave_winsize;
                pid_t ppid;

                ret = -1;
                ptrfdm = -1;
                memset(slave_name, 0, PTY_NAME_SIZE);
                ppid = -1;

                ret = pty_fork(&ptrfdm, slave_name, PTY_NAME_SIZE, &slave_termiors, &slave_winsize, &ppid);
                if (ret < 0)
                {
                    printf("pty_fork err ! ret = %d", ret);
                    return -1;
                }
                if (ppid < 0)
                {
                    printf("pty_fork err !");
                    return -1;
                }
                else if (ppid == 0)
                    execl("/bin/bash", "bash", NULL);
                else
                    read_write_pty(ptrfdm, new_fd);
            }
            close(new_fd);
        }
        close(sock_fd);
        return 0;
    }
  评论这张
 
阅读(548)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017