aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>1999-12-07 23:14:59 +0000
committerEric Andersen <andersen@codepoet.org>1999-12-07 23:14:59 +0000
commit485b9550fd01eb519fc0d4f4f148af39fe22250e (patch)
tree7cf511946e5991ad2fd66734b1a1d2a5045d7c6b
parentd00c2628474b9e6a3fe34c988fe197cf2425ff1a (diff)
downloadbusybox-w32-485b9550fd01eb519fc0d4f4f148af39fe22250e.tar.gz
busybox-w32-485b9550fd01eb519fc0d4f4f148af39fe22250e.tar.bz2
busybox-w32-485b9550fd01eb519fc0d4f4f148af39fe22250e.zip
Stuf
-rw-r--r--Changelog9
-rw-r--r--TODO4
-rw-r--r--applets/busybox.c6
-rw-r--r--busybox.c6
-rw-r--r--busybox.def.h2
-rw-r--r--hostname.c126
-rw-r--r--init.c10
-rw-r--r--init/init.c10
-rw-r--r--internal.h2
-rw-r--r--networking/hostname.c126
-rw-r--r--networking/ping.c374
-rw-r--r--ping.c374
-rw-r--r--umount.c7
-rw-r--r--util-linux/umount.c7
14 files changed, 1029 insertions, 34 deletions
diff --git a/Changelog b/Changelog
index 9698396e0..10648dbde 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,12 @@
10.38
2 * New Apps: ping and hostname contributed by Randolph Chung
3 <tausq@debian.org>
4 * on reboot, init called 'umount -a -n', which caused errors
5 when BB_MTAB was not enabled. Changed to 'umount -a',
6 which does the right thing.
7
8 -Erik Andrsen
9
10.38 100.38
2 * Fixed a segfault in 'umount -a' when a badly formed /etc/fstab 11 * Fixed a segfault in 'umount -a' when a badly formed /etc/fstab
3 file existed. 12 file existed.
diff --git a/TODO b/TODO
index 1a65a57a8..52a4a53ad 100644
--- a/TODO
+++ b/TODO
@@ -14,8 +14,8 @@ around to it some time. If you have any good ideas, please let me know.
14* poweroff 14* poweroff
15* du 15* du
16* mkfifo 16* mkfifo
17* hostname/dnsdomainname 17* dnsdomainname
18* ping/traceroute/nslookup/netstat 18* traceroute/nslookup/netstat
19* rdate 19* rdate
20* hwclock 20* hwclock
21* login/getty 21* login/getty
diff --git a/applets/busybox.c b/applets/busybox.c
index af81ad8a2..95c294425 100644
--- a/applets/busybox.c
+++ b/applets/busybox.c
@@ -69,6 +69,9 @@ static const struct Applet applets[] = {
69#ifdef BB_HALT //sbin 69#ifdef BB_HALT //sbin
70 {"halt", halt_main}, 70 {"halt", halt_main},
71#endif 71#endif
72#ifdef BB_HOSTNAME //bin
73 {"hostname", hostname_main},
74#endif
72#ifdef BB_INIT //sbin 75#ifdef BB_INIT //sbin
73 {"init", init_main}, 76 {"init", init_main},
74#endif 77#endif
@@ -123,6 +126,9 @@ static const struct Applet applets[] = {
123#ifdef BB_MV //bin 126#ifdef BB_MV //bin
124 {"mv", mv_main}, 127 {"mv", mv_main},
125#endif 128#endif
129#ifdef BB_PING //bin
130 {"ping", ping_main},
131#endif
126#ifdef BB_PRINTF //usr/bin 132#ifdef BB_PRINTF //usr/bin
127 {"printf", printf_main}, 133 {"printf", printf_main},
128#endif 134#endif
diff --git a/busybox.c b/busybox.c
index af81ad8a2..95c294425 100644
--- a/busybox.c
+++ b/busybox.c
@@ -69,6 +69,9 @@ static const struct Applet applets[] = {
69#ifdef BB_HALT //sbin 69#ifdef BB_HALT //sbin
70 {"halt", halt_main}, 70 {"halt", halt_main},
71#endif 71#endif
72#ifdef BB_HOSTNAME //bin
73 {"hostname", hostname_main},
74#endif
72#ifdef BB_INIT //sbin 75#ifdef BB_INIT //sbin
73 {"init", init_main}, 76 {"init", init_main},
74#endif 77#endif
@@ -123,6 +126,9 @@ static const struct Applet applets[] = {
123#ifdef BB_MV //bin 126#ifdef BB_MV //bin
124 {"mv", mv_main}, 127 {"mv", mv_main},
125#endif 128#endif
129#ifdef BB_PING //bin
130 {"ping", ping_main},
131#endif
126#ifdef BB_PRINTF //usr/bin 132#ifdef BB_PRINTF //usr/bin
127 {"printf", printf_main}, 133 {"printf", printf_main},
128#endif 134#endif
diff --git a/busybox.def.h b/busybox.def.h
index 3284a63d3..ac7a9b76f 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -22,6 +22,7 @@
22#define BB_DEALLOCVT 22#define BB_DEALLOCVT
23#define BB_GREP 23#define BB_GREP
24//#define BB_HALT 24//#define BB_HALT
25#define BB_HOSTNAME
25#define BB_INIT 26#define BB_INIT
26#define BB_KILL 27#define BB_KILL
27//#define BB_LENGTH 28//#define BB_LENGTH
@@ -42,6 +43,7 @@
42//#define BB_MT 43//#define BB_MT
43//#define BB_MTAB 44//#define BB_MTAB
44#define BB_MV 45#define BB_MV
46#define BB_PING
45//#define BB_PRINTF 47//#define BB_PRINTF
46#define BB_PS 48#define BB_PS
47#define BB_PWD 49#define BB_PWD
diff --git a/hostname.c b/hostname.c
new file mode 100644
index 000000000..27f2800d8
--- /dev/null
+++ b/hostname.c
@@ -0,0 +1,126 @@
1/*
2 * $Id: hostname.c,v 1.1 1999/12/07 23:14:59 andersen Exp $
3 * Mini hostname implementation for busybox
4 *
5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include "internal.h"
23#include <errno.h>
24#include <getopt.h>
25#include <arpa/inet.h>
26#include <netdb.h>
27#include <unistd.h>
28#include <stdio.h>
29
30static const char* hostname_usage = "hostname [OPTION] {hostname | -F file}\n\n"
31"Options:\n"
32"\t-s, --short\t\tshort\n"
33"\t-i, --ip-address\t\taddresses for the hostname\n"
34"\t-d, --domain\t\tDNS domain name\n"
35"If a hostname is given, or a file is given with the -F parameter, the host\n"
36"name will be set\n";
37
38static char short_opts[] = "sidF:";
39static const struct option long_opts[] = {
40 { "short", no_argument, NULL, 's' },
41 { "ip-address", no_argument, NULL, 'i' },
42 { "domain", no_argument, NULL, 'd' },
43 { NULL, 0, NULL, 0 }
44};
45
46void do_sethostname(char *s, int isfile)
47{
48 FILE *f;
49 char buf[255];
50
51 if (!s) return;
52 if (!isfile) {
53 if (sethostname(s, strlen(s)) < 0) {
54 if (errno == EPERM)
55 fprintf(stderr, "hostname: you must be root to change the hostname\n");
56 else
57 perror("sethostname");
58 exit(1);
59 }
60 } else {
61 if ((f = fopen(s, "r")) == NULL) {
62 perror(s);
63 exit(1);
64 } else {
65 fgets(buf, 255, f);
66 fclose(f);
67 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
68 if (sethostname(buf, strlen(buf)) < 0) {
69 perror("sethostname");
70 exit(1);
71 }
72 }
73 }
74}
75
76int hostname_main(int argc, char **argv)
77{
78 int c;
79 int opt_short = 0;
80 int opt_domain = 0;
81 int opt_ip = 0;
82 int opt_file = 0;
83 struct hostent *h;
84 char *filename = NULL;
85 char buf[255];
86 char *s = NULL;
87
88 if (argc < 1) usage(hostname_usage);
89
90 while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
91 switch (c) {
92 case 's': opt_short = 1; break;
93 case 'i': opt_ip = 1; break;
94 case 'd': opt_domain = 1; break;
95 case 'F': opt_file = 1; filename = optarg; break;
96 default: usage(hostname_usage);
97 }
98 }
99
100 if (optind < argc) {
101 do_sethostname(argv[optind], 0);
102 } else if (opt_file) {
103 do_sethostname(filename, 1);
104 } else {
105 gethostname(buf, 255);
106 if (opt_short) {
107 s = strchr(buf, '.');
108 if (!s) s = buf; *s = 0;
109 printf("%s\n", buf);
110 } else if (opt_domain) {
111 s = strchr(buf, '.');
112 printf("%s\n", (s ? s+1 : ""));
113 } else if (opt_ip) {
114 h = gethostbyname(buf);
115 if (!h) {
116 printf("Host not found\n");
117 exit(1);
118 }
119 printf("%s\n", inet_ntoa(*(struct in_addr *)(h->h_addr)));
120 } else {
121 printf("%s\n", buf);
122 }
123 }
124 return 0;
125}
126
diff --git a/init.c b/init.c
index dbd9f2812..164ee69a3 100644
--- a/init.c
+++ b/init.c
@@ -151,19 +151,11 @@ void message(int device, char *fmt, ...)
151void set_term( int fd) 151void set_term( int fd)
152{ 152{
153 struct termios tty; 153 struct termios tty;
154#if 0
155 static const char control_characters[] = {
156 '\003', '\034', '\177', '\030', '\004', '\0',
157 '\1', '\0', '\021', '\023', '\032', '\0', '\022',
158 '\017', '\027', '\026', '\0'
159 };
160#else
161 static const char control_characters[] = { 154 static const char control_characters[] = {
162 '\003', '\034', '\177', '\025', '\004', '\0', 155 '\003', '\034', '\177', '\025', '\004', '\0',
163 '\1', '\0', '\021', '\023', '\032', '\0', '\022', 156 '\1', '\0', '\021', '\023', '\032', '\0', '\022',
164 '\017', '\027', '\026', '\0' 157 '\017', '\027', '\026', '\0'
165 }; 158 };
166#endif
167 159
168 tcgetattr(fd, &tty); 160 tcgetattr(fd, &tty);
169 161
@@ -386,7 +378,7 @@ goodnight:
386static void shutdown_system(void) 378static void shutdown_system(void)
387{ 379{
388 const char* const swap_off_cmd[] = { "swapoff", "swapoff", "-a", 0}; 380 const char* const swap_off_cmd[] = { "swapoff", "swapoff", "-a", 0};
389 const char* const umount_cmd[] = { "umount", "umount", "-a", "-n", 0}; 381 const char* const umount_cmd[] = { "umount", "umount", "-a", 0};
390 382
391#ifndef DEBUG_INIT 383#ifndef DEBUG_INIT
392 /* Allow Ctrl-Alt-Del to reboot system. */ 384 /* Allow Ctrl-Alt-Del to reboot system. */
diff --git a/init/init.c b/init/init.c
index dbd9f2812..164ee69a3 100644
--- a/init/init.c
+++ b/init/init.c
@@ -151,19 +151,11 @@ void message(int device, char *fmt, ...)
151void set_term( int fd) 151void set_term( int fd)
152{ 152{
153 struct termios tty; 153 struct termios tty;
154#if 0
155 static const char control_characters[] = {
156 '\003', '\034', '\177', '\030', '\004', '\0',
157 '\1', '\0', '\021', '\023', '\032', '\0', '\022',
158 '\017', '\027', '\026', '\0'
159 };
160#else
161 static const char control_characters[] = { 154 static const char control_characters[] = {
162 '\003', '\034', '\177', '\025', '\004', '\0', 155 '\003', '\034', '\177', '\025', '\004', '\0',
163 '\1', '\0', '\021', '\023', '\032', '\0', '\022', 156 '\1', '\0', '\021', '\023', '\032', '\0', '\022',
164 '\017', '\027', '\026', '\0' 157 '\017', '\027', '\026', '\0'
165 }; 158 };
166#endif
167 159
168 tcgetattr(fd, &tty); 160 tcgetattr(fd, &tty);
169 161
@@ -386,7 +378,7 @@ goodnight:
386static void shutdown_system(void) 378static void shutdown_system(void)
387{ 379{
388 const char* const swap_off_cmd[] = { "swapoff", "swapoff", "-a", 0}; 380 const char* const swap_off_cmd[] = { "swapoff", "swapoff", "-a", 0};
389 const char* const umount_cmd[] = { "umount", "umount", "-a", "-n", 0}; 381 const char* const umount_cmd[] = { "umount", "umount", "-a", 0};
390 382
391#ifndef DEBUG_INIT 383#ifndef DEBUG_INIT
392 /* Allow Ctrl-Alt-Del to reboot system. */ 384 /* Allow Ctrl-Alt-Del to reboot system. */
diff --git a/internal.h b/internal.h
index 85c37c429..2e7d48d46 100644
--- a/internal.h
+++ b/internal.h
@@ -72,6 +72,7 @@ extern int mkfs_minix_main(int argc, char **argv);
72extern int find_main(int argc, char** argv); 72extern int find_main(int argc, char** argv);
73extern int grep_main(int argc, char** argv); 73extern int grep_main(int argc, char** argv);
74extern int halt_main(int argc, char** argv); 74extern int halt_main(int argc, char** argv);
75extern int hostname_main(int argc, char** argv);
75extern int init_main(int argc, char** argv); 76extern int init_main(int argc, char** argv);
76extern int kill_main(int argc, char** argv); 77extern int kill_main(int argc, char** argv);
77extern int length_main(int argc, char** argv); 78extern int length_main(int argc, char** argv);
@@ -91,6 +92,7 @@ extern int mnc_main(int argc, char** argv);
91extern int mount_main(int argc, char** argv); 92extern int mount_main(int argc, char** argv);
92extern int mt_main(int argc, char** argv); 93extern int mt_main(int argc, char** argv);
93extern int mv_main(int argc, char** argv); 94extern int mv_main(int argc, char** argv);
95extern int ping_main(int argc, char **argv);
94extern int printf_main(int argc, char** argv); 96extern int printf_main(int argc, char** argv);
95extern int ps_main(int argc, char** argv); 97extern int ps_main(int argc, char** argv);
96extern int pwd_main(int argc, char** argv); 98extern int pwd_main(int argc, char** argv);
diff --git a/networking/hostname.c b/networking/hostname.c
new file mode 100644
index 000000000..27f2800d8
--- /dev/null
+++ b/networking/hostname.c
@@ -0,0 +1,126 @@
1/*
2 * $Id: hostname.c,v 1.1 1999/12/07 23:14:59 andersen Exp $
3 * Mini hostname implementation for busybox
4 *
5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include "internal.h"
23#include <errno.h>
24#include <getopt.h>
25#include <arpa/inet.h>
26#include <netdb.h>
27#include <unistd.h>
28#include <stdio.h>
29
30static const char* hostname_usage = "hostname [OPTION] {hostname | -F file}\n\n"
31"Options:\n"
32"\t-s, --short\t\tshort\n"
33"\t-i, --ip-address\t\taddresses for the hostname\n"
34"\t-d, --domain\t\tDNS domain name\n"
35"If a hostname is given, or a file is given with the -F parameter, the host\n"
36"name will be set\n";
37
38static char short_opts[] = "sidF:";
39static const struct option long_opts[] = {
40 { "short", no_argument, NULL, 's' },
41 { "ip-address", no_argument, NULL, 'i' },
42 { "domain", no_argument, NULL, 'd' },
43 { NULL, 0, NULL, 0 }
44};
45
46void do_sethostname(char *s, int isfile)
47{
48 FILE *f;
49 char buf[255];
50
51 if (!s) return;
52 if (!isfile) {
53 if (sethostname(s, strlen(s)) < 0) {
54 if (errno == EPERM)
55 fprintf(stderr, "hostname: you must be root to change the hostname\n");
56 else
57 perror("sethostname");
58 exit(1);
59 }
60 } else {
61 if ((f = fopen(s, "r")) == NULL) {
62 perror(s);
63 exit(1);
64 } else {
65 fgets(buf, 255, f);
66 fclose(f);
67 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
68 if (sethostname(buf, strlen(buf)) < 0) {
69 perror("sethostname");
70 exit(1);
71 }
72 }
73 }
74}
75
76int hostname_main(int argc, char **argv)
77{
78 int c;
79 int opt_short = 0;
80 int opt_domain = 0;
81 int opt_ip = 0;
82 int opt_file = 0;
83 struct hostent *h;
84 char *filename = NULL;
85 char buf[255];
86 char *s = NULL;
87
88 if (argc < 1) usage(hostname_usage);
89
90 while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
91 switch (c) {
92 case 's': opt_short = 1; break;
93 case 'i': opt_ip = 1; break;
94 case 'd': opt_domain = 1; break;
95 case 'F': opt_file = 1; filename = optarg; break;
96 default: usage(hostname_usage);
97 }
98 }
99
100 if (optind < argc) {
101 do_sethostname(argv[optind], 0);
102 } else if (opt_file) {
103 do_sethostname(filename, 1);
104 } else {
105 gethostname(buf, 255);
106 if (opt_short) {
107 s = strchr(buf, '.');
108 if (!s) s = buf; *s = 0;
109 printf("%s\n", buf);
110 } else if (opt_domain) {
111 s = strchr(buf, '.');
112 printf("%s\n", (s ? s+1 : ""));
113 } else if (opt_ip) {
114 h = gethostbyname(buf);
115 if (!h) {
116 printf("Host not found\n");
117 exit(1);
118 }
119 printf("%s\n", inet_ntoa(*(struct in_addr *)(h->h_addr)));
120 } else {
121 printf("%s\n", buf);
122 }
123 }
124 return 0;
125}
126
diff --git a/networking/ping.c b/networking/ping.c
new file mode 100644
index 000000000..9f8a103bd
--- /dev/null
+++ b/networking/ping.c
@@ -0,0 +1,374 @@
1/*
2 * $Id: ping.c,v 1.1 1999/12/07 23:14:59 andersen Exp $
3 * Mini ping implementation for busybox
4 *
5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * This version of ping is adapted from the ping in netkit-base 0.10,
22 * which is:
23 *
24 * Copyright (c) 1989 The Regents of the University of California.
25 * All rights reserved.
26 *
27 * This code is derived from software contributed to Berkeley by
28 * Mike Muuss.
29 *
30 * Original copyright notice is retained at the end of this file.
31 */
32
33#include "internal.h"
34#include <sys/param.h>
35#include <sys/socket.h>
36#include <sys/file.h>
37#include <sys/time.h>
38#include <sys/times.h>
39#include <sys/signal.h>
40
41#include <netinet/in.h>
42#include <netinet/ip.h>
43#include <netinet/ip_icmp.h>
44#include <arpa/inet.h>
45#include <netdb.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <errno.h>
49
50#define DEFDATALEN 56
51#define MAXIPLEN 60
52#define MAXICMPLEN 76
53#define MAXPACKET 65468
54#define MAX_DUP_CHK (8 * 128)
55#define MAXWAIT 10
56
57#define O_QUIET (1 << 0)
58
59#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */
60#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */
61#define SET(bit) (A(bit) |= B(bit))
62#define CLR(bit) (A(bit) &= (~B(bit)))
63#define TST(bit) (A(bit) & B(bit))
64
65static const char* ping_usage = "ping [OPTION]... host\n\n"
66"Options:\n"
67"\t-q\t\tquiet\n"
68"\t-c\t\tping count\n";
69
70static char *hostname = NULL;
71static struct sockaddr_in pingaddr;
72static int pingsock = -1;
73static long ntransmitted = 0, nreceived = 0, nrepeats = 0, pingcount = 0;
74static int myid = 0, options = 0;
75static unsigned long tmin = ULONG_MAX, tmax = 0, tsum = 0;
76static char rcvd_tbl[MAX_DUP_CHK / 8];
77
78static void pingstats(int);
79static void sendping(int);
80static void unpack(char *, int, struct sockaddr_in *);
81static void ping(char *);
82static int in_cksum(unsigned short *, int);
83
84/**************************************************************************/
85
86static int in_cksum(unsigned short *buf, int sz)
87{
88 int nleft = sz;
89 int sum = 0;
90 unsigned short *w = buf;
91 unsigned short ans = 0;
92
93 while (nleft > 1) {
94 sum += *w++;
95 nleft -= 2;
96 }
97
98 if (nleft == 1) {
99 *(unsigned char *)(&ans) = *(unsigned char *)w;
100 sum += ans;
101 }
102
103 sum = (sum >> 16) + (sum & 0xFFFF);
104 sum += (sum >> 16);
105 ans = ~sum;
106 return(ans);
107}
108
109static void pingstats(int ign) {
110 signal(SIGINT, SIG_IGN);
111
112 printf("\n--- %s ping statistics ---\n", hostname);
113 printf("%ld packets transmitted, ", ntransmitted);
114 printf("%ld packets received, ", nreceived);
115 if (nrepeats)
116 printf("%ld duplicates, ", nrepeats);
117 if (ntransmitted)
118 printf("%ld%% packet loss\n",
119 (ntransmitted - nreceived)*100/ntransmitted);
120 if (nreceived)
121 printf("round-trip min/avg/max = %lu.%lu/%lu.%lu/%lu.%lu ms\n",
122 tmin/10, tmin%10,
123 (tsum/(nreceived+nrepeats))/10,
124 (tsum/(nreceived+nrepeats))%10,
125 tmax/10, tmax%10);
126 exit(0);
127}
128
129static void sendping(int ign)
130{
131 struct icmp *pkt;
132 int i;
133 char packet[DEFDATALEN + 8];
134
135 pkt = (struct icmp *)packet;
136
137 pkt->icmp_type = ICMP_ECHO;
138 pkt->icmp_code = 0;
139 pkt->icmp_cksum = 0;
140 pkt->icmp_seq = ntransmitted++;
141 pkt->icmp_id = myid;
142 CLR(pkt->icmp_seq % MAX_DUP_CHK);
143
144 gettimeofday((struct timeval *)&packet[8], NULL);
145 pkt->icmp_cksum = in_cksum((unsigned short *)pkt, sizeof(packet));
146
147 i = sendto(pingsock, packet, sizeof(packet), 0,
148 (struct sockaddr *)&pingaddr, sizeof(struct sockaddr_in));
149
150 if (i < 0 || i != sizeof(packet)) {
151 if (i < 0) perror("ping");
152 fprintf(stderr, "ping wrote %d chars; %d expected\n", i, sizeof(packet));
153 exit(1);
154 }
155
156 signal(SIGALRM, sendping);
157 if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next */
158 alarm(1);
159 } else { /* done, wait for the last ping to come back */
160 /* todo, don't necessarily need to wait so long... */
161 signal(SIGALRM, pingstats);
162 alarm(MAXWAIT);
163 }
164}
165
166static void unpack(char *buf, int sz, struct sockaddr_in *from)
167{
168 struct icmp *icmppkt;
169 struct iphdr *iphdr;
170 struct timeval tv, *tp;
171 int hlen, dupflag;
172 unsigned long triptime;
173
174 gettimeofday(&tv, NULL);
175
176 /* check IP header */
177 iphdr = (struct iphdr *)buf;
178 hlen = iphdr->ihl << 2;
179 /* discard if too short */
180 if (sz < (DEFDATALEN + ICMP_MINLEN)) return;
181
182 sz -= hlen;
183 icmppkt = (struct icmp *)(buf + hlen);
184
185 if (icmppkt->icmp_type == ICMP_ECHOREPLY) {
186 if (icmppkt->icmp_id != myid) return; /* not our ping */
187 ++nreceived;
188 tp = (struct timeval *)icmppkt->icmp_data;
189
190 if ((tv.tv_usec -= tp->tv_usec) < 0) {
191 --tv.tv_sec;
192 tv.tv_usec += 1000000;
193 }
194 tv.tv_sec -= tp->tv_sec;
195
196 triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100);
197 tsum += triptime;
198 if (triptime < tmin) tmin = triptime;
199 if (triptime > tmax) tmax = triptime;
200
201 if (TST(icmppkt->icmp_seq % MAX_DUP_CHK)) {
202 ++nrepeats;
203 --nreceived;
204 dupflag = 1;
205 } else {
206 SET(icmppkt->icmp_seq % MAX_DUP_CHK);
207 dupflag = 0;
208 }
209
210 if (options & O_QUIET) return;
211
212 printf("%d bytes from %s: icmp_seq=%u", sz,
213 inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
214 icmppkt->icmp_seq);
215 printf(" ttl=%d", iphdr->ttl);
216 printf(" time=%lu.%lu ms", triptime/10, triptime%10);
217 if (dupflag) printf(" (DUP!)");
218 printf("\n");
219 } else {
220 fprintf(stderr, "Warning: unknown ICMP packet received (not echo-reply)\n");
221 }
222}
223
224static void ping(char *host)
225{
226 struct protoent *proto;
227 struct hostent *h;
228 char buf[MAXHOSTNAMELEN];
229 char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
230 int sockopt;
231
232 if (!(proto = getprotobyname("icmp"))) {
233 fprintf(stderr, "ping: unknown protocol icmp\n");
234 exit(1);
235 }
236 if ((pingsock = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) {
237 if (errno == EPERM) {
238 fprintf(stderr, "ping: permission denied. (are you root?)\n");
239 } else {
240 perror("ping");
241 }
242 exit(1);
243 }
244
245#ifdef SUID_BUSYBOX
246 setuid(getuid());
247#endif
248
249 memset(&pingaddr, 0, sizeof(struct sockaddr_in));
250 pingaddr.sin_family = AF_INET;
251 if (inet_aton(host, &pingaddr.sin_addr)) {
252 hostname = host;
253 } else {
254 if (!(h = gethostbyname(host))) {
255 fprintf(stderr, "ping: unknown host %s\n", host);
256 exit(1);
257 }
258
259 if (h->h_addrtype != AF_INET) {
260 fprintf(stderr, "ping: unknown address type; only AF_INET is currently supported.\n");
261 exit(1);
262 }
263
264 pingaddr.sin_family = AF_INET; /* h->h_addrtype */
265 memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr));
266 strncpy(buf, h->h_name, sizeof(buf)-1);
267 hostname = buf;
268 }
269
270 /* enable broadcast pings */
271 sockopt = 1;
272 setsockopt(pingsock, SOL_SOCKET, SO_BROADCAST, (char *)&sockopt, sizeof(sockopt));
273
274 /* set recv buf for broadcast pings */
275 sockopt = 48 * 1024;
276 setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, (char *)&sockopt, sizeof(sockopt));
277
278 printf("PING %s (%s): %d data bytes\n",
279 hostname, inet_ntoa(*(struct in_addr *)&pingaddr.sin_addr.s_addr),
280 DEFDATALEN);
281
282 signal(SIGINT, pingstats);
283
284 /* start the ping's going ... */
285 sendping(0);
286
287 /* listen for replies */
288 while (1) {
289 struct sockaddr_in from;
290 size_t fromlen = sizeof(from);
291 int c;
292
293 if ((c = recvfrom(pingsock, packet, sizeof(packet), 0,
294 (struct sockaddr *)&from, &fromlen)) < 0) {
295 if (errno == EINTR) continue;
296 perror("ping");
297 continue;
298 }
299 unpack(packet, c, &from);
300 if (pingcount > 0 && nreceived >= pingcount) break;
301 }
302 pingstats(0);
303}
304
305extern int ping_main(int argc, char **argv)
306{
307 argc--;
308 argv++;
309 options = 0;
310 /* Parse any options */
311 if (argc < 1) usage(ping_usage);
312
313 while (**argv == '-') {
314 while (*++(*argv))
315 switch (**argv) {
316 case 'c':
317 argc--; argv++;
318 if (argc < 1) usage(ping_usage);
319 pingcount = atoi(*argv);
320 break;
321 case 'q':
322 options |= O_QUIET;
323 break;
324 default:
325 usage(ping_usage);
326 }
327 argc--;
328 argv++;
329 }
330
331 if (argc < 1) usage(ping_usage);
332
333 myid = getpid() & 0xFFFF;
334 ping(*(argv++));
335 exit( TRUE);
336}
337
338/*
339 * Copyright (c) 1989 The Regents of the University of California.
340 * All rights reserved.
341 *
342 * This code is derived from software contributed to Berkeley by
343 * Mike Muuss.
344 *
345 * Redistribution and use in source and binary forms, with or without
346 * modification, are permitted provided that the following conditions
347 * are met:
348 * 1. Redistributions of source code must retain the above copyright
349 * notice, this list of conditions and the following disclaimer.
350 * 2. Redistributions in binary form must reproduce the above copyright
351 * notice, this list of conditions and the following disclaimer in the
352 * documentation and/or other materials provided with the distribution.
353 * 3. All advertising materials mentioning features or use of this software
354 * must display the following acknowledgement:
355 * This product includes software developed by the University of
356 * California, Berkeley and its contributors.
357 * 4. Neither the name of the University nor the names of its contributors
358 * may be used to endorse or promote products derived from this software
359 * without specific prior written permission.
360 *
361 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
362 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
363 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
364 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
365 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
366 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
367 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
368 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
369 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
370 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
371 * SUCH DAMAGE.
372 */
373
374
diff --git a/ping.c b/ping.c
new file mode 100644
index 000000000..9f8a103bd
--- /dev/null
+++ b/ping.c
@@ -0,0 +1,374 @@
1/*
2 * $Id: ping.c,v 1.1 1999/12/07 23:14:59 andersen Exp $
3 * Mini ping implementation for busybox
4 *
5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * This version of ping is adapted from the ping in netkit-base 0.10,
22 * which is:
23 *
24 * Copyright (c) 1989 The Regents of the University of California.
25 * All rights reserved.
26 *
27 * This code is derived from software contributed to Berkeley by
28 * Mike Muuss.
29 *
30 * Original copyright notice is retained at the end of this file.
31 */
32
33#include "internal.h"
34#include <sys/param.h>
35#include <sys/socket.h>
36#include <sys/file.h>
37#include <sys/time.h>
38#include <sys/times.h>
39#include <sys/signal.h>
40
41#include <netinet/in.h>
42#include <netinet/ip.h>
43#include <netinet/ip_icmp.h>
44#include <arpa/inet.h>
45#include <netdb.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <errno.h>
49
50#define DEFDATALEN 56
51#define MAXIPLEN 60
52#define MAXICMPLEN 76
53#define MAXPACKET 65468
54#define MAX_DUP_CHK (8 * 128)
55#define MAXWAIT 10
56
57#define O_QUIET (1 << 0)
58
59#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */
60#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */
61#define SET(bit) (A(bit) |= B(bit))
62#define CLR(bit) (A(bit) &= (~B(bit)))
63#define TST(bit) (A(bit) & B(bit))
64
65static const char* ping_usage = "ping [OPTION]... host\n\n"
66"Options:\n"
67"\t-q\t\tquiet\n"
68"\t-c\t\tping count\n";
69
70static char *hostname = NULL;
71static struct sockaddr_in pingaddr;
72static int pingsock = -1;
73static long ntransmitted = 0, nreceived = 0, nrepeats = 0, pingcount = 0;
74static int myid = 0, options = 0;
75static unsigned long tmin = ULONG_MAX, tmax = 0, tsum = 0;
76static char rcvd_tbl[MAX_DUP_CHK / 8];
77
78static void pingstats(int);
79static void sendping(int);
80static void unpack(char *, int, struct sockaddr_in *);
81static void ping(char *);
82static int in_cksum(unsigned short *, int);
83
84/**************************************************************************/
85
86static int in_cksum(unsigned short *buf, int sz)
87{
88 int nleft = sz;
89 int sum = 0;
90 unsigned short *w = buf;
91 unsigned short ans = 0;
92
93 while (nleft > 1) {
94 sum += *w++;
95 nleft -= 2;
96 }
97
98 if (nleft == 1) {
99 *(unsigned char *)(&ans) = *(unsigned char *)w;
100 sum += ans;
101 }
102
103 sum = (sum >> 16) + (sum & 0xFFFF);
104 sum += (sum >> 16);
105 ans = ~sum;
106 return(ans);
107}
108
109static void pingstats(int ign) {
110 signal(SIGINT, SIG_IGN);
111
112 printf("\n--- %s ping statistics ---\n", hostname);
113 printf("%ld packets transmitted, ", ntransmitted);
114 printf("%ld packets received, ", nreceived);
115 if (nrepeats)
116 printf("%ld duplicates, ", nrepeats);
117 if (ntransmitted)
118 printf("%ld%% packet loss\n",
119 (ntransmitted - nreceived)*100/ntransmitted);
120 if (nreceived)
121 printf("round-trip min/avg/max = %lu.%lu/%lu.%lu/%lu.%lu ms\n",
122 tmin/10, tmin%10,
123 (tsum/(nreceived+nrepeats))/10,
124 (tsum/(nreceived+nrepeats))%10,
125 tmax/10, tmax%10);
126 exit(0);
127}
128
129static void sendping(int ign)
130{
131 struct icmp *pkt;
132 int i;
133 char packet[DEFDATALEN + 8];
134
135 pkt = (struct icmp *)packet;
136
137 pkt->icmp_type = ICMP_ECHO;
138 pkt->icmp_code = 0;
139 pkt->icmp_cksum = 0;
140 pkt->icmp_seq = ntransmitted++;
141 pkt->icmp_id = myid;
142 CLR(pkt->icmp_seq % MAX_DUP_CHK);
143
144 gettimeofday((struct timeval *)&packet[8], NULL);
145 pkt->icmp_cksum = in_cksum((unsigned short *)pkt, sizeof(packet));
146
147 i = sendto(pingsock, packet, sizeof(packet), 0,
148 (struct sockaddr *)&pingaddr, sizeof(struct sockaddr_in));
149
150 if (i < 0 || i != sizeof(packet)) {
151 if (i < 0) perror("ping");
152 fprintf(stderr, "ping wrote %d chars; %d expected\n", i, sizeof(packet));
153 exit(1);
154 }
155
156 signal(SIGALRM, sendping);
157 if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next */
158 alarm(1);
159 } else { /* done, wait for the last ping to come back */
160 /* todo, don't necessarily need to wait so long... */
161 signal(SIGALRM, pingstats);
162 alarm(MAXWAIT);
163 }
164}
165
166static void unpack(char *buf, int sz, struct sockaddr_in *from)
167{
168 struct icmp *icmppkt;
169 struct iphdr *iphdr;
170 struct timeval tv, *tp;
171 int hlen, dupflag;
172 unsigned long triptime;
173
174 gettimeofday(&tv, NULL);
175
176 /* check IP header */
177 iphdr = (struct iphdr *)buf;
178 hlen = iphdr->ihl << 2;
179 /* discard if too short */
180 if (sz < (DEFDATALEN + ICMP_MINLEN)) return;
181
182 sz -= hlen;
183 icmppkt = (struct icmp *)(buf + hlen);
184
185 if (icmppkt->icmp_type == ICMP_ECHOREPLY) {
186 if (icmppkt->icmp_id != myid) return; /* not our ping */
187 ++nreceived;
188 tp = (struct timeval *)icmppkt->icmp_data;
189
190 if ((tv.tv_usec -= tp->tv_usec) < 0) {
191 --tv.tv_sec;
192 tv.tv_usec += 1000000;
193 }
194 tv.tv_sec -= tp->tv_sec;
195
196 triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100);
197 tsum += triptime;
198 if (triptime < tmin) tmin = triptime;
199 if (triptime > tmax) tmax = triptime;
200
201 if (TST(icmppkt->icmp_seq % MAX_DUP_CHK)) {
202 ++nrepeats;
203 --nreceived;
204 dupflag = 1;
205 } else {
206 SET(icmppkt->icmp_seq % MAX_DUP_CHK);
207 dupflag = 0;
208 }
209
210 if (options & O_QUIET) return;
211
212 printf("%d bytes from %s: icmp_seq=%u", sz,
213 inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
214 icmppkt->icmp_seq);
215 printf(" ttl=%d", iphdr->ttl);
216 printf(" time=%lu.%lu ms", triptime/10, triptime%10);
217 if (dupflag) printf(" (DUP!)");
218 printf("\n");
219 } else {
220 fprintf(stderr, "Warning: unknown ICMP packet received (not echo-reply)\n");
221 }
222}
223
224static void ping(char *host)
225{
226 struct protoent *proto;
227 struct hostent *h;
228 char buf[MAXHOSTNAMELEN];
229 char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
230 int sockopt;
231
232 if (!(proto = getprotobyname("icmp"))) {
233 fprintf(stderr, "ping: unknown protocol icmp\n");
234 exit(1);
235 }
236 if ((pingsock = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) {
237 if (errno == EPERM) {
238 fprintf(stderr, "ping: permission denied. (are you root?)\n");
239 } else {
240 perror("ping");
241 }
242 exit(1);
243 }
244
245#ifdef SUID_BUSYBOX
246 setuid(getuid());
247#endif
248
249 memset(&pingaddr, 0, sizeof(struct sockaddr_in));
250 pingaddr.sin_family = AF_INET;
251 if (inet_aton(host, &pingaddr.sin_addr)) {
252 hostname = host;
253 } else {
254 if (!(h = gethostbyname(host))) {
255 fprintf(stderr, "ping: unknown host %s\n", host);
256 exit(1);
257 }
258
259 if (h->h_addrtype != AF_INET) {
260 fprintf(stderr, "ping: unknown address type; only AF_INET is currently supported.\n");
261 exit(1);
262 }
263
264 pingaddr.sin_family = AF_INET; /* h->h_addrtype */
265 memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr));
266 strncpy(buf, h->h_name, sizeof(buf)-1);
267 hostname = buf;
268 }
269
270 /* enable broadcast pings */
271 sockopt = 1;
272 setsockopt(pingsock, SOL_SOCKET, SO_BROADCAST, (char *)&sockopt, sizeof(sockopt));
273
274 /* set recv buf for broadcast pings */
275 sockopt = 48 * 1024;
276 setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, (char *)&sockopt, sizeof(sockopt));
277
278 printf("PING %s (%s): %d data bytes\n",
279 hostname, inet_ntoa(*(struct in_addr *)&pingaddr.sin_addr.s_addr),
280 DEFDATALEN);
281
282 signal(SIGINT, pingstats);
283
284 /* start the ping's going ... */
285 sendping(0);
286
287 /* listen for replies */
288 while (1) {
289 struct sockaddr_in from;
290 size_t fromlen = sizeof(from);
291 int c;
292
293 if ((c = recvfrom(pingsock, packet, sizeof(packet), 0,
294 (struct sockaddr *)&from, &fromlen)) < 0) {
295 if (errno == EINTR) continue;
296 perror("ping");
297 continue;
298 }
299 unpack(packet, c, &from);
300 if (pingcount > 0 && nreceived >= pingcount) break;
301 }
302 pingstats(0);
303}
304
305extern int ping_main(int argc, char **argv)
306{
307 argc--;
308 argv++;
309 options = 0;
310 /* Parse any options */
311 if (argc < 1) usage(ping_usage);
312
313 while (**argv == '-') {
314 while (*++(*argv))
315 switch (**argv) {
316 case 'c':
317 argc--; argv++;
318 if (argc < 1) usage(ping_usage);
319 pingcount = atoi(*argv);
320 break;
321 case 'q':
322 options |= O_QUIET;
323 break;
324 default:
325 usage(ping_usage);
326 }
327 argc--;
328 argv++;
329 }
330
331 if (argc < 1) usage(ping_usage);
332
333 myid = getpid() & 0xFFFF;
334 ping(*(argv++));
335 exit( TRUE);
336}
337
338/*
339 * Copyright (c) 1989 The Regents of the University of California.
340 * All rights reserved.
341 *
342 * This code is derived from software contributed to Berkeley by
343 * Mike Muuss.
344 *
345 * Redistribution and use in source and binary forms, with or without
346 * modification, are permitted provided that the following conditions
347 * are met:
348 * 1. Redistributions of source code must retain the above copyright
349 * notice, this list of conditions and the following disclaimer.
350 * 2. Redistributions in binary form must reproduce the above copyright
351 * notice, this list of conditions and the following disclaimer in the
352 * documentation and/or other materials provided with the distribution.
353 * 3. All advertising materials mentioning features or use of this software
354 * must display the following acknowledgement:
355 * This product includes software developed by the University of
356 * California, Berkeley and its contributors.
357 * 4. Neither the name of the University nor the names of its contributors
358 * may be used to endorse or promote products derived from this software
359 * without specific prior written permission.
360 *
361 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
362 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
363 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
364 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
365 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
366 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
367 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
368 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
369 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
370 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
371 * SUCH DAMAGE.
372 */
373
374
diff --git a/umount.c b/umount.c
index 522498be7..ab76be4da 100644
--- a/umount.c
+++ b/umount.c
@@ -107,13 +107,6 @@ umount_all(int useMtab)
107extern int 107extern int
108umount_main(int argc, char** argv) 108umount_main(int argc, char** argv)
109{ 109{
110 int i=0;
111 char **foo=argv;
112 while(*foo) {
113 fprintf(stderr, "argv[%d]='%s'\n", i++, *foo);
114 foo++;
115 }
116
117 if (argc < 2) { 110 if (argc < 2) {
118 usage( umount_usage); 111 usage( umount_usage);
119 } 112 }
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 522498be7..ab76be4da 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -107,13 +107,6 @@ umount_all(int useMtab)
107extern int 107extern int
108umount_main(int argc, char** argv) 108umount_main(int argc, char** argv)
109{ 109{
110 int i=0;
111 char **foo=argv;
112 while(*foo) {
113 fprintf(stderr, "argv[%d]='%s'\n", i++, *foo);
114 foo++;
115 }
116
117 if (argc < 2) { 110 if (argc < 2) {
118 usage( umount_usage); 111 usage( umount_usage);
119 } 112 }