]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - unix/uxsftp.c
d1989f83d822656a6c08090391bb44f8e43e003e
[PuTTY.git] / unix / uxsftp.c
1 /*\r
2  * uxsftp.c: the Unix-specific parts of PSFTP and PSCP.\r
3  */\r
4 \r
5 #include <sys/time.h>\r
6 #include <sys/types.h>\r
7 #include <unistd.h>\r
8 #include <errno.h>\r
9 \r
10 #include "putty.h"\r
11 #include "psftp.h"\r
12 \r
13 /*\r
14  * In PSFTP our selects are synchronous, so these functions are\r
15  * empty stubs.\r
16  */\r
17 int uxsel_input_add(int fd, int rwx) { return 0; }\r
18 void uxsel_input_remove(int id) { }\r
19 \r
20 char *x_get_default(const char *key)\r
21 {\r
22     return NULL;                       /* this is a stub */\r
23 }\r
24 \r
25 void platform_get_x11_auth(char *display, int *protocol,\r
26                            unsigned char *data, int *datalen)\r
27 {\r
28     /* Do nothing, therefore no auth. */\r
29 }\r
30 \r
31 /*\r
32  * Default settings that are specific to PSFTP.\r
33  */\r
34 char *platform_default_s(const char *name)\r
35 {\r
36     return NULL;\r
37 }\r
38 \r
39 int platform_default_i(const char *name, int def)\r
40 {\r
41     return def;\r
42 }\r
43 \r
44 FontSpec platform_default_fontspec(const char *name)\r
45 {\r
46     FontSpec ret;\r
47     *ret.name = '\0';\r
48     return ret;\r
49 }\r
50 \r
51 Filename platform_default_filename(const char *name)\r
52 {\r
53     Filename ret;\r
54     if (!strcmp(name, "LogFileName"))\r
55         strcpy(ret.path, "putty.log");\r
56     else\r
57         *ret.path = '\0';\r
58     return ret;\r
59 }\r
60 \r
61 /*\r
62  * Stubs for the GUI feedback mechanism in Windows PSCP.\r
63  */\r
64 void gui_update_stats(char *name, unsigned long size,\r
65                       int percentage, unsigned long elapsed,\r
66                       unsigned long done, unsigned long eta,\r
67                       unsigned long ratebs) {}\r
68 void gui_send_errcount(int list, int errs) {}\r
69 void gui_send_char(int is_stderr, int c) {}\r
70 void gui_enable(char *arg) {}\r
71 \r
72 \r
73 /*\r
74  * Set local current directory. Returns NULL on success, or else an\r
75  * error message which must be freed after printing.\r
76  */\r
77 char *psftp_lcd(char *dir)\r
78 {\r
79     if (chdir(dir) < 0)\r
80         return dupprintf("%s: chdir: %s", dir, strerror(errno));\r
81     else\r
82         return NULL;\r
83 }\r
84 \r
85 /*\r
86  * Get local current directory. Returns a string which must be\r
87  * freed.\r
88  */\r
89 char *psftp_getcwd(void)\r
90 {\r
91     char *buffer, *ret;\r
92     int size = 256;\r
93 \r
94     buffer = snewn(size, char);\r
95     while (1) {\r
96         ret = getcwd(buffer, size);\r
97         if (ret != NULL)\r
98             return ret;\r
99         if (errno != ERANGE) {\r
100             sfree(buffer);\r
101             return dupprintf("[cwd unavailable: %s]", strerror(errno));\r
102         }\r
103         /*\r
104          * Otherwise, ERANGE was returned, meaning the buffer\r
105          * wasn't big enough.\r
106          */\r
107         size = size * 3 / 2;\r
108         buffer = sresize(buffer, size, char);\r
109     }\r
110 }\r
111 \r
112 /*\r
113  * Wait for some network data and process it.\r
114  */\r
115 int ssh_sftp_loop_iteration(void)\r
116 {\r
117     fd_set rset, wset, xset;\r
118     int i, fdcount, fdsize, *fdlist;\r
119     int fd, fdstate, rwx, ret, maxfd;\r
120 \r
121     fdlist = NULL;\r
122     fdcount = fdsize = 0;\r
123 \r
124     /* Count the currently active fds. */\r
125     i = 0;\r
126     for (fd = first_fd(&fdstate, &rwx); fd >= 0;\r
127          fd = next_fd(&fdstate, &rwx)) i++;\r
128 \r
129     if (i < 1)\r
130         return -1;                     /* doom */\r
131 \r
132     /* Expand the fdlist buffer if necessary. */\r
133     if (i > fdsize) {\r
134         fdsize = i + 16;\r
135         fdlist = sresize(fdlist, fdsize, int);\r
136     }\r
137 \r
138     FD_ZERO(&rset);\r
139     FD_ZERO(&wset);\r
140     FD_ZERO(&xset);\r
141     maxfd = 0;\r
142 \r
143     /*\r
144      * Add all currently open fds to the select sets, and store\r
145      * them in fdlist as well.\r
146      */\r
147     fdcount = 0;\r
148     for (fd = first_fd(&fdstate, &rwx); fd >= 0;\r
149          fd = next_fd(&fdstate, &rwx)) {\r
150         fdlist[fdcount++] = fd;\r
151         if (rwx & 1)\r
152             FD_SET_MAX(fd, maxfd, rset);\r
153         if (rwx & 2)\r
154             FD_SET_MAX(fd, maxfd, wset);\r
155         if (rwx & 4)\r
156             FD_SET_MAX(fd, maxfd, xset);\r
157     }\r
158 \r
159     do {\r
160         ret = select(maxfd, &rset, &wset, &xset, NULL);\r
161     } while (ret < 0 && errno == EINTR);\r
162 \r
163     if (ret < 0) {\r
164         perror("select");\r
165         exit(1);\r
166     }\r
167 \r
168     for (i = 0; i < fdcount; i++) {\r
169         fd = fdlist[i];\r
170         /*\r
171          * We must process exceptional notifications before\r
172          * ordinary readability ones, or we may go straight\r
173          * past the urgent marker.\r
174          */\r
175         if (FD_ISSET(fd, &xset))\r
176             select_result(fd, 4);\r
177         if (FD_ISSET(fd, &rset))\r
178             select_result(fd, 1);\r
179         if (FD_ISSET(fd, &wset))\r
180             select_result(fd, 2);\r
181     }\r
182 \r
183     sfree(fdlist);\r
184 \r
185     return 0;\r
186 }\r
187 \r
188 /*\r
189  * Main program: do platform-specific initialisation and then call\r
190  * psftp_main().\r
191  */\r
192 int main(int argc, char *argv[])\r
193 {\r
194     uxsel_init();\r
195     return psftp_main(argc, argv);\r
196 }\r