More stuff works.
authorEric Andersen <andersen@codepoet.org>
Tue, 5 Oct 1999 22:58:32 +0000 (22:58 -0000)
committerEric Andersen <andersen@codepoet.org>
Tue, 5 Oct 1999 22:58:32 +0000 (22:58 -0000)
 -Erik

17 files changed:
Makefile
applets/busybox.c
busybox.c
busybox.def.h
cat.c
chgrp.c [deleted file]
chown.c
chroot.c
clear.c
console-tools/clear.c
coreutils/cat.c
coreutils/chgrp.c [deleted file]
coreutils/chown.c
coreutils/chroot.c
internal.h
utility.c
utility.h [deleted file]

index bef25a3ae160d5542758a93e5409bce718761049..62c4ac6fe655675101fde6d5020604becb165784 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ CFLAGS=-Wall -O2 -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE
 # For debugging only
 #CFLAGS=-Wall -g -D_GNU_SOURCE
 LIBRARIES=-lc
-OBJECTS=$(shell ./busybox.obj) utility.o
+OBJECTS=$(shell ./busybox.sh) utility.o
 
 CFLAGS+= -DBB_VER='"$(VERSION)"'
 CFLAGS+= -DBB_BT='"$(BUILDTIME)"'
@@ -36,3 +36,5 @@ distclean: clean
        - rm -f busybox
 
 force:
+
+$(OBJECTS):  busybox.def.h Makefile
index b7b2b6009e5a527b019f774b714c8c679b3cbae0..08ba88d655454c7e7fc6635f86444ba4bfc475e8 100644 (file)
@@ -16,14 +16,12 @@ static const struct Applet applets[] = {
 #ifdef BB_CAT                  //bin
     {"cat", cat_more_main},
 #endif
-#ifdef BB_CHGRP                        //bin
-    {"chgrp", chgrp_main},
-#endif
 #ifdef BB_CHMOD                        //bin
     {"chmod", chmod_main},
 #endif
 #ifdef BB_CHOWN                        //bin
     {"chown", chown_main},
+    {"chgrp", chown_main},
 #endif
 #ifdef BB_CHROOT               //sbin
     {"chroot", chroot_main},
index b7b2b6009e5a527b019f774b714c8c679b3cbae0..08ba88d655454c7e7fc6635f86444ba4bfc475e8 100644 (file)
--- a/busybox.c
+++ b/busybox.c
@@ -16,14 +16,12 @@ static const struct Applet applets[] = {
 #ifdef BB_CAT                  //bin
     {"cat", cat_more_main},
 #endif
-#ifdef BB_CHGRP                        //bin
-    {"chgrp", chgrp_main},
-#endif
 #ifdef BB_CHMOD                        //bin
     {"chmod", chmod_main},
 #endif
 #ifdef BB_CHOWN                        //bin
     {"chown", chown_main},
+    {"chgrp", chown_main},
 #endif
 #ifdef BB_CHROOT               //sbin
     {"chroot", chroot_main},
index ad6480a25837588cf7520909049705ba06ba34d5..7d49ed0c2504db703b36240f07c6244d40cc4101 100644 (file)
@@ -6,11 +6,10 @@
 //#define BB_BLOCK_DEVICE
 #define BB_BUSYBOX
 #define BB_CAT
-#define BB_CHGRP
 //#define BB_CHMOD
-//#define BB_CHOWN
-//#define BB_CHROOT
-//#define BB_CLEAR
+#define BB_CHOWN
+#define BB_CHROOT
+#define BB_CLEAR
 //#define BB_CP
 //#define BB_DATE
 //#define BB_DD
@@ -19,7 +18,7 @@
 //#define BB_DMESG
 //#define BB_DUTMP
 //#define BB_DYADIC
-//#define BB_FALSE
+#define BB_FALSE
 //#define BB_FDFLUSH
 //#define BB_FIND
 //#define BB_FINDMOUNT
@@ -56,7 +55,7 @@
 //#define BB_SYNC
 //#define BB_TAR
 //#define BB_TOUCH
-//#define BB_TRUE
+#define BB_TRUE
 //#define BB_UMOUNT
 //#define BB_UPDATE
 //#define BB_UTILITY
diff --git a/cat.c b/cat.c
index 12faf55abb01ef32d3cd8fbc7b728f99cb117b36..0f2460eb7a6da6bcd62856f0dd7dca8c710d1240 100644 (file)
--- a/cat.c
+++ b/cat.c
@@ -31,7 +31,7 @@ extern int cat_more_main(int argc, char **argv)
 
     if (argc < 2) {
        fprintf(stderr, "Usage: %s %s", *argv, cat_usage);
-       return 1;
+       return(FALSE);
     }
     argc--;
     argv++;
@@ -39,8 +39,8 @@ extern int cat_more_main(int argc, char **argv)
     while (argc-- > 0) {
        file = fopen(*argv, "r");
        if (file == NULL) {
-           name_and_error(*argv);
-           return 1;
+           perror(*argv);
+           return(FALSE);
        }
        while ((c = getc(file)) != EOF)
            putc(c, stdout);
@@ -50,5 +50,5 @@ extern int cat_more_main(int argc, char **argv)
        argc--;
        argv++;
     }
-    return 0;
+    return(TRUE);
 }
diff --git a/chgrp.c b/chgrp.c
deleted file mode 100644 (file)
index 038c665..0000000
--- a/chgrp.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Mini chgrp implementation for busybox
- *
- * Copyright (C) 1998 by Erik Andersen <andersee@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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "internal.h"
-#include <grp.h>
-#include <stdio.h>
-
-const char chgrp_usage[] = "chgrp [OPTION]... GROUP FILE...\n"
-    "Change the group membership of each FILE to GROUP.\n"
-    "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n";
-
-int chgrp_main(int argc, char **argv)
-{
-    const char *cp;
-    int gid;
-    struct group *grp;
-    struct stat statBuf;
-
-    if (argc < 2) {
-       fprintf(stderr, "Usage: %s %s", *argv, chgrp_usage);
-       return 1;
-    }
-    argc--;
-    argv++;
-
-    cp = argv[1];
-    if (isDecimal(*cp)) {
-       gid = 0;
-       while (isDecimal(*cp))
-           gid = gid * 10 + (*cp++ - '0');
-       if (*cp) {
-           fprintf(stderr, "Bad gid value\n");
-           return -1;
-       }
-    } else {
-       grp = getgrnam(cp);
-       if (grp == NULL) {
-           fprintf(stderr, "Unknown group name\n");
-           return -1;
-       }
-       gid = grp->gr_gid;
-    }
-    argc--;
-    argv++;
-    while (argc-- > 1) {
-       argv++;
-       if ((stat(*argv, &statBuf) < 0) ||
-           (chown(*argv, statBuf.st_uid, gid) < 0)) {
-           perror(*argv);
-       }
-    }
-    return 1;
-}
-
-
-
-
-
-
-
-
-
-#if 0
-int
-recursive(const char *fileName, BOOL followLinks, const char *pattern,
-         int (*fileAction) (const char *fileName,
-                            const struct stat * statbuf),
-         int (*dirAction) (const char *fileName,
-                           const struct stat * statbuf))
-
-#endif
diff --git a/chown.c b/chown.c
index a611f92f1863961a61ec017311465954e59c3ed5..fc0c2424fd0dc369a141a4ea0870c4987eb49c8c 100644 (file)
--- a/chown.c
+++ b/chown.c
-#include "internal.h"
-#include <pwd.h>
-#include <grp.h>
-#include <string.h>
+/*
+ * Mini chown/chgrp implementation for busybox
+ *
+ * Copyright (C) 1998 by Erik Andersen <andersee@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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
 #include <stdio.h>
+#include <grp.h>
+#include <pwd.h>
+#include "internal.h"
 
-const char     chown_usage[] = "chown [-R] user-name file [file ...]\n"
-"\n\tThe group list is kept in the file /etc/groups.\n\n"
-"\t-R:\tRecursively change the mode of all files and directories\n"
-"\t\tunder the argument directory.";
 
-int
-parse_user_name(const char * s, struct FileInfo * i)
-{
-       struct  passwd *        p;
-       char *                          dot = strchr(s, '.');
+static int uid=-1;
+static int gid=0;
+static int chownApp;
+static char* invocationName=NULL;
 
-       if (! dot )
-               dot = strchr(s, ':');
 
-       if ( dot )
-               *dot = '\0';
+const char chgrp_usage[] = "[OPTION]... GROUP FILE...\n"
+    "Change the group membership of each FILE to GROUP.\n"
+    "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n";
+const char chown_usage[] = "[OPTION]...  OWNER[.[GROUP] FILE...\n"
+    "Change the owner and/or group of each FILE to OWNER and/or GROUP.\n"
+    "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n";
 
-       if ( (p = getpwnam(s)) == 0 ) {
-               fprintf(stderr, "%s: no such user.\n", s);
-               return 1;
-       }
-       i->userID = p->pw_uid;
-
-       if ( dot ) {
-               struct group *  g = getgrnam(++dot);
-               if ( g == 0 ) {
-                       fprintf(stderr, "%s: no such group.\n", dot);
-                       return 1;
-               }
-               i->groupID = g->gr_gid;
-               i->changeGroupID = 1;
-       }
-       return 0;
+
+
+static int fileAction(const char *fileName)
+{
+    struct stat statBuf;
+    if ((stat(fileName, &statBuf) < 0) || 
+           (chown(fileName, 
+                  ((chownApp==TRUE)? uid: statBuf.st_uid), 
+                  gid) < 0)) { 
+       perror(fileName);
+       return( TRUE);
+    }
+    return( FALSE);
 }
 
-extern int
-chown_main(struct FileInfo * i, int argc, char * * argv)
+int chown_main(int argc, char **argv)
 {
-       int                                     status;
+    struct group *grp;
+    struct passwd *pwd;
+    int recursiveFlag=FALSE;
+    char *groupName;
 
-       while ( argc >= 3 && strcmp("-R", argv[1]) == 0 ) {
-               i->recursive = 1;
-               argc--;
-               argv++;
-       }
 
-       if ( (status = parse_user_name(argv[1], i)) != 0 )
-               return status;
+    chownApp = (strcmp(*argv, "chown")==0)? TRUE : FALSE;
 
-       argv++;
+    if (argc < 2) {
+       fprintf(stderr, "Usage: %s %s", *argv, 
+               (chownApp==TRUE)? chown_usage : chgrp_usage);
+       return( FALSE);
+    }
+    invocationName=*argv;
+    argc--;
+    argv++;
+
+    /* Parse options */
+    while (**argv == '-') {
+       while (*++(*argv)) switch (**argv) {
+           case 'R':
+               recursiveFlag = TRUE;
+               break;
+           default:
+               fprintf(stderr, "Unknown option: %c\n", **argv);
+               return( FALSE);
+       }
        argc--;
+       argv++;
+    }
+    
+    /* Find the selected group */
+    groupName = strchr(*argv, '.');
+    if ( chownApp==TRUE && groupName )
+       *groupName++ = '\0';
+    else
+       groupName = *argv;
+    grp = getgrnam(groupName);
+    if (grp == NULL) {
+       fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName);
+       return( FALSE);
+    }
+    gid = grp->gr_gid;
 
-       i->changeUserID = 1;
-       i->complainInPostProcess = 1;
+    /* Find the selected user (if appropriate)  */
+    if (chownApp==TRUE) {
+       pwd = getpwnam(*argv);
+       if (pwd == NULL) {
+           fprintf(stderr, "%s: Unknown user name: %s\n", invocationName, *argv);
+           return( FALSE);
+       }
+       uid = pwd->pw_uid;
+    }
 
-       return monadic_main(i, argc, argv);
+    /* Ok, ready to do the deed now */
+    if (argc <= 1) {
+       fprintf(stderr, "%s: too few arguments", invocationName);
+       return( FALSE);
+    }
+    while (argc-- > 1) {
+       argv++;
+       if (recursiveFlag==TRUE) 
+           recursiveAction( *argv, TRUE, fileAction, fileAction);
+       else
+           fileAction( *argv);
+    }
+    return(TRUE);
 }
index ca0bfcf3fbc6c58a3506b5c2f36b8049f1273b83..d39549496542978484a089ad02e91c7ac404b254 100644 (file)
--- a/chroot.c
+++ b/chroot.c
@@ -1,32 +1,65 @@
+/*
+ * Mini chroot implementation for busybox
+ *
+ * Copyright (C) 1998 by Erik Andersen <andersee@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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
 #include "internal.h"
 #include <stdio.h>
 #include <unistd.h>
 
 
-const char chroot_usage[] = "chroot directory [command]\n"
-  "Run a command with special root directory.\n";
+static const char chroot_usage[] = "NEWROOT [COMMAND...]\n"
+"Run COMMAND with root directory set to NEWROOT.\n";
+
+
 
-extern int
-chroot_main (struct FileInfo *i, int argc, char **argv)
+int chroot_main(int argc, char **argv)
 {
-  char *prog;
+    if (argc < 2) {
+       fprintf(stderr, "Usage: %s %s", *argv, chroot_usage);
+       return( FALSE);
+    }
+    argc--;
+    argv++;
 
-  if (chroot (argv[1]))
-    {
-      name_and_error ("cannot chroot to that directory");
-      return 1;
+    fprintf(stderr, "new root: %s\n", *argv);
+    
+    if (chroot (*argv) || (chdir ("/"))) {
+       perror("cannot chroot");
+       return( FALSE);
     }
-  if (argc > 2)
-    {
-      execvp (argv[2], argv + 2);
+
+    argc--;
+    argv++;
+    if (argc >= 1) {
+       fprintf(stderr, "command: %s\n", *argv);
+       execvp (*argv, argv);
     }
-  else
-    {
-      prog = getenv ("SHELL");
-      if (!prog)
-       prog = "/bin/sh";
-      execlp (prog, prog, NULL);
+    else {
+       char *prog;
+       prog = getenv ("SHELL");
+       if (!prog)
+           prog = "/bin/sh";
+       fprintf(stderr, "no command. running: %s\n", prog);
+       execlp (prog, prog, NULL);
     }
-  name_and_error ("cannot exec");
-  return 1;
+    perror("cannot exec");
+    return(FALSE);
 }
+
diff --git a/clear.c b/clear.c
index 21a890c9e3762889b8533bb67a53d2fe9979785f..c0c94d06e5f1b88e12633cf1e281bf1511ae1f2b 100644 (file)
--- a/clear.c
+++ b/clear.c
@@ -1,12 +1,30 @@
+/*
+ * Mini clear implementation for busybox
+ *
+ * Copyright (C) 1998 by Erik Andersen <andersee@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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
 #include "internal.h"
 #include <stdio.h>
 
-const char     clear_usage[] = "clear\n"
-"\n"
-"\tClears the screen.\n";
 
 extern int
-clear_main(struct FileInfo * i, int argc, char * * argv)
+clear_main(int argc, char** argv)
 {
        printf("\033[H\033[J");
        return 0;
index 21a890c9e3762889b8533bb67a53d2fe9979785f..c0c94d06e5f1b88e12633cf1e281bf1511ae1f2b 100644 (file)
@@ -1,12 +1,30 @@
+/*
+ * Mini clear implementation for busybox
+ *
+ * Copyright (C) 1998 by Erik Andersen <andersee@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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
 #include "internal.h"
 #include <stdio.h>
 
-const char     clear_usage[] = "clear\n"
-"\n"
-"\tClears the screen.\n";
 
 extern int
-clear_main(struct FileInfo * i, int argc, char * * argv)
+clear_main(int argc, char** argv)
 {
        printf("\033[H\033[J");
        return 0;
index 12faf55abb01ef32d3cd8fbc7b728f99cb117b36..0f2460eb7a6da6bcd62856f0dd7dca8c710d1240 100644 (file)
@@ -31,7 +31,7 @@ extern int cat_more_main(int argc, char **argv)
 
     if (argc < 2) {
        fprintf(stderr, "Usage: %s %s", *argv, cat_usage);
-       return 1;
+       return(FALSE);
     }
     argc--;
     argv++;
@@ -39,8 +39,8 @@ extern int cat_more_main(int argc, char **argv)
     while (argc-- > 0) {
        file = fopen(*argv, "r");
        if (file == NULL) {
-           name_and_error(*argv);
-           return 1;
+           perror(*argv);
+           return(FALSE);
        }
        while ((c = getc(file)) != EOF)
            putc(c, stdout);
@@ -50,5 +50,5 @@ extern int cat_more_main(int argc, char **argv)
        argc--;
        argv++;
     }
-    return 0;
+    return(TRUE);
 }
diff --git a/coreutils/chgrp.c b/coreutils/chgrp.c
deleted file mode 100644 (file)
index 038c665..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Mini chgrp implementation for busybox
- *
- * Copyright (C) 1998 by Erik Andersen <andersee@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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "internal.h"
-#include <grp.h>
-#include <stdio.h>
-
-const char chgrp_usage[] = "chgrp [OPTION]... GROUP FILE...\n"
-    "Change the group membership of each FILE to GROUP.\n"
-    "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n";
-
-int chgrp_main(int argc, char **argv)
-{
-    const char *cp;
-    int gid;
-    struct group *grp;
-    struct stat statBuf;
-
-    if (argc < 2) {
-       fprintf(stderr, "Usage: %s %s", *argv, chgrp_usage);
-       return 1;
-    }
-    argc--;
-    argv++;
-
-    cp = argv[1];
-    if (isDecimal(*cp)) {
-       gid = 0;
-       while (isDecimal(*cp))
-           gid = gid * 10 + (*cp++ - '0');
-       if (*cp) {
-           fprintf(stderr, "Bad gid value\n");
-           return -1;
-       }
-    } else {
-       grp = getgrnam(cp);
-       if (grp == NULL) {
-           fprintf(stderr, "Unknown group name\n");
-           return -1;
-       }
-       gid = grp->gr_gid;
-    }
-    argc--;
-    argv++;
-    while (argc-- > 1) {
-       argv++;
-       if ((stat(*argv, &statBuf) < 0) ||
-           (chown(*argv, statBuf.st_uid, gid) < 0)) {
-           perror(*argv);
-       }
-    }
-    return 1;
-}
-
-
-
-
-
-
-
-
-
-#if 0
-int
-recursive(const char *fileName, BOOL followLinks, const char *pattern,
-         int (*fileAction) (const char *fileName,
-                            const struct stat * statbuf),
-         int (*dirAction) (const char *fileName,
-                           const struct stat * statbuf))
-
-#endif
index a611f92f1863961a61ec017311465954e59c3ed5..fc0c2424fd0dc369a141a4ea0870c4987eb49c8c 100644 (file)
-#include "internal.h"
-#include <pwd.h>
-#include <grp.h>
-#include <string.h>
+/*
+ * Mini chown/chgrp implementation for busybox
+ *
+ * Copyright (C) 1998 by Erik Andersen <andersee@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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
 #include <stdio.h>
+#include <grp.h>
+#include <pwd.h>
+#include "internal.h"
 
-const char     chown_usage[] = "chown [-R] user-name file [file ...]\n"
-"\n\tThe group list is kept in the file /etc/groups.\n\n"
-"\t-R:\tRecursively change the mode of all files and directories\n"
-"\t\tunder the argument directory.";
 
-int
-parse_user_name(const char * s, struct FileInfo * i)
-{
-       struct  passwd *        p;
-       char *                          dot = strchr(s, '.');
+static int uid=-1;
+static int gid=0;
+static int chownApp;
+static char* invocationName=NULL;
 
-       if (! dot )
-               dot = strchr(s, ':');
 
-       if ( dot )
-               *dot = '\0';
+const char chgrp_usage[] = "[OPTION]... GROUP FILE...\n"
+    "Change the group membership of each FILE to GROUP.\n"
+    "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n";
+const char chown_usage[] = "[OPTION]...  OWNER[.[GROUP] FILE...\n"
+    "Change the owner and/or group of each FILE to OWNER and/or GROUP.\n"
+    "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n";
 
-       if ( (p = getpwnam(s)) == 0 ) {
-               fprintf(stderr, "%s: no such user.\n", s);
-               return 1;
-       }
-       i->userID = p->pw_uid;
-
-       if ( dot ) {
-               struct group *  g = getgrnam(++dot);
-               if ( g == 0 ) {
-                       fprintf(stderr, "%s: no such group.\n", dot);
-                       return 1;
-               }
-               i->groupID = g->gr_gid;
-               i->changeGroupID = 1;
-       }
-       return 0;
+
+
+static int fileAction(const char *fileName)
+{
+    struct stat statBuf;
+    if ((stat(fileName, &statBuf) < 0) || 
+           (chown(fileName, 
+                  ((chownApp==TRUE)? uid: statBuf.st_uid), 
+                  gid) < 0)) { 
+       perror(fileName);
+       return( TRUE);
+    }
+    return( FALSE);
 }
 
-extern int
-chown_main(struct FileInfo * i, int argc, char * * argv)
+int chown_main(int argc, char **argv)
 {
-       int                                     status;
+    struct group *grp;
+    struct passwd *pwd;
+    int recursiveFlag=FALSE;
+    char *groupName;
 
-       while ( argc >= 3 && strcmp("-R", argv[1]) == 0 ) {
-               i->recursive = 1;
-               argc--;
-               argv++;
-       }
 
-       if ( (status = parse_user_name(argv[1], i)) != 0 )
-               return status;
+    chownApp = (strcmp(*argv, "chown")==0)? TRUE : FALSE;
 
-       argv++;
+    if (argc < 2) {
+       fprintf(stderr, "Usage: %s %s", *argv, 
+               (chownApp==TRUE)? chown_usage : chgrp_usage);
+       return( FALSE);
+    }
+    invocationName=*argv;
+    argc--;
+    argv++;
+
+    /* Parse options */
+    while (**argv == '-') {
+       while (*++(*argv)) switch (**argv) {
+           case 'R':
+               recursiveFlag = TRUE;
+               break;
+           default:
+               fprintf(stderr, "Unknown option: %c\n", **argv);
+               return( FALSE);
+       }
        argc--;
+       argv++;
+    }
+    
+    /* Find the selected group */
+    groupName = strchr(*argv, '.');
+    if ( chownApp==TRUE && groupName )
+       *groupName++ = '\0';
+    else
+       groupName = *argv;
+    grp = getgrnam(groupName);
+    if (grp == NULL) {
+       fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName);
+       return( FALSE);
+    }
+    gid = grp->gr_gid;
 
-       i->changeUserID = 1;
-       i->complainInPostProcess = 1;
+    /* Find the selected user (if appropriate)  */
+    if (chownApp==TRUE) {
+       pwd = getpwnam(*argv);
+       if (pwd == NULL) {
+           fprintf(stderr, "%s: Unknown user name: %s\n", invocationName, *argv);
+           return( FALSE);
+       }
+       uid = pwd->pw_uid;
+    }
 
-       return monadic_main(i, argc, argv);
+    /* Ok, ready to do the deed now */
+    if (argc <= 1) {
+       fprintf(stderr, "%s: too few arguments", invocationName);
+       return( FALSE);
+    }
+    while (argc-- > 1) {
+       argv++;
+       if (recursiveFlag==TRUE) 
+           recursiveAction( *argv, TRUE, fileAction, fileAction);
+       else
+           fileAction( *argv);
+    }
+    return(TRUE);
 }
index ca0bfcf3fbc6c58a3506b5c2f36b8049f1273b83..d39549496542978484a089ad02e91c7ac404b254 100644 (file)
@@ -1,32 +1,65 @@
+/*
+ * Mini chroot implementation for busybox
+ *
+ * Copyright (C) 1998 by Erik Andersen <andersee@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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
 #include "internal.h"
 #include <stdio.h>
 #include <unistd.h>
 
 
-const char chroot_usage[] = "chroot directory [command]\n"
-  "Run a command with special root directory.\n";
+static const char chroot_usage[] = "NEWROOT [COMMAND...]\n"
+"Run COMMAND with root directory set to NEWROOT.\n";
+
+
 
-extern int
-chroot_main (struct FileInfo *i, int argc, char **argv)
+int chroot_main(int argc, char **argv)
 {
-  char *prog;
+    if (argc < 2) {
+       fprintf(stderr, "Usage: %s %s", *argv, chroot_usage);
+       return( FALSE);
+    }
+    argc--;
+    argv++;
 
-  if (chroot (argv[1]))
-    {
-      name_and_error ("cannot chroot to that directory");
-      return 1;
+    fprintf(stderr, "new root: %s\n", *argv);
+    
+    if (chroot (*argv) || (chdir ("/"))) {
+       perror("cannot chroot");
+       return( FALSE);
     }
-  if (argc > 2)
-    {
-      execvp (argv[2], argv + 2);
+
+    argc--;
+    argv++;
+    if (argc >= 1) {
+       fprintf(stderr, "command: %s\n", *argv);
+       execvp (*argv, argv);
     }
-  else
-    {
-      prog = getenv ("SHELL");
-      if (!prog)
-       prog = "/bin/sh";
-      execlp (prog, prog, NULL);
+    else {
+       char *prog;
+       prog = getenv ("SHELL");
+       if (!prog)
+           prog = "/bin/sh";
+       fprintf(stderr, "no command. running: %s\n", prog);
+       execlp (prog, prog, NULL);
     }
-  name_and_error ("cannot exec");
-  return 1;
+    perror("cannot exec");
+    return(FALSE);
 }
+
index e658d3b7db3866c7cf2897c4777be9e0d2ad7d3c..75e5503cfd170c3d12254b24aa484eadf253ff83 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * Busybox main header file
+ *
+ * Copyright (C) 1998 by Erik Andersen <andersee@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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based in part on code from sash, Copyright (c) 1999 by David I. Bell 
+ * Permission has been granted to redistribute this code under the GPL.
+ *
+ */
 #ifndef        _INTERNAL_H_
 #define        _INTERNAL_H_
 
@@ -13,8 +36,8 @@
 typedef int     BOOL;
 #define STDIN  0
 #define STDOUT 1
-#define FALSE   ((BOOL) 0)
-#define TRUE    ((BOOL) 1)
+#define FALSE   ((BOOL) 1)
+#define TRUE    ((BOOL) 0)
 
 #define PATH_LEN        1024
 #define BUF_SIZE        8192
@@ -129,60 +152,36 @@ parse_mode(
 
 extern int             parse_user_name(const char* string, struct FileInfo * i);
 
-extern const char      block_device_usage[];
-extern const char      chgrp_usage[];
-extern const char      chmod_usage[];
-extern const char      chown_usage[];
-extern const char      chroot_usage[];
-extern const char      clear_usage[];
-extern const char      cp_usage[];
-extern const char      date_usage[];
-extern const char      dd_usage[];
-extern const char      df_usage[];
-extern const char      dmesg_usage[];
-extern const char      dutmp_usage[];
-extern const char      false_usage[];
-extern const char      fdflush_usage[];
-extern const char      find_usage[];
-extern const char      grep_usage[];
-extern const char      halt_usage[];
-extern const char      init_usage[];
-extern const char      kill_usage[];
-extern const char      length_usage[];
-extern const char      ln_usage[];
-extern const char      loadkmap_usage[];
-extern const char      losetup_usage[];
-extern const char      ls_usage[];
-extern const char      math_usage[];
-extern const char      makedevs_usage[];
-extern const char      mkdir_usage[];
-extern const char      mknod_usage[];
-extern const char      mkswap_usage[];
-extern const char      mnc_usage[];
-extern const char      more_usage[];
-extern const char      mount_usage[];
-extern const char      mt_usage[];
-extern const char      mv_usage[];
-extern const char      printf_usage[];
-extern const char      pwd_usage[];
-extern const char      reboot_usage[];
-extern const char      rm_usage[];
-extern const char      rmdir_usage[];
-extern const char      scan_partitions_usage[];
-extern const char      sleep_usage[];
-extern const char      tar_usage[];
-extern const char      swapoff_usage[];
-extern const char      swapon_usage[];
-extern const char      sync_usage[];
-extern const char      touch_usage[];
-extern const char      tput_usage[];
-extern const char      true_usage[];
-extern const char      tryopen_usage[];
-extern const char      umount_usage[];
-extern const char      update_usage[];
-extern const char      zcat_usage[];
-extern const char      gzip_usage[];
 
+/*
+ * A chunk of data.
+ * Chunks contain data which is allocated as needed, but which is
+ * not freed until all of the data needs freeing, such as at
+ * the beginning of the next command.
+ */
+typedef struct chunk CHUNK;
+#define CHUNK_INIT_SIZE 4
+
+struct chunk {
+    CHUNK *next;
+    char data[CHUNK_INIT_SIZE];        /* actually of varying length */
+};
+
+const char *modeString(int mode);
+const char *timeString(time_t timeVal);
+BOOL isDirectory(const char *name);
+BOOL isDevice(const char *name);
+BOOL copyFile(const char *srcName, const char *destName, BOOL setModes);
+const char *buildName(const char *dirName, const char *fileName);
+BOOL makeString(int argc, const char **argv, char *buf, int bufLen);
+char *getChunk(int size);
+char *chunkstrdup(const char *str);
+void freeChunks(void);
+int fullWrite(int fd, const char *buf, int len);
+int fullRead(int fd, char *buf, int len);
+int recursiveAction(const char *fileName, BOOL followLinks,
+         int (*fileAction) (const char *fileName),
+         int (*dirAction) (const char *fileName));
 
 
 #endif
index 68259710b641c9972dc8f93bf2dfe7e05070456d..a516355b61a8067f54cac5350d72fe7807e06278 100644 (file)
--- a/utility.c
+++ b/utility.c
  *
  */
 
-#include "utility.h"
+#include "internal.h"
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+//#include <sys/types.h>
+//#include <sys/stat.h>
+#include <dirent.h>
+#include <time.h>
+#include <utime.h>
 
 #if 0
 
@@ -54,13 +63,6 @@ join_paths(char * buffer, const char * a, const char * b)
 
 static CHUNK * chunkList;
 
-extern void
-name_and_error(const char * name)
-{
-       fprintf(stderr, "%s: %s\n", name, strerror(errno));
-}
-
-
 
 /*
  * Return the standard ls-like mode string from a file mode.
@@ -129,36 +131,6 @@ modeString(int mode)
 }
 
 
-/*
- * Get the time string to be used for a file.
- * This is down to the minute for new files, but only the date for old files.
- * The string is returned from a static buffer, and so is overwritten for
- * each call.
- */
-const char *
-timeString(time_t timeVal)
-{
-       time_t          now;
-       char *          str;
-       static  char    buf[26];
-
-       time(&now);
-
-       str = ctime(&timeVal);
-
-       strcpy(buf, &str[4]);
-       buf[12] = '\0';
-
-       if ((timeVal > now) || (timeVal < now - 365*24*60*60L))
-       {
-               strcpy(&buf[7], &str[20]);
-               buf[11] = '\0';
-       }
-
-       return buf;
-}
-
-
 /*
  * Return TRUE if a fileName is a directory.
  * Nonexistant files return FALSE.
@@ -324,624 +296,6 @@ buildName(const char * dirName, const char * fileName)
 
 
 
-/*
- * Expand the wildcards in a fileName wildcard pattern, if any.
- * Returns an argument list with matching fileNames in sorted order.
- * The expanded names are stored in memory chunks which can later all
- * be freed at once.  The returned list is only valid until the next
- * call or until the next command.  Returns zero if the name is not a
- * wildcard, or returns the count of matched files if the name is a
- * wildcard and there was at least one match, or returns -1 if either
- * no fileNames matched or there was an allocation error.
- */
-int
-expandWildCards(const char * fileNamePattern, const char *** retFileTable)
-{
-       const char *    last;
-       const char *    cp1;
-       const char *    cp2;
-       const char *    cp3;
-       char *          str;
-       DIR *           dirp;
-       struct dirent * dp;
-       int             dirLen;
-       int             newFileTableSize;
-       char **         newFileTable;
-       char            dirName[PATH_LEN];
-
-       static int      fileCount;
-       static int      fileTableSize;
-       static char **  fileTable;
-
-       /*
-        * Clear the return values until we know their final values.
-        */
-       fileCount = 0;
-       *retFileTable = NULL;
-
-       /*
-        * Scan the file name pattern for any wildcard characters.
-        */
-       cp1 = strchr(fileNamePattern, '*');
-       cp2 = strchr(fileNamePattern, '?');
-       cp3 = strchr(fileNamePattern, '[');
-
-       /*
-        * If there are no wildcard characters then return zero to
-        * indicate that there was actually no wildcard pattern.
-        */
-       if ((cp1 == NULL) && (cp2 == NULL) && (cp3 == NULL))
-               return 0;
-
-       /*
-        * There are wildcards in the specified filename.
-        * Get the last component of the file name.
-        */
-       last = strrchr(fileNamePattern, '/');
-
-       if (last)
-               last++;
-       else
-               last = fileNamePattern;
-
-       /*
-        * If any wildcards were found before the last filename component
-        * then return an error.
-        */
-       if ((cp1 && (cp1 < last)) || (cp2 && (cp2 < last)) ||
-               (cp3 && (cp3 < last)))
-       {
-               fprintf(stderr,
-               "Wildcards only implemented for last file name component\n");
-
-               return -1;
-       }
-
-       /*
-        * Assume at first that we are scanning the current directory.
-        */
-       dirName[0] = '.';
-       dirName[1] = '\0';
-
-       /*
-        * If there was a directory given as part of the file name then
-        * copy it and null terminate it.
-        */
-       if (last != fileNamePattern)
-       {
-               memcpy(dirName, fileNamePattern, last - fileNamePattern);
-               dirName[last - fileNamePattern - 1] = '\0';
-
-               if (dirName[0] == '\0')
-               {
-                       dirName[0] = '/';
-                       dirName[1] = '\0';
-               }
-       }
-
-       /*
-        * Open the directory containing the files to be checked.
-        */
-       dirp = opendir(dirName);
-
-       if (dirp == NULL)
-       {
-               perror(dirName);
-
-               return -1;
-       }
-
-       /*
-        * Prepare the directory name for use in making full path names.
-        */
-       dirLen = strlen(dirName);
-
-       if (last == fileNamePattern)
-       {
-               dirLen = 0;
-               dirName[0] = '\0';
-       }
-       else if (dirName[dirLen - 1] != '/')
-       {
-               dirName[dirLen++] = '/';
-               dirName[dirLen] = '\0';
-       }
-
-       /*
-        * Find all of the files in the directory and check them against
-        * the wildcard pattern.
-        */
-       while ((dp = readdir(dirp)) != NULL)
-       {
-               /*
-                * Skip the current and parent directories.
-                */
-               if ((strcmp(dp->d_name, ".") == 0) ||
-                       (strcmp(dp->d_name, "..") == 0))
-               {
-                       continue;
-               }
-
-               /*
-                * If the file name doesn't match the pattern then skip it.
-                */
-               if (!match(dp->d_name, last))
-                       continue;
-
-               /*
-                * This file name is selected.
-                * See if we need to reallocate the file name table.
-                */
-               if (fileCount >= fileTableSize)
-               {
-                       /*
-                        * Increment the file table size and reallocate it.
-                        */
-                       newFileTableSize = fileTableSize + EXPAND_ALLOC;
-
-                       newFileTable = (char **) realloc((char *) fileTable,
-                               (newFileTableSize * sizeof(char *)));
-
-                       if (newFileTable == NULL)
-                       {
-                               fprintf(stderr, "Cannot allocate file list\n");
-                               closedir(dirp);
-
-                               return -1;
-                       }
-
-                       fileTable = newFileTable;
-                       fileTableSize = newFileTableSize;
-               }
-
-               /*
-                * Allocate space for storing the file name in a chunk.
-                */
-               str = getChunk(dirLen + strlen(dp->d_name) + 1);
-
-               if (str == NULL)
-               {
-                       fprintf(stderr, "No memory for file name\n");
-                       closedir(dirp);
-
-                       return -1;
-               }
-
-               /*
-                * Save the file name in the chunk.
-                */
-               if (dirLen)
-                       memcpy(str, dirName, dirLen);
-
-               strcpy(str + dirLen, dp->d_name);
-
-               /*
-                * Save the allocated file name into the file table.
-                */
-               fileTable[fileCount++] = str;
-       }
-
-       /*
-        * Close the directory and check for any matches.
-        */
-       closedir(dirp);
-
-       if (fileCount == 0)
-       {
-               fprintf(stderr, "No matches\n");
-
-               return -1;
-       }
-
-       /*
-        * Sort the list of file names.
-        */
-       qsort((void *) fileTable, fileCount, sizeof(char *), nameSort);
-
-       /*
-        * Return the file list and count.
-        */
-       *retFileTable = (const char **) fileTable;
-
-       return fileCount;
-}
-
-
-/*
- * Sort routine for list of fileNames.
- */
-int
-nameSort(const void * p1, const void * p2)
-{
-       const char **   s1;
-       const char **   s2;
-
-       s1 = (const char **) p1;
-       s2 = (const char **) p2;
-
-       return strcmp(*s1, *s2);
-}
-
-
-
-/*
- * Routine to see if a text string is matched by a wildcard pattern.
- * Returns TRUE if the text is matched, or FALSE if it is not matched
- * or if the pattern is invalid.
- *  *          matches zero or more characters
- *  ?          matches a single character
- *  [abc]      matches 'a', 'b' or 'c'
- *  \c         quotes character c
- *  Adapted from code written by Ingo Wilken.
- */
-BOOL
-match(const char * text, const char * pattern)
-{
-       const char *    retryPat;
-       const char *    retryText;
-       int             ch;
-       BOOL            found;
-
-       retryPat = NULL;
-       retryText = NULL;
-
-       while (*text || *pattern)
-       {
-               ch = *pattern++;
-
-               switch (ch)
-               {
-                       case '*':  
-                               retryPat = pattern;
-                               retryText = text;
-                               break;
-
-                       case '[':  
-                               found = FALSE;
-
-                               while ((ch = *pattern++) != ']')
-                               {
-                                       if (ch == '\\')
-                                               ch = *pattern++;
-
-                                       if (ch == '\0')
-                                               return FALSE;
-
-                                       if (*text == ch)
-                                               found = TRUE;
-                               }
-
-                               if (!found)
-                               {
-                                       pattern = retryPat;
-                                       text = ++retryText;
-                               }
-
-                               /* fall into next case */
-
-                       case '?':  
-                               if (*text++ == '\0')
-                                       return FALSE;
-
-                               break;
-
-                       case '\\':  
-                               ch = *pattern++;
-
-                               if (ch == '\0')
-                                       return FALSE;
-
-                               /* fall into next case */
-
-                       default:        
-                               if (*text == ch)
-                               {
-                                       if (*text)
-                                               text++;
-                                       break;
-                               }
-
-                               if (*text)
-                               {
-                                       pattern = retryPat;
-                                       text = ++retryText;
-                                       break;
-                               }
-
-                               return FALSE;
-               }
-
-               if (pattern == NULL)
-                       return FALSE;
-       }
-
-       return TRUE;
-}
-
-
-/*
- * Take a command string and break it up into an argc, argv list while
- * handling quoting and wildcards.  The returned argument list and
- * strings are in static memory, and so are overwritten on each call.
- * The argument list is ended with a NULL pointer for convenience.
- * Returns TRUE if successful, or FALSE on an error with a message
- * already output.
- */
-BOOL
-makeArgs(const char * cmd, int * retArgc, const char *** retArgv)
-{
-       const char *            argument;
-       char *                  cp;
-       char *                  cpOut;
-       char *                  newStrings;
-       const char **           fileTable;
-       const char **           newArgTable;
-       int                     newArgTableSize;
-       int                     fileCount;
-       int                     len;
-       int                     ch;
-       int                     quote;
-       BOOL                    quotedWildCards;
-       BOOL                    unquotedWildCards;
-
-       static int              stringsLength;
-       static char *           strings;
-       static int              argCount;
-       static int              argTableSize;
-       static const char **    argTable;
-
-       /*
-        * Clear the returned values until we know them.
-        */
-       argCount = 0;
-       *retArgc = 0;
-       *retArgv = NULL;
-
-       /*
-        * Copy the command string into a buffer that we can modify,
-        * reallocating it if necessary.
-        */
-       len = strlen(cmd) + 1;
-
-       if (len > stringsLength)
-       {
-               newStrings = realloc(strings, len);
-
-               if (newStrings == NULL)
-               {
-                       fprintf(stderr, "Cannot allocate string\n");
-
-                       return FALSE;
-               }
-
-               strings = newStrings;
-               stringsLength = len;
-       }
-
-       memcpy(strings, cmd, len);
-       cp = strings;
-
-       /*
-        * Keep parsing the command string as long as there are any
-        * arguments left.
-        */
-       while (*cp)
-       {
-               /*
-                * Save the beginning of this argument.
-                */
-               argument = cp;
-               cpOut = cp;
-
-               /*
-                * Reset quoting and wildcarding for this argument.
-                */
-               quote = '\0';
-               quotedWildCards = FALSE;
-               unquotedWildCards = FALSE;
-
-               /*
-                * Loop over the string collecting the next argument while
-                * looking for quoted strings or quoted characters, and
-                * remembering whether there are any wildcard characters
-                * in the argument.
-                */
-               while (*cp)
-               {
-                       ch = *cp++;
-
-                       /*
-                        * If we are not in a quote and we see a blank then
-                        * this argument is done.
-                        */
-                       if (isBlank(ch) && (quote == '\0'))
-                               break;
-
-                       /*
-                        * If we see a backslash then accept the next
-                        * character no matter what it is.
-                        */
-                       if (ch == '\\')
-                       {
-                               ch = *cp++;
-
-                               /*
-                                * Make sure there is a next character.
-                                */
-                               if (ch == '\0')
-                               {
-                                       fprintf(stderr,
-                                               "Bad quoted character\n");
-
-                                       return FALSE;
-                               }
-
-                               /*
-                                * Remember whether the quoted character
-                                * is a wildcard.
-                                */
-                               if (isWildCard(ch))
-                                       quotedWildCards = TRUE;
-
-                               *cpOut++ = ch;
-
-                               continue;
-                       }
-
-                       /*
-                        * If we see one of the wildcard characters then
-                        * remember whether it was seen inside or outside
-                        * of quotes.
-                        */
-                       if (isWildCard(ch))
-                       {
-                               if (quote)
-                                       quotedWildCards = TRUE;
-                               else
-                                       unquotedWildCards = TRUE;
-                       }
-
-                       /*
-                        * If we were in a quote and we saw the same quote
-                        * character again then the quote is done.
-                        */
-                       if (ch == quote)
-                       {
-                               quote = '\0';
-
-                               continue;
-                       }
-
-                       /*
-                        * If we weren't in a quote and we see either type
-                        * of quote character, then remember that we are
-                        * now inside of a quote.
-                        */
-                       if ((quote == '\0') && ((ch == '\'') || (ch == '"')))
-                       {
-                               quote = ch;
-
-                               continue;
-                       }
-
-                       /*
-                        * Store the character.
-                        */
-                       *cpOut++ = ch;
-               }
-
-               /*
-                * Make sure that quoting is terminated properly.
-                */
-               if (quote)
-               {
-                       fprintf(stderr, "Unmatched quote character\n");
-
-                       return FALSE;
-               }
-
-               /*
-                * Null terminate the argument if it had shrunk, and then
-                * skip over all blanks to the next argument, nulling them
-                * out too.
-                */
-               if (cp != cpOut)
-                       *cpOut = '\0';
-
-               while (isBlank(*cp))
-                       *cp++ = '\0';
-
-               /*
-                * If both quoted and unquoted wildcards were used then
-                * complain since we don't handle them properly.
-                */
-               if (quotedWildCards && unquotedWildCards)
-               {
-                       fprintf(stderr,
-                               "Cannot use quoted and unquoted wildcards\n");
-
-                       return FALSE;
-               }
-
-               /*
-                * Expand the argument into the matching filenames or accept
-                * it as is depending on whether there were any unquoted
-                * wildcard characters in it.
-                */
-               if (unquotedWildCards)
-               {
-                       /*
-                        * Expand the argument into the matching filenames.
-                        */
-                       fileCount = expandWildCards(argument, &fileTable);
-
-                       /*
-                        * Return an error if the wildcards failed to match.
-                        */
-                       if (fileCount < 0)
-                               return FALSE;
-
-                       if (fileCount == 0)
-                       {
-                               fprintf(stderr, "Wildcard expansion error\n");
-
-                               return FALSE;
-                       }
-               }
-               else
-               {
-                       /*
-                        * Set up to only store the argument itself.
-                        */
-                       fileTable = &argument;
-                       fileCount = 1;
-               }
-
-               /*
-                * Now reallocate the argument table to hold the file name.
-                */
-               if (argCount + fileCount >= argTableSize)
-               {
-                       newArgTableSize = argCount + fileCount + 1;
-
-                       newArgTable = (const char **) realloc(argTable,
-                               (sizeof(const char *) * newArgTableSize));
-
-                       if (newArgTable == NULL)
-                       {
-                               fprintf(stderr, "No memory for arg list\n");
-
-                               return FALSE;
-                       }
-
-                       argTable = newArgTable;
-                       argTableSize = newArgTableSize;
-               }
-
-               /*
-                * Copy the new arguments to the end of the old ones.
-                */
-               memcpy((void *) &argTable[argCount], (const void *) fileTable,
-                       (sizeof(const char **) * fileCount));
-
-               /*
-                * Add to the argument count.
-                */
-               argCount += fileCount;
-       }
-
-       /*
-        * Null terminate the argument list and return it.
-        */
-       argTable[argCount] = NULL;
-
-       *retArgc = argCount;
-       *retArgv = argTable;
-
-       return TRUE;
-}
-
-
 /*
  * Make a NULL-terminated string out of an argc, argv pair.
  * Returns TRUE if successful, or FALSE if the string is too long,
@@ -1114,15 +468,14 @@ fullRead(int fd, char * buf, int len)
 
 
 /*
- * Read all of the supplied buffer from a file.
- * This does multiple reads as necessary.
- * Returns the amount read, or -1 on an error.
- * A short read is returned on an end of file.
+ * Walk down all the directories under the specified 
+ * location, and do something (something specified
+ * by the fileAction and dirAction function pointers).
  */
 int
-recursive( const char *fileName, BOOL followLinks, const char* pattern, 
-       int (*fileAction)(const char* fileName, const struct stat* statbuf), 
-       int (*dirAction)(const char* fileName, const struct stat* statbuf))
+recursiveAction( const char *fileName, BOOL followLinks,
+       int (*fileAction)(const char* fileName), 
+       int (*dirAction)(const char* fileName))
 {
     int             status;
     struct stat     statbuf;
@@ -1135,45 +488,44 @@ recursive( const char *fileName, BOOL followLinks, const char* pattern,
 
     if (status < 0) {
        perror(fileName);
-       return( -1);
+       return( FALSE);
     }
 
-    if (S_ISREG(statbuf.st_mode)) {
-       if (match(fileName, pattern)) {
-           if (fileAction==NULL)
-               fprintf( stdout, "%s\n", fileName);
-           else
-               return(fileAction(fileName, &statbuf));
+    if (S_ISDIR(statbuf.st_mode)) {
+       DIR *dir;
+       dir = opendir(fileName);
+       if (!dir) {
+           perror(fileName);
+           return(FALSE);
        }
-    }
-    else if (S_ISDIR(statbuf.st_mode)) {
-       if (dirAction==NULL) {
-           DIR *dir;
-           if (! match(fileName, pattern))
-               return 1;
-           dir = opendir(fileName);
-           if (!dir) {
-               perror(fileName);
-               return( -1);
-           }
-           while ((next = readdir (dir)) != NULL) {
-                   status = recursive(fileName, followLinks, pattern, fileAction, dirAction);
-                   if (status < 0) {
-                       closedir(dir);
-                       return(status);
-                   }
-           }
-           status = closedir (dir);
-           if (status < 0) {
-               perror(fileName);
-               return( -1);
-           }
+       while ((next = readdir (dir)) != NULL) {
+               char nextFile[NAME_MAX];
+               if ( (strcmp(next->d_name, "..") == 0) || (strcmp(next->d_name, ".") == 0) ) {
+                   continue;
+               }
+               sprintf(nextFile, "%s/%s", fileName, next->d_name);
+               status = recursiveAction(nextFile, followLinks, fileAction, dirAction);
+               if (status < 0) {
+                   closedir(dir);
+                   return(FALSE);
+               }
+       }
+       status = closedir (dir);
+       if (status < 0) {
+           perror(fileName);
+           return( FALSE);
        }
+       if (dirAction==NULL)
+           return(TRUE);
        else
-           return(dirAction(fileName, &statbuf));
+           return(dirAction(fileName));
+    }
+    else {
+       if (fileAction==NULL)
+           return(TRUE);
+       else
+           return(fileAction(fileName));
     }
-    return( 1);
-
 }
 
 
diff --git a/utility.h b/utility.h
deleted file mode 100644 (file)
index 7b275ba..0000000
--- a/utility.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Utility routines.
- *
- * Copyright (C) 1998 by Erik Andersen <andersee@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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Based in part on code from sash, Copyright (c) 1999 by David I. Bell 
- * Permission has been granted to redistribute this code under the GPL.
- *
- */
-
-#include "internal.h"
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-//#include <sys/types.h>
-//#include <sys/stat.h>
-#include <dirent.h>
-#include <time.h>
-#include <utime.h>
-
-/*
- * A chunk of data.
- * Chunks contain data which is allocated as needed, but which is
- * not freed until all of the data needs freeing, such as at
- * the beginning of the next command.
- */
-typedef struct chunk CHUNK;
-#define CHUNK_INIT_SIZE 4
-
-struct chunk {
-    CHUNK *next;
-    char data[CHUNK_INIT_SIZE];        /* actually of varying length */
-};
-
-const char *modeString(int mode);
-const char *timeString(time_t timeVal);
-BOOL isDirectory(const char *name);
-BOOL isDevice(const char *name);
-BOOL copyFile(const char *srcName, const char *destName, BOOL setModes);
-const char *buildName(const char *dirName, const char *fileName);
-BOOL match(const char *text, const char *pattern);
-BOOL makeArgs(const char *cmd, int *retArgc, const char ***retArgv);
-BOOL makeString(int argc, const char **argv, char *buf, int bufLen);
-char *getChunk(int size);
-char *chunkstrdup(const char *str);
-void freeChunks(void);
-int fullWrite(int fd, const char *buf, int len);
-int fullRead(int fd, char *buf, int len);
-int
-recursive(const char *fileName, BOOL followLinks, const char *pattern,
-         int (*fileAction) (const char *fileName,
-                            const struct stat * statbuf),
-         int (*dirAction) (const char *fileName,
-                           const struct stat * statbuf));
-
-int nameSort(const void *p1, const void *p2);
-int expandWildCards(const char *fileNamePattern,
-                   const char ***retFileTable);