More stuff.
No binary (build failed)
—
(log yok)
| @@ -30,7 +30,7 @@ static const struct Applet applets[] = { | |
| {"clear", clear_main}, | |
| #endif | |
| #ifdef BB_CP //bin | |
| - | {"cp", dyadic_main}, |
| + | {"cp", cp_main}, |
| #endif | |
| #ifdef BB_DATE //bin | |
| {"date", date_main}, | |
| @@ -73,18 +73,18 @@ typedef struct | |
| /* | |
| * Static data. | |
| */ | |
| - | static BOOL listFlag; |
| - | static BOOL extractFlag; |
| - | static BOOL createFlag; |
| - | static BOOL verboseFlag; |
| - | static BOOL tostdoutFlag; |
| - | |
| - | static BOOL inHeader; |
| - | static BOOL badHeader; |
| - | static BOOL errorFlag; |
| - | static BOOL skipFileFlag; |
| - | static BOOL warnedRoot; |
| - | static BOOL eofFlag; |
| + | static int listFlag; |
| + | static int extractFlag; |
| + | static int createFlag; |
| + | static int verboseFlag; |
| + | static int tostdoutFlag; |
| + | |
| + | static int inHeader; |
| + | static int badHeader; |
| + | static int errorFlag; |
| + | static int skipFileFlag; |
| + | static int warnedRoot; |
| + | static int eofFlag; |
| static long dataCc; | |
| static int outFd; | |
| static char outName[TAR_NAME_SIZE]; | |
| @@ -114,7 +114,7 @@ static void readHeader(const TarHeader * hp, | |
| /* | |
| * Local procedures to save files into a tar file. | |
| */ | |
| - | static void saveFile(const char * fileName, BOOL seeLinks); |
| + | static void saveFile(const char * fileName, int seeLinks); |
| static void saveRegularFile(const char * fileName, | |
| const struct stat * statbuf); | |
| @@ -122,7 +122,7 @@ static void saveRegularFile(const char * fileName, | |
| static void saveDirectory(const char * fileName, | |
| const struct stat * statbuf); | |
| - | static BOOL wantFileName(const char * fileName, |
| + | static int wantFileName(const char * fileName, |
| int fileCount, char ** fileTable); | |
| static void writeHeader(const char * fileName, | |
| @@ -130,7 +130,7 @@ static void writeHeader(const char * fileName, | |
| static void writeTarFile(int fileCount, char ** fileTable); | |
| static void writeTarBlock(const char * buf, int len); | |
| - | static BOOL putOctal(char * cp, int len, long value); |
| + | static int putOctal(char * cp, int len, long value); |
| extern int | |
| @@ -383,8 +383,8 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable) | |
| time_t mtime; | |
| const char * name; | |
| int cc; | |
| - | BOOL hardLink; |
| - | BOOL softLink; |
| + | int hardLink; |
| + | int softLink; |
| /* | |
| * If the block is completely empty, then this is the end of the | |
| @@ -710,7 +710,7 @@ done: | |
| * they really are, instead of blindly following them. | |
| */ | |
| static void | |
| - | saveFile(const char * fileName, BOOL seeLinks) |
| + | saveFile(const char * fileName, int seeLinks) |
| { | |
| int status; | |
| int mode; | |
| @@ -788,7 +788,7 @@ saveFile(const char * fileName, BOOL seeLinks) | |
| static void | |
| saveRegularFile(const char * fileName, const struct stat * statbuf) | |
| { | |
| - | BOOL sawEof; |
| + | int sawEof; |
| int fileFd; | |
| int cc; | |
| int dataCount; | |
| @@ -897,7 +897,7 @@ saveDirectory(const char * dirName, const struct stat * statbuf) | |
| { | |
| DIR * dir; | |
| struct dirent * entry; | |
| - | BOOL needSlash; |
| + | int needSlash; |
| char fullName[PATH_LEN]; | |
| /* | |
| @@ -1160,7 +1160,7 @@ getOctal(const char * cp, int len) | |
| * The number is zero and space padded and possibly null padded. | |
| * Returns TRUE if successful. | |
| */ | |
| - | static BOOL |
| + | static int |
| putOctal(char * cp, int len, long value) | |
| { | |
| int tempLength; | |
| @@ -1212,7 +1212,7 @@ putOctal(char * cp, int len, long value) | |
| * of path prefixes. An empty list implies that all files are wanted. | |
| * Returns TRUE if the file is selected. | |
| */ | |
| - | static BOOL |
| + | static int |
| wantFileName(const char * fileName, int fileCount, char ** fileTable) | |
| { | |
| const char * pathName; | |
| @@ -30,7 +30,7 @@ static const struct Applet applets[] = { | |
| {"clear", clear_main}, | |
| #endif | |
| #ifdef BB_CP //bin | |
| - | {"cp", dyadic_main}, |
| + | {"cp", cp_main}, |
| #endif | |
| #ifdef BB_DATE //bin | |
| {"date", date_main}, | |
| @@ -10,7 +10,7 @@ | |
| #define BB_CHOWN | |
| #define BB_CHROOT | |
| #define BB_CLEAR | |
| - | //#define BB_CP |
| + | #define BB_CP |
| #define BB_DATE | |
| #define BB_DD | |
| //#define BB_DESCEND | |
| @@ -54,7 +54,7 @@ | |
| #define BB_TAR | |
| #define BB_TOUCH | |
| #define BB_TRUE | |
| - | //#define BB_UMOUNT |
| + | #define BB_UMOUNT |
| //#define BB_UPDATE | |
| #define BB_UTILITY | |
| #define BB_ZCAT | |
| @@ -1,89 +1,141 @@ | |
| + | /* |
| + | * Mini cp 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/fcntl.h> |
| - | #include <sys/param.h> |
| - | #include <errno.h> |
| - | |
| - | const char cp_usage[] = "cp [-r] source-file destination-file\n" |
| - | "\t\tcp [-r] source-file [source-file ...] destination-directory\n" |
| - | "\n" |
| - | "\tCopy the source files to the destination.\n" |
| - | "\n" |
| - | "\t-r:\tRecursively copy all files and directories\n" |
| - | "\t\tunder the argument directory."; |
| - | |
| - | extern int |
| - | cp_fn(const struct FileInfo * i) |
| + | #include <time.h> |
| + | #include <utime.h> |
| + | #include <dirent.h> |
| + | |
| + | const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n" |
| + | " or: cp [OPTION]... SOURCE... DIRECTORY\n" |
| + | "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n" |
| + | "\n" |
| + | "\t-a\tsame as -dpR\n" |
| + | "\t-d\tpreserve links\n" |
| + | "\t-p\tpreserve file attributes if possable\n" |
| + | "\t-R\tcopy directories recursively\n"; |
| + | |
| + | |
| + | static int recursiveFlag = FALSE; |
| + | static int followLinks = FALSE; |
| + | static int preserveFlag = FALSE; |
| + | static const char *srcName; |
| + | static const char *destName; |
| + | |
| + | |
| + | static int fileAction(const char *fileName) |
| { | |
| - | int sourceFd; |
| - | int destinationFd; |
| - | const char * destination = i->destination; |
| - | struct stat destination_stat; |
| - | int status; |
| - | char buf[8192]; |
| - | char d[PATH_MAX]; |
| - | |
| - | if ( (i->stat.st_mode & S_IFMT) == S_IFDIR ) { |
| - | if ( mkdir(destination, i->stat.st_mode & ~S_IFMT) |
| - | != 0 && errno != EEXIST ) { |
| - | name_and_error(destination); |
| - | return 1; |
| - | } |
| - | return 0; |
| + | char newdestName[NAME_MAX]; |
| + | strcpy(newdestName, destName); |
| + | strcat(newdestName, fileName+(strlen(srcName))); |
| + | fprintf(stderr, "A: copying %s to %s\n", fileName, newdestName); |
| + | return (copyFile(fileName, newdestName, preserveFlag, followLinks)); |
| + | } |
| + | |
| + | static int dirAction(const char *fileName) |
| + | { |
| + | char newdestName[NAME_MAX]; |
| + | struct stat statBuf; |
| + | struct utimbuf times; |
| + | |
| + | strcpy(newdestName, destName); |
| + | strcat(newdestName, fileName+(strlen(srcName))); |
| + | if (stat(newdestName, &statBuf)) { |
| + | if (mkdir( newdestName, 0777777 ^ umask (0))) { |
| + | perror(newdestName); |
| + | return( FALSE); |
| + | } |
| } | |
| - | if ( (sourceFd = open(i->source, O_RDONLY)) < 0 ) { |
| - | name_and_error(i->source); |
| - | return 1; |
| + | else if (!S_ISDIR (statBuf.st_mode)) { |
| + | fprintf(stderr, "`%s' exists but is not a directory", newdestName); |
| + | return( FALSE); |
| } | |
| - | if ( stat(destination, &destination_stat) == 0 ) { |
| - | if ( i->stat.st_ino == destination_stat.st_ino |
| - | && i->stat.st_dev == destination_stat.st_dev ) { |
| - | fprintf(stderr |
| - | ,"copy of %s to %s would copy file to itself.\n" |
| - | ,i->source |
| - | ,destination); |
| - | close(sourceFd); |
| - | return 1; |
| - | } |
| + | if (preserveFlag==TRUE) { |
| + | /* Try to preserve premissions, but don't whine on failure */ |
| + | if (stat(newdestName, &statBuf)) { |
| + | perror(newdestName); |
| + | return( FALSE); |
| + | } |
| + | chmod(newdestName, statBuf.st_mode); |
| + | chown(newdestName, statBuf.st_uid, statBuf.st_gid); |
| + | times.actime = statBuf.st_atime; |
| + | times.modtime = statBuf.st_mtime; |
| + | utime(newdestName, ×); |
| } | |
| - | /* |
| - | * If the destination is a directory, create a file within it. |
| - | */ |
| - | if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { |
| - | destination = join_paths( |
| - | d |
| - | ,i->destination |
| - | ,&i->source[i->directoryLength]); |
| - | |
| - | if ( stat(destination, &destination_stat) == 0 ) { |
| - | if ( i->stat.st_ino == destination_stat.st_ino |
| - | && i->stat.st_dev == destination_stat.st_dev ) { |
| - | fprintf(stderr |
| - | ,"copy of %s to %s would copy file to itself.\n" |
| - | ,i->source |
| - | ,destination); |
| - | close(sourceFd); |
| - | return 1; |
| - | } |
| - | } |
| + | return TRUE; |
| + | } |
| + | |
| + | extern int cp_main(int argc, char **argv) |
| + | { |
| + | |
| + | int dirFlag; |
| + | |
| + | if (argc < 3) { |
| + | fprintf(stderr, "Usage: %s", cp_usage); |
| + | return (FALSE); |
| } | |
| + | argc--; |
| + | argv++; |
| - | destinationFd = creat(destination, i->stat.st_mode & 07777); |
| + | /* Parse any options */ |
| + | while (**argv == '-') { |
| + | while (*++(*argv)) |
| + | switch (**argv) { |
| + | case 'a': |
| + | followLinks = TRUE; |
| + | preserveFlag = TRUE; |
| + | recursiveFlag = TRUE; |
| + | break; |
| + | case 'd': |
| + | followLinks = TRUE; |
| + | break; |
| + | case 'p': |
| + | preserveFlag = TRUE; |
| + | break; |
| + | case 'R': |
| + | recursiveFlag = TRUE; |
| + | break; |
| + | default: |
| + | fprintf(stderr, "Usage: %s\n", cp_usage); |
| + | exit(FALSE); |
| + | } |
| + | argc--; |
| + | argv++; |
| + | } |
| + | |
| + | |
| + | destName = argv[argc - 1]; |
| - | while ( (status = read(sourceFd, buf, sizeof(buf))) > 0 ) { |
| - | if ( write(destinationFd, buf, status) != status ) { |
| - | name_and_error(destination); |
| - | close(sourceFd); |
| - | close(destinationFd); |
| - | return 1; |
| - | } |
| + | dirFlag = isDirectory(destName); |
| + | |
| + | if ((argc > 3) && !dirFlag) { |
| + | fprintf(stderr, "%s: not a directory\n", destName); |
| + | return (FALSE); |
| } | |
| - | close(sourceFd); |
| - | close(destinationFd); |
| - | if ( status < 0 ) { |
| - | name_and_error(i->source); |
| - | return 1; |
| + | |
| + | while (argc-- >= 2) { |
| + | srcName = *(argv++); |
| + | return recursiveAction(srcName, recursiveFlag, followLinks, |
| + | fileAction, fileAction); |
| } | |
| - | return 0; |
| + | return( TRUE); |
| } | |
| @@ -37,7 +37,7 @@ extern int mv_main (int argc, char **argv) | |
| const char *srcName; | |
| const char *destName; | |
| const char *lastArg; | |
| - | BOOL dirFlag; |
| + | int dirFlag; |
| if (argc < 3) { | |
| fprintf (stderr, "Usage: %s %s", *argv, mv_usage); | |
| @@ -63,7 +63,7 @@ extern int mv_main (int argc, char **argv) | |
| destName = lastArg; | |
| - | if (dirFlag) |
| + | if (dirFlag==TRUE) |
| destName = buildName (destName, srcName); | |
| if (rename (srcName, destName) >= 0) | |
| @@ -74,7 +74,7 @@ extern int mv_main (int argc, char **argv) | |
| continue; | |
| } | |
| - | if (!copyFile (srcName, destName, TRUE)) |
| + | if (!copyFile (srcName, destName, TRUE, FALSE)) |
| continue; | |
| if (unlink (srcName) < 0) | |
| @@ -1,89 +1,141 @@ | |
| + | /* |
| + | * Mini cp 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/fcntl.h> |
| - | #include <sys/param.h> |
| - | #include <errno.h> |
| - | |
| - | const char cp_usage[] = "cp [-r] source-file destination-file\n" |
| - | "\t\tcp [-r] source-file [source-file ...] destination-directory\n" |
| - | "\n" |
| - | "\tCopy the source files to the destination.\n" |
| - | "\n" |
| - | "\t-r:\tRecursively copy all files and directories\n" |
| - | "\t\tunder the argument directory."; |
| - | |
| - | extern int |
| - | cp_fn(const struct FileInfo * i) |
| + | #include <time.h> |
| + | #include <utime.h> |
| + | #include <dirent.h> |
| + | |
| + | const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n" |
| + | " or: cp [OPTION]... SOURCE... DIRECTORY\n" |
| + | "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n" |
| + | "\n" |
| + | "\t-a\tsame as -dpR\n" |
| + | "\t-d\tpreserve links\n" |
| + | "\t-p\tpreserve file attributes if possable\n" |
| + | "\t-R\tcopy directories recursively\n"; |
| + | |
| + | |
| + | static int recursiveFlag = FALSE; |
| + | static int followLinks = FALSE; |
| + | static int preserveFlag = FALSE; |
| + | static const char *srcName; |
| + | static const char *destName; |
| + | |
| + | |
| + | static int fileAction(const char *fileName) |
| { | |
| - | int sourceFd; |
| - | int destinationFd; |
| - | const char * destination = i->destination; |
| - | struct stat destination_stat; |
| - | int status; |
| - | char buf[8192]; |
| - | char d[PATH_MAX]; |
| - | |
| - | if ( (i->stat.st_mode & S_IFMT) == S_IFDIR ) { |
| - | if ( mkdir(destination, i->stat.st_mode & ~S_IFMT) |
| - | != 0 && errno != EEXIST ) { |
| - | name_and_error(destination); |
| - | return 1; |
| - | } |
| - | return 0; |
| + | char newdestName[NAME_MAX]; |
| + | strcpy(newdestName, destName); |
| + | strcat(newdestName, fileName+(strlen(srcName))); |
| + | fprintf(stderr, "A: copying %s to %s\n", fileName, newdestName); |
| + | return (copyFile(fileName, newdestName, preserveFlag, followLinks)); |
| + | } |
| + | |
| + | static int dirAction(const char *fileName) |
| + | { |
| + | char newdestName[NAME_MAX]; |
| + | struct stat statBuf; |
| + | struct utimbuf times; |
| + | |
| + | strcpy(newdestName, destName); |
| + | strcat(newdestName, fileName+(strlen(srcName))); |
| + | if (stat(newdestName, &statBuf)) { |
| + | if (mkdir( newdestName, 0777777 ^ umask (0))) { |
| + | perror(newdestName); |
| + | return( FALSE); |
| + | } |
| } | |
| - | if ( (sourceFd = open(i->source, O_RDONLY)) < 0 ) { |
| - | name_and_error(i->source); |
| - | return 1; |
| + | else if (!S_ISDIR (statBuf.st_mode)) { |
| + | fprintf(stderr, "`%s' exists but is not a directory", newdestName); |
| + | return( FALSE); |
| } | |
| - | if ( stat(destination, &destination_stat) == 0 ) { |
| - | if ( i->stat.st_ino == destination_stat.st_ino |
| - | && i->stat.st_dev == destination_stat.st_dev ) { |
| - | fprintf(stderr |
| - | ,"copy of %s to %s would copy file to itself.\n" |
| - | ,i->source |
| - | ,destination); |
| - | close(sourceFd); |
| - | return 1; |
| - | } |
| + | if (preserveFlag==TRUE) { |
| + | /* Try to preserve premissions, but don't whine on failure */ |
| + | if (stat(newdestName, &statBuf)) { |
| + | perror(newdestName); |
| + | return( FALSE); |
| + | } |
| + | chmod(newdestName, statBuf.st_mode); |
| + | chown(newdestName, statBuf.st_uid, statBuf.st_gid); |
| + | times.actime = statBuf.st_atime; |
| + | times.modtime = statBuf.st_mtime; |
| + | utime(newdestName, ×); |
| } | |
| - | /* |
| - | * If the destination is a directory, create a file within it. |
| - | */ |
| - | if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { |
| - | destination = join_paths( |
| - | d |
| - | ,i->destination |
| - | ,&i->source[i->directoryLength]); |
| - | |
| - | if ( stat(destination, &destination_stat) == 0 ) { |
| - | if ( i->stat.st_ino == destination_stat.st_ino |
| - | && i->stat.st_dev == destination_stat.st_dev ) { |
| - | fprintf(stderr |
| - | ,"copy of %s to %s would copy file to itself.\n" |
| - | ,i->source |
| - | ,destination); |
| - | close(sourceFd); |
| - | return 1; |
| - | } |
| - | } |
| + | return TRUE; |
| + | } |
| + | |
| + | extern int cp_main(int argc, char **argv) |
| + | { |
| + | |
| + | int dirFlag; |
| + | |
| + | if (argc < 3) { |
| + | fprintf(stderr, "Usage: %s", cp_usage); |
| + | return (FALSE); |
| } | |
| + | argc--; |
| + | argv++; |
| - | destinationFd = creat(destination, i->stat.st_mode & 07777); |
| + | /* Parse any options */ |
| + | while (**argv == '-') { |
| + | while (*++(*argv)) |
| + | switch (**argv) { |
| + | case 'a': |
| + | followLinks = TRUE; |
| + | preserveFlag = TRUE; |
| + | recursiveFlag = TRUE; |
| + | break; |
| + | case 'd': |
| + | followLinks = TRUE; |
| + | break; |
| + | case 'p': |
| + | preserveFlag = TRUE; |
| + | break; |
| + | case 'R': |
| + | recursiveFlag = TRUE; |
| + | break; |
| + | default: |
| + | fprintf(stderr, "Usage: %s\n", cp_usage); |
| + | exit(FALSE); |
| + | } |
| + | argc--; |
| + | argv++; |
| + | } |
| + | |
| + | |
| + | destName = argv[argc - 1]; |
| - | while ( (status = read(sourceFd, buf, sizeof(buf))) > 0 ) { |
| - | if ( write(destinationFd, buf, status) != status ) { |
| - | name_and_error(destination); |
| - | close(sourceFd); |
| - | close(destinationFd); |
| - | return 1; |
| - | } |
| + | dirFlag = isDirectory(destName); |
| + | |
| + | if ((argc > 3) && !dirFlag) { |
| + | fprintf(stderr, "%s: not a directory\n", destName); |
| + | return (FALSE); |
| } | |
| - | close(sourceFd); |
| - | close(destinationFd); |
| - | if ( status < 0 ) { |
| - | name_and_error(i->source); |
| - | return 1; |
| + | |
| + | while (argc-- >= 2) { |
| + | srcName = *(argv++); |
| + | return recursiveAction(srcName, recursiveFlag, followLinks, |
| + | fileAction, fileAction); |
| } | |
| - | return 0; |
| + | return( TRUE); |
| } | |
| @@ -27,7 +27,7 @@ | |
| static char* pattern=NULL; | |
| static char* directory=NULL; | |
| - | int dereferenceFlag=FALSE; |
| + | static int dereferenceFlag=FALSE; |
| static const char find_usage[] = "find [path...] [expression]\n" | |
| "default path is the current directory; default expression is -print\n" | |
| @@ -27,7 +27,7 @@ | |
| static char* pattern=NULL; | |
| static char* directory=NULL; | |
| - | int dereferenceFlag=FALSE; |
| + | static int dereferenceFlag=FALSE; |
| static const char find_usage[] = "find [path...] [expression]\n" | |
| "default path is the current directory; default expression is -print\n" | |
| @@ -31,7 +31,7 @@ const char grep_usage[] = | |
| - | static BOOL search (const char *string, const char *word, BOOL ignoreCase); |
| + | static int search (const char *string, const char *word, int ignoreCase); |
| extern int grep_main (int argc, char **argv) | |
| @@ -40,9 +40,9 @@ extern int grep_main (int argc, char **argv) | |
| const char *word; | |
| const char *name; | |
| const char *cp; | |
| - | BOOL tellName; |
| - | BOOL ignoreCase; |
| - | BOOL tellLine; |
| + | int tellName; |
| + | int ignoreCase; |
| + | int tellLine; |
| long line; | |
| char buf[BUF_SIZE]; | |
| @@ -125,7 +125,7 @@ extern int grep_main (int argc, char **argv) | |
| /* | |
| * See if the specified word is found in the specified string. | |
| */ | |
| - | static BOOL search (const char *string, const char *word, BOOL ignoreCase) |
| + | static int search (const char *string, const char *word, int ignoreCase) |
| { | |
| const char *cp1; | |
| const char *cp2; | |
| @@ -31,7 +31,7 @@ const char grep_usage[] = | |
| - | static BOOL search (const char *string, const char *word, BOOL ignoreCase); |
| + | static int search (const char *string, const char *word, int ignoreCase); |
| extern int grep_main (int argc, char **argv) | |
| @@ -40,9 +40,9 @@ extern int grep_main (int argc, char **argv) | |
| const char *word; | |
| const char *name; | |
| const char *cp; | |
| - | BOOL tellName; |
| - | BOOL ignoreCase; |
| - | BOOL tellLine; |
| + | int tellName; |
| + | int ignoreCase; |
| + | int tellLine; |
| long line; | |
| char buf[BUF_SIZE]; | |
| @@ -125,7 +125,7 @@ extern int grep_main (int argc, char **argv) | |
| /* | |
| * See if the specified word is found in the specified string. | |
| */ | |
| - | static BOOL search (const char *string, const char *word, BOOL ignoreCase) |
| + | static int search (const char *string, const char *word, int ignoreCase) |
| { | |
| const char *cp1; | |
| const char *cp2; | |
| @@ -33,11 +33,10 @@ | |
| /* Some useful definitions */ | |
| - | typedef int BOOL; |
| #define STDIN 0 | |
| #define STDOUT 1 | |
| - | #define FALSE ((BOOL) 1) |
| - | #define TRUE ((BOOL) 0) |
| + | #define FALSE ((int) 1) |
| + | #define TRUE ((int) 0) |
| #define PATH_LEN 1024 | |
| #define BUF_SIZE 8192 | |
| @@ -97,6 +96,7 @@ extern int busybox_main(int argc, char** argv); | |
| extern int block_device_main(int argc, char** argv); | |
| extern int cat_more_main(int argc, char** argv); | |
| extern int more_main(int argc, char** argv); | |
| + | extern int cp_main(int argc, char** argv); |
| extern int chgrp_main(int argc, char** argv); | |
| extern int chmod_main(int argc, char** argv); | |
| extern int chown_main(int argc, char** argv); | |
| @@ -172,20 +172,21 @@ struct chunk { | |
| 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); |
| + | int isDirectory(const char *name); |
| + | int isDevice(const char *name); |
| + | int copyFile(const char *srcName, const char *destName, int setModes, |
| + | int followLinks); |
| + | char *buildName(const char *dirName, const char *fileName); |
| + | int 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 recurse, BOOL followLinks, |
| + | int recursiveAction(const char *fileName, int recurse, int followLinks, |
| int (*fileAction) (const char *fileName), | |
| int (*dirAction) (const char *fileName)); | |
| - | BOOL match(const char* text, const char * pattern); |
| + | int match(const char* text, const char * pattern); |
| const char* timeString(time_t timeVal); | |
| @@ -37,7 +37,7 @@ extern int mv_main (int argc, char **argv) | |
| const char *srcName; | |
| const char *destName; | |
| const char *lastArg; | |
| - | BOOL dirFlag; |
| + | int dirFlag; |
| if (argc < 3) { | |
| fprintf (stderr, "Usage: %s %s", *argv, mv_usage); | |
| @@ -63,7 +63,7 @@ extern int mv_main (int argc, char **argv) | |
| destName = lastArg; | |
| - | if (dirFlag) |
| + | if (dirFlag==TRUE) |
| destName = buildName (destName, srcName); | |
| if (rename (srcName, destName) >= 0) | |
| @@ -74,7 +74,7 @@ extern int mv_main (int argc, char **argv) | |
| continue; | |
| } | |
| - | if (!copyFile (srcName, destName, TRUE)) |
| + | if (!copyFile (srcName, destName, TRUE, FALSE)) |
| continue; | |
| if (unlink (srcName) < 0) | |
| @@ -73,18 +73,18 @@ typedef struct | |
| /* | |
| * Static data. | |
| */ | |
| - | static BOOL listFlag; |
| - | static BOOL extractFlag; |
| - | static BOOL createFlag; |
| - | static BOOL verboseFlag; |
| - | static BOOL tostdoutFlag; |
| - | |
| - | static BOOL inHeader; |
| - | static BOOL badHeader; |
| - | static BOOL errorFlag; |
| - | static BOOL skipFileFlag; |
| - | static BOOL warnedRoot; |
| - | static BOOL eofFlag; |
| + | static int listFlag; |
| + | static int extractFlag; |
| + | static int createFlag; |
| + | static int verboseFlag; |
| + | static int tostdoutFlag; |
| + | |
| + | static int inHeader; |
| + | static int badHeader; |
| + | static int errorFlag; |
| + | static int skipFileFlag; |
| + | static int warnedRoot; |
| + | static int eofFlag; |
| static long dataCc; | |
| static int outFd; | |
| static char outName[TAR_NAME_SIZE]; | |
| @@ -114,7 +114,7 @@ static void readHeader(const TarHeader * hp, | |
| /* | |
| * Local procedures to save files into a tar file. | |
| */ | |
| - | static void saveFile(const char * fileName, BOOL seeLinks); |
| + | static void saveFile(const char * fileName, int seeLinks); |
| static void saveRegularFile(const char * fileName, | |
| const struct stat * statbuf); | |
| @@ -122,7 +122,7 @@ static void saveRegularFile(const char * fileName, | |
| static void saveDirectory(const char * fileName, | |
| const struct stat * statbuf); | |
| - | static BOOL wantFileName(const char * fileName, |
| + | static int wantFileName(const char * fileName, |
| int fileCount, char ** fileTable); | |
| static void writeHeader(const char * fileName, | |
| @@ -130,7 +130,7 @@ static void writeHeader(const char * fileName, | |
| static void writeTarFile(int fileCount, char ** fileTable); | |
| static void writeTarBlock(const char * buf, int len); | |
| - | static BOOL putOctal(char * cp, int len, long value); |
| + | static int putOctal(char * cp, int len, long value); |
| extern int | |
| @@ -383,8 +383,8 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable) | |
| time_t mtime; | |
| const char * name; | |
| int cc; | |
| - | BOOL hardLink; |
| - | BOOL softLink; |
| + | int hardLink; |
| + | int softLink; |
| /* | |
| * If the block is completely empty, then this is the end of the | |
| @@ -710,7 +710,7 @@ done: | |
| * they really are, instead of blindly following them. | |
| */ | |
| static void | |
| - | saveFile(const char * fileName, BOOL seeLinks) |
| + | saveFile(const char * fileName, int seeLinks) |
| { | |
| int status; | |
| int mode; | |
| @@ -788,7 +788,7 @@ saveFile(const char * fileName, BOOL seeLinks) | |
| static void | |
| saveRegularFile(const char * fileName, const struct stat * statbuf) | |
| { | |
| - | BOOL sawEof; |
| + | int sawEof; |
| int fileFd; | |
| int cc; | |
| int dataCount; | |
| @@ -897,7 +897,7 @@ saveDirectory(const char * dirName, const struct stat * statbuf) | |
| { | |
| DIR * dir; | |
| struct dirent * entry; | |
| - | BOOL needSlash; |
| + | int needSlash; |
| char fullName[PATH_LEN]; | |
| /* | |
| @@ -1160,7 +1160,7 @@ getOctal(const char * cp, int len) | |
| * The number is zero and space padded and possibly null padded. | |
| * Returns TRUE if successful. | |
| */ | |
| - | static BOOL |
| + | static int |
| putOctal(char * cp, int len, long value) | |
| { | |
| int tempLength; | |
| @@ -1212,7 +1212,7 @@ putOctal(char * cp, int len, long value) | |
| * of path prefixes. An empty list implies that all files are wanted. | |
| * Returns TRUE if the file is selected. | |
| */ | |
| - | static BOOL |
| + | static int |
| wantFileName(const char * fileName, int fileCount, char ** fileTable) | |
| { | |
| const char * pathName; | |
| @@ -1,135 +1,95 @@ | |
| + | /* |
| + | * Mini umount 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 <stdlib.h> |
| - | #include <unistd.h> |
| - | #include <errno.h> |
| - | #include <string.h> |
| #include <stdio.h> | |
| - | #include <mntent.h> |
| #include <sys/mount.h> | |
| + | #include <mntent.h> |
| + | #include <fstab.h> |
| + | #include <errno.h> |
| - | const char umount_usage[] = "umount {filesystem|directory}\n" |
| - | "\tumount -a\n" |
| - | "\n" |
| - | "\tUnmount a filesystem.\n" |
| - | "\t-a:\tUnmounts all mounted filesystems.\n"; |
| - | |
| - | static char * |
| - | stralloc(const char * string) |
| - | { |
| - | int length = strlen(string) + 1; |
| - | char * n = malloc(length); |
| - | memcpy(n, string, length); |
| - | return n; |
| - | } |
| - | |
| - | extern void |
| - | erase_mtab(const char * name) |
| - | { |
| - | struct mntent entries[100]; |
| - | int count = 0; |
| - | FILE * mountTable = setmntent("/etc/mtab", "r"); |
| - | struct mntent * m; |
| - | |
| - | if ( mountTable == 0 |
| - | && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) { |
| - | name_and_error("/etc/mtab"); |
| - | return; |
| - | } |
| - | |
| - | while ( (m = getmntent(mountTable)) != 0 ) { |
| - | entries[count].mnt_fsname = stralloc(m->mnt_fsname); |
| - | entries[count].mnt_dir = stralloc(m->mnt_dir); |
| - | entries[count].mnt_type = stralloc(m->mnt_type); |
| - | entries[count].mnt_opts = stralloc(m->mnt_opts); |
| - | entries[count].mnt_freq = m->mnt_freq; |
| - | entries[count].mnt_passno = m->mnt_passno; |
| - | count++; |
| - | } |
| - | endmntent(mountTable); |
| - | if ( (mountTable = setmntent("/etc/mtab", "w")) ) { |
| - | int i; |
| - | for ( i = 0; i < count; i++ ) { |
| - | int result = ( strcmp(entries[i].mnt_fsname, name) == 0 |
| - | || strcmp(entries[i].mnt_dir, name) == 0 ); |
| - | |
| - | if ( result ) |
| - | continue; |
| - | else |
| - | addmntent(mountTable, &entries[i]); |
| - | } |
| - | endmntent(mountTable); |
| - | } |
| - | else if ( errno != EROFS ) |
| - | name_and_error("/etc/mtab"); |
| - | } |
| + | const char umount_usage[] = "\tumount {filesystem|directory}\n" |
| + | "or to unmount all mounted file systems:\n\tumount -a\n"; |
| static int | |
| - | umount_all(int noMtab) |
| + | umount_all() |
| { | |
| - | struct mntent entries[100]; |
| - | int count = 0; |
| - | FILE * mountTable = setmntent("/etc/mtab", "r"); |
| - | struct mntent * m; |
| - | int status = 0; |
| - | |
| - | if ( mountTable == 0 |
| - | && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) { |
| - | name_and_error("/etc/mtab"); |
| - | return 1; |
| - | } |
| + | int status; |
| + | struct mntent *m; |
| + | FILE *mountTable; |
| - | while ( (m = getmntent(mountTable)) != 0 ) { |
| - | entries[count].mnt_fsname = stralloc(m->mnt_fsname); |
| - | count++; |
| - | } |
| - | endmntent(mountTable); |
| - | |
| - | while ( count > 0 ) { |
| - | int result = umount(entries[--count].mnt_fsname) == 0; |
| - | /* free(entries[count].mnt_fsname); */ |
| - | if ( result ) { |
| - | if ( !noMtab ) |
| - | erase_mtab(entries[count].mnt_fsname); |
| + | if ((mountTable = setmntent ("/proc/mounts", "r"))) { |
| + | while ((m = getmntent (mountTable)) != 0) { |
| + | char *blockDevice = m->mnt_fsname; |
| + | if (strcmp (blockDevice, "/dev/root") == 0) |
| + | blockDevice = (getfsfile ("/"))->fs_spec; |
| + | status=umount (m->mnt_dir); |
| + | if (status!=0) { |
| + | /* Don't bother retrying the umount on busy devices */ |
| + | if (errno==EBUSY) { |
| + | perror(m->mnt_dir); |
| + | continue; |
| + | } |
| + | printf ("Trying to umount %s failed: %s\n", |
| + | m->mnt_dir, strerror(errno)); |
| + | printf ("Instead trying to umount %s\n", blockDevice); |
| + | status=umount (blockDevice); |
| + | if (status!=0) { |
| + | printf ("Couldn't umount %s on %s (type %s): %s\n", |
| + | blockDevice, m->mnt_dir, m->mnt_type, strerror(errno)); |
| + | } |
| } | |
| - | else { |
| - | status = 1; |
| - | name_and_error(entries[count].mnt_fsname); |
| - | } |
| - | } |
| - | return status; |
| + | } |
| + | endmntent (mountTable); |
| + | } |
| + | return( TRUE); |
| } | |
| extern int | |
| - | do_umount(const char * name, int noMtab) |
| + | umount_main(int argc, char * * argv) |
| { | |
| - | if ( umount(name) == 0 ) { |
| - | if ( !noMtab ) |
| - | erase_mtab(name); |
| - | return 0; |
| - | } |
| - | return 1; |
| - | } |
| - | extern int |
| - | umount_main(struct FileInfo * i, int argc, char * * argv) |
| - | { |
| - | int noMtab = 0; |
| + | if (argc < 2) { |
| + | fprintf(stderr, "Usage: %s", umount_usage); |
| + | return(FALSE); |
| + | } |
| + | argc--; |
| + | argv++; |
| - | if ( argv[1][0] == '-' ) { |
| - | switch ( argv[1][1] ) { |
| - | case 'a': |
| - | return umount_all(noMtab); |
| - | case 'n': |
| - | noMtab = 1; |
| - | break; |
| - | default: |
| - | usage(umount_usage); |
| - | return 1; |
| - | } |
| - | } |
| - | if ( do_umount(argv[1],noMtab) != 0 ) { |
| - | fprintf(stderr, "%s: %s.\n", argv[1], strerror(errno)); |
| - | return 1; |
| + | /* Parse any options */ |
| + | while (**argv == '-') { |
| + | while (*++(*argv)) switch (**argv) { |
| + | case 'a': |
| + | return umount_all(); |
| + | break; |
| + | default: |
| + | fprintf(stderr, "Usage: %s\n", umount_usage); |
| + | exit( FALSE); |
| } | |
| - | return 0; |
| + | } |
| + | if ( umount(*argv) == 0 ) |
| + | return (TRUE); |
| + | else { |
| + | perror("umount"); |
| + | return( FALSE); |
| + | } |
| } | |
| + | |
| @@ -1,135 +1,95 @@ | |
| + | /* |
| + | * Mini umount 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 <stdlib.h> |
| - | #include <unistd.h> |
| - | #include <errno.h> |
| - | #include <string.h> |
| #include <stdio.h> | |
| - | #include <mntent.h> |
| #include <sys/mount.h> | |
| + | #include <mntent.h> |
| + | #include <fstab.h> |
| + | #include <errno.h> |
| - | const char umount_usage[] = "umount {filesystem|directory}\n" |
| - | "\tumount -a\n" |
| - | "\n" |
| - | "\tUnmount a filesystem.\n" |
| - | "\t-a:\tUnmounts all mounted filesystems.\n"; |
| - | |
| - | static char * |
| - | stralloc(const char * string) |
| - | { |
| - | int length = strlen(string) + 1; |
| - | char * n = malloc(length); |
| - | memcpy(n, string, length); |
| - | return n; |
| - | } |
| - | |
| - | extern void |
| - | erase_mtab(const char * name) |
| - | { |
| - | struct mntent entries[100]; |
| - | int count = 0; |
| - | FILE * mountTable = setmntent("/etc/mtab", "r"); |
| - | struct mntent * m; |
| - | |
| - | if ( mountTable == 0 |
| - | && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) { |
| - | name_and_error("/etc/mtab"); |
| - | return; |
| - | } |
| - | |
| - | while ( (m = getmntent(mountTable)) != 0 ) { |
| - | entries[count].mnt_fsname = stralloc(m->mnt_fsname); |
| - | entries[count].mnt_dir = stralloc(m->mnt_dir); |
| - | entries[count].mnt_type = stralloc(m->mnt_type); |
| - | entries[count].mnt_opts = stralloc(m->mnt_opts); |
| - | entries[count].mnt_freq = m->mnt_freq; |
| - | entries[count].mnt_passno = m->mnt_passno; |
| - | count++; |
| - | } |
| - | endmntent(mountTable); |
| - | if ( (mountTable = setmntent("/etc/mtab", "w")) ) { |
| - | int i; |
| - | for ( i = 0; i < count; i++ ) { |
| - | int result = ( strcmp(entries[i].mnt_fsname, name) == 0 |
| - | || strcmp(entries[i].mnt_dir, name) == 0 ); |
| - | |
| - | if ( result ) |
| - | continue; |
| - | else |
| - | addmntent(mountTable, &entries[i]); |
| - | } |
| - | endmntent(mountTable); |
| - | } |
| - | else if ( errno != EROFS ) |
| - | name_and_error("/etc/mtab"); |
| - | } |
| + | const char umount_usage[] = "\tumount {filesystem|directory}\n" |
| + | "or to unmount all mounted file systems:\n\tumount -a\n"; |
| static int | |
| - | umount_all(int noMtab) |
| + | umount_all() |
| { | |
| - | struct mntent entries[100]; |
| - | int count = 0; |
| - | FILE * mountTable = setmntent("/etc/mtab", "r"); |
| - | struct mntent * m; |
| - | int status = 0; |
| - | |
| - | if ( mountTable == 0 |
| - | && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) { |
| - | name_and_error("/etc/mtab"); |
| - | return 1; |
| - | } |
| + | int status; |
| + | struct mntent *m; |
| + | FILE *mountTable; |
| - | while ( (m = getmntent(mountTable)) != 0 ) { |
| - | entries[count].mnt_fsname = stralloc(m->mnt_fsname); |
| - | count++; |
| - | } |
| - | endmntent(mountTable); |
| - | |
| - | while ( count > 0 ) { |
| - | int result = umount(entries[--count].mnt_fsname) == 0; |
| - | /* free(entries[count].mnt_fsname); */ |
| - | if ( result ) { |
| - | if ( !noMtab ) |
| - | erase_mtab(entries[count].mnt_fsname); |
| + | if ((mountTable = setmntent ("/proc/mounts", "r"))) { |
| + | while ((m = getmntent (mountTable)) != 0) { |
| + | char *blockDevice = m->mnt_fsname; |
| + | if (strcmp (blockDevice, "/dev/root") == 0) |
| + | blockDevice = (getfsfile ("/"))->fs_spec; |
| + | status=umount (m->mnt_dir); |
| + | if (status!=0) { |
| + | /* Don't bother retrying the umount on busy devices */ |
| + | if (errno==EBUSY) { |
| + | perror(m->mnt_dir); |
| + | continue; |
| + | } |
| + | printf ("Trying to umount %s failed: %s\n", |
| + | m->mnt_dir, strerror(errno)); |
| + | printf ("Instead trying to umount %s\n", blockDevice); |
| + | status=umount (blockDevice); |
| + | if (status!=0) { |
| + | printf ("Couldn't umount %s on %s (type %s): %s\n", |
| + | blockDevice, m->mnt_dir, m->mnt_type, strerror(errno)); |
| + | } |
| } | |
| - | else { |
| - | status = 1; |
| - | name_and_error(entries[count].mnt_fsname); |
| - | } |
| - | } |
| - | return status; |
| + | } |
| + | endmntent (mountTable); |
| + | } |
| + | return( TRUE); |
| } | |
| extern int | |
| - | do_umount(const char * name, int noMtab) |
| + | umount_main(int argc, char * * argv) |
| { | |
| - | if ( umount(name) == 0 ) { |
| - | if ( !noMtab ) |
| - | erase_mtab(name); |
| - | return 0; |
| - | } |
| - | return 1; |
| - | } |
| - | extern int |
| - | umount_main(struct FileInfo * i, int argc, char * * argv) |
| - | { |
| - | int noMtab = 0; |
| + | if (argc < 2) { |
| + | fprintf(stderr, "Usage: %s", umount_usage); |
| + | return(FALSE); |
| + | } |
| + | argc--; |
| + | argv++; |
| - | if ( argv[1][0] == '-' ) { |
| - | switch ( argv[1][1] ) { |
| - | case 'a': |
| - | return umount_all(noMtab); |
| - | case 'n': |
| - | noMtab = 1; |
| - | break; |
| - | default: |
| - | usage(umount_usage); |
| - | return 1; |
| - | } |
| - | } |
| - | if ( do_umount(argv[1],noMtab) != 0 ) { |
| - | fprintf(stderr, "%s: %s.\n", argv[1], strerror(errno)); |
| - | return 1; |
| + | /* Parse any options */ |
| + | while (**argv == '-') { |
| + | while (*++(*argv)) switch (**argv) { |
| + | case 'a': |
| + | return umount_all(); |
| + | break; |
| + | default: |
| + | fprintf(stderr, "Usage: %s\n", umount_usage); |
| + | exit( FALSE); |
| } | |
| - | return 0; |
| + | } |
| + | if ( umount(*argv) == 0 ) |
| + | return (TRUE); |
| + | else { |
| + | perror("umount"); |
| + | return( FALSE); |
| + | } |
| } | |
| + | |
| @@ -27,31 +27,30 @@ | |
| #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> | |
| + | #include <sys/stat.h> |
| + | #include <unistd.h> |
| #if 0 | |
| - | extern char * |
| - | join_paths(char * buffer, const char * a, const char * b) |
| + | extern char *join_paths(char *buffer, const char *a, const char *b) |
| { | |
| - | int length = 0; |
| + | int length = 0; |
| - | if ( a && *a ) { |
| - | length = strlen(a); |
| - | memcpy(buffer, a, length); |
| - | } |
| - | if ( b && *b ) { |
| - | if ( length > 0 && buffer[length - 1] != '/' ) |
| - | buffer[length++] = '/'; |
| - | if ( *b == '/' ) |
| - | b++; |
| - | strcpy(&buffer[length], b); |
| - | } |
| - | return buffer; |
| + | if (a && *a) { |
| + | length = strlen(a); |
| + | memcpy(buffer, a, length); |
| + | } |
| + | if (b && *b) { |
| + | if (length > 0 && buffer[length - 1] != '/') |
| + | buffer[length++] = '/'; |
| + | if (*b == '/') |
| + | b++; |
| + | strcpy(&buffer[length], b); |
| + | } |
| + | return buffer; |
| } | |
| #endif | |
| @@ -61,73 +60,72 @@ join_paths(char * buffer, const char * a, const char * b) | |
| - | static CHUNK * chunkList; |
| + | static CHUNK *chunkList; |
| /* | |
| * Return the standard ls-like mode string from a file mode. | |
| * This is static and so is overwritten on each call. | |
| */ | |
| - | const char * |
| - | modeString(int mode) |
| + | const char *modeString(int mode) |
| { | |
| - | static char buf[12]; |
| - | |
| - | strcpy(buf, "----------"); |
| - | |
| - | /* |
| - | * Fill in the file type. |
| - | */ |
| - | if (S_ISDIR(mode)) |
| - | buf[0] = 'd'; |
| - | if (S_ISCHR(mode)) |
| - | buf[0] = 'c'; |
| - | if (S_ISBLK(mode)) |
| - | buf[0] = 'b'; |
| - | if (S_ISFIFO(mode)) |
| - | buf[0] = 'p'; |
| + | static char buf[12]; |
| + | |
| + | strcpy(buf, "----------"); |
| + | |
| + | /* |
| + | * Fill in the file type. |
| + | */ |
| + | if (S_ISDIR(mode)) |
| + | buf[0] = 'd'; |
| + | if (S_ISCHR(mode)) |
| + | buf[0] = 'c'; |
| + | if (S_ISBLK(mode)) |
| + | buf[0] = 'b'; |
| + | if (S_ISFIFO(mode)) |
| + | buf[0] = 'p'; |
| #ifdef S_ISLNK | |
| - | if (S_ISLNK(mode)) |
| - | buf[0] = 'l'; |
| + | if (S_ISLNK(mode)) |
| + | buf[0] = 'l'; |
| #endif | |
| #ifdef S_ISSOCK | |
| - | if (S_ISSOCK(mode)) |
| - | buf[0] = 's'; |
| + | if (S_ISSOCK(mode)) |
| + | buf[0] = 's'; |
| #endif | |
| - | /* |
| - | * Now fill in the normal file permissions. |
| - | */ |
| - | if (mode & S_IRUSR) |
| - | buf[1] = 'r'; |
| - | if (mode & S_IWUSR) |
| - | buf[2] = 'w'; |
| - | if (mode & S_IXUSR) |
| - | buf[3] = 'x'; |
| - | if (mode & S_IRGRP) |
| - | buf[4] = 'r'; |
| - | if (mode & S_IWGRP) |
| - | buf[5] = 'w'; |
| - | if (mode & S_IXGRP) |
| - | buf[6] = 'x'; |
| - | if (mode & S_IROTH) |
| - | buf[7] = 'r'; |
| - | if (mode & S_IWOTH) |
| - | buf[8] = 'w'; |
| - | if (mode & S_IXOTH) |
| - | buf[9] = 'x'; |
| - | |
| - | /* |
| - | * Finally fill in magic stuff like suid and sticky text. |
| - | */ |
| - | if (mode & S_ISUID) |
| - | buf[3] = ((mode & S_IXUSR) ? 's' : 'S'); |
| - | if (mode & S_ISGID) |
| - | buf[6] = ((mode & S_IXGRP) ? 's' : 'S'); |
| - | if (mode & S_ISVTX) |
| - | buf[9] = ((mode & S_IXOTH) ? 't' : 'T'); |
| - | |
| - | return buf; |
| + | /* |
| + | * Now fill in the normal file permissions. |
| + | */ |
| + | if (mode & S_IRUSR) |
| + | buf[1] = 'r'; |
| + | if (mode & S_IWUSR) |
| + | buf[2] = 'w'; |
| + | if (mode & S_IXUSR) |
| + | buf[3] = 'x'; |
| + | if (mode & S_IRGRP) |
| + | buf[4] = 'r'; |
| + | if (mode & S_IWGRP) |
| + | buf[5] = 'w'; |
| + | if (mode & S_IXGRP) |
| + | buf[6] = 'x'; |
| + | if (mode & S_IROTH) |
| + | buf[7] = 'r'; |
| + | if (mode & S_IWOTH) |
| + | buf[8] = 'w'; |
| + | if (mode & S_IXOTH) |
| + | buf[9] = 'x'; |
| + | |
| + | /* |
| + | * Finally fill in magic stuff like suid and sticky text. |
| + | */ |
| + | if (mode & S_ISUID) |
| + | buf[3] = ((mode & S_IXUSR) ? 's' : 'S'); |
| + | if (mode & S_ISGID) |
| + | buf[6] = ((mode & S_IXGRP) ? 's' : 'S'); |
| + | if (mode & S_ISVTX) |
| + | buf[9] = ((mode & S_IXOTH) ? 't' : 'T'); |
| + | |
| + | return buf; |
| } | |
| @@ -135,15 +133,14 @@ modeString(int mode) | |
| * Return TRUE if a fileName is a directory. | |
| * Nonexistant files return FALSE. | |
| */ | |
| - | BOOL |
| - | isDirectory(const char * name) |
| + | int isDirectory(const char *name) |
| { | |
| - | struct stat statBuf; |
| + | struct stat statBuf; |
| - | if (stat(name, &statBuf) < 0) |
| - | return FALSE; |
| + | if (stat(name, &statBuf) < 0) |
| + | return FALSE; |
| - | return S_ISDIR(statBuf.st_mode); |
| + | return S_ISDIR(statBuf.st_mode); |
| } | |
| @@ -151,15 +148,14 @@ isDirectory(const char * name) | |
| * Return TRUE if a filename is a block or character device. | |
| * Nonexistant files return FALSE. | |
| */ | |
| - | BOOL |
| - | isDevice(const char * name) |
| + | int isDevice(const char *name) |
| { | |
| - | struct stat statBuf; |
| + | struct stat statBuf; |
| - | if (stat(name, &statBuf) < 0) |
| - | return FALSE; |
| + | if (stat(name, &statBuf) < 0) |
| + | return FALSE; |
| - | return S_ISBLK(statBuf.st_mode) || S_ISCHR(statBuf.st_mode); |
| + | return S_ISBLK(statBuf.st_mode) || S_ISCHR(statBuf.st_mode); |
| } | |
| @@ -169,102 +165,118 @@ isDevice(const char * name) | |
| * error message output. (Failure is not indicted if the attributes cannot | |
| * be set.) | |
| */ | |
| - | BOOL |
| + | int |
| copyFile( | |
| - | const char * srcName, |
| - | const char * destName, |
| - | BOOL setModes |
| - | ) |
| + | const char *srcName, |
| + | const char *destName, int setModes, int followLinks) |
| { | |
| - | int rfd; |
| - | int wfd; |
| - | int rcc; |
| - | char buf[BUF_SIZE]; |
| - | struct stat statBuf1; |
| - | struct stat statBuf2; |
| - | struct utimbuf times; |
| - | |
| - | if (stat(srcName, &statBuf1) < 0) |
| - | { |
| - | perror(srcName); |
| - | |
| - | return FALSE; |
| - | } |
| + | int rfd; |
| + | int wfd; |
| + | int rcc; |
| + | char buf[BUF_SIZE]; |
| + | struct stat statBuf1; |
| + | struct stat statBuf2; |
| + | struct utimbuf times; |
| + | |
| + | if (stat(srcName, &statBuf1) < 0) { |
| + | perror(srcName); |
| + | return FALSE; |
| + | } |
| - | if (stat(destName, &statBuf2) < 0) |
| - | { |
| - | statBuf2.st_ino = -1; |
| - | statBuf2.st_dev = -1; |
| - | } |
| + | if (stat(destName, &statBuf2) < 0) { |
| + | statBuf2.st_ino = -1; |
| + | statBuf2.st_dev = -1; |
| + | } |
| - | if ((statBuf1.st_dev == statBuf2.st_dev) && |
| - | (statBuf1.st_ino == statBuf2.st_ino)) |
| - | { |
| - | fprintf(stderr, "Copying file \"%s\" to itself\n", srcName); |
| + | if ((statBuf1.st_dev == statBuf2.st_dev) && |
| + | (statBuf1.st_ino == statBuf2.st_ino)) { |
| + | fprintf(stderr, "Copying file \"%s\" to itself\n", srcName); |
| + | return FALSE; |
| + | } |
| - | return FALSE; |
| + | if (S_ISDIR(statBuf1.st_mode)) { |
| + | /* Make sure the directory is writable */ |
| + | if (mkdir(destName, 0777777 ^ umask(0))) { |
| + | perror(destName); |
| + | return (FALSE); |
| } | |
| - | |
| + | } else if (S_ISFIFO(statBuf1.st_mode)) { |
| + | if (mkfifo(destName, 644)) { |
| + | perror(destName); |
| + | return (FALSE); |
| + | } |
| + | } else if (S_ISBLK(statBuf1.st_mode) || S_ISCHR(statBuf1.st_mode)) { |
| + | if (mknod(destName, 644, statBuf1.st_rdev)) { |
| + | perror(destName); |
| + | return (FALSE); |
| + | } |
| + | } else if (S_ISLNK(statBuf1.st_mode)) { |
| + | char *link_val; |
| + | int link_size; |
| + | |
| + | link_val = (char *) alloca(PATH_MAX + 2); |
| + | link_size = readlink(srcName, link_val, PATH_MAX + 1); |
| + | if (link_size < 0) { |
| + | perror(srcName); |
| + | return (FALSE); |
| + | } |
| + | link_val[link_size] = '\0'; |
| + | if (symlink(link_val, destName)) { |
| + | perror(srcName); |
| + | return (FALSE); |
| + | } |
| + | } else { |
| rfd = open(srcName, O_RDONLY); | |
| - | |
| - | if (rfd < 0) |
| - | { |
| - | perror(srcName); |
| - | |
| - | return FALSE; |
| + | if (rfd < 0) { |
| + | perror(srcName); |
| + | return FALSE; |
| } | |
| wfd = creat(destName, statBuf1.st_mode); | |
| - | |
| - | if (wfd < 0) |
| - | { |
| - | perror(destName); |
| - | close(rfd); |
| - | |
| - | return FALSE; |
| - | } |
| - | |
| - | while ((rcc = read(rfd, buf, sizeof(buf))) > 0) |
| - | { |
| - | if (fullWrite(wfd, buf, rcc) < 0) |
| - | goto error_exit; |
| + | if (wfd < 0) { |
| + | perror(destName); |
| + | close(rfd); |
| + | return FALSE; |
| } | |
| - | if (rcc < 0) |
| - | { |
| - | perror(srcName); |
| + | while ((rcc = read(rfd, buf, sizeof(buf))) > 0) { |
| + | if (fullWrite(wfd, buf, rcc) < 0) |
| goto error_exit; | |
| } | |
| + | if (rcc < 0) { |
| + | perror(srcName); |
| + | goto error_exit; |
| + | } |
| - | (void) close(rfd); |
| - | |
| - | if (close(wfd) < 0) |
| - | { |
| - | perror(destName); |
| + | close(rfd); |
| - | return FALSE; |
| + | if (close(wfd) < 0) { |
| + | perror(destName); |
| + | return FALSE; |
| } | |
| + | } |
| - | if (setModes) |
| - | { |
| - | (void) chmod(destName, statBuf1.st_mode); |
| - | |
| - | (void) chown(destName, statBuf1.st_uid, statBuf1.st_gid); |
| + | if (setModes == TRUE) { |
| + | chmod(destName, statBuf1.st_mode); |
| + | if (followLinks == TRUE) |
| + | chown(destName, statBuf1.st_uid, statBuf1.st_gid); |
| + | else |
| + | lchown(destName, statBuf1.st_uid, statBuf1.st_gid); |
| - | times.actime = statBuf1.st_atime; |
| - | times.modtime = statBuf1.st_mtime; |
| + | times.actime = statBuf1.st_atime; |
| + | times.modtime = statBuf1.st_mtime; |
| - | (void) utime(destName, ×); |
| - | } |
| + | utime(destName, ×); |
| + | } |
| - | return TRUE; |
| + | return TRUE; |
| - | error_exit: |
| - | close(rfd); |
| - | close(wfd); |
| + | error_exit: |
| + | close(rfd); |
| + | close(wfd); |
| - | return FALSE; |
| + | return FALSE; |
| } | |
| @@ -273,25 +285,25 @@ error_exit: | |
| * If the directory name is NULL, then the original fileName is returned. | |
| * The built path is in a static area, and is overwritten for each call. | |
| */ | |
| - | const char * |
| - | buildName(const char * dirName, const char * fileName) |
| + | char *buildName(const char *dirName, const char *fileName) |
| { | |
| - | const char * cp; |
| - | static char buf[PATH_LEN]; |
| + | const char *cp; |
| + | static char buf[PATH_LEN]; |
| - | if ((dirName == NULL) || (*dirName == '\0')) |
| - | return fileName; |
| + | if ((dirName == NULL) || (*dirName == '\0')) { |
| + | strcpy(buf, fileName); |
| + | return buf; |
| + | } |
| - | cp = strrchr(fileName, '/'); |
| + | cp = strrchr(fileName, '/'); |
| - | if (cp) |
| - | fileName = cp + 1; |
| + | if (cp) |
| + | fileName = cp + 1; |
| - | strcpy(buf, dirName); |
| - | strcat(buf, "/"); |
| - | strcat(buf, fileName); |
| + | strcpy(buf, dirName); |
| + | strcat(buf, "/"); |
| - | return buf; |
| + | return buf; |
| } | |
| @@ -302,41 +314,33 @@ buildName(const char * dirName, const char * fileName) | |
| * with an error message given. This does not handle spaces within | |
| * arguments correctly. | |
| */ | |
| - | BOOL |
| - | makeString( |
| - | int argc, |
| - | const char ** argv, |
| - | char * buf, |
| - | int bufLen |
| - | ) |
| + | int makeString( int argc, const char **argv, char *buf, int bufLen) |
| { | |
| - | int len; |
| + | int len; |
| - | while (argc-- > 0) |
| - | { |
| - | len = strlen(*argv); |
| + | while (argc-- > 0) { |
| + | len = strlen(*argv); |
| - | if (len >= bufLen) |
| - | { |
| - | fprintf(stderr, "Argument string too long\n"); |
| + | if (len >= bufLen) { |
| + | fprintf(stderr, "Argument string too long\n"); |
| - | return FALSE; |
| - | } |
| + | return FALSE; |
| + | } |
| - | strcpy(buf, *argv++); |
| + | strcpy(buf, *argv++); |
| - | buf += len; |
| - | bufLen -= len; |
| + | buf += len; |
| + | bufLen -= len; |
| - | if (argc) |
| - | *buf++ = ' '; |
| + | if (argc) |
| + | *buf++ = ' '; |
| - | bufLen--; |
| - | } |
| + | bufLen--; |
| + | } |
| - | *buf = '\0'; |
| + | *buf = '\0'; |
| - | return TRUE; |
| + | return TRUE; |
| } | |
| @@ -346,23 +350,22 @@ makeString( | |
| * list of chunks which can be freed all at one time. You CAN NOT free | |
| * an individual chunk. | |
| */ | |
| - | char * |
| - | getChunk(int size) |
| + | char *getChunk(int size) |
| { | |
| - | CHUNK * chunk; |
| + | CHUNK *chunk; |
| - | if (size < CHUNK_INIT_SIZE) |
| - | size = CHUNK_INIT_SIZE; |
| + | if (size < CHUNK_INIT_SIZE) |
| + | size = CHUNK_INIT_SIZE; |
| - | chunk = (CHUNK *) malloc(size + sizeof(CHUNK) - CHUNK_INIT_SIZE); |
| + | chunk = (CHUNK *) malloc(size + sizeof(CHUNK) - CHUNK_INIT_SIZE); |
| - | if (chunk == NULL) |
| - | return NULL; |
| + | if (chunk == NULL) |
| + | return NULL; |
| - | chunk->next = chunkList; |
| - | chunkList = chunk; |
| + | chunk->next = chunkList; |
| + | chunkList = chunk; |
| - | return chunk->data; |
| + | return chunk->data; |
| } | |
| @@ -371,19 +374,18 @@ getChunk(int size) | |
| * The returned string cannot be individually freed, but can only be freed | |
| * with other strings when freeChunks is called. Returns NULL on failure. | |
| */ | |
| - | char * |
| - | chunkstrdup(const char * str) |
| + | char *chunkstrdup(const char *str) |
| { | |
| - | int len; |
| - | char * newStr; |
| + | int len; |
| + | char *newStr; |
| - | len = strlen(str) + 1; |
| - | newStr = getChunk(len); |
| + | len = strlen(str) + 1; |
| + | newStr = getChunk(len); |
| - | if (newStr) |
| - | memcpy(newStr, str, len); |
| + | if (newStr) |
| + | memcpy(newStr, str, len); |
| - | return newStr; |
| + | return newStr; |
| } | |
| @@ -391,17 +393,15 @@ chunkstrdup(const char * str) | |
| * Free all chunks of memory that had been allocated since the last | |
| * call to this routine. | |
| */ | |
| - | void |
| - | freeChunks(void) |
| + | void freeChunks(void) |
| { | |
| - | CHUNK * chunk; |
| + | CHUNK *chunk; |
| - | while (chunkList) |
| - | { |
| - | chunk = chunkList; |
| - | chunkList = chunk->next; |
| - | free((char *) chunk); |
| - | } |
| + | while (chunkList) { |
| + | chunk = chunkList; |
| + | chunkList = chunk->next; |
| + | free((char *) chunk); |
| + | } |
| } | |
| @@ -411,27 +411,25 @@ freeChunks(void) | |
| * The string is returned from a static buffer, and so is overwritten for | |
| * each call. | |
| */ | |
| - | const char * |
| - | timeString(time_t timeVal) |
| + | const char *timeString(time_t timeVal) |
| { | |
| - | time_t now; |
| - | char * str; |
| - | static char buf[26]; |
| + | time_t now; |
| + | char *str; |
| + | static char buf[26]; |
| - | time(&now); |
| + | time(&now); |
| - | str = ctime(&timeVal); |
| + | str = ctime(&timeVal); |
| - | strcpy(buf, &str[4]); |
| - | buf[12] = '\0'; |
| + | strcpy(buf, &str[4]); |
| + | buf[12] = '\0'; |
| - | if ((timeVal > now) || (timeVal < now - 365*24*60*60L)) |
| - | { |
| - | strcpy(&buf[7], &str[20]); |
| - | buf[11] = '\0'; |
| - | } |
| + | if ((timeVal > now) || (timeVal < now - 365 * 24 * 60 * 60L)) { |
| + | strcpy(&buf[7], &str[20]); |
| + | buf[11] = '\0'; |
| + | } |
| - | return buf; |
| + | return buf; |
| } | |
| @@ -445,88 +443,81 @@ timeString(time_t timeVal) | |
| * \c quotes character c | |
| * Adapted from code written by Ingo Wilken. | |
| */ | |
| - | BOOL |
| - | match(const char * text, const char * pattern) |
| + | int 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; |
| + | const char *retryPat; |
| + | const char *retryText; |
| + | int ch; |
| + | int 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; |
| } | |
| - | return TRUE; |
| + | if (pattern == NULL) |
| + | return FALSE; |
| + | } |
| + | |
| + | return TRUE; |
| } | |
| @@ -535,27 +526,25 @@ match(const char * text, const char * pattern) | |
| * This does multiple writes as necessary. | |
| * Returns the amount written, or -1 on an error. | |
| */ | |
| - | int |
| - | fullWrite(int fd, const char * buf, int len) |
| + | int fullWrite(int fd, const char *buf, int len) |
| { | |
| - | int cc; |
| - | int total; |
| + | int cc; |
| + | int total; |
| - | total = 0; |
| + | total = 0; |
| - | while (len > 0) |
| - | { |
| - | cc = write(fd, buf, len); |
| + | while (len > 0) { |
| + | cc = write(fd, buf, len); |
| - | if (cc < 0) |
| - | return -1; |
| + | if (cc < 0) |
| + | return -1; |
| - | buf += cc; |
| - | total+= cc; |
| - | len -= cc; |
| - | } |
| + | buf += cc; |
| + | total += cc; |
| + | len -= cc; |
| + | } |
| - | return total; |
| + | return total; |
| } | |
| @@ -565,30 +554,28 @@ fullWrite(int fd, const char * buf, int len) | |
| * Returns the amount read, or -1 on an error. | |
| * A short read is returned on an end of file. | |
| */ | |
| - | int |
| - | fullRead(int fd, char * buf, int len) |
| + | int fullRead(int fd, char *buf, int len) |
| { | |
| - | int cc; |
| - | int total; |
| + | int cc; |
| + | int total; |
| - | total = 0; |
| + | total = 0; |
| - | while (len > 0) |
| - | { |
| - | cc = read(fd, buf, len); |
| + | while (len > 0) { |
| + | cc = read(fd, buf, len); |
| - | if (cc < 0) |
| - | return -1; |
| + | if (cc < 0) |
| + | return -1; |
| - | if (cc == 0) |
| - | break; |
| + | if (cc == 0) |
| + | break; |
| - | buf += cc; |
| - | total+= cc; |
| - | len -= cc; |
| - | } |
| + | buf += cc; |
| + | total += cc; |
| + | len -= cc; |
| + | } |
| - | return total; |
| + | return total; |
| } | |
| @@ -598,84 +585,82 @@ fullRead(int fd, char * buf, int len) | |
| * by the fileAction and dirAction function pointers). | |
| */ | |
| int | |
| - | recursiveAction( const char *fileName, BOOL recurse, BOOL followLinks, |
| - | int (*fileAction)(const char* fileName), |
| - | int (*dirAction)(const char* fileName)) |
| + | recursiveAction(const char *fileName, int recurse, int followLinks, |
| + | int (*fileAction) (const char *fileName), |
| + | int (*dirAction) (const char *fileName)) |
| { | |
| - | int status; |
| - | struct stat statbuf; |
| - | struct dirent* next; |
| - | |
| - | if (!recurse && S_ISDIR(statbuf.st_mode)) { |
| - | if (dirAction==NULL) |
| - | return(TRUE); |
| - | else |
| - | return(dirAction(fileName)); |
| - | } else { |
| - | if (fileAction==NULL) |
| - | return(TRUE); |
| - | else |
| - | return(fileAction(fileName)); |
| - | } |
| + | int status; |
| + | struct stat statbuf; |
| + | struct dirent *next; |
| if (followLinks) | |
| - | status = stat(fileName, &statbuf); |
| - | else |
| status = lstat(fileName, &statbuf); | |
| - | |
| + | else |
| + | status = stat(fileName, &statbuf); |
| if (status < 0) { | |
| perror(fileName); | |
| - | return( FALSE); |
| + | return (FALSE); |
| + | } |
| + | |
| + | if (recurse == FALSE) { |
| + | if (S_ISDIR(statbuf.st_mode)) { |
| + | if (dirAction == NULL) |
| + | return (TRUE); |
| + | else |
| + | return (dirAction(fileName)); |
| + | } else { |
| + | if (fileAction == NULL) |
| + | return (TRUE); |
| + | else |
| + | return (fileAction(fileName)); |
| + | } |
| } | |
| if (S_ISDIR(statbuf.st_mode)) { | |
| DIR *dir; | |
| + | fprintf(stderr, "Dir: %s\n", fileName); |
| dir = opendir(fileName); | |
| if (!dir) { | |
| perror(fileName); | |
| - | return(FALSE); |
| + | return (FALSE); |
| + | } |
| + | if (dirAction != NULL) { |
| + | status = dirAction(fileName); |
| + | if (status == FALSE) { |
| + | perror("cp"); |
| + | return (FALSE); |
| + | } |
| } | |
| - | 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, TRUE, followLinks, fileAction, dirAction); |
| - | if (status < 0) { |
| - | closedir(dir); |
| - | return(FALSE); |
| - | } |
| + | 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, TRUE, followLinks, fileAction, |
| + | dirAction); |
| + | if (status < 0) { |
| + | closedir(dir); |
| + | return (FALSE); |
| + | } |
| } | |
| - | status = closedir (dir); |
| + | status = closedir(dir); |
| if (status < 0) { | |
| perror(fileName); | |
| - | return( FALSE); |
| + | return (FALSE); |
| } | |
| - | if (dirAction==NULL) |
| - | return(TRUE); |
| - | else |
| - | return(dirAction(fileName)); |
| - | } |
| - | else { |
| - | if (fileAction==NULL) |
| - | return(TRUE); |
| + | } else { |
| + | fprintf(stderr, "File: %s\n", fileName); |
| + | if (fileAction == NULL) |
| + | return (TRUE); |
| else | |
| - | return(fileAction(fileName)); |
| + | return (fileAction(fileName)); |
| } | |
| + | return (TRUE); |
| } | |
| /* END CODE */ | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |