compats.c (38019B)
1 #include "config.h" 2 #if !HAVE_ERR 3 /* 4 * Copyright (c) 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <errno.h> 33 #include <stdarg.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 38 void 39 vwarnx(const char *fmt, va_list ap) 40 { 41 fprintf(stderr, "%s: ", getprogname()); 42 if (fmt != NULL) 43 vfprintf(stderr, fmt, ap); 44 } 45 46 void 47 vwarn(const char *fmt, va_list ap) 48 { 49 int sverrno; 50 51 sverrno = errno; 52 vwarnx(fmt, ap); 53 if (fmt != NULL) 54 fputs(": ", stderr); 55 fprintf(stderr, "%s\n", strerror(sverrno)); 56 } 57 58 void 59 err(int eval, const char *fmt, ...) 60 { 61 va_list ap; 62 63 va_start(ap, fmt); 64 vwarn(fmt, ap); 65 va_end(ap); 66 exit(eval); 67 } 68 69 void 70 errx(int eval, const char *fmt, ...) 71 { 72 va_list ap; 73 74 va_start(ap, fmt); 75 vwarnx(fmt, ap); 76 va_end(ap); 77 fputc('\n', stderr); 78 exit(eval); 79 } 80 81 void 82 warn(const char *fmt, ...) 83 { 84 va_list ap; 85 86 va_start(ap, fmt); 87 vwarn(fmt, ap); 88 va_end(ap); 89 } 90 91 void 92 warnx(const char *fmt, ...) 93 { 94 va_list ap; 95 96 va_start(ap, fmt); 97 vwarnx(fmt, ap); 98 va_end(ap); 99 fputc('\n', stderr); 100 } 101 #endif /* !HAVE_ERR */ 102 #if !HAVE_B64_NTOP 103 /* $OpenBSD$ */ 104 105 /* 106 * Copyright (c) 1996 by Internet Software Consortium. 107 * 108 * Permission to use, copy, modify, and distribute this software for any 109 * purpose with or without fee is hereby granted, provided that the above 110 * copyright notice and this permission notice appear in all copies. 111 * 112 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 113 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 114 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 115 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 116 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 117 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 118 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 119 * SOFTWARE. 120 */ 121 122 /* 123 * Portions Copyright (c) 1995 by International Business Machines, Inc. 124 * 125 * International Business Machines, Inc. (hereinafter called IBM) grants 126 * permission under its copyrights to use, copy, modify, and distribute this 127 * Software with or without fee, provided that the above copyright notice and 128 * all paragraphs of this notice appear in all copies, and that the name of IBM 129 * not be used in connection with the marketing of any product incorporating 130 * the Software or modifications thereof, without specific, written prior 131 * permission. 132 * 133 * To the extent it has a right to do so, IBM grants an immunity from suit 134 * under its patents, if any, for the use, sale or manufacture of products to 135 * the extent that such products are used for performing Domain Name System 136 * dynamic updates in TCP/IP networks by means of the Software. No immunity is 137 * granted for any product per se or for any other function of any product. 138 * 139 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, 140 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 141 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, 142 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING 143 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN 144 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. 145 */ 146 147 #include <sys/types.h> 148 #include <sys/socket.h> 149 #include <netinet/in.h> 150 #include <arpa/inet.h> 151 #include <arpa/nameser.h> 152 153 #include <ctype.h> 154 #include <resolv.h> 155 #include <stdio.h> 156 157 #include <stdlib.h> 158 #include <string.h> 159 160 static const char b64_Base64[] = 161 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 162 static const char b64_Pad64 = '='; 163 164 /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) 165 The following encoding technique is taken from RFC 1521 by Borenstein 166 and Freed. It is reproduced here in a slightly edited form for 167 convenience. 168 169 A 65-character subset of US-ASCII is used, enabling 6 bits to be 170 represented per printable character. (The extra 65th character, "=", 171 is used to signify a special processing function.) 172 173 The encoding process represents 24-bit groups of input bits as output 174 strings of 4 encoded characters. Proceeding from left to right, a 175 24-bit input group is formed by concatenating 3 8-bit input groups. 176 These 24 bits are then treated as 4 concatenated 6-bit groups, each 177 of which is translated into a single digit in the base64 alphabet. 178 179 Each 6-bit group is used as an index into an array of 64 printable 180 characters. The character referenced by the index is placed in the 181 output string. 182 183 Table 1: The Base64 Alphabet 184 185 Value Encoding Value Encoding Value Encoding Value Encoding 186 0 A 17 R 34 i 51 z 187 1 B 18 S 35 j 52 0 188 2 C 19 T 36 k 53 1 189 3 D 20 U 37 l 54 2 190 4 E 21 V 38 m 55 3 191 5 F 22 W 39 n 56 4 192 6 G 23 X 40 o 57 5 193 7 H 24 Y 41 p 58 6 194 8 I 25 Z 42 q 59 7 195 9 J 26 a 43 r 60 8 196 10 K 27 b 44 s 61 9 197 11 L 28 c 45 t 62 + 198 12 M 29 d 46 u 63 / 199 13 N 30 e 47 v 200 14 O 31 f 48 w (pad) = 201 15 P 32 g 49 x 202 16 Q 33 h 50 y 203 204 Special processing is performed if fewer than 24 bits are available 205 at the end of the data being encoded. A full encoding quantum is 206 always completed at the end of a quantity. When fewer than 24 input 207 bits are available in an input group, zero bits are added (on the 208 right) to form an integral number of 6-bit groups. Padding at the 209 end of the data is performed using the '=' character. 210 211 Since all base64 input is an integral number of octets, only the 212 ------------------------------------------------- 213 following cases can arise: 214 215 (1) the final quantum of encoding input is an integral 216 multiple of 24 bits; here, the final unit of encoded 217 output will be an integral multiple of 4 characters 218 with no "=" padding, 219 (2) the final quantum of encoding input is exactly 8 bits; 220 here, the final unit of encoded output will be two 221 characters followed by two "=" padding characters, or 222 (3) the final quantum of encoding input is exactly 16 bits; 223 here, the final unit of encoded output will be three 224 characters followed by one "=" padding character. 225 */ 226 227 int 228 b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) 229 { 230 size_t datalength = 0; 231 u_char input[3]; 232 u_char output[4]; 233 size_t i; 234 235 while (2 < srclength) { 236 input[0] = *src++; 237 input[1] = *src++; 238 input[2] = *src++; 239 srclength -= 3; 240 241 output[0] = input[0] >> 2; 242 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 243 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 244 output[3] = input[2] & 0x3f; 245 246 if (datalength + 4 > targsize) 247 return (-1); 248 target[datalength++] = b64_Base64[output[0]]; 249 target[datalength++] = b64_Base64[output[1]]; 250 target[datalength++] = b64_Base64[output[2]]; 251 target[datalength++] = b64_Base64[output[3]]; 252 } 253 254 /* Now we worry about padding. */ 255 if (0 != srclength) { 256 /* Get what's left. */ 257 input[0] = input[1] = input[2] = '\0'; 258 for (i = 0; i < srclength; i++) 259 input[i] = *src++; 260 261 output[0] = input[0] >> 2; 262 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 263 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 264 265 if (datalength + 4 > targsize) 266 return (-1); 267 target[datalength++] = b64_Base64[output[0]]; 268 target[datalength++] = b64_Base64[output[1]]; 269 if (srclength == 1) 270 target[datalength++] = b64_Pad64; 271 else 272 target[datalength++] = b64_Base64[output[2]]; 273 target[datalength++] = b64_Pad64; 274 } 275 if (datalength >= targsize) 276 return (-1); 277 target[datalength] = '\0'; /* Returned value doesn't count \0. */ 278 return (datalength); 279 } 280 281 /* skips all whitespace anywhere. 282 converts characters, four at a time, starting at (or after) 283 src from base - 64 numbers into three 8 bit bytes in the target area. 284 it returns the number of data bytes stored at the target, or -1 on error. 285 */ 286 287 int 288 b64_pton(char const *src, u_char *target, size_t targsize) 289 { 290 int state, ch; 291 size_t tarindex; 292 u_char nextbyte; 293 char *pos; 294 295 state = 0; 296 tarindex = 0; 297 298 while ((ch = (unsigned char)*src++) != '\0') { 299 if (isspace(ch)) /* Skip whitespace anywhere. */ 300 continue; 301 302 if (ch == b64_Pad64) 303 break; 304 305 pos = strchr(b64_Base64, ch); 306 if (pos == 0) /* A non-base64 character. */ 307 return (-1); 308 309 switch (state) { 310 case 0: 311 if (target) { 312 if (tarindex >= targsize) 313 return (-1); 314 target[tarindex] = (pos - b64_Base64) << 2; 315 } 316 state = 1; 317 break; 318 case 1: 319 if (target) { 320 if (tarindex >= targsize) 321 return (-1); 322 target[tarindex] |= (pos - b64_Base64) >> 4; 323 nextbyte = ((pos - b64_Base64) & 0x0f) << 4; 324 if (tarindex + 1 < targsize) 325 target[tarindex+1] = nextbyte; 326 else if (nextbyte) 327 return (-1); 328 } 329 tarindex++; 330 state = 2; 331 break; 332 case 2: 333 if (target) { 334 if (tarindex >= targsize) 335 return (-1); 336 target[tarindex] |= (pos - b64_Base64) >> 2; 337 nextbyte = ((pos - b64_Base64) & 0x03) << 6; 338 if (tarindex + 1 < targsize) 339 target[tarindex+1] = nextbyte; 340 else if (nextbyte) 341 return (-1); 342 } 343 tarindex++; 344 state = 3; 345 break; 346 case 3: 347 if (target) { 348 if (tarindex >= targsize) 349 return (-1); 350 target[tarindex] |= (pos - b64_Base64); 351 } 352 tarindex++; 353 state = 0; 354 break; 355 } 356 } 357 358 /* 359 * We are done decoding Base-64 chars. Let's see if we ended 360 * on a byte boundary, and/or with erroneous trailing characters. 361 */ 362 363 if (ch == b64_Pad64) { /* We got a pad char. */ 364 ch = (unsigned char)*src++; /* Skip it, get next. */ 365 switch (state) { 366 case 0: /* Invalid = in first position */ 367 case 1: /* Invalid = in second position */ 368 return (-1); 369 370 case 2: /* Valid, means one byte of info */ 371 /* Skip any number of spaces. */ 372 for (; ch != '\0'; ch = (unsigned char)*src++) 373 if (!isspace(ch)) 374 break; 375 /* Make sure there is another trailing = sign. */ 376 if (ch != b64_Pad64) 377 return (-1); 378 ch = (unsigned char)*src++; /* Skip the = */ 379 /* Fall through to "single trailing =" case. */ 380 /* FALLTHROUGH */ 381 382 case 3: /* Valid, means two bytes of info */ 383 /* 384 * We know this char is an =. Is there anything but 385 * whitespace after it? 386 */ 387 for (; ch != '\0'; ch = (unsigned char)*src++) 388 if (!isspace(ch)) 389 return (-1); 390 391 /* 392 * Now make sure for cases 2 and 3 that the "extra" 393 * bits that slopped past the last full byte were 394 * zeros. If we don't check them, they become a 395 * subliminal channel. 396 */ 397 if (target && tarindex < targsize && 398 target[tarindex] != 0) 399 return (-1); 400 } 401 } else { 402 /* 403 * We ended by seeing the end of the string. Make sure we 404 * have no partial bytes lying around. 405 */ 406 if (state != 0) 407 return (-1); 408 } 409 410 return (tarindex); 411 } 412 #endif /* !HAVE_B64_NTOP */ 413 #if !HAVE_EXPLICIT_BZERO 414 /* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */ 415 /* 416 * Public domain. 417 * Written by Ted Unangst 418 */ 419 420 #include <string.h> 421 422 /* 423 * explicit_bzero - don't let the compiler optimize away bzero 424 */ 425 426 #if HAVE_MEMSET_S 427 428 void 429 explicit_bzero(void *p, size_t n) 430 { 431 if (n == 0) 432 return; 433 (void)memset_s(p, n, 0, n); 434 } 435 436 #else /* HAVE_MEMSET_S */ 437 438 /* 439 * Indirect bzero through a volatile pointer to hopefully avoid 440 * dead-store optimisation eliminating the call. 441 */ 442 static void (* volatile ssh_bzero)(void *, size_t) = bzero; 443 444 void 445 explicit_bzero(void *p, size_t n) 446 { 447 if (n == 0) 448 return; 449 /* 450 * clang -fsanitize=memory needs to intercept memset-like functions 451 * to correctly detect memory initialisation. Make sure one is called 452 * directly since our indirection trick above sucessfully confuses it. 453 */ 454 #if defined(__has_feature) 455 # if __has_feature(memory_sanitizer) 456 memset(p, 0, n); 457 # endif 458 #endif 459 460 ssh_bzero(p, n); 461 } 462 463 #endif /* HAVE_MEMSET_S */ 464 #endif /* !HAVE_EXPLICIT_BZERO */ 465 #if !HAVE_GETPROGNAME 466 /* 467 * Copyright (c) 2016 Nicholas Marriott <nicholas.marriott@gmail.com> 468 * Copyright (c) 2017 Kristaps Dzonsons <kristaps@bsd.lv> 469 * 470 * Permission to use, copy, modify, and distribute this software for any 471 * purpose with or without fee is hereby granted, provided that the above 472 * copyright notice and this permission notice appear in all copies. 473 * 474 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 475 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 476 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 477 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 478 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 479 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 480 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 481 */ 482 483 #include <sys/types.h> 484 485 #include <errno.h> 486 487 #if HAVE_PROGRAM_INVOCATION_SHORT_NAME 488 const char * 489 getprogname(void) 490 { 491 return (program_invocation_short_name); 492 } 493 #elif HAVE___PROGNAME 494 const char * 495 getprogname(void) 496 { 497 extern char *__progname; 498 499 return (__progname); 500 } 501 #else 502 static const char *progname; 503 504 void 505 setprogname(const char *name) 506 { 507 progname = name; 508 } 509 510 const char * 511 getprogname(void) 512 { 513 return progname; 514 } 515 #endif 516 #endif /* !HAVE_GETPROGNAME */ 517 #if !HAVE_MD5 518 /* 519 * This code implements the MD5 message-digest algorithm. 520 * The algorithm is due to Ron Rivest. This code was 521 * written by Colin Plumb in 1993, no copyright is claimed. 522 * This code is in the public domain; do with it what you wish. 523 * 524 * Equivalent code is available from RSA Data Security, Inc. 525 * This code has been tested against that, and is equivalent, 526 * except that you don't need to include two pages of legalese 527 * with every copy. 528 * 529 * To compute the message digest of a chunk of bytes, declare an 530 * MD5Context structure, pass it to MD5Init, call MD5Update as 531 * needed on buffers full of bytes, and then call MD5Final, which 532 * will fill a supplied 16-byte array with the digest. 533 */ 534 535 #include <sys/types.h> 536 #include <stdlib.h> 537 #include <string.h> 538 539 #define PUT_64BIT_LE(cp, value) do { \ 540 (cp)[7] = (value) >> 56; \ 541 (cp)[6] = (value) >> 48; \ 542 (cp)[5] = (value) >> 40; \ 543 (cp)[4] = (value) >> 32; \ 544 (cp)[3] = (value) >> 24; \ 545 (cp)[2] = (value) >> 16; \ 546 (cp)[1] = (value) >> 8; \ 547 (cp)[0] = (value); } while (0) 548 549 #define PUT_32BIT_LE(cp, value) do { \ 550 (cp)[3] = (value) >> 24; \ 551 (cp)[2] = (value) >> 16; \ 552 (cp)[1] = (value) >> 8; \ 553 (cp)[0] = (value); } while (0) 554 555 static u_int8_t PADDING[MD5_BLOCK_LENGTH] = { 556 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 557 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 558 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 559 }; 560 561 /* 562 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 563 * initialization constants. 564 */ 565 void 566 MD5Init(MD5_CTX *ctx) 567 { 568 ctx->count = 0; 569 ctx->state[0] = 0x67452301; 570 ctx->state[1] = 0xefcdab89; 571 ctx->state[2] = 0x98badcfe; 572 ctx->state[3] = 0x10325476; 573 } 574 575 /* 576 * Update context to reflect the concatenation of another buffer full 577 * of bytes. 578 */ 579 void 580 MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len) 581 { 582 size_t have, need; 583 584 /* Check how many bytes we already have and how many more we need. */ 585 have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); 586 need = MD5_BLOCK_LENGTH - have; 587 588 /* Update bitcount */ 589 ctx->count += (u_int64_t)len << 3; 590 591 if (len >= need) { 592 if (have != 0) { 593 memcpy(ctx->buffer + have, input, need); 594 MD5Transform(ctx->state, ctx->buffer); 595 input += need; 596 len -= need; 597 have = 0; 598 } 599 600 /* Process data in MD5_BLOCK_LENGTH-byte chunks. */ 601 while (len >= MD5_BLOCK_LENGTH) { 602 MD5Transform(ctx->state, input); 603 input += MD5_BLOCK_LENGTH; 604 len -= MD5_BLOCK_LENGTH; 605 } 606 } 607 608 /* Handle any remaining bytes of data. */ 609 if (len != 0) 610 memcpy(ctx->buffer + have, input, len); 611 } 612 613 /* 614 * Pad pad to 64-byte boundary with the bit pattern 615 * 1 0* (64-bit count of bits processed, MSB-first) 616 */ 617 void 618 MD5Pad(MD5_CTX *ctx) 619 { 620 u_int8_t count[8]; 621 size_t padlen; 622 623 /* Convert count to 8 bytes in little endian order. */ 624 PUT_64BIT_LE(count, ctx->count); 625 626 /* Pad out to 56 mod 64. */ 627 padlen = MD5_BLOCK_LENGTH - 628 ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); 629 if (padlen < 1 + 8) 630 padlen += MD5_BLOCK_LENGTH; 631 MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ 632 MD5Update(ctx, count, 8); 633 } 634 635 /* 636 * Final wrapup--call MD5Pad, fill in digest and zero out ctx. 637 */ 638 void 639 MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx) 640 { 641 int i; 642 643 MD5Pad(ctx); 644 for (i = 0; i < 4; i++) 645 PUT_32BIT_LE(digest + i * 4, ctx->state[i]); 646 memset(ctx, 0, sizeof(*ctx)); 647 } 648 649 650 /* The four core functions - F1 is optimized somewhat */ 651 652 /* #define F1(x, y, z) (x & y | ~x & z) */ 653 #define F1(x, y, z) (z ^ (x & (y ^ z))) 654 #define F2(x, y, z) F1(z, x, y) 655 #define F3(x, y, z) (x ^ y ^ z) 656 #define F4(x, y, z) (y ^ (x | ~z)) 657 658 /* This is the central step in the MD5 algorithm. */ 659 #define MD5STEP(f, w, x, y, z, data, s) \ 660 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) 661 662 /* 663 * The core of the MD5 algorithm, this alters an existing MD5 hash to 664 * reflect the addition of 16 longwords of new data. MD5Update blocks 665 * the data and converts bytes into longwords for this routine. 666 */ 667 void 668 MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH]) 669 { 670 u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4]; 671 672 #if BYTE_ORDER == LITTLE_ENDIAN 673 memcpy(in, block, sizeof(in)); 674 #else 675 for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) { 676 in[a] = (u_int32_t)( 677 (u_int32_t)(block[a * 4 + 0]) | 678 (u_int32_t)(block[a * 4 + 1]) << 8 | 679 (u_int32_t)(block[a * 4 + 2]) << 16 | 680 (u_int32_t)(block[a * 4 + 3]) << 24); 681 } 682 #endif 683 684 a = state[0]; 685 b = state[1]; 686 c = state[2]; 687 d = state[3]; 688 689 MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); 690 MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); 691 MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); 692 MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); 693 MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); 694 MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); 695 MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); 696 MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); 697 MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); 698 MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); 699 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 700 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 701 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 702 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 703 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 704 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 705 706 MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); 707 MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); 708 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 709 MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); 710 MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); 711 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 712 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 713 MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); 714 MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); 715 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 716 MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); 717 MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); 718 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 719 MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); 720 MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); 721 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 722 723 MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); 724 MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); 725 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 726 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 727 MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); 728 MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); 729 MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); 730 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 731 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 732 MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); 733 MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); 734 MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); 735 MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); 736 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 737 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 738 MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23); 739 740 MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); 741 MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10); 742 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 743 MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21); 744 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 745 MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10); 746 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 747 MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21); 748 MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6); 749 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 750 MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15); 751 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 752 MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6); 753 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 754 MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15); 755 MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21); 756 757 state[0] += a; 758 state[1] += b; 759 state[2] += c; 760 state[3] += d; 761 } 762 763 char * 764 MD5End(MD5_CTX *ctx, char *buf) 765 { 766 int i; 767 unsigned char digest[MD5_DIGEST_LENGTH]; 768 static const char hex[]="0123456789abcdef"; 769 770 if (!buf) 771 buf = malloc(2*MD5_DIGEST_LENGTH + 1); 772 if (!buf) 773 return 0; 774 MD5Final(digest, ctx); 775 for (i = 0; i < MD5_DIGEST_LENGTH; i++) { 776 buf[i+i] = hex[digest[i] >> 4]; 777 buf[i+i+1] = hex[digest[i] & 0x0f]; 778 } 779 buf[i+i] = '\0'; 780 return buf; 781 } 782 #endif /* !HAVE_MD5 */ 783 #if !HAVE_MEMMEM 784 /*- 785 * Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com> 786 * 787 * Redistribution and use in source and binary forms, with or without 788 * modification, are permitted provided that the following conditions 789 * are met: 790 * 1. Redistributions of source code must retain the above copyright 791 * notice, this list of conditions and the following disclaimer. 792 * 2. Redistributions in binary form must reproduce the above copyright 793 * notice, this list of conditions and the following disclaimer in 794 * the documentation and/or other materials provided with the 795 * distribution. 796 * 3. The name of the author may not be used to endorse or promote 797 * products derived from this software without specific prior written 798 * permission. 799 * 800 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 801 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 802 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 803 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 804 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 805 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 806 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 807 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 808 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 809 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 810 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 811 */ 812 /* 813 * Find the first occurrence of the byte string s in byte string l. 814 */ 815 void * 816 memmem(const void *l, size_t l_len, const void *s, size_t s_len) 817 { 818 const char *cur, *last; 819 const char *cl = l; 820 const char *cs = s; 821 822 /* a zero length needle should just return the haystack */ 823 if (l_len == 0) 824 return (void *)cl; 825 826 /* "s" must be smaller or equal to "l" */ 827 if (l_len < s_len) 828 return NULL; 829 830 /* special case where s_len == 1 */ 831 if (s_len == 1) 832 return memchr(l, *cs, l_len); 833 834 /* the last position where its possible to find "s" in "l" */ 835 last = cl + l_len - s_len; 836 837 for (cur = cl; cur <= last; cur++) 838 if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) 839 return (void *)cur; 840 841 return NULL; 842 } 843 #endif /* !HAVE_MEMMEM */ 844 #if !HAVE_MEMRCHR 845 /* 846 * Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com> 847 * 848 * Permission to use, copy, modify, and distribute this software for any 849 * purpose with or without fee is hereby granted, provided that the above 850 * copyright notice and this permission notice appear in all copies. 851 * 852 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 853 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 854 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 855 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 856 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 857 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 858 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 859 * 860 */ 861 862 #include <string.h> 863 864 /* 865 * Reverse memchr() 866 * Find the last occurrence of 'c' in the buffer 's' of size 'n'. 867 */ 868 void * 869 memrchr(const void *s, int c, size_t n) 870 { 871 const unsigned char *cp; 872 873 if (n != 0) { 874 cp = (unsigned char *)s + n; 875 do { 876 if (*(--cp) == (unsigned char)c) 877 return((void *)cp); 878 } while (--n != 0); 879 } 880 return(NULL); 881 } 882 #endif /* !HAVE_MEMRCHR */ 883 #if !HAVE_REALLOCARRAY 884 /* 885 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> 886 * 887 * Permission to use, copy, modify, and distribute this software for any 888 * purpose with or without fee is hereby granted, provided that the above 889 * copyright notice and this permission notice appear in all copies. 890 * 891 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 892 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 893 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 894 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 895 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 896 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 897 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 898 */ 899 900 #include <sys/types.h> 901 #include <errno.h> 902 #include <stdint.h> 903 #include <stdlib.h> 904 905 /* 906 * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX 907 * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW 908 */ 909 #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) 910 911 void * 912 reallocarray(void *optr, size_t nmemb, size_t size) 913 { 914 if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && 915 nmemb > 0 && SIZE_MAX / nmemb < size) { 916 errno = ENOMEM; 917 return NULL; 918 } 919 return realloc(optr, size * nmemb); 920 } 921 #endif /* !HAVE_REALLOCARRAY */ 922 #if !HAVE_RECALLOCARRAY 923 /* 924 * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net> 925 * 926 * Permission to use, copy, modify, and distribute this software for any 927 * purpose with or without fee is hereby granted, provided that the above 928 * copyright notice and this permission notice appear in all copies. 929 * 930 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 931 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 932 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 933 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 934 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 935 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 936 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 937 */ 938 939 /* OPENBSD ORIGINAL: lib/libc/stdlib/recallocarray.c */ 940 941 #include <errno.h> 942 #include <stdlib.h> 943 #include <stdint.h> 944 #include <string.h> 945 #include <unistd.h> 946 947 /* 948 * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX 949 * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW 950 */ 951 #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) 952 953 void * 954 recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) 955 { 956 size_t oldsize, newsize; 957 void *newptr; 958 959 if (ptr == NULL) 960 return calloc(newnmemb, size); 961 962 if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && 963 newnmemb > 0 && SIZE_MAX / newnmemb < size) { 964 errno = ENOMEM; 965 return NULL; 966 } 967 newsize = newnmemb * size; 968 969 if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && 970 oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { 971 errno = EINVAL; 972 return NULL; 973 } 974 oldsize = oldnmemb * size; 975 976 /* 977 * Don't bother too much if we're shrinking just a bit, 978 * we do not shrink for series of small steps, oh well. 979 */ 980 if (newsize <= oldsize) { 981 size_t d = oldsize - newsize; 982 983 if (d < oldsize / 2 && d < (size_t)getpagesize()) { 984 memset((char *)ptr + newsize, 0, d); 985 return ptr; 986 } 987 } 988 989 newptr = malloc(newsize); 990 if (newptr == NULL) 991 return NULL; 992 993 if (newsize > oldsize) { 994 memcpy(newptr, ptr, oldsize); 995 memset((char *)newptr + oldsize, 0, newsize - oldsize); 996 } else 997 memcpy(newptr, ptr, newsize); 998 999 explicit_bzero(ptr, oldsize); 1000 free(ptr); 1001 1002 return newptr; 1003 } 1004 #endif /* !HAVE_RECALLOCARRAY */ 1005 #if !HAVE_STRLCAT 1006 /* 1007 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> 1008 * 1009 * Permission to use, copy, modify, and distribute this software for any 1010 * purpose with or without fee is hereby granted, provided that the above 1011 * copyright notice and this permission notice appear in all copies. 1012 * 1013 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1014 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1015 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1016 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1017 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1018 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1019 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1020 */ 1021 1022 #include <sys/types.h> 1023 #include <string.h> 1024 1025 /* 1026 * Appends src to string dst of size siz (unlike strncat, siz is the 1027 * full size of dst, not space left). At most siz-1 characters 1028 * will be copied. Always NUL terminates (unless siz <= strlen(dst)). 1029 * Returns strlen(src) + MIN(siz, strlen(initial dst)). 1030 * If retval >= siz, truncation occurred. 1031 */ 1032 size_t 1033 strlcat(char *dst, const char *src, size_t siz) 1034 { 1035 char *d = dst; 1036 const char *s = src; 1037 size_t n = siz; 1038 size_t dlen; 1039 1040 /* Find the end of dst and adjust bytes left but don't go past end */ 1041 while (n-- != 0 && *d != '\0') 1042 d++; 1043 dlen = d - dst; 1044 n = siz - dlen; 1045 1046 if (n == 0) 1047 return(dlen + strlen(s)); 1048 while (*s != '\0') { 1049 if (n != 1) { 1050 *d++ = *s; 1051 n--; 1052 } 1053 s++; 1054 } 1055 *d = '\0'; 1056 1057 return(dlen + (s - src)); /* count does not include NUL */ 1058 } 1059 #endif /* !HAVE_STRLCAT */ 1060 #if !HAVE_STRLCPY 1061 /* 1062 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> 1063 * 1064 * Permission to use, copy, modify, and distribute this software for any 1065 * purpose with or without fee is hereby granted, provided that the above 1066 * copyright notice and this permission notice appear in all copies. 1067 * 1068 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1069 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1070 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1071 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1072 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1073 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1074 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1075 */ 1076 1077 #include <sys/types.h> 1078 #include <string.h> 1079 1080 /* 1081 * Copy src to string dst of size siz. At most siz-1 characters 1082 * will be copied. Always NUL terminates (unless siz == 0). 1083 * Returns strlen(src); if retval >= siz, truncation occurred. 1084 */ 1085 size_t 1086 strlcpy(char *dst, const char *src, size_t siz) 1087 { 1088 char *d = dst; 1089 const char *s = src; 1090 size_t n = siz; 1091 1092 /* Copy as many bytes as will fit */ 1093 if (n != 0) { 1094 while (--n != 0) { 1095 if ((*d++ = *s++) == '\0') 1096 break; 1097 } 1098 } 1099 1100 /* Not enough room in dst, add NUL and traverse rest of src */ 1101 if (n == 0) { 1102 if (siz != 0) 1103 *d = '\0'; /* NUL-terminate dst */ 1104 while (*s++) 1105 ; 1106 } 1107 1108 return(s - src - 1); /* count does not include NUL */ 1109 } 1110 #endif /* !HAVE_STRLCPY */ 1111 #if !HAVE_STRNDUP 1112 /* $OpenBSD$ */ 1113 /* 1114 * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com> 1115 * 1116 * Permission to use, copy, modify, and distribute this software for any 1117 * purpose with or without fee is hereby granted, provided that the above 1118 * copyright notice and this permission notice appear in all copies. 1119 * 1120 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1121 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1122 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1123 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1124 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1125 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1126 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1127 */ 1128 1129 #include <sys/types.h> 1130 1131 #include <stddef.h> 1132 #include <stdlib.h> 1133 #include <string.h> 1134 1135 char * 1136 strndup(const char *str, size_t maxlen) 1137 { 1138 char *copy; 1139 size_t len; 1140 1141 len = strnlen(str, maxlen); 1142 copy = malloc(len + 1); 1143 if (copy != NULL) { 1144 (void)memcpy(copy, str, len); 1145 copy[len] = '\0'; 1146 } 1147 1148 return copy; 1149 } 1150 #endif /* !HAVE_STRNDUP */ 1151 #if !HAVE_STRNLEN 1152 /* $OpenBSD$ */ 1153 1154 /* 1155 * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com> 1156 * 1157 * Permission to use, copy, modify, and distribute this software for any 1158 * purpose with or without fee is hereby granted, provided that the above 1159 * copyright notice and this permission notice appear in all copies. 1160 * 1161 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1162 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1163 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1164 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1165 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1166 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1167 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1168 */ 1169 1170 #include <sys/types.h> 1171 #include <string.h> 1172 1173 size_t 1174 strnlen(const char *str, size_t maxlen) 1175 { 1176 const char *cp; 1177 1178 for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--) 1179 ; 1180 1181 return (size_t)(cp - str); 1182 } 1183 #endif /* !HAVE_STRNLEN */ 1184 #if !HAVE_STRTONUM 1185 /* 1186 * Copyright (c) 2004 Ted Unangst and Todd Miller 1187 * All rights reserved. 1188 * 1189 * Permission to use, copy, modify, and distribute this software for any 1190 * purpose with or without fee is hereby granted, provided that the above 1191 * copyright notice and this permission notice appear in all copies. 1192 * 1193 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1194 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1195 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1196 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1197 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1198 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1199 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1200 */ 1201 1202 #include <errno.h> 1203 #include <limits.h> 1204 #include <stdlib.h> 1205 1206 #define INVALID 1 1207 #define TOOSMALL 2 1208 #define TOOLARGE 3 1209 1210 long long 1211 strtonum(const char *numstr, long long minval, long long maxval, 1212 const char **errstrp) 1213 { 1214 long long ll = 0; 1215 int error = 0; 1216 char *ep; 1217 struct errval { 1218 const char *errstr; 1219 int err; 1220 } ev[4] = { 1221 { NULL, 0 }, 1222 { "invalid", EINVAL }, 1223 { "too small", ERANGE }, 1224 { "too large", ERANGE }, 1225 }; 1226 1227 ev[0].err = errno; 1228 errno = 0; 1229 if (minval > maxval) { 1230 error = INVALID; 1231 } else { 1232 ll = strtoll(numstr, &ep, 10); 1233 if (numstr == ep || *ep != '\0') 1234 error = INVALID; 1235 else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) 1236 error = TOOSMALL; 1237 else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) 1238 error = TOOLARGE; 1239 } 1240 if (errstrp != NULL) 1241 *errstrp = ev[error].errstr; 1242 errno = ev[error].err; 1243 if (error) 1244 ll = 0; 1245 1246 return (ll); 1247 } 1248 #endif /* !HAVE_STRTONUM */