Windows PSCP now links against winsftp.c, and scp.c is now a
[u/mdw/putty] / unix / uxsftp.c
CommitLineData
b51259f6 1/*\r
799dfcfa 2 * uxsftp.c: the Unix-specific parts of PSFTP and PSCP.\r
b51259f6 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
b51259f6 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
17int uxsel_input_add(int fd, int rwx) { return 0; }\r
18void uxsel_input_remove(int id) { }\r
19\r
20char *x_get_default(const char *key)\r
21{\r
22 return NULL; /* this is a stub */\r
23}\r
24\r
25void 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
34char *platform_default_s(const char *name)\r
35{\r
b51259f6 36 return NULL;\r
37}\r
38\r
39int platform_default_i(const char *name, int def)\r
40{\r
41 return def;\r
42}\r
43\r
44FontSpec 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
51Filename 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
799dfcfa 62 * Stubs for the GUI feedback mechanism in Windows PSCP.\r
63 */\r
64void 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
68void gui_send_errcount(int list, int errs) {}\r
69void gui_send_char(int is_stderr, int c) {}\r
70void gui_enable(char *arg) {}\r
71\r
72\r
73/*\r
b51259f6 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
77char *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
89char *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
115int 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
192int main(int argc, char *argv[])\r
193{\r
194 uxsel_init();\r
195 return psftp_main(argc, argv);\r
196}\r