Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/util.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3227 - (show annotations) (download) (as text)
Tue Mar 24 15:10:33 2009 UTC (15 years, 1 month ago) by maya
File MIME type: text/x-csrc
File size: 7522 byte(s)
CVS から SVN へ移行: 改行コードを LF から CR+LF へ変換
1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 Redistributions of source code must retain the above copyright notice, this list of
9 conditions and the following disclaimer.
10
11 Redistributions in binary form must reproduce the above copyright notice, this list
12 of conditions and the following disclaimer in the documentation and/or other materials
13 provided with the distribution.
14
15 The name of Robert O'Callahan may not be used to endorse or promote products derived from
16 this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 This code is copyright (C) 1998-1999 Robert O'Callahan.
31 See LICENSE.TXT for the license.
32 */
33
34 #include "ttxssh.h"
35
36 void UTIL_init_sock_write_buf(UTILSockWriteBuf FAR * buf)
37 {
38 buf_create(&buf->bufdata, &buf->buflen);
39 buf->datastart = 0;
40 buf->datalen = 0;
41 }
42
43 static int send_until_block(PTInstVar pvar, SOCKET s,
44 const char FAR * data, int len)
45 {
46 int total_sent = 0;
47
48 while (len > 0) {
49 int sent_amount = (pvar->Psend) (s, data, len, 0);
50
51 if (sent_amount < 0) {
52 if (WSAGetLastError() == WSAEWOULDBLOCK) {
53 return total_sent;
54 } else {
55 return sent_amount;
56 }
57 } else {
58 total_sent += sent_amount;
59 data += sent_amount;
60 len -= sent_amount;
61 }
62 }
63
64 return total_sent;
65 }
66
67 BOOL UTIL_sock_buffered_write(PTInstVar pvar, UTILSockWriteBuf FAR * buf,
68 UTILBlockingWriteCallback blocking_write,
69 SOCKET socket, const char FAR * data,
70 int len)
71 {
72 int curlen;
73 int desiredlen;
74 int space_required;
75 int amount_to_write_from_buffer;
76 BOOL did_block = FALSE;
77 int first_copy_start;
78 int first_copy_amount;
79
80 /* Fast path case: buffer is empty, try nonblocking write */
81 if (buf->datalen == 0) {
82 #if 0
83 int sent_amount = send_until_block(pvar, socket, data, len);
84
85 if (sent_amount < 0) {
86 return FALSE;
87 }
88 data += sent_amount;
89 len -= sent_amount;
90 #else
91 // �m���u���b�L���O���[�h�������������������A���~���������������A�o�O�����������A
92 // �����������������B�������A�������u���b�L���O���[�h���g���A�m�������M�����������B
93 // �|�[�g�]��(local-to-remote)���������A�������p�P�b�g�����M���������������������B
94 // (2007.11.29 yutaka)
95 if (!blocking_write(pvar, socket, data, len)) {
96 return FALSE;
97 } else {
98 len = 0;
99 }
100 #endif
101 }
102
103 if (len == 0) {
104 return TRUE;
105 }
106
107 /* We blocked or the buffer has data in it. We need to put this data
108 into the buffer.
109 First, expand buffer as much as possible and necessary. */
110 curlen = buf->buflen;
111 desiredlen =
112 min(pvar->session_settings.WriteBufferSize, buf->datalen + len);
113
114 if (curlen < desiredlen) {
115 int wrap_amount = buf->datastart + buf->datalen - curlen;
116 int newlen =
117 min(pvar->session_settings.WriteBufferSize, 2 * desiredlen);
118
119 buf->bufdata = realloc(buf->bufdata, newlen);
120 buf->buflen = newlen;
121
122 if (wrap_amount > 0) {
123 int wrap_to_copy = min(wrap_amount, newlen - curlen);
124
125 memmove(buf->bufdata + curlen, buf->bufdata, wrap_to_copy);
126 memmove(buf->bufdata, buf->bufdata + wrap_to_copy,
127 wrap_amount - wrap_to_copy);
128 }
129 }
130
131 /* 1) Write data from buffer
132 2) Write data from user
133 3) Copy remaining user data into buffer
134 */
135 space_required = max(0, buf->datalen + len - buf->buflen);
136 amount_to_write_from_buffer = min(buf->datalen, space_required);
137
138 if (amount_to_write_from_buffer > 0) {
139 int first_part =
140 min(amount_to_write_from_buffer, buf->buflen - buf->datastart);
141
142 did_block = TRUE;
143 if (!blocking_write
144 (pvar, socket, buf->bufdata + buf->datastart, first_part)) {
145 return FALSE;
146 }
147 if (first_part < amount_to_write_from_buffer) {
148 if (!blocking_write
149 (pvar, socket, buf->bufdata,
150 amount_to_write_from_buffer - first_part)) {
151 return FALSE;
152 }
153 }
154
155 buf->datalen -= amount_to_write_from_buffer;
156 if (buf->datalen == 0) {
157 buf->datastart = 0;
158 } else {
159 buf->datastart =
160 (buf->datastart +
161 amount_to_write_from_buffer) % buf->buflen;
162 }
163 space_required -= amount_to_write_from_buffer;
164 }
165
166 if (space_required > 0) {
167 did_block = TRUE;
168 if (!blocking_write(pvar, socket, data, space_required)) {
169 return FALSE;
170 }
171 data += space_required;
172 len -= space_required;
173 }
174
175 first_copy_start = (buf->datastart + buf->datalen) % buf->buflen;
176 first_copy_amount = min(len, buf->buflen - first_copy_start);
177 memcpy(buf->bufdata + first_copy_start, data, first_copy_amount);
178 if (first_copy_amount < len) {
179 memcpy(buf->bufdata, data + first_copy_amount,
180 len - first_copy_amount);
181 }
182 buf->datalen += len;
183
184 if (did_block) {
185 return UTIL_sock_write_more(pvar, buf, socket);
186 } else {
187 return TRUE;
188 }
189 }
190
191 BOOL UTIL_sock_write_more(PTInstVar pvar, UTILSockWriteBuf FAR * buf,
192 SOCKET socket)
193 {
194 int first_amount = min(buf->buflen - buf->datastart, buf->datalen);
195 int sent =
196 send_until_block(pvar, socket, buf->bufdata + buf->datastart,
197 first_amount);
198
199 if (sent < 0) {
200 return FALSE;
201 } else {
202 if (sent == first_amount && first_amount < buf->datalen) {
203 int sentmore =
204 send_until_block(pvar, socket, buf->bufdata,
205 buf->datalen - first_amount);
206
207 if (sentmore < 0) {
208 return FALSE;
209 }
210 sent += sentmore;
211 }
212
213 buf->datalen -= sent;
214 if (buf->datalen == 0) {
215 buf->datastart = 0;
216 } else {
217 buf->datastart = (buf->datastart + sent) % buf->buflen;
218 }
219 }
220
221 return TRUE;
222 }
223
224 void UTIL_destroy_sock_write_buf(UTILSockWriteBuf FAR * buf)
225 {
226 memset(buf->bufdata, 0, buf->buflen);
227 buf_destroy(&buf->bufdata, &buf->buflen);
228 }
229
230 BOOL UTIL_is_sock_deeply_buffered(UTILSockWriteBuf FAR * buf)
231 {
232 return buf->buflen / 2 < buf->datalen;
233 }
234
235 void UTIL_get_lang_msg(PCHAR key, PTInstVar pvar, PCHAR def)
236 {
237 GetI18nStr("TTSSH", key, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg),
238 def, pvar->ts->UILanguageFile);
239 }
240
241 int UTIL_get_lang_font(PCHAR key, HWND dlg, PLOGFONT logfont, HFONT *font, PTInstVar pvar)
242 {
243 if (GetI18nLogfont("TTSSH", key, logfont,
244 GetDeviceCaps(GetDC(dlg),LOGPIXELSY),
245 pvar->ts->UILanguageFile) == FALSE) {
246 return FALSE;
247 }
248
249 if ((*font = CreateFontIndirect(logfont)) == NULL) {
250 return FALSE;
251 }
252
253 return TRUE;
254 }
255
256 BOOL is_NT4()
257 {
258 OSVERSIONINFO osvi;
259
260 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
261 GetVersionEx(&osvi);
262 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
263 osvi.dwMajorVersion == 4) {
264 return TRUE;
265 }
266 return FALSE;
267 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26