OSDN Git Service

Add VC++ Project files for PuTTY DLL without exported functions.
[ffftp/ffftp.git] / putty / CONTRIB / CYGTERMD / MAIN.C
1 /*\r
2  * Main program.\r
3  */\r
4 \r
5 #include <stdio.h>\r
6 #include <stdlib.h>\r
7 #include <stddef.h>\r
8 #include <stdarg.h>\r
9 #include <signal.h>\r
10 #include <string.h>\r
11 #include <errno.h>\r
12 \r
13 #include <unistd.h>\r
14 #include <sys/types.h>\r
15 #include <sys/wait.h>\r
16 \r
17 #include "sel.h"\r
18 #include "pty.h"\r
19 #include "telnet.h"\r
20 \r
21 int signalpipe[2];\r
22 \r
23 sel *asel;\r
24 sel_rfd *netr, *ptyr, *sigr;\r
25 int ptyfd;\r
26 sel_wfd *netw, *ptyw;\r
27 Telnet telnet;\r
28 \r
29 #define BUF 65536\r
30 \r
31 void sigchld(int signum)\r
32 {\r
33     write(signalpipe[1], "C", 1);\r
34 }\r
35 \r
36 void fatal(const char *fmt, ...)\r
37 {\r
38     va_list ap;\r
39     fprintf(stderr, "FIXME: ");\r
40     va_start(ap, fmt);\r
41     vfprintf(stderr, fmt, ap);\r
42     va_end(ap);\r
43     fprintf(stderr, "\n");\r
44     exit(1);\r
45 }\r
46 \r
47 void net_readdata(sel_rfd *rfd, void *data, size_t len)\r
48 {\r
49     if (len == 0)\r
50         exit(0);                       /* EOF on network - client went away */\r
51     telnet_from_net(telnet, data, len);\r
52     if (sel_write(netw, NULL, 0) > BUF)\r
53         sel_rfd_freeze(ptyr);\r
54     if (sel_write(ptyw, NULL, 0) > BUF)\r
55         sel_rfd_freeze(netr);\r
56 }\r
57 \r
58 void net_readerr(sel_rfd *rfd, int error)\r
59 {\r
60     fprintf(stderr, "standard input: read: %s\n", strerror(errno));\r
61     exit(1);\r
62 }\r
63 \r
64 void net_written(sel_wfd *wfd, size_t bufsize)\r
65 {\r
66     if (bufsize < BUF)\r
67         sel_rfd_unfreeze(ptyr);\r
68 }\r
69 \r
70 void net_writeerr(sel_wfd *wfd, int error)\r
71 {\r
72     fprintf(stderr, "standard input: write: %s\n", strerror(errno));\r
73     exit(1);\r
74 }\r
75 \r
76 void pty_readdata(sel_rfd *rfd, void *data, size_t len)\r
77 {\r
78     if (len == 0)\r
79         exit(0);                       /* EOF on pty */\r
80     telnet_from_pty(telnet, data, len);\r
81     if (sel_write(netw, NULL, 0) > BUF)\r
82         sel_rfd_freeze(ptyr);\r
83     if (sel_write(ptyw, NULL, 0) > BUF)\r
84         sel_rfd_freeze(netr);\r
85 }\r
86 \r
87 void pty_readerr(sel_rfd *rfd, int error)\r
88 {\r
89     if (error == EIO)                  /* means EOF, on a pty */\r
90         exit(0);\r
91     fprintf(stderr, "pty: read: %s\n", strerror(errno));\r
92     exit(1);\r
93 }\r
94 \r
95 void pty_written(sel_wfd *wfd, size_t bufsize)\r
96 {\r
97     if (bufsize < BUF)\r
98         sel_rfd_unfreeze(netr);\r
99 }\r
100 \r
101 void pty_writeerr(sel_wfd *wfd, int error)\r
102 {\r
103     fprintf(stderr, "pty: write: %s\n", strerror(errno));\r
104     exit(1);\r
105 }\r
106 \r
107 void sig_readdata(sel_rfd *rfd, void *data, size_t len)\r
108 {\r
109     char *p = data;\r
110 \r
111     while (len > 0) {\r
112         if (*p == 'C') {\r
113             int status;\r
114             pid_t pid = waitpid(-1, &status, WNOHANG);\r
115             if (WIFEXITED(status) || WIFSIGNALED(status))\r
116                 exit(0);               /* child process vanished */\r
117         }\r
118     }\r
119 }\r
120 \r
121 void sig_readerr(sel_rfd *rfd, int error)\r
122 {\r
123     fprintf(stderr, "signal pipe: read: %s\n", strerror(errno));\r
124     exit(1);\r
125 }\r
126 \r
127 int main(int argc, char **argv)\r
128 {\r
129     int ret;\r
130     int shell_started = 0;\r
131     char *directory = NULL;\r
132     char **program_args = NULL;\r
133 \r
134     if (argc > 1 && argv[1][0]) {\r
135         directory = argv[1];\r
136         argc--, argv++;\r
137     }\r
138     if (argc > 1) {\r
139         program_args = argv + 1;\r
140     }\r
141 \r
142     pty_preinit();\r
143 \r
144     asel = sel_new(NULL);\r
145     netr = sel_rfd_add(asel, 0, net_readdata, net_readerr, NULL);\r
146     netw = sel_wfd_add(asel, 1, net_written, net_writeerr, NULL);\r
147     ptyr = sel_rfd_add(asel, -1, pty_readdata, pty_readerr, NULL);\r
148     ptyw = sel_wfd_add(asel, -1, pty_written, pty_writeerr, NULL);\r
149 \r
150     telnet = telnet_new(netw, ptyw);\r
151 \r
152     if (pipe(signalpipe) < 0) {\r
153         perror("pipe");\r
154         return 1;\r
155     }\r
156     sigr = sel_rfd_add(asel, signalpipe[0], sig_readdata,\r
157                        sig_readerr, NULL);\r
158 \r
159     signal(SIGCHLD, sigchld);\r
160 \r
161     do {\r
162         struct shell_data shdata;\r
163 \r
164         ret = sel_iterate(asel, -1);\r
165         if (!shell_started && telnet_shell_ok(telnet, &shdata)) {\r
166             ptyfd = run_program_in_pty(&shdata, directory, program_args);\r
167             sel_rfd_setfd(ptyr, ptyfd);\r
168             sel_wfd_setfd(ptyw, ptyfd);\r
169             shell_started = 1;\r
170         }\r
171     } while (ret == 0);\r
172 \r
173     return 0;\r
174 }\r