Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

external-toybox: Commit

external/toybox


Commit MetaInfo

Revision4c44317a7509c91658bd8ea80fcc27d8b2d2a809 (tree)
Time2018-02-09 04:45:15
AuthorElliott Hughes <enh@goog...>
Commiterandroid-build-merger

Log Message

Merge remote-tracking branch 'toybox/master' into HEAD am: b02120dad8 am: 7f1d01238d
am: ffcd050779

Change-Id: I9712e269013d40f33546584e35dbfb528c5e492d

Change Summary

Incremental Difference

--- a/.config
+++ b/.config
@@ -72,6 +72,7 @@ CONFIG_CPIO=y
7272 CONFIG_CP_MORE=y
7373 CONFIG_CP_PRESERVE=y
7474 CONFIG_CP=y
75+# CONFIG_CRC32 is not set
7576 # CONFIG_CROND is not set
7677 # CONFIG_CRONTAB is not set
7778 CONFIG_CUT=y
--- a/configure
+++ b/configure
@@ -1,7 +1,16 @@
1-# Toybox configuration file.
1+#!/bin/bash
22
33 # This sets environment variables used by scripts/make.sh
44
5+# People run ./configure out of habit, so do "defconfig" for them.
6+
7+if [ "$(basename "$0")" == configure ]
8+then
9+ echo "Assuming you want 'make defconfig', but you should probably check the README."
10+ make defconfig
11+ exit $?
12+fi
13+
514 # A synonym.
615 [ -z "$CROSS_COMPILE" ] && CROSS_COMPILE="$CROSS"
716
--- a/generated/config.h
+++ b/generated/config.h
@@ -118,6 +118,8 @@
118118 #define USE_CP_PRESERVE(...) __VA_ARGS__
119119 #define CFG_CP 1
120120 #define USE_CP(...) __VA_ARGS__
121+#define CFG_CRC32 0
122+#define USE_CRC32(...)
121123 #define CFG_CROND 0
122124 #define USE_CROND(...)
123125 #define CFG_CRONTAB 0
--- a/generated/flags.h
+++ b/generated/flags.h
@@ -375,6 +375,14 @@
375375 #undef FLAG_no_preserve_owner
376376 #endif
377377
378+// crc32
379+#undef OPTSTR_crc32
380+#define OPTSTR_crc32 0
381+#ifdef CLEANUP_crc32
382+#undef CLEANUP_crc32
383+#undef FOR_crc32
384+#endif
385+
378386 // crond fbSl#<0=8d#<0L:c:[-bf][-LS][-ld]
379387 #undef OPTSTR_crond
380388 #define OPTSTR_crond "fbSl#<0=8d#<0L:c:[-bf][-LS][-ld]"
@@ -1955,17 +1963,19 @@
19551963 #undef FLAG_s
19561964 #endif
19571965
1958-// ping <1>1t#<0>255c#<0s#<0>65535I:W#<0w#<0q46[-46]
1966+// ping <1>1t#<0>255=64c#<0=3s#<0>4088=56I:i:W#<0=10w#<0qf46[-46]
19591967 #undef OPTSTR_ping
1960-#define OPTSTR_ping "<1>1t#<0>255c#<0s#<0>65535I:W#<0w#<0q46[-46]"
1968+#define OPTSTR_ping "<1>1t#<0>255=64c#<0=3s#<0>4088=56I:i:W#<0=10w#<0qf46[-46]"
19611969 #ifdef CLEANUP_ping
19621970 #undef CLEANUP_ping
19631971 #undef FOR_ping
19641972 #undef FLAG_6
19651973 #undef FLAG_4
1974+#undef FLAG_f
19661975 #undef FLAG_q
19671976 #undef FLAG_w
19681977 #undef FLAG_W
1978+#undef FLAG_i
19691979 #undef FLAG_I
19701980 #undef FLAG_s
19711981 #undef FLAG_c
@@ -3572,6 +3582,12 @@
35723582 #define FLAG_no_preserve_owner (1<<11)
35733583 #endif
35743584
3585+#ifdef FOR_crc32
3586+#ifndef TT
3587+#define TT this.crc32
3588+#endif
3589+#endif
3590+
35753591 #ifdef FOR_crond
35763592 #ifndef TT
35773593 #define TT this.crond
@@ -4912,13 +4928,15 @@
49124928 #endif
49134929 #define FLAG_6 (FORCED_FLAG<<0)
49144930 #define FLAG_4 (FORCED_FLAG<<1)
4915-#define FLAG_q (FORCED_FLAG<<2)
4916-#define FLAG_w (FORCED_FLAG<<3)
4917-#define FLAG_W (FORCED_FLAG<<4)
4918-#define FLAG_I (FORCED_FLAG<<5)
4919-#define FLAG_s (FORCED_FLAG<<6)
4920-#define FLAG_c (FORCED_FLAG<<7)
4921-#define FLAG_t (FORCED_FLAG<<8)
4931+#define FLAG_f (FORCED_FLAG<<2)
4932+#define FLAG_q (FORCED_FLAG<<3)
4933+#define FLAG_w (FORCED_FLAG<<4)
4934+#define FLAG_W (FORCED_FLAG<<5)
4935+#define FLAG_i (FORCED_FLAG<<6)
4936+#define FLAG_I (FORCED_FLAG<<7)
4937+#define FLAG_s (FORCED_FLAG<<8)
4938+#define FLAG_c (FORCED_FLAG<<9)
4939+#define FLAG_t (FORCED_FLAG<<10)
49224940 #endif
49234941
49244942 #ifdef FOR_pivot_root
--- a/generated/globals.h
+++ b/generated/globals.h
@@ -765,14 +765,16 @@ struct openvt_data {
765765 // toys/pending/ping.c
766766
767767 struct ping_data {
768- long wait_exit;
769- long wait_resp;
770- char *iface;
771- long size;
772- long count;
773- long ttl;
768+ long w;
769+ long W;
770+ char *i;
771+ char *I;
772+ long s;
773+ long c;
774+ long t;
774775
775776 int sock;
777+ long i_ms;
776778 };
777779
778780 // toys/pending/route.c
--- a/generated/help.h
+++ b/generated/help.h
@@ -336,7 +336,7 @@
336336
337337 #define HELP_route "usage: route [-ne] [-A [46]] [add|del TARGET [OPTIONS]]\n\nDisplay, add or delete network routes in the \"Forwarding Information Base\".\n\n-n Show numerical addresses (no DNS lookups)\n-e display netstat fields\n\nRouting means sending packets out a network interface to an address.\nThe kernel can tell where to send packets one hop away by examining each\ninterface's address and netmask, so the most common use of this command\nis to identify a \"gateway\" that forwards other traffic.\n\nAssigning an address to an interface automatically creates an appropriate\nnetwork route (\"ifconfig eth0 10.0.2.15/8\" does \"route add 10.0.0.0/8 eth0\"\nfor you), although some devices (such as loopback) won't show it in the\ntable. For machines more than one hop away, you need to specify a gateway\n(ala \"route add default gw 10.0.2.2\").\n\nThe address \"default\" is a wildcard address (0.0.0.0/0) matching all\npackets without a more specific route.\n\nAvailable OPTIONS include:\nreject - blocking route (force match failure)\ndev NAME - force packets out this interface (ala \"eth0\")\nnetmask - old way of saying things like ADDR/24\ngw ADDR - forward packets to gateway ADDR\n\n\n"
338338
339-#define HELP_ping "usage: ping [OPTIONS] HOST\n\nCheck network connectivity by sending packets to a host and reporting\nits response.\n\nSend ICMP ECHO_REQUEST packets to ipv4 or ipv6 addresses and prints each\necho it receives back, with round trip time.\n\nOptions:\n-4, -6 Force IPv4 or IPv6\n-c CNT Send CNT many packets\n-I IFACE/IP Source interface or address\n-q Quiet, only displays output at start and when finished\n-s SIZE Packet SIZE in bytes (default 56)\n-t TTL Set Time (number of hops) To Live\n-W SEC Seconds to wait for response after all packets sent (default 10)\n-w SEC Exit after this many seconds\n\n"
339+#define HELP_ping "usage: ping [OPTIONS] HOST\n\nCheck network connectivity by sending packets to a host and reporting\nits response.\n\nSend ICMP ECHO_REQUEST packets to ipv4 or ipv6 addresses and prints each\necho it receives back, with round trip time. Returns true if host alive.\n\nOptions:\n-4, -6 Force IPv4 or IPv6\n-c CNT Send CNT many packets (default 3, 0 = infinite)\n-f Flood (. on send, backspace on receive, to show packet drops)\n-i TIME Interval between packets (default 1, need root for < .2)\n-I IFACE/IP Source interface or address\n-q Quiet (stops after one returns true if host is alive)\n-s SIZE Data SIZE in bytes (default 56)\n-t TTL Set Time To Live (number of hops)\n-W SEC Seconds to wait for response after -c (default 10)\n-w SEC Exit after this many seconds\n\n"
340340
341341 #define HELP_deallocvt "usage: deallocvt [N]\n\nDeallocate unused virtual terminal /dev/ttyN, or all unused consoles.\n\n"
342342
@@ -576,7 +576,9 @@
576576
577577 #define HELP_cmp "usage: cmp [-l] [-s] FILE1 FILE2\n\nCompare the contents of two files.\n\n-l show all differing bytes\n-s silent\n\n"
578578
579-#define HELP_cksum "usage: cksum [-IPLN] [file...]\n\nFor each file, output crc32 checksum value, length and name of file.\nIf no files listed, copy from stdin. Filename \"-\" is a synonym for stdin.\n\n-H Hexadecimal checksum (defaults to decimal)\n-L Little endian (defaults to big endian)\n-P Pre-inversion\n-I Skip post-inversion\n-N Do not include length in CRC calculation\n\n"
579+#define HELP_crc32 "usage: crc32 [file...]\n\nOutput crc32 checksum for each file.\n\n"
580+
581+#define HELP_cksum "usage: cksum [-IPLN] [file...]\n\nFor each file, output crc32 checksum value, length and name of file.\nIf no files listed, copy from stdin. Filename \"-\" is a synonym for stdin.\n\n-H Hexadecimal checksum (defaults to decimal)\n-L Little endian (defaults to big endian)\n-P Pre-inversion\n-I Skip post-inversion\n-N Do not include length in CRC calculation (or output)\n\n"
580582
581583 #define HELP_chmod "usage: chmod [-R] MODE FILE...\n\nChange mode of listed file[s] (recursively with -R).\n\nMODE can be (comma-separated) stanzas: [ugoa][+-=][rwxstXugo]\n\nStanzas are applied in order: For each category (u = user,\ng = group, o = other, a = all three, if none specified default is a),\nset (+), clear (-), or copy (=), r = read, w = write, x = execute.\ns = u+s = suid, g+s = sgid, o+s = sticky. (+t is an alias for o+s).\nsuid/sgid: execute as the user/group who owns the file.\nsticky: can't delete files you don't own out of this directory\nX = x for directories or if any category already has x set.\n\nOr MODE can be an octal value up to 7777 ug uuugggooo top +\nbit 1 = o+x, bit 1<<8 = u+w, 1<<11 = g+1 sstrwxrwxrwx bottom\n\nExamples:\nchmod u+w file - allow owner of \"file\" to write to it.\nchmod 744 file - user can read/write/execute, everyone else read only\n\n"
582584
--- a/generated/newtoys.h
+++ b/generated/newtoys.h
@@ -36,6 +36,7 @@ USE_COMPRESS(NEWTOY(compress, "zcd9lrg[-cd][!zgLr]", TOYFLAG_USR|TOYFLAG_BIN))
3636 USE_COUNT(NEWTOY(count, NULL, TOYFLAG_USR|TOYFLAG_BIN))
3737 USE_CP(NEWTOY(cp, "<2"USE_CP_PRESERVE("(preserve):;")"RHLPprdaslvnF(remove-destination)fi[-HLPd][-ni]", TOYFLAG_BIN))
3838 USE_CPIO(NEWTOY(cpio, "(no-preserve-owner)(trailer)mduH:p:|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
39+USE_CRC32(NEWTOY(crc32, 0, TOYFLAG_BIN))
3940 USE_CROND(NEWTOY(crond, "fbSl#<0=8d#<0L:c:[-bf][-LS][-ld]", TOYFLAG_USR|TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
4041 USE_CRONTAB(NEWTOY(crontab, "c:u:elr[!elr]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
4142 USE_CUT(NEWTOY(cut, "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]", TOYFLAG_USR|TOYFLAG_BIN))
@@ -172,7 +173,7 @@ USE_PASTE(NEWTOY(paste, "d:s", TOYFLAG_BIN|TOYFLAG_LOCALE))
172173 USE_PATCH(NEWTOY(patch, "(dry-run)"USE_TOYBOX_DEBUG("x")"d:ulp#i:R", TOYFLAG_USR|TOYFLAG_BIN))
173174 USE_PGREP(NEWTOY(pgrep, "?cld:u*U*t*s*P*g*G*fnovxL:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
174175 USE_PIDOF(NEWTOY(pidof, "<1so:", TOYFLAG_BIN))
175-USE_PING(NEWTOY(ping, "<1>1t#<0>255c#<0s#<0>65535I:W#<0w#<0q46[-46]", TOYFLAG_ROOTONLY|TOYFLAG_USR|TOYFLAG_BIN))
176+USE_PING(NEWTOY(ping, "<1>1t#<0>255=64c#<0=3s#<0>4088=56I:i:W#<0=10w#<0qf46[-46]", TOYFLAG_ROOTONLY|TOYFLAG_USR|TOYFLAG_BIN))
176177 USE_PIVOT_ROOT(NEWTOY(pivot_root, "<2>2", TOYFLAG_SBIN))
177178 USE_PKILL(NEWTOY(pkill, "?Vu*U*t*s*P*g*G*fnovxl:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
178179 USE_PMAP(NEWTOY(pmap, "<1xq", TOYFLAG_BIN))
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -294,6 +294,7 @@ struct addrinfo *xgetaddrinfo(char *host, char *port, int family, int socktype,
294294 int xconnect(struct addrinfo *ai_arg);
295295 int xpoll(struct pollfd *fds, int nfds, int timeout);
296296 int pollinate(int in1, int in2, int out1, int out2, int timeout, int shutdown_timeout);
297+char *ntop(struct sockaddr *sa);
297298
298299 // password.c
299300 int get_salt(char *salt, char * algo);
--- a/lib/net.c
+++ b/lib/net.c
@@ -102,3 +102,16 @@ int pollinate(int in1, int in2, int out1, int out2, int timeout, int shutdown_ti
102102 }
103103 }
104104 }
105+
106+// Return converted numeric address in libbuf
107+char *ntop(struct sockaddr *sa)
108+{
109+ void *addr;
110+
111+ if (sa->sa_family == AF_INET) addr = &((struct sockaddr_in *)sa)->sin_addr;
112+ else addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
113+
114+ inet_ntop(sa->sa_family, addr, libbuf, sizeof(libbuf));
115+
116+ return libbuf;
117+}
--- a/toys/pending/ping.c
+++ b/toys/pending/ping.c
@@ -3,8 +3,14 @@
33 * Copyright 2014 Rob Landley <rob@landley.net>
44 *
55 * Not in SUSv4.
6+ *
7+ * Note: ping_group_range should never have existed. To disable it, do:
8+ * echo 0 $(((1<<31)-1)) > /proc/sys/net/ipv4/ping_group_range
9+ * (Android does this by default in its init script.)
10+ *
11+ * Yes, I wimped out and capped -s at sizeof(toybuf), waiting for a complaint...
612
7-USE_PING(NEWTOY(ping, "<1>1t#<0>255c#<0s#<0>65535I:W#<0w#<0q46[-46]", TOYFLAG_ROOTONLY|TOYFLAG_USR|TOYFLAG_BIN))
13+USE_PING(NEWTOY(ping, "<1>1t#<0>255=64c#<0=3s#<0>4088=56I:i:W#<0=10w#<0qf46[-46]", TOYFLAG_ROOTONLY|TOYFLAG_USR|TOYFLAG_BIN))
814
915 config PING
1016 bool "ping"
@@ -16,16 +22,18 @@ config PING
1622 its response.
1723
1824 Send ICMP ECHO_REQUEST packets to ipv4 or ipv6 addresses and prints each
19- echo it receives back, with round trip time.
25+ echo it receives back, with round trip time. Returns true if host alive.
2026
2127 Options:
2228 -4, -6 Force IPv4 or IPv6
23- -c CNT Send CNT many packets
29+ -c CNT Send CNT many packets (default 3, 0 = infinite)
30+ -f Flood (. on send, backspace on receive, to show packet drops)
31+ -i TIME Interval between packets (default 1, need root for < .2)
2432 -I IFACE/IP Source interface or address
25- -q Quiet, only displays output at start and when finished
26- -s SIZE Packet SIZE in bytes (default 56)
27- -t TTL Set Time (number of hops) To Live
28- -W SEC Seconds to wait for response after all packets sent (default 10)
33+ -q Quiet (stops after one returns true if host is alive)
34+ -s SIZE Data SIZE in bytes (default 56)
35+ -t TTL Set Time To Live (number of hops)
36+ -W SEC Seconds to wait for response after -c (default 10)
2937 -w SEC Exit after this many seconds
3038 */
3139
@@ -33,23 +41,44 @@ config PING
3341 #include "toys.h"
3442
3543 #include <ifaddrs.h>
44+#include <netinet/ip_icmp.h>
3645
3746 GLOBALS(
38- long wait_exit;
39- long wait_resp;
40- char *iface;
41- long size;
42- long count;
43- long ttl;
47+ long w;
48+ long W;
49+ char *i;
50+ char *I;
51+ long s;
52+ long c;
53+ long t;
4454
4555 int sock;
56+ long i_ms;
4657 )
4758
48-void *sock2addr(struct sockaddr *sa)
59+static void xsendto(int sockfd, void *buf, size_t len, struct sockaddr *dest)
60+{
61+ int rc = sendto(TT.sock, buf, len, 0, dest,
62+ dest->sa_family == AF_INET ? sizeof(struct sockaddr_in) :
63+ sizeof(struct sockaddr_in6));
64+
65+ if (rc != len) perror_exit("sendto");
66+}
67+
68+// assumes aligned and can read even number of bytes
69+static unsigned short pingchksum(unsigned short *data, int len)
4970 {
50- if (sa->sa_family == AF_INET)
51- return &((struct sockaddr_in *)sa)->sin_addr;
52- return &((struct sockaddr_in6 *)sa)->sin6_addr;
71+ unsigned short u = 0, d;
72+
73+ // circular carry is endian independent: bits from high byte go to low byte
74+ while (len>0) {
75+ d = *data++;
76+ if (len == 1) d &= 255<<IS_BIG_ENDIAN;
77+ if (d >= (u += d)) u++;
78+ len -= 2;
79+ }
80+
81+ return u;
5382 }
5483
5584 void ping_main(void)
@@ -59,41 +88,55 @@ void ping_main(void)
5988 union {
6089 struct sockaddr_in in;
6190 struct sockaddr_in6 in6;
62- } src_addr;
63- struct sockaddr *sa = (void *)&src_addr;
64- int family = 0;
65-
66- // no 4/6 specified: -I has only one, arg must match
67- // no 4/6 specified: arg is one, -I must match
68- // 4/6 specified, both must match
69-
70- if (!(toys.optflags&FLAG_s)) TT.size = 56; // 64-PHDR_LEN
91+ } src_addr, src_addr2;
92+ struct sockaddr *sa = (void *)&src_addr, *sa2 = (void *)&src_addr2;
93+ struct pollfd pfd;
94+ int family = 0, sent = 0, len;
95+ long long tnext, tW, tnow, tw;
96+ unsigned short seq = 0;
97+ struct icmphdr *ih = (void *)toybuf;
98+
99+ // Interval
100+ if (TT.i) {
101+ long frac;
102+
103+ TT.i_ms = xparsetime(TT.i, 1000, &frac) * 1000;
104+ TT.i_ms += frac;
105+ if (TT.i_ms<200 && getuid()) error_exit("need root for -i <200");
106+ } else TT.i_ms = 1000;
107+ if (!(toys.optflags&FLAG_s)) TT.s = 56; // 64-PHDR_LEN
108+
109+ // ipv4 or ipv6? (0 = autodetect if -I or arg have only one address type.)
71110 if (toys.optflags&FLAG_6) family = AF_INET6;
72111 else if (toys.optflags&FLAG_4) family = AF_INET;
73112 else family = 0;
74113
75114 // If -I src_addr look it up. Allow numeric address of correct type.
76115 memset(&src_addr, 0, sizeof(src_addr));
77- if (TT.iface) {
78- if (!(toys.optflags&FLAG_6) && inet_pton(AF_INET, TT.iface,
116+ if (TT.I) {
117+ if (!(toys.optflags&FLAG_6) && inet_pton(AF_INET, TT.I,
79118 (void *)&src_addr.in.sin_addr))
80- family = sa->sa_family = AF_INET;
81- else if (!(toys.optflags&FLAG_4) && inet_pton(AF_INET6, TT.iface,
119+ family = AF_INET;
120+ else if (!(toys.optflags&FLAG_4) && inet_pton(AF_INET6, TT.I,
82121 (void *)&src_addr.in6.sin6_addr))
83- family = sa->sa_family = AF_INET6;
122+ family = AF_INET6;
84123 else if (getifaddrs(&ifa2)) perror_exit("getifaddrs");
85124 }
86125
87- // Look up HOST address, filtering for correct type.
126+ // Look up HOST address, filtering for correct type and interface.
88127 // If -I but no -46 then find compatible type between -I and HOST
89- ai2 = xgetaddrinfo(toys.optargs[0], 0, family, 0, 0, 0);
128+ ai2 = xgetaddrinfo(*toys.optargs, 0, family, 0, 0, 0);
90129 for (ai = ai2; ai; ai = ai->ai_next) {
130+
131+ // correct type?
91132 if (family && family!=ai->ai_family) continue;
92133 if (ai->ai_family!=AF_INET && ai->ai_family!=AF_INET6) continue;
93- if (!TT.iface || !ifa2) break;
134+
135+ // correct interface?
136+ if (!TT.I || !ifa2) break;
94137 for (ifa = ifa2; ifa; ifa = ifa->ifa_next) {
95138 if (!ifa->ifa_addr || ifa->ifa_addr->sa_family!=ai->ai_family
96- || strcmp(ifa->ifa_name, TT.iface)) continue;
139+ || strcmp(ifa->ifa_name, TT.I)) continue;
97140 sa = (void *)ifa->ifa_addr;
98141
99142 break;
@@ -102,19 +145,101 @@ void ping_main(void)
102145 }
103146
104147 if (!ai)
105- error_exit("no v%d addr for -I %s", 4+2*(family==AF_INET6), TT.iface);
106-
107- inet_ntop(family, sock2addr(sa), toybuf, sizeof(toybuf));
108- printf("host=%s\n", toybuf);
109- *toybuf = 0;
110- inet_ntop(ai->ai_family, sock2addr(ai->ai_addr), toybuf, sizeof(toybuf));
111- printf("targ=%s\n", toybuf);
112-
113- // Open raw socket
114- TT.sock = xsocket(ai->ai_family, SOCK_DGRAM, (ifa->ifa_addr->sa_family == AF_INET) ?
115- IPPROTO_ICMP : IPPROTO_ICMPV6);
116- if (TT.iface && bind(TT.sock, ifa->ifa_addr, sizeof(src_addr)))
117- perror_exit("bind");
148+ error_exit("no v%d addr for -I %s", 4+2*(family==AF_INET6), TT.I);
149+
150+ // Open DGRAM socket
151+ sa->sa_family = ai->ai_family;
152+ TT.sock = xsocket(ai->ai_family, SOCK_DGRAM,
153+ (ai->ai_family == AF_INET) ? IPPROTO_ICMP : IPPROTO_ICMPV6);
154+ if (TT.I && bind(TT.sock, sa, sizeof(src_addr))) perror_exit("bind");
155+
156+ if (TT.t) {
157+ len = TT.t;
158+
159+ if (ai->ai_family == AF_INET)
160+ setsockopt(TT.sock, IPPROTO_IP, IP_TTL, &len, 4);
161+ else setsockopt(TT.sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &len, 4);
162+ }
163+
164+ if (!(toys.optflags&FLAG_q)) {
165+ printf("Ping %s (%s)", *toys.optargs, ntop(ai->ai_addr));
166+ if (TT.I) {
167+ *toybuf = 0;
168+ printf(" from %s (%s)", TT.I, ntop(sa));
169+ }
170+ // 20 byte TCP header, 8 byte ICMP header, plus data payload
171+ printf(": %ld(%ld) bytes.\n", TT.s, TT.s+28);
172+ }
173+ toys.exitval = 1;
174+
175+ tW = tw = 0;
176+ tnext = millitime();
177+ if (TT.w) tw = TT.w*1000+tnext;
178+
179+ // Send/receive packets
180+ for (;;) {
181+ int waitms = INT_MAX;
182+
183+ // Exit due to timeout? (TODO: timeout is after last packet, waiting if
184+ // any packets ever dropped. Not timeout since packet was dropped.)
185+ tnow = millitime();
186+ if (tW) if (0>=(waitms = tW-tnow) || !sent) break;
187+ if (tw) {
188+ if (tnow>tw) break;
189+ else if (waitms>tw-tnow) waitms = tw-tnow;
190+ // Time to send the next packet?
191+ } else if (tnext-tnow <= 0) {
192+ tnext += TT.i_ms;
193+
194+ memset(ih, 0, sizeof(*ih));
195+ ih->type = (ai->ai_family == AF_INET) ? 8 : 128;
196+ ih->un.echo.id = getpid();
197+ ih->un.echo.sequence = ++seq;
198+ if (TT.s >= 4) *(unsigned *)(ih+1) = tnow;
199+
200+ ih->checksum = 0;
201+ ih->checksum = pingchksum((void *)toybuf, TT.s+sizeof(*ih));
202+ xsendto(TT.sock, toybuf, TT.s+sizeof(*ih), ai->ai_addr);
203+ sent++;
204+ if (toys.optflags&FLAG_f) printf(".");
205+
206+ // last packet?
207+ if (TT.c) if (!--TT.c) {
208+ if (!TT.W) break;
209+ tW = tnow + TT.W*1000;
210+ }
211+ }
212+
213+ // This is down here so it's against new period if we just sent a packet
214+ if (!tw && waitms>tnext-tnow) waitms = tnext-tnow;
215+
216+ // wait for next packet or timeout
217+
218+ if (waitms<0) waitms = 0;
219+ pfd.fd = TT.sock;
220+ pfd.events = POLLIN;
221+ if (0>(len = poll(&pfd, 1, waitms))) break;
222+ if (!len) continue;
223+
224+ len = sizeof(src_addr2);
225+ len = recvfrom(TT.sock, toybuf, sizeof(toybuf), 0, sa2, (void *)&len);
226+ sent--;
227+
228+ // reply id == 0 for ipv4, 129 for ipv6
229+
230+ if (!(toys.optflags&FLAG_q)) {
231+ printf("%d bytes from %s: icmp_seq=%d ttl=%d", len, ntop(sa2),
232+ ih->un.echo.sequence, 0);
233+ if (len >= sizeof(*ih)+4) {
234+ unsigned lunchtime = millitime()-*(unsigned *)(ih+1);
235+
236+ printf(" time=%u.%03u", lunchtime/1000, lunchtime%1000);
237+ }
238+ xputc('\n');
239+ }
240+
241+ toys.exitval = 0;
242+ }
118243
119244 if (CFG_TOYBOX_FREE) {
120245 freeaddrinfo(ai2);
--- a/toys/posix/cksum.c
+++ b/toys/posix/cksum.c
@@ -5,6 +5,7 @@
55 * See http://opengroup.org/onlinepubs/9699919799/utilities/cksum.html
66
77 USE_CKSUM(NEWTOY(cksum, "HIPLN", TOYFLAG_BIN))
8+USE_CRC32(NEWTOY(crc32, 0, TOYFLAG_BIN))
89
910 config CKSUM
1011 bool "cksum"
@@ -19,10 +20,19 @@ config CKSUM
1920 -L Little endian (defaults to big endian)
2021 -P Pre-inversion
2122 -I Skip post-inversion
22- -N Do not include length in CRC calculation
23+ -N Do not include length in CRC calculation (or output)
24+
25+config CRC32
26+ bool "crc32"
27+ default y
28+ help
29+ usage: crc32 [file...]
30+
31+ Output crc32 checksum for each file.
2332 */
2433
2534 #define FOR_cksum
35+#define FORCE_FLAGS
2636 #include "toys.h"
2737
2838 GLOBALS(
@@ -44,13 +54,12 @@ static void do_cksum(int fd, char *name)
4454 unsigned crc = (toys.optflags & FLAG_P) ? 0xffffffff : 0;
4555 uint64_t llen = 0, llen2;
4656 unsigned (*cksum)(unsigned crc, unsigned char c);
57+ int len, i;
4758
4859 cksum = (toys.optflags & FLAG_L) ? cksum_le : cksum_be;
4960 // CRC the data
5061
5162 for (;;) {
52- int len, i;
53-
5463 len = read(fd, toybuf, sizeof(toybuf));
5564 if (len<0) perror_msg_raw(name);
5665 if (len<1) break;
@@ -69,10 +78,10 @@ static void do_cksum(int fd, char *name)
6978 }
7079 }
7180
72- printf((toys.optflags & FLAG_H) ? "%x" : "%u",
81+ printf((toys.optflags & FLAG_H) ? "%08x" : "%u",
7382 (toys.optflags & FLAG_I) ? crc : ~crc);
74- printf(" %"PRIu64, llen2);
75- if (strcmp("-", name)) printf(" %s", name);
83+ if (!(toys.optflags&FLAG_N)) printf(" %"PRIu64, llen2);
84+ if (toys.optc) printf(" %s", name);
7685 xputc('\n');
7786 }
7887
@@ -81,3 +90,10 @@ void cksum_main(void)
8190 crc_init(TT.crc_table, toys.optflags & FLAG_L);
8291 loopfiles(toys.optargs, do_cksum);
8392 }
93+
94+void crc32_main(void)
95+{
96+ toys.optflags |= FLAG_H|FLAG_N|FLAG_P|FLAG_L;
97+ if (toys.optc) toys.optc--;
98+ cksum_main();
99+}
--- a/toys/posix/ps.c
+++ b/toys/posix/ps.c
@@ -1417,7 +1417,7 @@ static void top_common(
14171417 mix.count = 0;
14181418
14191419 while (old.count || new.count) {
1420- struct carveup *otb = *old.tb, *ntb = *new.tb;
1420+ struct carveup *otb = old.tb ? *old.tb : 0, *ntb = new.tb ? *new.tb : 0;
14211421
14221422 // If we just have old for this process, it exited. Discard it.
14231423 if (old.count && (!new.count || *otb->slot < *ntb->slot)) {
Show on old repository browser