Patch from vodz:

Changed email address
    cmdedit API change
    optimizations for traceroute and md5sum
    added a new shared create_icmp_socket() function
This commit is contained in:
Eric Andersen 2001-07-12 20:26:32 +00:00
parent f69bfc76fa
commit 7467c8d3b6
27 changed files with 641 additions and 788 deletions

View File

@ -74,7 +74,7 @@ Enrique Zanardi <ezanardi@ull.es>
tarcat (since removed), loadkmap, various fixes, Debian maintenance
Vladimir Oleynik <dzo@simtreas.ru>
cmdedit, stty-port, locale, various fixes
cmdedit; ports: ash, stty, traceroute; locale, various fixes
and irreconcilable critic of everything not perfect.
Tim Riker <Tim@Rikers.org>

View File

@ -4,10 +4,11 @@
* None yet
New Applets:
* None yet
* Vladimir Oleynik -- traceroute
Other Changes:
* Vladimir Oleynik -- Fixed tr to support 'tr a-z A-Z' syntax.
* Vladimir Oleynik -- Fixed tr to support 'tr a-z A-Z' syntax,
many ash corrections, and others optimizations, and cleanups.
-Not Yet Released

View File

@ -247,7 +247,7 @@ safe_read.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \
trim.c unzip.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c \
xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \
copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \
dirname.c make_directory.c
dirname.c make_directory.c create_icmp_socket.c
LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC))
LIBBB_CFLAGS = -I$(LIBBB)
ifneq ($(strip $(BB_SRC_DIR)),)
@ -257,7 +257,7 @@ endif
LIBBB_MSRC=libbb/messages.c
LIBBB_MESSAGES= full_version name_too_long omitting_directory not_a_directory \
memory_exhausted invalid_date invalid_option io_error dash_dash_help \
write_error too_few_args name_longer_than_foo unknown
write_error too_few_args name_longer_than_foo unknown can_not_create_raw_socket
LIBBB_MOBJ=$(patsubst %,$(LIBBB)/%.o, $(LIBBB_MESSAGES))
LIBBB_ARCSRC=libbb/unarchive.c
@ -365,7 +365,7 @@ $(LIBBB_MOBJ): $(LIBBB_MSRC)
- mkdir -p $(LIBBB)
$(CC) $(CFLAGS) $(LIBBB_CFLAGS) -DL_$(patsubst libbb/%,%,$*) -c $< -o $*.o
$(LIBBB_AROBJS): $(LIBBB_ARCSRC) Makefile
$(LIBBB_AROBJS): $(LIBBB_ARCSRC)
- mkdir -p $(LIBBB)
$(CC) $(CFLAGS) $(LIBBB_CFLAGS) -DL_$(patsubst libbb/%,%,$*) -c $< -o $*.o

34
ash.c
View File

@ -26,7 +26,7 @@
* package.
*
* Modified by Erik Andersen <andersee@debian.org> and
* Vladimir Oleynik <vodz@usa.net> to be used in busybox
* Vladimir Oleynik <dzo@simtreas.ru> to be used in busybox
*
*
* Original copyright notice is retained at the end of this file.
@ -4995,7 +4995,7 @@ err1:
if (--in.nleft < 0) {
if (in.fd < 0)
break;
while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR);
i = safe_read(in.fd, buf, sizeof buf);
TRACE(("expbackq: read returns %d\n", i));
if (i <= 0)
break;
@ -6091,10 +6091,8 @@ init(void) {
* interactive shell and control is returned to the main command loop.
*/
#ifdef ASH_ALIAS
/* 1 == check for aliases, 2 == also check for assignments */
static int checkalias;
#endif
static int checkalias; /* also used in no alias mode for check assignments */
static void
reset(void) {
@ -6117,9 +6115,7 @@ reset(void) {
{
tokpushback = 0;
checkkwd = 0;
#ifdef ASH_ALIAS
checkalias = 0;
#endif
}
/* from redir.c: */
@ -6137,7 +6133,6 @@ reset(void) {
*/
#ifdef BB_FEATURE_COMMAND_EDITING
unsigned int shell_context;
static const char * cmdedit_prompt;
static inline void putprompt(const char *s) {
cmdedit_prompt = s;
@ -6206,23 +6201,18 @@ preadfd(void)
retry:
#ifdef BB_FEATURE_COMMAND_EDITING
{
if (parsefile->fd)
nr = read(parsefile->fd, buf, BUFSIZ - 1);
if (!iflag)
nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
else {
do {
cmdedit_read_input((char*)cmdedit_prompt, buf);
nr = strlen(buf);
} while (nr <=0 || shell_context);
cmdedit_terminate();
}
}
#else
nr = read(parsefile->fd, buf, BUFSIZ - 1);
nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
#endif
if (nr < 0) {
if (errno == EINTR)
goto retry;
if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
int flags = fcntl(0, F_GETFL, 0);
if (flags >= 0 && flags & O_NONBLOCK) {
@ -9872,9 +9862,7 @@ simplecmd() {
redir = NULL;
rpp = &redir;
#ifdef ASH_ALIAS
checkalias = 2;
#endif
for (;;) {
switch (readtoken()) {
case TWORD:
@ -10036,9 +10024,10 @@ peektoken() {
static int
readtoken() {
int t;
#ifdef ASH_ALIAS
int savecheckkwd = checkkwd;
int savecheckalias = checkalias;
int savecheckkwd = checkkwd;
struct alias *ap;
#endif
@ -10083,13 +10072,14 @@ top:
}
}
#ifdef ASH_ALIAS
if (t != TWORD) {
if (t != TREDIR) {
checkalias = 0;
}
} else if (checkalias == 2 && isassignment(wordtext)) {
lasttoken = t = TASSIGN;
#ifdef ASH_ALIAS
} else if (checkalias) {
if (!quoteflag && (ap = lookupalias(wordtext, 1)) != NULL) {
if (*ap->val) {
@ -10099,8 +10089,8 @@ top:
goto top;
}
checkalias = 0;
}
#endif
}
out:
#ifdef DEBUG
if (!alreadyseen)
@ -12927,7 +12917,7 @@ findvar(struct var **vpp, const char *name)
/*
* Copyright (c) 1999 Herbert Xu <herbert@debian.org>
* This file contains code for the times builtin.
* $Id: ash.c,v 1.9 2001/07/10 16:57:09 andersen Exp $
* $Id: ash.c,v 1.10 2001/07/12 20:26:31 andersen Exp $
*/
static int timescmd (int argc, char **argv)
{

View File

@ -3,7 +3,7 @@
* Termios command line History and Editting.
*
* Copyright (c) 1986-2001 may safely be consumed by a BSD or GPL license.
* Written by: Vladimir Oleynik <vodz@usa.net>
* Written by: Vladimir Oleynik <dzo@simtreas.ru>
*
* Used ideas:
* Adam Rogoyski <rogoyski@cs.utexas.edu>
@ -123,9 +123,8 @@ volatile int handlers_sets = 0; /* Set next bites: */
enum {
SET_ATEXIT = 1, /* when atexit() has been called
and get euid,uid,gid to fast compare */
SET_TERM_HANDLERS = 2, /* set many terminates signal handlers */
SET_WCHG_HANDLERS = 4, /* winchg signal handler */
SET_RESET_TERM = 8, /* if the terminal needs to be reset upon exit */
SET_WCHG_HANDLERS = 2, /* winchg signal handler */
SET_RESET_TERM = 4, /* if the terminal needs to be reset upon exit */
};
@ -142,10 +141,6 @@ static
#endif
char *cmdedit_prompt; /* --- "" - - "" - -"- --""-- --""--- */
/* Link into lash to reset context to 0 on ^C and such */
extern unsigned int shell_context;
#ifdef BB_FEATURE_GETUSERNAME_AND_HOMEDIR
static char *user_buf = "";
static char *home_pwd_buf = "";
@ -319,6 +314,7 @@ static void put_prompt(void)
out1str(cmdedit_prompt);
cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */
cursor = 0;
cmdedit_y = 0; /* new quasireal y */
}
#ifndef BB_FEATURE_SH_FANCY_PROMPT
@ -456,7 +452,6 @@ static void redraw(int y, int back_cursor)
{
if (y > 0) /* up to start y */
printf("\033[%dA", y);
cmdedit_y = 0; /* new quasireal y */
putchar('\r');
put_prompt();
input_end(); /* rewrite */
@ -497,14 +492,6 @@ static void input_forward(void)
}
static void clean_up_and_die(int sig)
{
goto_new_line();
if (sig != SIGINT)
exit(EXIT_SUCCESS); /* cmdedit_reset_term() called in atexit */
cmdedit_reset_term();
}
static void cmdedit_setwidth(int w, int redraw_flg)
{
cmdedit_termw = cmdedit_prmt_len + 2;
@ -525,7 +512,7 @@ static void cmdedit_setwidth(int w, int redraw_flg)
}
}
extern void cmdedit_init(void)
static void cmdedit_init(void)
{
cmdedit_prmt_len = 0;
if ((handlers_sets & SET_WCHG_HANDLERS) == 0) {
@ -557,14 +544,6 @@ extern void cmdedit_init(void)
handlers_sets |= SET_ATEXIT;
atexit(cmdedit_reset_term); /* be sure to do this only once */
}
if ((handlers_sets & SET_TERM_HANDLERS) == 0) {
signal(SIGKILL, clean_up_and_die);
signal(SIGINT, clean_up_and_die);
signal(SIGQUIT, clean_up_and_die);
signal(SIGTERM, clean_up_and_die);
handlers_sets |= SET_TERM_HANDLERS;
}
}
#ifdef BB_FEATURE_COMMAND_TAB_COMPLETION
@ -1220,7 +1199,7 @@ extern void cmdedit_read_input(char *prompt, char command[BUFSIZ])
fflush(stdout); /* buffered out to fast */
if (read(0, &c, 1) < 1)
if (safe_read(0, &c, 1) < 1)
/* if we can't read input then exit */
goto prepare_to_die;
@ -1241,22 +1220,21 @@ extern void cmdedit_read_input(char *prompt, char command[BUFSIZ])
break;
case 3:
/* Control-c -- stop gathering input */
/* Link into lash to reset context to 0 on ^C and such */
shell_context = 0;
/* Go to the next line */
goto_new_line();
command[0] = 0;
return;
len = 0;
lastWasTab = FALSE;
put_prompt();
break;
case 4:
/* Control-d -- Delete one character, or exit
* if the len=0 and no chars to delete */
if (len == 0) {
prepare_to_die:
printf("exit");
clean_up_and_die(0);
goto_new_line();
/* cmdedit_reset_term() called in atexit */
exit(EXIT_SUCCESS);
} else {
input_delete();
}
@ -1307,12 +1285,12 @@ prepare_to_die:
case ESC:{
/* escape sequence follows */
if (read(0, &c, 1) < 1)
return;
if (safe_read(0, &c, 1) < 1)
goto prepare_to_die;
/* different vt100 emulations */
if (c == '[' || c == 'O') {
if (read(0, &c, 1) < 1)
return;
if (safe_read(0, &c, 1) < 1)
goto prepare_to_die;
}
switch (c) {
#ifdef BB_FEATURE_COMMAND_TAB_COMPLETION
@ -1376,8 +1354,8 @@ prepare_to_die:
}
if (c >= '1' && c <= '9')
do
if (read(0, &c, 1) < 1)
return;
if (safe_read(0, &c, 1) < 1)
goto prepare_to_die;
while (c != '~');
break;
}
@ -1386,8 +1364,8 @@ prepare_to_die:
#ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT
/* Control-V -- Add non-printable symbol */
if (c == 22) {
if (read(0, &c, 1) < 1)
return;
if (safe_read(0, &c, 1) < 1)
goto prepare_to_die;
if (c == 0) {
beep();
break;
@ -1485,24 +1463,11 @@ prepare_to_die:
#if defined(BB_FEATURE_SH_FANCY_PROMPT)
free(cmdedit_prompt);
#endif
return;
}
/* Undo the effects of cmdedit_init(). */
extern void cmdedit_terminate(void)
{
cmdedit_reset_term();
if ((handlers_sets & SET_TERM_HANDLERS) != 0) {
signal(SIGKILL, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGWINCH, SIG_DFL);
handlers_sets &= ~SET_TERM_HANDLERS;
}
}
#endif /* BB_FEATURE_COMMAND_EDITING */
@ -1515,8 +1480,6 @@ const char *memory_exhausted = "Memory exhausted";
#include <locale.h>
#endif
unsigned int shell_context;
int main(int argc, char **argv)
{
char buff[BUFSIZ];
@ -1532,15 +1495,16 @@ int main(int argc, char **argv)
#ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT
setlocale(LC_ALL, "");
#endif
shell_context = 1;
do {
while(1) {
int l;
cmdedit_read_input(prompt, buff);
l = strlen(buff);
if(l==0)
break;
if(l > 0 && buff[l-1] == '\n')
buff[l-1] = 0;
printf("*** cmdedit_read_input() returned line =%s=\n", buff);
} while (shell_context);
}
printf("*** cmdedit_read_input() detect ^C\n");
return 0;
}

View File

@ -1,8 +1,6 @@
#ifndef CMDEDIT_H
#define CMDEDIT_H
void cmdedit_init(void);
void cmdedit_terminate(void);
void cmdedit_read_input(char* promptStr, char* command); /* read a line of input */
#endif /* CMDEDIT_H */

View File

@ -770,12 +770,10 @@ static int md5_file(const char *filename,
have_read_stdin = 1;
fp = stdin;
} else {
fp = fopen(filename, "r");
if (fp == NULL) {
perror_msg("%s", filename);
fp = wfopen(filename, "r");
if (fp == NULL)
return FALSE;
}
}
if (md5_stream(fp, md5_result)) {
perror_msg("%s", filename);
@ -807,12 +805,10 @@ static int md5_check(const char *checkfile_name)
have_read_stdin = 1;
checkfile_stream = stdin;
} else {
checkfile_stream = fopen(checkfile_name, "r");
if (checkfile_stream == NULL) {
perror_msg("%s", checkfile_name);
checkfile_stream = wfopen(checkfile_name, "r");
if (checkfile_stream == NULL)
return FALSE;
}
}
line_number = 0;

View File

@ -24,7 +24,7 @@
David MacKenzie <djm@gnu.ai.mit.edu>
Special for busybox ported by Vladimir Oleynik <vodz@usa.net> 2001
Special for busybox ported by Vladimir Oleynik <dzo@simtreas.ru> 2001
*/

7
hush.c
View File

@ -237,10 +237,6 @@ unsigned int global_argc;
unsigned int last_return_code;
extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */
/* Variables we export */
unsigned int shell_context; /* Used in cmdedit.c to reset the
* context when someone hits ^C */
/* "globals" within this file */
static char *ifs;
static char map[256];
@ -883,7 +879,6 @@ static void get_user_input(struct in_str *i)
** child processes (rob@sysgo.de)
*/
cmdedit_read_input(prompt_str, the_command);
cmdedit_terminate();
#else
fputs(prompt_str, stdout);
fflush(stdout);
@ -1411,6 +1406,7 @@ static int run_pipe_real(struct pipe *pi)
/* Set the handling for job control signals back to the default. */
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGTSTP, SIG_DFL);
signal(SIGTTIN, SIG_DFL);
signal(SIGTTOU, SIG_DFL);
@ -2551,6 +2547,7 @@ static void setup_job_control()
/* Ignore interactive and job-control signals. */
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);

View File

@ -252,6 +252,7 @@ extern void gz_close(int gunzip_pid);
extern FILE *gz_open(FILE *compressed_file, int *pid);
extern struct hostent *xgethostbyname(const char *name);
extern int create_icmp_socket(void);
char *dirname (const char *path);
@ -284,5 +285,6 @@ extern const char * const write_error;
extern const char * const too_few_args;
extern const char * const name_longer_than_foo;
extern const char * const unknown;
extern const char * const can_not_create_raw_socket;
#endif /* __LIBBB_H__ */

6
lash.c
View File

@ -170,9 +170,7 @@ static struct built_in_command bltins_forking[] = {
};
/* Variables we export */
unsigned int shell_context; /* Used in cmdedit.c to reset the
context when someone hits ^C */
static int shell_context; /* Type prompt trigger (PS1 or PS2) */
/* Globals that are static to this file */
@ -716,7 +714,6 @@ static int get_command(FILE * source, char *command)
** child processes (rob@sysgo.de)
*/
cmdedit_read_input(prompt_str, command);
cmdedit_terminate();
return 0;
#else
fputs(prompt_str, stdout);
@ -1557,7 +1554,6 @@ int shell_main(int argc_l, char **argv_l)
/* These variables need re-initializing when recursing */
last_jobid = 0;
shell_context = 0;
local_pending_command = NULL;
close_me_head = NULL;
job_list.head = NULL;

View File

@ -0,0 +1,37 @@
/* vi: set sw=4 ts=4: */
/*
* Utility routines.
*
* create raw socket for icmp protocol test permision
* and drop root privilegies if running setuid
*
*/
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
#include "libbb.h"
int create_icmp_socket(void)
{
struct protoent *proto;
int sock;
proto = getprotobyname("icmp");
/* if getprotobyname failed, just silently force
* proto->p_proto to have the correct value for "icmp" */
if ((sock = socket(AF_INET, SOCK_RAW,
(proto ? proto->p_proto : 1))) < 0) { /* 1 == ICMP */
if (errno == EPERM)
error_msg_and_die("permission denied. (are you root?)");
else
perror_msg_and_die(can_not_create_raw_socket);
}
/* drop root privs if running setuid */
setuid(getuid());
return sock;
}

View File

@ -252,6 +252,7 @@ extern void gz_close(int gunzip_pid);
extern FILE *gz_open(FILE *compressed_file, int *pid);
extern struct hostent *xgethostbyname(const char *name);
extern int create_icmp_socket(void);
char *dirname (const char *path);
@ -284,5 +285,6 @@ extern const char * const write_error;
extern const char * const too_few_args;
extern const char * const name_longer_than_foo;
extern const char * const unknown;
extern const char * const can_not_create_raw_socket;
#endif /* __LIBBB_H__ */

View File

@ -62,3 +62,6 @@
const char * const unknown = "(unknown)";
#endif
#ifdef L_can_not_create_raw_socket
const char * const can_not_create_raw_socket = "can`t create raw socket";
#endif

View File

@ -770,12 +770,10 @@ static int md5_file(const char *filename,
have_read_stdin = 1;
fp = stdin;
} else {
fp = fopen(filename, "r");
if (fp == NULL) {
perror_msg("%s", filename);
fp = wfopen(filename, "r");
if (fp == NULL)
return FALSE;
}
}
if (md5_stream(fp, md5_result)) {
perror_msg("%s", filename);
@ -807,12 +805,10 @@ static int md5_check(const char *checkfile_name)
have_read_stdin = 1;
checkfile_stream = stdin;
} else {
checkfile_stream = fopen(checkfile_name, "r");
if (checkfile_stream == NULL) {
perror_msg("%s", checkfile_name);
checkfile_stream = wfopen(checkfile_name, "r");
if (checkfile_stream == NULL)
return FALSE;
}
}
line_number = 0;

12
msh.c
View File

@ -682,8 +682,7 @@ static void * brkaddr;
#ifdef BB_FEATURE_COMMAND_EDITING
char * current_prompt;
unsigned int shell_context;
static char * current_prompt;
#endif
@ -4449,9 +4448,7 @@ register struct ioarg *ap;
if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
if (i)
lseek(ap->afile, ap->afpos, 0);
do {
i = read(ap->afile, bp->buf, sizeof(bp->buf));
} while (i < 0 && errno == EINTR);
i = safe_read(ap->afile, bp->buf, sizeof(bp->buf));
if (i <= 0) {
closef(ap->afile);
return 0;
@ -4470,7 +4467,6 @@ register struct ioarg *ap;
while (size == 0 || position >= size) {
cmdedit_read_input(current_prompt, mycommand);
cmdedit_terminate();
size = strlen(mycommand);
position = 0;
}
@ -4480,9 +4476,7 @@ register struct ioarg *ap;
} else
#endif
{
do {
i = read(ap->afile, &c, sizeof(c));
} while (i < 0 && errno == EINTR);
i = safe_read(ap->afile, &c, sizeof(c));
return(i == sizeof(c)? c&0177: (closef(ap->afile), 0));
}
}

View File

@ -1,6 +1,6 @@
/* vi: set sw=4 ts=4: */
/*
* $Id: ping.c,v 1.43 2001/05/21 20:30:51 andersen Exp $
* $Id: ping.c,v 1.44 2001/07/12 20:26:31 andersen Exp $
* Mini ping implementation for busybox
*
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@ -191,11 +191,7 @@ static void ping(const char *host)
int pingsock, c;
char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) /* 1 == ICMP */
perror_msg_and_die("creating a raw socket");
/* drop root privs if running setuid */
setuid(getuid());
pingsock = create_raw_socket();
memset(&pingaddr, 0, sizeof(struct sockaddr_in));
@ -434,7 +430,7 @@ static void ping(const char *host)
if (errno == EPERM)
error_msg_and_die("permission denied. (are you root?)");
else
perror_msg_and_die("creating a raw socket");
perror_msg_and_die(can_not_create_raw_socket);
}
/* drop root privs if running setuid */

View File

@ -5,6 +5,7 @@
* This code is derived from software contributed to Berkeley by
* Van Jacobson.
*
* Special for busybox ported by Vladimir Oleynik <dzo@simtreas.ru> 2001
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -61,6 +62,10 @@
* Tue Dec 20 03:50:13 PST 1988
*/
#undef BB_FEATURE_TRACEROUTE_VERBOSE
//#define BB_FEATURE_TRACEROUTE_VERBOSE
#undef BB_FEATURE_TRACEROUTE_SO_DEBUG /* not in documentation man */
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
@ -100,13 +105,6 @@ struct opacket {
#include "busybox.h"
static int wait_for_reply (int, struct sockaddr_in *, int);
static void send_probe (int, int);
static double deltaT (struct timeval *, struct timeval *);
static int packet_ok (u_char *, int, struct sockaddr_in *, int);
static void print (u_char *, int, struct sockaddr_in *);
static char *inetname (struct in_addr);
static u_char packet[512]; /* last inbound (icmp) packet */
static struct opacket *outpacket; /* last output (udp) packet */
@ -122,10 +120,229 @@ static int max_ttl = 30;
static u_short ident;
static u_short port = 32768+666; /* start udp dest port # for probe packets */
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
static int verbose;
#endif
static int waittime = 5; /* time to wait for response (in seconds) */
static int nflag; /* print addresses numerically */
/*
* Construct an Internet address representation.
* If the nflag has been supplied, give
* numeric value, otherwise try for symbolic name.
*/
static inline char *
inetname(struct in_addr in)
{
char *cp;
static char line[50];
struct hostent *hp;
static char domain[MAXHOSTNAMELEN + 1];
static int first = 1;
if (first && !nflag) {
first = 0;
if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
(cp = index(domain, '.')))
(void) strcpy(domain, cp + 1);
else
domain[0] = 0;
}
cp = 0;
if (!nflag && in.s_addr != INADDR_ANY) {
hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);
if (hp) {
if ((cp = index(hp->h_name, '.')) &&
!strcmp(cp + 1, domain))
*cp = 0;
cp = (char *)hp->h_name;
}
}
if (cp)
(void) strcpy(line, cp);
else {
in.s_addr = ntohl(in.s_addr);
strcpy(line, inet_ntoa(in));
}
return (line);
}
static inline void
print(u_char *buf, int cc, struct sockaddr_in *from)
{
struct ip *ip;
int hlen;
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
cc -= hlen;
if (nflag)
printf(" %s", inet_ntoa(from->sin_addr));
else
printf(" %s (%s)", inetname(from->sin_addr),
inet_ntoa(from->sin_addr));
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
if (verbose)
printf (" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
#endif
}
static inline double
deltaT(struct timeval *t1p, struct timeval *t2p)
{
double dt;
dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
(double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
return (dt);
}
static inline int
wait_for_reply(int sock, struct sockaddr_in *from, int reset_timer)
{
fd_set fds;
static struct timeval wait;
int cc = 0;
int fromlen = sizeof (*from);
FD_ZERO(&fds);
FD_SET(sock, &fds);
if (reset_timer) {
/*
* traceroute could hang if someone else has a ping
* running and our ICMP reply gets dropped but we don't
* realize it because we keep waking up to handle those
* other ICMP packets that keep coming in. To fix this,
* "reset_timer" will only be true if the last packet that
* came in was for us or if this is the first time we're
* waiting for a reply since sending out a probe. Note
* that this takes advantage of the select() feature on
* Linux where the remaining timeout is written to the
* struct timeval area.
*/
wait.tv_sec = waittime;
wait.tv_usec = 0;
}
if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0)
cc=recvfrom(s, (char *)packet, sizeof(packet), 0,
(struct sockaddr *)from, &fromlen);
return(cc);
}
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
/*
* Convert an ICMP "type" field to a printable string.
*/
static inline const char *
pr_type(t)
u_char t;
{
static const char * const ttab[] = {
"Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
"Source Quench", "Redirect", "ICMP 6", "ICMP 7",
"Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
"Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
"Info Reply"
};
if(t > 16)
return("OUT-OF-RANGE");
return(ttab[t]);
}
#endif
static inline int
packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq)
{
struct icmp *icp;
u_char type, code;
int hlen;
struct ip *ip;
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
if (cc < hlen + ICMP_MINLEN) {
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
if (verbose)
printf("packet too short (%d bytes) from %s\n", cc,
inet_ntoa(from->sin_addr));
#endif
return (0);
}
cc -= hlen;
icp = (struct icmp *)(buf + hlen);
type = icp->icmp_type; code = icp->icmp_code;
if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
type == ICMP_UNREACH) {
struct ip *hip;
struct udphdr *up;
hip = &icp->icmp_ip;
hlen = hip->ip_hl << 2;
up = (struct udphdr *)((u_char *)hip + hlen);
if (hlen + 12 <= cc && hip->ip_p == IPPROTO_UDP &&
up->source == htons(ident) &&
up->dest == htons(port+seq))
return (type == ICMP_TIMXCEED? -1 : code+1);
}
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
if (verbose) {
int i;
u_long *lp = (u_long *)&icp->icmp_ip;
printf("\n%d bytes from %s to %s: icmp type %d (%s) code %d\n",
cc, inet_ntoa(from->sin_addr), inet_ntoa(ip->ip_dst),
type, pr_type(type), icp->icmp_code);
for (i = 4; i < cc ; i += sizeof(long))
printf("%2d: x%8.8lx\n", i, *lp++);
}
#endif
return(0);
}
static void /* not inline */
send_probe(int seq, int ttl)
{
struct opacket *op = outpacket;
struct ip *ip = &op->ip;
struct udphdr *up = &op->udp;
int i;
struct timezone tz;
ip->ip_off = 0;
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_p = IPPROTO_UDP;
ip->ip_len = datalen;
ip->ip_ttl = ttl;
ip->ip_v = IPVERSION;
ip->ip_id = htons(ident+seq);
up->source = htons(ident);
up->dest = htons(port+seq);
up->len = htons((u_short)(datalen - sizeof(struct ip)));
up->check = 0;
op->seq = seq;
op->ttl = ttl;
(void) gettimeofday(&op->tv, &tz);
i = sendto(sndsock, (char *)outpacket, datalen, 0, &whereto,
sizeof(struct sockaddr));
if (i < 0 || i != datalen) {
if (i<0)
perror("sendto");
printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
datalen, i);
(void) fflush(stdout);
}
}
int
#ifndef BB_TRACEROUTE
main(argc, argv)
@ -138,7 +355,6 @@ traceroute_main(argc, argv)
extern char *optarg;
extern int optind;
struct hostent *hp;
struct protoent *pe;
struct sockaddr_in from, *to;
int ch, i, on, probe, seq, tos, ttl;
@ -152,7 +368,9 @@ traceroute_main(argc, argv)
while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF)
switch(ch) {
case 'd':
#ifdef BB_FEATURE_TRACEROUTE_SO_DEBUG
options |= SO_DEBUG;
#endif
break;
case 'm':
max_ttl = atoi(optarg);
@ -188,7 +406,9 @@ traceroute_main(argc, argv)
error_msg_and_die("tos must be 0 to 255.");
break;
case 'v':
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
verbose++;
#endif
break;
case 'w':
waittime = atoi(optarg);
@ -206,21 +426,11 @@ traceroute_main(argc, argv)
setlinebuf (stdout);
(void) bzero((char *)&whereto, sizeof(struct sockaddr));
to->sin_family = AF_INET;
to->sin_addr.s_addr = inet_addr(*argv);
if (to->sin_addr.s_addr != -1)
hostname = *argv;
else {
hp = gethostbyname(*argv);
if (hp) {
memset(&whereto, 0, sizeof(struct sockaddr));
hp = xgethostbyname(*argv);
to->sin_family = hp->h_addrtype;
bcopy(hp->h_addr, (caddr_t)&to->sin_addr, hp->h_length);
memcpy(&to->sin_addr, hp->h_addr, hp->h_length);
hostname = (char *)hp->h_name;
} else {
error_msg_and_die("unknown host %s", *argv);
}
}
if (*++argv)
datalen = atoi(*argv);
if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket))
@ -228,7 +438,7 @@ traceroute_main(argc, argv)
MAXPACKET - sizeof(struct opacket));
datalen += sizeof(struct opacket);
outpacket = (struct opacket *)xmalloc((unsigned)datalen);
(void) bzero((char *)outpacket, datalen);
memset(outpacket, 0, datalen);
outpacket->ip.ip_dst = to->sin_addr;
outpacket->ip.ip_tos = tos;
outpacket->ip.ip_v = IPVERSION;
@ -236,19 +446,19 @@ traceroute_main(argc, argv)
ident = (getpid() & 0xffff) | 0x8000;
if ((pe = getprotobyname("icmp")) == NULL)
error_msg_and_die("icmp: unknown protocol");
if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0)
perror_msg_and_die("icmp socket");
if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
perror_msg_and_die(can_not_create_raw_socket);
s = create_icmp_socket();
#ifdef BB_FEATURE_TRACEROUTE_SO_DEBUG
if (options & SO_DEBUG)
(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
(char *)&on, sizeof(on));
#endif
if (options & SO_DONTROUTE)
(void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE,
(char *)&on, sizeof(on));
if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
perror_msg_and_die("raw socket");
#ifdef SO_SNDBUF
if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
sizeof(datalen)) < 0)
@ -259,15 +469,17 @@ traceroute_main(argc, argv)
sizeof(on)) < 0)
perror_msg_and_die("IP_HDRINCL");
#endif IP_HDRINCL
#ifdef BB_FEATURE_TRACEROUTE_SO_DEBUG
if (options & SO_DEBUG)
(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
(char *)&on, sizeof(on));
#endif
if (options & SO_DONTROUTE)
(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
(char *)&on, sizeof(on));
if (source) {
(void) bzero((char *)&from, sizeof(struct sockaddr));
memset(&from, 0, sizeof(struct sockaddr));
from.sin_family = AF_INET;
from.sin_addr.s_addr = inet_addr(source);
if (from.sin_addr.s_addr == -1)
@ -284,7 +496,6 @@ traceroute_main(argc, argv)
if (source)
fprintf(stderr, " from %s", source);
fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen);
(void) fflush(stderr);
for (ttl = 1; ttl <= max_ttl; ++ttl) {
u_long lastaddr = 0;
@ -312,11 +523,9 @@ traceroute_main(argc, argv)
printf(" %g ms", deltaT(&t1, &t2));
switch(i - 1) {
case ICMP_UNREACH_PORT:
#ifndef ARCHAIC
ip = (struct ip *)packet;
if (ip->ip_ttl <= 1)
printf(" !");
#endif ARCHAIC
++got_there;
break;
case ICMP_UNREACH_NET:
@ -355,239 +564,3 @@ traceroute_main(argc, argv)
return 0;
}
static int
wait_for_reply(sock, from, reset_timer)
int sock;
struct sockaddr_in *from;
int reset_timer;
{
fd_set fds;
static struct timeval wait;
int cc = 0;
int fromlen = sizeof (*from);
FD_ZERO(&fds);
FD_SET(sock, &fds);
if (reset_timer) {
/*
* traceroute could hang if someone else has a ping
* running and our ICMP reply gets dropped but we don't
* realize it because we keep waking up to handle those
* other ICMP packets that keep coming in. To fix this,
* "reset_timer" will only be true if the last packet that
* came in was for us or if this is the first time we're
* waiting for a reply since sending out a probe. Note
* that this takes advantage of the select() feature on
* Linux where the remaining timeout is written to the
* struct timeval area.
*/
wait.tv_sec = waittime;
wait.tv_usec = 0;
}
if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0)
cc=recvfrom(s, (char *)packet, sizeof(packet), 0,
(struct sockaddr *)from, &fromlen);
return(cc);
}
static void
send_probe(seq, ttl)
int seq, ttl;
{
struct opacket *op = outpacket;
struct ip *ip = &op->ip;
struct udphdr *up = &op->udp;
int i;
struct timezone tz;
ip->ip_off = 0;
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_p = IPPROTO_UDP;
ip->ip_len = datalen;
ip->ip_ttl = ttl;
ip->ip_v = IPVERSION;
ip->ip_id = htons(ident+seq);
up->source = htons(ident);
up->dest = htons(port+seq);
up->len = htons((u_short)(datalen - sizeof(struct ip)));
up->check = 0;
op->seq = seq;
op->ttl = ttl;
(void) gettimeofday(&op->tv, &tz);
i = sendto(sndsock, (char *)outpacket, datalen, 0, &whereto,
sizeof(struct sockaddr));
if (i < 0 || i != datalen) {
if (i<0)
perror("sendto");
printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
datalen, i);
(void) fflush(stdout);
}
}
static double
deltaT(t1p, t2p)
struct timeval *t1p, *t2p;
{
register double dt;
dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
(double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
return (dt);
}
/*
* Convert an ICMP "type" field to a printable string.
*/
static const char *
pr_type(t)
u_char t;
{
static const char * const ttab[] = {
"Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
"Source Quench", "Redirect", "ICMP 6", "ICMP 7",
"Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
"Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
"Info Reply"
};
if(t > 16)
return("OUT-OF-RANGE");
return(ttab[t]);
}
static int
packet_ok(buf, cc, from, seq)
u_char *buf;
int cc;
struct sockaddr_in *from;
int seq;
{
register struct icmp *icp;
u_char type, code;
int hlen;
#ifndef ARCHAIC
struct ip *ip;
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
if (cc < hlen + ICMP_MINLEN) {
if (verbose)
printf("packet too short (%d bytes) from %s\n", cc,
inet_ntoa(from->sin_addr));
return (0);
}
cc -= hlen;
icp = (struct icmp *)(buf + hlen);
#else
icp = (struct icmp *)buf;
#endif ARCHAIC
type = icp->icmp_type; code = icp->icmp_code;
if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
type == ICMP_UNREACH) {
struct ip *hip;
struct udphdr *up;
hip = &icp->icmp_ip;
hlen = hip->ip_hl << 2;
up = (struct udphdr *)((u_char *)hip + hlen);
if (hlen + 12 <= cc && hip->ip_p == IPPROTO_UDP &&
up->source == htons(ident) &&
up->dest == htons(port+seq))
return (type == ICMP_TIMXCEED? -1 : code+1);
}
#ifndef ARCHAIC
if (verbose) {
int i;
u_long *lp = (u_long *)&icp->icmp_ip;
printf("\n%d bytes from %s to %s", cc,
inet_ntoa(from->sin_addr), inet_ntoa(ip->ip_dst));
printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
icp->icmp_code);
for (i = 4; i < cc ; i += sizeof(long))
printf("%2d: x%8.8lx\n", i, *lp++);
}
#endif ARCHAIC
return(0);
}
static void
print(buf, cc, from)
u_char *buf;
int cc;
struct sockaddr_in *from;
{
struct ip *ip;
int hlen;
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
cc -= hlen;
if (nflag)
printf(" %s", inet_ntoa(from->sin_addr));
else
printf(" %s (%s)", inetname(from->sin_addr),
inet_ntoa(from->sin_addr));
if (verbose)
printf (" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
}
/*
* Construct an Internet address representation.
* If the nflag has been supplied, give
* numeric value, otherwise try for symbolic name.
*/
static char *
inetname(in)
struct in_addr in;
{
register char *cp;
static char line[50];
struct hostent *hp;
static char domain[MAXHOSTNAMELEN + 1];
static int first = 1;
if (first && !nflag) {
first = 0;
if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
(cp = index(domain, '.')))
(void) strcpy(domain, cp + 1);
else
domain[0] = 0;
}
cp = 0;
if (!nflag && in.s_addr != INADDR_ANY) {
hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);
if (hp) {
if ((cp = index(hp->h_name, '.')) &&
!strcmp(cp + 1, domain))
*cp = 0;
cp = (char *)hp->h_name;
}
}
if (cp)
(void) strcpy(line, cp);
else {
in.s_addr = ntohl(in.s_addr);
#define C(x) ((x) & 0xff)
sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
}
return (line);
}

10
ping.c
View File

@ -1,6 +1,6 @@
/* vi: set sw=4 ts=4: */
/*
* $Id: ping.c,v 1.43 2001/05/21 20:30:51 andersen Exp $
* $Id: ping.c,v 1.44 2001/07/12 20:26:31 andersen Exp $
* Mini ping implementation for busybox
*
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@ -191,11 +191,7 @@ static void ping(const char *host)
int pingsock, c;
char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) /* 1 == ICMP */
perror_msg_and_die("creating a raw socket");
/* drop root privs if running setuid */
setuid(getuid());
pingsock = create_raw_socket();
memset(&pingaddr, 0, sizeof(struct sockaddr_in));
@ -434,7 +430,7 @@ static void ping(const char *host)
if (errno == EPERM)
error_msg_and_die("permission denied. (are you root?)");
else
perror_msg_and_die("creating a raw socket");
perror_msg_and_die(can_not_create_raw_socket);
}
/* drop root privs if running setuid */

View File

@ -26,7 +26,7 @@
* package.
*
* Modified by Erik Andersen <andersee@debian.org> and
* Vladimir Oleynik <vodz@usa.net> to be used in busybox
* Vladimir Oleynik <dzo@simtreas.ru> to be used in busybox
*
*
* Original copyright notice is retained at the end of this file.
@ -4995,7 +4995,7 @@ err1:
if (--in.nleft < 0) {
if (in.fd < 0)
break;
while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR);
i = safe_read(in.fd, buf, sizeof buf);
TRACE(("expbackq: read returns %d\n", i));
if (i <= 0)
break;
@ -6091,10 +6091,8 @@ init(void) {
* interactive shell and control is returned to the main command loop.
*/
#ifdef ASH_ALIAS
/* 1 == check for aliases, 2 == also check for assignments */
static int checkalias;
#endif
static int checkalias; /* also used in no alias mode for check assignments */
static void
reset(void) {
@ -6117,9 +6115,7 @@ reset(void) {
{
tokpushback = 0;
checkkwd = 0;
#ifdef ASH_ALIAS
checkalias = 0;
#endif
}
/* from redir.c: */
@ -6137,7 +6133,6 @@ reset(void) {
*/
#ifdef BB_FEATURE_COMMAND_EDITING
unsigned int shell_context;
static const char * cmdedit_prompt;
static inline void putprompt(const char *s) {
cmdedit_prompt = s;
@ -6206,23 +6201,18 @@ preadfd(void)
retry:
#ifdef BB_FEATURE_COMMAND_EDITING
{
if (parsefile->fd)
nr = read(parsefile->fd, buf, BUFSIZ - 1);
if (!iflag)
nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
else {
do {
cmdedit_read_input((char*)cmdedit_prompt, buf);
nr = strlen(buf);
} while (nr <=0 || shell_context);
cmdedit_terminate();
}
}
#else
nr = read(parsefile->fd, buf, BUFSIZ - 1);
nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
#endif
if (nr < 0) {
if (errno == EINTR)
goto retry;
if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
int flags = fcntl(0, F_GETFL, 0);
if (flags >= 0 && flags & O_NONBLOCK) {
@ -9872,9 +9862,7 @@ simplecmd() {
redir = NULL;
rpp = &redir;
#ifdef ASH_ALIAS
checkalias = 2;
#endif
for (;;) {
switch (readtoken()) {
case TWORD:
@ -10036,9 +10024,10 @@ peektoken() {
static int
readtoken() {
int t;
#ifdef ASH_ALIAS
int savecheckkwd = checkkwd;
int savecheckalias = checkalias;
int savecheckkwd = checkkwd;
struct alias *ap;
#endif
@ -10083,13 +10072,14 @@ top:
}
}
#ifdef ASH_ALIAS
if (t != TWORD) {
if (t != TREDIR) {
checkalias = 0;
}
} else if (checkalias == 2 && isassignment(wordtext)) {
lasttoken = t = TASSIGN;
#ifdef ASH_ALIAS
} else if (checkalias) {
if (!quoteflag && (ap = lookupalias(wordtext, 1)) != NULL) {
if (*ap->val) {
@ -10099,8 +10089,8 @@ top:
goto top;
}
checkalias = 0;
}
#endif
}
out:
#ifdef DEBUG
if (!alreadyseen)
@ -12927,7 +12917,7 @@ findvar(struct var **vpp, const char *name)
/*
* Copyright (c) 1999 Herbert Xu <herbert@debian.org>
* This file contains code for the times builtin.
* $Id: ash.c,v 1.9 2001/07/10 16:57:09 andersen Exp $
* $Id: ash.c,v 1.10 2001/07/12 20:26:31 andersen Exp $
*/
static int timescmd (int argc, char **argv)
{

View File

@ -3,7 +3,7 @@
* Termios command line History and Editting.
*
* Copyright (c) 1986-2001 may safely be consumed by a BSD or GPL license.
* Written by: Vladimir Oleynik <vodz@usa.net>
* Written by: Vladimir Oleynik <dzo@simtreas.ru>
*
* Used ideas:
* Adam Rogoyski <rogoyski@cs.utexas.edu>
@ -123,9 +123,8 @@ volatile int handlers_sets = 0; /* Set next bites: */
enum {
SET_ATEXIT = 1, /* when atexit() has been called
and get euid,uid,gid to fast compare */
SET_TERM_HANDLERS = 2, /* set many terminates signal handlers */
SET_WCHG_HANDLERS = 4, /* winchg signal handler */
SET_RESET_TERM = 8, /* if the terminal needs to be reset upon exit */
SET_WCHG_HANDLERS = 2, /* winchg signal handler */
SET_RESET_TERM = 4, /* if the terminal needs to be reset upon exit */
};
@ -142,10 +141,6 @@ static
#endif
char *cmdedit_prompt; /* --- "" - - "" - -"- --""-- --""--- */
/* Link into lash to reset context to 0 on ^C and such */
extern unsigned int shell_context;
#ifdef BB_FEATURE_GETUSERNAME_AND_HOMEDIR
static char *user_buf = "";
static char *home_pwd_buf = "";
@ -319,6 +314,7 @@ static void put_prompt(void)
out1str(cmdedit_prompt);
cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */
cursor = 0;
cmdedit_y = 0; /* new quasireal y */
}
#ifndef BB_FEATURE_SH_FANCY_PROMPT
@ -456,7 +452,6 @@ static void redraw(int y, int back_cursor)
{
if (y > 0) /* up to start y */
printf("\033[%dA", y);
cmdedit_y = 0; /* new quasireal y */
putchar('\r');
put_prompt();
input_end(); /* rewrite */
@ -497,14 +492,6 @@ static void input_forward(void)
}
static void clean_up_and_die(int sig)
{
goto_new_line();
if (sig != SIGINT)
exit(EXIT_SUCCESS); /* cmdedit_reset_term() called in atexit */
cmdedit_reset_term();
}
static void cmdedit_setwidth(int w, int redraw_flg)
{
cmdedit_termw = cmdedit_prmt_len + 2;
@ -525,7 +512,7 @@ static void cmdedit_setwidth(int w, int redraw_flg)
}
}
extern void cmdedit_init(void)
static void cmdedit_init(void)
{
cmdedit_prmt_len = 0;
if ((handlers_sets & SET_WCHG_HANDLERS) == 0) {
@ -557,14 +544,6 @@ extern void cmdedit_init(void)
handlers_sets |= SET_ATEXIT;
atexit(cmdedit_reset_term); /* be sure to do this only once */
}
if ((handlers_sets & SET_TERM_HANDLERS) == 0) {
signal(SIGKILL, clean_up_and_die);
signal(SIGINT, clean_up_and_die);
signal(SIGQUIT, clean_up_and_die);
signal(SIGTERM, clean_up_and_die);
handlers_sets |= SET_TERM_HANDLERS;
}
}
#ifdef BB_FEATURE_COMMAND_TAB_COMPLETION
@ -1220,7 +1199,7 @@ extern void cmdedit_read_input(char *prompt, char command[BUFSIZ])
fflush(stdout); /* buffered out to fast */
if (read(0, &c, 1) < 1)
if (safe_read(0, &c, 1) < 1)
/* if we can't read input then exit */
goto prepare_to_die;
@ -1241,22 +1220,21 @@ extern void cmdedit_read_input(char *prompt, char command[BUFSIZ])
break;
case 3:
/* Control-c -- stop gathering input */
/* Link into lash to reset context to 0 on ^C and such */
shell_context = 0;
/* Go to the next line */
goto_new_line();
command[0] = 0;
return;
len = 0;
lastWasTab = FALSE;
put_prompt();
break;
case 4:
/* Control-d -- Delete one character, or exit
* if the len=0 and no chars to delete */
if (len == 0) {
prepare_to_die:
printf("exit");
clean_up_and_die(0);
goto_new_line();
/* cmdedit_reset_term() called in atexit */
exit(EXIT_SUCCESS);
} else {
input_delete();
}
@ -1307,12 +1285,12 @@ prepare_to_die:
case ESC:{
/* escape sequence follows */
if (read(0, &c, 1) < 1)
return;
if (safe_read(0, &c, 1) < 1)
goto prepare_to_die;
/* different vt100 emulations */
if (c == '[' || c == 'O') {
if (read(0, &c, 1) < 1)
return;
if (safe_read(0, &c, 1) < 1)
goto prepare_to_die;
}
switch (c) {
#ifdef BB_FEATURE_COMMAND_TAB_COMPLETION
@ -1376,8 +1354,8 @@ prepare_to_die:
}
if (c >= '1' && c <= '9')
do
if (read(0, &c, 1) < 1)
return;
if (safe_read(0, &c, 1) < 1)
goto prepare_to_die;
while (c != '~');
break;
}
@ -1386,8 +1364,8 @@ prepare_to_die:
#ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT
/* Control-V -- Add non-printable symbol */
if (c == 22) {
if (read(0, &c, 1) < 1)
return;
if (safe_read(0, &c, 1) < 1)
goto prepare_to_die;
if (c == 0) {
beep();
break;
@ -1485,24 +1463,11 @@ prepare_to_die:
#if defined(BB_FEATURE_SH_FANCY_PROMPT)
free(cmdedit_prompt);
#endif
return;
}
/* Undo the effects of cmdedit_init(). */
extern void cmdedit_terminate(void)
{
cmdedit_reset_term();
if ((handlers_sets & SET_TERM_HANDLERS) != 0) {
signal(SIGKILL, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGWINCH, SIG_DFL);
handlers_sets &= ~SET_TERM_HANDLERS;
}
}
#endif /* BB_FEATURE_COMMAND_EDITING */
@ -1515,8 +1480,6 @@ const char *memory_exhausted = "Memory exhausted";
#include <locale.h>
#endif
unsigned int shell_context;
int main(int argc, char **argv)
{
char buff[BUFSIZ];
@ -1532,15 +1495,16 @@ int main(int argc, char **argv)
#ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT
setlocale(LC_ALL, "");
#endif
shell_context = 1;
do {
while(1) {
int l;
cmdedit_read_input(prompt, buff);
l = strlen(buff);
if(l==0)
break;
if(l > 0 && buff[l-1] == '\n')
buff[l-1] = 0;
printf("*** cmdedit_read_input() returned line =%s=\n", buff);
} while (shell_context);
}
printf("*** cmdedit_read_input() detect ^C\n");
return 0;
}

View File

@ -1,8 +1,6 @@
#ifndef CMDEDIT_H
#define CMDEDIT_H
void cmdedit_init(void);
void cmdedit_terminate(void);
void cmdedit_read_input(char* promptStr, char* command); /* read a line of input */
#endif /* CMDEDIT_H */

View File

@ -237,10 +237,6 @@ unsigned int global_argc;
unsigned int last_return_code;
extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */
/* Variables we export */
unsigned int shell_context; /* Used in cmdedit.c to reset the
* context when someone hits ^C */
/* "globals" within this file */
static char *ifs;
static char map[256];
@ -883,7 +879,6 @@ static void get_user_input(struct in_str *i)
** child processes (rob@sysgo.de)
*/
cmdedit_read_input(prompt_str, the_command);
cmdedit_terminate();
#else
fputs(prompt_str, stdout);
fflush(stdout);
@ -1411,6 +1406,7 @@ static int run_pipe_real(struct pipe *pi)
/* Set the handling for job control signals back to the default. */
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGTSTP, SIG_DFL);
signal(SIGTTIN, SIG_DFL);
signal(SIGTTOU, SIG_DFL);
@ -2551,6 +2547,7 @@ static void setup_job_control()
/* Ignore interactive and job-control signals. */
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);

View File

@ -170,9 +170,7 @@ static struct built_in_command bltins_forking[] = {
};
/* Variables we export */
unsigned int shell_context; /* Used in cmdedit.c to reset the
context when someone hits ^C */
static int shell_context; /* Type prompt trigger (PS1 or PS2) */
/* Globals that are static to this file */
@ -716,7 +714,6 @@ static int get_command(FILE * source, char *command)
** child processes (rob@sysgo.de)
*/
cmdedit_read_input(prompt_str, command);
cmdedit_terminate();
return 0;
#else
fputs(prompt_str, stdout);
@ -1557,7 +1554,6 @@ int shell_main(int argc_l, char **argv_l)
/* These variables need re-initializing when recursing */
last_jobid = 0;
shell_context = 0;
local_pending_command = NULL;
close_me_head = NULL;
job_list.head = NULL;

View File

@ -682,8 +682,7 @@ static void * brkaddr;
#ifdef BB_FEATURE_COMMAND_EDITING
char * current_prompt;
unsigned int shell_context;
static char * current_prompt;
#endif
@ -4449,9 +4448,7 @@ register struct ioarg *ap;
if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
if (i)
lseek(ap->afile, ap->afpos, 0);
do {
i = read(ap->afile, bp->buf, sizeof(bp->buf));
} while (i < 0 && errno == EINTR);
i = safe_read(ap->afile, bp->buf, sizeof(bp->buf));
if (i <= 0) {
closef(ap->afile);
return 0;
@ -4470,7 +4467,6 @@ register struct ioarg *ap;
while (size == 0 || position >= size) {
cmdedit_read_input(current_prompt, mycommand);
cmdedit_terminate();
size = strlen(mycommand);
position = 0;
}
@ -4480,9 +4476,7 @@ register struct ioarg *ap;
} else
#endif
{
do {
i = read(ap->afile, &c, sizeof(c));
} while (i < 0 && errno == EINTR);
i = safe_read(ap->afile, &c, sizeof(c));
return(i == sizeof(c)? c&0177: (closef(ap->afile), 0));
}
}

2
stty.c
View File

@ -24,7 +24,7 @@
David MacKenzie <djm@gnu.ai.mit.edu>
Special for busybox ported by Vladimir Oleynik <vodz@usa.net> 2001
Special for busybox ported by Vladimir Oleynik <dzo@simtreas.ru> 2001
*/

View File

@ -5,6 +5,7 @@
* This code is derived from software contributed to Berkeley by
* Van Jacobson.
*
* Special for busybox ported by Vladimir Oleynik <dzo@simtreas.ru> 2001
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -61,6 +62,10 @@
* Tue Dec 20 03:50:13 PST 1988
*/
#undef BB_FEATURE_TRACEROUTE_VERBOSE
//#define BB_FEATURE_TRACEROUTE_VERBOSE
#undef BB_FEATURE_TRACEROUTE_SO_DEBUG /* not in documentation man */
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
@ -100,13 +105,6 @@ struct opacket {
#include "busybox.h"
static int wait_for_reply (int, struct sockaddr_in *, int);
static void send_probe (int, int);
static double deltaT (struct timeval *, struct timeval *);
static int packet_ok (u_char *, int, struct sockaddr_in *, int);
static void print (u_char *, int, struct sockaddr_in *);
static char *inetname (struct in_addr);
static u_char packet[512]; /* last inbound (icmp) packet */
static struct opacket *outpacket; /* last output (udp) packet */
@ -122,10 +120,229 @@ static int max_ttl = 30;
static u_short ident;
static u_short port = 32768+666; /* start udp dest port # for probe packets */
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
static int verbose;
#endif
static int waittime = 5; /* time to wait for response (in seconds) */
static int nflag; /* print addresses numerically */
/*
* Construct an Internet address representation.
* If the nflag has been supplied, give
* numeric value, otherwise try for symbolic name.
*/
static inline char *
inetname(struct in_addr in)
{
char *cp;
static char line[50];
struct hostent *hp;
static char domain[MAXHOSTNAMELEN + 1];
static int first = 1;
if (first && !nflag) {
first = 0;
if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
(cp = index(domain, '.')))
(void) strcpy(domain, cp + 1);
else
domain[0] = 0;
}
cp = 0;
if (!nflag && in.s_addr != INADDR_ANY) {
hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);
if (hp) {
if ((cp = index(hp->h_name, '.')) &&
!strcmp(cp + 1, domain))
*cp = 0;
cp = (char *)hp->h_name;
}
}
if (cp)
(void) strcpy(line, cp);
else {
in.s_addr = ntohl(in.s_addr);
strcpy(line, inet_ntoa(in));
}
return (line);
}
static inline void
print(u_char *buf, int cc, struct sockaddr_in *from)
{
struct ip *ip;
int hlen;
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
cc -= hlen;
if (nflag)
printf(" %s", inet_ntoa(from->sin_addr));
else
printf(" %s (%s)", inetname(from->sin_addr),
inet_ntoa(from->sin_addr));
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
if (verbose)
printf (" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
#endif
}
static inline double
deltaT(struct timeval *t1p, struct timeval *t2p)
{
double dt;
dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
(double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
return (dt);
}
static inline int
wait_for_reply(int sock, struct sockaddr_in *from, int reset_timer)
{
fd_set fds;
static struct timeval wait;
int cc = 0;
int fromlen = sizeof (*from);
FD_ZERO(&fds);
FD_SET(sock, &fds);
if (reset_timer) {
/*
* traceroute could hang if someone else has a ping
* running and our ICMP reply gets dropped but we don't
* realize it because we keep waking up to handle those
* other ICMP packets that keep coming in. To fix this,
* "reset_timer" will only be true if the last packet that
* came in was for us or if this is the first time we're
* waiting for a reply since sending out a probe. Note
* that this takes advantage of the select() feature on
* Linux where the remaining timeout is written to the
* struct timeval area.
*/
wait.tv_sec = waittime;
wait.tv_usec = 0;
}
if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0)
cc=recvfrom(s, (char *)packet, sizeof(packet), 0,
(struct sockaddr *)from, &fromlen);
return(cc);
}
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
/*
* Convert an ICMP "type" field to a printable string.
*/
static inline const char *
pr_type(t)
u_char t;
{
static const char * const ttab[] = {
"Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
"Source Quench", "Redirect", "ICMP 6", "ICMP 7",
"Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
"Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
"Info Reply"
};
if(t > 16)
return("OUT-OF-RANGE");
return(ttab[t]);
}
#endif
static inline int
packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq)
{
struct icmp *icp;
u_char type, code;
int hlen;
struct ip *ip;
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
if (cc < hlen + ICMP_MINLEN) {
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
if (verbose)
printf("packet too short (%d bytes) from %s\n", cc,
inet_ntoa(from->sin_addr));
#endif
return (0);
}
cc -= hlen;
icp = (struct icmp *)(buf + hlen);
type = icp->icmp_type; code = icp->icmp_code;
if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
type == ICMP_UNREACH) {
struct ip *hip;
struct udphdr *up;
hip = &icp->icmp_ip;
hlen = hip->ip_hl << 2;
up = (struct udphdr *)((u_char *)hip + hlen);
if (hlen + 12 <= cc && hip->ip_p == IPPROTO_UDP &&
up->source == htons(ident) &&
up->dest == htons(port+seq))
return (type == ICMP_TIMXCEED? -1 : code+1);
}
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
if (verbose) {
int i;
u_long *lp = (u_long *)&icp->icmp_ip;
printf("\n%d bytes from %s to %s: icmp type %d (%s) code %d\n",
cc, inet_ntoa(from->sin_addr), inet_ntoa(ip->ip_dst),
type, pr_type(type), icp->icmp_code);
for (i = 4; i < cc ; i += sizeof(long))
printf("%2d: x%8.8lx\n", i, *lp++);
}
#endif
return(0);
}
static void /* not inline */
send_probe(int seq, int ttl)
{
struct opacket *op = outpacket;
struct ip *ip = &op->ip;
struct udphdr *up = &op->udp;
int i;
struct timezone tz;
ip->ip_off = 0;
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_p = IPPROTO_UDP;
ip->ip_len = datalen;
ip->ip_ttl = ttl;
ip->ip_v = IPVERSION;
ip->ip_id = htons(ident+seq);
up->source = htons(ident);
up->dest = htons(port+seq);
up->len = htons((u_short)(datalen - sizeof(struct ip)));
up->check = 0;
op->seq = seq;
op->ttl = ttl;
(void) gettimeofday(&op->tv, &tz);
i = sendto(sndsock, (char *)outpacket, datalen, 0, &whereto,
sizeof(struct sockaddr));
if (i < 0 || i != datalen) {
if (i<0)
perror("sendto");
printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
datalen, i);
(void) fflush(stdout);
}
}
int
#ifndef BB_TRACEROUTE
main(argc, argv)
@ -138,7 +355,6 @@ traceroute_main(argc, argv)
extern char *optarg;
extern int optind;
struct hostent *hp;
struct protoent *pe;
struct sockaddr_in from, *to;
int ch, i, on, probe, seq, tos, ttl;
@ -152,7 +368,9 @@ traceroute_main(argc, argv)
while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF)
switch(ch) {
case 'd':
#ifdef BB_FEATURE_TRACEROUTE_SO_DEBUG
options |= SO_DEBUG;
#endif
break;
case 'm':
max_ttl = atoi(optarg);
@ -188,7 +406,9 @@ traceroute_main(argc, argv)
error_msg_and_die("tos must be 0 to 255.");
break;
case 'v':
#ifdef BB_FEATURE_TRACEROUTE_VERBOSE
verbose++;
#endif
break;
case 'w':
waittime = atoi(optarg);
@ -206,21 +426,11 @@ traceroute_main(argc, argv)
setlinebuf (stdout);
(void) bzero((char *)&whereto, sizeof(struct sockaddr));
to->sin_family = AF_INET;
to->sin_addr.s_addr = inet_addr(*argv);
if (to->sin_addr.s_addr != -1)
hostname = *argv;
else {
hp = gethostbyname(*argv);
if (hp) {
memset(&whereto, 0, sizeof(struct sockaddr));
hp = xgethostbyname(*argv);
to->sin_family = hp->h_addrtype;
bcopy(hp->h_addr, (caddr_t)&to->sin_addr, hp->h_length);
memcpy(&to->sin_addr, hp->h_addr, hp->h_length);
hostname = (char *)hp->h_name;
} else {
error_msg_and_die("unknown host %s", *argv);
}
}
if (*++argv)
datalen = atoi(*argv);
if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket))
@ -228,7 +438,7 @@ traceroute_main(argc, argv)
MAXPACKET - sizeof(struct opacket));
datalen += sizeof(struct opacket);
outpacket = (struct opacket *)xmalloc((unsigned)datalen);
(void) bzero((char *)outpacket, datalen);
memset(outpacket, 0, datalen);
outpacket->ip.ip_dst = to->sin_addr;
outpacket->ip.ip_tos = tos;
outpacket->ip.ip_v = IPVERSION;
@ -236,19 +446,19 @@ traceroute_main(argc, argv)
ident = (getpid() & 0xffff) | 0x8000;
if ((pe = getprotobyname("icmp")) == NULL)
error_msg_and_die("icmp: unknown protocol");
if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0)
perror_msg_and_die("icmp socket");
if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
perror_msg_and_die(can_not_create_raw_socket);
s = create_icmp_socket();
#ifdef BB_FEATURE_TRACEROUTE_SO_DEBUG
if (options & SO_DEBUG)
(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
(char *)&on, sizeof(on));
#endif
if (options & SO_DONTROUTE)
(void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE,
(char *)&on, sizeof(on));
if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
perror_msg_and_die("raw socket");
#ifdef SO_SNDBUF
if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
sizeof(datalen)) < 0)
@ -259,15 +469,17 @@ traceroute_main(argc, argv)
sizeof(on)) < 0)
perror_msg_and_die("IP_HDRINCL");
#endif IP_HDRINCL
#ifdef BB_FEATURE_TRACEROUTE_SO_DEBUG
if (options & SO_DEBUG)
(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
(char *)&on, sizeof(on));
#endif
if (options & SO_DONTROUTE)
(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
(char *)&on, sizeof(on));
if (source) {
(void) bzero((char *)&from, sizeof(struct sockaddr));
memset(&from, 0, sizeof(struct sockaddr));
from.sin_family = AF_INET;
from.sin_addr.s_addr = inet_addr(source);
if (from.sin_addr.s_addr == -1)
@ -284,7 +496,6 @@ traceroute_main(argc, argv)
if (source)
fprintf(stderr, " from %s", source);
fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen);
(void) fflush(stderr);
for (ttl = 1; ttl <= max_ttl; ++ttl) {
u_long lastaddr = 0;
@ -312,11 +523,9 @@ traceroute_main(argc, argv)
printf(" %g ms", deltaT(&t1, &t2));
switch(i - 1) {
case ICMP_UNREACH_PORT:
#ifndef ARCHAIC
ip = (struct ip *)packet;
if (ip->ip_ttl <= 1)
printf(" !");
#endif ARCHAIC
++got_there;
break;
case ICMP_UNREACH_NET:
@ -355,239 +564,3 @@ traceroute_main(argc, argv)
return 0;
}
static int
wait_for_reply(sock, from, reset_timer)
int sock;
struct sockaddr_in *from;
int reset_timer;
{
fd_set fds;
static struct timeval wait;
int cc = 0;
int fromlen = sizeof (*from);
FD_ZERO(&fds);
FD_SET(sock, &fds);
if (reset_timer) {
/*
* traceroute could hang if someone else has a ping
* running and our ICMP reply gets dropped but we don't
* realize it because we keep waking up to handle those
* other ICMP packets that keep coming in. To fix this,
* "reset_timer" will only be true if the last packet that
* came in was for us or if this is the first time we're
* waiting for a reply since sending out a probe. Note
* that this takes advantage of the select() feature on
* Linux where the remaining timeout is written to the
* struct timeval area.
*/
wait.tv_sec = waittime;
wait.tv_usec = 0;
}
if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0)
cc=recvfrom(s, (char *)packet, sizeof(packet), 0,
(struct sockaddr *)from, &fromlen);
return(cc);
}
static void
send_probe(seq, ttl)
int seq, ttl;
{
struct opacket *op = outpacket;
struct ip *ip = &op->ip;
struct udphdr *up = &op->udp;
int i;
struct timezone tz;
ip->ip_off = 0;
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_p = IPPROTO_UDP;
ip->ip_len = datalen;
ip->ip_ttl = ttl;
ip->ip_v = IPVERSION;
ip->ip_id = htons(ident+seq);
up->source = htons(ident);
up->dest = htons(port+seq);
up->len = htons((u_short)(datalen - sizeof(struct ip)));
up->check = 0;
op->seq = seq;
op->ttl = ttl;
(void) gettimeofday(&op->tv, &tz);
i = sendto(sndsock, (char *)outpacket, datalen, 0, &whereto,
sizeof(struct sockaddr));
if (i < 0 || i != datalen) {
if (i<0)
perror("sendto");
printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
datalen, i);
(void) fflush(stdout);
}
}
static double
deltaT(t1p, t2p)
struct timeval *t1p, *t2p;
{
register double dt;
dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
(double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
return (dt);
}
/*
* Convert an ICMP "type" field to a printable string.
*/
static const char *
pr_type(t)
u_char t;
{
static const char * const ttab[] = {
"Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
"Source Quench", "Redirect", "ICMP 6", "ICMP 7",
"Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
"Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
"Info Reply"
};
if(t > 16)
return("OUT-OF-RANGE");
return(ttab[t]);
}
static int
packet_ok(buf, cc, from, seq)
u_char *buf;
int cc;
struct sockaddr_in *from;
int seq;
{
register struct icmp *icp;
u_char type, code;
int hlen;
#ifndef ARCHAIC
struct ip *ip;
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
if (cc < hlen + ICMP_MINLEN) {
if (verbose)
printf("packet too short (%d bytes) from %s\n", cc,
inet_ntoa(from->sin_addr));
return (0);
}
cc -= hlen;
icp = (struct icmp *)(buf + hlen);
#else
icp = (struct icmp *)buf;
#endif ARCHAIC
type = icp->icmp_type; code = icp->icmp_code;
if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
type == ICMP_UNREACH) {
struct ip *hip;
struct udphdr *up;
hip = &icp->icmp_ip;
hlen = hip->ip_hl << 2;
up = (struct udphdr *)((u_char *)hip + hlen);
if (hlen + 12 <= cc && hip->ip_p == IPPROTO_UDP &&
up->source == htons(ident) &&
up->dest == htons(port+seq))
return (type == ICMP_TIMXCEED? -1 : code+1);
}
#ifndef ARCHAIC
if (verbose) {
int i;
u_long *lp = (u_long *)&icp->icmp_ip;
printf("\n%d bytes from %s to %s", cc,
inet_ntoa(from->sin_addr), inet_ntoa(ip->ip_dst));
printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
icp->icmp_code);
for (i = 4; i < cc ; i += sizeof(long))
printf("%2d: x%8.8lx\n", i, *lp++);
}
#endif ARCHAIC
return(0);
}
static void
print(buf, cc, from)
u_char *buf;
int cc;
struct sockaddr_in *from;
{
struct ip *ip;
int hlen;
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
cc -= hlen;
if (nflag)
printf(" %s", inet_ntoa(from->sin_addr));
else
printf(" %s (%s)", inetname(from->sin_addr),
inet_ntoa(from->sin_addr));
if (verbose)
printf (" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
}
/*
* Construct an Internet address representation.
* If the nflag has been supplied, give
* numeric value, otherwise try for symbolic name.
*/
static char *
inetname(in)
struct in_addr in;
{
register char *cp;
static char line[50];
struct hostent *hp;
static char domain[MAXHOSTNAMELEN + 1];
static int first = 1;
if (first && !nflag) {
first = 0;
if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
(cp = index(domain, '.')))
(void) strcpy(domain, cp + 1);
else
domain[0] = 0;
}
cp = 0;
if (!nflag && in.s_addr != INADDR_ANY) {
hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);
if (hp) {
if ((cp = index(hp->h_name, '.')) &&
!strcmp(cp + 1, domain))
*cp = 0;
cp = (char *)hp->h_name;
}
}
if (cp)
(void) strcpy(line, cp);
else {
in.s_addr = ntohl(in.s_addr);
#define C(x) ((x) & 0xff)
sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
}
return (line);
}