Fix a tar bug: tar removed leading '/'s for symlink targets.

Fix a syslogd bug: Only the first sizeof(buffer) was read from the
/dev/log socket, causing (for most cases) only every other log item to be logged.
 -Erik
This commit is contained in:
Erik Andersen 2000-04-14 21:45:29 +00:00
parent d5ba77d03e
commit 95c1c1e05f
6 changed files with 48 additions and 141 deletions

8
TODO
View File

@ -23,7 +23,9 @@ around to it some time. If you have any good ideas, please let me know.
* stty * stty
* cut * cut
* expr * expr
* wget (or whatever I call it)
* tftp
* ftp
----------------------- -----------------------
@ -31,24 +33,20 @@ around to it some time. If you have any good ideas, please let me know.
Compile with debugging on, run 'nm --size-sort ./busybox' Compile with debugging on, run 'nm --size-sort ./busybox'
and then start with the biggest things and make them smaller... and then start with the biggest things and make them smaller...
----------------------- -----------------------
busybox.defs.h is too big and hard to follow. busybox.defs.h is too big and hard to follow.
Perhaps I need to add a better build system (like the Linux kernel?) Perhaps I need to add a better build system (like the Linux kernel?)
----------------------- -----------------------
Feature request: Feature request:
/bin/busybox --install -s which makes all links to commands that it /bin/busybox --install -s which makes all links to commands that it
can support (an optionnal -s should be used for symbolic links instead can support (an optionnal -s should be used for symbolic links instead
of hard links). of hard links).
----------------------- -----------------------

View File

@ -493,18 +493,6 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
chksum = getOctal(rawHeader->chksum, sizeof(rawHeader->chksum)); chksum = getOctal(rawHeader->chksum, sizeof(rawHeader->chksum));
header->type = rawHeader->typeflag; header->type = rawHeader->typeflag;
header->linkname = rawHeader->linkname; header->linkname = rawHeader->linkname;
/* Check for and relativify any absolute paths */
if ( *(header->linkname) == '/' ) {
static int alreadyWarned=FALSE;
while (*(header->linkname) == '/')
++*(header->linkname);
if (alreadyWarned == FALSE) {
errorMsg("tar: Removing leading '/' from link names\n");
alreadyWarned = TRUE;
}
}
header->devmajor = getOctal(rawHeader->devmajor, sizeof(rawHeader->devmajor)); header->devmajor = getOctal(rawHeader->devmajor, sizeof(rawHeader->devmajor));
header->devminor = getOctal(rawHeader->devminor, sizeof(rawHeader->devminor)); header->devminor = getOctal(rawHeader->devminor, sizeof(rawHeader->devminor));
@ -826,7 +814,7 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st
if (! *header.uname) if (! *header.uname)
strcpy(header.uname, "root"); strcpy(header.uname, "root");
// FIXME (or most likely not): I break Hard Links /* WARNING/NOTICE: I break Hard Links */
if (S_ISLNK(statbuf->st_mode)) { if (S_ISLNK(statbuf->st_mode)) {
char buffer[BUFSIZ]; char buffer[BUFSIZ];
header.typeflag = SYMTYPE; header.typeflag = SYMTYPE;
@ -834,17 +822,7 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st
errorMsg("Error reading symlink '%s': %s\n", header.name, strerror(errno)); errorMsg("Error reading symlink '%s': %s\n", header.name, strerror(errno));
return ( FALSE); return ( FALSE);
} }
if (*buffer=='/') { strncpy(header.linkname, buffer, sizeof(header.linkname));
static int alreadyWarned=FALSE;
if (alreadyWarned==FALSE) {
errorMsg("tar: Removing leading '/' from link names\n");
alreadyWarned=TRUE;
}
strncpy(header.linkname, buffer+1, sizeof(header.linkname));
}
else {
strncpy(header.linkname, buffer, sizeof(header.linkname));
}
} else if (S_ISDIR(statbuf->st_mode)) { } else if (S_ISDIR(statbuf->st_mode)) {
header.typeflag = DIRTYPE; header.typeflag = DIRTYPE;
strncat(header.name, "/", sizeof(header.name)); strncat(header.name, "/", sizeof(header.name));

View File

@ -12,6 +12,7 @@ doc:
@rm pod2html-* @rm pod2html-*
pod2man --center=BusyBox --release="version $(VERSION)" busybox.pod > ../BusyBox.1 pod2man --center=BusyBox --release="version $(VERSION)" busybox.pod > ../BusyBox.1
pod2text busybox.pod > ../BusyBox.txt pod2text busybox.pod > ../BusyBox.txt
@rm -f pod2html*
clean:: clean::
@rm -f ../BusyBox.html ../BusyBox.1 ../BusyBox.txt pod2html* @rm -f ../BusyBox.html ../BusyBox.1 ../BusyBox.txt pod2html*

View File

@ -81,21 +81,17 @@ static void message(char *fmt, ...)
int fd; int fd;
va_list arguments; va_list arguments;
if ( if ( (fd = device_open(logFilePath,
(fd = O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
device_open(logFilePath, O_NONBLOCK)) >= 0) {
O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
O_NONBLOCK)) >= 0) {
va_start(arguments, fmt); va_start(arguments, fmt);
vdprintf(fd, fmt, arguments); vdprintf(fd, fmt, arguments);
va_end(arguments); va_end(arguments);
close(fd); close(fd);
} else { } else {
/* Always send console messages to /dev/console so people will see them. */ /* Always send console messages to /dev/console so people will see them. */
if ( if ( (fd = device_open(_PATH_CONSOLE,
(fd = O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) {
device_open(_PATH_CONSOLE,
O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) {
va_start(arguments, fmt); va_start(arguments, fmt);
vdprintf(fd, fmt, arguments); vdprintf(fd, fmt, arguments);
va_end(arguments); va_end(arguments);
@ -177,14 +173,10 @@ static void doSyslogd (void)
signal (SIGALRM, domark); signal (SIGALRM, domark);
alarm (MarkInterval); alarm (MarkInterval);
/* create the syslog file so realpath() can work /* create the syslog file so realpath() can work */
* (the ugle close(open()) stuff is just a cheap close(open(_PATH_LOG, O_RDWR | O_CREAT, 0644));
* touch command that avoids using system (system
* is always a bad thing to use) */
close(open("touch " _PATH_LOG, O_RDWR | O_CREAT, 0644));
if (realpath(_PATH_LOG, lfile) == NULL) { if (realpath(_PATH_LOG, lfile) == NULL) {
perror("Could not resolv path to " _PATH_LOG); fatalError("Could not resolv path to " _PATH_LOG);
exit (FALSE);
} }
unlink (lfile); unlink (lfile);
@ -194,20 +186,17 @@ static void doSyslogd (void)
sunx.sun_family = AF_UNIX; sunx.sun_family = AF_UNIX;
strncpy (sunx.sun_path, lfile, sizeof(sunx.sun_path)); strncpy (sunx.sun_path, lfile, sizeof(sunx.sun_path));
if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror ("Couldn't obtain descriptor for socket " _PATH_LOG); fatalError ("Couldn't obtain descriptor for socket " _PATH_LOG);
exit (FALSE);
} }
addrLength = sizeof (sunx.sun_family) + strlen (sunx.sun_path); addrLength = sizeof (sunx.sun_family) + strlen (sunx.sun_path);
if ((bind (sock_fd, (struct sockaddr *) &sunx, addrLength)) || if ((bind (sock_fd, (struct sockaddr *) &sunx, addrLength)) ||
(listen (sock_fd, 5))) { (listen (sock_fd, 5))) {
perror ("Could not connect to socket " _PATH_LOG); fatalError ("Could not connect to socket " _PATH_LOG);
exit (FALSE);
} }
if (chmod (lfile, 0666) < 0) { if (chmod (lfile, 0666) < 0) {
perror ("Could not set permission on " _PATH_LOG); fatalError ("Could not set permission on " _PATH_LOG);
exit (FALSE);
} }
FD_ZERO (&readfds); FD_ZERO (&readfds);
@ -221,19 +210,17 @@ static void doSyslogd (void)
if ((n_ready = select (FD_SETSIZE, &readfds, NULL, NULL, NULL)) < 0) { if ((n_ready = select (FD_SETSIZE, &readfds, NULL, NULL, NULL)) < 0) {
if (errno == EINTR) continue; /* alarm may have happened. */ if (errno == EINTR) continue; /* alarm may have happened. */
perror ("select"); fatalError( "select error: %s\n", strerror(errno));
exit (FALSE);
} }
/* Skip stdin, stdout, stderr */ /* Skip stdin, stdout, stderr */
for (fd = 3; fd <= FD_SETSIZE; fd++) { for (fd = 3; fd < FD_SETSIZE; fd++) {
if (FD_ISSET (fd, &readfds)) { if (FD_ISSET (fd, &readfds)) {
if (fd == sock_fd) { if (fd == sock_fd) {
int conn; int conn;
if ((conn = accept(sock_fd, (struct sockaddr *) &sunx, if ((conn = accept(sock_fd, (struct sockaddr *) &sunx,
&addrLength)) < 0) { &addrLength)) < 0) {
perror ("accept"); fatalError( "accept error: %s\n", strerror(errno));
exit (FALSE); /* #### ??? */
} }
FD_SET (conn, &readfds); FD_SET (conn, &readfds);
} }
@ -242,17 +229,11 @@ static void doSyslogd (void)
char buf[BUFSIZE]; char buf[BUFSIZE];
char *q, *p; char *q, *p;
int n_read; int n_read;
char line[BUFSIZE];
unsigned char c;
n_read = read (fd, buf, BUFSIZE); /* Keep reading stuff till there is nothing else to read */
while( (n_read = read (fd, buf, BUFSIZE)) > 0 && errno != EOF) {
if (n_read < 0) {
// FIXME .. fd isn't set
perror ("read error");
goto close_fd;
}
else if (n_read > 0) {
char line[BUFSIZE];
unsigned char c;
int pri = (LOG_USER | LOG_NOTICE); int pri = (LOG_USER | LOG_NOTICE);
memset (line, 0, sizeof(line)); memset (line, 0, sizeof(line));
@ -281,14 +262,9 @@ static void doSyslogd (void)
/* Now log it */ /* Now log it */
logMessage(pri, line); logMessage(pri, line);
close_fd:
close (fd);
FD_CLR (fd, &readfds);
}
else { /* EOF */
goto close_fd;
} }
close (fd);
FD_CLR (fd, &readfds);
} }
} }
} }

View File

@ -81,21 +81,17 @@ static void message(char *fmt, ...)
int fd; int fd;
va_list arguments; va_list arguments;
if ( if ( (fd = device_open(logFilePath,
(fd = O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
device_open(logFilePath, O_NONBLOCK)) >= 0) {
O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
O_NONBLOCK)) >= 0) {
va_start(arguments, fmt); va_start(arguments, fmt);
vdprintf(fd, fmt, arguments); vdprintf(fd, fmt, arguments);
va_end(arguments); va_end(arguments);
close(fd); close(fd);
} else { } else {
/* Always send console messages to /dev/console so people will see them. */ /* Always send console messages to /dev/console so people will see them. */
if ( if ( (fd = device_open(_PATH_CONSOLE,
(fd = O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) {
device_open(_PATH_CONSOLE,
O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) {
va_start(arguments, fmt); va_start(arguments, fmt);
vdprintf(fd, fmt, arguments); vdprintf(fd, fmt, arguments);
va_end(arguments); va_end(arguments);
@ -177,14 +173,10 @@ static void doSyslogd (void)
signal (SIGALRM, domark); signal (SIGALRM, domark);
alarm (MarkInterval); alarm (MarkInterval);
/* create the syslog file so realpath() can work /* create the syslog file so realpath() can work */
* (the ugle close(open()) stuff is just a cheap close(open(_PATH_LOG, O_RDWR | O_CREAT, 0644));
* touch command that avoids using system (system
* is always a bad thing to use) */
close(open("touch " _PATH_LOG, O_RDWR | O_CREAT, 0644));
if (realpath(_PATH_LOG, lfile) == NULL) { if (realpath(_PATH_LOG, lfile) == NULL) {
perror("Could not resolv path to " _PATH_LOG); fatalError("Could not resolv path to " _PATH_LOG);
exit (FALSE);
} }
unlink (lfile); unlink (lfile);
@ -194,20 +186,17 @@ static void doSyslogd (void)
sunx.sun_family = AF_UNIX; sunx.sun_family = AF_UNIX;
strncpy (sunx.sun_path, lfile, sizeof(sunx.sun_path)); strncpy (sunx.sun_path, lfile, sizeof(sunx.sun_path));
if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror ("Couldn't obtain descriptor for socket " _PATH_LOG); fatalError ("Couldn't obtain descriptor for socket " _PATH_LOG);
exit (FALSE);
} }
addrLength = sizeof (sunx.sun_family) + strlen (sunx.sun_path); addrLength = sizeof (sunx.sun_family) + strlen (sunx.sun_path);
if ((bind (sock_fd, (struct sockaddr *) &sunx, addrLength)) || if ((bind (sock_fd, (struct sockaddr *) &sunx, addrLength)) ||
(listen (sock_fd, 5))) { (listen (sock_fd, 5))) {
perror ("Could not connect to socket " _PATH_LOG); fatalError ("Could not connect to socket " _PATH_LOG);
exit (FALSE);
} }
if (chmod (lfile, 0666) < 0) { if (chmod (lfile, 0666) < 0) {
perror ("Could not set permission on " _PATH_LOG); fatalError ("Could not set permission on " _PATH_LOG);
exit (FALSE);
} }
FD_ZERO (&readfds); FD_ZERO (&readfds);
@ -221,19 +210,17 @@ static void doSyslogd (void)
if ((n_ready = select (FD_SETSIZE, &readfds, NULL, NULL, NULL)) < 0) { if ((n_ready = select (FD_SETSIZE, &readfds, NULL, NULL, NULL)) < 0) {
if (errno == EINTR) continue; /* alarm may have happened. */ if (errno == EINTR) continue; /* alarm may have happened. */
perror ("select"); fatalError( "select error: %s\n", strerror(errno));
exit (FALSE);
} }
/* Skip stdin, stdout, stderr */ /* Skip stdin, stdout, stderr */
for (fd = 3; fd <= FD_SETSIZE; fd++) { for (fd = 3; fd < FD_SETSIZE; fd++) {
if (FD_ISSET (fd, &readfds)) { if (FD_ISSET (fd, &readfds)) {
if (fd == sock_fd) { if (fd == sock_fd) {
int conn; int conn;
if ((conn = accept(sock_fd, (struct sockaddr *) &sunx, if ((conn = accept(sock_fd, (struct sockaddr *) &sunx,
&addrLength)) < 0) { &addrLength)) < 0) {
perror ("accept"); fatalError( "accept error: %s\n", strerror(errno));
exit (FALSE); /* #### ??? */
} }
FD_SET (conn, &readfds); FD_SET (conn, &readfds);
} }
@ -242,17 +229,11 @@ static void doSyslogd (void)
char buf[BUFSIZE]; char buf[BUFSIZE];
char *q, *p; char *q, *p;
int n_read; int n_read;
char line[BUFSIZE];
unsigned char c;
n_read = read (fd, buf, BUFSIZE); /* Keep reading stuff till there is nothing else to read */
while( (n_read = read (fd, buf, BUFSIZE)) > 0 && errno != EOF) {
if (n_read < 0) {
// FIXME .. fd isn't set
perror ("read error");
goto close_fd;
}
else if (n_read > 0) {
char line[BUFSIZE];
unsigned char c;
int pri = (LOG_USER | LOG_NOTICE); int pri = (LOG_USER | LOG_NOTICE);
memset (line, 0, sizeof(line)); memset (line, 0, sizeof(line));
@ -281,14 +262,9 @@ static void doSyslogd (void)
/* Now log it */ /* Now log it */
logMessage(pri, line); logMessage(pri, line);
close_fd:
close (fd);
FD_CLR (fd, &readfds);
}
else { /* EOF */
goto close_fd;
} }
close (fd);
FD_CLR (fd, &readfds);
} }
} }
} }

26
tar.c
View File

@ -493,18 +493,6 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
chksum = getOctal(rawHeader->chksum, sizeof(rawHeader->chksum)); chksum = getOctal(rawHeader->chksum, sizeof(rawHeader->chksum));
header->type = rawHeader->typeflag; header->type = rawHeader->typeflag;
header->linkname = rawHeader->linkname; header->linkname = rawHeader->linkname;
/* Check for and relativify any absolute paths */
if ( *(header->linkname) == '/' ) {
static int alreadyWarned=FALSE;
while (*(header->linkname) == '/')
++*(header->linkname);
if (alreadyWarned == FALSE) {
errorMsg("tar: Removing leading '/' from link names\n");
alreadyWarned = TRUE;
}
}
header->devmajor = getOctal(rawHeader->devmajor, sizeof(rawHeader->devmajor)); header->devmajor = getOctal(rawHeader->devmajor, sizeof(rawHeader->devmajor));
header->devminor = getOctal(rawHeader->devminor, sizeof(rawHeader->devminor)); header->devminor = getOctal(rawHeader->devminor, sizeof(rawHeader->devminor));
@ -826,7 +814,7 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st
if (! *header.uname) if (! *header.uname)
strcpy(header.uname, "root"); strcpy(header.uname, "root");
// FIXME (or most likely not): I break Hard Links /* WARNING/NOTICE: I break Hard Links */
if (S_ISLNK(statbuf->st_mode)) { if (S_ISLNK(statbuf->st_mode)) {
char buffer[BUFSIZ]; char buffer[BUFSIZ];
header.typeflag = SYMTYPE; header.typeflag = SYMTYPE;
@ -834,17 +822,7 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st
errorMsg("Error reading symlink '%s': %s\n", header.name, strerror(errno)); errorMsg("Error reading symlink '%s': %s\n", header.name, strerror(errno));
return ( FALSE); return ( FALSE);
} }
if (*buffer=='/') { strncpy(header.linkname, buffer, sizeof(header.linkname));
static int alreadyWarned=FALSE;
if (alreadyWarned==FALSE) {
errorMsg("tar: Removing leading '/' from link names\n");
alreadyWarned=TRUE;
}
strncpy(header.linkname, buffer+1, sizeof(header.linkname));
}
else {
strncpy(header.linkname, buffer, sizeof(header.linkname));
}
} else if (S_ISDIR(statbuf->st_mode)) { } else if (S_ISDIR(statbuf->st_mode)) {
header.typeflag = DIRTYPE; header.typeflag = DIRTYPE;
strncat(header.name, "/", sizeof(header.name)); strncat(header.name, "/", sizeof(header.name));