2 * Platform-independent routines shared between all PuTTY programs.
14 * Parse a string block size specification. This is approximately a
15 * subset of the block size specs supported by GNU fileutils:
19 * All numbers are decimal, and suffixes refer to powers of two.
22 unsigned long parse_blocksize(const char *bs
)
25 unsigned long r
= strtoul(bs
, &suf
, 10);
27 while (*suf
&& isspace((unsigned char)*suf
)) suf
++;
36 r
*= 1024ul * 1024ul * 1024ul;
46 /* ----------------------------------------------------------------------
47 * String handling routines.
50 char *dupstr(const char *s
)
55 p
= snewn(len
+ 1, char);
61 /* Allocate the concatenation of N strings. Terminate arg list with NULL. */
62 char *dupcat(const char *s1
, ...)
71 sn
= va_arg(ap
, char *);
78 p
= snewn(len
+ 1, char);
84 sn
= va_arg(ap
, char *);
96 * Do an sprintf(), but into a custom-allocated buffer.
98 * Currently I'm doing this via vsnprintf. This has worked so far,
99 * but it's not good, because:
101 * - vsnprintf is not available on all platforms. There's an ifdef
102 * to use `_vsnprintf', which seems to be the local name for it
103 * on Windows. Other platforms may lack it completely, in which
104 * case it'll be time to rewrite this function in a totally
107 * - technically you can't reuse a va_list like this: it is left
108 * unspecified whether advancing a va_list pointer modifies its
109 * value or something it points to, so on some platforms calling
110 * vsnprintf twice on the same va_list might fail hideously. It
111 * would be better to use the `va_copy' macro mandated by C99,
112 * but that too is not yet ubiquitous.
114 * The only `properly' portable solution I can think of is to
115 * implement my own format string scanner, which figures out an
116 * upper bound for the length of each formatting directive,
117 * allocates the buffer as it goes along, and calls sprintf() to
118 * actually process each directive. If I ever need to actually do
119 * this, some caveats:
121 * - It's very hard to find a reliable upper bound for
122 * floating-point values. %f, in particular, when supplied with
123 * a number near to the upper or lower limit of representable
124 * numbers, could easily take several hundred characters. It's
125 * probably feasible to predict this statically using the
126 * constants in <float.h>, or even to predict it dynamically by
127 * looking at the exponent of the specific float provided, but
130 * - Don't forget to _check_, after calling sprintf, that it's
131 * used at most the amount of space we had available.
133 * - Fault any formatting directive we don't fully understand. The
134 * aim here is to _guarantee_ that we never overflow the buffer,
135 * because this is a security-critical function. If we see a
136 * directive we don't know about, we should panic and die rather
139 char *dupprintf(const char *fmt
, ...)
144 ret
= dupvprintf(fmt
, ap
);
148 char *dupvprintf(const char *fmt
, va_list ap
)
153 buf
= snewn(512, char);
158 #define vsnprintf _vsnprintf
160 len
= vsnprintf(buf
, size
, fmt
, ap
);
161 if (len
>= 0 && len
< size
) {
162 /* This is the C99-specified criterion for snprintf to have
163 * been completely successful. */
165 } else if (len
> 0) {
166 /* This is the C99 error condition: the returned length is
167 * the required buffer size not counting the NUL. */
170 /* This is the pre-C99 glibc error condition: <0 means the
171 * buffer wasn't big enough, so we enlarge it a bit and hope. */
174 buf
= sresize(buf
, size
, char);
179 * Read an entire line of text from a file. Return a buffer
180 * malloced to be as big as necessary (caller must free).
182 char *fgetline(FILE *fp
)
184 char *ret
= snewn(512, char);
185 int size
= 512, len
= 0;
186 while (fgets(ret
+ len
, size
- len
, fp
)) {
187 len
+= strlen(ret
+ len
);
188 if (ret
[len
-1] == '\n')
189 break; /* got a newline, we're done */
191 ret
= sresize(ret
, size
, char);
193 if (len
== 0) { /* first fgets returned NULL */
201 /* ----------------------------------------------------------------------
202 * Base64 encoding routine. This is required in public-key writing
203 * but also in HTTP proxy handling, so it's centralised here.
206 void base64_encode_atom(unsigned char *data
, int n
, char *out
)
208 static const char base64_chars
[] =
209 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
213 word
= data
[0] << 16;
215 word
|= data
[1] << 8;
218 out
[0] = base64_chars
[(word
>> 18) & 0x3F];
219 out
[1] = base64_chars
[(word
>> 12) & 0x3F];
221 out
[2] = base64_chars
[(word
>> 6) & 0x3F];
225 out
[3] = base64_chars
[word
& 0x3F];
230 /* ----------------------------------------------------------------------
231 * Generic routines to deal with send buffers: a linked list of
232 * smallish blocks, with the operations
234 * - add an arbitrary amount of data to the end of the list
235 * - remove the first N bytes from the list
236 * - return a (pointer,length) pair giving some initial data in
237 * the list, suitable for passing to a send or write system
239 * - retrieve a larger amount of initial data from the list
240 * - return the current size of the buffer chain in bytes
243 #define BUFFER_GRANULE 512
245 struct bufchain_granule
{
246 struct bufchain_granule
*next
;
248 char buf
[BUFFER_GRANULE
];
251 void bufchain_init(bufchain
*ch
)
253 ch
->head
= ch
->tail
= NULL
;
257 void bufchain_clear(bufchain
*ch
)
259 struct bufchain_granule
*b
;
262 ch
->head
= ch
->head
->next
;
269 int bufchain_size(bufchain
*ch
)
271 return ch
->buffersize
;
274 void bufchain_add(bufchain
*ch
, const void *data
, int len
)
276 const char *buf
= (const char *)data
;
278 if (len
== 0) return;
280 ch
->buffersize
+= len
;
282 if (ch
->tail
&& ch
->tail
->buflen
< BUFFER_GRANULE
) {
283 int copylen
= min(len
, BUFFER_GRANULE
- ch
->tail
->buflen
);
284 memcpy(ch
->tail
->buf
+ ch
->tail
->buflen
, buf
, copylen
);
287 ch
->tail
->buflen
+= copylen
;
290 int grainlen
= min(len
, BUFFER_GRANULE
);
291 struct bufchain_granule
*newbuf
;
292 newbuf
= snew(struct bufchain_granule
);
294 newbuf
->buflen
= grainlen
;
295 memcpy(newbuf
->buf
, buf
, grainlen
);
299 ch
->tail
->next
= newbuf
;
301 ch
->head
= ch
->tail
= newbuf
;
307 void bufchain_consume(bufchain
*ch
, int len
)
309 struct bufchain_granule
*tmp
;
311 assert(ch
->buffersize
>= len
);
314 assert(ch
->head
!= NULL
);
315 if (remlen
>= ch
->head
->buflen
- ch
->head
->bufpos
) {
316 remlen
= ch
->head
->buflen
- ch
->head
->bufpos
;
318 ch
->head
= tmp
->next
;
323 ch
->head
->bufpos
+= remlen
;
324 ch
->buffersize
-= remlen
;
329 void bufchain_prefix(bufchain
*ch
, void **data
, int *len
)
331 *len
= ch
->head
->buflen
- ch
->head
->bufpos
;
332 *data
= ch
->head
->buf
+ ch
->head
->bufpos
;
335 void bufchain_fetch(bufchain
*ch
, void *data
, int len
)
337 struct bufchain_granule
*tmp
;
338 char *data_c
= (char *)data
;
342 assert(ch
->buffersize
>= len
);
347 if (remlen
>= tmp
->buflen
- tmp
->bufpos
)
348 remlen
= tmp
->buflen
- tmp
->bufpos
;
349 memcpy(data_c
, tmp
->buf
+ tmp
->bufpos
, remlen
);
357 /* ----------------------------------------------------------------------
358 * My own versions of malloc, realloc and free. Because I want
359 * malloc and realloc to bomb out and exit the program if they run
360 * out of memory, realloc to reliably call malloc if passed a NULL
361 * pointer, and free to reliably do nothing if passed a NULL
362 * pointer. We can also put trace printouts in, if we need to; and
363 * we can also replace the allocator with an ElectricFence-like
368 void *minefield_c_malloc(size_t size
);
369 void minefield_c_free(void *p
);
370 void *minefield_c_realloc(void *p
, size_t size
);
374 static FILE *fp
= NULL
;
376 static char *mlog_file
= NULL
;
377 static int mlog_line
= 0;
379 void mlog(char *file
, int line
)
384 fp
= fopen("putty_mem.log", "w");
385 setvbuf(fp
, NULL
, _IONBF
, BUFSIZ
);
388 fprintf(fp
, "%s:%d: ", file
, line
);
392 void *safemalloc(size_t n
, size_t size
)
396 if (n
> INT_MAX
/ size
) {
401 p
= minefield_c_malloc(size
);
410 sprintf(str
, "Out of memory! (%s:%d, size=%d)",
411 mlog_file
, mlog_line
, size
);
412 fprintf(fp
, "*** %s\n", str
);
415 strcpy(str
, "Out of memory!");
421 fprintf(fp
, "malloc(%d) returns %p\n", size
, p
);
426 void *saferealloc(void *ptr
, size_t n
, size_t size
)
430 if (n
> INT_MAX
/ size
) {
436 p
= minefield_c_malloc(size
);
442 p
= minefield_c_realloc(ptr
, size
);
444 p
= realloc(ptr
, size
);
452 sprintf(str
, "Out of memory! (%s:%d, size=%d)",
453 mlog_file
, mlog_line
, size
);
454 fprintf(fp
, "*** %s\n", str
);
457 strcpy(str
, "Out of memory!");
463 fprintf(fp
, "realloc(%p,%d) returns %p\n", ptr
, size
, p
);
468 void safefree(void *ptr
)
473 fprintf(fp
, "free(%p)\n", ptr
);
476 minefield_c_free(ptr
);
483 fprintf(fp
, "freeing null pointer - no action taken\n");
487 /* ----------------------------------------------------------------------
488 * Debugging routines.
492 extern void dputs(char *); /* defined in per-platform *misc.c */
494 void debug_printf(char *fmt
, ...)
500 buf
= dupvprintf(fmt
, ap
);
507 void debug_memdump(void *buf
, int len
, int L
)
510 unsigned char *p
= buf
;
514 debug_printf("\t%d (0x%x) bytes:\n", len
, len
);
515 delta
= 15 & (int) p
;
519 for (; 0 < len
; p
+= 16, len
-= 16) {
522 debug_printf("%p: ", p
);
523 strcpy(foo
, "................"); /* sixteen dots */
524 for (i
= 0; i
< 16 && i
< len
; ++i
) {
525 if (&p
[i
] < (unsigned char *) buf
) {
526 dputs(" "); /* 3 spaces */
529 debug_printf("%c%02.2x",
530 &p
[i
] != (unsigned char *) buf
531 && i
% 4 ?
'.' : ' ', p
[i
]
533 if (p
[i
] >= ' ' && p
[i
] <= '~')
534 foo
[i
] = (char) p
[i
];
538 debug_printf("%*s%s\n", (16 - i
) * 3 + 2, "", foo
);
542 #endif /* def DEBUG */