diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2011-01-04 19:52:10 +0700 |
---|---|---|
committer | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2011-01-04 19:52:10 +0700 |
commit | 8cef222175855ae08f3768a5586b00650240403d (patch) | |
tree | 224364dc08e460fea425df95fc45e1cbc9bbbd96 | |
parent | 9fab97cbb70312170739e29a5fbbbe072f07bb78 (diff) | |
parent | cbfeaac7afe31323d46c52da3b98a949232d708e (diff) | |
download | busybox-w32-8cef222175855ae08f3768a5586b00650240403d.tar.gz busybox-w32-8cef222175855ae08f3768a5586b00650240403d.tar.bz2 busybox-w32-8cef222175855ae08f3768a5586b00650240403d.zip |
Merge commit '6722737ece4b8db3e30b53aef8f981f53db1621e^'
-rw-r--r-- | coreutils/fsync.c | 2 | ||||
-rw-r--r-- | coreutils/stat.c | 12 | ||||
-rw-r--r-- | coreutils/tail.c | 1 | ||||
-rw-r--r-- | editors/patch.c | 25 | ||||
-rw-r--r-- | include/libbb.h | 54 | ||||
-rw-r--r-- | include/usage.src.h | 94 | ||||
-rw-r--r-- | libbb/hash_md5_sha.c | 957 | ||||
-rw-r--r-- | libbb/safe_strncpy.c | 11 | ||||
-rw-r--r-- | loginutils/add-remove-shell.c | 135 | ||||
-rw-r--r-- | miscutils/crond.c | 2 | ||||
-rw-r--r-- | miscutils/nandwrite.c | 12 | ||||
-rw-r--r-- | networking/nbd-client.c | 2 | ||||
-rw-r--r-- | networking/ntpd.c | 10 | ||||
-rw-r--r-- | networking/udhcp/common.c | 7 | ||||
-rw-r--r-- | networking/udhcp/common.h | 6 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 294 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 12 | ||||
-rw-r--r-- | networking/udhcp/packet.c | 8 | ||||
-rw-r--r-- | procps/pmap.c | 4 | ||||
-rw-r--r-- | procps/smemcap.c | 3 | ||||
-rwxr-xr-x | scripts/mkmakefile | 5 | ||||
-rw-r--r-- | sysklogd/klogd.c | 19 | ||||
-rw-r--r-- | util-linux/dmesg.c | 19 |
23 files changed, 942 insertions, 752 deletions
diff --git a/coreutils/fsync.c b/coreutils/fsync.c index d1fe2b584..b8b463cd1 100644 --- a/coreutils/fsync.c +++ b/coreutils/fsync.c | |||
@@ -27,7 +27,7 @@ int fsync_main(int argc UNUSED_PARAM, char **argv) | |||
27 | 27 | ||
28 | status = EXIT_SUCCESS; | 28 | status = EXIT_SUCCESS; |
29 | do { | 29 | do { |
30 | int fd = open3_or_warn(*argv, O_NOATIME | O_NOCTTY | O_RDONLY, 0); | 30 | int fd = open_or_warn(*argv, O_NOATIME | O_NOCTTY | O_RDONLY); |
31 | 31 | ||
32 | if (fd == -1) { | 32 | if (fd == -1) { |
33 | status = EXIT_FAILURE; | 33 | status = EXIT_FAILURE; |
diff --git a/coreutils/stat.c b/coreutils/stat.c index 777197292..d176d07ea 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c | |||
@@ -247,14 +247,12 @@ static void FAST_FUNC print_stat(char *pformat, const char m, | |||
247 | strcat(pformat, "lu"); | 247 | strcat(pformat, "lu"); |
248 | printf(pformat, (unsigned long) statbuf->st_uid); | 248 | printf(pformat, (unsigned long) statbuf->st_uid); |
249 | } else if (m == 'U') { | 249 | } else if (m == 'U') { |
250 | setpwent(); | ||
251 | pw_ent = getpwuid(statbuf->st_uid); | 250 | pw_ent = getpwuid(statbuf->st_uid); |
252 | printfs(pformat, (pw_ent != NULL) ? pw_ent->pw_name : "UNKNOWN"); | 251 | printfs(pformat, (pw_ent != NULL) ? pw_ent->pw_name : "UNKNOWN"); |
253 | } else if (m == 'g') { | 252 | } else if (m == 'g') { |
254 | strcat(pformat, "lu"); | 253 | strcat(pformat, "lu"); |
255 | printf(pformat, (unsigned long) statbuf->st_gid); | 254 | printf(pformat, (unsigned long) statbuf->st_gid); |
256 | } else if (m == 'G') { | 255 | } else if (m == 'G') { |
257 | setgrent(); | ||
258 | gw_ent = getgrgid(statbuf->st_gid); | 256 | gw_ent = getgrgid(statbuf->st_gid); |
259 | printfs(pformat, (gw_ent != NULL) ? gw_ent->gr_name : "UNKNOWN"); | 257 | printfs(pformat, (gw_ent != NULL) ? gw_ent->gr_name : "UNKNOWN"); |
260 | } else if (m == 't') { | 258 | } else if (m == 't') { |
@@ -591,20 +589,20 @@ static bool do_stat(const char *filename, const char *format) | |||
591 | # endif | 589 | # endif |
592 | } else { | 590 | } else { |
593 | char *linkname = NULL; | 591 | char *linkname = NULL; |
594 | |||
595 | struct passwd *pw_ent; | 592 | struct passwd *pw_ent; |
596 | struct group *gw_ent; | 593 | struct group *gw_ent; |
597 | setgrent(); | 594 | |
598 | gw_ent = getgrgid(statbuf.st_gid); | 595 | gw_ent = getgrgid(statbuf.st_gid); |
599 | setpwent(); | ||
600 | pw_ent = getpwuid(statbuf.st_uid); | 596 | pw_ent = getpwuid(statbuf.st_uid); |
601 | 597 | ||
602 | if (S_ISLNK(statbuf.st_mode)) | 598 | if (S_ISLNK(statbuf.st_mode)) |
603 | linkname = xmalloc_readlink_or_warn(filename); | 599 | linkname = xmalloc_readlink_or_warn(filename); |
604 | if (linkname) | 600 | if (linkname) { |
605 | printf(" File: '%s' -> '%s'\n", filename, linkname); | 601 | printf(" File: '%s' -> '%s'\n", filename, linkname); |
606 | else | 602 | free(linkname); |
603 | } else { | ||
607 | printf(" File: '%s'\n", filename); | 604 | printf(" File: '%s'\n", filename); |
605 | } | ||
608 | 606 | ||
609 | printf(" Size: %-10llu\tBlocks: %-10llu IO Block: %-6lu %s\n" | 607 | printf(" Size: %-10llu\tBlocks: %-10llu IO Block: %-6lu %s\n" |
610 | "Device: %llxh/%llud\tInode: %-10llu Links: %-5lu", | 608 | "Device: %llxh/%llud\tInode: %-10llu Links: %-5lu", |
diff --git a/coreutils/tail.c b/coreutils/tail.c index 44698f304..df881a37a 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
@@ -346,6 +346,7 @@ int tail_main(int argc, char **argv) | |||
346 | } | 346 | } |
347 | if (ENABLE_FEATURE_CLEAN_UP) { | 347 | if (ENABLE_FEATURE_CLEAN_UP) { |
348 | free(fds); | 348 | free(fds); |
349 | free(tailbuf); | ||
349 | } | 350 | } |
350 | return G.status; | 351 | return G.status; |
351 | } | 352 | } |
diff --git a/editors/patch.c b/editors/patch.c index 66a9474fe..fff06907f 100644 --- a/editors/patch.c +++ b/editors/patch.c | |||
@@ -17,7 +17,6 @@ | |||
17 | * -o outfile output here instead of in place | 17 | * -o outfile output here instead of in place |
18 | * -r rejectfile write rejected hunks to this file | 18 | * -r rejectfile write rejected hunks to this file |
19 | * | 19 | * |
20 | * -E remove empty files --remove-empty-files | ||
21 | * -f force (no questions asked) | 20 | * -f force (no questions asked) |
22 | * -F fuzz (number, default 2) | 21 | * -F fuzz (number, default 2) |
23 | * [file] which file to patch | 22 | * [file] which file to patch |
@@ -42,7 +41,7 @@ config PATCH | |||
42 | hunks to stderr, and exits with nonzero status if any hunks fail. | 41 | hunks to stderr, and exits with nonzero status if any hunks fail. |
43 | 42 | ||
44 | A file compared against /dev/null (or with a date <= the epoch) is | 43 | A file compared against /dev/null (or with a date <= the epoch) is |
45 | created/deleted as appropriate. | 44 | created or deleted if -E or --remove-empty-files set. |
46 | */ | 45 | */ |
47 | #include "libbb.h" | 46 | #include "libbb.h" |
48 | 47 | ||
@@ -243,15 +242,16 @@ struct globals { | |||
243 | } while (0) | 242 | } while (0) |
244 | 243 | ||
245 | 244 | ||
246 | #define FLAG_STR "Rup:i:Nx" | 245 | #define FLAG_STR "Rup:i:NEx" |
247 | /* FLAG_REVERSE must be == 1! Code uses this fact. */ | 246 | /* FLAG_REVERSE must be == 1! Code uses this fact. */ |
248 | #define FLAG_REVERSE (1 << 0) | 247 | #define FLAG_REVERSE (1 << 0) |
249 | #define FLAG_u (1 << 1) | 248 | #define FLAG_u (1 << 1) |
250 | #define FLAG_PATHLEN (1 << 2) | 249 | #define FLAG_PATHLEN (1 << 2) |
251 | #define FLAG_INPUT (1 << 3) | 250 | #define FLAG_INPUT (1 << 3) |
252 | #define FLAG_IGNORE (1 << 4) | 251 | #define FLAG_IGNORE (1 << 4) |
252 | #define FLAG_RMEMPTY (1 << 5) | ||
253 | //non-standard: | 253 | //non-standard: |
254 | #define FLAG_DEBUG (1 << 5) | 254 | #define FLAG_DEBUG (1 << 6) |
255 | 255 | ||
256 | // Dispose of a line of input, either by writing it out or discarding it. | 256 | // Dispose of a line of input, either by writing it out or discarding it. |
257 | 257 | ||
@@ -551,7 +551,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
551 | 551 | ||
552 | // If this is the first hunk, open the file. | 552 | // If this is the first hunk, open the file. |
553 | if (TT.filein == -1) { | 553 | if (TT.filein == -1) { |
554 | int oldsum, newsum, del = 0; | 554 | int oldsum, newsum, empty = 0; |
555 | char *name; | 555 | char *name; |
556 | 556 | ||
557 | oldsum = TT.oldline + TT.oldlen; | 557 | oldsum = TT.oldline + TT.oldlen; |
@@ -564,7 +564,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
564 | if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) | 564 | if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) |
565 | { | 565 | { |
566 | name = reverse ? newname : oldname; | 566 | name = reverse ? newname : oldname; |
567 | del++; | 567 | empty++; |
568 | } | 568 | } |
569 | 569 | ||
570 | // handle -p path truncation. | 570 | // handle -p path truncation. |
@@ -576,10 +576,17 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
576 | } | 576 | } |
577 | } | 577 | } |
578 | 578 | ||
579 | if (del) { | 579 | if (empty) { |
580 | printf("removing %s\n", name); | 580 | // File is empty after the patches have been applied |
581 | xunlink(name); | ||
582 | state = 0; | 581 | state = 0; |
582 | if (option_mask32 & FLAG_RMEMPTY) { | ||
583 | // If flag -E or --remove-empty-files is set | ||
584 | printf("removing %s\n", name); | ||
585 | xunlink(name); | ||
586 | } else { | ||
587 | printf("patching file %s\n", name); | ||
588 | xclose(xopen(name, O_WRONLY | O_TRUNC)); | ||
589 | } | ||
583 | // If we've got a file to open, do so. | 590 | // If we've got a file to open, do so. |
584 | } else if (!(option_mask32 & FLAG_PATHLEN) || i <= TT.prefix) { | 591 | } else if (!(option_mask32 & FLAG_PATHLEN) || i <= TT.prefix) { |
585 | // If the old file was null, we're creating a new one. | 592 | // If the old file was null, we're creating a new one. |
diff --git a/include/libbb.h b/include/libbb.h index 0ea7700f2..99bfe085c 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1532,47 +1532,31 @@ enum { | |||
1532 | }; | 1532 | }; |
1533 | void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags); | 1533 | void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags); |
1534 | 1534 | ||
1535 | typedef struct sha1_ctx_t { | 1535 | typedef struct md5_ctx_t { |
1536 | uint32_t hash[8]; /* 5, +3 elements for sha256 */ | 1536 | uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ |
1537 | uint64_t total64; /* must be directly after hash[] */ | 1537 | void (*process_block)(struct md5_ctx_t*) FAST_FUNC; |
1538 | uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */ | 1538 | uint64_t total64; /* must be directly before hash[] */ |
1539 | void (*process_block)(struct sha1_ctx_t*) FAST_FUNC; | 1539 | uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */ |
1540 | } sha1_ctx_t; | 1540 | } md5_ctx_t; |
1541 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; | 1541 | typedef struct md5_ctx_t sha1_ctx_t; |
1542 | void sha1_hash(sha1_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; | 1542 | typedef struct md5_ctx_t sha256_ctx_t; |
1543 | void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; | ||
1544 | typedef struct sha1_ctx_t sha256_ctx_t; | ||
1545 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; | ||
1546 | #define sha256_hash sha1_hash | ||
1547 | #define sha256_end sha1_end | ||
1548 | typedef struct sha512_ctx_t { | 1543 | typedef struct sha512_ctx_t { |
1544 | uint64_t total64[2]; /* must be directly before hash[] */ | ||
1549 | uint64_t hash[8]; | 1545 | uint64_t hash[8]; |
1550 | uint64_t total64[2]; /* must be directly after hash[] */ | 1546 | uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */ |
1551 | uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */ | ||
1552 | } sha512_ctx_t; | 1547 | } sha512_ctx_t; |
1553 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; | ||
1554 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | ||
1555 | void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; | ||
1556 | #if 1 | ||
1557 | typedef struct md5_ctx_t { | ||
1558 | uint32_t A; | ||
1559 | uint32_t B; | ||
1560 | uint32_t C; | ||
1561 | uint32_t D; | ||
1562 | uint64_t total64; | ||
1563 | char wbuffer[64]; /* NB: always correctly aligned for uint64_t */ | ||
1564 | } md5_ctx_t; | ||
1565 | #else | ||
1566 | /* libbb/md5prime.c uses a bit different one: */ | ||
1567 | typedef struct md5_ctx_t { | ||
1568 | uint32_t state[4]; /* state (ABCD) */ | ||
1569 | uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ | ||
1570 | unsigned char buffer[64]; /* input buffer */ | ||
1571 | } md5_ctx_t; | ||
1572 | #endif | ||
1573 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; | 1548 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; |
1574 | void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; | 1549 | void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; |
1575 | void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1550 | void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; |
1551 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; | ||
1552 | #define sha1_hash md5_hash | ||
1553 | void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; | ||
1554 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; | ||
1555 | #define sha256_hash md5_hash | ||
1556 | #define sha256_end sha1_end | ||
1557 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; | ||
1558 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | ||
1559 | void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; | ||
1576 | 1560 | ||
1577 | 1561 | ||
1578 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; | 1562 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; |
diff --git a/include/usage.src.h b/include/usage.src.h index 5d7767bb4..f5ddd7ba5 100644 --- a/include/usage.src.h +++ b/include/usage.src.h | |||
@@ -2788,7 +2788,7 @@ INSERT | |||
2788 | "Address: 127.0.0.1\n" | 2788 | "Address: 127.0.0.1\n" |
2789 | 2789 | ||
2790 | #define ntpd_trivial_usage \ | 2790 | #define ntpd_trivial_usage \ |
2791 | "[-dnqwl] [-S PROG] [-p PEER]..." | 2791 | "[-dnqNw"IF_FEATURE_NTPD_SERVER("l")"] [-S PROG] [-p PEER]..." |
2792 | #define ntpd_full_usage "\n\n" \ | 2792 | #define ntpd_full_usage "\n\n" \ |
2793 | "NTP client/server\n" \ | 2793 | "NTP client/server\n" \ |
2794 | "\nOptions:" \ | 2794 | "\nOptions:" \ |
@@ -2797,7 +2797,9 @@ INSERT | |||
2797 | "\n -q Quit after clock is set" \ | 2797 | "\n -q Quit after clock is set" \ |
2798 | "\n -N Run at high priority" \ | 2798 | "\n -N Run at high priority" \ |
2799 | "\n -w Do not set time (only query peers), implies -n" \ | 2799 | "\n -w Do not set time (only query peers), implies -n" \ |
2800 | IF_FEATURE_NTPD_SERVER( \ | ||
2800 | "\n -l Run as server on port 123" \ | 2801 | "\n -l Run as server on port 123" \ |
2802 | ) \ | ||
2801 | "\n -S PROG Run PROG after stepping time, stratum change, and every 11 mins" \ | 2803 | "\n -S PROG Run PROG after stepping time, stratum change, and every 11 mins" \ |
2802 | "\n -p PEER Obtain time from PEER (may be repeated)" \ | 2804 | "\n -p PEER Obtain time from PEER (may be repeated)" \ |
2803 | 2805 | ||
@@ -2855,17 +2857,19 @@ INSERT | |||
2855 | "[OPTIONS] [ORIGFILE [PATCHFILE]]" | 2857 | "[OPTIONS] [ORIGFILE [PATCHFILE]]" |
2856 | #define patch_full_usage "\n\n" \ | 2858 | #define patch_full_usage "\n\n" \ |
2857 | IF_LONG_OPTS( \ | 2859 | IF_LONG_OPTS( \ |
2858 | " -p,--strip N Strip N leading components from file names" \ | 2860 | " -p,--strip N Strip N leading components from file names" \ |
2859 | "\n -i,--input DIFF Read DIFF instead of stdin" \ | 2861 | "\n -i,--input DIFF Read DIFF instead of stdin" \ |
2860 | "\n -R,--reverse Reverse patch" \ | 2862 | "\n -R,--reverse Reverse patch" \ |
2861 | "\n -N,--forward Ignore already applied patches" \ | 2863 | "\n -N,--forward Ignore already applied patches" \ |
2862 | "\n --dry-run Don't actually change files" \ | 2864 | "\n --dry-run Don't actually change files" \ |
2865 | "\n -E,--remove-empty-files Remove output files if they become empty" \ | ||
2863 | ) \ | 2866 | ) \ |
2864 | IF_NOT_LONG_OPTS( \ | 2867 | IF_NOT_LONG_OPTS( \ |
2865 | " -p N Strip N leading components from file names" \ | 2868 | " -p N Strip N leading components from file names" \ |
2866 | "\n -i DIFF Read DIFF instead of stdin" \ | 2869 | "\n -i DIFF Read DIFF instead of stdin" \ |
2867 | "\n -R Reverse patch" \ | 2870 | "\n -R Reverse patch" \ |
2868 | "\n -N Ignore already applied patches" \ | 2871 | "\n -N Ignore already applied patches" \ |
2872 | "\n -E Remove output files if they become empty" \ | ||
2869 | ) | 2873 | ) |
2870 | 2874 | ||
2871 | #define patch_example_usage \ | 2875 | #define patch_example_usage \ |
@@ -4232,84 +4236,6 @@ INSERT | |||
4232 | "# tunctl\n" \ | 4236 | "# tunctl\n" \ |
4233 | "# tunctl -d tun0\n" | 4237 | "# tunctl -d tun0\n" |
4234 | 4238 | ||
4235 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | ||
4236 | # define IF_UDHCP_VERBOSE(...) __VA_ARGS__ | ||
4237 | #else | ||
4238 | # define IF_UDHCP_VERBOSE(...) | ||
4239 | #endif | ||
4240 | #define udhcpc_trivial_usage \ | ||
4241 | "[-fbnq"IF_UDHCP_VERBOSE("v")"oCR] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" \ | ||
4242 | " [-H HOSTNAME] [-c CID] [-V VENDOR] [-O DHCP_OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") | ||
4243 | #define udhcpc_full_usage "\n" \ | ||
4244 | IF_LONG_OPTS( \ | ||
4245 | "\n -i,--interface IFACE Interface to use (default eth0)" \ | ||
4246 | "\n -p,--pidfile FILE Create pidfile" \ | ||
4247 | "\n -r,--request IP IP address to request" \ | ||
4248 | "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" \ | ||
4249 | "\n -t,--retries N Send up to N discover packets" \ | ||
4250 | "\n -T,--timeout N Pause between packets (default 3 seconds)" \ | ||
4251 | "\n -A,--tryagain N Wait N seconds after failure (default 20)" \ | ||
4252 | "\n -f,--foreground Run in foreground" \ | ||
4253 | USE_FOR_MMU( \ | ||
4254 | "\n -b,--background Background if lease is not obtained" \ | ||
4255 | ) \ | ||
4256 | "\n -S,--syslog Log to syslog too" \ | ||
4257 | "\n -n,--now Exit if lease is not obtained" \ | ||
4258 | "\n -q,--quit Exit after obtaining lease" \ | ||
4259 | "\n -R,--release Release IP on exit" \ | ||
4260 | IF_FEATURE_UDHCP_PORT( \ | ||
4261 | "\n -P,--client-port N Use port N (default 68)" \ | ||
4262 | ) \ | ||
4263 | IF_FEATURE_UDHCPC_ARPING( \ | ||
4264 | "\n -a,--arping Use arping to validate offered address" \ | ||
4265 | ) \ | ||
4266 | "\n -O,--request-option OPT Request DHCP option OPT (cumulative)" \ | ||
4267 | "\n -o,--no-default-options Don't request any options (unless -O is given)" \ | ||
4268 | "\n -x OPT:VAL Include option OPT in sent packets (cumulative)" \ | ||
4269 | "\n -F,--fqdn NAME Ask server to update DNS mapping for NAME" \ | ||
4270 | "\n -H,-h,--hostname NAME Send NAME as client hostname (default none)" \ | ||
4271 | "\n -V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')" \ | ||
4272 | "\n -c,--clientid CLIENTID Client identifier (default own MAC)" \ | ||
4273 | "\n -C,--clientid-none Don't send client identifier" \ | ||
4274 | IF_UDHCP_VERBOSE( \ | ||
4275 | "\n -v Verbose" \ | ||
4276 | ) \ | ||
4277 | ) \ | ||
4278 | IF_NOT_LONG_OPTS( \ | ||
4279 | "\n -i IFACE Interface to use (default eth0)" \ | ||
4280 | "\n -p FILE Create pidfile" \ | ||
4281 | "\n -r IP IP address to request" \ | ||
4282 | "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" \ | ||
4283 | "\n -t N Send up to N discover packets" \ | ||
4284 | "\n -T N Pause between packets (default 3 seconds)" \ | ||
4285 | "\n -A N Wait N seconds (default 20) after failure" \ | ||
4286 | "\n -x OPT:VAL Include option OPT in sent packets" \ | ||
4287 | "\n -O OPT Request DHCP option OPT (cumulative)" \ | ||
4288 | "\n -o Don't request any options (unless -O is given)" \ | ||
4289 | "\n -f Run in foreground" \ | ||
4290 | USE_FOR_MMU( \ | ||
4291 | "\n -b Background if lease is not obtained" \ | ||
4292 | ) \ | ||
4293 | "\n -S Log to syslog too" \ | ||
4294 | "\n -n Exit if lease is not obtained" \ | ||
4295 | "\n -q Exit after obtaining lease" \ | ||
4296 | "\n -R Release IP on exit" \ | ||
4297 | IF_FEATURE_UDHCP_PORT( \ | ||
4298 | "\n -P N Use port N (default 68)" \ | ||
4299 | ) \ | ||
4300 | IF_FEATURE_UDHCPC_ARPING( \ | ||
4301 | "\n -a Use arping to validate offered address" \ | ||
4302 | ) \ | ||
4303 | "\n -F NAME Ask server to update DNS mapping for NAME" \ | ||
4304 | "\n -H,-h NAME Send NAME as client hostname (default none)" \ | ||
4305 | "\n -V VENDOR Vendor identifier (default 'udhcp VERSION')" \ | ||
4306 | "\n -c CLIENTID Client identifier (default own MAC)" \ | ||
4307 | "\n -C Don't send client identifier" \ | ||
4308 | IF_UDHCP_VERBOSE( \ | ||
4309 | "\n -v Verbose" \ | ||
4310 | ) \ | ||
4311 | ) \ | ||
4312 | |||
4313 | #define udhcpd_trivial_usage \ | 4239 | #define udhcpd_trivial_usage \ |
4314 | "[-fS]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]" \ | 4240 | "[-fS]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]" \ |
4315 | 4241 | ||
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index 3e708ef7e..aeacddef8 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -1,31 +1,10 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Based on shasum from http://www.netsw.org/crypto/hash/ | 3 | * Utility routines. |
4 | * Majorly hacked up to use Dr Brian Gladman's sha1 code | ||
5 | * | 4 | * |
6 | * Copyright (C) 2002 Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. | 5 | * Copyright (C) 2010 Denys Vlasenko |
7 | * Copyright (C) 2003 Glenn L. McGrath | ||
8 | * Copyright (C) 2003 Erik Andersen | ||
9 | * | 6 | * |
10 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
11 | * | ||
12 | * --------------------------------------------------------------------------- | ||
13 | * Issue Date: 10/11/2002 | ||
14 | * | ||
15 | * This is a byte oriented version of SHA1 that operates on arrays of bytes | ||
16 | * stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor | ||
17 | * | ||
18 | * --------------------------------------------------------------------------- | ||
19 | * | ||
20 | * SHA256 and SHA512 parts are: | ||
21 | * Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. | ||
22 | * Shrank by Denys Vlasenko. | ||
23 | * | ||
24 | * --------------------------------------------------------------------------- | ||
25 | * | ||
26 | * The best way to test random blocksizes is to go to coreutils/md5_sha1_sum.c | ||
27 | * and replace "4096" with something like "2000 + time(NULL) % 2097", | ||
28 | * then rebuild and compare "shaNNNsum bigfile" results. | ||
29 | */ | 8 | */ |
30 | 9 | ||
31 | #include "libbb.h" | 10 | #include "libbb.h" |
@@ -53,332 +32,18 @@ static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned n) | |||
53 | } | 32 | } |
54 | 33 | ||
55 | 34 | ||
56 | static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx) | 35 | /* Feed data through a temporary buffer. |
57 | { | 36 | * The internal buffer remembers previous data until it has 64 |
58 | unsigned t; | 37 | * bytes worth to pass on. |
59 | uint32_t W[80], a, b, c, d, e; | ||
60 | const uint32_t *words = (uint32_t*) ctx->wbuffer; | ||
61 | |||
62 | for (t = 0; t < 16; ++t) | ||
63 | W[t] = SWAP_BE32(words[t]); | ||
64 | for (/*t = 16*/; t < 80; ++t) { | ||
65 | uint32_t T = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]; | ||
66 | W[t] = rotl32(T, 1); | ||
67 | } | ||
68 | |||
69 | a = ctx->hash[0]; | ||
70 | b = ctx->hash[1]; | ||
71 | c = ctx->hash[2]; | ||
72 | d = ctx->hash[3]; | ||
73 | e = ctx->hash[4]; | ||
74 | |||
75 | #undef ch | ||
76 | #undef parity | ||
77 | #undef maj | ||
78 | #undef rnd | ||
79 | #define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) | ||
80 | #define parity(x,y,z) ((x) ^ (y) ^ (z)) | ||
81 | #define maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) | ||
82 | /* A normal version as set out in the FIPS. */ | ||
83 | #define rnd(f,k) \ | ||
84 | do { \ | ||
85 | uint32_t T = a; \ | ||
86 | a = rotl32(a, 5) + f(b, c, d) + e + k + W[t]; \ | ||
87 | e = d; \ | ||
88 | d = c; \ | ||
89 | c = rotl32(b, 30); \ | ||
90 | b = T; \ | ||
91 | } while (0) | ||
92 | |||
93 | for (t = 0; t < 20; ++t) | ||
94 | rnd(ch, 0x5a827999); | ||
95 | |||
96 | for (/*t = 20*/; t < 40; ++t) | ||
97 | rnd(parity, 0x6ed9eba1); | ||
98 | |||
99 | for (/*t = 40*/; t < 60; ++t) | ||
100 | rnd(maj, 0x8f1bbcdc); | ||
101 | |||
102 | for (/*t = 60*/; t < 80; ++t) | ||
103 | rnd(parity, 0xca62c1d6); | ||
104 | #undef ch | ||
105 | #undef parity | ||
106 | #undef maj | ||
107 | #undef rnd | ||
108 | |||
109 | ctx->hash[0] += a; | ||
110 | ctx->hash[1] += b; | ||
111 | ctx->hash[2] += c; | ||
112 | ctx->hash[3] += d; | ||
113 | ctx->hash[4] += e; | ||
114 | } | ||
115 | |||
116 | /* Constants for SHA512 from FIPS 180-2:4.2.3. | ||
117 | * SHA256 constants from FIPS 180-2:4.2.2 | ||
118 | * are the most significant half of first 64 elements | ||
119 | * of the same array. | ||
120 | */ | 38 | */ |
121 | static const uint64_t sha_K[80] = { | 39 | static void FAST_FUNC common64_hash(md5_ctx_t *ctx, const void *buffer, size_t len) |
122 | 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, | ||
123 | 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, | ||
124 | 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, | ||
125 | 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, | ||
126 | 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, | ||
127 | 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, | ||
128 | 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, | ||
129 | 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, | ||
130 | 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, | ||
131 | 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, | ||
132 | 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, | ||
133 | 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, | ||
134 | 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, | ||
135 | 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, | ||
136 | 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, | ||
137 | 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, | ||
138 | 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, | ||
139 | 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, | ||
140 | 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, | ||
141 | 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, | ||
142 | 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, | ||
143 | 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, | ||
144 | 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, | ||
145 | 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, | ||
146 | 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, | ||
147 | 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, | ||
148 | 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, | ||
149 | 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, | ||
150 | 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, | ||
151 | 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, | ||
152 | 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, | ||
153 | 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, | ||
154 | 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, /* [64]+ are used for sha512 only */ | ||
155 | 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, | ||
156 | 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, | ||
157 | 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, | ||
158 | 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, | ||
159 | 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, | ||
160 | 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, | ||
161 | 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL | ||
162 | }; | ||
163 | |||
164 | #undef Ch | ||
165 | #undef Maj | ||
166 | #undef S0 | ||
167 | #undef S1 | ||
168 | #undef R0 | ||
169 | #undef R1 | ||
170 | |||
171 | static void FAST_FUNC sha256_process_block64(sha256_ctx_t *ctx) | ||
172 | { | ||
173 | unsigned t; | ||
174 | uint32_t W[64], a, b, c, d, e, f, g, h; | ||
175 | const uint32_t *words = (uint32_t*) ctx->wbuffer; | ||
176 | |||
177 | /* Operators defined in FIPS 180-2:4.1.2. */ | ||
178 | #define Ch(x, y, z) ((x & y) ^ (~x & z)) | ||
179 | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) | ||
180 | #define S0(x) (rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22)) | ||
181 | #define S1(x) (rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25)) | ||
182 | #define R0(x) (rotr32(x, 7) ^ rotr32(x, 18) ^ (x >> 3)) | ||
183 | #define R1(x) (rotr32(x, 17) ^ rotr32(x, 19) ^ (x >> 10)) | ||
184 | |||
185 | /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ | ||
186 | for (t = 0; t < 16; ++t) | ||
187 | W[t] = SWAP_BE32(words[t]); | ||
188 | for (/*t = 16*/; t < 64; ++t) | ||
189 | W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16]; | ||
190 | |||
191 | a = ctx->hash[0]; | ||
192 | b = ctx->hash[1]; | ||
193 | c = ctx->hash[2]; | ||
194 | d = ctx->hash[3]; | ||
195 | e = ctx->hash[4]; | ||
196 | f = ctx->hash[5]; | ||
197 | g = ctx->hash[6]; | ||
198 | h = ctx->hash[7]; | ||
199 | |||
200 | /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ | ||
201 | for (t = 0; t < 64; ++t) { | ||
202 | /* Need to fetch upper half of sha_K[t] | ||
203 | * (I hope compiler is clever enough to just fetch | ||
204 | * upper half) | ||
205 | */ | ||
206 | uint32_t K_t = sha_K[t] >> 32; | ||
207 | uint32_t T1 = h + S1(e) + Ch(e, f, g) + K_t + W[t]; | ||
208 | uint32_t T2 = S0(a) + Maj(a, b, c); | ||
209 | h = g; | ||
210 | g = f; | ||
211 | f = e; | ||
212 | e = d + T1; | ||
213 | d = c; | ||
214 | c = b; | ||
215 | b = a; | ||
216 | a = T1 + T2; | ||
217 | } | ||
218 | #undef Ch | ||
219 | #undef Maj | ||
220 | #undef S0 | ||
221 | #undef S1 | ||
222 | #undef R0 | ||
223 | #undef R1 | ||
224 | /* Add the starting values of the context according to FIPS 180-2:6.2.2 | ||
225 | step 4. */ | ||
226 | ctx->hash[0] += a; | ||
227 | ctx->hash[1] += b; | ||
228 | ctx->hash[2] += c; | ||
229 | ctx->hash[3] += d; | ||
230 | ctx->hash[4] += e; | ||
231 | ctx->hash[5] += f; | ||
232 | ctx->hash[6] += g; | ||
233 | ctx->hash[7] += h; | ||
234 | } | ||
235 | |||
236 | static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx) | ||
237 | { | ||
238 | unsigned t; | ||
239 | uint64_t W[80]; | ||
240 | /* On i386, having assignments here (not later as sha256 does) | ||
241 | * produces 99 bytes smaller code with gcc 4.3.1 | ||
242 | */ | ||
243 | uint64_t a = ctx->hash[0]; | ||
244 | uint64_t b = ctx->hash[1]; | ||
245 | uint64_t c = ctx->hash[2]; | ||
246 | uint64_t d = ctx->hash[3]; | ||
247 | uint64_t e = ctx->hash[4]; | ||
248 | uint64_t f = ctx->hash[5]; | ||
249 | uint64_t g = ctx->hash[6]; | ||
250 | uint64_t h = ctx->hash[7]; | ||
251 | const uint64_t *words = (uint64_t*) ctx->wbuffer; | ||
252 | |||
253 | /* Operators defined in FIPS 180-2:4.1.2. */ | ||
254 | #define Ch(x, y, z) ((x & y) ^ (~x & z)) | ||
255 | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) | ||
256 | #define S0(x) (rotr64(x, 28) ^ rotr64(x, 34) ^ rotr64(x, 39)) | ||
257 | #define S1(x) (rotr64(x, 14) ^ rotr64(x, 18) ^ rotr64(x, 41)) | ||
258 | #define R0(x) (rotr64(x, 1) ^ rotr64(x, 8) ^ (x >> 7)) | ||
259 | #define R1(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ (x >> 6)) | ||
260 | |||
261 | /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ | ||
262 | for (t = 0; t < 16; ++t) | ||
263 | W[t] = SWAP_BE64(words[t]); | ||
264 | for (/*t = 16*/; t < 80; ++t) | ||
265 | W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16]; | ||
266 | |||
267 | /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ | ||
268 | for (t = 0; t < 80; ++t) { | ||
269 | uint64_t T1 = h + S1(e) + Ch(e, f, g) + sha_K[t] + W[t]; | ||
270 | uint64_t T2 = S0(a) + Maj(a, b, c); | ||
271 | h = g; | ||
272 | g = f; | ||
273 | f = e; | ||
274 | e = d + T1; | ||
275 | d = c; | ||
276 | c = b; | ||
277 | b = a; | ||
278 | a = T1 + T2; | ||
279 | } | ||
280 | #undef Ch | ||
281 | #undef Maj | ||
282 | #undef S0 | ||
283 | #undef S1 | ||
284 | #undef R0 | ||
285 | #undef R1 | ||
286 | /* Add the starting values of the context according to FIPS 180-2:6.3.2 | ||
287 | step 4. */ | ||
288 | ctx->hash[0] += a; | ||
289 | ctx->hash[1] += b; | ||
290 | ctx->hash[2] += c; | ||
291 | ctx->hash[3] += d; | ||
292 | ctx->hash[4] += e; | ||
293 | ctx->hash[5] += f; | ||
294 | ctx->hash[6] += g; | ||
295 | ctx->hash[7] += h; | ||
296 | } | ||
297 | |||
298 | |||
299 | void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) | ||
300 | { | ||
301 | ctx->hash[0] = 0x67452301; | ||
302 | ctx->hash[1] = 0xefcdab89; | ||
303 | ctx->hash[2] = 0x98badcfe; | ||
304 | ctx->hash[3] = 0x10325476; | ||
305 | ctx->hash[4] = 0xc3d2e1f0; | ||
306 | ctx->total64 = 0; | ||
307 | ctx->process_block = sha1_process_block64; | ||
308 | } | ||
309 | |||
310 | static const uint32_t init256[] = { | ||
311 | 0x6a09e667, | ||
312 | 0xbb67ae85, | ||
313 | 0x3c6ef372, | ||
314 | 0xa54ff53a, | ||
315 | 0x510e527f, | ||
316 | 0x9b05688c, | ||
317 | 0x1f83d9ab, | ||
318 | 0x5be0cd19, | ||
319 | 0, | ||
320 | 0, | ||
321 | }; | ||
322 | static const uint32_t init512_lo[] = { | ||
323 | 0xf3bcc908, | ||
324 | 0x84caa73b, | ||
325 | 0xfe94f82b, | ||
326 | 0x5f1d36f1, | ||
327 | 0xade682d1, | ||
328 | 0x2b3e6c1f, | ||
329 | 0xfb41bd6b, | ||
330 | 0x137e2179, | ||
331 | 0, | ||
332 | 0, | ||
333 | }; | ||
334 | |||
335 | /* Initialize structure containing state of computation. | ||
336 | (FIPS 180-2:5.3.2) */ | ||
337 | void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | ||
338 | { | ||
339 | memcpy(ctx->hash, init256, sizeof(init256)); | ||
340 | /*ctx->total64 = 0; - done by extending init256 with two 32-bit zeros */ | ||
341 | ctx->process_block = sha256_process_block64; | ||
342 | } | ||
343 | |||
344 | /* Initialize structure containing state of computation. | ||
345 | (FIPS 180-2:5.3.3) */ | ||
346 | void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) | ||
347 | { | ||
348 | int i; | ||
349 | /* Two extra iterations zero out ctx->total64[] */ | ||
350 | for (i = 0; i < 8+2; i++) | ||
351 | ctx->hash[i] = ((uint64_t)(init256[i]) << 32) + init512_lo[i]; | ||
352 | /*ctx->total64[0] = ctx->total64[1] = 0; - already done */ | ||
353 | } | ||
354 | |||
355 | |||
356 | /* Used also for sha256 */ | ||
357 | void FAST_FUNC sha1_hash(sha1_ctx_t *ctx, const void *buffer, size_t len) | ||
358 | { | 40 | { |
359 | unsigned bufpos = ctx->total64 & 63; | 41 | unsigned bufpos = ctx->total64 & 63; |
360 | unsigned remaining; | ||
361 | 42 | ||
362 | ctx->total64 += len; | 43 | ctx->total64 += len; |
363 | #if 0 | ||
364 | remaining = 64 - bufpos; | ||
365 | |||
366 | /* Hash whole blocks */ | ||
367 | while (len >= remaining) { | ||
368 | memcpy(ctx->wbuffer + bufpos, buffer, remaining); | ||
369 | buffer = (const char *)buffer + remaining; | ||
370 | len -= remaining; | ||
371 | remaining = 64; | ||
372 | bufpos = 0; | ||
373 | ctx->process_block(ctx); | ||
374 | } | ||
375 | 44 | ||
376 | /* Save last, partial blosk */ | ||
377 | memcpy(ctx->wbuffer + bufpos, buffer, len); | ||
378 | #else | ||
379 | /* Tiny bit smaller code */ | ||
380 | while (1) { | 45 | while (1) { |
381 | remaining = 64 - bufpos; | 46 | unsigned remaining = 64 - bufpos; |
382 | if (remaining > len) | 47 | if (remaining > len) |
383 | remaining = len; | 48 | remaining = len; |
384 | /* Copy data into aligned buffer */ | 49 | /* Copy data into aligned buffer */ |
@@ -394,62 +59,12 @@ void FAST_FUNC sha1_hash(sha1_ctx_t *ctx, const void *buffer, size_t len) | |||
394 | ctx->process_block(ctx); | 59 | ctx->process_block(ctx); |
395 | /*bufpos = 0; - already is */ | 60 | /*bufpos = 0; - already is */ |
396 | } | 61 | } |
397 | #endif | ||
398 | } | 62 | } |
399 | 63 | ||
400 | void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) | 64 | /* Process the remaining bytes in the buffer */ |
401 | { | 65 | static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) |
402 | unsigned bufpos = ctx->total64[0] & 127; | ||
403 | unsigned remaining; | ||
404 | |||
405 | /* First increment the byte count. FIPS 180-2 specifies the possible | ||
406 | length of the file up to 2^128 _bits_. | ||
407 | We compute the number of _bytes_ and convert to bits later. */ | ||
408 | ctx->total64[0] += len; | ||
409 | if (ctx->total64[0] < len) | ||
410 | ctx->total64[1]++; | ||
411 | #if 0 | ||
412 | remaining = 128 - bufpos; | ||
413 | |||
414 | /* Hash whole blocks */ | ||
415 | while (len >= remaining) { | ||
416 | memcpy(ctx->wbuffer + bufpos, buffer, remaining); | ||
417 | buffer = (const char *)buffer + remaining; | ||
418 | len -= remaining; | ||
419 | remaining = 128; | ||
420 | bufpos = 0; | ||
421 | sha512_process_block128(ctx); | ||
422 | } | ||
423 | |||
424 | /* Save last, partial blosk */ | ||
425 | memcpy(ctx->wbuffer + bufpos, buffer, len); | ||
426 | #else | ||
427 | while (1) { | ||
428 | remaining = 128 - bufpos; | ||
429 | if (remaining > len) | ||
430 | remaining = len; | ||
431 | /* Copy data into aligned buffer */ | ||
432 | memcpy(ctx->wbuffer + bufpos, buffer, remaining); | ||
433 | len -= remaining; | ||
434 | buffer = (const char *)buffer + remaining; | ||
435 | bufpos += remaining; | ||
436 | /* clever way to do "if (bufpos != 128) break; ... ; bufpos = 0;" */ | ||
437 | bufpos -= 128; | ||
438 | if (bufpos != 0) | ||
439 | break; | ||
440 | /* Buffer is filled up, process it */ | ||
441 | sha512_process_block128(ctx); | ||
442 | /*bufpos = 0; - already is */ | ||
443 | } | ||
444 | #endif | ||
445 | } | ||
446 | |||
447 | |||
448 | /* Used also for sha256 */ | ||
449 | void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) | ||
450 | { | 66 | { |
451 | unsigned bufpos = ctx->total64 & 63; | 67 | unsigned bufpos = ctx->total64 & 63; |
452 | |||
453 | /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ | 68 | /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ |
454 | ctx->wbuffer[bufpos++] = 0x80; | 69 | ctx->wbuffer[bufpos++] = 0x80; |
455 | 70 | ||
@@ -459,9 +74,10 @@ void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) | |||
459 | memset(ctx->wbuffer + bufpos, 0, remaining); | 74 | memset(ctx->wbuffer + bufpos, 0, remaining); |
460 | /* Do we have enough space for the length count? */ | 75 | /* Do we have enough space for the length count? */ |
461 | if (remaining >= 8) { | 76 | if (remaining >= 8) { |
462 | /* Store the 64-bit counter of bits in the buffer in BE format */ | 77 | /* Store the 64-bit counter of bits in the buffer */ |
463 | uint64_t t = ctx->total64 << 3; | 78 | uint64_t t = ctx->total64 << 3; |
464 | t = SWAP_BE64(t); | 79 | if (swap_needed) |
80 | t = bb_bswap_64(t); | ||
465 | /* wbuffer is suitably aligned for this */ | 81 | /* wbuffer is suitably aligned for this */ |
466 | *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; | 82 | *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; |
467 | } | 83 | } |
@@ -470,49 +86,6 @@ void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) | |||
470 | break; | 86 | break; |
471 | bufpos = 0; | 87 | bufpos = 0; |
472 | } | 88 | } |
473 | |||
474 | bufpos = (ctx->process_block == sha1_process_block64) ? 5 : 8; | ||
475 | /* This way we do not impose alignment constraints on resbuf: */ | ||
476 | if (BB_LITTLE_ENDIAN) { | ||
477 | unsigned i; | ||
478 | for (i = 0; i < bufpos; ++i) | ||
479 | ctx->hash[i] = SWAP_BE32(ctx->hash[i]); | ||
480 | } | ||
481 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * bufpos); | ||
482 | } | ||
483 | |||
484 | void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | ||
485 | { | ||
486 | unsigned bufpos = ctx->total64[0] & 127; | ||
487 | |||
488 | /* Pad the buffer to the next 128-byte boundary with 0x80,0,0,0... */ | ||
489 | ctx->wbuffer[bufpos++] = 0x80; | ||
490 | |||
491 | while (1) { | ||
492 | unsigned remaining = 128 - bufpos; | ||
493 | memset(ctx->wbuffer + bufpos, 0, remaining); | ||
494 | if (remaining >= 16) { | ||
495 | /* Store the 128-bit counter of bits in the buffer in BE format */ | ||
496 | uint64_t t; | ||
497 | t = ctx->total64[0] << 3; | ||
498 | t = SWAP_BE64(t); | ||
499 | *(uint64_t *) (&ctx->wbuffer[128 - 8]) = t; | ||
500 | t = (ctx->total64[1] << 3) | (ctx->total64[0] >> 61); | ||
501 | t = SWAP_BE64(t); | ||
502 | *(uint64_t *) (&ctx->wbuffer[128 - 16]) = t; | ||
503 | } | ||
504 | sha512_process_block128(ctx); | ||
505 | if (remaining >= 16) | ||
506 | break; | ||
507 | bufpos = 0; | ||
508 | } | ||
509 | |||
510 | if (BB_LITTLE_ENDIAN) { | ||
511 | unsigned i; | ||
512 | for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i) | ||
513 | ctx->hash[i] = SWAP_BE64(ctx->hash[i]); | ||
514 | } | ||
515 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); | ||
516 | } | 89 | } |
517 | 90 | ||
518 | 91 | ||
@@ -539,18 +112,6 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |||
539 | # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED | 112 | # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED |
540 | #endif | 113 | #endif |
541 | 114 | ||
542 | /* Initialize structure containing state of computation. | ||
543 | * (RFC 1321, 3.3: Step 3) | ||
544 | */ | ||
545 | void FAST_FUNC md5_begin(md5_ctx_t *ctx) | ||
546 | { | ||
547 | ctx->A = 0x67452301; | ||
548 | ctx->B = 0xefcdab89; | ||
549 | ctx->C = 0x98badcfe; | ||
550 | ctx->D = 0x10325476; | ||
551 | ctx->total64 = 0; | ||
552 | } | ||
553 | |||
554 | /* These are the four functions used in the four steps of the MD5 algorithm | 115 | /* These are the four functions used in the four steps of the MD5 algorithm |
555 | * and defined in the RFC 1321. The first function is a little bit optimized | 116 | * and defined in the RFC 1321. The first function is a little bit optimized |
556 | * (as found in Colin Plumbs public domain implementation). | 117 | * (as found in Colin Plumbs public domain implementation). |
@@ -566,7 +127,7 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx) | |||
566 | #define FI(b, c, d) (c ^ (b | ~d)) | 127 | #define FI(b, c, d) (c ^ (b | ~d)) |
567 | 128 | ||
568 | /* Hash a single block, 64 bytes long and 4-byte aligned */ | 129 | /* Hash a single block, 64 bytes long and 4-byte aligned */ |
569 | static void md5_process_block64(md5_ctx_t *ctx) | 130 | static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) |
570 | { | 131 | { |
571 | #if MD5_SIZE_VS_SPEED > 0 | 132 | #if MD5_SIZE_VS_SPEED > 0 |
572 | /* Before we start, one word to the strange constants. | 133 | /* Before we start, one word to the strange constants. |
@@ -605,10 +166,10 @@ static void md5_process_block64(md5_ctx_t *ctx) | |||
605 | }; | 166 | }; |
606 | #endif | 167 | #endif |
607 | uint32_t *words = (void*) ctx->wbuffer; | 168 | uint32_t *words = (void*) ctx->wbuffer; |
608 | uint32_t A = ctx->A; | 169 | uint32_t A = ctx->hash[0]; |
609 | uint32_t B = ctx->B; | 170 | uint32_t B = ctx->hash[1]; |
610 | uint32_t C = ctx->C; | 171 | uint32_t C = ctx->hash[2]; |
611 | uint32_t D = ctx->D; | 172 | uint32_t D = ctx->hash[3]; |
612 | 173 | ||
613 | #if MD5_SIZE_VS_SPEED >= 2 /* 2 or 3 */ | 174 | #if MD5_SIZE_VS_SPEED >= 2 /* 2 or 3 */ |
614 | 175 | ||
@@ -705,10 +266,10 @@ static void md5_process_block64(md5_ctx_t *ctx) | |||
705 | } | 266 | } |
706 | # endif | 267 | # endif |
707 | /* Add checksum to the starting values */ | 268 | /* Add checksum to the starting values */ |
708 | ctx->A += A; | 269 | ctx->hash[0] += A; |
709 | ctx->B += B; | 270 | ctx->hash[1] += B; |
710 | ctx->C += C; | 271 | ctx->hash[2] += C; |
711 | ctx->D += D; | 272 | ctx->hash[3] += D; |
712 | 273 | ||
713 | #else /* MD5_SIZE_VS_SPEED == 0 or 1 */ | 274 | #else /* MD5_SIZE_VS_SPEED == 0 or 1 */ |
714 | 275 | ||
@@ -860,10 +421,10 @@ static void md5_process_block64(md5_ctx_t *ctx) | |||
860 | # undef OP | 421 | # undef OP |
861 | # endif | 422 | # endif |
862 | /* Add checksum to the starting values */ | 423 | /* Add checksum to the starting values */ |
863 | ctx->A = A_save + A; | 424 | ctx->hash[0] = A_save + A; |
864 | ctx->B = B_save + B; | 425 | ctx->hash[1] = B_save + B; |
865 | ctx->C = C_save + C; | 426 | ctx->hash[2] = C_save + C; |
866 | ctx->D = D_save + D; | 427 | ctx->hash[3] = D_save + D; |
867 | #endif | 428 | #endif |
868 | } | 429 | } |
869 | #undef FF | 430 | #undef FF |
@@ -871,37 +432,404 @@ static void md5_process_block64(md5_ctx_t *ctx) | |||
871 | #undef FH | 432 | #undef FH |
872 | #undef FI | 433 | #undef FI |
873 | 434 | ||
874 | /* Feed data through a temporary buffer to call md5_hash_aligned_block() | 435 | /* Initialize structure containing state of computation. |
875 | * with chunks of data that are 4-byte aligned and a multiple of 64 bytes. | 436 | * (RFC 1321, 3.3: Step 3) |
876 | * This function's internal buffer remembers previous data until it has 64 | 437 | */ |
877 | * bytes worth to pass on. Call md5_end() to flush this buffer. */ | 438 | void FAST_FUNC md5_begin(md5_ctx_t *ctx) |
439 | { | ||
440 | ctx->hash[0] = 0x67452301; | ||
441 | ctx->hash[1] = 0xefcdab89; | ||
442 | ctx->hash[2] = 0x98badcfe; | ||
443 | ctx->hash[3] = 0x10325476; | ||
444 | ctx->total64 = 0; | ||
445 | ctx->process_block = md5_process_block64; | ||
446 | } | ||
447 | |||
448 | /* Used also for sha1 and sha256 */ | ||
878 | void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | 449 | void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) |
879 | { | 450 | { |
880 | unsigned bufpos = ctx->total64 & 63; | 451 | common64_hash(ctx, buffer, len); |
452 | } | ||
453 | |||
454 | /* Process the remaining bytes in the buffer and put result from CTX | ||
455 | * in first 16 bytes following RESBUF. The result is always in little | ||
456 | * endian byte order, so that a byte-wise output yields to the wanted | ||
457 | * ASCII representation of the message digest. | ||
458 | */ | ||
459 | void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | ||
460 | { | ||
461 | /* MD5 stores total in LE, need to swap on BE arches: */ | ||
462 | common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN); | ||
463 | |||
464 | /* The MD5 result is in little endian byte order */ | ||
465 | #if BB_BIG_ENDIAN | ||
466 | ctx->hash[0] = SWAP_LE32(ctx->hash[0]); | ||
467 | ctx->hash[1] = SWAP_LE32(ctx->hash[1]); | ||
468 | ctx->hash[2] = SWAP_LE32(ctx->hash[2]); | ||
469 | ctx->hash[3] = SWAP_LE32(ctx->hash[3]); | ||
470 | #endif | ||
471 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); | ||
472 | } | ||
473 | |||
474 | |||
475 | /* | ||
476 | * Based on shasum from http://www.netsw.org/crypto/hash/ | ||
477 | * Majorly hacked up to use Dr Brian Gladman's sha1 code | ||
478 | * | ||
479 | * Copyright (C) 2002 Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. | ||
480 | * Copyright (C) 2003 Glenn L. McGrath | ||
481 | * Copyright (C) 2003 Erik Andersen | ||
482 | * | ||
483 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
484 | * | ||
485 | * --------------------------------------------------------------------------- | ||
486 | * Issue Date: 10/11/2002 | ||
487 | * | ||
488 | * This is a byte oriented version of SHA1 that operates on arrays of bytes | ||
489 | * stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor | ||
490 | * | ||
491 | * --------------------------------------------------------------------------- | ||
492 | * | ||
493 | * SHA256 and SHA512 parts are: | ||
494 | * Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. | ||
495 | * Shrank by Denys Vlasenko. | ||
496 | * | ||
497 | * --------------------------------------------------------------------------- | ||
498 | * | ||
499 | * The best way to test random blocksizes is to go to coreutils/md5_sha1_sum.c | ||
500 | * and replace "4096" with something like "2000 + time(NULL) % 2097", | ||
501 | * then rebuild and compare "shaNNNsum bigfile" results. | ||
502 | */ | ||
503 | |||
504 | static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx) | ||
505 | { | ||
506 | unsigned t; | ||
507 | uint32_t W[80], a, b, c, d, e; | ||
508 | const uint32_t *words = (uint32_t*) ctx->wbuffer; | ||
509 | |||
510 | for (t = 0; t < 16; ++t) | ||
511 | W[t] = SWAP_BE32(words[t]); | ||
512 | for (/*t = 16*/; t < 80; ++t) { | ||
513 | uint32_t T = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]; | ||
514 | W[t] = rotl32(T, 1); | ||
515 | } | ||
516 | |||
517 | a = ctx->hash[0]; | ||
518 | b = ctx->hash[1]; | ||
519 | c = ctx->hash[2]; | ||
520 | d = ctx->hash[3]; | ||
521 | e = ctx->hash[4]; | ||
522 | |||
523 | #undef ch | ||
524 | #undef parity | ||
525 | #undef maj | ||
526 | #undef rnd | ||
527 | #define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) | ||
528 | #define parity(x,y,z) ((x) ^ (y) ^ (z)) | ||
529 | #define maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) | ||
530 | /* A normal version as set out in the FIPS. */ | ||
531 | #define rnd(f,k) \ | ||
532 | do { \ | ||
533 | uint32_t T = a; \ | ||
534 | a = rotl32(a, 5) + f(b, c, d) + e + k + W[t]; \ | ||
535 | e = d; \ | ||
536 | d = c; \ | ||
537 | c = rotl32(b, 30); \ | ||
538 | b = T; \ | ||
539 | } while (0) | ||
540 | |||
541 | for (t = 0; t < 20; ++t) | ||
542 | rnd(ch, 0x5a827999); | ||
543 | |||
544 | for (/*t = 20*/; t < 40; ++t) | ||
545 | rnd(parity, 0x6ed9eba1); | ||
546 | |||
547 | for (/*t = 40*/; t < 60; ++t) | ||
548 | rnd(maj, 0x8f1bbcdc); | ||
549 | |||
550 | for (/*t = 60*/; t < 80; ++t) | ||
551 | rnd(parity, 0xca62c1d6); | ||
552 | #undef ch | ||
553 | #undef parity | ||
554 | #undef maj | ||
555 | #undef rnd | ||
556 | |||
557 | ctx->hash[0] += a; | ||
558 | ctx->hash[1] += b; | ||
559 | ctx->hash[2] += c; | ||
560 | ctx->hash[3] += d; | ||
561 | ctx->hash[4] += e; | ||
562 | } | ||
563 | |||
564 | /* Constants for SHA512 from FIPS 180-2:4.2.3. | ||
565 | * SHA256 constants from FIPS 180-2:4.2.2 | ||
566 | * are the most significant half of first 64 elements | ||
567 | * of the same array. | ||
568 | */ | ||
569 | static const uint64_t sha_K[80] = { | ||
570 | 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, | ||
571 | 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, | ||
572 | 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, | ||
573 | 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, | ||
574 | 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, | ||
575 | 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, | ||
576 | 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, | ||
577 | 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, | ||
578 | 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, | ||
579 | 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, | ||
580 | 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, | ||
581 | 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, | ||
582 | 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, | ||
583 | 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, | ||
584 | 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, | ||
585 | 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, | ||
586 | 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, | ||
587 | 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, | ||
588 | 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, | ||
589 | 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, | ||
590 | 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, | ||
591 | 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, | ||
592 | 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, | ||
593 | 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, | ||
594 | 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, | ||
595 | 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, | ||
596 | 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, | ||
597 | 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, | ||
598 | 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, | ||
599 | 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, | ||
600 | 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, | ||
601 | 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, | ||
602 | 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, /* [64]+ are used for sha512 only */ | ||
603 | 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, | ||
604 | 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, | ||
605 | 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, | ||
606 | 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, | ||
607 | 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, | ||
608 | 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, | ||
609 | 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL | ||
610 | }; | ||
611 | |||
612 | #undef Ch | ||
613 | #undef Maj | ||
614 | #undef S0 | ||
615 | #undef S1 | ||
616 | #undef R0 | ||
617 | #undef R1 | ||
618 | |||
619 | static void FAST_FUNC sha256_process_block64(sha256_ctx_t *ctx) | ||
620 | { | ||
621 | unsigned t; | ||
622 | uint32_t W[64], a, b, c, d, e, f, g, h; | ||
623 | const uint32_t *words = (uint32_t*) ctx->wbuffer; | ||
624 | |||
625 | /* Operators defined in FIPS 180-2:4.1.2. */ | ||
626 | #define Ch(x, y, z) ((x & y) ^ (~x & z)) | ||
627 | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) | ||
628 | #define S0(x) (rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22)) | ||
629 | #define S1(x) (rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25)) | ||
630 | #define R0(x) (rotr32(x, 7) ^ rotr32(x, 18) ^ (x >> 3)) | ||
631 | #define R1(x) (rotr32(x, 17) ^ rotr32(x, 19) ^ (x >> 10)) | ||
632 | |||
633 | /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ | ||
634 | for (t = 0; t < 16; ++t) | ||
635 | W[t] = SWAP_BE32(words[t]); | ||
636 | for (/*t = 16*/; t < 64; ++t) | ||
637 | W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16]; | ||
638 | |||
639 | a = ctx->hash[0]; | ||
640 | b = ctx->hash[1]; | ||
641 | c = ctx->hash[2]; | ||
642 | d = ctx->hash[3]; | ||
643 | e = ctx->hash[4]; | ||
644 | f = ctx->hash[5]; | ||
645 | g = ctx->hash[6]; | ||
646 | h = ctx->hash[7]; | ||
647 | |||
648 | /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ | ||
649 | for (t = 0; t < 64; ++t) { | ||
650 | /* Need to fetch upper half of sha_K[t] | ||
651 | * (I hope compiler is clever enough to just fetch | ||
652 | * upper half) | ||
653 | */ | ||
654 | uint32_t K_t = sha_K[t] >> 32; | ||
655 | uint32_t T1 = h + S1(e) + Ch(e, f, g) + K_t + W[t]; | ||
656 | uint32_t T2 = S0(a) + Maj(a, b, c); | ||
657 | h = g; | ||
658 | g = f; | ||
659 | f = e; | ||
660 | e = d + T1; | ||
661 | d = c; | ||
662 | c = b; | ||
663 | b = a; | ||
664 | a = T1 + T2; | ||
665 | } | ||
666 | #undef Ch | ||
667 | #undef Maj | ||
668 | #undef S0 | ||
669 | #undef S1 | ||
670 | #undef R0 | ||
671 | #undef R1 | ||
672 | /* Add the starting values of the context according to FIPS 180-2:6.2.2 | ||
673 | step 4. */ | ||
674 | ctx->hash[0] += a; | ||
675 | ctx->hash[1] += b; | ||
676 | ctx->hash[2] += c; | ||
677 | ctx->hash[3] += d; | ||
678 | ctx->hash[4] += e; | ||
679 | ctx->hash[5] += f; | ||
680 | ctx->hash[6] += g; | ||
681 | ctx->hash[7] += h; | ||
682 | } | ||
683 | |||
684 | static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx) | ||
685 | { | ||
686 | unsigned t; | ||
687 | uint64_t W[80]; | ||
688 | /* On i386, having assignments here (not later as sha256 does) | ||
689 | * produces 99 bytes smaller code with gcc 4.3.1 | ||
690 | */ | ||
691 | uint64_t a = ctx->hash[0]; | ||
692 | uint64_t b = ctx->hash[1]; | ||
693 | uint64_t c = ctx->hash[2]; | ||
694 | uint64_t d = ctx->hash[3]; | ||
695 | uint64_t e = ctx->hash[4]; | ||
696 | uint64_t f = ctx->hash[5]; | ||
697 | uint64_t g = ctx->hash[6]; | ||
698 | uint64_t h = ctx->hash[7]; | ||
699 | const uint64_t *words = (uint64_t*) ctx->wbuffer; | ||
700 | |||
701 | /* Operators defined in FIPS 180-2:4.1.2. */ | ||
702 | #define Ch(x, y, z) ((x & y) ^ (~x & z)) | ||
703 | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) | ||
704 | #define S0(x) (rotr64(x, 28) ^ rotr64(x, 34) ^ rotr64(x, 39)) | ||
705 | #define S1(x) (rotr64(x, 14) ^ rotr64(x, 18) ^ rotr64(x, 41)) | ||
706 | #define R0(x) (rotr64(x, 1) ^ rotr64(x, 8) ^ (x >> 7)) | ||
707 | #define R1(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ (x >> 6)) | ||
708 | |||
709 | /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ | ||
710 | for (t = 0; t < 16; ++t) | ||
711 | W[t] = SWAP_BE64(words[t]); | ||
712 | for (/*t = 16*/; t < 80; ++t) | ||
713 | W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16]; | ||
714 | |||
715 | /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ | ||
716 | for (t = 0; t < 80; ++t) { | ||
717 | uint64_t T1 = h + S1(e) + Ch(e, f, g) + sha_K[t] + W[t]; | ||
718 | uint64_t T2 = S0(a) + Maj(a, b, c); | ||
719 | h = g; | ||
720 | g = f; | ||
721 | f = e; | ||
722 | e = d + T1; | ||
723 | d = c; | ||
724 | c = b; | ||
725 | b = a; | ||
726 | a = T1 + T2; | ||
727 | } | ||
728 | #undef Ch | ||
729 | #undef Maj | ||
730 | #undef S0 | ||
731 | #undef S1 | ||
732 | #undef R0 | ||
733 | #undef R1 | ||
734 | /* Add the starting values of the context according to FIPS 180-2:6.3.2 | ||
735 | step 4. */ | ||
736 | ctx->hash[0] += a; | ||
737 | ctx->hash[1] += b; | ||
738 | ctx->hash[2] += c; | ||
739 | ctx->hash[3] += d; | ||
740 | ctx->hash[4] += e; | ||
741 | ctx->hash[5] += f; | ||
742 | ctx->hash[6] += g; | ||
743 | ctx->hash[7] += h; | ||
744 | } | ||
745 | |||
746 | |||
747 | void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) | ||
748 | { | ||
749 | ctx->hash[0] = 0x67452301; | ||
750 | ctx->hash[1] = 0xefcdab89; | ||
751 | ctx->hash[2] = 0x98badcfe; | ||
752 | ctx->hash[3] = 0x10325476; | ||
753 | ctx->hash[4] = 0xc3d2e1f0; | ||
754 | ctx->total64 = 0; | ||
755 | ctx->process_block = sha1_process_block64; | ||
756 | } | ||
757 | |||
758 | static const uint32_t init256[] = { | ||
759 | 0, | ||
760 | 0, | ||
761 | 0x6a09e667, | ||
762 | 0xbb67ae85, | ||
763 | 0x3c6ef372, | ||
764 | 0xa54ff53a, | ||
765 | 0x510e527f, | ||
766 | 0x9b05688c, | ||
767 | 0x1f83d9ab, | ||
768 | 0x5be0cd19, | ||
769 | }; | ||
770 | static const uint32_t init512_lo[] = { | ||
771 | 0, | ||
772 | 0, | ||
773 | 0xf3bcc908, | ||
774 | 0x84caa73b, | ||
775 | 0xfe94f82b, | ||
776 | 0x5f1d36f1, | ||
777 | 0xade682d1, | ||
778 | 0x2b3e6c1f, | ||
779 | 0xfb41bd6b, | ||
780 | 0x137e2179, | ||
781 | }; | ||
782 | |||
783 | /* Initialize structure containing state of computation. | ||
784 | (FIPS 180-2:5.3.2) */ | ||
785 | void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | ||
786 | { | ||
787 | memcpy(&ctx->total64, init256, sizeof(init256)); | ||
788 | /*ctx->total64 = 0; - done by prepending two 32-bit zeros to init256 */ | ||
789 | ctx->process_block = sha256_process_block64; | ||
790 | } | ||
791 | |||
792 | /* Initialize structure containing state of computation. | ||
793 | (FIPS 180-2:5.3.3) */ | ||
794 | void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) | ||
795 | { | ||
796 | int i; | ||
797 | /* Two extra iterations zero out ctx->total64[2] */ | ||
798 | uint64_t *tp = ctx->total64; | ||
799 | for (i = 0; i < 2+8; i++) | ||
800 | tp[i] = ((uint64_t)(init256[i]) << 32) + init512_lo[i]; | ||
801 | /*ctx->total64[0] = ctx->total64[1] = 0; - already done */ | ||
802 | } | ||
803 | |||
804 | void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) | ||
805 | { | ||
806 | unsigned bufpos = ctx->total64[0] & 127; | ||
881 | unsigned remaining; | 807 | unsigned remaining; |
882 | 808 | ||
883 | /* RFC 1321 specifies the possible length of the file up to 2^64 bits. | 809 | /* First increment the byte count. FIPS 180-2 specifies the possible |
884 | * Here we only track the number of bytes. */ | 810 | length of the file up to 2^128 _bits_. |
885 | ctx->total64 += len; | 811 | We compute the number of _bytes_ and convert to bits later. */ |
812 | ctx->total64[0] += len; | ||
813 | if (ctx->total64[0] < len) | ||
814 | ctx->total64[1]++; | ||
886 | #if 0 | 815 | #if 0 |
887 | remaining = 64 - bufpos; | 816 | remaining = 128 - bufpos; |
888 | 817 | ||
889 | /* Hash whole blocks */ | 818 | /* Hash whole blocks */ |
890 | while (len >= remaining) { | 819 | while (len >= remaining) { |
891 | memcpy(ctx->wbuffer + bufpos, buffer, remaining); | 820 | memcpy(ctx->wbuffer + bufpos, buffer, remaining); |
892 | buffer = (const char *)buffer + remaining; | 821 | buffer = (const char *)buffer + remaining; |
893 | len -= remaining; | 822 | len -= remaining; |
894 | remaining = 64; | 823 | remaining = 128; |
895 | bufpos = 0; | 824 | bufpos = 0; |
896 | md5_process_block64(ctx); | 825 | sha512_process_block128(ctx); |
897 | } | 826 | } |
898 | 827 | ||
899 | /* Save last, partial blosk */ | 828 | /* Save last, partial blosk */ |
900 | memcpy(ctx->wbuffer + bufpos, buffer, len); | 829 | memcpy(ctx->wbuffer + bufpos, buffer, len); |
901 | #else | 830 | #else |
902 | /* Tiny bit smaller code */ | ||
903 | while (1) { | 831 | while (1) { |
904 | remaining = 64 - bufpos; | 832 | remaining = 128 - bufpos; |
905 | if (remaining > len) | 833 | if (remaining > len) |
906 | remaining = len; | 834 | remaining = len; |
907 | /* Copy data into aligned buffer */ | 835 | /* Copy data into aligned buffer */ |
@@ -909,54 +837,65 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | |||
909 | len -= remaining; | 837 | len -= remaining; |
910 | buffer = (const char *)buffer + remaining; | 838 | buffer = (const char *)buffer + remaining; |
911 | bufpos += remaining; | 839 | bufpos += remaining; |
912 | /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ | 840 | /* clever way to do "if (bufpos != 128) break; ... ; bufpos = 0;" */ |
913 | bufpos -= 64; | 841 | bufpos -= 128; |
914 | if (bufpos != 0) | 842 | if (bufpos != 0) |
915 | break; | 843 | break; |
916 | /* Buffer is filled up, process it */ | 844 | /* Buffer is filled up, process it */ |
917 | md5_process_block64(ctx); | 845 | sha512_process_block128(ctx); |
918 | /*bufpos = 0; - already is */ | 846 | /*bufpos = 0; - already is */ |
919 | } | 847 | } |
920 | #endif | 848 | #endif |
921 | } | 849 | } |
922 | 850 | ||
923 | /* Process the remaining bytes in the buffer and put result from CTX | 851 | /* Used also for sha256 */ |
924 | * in first 16 bytes following RESBUF. The result is always in little | 852 | void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) |
925 | * endian byte order, so that a byte-wise output yields to the wanted | ||
926 | * ASCII representation of the message digest. | ||
927 | */ | ||
928 | void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | ||
929 | { | 853 | { |
930 | unsigned bufpos = ctx->total64 & 63; | 854 | unsigned hash_size; |
931 | /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ | 855 | |
856 | /* SHA stores total in BE, need to swap on LE arches: */ | ||
857 | common64_end(ctx, /*swap_needed:*/ BB_LITTLE_ENDIAN); | ||
858 | |||
859 | hash_size = (ctx->process_block == sha1_process_block64) ? 5 : 8; | ||
860 | /* This way we do not impose alignment constraints on resbuf: */ | ||
861 | if (BB_LITTLE_ENDIAN) { | ||
862 | unsigned i; | ||
863 | for (i = 0; i < hash_size; ++i) | ||
864 | ctx->hash[i] = SWAP_BE32(ctx->hash[i]); | ||
865 | } | ||
866 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * hash_size); | ||
867 | } | ||
868 | |||
869 | void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | ||
870 | { | ||
871 | unsigned bufpos = ctx->total64[0] & 127; | ||
872 | |||
873 | /* Pad the buffer to the next 128-byte boundary with 0x80,0,0,0... */ | ||
932 | ctx->wbuffer[bufpos++] = 0x80; | 874 | ctx->wbuffer[bufpos++] = 0x80; |
933 | 875 | ||
934 | /* This loop iterates either once or twice, no more, no less */ | ||
935 | while (1) { | 876 | while (1) { |
936 | unsigned remaining = 64 - bufpos; | 877 | unsigned remaining = 128 - bufpos; |
937 | memset(ctx->wbuffer + bufpos, 0, remaining); | 878 | memset(ctx->wbuffer + bufpos, 0, remaining); |
938 | /* Do we have enough space for the length count? */ | 879 | if (remaining >= 16) { |
939 | if (remaining >= 8) { | 880 | /* Store the 128-bit counter of bits in the buffer in BE format */ |
940 | /* Store the 64-bit counter of bits in the buffer in LE format */ | 881 | uint64_t t; |
941 | uint64_t t = ctx->total64 << 3; | 882 | t = ctx->total64[0] << 3; |
942 | t = SWAP_LE64(t); | 883 | t = SWAP_BE64(t); |
943 | /* wbuffer is suitably aligned for this */ | 884 | *(uint64_t *) (&ctx->wbuffer[128 - 8]) = t; |
944 | *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; | 885 | t = (ctx->total64[1] << 3) | (ctx->total64[0] >> 61); |
886 | t = SWAP_BE64(t); | ||
887 | *(uint64_t *) (&ctx->wbuffer[128 - 16]) = t; | ||
945 | } | 888 | } |
946 | md5_process_block64(ctx); | 889 | sha512_process_block128(ctx); |
947 | if (remaining >= 8) | 890 | if (remaining >= 16) |
948 | break; | 891 | break; |
949 | bufpos = 0; | 892 | bufpos = 0; |
950 | } | 893 | } |
951 | 894 | ||
952 | /* The MD5 result is in little endian byte order. | 895 | if (BB_LITTLE_ENDIAN) { |
953 | * We (ab)use the fact that A-D are consecutive in memory. | 896 | unsigned i; |
954 | */ | 897 | for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i) |
955 | #if BB_BIG_ENDIAN | 898 | ctx->hash[i] = SWAP_BE64(ctx->hash[i]); |
956 | ctx->A = SWAP_LE32(ctx->A); | 899 | } |
957 | ctx->B = SWAP_LE32(ctx->B); | 900 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); |
958 | ctx->C = SWAP_LE32(ctx->C); | ||
959 | ctx->D = SWAP_LE32(ctx->D); | ||
960 | #endif | ||
961 | memcpy(resbuf, &ctx->A, sizeof(ctx->A) * 4); | ||
962 | } | 901 | } |
diff --git a/libbb/safe_strncpy.c b/libbb/safe_strncpy.c index 8eb6a014f..5eb0db0bd 100644 --- a/libbb/safe_strncpy.c +++ b/libbb/safe_strncpy.c | |||
@@ -20,8 +20,13 @@ char* FAST_FUNC safe_strncpy(char *dst, const char *src, size_t size) | |||
20 | /* Like strcpy but can copy overlapping strings. */ | 20 | /* Like strcpy but can copy overlapping strings. */ |
21 | void FAST_FUNC overlapping_strcpy(char *dst, const char *src) | 21 | void FAST_FUNC overlapping_strcpy(char *dst, const char *src) |
22 | { | 22 | { |
23 | while ((*dst = *src) != '\0') { | 23 | /* Cheap optimization for dst == src case - |
24 | dst++; | 24 | * better to have it here than in many callers. |
25 | src++; | 25 | */ |
26 | if (dst != src) { | ||
27 | while ((*dst = *src) != '\0') { | ||
28 | dst++; | ||
29 | src++; | ||
30 | } | ||
26 | } | 31 | } |
27 | } | 32 | } |
diff --git a/loginutils/add-remove-shell.c b/loginutils/add-remove-shell.c new file mode 100644 index 000000000..757e50503 --- /dev/null +++ b/loginutils/add-remove-shell.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * add-shell and remove-shell implementation for busybox | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation. All rights reserved. | ||
5 | * Written by Alexander Shishkin <virtuoso@slind.org> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see the LICENSE file in this source tree | ||
8 | * for details. | ||
9 | */ | ||
10 | |||
11 | //applet:IF_ADD_SHELL( APPLET_ODDNAME(add-shell , add_remove_shell, _BB_DIR_USR_BIN, _BB_SUID_DROP, add_shell )) | ||
12 | //applet:IF_REMOVE_SHELL(APPLET_ODDNAME(remove-shell, add_remove_shell, _BB_DIR_USR_BIN, _BB_SUID_DROP, remove_shell)) | ||
13 | |||
14 | //kbuild:lib-$(CONFIG_ADD_SHELL) += add-remove-shell.o | ||
15 | //kbuild:lib-$(CONFIG_REMOVE_SHELL) += add-remove-shell.o | ||
16 | |||
17 | //config:config ADD_SHELL | ||
18 | //config: bool "add-shell" | ||
19 | //config: default y if DESKTOP | ||
20 | //config: help | ||
21 | //config: Add shells to /etc/shells. | ||
22 | //config: | ||
23 | //config:config REMOVE_SHELL | ||
24 | //config: bool "remove-shell" | ||
25 | //config: default y if DESKTOP | ||
26 | //config: help | ||
27 | //config: Remove shells from /etc/shells. | ||
28 | |||
29 | //usage:#define add_shell_trivial_usage | ||
30 | //usage: "SHELL..." | ||
31 | //usage:#define add_shell_full_usage "\n\n" | ||
32 | //usage: "Add SHELLs to /etc/shells" | ||
33 | |||
34 | //usage:#define remove_shell_trivial_usage | ||
35 | //usage: "SHELL..." | ||
36 | //usage:#define remove_shell_full_usage "\n\n" | ||
37 | //usage: "Remove SHELLs from /etc/shells" | ||
38 | |||
39 | #include "libbb.h" | ||
40 | |||
41 | #define SHELLS_FILE "/etc/shells" | ||
42 | |||
43 | #define REMOVE_SHELL (ENABLE_REMOVE_SHELL && (!ENABLE_ADD_SHELL || applet_name[0] == 'r')) | ||
44 | #define ADD_SHELL (ENABLE_ADD_SHELL && (!ENABLE_REMOVE_SHELL || applet_name[0] == 'a')) | ||
45 | |||
46 | /* NB: we use the _address_, not the value, of this string | ||
47 | * as a "special value of pointer" in the code. | ||
48 | */ | ||
49 | static const char dont_add[] ALIGN1 = "\n"; | ||
50 | |||
51 | int add_remove_shell_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
52 | int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) | ||
53 | { | ||
54 | FILE *orig_fp; | ||
55 | char *orig_fn; | ||
56 | char *new_fn; | ||
57 | |||
58 | argv++; | ||
59 | |||
60 | orig_fn = xmalloc_follow_symlinks(SHELLS_FILE); | ||
61 | if (!orig_fn) | ||
62 | return EXIT_FAILURE; | ||
63 | orig_fp = fopen_for_read(orig_fn); | ||
64 | |||
65 | new_fn = xasprintf("%s.tmp", orig_fn); | ||
66 | /* | ||
67 | * O_TRUNC or O_EXCL? At the first glance, O_EXCL looks better, | ||
68 | * since it prevents races. But: (1) it requires a retry loop, | ||
69 | * (2) if /etc/shells.tmp is *stale*, then retry loop | ||
70 | * with O_EXCL will never succeed - it should have a timeout, | ||
71 | * after which it should revert to O_TRUNC. | ||
72 | * For now, I settle for O_TRUNC instead. | ||
73 | */ | ||
74 | xmove_fd(xopen(new_fn, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO); | ||
75 | |||
76 | /* TODO: | ||
77 | struct stat sb; | ||
78 | xfstat(fileno(orig_fp), &sb); | ||
79 | xfchown(STDOUT_FILENO, sb.st_uid, sb.st_gid); | ||
80 | xfchmod(STDOUT_FILENO, sb.st_mode); | ||
81 | */ | ||
82 | |||
83 | if (orig_fp) { | ||
84 | /* Copy old file, possibly skipping removed shell names */ | ||
85 | char *line; | ||
86 | while ((line = xmalloc_fgetline(orig_fp)) != NULL) { | ||
87 | char **cpp = argv; | ||
88 | while (*cpp) { | ||
89 | if (strcmp(*cpp, line) == 0) { | ||
90 | /* Old file has this shell name */ | ||
91 | if (REMOVE_SHELL) { | ||
92 | /* we are remove-shell */ | ||
93 | /* delete this name by not copying it */ | ||
94 | goto next_line; | ||
95 | } | ||
96 | /* we are add-shell */ | ||
97 | /* mark this name as "do not add" */ | ||
98 | *cpp = (char*)dont_add; | ||
99 | } | ||
100 | cpp++; | ||
101 | } | ||
102 | /* copy shell name from old to new file */ | ||
103 | printf("%s\n", line); | ||
104 | next_line: | ||
105 | free(line); | ||
106 | } | ||
107 | if (ENABLE_FEATURE_CLEAN_UP) | ||
108 | fclose(orig_fp); | ||
109 | } | ||
110 | |||
111 | if (ADD_SHELL) { | ||
112 | char **cpp = argv; | ||
113 | while (*cpp) { | ||
114 | if (*cpp != dont_add) | ||
115 | printf("%s\n", *cpp); | ||
116 | cpp++; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | /* Ensure we wrote out everything */ | ||
121 | if (fclose(stdout) != 0) { | ||
122 | xunlink(new_fn); | ||
123 | bb_perror_msg_and_die("%s: write error", new_fn); | ||
124 | } | ||
125 | |||
126 | /* Small hole: if rename fails, /etc/shells.tmp is not removed */ | ||
127 | xrename(new_fn, orig_fn); | ||
128 | |||
129 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
130 | free(orig_fn); | ||
131 | free(new_fn); | ||
132 | } | ||
133 | |||
134 | return EXIT_SUCCESS; | ||
135 | } | ||
diff --git a/miscutils/crond.c b/miscutils/crond.c index fddddcd8c..7f2d54c9f 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c | |||
@@ -123,7 +123,7 @@ static void crondlog(const char *ctl, ...) | |||
123 | /* Syslog mode: all to syslog (logmode = LOGMODE_SYSLOG), */ | 123 | /* Syslog mode: all to syslog (logmode = LOGMODE_SYSLOG), */ |
124 | if (!DebugOpt && G.log_filename) { | 124 | if (!DebugOpt && G.log_filename) { |
125 | /* Otherwise (log to file): we reopen log file at every write: */ | 125 | /* Otherwise (log to file): we reopen log file at every write: */ |
126 | int logfd = open3_or_warn(G.log_filename, O_WRONLY | O_CREAT | O_APPEND, 0666); | 126 | int logfd = open_or_warn(G.log_filename, O_WRONLY | O_CREAT | O_APPEND); |
127 | if (logfd >= 0) | 127 | if (logfd >= 0) |
128 | xmove_fd(logfd, STDERR_FILENO); | 128 | xmove_fd(logfd, STDERR_FILENO); |
129 | } | 129 | } |
diff --git a/miscutils/nandwrite.c b/miscutils/nandwrite.c index 6c85ea346..de30a0c1f 100644 --- a/miscutils/nandwrite.c +++ b/miscutils/nandwrite.c | |||
@@ -60,7 +60,6 @@ | |||
60 | #define OPT_f (1 << 3) | 60 | #define OPT_f (1 << 3) |
61 | #define OPT_l (1 << 4) | 61 | #define OPT_l (1 << 4) |
62 | 62 | ||
63 | #define NAND_MAX_OOBSIZE 256 | ||
64 | /* helper for writing out 0xff for bad blocks pad */ | 63 | /* helper for writing out 0xff for bad blocks pad */ |
65 | static void dump_bad(struct mtd_info_user *meminfo, unsigned len, int oob) | 64 | static void dump_bad(struct mtd_info_user *meminfo, unsigned len, int oob) |
66 | { | 65 | { |
@@ -103,7 +102,7 @@ int nandwrite_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
103 | int nandwrite_main(int argc UNUSED_PARAM, char **argv) | 102 | int nandwrite_main(int argc UNUSED_PARAM, char **argv) |
104 | { | 103 | { |
105 | /* Buffer for OOB data */ | 104 | /* Buffer for OOB data */ |
106 | unsigned char oobbuf[NAND_MAX_OOBSIZE]; | 105 | unsigned char *oobbuf; |
107 | unsigned opts; | 106 | unsigned opts; |
108 | int fd; | 107 | int fd; |
109 | ssize_t cnt; | 108 | ssize_t cnt; |
@@ -135,10 +134,6 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) | |||
135 | fd = xopen(argv[0], O_RDWR); | 134 | fd = xopen(argv[0], O_RDWR); |
136 | xioctl(fd, MEMGETINFO, &meminfo); | 135 | xioctl(fd, MEMGETINFO, &meminfo); |
137 | 136 | ||
138 | oob.start = 0; | ||
139 | oob.length = meminfo.oobsize; | ||
140 | oob.ptr = oobbuf; | ||
141 | |||
142 | mtdoffset = xstrtou(opt_s, 0); | 137 | mtdoffset = xstrtou(opt_s, 0); |
143 | if (IS_NANDDUMP && (opts & OPT_l)) { | 138 | if (IS_NANDDUMP && (opts & OPT_l)) { |
144 | unsigned length = xstrtou(opt_l, 0); | 139 | unsigned length = xstrtou(opt_l, 0); |
@@ -153,6 +148,11 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) | |||
153 | bb_error_msg_and_die("start address is not page aligned"); | 148 | bb_error_msg_and_die("start address is not page aligned"); |
154 | 149 | ||
155 | filebuf = xmalloc(meminfo_writesize); | 150 | filebuf = xmalloc(meminfo_writesize); |
151 | oobbuf = xmalloc(meminfo.oobsize); | ||
152 | |||
153 | oob.start = 0; | ||
154 | oob.length = meminfo.oobsize; | ||
155 | oob.ptr = oobbuf; | ||
156 | 156 | ||
157 | blockstart = mtdoffset & ~(meminfo.erasesize - 1); | 157 | blockstart = mtdoffset & ~(meminfo.erasesize - 1); |
158 | if (blockstart != mtdoffset) { | 158 | if (blockstart != mtdoffset) { |
diff --git a/networking/nbd-client.c b/networking/nbd-client.c index 5ac190c32..8b856eda7 100644 --- a/networking/nbd-client.c +++ b/networking/nbd-client.c | |||
@@ -46,7 +46,9 @@ int nbdclient_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
46 | int nbdclient_main(int argc, char **argv) | 46 | int nbdclient_main(int argc, char **argv) |
47 | { | 47 | { |
48 | unsigned long timeout = 0; | 48 | unsigned long timeout = 0; |
49 | #if BB_MMU | ||
49 | int nofork = 0; | 50 | int nofork = 0; |
51 | #endif | ||
50 | char *host, *port, *device; | 52 | char *host, *port, *device; |
51 | struct nbd_header_t { | 53 | struct nbd_header_t { |
52 | uint64_t magic1; // "NBDMAGIC" | 54 | uint64_t magic1; // "NBDMAGIC" |
diff --git a/networking/ntpd.c b/networking/ntpd.c index ca4afa045..b7bd239b5 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -49,7 +49,7 @@ | |||
49 | /* High-level description of the algorithm: | 49 | /* High-level description of the algorithm: |
50 | * | 50 | * |
51 | * We start running with very small poll_exp, BURSTPOLL, | 51 | * We start running with very small poll_exp, BURSTPOLL, |
52 | * in order to quickly accumulate INITIAL_SAMLPES datapoints | 52 | * in order to quickly accumulate INITIAL_SAMPLES datapoints |
53 | * for each peer. Then, time is stepped if the offset is larger | 53 | * for each peer. Then, time is stepped if the offset is larger |
54 | * than STEP_THRESHOLD, otherwise it isn't; anyway, we enlarge | 54 | * than STEP_THRESHOLD, otherwise it isn't; anyway, we enlarge |
55 | * poll_exp to MINPOLL and enter frequency measurement step: | 55 | * poll_exp to MINPOLL and enter frequency measurement step: |
@@ -77,7 +77,7 @@ | |||
77 | 77 | ||
78 | #define RETRY_INTERVAL 5 /* on error, retry in N secs */ | 78 | #define RETRY_INTERVAL 5 /* on error, retry in N secs */ |
79 | #define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */ | 79 | #define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */ |
80 | #define INITIAL_SAMLPES 4 /* how many samples do we want for init */ | 80 | #define INITIAL_SAMPLES 4 /* how many samples do we want for init */ |
81 | 81 | ||
82 | /* Clock discipline parameters and constants */ | 82 | /* Clock discipline parameters and constants */ |
83 | 83 | ||
@@ -1972,14 +1972,14 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
1972 | idx2peer = xzalloc(sizeof(idx2peer[0]) * cnt); | 1972 | idx2peer = xzalloc(sizeof(idx2peer[0]) * cnt); |
1973 | pfd = xzalloc(sizeof(pfd[0]) * cnt); | 1973 | pfd = xzalloc(sizeof(pfd[0]) * cnt); |
1974 | 1974 | ||
1975 | /* Countdown: we never sync before we sent INITIAL_SAMLPES+1 | 1975 | /* Countdown: we never sync before we sent INITIAL_SAMPLES+1 |
1976 | * packets to each peer. | 1976 | * packets to each peer. |
1977 | * NB: if some peer is not responding, we may end up sending | 1977 | * NB: if some peer is not responding, we may end up sending |
1978 | * fewer packets to it and more to other peers. | 1978 | * fewer packets to it and more to other peers. |
1979 | * NB2: sync usually happens using INITIAL_SAMLPES packets, | 1979 | * NB2: sync usually happens using INITIAL_SAMPLES packets, |
1980 | * since last reply does not come back instantaneously. | 1980 | * since last reply does not come back instantaneously. |
1981 | */ | 1981 | */ |
1982 | cnt = G.peer_cnt * (INITIAL_SAMLPES + 1); | 1982 | cnt = G.peer_cnt * (INITIAL_SAMPLES + 1); |
1983 | 1983 | ||
1984 | while (!bb_got_signal) { | 1984 | while (!bb_got_signal) { |
1985 | llist_t *item; | 1985 | llist_t *item; |
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index b6b274d91..311f79e7e 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -68,9 +68,10 @@ const struct dhcp_optflag dhcp_optflags[] = { | |||
68 | { OPTION_IP , 0x32 }, /* DHCP_REQUESTED_IP */ | 68 | { OPTION_IP , 0x32 }, /* DHCP_REQUESTED_IP */ |
69 | { OPTION_U8 , 0x35 }, /* DHCP_MESSAGE_TYPE */ | 69 | { OPTION_U8 , 0x35 }, /* DHCP_MESSAGE_TYPE */ |
70 | { OPTION_U16 , 0x39 }, /* DHCP_MAX_SIZE */ | 70 | { OPTION_U16 , 0x39 }, /* DHCP_MAX_SIZE */ |
71 | { OPTION_STRING , 0x3c }, /* DHCP_VENDOR */ | 71 | //looks like these opts will work just fine even without these defs: |
72 | //FIXME: handling of this option is not exactly correct: | 72 | // { OPTION_STRING , 0x3c }, /* DHCP_VENDOR */ |
73 | { OPTION_STRING , 0x3d }, /* DHCP_CLIENT_ID */ | 73 | // /* not really a string: */ |
74 | // { OPTION_STRING , 0x3d }, /* DHCP_CLIENT_ID */ | ||
74 | { 0, 0 } /* zeroed terminating entry */ | 75 | { 0, 0 } /* zeroed terminating entry */ |
75 | }; | 76 | }; |
76 | 77 | ||
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 9020b9c96..f8f18ff01 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -63,14 +63,14 @@ struct udp_dhcp_packet { | |||
63 | } PACKED; | 63 | } PACKED; |
64 | 64 | ||
65 | enum { | 65 | enum { |
66 | IP_UPD_DHCP_SIZE = sizeof(struct ip_udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, | 66 | IP_UDP_DHCP_SIZE = sizeof(struct ip_udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, |
67 | UPD_DHCP_SIZE = sizeof(struct udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, | 67 | UDP_DHCP_SIZE = sizeof(struct udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, |
68 | DHCP_SIZE = sizeof(struct dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, | 68 | DHCP_SIZE = sizeof(struct dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | /* Let's see whether compiler understood us right */ | 71 | /* Let's see whether compiler understood us right */ |
72 | struct BUG_bad_sizeof_struct_ip_udp_dhcp_packet { | 72 | struct BUG_bad_sizeof_struct_ip_udp_dhcp_packet { |
73 | char c[IP_UPD_DHCP_SIZE == 576 ? 1 : -1]; | 73 | char c[IP_UDP_DHCP_SIZE == 576 ? 1 : -1]; |
74 | }; | 74 | }; |
75 | 75 | ||
76 | 76 | ||
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 27d6ad1a8..78aabedf2 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -346,31 +346,28 @@ static ALWAYS_INLINE uint32_t random_xid(void) | |||
346 | /* Initialize the packet with the proper defaults */ | 346 | /* Initialize the packet with the proper defaults */ |
347 | static void init_packet(struct dhcp_packet *packet, char type) | 347 | static void init_packet(struct dhcp_packet *packet, char type) |
348 | { | 348 | { |
349 | /* Fill in: op, htype, hlen, cookie fields; message type option: */ | ||
349 | udhcp_init_header(packet, type); | 350 | udhcp_init_header(packet, type); |
351 | |||
352 | packet->xid = random_xid(); | ||
353 | |||
350 | memcpy(packet->chaddr, client_config.client_mac, 6); | 354 | memcpy(packet->chaddr, client_config.client_mac, 6); |
351 | if (client_config.clientid) | 355 | if (client_config.clientid) |
352 | udhcp_add_binary_option(packet, client_config.clientid); | 356 | udhcp_add_binary_option(packet, client_config.clientid); |
353 | if (client_config.hostname) | ||
354 | udhcp_add_binary_option(packet, client_config.hostname); | ||
355 | if (client_config.fqdn) | ||
356 | udhcp_add_binary_option(packet, client_config.fqdn); | ||
357 | if (type != DHCPDECLINE | ||
358 | && type != DHCPRELEASE | ||
359 | && client_config.vendorclass | ||
360 | ) { | ||
361 | udhcp_add_binary_option(packet, client_config.vendorclass); | ||
362 | } | ||
363 | } | 357 | } |
364 | 358 | ||
365 | static void add_client_options(struct dhcp_packet *packet) | 359 | static void add_client_options(struct dhcp_packet *packet) |
366 | { | 360 | { |
361 | uint8_t c; | ||
362 | int i, end, len; | ||
363 | |||
364 | udhcp_add_simple_option(packet, DHCP_MAX_SIZE, htons(IP_UDP_DHCP_SIZE)); | ||
365 | |||
367 | /* Add a "param req" option with the list of options we'd like to have | 366 | /* Add a "param req" option with the list of options we'd like to have |
368 | * from stubborn DHCP servers. Pull the data from the struct in common.c. | 367 | * from stubborn DHCP servers. Pull the data from the struct in common.c. |
369 | * No bounds checking because it goes towards the head of the packet. */ | 368 | * No bounds checking because it goes towards the head of the packet. */ |
370 | uint8_t c; | 369 | end = udhcp_end_option(packet->options); |
371 | int end = udhcp_end_option(packet->options); | 370 | len = 0; |
372 | int i, len = 0; | ||
373 | |||
374 | for (i = 0; (c = dhcp_optflags[i].code) != 0; i++) { | 371 | for (i = 0; (c = dhcp_optflags[i].code) != 0; i++) { |
375 | if (( (dhcp_optflags[i].flags & OPTION_REQ) | 372 | if (( (dhcp_optflags[i].flags & OPTION_REQ) |
376 | && !client_config.no_default_options | 373 | && !client_config.no_default_options |
@@ -387,6 +384,13 @@ static void add_client_options(struct dhcp_packet *packet) | |||
387 | packet->options[end + OPT_DATA + len] = DHCP_END; | 384 | packet->options[end + OPT_DATA + len] = DHCP_END; |
388 | } | 385 | } |
389 | 386 | ||
387 | if (client_config.vendorclass) | ||
388 | udhcp_add_binary_option(packet, client_config.vendorclass); | ||
389 | if (client_config.hostname) | ||
390 | udhcp_add_binary_option(packet, client_config.hostname); | ||
391 | if (client_config.fqdn) | ||
392 | udhcp_add_binary_option(packet, client_config.fqdn); | ||
393 | |||
390 | /* Add -x options if any */ | 394 | /* Add -x options if any */ |
391 | { | 395 | { |
392 | struct option_set *curr = client_config.options; | 396 | struct option_set *curr = client_config.options; |
@@ -428,17 +432,25 @@ static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet) | |||
428 | } | 432 | } |
429 | 433 | ||
430 | /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ | 434 | /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ |
431 | static int send_discover(uint32_t xid, uint32_t requested) | 435 | /* NOINLINE: limit stack usage in caller */ |
436 | static NOINLINE int send_discover(uint32_t xid, uint32_t requested) | ||
432 | { | 437 | { |
433 | struct dhcp_packet packet; | 438 | struct dhcp_packet packet; |
434 | 439 | ||
440 | /* Fill in: op, htype, hlen, cookie, chaddr fields, | ||
441 | * random xid field (we override it below), | ||
442 | * client-id option (unless -C), message type option: | ||
443 | */ | ||
435 | init_packet(&packet, DHCPDISCOVER); | 444 | init_packet(&packet, DHCPDISCOVER); |
445 | |||
436 | packet.xid = xid; | 446 | packet.xid = xid; |
437 | if (requested) | 447 | if (requested) |
438 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); | 448 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); |
439 | /* Explicitly saying that we want RFC-compliant packets helps | 449 | |
440 | * some buggy DHCP servers to NOT send bigger packets */ | 450 | /* Add options: maxsize, |
441 | udhcp_add_simple_option(&packet, DHCP_MAX_SIZE, htons(576)); | 451 | * optionally: hostname, fqdn, vendorclass, |
452 | * "param req" option according to -O, options specified with -x | ||
453 | */ | ||
442 | add_client_options(&packet); | 454 | add_client_options(&packet); |
443 | 455 | ||
444 | bb_info_msg("Sending discover..."); | 456 | bb_info_msg("Sending discover..."); |
@@ -449,15 +461,39 @@ static int send_discover(uint32_t xid, uint32_t requested) | |||
449 | /* RFC 2131 3.1 paragraph 3: | 461 | /* RFC 2131 3.1 paragraph 3: |
450 | * "The client _broadcasts_ a DHCPREQUEST message..." | 462 | * "The client _broadcasts_ a DHCPREQUEST message..." |
451 | */ | 463 | */ |
452 | static int send_select(uint32_t xid, uint32_t server, uint32_t requested) | 464 | /* NOINLINE: limit stack usage in caller */ |
465 | static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requested) | ||
453 | { | 466 | { |
454 | struct dhcp_packet packet; | 467 | struct dhcp_packet packet; |
455 | struct in_addr addr; | 468 | struct in_addr addr; |
456 | 469 | ||
470 | /* | ||
471 | * RFC 2131 4.3.2 DHCPREQUEST message | ||
472 | * ... | ||
473 | * If the DHCPREQUEST message contains a 'server identifier' | ||
474 | * option, the message is in response to a DHCPOFFER message. | ||
475 | * Otherwise, the message is a request to verify or extend an | ||
476 | * existing lease. If the client uses a 'client identifier' | ||
477 | * in a DHCPREQUEST message, it MUST use that same 'client identifier' | ||
478 | * in all subsequent messages. If the client included a list | ||
479 | * of requested parameters in a DHCPDISCOVER message, it MUST | ||
480 | * include that list in all subsequent messages. | ||
481 | */ | ||
482 | /* Fill in: op, htype, hlen, cookie, chaddr fields, | ||
483 | * random xid field (we override it below), | ||
484 | * client-id option (unless -C), message type option: | ||
485 | */ | ||
457 | init_packet(&packet, DHCPREQUEST); | 486 | init_packet(&packet, DHCPREQUEST); |
487 | |||
458 | packet.xid = xid; | 488 | packet.xid = xid; |
459 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); | 489 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); |
490 | |||
460 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); | 491 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
492 | |||
493 | /* Add options: maxsize, | ||
494 | * optionally: hostname, fqdn, vendorclass, | ||
495 | * "param req" option according to -O, and options specified with -x | ||
496 | */ | ||
461 | add_client_options(&packet); | 497 | add_client_options(&packet); |
462 | 498 | ||
463 | addr.s_addr = requested; | 499 | addr.s_addr = requested; |
@@ -466,13 +502,38 @@ static int send_select(uint32_t xid, uint32_t server, uint32_t requested) | |||
466 | } | 502 | } |
467 | 503 | ||
468 | /* Unicast or broadcast a DHCP renew message */ | 504 | /* Unicast or broadcast a DHCP renew message */ |
469 | static int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | 505 | /* NOINLINE: limit stack usage in caller */ |
506 | static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | ||
470 | { | 507 | { |
471 | struct dhcp_packet packet; | 508 | struct dhcp_packet packet; |
472 | 509 | ||
510 | /* | ||
511 | * RFC 2131 4.3.2 DHCPREQUEST message | ||
512 | * ... | ||
513 | * DHCPREQUEST generated during RENEWING state: | ||
514 | * | ||
515 | * 'server identifier' MUST NOT be filled in, 'requested IP address' | ||
516 | * option MUST NOT be filled in, 'ciaddr' MUST be filled in with | ||
517 | * client's IP address. In this situation, the client is completely | ||
518 | * configured, and is trying to extend its lease. This message will | ||
519 | * be unicast, so no relay agents will be involved in its | ||
520 | * transmission. Because 'giaddr' is therefore not filled in, the | ||
521 | * DHCP server will trust the value in 'ciaddr', and use it when | ||
522 | * replying to the client. | ||
523 | */ | ||
524 | /* Fill in: op, htype, hlen, cookie, chaddr fields, | ||
525 | * random xid field (we override it below), | ||
526 | * client-id option (unless -C), message type option: | ||
527 | */ | ||
473 | init_packet(&packet, DHCPREQUEST); | 528 | init_packet(&packet, DHCPREQUEST); |
529 | |||
474 | packet.xid = xid; | 530 | packet.xid = xid; |
475 | packet.ciaddr = ciaddr; | 531 | packet.ciaddr = ciaddr; |
532 | |||
533 | /* Add options: maxsize, | ||
534 | * optionally: hostname, fqdn, vendorclass, | ||
535 | * "param req" option according to -O, and options specified with -x | ||
536 | */ | ||
476 | add_client_options(&packet); | 537 | add_client_options(&packet); |
477 | 538 | ||
478 | bb_info_msg("Sending renew..."); | 539 | bb_info_msg("Sending renew..."); |
@@ -485,13 +546,25 @@ static int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | |||
485 | 546 | ||
486 | #if ENABLE_FEATURE_UDHCPC_ARPING | 547 | #if ENABLE_FEATURE_UDHCPC_ARPING |
487 | /* Broadcast a DHCP decline message */ | 548 | /* Broadcast a DHCP decline message */ |
488 | static int send_decline(uint32_t xid, uint32_t server, uint32_t requested) | 549 | /* NOINLINE: limit stack usage in caller */ |
550 | static NOINLINE int send_decline(uint32_t xid, uint32_t server, uint32_t requested) | ||
489 | { | 551 | { |
490 | struct dhcp_packet packet; | 552 | struct dhcp_packet packet; |
491 | 553 | ||
554 | /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields, | ||
555 | * client-id option (unless -C), message type option: | ||
556 | */ | ||
492 | init_packet(&packet, DHCPDECLINE); | 557 | init_packet(&packet, DHCPDECLINE); |
558 | |||
559 | /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client, | ||
560 | * but in case the server is buggy and wants DHCPDECLINE's xid | ||
561 | * to match the xid which started entire handshake, | ||
562 | * we use the same xid we used in initial DHCPDISCOVER: | ||
563 | */ | ||
493 | packet.xid = xid; | 564 | packet.xid = xid; |
565 | /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */ | ||
494 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); | 566 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); |
567 | |||
495 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); | 568 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
496 | 569 | ||
497 | bb_info_msg("Sending decline..."); | 570 | bb_info_msg("Sending decline..."); |
@@ -504,8 +577,12 @@ static int send_release(uint32_t server, uint32_t ciaddr) | |||
504 | { | 577 | { |
505 | struct dhcp_packet packet; | 578 | struct dhcp_packet packet; |
506 | 579 | ||
580 | /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields, | ||
581 | * client-id option (unless -C), message type option: | ||
582 | */ | ||
507 | init_packet(&packet, DHCPRELEASE); | 583 | init_packet(&packet, DHCPRELEASE); |
508 | packet.xid = random_xid(); | 584 | |
585 | /* DHCPRELEASE uses ciaddr, not "requested ip", to store IP being released */ | ||
509 | packet.ciaddr = ciaddr; | 586 | packet.ciaddr = ciaddr; |
510 | 587 | ||
511 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); | 588 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
@@ -515,6 +592,7 @@ static int send_release(uint32_t server, uint32_t ciaddr) | |||
515 | } | 592 | } |
516 | 593 | ||
517 | /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */ | 594 | /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */ |
595 | /* NOINLINE: limit stack usage in caller */ | ||
518 | static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) | 596 | static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) |
519 | { | 597 | { |
520 | int bytes; | 598 | int bytes; |
@@ -765,12 +843,97 @@ static void client_background(void) | |||
765 | } | 843 | } |
766 | #endif | 844 | #endif |
767 | 845 | ||
846 | //usage:#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | ||
847 | //usage:# define IF_UDHCP_VERBOSE(...) __VA_ARGS__ | ||
848 | //usage:#else | ||
849 | //usage:# define IF_UDHCP_VERBOSE(...) | ||
850 | //usage:#endif | ||
851 | //usage:#define udhcpc_trivial_usage | ||
852 | //usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCR] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" | ||
853 | //usage: " [-H HOSTNAME] [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") | ||
854 | //usage:#define udhcpc_full_usage "\n" | ||
855 | //usage: IF_LONG_OPTS( | ||
856 | //usage: "\n -i,--interface IFACE Interface to use (default eth0)" | ||
857 | //usage: "\n -p,--pidfile FILE Create pidfile" | ||
858 | //usage: "\n -s,--script PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" | ||
859 | //usage: "\n -t,--retries N Send up to N discover packets" | ||
860 | //usage: "\n -T,--timeout N Pause between packets (default 3 seconds)" | ||
861 | //usage: "\n -A,--tryagain N Wait N seconds after failure (default 20)" | ||
862 | //usage: "\n -f,--foreground Run in foreground" | ||
863 | //usage: USE_FOR_MMU( | ||
864 | //usage: "\n -b,--background Background if lease is not obtained" | ||
865 | //usage: ) | ||
866 | //usage: "\n -n,--now Exit if lease is not obtained" | ||
867 | //usage: "\n -q,--quit Exit after obtaining lease" | ||
868 | //usage: "\n -R,--release Release IP on exit" | ||
869 | //usage: "\n -S,--syslog Log to syslog too" | ||
870 | //usage: IF_FEATURE_UDHCP_PORT( | ||
871 | //usage: "\n -P,--client-port N Use port N (default 68)" | ||
872 | //usage: ) | ||
873 | //usage: IF_FEATURE_UDHCPC_ARPING( | ||
874 | //usage: "\n -a,--arping Use arping to validate offered address" | ||
875 | //usage: ) | ||
876 | //usage: "\n -O,--request-option OPT Request option OPT from server (cumulative)" | ||
877 | //usage: "\n -o,--no-default-options Don't request any options (unless -O is given)" | ||
878 | //usage: "\n -r,--request IP Request this IP address" | ||
879 | //usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)" | ||
880 | //usage: "\n Examples of string, numeric, and hex byte opts:" | ||
881 | //usage: "\n -x hostname:bbox - option 12" | ||
882 | //usage: "\n -x lease:3600 - option 51 (lease time)" | ||
883 | //usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)" | ||
884 | //usage: "\n -F,--fqdn NAME Ask server to update DNS mapping for NAME" | ||
885 | //usage: "\n -H,-h,--hostname NAME Send NAME as client hostname (default none)" | ||
886 | //usage: "\n -V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')" | ||
887 | //usage: "\n -C,--clientid-none Don't send MAC as client identifier" | ||
888 | //usage: IF_UDHCP_VERBOSE( | ||
889 | //usage: "\n -v Verbose" | ||
890 | //usage: ) | ||
891 | //usage: ) | ||
892 | //usage: IF_NOT_LONG_OPTS( | ||
893 | //usage: "\n -i IFACE Interface to use (default eth0)" | ||
894 | //usage: "\n -p FILE Create pidfile" | ||
895 | //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" | ||
896 | //usage: "\n -t N Send up to N discover packets" | ||
897 | //usage: "\n -T N Pause between packets (default 3 seconds)" | ||
898 | //usage: "\n -A N Wait N seconds (default 20) after failure" | ||
899 | //usage: "\n -f Run in foreground" | ||
900 | //usage: USE_FOR_MMU( | ||
901 | //usage: "\n -b Background if lease is not obtained" | ||
902 | //usage: ) | ||
903 | //usage: "\n -n Exit if lease is not obtained" | ||
904 | //usage: "\n -q Exit after obtaining lease" | ||
905 | //usage: "\n -R Release IP on exit" | ||
906 | //usage: "\n -S Log to syslog too" | ||
907 | //usage: IF_FEATURE_UDHCP_PORT( | ||
908 | //usage: "\n -P N Use port N (default 68)" | ||
909 | //usage: ) | ||
910 | //usage: IF_FEATURE_UDHCPC_ARPING( | ||
911 | //usage: "\n -a Use arping to validate offered address" | ||
912 | //usage: ) | ||
913 | //usage: "\n -O OPT Request option OPT from server (cumulative)" | ||
914 | //usage: "\n -o Don't request any options (unless -O is given)" | ||
915 | //usage: "\n -r IP Request this IP address" | ||
916 | //usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)" | ||
917 | //usage: "\n Examples of string, numeric, and hex byte opts:" | ||
918 | //usage: "\n -x hostname:bbox - option 12" | ||
919 | //usage: "\n -x lease:3600 - option 51 (lease time)" | ||
920 | //usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)" | ||
921 | //usage: "\n -F NAME Ask server to update DNS mapping for NAME" | ||
922 | //usage: "\n -H,-h NAME Send NAME as client hostname (default none)" | ||
923 | //usage: "\n -V VENDOR Vendor identifier (default 'udhcp VERSION')" | ||
924 | //usage: "\n -C Don't send MAC as client identifier" | ||
925 | //usage: IF_UDHCP_VERBOSE( | ||
926 | //usage: "\n -v Verbose" | ||
927 | //usage: ) | ||
928 | //usage: ) | ||
929 | |||
768 | int udhcpc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 930 | int udhcpc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
769 | int udhcpc_main(int argc UNUSED_PARAM, char **argv) | 931 | int udhcpc_main(int argc UNUSED_PARAM, char **argv) |
770 | { | 932 | { |
771 | uint8_t *temp, *message; | 933 | uint8_t *temp, *message; |
772 | const char *str_c, *str_V, *str_h, *str_F, *str_r; | 934 | const char *str_V, *str_h, *str_F, *str_r; |
773 | IF_FEATURE_UDHCP_PORT(char *str_P;) | 935 | IF_FEATURE_UDHCP_PORT(char *str_P;) |
936 | void *clientid_mac_ptr; | ||
774 | llist_t *list_O = NULL; | 937 | llist_t *list_O = NULL; |
775 | llist_t *list_x = NULL; | 938 | llist_t *list_x = NULL; |
776 | int tryagain_timeout = 20; | 939 | int tryagain_timeout = 20; |
@@ -792,7 +955,6 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
792 | 955 | ||
793 | #if ENABLE_LONG_OPTS | 956 | #if ENABLE_LONG_OPTS |
794 | static const char udhcpc_longopts[] ALIGN1 = | 957 | static const char udhcpc_longopts[] ALIGN1 = |
795 | "clientid\0" Required_argument "c" | ||
796 | "clientid-none\0" No_argument "C" | 958 | "clientid-none\0" No_argument "C" |
797 | "vendorclass\0" Required_argument "V" | 959 | "vendorclass\0" Required_argument "V" |
798 | "hostname\0" Required_argument "H" | 960 | "hostname\0" Required_argument "H" |
@@ -818,29 +980,28 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
818 | ; | 980 | ; |
819 | #endif | 981 | #endif |
820 | enum { | 982 | enum { |
821 | OPT_c = 1 << 0, | 983 | OPT_C = 1 << 0, |
822 | OPT_C = 1 << 1, | 984 | OPT_V = 1 << 1, |
823 | OPT_V = 1 << 2, | 985 | OPT_H = 1 << 2, |
824 | OPT_H = 1 << 3, | 986 | OPT_h = 1 << 3, |
825 | OPT_h = 1 << 4, | 987 | OPT_F = 1 << 4, |
826 | OPT_F = 1 << 5, | 988 | OPT_i = 1 << 5, |
827 | OPT_i = 1 << 6, | 989 | OPT_n = 1 << 6, |
828 | OPT_n = 1 << 7, | 990 | OPT_p = 1 << 7, |
829 | OPT_p = 1 << 8, | 991 | OPT_q = 1 << 8, |
830 | OPT_q = 1 << 9, | 992 | OPT_R = 1 << 9, |
831 | OPT_R = 1 << 10, | 993 | OPT_r = 1 << 10, |
832 | OPT_r = 1 << 11, | 994 | OPT_s = 1 << 11, |
833 | OPT_s = 1 << 12, | 995 | OPT_T = 1 << 12, |
834 | OPT_T = 1 << 13, | 996 | OPT_t = 1 << 13, |
835 | OPT_t = 1 << 14, | 997 | OPT_S = 1 << 14, |
836 | OPT_S = 1 << 15, | 998 | OPT_A = 1 << 15, |
837 | OPT_A = 1 << 16, | 999 | OPT_O = 1 << 16, |
838 | OPT_O = 1 << 17, | 1000 | OPT_o = 1 << 17, |
839 | OPT_o = 1 << 18, | 1001 | OPT_x = 1 << 18, |
840 | OPT_x = 1 << 19, | 1002 | OPT_f = 1 << 19, |
841 | OPT_f = 1 << 20, | ||
842 | /* The rest has variable bit positions, need to be clever */ | 1003 | /* The rest has variable bit positions, need to be clever */ |
843 | OPTBIT_f = 20, | 1004 | OPTBIT_f = 19, |
844 | USE_FOR_MMU( OPTBIT_b,) | 1005 | USE_FOR_MMU( OPTBIT_b,) |
845 | IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,) | 1006 | IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,) |
846 | IF_FEATURE_UDHCP_PORT( OPTBIT_P,) | 1007 | IF_FEATURE_UDHCP_PORT( OPTBIT_P,) |
@@ -849,7 +1010,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
849 | IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) | 1010 | IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) |
850 | }; | 1011 | }; |
851 | 1012 | ||
852 | /* Default options. */ | 1013 | /* Default options */ |
853 | IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) | 1014 | IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) |
854 | IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) | 1015 | IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) |
855 | client_config.interface = "eth0"; | 1016 | client_config.interface = "eth0"; |
@@ -857,19 +1018,19 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
857 | str_V = "udhcp "BB_VER; | 1018 | str_V = "udhcp "BB_VER; |
858 | 1019 | ||
859 | /* Parse command line */ | 1020 | /* Parse command line */ |
860 | /* Cc: mutually exclusive; O,x: list; -T,-t,-A take numeric param */ | 1021 | /* O,x: list; -T,-t,-A take numeric param */ |
861 | opt_complementary = "c--C:C--c:O::x::T+:t+:A+" | 1022 | opt_complementary = "O::x::T+:t+:A+" |
862 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | 1023 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 |
863 | ":vv" | 1024 | ":vv" |
864 | #endif | 1025 | #endif |
865 | ; | 1026 | ; |
866 | IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) | 1027 | IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) |
867 | opt = getopt32(argv, "c:CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:f" | 1028 | opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:f" |
868 | USE_FOR_MMU("b") | 1029 | USE_FOR_MMU("b") |
869 | IF_FEATURE_UDHCPC_ARPING("a") | 1030 | IF_FEATURE_UDHCPC_ARPING("a") |
870 | IF_FEATURE_UDHCP_PORT("P:") | 1031 | IF_FEATURE_UDHCP_PORT("P:") |
871 | "v" | 1032 | "v" |
872 | , &str_c, &str_V, &str_h, &str_h, &str_F | 1033 | , &str_V, &str_h, &str_h, &str_F |
873 | , &client_config.interface, &client_config.pidfile, &str_r /* i,p */ | 1034 | , &client_config.interface, &client_config.pidfile, &str_r /* i,p */ |
874 | , &client_config.script /* s */ | 1035 | , &client_config.script /* s */ |
875 | , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ | 1036 | , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ |
@@ -931,13 +1092,13 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
931 | return 1; | 1092 | return 1; |
932 | } | 1093 | } |
933 | 1094 | ||
934 | if (opt & OPT_c) { | 1095 | clientid_mac_ptr = NULL; |
935 | client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, str_c, 0); | 1096 | if (!(opt & OPT_C) && !udhcp_find_option(client_config.options, DHCP_CLIENT_ID)) { |
936 | } else if (!(opt & OPT_C)) { | 1097 | /* not suppressed and not set, set the default client ID */ |
937 | /* not set and not suppressed, set the default client ID */ | ||
938 | client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7); | 1098 | client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7); |
939 | client_config.clientid[OPT_DATA] = 1; /* type: ethernet */ | 1099 | client_config.clientid[OPT_DATA] = 1; /* type: ethernet */ |
940 | memcpy(client_config.clientid + OPT_DATA+1, client_config.client_mac, 6); | 1100 | clientid_mac_ptr = client_config.clientid + OPT_DATA+1; |
1101 | memcpy(clientid_mac_ptr, client_config.client_mac, 6); | ||
941 | } | 1102 | } |
942 | if (str_V[0] != '\0') | 1103 | if (str_V[0] != '\0') |
943 | client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); | 1104 | client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); |
@@ -1015,6 +1176,21 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1015 | * resend discover/renew/whatever | 1176 | * resend discover/renew/whatever |
1016 | */ | 1177 | */ |
1017 | if (retval == 0) { | 1178 | if (retval == 0) { |
1179 | /* When running on a bridge, the ifindex may have changed | ||
1180 | * (e.g. if member interfaces were added/removed | ||
1181 | * or if the status of the bridge changed). | ||
1182 | * Refresh ifindex and client_mac: | ||
1183 | */ | ||
1184 | if (udhcp_read_interface(client_config.interface, | ||
1185 | &client_config.ifindex, | ||
1186 | NULL, | ||
1187 | client_config.client_mac) | ||
1188 | ) { | ||
1189 | return 1; /* iface is gone? */ | ||
1190 | } | ||
1191 | if (clientid_mac_ptr) | ||
1192 | memcpy(clientid_mac_ptr, client_config.client_mac, 6); | ||
1193 | |||
1018 | /* We will restart the wait in any case */ | 1194 | /* We will restart the wait in any case */ |
1019 | already_waited_sec = 0; | 1195 | already_waited_sec = 0; |
1020 | 1196 | ||
@@ -1174,7 +1350,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1174 | 1350 | ||
1175 | /* Ignore packets that aren't for us */ | 1351 | /* Ignore packets that aren't for us */ |
1176 | if (packet.hlen != 6 | 1352 | if (packet.hlen != 6 |
1177 | || memcmp(packet.chaddr, client_config.client_mac, 6) | 1353 | || memcmp(packet.chaddr, client_config.client_mac, 6) != 0 |
1178 | ) { | 1354 | ) { |
1179 | //FIXME: need to also check that last 10 bytes are zero | 1355 | //FIXME: need to also check that last 10 bytes are zero |
1180 | log1("chaddr does not match, ignoring packet"); // log2? | 1356 | log1("chaddr does not match, ignoring packet"); // log2? |
@@ -1194,13 +1370,13 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1194 | /* TODO: why we don't just fetch server's IP from IP header? */ | 1370 | /* TODO: why we don't just fetch server's IP from IP header? */ |
1195 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); | 1371 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); |
1196 | if (!temp) { | 1372 | if (!temp) { |
1197 | bb_error_msg("no server ID in message"); | 1373 | bb_error_msg("no server ID, ignoring packet"); |
1198 | continue; | 1374 | continue; |
1199 | /* still selecting - this server looks bad */ | 1375 | /* still selecting - this server looks bad */ |
1200 | } | 1376 | } |
1201 | /* it IS unaligned sometimes, don't "optimize" */ | 1377 | /* it IS unaligned sometimes, don't "optimize" */ |
1202 | move_from_unaligned32(server_addr, temp); | 1378 | move_from_unaligned32(server_addr, temp); |
1203 | xid = packet.xid; | 1379 | /*xid = packet.xid; - already is */ |
1204 | requested_ip = packet.yiaddr; | 1380 | requested_ip = packet.yiaddr; |
1205 | 1381 | ||
1206 | /* enter requesting state */ | 1382 | /* enter requesting state */ |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 043220de9..f0878652c 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
@@ -132,7 +132,8 @@ static uint32_t select_lease_time(struct dhcp_packet *packet) | |||
132 | } | 132 | } |
133 | 133 | ||
134 | /* We got a DHCP DISCOVER. Send an OFFER. */ | 134 | /* We got a DHCP DISCOVER. Send an OFFER. */ |
135 | static void send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, struct dyn_lease *lease) | 135 | /* NOINLINE: limit stack usage in caller */ |
136 | static NOINLINE void send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, struct dyn_lease *lease) | ||
136 | { | 137 | { |
137 | struct dhcp_packet packet; | 138 | struct dhcp_packet packet; |
138 | uint32_t lease_time_sec; | 139 | uint32_t lease_time_sec; |
@@ -202,7 +203,8 @@ static void send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, | |||
202 | send_packet(&packet, /*force_bcast:*/ 0); | 203 | send_packet(&packet, /*force_bcast:*/ 0); |
203 | } | 204 | } |
204 | 205 | ||
205 | static void send_NAK(struct dhcp_packet *oldpacket) | 206 | /* NOINLINE: limit stack usage in caller */ |
207 | static NOINLINE void send_NAK(struct dhcp_packet *oldpacket) | ||
206 | { | 208 | { |
207 | struct dhcp_packet packet; | 209 | struct dhcp_packet packet; |
208 | 210 | ||
@@ -212,7 +214,8 @@ static void send_NAK(struct dhcp_packet *oldpacket) | |||
212 | send_packet(&packet, /*force_bcast:*/ 1); | 214 | send_packet(&packet, /*force_bcast:*/ 1); |
213 | } | 215 | } |
214 | 216 | ||
215 | static void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) | 217 | /* NOINLINE: limit stack usage in caller */ |
218 | static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) | ||
216 | { | 219 | { |
217 | struct dhcp_packet packet; | 220 | struct dhcp_packet packet; |
218 | uint32_t lease_time_sec; | 221 | uint32_t lease_time_sec; |
@@ -243,7 +246,8 @@ static void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) | |||
243 | } | 246 | } |
244 | } | 247 | } |
245 | 248 | ||
246 | static void send_inform(struct dhcp_packet *oldpacket) | 249 | /* NOINLINE: limit stack usage in caller */ |
250 | static NOINLINE void send_inform(struct dhcp_packet *oldpacket) | ||
247 | { | 251 | { |
248 | struct dhcp_packet packet; | 252 | struct dhcp_packet packet; |
249 | 253 | ||
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index d8f9c5daa..2b7528cc7 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c | |||
@@ -216,19 +216,19 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, | |||
216 | packet.udp.source = htons(source_port); | 216 | packet.udp.source = htons(source_port); |
217 | packet.udp.dest = htons(dest_port); | 217 | packet.udp.dest = htons(dest_port); |
218 | /* size, excluding IP header: */ | 218 | /* size, excluding IP header: */ |
219 | packet.udp.len = htons(UPD_DHCP_SIZE - padding); | 219 | packet.udp.len = htons(UDP_DHCP_SIZE - padding); |
220 | /* for UDP checksumming, ip.len is set to UDP packet len */ | 220 | /* for UDP checksumming, ip.len is set to UDP packet len */ |
221 | packet.ip.tot_len = packet.udp.len; | 221 | packet.ip.tot_len = packet.udp.len; |
222 | packet.udp.check = udhcp_checksum(&packet, IP_UPD_DHCP_SIZE - padding); | 222 | packet.udp.check = udhcp_checksum(&packet, IP_UDP_DHCP_SIZE - padding); |
223 | /* but for sending, it is set to IP packet len */ | 223 | /* but for sending, it is set to IP packet len */ |
224 | packet.ip.tot_len = htons(IP_UPD_DHCP_SIZE - padding); | 224 | packet.ip.tot_len = htons(IP_UDP_DHCP_SIZE - padding); |
225 | packet.ip.ihl = sizeof(packet.ip) >> 2; | 225 | packet.ip.ihl = sizeof(packet.ip) >> 2; |
226 | packet.ip.version = IPVERSION; | 226 | packet.ip.version = IPVERSION; |
227 | packet.ip.ttl = IPDEFTTL; | 227 | packet.ip.ttl = IPDEFTTL; |
228 | packet.ip.check = udhcp_checksum(&packet.ip, sizeof(packet.ip)); | 228 | packet.ip.check = udhcp_checksum(&packet.ip, sizeof(packet.ip)); |
229 | 229 | ||
230 | udhcp_dump_packet(dhcp_pkt); | 230 | udhcp_dump_packet(dhcp_pkt); |
231 | result = sendto(fd, &packet, IP_UPD_DHCP_SIZE - padding, /*flags:*/ 0, | 231 | result = sendto(fd, &packet, IP_UDP_DHCP_SIZE - padding, /*flags:*/ 0, |
232 | (struct sockaddr *) &dest_sll, sizeof(dest_sll)); | 232 | (struct sockaddr *) &dest_sll, sizeof(dest_sll)); |
233 | msg = "sendto"; | 233 | msg = "sendto"; |
234 | ret_close: | 234 | ret_close: |
diff --git a/procps/pmap.c b/procps/pmap.c index cfa94ed82..bb5f9e7c2 100644 --- a/procps/pmap.c +++ b/procps/pmap.c | |||
@@ -44,7 +44,7 @@ enum { | |||
44 | 44 | ||
45 | static void print_smaprec(struct smaprec *currec, void *data) | 45 | static void print_smaprec(struct smaprec *currec, void *data) |
46 | { | 46 | { |
47 | unsigned opt = (unsigned)data; | 47 | unsigned opt = (uintptr_t)data; |
48 | 48 | ||
49 | printf("%0" AFMT "lx ", currec->smap_start); | 49 | printf("%0" AFMT "lx ", currec->smap_start); |
50 | 50 | ||
@@ -74,7 +74,7 @@ static int procps_get_maps(pid_t pid, unsigned opt) | |||
74 | 74 | ||
75 | memset(&total, 0, sizeof(total)); | 75 | memset(&total, 0, sizeof(total)); |
76 | 76 | ||
77 | ret = procps_read_smaps(pid, &total, print_smaprec, (void*)opt); | 77 | ret = procps_read_smaps(pid, &total, print_smaprec, (void*)(uintptr_t)opt); |
78 | if (ret) | 78 | if (ret) |
79 | return ret; | 79 | return ret; |
80 | 80 | ||
diff --git a/procps/smemcap.c b/procps/smemcap.c index f951a5fb6..196c91f54 100644 --- a/procps/smemcap.c +++ b/procps/smemcap.c | |||
@@ -125,5 +125,8 @@ int smemcap_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
125 | } | 125 | } |
126 | } | 126 | } |
127 | 127 | ||
128 | if (ENABLE_FEATURE_CLEAN_UP) | ||
129 | closedir(d); | ||
130 | |||
128 | return EXIT_SUCCESS; | 131 | return EXIT_SUCCESS; |
129 | } | 132 | } |
diff --git a/scripts/mkmakefile b/scripts/mkmakefile index 7f9d544f9..9fc51a7c9 100755 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile | |||
@@ -31,6 +31,9 @@ all: | |||
31 | 31 | ||
32 | Makefile:; | 32 | Makefile:; |
33 | 33 | ||
34 | \$(filter-out all Makefile,\$(MAKECMDGOALS)) %/: | 34 | \$(filter-out all Makefile,\$(MAKECMDGOALS)): |
35 | \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@ | ||
36 | |||
37 | %/: | ||
35 | \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@ | 38 | \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@ |
36 | EOF | 39 | EOF |
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index 6766b649d..0d4c2578d 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c | |||
@@ -132,7 +132,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) | |||
132 | int i = 0; | 132 | int i = 0; |
133 | char *opt_c; | 133 | char *opt_c; |
134 | int opt; | 134 | int opt; |
135 | int used = 0; | 135 | int used; |
136 | 136 | ||
137 | opt = getopt32(argv, "c:n", &opt_c); | 137 | opt = getopt32(argv, "c:n", &opt_c); |
138 | if (opt & OPT_LEVEL) { | 138 | if (opt & OPT_LEVEL) { |
@@ -159,6 +159,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) | |||
159 | 159 | ||
160 | syslog(LOG_NOTICE, "klogd started: %s", bb_banner); | 160 | syslog(LOG_NOTICE, "klogd started: %s", bb_banner); |
161 | 161 | ||
162 | used = 0; | ||
162 | while (!bb_got_signal) { | 163 | while (!bb_got_signal) { |
163 | int n; | 164 | int n; |
164 | int priority; | 165 | int priority; |
@@ -175,22 +176,22 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) | |||
175 | } | 176 | } |
176 | start[n] = '\0'; | 177 | start[n] = '\0'; |
177 | 178 | ||
178 | /* klogctl buffer parsing modelled after code in dmesg.c */ | ||
179 | /* Process each newline-terminated line in the buffer */ | 179 | /* Process each newline-terminated line in the buffer */ |
180 | start = log_buffer; | 180 | start = log_buffer; |
181 | while (1) { | 181 | while (1) { |
182 | char *newline = strchrnul(start, '\n'); | 182 | char *newline = strchrnul(start, '\n'); |
183 | 183 | ||
184 | if (*newline == '\0') { | 184 | if (*newline == '\0') { |
185 | /* This line is incomplete... */ | 185 | /* This line is incomplete */ |
186 | if (start != log_buffer) { | 186 | |
187 | /* move it to the front of the buffer */ | 187 | /* move it to the front of the buffer */ |
188 | overlapping_strcpy(log_buffer, start); | 188 | overlapping_strcpy(log_buffer, start); |
189 | used = newline - start; | 189 | used = newline - start; |
190 | /* don't log it yet */ | 190 | if (used < KLOGD_LOGBUF_SIZE-1) { |
191 | /* buffer isn't full */ | ||
191 | break; | 192 | break; |
192 | } | 193 | } |
193 | /* ...but if buffer is full, log it anyway */ | 194 | /* buffer is full, log it anyway */ |
194 | used = 0; | 195 | used = 0; |
195 | newline = NULL; | 196 | newline = NULL; |
196 | } else { | 197 | } else { |
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c index 06a03d3fb..6e43a22f5 100644 --- a/util-linux/dmesg.c +++ b/util-linux/dmesg.c | |||
@@ -45,20 +45,25 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv) | |||
45 | if (len == 0) | 45 | if (len == 0) |
46 | return EXIT_SUCCESS; | 46 | return EXIT_SUCCESS; |
47 | 47 | ||
48 | /* Skip <#> at the start of lines, and make sure we end with a newline */ | ||
49 | 48 | ||
50 | if (ENABLE_FEATURE_DMESG_PRETTY) { | 49 | if (ENABLE_FEATURE_DMESG_PRETTY) { |
51 | int last = '\n'; | 50 | int last = '\n'; |
52 | int in = 0; | 51 | int in = 0; |
53 | 52 | ||
54 | do { | 53 | /* Skip <#> at the start of lines */ |
55 | if (last == '\n' && buf[in] == '<') | 54 | while (1) { |
55 | if (last == '\n' && buf[in] == '<') { | ||
56 | in += 3; | 56 | in += 3; |
57 | else { | 57 | if (in >= len) |
58 | last = buf[in++]; | 58 | break; |
59 | bb_putchar(last); | ||
60 | } | 59 | } |
61 | } while (in < len); | 60 | last = buf[in]; |
61 | putchar(last); | ||
62 | in++; | ||
63 | if (in >= len) | ||
64 | break; | ||
65 | } | ||
66 | /* Make sure we end with a newline */ | ||
62 | if (last != '\n') | 67 | if (last != '\n') |
63 | bb_putchar('\n'); | 68 | bb_putchar('\n'); |
64 | } else { | 69 | } else { |