diff --git a/applets/busybox.c b/applets/busybox.c index 561aa01b5..45365b370 100644 --- a/applets/busybox.c +++ b/applets/busybox.c @@ -49,7 +49,7 @@ static const struct Applet applets[] = { {"false", false_main}, #endif #ifdef BB_FDFLUSH //bin - {"fdflush", monadic_main}, + {"fdflush", fdflush_main}, #endif #ifdef BB_FIND //usr/bin {"find", find_main}, @@ -70,7 +70,7 @@ static const struct Applet applets[] = { {"length", length_main}, #endif #ifdef BB_LN //bin - {"ln", dyadic_main}, + {"ln", ln_main}, #endif #ifdef BB_LOADKMAP //sbin {"loadkmap", loadkmap_main}, @@ -88,7 +88,7 @@ static const struct Applet applets[] = { {"math", math_main}, #endif #ifdef BB_MKDIR //bin - {"mkdir", monadic_main}, + {"mkdir", mkdir_main}, #endif #ifdef BB_MKNOD //bin {"mknod", mknod_main}, @@ -124,7 +124,7 @@ static const struct Applet applets[] = { {"rm", rm_main}, #endif #ifdef BB_RMDIR //bin - {"rmdir", monadic_main}, + {"rmdir", rmdir_main}, #endif #ifdef BB_SLEEP //bin {"sleep", sleep_main}, diff --git a/archival/tar.c b/archival/tar.c index ff60f0689..f222c3c9d 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -103,7 +103,6 @@ static ino_t tarInode; */ static void readTarFile (int fileCount, char **fileTable); static void readData (const char *cp, int count); -static void createPath (const char *name, int mode); static long getOctal (const char *cp, int len); static void readHeader (const TarHeader * hp, @@ -1022,36 +1021,6 @@ static void writeTarBlock (const char *buf, int len) } -/* - * Attempt to create the directories along the specified path, except for - * the final component. The mode is given for the final directory only, - * while all previous ones get default protections. Errors are not reported - * here, as failures to restore files can be reported later. - */ -static void createPath (const char *name, int mode) -{ - char *cp; - char *cpOld; - char buf[TAR_NAME_SIZE]; - - strcpy (buf, name); - - cp = strchr (buf, '/'); - - while (cp) { - cpOld = cp; - cp = strchr (cp + 1, '/'); - - *cpOld = '\0'; - - if (mkdir (buf, cp ? 0777 : mode) == 0) - printf ("Directory \"%s\" created\n", buf); - - *cpOld = '/'; - } -} - - /* * Read an octal value in a field of the specified width, with optional * spaces on both sides of the number and with an optional null character diff --git a/busybox.c b/busybox.c index 561aa01b5..45365b370 100644 --- a/busybox.c +++ b/busybox.c @@ -49,7 +49,7 @@ static const struct Applet applets[] = { {"false", false_main}, #endif #ifdef BB_FDFLUSH //bin - {"fdflush", monadic_main}, + {"fdflush", fdflush_main}, #endif #ifdef BB_FIND //usr/bin {"find", find_main}, @@ -70,7 +70,7 @@ static const struct Applet applets[] = { {"length", length_main}, #endif #ifdef BB_LN //bin - {"ln", dyadic_main}, + {"ln", ln_main}, #endif #ifdef BB_LOADKMAP //sbin {"loadkmap", loadkmap_main}, @@ -88,7 +88,7 @@ static const struct Applet applets[] = { {"math", math_main}, #endif #ifdef BB_MKDIR //bin - {"mkdir", monadic_main}, + {"mkdir", mkdir_main}, #endif #ifdef BB_MKNOD //bin {"mknod", mknod_main}, @@ -124,7 +124,7 @@ static const struct Applet applets[] = { {"rm", rm_main}, #endif #ifdef BB_RMDIR //bin - {"rmdir", monadic_main}, + {"rmdir", rmdir_main}, #endif #ifdef BB_SLEEP //bin {"sleep", sleep_main}, diff --git a/busybox.def.h b/busybox.def.h index ae9945d1b..e011bf9fc 100644 --- a/busybox.def.h +++ b/busybox.def.h @@ -3,7 +3,6 @@ * IE //#define BB_BLAH */ -//#define BB_BLOCK_DEVICE #define BB_BUSYBOX #define BB_CAT #define BB_CHMOD_CHOWN_CHGRP @@ -16,20 +15,20 @@ #define BB_DMESG #define BB_DUTMP #define BB_FALSE -//#define BB_FDFLUSH +#define BB_FDFLUSH #define BB_FIND #define BB_GREP ////#define BB_HALT //#define BB_INIT #define BB_KILL ////#define BB_LENGTH -//#define BB_LN +#define BB_LN //#define BB_LOADKMAP ////#define BB_LOSETUP #define BB_LS //#define BB_MAKEDEVS -////#define BB_MATH -//#define BB_MKDIR +#define BB_MATH +#define BB_MKDIR //#define BB_MKNOD ////#define BB_MKSWAP #define BB_MNC @@ -37,12 +36,11 @@ #define BB_MOUNT ////#define BB_MT #define BB_MV -//#define BB_POSTPROCESS //#define BB_PRINTF #define BB_PWD #define BB_REBOOT //#define BB_RM -//#define BB_RMDIR +#define BB_RMDIR #define BB_SLEEP ////#define BB_SWAPOFF //#define BB_SWAPON diff --git a/chmod_chown_chgrp.c b/chmod_chown_chgrp.c index 37a52281c..5c2adab78 100644 --- a/chmod_chown_chgrp.c +++ b/chmod_chown_chgrp.c @@ -29,7 +29,7 @@ static int uid=-1; static int gid=0; static int whichApp; static char* invocationName=NULL; -static mode_t mode=7777; +static mode_t mode=0644; #define CHGRP_APP 1 @@ -59,6 +59,7 @@ static int fileAction(const char *fileName) if (chown(fileName, ((whichApp==CHOWN_APP)? uid: statBuf.st_uid), gid) < 0) return( TRUE); case CHMOD_APP: + fprintf(stderr, "%s, %d\n", fileName, mode); if (chmod(fileName, mode)) return( TRUE); } @@ -67,118 +68,13 @@ static int fileAction(const char *fileName) return( FALSE); } -/* [ugoa]{+|-|=}[rwxstl] */ -int parse_mode( const char* s, mode_t* or, mode_t* and, int* group_execute) -{ - mode_t mode = 0; - mode_t groups = S_ISVTX; - char type; - char c; - - do { - for ( ; ; ) { - switch ( c = *s++ ) { - case '\0': - return (FALSE); - case 'u': - groups |= S_ISUID|S_IRWXU; - continue; - case 'g': - groups |= S_ISGID|S_IRWXG; - continue; - case 'o': - groups |= S_IRWXO; - continue; - case 'a': - groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; - continue; - case '+': - case '=': - case '-': - type = c; - if ( groups == S_ISVTX ) /* The default is "all" */ - groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; - break; - default: - if ( c >= '0' && c <= '7' && mode == 0 && groups == S_ISVTX ) { - *and = 0; - *or = strtol(--s, 0, 010); - return (TRUE); - } - else - return (FALSE); - } - break; - } - - while ( (c = *s++) != '\0' ) { - switch ( c ) { - case ',': - break; - case 'r': - mode |= S_IRUSR|S_IRGRP|S_IROTH; - continue; - case 'w': - mode |= S_IWUSR|S_IWGRP|S_IWOTH; - continue; - case 'x': - mode |= S_IXUSR|S_IXGRP|S_IXOTH; - continue; - case 's': - if ( group_execute != 0 && (groups & S_IRWXG) ) { - if ( *group_execute < 0 ) - return (FALSE); - if ( type != '-' ) { - mode |= S_IXGRP; - *group_execute = 1; - } - } - mode |= S_ISUID|S_ISGID; - continue; - case 'l': - if ( *group_execute > 0 ) - return (FALSE); - if ( type != '-' ) { - *and &= ~S_IXGRP; - *group_execute = -1; - } - mode |= S_ISGID; - groups |= S_ISGID; - continue; - case 't': - mode |= S_ISVTX; - continue; - default: - return (FALSE); - } - break; - } - switch ( type ) { - case '=': - *and &= ~(groups); - /* fall through */ - case '+': - *or |= mode & groups; - break; - case '-': - *and &= ~(mode & groups); - *or &= *and; - break; - } - } while ( c == ',' ); - return (TRUE); -} - - int chmod_chown_chgrp_main(int argc, char **argv) { struct group *grp; struct passwd *pwd; int recursiveFlag=FALSE; char *groupName; - mode_t andWithMode = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; - mode_t orWithMode = 0; - + mode_t andWithMode= S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; whichApp = (strcmp(*argv, "chown")==0)? CHOWN_APP : (strcmp(*argv, "chmod")==0)? CHMOD_APP : CHGRP_APP; @@ -207,12 +103,12 @@ int chmod_chown_chgrp_main(int argc, char **argv) if ( whichApp == CHMOD_APP ) { /* Find the specified modes */ - if ( parse_mode(*argv, &orWithMode, &andWithMode, 0) == FALSE ) { + if ( parse_mode(*argv, &mode) == FALSE ) { fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, *argv); exit( FALSE); } - mode &= andWithMode; - mode |= orWithMode; + //mode &= andWithMode; + fprintf(stderr, "mode %d\n", mode); } else { /* Find the selected group */ @@ -245,8 +141,8 @@ int chmod_chown_chgrp_main(int argc, char **argv) exit( FALSE); } while (argc-- > 1) { - argv++; - recursiveAction( *argv, recursiveFlag, TRUE, fileAction, fileAction); + if (recursiveAction( *(++argv), recursiveFlag, TRUE, fileAction, fileAction)==FALSE) + exit( FALSE); } exit(TRUE); } diff --git a/coreutils/ln.c b/coreutils/ln.c index 3e87b579e..cd3cb4e45 100644 --- a/coreutils/ln.c +++ b/coreutils/ln.c @@ -1,52 +1,100 @@ +/* + * Mini ln implementation for busybox + * + * Copyright (C) 1998 by Erik Andersen + * + * 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 -#include -#include +#include #include -const char ln_usage[] = "ln [-s] [-f] original-name additional-name\n" + +static const char ln_usage[] = "ln [-s] [-f] original-name additional-name\n" "\n" "\tAdd a new name that refers to the same file as \"original-name\"\n" "\n" "\t-s:\tUse a \"symbolic\" link, instead of a \"hard\" link.\n" "\t-f:\tRemove existing destination files.\n"; -int -ln_fn(const struct FileInfo * i) + +static int symlinkFlag = FALSE; +static int removeoldFlag = FALSE; +static const char *destName; + + +extern int ln_main(int argc, char **argv) { - int status = 0; - char d[PATH_MAX]; - const char * destination = i->destination; + int status; + char newdestName[NAME_MAX]; - if ( !i->makeSymbolicLink && (i->stat.st_mode & S_IFMT) == S_IFDIR ) { - fprintf(stderr, "Please use \"ln -s\" to link directories.\n"); - return 1; - } - - /* - * If the destination is a directory, create a file within it. - */ - if ( is_a_directory(i->destination) ) { - destination = join_paths( - d - ,i->destination - ,&i->source[i->directoryLength]); - } - - if ( i->force ) - status = ( unlink(destination) && errno != ENOENT ); - - if ( status == 0 ) { - if ( i->makeSymbolicLink ) - status = symlink(i->source, destination); - else - status = link(i->source, destination); - } - - if ( status != 0 ) { - name_and_error(destination); - return 1; + if (argc < 3) { + fprintf(stderr, "Usage: %s", ln_usage); + exit (FALSE); + } + argc--; + argv++; + + /* Parse any options */ + while (**argv == '-') { + while (*++(*argv)) + switch (**argv) { + case 's': + symlinkFlag = TRUE; + break; + case 'f': + removeoldFlag = TRUE; + break; + default: + fprintf(stderr, "Usage: %s\n", ln_usage); + exit(FALSE); + } + argc--; + argv++; + } + + + destName = argv[argc - 1]; + + if ((argc > 3) && !(isDirectory(destName))) { + fprintf(stderr, "%s: not a directory\n", destName); + exit (FALSE); + } + + while (argc-- >= 2) { + strcpy(newdestName, destName); + strcat(newdestName, (*argv)+(strlen(*(++argv)))); + + if (removeoldFlag==TRUE ) { + status = ( unlink(newdestName) && errno != ENOENT ); + if ( status != 0 ) { + perror(newdestName); + exit( FALSE); + } } + if ( symlinkFlag==TRUE) + status = symlink(*argv, newdestName); else - return 0; + status = link(*argv, newdestName); + if ( status != 0 ) { + perror(newdestName); + exit( FALSE); + } + } + exit( TRUE); } diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c index 8f1fa04db..61d35d5cd 100644 --- a/coreutils/mkdir.c +++ b/coreutils/mkdir.c @@ -1,58 +1,85 @@ +/* + * Mini mkdir implementation for busybox + * + * Copyright (C) 1998 by Erik Andersen + * + * 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 #include #include -const char mkdir_usage[] = "mkdir [-m mode] directory [directory ...]\n" -"\tCreate directories.\n" -"\n" -"\t-m mode:\tSpecifiy the mode for the new directory\n" -"\t\tunder the argument directory."; +const char mkdir_usage[] = "Usage: mkdir [OPTION] DIRECTORY...\n" +"Create the DIRECTORY(ies), if they do not already exist\n\n" +"-m\tset permission mode (as in chmod), not rwxrwxrwx - umask\n" +"-p\tno error if existing, make parent directories as needed\n"; -/*make directories skipping the last part of the path. Used here and by untar*/ -int mkdir_until(const char *fpath, const struct FileInfo * fi) + +static int parentFlag = FALSE; +static int permFlag = FALSE; +static mode_t mode = 0777; + + +extern int mkdir_main(int argc, char **argv) { - char path[PATH_MAX]; - char * s = path; + argc--; + argv++; - strcpy(path, fpath); - if ( s[0] == '\0' && s[1] == '\0' ) { - usage(mkdir_usage); - return 1; + /* Parse any options */ + while (argc > 1 && **argv == '-') { + while (*++(*argv)) + switch (**argv) { + case 'm': + permFlag = TRUE; + break; + case 'p': + parentFlag = TRUE; + break; + default: + fprintf(stderr, "%s\n", mkdir_usage); + exit(FALSE); + } + argc--; + argv++; + } + + + if (argc < 1) { + fprintf(stderr, "%s\n", mkdir_usage); + exit (FALSE); + } + + while (--argc > 0) { + struct stat statBuf; + if (stat(*(++argv), &statBuf) != ENOENT) { + fprintf(stderr, "%s: File exists\n", *argv); + return( FALSE); } - s++; - while ( *s != '\0' ) { - if ( *s == '/' ) { - int status; - - *s = '\0'; - status = mkdir(path, (fi?fi->orWithMode:0700) ); - *s = '/'; - - if ( status != 0 ) { - if ( errno != EEXIST ) { - name_and_error(fpath); - return 1; - } - } - - } - s++; + if (parentFlag == TRUE) + createPath(*argv, mode); + else { + if (mkdir (*argv, mode) != 0) { + perror(*argv); + exit( FALSE); + } } - return 0; + } + exit( TRUE); } -int -mkdir_fn(const struct FileInfo * i) -{ - if ( i->makeParentDirectories ) { - if(mkdir_until(i->source, i)) return 1; - } - - if ( mkdir(i->source, i->orWithMode) != 0 && errno != EEXIST ) { - name_and_error(i->source); - return 1; - } - else - return 0; -} diff --git a/coreutils/rmdir.c b/coreutils/rmdir.c index 069e68546..b4da03f12 100644 --- a/coreutils/rmdir.c +++ b/coreutils/rmdir.c @@ -1,17 +1,41 @@ +/* + * Mini rmdir implementation for busybox + * + * Copyright (C) 1998 by Erik Andersen + * + * 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 #include -const char rmdir_usage[] = "rmdir directory [directory ...]\n" -"\n" -"\tDelete directories.\n"; -extern int -rmdir_fn(const struct FileInfo * i) +extern int rmdir_main(int argc, char **argv) { - if ( rmdir(i->source) != 0 && errno != ENOENT && !i->force ) { - name_and_error(i->source); - return 1; + if ( argc==1 || **(argv+1) == '-' ) { + fprintf(stderr, "Usage: rmdir [OPTION]... DIRECTORY...\nRemove the DIRECTORY(ies), if they are empty."); + exit(FALSE); + } + + while (--argc > 0) { + if ( rmdir(*(++argv)) == -1 ) { + fprintf(stderr, "%s: %s\n", *argv, strerror(errno)); + exit(FALSE); } - else - return 0; + } + exit(TRUE); } diff --git a/fdflush.c b/fdflush.c index a15e9b3f7..ce6870cd1 100644 --- a/fdflush.c +++ b/fdflush.c @@ -1,36 +1,53 @@ + +/* + * Mini fdflush implementation for busybox + * + * Copyright (C) 1998 by Erik Andersen + * + * 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 #include #include -#include -#include #include -const char fdflush_usage[] = "fdflush device"; -int -fdflush(const char *filename) +extern int fdflush_main(int argc, char **argv) { - int status; - int fd = open(filename, 0); + int value; + int fd; + if ( **(argv+1) == '-' ) { + fprintf(stderr, "Usage: fdflush device\n"); + exit(FALSE); + } - if ( fd < 0 ) { - name_and_error(filename); - return 1; - } + fd = open(*argv, 0); + if ( fd < 0 ) { + perror(*argv); + exit(FALSE); + } - status = ioctl(fd, FDFLUSH, 0); - close(fd); + value = ioctl(fd, FDFLUSH, 0); + close(fd); - if ( status != 0 ) { - name_and_error(filename); - return 1; - } - return 0; -} - - -int -fdflush_fn(const struct FileInfo * i) -{ - return fdflush(i->source); + if ( value ) { + perror(*argv); + exit(FALSE); + } + exit (TRUE); } diff --git a/internal.h b/internal.h index f095091fc..397eca48a 100644 --- a/internal.h +++ b/internal.h @@ -66,9 +66,9 @@ extern int date_main(int argc, char** argv); extern int dd_main(int argc, char** argv); extern int df_main(int argc, char** argv); extern int dmesg_main(int argc, char** argv); -extern int dyadic_main(int argc, char** argv); extern int false_main(int argc, char** argv); extern int fdisk_main(int argc, char** argv); +extern int fdflush_main(int argc, char **argv); extern int find_main(int argc, char** argv); extern int grep_main(int argc, char** argv); extern int halt_main(int argc, char** argv); @@ -81,16 +81,17 @@ extern int losetup_main(int argc, char** argv); extern int ls_main(int argc, char** argv); extern int makedevs_main(int argc, char** argv); extern int math_main(int argc, char** argv); +extern int mkdir_main(int argc, char** argv); extern int mknod_main(int argc, char** argv); extern int mkswap_main(int argc, char** argv); extern int mnc_main(int argc, char** argv); -extern int monadic_main(int argc, char** argv); extern int mount_main(int argc, char** argv); extern int mt_main(int argc, char** argv); extern int mv_main(int argc, char** argv); extern int printf_main(int argc, char** argv); extern int pwd_main(int argc, char** argv); extern int reboot_main(int argc, char** argv); +extern int rmdir_main(int argc, char **argv); extern int rm_main(int argc, char** argv); extern int scan_partitions_main(int argc, char** argv); extern int sh_main(int argc, char** argv); @@ -126,6 +127,8 @@ int recursiveAction(const char *fileName, int recurse, int followLinks, int match(const char* text, const char * pattern); const char* timeString(time_t timeVal); +extern void createPath (const char *name, int mode); +extern int parse_mode( const char* s, mode_t* theMode); #endif diff --git a/ln.c b/ln.c index 3e87b579e..cd3cb4e45 100644 --- a/ln.c +++ b/ln.c @@ -1,52 +1,100 @@ +/* + * Mini ln implementation for busybox + * + * Copyright (C) 1998 by Erik Andersen + * + * 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 -#include -#include +#include #include -const char ln_usage[] = "ln [-s] [-f] original-name additional-name\n" + +static const char ln_usage[] = "ln [-s] [-f] original-name additional-name\n" "\n" "\tAdd a new name that refers to the same file as \"original-name\"\n" "\n" "\t-s:\tUse a \"symbolic\" link, instead of a \"hard\" link.\n" "\t-f:\tRemove existing destination files.\n"; -int -ln_fn(const struct FileInfo * i) + +static int symlinkFlag = FALSE; +static int removeoldFlag = FALSE; +static const char *destName; + + +extern int ln_main(int argc, char **argv) { - int status = 0; - char d[PATH_MAX]; - const char * destination = i->destination; + int status; + char newdestName[NAME_MAX]; - if ( !i->makeSymbolicLink && (i->stat.st_mode & S_IFMT) == S_IFDIR ) { - fprintf(stderr, "Please use \"ln -s\" to link directories.\n"); - return 1; - } - - /* - * If the destination is a directory, create a file within it. - */ - if ( is_a_directory(i->destination) ) { - destination = join_paths( - d - ,i->destination - ,&i->source[i->directoryLength]); - } - - if ( i->force ) - status = ( unlink(destination) && errno != ENOENT ); - - if ( status == 0 ) { - if ( i->makeSymbolicLink ) - status = symlink(i->source, destination); - else - status = link(i->source, destination); - } - - if ( status != 0 ) { - name_and_error(destination); - return 1; + if (argc < 3) { + fprintf(stderr, "Usage: %s", ln_usage); + exit (FALSE); + } + argc--; + argv++; + + /* Parse any options */ + while (**argv == '-') { + while (*++(*argv)) + switch (**argv) { + case 's': + symlinkFlag = TRUE; + break; + case 'f': + removeoldFlag = TRUE; + break; + default: + fprintf(stderr, "Usage: %s\n", ln_usage); + exit(FALSE); + } + argc--; + argv++; + } + + + destName = argv[argc - 1]; + + if ((argc > 3) && !(isDirectory(destName))) { + fprintf(stderr, "%s: not a directory\n", destName); + exit (FALSE); + } + + while (argc-- >= 2) { + strcpy(newdestName, destName); + strcat(newdestName, (*argv)+(strlen(*(++argv)))); + + if (removeoldFlag==TRUE ) { + status = ( unlink(newdestName) && errno != ENOENT ); + if ( status != 0 ) { + perror(newdestName); + exit( FALSE); + } } + if ( symlinkFlag==TRUE) + status = symlink(*argv, newdestName); else - return 0; + status = link(*argv, newdestName); + if ( status != 0 ) { + perror(newdestName); + exit( FALSE); + } + } + exit( TRUE); } diff --git a/math.c b/math.c index 5c1560a4e..29962a873 100644 --- a/math.c +++ b/math.c @@ -137,7 +137,7 @@ stack_machine(const char * argument) } int -math_main(struct FileInfo * i, int argc, char * * argv) +math_main(int argc, char * * argv) { while ( argc >= 2 ) { stack_machine(argv[1]); diff --git a/mkdir.c b/mkdir.c index 8f1fa04db..61d35d5cd 100644 --- a/mkdir.c +++ b/mkdir.c @@ -1,58 +1,85 @@ +/* + * Mini mkdir implementation for busybox + * + * Copyright (C) 1998 by Erik Andersen + * + * 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 #include #include -const char mkdir_usage[] = "mkdir [-m mode] directory [directory ...]\n" -"\tCreate directories.\n" -"\n" -"\t-m mode:\tSpecifiy the mode for the new directory\n" -"\t\tunder the argument directory."; +const char mkdir_usage[] = "Usage: mkdir [OPTION] DIRECTORY...\n" +"Create the DIRECTORY(ies), if they do not already exist\n\n" +"-m\tset permission mode (as in chmod), not rwxrwxrwx - umask\n" +"-p\tno error if existing, make parent directories as needed\n"; -/*make directories skipping the last part of the path. Used here and by untar*/ -int mkdir_until(const char *fpath, const struct FileInfo * fi) + +static int parentFlag = FALSE; +static int permFlag = FALSE; +static mode_t mode = 0777; + + +extern int mkdir_main(int argc, char **argv) { - char path[PATH_MAX]; - char * s = path; + argc--; + argv++; - strcpy(path, fpath); - if ( s[0] == '\0' && s[1] == '\0' ) { - usage(mkdir_usage); - return 1; + /* Parse any options */ + while (argc > 1 && **argv == '-') { + while (*++(*argv)) + switch (**argv) { + case 'm': + permFlag = TRUE; + break; + case 'p': + parentFlag = TRUE; + break; + default: + fprintf(stderr, "%s\n", mkdir_usage); + exit(FALSE); + } + argc--; + argv++; + } + + + if (argc < 1) { + fprintf(stderr, "%s\n", mkdir_usage); + exit (FALSE); + } + + while (--argc > 0) { + struct stat statBuf; + if (stat(*(++argv), &statBuf) != ENOENT) { + fprintf(stderr, "%s: File exists\n", *argv); + return( FALSE); } - s++; - while ( *s != '\0' ) { - if ( *s == '/' ) { - int status; - - *s = '\0'; - status = mkdir(path, (fi?fi->orWithMode:0700) ); - *s = '/'; - - if ( status != 0 ) { - if ( errno != EEXIST ) { - name_and_error(fpath); - return 1; - } - } - - } - s++; + if (parentFlag == TRUE) + createPath(*argv, mode); + else { + if (mkdir (*argv, mode) != 0) { + perror(*argv); + exit( FALSE); + } } - return 0; + } + exit( TRUE); } -int -mkdir_fn(const struct FileInfo * i) -{ - if ( i->makeParentDirectories ) { - if(mkdir_until(i->source, i)) return 1; - } - - if ( mkdir(i->source, i->orWithMode) != 0 && errno != EEXIST ) { - name_and_error(i->source); - return 1; - } - else - return 0; -} diff --git a/rmdir.c b/rmdir.c index 069e68546..b4da03f12 100644 --- a/rmdir.c +++ b/rmdir.c @@ -1,17 +1,41 @@ +/* + * Mini rmdir implementation for busybox + * + * Copyright (C) 1998 by Erik Andersen + * + * 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 #include -const char rmdir_usage[] = "rmdir directory [directory ...]\n" -"\n" -"\tDelete directories.\n"; -extern int -rmdir_fn(const struct FileInfo * i) +extern int rmdir_main(int argc, char **argv) { - if ( rmdir(i->source) != 0 && errno != ENOENT && !i->force ) { - name_and_error(i->source); - return 1; + if ( argc==1 || **(argv+1) == '-' ) { + fprintf(stderr, "Usage: rmdir [OPTION]... DIRECTORY...\nRemove the DIRECTORY(ies), if they are empty."); + exit(FALSE); + } + + while (--argc > 0) { + if ( rmdir(*(++argv)) == -1 ) { + fprintf(stderr, "%s: %s\n", *argv, strerror(errno)); + exit(FALSE); } - else - return 0; + } + exit(TRUE); } diff --git a/tar.c b/tar.c index ff60f0689..f222c3c9d 100644 --- a/tar.c +++ b/tar.c @@ -103,7 +103,6 @@ static ino_t tarInode; */ static void readTarFile (int fileCount, char **fileTable); static void readData (const char *cp, int count); -static void createPath (const char *name, int mode); static long getOctal (const char *cp, int len); static void readHeader (const TarHeader * hp, @@ -1022,36 +1021,6 @@ static void writeTarBlock (const char *buf, int len) } -/* - * Attempt to create the directories along the specified path, except for - * the final component. The mode is given for the final directory only, - * while all previous ones get default protections. Errors are not reported - * here, as failures to restore files can be reported later. - */ -static void createPath (const char *name, int mode) -{ - char *cp; - char *cpOld; - char buf[TAR_NAME_SIZE]; - - strcpy (buf, name); - - cp = strchr (buf, '/'); - - while (cp) { - cpOld = cp; - cp = strchr (cp + 1, '/'); - - *cpOld = '\0'; - - if (mkdir (buf, cp ? 0777 : mode) == 0) - printf ("Directory \"%s\" created\n", buf); - - *cpOld = '/'; - } -} - - /* * Read an octal value in a field of the specified width, with optional * spaces on both sides of the number and with an optional null character diff --git a/util-linux/fdflush.c b/util-linux/fdflush.c index a15e9b3f7..ce6870cd1 100644 --- a/util-linux/fdflush.c +++ b/util-linux/fdflush.c @@ -1,36 +1,53 @@ + +/* + * Mini fdflush implementation for busybox + * + * Copyright (C) 1998 by Erik Andersen + * + * 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 #include #include -#include -#include #include -const char fdflush_usage[] = "fdflush device"; -int -fdflush(const char *filename) +extern int fdflush_main(int argc, char **argv) { - int status; - int fd = open(filename, 0); + int value; + int fd; + if ( **(argv+1) == '-' ) { + fprintf(stderr, "Usage: fdflush device\n"); + exit(FALSE); + } - if ( fd < 0 ) { - name_and_error(filename); - return 1; - } + fd = open(*argv, 0); + if ( fd < 0 ) { + perror(*argv); + exit(FALSE); + } - status = ioctl(fd, FDFLUSH, 0); - close(fd); + value = ioctl(fd, FDFLUSH, 0); + close(fd); - if ( status != 0 ) { - name_and_error(filename); - return 1; - } - return 0; -} - - -int -fdflush_fn(const struct FileInfo * i) -{ - return fdflush(i->source); + if ( value ) { + perror(*argv); + exit(FALSE); + } + exit (TRUE); } diff --git a/utility.c b/utility.c index 21d69b6e8..b2228f0cb 100644 --- a/utility.c +++ b/utility.c @@ -544,4 +544,127 @@ recursiveAction(const char *fileName, int recurse, int followLinks, #endif + + +#if defined (BB_TAR) || defined (BB_MKDIR) +/* + * Attempt to create the directories along the specified path, except for + * the final component. The mode is given for the final directory only, + * while all previous ones get default protections. Errors are not reported + * here, as failures to restore files can be reported later. + */ +extern void createPath (const char *name, int mode) +{ + char *cp; + char *cpOld; + char buf[NAME_MAX]; + + strcpy (buf, name); + + cp = strchr (buf, '/'); + + while (cp) { + cpOld = cp; + cp = strchr (cp + 1, '/'); + + *cpOld = '\0'; + + if (mkdir (buf, cp ? 0777 : mode) == 0) + printf ("Directory \"%s\" created\n", buf); + + *cpOld = '/'; + } +} +#endif + + + +#if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_MKDIR) +/* [ugoa]{+|-|=}[rwxstl] */ +extern int parse_mode( const char* s, mode_t* theMode) +{ + mode_t or; + mode_t and; + mode_t mode = 0; + mode_t groups = S_ISVTX; + char type; + char c; + + do { + for ( ; ; ) { + switch ( c = *s++ ) { + case '\0': + return (FALSE); + case 'u': + groups |= S_ISUID|S_IRWXU; + continue; + case 'g': + groups |= S_ISGID|S_IRWXG; + continue; + case 'o': + groups |= S_IRWXO; + continue; + case 'a': + groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; + continue; + case '+': + case '=': + case '-': + type = c; + if ( groups == S_ISVTX ) /* The default is "all" */ + groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; + break; + default: + if ( c >= '0' && c <= '7' && mode == 0 && groups == S_ISVTX ) { + and = 0; + or = strtol(--s, 0, 010); + return (TRUE); + } + else + return (FALSE); + } + break; + } + + while ( (c = *s++) != '\0' ) { + switch ( c ) { + case ',': + break; + case 'r': + mode |= S_IRUSR|S_IRGRP|S_IROTH; + continue; + case 'w': + mode |= S_IWUSR|S_IWGRP|S_IWOTH; + continue; + case 'x': + mode |= S_IXUSR|S_IXGRP|S_IXOTH; + continue; + case 's': + mode |= S_IXGRP|S_ISUID|S_ISGID; + continue; + case 't': + mode |= S_ISVTX; + continue; + default: + return (FALSE); + } + break; + } + switch ( type ) { + case '=': + and &= ~(groups); + /* fall through */ + case '+': + or |= mode & groups; + break; + case '-': + and &= ~(mode & groups); + or &= and; + break; + } + } while ( c == ',' ); + return (TRUE); +} +#endif + /* END CODE */