A few updates (including the cp fix the Craig has been looking for)

-Erik
This commit is contained in:
Erik Andersen 2000-03-04 21:19:32 +00:00
parent 7c4b2f3fe5
commit 029011b9ee
34 changed files with 850 additions and 409 deletions

View File

@ -37,4 +37,5 @@ Charles P. Wright <cpwright@villagenet.com>
Enrique Zanardi <ezanardi@ull.es>
tarcat (since removed), loadkmap, various fixes, Debian maintenance
Karl M. Hegbloom <karlheg@debian.org>
cp_mv.c, the test suite, various fixes to utility.c, &c.

View File

@ -18,6 +18,20 @@
free). Use of /proc (or not) is policy that should be set up in
/etc/fstab (or in hardcoded scripts), not in init.
* Fixed rebooting when init runs as an initrd.
* Fixes and updates from Karl M. Hegbloom <karlheg@debian.org>
- update.c rewritten to look more like update-2.11
- moveed the inode hash out of du.c and into utility.c to make
it a common resource that can be used by other apps.
- cp_mv.c now checks inodes to see if a source and dest are
the same, and prints an error (instead of endlessly looping).
- mv now attempts to do a rename, and will fall back to doing
a copy only if the rename fails.
* Several fixes from Pavel Roskin <pavel_roskin@geocities.com>:
- Fixes to sort. Removed "-g", fixed and added "-r"
- Fixes to the makefile for handling "strip"
* An initial telnet implementation was added by
Randolph Chung <tausq@debian.org>.
-Erik Andersen

24
TODO
View File

@ -53,12 +53,6 @@ Hmm. Needs to be carefully thought out.
-----------------------
Some known bugs, todo items, etc...
-----------------------
-rw-r--r-- 1000/1000 4398 2000-01-06 21:55 uniq.c
-rw-r--r-- 1000/1000 1568 1999-10-20 18:08 update.c
-rw-r----- 0/1000 1168 2000-01-29 21:03 update.o
@ -116,3 +110,21 @@ messages from the embedded box logged to a remote network
syslog box, right? I can see that this would be useful.
I'll add this to the TODO list,
-----------------------
In utility.c:copyFile: It uses followLinks for both source and
destination files... is that right for `mv'? Will need to revisit
the GNU, freeBSD, and MINIX versions for this... Should read the
Unix98 and POSIX specs also.
-----------------------
I think that the add_inode &c in utility.c needs to also stow the
st_dev field, and that du.c should NOT call `reset_inode_list'
because there can be hard links from inside one argv/ to inside
another argv/. du.c probably ought to have an -x switch like GNU du
does also...

View File

@ -300,15 +300,17 @@ static const struct Applet applets[] = {
int main(int argc, char **argv)
{
char *s = argv[0];
char *name = argv[0];
const struct Applet *a = applets;
char *s = argv[0];
char *name = argv[0];
const struct Applet *a = applets;
while (*s != '\0') {
if (*s++ == '/')
name = s;
}
*argv = name;
while (a->name != 0) {
if (strcmp(name, a->name) == 0) {
int status;
@ -341,7 +343,7 @@ int busybox_main(int argc, char **argv)
fprintf(stderr, "Usage: busybox [function] [arguments]...\n");
fprintf(stderr, " or: [function] [arguments]...\n\n");
fprintf(stderr,
"\tMost people will create a symlink to busybox for each\n"
"\tMost people will create a link to busybox for each\n"
"\tfunction name, and busybox will act like whatever you invoke it as.\n");
fprintf(stderr, "\nCurrently defined functions:\n");
@ -362,3 +364,11 @@ int busybox_main(int argc, char **argv)
return (main(argc, argv));
}
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -300,15 +300,17 @@ static const struct Applet applets[] = {
int main(int argc, char **argv)
{
char *s = argv[0];
char *name = argv[0];
const struct Applet *a = applets;
char *s = argv[0];
char *name = argv[0];
const struct Applet *a = applets;
while (*s != '\0') {
if (*s++ == '/')
name = s;
}
*argv = name;
while (a->name != 0) {
if (strcmp(name, a->name) == 0) {
int status;
@ -341,7 +343,7 @@ int busybox_main(int argc, char **argv)
fprintf(stderr, "Usage: busybox [function] [arguments]...\n");
fprintf(stderr, " or: [function] [arguments]...\n\n");
fprintf(stderr,
"\tMost people will create a symlink to busybox for each\n"
"\tMost people will create a link to busybox for each\n"
"\tfunction name, and busybox will act like whatever you invoke it as.\n");
fprintf(stderr, "\nCurrently defined functions:\n");
@ -362,3 +364,11 @@ int busybox_main(int argc, char **argv)
return (main(argc, argv));
}
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -150,6 +150,9 @@
// Enable support for creation of tar files.
//#define BB_FEATURE_TAR_CREATE
//
//// Enable reverse sort
//#define BB_FEATURE_SORT_REVERSE
//
// Allow init to permenently chroot, and umount the old root fs
// just like an initrd does. Requires a kernel patch by Werner Almesberger.
// ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz

8
cat.c
View File

@ -59,3 +59,11 @@ extern int cat_main(int argc, char **argv)
}
exit(TRUE);
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -181,3 +181,11 @@ int chmod_chown_chgrp_main(int argc, char **argv)
bad_group:
fatalError( "%s: unknown group name: %s\n", invocationName, groupName);
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -65,3 +65,12 @@ int chroot_main(int argc, char **argv)
*argv, strerror(errno));
exit(FALSE);
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

9
chvt.c
View File

@ -34,3 +34,12 @@ int chvt_main(int argc, char **argv)
}
exit(TRUE);
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -34,3 +34,12 @@ int chvt_main(int argc, char **argv)
}
exit(TRUE);
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -59,3 +59,11 @@ extern int cat_main(int argc, char **argv)
}
exit(TRUE);
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -65,3 +65,12 @@ int chroot_main(int argc, char **argv)
*argv, strerror(errno));
exit(FALSE);
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -108,3 +108,11 @@ extern int df_main(int argc, char **argv)
exit(TRUE);
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -36,16 +36,6 @@
typedef void (Display) (long, char *);
typedef struct inode_type {
struct inode_type *next;
ino_t ino;
} INODETYPE;
#define HASH_SIZE 311 /* Should be prime */
#define hash_inode(i) ((i) % HASH_SIZE)
static INODETYPE *inode_hash_list[HASH_SIZE];
static const char du_usage[] =
"du [OPTION]... [FILE]...\n\n"
"Summarize disk space used for each FILE and/or directory.\n"
@ -71,52 +61,6 @@ static void print_summary(long size, char *filename)
}
}
/* Return 1 if inode is in inode hash list, else return 0 */
static int is_in_list(const ino_t ino)
{
INODETYPE *inode;
inode = inode_hash_list[hash_inode(ino)];
while (inode != NULL) {
if (inode->ino == ino)
return 1;
inode = inode->next;
}
return 0;
}
/* Add inode to inode hash list */
static void add_inode(const ino_t ino)
{
int i;
INODETYPE *inode;
i = hash_inode(ino);
inode = malloc(sizeof(INODETYPE));
if (inode == NULL)
fatalError("du: Not enough memory.");
inode->ino = ino;
inode->next = inode_hash_list[i];
inode_hash_list[i] = inode;
}
/* Clear inode hash list */
static void reset_inode_list(void)
{
int i;
INODETYPE *inode;
for (i = 0; i < HASH_SIZE; i++) {
while (inode_hash_list[i] != NULL) {
inode = inode_hash_list[i]->next;
free(inode_hash_list[i]);
inode_hash_list[i] = inode;
}
}
}
/* tiny recursive du */
static long du(char *filename)
{
@ -175,13 +119,13 @@ static long du(char *filename)
}
else if (statbuf.st_nlink > 1 && !count_hardlinks) {
/* Add files with hard links only once */
if (is_in_list(statbuf.st_ino)) {
if (is_in_ino_dev_hashtable(&statbuf, NULL)) {
sum = 0L;
if (du_depth == 1)
print(sum, filename);
}
else {
add_inode(statbuf.st_ino);
add_to_ino_dev_hashtable(&statbuf, NULL);
}
}
du_depth--;
@ -231,11 +175,18 @@ int du_main(int argc, char **argv)
if (sum && isDirectory(argv[i], FALSE, NULL)) {
print_normal(sum, argv[i]);
}
reset_inode_list();
reset_ino_dev_hashtable();
}
}
exit(0);
}
/* $Id: du.c,v 1.15 2000/02/21 17:27:17 erik Exp $ */
/* $Id: du.c,v 1.16 2000/03/04 21:19:32 erik Exp $ */
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -128,3 +128,11 @@ extern int ln_main(int argc, char **argv)
}
exit TRUE;
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -29,7 +29,18 @@
#include <stdio.h>
#include <errno.h>
static const char sort_usage[] = "sort [OPTION]... [FILE]...\n\n";
static const char sort_usage[] = "sort [-n]"
#ifdef BB_FEATURE_SORT_REVERSE
" [-r]"
#endif
" [FILE]...\n\n";
#ifdef BB_FEATURE_SORT_REVERSE
#define APPLY_REVERSE(x) (reverse ? -(x) : (x))
static int reverse = 0;
#else
#define APPLY_REVERSE(x) (x)
#endif
/* typedefs _______________________________________________________________ */
@ -120,7 +131,7 @@ static int compare_ascii(const void *a, const void *b)
y = *doh;
// fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data);
return strcmp(x->data, y->data);
return APPLY_REVERSE(strcmp(x->data, y->data));
}
/* numeric order */
@ -138,7 +149,7 @@ static int compare_numeric(const void *a, const void *b)
xint = strtoul(x->data, NULL, 10);
yint = strtoul(y->data, NULL, 10);
return (xint - yint);
return APPLY_REVERSE(xint - yint);
}
@ -254,20 +265,19 @@ int sort_main(int argc, char **argv)
if (argv[i][0] == '-') {
opt = argv[i][1];
switch (opt) {
case 'g':
/* what's the diff between -g && -n? */
compare = compare_numeric;
break;
case 'h':
usage(sort_usage);
break;
case 'n':
/* what's the diff between -g && -n? */
/* numeric comparison */
compare = compare_numeric;
break;
#ifdef BB_FEATURE_SORT_REVERSE
case 'r':
/* reverse */
reverse = 1;
break;
#endif
default:
fprintf(stderr, "sort: invalid option -- %c\n", opt);
usage(sort_usage);
@ -310,4 +320,4 @@ int sort_main(int argc, char **argv)
exit(0);
}
/* $Id: sort.c,v 1.11 2000/02/08 19:58:47 erik Exp $ */
/* $Id: sort.c,v 1.12 2000/03/04 21:19:32 erik Exp $ */

309
cp_mv.c
View File

@ -37,11 +37,15 @@
#include <utime.h>
#include <dirent.h>
#include <sys/param.h>
#include <setjmp.h> /* Ok to use this since `ash' does, therefore it's in the libc subset already. */
#include <string.h>
#include <unistd.h>
#include <errno.h>
#define is_cp 0
#define is_mv 1
static int dz_i; /* index into cp_mv_usage */
static const char *dz; /* dollar zero, .bss */
static int dz_i; /* index, .bss */
static const char *cp_mv_usage[] = /* .rodata */
{
"cp [OPTION]... SOURCE DEST\n"
@ -55,92 +59,131 @@ static const char *cp_mv_usage[] = /* .rodata */
"mv SOURCE DEST\n"
" or: mv SOURCE... DIRECTORY\n\n"
"Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n"
"Warning!! This is not GNU `mv'. It does not preserve hard links.\n"
};
static int recursiveFlag;
static int followLinks;
static int preserveFlag;
static const char *baseSrcName;
static int srcDirFlag;
static struct stat srcStatBuf;
static char baseDestName[PATH_MAX + 1];
static size_t baseDestLen;
static int destDirFlag;
static struct stat destStatBuf;
static jmp_buf catch;
static volatile int mv_Action_first_time;
static void name_too_long__exit (void) __attribute__((noreturn));
static
void name_too_long__exit (void)
{
fprintf(stderr, name_too_long, dz);
exit FALSE;
}
static void
fill_baseDest_buf(char *_buf, size_t * _buflen) {
const char *srcBasename;
if ((srcBasename = strrchr(baseSrcName, '/')) == NULL) {
srcBasename = baseSrcName;
if (_buf[*_buflen - 1] != '/') {
if (++(*_buflen) > PATH_MAX)
name_too_long__exit();
strcat(_buf, "/");
}
}
if (*_buflen + strlen(srcBasename) > PATH_MAX)
name_too_long__exit();
strcat(_buf, srcBasename);
return;
}
static int
cp_mv_Action(const char *fileName, struct stat *statbuf)
{
char destName[PATH_MAX + 1];
size_t destLen;
const char *srcBasename;
char *name;
strcpy(destName, baseDestName);
destLen = strlen(destName);
if (srcDirFlag == TRUE) {
if (recursiveFlag == FALSE) {
fprintf(stderr, omitting_directory, dz, baseSrcName);
return TRUE;
}
srcBasename = (strstr(fileName, baseSrcName)
+ strlen(baseSrcName));
if (destLen + strlen(srcBasename) > PATH_MAX) {
fprintf(stderr, name_too_long, dz);
return FALSE;
}
strcat(destName, srcBasename);
}
else if (destDirFlag == TRUE) {
fill_baseDest_buf(&destName[0], &destLen);
}
else {
srcBasename = baseSrcName;
}
if (mv_Action_first_time && (dz_i == is_mv)) {
mv_Action_first_time = errno = 0;
if (rename(fileName, destName) < 0 && errno != EXDEV) {
fprintf(stderr, "%s: rename(%s, %s): %s\n",
dz, fileName, destName, strerror(errno));
goto do_copyFile; /* Try anyway... */
}
else if (errno == EXDEV)
goto do_copyFile;
else
longjmp(catch, 1); /* succeeded with rename() */
}
do_copyFile:
if (preserveFlag == TRUE && statbuf->st_nlink > 1) {
if (is_in_ino_dev_hashtable(statbuf, &name)) {
if (link(name, destName) < 0) {
fprintf(stderr, "%s: link(%s, %s): %s\n",
dz, name, destName, strerror(errno));
return FALSE;
}
return TRUE;
}
else {
add_to_ino_dev_hashtable(statbuf, destName);
}
}
return copyFile(fileName, destName, preserveFlag, followLinks);
}
static int
rm_Action(const char *fileName, struct stat *statbuf)
{
int status = TRUE;
if (S_ISDIR(statbuf->st_mode)) {
if (rmdir(fileName) < 0) {
fprintf(stderr, "%s: rmdir(%s): %s\n", dz, fileName, strerror(errno));
status = FALSE;
}
} else if (unlink(fileName) < 0) {
fprintf(stderr, "%s: unlink(%s): %s\n", dz, fileName, strerror(errno));
status = FALSE;
}
return status;
}
extern int cp_mv_main(int argc, char **argv)
{
__label__ name_too_long__exit;
__label__ exit_false;
int recursiveFlag;
int followLinks;
int preserveFlag;
const char *baseSrcName;
int srcDirFlag;
struct stat srcStatBuf;
char baseDestName[PATH_MAX + 1];
size_t baseDestLen;
int destDirFlag;
struct stat destStatBuf;
void fill_baseDest_buf(char *_buf, size_t * _buflen) {
const char *srcBasename;
if ((srcBasename = strrchr(baseSrcName, '/')) == NULL) {
srcBasename = baseSrcName;
if (_buf[*_buflen - 1] != '/') {
if (++(*_buflen) > PATH_MAX)
goto name_too_long__exit;
strcat(_buf, "/");
}
}
if (*_buflen + strlen(srcBasename) > PATH_MAX)
goto name_too_long__exit;
strcat(_buf, srcBasename);
return;
}
int fileAction(const char *fileName, struct stat *statbuf) {
char destName[PATH_MAX + 1];
size_t destLen;
const char *srcBasename;
strcpy(destName, baseDestName);
destLen = strlen(destName);
if (srcDirFlag == TRUE) {
if (recursiveFlag == FALSE) {
fprintf(stderr, omitting_directory, "cp", baseSrcName);
return TRUE;
}
srcBasename = (strstr(fileName, baseSrcName)
+ strlen(baseSrcName));
if (destLen + strlen(srcBasename) > PATH_MAX) {
fprintf(stderr, name_too_long, "cp");
return FALSE;
}
strcat(destName, srcBasename);
} else if (destDirFlag == TRUE) {
fill_baseDest_buf(&destName[0], &destLen);
} else {
srcBasename = baseSrcName;
}
return copyFile(fileName, destName, preserveFlag, followLinks);
}
int rmfileAction(const char *fileName, struct stat *statbuf) {
if (unlink(fileName) < 0) {
perror(fileName);
return FALSE;
}
return TRUE;
}
int rmdirAction(const char *fileName, struct stat *statbuf) {
if (rmdir(fileName) < 0) {
perror(fileName);
return FALSE;
}
return TRUE;
}
if ((dz = strrchr(*argv, '/')) == NULL)
dz = *argv;
else
dz++;
dz = *argv; /* already basename'd by busybox.c:main */
if (*dz == 'c' && *(dz + 1) == 'p')
dz_i = is_cp;
else
@ -199,53 +242,93 @@ extern int cp_mv_main(int argc, char **argv)
while (argc-- > 1) {
size_t srcLen;
int flags_memo;
volatile int flags_memo;
int status;
baseSrcName = *(argv++);
if ((srcLen = strlen(baseSrcName)) > PATH_MAX)
goto name_too_long__exit;
name_too_long__exit();
if (srcLen == 0)
continue;
if (srcLen == 0) continue; /* "" */
srcDirFlag = isDirectory(baseSrcName, followLinks, &srcStatBuf);
if ((flags_memo = (recursiveFlag == TRUE &&
srcDirFlag == TRUE && destDirFlag == TRUE))) {
if ((destStatBuf.st_ino == srcStatBuf.st_ino) &&
(destStatBuf.st_rdev == srcStatBuf.st_rdev)) {
fprintf(stderr,
"%s: Cannot %s `%s' into a subdirectory of itself, `%s/%s'\n",
dz, dz, baseSrcName, baseDestName, baseSrcName);
continue;
struct stat sb;
int state = 0;
char *pushd, *d, *p;
if ((pushd = getcwd(NULL, PATH_MAX + 1)) == NULL) {
fprintf(stderr, "%s: getcwd(): %s\n", dz, strerror(errno));
continue;
}
if (chdir(baseDestName) < 0) {
fprintf(stderr, "%s: chdir(%s): %s\n", dz, baseSrcName, strerror(errno));
continue;
}
if ((d = getcwd(NULL, PATH_MAX + 1)) == NULL) {
fprintf(stderr, "%s: getcwd(): %s\n", dz, strerror(errno));
continue;
}
while (!state && *d != '\0') {
if (stat(d, &sb) < 0) { /* stat not lstat - always dereference targets */
fprintf(stderr, "%s: stat(%s) :%s\n", dz, d, strerror(errno));
state = -1;
continue;
}
if ((sb.st_ino == srcStatBuf.st_ino) &&
(sb.st_dev == srcStatBuf.st_dev)) {
fprintf(stderr,
"%s: Cannot %s `%s' "
"into a subdirectory of itself, `%s/%s'\n",
dz, dz, baseSrcName, baseDestName, baseSrcName);
state = -1;
continue;
}
if ((p = strrchr(d, '/')) != NULL) {
*p = '\0';
}
}
if (chdir(pushd) < 0) {
fprintf(stderr, "%s: chdir(%s): %s\n", dz, pushd, strerror(errno));
free(pushd);
free(d);
continue;
}
free(pushd);
free(d);
if (state < 0)
continue;
else
fill_baseDest_buf(baseDestName, &baseDestLen);
}
if (recursiveAction(baseSrcName,
recursiveFlag, followLinks, FALSE,
fileAction, fileAction) == FALSE)
goto exit_false;
if (dz_i == is_mv &&
recursiveAction(baseSrcName,
recursiveFlag, followLinks, TRUE,
rmfileAction, rmdirAction) == FALSE)
goto exit_false;
status = setjmp(catch);
if (status == 0) {
mv_Action_first_time = 1;
if (recursiveAction(baseSrcName,
recursiveFlag, followLinks, FALSE,
cp_mv_Action, cp_mv_Action) == FALSE) goto exit_false;
if (dz_i == is_mv &&
recursiveAction(baseSrcName,
recursiveFlag, followLinks, TRUE,
rm_Action, rm_Action) == FALSE) goto exit_false;
}
if (flags_memo)
*(baseDestName + baseDestLen) = '\0';
}
// exit_true:
exit TRUE;
name_too_long__exit:
fprintf(stderr, name_too_long, "cp");
exit_false:
exit_false:
exit FALSE;
}
// Local Variables:
// c-file-style: "linux"
// tab-width: 4
// End:
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

8
df.c
View File

@ -108,3 +108,11 @@ extern int df_main(int argc, char **argv)
exit(TRUE);
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

71
du.c
View File

@ -36,16 +36,6 @@
typedef void (Display) (long, char *);
typedef struct inode_type {
struct inode_type *next;
ino_t ino;
} INODETYPE;
#define HASH_SIZE 311 /* Should be prime */
#define hash_inode(i) ((i) % HASH_SIZE)
static INODETYPE *inode_hash_list[HASH_SIZE];
static const char du_usage[] =
"du [OPTION]... [FILE]...\n\n"
"Summarize disk space used for each FILE and/or directory.\n"
@ -71,52 +61,6 @@ static void print_summary(long size, char *filename)
}
}
/* Return 1 if inode is in inode hash list, else return 0 */
static int is_in_list(const ino_t ino)
{
INODETYPE *inode;
inode = inode_hash_list[hash_inode(ino)];
while (inode != NULL) {
if (inode->ino == ino)
return 1;
inode = inode->next;
}
return 0;
}
/* Add inode to inode hash list */
static void add_inode(const ino_t ino)
{
int i;
INODETYPE *inode;
i = hash_inode(ino);
inode = malloc(sizeof(INODETYPE));
if (inode == NULL)
fatalError("du: Not enough memory.");
inode->ino = ino;
inode->next = inode_hash_list[i];
inode_hash_list[i] = inode;
}
/* Clear inode hash list */
static void reset_inode_list(void)
{
int i;
INODETYPE *inode;
for (i = 0; i < HASH_SIZE; i++) {
while (inode_hash_list[i] != NULL) {
inode = inode_hash_list[i]->next;
free(inode_hash_list[i]);
inode_hash_list[i] = inode;
}
}
}
/* tiny recursive du */
static long du(char *filename)
{
@ -175,13 +119,13 @@ static long du(char *filename)
}
else if (statbuf.st_nlink > 1 && !count_hardlinks) {
/* Add files with hard links only once */
if (is_in_list(statbuf.st_ino)) {
if (is_in_ino_dev_hashtable(&statbuf, NULL)) {
sum = 0L;
if (du_depth == 1)
print(sum, filename);
}
else {
add_inode(statbuf.st_ino);
add_to_ino_dev_hashtable(&statbuf, NULL);
}
}
du_depth--;
@ -231,11 +175,18 @@ int du_main(int argc, char **argv)
if (sum && isDirectory(argv[i], FALSE, NULL)) {
print_normal(sum, argv[i]);
}
reset_inode_list();
reset_ino_dev_hashtable();
}
}
exit(0);
}
/* $Id: du.c,v 1.15 2000/02/21 17:27:17 erik Exp $ */
/* $Id: du.c,v 1.16 2000/03/04 21:19:32 erik Exp $ */
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

11
init.c
View File

@ -242,6 +242,7 @@ static void console_init()
int fd;
int tried_devcons = 0;
int tried_vtprimary = 0;
struct vt_stat vt;
struct serial_struct sr;
char *s;
@ -264,8 +265,6 @@ static void console_init()
}
#endif
else {
struct vt_stat vt;
/* 2.2 kernels: identify the real console backend and try to use it */
if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
/* this is a serial console */
@ -951,3 +950,11 @@ extern int init_main(int argc, char **argv)
sleep(1);
}
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -242,6 +242,7 @@ static void console_init()
int fd;
int tried_devcons = 0;
int tried_vtprimary = 0;
struct vt_stat vt;
struct serial_struct sr;
char *s;
@ -264,8 +265,6 @@ static void console_init()
}
#endif
else {
struct vt_stat vt;
/* 2.2 kernels: identify the real console backend and try to use it */
if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
/* this is a serial console */
@ -951,3 +950,11 @@ extern int init_main(int argc, char **argv)
sleep(1);
}
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -29,3 +29,11 @@ extern int reboot_main(int argc, char **argv)
/* don't assume init's pid == 1 */
exit(kill(findInitPid(), SIGINT));
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -154,6 +154,17 @@ const char *modeString(int mode);
const char *timeString(time_t timeVal);
int isDirectory(const char *name, const int followLinks, struct stat *statBuf);
int isDevice(const char *name);
typedef struct ino_dev_hash_bucket_struct {
struct ino_dev_hash_bucket_struct *next;
ino_t ino;
dev_t dev;
char name[1];
} ino_dev_hashtable_bucket_t;
int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name);
void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name);
void reset_ino_dev_hashtable(void);
int copyFile(const char *srcName, const char *destName, int setModes,
int followLinks);
char *buildName(const char *dirName, const char *fileName);

8
ln.c
View File

@ -128,3 +128,11 @@ extern int ln_main(int argc, char **argv)
}
exit TRUE;
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -1,9 +1,11 @@
/* vi: set sw=4 ts=4: */
/*
* Mini update implementation for busybox
* Mini update implementation for busybox; much pasted from update-2.11
*
*
* Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
* Copyright (c) 1996, 1997, 1999 Torsten Poulin.
* Copyright (c) 2000 by Karl M. Hegbloom <karlheg@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,6 +25,8 @@
#include "internal.h"
#include <linux/unistd.h>
#include <sys/param.h>
#include <sys/syslog.h>
#if defined(__GLIBC__)
#include <sys/kdaemon.h>
@ -30,37 +34,79 @@
_syscall2(int, bdflush, int, func, int, data);
#endif /* __GLIBC__ */
static char update_usage[] =
"update [options]\n"
" -S\tforce use of sync(2) instead of flushing\n"
" -s SECS\tcall sync this often (default 30)\n"
" -f SECS\tflush some buffers this often (default 5)\n";
static unsigned int sync_duration = 30;
static unsigned int flush_duration = 5;
static int use_sync = 0;
extern int update_main(int argc, char **argv)
{
/*
* Update is actually two daemons, bdflush and update.
*/
int pid;
while (**argv == '-') {
while (*++(*argv)) {
switch (**argv) {
case 'S':
use_sync = 1;
break;
case 's':
if (--argc < 1) usage(update_usage);
sync_duration = atoi(*(++argv));
break;
case 'f':
if (--argc < 1) usage(update_usage);
flush_duration = atoi(*(++argv));
break;
}
}
argc--;
argv++;
}
pid = fork();
if (pid < 0)
return pid;
exit(FALSE);
else if (pid == 0) {
/* Become a proper daemon */
setsid();
chdir("/");
for (pid = 0; pid < OPEN_MAX; pid++) close(pid);
/*
* This is no longer necessary since 1.3.5x, but it will harmlessly
* exit if that is the case.
*/
strcpy(argv[0], "bdflush (update)");
argv[1] = 0;
argv[2] = 0;
bdflush(1, 0);
_exit(0);
}
pid = fork();
if (pid < 0)
return pid;
else if (pid == 0) {
argv[0] = "update";
argv[0] = "bdflush (update)";
argv[1] = NULL;
argv[2] = NULL;
for (;;) {
sync();
sleep(30);
if (use_sync) {
sleep(sync_duration);
sync();
} else {
sleep(flush_duration);
if (bdflush(1, 0) < 0) {
openlog("update", LOG_CONS, LOG_DAEMON);
syslog(LOG_INFO,
"This kernel does not need update(8). Exiting.");
closelog();
exit(TRUE);
}
}
}
}
return 0;
return TRUE;
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -29,3 +29,11 @@ extern int reboot_main(int argc, char **argv)
/* don't assume init's pid == 1 */
exit(kill(findInitPid(), SIGINT));
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

28
sort.c
View File

@ -29,7 +29,18 @@
#include <stdio.h>
#include <errno.h>
static const char sort_usage[] = "sort [OPTION]... [FILE]...\n\n";
static const char sort_usage[] = "sort [-n]"
#ifdef BB_FEATURE_SORT_REVERSE
" [-r]"
#endif
" [FILE]...\n\n";
#ifdef BB_FEATURE_SORT_REVERSE
#define APPLY_REVERSE(x) (reverse ? -(x) : (x))
static int reverse = 0;
#else
#define APPLY_REVERSE(x) (x)
#endif
/* typedefs _______________________________________________________________ */
@ -120,7 +131,7 @@ static int compare_ascii(const void *a, const void *b)
y = *doh;
// fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data);
return strcmp(x->data, y->data);
return APPLY_REVERSE(strcmp(x->data, y->data));
}
/* numeric order */
@ -138,7 +149,7 @@ static int compare_numeric(const void *a, const void *b)
xint = strtoul(x->data, NULL, 10);
yint = strtoul(y->data, NULL, 10);
return (xint - yint);
return APPLY_REVERSE(xint - yint);
}
@ -254,20 +265,19 @@ int sort_main(int argc, char **argv)
if (argv[i][0] == '-') {
opt = argv[i][1];
switch (opt) {
case 'g':
/* what's the diff between -g && -n? */
compare = compare_numeric;
break;
case 'h':
usage(sort_usage);
break;
case 'n':
/* what's the diff between -g && -n? */
/* numeric comparison */
compare = compare_numeric;
break;
#ifdef BB_FEATURE_SORT_REVERSE
case 'r':
/* reverse */
reverse = 1;
break;
#endif
default:
fprintf(stderr, "sort: invalid option -- %c\n", opt);
usage(sort_usage);
@ -310,4 +320,4 @@ int sort_main(int argc, char **argv)
exit(0);
}
/* $Id: sort.c,v 1.11 2000/02/08 19:58:47 erik Exp $ */
/* $Id: sort.c,v 1.12 2000/03/04 21:19:32 erik Exp $ */

View File

@ -1,16 +1,21 @@
all test_all: message_header cp_tests mv_tests ln_tests
# busybox/tests/Makefile - Run through all defined tests.
# ------------------------
# Copyright (C) 2000 Karl M. Hegbloom <karlheg@debian.org> GPL
clean: cp_clean mv_clean ln_clean
all:: message_header
message_header:
@echo
@echo If tests faile due to differences in timestamps in commands that are not set
@echo to preserve timestamps, just run the tests again.
@echo BusyBox Test Suite.
@echo
include cp_tests.mk
include mv_tests.mk
include ln_tests.mk
clean::
distclean: clean
.PHONY: all clean distclean message_header
include $(wildcard *_tests.mk)
BBL := $(shell pushd .. >/dev/null && \
${MAKE} busybox.links >/dev/null && \
@ -21,8 +26,6 @@ BBL := $(shell pushd .. >/dev/null && \
../busybox:
cd .. && ${MAKE} busybox
$(BBL): ../busybox
${BBL}: ../busybox
rm -f $@
ln ../busybox $@
.PHONY: all test_all message_header

View File

@ -1,18 +1,23 @@
# This is a -*- makefile -*-
# cp_tests.mk - Set of test cases for busybox cp
# -------------
# Copyright (C) 2000 Karl M. Hegbloom <karlheg@debian.org> GPL
#
# GNU `cp'
GCP = /bin/cp
# BusyBox `cp'
BCP = $(shell pwd)/cp
.PHONY: cp_clean
cp_clean:
rm -rf cp_tests cp_*.{gnu,bb} cp
all:: cp_tests
clean:: cp_clean
cp_clean:
- rm -rf cp_tests cp_*.{gnu,bb} cp
.PHONY: cp_tests
cp_tests: cp_clean cp
@echo;
@echo "No output from diff means busybox cp is functioning properly.";
@echo "Some tests might show timestamp differences that are Ok.";
@echo;
${BCP} || true;
@ -20,7 +25,8 @@ cp_tests: cp_clean cp
@echo;
mkdir cp_tests;
@echo;
# Copy a file to a copy of the file
@echo ------------------------------;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_afile_afilecopy.gnu; \
@ -28,7 +34,7 @@ cp_tests: cp_clean cp
ls -l afile afilecopy >> ../cp_afile_afilecopy.gnu;
@echo;
rm -f cp_tests/afile*;
rm -rf cp_tests/*;
@echo;
cd cp_tests; \
@ -38,118 +44,135 @@ cp_tests: cp_clean cp
ls -l afile afilecopy >> ../cp_afile_afilecopy.bb;
@echo;
diff -u cp_afile_afilecopy.gnu cp_afile_afilecopy.bb;
@echo Might show timestamp differences.
-diff -u cp_afile_afilecopy.gnu cp_afile_afilecopy.bb;
@echo;
rm -f cp_tests/afile*;
rm -rf cp_tests/*;
@echo; echo;
# Copy a file pointed to by a symlink
@echo; echo ------------------------------;
cd cp_tests; \
mkdir there there1; \
cd there; \
ln -s ../afile .;
mkdir here there; \
echo A file > afile; \
cd here; \
ln -s ../afile .; \
@echo;
cd cp_tests; \
ls -lR . > ../cp_symlink.gnu; \
${GCP} here/afile there; \
ls -lR . >> ../cp_symlink.gnu;
@echo;
rm -rf cp_tests/there/*;
sleep 1;
@echo;
cd cp_tests; \
ls -lR . > ../cp_symlink.bb; \
${BCP} here/afile there; \
ls -lR . >> ../cp_symlink.bb;
@echo;
@echo Will show timestamp difference.
-diff -u cp_symlink.gnu cp_symlink.bb;
@echo;
rm -rf cp_tests/*
# Copy a symlink, useing the -a switch.
@echo; echo ------------------------------;
cd cp_tests; \
echo A file > afile; \
mkdir here there; \
cd here; \
ln -s ../afile .
cd cp_test; \
ls -lR . > ../cp_a_symlink.gnu; \
${GCP} -a here/afile there; \
ls -lR . >> ../cp_a_symlink.gnu;
@echo;
rm -f cp_tests/there/*;
sleep 1;
@echo;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_symlink.gnu; \
${GCP} there/afile there1/; \
ls -l afile there/afile there1/afile >> ../cp_symlink.gnu;
@echo;
rm -f cp_tests/afile cp_tests/there1/afile;
@echo;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_symlink.bb; \
${BCP} there/afile there1/; \
ls -l afile there/afile there1/afile >> ../cp_symlink.bb;
@echo;
diff -u cp_symlink.gnu cp_symlink.bb;
@echo;
rm -f cp_tests/afile cp_tests/there1/afile;
@echo; echo;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_a_symlink.gnu; \
${GCP} -a there/afile there1/; \
ls -l afile there/afile there1/afile >> ../cp_a_symlink.gnu;
@echo;
rm -f cp_tests/afile cp_tests/there1/afile;
@echo;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_a_symlink.bb; \
${BCP} -a there/afile there1/; \
ls -l afile there/afile there1/afile >> ../cp_a_symlink.bb;
ls -lR . > ../cp_a_symlink.bb; \
${BCP} -a here/afile there; \
ls -lR . >> ../cp_a_symlink.bb;
@echo;
diff -u cp_a_symlink.gnu cp_a_symlink.bb;
@echo;
rm -f cp_tests/afile
rm -rf cp_tests/there{,1};
rm -f cp_tests/*;
@echo; echo;
# Copy a directory into another directory with the -a switch
@echo; echo ------------------------------;
cd cp_tests; \
echo A file > there/afile; \
mkdir there/adir; \
touch there/adir/afileinadir; \
ln -s $(shell pwd) there/alink;
mkdir here there; \
echo A file > here/afile; \
mkdir here/adir; \
touch here/adir/afileinadir; \
ln -s $$(pwd) here/alink;
@echo;
cd cp_tests; \
${GCP} -a there/ there1/; \
ls -lR there/ there1/ > ../cp_a_dir_dir.gnu;
ls -lR . > ../cp_a_dir_dir.gnu; \
${GCP} -a here/ there/; \
ls -lR . >> ../cp_a_dir_dir.gnu;
@echo;
rm -rf cp_tests/there1;
rm -rf cp_tests/there/*;
sleep 1;
@echo;
cd cp_tests; \
${BCP} -a there/ there1/; \
ls -lR there/ there1/ > ../cp_a_dir_dir.bb;
ls -lR . > ../cp_a_dir_dir.bb; \
${BCP} -a here/ there/; \
ls -lR . >> ../cp_a_dir_dir.bb;
@echo;
diff -u cp_a_dir_dir.gnu cp_a_dir_dir.bb;
@echo;
rm -rf cp_tests/there1/;
rm -rf cp_tests/*;
@echo; echo;
# Copy a set of files to a directory.
@echo; echo ------------------------------;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
ln -s afile1 symlink1; \
mkdir there1; \
${GCP} afile1 afile2 symlink1 there1/; \
mkdir there;
cd cp_tests; \
${GCP} afile1 afile2 symlink1 there/; \
ls -lR > ../cp_files_dir.gnu;
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
rm -rf cp_tests/there/*;
@echo;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
ln -s afile1 symlink1; \
mkdir there1; \
${BCP} afile1 afile2 symlink1 there1/; \
${BCP} afile1 afile2 symlink1 there/; \
ls -lR > ../cp_files_dir.bb;
@echo;
diff -u cp_files_dir.gnu cp_files_dir.bb;
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
rm -rf cp_tests/*;
@echo; echo;
# Copy a set of files to a directory with the -d switch.
@echo; echo ------------------------------;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
@ -176,7 +199,8 @@ cp_tests: cp_clean cp
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo; echo;
# Copy a set of files to a directory with the -p switch.
@echo; echo ------------------------------;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
@ -205,7 +229,8 @@ cp_tests: cp_clean cp
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo; echo;
# Copy a set of files to a directory with -p and -d switches.
@echo; echo ------------------------------;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
@ -234,7 +259,8 @@ cp_tests: cp_clean cp
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo; echo;
# Copy a directory into another directory with the -a switch.
@echo; echo ------------------------------;
cd cp_tests; \
mkdir dir{a,b}; \
echo A file > dira/afile; \
@ -246,7 +272,6 @@ cp_tests: cp_clean cp
${GCP} -a dira dirb; \
ls -lR . >> ../cp_a_dira_dirb.gnu;
# false;
@echo;
rm -rf cp_tests/dir{a,b};
@ -265,6 +290,31 @@ cp_tests: cp_clean cp
@echo;
diff -u cp_a_dira_dirb.gnu cp_a_dira_dirb.bb;
# false;
@echo;
rm -rf cp_tests/dir{a,b};
# Copy a directory to another directory, without the -a switch.
@echo; echo ------------------------------;
@echo There should be an error message about cannot cp a dir to a subdir of itself.
cd cp_tests; \
touch a b c; \
mkdir adir; \
ls -lR . > ../cp_a_star_adir.gnu; \
${GCP} -a * adir; \
ls -lR . >> ../cp_a_star_adir.gnu;
@echo
@echo There should be an error message about cannot cp a dir to a subdir of itself.
cd cp_tests; \
rm -rf adir; \
mkdir adir; \
ls -lR . > ../cp_a_star_adir.bb; \
${BCP} -a * adir; \
ls -lR . >> ../cp_a_star_adir.bb;
@echo;
diff -u cp_a_star_adir.gnu cp_a_star_adir.bb;
@echo;
rm -rf cp_tests;
@echo; echo Done.

View File

@ -1,14 +1,19 @@
# ln_tests.mk - Set of tests for busybox ln
# -------------
# Copyright (C) 2000 Karl M. Hegbloom <karlheg@debian.org> GPL
#
# GNU `ln'
GLN = /bin/ln
# BusyBox `ln'
BLN = $(shell pwd)/ln
.PHONY: ln_clean
all:: ln_tests
clean:: ln_clean
ln_clean:
rm -rf ln_tests ln_*.{gnu,bb} ln
.PHONY: ln_tests
ln_tests: ln_clean ln
@echo;
@echo "No output from diff means busybox ln is functioning properly.";

View File

@ -1,14 +1,19 @@
# mv_tests.mk - Set of tests cases for busybox mv
# -------------
# Copyright (C) 2000 Karl M. Hegbloom <karlheg@debian.org> GPL
#
# GNU `mv'
GMV = /bin/mv
# BusyBox `mv'
BMV = $(shell pwd)/mv
.PHONY: mv_clean
all:: mv_tests
clean:: mv_clean
mv_clean:
rm -rf mv_tests mv_*.{gnu,bb} mv
.PHONY: mv_tests
mv_tests: mv_clean mv
@echo;
@echo "No output from diff means busybox mv is functioning properly.";
@ -45,7 +50,7 @@ mv_tests: mv_clean mv
@echo;
rm -f mv_tests/{afile,newname};
@echo; echo;
@echo; echo ------------------------------;
cd mv_tests; \
echo A file > afile; \
ln -s afile symlink; \
@ -72,7 +77,7 @@ mv_tests: mv_clean mv
@echo;
rm -rf mv_tests/*;
@echo; echo;
@echo; echo ------------------------------;
cd mv_tests; \
echo A file > afile; \
ln -s afile symlink; \
@ -85,7 +90,7 @@ mv_tests: mv_clean mv
@echo;
rm -rf mv_tests/*
@echo; echo;
@echo; echo ------------------------------;
cd mv_tests; \
echo A file > afile; \
ln -s afile symlink; \
@ -101,7 +106,7 @@ mv_tests: mv_clean mv
@echo;
rm -rf mv_tests/*;
@echo; echo;
@echo; echo ------------------------------;
cd mv_tests; \
mkdir dir{a,b}; \
echo A file > dira/afile; \
@ -135,3 +140,27 @@ mv_tests: mv_clean mv
# false;
@echo;
rm -rf mv_tests/dir{a,b};
@echo; echo ------------------------------;
@echo There should be an error message about cannot mv a dir to a subdir of itself.
cd mv_tests; \
touch a b c; \
mkdir adir; \
ls -lR . > ../mv_a_star_adir.gnu; \
${GMV} * adir; \
ls -lR . >> ../mv_a_star_adir.gnu;
@echo
@echo There should be an error message about cannot mv a dir to a subdir of itself.
cd mv_tests; \
rm -rf adir; \
mkdir adir; \
ls -lR . > ../mv_a_star_adir.bb; \
${BMV} * adir; \
ls -lR . >> ../mv_a_star_adir.bb;
@echo;
diff -u mv_a_star_adir.gnu mv_a_star_adir.bb;
@echo;
rm -rf mv_test/*;

View File

@ -1,9 +1,11 @@
/* vi: set sw=4 ts=4: */
/*
* Mini update implementation for busybox
* Mini update implementation for busybox; much pasted from update-2.11
*
*
* Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
* Copyright (c) 1996, 1997, 1999 Torsten Poulin.
* Copyright (c) 2000 by Karl M. Hegbloom <karlheg@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,6 +25,8 @@
#include "internal.h"
#include <linux/unistd.h>
#include <sys/param.h>
#include <sys/syslog.h>
#if defined(__GLIBC__)
#include <sys/kdaemon.h>
@ -30,37 +34,79 @@
_syscall2(int, bdflush, int, func, int, data);
#endif /* __GLIBC__ */
static char update_usage[] =
"update [options]\n"
" -S\tforce use of sync(2) instead of flushing\n"
" -s SECS\tcall sync this often (default 30)\n"
" -f SECS\tflush some buffers this often (default 5)\n";
static unsigned int sync_duration = 30;
static unsigned int flush_duration = 5;
static int use_sync = 0;
extern int update_main(int argc, char **argv)
{
/*
* Update is actually two daemons, bdflush and update.
*/
int pid;
while (**argv == '-') {
while (*++(*argv)) {
switch (**argv) {
case 'S':
use_sync = 1;
break;
case 's':
if (--argc < 1) usage(update_usage);
sync_duration = atoi(*(++argv));
break;
case 'f':
if (--argc < 1) usage(update_usage);
flush_duration = atoi(*(++argv));
break;
}
}
argc--;
argv++;
}
pid = fork();
if (pid < 0)
return pid;
exit(FALSE);
else if (pid == 0) {
/* Become a proper daemon */
setsid();
chdir("/");
for (pid = 0; pid < OPEN_MAX; pid++) close(pid);
/*
* This is no longer necessary since 1.3.5x, but it will harmlessly
* exit if that is the case.
*/
strcpy(argv[0], "bdflush (update)");
argv[1] = 0;
argv[2] = 0;
bdflush(1, 0);
_exit(0);
}
pid = fork();
if (pid < 0)
return pid;
else if (pid == 0) {
argv[0] = "update";
argv[0] = "bdflush (update)";
argv[1] = NULL;
argv[2] = NULL;
for (;;) {
sync();
sleep(30);
if (use_sync) {
sleep(sync_duration);
sync();
} else {
sleep(flush_duration);
if (bdflush(1, 0) < 0) {
openlog("update", LOG_CONS, LOG_DAEMON);
syslog(LOG_INFO,
"This kernel does not need update(8). Exiting.");
closelog();
exit(TRUE);
}
}
}
}
return 0;
return TRUE;
}
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

View File

@ -122,7 +122,76 @@ int get_kernel_revision()
}
#endif /* BB_INIT || BB_PS */
#if defined (BB_CP_MV) || defined (BB_DU)
#define HASH_SIZE 311 /* Should be prime */
#define hash_inode(i) ((i) % HASH_SIZE)
static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE];
/*
* Return 1 if statbuf->st_ino && statbuf->st_dev are recorded in
* `ino_dev_hashtable', else return 0
*
* If NAME is a non-NULL pointer to a character pointer, and there is
* a match, then set *NAME to the value of the name slot in that
* bucket.
*/
int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name)
{
ino_dev_hashtable_bucket_t *bucket;
bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)];
while (bucket != NULL) {
if ((bucket->ino == statbuf->st_ino) &&
(bucket->dev == statbuf->st_dev))
{
if (name) *name = bucket->name;
return 1;
}
bucket = bucket->next;
}
return 0;
}
/* Add statbuf to statbuf hash table */
void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name)
{
int i;
size_t s;
ino_dev_hashtable_bucket_t *bucket;
i = hash_inode(statbuf->st_ino);
s = name ? strlen(name) : 0;
bucket = malloc(sizeof(ino_dev_hashtable_bucket_t) + s);
if (bucket == NULL)
fatalError("Not enough memory.");
bucket->ino = statbuf->st_ino;
bucket->dev = statbuf->st_dev;
if (name)
strcpy(bucket->name, name);
else
bucket->name[0] = '\0';
bucket->next = ino_dev_hashtable[i];
ino_dev_hashtable[i] = bucket;
}
/* Clear statbuf hash table */
void reset_ino_dev_hashtable(void)
{
int i;
ino_dev_hashtable_bucket_t *bucket;
for (i = 0; i < HASH_SIZE; i++) {
while (ino_dev_hashtable[i] != NULL) {
bucket = ino_dev_hashtable[i]->next;
free(ino_dev_hashtable[i]);
ino_dev_hashtable[i] = bucket;
}
}
}
#endif /* BB_CP_MV || BB_DU */
#if defined (BB_CP_MV) || defined (BB_DU) || defined (BB_LN)
/*
@ -161,7 +230,7 @@ int isDirectory(const char *fileName, const int followLinks, struct stat *statBu
/*
* Copy one file to another, while possibly preserving its modes, times,
* and modes. Returns TRUE if successful, or FALSE on a failure with an
* error message output. (Failure is not indicted if the attributes cannot
* error message output. (Failure is not indicated if the attributes cannot
* be set.)
* -Erik Andersen
*/
@ -1335,6 +1404,11 @@ extern void whine_if_fstab_is_missing()
}
#endif
/* END CODE */
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/