More stuff
No binary (build failed)
—
(log yok)
| @@ -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}, | |
| @@ -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 | |
| @@ -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}, | |
| @@ -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 | |
| @@ -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); | |
| } | |
| @@ -1,52 +1,100 @@ | |
| + | /* |
| + | * Mini ln implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * 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 <sys/stat.h> |
| - | #include <sys/param.h> |
| + | #include <dirent.h> |
| #include <errno.h> | |
| - | 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 (argc < 3) { |
| + | fprintf(stderr, "Usage: %s", ln_usage); |
| + | exit (FALSE); |
| + | } |
| + | argc--; |
| + | argv++; |
| - | /* |
| - | * 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]); |
| - | } |
| + | /* 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++; |
| + | } |
| - | 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); |
| - | } |
| + | destName = argv[argc - 1]; |
| - | if ( status != 0 ) { |
| - | name_and_error(destination); |
| - | return 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); |
| } | |
| @@ -1,58 +1,85 @@ | |
| + | /* |
| + | * Mini mkdir implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * 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 <errno.h> | |
| #include <sys/param.h> | |
| - | 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) |
| - | { |
| - | char path[PATH_MAX]; |
| - | char * s = path; |
| - | strcpy(path, fpath); |
| - | if ( s[0] == '\0' && s[1] == '\0' ) { |
| - | usage(mkdir_usage); |
| - | return 1; |
| - | } |
| - | 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++; |
| - | } |
| - | return 0; |
| - | } |
| + | static int parentFlag = FALSE; |
| + | static int permFlag = FALSE; |
| + | static mode_t mode = 0777; |
| + | |
| - | int |
| - | mkdir_fn(const struct FileInfo * i) |
| + | extern int mkdir_main(int argc, char **argv) |
| { | |
| - | if ( i->makeParentDirectories ) { |
| - | if(mkdir_until(i->source, i)) return 1; |
| - | } |
| + | argc--; |
| + | argv++; |
| + | |
| + | /* 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 ( mkdir(i->source, i->orWithMode) != 0 && errno != EEXIST ) { |
| - | name_and_error(i->source); |
| - | return 1; |
| + | 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); |
| + | } |
| + | if (parentFlag == TRUE) |
| + | createPath(*argv, mode); |
| + | else { |
| + | if (mkdir (*argv, mode) != 0) { |
| + | perror(*argv); |
| + | exit( FALSE); |
| + | } |
| } | |
| - | else |
| - | return 0; |
| + | } |
| + | exit( TRUE); |
| } | |
| + | |
| @@ -1,17 +1,41 @@ | |
| + | /* |
| + | * Mini rmdir implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * 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 <errno.h> | |
| - | 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); |
| } | |
| @@ -1,36 +1,53 @@ | |
| + | |
| + | /* |
| + | * Mini fdflush implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * 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 <sys/ioctl.h> | |
| #include <linux/fd.h> | |
| - | #include <sys/types.h> |
| - | #include <sys/stat.h> |
| #include <fcntl.h> | |
| - | 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); |
| - | |
| - | if ( fd < 0 ) { |
| - | name_and_error(filename); |
| - | return 1; |
| - | } |
| + | int value; |
| + | int fd; |
| + | if ( **(argv+1) == '-' ) { |
| + | fprintf(stderr, "Usage: fdflush device\n"); |
| + | exit(FALSE); |
| + | } |
| - | status = ioctl(fd, FDFLUSH, 0); |
| - | close(fd); |
| - | |
| - | if ( status != 0 ) { |
| - | name_and_error(filename); |
| - | return 1; |
| - | } |
| - | return 0; |
| - | } |
| + | fd = open(*argv, 0); |
| + | if ( fd < 0 ) { |
| + | perror(*argv); |
| + | exit(FALSE); |
| + | } |
| + | value = ioctl(fd, FDFLUSH, 0); |
| + | close(fd); |
| - | int |
| - | fdflush_fn(const struct FileInfo * i) |
| - | { |
| - | return fdflush(i->source); |
| + | if ( value ) { |
| + | perror(*argv); |
| + | exit(FALSE); |
| + | } |
| + | exit (TRUE); |
| } | |
| @@ -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 | |
| @@ -1,52 +1,100 @@ | |
| + | /* |
| + | * Mini ln implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * 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 <sys/stat.h> |
| - | #include <sys/param.h> |
| + | #include <dirent.h> |
| #include <errno.h> | |
| - | 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 (argc < 3) { |
| + | fprintf(stderr, "Usage: %s", ln_usage); |
| + | exit (FALSE); |
| + | } |
| + | argc--; |
| + | argv++; |
| - | /* |
| - | * 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]); |
| - | } |
| + | /* 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++; |
| + | } |
| - | 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); |
| - | } |
| + | destName = argv[argc - 1]; |
| - | if ( status != 0 ) { |
| - | name_and_error(destination); |
| - | return 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); |
| } | |
| @@ -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]); | |
| @@ -1,58 +1,85 @@ | |
| + | /* |
| + | * Mini mkdir implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * 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 <errno.h> | |
| #include <sys/param.h> | |
| - | 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) |
| - | { |
| - | char path[PATH_MAX]; |
| - | char * s = path; |
| - | strcpy(path, fpath); |
| - | if ( s[0] == '\0' && s[1] == '\0' ) { |
| - | usage(mkdir_usage); |
| - | return 1; |
| - | } |
| - | 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++; |
| - | } |
| - | return 0; |
| - | } |
| + | static int parentFlag = FALSE; |
| + | static int permFlag = FALSE; |
| + | static mode_t mode = 0777; |
| + | |
| - | int |
| - | mkdir_fn(const struct FileInfo * i) |
| + | extern int mkdir_main(int argc, char **argv) |
| { | |
| - | if ( i->makeParentDirectories ) { |
| - | if(mkdir_until(i->source, i)) return 1; |
| - | } |
| + | argc--; |
| + | argv++; |
| + | |
| + | /* 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 ( mkdir(i->source, i->orWithMode) != 0 && errno != EEXIST ) { |
| - | name_and_error(i->source); |
| - | return 1; |
| + | 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); |
| + | } |
| + | if (parentFlag == TRUE) |
| + | createPath(*argv, mode); |
| + | else { |
| + | if (mkdir (*argv, mode) != 0) { |
| + | perror(*argv); |
| + | exit( FALSE); |
| + | } |
| } | |
| - | else |
| - | return 0; |
| + | } |
| + | exit( TRUE); |
| } | |
| + | |
| @@ -1,17 +1,41 @@ | |
| + | /* |
| + | * Mini rmdir implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * 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 <errno.h> | |
| - | 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); |
| } | |
| @@ -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 | |
| @@ -1,36 +1,53 @@ | |
| + | |
| + | /* |
| + | * Mini fdflush implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * 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 <sys/ioctl.h> | |
| #include <linux/fd.h> | |
| - | #include <sys/types.h> |
| - | #include <sys/stat.h> |
| #include <fcntl.h> | |
| - | 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); |
| - | |
| - | if ( fd < 0 ) { |
| - | name_and_error(filename); |
| - | return 1; |
| - | } |
| + | int value; |
| + | int fd; |
| + | if ( **(argv+1) == '-' ) { |
| + | fprintf(stderr, "Usage: fdflush device\n"); |
| + | exit(FALSE); |
| + | } |
| - | status = ioctl(fd, FDFLUSH, 0); |
| - | close(fd); |
| - | |
| - | if ( status != 0 ) { |
| - | name_and_error(filename); |
| - | return 1; |
| - | } |
| - | return 0; |
| - | } |
| + | fd = open(*argv, 0); |
| + | if ( fd < 0 ) { |
| + | perror(*argv); |
| + | exit(FALSE); |
| + | } |
| + | value = ioctl(fd, FDFLUSH, 0); |
| + | close(fd); |
| - | int |
| - | fdflush_fn(const struct FileInfo * i) |
| - | { |
| - | return fdflush(i->source); |
| + | if ( value ) { |
| + | perror(*argv); |
| + | exit(FALSE); |
| + | } |
| + | exit (TRUE); |
| } | |
| @@ -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 */ | |